Metropoli BBS
VIEWER: vgapan.asm MODE: TEXT (CP437)
;**********************************************************;
;* VGAPAN.ASM -- Demonstration of smooth panning in text  *;
;* mode.  Uses an 80x25 window into a 200x80 field.       *;
;**********************************************************;

Ideal

UP          = 4800h                 ;Scan codes for various keys
DOWN        = 5000h
LEFT        = 4B00h
RIGHT       = 4D00h
ESCAPE      = 011Bh

Model Tiny
P186
CodeSeg
Org 100h

Proc        Prog

            mov ax,3                ;Set video mode 3, clear screen
            int 10h

            push 0B800h             ;ES = video memory
            pop es

            mov dx,03D4h            ;Set logical width = 200
            mov ax,6413h
            out dx,ax
            mov ax,9F0Eh            ;Turn off cursor
            out dx,ax

            mov dx,03C2h            ;Set clock for 8 pixels/char
            mov al,063h
            out dx,al
            mov dx,03C4h            ;Set 8 pixels/char
            mov ax,0101h
            out dx,ax

            mov dx,03DAh            ;Re-init AC port
            in al,dx
            mov dx,03C0h            ;Zero panning value
            mov al,33h
            out dx,al
            xor al,al
            out dx,al

            mov si,offset SData     ;SI = screen dump, DI = 0
            xor di,di
            mov ah,1Eh              ;Color is yellow on blue
            xor cx,cx               ;Zero CX

RLEloop:    cmp di,32000            ;32000 bytes in screen
            jae KeyLoop

            lodsb                   ;Get byte

            test al,al              ;0 = 2 spaces
            jz Spaces
            cmp al,0FFh             ;0FFh = 2 █'s
            je Blocks
            cmp al,101              ;> 101, single char
            ja Char                 ;< 101, RLE count

            mov cl,al               ;Store repeated chars
            lodsb
            rep stosw
            jmp RLEloop             ;Loop back

Spaces:     mov al,20h              ;Store 2 spaces
            stosw
            stosw
            jmp RLEloop             ;Loop back

Blocks:     mov al,0DBh             ;Store 2 blocks
            stosw
            stosw
            jmp RLEloop             ;Loop back

Char:       stosw                   ;Store char
            jmp RLEloop             ;Loop back

KeyLoop:    mov ah,1                ;Check for key
            int 16h
            jz Decide

            mov dx,ax               ;DX = key
            xor ah,ah               ;Eat the key
            int 16h

Decide:     cmp dx,UP               ;Up?
            je GoUp
            cmp dx,DOWN             ;Down?
            je GoDown
            cmp dx,LEFT             ;Left?
            je GoLeft
            cmp dx,RIGHT            ;Right?
            je GoRight
            cmp dx,ESCAPE           ;Escape?
            je Quit
            jmp KeyLoop             ;None, loop back

GoUp:       call PanUp              ;Pan up
            jmp KeyLoop

GoDown:     call PanDown            ;Pan down
            jmp KeyLoop

GoLeft:     call PanLeft            ;Pan left
            jmp KeyLoop

GoRight:    call PanRight           ;Pan right
            jmp KeyLoop

Quit:       mov ax,3                ;Reset video mode
            int 10h
            ret                     ;Return

EndP        Prog

;**************************** PanUp -- Pan 2 pixels up

Proc        PanUp

            pusha                   ;Save all registers

            cmp [VByte],0           ;Already at top, quit
            jne PU_ok
            cmp [VPixel],0
            je PU_done

PU_ok:      call WaitNVRT           ;Wait for active period
            mov dx,03D4h            ;DX = CRTC port

            mov ah,[VPixel]         ;AH = pixel
            test ah,ah              ;Next char?
            jnz PU_nobyte

            sub [VByte],200         ;Next char
            mov bx,[VByte]          ;BX = offset
            add bx,[HByte]

            mov al,0Ch              ;Start Address High
            mov ah,bh               ;Get value
            out dx,ax               ;Send command
            inc ax                  ;Start Address Low
            mov ah,bl               ;Get value
            out dx,ax               ;Send command

            xor ah,ah               ;Zero AH

