home *** CD-ROM | disk | FTP | other *** search
-
- include grphdrvr.inc
-
- ;******************************************************************************}
- ; TEGL Windows ToolKit II }
- ; Copyright (C) 1990, TEGL Systems Corporation }
- ; All Rights Reserved. }
- ;******************************************************************************}
-
- .code
-
- db 'RT',8,8,'TGI Device Driver (EGA640x350x16/VGA640x480x16) 1.00 - Dec 15 1990',13,10
- db 'Copyright (c) 1989,1990 TEGL Systems Corporation',13,10
- db 01ah ; end of file for TYPE
- db 00 ; end of Copyright Header
-
- db 8,'GRHERCBW',0 ; driver module name
-
- mode0: db 13,'HERC720x348x2',0,0,0,0,0,0,0,0
- dw 0 ; Mode Number
- dw 719 ; Device Full Resolution in X
- dw 347 ; Device Full Resolution in Y
- dw 8 ; Standard char size X
- dw 8 ; Standard char size Y
- dw 1 ; Number of colors
- dw 2 ; Number of pages
- dw 1 ; max palette
- dw 0 ; buffer offset for 2 page
- dw 0B000h ; Screen Segment
- dw 90 ; bytes per line
- dw 7000 ; x aspect
- dw 10000 ; y aspect
- dd 0 ; Driver Pointer
- dd 0 ; Driver Name Pointer
- dd 0 ; Driver Jump Table
- dd 0 ; Graphics Work Buffer
- dw 0 ; Graphics Buffer Size
- dw 0 ; Read/Write modes
- db 0 ; transparency on-$ff/off-$00
- db 0 ; jagged characters
- dd 0 ; pointer to font table
- db 0 ; allow EGA palette changes
- db 0 ; allow VGA 256 palette changes
- db 1 ; proportional font switch
- dw 0ffffh ; fillmask for lines
- dw 0 ; viewport - minx
- dw 0 ; viewport - miny
- dw 719 ; viewport - maxx
- dw 347 ; viewport - maxy
- db 1 ; viewport - clipping on/off
- dw 15 ; Mouse color
- dw 0 ; Mouse hotspot
- dw 0 ; Mouse hotspot
- dd 0 ; Mouse Cursor Mask
- dd 0 ; Next VideoMode
-
- mode1: db 13,'HGC1720x348x2',0,0,0,0,0,0,0,0
- dw 1 ; Mode Number
- dw 719 ; Device Full Resolution in X
- dw 347 ; Device Full Resolution in Y
- dw 8 ; Standard char size X
- dw 8 ; Standard char size Y
- dw 1 ; Number of colors
- dw 1 ; Number of pages
- dw 1 ; max palette
- dw 0 ; buffer offset for 2 page
- dw 0B000h ; Screen Segment
- dw 90 ; bytes per line
- dw 7000 ; x aspect
- dw 10000 ; y aspect
- dd 0 ; Driver Pointer
- dd 0 ; Driver Name Pointer
- dd 0 ; Driver Jump Table
- dd 0 ; Graphics Work Buffer
- dw 0 ; Graphics Buffer Size
- dw 0 ; Read/Write modes
- db 0 ; transparency on-$ff/off-$00
- db 0 ; jagged characters
- dd 0 ; pointer to font table
- db 0 ; allow EGA palette changes
- db 0 ; allow VGA 256 palette changes
- db 1 ; proportional font switch
- dw 0ffffh ; fillmask for lines
- dw 0 ; viewport - minx
- dw 0 ; viewport - miny
- dw 719 ; viewport - maxx
- dw 347 ; viewport - maxy
- db 1 ; viewport - clipping on/off
- dw 15 ; Mouse color
- dw 0 ; Mouse hotspot
- dw 0 ; Mouse hotspot
- dd 0 ; Mouse Cursor Mask
- dd 0 ; Next VideoMode
-
- modeend: dw 0ffffh ; 0ffff - last mode
-
- dw initvideomode ; mode:word,TEGLTable:dword,initflg:byte
- dw setxlattable ; XlatTable:dword
- dw setvideotable ; TEGLTable:dword
- dw getvideotable ; returns pointer to TEGLTable
- dw imagesize ; argx1:word,argy1:word,argx2:word,argy2:word
- dw fastline ; argx1:word,argy1:word,argx2:word,argy2:word,color:word
- dw scanborder ; argx:word,argy:word,bordercolor:word,scan:word
- dw putpixs ; argx:word,argy:word,color:word
- dw getpixs ; argx:word,argy:word
- dw getbiti ; argx0:word,argy0:word,argx1:word,argy1:word,addrbuf:dword
- dw putbiti ; argx:word,argy:word,addrbuf:dword,rmwb:word
- dw extractimg ; argx0:word,argy0:word,argx1:word,argy1:word,addrbuf1:dword,addrbuf2:dword
- dw overlayimg ; argx0:word,argy0:word,addrbuf1:dword,addrbuf2:dword
- dw extractpixs ; argx0:word,argy0:word,addrbuff:dword
- dw wrtchar ; argc:word,argx:word,argy:word,argfgd:word
- dw mcursoroff ;
- dw mcursoron ; argx:word,argy:word
- dw msetpos ; argx:word,argy:word
- dw movevideopixels ; argx0:word,argy0:word,argx1:word,argy1:word,argx2:word,argy2:word,vertlines:word,horzlines:word,spage:word,tpage:word
- dw setvpage ; pagen:word
- dw setapage ; pagen:word
-
- db 16 dup (0) ;required for driver alignment
-
- ; 3 bytes/row * 17rows + 5 byte header
- mcursorsavearea db 60 dup (0)
- mflag dw 0
- scradrofs dw 0
- scradrseg dw 0
- TDTable dd 0
- XLTable dd 0
-
-
- nextinterleave = 2000h
- firstinterleave = 90-8000h
-
-
- CRTCParms DB 00h,35h ; Horizontal Total: 54 characters
- DB 01h,2Dh ; Horizontal Displayed: 45 characters
- DB 02h,2Eh ; Horizontal Sync Position: at 46th character
- DB 03h,07h ; Horizontal Sync Width: 7 character clocks
- DB 04h,5Bh ; Vertical Total: 92 characters (368 lines)
- DB 05h,02h ; Vertical Adjust: 2 scan lines
- DB 06h,57h ; Vertical Displayed: 87 character rows (348 lines)
- DB 07h,57h ; Vertical Sync Position: after 87th char row
- DB 09h,03h ; Max Scan Line: 4 scan lines per char
- CRTCParmsLen EQU ($-CRTCParms)/2
-
- BIOSData DB 6 ; CRT_MODE
- DW 80 ; CRT_COLS
- DW 8000h ; CRT_LEN
- DW 0 ; CRT_START
- DW 8 dup(0) ; CURSOR_POSN
- DW 0 ; CURSOR_MODE
- DB 0 ; ACTIVE_PAGE
- CRTCAddr DW 3B4h ; ADDR_6845
- CRTMode DB 0Ah ; CRT_MODE_SET (value for port 3B8h)
- DB 0 ; CRT_PALETTE (unused)
- BIOSDataLen EQU $-BIOSData
-
-
- initvideomode proc far
- local crtcptr:word
-
- push ds
- push si
- push es
- push di
-
- mov ax,-10
-
- lds si,cs:TDTable
- mov cx,8000h
-
- mov bx,ds:[si].vmodenum
- or bx,bx
- jnz isonepage
-
- push si
- add si,CRTCParms-Mode0
- mov crtcptr,si
- pop si
- add si,BIOSData-Mode0
- jmp short clearvid
-
- isonepage: cmp bx,1
- jne noinitmode
-
- shr cx,1
- push si
- add si,CRTCParms-Mode1
- mov crtcptr,si
- pop si
- add si,BIOSData-Mode1
-
-
- ; clear hercules memory
- clearvid: mov ax,0b000h
- mov es,ax
- xor di,di
- xor ax,ax
-
- cld
- rep stosw
-
- ; Update Video BIOS Data Area
- mov ax,40h
- mov es,ax
- mov di,49h
-
- mov cx,BIOSDataLen
- cld
- rep movsb
-
- ; Set Configuration Switch
- mov dx,3bfh ; configuration port
- mov al,3 ; set to two pages
- test bx,1 ;
- jz settwopage
- shr al,1 ; set to one page
- settwopage: out dx,al
-
- ; set Control Port
- mov dx,3b8h ; control port
- xor al,al ; disable video signal
- out dx,al ; blank screen
-
- ; Program CRTC
- mov dx,3b4h ; Indexport
-
- mov si,crtcptr
- mov cx,CRTCParmsLen
-
- HGCMode0_001: lodsw ; AL := CRTC index
- ; AH := data
- out dx,ax
- loop HGCMode0_001
-
- ; set Graphic Mode
- mov dx,3b8h ; control port
- mov al,10
- out dx,al
- xor ax,ax
-
- noinitmode: pop di
- pop es
- pop si
- pop ds
- ret
- initvideomode endp
-
-
- setxlattable proc far XlatTable:dword
- push es
- push di
-
- les di,XlatTable
- mov word ptr cs:XLTable,di
- mov word ptr cs:XLTable+2,es
-
- pop di
- pop es
- ret
- setxlattable endp
-
- setvideotable proc far TEGLTable:dword
- push es
- push di
-
- les di,TEGLTable
- mov word ptr cs:TDTable,di
- mov word ptr cs:TDTable+2,es
-
- pop di
- pop es
- ret
- setvideotable endp
-
- getvideotable proc far
-
- mov ax,word ptr cs:TDTable
- mov dx,word ptr cs:TDTable+2
-
- ret
- getvideotable endp
-
-
- imagesize proc far argx1:word,argy1:word,argx2:word,argy2:word
- push bx
-
- mov ax,argx2 ;x1-x+1
- sub ax,argx1
- inc ax
-
- mov dx,ax
- mov cl,3
- shr ax,cl ; /8
-
- and dl,07h ; check for byte
- jz hisz01 ; boundary
- inc ax
- hisz01: mov bx,argy2 ;y1-y+1
- sub bx,argy1
- inc bx
- mul bx ;rows x bytes per row
- add ax,6 ;add 6 for header
- adc dx,0
-
- pop bx
- ret
- imagesize endp
-
-
- fastline proc far argx1:word,argy1:word,argx2:word,argy2:word,color:word
- local varleafincr:word,varincr1:word,varincr2:word,varroutine:word
- local rmwb:byte,fillmask:byte,bpline:word,transparent:byte
-
- push ds
- push si
- push es
- push di
-
- cld
- colorxlat color
-
- lds si,cs:TDtable
- mov ax,ds:[si].rmwbits
- mov rmwb,al
-
- mov ax,ds:[si].vbytesperline
- mov bpline,ax
-
- mov ax,ds:[si].teglfillmask
- mov fillmask,al
-
- mov al,ds:[si].transparency
- mov transparent,al
-
- mov si,nextinterleave ; increment for video buffer interleave
- mov di,firstinterleave ; increment from last to first interleave
-
- mov cx,argx2
- sub cx,argx1 ; cx := x2 - x1
- jz vertlinehgc ; jump if vertical line
-
- ; force x1 < x2
-
- jns hgl01 ; jump if x2 > x1
-
- neg cx ; cx := x1 - x2
-
- mov bx,argx2 ; exchange x1 and x2
- xchg bx,argx1
- mov argx2,bx
-
- mov bx,argy2 ; exchange y1 and y2
- xchg bx,argy1
- mov argy2,bx
-
- ; calculate dy = abs(y2-y1)
-
- hgl01: mov bx,argy2
- sub bx,argy1 ; bx := y2 - y1
- jnz hgl02
-
- jmp horizlinehgc ; jump if horizontal line
-
- hgl02: jns hgl03
-
- neg bx ; bx := y1 - y2
- neg si ; negate increments for buffer interleave
- neg di
-
- ; select appropriate routine for slope of line
-
- hgl03: mov varleafincr,di ; save increment for buffer interleave
-
- mov varroutine,0 ; loslopelinehgc
- cmp bx,cx
- jle hgl04 ; jump if dy <= dx (slope <= 1)
- not varroutine ; hislopelinehgc
- xchg bx,cx ; exchange dy and dx
-
- ; calculate initial decision variable and increments
-
- hgl04: shl bx,1 ; bx := 2 * dy
- mov varincr1,bx ; incr1 := 2 * dy
- sub bx,cx
- mov di,bx ; di := d = 2 * dy - dx
- sub bx,cx
- mov varincr2,bx ; incr2 := 2 * (dy - dx)
-
- ; calculate first pixel address
-
- push cx ; preserve this register
- mov ax,argy1 ; ax := y
- mov bx,argx1 ; bx := x
- call activeaddr ; ah := bit mask
- ; es:bx -> buffer
- ; cl := # bits to shift left
-
- rol fillmask,cl ; ***********fillmask
-
- mov al,byte ptr [color] ; al := unshifted pixel value
-
- cmp rmwb,80h
- jnz oknot
- not al
- oknot: and al,1
- shl ax,cl ; ah := bit mask in proper position
- ; al := pixel value in proper position
-
- mov dx,ax ; dh := bit mask
- ; dl := pixel value
- not dh ; dh := inverse bit mask
-
- pop cx ; restore this register
- inc cx ; cx := # of pixels to draw
-
- test varroutine,1 ; jump to appropriate routine for slope
- jnz jmphislopeline
- jmp loslopelinehgc
- jmphislopeline: jmp hislopelinehgc
-
-
- ; routine for vertical lines
-
- vertlinehgc: mov ax,argy1 ; ax := y1
- mov bx,argy2 ; bx := y2
- mov cx,bx
- sub cx,ax ; cx := dy
- jge hgl31 ; jump if dy >= 0
-
- neg cx ; force dy >= 0
- mov ax,bx ; ax := y2
-
- hgl31: inc cx ; cx := # of pixels to draw
- mov bx,argx1 ; bx := x
- push cx ; preserve this register
- call activeaddr ; ah := bit mask
- ; es:bx -> video buffer
- ; cl := # bits to shift left
-
- rol fillmask,cl ; ***********fillmask
-
- mov al,byte ptr [color] ; al := unshifted pixel value
-
- cmp rmwb,80h
- jnz oknot2
- not al
- oknot2: and al,1
- shl ax,cl ; ah := bit mask in proper position
- ; al := pixel value in proper position
- not ah ; ah := inverse bit mask
- pop cx ; restore this register
-
- ; draw the line
- cmp rmwb,18h ; fgxor
- jz hgl36a ; jump if pixel should be xored
-
- test rmwb,08h ; fgand
- jnz hgl35a ; jump if pixel should be anded
-
- test rmwb,10h ; fgor
- jnz hgl37a ; jump if pixel should be ored
-
- ;------------------ [fgnorm] set bit
- hgl32: and es:[bx],ah
-
- mov dh,al
- and al,fillmask
-
- or es:[bx],al ; set pixel values in buffer
- mov al,dh
-
- ror fillmask,1 ; pattern
- add bx,si ; increment to next portion of interleave
- jns hgl33
- add bx,di ; increment to first portion of interleave
- hgl33: loop hgl32
- jmp short hgl36
-
- ;------------------ [fgand] set bit
- hgl35a: mov dh,es:[bx]
-
- mov dl,al
- and al,fillmask
-
- and dh,al
- and es:[bx],ah
- or es:[bx],dh
-
- mov al,dl
- ror fillmask,1 ; pattern
-
- add bx,si ; increment to next portion of interleave
- jns hgl35c
- add bx,di ; increment to first portion of interleave
- hgl35c: loop hgl35a
- jmp short hgl36
-
- ;------------------ [fgxor] set bit
- hgl36a:
- mov dl,al
- and al,fillmask
-
- xor es:[bx],al
- mov al,dl
- ror fillmask,1 ; pattern
-
- add bx,si ; increment to next portion of interleave
- jns hgl36c
- add bx,di ; increment to first portion of interleave
- hgl36c: loop hgl36a
- jmp short hgl36
-
- ;------------------ [fgor] set bit
- hgl37a: mov dh,ah
- not dh ; reverse bits
-
- hgl37b: push dx
- push ax
-
- and al,fillmask
- mov dl,es:[bx] ; get original screen pixel
- and dl,dh ; and with required pixel
- or al,dl ; set it on or off
- and al,dh
- jz hgl37and
- or es:[bx],al ; reset pixel values in buffer
- jmp short hgl37n
- hgl37and: and es:[bx],ah ; reset pixel values in buffer
-
- hgl37n: pop ax
- pop dx
-
- ror fillmask,1 ; pattern
- add bx,si ; increment to next portion of interleave
- jns hgl37c
- add bx,di ; increment to first portion of interleave
- hgl37c: loop hgl37b
- ;------------------
- hgl36: jmp hglexit
-
-
- ; routine for horizontal lines (slope = 0)
-
- horizlinehgc: mov ax,argy1
- mov bx,argx1
- call activeaddr ; ah := bit mask
- ; es:bx -> video buffer
- ; cl := # bits to shift left
- mov di,bx ; es:di -> buffer
-
- mov dh,ah
- not dh ; dh := unshifted bit mask for leftmost
- ; byte
- mov dl,0ffh ; dl := unshifted bit mask for
- ; rightmost byte
-
- shl dh,cl ; dh := reverse bit mask for first byte
- not dh ; dh := bit mask for first byte
-
- test transparent,0ffh
- jnz backfill ; leave the mask alone if pattern fill
- ror fillmask,cl ; ***********fillmask
- ror fillmask,1 ; ***********fillmask
-
- backfill: mov cx,argx2
- and cl,7
- xor cl,7 ; cl := number of bits to shift left
- shl dl,cl ; dl := bit mask for last byte
-
- ; determine byte offset of first and last pixel in the line
-
- mov ax,argx2 ; ax := x2
- mov bx,argx1 ; bx := x1
-
- mov cl,3 ; number of bits to shift to
- ; convert pixels to bytes
-
- shr ax,cl ; ax := byte offset of x2
- shr bx,cl ; bx := byte offset of x1
- mov cx,ax
- sub cx,bx ; cx := (# bytes in line) - 1
-
- mov al,byte ptr [color] ; al := pixel value
- mov ah,byte ptr [fillmask]
- not ah
-
- xor al,ah
- test byte ptr [color],0ffh
- jnz hglcolored
- xor al,al
-
- hglcolored: cmp rmwb,18h ; fgxor
- jz hglxor ; jump if pixel should be xored
-
- test rmwb,08h ; fgand
- jnz hgland ; jump if pixel should be anded
-
- test rmwb,10h ; fgor
- jz chknot
- jmp hglor ; jump if pixel should be ored
-
- chknot: cmp rmwb,80h
- jnz hglnorm
- not al
-
- ;------------------ [fgnorm] set bit
- hglnorm: or dh,dh
- js hgl43 ; jump if byte-aligned (x1 is leftmost
- ; pixel in byte)
- or cx,cx
- jnz hgl42 ; jump if more than one byte in the line
- and dl,dh ; bit mask for the line
- jmp short hgl44
- hgl42: mov ah,al
- and ah,dh ; ah := masked pixel bits
- not dh ; dh := reverse bit mask for 1st byte
- and es:[di],dh ; zero masked pixels in buffer
- or es:[di],ah ; update masked pixels in buffer
- inc di
- dec cx
- hgl43: rep stosb ; update all pixels in the line
- hgl44: and al,dl ; al := masked pixels for last byte
- not dl
- and es:[di],dl ; zero masked pixels in buffer
- or es:[di],al ; update masked pixels in buffer
- jmp hglexit
-
- ;------------------ [fgxor] set bit
- hglxor:
- or cx,cx
- jnz hlxor42 ; jump if more than one byte in the line
- and dl,dh ; bit mask for the line
- jmp short hlxor44
- hlxor42: mov ah,al
- xor ah,es:[di]
- and ah,dh ; ah := masked pixel bits
- not dh ; dh := reverse bit mask for 1st byte
- and es:[di],dh ; zero masked pixels in buffer
- or es:[di],ah ; update masked pixels in buffer
- inc di
- dec cx
- jz hlxor44
- hlxor43: xor es:[di],al
- inc di
- loop hlxor43 ; update all pixels in the line
- hlxor44: xor al,es:[di]
- and al,dl ; al := masked pixels for last byte
- not dl
- and es:[di],dl ; zero masked pixels in buffer
- or es:[di],al ; update masked pixels in buffer
- jmp hglexit
-
- ;------------------ [fgand] set bit
- hgland:
- or cx,cx
- jnz hland42 ; jump if more than one byte in the line
- and dl,dh ; bit mask for the line
- jmp short hland44
- hland42: mov ah,al
- and ah,es:[di]
- and ah,dh ; ah := masked pixel bits
- not dh ; dh := reverse bit mask for 1st byte
- and es:[di],dh ; zero masked pixels in buffer
- or es:[di],ah ; update masked pixels in buffer
- inc di
- dec cx
- jz hland44
- hland43: and es:[di],al
- inc di
- loop hland43 ; update all pixels in the line
- hland44: and al,es:[di]
- and al,dl ; al := masked pixels for last byte
- not dl
- and es:[di],dl ; zero masked pixels in buffer
- or es:[di],al ; update masked pixels in buffer
- jmp hglexit
-
- ;------------------ [fgor] set bit
- hglor:
- or cx,cx
- jnz hlor42 ; jump if more than one byte in the line
- and dl,dh ; bit mask for the line
- jmp short hlor44
- hlor42: mov ah,al
- or ah,es:[di]
- and ah,dh ; ah := masked pixel bits
- not dh ; dh := reverse bit mask for 1st byte
- and es:[di],dh ; zero masked pixels in buffer
- or es:[di],ah ; update masked pixels in buffer
- inc di
- dec cx
- jz hlor44
- hlor43: or es:[di],al
- inc di
- loop hlor43 ; update all pixels in the line
- hlor44: or al,es:[di]
- and al,dl ; al := masked pixels for last byte
- not dl
- and es:[di],dl ; zero masked pixels in buffer
- or es:[di],al ; update masked pixels in buffer
- jmp hglexit
-
-
-
- ; routine for dy <= dx (slope <= 1) ; es:bx -> video buffer
- ; cx = #pixels to draw
- ; dh = inverse bit mask
- ; dl = pixel value in proper position
- ; si = buffer interleave increment
- ; di = decision variable
- loslopelinehgc:
-
- hgl10: mov ah,es:[bx] ; ah := byte from video buffer
-
- hgl11:
- ;****************** check for norm/and/or/xor/not
- test rmwb,0ffh ; fgnorm
- jz hgl14d
-
- test rmwb,08h ; fgand
- jz hgl14b
-
- test rmwb,10h ; fgxor
- jnz hgl14a
-
- push dx
- and dl,fillmask
- mov al,ah ; screen
- and ah,dl ; and with bit
- and al,dh ; mask screen to zero
- or ah,al ; or with new and bit
- pop dx
- jmp short hgl14e
-
- hgl14a: mov al,dl
- and al,fillmask
- xor ah,al
- jmp short hgl14e
-
- hgl14b: test rmwb,80h ; fgnot (implemented above)
- jz hgl14c
- jmp short hgl14d
-
- hgl14c: test rmwb,10h ; fgor
- jz hgl14d
- jmp short hgl14f
-
- ; mov al,dl
- ; and al,fillmask
- ; or ah,al ; set pixel value in byte
- ; jmp short hgl14e
-
- hgl14d: and ah,dh ; zero pixel value at current bit offset
- hgl14f: mov al,dl
- and al,fillmask
- or ah,al ; set pixel value in byte
-
- ;************************************************
- hgl14e: ror dl,1 ; rotate pixel value
- ror dh,1 ; rotate bit mask
- jnc hgl14 ; jump if bit mask rotated to
- ; leftmost pixel position
-
- ; bit mask not shifted out
-
- or di,di ; test sign of d
- jns hgl12 ; jump if d >= 0
-
- add di,varincr1 ; d := d + incr1
- loop hgl11
-
- mov es:[bx],ah ; store remaining pixels in buffer
- jmp hglexit
-
- hgl12: add di,varincr2 ; d := d + incr2
- mov es:[bx],ah ; update buffer
- jmp short hgl15b
-
- ; add bx,si ; increment y
- ; jns hgl13 ; jump if not in last interleave
- ;
- ; add bx,varleafincr ; increment into next interleave
- ;
- ;hgl13: loop hgl10
- ; jmp hglexit
-
- ; bit mask shifted out
-
- hgl14: mov es:[bx],ah ; update buffer
- inc bx ; bx := offset of next byte
-
- or di,di ; test sign of d
- jns hgl15 ; jump if non-negative
-
- add di,varincr1 ; d := d + incr1
- loop hgl10
- jmp short hglexit
-
- hgl15: add di,varincr2 ; d := d + incr2
-
- hgl15b: add bx,si ; increment y
- jns hgl16 ; jump if not in last interleave
-
- add bx,varleafincr ; increment into next interleave
-
- hgl16: loop hgl10 ; loop until all pixels are set
- jmp short hglexit
-
-
- ; routine for dy > dx (slope > 1) ; es:bx -> video buffer
- ; cx = #pixels to draw
- ; dh = inverse bit mask
- ; dl = pixel value in proper position
- ; si = buffer interleave increment
- ; di = decision variable
- hislopelinehgc:
-
- hgl21:
- ;****************** check for norm/and/or/xor/not
- test rmwb,0ffh ; fgnorm
- jz hgl21d
-
- test rmwb,08h ; fgand
- jz hgl21b
-
- test rmwb,10h ; fgxor
- jnz hgl21a
-
- push dx
- and dl,fillmask
- mov al,es:[bx] ; screen
- and al,dl ; and with bit
- and es:[bx],dh ; mask screen to zero
- or es:[bx],al ; or with new and bit
- pop dx
- jmp short hgl21e
-
- hgl21a: push dx
- and dl,fillmask
- xor es:[bx],dl
- pop dx
- jmp short hgl21e
-
- hgl21b: test rmwb,80h ; fgnot (implemented above)
- jz hgl21c
- jmp short hgl21d
-
- hgl21c: test rmwb,10h ; fgor
- jz hgl21d
- push dx
- and dl,fillmask
- or es:[bx],dl ; set pixel value in byte
- pop dx
- jmp short hgl21e
-
- hgl21d: push dx
- and dl,fillmask
- and es:[bx],dh ; zero pixel value in video buffer
- or es:[bx],dl ; set pixel value in byte
- pop dx
-
- ;************************************************
-
- hgl21e: add bx,si ; increment y
- jns hgl22 ; jump if not in last interleave
-
- add bx,varleafincr ; increment into next interleave
-
- hgl22: or di,di
- jns hgl23 ; jump if d >= 0
-
- add di,varincr1 ; d := d + incr1
- loop hgl21
- jmp short hglexit
-
-
- hgl23: add di,varincr2 ; d := d + incr2
-
- ror dl,1 ; rotate pixel value
- ror dh,1 ; rotate bit mask
- cmc ; cf set if bit mask not rotated to
- ; leftmost pixel position
- adc bx,0 ; bx := offset of next byte
-
- loop hgl21
-
- hglexit: pop di
- pop es
- pop si
- pop ds
- ret
- fastline endp
-
-
- putpixs proc far argx:word,argy:word,color:word
- local rmwb:word
-
- push ds
- push si
- push es
- push di
-
- colorxlat color
-
- lds si,cs:TDtable
- mov ax,ds:[si].rmwbits
- mov rmwb,ax
-
- mov ax,ds:[si].wminy
- cmp argy,ax
- jl pix14e
-
- mov ax,ds:[si].wmaxy
- cmp argy,ax
- jg pix14e
-
- mov ax,ds:[si].wminx
- cmp argx,ax
- jl pix14e
-
- mov ax,ds:[si].wmaxx
- cmp argx,ax
- jg pix14e
-
- mov al,byte ptr [color] ; al := unshifted pixel value
- cmp rmwb,80h
- jnz pixnot
- not al
- pixnot: mov byte ptr [color],al
-
- mov ax,argy ; ax := y
- mov bx,argx ; bx := x
- call activeaddr ; ah := bit mask
- ; es:bx -> buffer
- ; cl := # bits to shift left
-
- ; set the pixel value
- shl ah,cl ; ah := bit mask in proper position
- mov al,ah
- not ah
- and al,byte ptr [color]
-
- ;****************** check for norm/and/or/xor/not
- test rmwb,0ffh ; fgnorm
- jz pix14d
-
- test rmwb,08h ; fgand
- jz pix14b
-
- test rmwb,10h ; fgxor
- jnz pix14a
-
- mov dl,es:[bx] ; screen
- and dl,al ; and with bit
- and es:[bx],ah ; mask screen to zero
- or es:[bx],dl ; or with new and bit
- jmp short pix14e
-
- pix14a: xor es:[bx],al
- jmp short pix14e
-
- pix14b: test rmwb,80h ; fgnot (implemented above)
- jz pix14c
- jmp short pix14d
-
- pix14c: test rmwb,10h ; fgor
- jz pix14d
- or es:[bx],al
- jmp short pix14e
-
- pix14d: and es:[bx],ah
- or es:[bx],al
- ;************************************************
- pix14e:
- pop di
- pop es
- pop si
- pop ds
- ret
- putpixs endp
-
-
- scanborder proc far argx:word,argy:word,bordercolor:word,scan:word
- local swminx:word,swmaxx:word,bwminx:word,bwmaxx:word
- push ds
- push si
- push es
- push di
-
- mov cl,3
- lds si,cs:TDtable
- mov ax,ds:[si].wminx
- mov swminx,ax
- shr ax,cl
- mov bwminx,ax
- mov ax,ds:[si].wmaxx
- mov swmaxx,ax
- shr ax,cl
- mov bwmaxx,ax
-
-
- mov ax,argy ; ax := y
- xor bx,bx ; bx := x = 0
- call activeaddr ; ah := bit mask
- ; es:bx -> buffer
- ; cl := #bits to shift
- mov di,bx ; es:di -> buffer
-
- mov ax,argx
- mov si,ax
- mov cl,3
- shr si,cl
- add di,si
-
- test scan,8000h
- jz forwscan
-
- ; inspect first byte
- backscan: mov cx,argx ;create mask to check
- not cl ;first byte
- and cl,7
- mov ch,0ffh
- shl ch,cl
-
- mov al,es:[di]
- dec di
- and al,ch
- jnz scanl05
-
- ;scan remainder of line for border pixels
- mov cx,si
- inc cx
- sub cx,bwminx
- jle scanl05
- jcxz scanl05
-
- std
- repe scasb
- mov al,es:[di+1]
- cld
-
- scanl05: sub di,bx
- inc di
- mov cl,3
- shl di,cl
- mov cx,7
-
- scanl06: shr al,1
- jc scanl07
- loop scanl06
-
- scanl07: add di,cx
- jmp scanl08
-
-
-
- ; inspect first byte
- forwscan: mov cx,argx ;create mask to check
- and cl,7 ;first byte
- mov ch,0ffh
- shr ch,cl
-
- mov al,es:[di]
- inc di
- and al,ch
- jnz scanl01
-
- ;scan remainder of line for border pixels
-
- mov cx,bwmaxx
- inc cx
- sub cx,si
- jle scanl01
- jcxz scanl01
- dec cx
-
- cld
- repe scasb
- mov al,es:[di-1]
-
- scanl01: sub di,bx
- mov cl,3
- shl di,cl
- mov cx,8
-
- scanl02: shl al,1
- jc scanl03
- loop scanl02
-
- scanl03: sub di,cx
-
- scanl08: mov ax,swminx
- dec ax
- cmp di,ax
- jle scanl04
- mov ax,swmaxx
- inc ax
- cmp di,ax
- jge scanl04
-
- mov ax,di
- scanl04:
- pop di
- pop es
- pop si
- pop ds
- ret
- scanborder endp
-
-
- getpixs proc far argx:word,argy:word
- push si
-
- mov ax,argy ; ax := y
- mov bx,argx ; bx := x
- call activeaddr ; ah := bit mask
- ; es:bx -> buffer
- ; cl := #bits to shift
-
- mov al,es:[bx]
- shr al,cl
- and al,ah
- xor ah,ah
-
- pop si
- ret
- getpixs endp
-
-
- getbiti proc far argx0:word,argy0:word,argx1:word,argy1:word,addrbuf:dword
- local varpixelrows : word, varpixelrowlen : word
-
- push ds
- push si
- push di
-
- cld
- ; compute dimensions of bit block
-
- mov ax,argx1
- sub ax,argx0
- mov cx,0ff07h ; ch := unshifted bit mask
- ; cl := and mask for al
- and cl,al ; cl := number of pixels in last
- ; byte of row
- xor cl,7 ; cl := number of bits to shift
- shl ch,cl ; ch := bit mask for last byte of row
- mov cl,ch
- push cx ; save on stack
-
- mov cl,3
- shr ax,cl
- inc ax ; ax := number of bytes per row
- push ax ; save on stack
-
- mov ax,argy1
- sub ax,argy0
- inc ax ; ax := number of pixel rows
- push ax ; save on stack
-
- ; establish addressing
-
- mov ax,argy0
- mov bx,argx0
- call activeaddr ; es:bx -> x0,y0 in video buffer
- xor cl,7 ; cl := number of bits to shift left
- push es
- pop ds
- mov si,bx ; ds:si -> video buffer
-
- les di,addrbuf ; es:di -> buffer in system ram
-
- ; build 5-byte bit block header
-
- pop ax
- mov varpixelrows,ax
- stosw ; byte 0-1 := number of pixel rows
- pop ax
- mov varpixelrowlen,ax
- stosw ; byte 2-3 := bytes per pixel row
- pop ax
- mov ch,al ; ch := bit mask for last byte
- stosb ; byte 4 := bit mask for last byte
-
- ; copy from video buffer to system ram
-
- getbl02: mov bx,varpixelrowlen
- push si ; preserve si at start of pixel row
-
- getbl03: lodsw ; al := next byte in video buffer
- ; ah := (next byte) + 1
- dec si ; ds:si -> (next byte) + 1
- rol ax,cl ; al := next 4 pixels in row
- stosb ; copy to system ram
- dec bx ; loop across row
- jnz getbl03
-
- and es:[di-1],ch ; mask last byte of row
- pop si ; ds:si -> start of row
- add si,nextinterleave ; ds:si -> start of next row
- jns gbl03a
- add si,firstinterleave
- gbl03a: dec varpixelrows
- jnz getbl02 ; loop down rows
-
-
- pop di
- pop si
- pop ds
- ret
- getbiti endp
-
-
- putbiti proc far argx:word,argy:word,addrbuf:dword,rmwb:word
- local varpixelrows:word,varpixelrowlen:word
-
- ; rmwbits - normalput 00h
- ; xorput 18h
- ; orput 10h
- ; andput 08h
- ; notput 80h
-
- push ds
- push si
- push di
-
- cld
- ; establish addressing
-
- mov ax,argy
- mov bx,argx
- call activeaddr ; es:bx -> byte offset of x,y
- xor cl,7 ; cl := number of bits to shift right
-
- mov di,bx ; es:di -> x,y in video buffer
- lds si,addrbuf ; es:di -> buffer in system ram
-
- ; obtain dimensions of bit block from header
-
- lodsw ; ax := number of pixel rows
- mov varpixelrows,ax
- lodsw ; ax := bytes per pixel row
- mov varpixelrowlen,ax
- lodsb ; al := bit mask for last byte in row
- mov ch,al
-
- ;****************** check for norm/and/or/xor/not
- test rmwb,0ffh ; fgnorm
- jz replacebitblock
-
- cmp rmwb,18h ; fgxor
- jnz puttst00
- jmp xorbitblock
-
- puttst00: test rmwb,08h ; fgand
- jz puttst01
- jmp andbitblock
-
- puttst01: test rmwb,10h ; fgor
- jz puttst02
- jmp orbitblock
-
- puttst02: test rmwb,80h ; fgnot (implemented above)
- jz replacebitblock
- jmp notbitblock
- ;************************************************
-
- replacebitblock:
- cmp cx,0ff00h ; if mask <> 0ffh or bits to shift <> 0
- jne putbl15 ; jump if not byte-aligned
-
- ; routine for byte-aligned bit blocks
-
- mov cx,varpixelrowlen
-
- putbl10: push di ; preserve di and cx
- push cx
-
- shr cx,1 ; copy one pixel row into video buffer
- rep movsw
- adc cx,0
- rep movsb
-
- pop cx ; restore di and cx
- pop di
- add di,nextinterleave ; es:di -> next pixel row in buffer
- jns pbl10a
- add di,firstinterleave
- pbl10a: dec varpixelrows
- jnz putbl10 ; loop down pixel rows
-
- jmp lexit2
-
- ; routine for all other bit blocks
-
- putbl15: not ch ; ch := mask for end of row
- mov dx,0ff00h
- ror dx,cl ; dx := rotated mask for each byte
-
- mov bx,varpixelrowlen
- dec bx ; bx := bytes per row - 1
-
- putbl16: push di
- test bx,bx
- jz putbl18 ; jump if only one byte per row
-
- push bx
-
- putbl17: and es:[di],dx ; mask next 8 pixels in video buffer
- lodsb ; al := pixels in bit block
- xor ah,ah
- ror ax,cl ; ax := pixels rotated into position
- or es:[di],ax ; set pixels in video buffer
- inc di ; es:di -> next byte in bit block
- dec bx
- jnz putbl17
-
- pop bx
-
- putbl18: mov al,ch
- mov ah,0ffh ; ax := mask for last pixels in row
- ror ax,cl ; ax := mask rotated into position
- and es:[di],ax ; mask last pixels in video buffer
- lodsb ; al := last byte in row
- xor ah,ah
- ror ax,cl ; ax := pixels rotated into position
- or es:[di],ax ; set pixels in video buffer
-
- pop di
- add di,nextinterleave ; es:di -> next pixel row in buffer
- jns pbl18a
- add di,firstinterleave
- pbl18a: dec varpixelrows
- jnz putbl16 ; loop down pixel rows
-
- jmp lexit2
-
-
- xorbitblock:
- mov bx,varpixelrowlen
-
- putbl20: push di
- push bx
-
- putbl21: lodsb ; al := pixels in bit block
- xor ah,ah
- ror ax,cl ; ax := pixels rotated into position
- xor es:[di],ax ; xor pixels into video buffer
- inc di ; es:di -> next byte in bit block
- dec bx
- jnz putbl21
-
- pop bx
- pop di
- add di,nextinterleave ; es:di -> next pixel row in buffer
- jns pbl21a
- add di,firstinterleave
- pbl21a: dec varpixelrows
- jnz putbl20 ; loop down pixel rows
-
- jmp lexit2
-
- andbitblock:
- not ch ; ch := mask for end of row
-
- mov bx,varpixelrowlen
- dec bx ; bx := bytes per row - 1
-
- putbl30: push di
- test bx,bx
- jz putbl32 ; jump if only one byte per row
-
- push bx
-
- putbl31: lodsb ; al := pixels in bit block
- mov ah,0ffh
- ror ax,cl ; ax := pixels rotated into position
- and es:[di],ax ; and pixels into video buffer
- inc di ; es:di -> next byte in bit block
- dec bx
- jnz putbl31
-
- pop bx
-
- putbl32: lodsb ; al := last byte in row
- or al,ch ; mask last pixels in row
- mov ah,0ffh
- ror ax,cl ; ax := pixels rotated into position
- and es:[di],ax ; and pixels into video buffer
-
- pop di
- add di,nextinterleave ; es:di -> next pixel row in buffer
- jns pbl32a
- add di,firstinterleave
- pbl32a: dec varpixelrows
- jnz putbl30 ; loop down pixel rows
-
- jmp lexit2
-
-
- orbitblock:
- mov bx,varpixelrowlen
-
- putbl40: push di
- push bx
-
- putbl41: lodsb ; al := pixels in bit block
- xor ah,ah
- ror ax,cl ; ax := pixels rotated into position
- or es:[di],ax ; or pixels into video buffer
- inc di ; es:di -> next byte in bit block
- dec bx
- jnz putbl41
-
- pop bx
- pop di
- add di,nextinterleave ; es:di -> next pixel row in buffer
- jns pbl41a
- add di,firstinterleave
- pbl41a: dec varpixelrows
- jnz putbl40 ; loop down pixel rows
- jmp lexit2
-
- notbitblock:
- not ch ; ch := mask for end of row
- mov dx,0ff00h
- ror dx,cl ; dx := rotated mask for each byte
-
- mov bx,varpixelrowlen
- dec bx ; bx := bytes per row - 1
-
- notbl16: push di
- test bx,bx
- jz notbl18 ; jump if only one byte per row
-
- push bx
-
- notbl17: and es:[di],dx ; mask next 8 pixels in video buffer
- lodsb ; al := pixels in bit block
- not al
- xor ah,ah
- ror ax,cl ; ax := pixels rotated into position
- or es:[di],ax ; set pixels in video buffer
- inc di ; es:di -> next byte in bit block
- dec bx
- jnz notbl17
-
- pop bx
-
- notbl18: mov al,ch
- mov ah,0ffh ; ax := mask for last pixels in row
- ror ax,cl ; ax := mask rotated into position
- and es:[di],ax ; mask last pixels in video buffer
- lodsb ; al := last byte in row
- not al
- not ch
- and al,ch
- not ch
- xor ah,ah
- ror ax,cl ; ax := pixels rotated into position
- or es:[di],ax ; set pixels in video buffer
-
- pop di
- add di,nextinterleave ; es:di -> next pixel row in buffer
- jns nbl18a
- add di,firstinterleave
- nbl18a: dec varpixelrows
- jnz notbl16 ; loop down pixel rows
-
-
- lexit2: pop di
- pop si
- pop ds
- ret
-
- putbiti endp
-
-
-
- extractimg proc far argx0:word,argy0:word,argx1:word,argy1:word,addrbuf1:dword,addrbuf2:dword
- local var1pixelrows : word, var1pixelrowlen : word
- local var2pixelrows : word, var2pixelrowlen : word
-
- push ds
- push si
- push es
- push di
-
- les di,addrbuf1
- lds si,addrbuf2
-
- cld
- lodsw ; var2pixelrows
- mov var2pixelrows,ax
- lodsw ; var2pixelrows
- mov var2pixelrowlen,ax
- lodsb
-
-
- ; compute dimensions of bit block
- ; build 5-byte bit block header
-
- ; number of pixel rows
- mov ax,argy1
- sub ax,argy0
- inc ax
- mov var1pixelrows,ax
- stosw
-
- ; number of bytes per row
- mov ax,argx1
- sub ax,argx0
- push ax
- mov cl,3 ; divide by 8 pix per byte
- shr ax,cl
- inc ax ; ax := number of bytes per row
- mov var1pixelrowlen,ax
- stosw
- pop ax
-
- ; last byte in row bit mask
- mov cx,0ff07h ; ch := unshifted bit mask
- ; cl := and mask for al
- and cl,al ; cl := remaining pixels in
- ; last byte of row
- xor cl,7
- shl ch,cl ; create the last byte mask
-
- mov al,ch
- stosb
-
- ; establish addressing
-
- mov ax,argy0
- mov bx,argx0
- mov cl,bl
-
- mov dx,var2pixelrowlen
- mul dx ; multiply rows by bytesperrow
-
- shr bx,1 ; divide x coordinate by 8
- shr bx,1
- shr bx,1
- add bx,ax ; add to address
- add si,bx
-
- and cl,7 ; bits remainder
-
- ; copy from bit block2 to bit block1
- mov dx,var1pixelrows
- extrc07: mov bx,var1pixelrowlen
- push si
-
- extrc08: lodsw
- dec si
- rol ax,cl
- stosb
- dec bx
- jnz extrc08
-
- and es:[di-1],ch
- pop si
- add si,var2pixelrowlen
-
- dec dx
- jnz extrc07
-
-
- pop di
- pop es
- pop si
- pop ds
- ret
-
- extractimg endp
-
-
-
- overlayimg proc far argx0:word,argy0:word,addrbuf1:dword,addrbuf2:dword
- local var1pixelrows : word, var1pixelrowlen : word
- local var2pixelrows : word, var2pixelrowlen : word
- local varstartmask : byte, varendmaskl : byte
- local varendmaskr : byte, screenmask : byte
-
- push ds
- push si
- push es
- push di
-
- cld
-
- lds si,addrbuf2
- lodsw ; var2pixelrows
- mov var2pixelrows,ax
- lodsw ; var2pixelrows
- mov var2pixelrowlen,ax
- lodsb
-
- push ds
- push si
- pop di ; es:di -> addrbuf2
- pop es
-
- lds si,addrbuf1
- lodsw ; var1pixelrows
- mov var1pixelrows,ax
- lodsw ; var1pixelrows
- mov var1pixelrowlen,ax
- lodsb
- mov ch,al ; ds:si -> addrbuf1
- ; ch -> last byte mask
-
- ; establish addressing
-
- mov ax,argy0
- mov bx,argx0
- mov cl,bl
-
- mov dx,var2pixelrowlen
- mul dx ; multiply rows by bytesperrow
-
- shr bx,1 ; divide x coordinate by 8
- shr bx,1
- shr bx,1
- add bx,ax
- add di,bx ; add to address of addrbuf2
-
- and cl,7
- xor cl,7
- inc cl
- and cl,7 ; bits remainder
-
- cmp cx,0ff00h
- jne overl15
-
- ; routine for byte-aligned bit blocks
- mov cx,var1pixelrowlen
-
- mov bx,var1pixelrows
-
- overl11: push di
- push cx
-
- shr cx,1
- rep movsw
- adc cx,0
- rep movsb
-
- pop cx
- pop di
- add di,var2pixelrowlen
- dec bx
- jnz overl11
- jmp overlexit
-
-
- ; copy from bit block2 to bit block1
-
- overl15: mov bx,0ffh ; bh := 0 (mask for first byte in row
- ; bl := 0ffh
- mov al,ch ; al := mask for last byte in pixel row
- cbw ; ah := 0ffh (mask for last-1 byte)
-
- cmp var1pixelrowlen,1
- jne overl16 ; jump if more than one byte per row
-
- mov bl,ch
- mov ah,ch ; ah := mask for last-1 byte
- xor al,al ; al := 0 (mask for last byte)
-
- overl16: shl ax,cl ; shift masks into position
- shl bx,cl
-
-
- ; use not to invert mask
- not ax
- mov varendmaskl,ah
- mov varendmaskr,al
- not bh
- mov varstartmask,bh
-
- mov bx,var1pixelrowlen
-
- ; set pixels row by row in the bit planes
-
- mov ax,var1pixelrows
- overl18: push ax
- push di ; offset of start of pixel row
- push si ; offset of row in bit block
- push bx ; bytes per pixel row
-
- mov al,varstartmask ; mask first byte of row
- mov screenmask,al
-
- lodsw ; ah := 2nd byte of pixels
- ; al := 1st byte of pixels
- dec si ; ds:si -> 2nd byte of pixels
- test cl,cl
- jnz overl19 ; jump if not left-aligned
-
- dec bx ; bx := bytes per row - 1
- jnz overl20 ; jump if at least 2 bytes per row
- jmp short overl22 ; jump if only one byte per row
-
- overl19: rol ax,cl ; ah := left part of 1st byte,
- ; right part of 2nd byte
-
- mov dl,screenmask
- push ax
- and es:[di],dl
- not dl
- and ah,dl
- or es:[di],ah ; or pixels for left part of first byte
- pop ax
-
- inc di
- dec bx ; bx := bytes per row - 2
-
- overl20: ; set up bit mask for succeeding bytes
-
- mov screenmask,0
-
- dec bx
- jng overl22 ; jump if only 1 or 2 bytes in pixel
-
- ; set pixels in middle of row
-
- overl21: mov dl,screenmask
- and es:[di],dl ; set pixels in right part of current
- not dl
- and al,dl
- or es:[di],al ; set pixels in right part of current
- inc di ; byte and left part of next byte
-
- lodsw ; ah := next+1 byte of pixels
- dec si ; al := next byte of pixels
- rol ax,cl ; ah := left part of next byte, right
- ; part of next+1 byte
- dec bx
- jnz overl21 ; loop across pixel row
-
- ; set pixels at end of row
-
- overl22: mov bx,ax
- mov al,varendmaskl
- and es:[di],al
- not al
- and bl,al
- or es:[di],bl
-
- mov al,varendmaskr
- and es:[di+1],al
- not al
- and bh,al
- or es:[di+1],bh
-
- pop bx
- pop si
- add si,bx
- pop di
- add di,var2pixelrowlen
-
- pop ax
- dec ax
- jnz overl18
-
- overlexit: pop di
- pop es
- pop si
- pop ds
- ret
- overlayimg endp
-
-
- extractpixs proc far argx0:word,argy0:word,addrbuff:dword
- local varpixelrows : word, varpixelrowlen : word
-
- push ds
- push si
- lds si,addrbuff
-
- cld
- lodsw ; varpixelrows
- mov varpixelrows,ax
- lodsw ; varpixelrows
- mov varpixelrowlen,ax
- lodsb
-
- ; establish addressing
- mov ax,argy0
- mov bx,argx0
- mov cl,bl
-
- mov dx,varpixelrowlen
- mul dx ; multiply rows by bytesperrow
-
- shr bx,1 ; divide x coordinate by 8
- shr bx,1
- shr bx,1
- add bx,ax ; add to address
- add si,bx
-
- and cl,7 ; bits remainder
- xor cl,7
-
- xor ax,ax
-
- mov al,ds:[si]
- shr al,cl
- and al,1
-
- pop si
- pop ds
- ret
-
- extractpixs endp
-
-
- wrtchar proc far argc:word,argx:word,argy:word,argfgd:word,argbgd:word
- local varshift:word,jaggy:word,transparent:byte,charshift:byte
- local rmwb:word,bpline:word,bpchar:byte,lastbytemask:byte
- local jaghold:byte
-
- push ds
- push si
- push es
- push di
-
- colorxlat argfgd
-
- ; set up character definition table addressing
-
- lds si,cs:TDtable
- les di,ds:[si].fonttable
-
- mov ax,argc ; al := character code
- xor ah,ah
- cmp al,es:[di].FontAsciiStart
- jb nowrtjmp
- cmp al,es:[di].FontAsciiEnd
- jbe okwrtjmp
-
- nowrtjmp: jmp wrtcexit
- okwrtjmp:
-
- mov ax,ds:[si].rmwbits
- mov rmwb,ax
-
- mov ax,ds:[si].vbytesperline
- mov bpline,ax
-
- mov al,ds:[si].transparency
- mov transparent,al
-
- xor ax,ax
- mov al,ds:[si].jagged
- and al,1
- xchg al,ah
- mov jaggy,ax
-
- ; calculate first pixel address
- push es
-
- mov ax,argy ; ax := y
- mov bx,argx ; bx := x
- call activeaddr ; es:bx -> buffer
- ; cl := # bits to shift left to mask
- ; pixel
- inc cx
- and cl,7 ; cl := # bits to shift to mask char
-
- mov ch,0ffh
- shl ch,cl ; ch := bit mask for right side of char
- mov varshift,cx
-
- push es ; transfer es to ds
- pop ds
- mov si,bx ; si := video buffer offset
-
- ; set up character definition table addressing
- pop es
-
- xor ax,ax
- mov al,es:[di].FontHeight ;Multiply fontheight by fontwidth
- mov cx,ax
-
- xor bx,bx
- mov bl,es:[di].fontbytewidth
- mov bpchar,bl
- mul bx
-
- mov dx,argc ; dl := character code
- sub dl,es:[di].FontAsciiStart
- mul dx ; ax := offset into char def table
- ; (points * char code)
-
- add di,255 + size TEGLFontInfo ;skip font table info
- add di,ax ; add character offset
-
-
- xor bx,bx
- mov bl,bpchar ; bytes per character
- mov al,byte ptr [argfgd] ; al := pixel value
-
- cmp rmwb,80h
- jnz oknot5
- not al
- oknot5: mov byte ptr [argfgd],al
-
- ; select output routine depending on whether character is byte-aligned
-
- test byte ptr [varshift],0ffh ; test # bits to shift
- jne I20a ; jump if character is not byte-aligned
-
-
- ; routine for byte-aligned characters
-
- mov dx,jaggy
- xchg cl,dl
- wrtcl10: mov ah,es:[di] ; ah := pattern for next row of pixels
-
- shr ah,cl ; jaggies
-
- mov al,ah
- and al,byte ptr [argfgd]
-
- cmp rmwb,18h ; fgxor
- jz wrt14a
- cmp rmwb,10h ; fgor
- jz wrt14c
- test rmwb,88h ; fgand and fgnot
- jz wrt14b
- and al,ds:[si]
-
- wrt14b: not ah
- and ds:[si],ah ; clear bit pixels
- not ah
- wrt14c: or ds:[si],al
-
- wrt14e: inc di ; es:di -> next byte in char def table
- inc si
- dec bl
- jnz wrtcl10
-
- mov bl,bpchar
- sub si,bx
- add si,nextinterleave ; increment to next line in video buffer
- jns l20a
- add si,firstinterleave ; increment from last to first interleave
- l20a:
- xchg cl,dh
- dec dl
- jnz wrtcl10
- jmp short wrtcexit
-
-
- wrt14a: xor ds:[si],al
- jmp short wrt14e
-
-
- wrt20a: xor ds:[si],dx
- jmp short wrt20e
-
- ; routine for non-byte-aligned characters
-
- I20a: mov ch,cl ; preserve loop counter
- I20: mov cl,byte ptr varshift
- ; ch := mask for left side of character
- ; cl := # bits to shift left
-
- mov al,es:[di] ; al := bits for next row of pixels
- xor ah,ah
- shl ax,cl ; ah := bits for left side of char
- ; al := bits for right side of char
-
- mov cl,byte ptr jaggy ; jaggies
- shr ax,cl
-
- xchg al,ah
- mov dx,ax
- and dl,byte ptr [argfgd]
- and dh,byte ptr [argfgd]
-
- cmp rmwb,18h ; fgxor
- jz wrt20a
- cmp rmwb,10h ; fgor
- jz wrt20c
- test rmwb,88h ; fgand / fgnot
- jz wrt20d
- and dx,ds:[si]
-
- wrt20d: not ax
- and ds:[si],ax ; clear bit pixels
- not ax
- wrt20c: or ds:[si],dx
-
- wrt20e: inc di ; es:di -> next byte in char def table
- inc si
- dec bl
- jnz I20
-
- mov bl,bpchar
- sub si,bx
-
- add si,nextinterleave ; increment to next line in video buffer
- jns l20b
- add si,firstinterleave ; increment from last to first interleave
- l20b:
- mov dx,jaggy
- xchg dh,dl
- mov jaggy,dx
- dec ch
- jnz I20
-
- wrtcexit:
- pop di
- pop es
- pop si
- pop ds
-
- ret
- wrtchar endp
-
-
- activeaddr proc near
-
- mov cl,bl
-
- shr ax,1 ; ax := y/2
- rcr bx,1 ; bx := 8000h*(y&1)+x/2
- shr ax,1 ; ax := y/4
- rcr bx,1 ; bx := 4000h*(y&3)+x/4
- shr bx,1 ; bx := 2000h*(y&3)+x/8
- mov ah,90 ;<---constant bytesperline
- mul ah
- add bx,ax
-
- push ds
- push si
- lds si,cs:TDtable
- mov ax,ds:[si].activepage
- shr ax,1
- shr ax,1
- shr ax,1
- shr ax,1
- add ax,0b000h
- mov es,ax
- pop si
- pop ds
-
- and cl,7
- xor cl,7
- mov ah,1
- ret
-
- activeaddr endp
-
-
- mcursoroff proc far
- push es
- push di
- push ds
- push si
-
- ; replace mouse cursor area
- test cs:mflag,1
- jz nomoff
-
- mov cs:mflag,0
- les di,dword ptr cs:scradrofs
- push cs
- pop ds
- mov si,offset mcursorsavearea
- call mputblock
-
- nomoff: pop si ; restore caller registers and return
- pop ds
- pop di
- pop es
- ret
- mcursoroff endp
-
-
- mcursoron proc far argx:word,argy:word
- local varshift:word,wordmask:word,mscolor:byte
- push es
- push di
- push ds
- push si
-
- ; save mouse cursor area
- lds si,cs:TDtable
- mov ax,ds:[si].mousecolor
- or al,al
- jz okcolor
- mov al,0ffh
- okcolor: mov mscolor,al
-
- mov ax,argy ; ax := y
- sub ax,ds:[si].mousehotspot_yofs
- jnc hotset1
- mov ax,argy
-
- hotset1: mov bx,argx ; bx := x
- sub bx,ds:[si].mousehotspot_xofs
- jnc hotset2
- mov bx,argx
-
- hotset2: call hercvisualaddr ; es:bx -> screen buffer
- inc cx
- and cl,7 ; cl := # bits to shift to mask char
- mov ch,0ffh
- shl ch,cl ; ch := bit mask for right side of char
- mov varshift,cx
-
- mov cs:scradrseg,es
- mov cs:scradrofs,bx
- mov cs:mflag,1 ; mouse cursor on
-
- push es
- push ds
- pop es
- pop ds
-
- mov si,bx
- mov di,offset mcursorsavearea
- call mgetblock
-
-
- ; set up mouse cursor table addressing
-
- les di,cs:TDtable
- les di,es:[di].mousemask
- mov cx,16 ; number of pixel rows in cursor
-
- ; set up graphics controller registers
- ; select output routine depending on whether character is byte-aligned
-
- test byte ptr [varshift],0ffh ; test # bits to shift
- jne mcl20 ; jump if character is not byte-aligned
-
-
- ; routine for byte-aligned characters
- l10: mov ax,es:[di] ; mouse mask
- and byte ptr [si],ah ; ah := bits for left side of char
- and byte ptr [si+1],al ; al := bits for right side of char
-
- mov bl,mscolor
- mov ax,es:[di+32]
- and al,bl ;sets it to black or white
- and ah,bl
- or byte ptr [si],ah
- or byte ptr [si+1],al
-
- inc di
- inc di
-
- add si,nextinterleave
- jns l10a
- add si,firstinterleave
-
- l10a: loop l10
- jmp short lexit
-
-
- ; routine for non-byte-aligned characters
- mcl20: push cx ; preserve loop counter
- mov cx,varshift ; ch := mask for left side of character
- ; cl := # bits to shift left
- ; left side of mask
- mov ax,es:[di]
- push ax
-
- mov al,ah
- mov ah,0ffh
- rol ax,cl ; ah := bits for left side of char
- ; al := bits for right side of char
-
- and byte ptr [si],ah
- and byte ptr [si+1],al
-
- pop ax
- mov ah,0ffh
- rol ax,cl ; ah := bits for left side of char
- ; al := bits for right side of char
- and byte ptr [si+1],ah
- and byte ptr [si+2],al
-
-
- ; colorize
- mov bl,mscolor
- mov ax,es:[di+32]
- and al,bl ;sets it to black or white
- and ah,bl
-
- push ax
- mov al,ah
- xor ah,ah
- shl ax,cl ; ah := bits for left side of char
- ; al := bits for right side of char
- or byte ptr [si],ah
- or byte ptr [si+1],al
-
- pop ax
- xor ah,ah
- shl ax,cl ; ah := bits for left side of char
- ; al := bits for right side of char
- or byte ptr [si+1],ah
- or byte ptr [si+2],al
-
- ; increment to next row of pixels in character
- inc di
- inc di
-
- add si,nextinterleave ; ds:si -> next line in video buffer
- jns mcl20a
- add si,firstinterleave
- mcl20a:
- pop cx
- loop mcl20
-
-
- lexit: pop si ; restore caller registers and return
- pop ds
- pop di
- pop es
- ret
- mcursoron endp
-
-
- msetpos proc far argx:word,argy:word
-
- test cs:mflag,1
- jz nomset
-
- call mcursoroff
-
- mov ax,argx
- push ax
- mov ax,argy
- push ax
- call mcursoron
-
- nomset: ret
- msetpos endp
-
-
- ; assume ds:si=addrbuf es:di=screenadr
- mputblock proc near
- cld
- push si
- push di
-
- mov cx,16
- hcputbl10: push di
- movsw
- movsb
- pop di
-
- add di,nextinterleave
- jns bl10a
- add di,firstinterleave
- bl10a:
- loop hcputbl10
-
- pop di
- pop si
- ret
- mputblock endp
-
-
- ; assume es:di=addrbuf ds:si=screenadr
- mgetblock proc near
- cld
- push si
- push di
-
- mov cx,16
- getbl01: push si
- movsw
- movsb
- pop si
-
- add si,nextinterleave ; ds:si -> next line in video buffer
- jns bl01a
- add si,firstinterleave
- bl01a:
- loop getbl01
-
- pop di
- pop si
- ret
- mgetblock endp
-
-
- hercvisualaddr proc near
-
- mov cl,bl
-
- shr ax,1 ; ax := y/2
- rcr bx,1 ; bx := 8000h*(y&1)+x/2
- shr ax,1 ; ax := y/4
- rcr bx,1 ; bx := 4000h*(y&3)+x/4
- shr bx,1 ; bx := 2000h*(y&3)+x/8
- mov ah,90 ;<----constant bytesperline
- mul ah
- add bx,ax
-
- push ds
- mov ax,40h ;determine page
- mov ds,ax
- mov ax,ds:[4eh]
- shr ax,1
- shr ax,1
- shr ax,1
- shr ax,1
- add ax,0b000h
- mov es,ax
- pop ds
-
- and cl,7
- xor cl,7
- mov ah,1
- ret
-
- hercvisualaddr endp
-
-
- incnextline macro cofs
- local cofsjmp
-
- add cofs,nextinterleave
- jns cofsjmp
- add cofs,firstinterleave
- cofsjmp:
- endm
-
-
- decnextline macro cofs
- local cofsjmp
-
- sub cofs,nextinterleave
- jae cofsjmp
- sub cofs,firstinterleave
- cofsjmp:
- endm
-
-
- movevideopixels proc far argx0:word,argy0:word,argx1:word,argy1:word,argx2:word,argy2:word,vertlines:word,horzlines:word,spage:dword,tpage:dword
- local bpline:word,varpixelrows:word,varpixelrowlen:word
- local varstartmask:byte,varendmaskl:byte,varendmaskr:byte
- local sourcescr:dword,sourceshft:byte,lastbytemask:byte
- local targetscr:dword,targetshft:byte,workbuffer:dword
- local varpixelcontlen:word
-
- push ds
- push es
- push si
- push di
-
- ;-----------------------------------------------
- cld
-
- lds si,cs:TDtable
- mov ax,ds:[si].vbytesperline
- mov bpline,ax
-
- les di,ds:[si].vgraphbuffer
- mov word ptr [workbuffer],di
- mov word ptr [workbuffer+2],es
-
-
- ;-----------------------------------------------
- mov ax,horzlines
- or ax,ax
- jz noadj_89
- mov ax,horzlines
- test ah,80h
- jz notneg1 ;scroll left? ; +-+--------+
- ; | <<<< -1 |
- ; +-+--------+
- mov bx,argx0
- sub bx,ax
- mov argx0,bx
- jmp short noadj_89
-
- notneg1: mov bx,argx2 ;scroll right? ; +--------+-+
- add bx,ax ; | 1 >>>> |
- mov argx2,bx ; +--------+-+
-
- mov bx,argx1
- sub bx,ax
- mov argx1,bx
-
- noadj_89:
-
- mov al,byte ptr [argx0]
- mov ah,byte ptr [argx2]
- and ax,0707h
- cmp ah,al
- jne movevideobits
- jmp movevideobytes
-
- ;-----------------------------------------------
- movevideobits: mov ax,argx1
- sub ax,argx0
- mov cx,0ff07h
- and cl,al
- xor cl,7
- shl ch,cl ;last byte mask in ch
- mov lastbytemask,ch
-
- shr ax,1 ;number of bytes to mov
- shr ax,1
- shr ax,1
- inc ax
- mov varpixelrowlen,ax
-
- mov ax,argy1 ;number of lines
- sub ax,argy0 ;number of lines
- inc ax
-
- ;-----------------------------------------------
- ; extablish addressing
- test vertlines,8000h
- jnz bottomupmove
-
- sub ax,vertlines
- mov varpixelrows,ax
-
- mov ax,argy0 ;source ; +----------+
- add ax,vertlines ; +----/\----+
- mov si,argx0 ; | |
- ; | |
- ; +----------+
- mov cx,si
- and cl,7
- mov sourceshft,cl
-
- shr ax,1 ; ax := y/2
- rcr si,1 ; bx := 8000h*(y&1)+x/2
- shr ax,1 ; ax := y/4
- rcr si,1 ; bx := 4000h*(y&3)+x/4
- shr si,1 ; bx := 2000h*(y&3)+x/8
- mov ah,90 ;<---constant bytesperline
- mul ah
- add si,ax
-
- mov ax,word ptr [spage]
- and ax,000fh
- add si,ax
-
- mov ax,word ptr [spage]
- shr ax,1
- shr ax,1
- shr ax,1
- shr ax,1
- add ax,word ptr [spage+2]
- mov ds,ax
-
- ;-------
-
- mov ax,argy2 ;target
- mov di,argx2
-
- mov cx,di
- xor cl,7
- inc cl
- and cl,7
- mov targetshft,cl
-
- shr ax,1 ; ax := y/2
- rcr di,1 ; bx := 8000h*(y&1)+x/2
- shr ax,1 ; ax := y/4
- rcr di,1 ; bx := 4000h*(y&3)+x/4
- shr di,1 ; bx := 2000h*(y&3)+x/8
- mov ah,90 ;<---constant bytesperline
- mul ah
- add di,ax
-
- mov ax,word ptr [tpage]
- and ax,000fh
- add di,ax
-
- mov ax,word ptr [tpage]
- shr ax,1
- shr ax,1
- shr ax,1
- shr ax,1
- add ax,word ptr [tpage+2]
- mov es,ax
-
- jmp movevideobl_23
-
- bottomupmove: add ax,vertlines
- mov varpixelrows,ax
-
- mov ax,argy0 ;source ; +----------+
- add ax,varpixelrows ; | |
- dec ax ; | |
- mov si,argx0 ; +----\/----+
- ; +----------+
- mov cx,si
- and cl,7
- mov sourceshft,cl
-
- shr ax,1 ; ax := y/2
- rcr si,1 ; bx := 8000h*(y&1)+x/2
- shr ax,1 ; ax := y/4
- rcr si,1 ; bx := 4000h*(y&3)+x/4
- shr si,1 ; bx := 2000h*(y&3)+x/8
- mov ah,90 ;<---constant bytesperline
- mul ah
- add si,ax
-
- mov ax,word ptr [spage]
- and ax,000fh
- add si,ax
-
- mov ax,word ptr [spage]
- shr ax,1
- shr ax,1
- shr ax,1
- shr ax,1
- add ax,word ptr [spage+2]
- mov ds,ax
-
-
- mov ax,argy1
- sub ax,argy0
- add ax,argy2
- mov di,argx2 ;target
-
- mov cx,di
- xor cl,7
- inc cl
- and cl,7
- mov targetshft,cl
-
- shr ax,1 ; ax := y/2
- rcr di,1 ; bx := 8000h*(y&1)+x/2
- shr ax,1 ; ax := y/4
- rcr di,1 ; bx := 4000h*(y&3)+x/4
- shr di,1 ; bx := 2000h*(y&3)+x/8
- mov ah,90 ;<---constant bytesperline
- mul ah
- add di,ax
-
- mov ax,word ptr [tpage]
- and ax,000fh
- add di,ax
-
- mov ax,word ptr [tpage]
- shr ax,1
- shr ax,1
- shr ax,1
- shr ax,1
- add ax,word ptr [tpage+2]
- mov es,ax
-
- xor ax,ax
- sub ax,bpline ; negate bpline
- mov bpline,ax
-
- ;-----------------------------------------------
- movevideobl_23:
- mov word ptr [sourcescr],si
- mov word ptr [sourcescr+2],ds
- mov word ptr [targetscr],di
- mov word ptr [targetscr+2],es
-
- mov cl,targetshft
- mov ch,lastbytemask
- mov bx,0ffh ; bx = 00000000 11111111
- mov al,ch ; al = 11110000
- cbw ; ax = 11111111 11110000
-
- cmp varpixelrowlen,1 ;if only 1 byte to move then
- jne movevideobl_16
-
- ; create start and end mask based
- ; on one byte
- mov bl,ch ; bx = 00000000 11110000
- mov ah,ch ;
- xor al,al ; ax = 11110000 00000000
-
- movevideobl_16: shl ax,cl
- shl bx,cl
-
- mov varendmaskl,ah ; ah=endmask left
- mov varendmaskr,al ; al=endmask right
- mov varstartmask,bh ; bh=startmask
-
-
- ;-----------------------------------------------
- ;----move from screen to buffer
- movevideobl_01: lds si,sourcescr
- les di,workbuffer
-
- mov bx,varpixelrowlen
- mov cl,sourceshft
-
- or cl,cl ; bit shifts?
- jz mvetobuf_06
-
- ; routine for non-aligned bit blocks
- mvetobuf_04: lodsw
- dec si
- rol ax,cl
- stosb
- dec bx
- jnz mvetobuf_04
- jmp short mvetoscr_09
-
- ; routine for byte-aligned bit blocks
- mvetobuf_06: mov cx,bx
-
- shr cx,1
- rep movsw
- adc cx,0
- rep movsb
-
- ;----move from buffer to screen
- mvetoscr_09: lds si,workbuffer
- les di,targetscr
-
- mov bx,varpixelrowlen
- mov ch,lastbytemask
- mov cl,targetshft
-
- cmp cx,0ff00h ; start and end must be byte aligned
- jne mvetoscr_17
-
- ; routine for byte-aligned bit blocks
- mov cx,bx
-
- shr cx,1
- rep movsw
- adc cx,0
- rep movsb
-
- ; routine for non-aligned bit blocks
- mvetoscr_17:
- lodsw ; eg. 10101110 11111111
- dec si ; <junk> 8 bits
- or cl,cl ; shift?
- jnz mvetoscr_shf ; go shift
-
- dec bx ; no shift, just dec bx
- jnz mvetoscr_mid ; more bytes
- jmp short mvetoscr_end ; do end bytes
-
- mvetoscr_shf: rol ax,cl ; eg. 01110111 11111101
- mov dl,varstartmask
- and ah,dl
- not dl
- and es:[di],dl ; and screen 11111000
- or es:[di],ah ; or screen 00000111
- inc di
- dec bx ; bx = 0
-
- mvetoscr_mid: dec bx ; bx < 0
- jng mvetoscr_end
-
- mvetoscr_loop: mov es:[di],al
- inc di
- lodsw
- dec si
- rol ax,cl
- dec bx
- jnz mvetoscr_loop
-
- ; set pixels at end of row
- mvetoscr_end: mov dl,varendmaskl
- and al,dl
- not dl
- and es:[di],dl
- or es:[di],al
- inc di
-
- mov dl,varendmaskr ; eg. 00000000
- and ah,dl
- not dl
- and es:[di],dl
- or es:[di],ah
- ;-----------------------------------------------------move buffer to screen
-
- mvetoscr_20: test byte ptr [bpline+1],80h
- jnz mvetoscr_20a
-
- incnextline <word ptr [targetscr]>
- incnextline <word ptr [sourcescr]>
-
- dec varpixelrows
- jz movevideobl_02
- jmp movevideobl_01
- movevideobl_02: jmp vertmove_12
-
-
- mvetoscr_20a: decnextline <word ptr [targetscr]>
- decnextline <word ptr [sourcescr]>
-
- dec varpixelrows
- jz movevideobl_02
- jmp movevideobl_01
-
-
- ; movevideobytes allows for direct latch block moves of pixel lines, rather
- ; than having to (move and shift) a block of pixels to memory and back.
-
- movevideobytes: mov ax,argx1
- mov cx,0ff07h
- and cl,al
- xor cl,7
- shl ch,cl ;mask for last byte
- mov varendmaskl,ch
- push cx
-
- mov bx,argx0
- mov cx,0ff07h
- and cl,bl
- shr ch,cl ;mask for start byte
- mov varstartmask,ch
-
- pop cx
- shr bx,1 ;number of bytes to mov
- shr bx,1
- shr bx,1
- shr ax,1
- shr ax,1
- shr ax,1
- sub ax,bx
- shl ch,1
- adc ax,0 ;1 byte - start and end bytes same
- ;2 bytes - start and end bytes
- ;>2 bytes - start, mid, end bytes
- mov varpixelrowlen,ax
-
- cmp ax,1 ;if 1 byte then
- jne vertmove_01
- mov al,varstartmask
- and al,varendmaskl ;combine both mask together
- mov varstartmask,al
- mov varendmaskl,0
-
- vertmove_01: mov ah,varstartmask
- xor ah,0ffh
- jnz vertmove_07
- mov varstartmask,ah
- vertmove_07: mov ah,varendmaskl
- xor ah,0ffh
- jnz vertmove_08
- mov varendmaskl,ah
- vertmove_08:
- mov ax,argy1 ;number of lines
- sub ax,argy0
- inc ax
-
- ;-----------------------------------------------
- ; extablish addressing
- test vertlines,8000h
- jnz vertmove_00
-
- sub ax,vertlines ;subtract number of lines to scroll
- mov varpixelrows,ax
-
- mov ax,argy0 ;source ; +----------+
- add ax,vertlines ; +----/\----+
- mov si,argx0 ; | |
- ; | |
- ; +----------+
-
- shr ax,1 ; ax := y/2
- rcr si,1 ; bx := 8000h*(y&1)+x/2
- shr ax,1 ; ax := y/4
- rcr si,1 ; bx := 4000h*(y&3)+x/4
- shr si,1 ; bx := 2000h*(y&3)+x/8
- mov ah,90 ;<---constant bytesperline
- mul ah
- add si,ax
-
- mov ax,word ptr [spage]
- and ax,000fh
- add si,ax
-
- mov ax,word ptr [spage]
- shr ax,1
- shr ax,1
- shr ax,1
- shr ax,1
- add ax,word ptr [spage+2]
- mov ds,ax
-
-
- mov ax,argy2 ;target
- mov di,argx2
-
- shr ax,1 ; ax := y/2
- rcr di,1 ; bx := 8000h*(y&1)+x/2
- shr ax,1 ; ax := y/4
- rcr di,1 ; bx := 4000h*(y&3)+x/4
- shr di,1 ; bx := 2000h*(y&3)+x/8
- mov ah,90 ;<---constant bytesperline
- mul ah
- add di,ax
-
- mov ax,word ptr [tpage]
- and ax,000fh
- add di,ax
-
- mov ax,word ptr [tpage]
- shr ax,1
- shr ax,1
- shr ax,1
- shr ax,1
- add ax,word ptr [tpage+2]
- mov es,ax
-
- mov bx,bpline
- sub bx,varpixelrowlen
- mov varpixelcontlen,bx
-
- jmp short vertmove_31
-
-
- vertmove_00: add ax,vertlines ;subtract number of lines to scroll
- mov varpixelrows,ax
-
- mov ax,argy0 ;source ; +----------+
- add ax,varpixelrows ; | |
- dec ax ; | |
- mov si,argx0 ; +----\/----+
- ; +----------+
-
- shr ax,1 ; ax := y/2
- rcr si,1 ; bx := 8000h*(y&1)+x/2
- shr ax,1 ; ax := y/4
- rcr si,1 ; bx := 4000h*(y&3)+x/4
- shr si,1 ; bx := 2000h*(y&3)+x/8
- mov ah,90 ;<---constant bytesperline
- mul ah
- add si,ax
-
- mov ax,word ptr [spage]
- and ax,000fh
- add si,ax
-
- mov ax,word ptr [spage]
- shr ax,1
- shr ax,1
- shr ax,1
- shr ax,1
- add ax,word ptr [spage+2]
- mov ds,ax
-
-
- mov ax,argy1
- sub ax,argy0
- add ax,argy2
- mov di,argx2 ;target
-
- shr ax,1 ; ax := y/2
- rcr di,1 ; bx := 8000h*(y&1)+x/2
- shr ax,1 ; ax := y/4
- rcr di,1 ; bx := 4000h*(y&3)+x/4
- shr di,1 ; bx := 2000h*(y&3)+x/8
- mov ah,90 ;<---constant bytesperline
- mul ah
- add di,ax
-
- mov ax,word ptr [tpage]
- and ax,000fh
- add di,ax
-
- mov ax,word ptr [tpage]
- shr ax,1
- shr ax,1
- shr ax,1
- shr ax,1
- add ax,word ptr [tpage+2]
- mov es,ax
-
- mov ax,bpline
- not ax
- inc ax
- sub ax,varpixelrowlen
- mov varpixelcontlen,ax
-
- ;-----------------------------------------------
- vertmove_31:
- mov word ptr [sourcescr],si
- mov word ptr [sourcescr+2],ds
- mov word ptr [targetscr],di
- mov word ptr [targetscr+2],es
-
- ; check if we need to move backwards
-
- mov ax,argy0
- cmp ax,argy2 ;compare vertical y's
- jne vertmove_02 ;jump if not same line
-
- mov ax,word ptr [spage] ;compare base video segs
- cmp ax,word ptr [tpage]
- jne vertmove_02 ;jump if different pages
-
- mov ax,word ptr [spage+2] ;compare base video segs
- cmp ax,word ptr [tpage+2]
- jne vertmove_02 ;jump if different pages
-
- mov ax,argx0 ;compare end and start segments
- cmp ax,argx2
- jge vertmove_02 ;jump if tail < begining
-
- std
- mov ax,varpixelrowlen
- dec ax
- add si,ax
- add di,ax
- inc ax
-
- add ax,bpline
- mov varpixelcontlen,ax
- jmp vertmove_20
-
- vertmove_02: mov cx,varpixelrowlen
- lds si,sourcescr
- les di,targetscr
-
- mov ah,varstartmask ; ah := 0ffh (value for bit mask reg)
- or ah,ah
- jz vertmove_09
-
- vertmove_03:
- mov dh,varstartmask
- mov dl,ds:[si] ; get start byte
- and dl,dh
- not dh
- and es:[di],dh ; latch destination bytes
- or es:[di],dl ; mask new info
-
- shr bh,1
- dec ah
- jns vertmove_03
-
- dec cx ; 1 byte - start and end bytes same
- jcxz vertmove_06 ; 2 bytes - start and end bytes
- ;>2 bytes - start, mid, end bytes
- inc si
- inc di
-
- vertmove_09: test varendmaskl,0ffh
- jz vertmove_10
- dec cx
- vertmove_10: jcxz vertmove_04 ;do end part of scroll
-
- ; middle part of direct memory scroll
- shr cx,1
- rep movsw
- adc cx,0
- rep movsb
-
- ; end part of direct memory scroll
- vertmove_04: mov dh,varendmaskl ; ah := 0ffh (value for bit mask reg)
- or dh,dh
- jz vertmove_06
-
- mov dl,ds:[si] ; get end byte
- and dl,dh
- not dh
- and es:[di],dh ; mask new info
- or es:[di],dl
-
- vertmove_06:
- test byte ptr [varpixelcontlen+1],80h
- jnz vertmove_12_S
-
- incnextline <word ptr [targetscr]>
- incnextline <word ptr [sourcescr]>
-
- dec varpixelrows
- jz vertmove_12_F
- jmp vertmove_02
- vertmove_12_F: jmp vertmove_12
-
-
- vertmove_12_S:
- decnextline <word ptr [targetscr]>
- decnextline <word ptr [sourcescr]>
-
- dec varpixelrows
- jz vertmove_12_F
- jmp vertmove_02
-
- ;-----------------------------------------------
- vertmove_20: mov cx,varpixelrowlen
- lds si,sourcescr
- les di,targetscr
-
- mov al,varendmaskl ; ah := 0ffh (value for bit mask reg)
- or al,al
- jz vertmove_21
-
- vertmove_22: mov dl,ds:[si] ; get start byte
- and dl,al
- not al
- and es:[di],al
- or es:[di],dl ; mask new info
-
- dec cx ; 1 byte - start and end bytes same
- jcxz vertmove_23 ; 2 bytes - start and end bytes
- ;>2 bytes - start, mid, end bytes
-
- dec si
- dec di
-
- vertmove_21: test varstartmask,0ffh
- jz vertmove_24
- dec cx
- vertmove_24: jcxz vertmove_25 ;do begining part of scroll
-
- ; middle part of direct memory scroll
-
- shr cx,1
- rep movsw
- adc cx,0
- rep movsb
-
- ; end part of direct memory scroll
- vertmove_25:
- mov al,varstartmask ; ah := 0ffh (value for bit mask reg)
- test al,0ffh
- jz vertmove_23
-
- vertmove_26:
- mov dl,ds:[si] ; get start byte
- and dl,al
- not al
- and es:[di],al
- or es:[di],dl ; mask new info
-
-
- vertmove_23:
- decnextline <word ptr [targetscr]>
- decnextline <word ptr [sourcescr]>
-
- dec varpixelrows
- jnz vertmove_20
-
-
- vertmove_12:
- cld
- pop di
- pop si
- pop es
- pop ds
- ret
-
- movevideopixels endp
-
- setvpage proc far pagen:word
- push ds
- push si
- push es
- push di
-
- lds si,cs:TDtable
- mov ax,pagen
- cmp ax,ds:[si].vmaxpages
-
- mov bx,40h
- mov ds,bx
- mov si,62h
- mov ds:[si],al
- mov si,4eh
-
- mov dx,03B8h
- xor bx,bx
- or al,al
- mov al,0ah
- jz vpageit
-
- mov bx,8000h
- mov al,8ah
- vpageit: out dx,al
- mov ds:[si],bx
-
- novpage: pop di
- pop es
- pop si
- pop ds
- ret
- setvpage endp
-
- setapage proc far pagen:word
- push ds
- push si
- push es
- push di
-
- lds si,cs:TDtable
- mov ax,pagen
- cmp ax,ds:[si].vmaxpages
- jg noapage
-
- or al,al ; if 0 then mov 0 to activepage
- mov ds:[si].activepage,0
- jz noapage
- mov ds:[si].activepage,8000h
-
- noapage: pop di
- pop es
- pop si
- pop ds
- ret
- setapage endp
-
- end