CGA und Pixel



  • Hi!
    Habe einen alten Laptop mit 10 MHz 640 KByte WRAM und einem Monocromedisplay
    (unterstützt wie ich vermute 4 Helligkeitsstufen ala GamaboyClassic)
    Jetzt ist aber folgende Rotine nicht besonders schnell:

    int main()
    {
       // Videomodus(CGA) einschalten
       asm{
          mov ah,00h
          mov al,06h
          int 10h
       }
    
       for(int x=0; x<640;)
       {
          // x++
          asm{
             inc x
          }
          for(int y=0; y<200;)
          {
             // Pixel via BIOS-Rotine zeichnen
             asm{
                inc y
                mov ah,0Ch
                mov dx,y
                mov cx,x
                mov al,1
                int 10h
             }
          }
       }
    
       // Auf Tasteneingabe warten
       asm{
          mov ah, 0
          int 016h
       }
    }
    

    Wenn es nur auf dem Laptop so lahm laufen würde, wäre es ja OK, aber das es
    auf meinen Athlon XP 2000+ so lahm läuft nicht. (dauert ca. eine halbe sekunde)
    Deswegen wollte ich fragen, wie ich direkt in den Videospeicher schreiben
    kann.
    thx schonmal!
    mfg olli



  • du musst die pixeldaten auf segment adresse 0B800h schreiben, das wird aber nicht so einfach, da du den modus 06h benutzt und der arbeitet etwas komplizierter.

    dieser modus braucht nur ein bit pro pixel deshalb sind in jedem byte, das du schreibst, acht pixel gespeichert. somit musst du, um eine richtige pixelroutine zu schreiben, entweder ein wenig rumtriksen oder gleich die hardware benutzen.

    komischerweise hatte der modus 06 bei mir nur 100 zeilen, ka warum.

    hier ist der source, den ich heute geschrieben hab für TASM. könnte also noch fehler enthalten.

    model   tiny, pascal
    
    .code
            org     100h
    main:
            mov     ax,06h         ; setze modus 06
            int     10h
    
            CALL    pix, x,y,c     ; setze drei pixel in einem abstand
            add     x,2
            CALL    pix, x,y,c
            add     x,2
            CALL    pix, x,y,c
    
            mov     ah,08h         ; warte auf taste
            int     21h
    
            mov     ax,03h         ; zurck in modus 3
            int     10h            
    
            ret                    ; zurck zu dos
    
    ;****************************************************************
    ; die "pix" routine verlangt die x,y koordinate und die farbe
    ; entweder FFh fr weis oder 0 fr schwarz
    ;****************************************************************
    
    pix proc USES ax bx cx dx es, xp,yp,color : word
    
            mov     ax,0B800h           ; grafik speicher ist bei 0B800h
            mov     es,ax
    
            mov     ax,yp
            mov     bx,xp
            mov     cl,bl               ; die bitposition des pixels im byte 
            and     cl,111b              
            shr     bx,3                ; dividiere bx mit 8, da 8 pixel pro byte
    
            shl     ax,1                ; fre aus y*80+x
            shl     ax,1
            shl     ax,1
            shl     ax,1
            shl     ax,1
            shl     ax,1
            add     bx,ax               ; oder hier y*64 + y*16 + x
            shr     ax,1
            shr     ax,1
            add     bx,ax
    
            mov     al,08               ; stelle das bitmask register ein
            mov     dx,3CEh             ; damit nur das bit ver„ndert wird, das
            out     dx,al               ; zum pixel geh”rt
            inc     dx
            mov     al,1
            shl     al,cl
            out     dx,al
    
            mov     al,es:[bx]          ; lade die display latches mit den daten
            mov     al,byte ptr color   ; der anderen pixel
            mov     es:[bx],al          ; setze den pixel
    
            ret
    pix endp
    
    x dw 320
    y dw 50
    c dw 0FFh
    
    end main
    


  • hmm mir ist grad noch aufgefallen, dass der code auf deinem laptop wahrscheinlich nicht läuft falls es ein CGA ist, da der code für eine EGA/VGA geschrieben ist. von CGA hab ich leider keine ahnung, sorry.



  • Dann laesst du halt den Port-Zugriff weg... (ist sogar guenstiger 😉 )
    etwa so:

    mov dl, 01h
    shl dl, cl ;dl enthaelt jetzt das bit, das veraendert wird
    mov dh, dl
    mov al, es:[bx] ;Wert von BS lesen..
    not dh
    and al, dh ;das Bit loeschen, das veraendert wird
    or  al, dl ;neu setzen...
    mov es:[bx], al
    

    Zwar nicht schoen, sollte aber funktionieren...


Anmelden zum Antworten