PU_nobyte:  call WaitVRT            ;Wait for vertical retrace

            mov al,8                ;Preset Row Scan
            sub ah,2                ;Move up 2 pixels
            and ah,0Fh              ;0 through 15
            out dx,ax               ;Send command

            mov [VPixel],ah         ;Save value

PU_done:    popa                    ;Restore registers
            ret                     ;Return

EndP        PanUp

;**************************** PanDown -- Pan 2 pixels down

Proc        PanDown

            pusha                   ;Save all registers

            cmp [VByte],11000       ;Already at bottom, quit
            je PD_done

            call WaitNVRT           ;Wait for active period
            mov dx,03D4h            ;DX = CRTC port

            mov ah,[VPixel]         ;AH = pixel
            cmp ah,0Eh              ;Next char?
            jne PD_nobyte

            add [VByte],200         ;Next char
            mov bx,[VByte]          ;BX = offset
            add bx,[HByte]

            mov al,0Ch              ;Start Address High
            mov ah,bh               ;Get value
            out dx,ax               ;Send command
            inc ax                  ;Start Address Low
            mov ah,bl               ;Get value
            out dx,ax               ;Send command

            mov ah,0Eh              ;AH = 0Eh

PD_nobyte:  call WaitVRT            ;Wait for vertical retrace

            mov al,8                ;Preset Row Scan
            add ah,2                ;Move down 2 pixels
            and ah,0Fh              ;0 through 15
            out dx,ax               ;Send command

            mov [VPixel],ah         ;Save value

PD_done:    popa                    ;Restore registers
            ret                     ;Return

EndP        PanDown

;**************************** PanLeft -- Pan 2 pixels left

Proc        PanLeft

            pusha                   ;Save all registers

            cmp [HByte],0           ;Already at left, quit
            jne PL_ok
            cmp [HPixel],0
            je PL_done

PL_ok:      call WaitNVRT           ;Wait for active period
            mov dx,03D4h            ;DX = CRTC port

            mov ah,[HPixel]         ;AH = pixel
            test ah,ah              ;Next char?
            jnz PL_nobyte

            dec [HByte]             ;Next char
            mov bx,[VByte]          ;BX = offset
            add bx,[HByte]

            mov al,0Ch              ;Start Address High
            mov ah,bh               ;Get value
            out dx,ax               ;Send command
            inc ax                  ;Start Address Low
            mov ah,bl               ;Get value
            out dx,ax               ;Send command

            xor ah,ah               ;Zero AH

PL_nobyte:  call WaitVRT            ;Wait for vertical retrace

            mov dx,03C0h            ;AC port
            mov al,33h              ;Horiz. Pixel Pan
            out dx,al               ;Set register
            sub ah,2                ;Move left 2 pixels
            and ah,07h              ;0 through 7
            mov al,ah
            out dx,al               ;Send command

            mov [HPixel],ah         ;Save value

PL_done:    popa                    ;Restore registers
            ret                     ;Return

EndP        PanLeft

;**************************** PanRight -- Pan 2 pixels right

Proc        PanRight

            pusha                   ;Save all registers

            cmp [HByte],120         ;Already at right, quit
            je PR_done

            call WaitNVRT           ;Wait for active period
            mov dx,03D4h            ;DX = CRTC port

            mov ah,[HPixel]         ;AH = pixel
            cmp ah,06h              ;Next char?
            jne PR_nobyte

            inc [HByte]             ;Next char
            mov bx,[VByte]          ;BX = offset
            add bx,[HByte]

            mov al,0Ch              ;Start Address High
            mov ah,bh               ;Get value
            out dx,ax               ;Send command
            inc ax                  ;Start Address Low
            mov ah,bl               ;Get value
            out dx,ax               ;Send command

            mov ah,06h              ;AH = 06h

PR_nobyte:  call WaitVRT            ;Wait for vertical retrace

            mov dx,03C0h            ;AC port
            mov al,33h              ;Horiz. Pixel Pan
            out dx,al               ;Set register
            add ah,2                ;Move right 2 pixels
            and ah,07h              ;0 through 7
            mov al,ah
            out dx,al               ;Send command

            mov [HPixel],ah         ;Save value

