;**********************************************************;
;* 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