; GWIN.ASM: Graphics window in text mode.
Ideal
Model Tiny
P186
CodeSeg
Org 100h
Start: jmp Prog
PicX dw 8 dup(-1),128,6 dup(0),256,128,3,0,-193,254,0,-256,448,128,3
dw 0,-193,-7937,0,-241,508,128,32775,0,60,-1023,0,127,33087,128
dw 32775,0,60,7936,256,240,-7933,128,49167,0,60,1792,896,192,-3840
dw 128,49167,0,60,768,960,192,-3840,128,-8161,0,60,768,1984,128
dw 30976,128,-8161,0,60,256,2016,128,30976,128,-4036,0,60,256,2016
dw 128,30976,128,-4036,0,60,256,4064,0,15616,128,30840,0,60,0,4080
dw 0,15616,128,30840,0,60,0,4080,0,15616,128,15600,0,60,0,7920,0
dw 256,128,15600,0,60,0,7920,0,256,384,7904,0,60,256,7904,0,256
dw 384,7904,0,60,256,7904,0,256,896,4032,0,60,256,7904,0,256,896
dw 4032,0,60,768,7872,0,256,1920,1920,128,60,768,7872,0,256,1920
dw 1920,128,60,1792,7808,0,256,3968,768,192,60,15872,7680,0,256
dw 3968,768,192,-193,-1793,7680,0,256,7808,256,224,-193,-1793,7680
dw 0,256,7808,256,224,60,15872,7680,0,256,15488,0,240,60,1792,7808
dw 0,256,15488,0,240,60,768,7872,0,256,32640,-1,248,60,768,7872
dw 0,256,32640,-1,248,60,256,7904,0,256,-3968,0,60,60,256,7904,0
dw 256,-3968,0,60,60,256,7904,0,256,-8063,0,30,60,0,7920,0,256,-8063
dw 0,30,60,0,7920,0,256,49283,0,15,60,0,4080,0,15616,49283,0,15
dw 60,0,4080,0,15616,32903,0,32775,60,256,4064,0,15616,32903,0,32775
dw 60,256,2016,128,30976,143,0,49155,60,256,2016,128,30976,143,0
dw 49155,60,768,1984,128,30976,143,0,49155,60,768,960,192,-3840
dw 158,0,-8191,60,1792,896,192,-3840,158,0,-8191,60,7936,256,240
dw -7933,188,0,-4096,60,-1023,0,127,33087,188,0,-4096,-193,-7937
dw 0,-241,508,188,0,-4096,-193,254,0,-256,448,128,6 dup(0),256
dw 8 dup(-1)
Proc Prog
call InitTG ;Init textgraphics
call FillScr ;Fill screen with chars
mov ax,10 ;Open window from
mov bx,5 ;(10, 5) to (25, 7)
mov cx,25 ;in green
mov dx,7
mov si,2
call OpenWin ;Do it...
jc pr_done ;Jump if error
mov si,offset PicX ;Show the picture
call ShowPic
xor ah,ah ;Wait for a key
int 16h
pr_done: mov ax,3 ;Set text mode
int 10h
ret ;Return
EndP Prog
Proc FillScr
pusha ;Save all registers
push es
push 0B800h ;ES = 0B800h
pop es
xor di,di ;Set up for loop
mov ax,0700h
mov cx,2000
fs_loop: stosw ;Write char
inc al ;Next char
loop fs_loop ;Loop back
pop es ;Restore registers
popa
ret ;Return
EndP FillScr
;---------------------------------------------------------------
; Text-Mode Graphics Window procedures start here
;---------------------------------------------------------------
GWinX1 dw 0 ;Graphics window position
GWinY1 dw 0
GWinXD dw 0 ;Graphics window size
GWinYD dw 0
OEData1 dw 0402h,0704h,0204h ;Odd/Even release data
dw 0005h,0C06h
OEData2 dw 0302h,0304h,0004h ;Odd/Even restore data
dw 1005h,0E06h
;**************************** InitTG -- Init textgraphics mode
Proc InitTG
pusha ;Save all registers
mov ax,3 ;Set text mode
int 10h
mov ax,1114h ;Load 16-point font
int 10h
mov dx,03C2h ;Set 25MHz clock
mov al,63h
out dx,al
mov dl,0C4h ;Set 8 bit chars
mov ax,0101h
out dx,ax
mov ax,0403h ;Set double font
out dx,ax
mov dl,0DAh ;Reset AC
in al,dx
mov dl,0C0h ;Set pixel pan 0
mov al,33h
out dx,al
mov al,00h
out dx,al
popa ;Restore registers
ret ;Return
EndP InitTG
;**************************** OpenWin -- Open a graphics window
; ---------------------------------
; AX=x1, BX=y1, CX=x2, DX=y2, SI=color
; Returns: CF=error
Proc OpenWin
pusha ;Save all registers
push es
push 0B800h ;ES = video memory
pop es
sub cx,ax ;CX, DX = distances
sub dx,bx
inc cx
inc dx
push cx dx ;Save CX, DX
xchg ax,cx ;CX = size
mul dx
xchg ax,cx
cmp cx,257 ;Too big?
pop dx cx ;Restore CX, DX
jae ow_done
mov [GWinX1],ax ;Save parameters
mov [GWinY1],bx
mov [GWinXD],cx
mov [GWinYD],dx
imul bp,bx,160 ;BP = offset
add bp,ax
add bp,ax
mov ax,si ;AX = char data
and al,7
add al,8
shl ax,8
mov si,cx ;SI = X distance
ow_oloop: mov cx,si ;CX = length
mov di,bp ;DI = offset
ow_loop: stosw ;Write data
inc ax ;Next char
loop ow_loop ;Loop back
add bp,160 ;Next line
dec dx ;Loop back
jnz ow_oloop
call ClearWin ;Clear the window
stc ;Set carry (gets flipped)
ow_done: pop es ;Restore registers
popa
cmc ;Flip carry flag
ret ;Return
EndP OpenWin
;**************************** ClearWin -- Clear the graphics window
Proc ClearWin
pusha ;Save all registers
push es
push 0B800h ;ES = video memory
pop es
call FontOn ;Get font memory
mov di,4000h ;Clear font bank 1
mov cx,2000h
xor ax,ax
rep stosw
call FontOff ;Back to normal mode
pop es ;Restore registers
popa
ret ;Return
EndP ClearWin
;**************************** FontOn -- Map in font memory
Proc FontOn
pusha ;Save all registers
mov si,offset OEData1 ;SI = OE data 1 (on)
mov dx,03C4h ;Send 2 words to SC
outsw
outsw
mov dl,0CEh ;Send 3 words to GC
outsw
outsw
outsw
popa ;Restore registers
ret ;Return
EndP FontOn
;**************************** FontOff -- Map out font memory
Proc FontOff
pusha ;Save all registers
mov si,offset OEData2 ;SI = OE data 2 (off)
mov dx,03C4h ;Send 2 words to SC
outsw
outsw
mov dl,0CEh ;Send 3 words to GC
outsw
outsw
outsw
popa ;Restore registers
ret ;Return
EndP FontOff
;**************************** SetPixel -- Set one pixel in window
; -----------------------------------
; BX=X, CX=Y, AL=on/off
Proc SetPixel
pusha ;Save all registers
push es
push 0B800h ;ES = video memory
pop es
mov dx,[GWinXD] ;Out of range X?
shl dx,3
cmp bx,dx
jae sp_done
mov dx,[GWinYD] ;Out of range Y?
shl dx,4
cmp cx,dx
jae sp_done
call FontOn ;Get font memory
push ax ;Save AX
mov ax,cx ;AX = Y char * XD
shr ax,4
imul [GWinXD]
mov si,bx ;AX = Y char * XD + X char
shr si,3
add si,ax
shl si,5 ;SI = offset
and cx,15
add si,cx
add si,4000h
mov cx,bx ;CX = position
and cx,7
mov al,80h ;AL = value
shr al,cl
pop bx ;BX = color value
test bx,bx ;Check color value
jz sp_skip1
or [es:si],al ;Set pixel
jmp sp_skip2
sp_skip1: not al ;Reset pixel
and [es:si],al
sp_skip2: call FontOff ;Back to normal mode
sp_done: pop es ;Restore registers
popa
ret ;Return
EndP SetPixel
;**************************** ShowPic -- Load a picture in the window
; ---------------------------------------
; SI = pointer to picture
Proc ShowPic
pusha ;Save all registers
push es
push 0B800h ;ES = video memory
pop es
call FontOn ;Get font memory
mov bp,4000h ;BP = 4000h
mov dx,[GWinXD] ;DX = width * 32
shl dx,5
mov bx,[GWinYD] ;BX = height in chars
sp_loop1: mov ax,16 ;16 lines/char
sp_loop2: mov cx,dx ;CX = length
shr cx,5
mov di,bp ;DI = offset
sp_loop3: movsb ;Move byte
add di,31 ;Next byte
loop sp_loop3 ;Loop back
inc bp ;Move down 1 line
dec ax ;Loop back
jnz sp_loop2
add bp,dx ;Move down 1 char
sub bp,16
dec bx ;Loop back
jnz sp_loop1
call FontOff ;Back to normal mode
pop es ;Restore registers
popa
ret ;Return
EndP ShowPic
End Start