PR_done:    popa                    ;Restore registers
            ret                     ;Return

EndP        PanRight

;**************************** WaitVRT -- Wait for next vertical retrace

Proc        WaitVRT

            pusha                   ;Save all registers

            mov dx,03DAh            ;DX = IS1 port

WVloop1:    in al,dx                ;Wait for end of retrace
            test al,8
            jnz WVloop1

WVloop2:    in al,dx                ;Wait for next retrace
            test al,8
            jz WVloop2

            popa                    ;Restore registers
            ret                     ;Return

EndP        WaitVRT

;**************************** WaitNVRT -- Wait for next active period

Proc        WaitNVRT

            pusha                   ;Save all registers

            mov dx,03DAh            ;DX = IS1 port

WNloop1:    in al,dx                ;Wait for end of retrace
            test al,8
            jnz WNloop1

            popa                    ;Restore registers
            ret                     ;Return

EndP        WaitNVRT

;**************************** Memory variables

EVEN

VByte       dw 0
HByte       dw 0
VPixel      db 0
HPixel      db 0

;**************************** Screen data

SData:
 dw 23770,452,288,562,304,288,28483,30060,28269,371,23840,49092,26035
 dw 24864,544,26035,24864,544,26035,24864,544,26035,24864,544,21171
 dw -224,8198,1023,-9184,-9466,2012,-224,8278,45826,8274,-9250,1245
 dw -8672,-8741,-256,1247,-8416,1535,1056,21979,544,21427,-224,8196
 dw 1023,-224,8204,-9250,-8483,-8741,8276,45826,8275,-9250,221,-9250
 dw 989,-224,8195,-9211,8196,255,21759,544,21683,-224,-256,8196,1023
 dw 800,-33,8195,1758,-8741,8275,45826,8276,-9250,-8483,-8741,8196
 dw 1791,-224,8195,1279,-224,8275,45826,8277,-9468,8197,-8961,8196
 dw -36,-8704,-8741,8196,-9250,21213,544,22195,-224,8199,1759,-8229
 dw 8195,1791,-224,8274,45826,8293,8289,45826,8293,8289,45826,8252
 dw -9464,1500,-224,8198,-8961,8197,255,-8961,8197,255,-9464,-256
 dw 1500,-224,8195,1756,-8997,8253,45826,8252,1535,-8416,1023,1056
 dw 1499,800,-8997,8196,255,-9469,1244,-224,8197,1535,800,-8997,8196
 dw 255,-8193,8196,-33,8252,45826,8252,1535,-9184,255,-9250,-8483
 dw -8741,8196,-8193,-8997,8195,255,-8193,-8997,8195,1535,-224,8197
 dw -8193,-8997,8195,255,17663,544,15539,2080,-8229,8195,255,1279
 dw -224,8193,-9249,220,255,511,-8416,-8997,-256,8197,1535,-224,8193
 dw -9249,220,255,1023,1312,15580,544,15539,-224,8201,1758,-8741
 dw 8195,255,-9249,476,-224,-256,-8448,-8997,8193,1535,-224,8197
 dw 255,-9249,476,-224,-256,8195,-8445,15615,544,15539,-224,8201
 dw 1279,-224,8195,1023,-8416,-8997,255,1023,-8416,-8997,1535,-224
 dw 8197,1023,-8416,-8997,255,1791,-224,8252,45826,8252,2303,-8672
 dw -8741,8196,-9250,221,1279,-8416,-9469,-256,8196,991,1499,-224
 dw 8197,1279,-8416,-9469,-256,1244,-9184,15615,544,15539,-224,8200
 dw 1791,-224,-256,8197,-33,-256,8197,-33,2048,219,1535,-8416,1023
 dw -8416,-9466,15839,544,26035,24864,544,26035,24864,544,19379,2080
 dw -8997,8195,-9462,-256,1757,-8672,1023,-9184,-9466,19676,544,19379
 dw -224,8197,-33,-256,8202,-9469,1245,-8672,-9469,-256,1247,-8416
 dw 19455,544,19379,-224,8198,255,2815,-224,-9250,221,-9250,-35,-256
 dw 8198,19455,544,19379,-224,8198,255,-9464,8196,511,-8672,-8741
 dw -9250,477,-224,-256,8198,19455,544,19379,-224,8198,255,2815,-224
 dw -8704,-8705,-256,-256,8198,19455,544,19379,-224,8198,255,2815
 dw -224,8195,-8738,8195,255,1791,-224,8267,45826,8267,1535,-9184
 dw 255,2815,-224,8200,255,-8961,8196,-36,8267,45826,8267,-9464,991
 dw 2592,219,2303,-224,8195,1759,-8229,8268,45826,8293,8289,45826
 dw 8293,8289,45826,8293,8289,26035,25376,288,25912,24864,288,312
 dw 25904,24864,288,25904,25376,288,25938,24864,288,28498,8293,8289
 dw 30575,8293,8289,29559,8293,8289,25971,25376,45856,8293,8289,45826
 dw 8293,8289,45826,8293,8289,45826,8293,8289,45826,8293,8289,45826
 dw 8293,8289,45826,8293,8289,45826,8293,8289,45826,8293,8289,45826
 dw 8293,8289,45826,8293,8289,45826,8241,25306,49092,8241,45826,8241
 dw 25267,45856,8241,45826,8241,1459,288,1,513,256,3,1025,256,5,1537
 dw 256,7,2049,256,9,2561,256,11,3073,256,13,3585,256,15,4097,256
 dw 17,4609,256,19,5121,256,21,5633,256,23,6145,256,25,6657,256,27
 dw 7169,256,29,7681,256,31,12723,544,12723,45856,8290,12723,544
 dw 12723,45856,8197,8449,256,34,8961,256,36,9473,256,38,9985,256
 dw 40,10497,256,42,11009,256,44,11521,256,46,12033,256,48,12545
 dw 256,50,13057,256,52,13569,256,54,14081,256,56,14593,256,58,15105
 dw 256,60,15617,256,62,16129,45824,8241,45826,8241,25267,45856,8241
 dw 45826,8241,179,16385,256,65,16897,256,67,17409,256,69,17921,256
 dw 71,18433,256,73,18945,256,75,19457,256,77,19969,256,79,20481
 dw 256,81,20993,256,83,21505,256,85,22017,256,87,22529,256,89,23041
 dw 256,91,23553,256,93,24065,256,95,12723,544,12723,45856,8290,12723
 dw 544,12723,45856,256,96,24833,256,98,25345,256,100,25857,26112
 dw 26368,26624,26880,27136,27392,27648,27904,28160,28416,28672,28928
 dw 29184,29440,29696,29952,30208,30464,30720,30976,31232,31488,31744
 dw 32000,32256,32512,45824,8241,45826,8241,25267,45856,8241,45826
 dw 8241,179,128,129,130,131,132,133,134,135,136,137,138,139,140
 dw 141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156
 dw 157,158,159,12723,544,12723,45856,8290,12723,544,12723,45856
 dw 40960,41216,41472,41728,41984,42240,42496,42752,43008,43264,43520
 dw 43776,44032,44288,44544,44800,45056,45312,45568,45824,46080,46336
 dw 46592,46848,47104,47360,47616,47872,48128,48384,48640,48896,45824
 dw 8241,45826,8241,25267,45856,8241,45826,8241,179,192,193,194,195
 dw 196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211
 dw 212,213,214,215,216,217,218,219,220,221,222,223,12723,544,12723
 dw 45856,8290,12723,544,12723,45856,-8192,-7936,-7680,-7424,-7168
 dw -6912,-6656,-6400,-6144,-5888,-5632,-5376,-5120,-4864,-4608,-4352
 dw -4096,-3840,-3584,-3328,-3072,-2816,-2560,-2304,-2048,-1792,-1536
 dw -1280,-1024,-768,-512,8197,12723,544,12723,45856,8290,12723,544
 dw 12723,49184,50274,12761,544,26035,24864,544,26035,24864,544,26035
 dw 24864,544,26035,24864,45856,23744,452,288,562,304,288,28483,30060
 dw 28269,371,23840,-9788
End Prog

[ RETURN TO DIRECTORY ]