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,'GREVGA16',0 ; driver module name
-
- ; EGA 640x350
- mode0: db 13,'EGA640x350x16',0,0,0,0,0,0,0,0
- dw 0 ; Mode Number
- dw 639 ; Device Full Resolution in X
- dw 349 ; Device Full Resolution in Y
- dw 8 ; Standard char size X
- dw 8 ; Standard char size Y
- dw 15 ; Number of colors
- dw 2 ; Number of pages
- dw 16 ; max palette
- dw 0 ; buffer offset for 2 page, Active page
- dw 0A000h ; Screen Segment
- dw 80 ; bytes per line
- dw 7750 ; 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 1 ; 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 639 ; viewport - maxx
- dw 349 ; viewport - maxy
- db 0 ; 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,'VGA640x480x16',0,0,0,0,0,0,0,0
- dw 1 ; Mode Number
- dw 639 ; Device Full Resolution in X
- dw 479 ; Device Full Resolution in Y
- dw 8 ; Standard char size X
- dw 8 ; Standard char size Y
- dw 15 ; Number of colors
- dw 1 ; Number of pages
- dw 16 ; max palette
- dw 0 ; buffer offset for 2 page, Active page
- dw 0A000h ; Screen Segment
- dw 80 ; bytes per line
- dw 10000 ; 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 1 ; 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 639 ; viewport - maxx
- dw 479 ; viewport - maxy
- db 0 ; 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
-
- mode2: db 14,'SVGA800x600x16',0,0,0,0,0,0,0
- dw 2 ; Mode Number
- dw 799 ; Device Full Resolution in X
- dw 599 ; Device Full Resolution in Y
- dw 8 ; Standard char size X
- dw 14 ; Standard char size Y
- dw 15 ; Number of colors
- dw 1 ; Number of pages
- dw 16 ; max palette
- dw 0 ; buffer offset for 2 page, Active page
- dw 0A000h ; Screen Segment
- dw 100 ; bytes per line
- dw 10000 ; 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 1 ; 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 799 ; viewport - maxx
- dw 599 ; viewport - maxy
- db 0 ; 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
-
- mode3: db 15,'TWVGA800x600x16',0,0,0,0,0,0
- dw 3 ; Mode Number
- dw 799 ; Device Full Resolution in X
- dw 599 ; Device Full Resolution in Y
- dw 8 ; Standard char size X
- dw 14 ; Standard char size Y
- dw 15 ; Number of colors
- dw 1 ; Number of pages
- dw 16 ; max palette
- dw 0 ; buffer offset for 2 page, Active page
- dw 0A000h ; Screen Segment
- dw 100 ; bytes per line
- dw 10000 ; 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 1 ; 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 799 ; viewport - maxx
- dw 599 ; viewport - maxy
- db 0 ; 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
-
- mode4: db 15,'TWVGA800x564x16',0,0,0,0,0,0
- dw 4 ; Mode Number
- dw 799 ; Device Full Resolution in X
- dw 563 ; Device Full Resolution in Y
- dw 8 ; Standard char size X
- dw 14 ; Standard char size Y
- dw 15 ; Number of colors
- dw 1 ; Number of pages
- dw 16 ; max palette
- dw 0 ; buffer offset for 2 page, Active page
- dw 0A000h ; Screen Segment
- dw 100 ; bytes per line
- dw 10000 ; 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 1 ; 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 799 ; viewport - maxx
- dw 563 ; viewport - maxy
- db 0 ; 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
-
- mode5: db 15,'TWVGA752x564x16',0,0,0,0,0,0
- dw 5 ; Mode Number
- dw 751 ; Device Full Resolution in X
- dw 563 ; Device Full Resolution in Y
- dw 8 ; Standard char size X
- dw 14 ; Standard char size Y
- dw 15 ; Number of colors
- dw 1 ; Number of pages
- dw 16 ; max palette
- dw 0 ; buffer offset for 2 page, Active page
- dw 0A000h ; Screen Segment
- dw 94 ; bytes per line
- dw 10000 ; 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 1 ; 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 751 ; viewport - maxx
- dw 563 ; viewport - maxy
- db 0 ; 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 * 4 color planes + 5 byte header
- mcursorsavearea db 280 dup (0)
- mflag dw 0
- scradrofs dw 0
- scradrseg dw 0
- TDTable dd 0
- XLTable dd 0
-
- vesashift db 0
- vga512flag dw ?
- vga1024flag dw ?
- svgatype dw 0
- bankadr dw ?
-
- x_cirrus equ 1
- x_everex equ 2
- x_paradise equ 3
- x_tseng equ 4
- x_trident equ 5
- x_t8900 equ 6
- x_ativga equ 7
- x_aheada equ 8
- x_aheadb equ 9
- x_oaktech equ 10
- x_video7 equ 11
- x_chipstech equ 12
- x_tseng4 equ 13
- x_genoa equ 14
- x_ncr equ 15
- x_compaq equ 16
- x_vesa equ 17
-
- initvideomode proc far
-
- push ds
- push si
- lds si,cs:TDTable
- mov bx,ds:[si].vmodenum
- pop si
- pop ds
-
- mov ax,ds
- or ax,ax
- mov ax,-10
- jz initvideodone
-
- or bx,bx
- jnz nxtevgamode1
- call SetEGA640x350
- jmp short initvideodone
-
- nxtevgamode1: cmp bx,1
- jne nxtevgamode2
- call SetVGA640x480
- jmp short initvideodone
-
- nxtevgamode2: cmp bx,2
- jne nxtevgamode3
- call SetSVGA800x600
- jmp short initvideodone
-
- nxtevgamode3: cmp bx,3
- jne nxtevgamode4
- call TWVGA800x600
- jmp short initvideodone
-
- nxtevgamode4: cmp bx,4
- jne nxtevgamode5
- call TWVGA800x564
- jmp short initvideodone
-
- nxtevgamode5: cmp bx,5
- jne initvideodone
- call TWVGA752x564
-
- initvideodone: ret
- initvideomode endp
-
-
- SetEGA640x350 proc near
- mov ax,010h
- int 10h
- xor ax,ax
- ret
- SetEGA640x350 endp
-
- SetVGA640x480 proc near
- mov ax,012h
- int 10h
- xor ax,ax
- ret
- SetVGA640x480 endp
-
- SetSVGA800x600 proc near
- mov ax,cs:svgatype
- cmp ax,0
- jnz gottype
-
- call whichsvga
- mov ax,cs:svgatype
- cmp ax,0
-
- gottype: jb nosvga800
- mov cx,ax
-
- cmp cx,x_genoa
- mov ax,79h
- je set800
-
- cmp cx,x_paradise
- mov ax,58h
- je set800
- cmp cx,x_compaq
- je set800
-
- cmp cx,x_ativga
- mov ax,54h
- je set800
-
- cmp cx,x_everex
- mov ax,70h
- mov bl,02h
- je set800
-
- cmp cx,x_trident
- mov ax,5bh
- je set800
- cmp cx,x_t8900
- je set800
-
- cmp cx,x_video7
- mov ax,6f05h
- mov bl,62h
- je set800
-
- cmp cx,x_chipstech
- mov ax,70h
- je set800
-
- cmp cx,x_tseng4
- mov ax,29h
- je set800
- cmp cx,x_tseng
- je set800
-
- cmp cx,x_aheada
- mov ax,6ah
- je set800
- cmp cx,x_aheadb
- je set800
-
- cmp cx,x_oaktech
- mov ax,52h
- je set800
-
- cmp cx,x_ncr
- mov ax,58h
- je set800
-
- ; cmp cx,x_cirrus ;cirrus doesn't have a 800x600(16)
- mov ax,-2
- jmp short nosvga800
-
- set800: int 10h
- xor ax,ax
- nosvga800: ret
- SetSVGA800x600 endp
-
-
- crtcparm800x600 db 074h ; horisontal total time (0)
- db 063h ; horisontal display end (1)
- db 064h ; start horisontal blank (2)
- db 097h ; end horisontal blank (3)
- db 068h ; start horisontal retrace (4)
- db 095h ; end horisontal retrace (5)
- db 086h ; vertical total (6)
- db 0F0h ; overflow register (7)
- db 000h, 060h, 000h, 000h ; misc
- db 000h, 000h, 002h, 085h
- db 05Bh ; vertical retrace start (10)
- db 08Dh ; vertical retrace end
- db 057h ; vertical display end
- db 032h ; offset register
- db 000h
- db 060h ; start vertical blank
- db 080h ; end vertical blank
- db 0E3h ; mode control
- db 0FFh
-
- crtcparm800x564 db 074h ; horisontal total time (0)
- db 063h ; horisontal display end (1)
- db 064h ; start horisontal blank (2)
- db 097h ; end horisontal blank (3)
- db 068h ; start horisontal retrace (4)
- db 095h ; end horisontal retrace (5)
- db 062h ; vertical total (6)
- db 0F0h ; overflow register (7)
- db 000h, 060h, 000h, 000h ; misc
- db 000h, 000h, 002h, 061h
- db 037h ; vertical retrace start (10)
- db 089h ; vertical retrace end
- db 033h ; vertical display end
- db 032h ; offset register
- db 000h
- db 03Ch ; start vertical blank
- db 05Ch ; end vertical blank
- db 0E3h ; mode control
- db 0FFh
-
-
- crtcparm752x564 db 06Eh ; horisontal total time (0)
- db 05Dh ; horisontal display end (1)
- db 05Eh ; start horisontal blank (2)
- db 091h ; end horisontal blank (3)
- db 062h ; start horisontal retrace (4)
- db 08Fh ; end horisontal retrace (5)
- db 062h ; vertical total (6)
- db 0F0h ; overflow register (7)
- db 000h, 060h, 000h, 000h ; misc
- db 000h, 000h, 002h, 061h
- db 037h ; vertical retrace start (10)
- db 089h ; vertical retrace end
- db 033h ; vertical display end
- db 02Fh ; offset register
- db 000h
- db 03Ch ; start vertical blank
- db 05Ch ; end vertical blank
- db 0E3h ; mode control
- db 0FFh
-
- TWVGA800x600 proc near
- push ds
- push si
- push es
- push di
-
- lds si,cs:TDTable
- add si,crtcparm800x600-Mode3
- mov dx,600
- mov ax,800
- call setvgaparms
- xor ax,ax
-
- pop di
- pop es
- pop si
- pop ds
- ret
- TWVGA800x600 endp
-
-
- TWVGA800x564 proc near
- push ds
- push si
- push es
- push di
-
- lds si,cs:TDTable
- add si,crtcparm800x564-Mode4
- mov dx,564
- mov ax,800
- call setvgaparms
- xor ax,ax
-
- pop di
- pop es
- pop si
- pop ds
- ret
- TWVGA800x564 endp
-
-
- TWVGA752x564 proc near
- push ds
- push si
- push es
- push di
-
- lds si,cs:TDTable
- add si,crtcparm752x564-Mode5
- mov dx,564
- mov ax,752
- call setvgaparms
- xor ax,ax
-
- pop di
- pop es
- pop si
- pop ds
- ret
- TWVGA752x564 endp
-
-
- SetVGAParms proc near
- push ax ;cols
- push dx ;rows
-
- mov ax,12h ; set video mode to 12
- int 10h
-
- mov ax,40h ; Video BIOS DATA area
- mov es,ax
-
- pop dx
- pop ax
-
- mov cl,3
- shr ax,cl ; div 8
- shr dx,cl ; div 8
-
- ; push ax
- ; push dx
- ; mov ax,1124h ; load ROM 8*16 characters
- ; mov bx,0
- ; mov dh,0
- ; shr dl,1
- ; int 10h
- ; pop dx
- ; pop ax
-
- mov word ptr es:[4ah],ax ;columns
- mul dl
- mov word ptr es:[4ch],ax ;screen size
-
- mov dx,word ptr es:[63h]
- add dx,6
- vrdly1: in al,dx ; wait for vertical retrace off
- test al,8
- jnz vrdly1
-
- vrdly2: in al,dx ; wait for vertical retrace on
- test al,8
- jz vrdly2
-
- cli ; turn off all interrupts
- mov dx,03c4h ; Sequencer Synchronous reset
- mov ax,0100h ; set sequencer reset
- out dx,ax
-
- mov dx,03c2h ; Update Misc Output Reg
- mov al,0E7h
- out dx,al
-
- mov dx,03c4h ; Sequencer Synchronous reset
- mov ax,0300h ; clear sequencer reset
- out dx,ax
-
- mov dx,word ptr es:[63h] ; 6845
- mov al,11h ; deprotect registers 0-7
- mov ah,byte ptr ds:[si+11h]
- and ah,7fh
- out dx,ax
-
- mov cx,18h
- mov bx,0
- crtcloop: mov al,bl
- mov ah,byte ptr ds:[bx+si]
- out dx,ax
- inc bx
- loop crtcloop
- sti
- ret
- SetVGAParms 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 ; /8
- shr ax,cl
-
- 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 * bytes per row
-
- shl ax,1 ;multiply by 4
- rcl dx,1
- shl ax,1
- rcl dx,1
-
- 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 varvertincr:word,varincr1:word,varincr2:word,varroutine:word
- local rmwb:word,fillmask:byte,bpline:word,transparent:byte
-
- push ds
- push si
- push es
- push di
-
- cld
-
- lds si,cs:TDtable
- mov ax,ds:[si].rmwbits
- mov rmwb,ax
-
- mov ax,ds:[si].vbytesperline
- mov bpline,ax
-
- mov ax,ds:[si].teglfillmask
- mov fillmask,al
-
- mov al,ds:[si].transparency
- mov transparent,al
-
- ; configure the graphics controller
-
- mov dx,3ceh ; dx := graphics controller port addr
-
- mov ah,byte ptr [color] ; ah := pixel value
- xor al,al ; al := set/reset register number
- out dx,ax
-
- mov ax,0f01h ; ah := 1111b (bit plane mask for
- ; enable set/reset
- out dx,ax ; al := enable set/reset register #
-
- mov ah,byte ptr [rmwb] ; bits 3 and 4 of ah := function
- mov al,3 ; al := data rotate/func select reg #
- out dx,ax
-
- ; check for vertical line
-
- mov si,bpline ; increment for video buffer
-
- mov cx,argx2
- sub cx,argx1 ; cx := x2 - x1
- jnz nvertline10 ; jump if not vertical line
-
-
- ; routine for vertical lines
- mov ax,argy1 ; ax := y1
- mov bx,argy2 ; bx := y2
- mov cx,bx
- sub cx,ax ; cx := dy
- jge l31 ; jump if dy >= 0
-
- neg cx ; force dy >= 0
- mov ax,bx ; ax := y2
-
- l31: 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
- ; set up graphics controller
-
- shl ah,cl ; ah := bit mask in proper position
- rol fillmask,cl ; ***********fillmask
- ; rol fillmask,1 ; ***********fillmask
-
- mov al,8 ; al := bit mask reg number
- out dx,ax
-
- pop cx ; restore this register
-
- ; draw the line
-
- l32: test ah,fillmask
- jz l32a
- or es:[bx],al ; set pixel
- l32a: add bx,si ; increment to next line
- ; rol fillmask,1
- ror fillmask,1
- loop l32
-
- jmp lexit
-
-
- ; force x1 < x2
-
- nvertline10: jns l01 ; 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)
-
- l01: mov bx,argy2
- sub bx,argy1 ; bx := y2 - y1
- jz horizline10 ; jump if horizontal line
-
- jns l03 ; jump if slope is positive
-
- neg bx ; bx := y1 - y2
- neg si ; negate increment for buffer interleave
-
- ; select appropriate routine for slope of line
-
- l03: mov varvertincr,si ; save vertical increment
-
- mov varroutine,0
- cmp bx,cx
- jle l04 ; jump if dy <= dx (slope <= 1)
- mov varroutine,1
- xchg bx,cx ; exchange dy and dx
-
- ; calculate initial decision variable and increments
-
- l04: shl bx,1 ; bx := 2 * dy
- mov varincr1,bx ; incr1 := 2 * dy
- sub bx,cx
- mov si,bx ; si := 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
- ; ror fillmask,1 ; ***********fillmask
-
- mov di,bx ; es:di -> buffer
- shl ah,cl ; ah := bit mask in proper position
- mov bl,ah ; ah,bl := bit mask
- mov al,8 ; al := bit mask register number
-
- pop cx ; restore this register
- inc cx ; cx := # of pixels to draw
-
- test varroutine,1 ; jump to appropriate routine for slope
- jnz jmphislopeline
- jmp loslopeline10
- jmphislopeline: jmp hislopeline10
-
-
-
-
- ; routine for horizontal lines (slope = 0)
-
- horizline10:
- push ds ; preserve ds
-
- 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 ; dh := unshifted bit mask for leftmost
- ; byte
- not dh
- 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
- mov dl,0ffh ; dl := unshifted bit mask for
- ; rightmost byte
- 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
-
- ; get graphics controller port address into dx
-
- mov bx,dx ; bh := bit mask for first byte
- ; bl := bit mask for last byte
- mov dx,3ceh ; dx := graphics controller port
- mov al,8 ; al := bit mask register number
-
- ; make video buffer addressible through ds:si
-
- push es
- pop ds
- mov si,di ; ds:si -> video buffer
-
- push di
- push cx
-
- ; set pixels in leftmost byte of the line
-
- or bh,bh
- js l43 ; jump if byte-aligned (x1 is leftmost
- ; pixel in byte)
- or cx,cx
- jnz l42 ; jump if more than one byte in the line
-
- and bl,bh ; bl := bit mask for the line
- jmp short l44
-
- l42: mov ah,bh ; ah := bit mask for 1st byte
- and ah,fillmask
- out dx,ax ; update graphics controller
-
- movsb ; update bit planes
- dec cx
-
- ; use a fast 8086 machine instruction to draw the remainder of the line
-
- l43: mov ah,11111111b ; ah := bit mask
- and ah,fillmask
- out dx,ax ; update bit mask register
-
- rep movsb ; update all pixels in the line
-
- ; set pixels in the rightmost byte of the line
-
- l44: mov ah,bl ; ah := bit mask for last byte
- and ah,fillmask
- out dx,ax ; update graphics controller
-
- movsb ; update bit planes
-
-
- ;---------
- ; es:di/ds:si - pointer to same video buffer address
- ; bx - bh/bl - bit mask for first/last byte
- ; dx - 3ceh graphics controller port
- ; cx - number of bytes to write
- ; al - contains 8 - bit mask register number
- ;---------
- pop cx
- pop di
-
- test transparent,0ffh
- jz oksolid
- cmp fillmask,0ffh
- jz oksolid
-
- mov si,di
- xor ax,ax ; ah := black
- out dx,ax ; al := set/reset register number
- not fillmask
- mov al,8
-
- ; set pixels in leftmost byte of the line
- or bh,bh
- js l43f ; jump if byte-aligned (x1 is leftmost
- ; pixel in byte)
- or cx,cx
- jnz l42f ; jump if more than one byte in the line
-
- and bl,bh ; bl := bit mask for the line
- jmp short l44f
-
- l42f: mov ah,bh ; ah := bit mask for 1st byte
- and ah,fillmask
- out dx,ax ; update graphics controller
-
- movsb ; update bit planes
- dec cx
-
- ; use a fast 8086 machine instruction to draw the remainder of the line
-
- l43f: mov ah,11111111b ; ah := bit mask
- and ah,fillmask
- out dx,ax ; update bit mask register
-
- rep movsb ; update all pixels in the line
-
- ; set pixels in the rightmost byte of the line
-
- l44f: mov ah,bl ; ah := bit mask for last byte
- and ah,fillmask
- out dx,ax ; update graphics controller
-
- movsb ; update bit planes
-
-
- oksolid: pop ds ; restore ds
- jmp lexit
-
-
- ;---------
- ; routine for dy <= dx (slope <= 1) ; es:di -> video buffer
- ; al = bit mask register number
- ; bl = bit mask for 1st pixel
- ; cx = #pixels to draw
- ; dx = graphics controller port addr
- ; si = decision variable
- loslopeline10:
-
- l10: mov ah,bl ; ah := bit mask for next pixel
-
- l11: or ah,bl ; mask current pixel position
- ror bl,1 ; rotate pixel value
- jc l14 ; jump if bit mask rotated to
- ; leftmost pixel position
-
- ; bit mask not shifted out
-
- or si,si ; test sign of d
- jns l12 ; jump if d >= 0
-
- add si,varincr1 ; d := d + incr1
- loop l11
-
- and ah,fillmask ; ***********fillmask
- out dx,ax ; update bit mask register
- or es:[di],al ; set remaining pixel(s)
- jmp short lexit
-
- l12: add si,varincr2 ; d := d + incr2
- mov bh,ah
- and ah,fillmask ; ***********fillmask
- out dx,ax ; update bit mask register
-
- or es:[di],al ; update bit planes
- mov ah,bh
-
- add di,varvertincr ; increment y
- loop l10
- jmp short lexit
-
- ; bit mask shifted out
-
- l14: mov bh,ah ; ***********fillmask
- and ah,fillmask ; ***********fillmask
- out dx,ax ; update bit mask register ...
- mov ah,bh
-
- or es:[di],al ; update bit planes
- inc di ; increment x
-
- or si,si ; test sign of d
- jns l15 ; jump if non-negative
-
- add si,varincr1 ; d := d + incr1
- loop l10
- jmp short lexit
-
- l15: add si,varincr2 ; d := d + incr2
- add di,varvertincr ; vertical increment
- loop l10
- jmp short lexit
-
-
- ; routine for dy > dx (slope > 1) ; es:di -> video buffer
- ; ah = bit mask for 1st pixel
- ; al = bit mask register number
- ; cx = #pixels to draw
- ; dx = graphics controller port addr
- ; si = decision variable
- hislopeline10:
- ; mov bx,varvertincr ; bx := y-increment
-
- l21: mov bh,ah
- and ah,fillmask ; ***********fillmask
- out dx,ax ; update bit mask register
- or es:[di],al ; update bit planes
- mov ah,bh
-
- add di,varvertincr ; increment y
- ; add di,bx ; increment y
-
- l22: or si,si ; test sign of d
- jns l23 ; jump if d >= 0
-
- add si,varincr1 ; d := d + incr1
- loop l21
- jmp short lexit
-
-
- l23: add si,varincr2 ; d := d + incr2
-
- ror ah,1 ; rotate bit mask
- adc di,0 ; increment di if when mask rotated to
- ; leftmost pixel position
-
- loop l21
-
-
- ; restore default graphics controller state and return to caller
-
- lexit: xor ax,ax ; ah := 0, al := 0
- out dx,ax ; restore set/reset register
-
- inc ax ; ah := 0, al := 1
- out dx,ax ; restore enable set/reset register
-
- mov al,3 ; ah := 0, al := 3
- out dx,ax ; al := data rotate/func select reg #
-
- mov ax,0ff08h ; ah := 1111111b, al := 8
- out dx,ax ; restore bit mask register
-
- 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
-
- lds si,cs:TDtable
- mov ax,ds:[si].rmwbits
- mov rmwb,ax
-
- mov al,ds:[si].clipped
- or al,al
- jz noclippix
-
- mov ax,ds:[si].wminy
- cmp argy,ax
- jl noputpixs
-
- mov ax,ds:[si].wmaxy
- cmp argy,ax
- jg noputpixs
-
- mov ax,ds:[si].wminx
- cmp argx,ax
- jl noputpixs
-
- mov ax,ds:[si].wmaxx
- cmp argx,ax
- jg noputpixs
-
- noclippix: mov ax,argy ; ax := y
- mov bx,argx ; bx := x
- call activeaddr ; ah := bit mask
- ; es:bx -> buffer
- ; cl := # bits to shift left
-
- ; set graphics controller bit mask register
-
- shl ah,cl ; ah := bit mask in proper position
- mov dx,3ceh ; gc address register port
- mov al,8 ; al := bit mask register number
- out dx,ax
-
- ; set graphics controller mode register
-
- mov ax,205h ; al := mode register number
- ; ah := write mode 2 (bits 0,1)
- ; read mode 0 (bit 3)
- out dx,ax
-
- ; set data rotate/function select register
-
- mov ah,byte ptr [rmwb] ; ah := read-modify-write bits
- mov al,3 ; al := data rotate/function select reg
- out dx,ax
-
- ; set the pixel value
-
- mov al,es:[bx] ; latch one byte from each bit plane
- mov al,byte ptr [color] ; al := pixel value
- mov es:[bx],al ; update all bit planes
-
- ; restore default graphics controller registers
-
- mov ax,0ff08h ; default bit mask
- out dx,ax
-
- mov ax,0005 ; default mode register
- out dx,ax
-
- mov ax,0003 ; default function select
- out dx,ax
-
- noputpixs: 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
-
-
- mov dx,3ceh ; dx := graphics controller port
- mov ah,byte ptr [bordercolor] ; ah := color for comparing
- mov al,2 ; al := color compare register
- out dx,ax
-
- mov ax,805h ; ah := 00001000b (read mode 1)
- out dx,ax ; al := mode reg number
-
- mov ax,0f07h ; ah := 00000111b (color compare reg)
- out dx,ax
-
- 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,2
- out dx,ax
-
- mov al,5
- out dx,ax
-
- 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 ch,ah
- shl ch,cl ; ch := bit mask in proper position
-
- mov si,bx ; es:si -> regen buffer byte
- xor bl,bl ; bl is used to accumulate the pixel value
-
- mov dx,3ceh ; dx := graphics controller port
- mov ax,304h ; ah := initial bit plane number
- ; al := read map select register number
-
- getpl01: out dx,ax ; select bit plane
- mov bh,es:[si] ; bh := byte from current bit plane
- and bh,ch ; mask one bit
- neg bh ; bit 7 of bh := 1 (if masked bit = 1)
- ; bit 7 of bh := 0 (if masked bit = 0)
- rol bx,1 ; bit 0 of bl := next bit from pixel value
- dec ah ; ah := next bit plane number
- jge getpl01
-
- mov al,bl ; al := pixel value
- xor ah,ah ; ax := pixel value
- pop si
- ret
- getpixs endp
-
-
- getbiti proc far argx0:word,argy0:word,argx1:word,argy1:word,addrbuf:dword
- local varpixelrows:word,varpixelrowlen:word,bpline:word,varpixelcontlen:word
-
- push ds
- push si
- push di
-
- cld
-
- lds si,cs:TDtable
- mov ax,ds:[si].vbytesperline
- mov bpline,ax
-
- ; compute dimensions of bit block
-
- mov ax,argx1
- sub ax,argx0
- mov cx,0ff07h
-
- and cl,al
-
- xor cl,7
- shl ch,cl
- mov cl,ch
- push cx
-
- mov cl,3
- shr ax,cl
- inc ax
- push ax
-
- mov ax,argy1
- sub ax,argy0
- inc ax
- push ax
-
- ; establish addressing
-
- mov ax,argy0
- mov bx,argx0
- call activeaddr
- xor cl,7
- push es
- pop ds
- mov si,bx
-
- les di,addrbuf
-
- ; build 5-byte bit block header
-
- pop ax
- mov varpixelrows,ax
- stosw
- pop ax
- mov varpixelrowlen,ax
- stosw
- pop ax
- mov ch,al
- stosb
-
- ; set up graphics controller
-
- mov dx,3ceh ; dx := graphics controller i/o port
-
- mov ax,0005 ; ah := 0 (read mode 0, write mode 0)
- out dx,ax ; al := 5 (mode register)
-
- mov ax,0304h ; ah := 3 (plane #3)
- ; mov ax,0004h ; ah := 3 (plane #3)
- ; al := 4 (read map select)
-
- mov bx,bpline
- sub bx,varpixelrowlen
- mov varpixelcontlen,bx
-
- or cl,cl ; bit shifts?
- jnz getbl06
-
- ; copy from video buffer to system ram
- ; routine for byte-aligned bit blocks
-
- mov cx,varpixelrowlen
- ; shr cx,1 ; divide by 2
-
- getbl01: out dx,ax
- push si
- mov bx,varpixelrows
-
- getbl02: push cx
-
- shr cx,1
- rep movsw
- adc cx,0
- rep movsb
-
- getbl04: pop cx
- add si,varpixelcontlen
-
- dec bx
- jnz getbl02
-
- normalize es,di,si ;pointer to stored bit block
- ;use si as temporary storage
- pop si
- dec ah
- jns getbl01
-
- jmp lexit1
-
-
- ; copy from video buffer to system ram
- ; routine for non-aligned bit blocks
-
- getbl06: out dx,ax ;next bit plane
- push ax ;save ax - plane & register
- push dx ;save dx - controller
- push si ;save si - start of bit block
-
- mov dx,varpixelrows
- getbl07: mov bx,varpixelrowlen
-
- getbl08: lodsw ;ax - used for rotating pixels
- dec si
- rol ax,cl
- stosb
-
- dec bx
- jnz getbl08
-
- add si,varpixelcontlen
- dec dx
- jnz getbl07
-
- normalize es,di,si ;pointer to stored bit block
- ;use si as temporary storage
-
- pop si
- pop dx
- pop ax
- dec ah
- jns getbl06
-
- lexit1: 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
- local varstartmask:word,varrowcount:word
- local varendmaskl:word,varendmaskr:word,bpline:word
-
- ; rmwbits - normalput 00h
- ; xorput 18h
- ; orput 10h
- ; andput 08h
- ; notput 80h
-
- push ds
- push si
- push di
-
- cld
- lds si,cs:TDtable
- mov ax,ds:[si].vbytesperline
- mov bpline,ax
-
- ; extablish addressing
-
- mov ax,argy
- mov bx,argx
- call activeaddr
- inc cl
- and cl,7
- mov di,bx
-
- lds si,addrbuf
-
- ; obtain dimensions of bit block from header
-
- lodsw
- mov varpixelrows,ax
- lodsw
- mov varpixelrowlen,ax
- lodsb
- mov ch,al
-
- ; set up graphics controller
-
- mov dx,3ceh ; dx := graphics controller i/o port
-
- mov ah,byte ptr [rmwb] ; ah := value for data rotate/function
- and ah,18h
- mov al,3 ; select register
- out dx,ax ; 18h is xor
-
- mov ax,0805h ; ah := 8 (read mode 1, write mode 0)
- out dx,ax ; al := 5 (mode register)
-
- mov ax,0007 ; ah := 0 (don't care for all maps;
- out dx,ax ; cpu reads always return 0ffh)
- ; al := 7 (color don't care reg number)
-
- mov ax,0ff08h ; ah := 0ffh (value for bit mask reg)
- out dx,ax ; set up bit mask reg
-
- mov dl,0c4h ; dx := 3c4h (sequence i/o port)
-
- mov ax,0802h ; ah := 1000b (value for map mask reg)
- ; al := 2 (map mask register number)
-
- cmp byte ptr [rmwb],18h
- jne putbl09
- jmp putbl15
-
- putbl09: or cl,cl ; check if we need to shift the image
- jne putbl15 ; if so then everything in image
- ; needs to shifted
-
- ; otherwise we will use fast byte-aligned block moves
- ; routine for byte-aligned bit blocks
-
- mov byte ptr [varendmaskl],ch ; save the mask if not 0ffh
- test ch,1 ; check if right side is even
- mov cx,varpixelrowlen
- jnz putbl10
- dec cx
-
- putbl10: out dx,ax
- push ax
- push di
- mov bx,varpixelrows
-
- putbl11: push di
- push cx
-
- test byte ptr [rmwb],80h
- jz normal
-
- shr cx,1 ; divide by 2
- jcxz putbl12a
- notnorm: lodsw
- not ax
- stosw
- loop notnorm
- putbl12a: lodsb
- not al
- jnc putbl12b
- stosb
- lodsb
- not al
- jmp short putbl12b
-
- normal: shr cx,1
- rep movsw
- adc cx,0
- rep movsb
- lodsb
-
- putbl12b: dec si
- mov cl,byte ptr [varendmaskl]
- test cl,1
- jnz putbl13
-
- inc si
-
- xchg cl,al
- mov ah,al
- mov al,8
- mov dl,0ceh
- out dx,ax
-
- and es:[di],cl
- mov ah,0ffh
- out dx,ax
- mov dl,0c4h
-
- putbl13: pop cx
- pop di
- add di,bpline
- dec bx
- jnz putbl11
-
- ;normalize ds,si pointer to stored bit block
- normalize ds,si,ax ;pointer to stored bit block
- ;use ax as temporary storage
-
- pop di
- pop ax
- shr ah,1
- jnz putbl10
- jmp lexit2
-
- ; routine for non-aligned bit blocks
-
- putbl15: push ax ; bit plane and function code 8
- mov bx,0ffh
- mov al,ch ; end of row bit pattern
- cbw
-
- cmp varpixelrowlen,1
- jne putbl16
-
- mov bl,ch
- mov ah,ch
- xor al,al
-
- putbl16: shl ax,cl
- shl bx,cl
-
- mov bl,al
- mov al,8
- mov varendmaskl,ax
- mov ah,bl
- mov varendmaskr,ax
- mov ah,bh
- mov varstartmask,ax
-
-
- xor ch,ch ; ch is set to 00h if FGNORM
- test byte ptr [rmwb],80h ; otherwise 0FFh if FGNOT
- jz oknot001
- not ch
-
- oknot001: mov bx,varpixelrowlen
- pop ax ; bit plane and function code 8
-
- ; set pixels row by row in the bit planes
-
- putbl17: out dx,ax
- push ax
- push di
- mov dl,0ceh
-
- mov ax,varpixelrows
- mov varrowcount,ax ; # of rows
-
- putbl18: push di
- push si
- push bx ; # of bytes/row
-
- mov ax,varstartmask
- out dx,ax
-
- lodsw
- dec si
-
- xor ah,ch ; xors 00h or ffh dependant
- xor al,ch ; on RMWB for FGNOT
-
- ;norm001:
- or cl,cl
- jnz putbl19
-
- dec bx
- jnz putbl20
- jmp short putbl22
-
- putbl19: rol ax,cl
-
- and es:[di],ah
- inc di
-
- dec bx
-
- putbl20: push ax
- mov ax,0ff08h
- out dx,ax
- pop ax
-
- dec bx
- jng putbl22
-
- ; set pixels in middle of row
-
- putbl21: and es:[di],al
- inc di
-
- lodsw
- dec si
-
- xor ah,ch ; xors 00h or ffh dependant
- xor al,ch ; on RMWB for FGNOT
-
- ;norm002:
- rol ax,cl
- dec bx
- jnz putbl21
-
- ; set pixels at end of row
-
- putbl22: mov bx,ax
- mov ax,varendmaskl
-
- out dx,ax
- and es:[di],bl
- inc di
-
- mov ax,varendmaskr
- out dx,ax
- and es:[di],bh
-
- pop bx ; # of bytes/row
- pop si
- pop di
-
- add si,bx
- add di,bpline
-
- dec varrowcount
- jnz putbl18
-
- ;normalize ds,si pointer to stored bit block
- normalize ds,si,ax ;pointer to stored bit block
- ;use ax as temporary storage
-
- pop di
- pop ax
- mov dl,0c4h ; dx := 3c4h (sequence i/o port)
- shr ah,1
- jnz putbl17
-
- ; restore graphics controller and sequencer to their default states
-
- lexit2: mov ax,0f02h
- out dx,ax
-
- mov dl,0ceh
- mov ax,003
- out dx,ax
-
- mov ax,0005
- out dx,ax
-
- mov ax,0f07h
- out dx,ax
-
- mov ax,0ff08h
- out dx,ax
-
- 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
- local nextplaneofs : 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 bit block2 size
- mov ax,var2pixelrowlen
- mov dx,var2pixelrows
- mul dx
- mov nextplaneofs,ax
-
- ; 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
-
- ;normalize ds,si pointer to stored bit block
- normalize ds,si,ax ;pointer to stored bit block
- ;use ax as temporary storage
- ;normalize es,di pointer to stored bit block
- normalize es,di,ax ;pointer to stored bit block
- ;use ax as temporary storage
-
-
- mov ax,4 ; four bit planes
- mov dx,var1pixelrows
-
- extrc06: push ax
- push dx
- push si
-
- 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 si
- pop dx
-
- add si,nextplaneofs
-
- ;normalize ds,si pointer to stored bit block
- normalize ds,si,ax ;pointer to stored bit block
- ;use ax as temporary storage
- ;normalize es,di pointer to stored bit block
- normalize es,di,ax ;pointer to stored bit block
- ;use ax as temporary storage
-
- pop ax
- dec ax
- jnz extrc06
-
- 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 nextplaneofs : 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 bit block2 size
- mov ax,var2pixelrowlen
- mov dx,var2pixelrows
- mul dx
- mov nextplaneofs,ax ; addrbuf2 size
-
- ; 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
- push ax
- ;normalize es,di pointer to stored bit block
- normalize es,di,ax ;pointer to stored bit block
- ;use ax as temporary storage
- ;normalize ds,si pointer to stored bit block
- normalize ds,si,ax ;pointer to stored bit block
- ;use ax as temporary storage
- pop ax
-
- cmp cx,0ff00h
- jne overl15
-
- ; routine for byte-aligned bit blocks
- mov cx,var1pixelrowlen
- mov dx,4
-
- overl10: push di
- 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
-
- pop di
- add di,nextplaneofs
-
- ;normalize es,di pointer to stored bit block
- normalize es,di,ax ;pointer to stored bit block
- ;use ax as temporary storage
- ;normalize ds,si pointer to stored bit block
- normalize ds,si,ax ;pointer to stored bit block
- ;use ax as temporary storage
-
- dec dx
- jnz overl10
- 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,4 ; 4 planes
- overl17: push ax
- push di
-
- 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
- or 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
-
- pop di
- add di,nextplaneofs
-
- call ovlnormalze
-
- pop ax
- dec ax
- jnz overl17
-
- overlexit: pop di
- pop es
- pop si
- pop ds
- ret
-
- overlayimg endp
-
-
- ovlnormalze proc near
- ;normalize ds,si pointer to stored bit block
- normalize ds,si,ax ;pointer to stored bit block
- ;use ax as temporary storage
- ;normalize es,di pointer to stored bit block
- normalize es,di,ax ;pointer to stored bit block
- ;use ax as temporary storage
- ret
- ovlnormalze endp
-
-
-
- extractpixs proc far argx0:word,argy0:word,addrbuff:dword
- local varpixelrows:word,varpixelrowlen:word
- local nextplaneofs:word
-
- push ds
- push si
- lds si,addrbuff
-
- cld
- lodsw ; varpixelrows
- mov varpixelrows,ax
- lodsw ; varpixelrows
- mov varpixelrowlen,ax
- lodsb
-
-
- ; establish bit block2 size
- mov ax,varpixelrowlen
- mov dx,varpixelrows
- mul dx
- mov nextplaneofs,ax
-
- ; establish addressing
-
- mov ax,argy0
- mov dx,varpixelrowlen
- mul dx ; multiply rows by bytesperrow
- add si,ax
-
- mov bx,argx0
- mov cl,bl
- shr bx,1 ; divide x coordinate by 8
- shr bx,1
- shr bx,1
- add si,bx ; add to address
-
- and cl,7 ; bits remainder
-
- xor cl,7
- mov ch,1
- shl ch,cl ; ch:=bit mask in proper position
-
- xor cl,7
- xor bl,bl ; bl is used to accumulate the pixel value
-
- mov dl,4 ; four bit planes
- extrbit: mov bh,ds:[si] ; bh := byte from current bit plane
- and bh,ch ; mask one bit
- shl bh,cl
- rol bx,1 ; bit 0 of bl := next bit from pixel value
- add si,nextplaneofs
-
- ;normalize ds,si pointer to stored bit block
- normalize ds,si,ax ;pointer to stored bit block
- ;use ax as temporary storage
-
- dec dl
- jnz extrbit
-
- mov al,bl ; al := pixel value
- xor ah,ah ; ax := pixel value
-
- 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
-
- push ds
- push si
- push es
- push di
-
- ; 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 nowrt
- 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
-
- ; xor cx,cx
- ; mov cl,es:[di].fontwidth ;calculate last byte mask
- ; and cl,7
- ; xor cl,7
- ; mov ch,0ffh
- ; shl ch,cl
- ; mov lastbytemask,ch
- ;
- ; mov al,ds:[si].proportional
- ; or al,al
- ; jnz okpropjmp
- ;
- ; ;otherwise check if proportional character needs alignment
- ; xor ax,ax
- ; mov al,es:[di].fontwidth
- ; xor bx,bx
- ; mov bl,byte ptr [argc] ;character
- ; sub al,es:[di][bx].Fontbytewidth ;index into width table
- ; shr al,1 ;divide by two
- ; mov charshift,al
- ; add argx,ax ;add it to argx
-
- ; calculate first pixel address
- okpropjmp: 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
- ; dec cx
-
- 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
-
- ; set up graphics controller registers
- mov dx,3ceh ; graphics controller address reg port
- mov ax,0a05h ; al := mode register number
- ; ah := write mode 2 (bits 0-1)
- ; read mode 1 (bit 4)
- out dx,ax
-
- mov ah,byte ptr [rmwb] ; ah := read-modify-write bits
- mov al,3 ; al := data rotate/function select reg
- out dx,ax
-
- mov ax,0007 ; ah := color don't care bits
- ; al := color don't care reg number
- out dx,ax ; "don't care" for all bit planes
-
- ; select output routine depending on whether character is byte-aligned
-
- mov bl,byte ptr [argfgd] ; bl := foreground pixel value
- mov bh,byte ptr [argbgd] ; bh := background pixel value
-
- mov ch,bpchar ; bytes per character
- xor ax,ax
- mov al,ch ; number of bytes per char width
- sub bpline,ax
-
- test byte ptr [varshift],0ffh ; test # bits to shift
- jne l20 ; jump if character is not byte-aligned
-
-
- ;------------------------------------------------
- ; routine for byte-aligned characters
- ;------------------------------------------------
-
- mov al,8 ; al := bit mask register number
- wrtcl10a: xchg cl,byte ptr jaggy ; jaggies
- wrtcl10: mov ah,es:[di] ; ah := pattern
-
- shr ah,cl
-
- jag1done: out dx,ax ; update bit mask register
- and [si],bl ; update foreground pixels
-
- not ah
- and ah,transparent ; transparent bits are either $ff or $00
- out dx,ax
- and [si],bh ; update background pixels
-
- inc di ; es:di -> next byte in char def table
- inc si
- dec ch
- jnz wrtcl10
-
- mov ch,bpchar ; bytes per character
- add si,bpline ; increment to next line in video buffer
-
- xchg cl,byte ptr jaggy+1
- xchg cl,byte ptr jaggy
- dec cl
- jnz wrtcl10a
- jmp short wrtcexit
-
- ;------------------------------------------------
- ; routine for non-byte-aligned characters
- ;------------------------------------------------
-
- l20: push cx ; preserve loop counter
- mov cx,varshift ; ch := mask for left side of character
- ; cl := # bits to shift left
- ; left side of character
-
- mov al,es:[di] ; al := bits for next row of pixels
- xor ah,ah
-
- xchg cl,byte ptr jaggy
- shr ax,cl
- xchg cl,byte ptr jaggy
-
- jag2done: shl ax,cl ; ah := bits for left side of char
- ; al := bits for right side of char
-
- push ax ; save bits for right side on stack
- mov al,8 ; al := bit mask register number
- out dx,ax ; set bit mask for foreground pixels
- and [si],bl ; update foreground pixels
-
- not ch ; ch mask for left side of char
- xor ah,ch ; ah bits for background
- and ah,transparent ; transparent bits are either $ff or $00
- out dx,ax
- and [si],bh ; update background pixels
-
- ; right side of character
-
- pop ax
- mov ah,al ; ah := bits for right side of char
- mov al,8
- out dx,ax ; set bit mask
- inc si ; ds:si -> right side of char in buffer
- and [si],bl ; update foreground pixels
-
- not ch ; ch mask for right side of char
- xor ah,ch ; ah bits for background
- and ah,transparent ; transparent bits are either $ff or $00
- out dx,ax
- and [si],bh ; update background pixels
-
- pop cx
- inc di ; es:di -> next byte in char def table
- dec ch
- jnz l20
-
- ; increment to next row of pixels in character
- mov ch,bpchar ; bytes per character
- add si,bpline ; ds:si -> next line in video buffer
-
- xchg cx,jaggy
- xchg cl,ch
- xchg cx,jaggy
-
- dec cl
- jnz l20
-
- ;------------------------------------------------
- ; restore default graphics controller registers
- ;------------------------------------------------
- wrtcexit: mov ax,0ff08h ; default bit mask
- out dx,ax
-
- mov ax,0005 ; default mode register
- out dx,ax
-
- mov ax,0003 ; default data rotate/function select
- out dx,ax
-
- mov ax,0f07h ; default color don't care
- out dx,ax
-
- nowrt: pop di
- pop es
- pop si
- pop ds
-
- ret
-
- wrtchar endp
-
- activeaddr proc near
-
- mov cl,bl
- push ds
- push si
- push dx
-
- lds si,cs:TDtable
- mov dx,ds:[si].vbytesperline
- mul dx
-
- pop dx
- shr bx,1
- shr bx,1
- shr bx,1
- add bx,ax
-
- mov ax,ds:[si].activepage
- shr ax,1
- shr ax,1
- shr ax,1
- shr ax,1
- add ax,0a000h
- 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
-
- ; modify putbiti to put an array of 3x16 bytes for four planes
- 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,bpline:word
-
- push es
- push di
- push ds
- push si
-
- ; save mouse cursor area
- lds si,cs:TDtable
- mov ax,ds:[si].vbytesperline
- mov bpline,ax
-
- mov ax,ds:[si].mousecolor
- 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 visualaddr ; es:bx -> 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 cs
- 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
-
- mov dx,3ceh ; graphics controller address reg port
-
- mov ax,0a05h ; al := mode register number
- ; ah := write mode 2 (bits 0-1)
- ; read mode 1 (bit 4)
- out dx,ax
-
- mov ah,0 ; ah := read-modify-write bits
- mov al,3 ; al := data rotate/function select reg
- out dx,ax
-
- mov ax,0007 ; ah := color don't care bits
- ; al := color don't care reg number
- out dx,ax ; "don't care" for all bit planes
-
- ; 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
-
-
- ; add code here to save three bytes at ds:[si] for four planes
- ; call subroutine
- mcl10: mov ax,es:[di]
- not ax
- push ax
- mov al,8
- out dx,ax
- and byte ptr [si],0
-
- pop ax
- mov ah,al
- mov al,8
- out dx,ax
- and byte ptr [si+1],0
-
- mov bl,mscolor
- mov ax,es:[di+32]
- push ax
- mov al,8
- out dx,ax
- and byte ptr [si],bl
-
- pop ax
- mov ah,al
- mov al,8
- out dx,ax
- and byte ptr [si+1],bl
-
- inc di
- inc di
-
- add si,bpline
- loop mcl10
- jmp short mclexit
-
-
- ; routine for non-byte-aligned characters
-
-
- ; add code here to save three bytes at ds:[si] for four planes
- ; call subroutine
- 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]
- not ax
- 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
- push ax
- mov al,8
- out dx,ax
- and byte ptr [si],0
-
- pop ax
- mov ah,al
- mov al,8
- out dx,ax
- and byte ptr [si+1],0
-
- pop ax
- xor ah,ah
- shl ax,cl ; ah := bits for left side of char
- ; al := bits for right side of char
- push ax
- mov al,8
- out dx,ax
- and byte ptr [si+1],0
-
- pop ax
- mov ah,al
- mov al,8
- out dx,ax
- and byte ptr [si+2],0
-
-
- ; colorize
- mov ax,es:[di+32]
-
- 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
- mov bl,mscolor
- push ax
- mov al,8
- out dx,ax
- and byte ptr [si],bl
- pop ax
-
- mov ah,al
- mov al,8
- out dx,ax
- and byte ptr [si+1],bl
- pop ax
-
- xor ah,ah
- shl ax,cl ; ah := bits for left side of char
- ; al := bits for right side of char
- push ax
- mov al,8
- out dx,ax
- and byte ptr [si+1],bl
- pop ax
- mov ah,al
- mov al,8
- out dx,ax
- and byte ptr [si+2],bl
-
- ; increment to next row of pixels in character
- inc di
- inc di
- add si,bpline ; ds:si -> next line in video buffer
-
- pop cx
- loop mcl20
-
-
- ; restore default graphics controller registers
-
- mclexit: mov ax,0ff08h ; default bit mask
- out dx,ax
-
- mov ax,0005 ; default mode register
- out dx,ax
-
- mov ax,0003 ; default data rotate/function select
- out dx,ax
-
- mov ax,0f07h ; default color don't care
- out dx,ax
-
- pop si ; restore caller registers and return
- pop ds
- pop di
- pop es
- ret
-
- mcursoron endp
-
- msetpos proc far argx:word,argy:word
- push ds
-
- test cs:mflag,1
- jz nomset
-
- call mcursoroff
-
- mov ax,argx
- push ax
- mov ax,argy
- push ax
- call mcursoron
-
- nomset: pop ds
- ret
- msetpos endp
-
-
- ; assume ds:si=addrbuf es:di=screenadr
- mputblock proc near
- push si
- push di
- push bx
-
- mov dx,ds
- mov ax,si
- lds si,cs:TDtable
- mov bx,ds:[si].vbytesperline
- mov si,ax
- mov ds,dx
-
- ; set up graphics controller
- mov dx,3ceh ; dx := graphics controller i/o port
-
- mov ax,0003h ; ah := normal put
- out dx,ax ; al := 3 select register
-
- mov ax,0805h ; ah := 8 (read mode 1, write mode 0)
- out dx,ax ; al := 5 (mode register)
-
- mov ax,0007 ; ah := 0 (don't care for all maps;
- out dx,ax ; cpu reads always return 0ffh)
- ; al := 7 (color don't care reg number)
-
- mov ax,0ff08h ; ah := 0ffh (value for bit mask reg)
- out dx,ax ; set up bit mask reg
-
- mov dl,0c4h ; dx := 3c4h (sequence i/o port)
-
- mov cx,16
- mcputbl10: mov ax,0802h ; ah := 1000b (value for map mask reg)
- ; al := 2 (map mask register number)
-
- cld
- mcputbl11: out dx,ax
- push di
-
- movsw
- movsb
-
- pop di
- shr ah,1
- jnz mcputbl11
-
- add di,bx
- loop mcputbl10
-
- ; restore graphics controller and sequencer to their default states
- mov ax,0f02h
- out dx,ax
-
- mov dl,0ceh
- mov ax,003
- out dx,ax
-
- mov ax,0005
- out dx,ax
-
- mov ax,0f07h
- out dx,ax
-
- mov ax,0ff08h
- out dx,ax
-
- pop bx
- pop di
- pop si
- ret
-
- mputblock endp
-
-
- ; assume es:di=addrbuf ds:si=screenadr
- mgetblock proc near
-
- cld
- push si
- push di
- push bx
-
- mov dx,ds
- mov ax,si
- lds si,cs:TDtable
- mov bx,ds:[si].vbytesperline
- mov si,ax
- mov ds,dx
-
- ; set up graphics controller
-
- mov dx,3ceh ; dx := graphics controller i/o port
- mov ax,0005 ; ah := 0 (read mode 0, write mode 0)
- out dx,ax ; al := 5 (mode register)
-
- mov cx,16
- mcgetbl01: mov ax,0304h ; ah := 3 (plane #3)
- ; al := 4 (read map select)
- mcgetbl02: out dx,ax
- push si
-
- movsw
- movsb
-
- pop si
- dec ah
- jns mcgetbl02
-
- add si,bx
- loop mcgetbl01
-
- pop bx
- pop di
- pop si
- ret
- mgetblock endp
-
-
- visualaddr proc near
-
- mov cl,bl
- push ds
- push dx
-
- push si
- lds si,cs:TDtable
- mov dx,ds:[si].vbytesperline
- pop si
- mul dx
-
- pop dx
- shr bx,1
- shr bx,1
- shr bx,1
- add bx,ax
-
- mov ax,40h
- mov ds,ax
- mov ax,ds:[4eh]
- shr ax,1
- shr ax,1
- shr ax,1
- shr ax,1
- add ax,0a000h
- mov es,ax
- pop ds
-
- and cl,7
- xor cl,7
- mov ah,1
- ret
-
- visualaddr endp
-
-
- 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:word,varendmaskl:word,varendmaskr:word
- 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 bx,argx0 ; | |
- ; | |
- ; +----------+
- mov cl,bl
- mov dx,bpline
- mul dx
- shr bx,1
- shr bx,1
- shr bx,1
- add bx,ax
-
- mov ax,word ptr [spage]
- and ax,000fh
- add bx,ax
-
- mov ax,word ptr [spage]
- shr ax,1
- shr ax,1
- shr ax,1
- shr ax,1
- ; add ax,0a000h
- add ax,word ptr [spage+2]
-
- mov word ptr [sourcescr],bx
- mov word ptr [sourcescr+2],ax
-
- and cl,7
- mov sourceshft,cl
-
- ;-------
- mov ax,argy2 ;target
- mov bx,argx2
-
- mov cl,bl
- mov dx,bpline
- mul dx
- shr bx,1
- shr bx,1
- shr bx,1
- add bx,ax
-
- mov ax,word ptr [tpage]
- and ax,000fh
- add bx,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 word ptr [targetscr],bx
- mov word ptr [targetscr+2],ax
-
- xor cl,7
- inc cl
- and cl,7
- mov targetshft,cl
-
- jmp movevideobl_23
-
- bottomupmove: add ax,vertlines
- mov varpixelrows,ax
-
- mov ax,argy0 ;source ; +----------+
- add ax,varpixelrows ; | |
- dec ax ; | |
- mov bx,argx0 ; +----\/----+
- ; +----------+
- mov cl,bl
- mov dx,bpline
- mul dx
-
- shr bx,1
- shr bx,1
- shr bx,1
- add bx,ax
-
- mov ax,word ptr [spage]
- and ax,000fh
- add bx,ax
-
- mov ax,word ptr [spage]
- shr ax,1
- shr ax,1
- shr ax,1
- shr ax,1
- ; add ax,0a000h
- add ax,word ptr [spage+2]
-
- mov word ptr [sourcescr],bx
- mov word ptr [sourcescr+2],ax
- and cl,7
- mov sourceshft,cl
-
- mov ax,argy1
- sub ax,argy0
- add ax,argy2
- mov bx,argx2 ;target
-
- mov cl,bl
- mov dx,bpline
- mul dx
-
- shr bx,1
- shr bx,1
- shr bx,1
- add bx,ax
-
- mov ax,word ptr [tpage]
- and ax,000fh
- add bx,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 word ptr [targetscr],bx
- mov word ptr [targetscr+2],ax
- xor cl,7
- inc cl
- and cl,7
- mov targetshft,cl
-
- xor ax,ax
- sub ax,bpline ; negate bpline
- mov bpline,ax
-
-
- ;-----------------------------------------------
- movevideobl_23:
- 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 bl,al ; al=endmask right
- mov al,8 ; ah=endmask left
- mov varendmaskl,ax
- mov ah,bl ;
- mov varendmaskr,ax
- mov ah,bh ; bh=startmask
- mov varstartmask,ax
-
-
- ; set up graphics controller
- mov dx,3ceh ; dx := graphics controller i/o port
-
- mov ax,0005 ; ah := 0 (read mode 0, write mode 0)
- out dx,ax ; al := 5 (mode register)
-
- mov ax,3 ; ah := value for data rotate/function
- out dx,ax ; 0 is normal put
-
-
- ;-----------------------------------------------
- movevideobl_22: mov ax,0ff08h ; ah := 0ffh (value for bit mask reg)
- out dx,ax ; set up bit mask reg
-
- mov ax,0802h ; ah := 1000b (value for map mask reg)
- ; al := 2 (map mask register number)
- mov bx,0304h ; ah := 3 (plane #3)
- ; al := 4 (read map select)
-
- movevideobl_01: push ax ; plane for writing
- push bx ; plane for reading
- lds si,sourcescr
- les di,workbuffer
-
- mov dl,0c4h ; dx := 3c4h (sequence i/o port)
- out dx,ax
-
- mov dl,0ceh ; dx := graphics controller i/o port
- mov ax,bx
- out dx,ax
-
- 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
-
- 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
- jmp mvetoscr_20
-
-
- ; routine for non-aligned bit blocks
- mvetoscr_17:
- mov ax,varstartmask ; eg. 00000111
- out dx,ax
-
- 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 ch,es:[di] ; latch byte
- mov es:[di],ah ; and screen 00000111
- inc di
- dec bx ; bx = 0
-
- mvetoscr_mid: dec bx ; bx < 0
- jng mvetoscr_end
-
- push ax
- mov ax,0ff08h ; set mask to 0ffh
- out dx,ax
- pop ax
-
- 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 bx,ax
- mov ax,varendmaskl
- out dx,ax
- mov ch,es:[di] ;latch byte
- mov es:[di],bl ; eg. 11111000
- inc di
- mov ax,varendmaskr ; eg. 00000000
- out dx,ax
- mov ch,es:[di] ;latch byte
- mov es:[di],bh
- ;-----------------------------------------------------move buffer to screen
-
- mvetoscr_20:
- pop bx
- pop ax
- shr ah,1
- dec bh
- js mvetoscr_30
- jmp movevideobl_01
-
- mvetoscr_30: mov ax,bpline
- add word ptr [targetscr],ax
- add word ptr [sourcescr],ax
- dec varpixelrows
- jz movevideobl_02
- jmp movevideobl_22
- movevideobl_02: jmp vertmove_12
-
-
- ; 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 cl,8
- mov varendmaskl,cx
- push cx
-
- mov bx,argx0
- mov cx,0ff07h
- and cl,bl
- shr ch,cl ;mask for start byte
- mov cl,8
- mov varstartmask,cx
-
- 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 ax,varstartmask
- and ax,varendmaskl ;combine both mask together
- mov varstartmask,ax
- mov varendmaskl,0
-
- vertmove_01: mov ax,varstartmask
- xor ah,0ffh
- jnz vertmove_07
- mov varstartmask,ax
- vertmove_07: mov ax,varendmaskl
- xor ah,0ffh
- jnz vertmove_08
- mov varendmaskl,ax
- 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 bx,argx0 ; | |
- ; | |
- ; +----------+
- mov dx,bpline
- mul dx
- shr bx,1
- shr bx,1
- shr bx,1
- add bx,ax
-
- mov ax,word ptr [spage]
- and ax,000fh
- add bx,ax
-
- mov ax,word ptr [spage]
- shr ax,1
- shr ax,1
- shr ax,1
- shr ax,1
- ; add ax,0a000h
- add ax,word ptr [spage+2]
- mov ds,ax
- mov si,bx
-
- mov ax,argy2 ;target
- mov bx,argx2
-
- mov dx,bpline
- mul dx
- shr bx,1
- shr bx,1
- shr bx,1
- add bx,ax
-
- mov ax,word ptr [tpage]
- and ax,000fh
- add bx,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 di,bx
-
-
- 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 bx,argx0 ; +----\/----+
- ; +----------+
-
- mov dx,bpline
- mul dx
- shr bx,1
- shr bx,1
- shr bx,1
- add bx,ax
-
- mov ax,word ptr [spage]
- and ax,000fh
- add bx,ax
-
- mov ax,word ptr [spage]
- shr ax,1
- shr ax,1
- shr ax,1
- shr ax,1
- ; add ax,0a000h
- add ax,word ptr [spage+2]
- mov ds,ax
- mov si,bx
-
- mov ax,argy1
- sub ax,argy0
- add ax,argy2
- mov bx,argx2 ;target
-
- mov dx,bpline
- mul dx
- shr bx,1
- shr bx,1
- shr bx,1
- add bx,ax
-
- mov ax,word ptr [tpage]
- and ax,000fh
- add bx,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 di,bx
-
- mov ax,bpline
- not ax
- inc ax
- sub ax,varpixelrowlen
- mov varpixelcontlen,ax
-
- ;-----------------------------------------------
- vertmove_31: mov dx,3ceh ; dx := graphics controller i/o port
-
- ; 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
-
- mov ax,varstartmask ; ah := 0ffh (value for bit mask reg)
- or ah,ah
- jz vertmove_09
-
- ; set up graphics controller
- mov dl,0ceh ; dx := graphics controller i/o port
- out dx,ax ; set up bit mask reg
-
- mov ax,0005 ; ah := 0 (read mode 0, write mode 0)
- out dx,ax ; al := 5 (mode register)
-
- mov bx,0802h ; bh := 1000b (value for map mask reg)
- ; bl := 2 (map mask register number)
- mov ax,0304h ; ah := 3 (plane #3)
- ; al := 4 (read map select)
-
- vertmove_03:
- mov dl,0ceh ; dx := graphics controller i/o port
- out dx,ax ; set read map select
-
- mov dl,0c4h ; dx := 3c4h (sequence i/o port)
- xchg ax,bx
- out dx,ax
- xchg ax,bx
-
- mov dl,ds:[si] ; get start byte
- or es:[di],dl ; latch destination bytes
- mov 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+1,0ffh
- jz vertmove_10
- dec cx
- vertmove_10: jcxz vertmove_04 ;do end part of scroll
-
- ; middle part of direct memory scroll
-
- ; the sequencer must be set back to all planes
- mov dl,0c4h ; dx := 3c4h (sequence i/o port)
- mov ax,0f02h ; bh := 1111b (value for map mask reg)
- out dx,ax ; bl := 2 (map mask register number)
-
- ; set bit mask. The book is incorrect in stating that
- ; write mode 1 ignores the bit mask.
- mov dl,0ceh ; dx := graphics controller i/o port
- mov ax,0008h ; ah := 000h (ignore bits, use latches)
- out dx,ax ; set up bit mask reg
-
- mov ax,0105 ; ah := 0 (read mode 0, write mode 1)
- out dx,ax ; al := 5 (mode register)
-
- rep movsb
-
- ; end part of direct memory scroll
- vertmove_04:
- mov ax,varendmaskl ; ah := 0ffh (value for bit mask reg)
- or ah,ah
- jz vertmove_06
-
- mov dl,0ceh ; dx := graphics controller i/o port
- out dx,ax ; set up bit mask reg
-
- mov ax,0005 ; ah := 0 (read mode 0, write mode 0)
- out dx,ax ; al := 5 (mode register)
-
- mov bx,0802h ; bh := 1000b (value for map mask reg)
- ; bl := 2 (map mask register number)
- mov ax,0304h ; ah := 3 (plane #3)
- ; al := 4 (read map select)
-
- vertmove_05: mov dl,0ceh ; dx := graphics controller i/o port
- out dx,ax ; set read map select
-
- mov dl,0c4h ; dx := 3c4h (sequence i/o port)
- xchg ax,bx
- out dx,ax
- xchg ax,bx
-
- mov dl,ds:[si] ; get start byte
- or es:[di],dl ; latch destination bytes
- mov es:[di],dl ; mask new info
-
- shr bh,1
- dec ah
- jns vertmove_05
-
- inc si
- inc di
-
- vertmove_06: ;mov ax,varpixelcontlen
- add si,varpixelcontlen
- add di,varpixelcontlen
- dec varpixelrows
- jz vertmove_12_F
- jmp vertmove_02
- vertmove_12_F: jmp vertmove_12
-
-
- ;-----------------------------------------------
- vertmove_20: mov cx,varpixelrowlen
-
- mov ax,varendmaskl ; ah := 0ffh (value for bit mask reg)
- or ah,ah
- jz vertmove_21
-
- ; set up graphics controller
- mov dl,0ceh ; dx := graphics controller i/o port
- out dx,ax ; set up bit mask reg
-
- mov ax,0005 ; ah := 0 (read mode 0, write mode 0)
- out dx,ax ; al := 5 (mode register)
-
- mov bx,0802h ; bh := 1000b (value for map mask reg)
- ; bl := 2 (map mask register number)
- mov ax,0304h ; ah := 3 (plane #3)
- ; al := 4 (read map select)
-
- vertmove_22: mov dl,0ceh ; dx := graphics controller i/o port
- out dx,ax ; set read map select
-
- mov dl,0c4h ; dx := 3c4h (sequence i/o port)
- xchg ax,bx
- out dx,ax
- xchg ax,bx
-
- mov dl,ds:[si] ; get start byte
- or es:[di],dl ; latch destination bytes
- mov es:[di],dl ; mask new info
-
- shr bh,1
- dec ah
- jns vertmove_22
-
- 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+1,0ffh
- jz vertmove_24
- dec cx
- vertmove_24: jcxz vertmove_25 ;do begining part of scroll
-
- ; middle part of direct memory scroll
- mov dl,0c4h ; dx := 3c4h (sequence i/o port)
- mov ax,0f02h ; bh := 1111b (value for map mask reg)
- out dx,ax ; bl := 2 (map mask register number)
-
- mov dl,0ceh ; dx := graphics controller i/o port
- mov ax,0008h ; ah := 0ffh (value for bit mask reg)
- out dx,ax ; set up bit mask reg
-
- mov ax,0105 ; ah := 0 (read mode 0, write mode 1)
- out dx,ax ; al := 5 (mode register)
-
- rep movsb ; movsb backwards to start byte
-
- ; end part of direct memory scroll
- vertmove_25:
- mov ax,varstartmask ; ah := 0ffh (value for bit mask reg)
- test ah,0ffh
- jz vertmove_23
-
- mov dl,0ceh ; dx := graphics controller i/o port
- out dx,ax ; set up bit mask reg
-
- mov ax,0005 ; ah := 0 (read mode 0, write mode 0)
- out dx,ax ; al := 5 (mode register)
-
- mov bx,0802h ; bh := 1000b (value for map mask reg)
- ; bl := 2 (map mask register number)
- mov ax,0304h ; ah := 3 (plane #3)
- ; al := 4 (read map select)
-
- vertmove_26: mov dl,0ceh ; dx := graphics controller i/o port
- out dx,ax ; set read map select
-
- mov dl,0c4h ; dx := 3c4h (sequence i/o port)
- xchg ax,bx
- out dx,ax
- xchg ax,bx
-
- mov dl,ds:[si] ; get start byte
- or es:[di],dl ; latch destination bytes
- mov es:[di],dl ; mask new info
-
- shr bh,1
- dec ah
- jns vertmove_26
-
- dec si
- dec di
-
- vertmove_23:
- add si,varpixelcontlen
- add di,varpixelcontlen
- dec varpixelrows
- jz vertmove_12
- jmp vertmove_20
-
-
-
- ; restore screen controller
- vertmove_12: mov dx,3c4h ; dx := 3c4h (sequence i/o port)
- mov ax,0f02h
- out dx,ax
-
- mov dl,0ceh
- mov ax,003
- out dx,ax
-
- mov ax,0005
- out dx,ax
-
- mov ax,0f07h
- out dx,ax
-
- mov ax,0ff08h
- out dx,ax
-
- 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
- jg novpage
-
- mov bx,40h
- mov ds,bx
- mov si,62h
- mov ds:[si],al
- mov si,4eh
- xor bx,bx
- or al,al
- jz vpageit
- mov bx,8000h
- vpageit: mov ds:[si],bx
-
- mov ah,5
- int 10h
-
- 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
-
- ;----------------------------------------------------------------------------;
- ; ;
- ;----------------------------------------------------------------------------;
- whichsvga proc near
- push es
- push di
- push ds
- push si
- push dx
- push cx
- push bx
-
- mov cs:vga512flag,0
- mov cs:vga1024flag,0
- mov cs:svgatype,-2
-
- call getvgatype
- mov ax,cs:svgatype
-
- pop bx
- pop cx
- pop dx
- pop si
- pop ds
- pop di
- pop es
- ret
- whichsvga endp
-
- ;----------------------------------------------------------------------------;
- ; ;
- ;----------------------------------------------------------------------------;
- nojmp macro
- local lbl
- jmp lbl
- lbl:
- endm
-
-
- getvgatype proc near
- mov si,1
- mov ax,0c000h
- mov es,ax
- cmp word ptr es:[40h],'13' ;ATI Signiture on the Video BIOS
- jnz noati
-
- mov cs:svgatype,x_ativga
- cli
- mov dx,1ceh
- mov al,0bbh
- out dx,al
- inc dl
- in al,dx
- sti
- and al,20h
- jz no512
- mov cs:vga512flag,1
- no512: jmp fini
-
- noati: mov ax,7000h ;Test for Everex
- xor bx,bx
- cld
- int 10h
- cmp al,70h
- jnz noev
-
- mov cs:svgatype,x_everex
- and ch,11000000b ;how much memory on board
- jz skp
- mov cs:vga512flag,1
- skp: ;fall through for Everex boards using Trident or Tseng4000
-
- noev: mov ax,0bf03h ;Test for Compaq
- xor bx,bx
- mov cx,bx
- int 10h
- cmp ax,0bf03h
- jnz nocp
- test cl,40h ;is 640x480x256 available?
- jz nocp
- mov cs:svgatype,x_compaq
- mov cs:vga512flag,1
- jmp fini
-
- nocp: mov dx,3c4h ;Test for NCR 77C22E
- mov ax,0ff05h
- call _isport2
- jnz noncr
- mov ax,5 ;Disable extended registers
- out dx,ax
- mov ax,0ff10h ;Try to write to extended register 10
- call _isport2 ;If it writes then not NCR
- jz noncr
- mov ax,105h ;Enable extended registers
- out dx,ax
- mov ax,0ff10h
- call _isport2
- jnz noncr ;If it does NOT write then not NCR
- mov cs:svgatype,x_ncr
- mov cs:vga512flag,1
- jmp fini
-
- noncr: mov dx,3c4h ;Test for Trident
- mov al,0bh
- out dx,al
- inc dl
- in al,dx
- cmp al,06h
- ja notri
- cmp al,2
- jb notri
- mov cs:svgatype,x_trident
- cmp al,3
- jb no89
- mov cs:svgatype,x_t8900
- mov dx,3d5h
- mov al,1fh
- out dx,al
- inc dx
- in al,dx
- and al,3
- cmp al,1
- jb notmem
- mov cs:vga512flag,1
- je notmem
- mov cs:vga1024flag,1
- notmem: jmp fini
-
- no89: mov cs:vga512flag,1
- jmp fini
-
- notri: mov ax,6f00h ;Test for Video 7
- xor bx,bx
- cld
- int 10h
- cmp bx,'V7'
- jnz nov7
- mov cs:svgatype,x_video7
- mov ax,6f07h
- cld
- int 10h
- and ah,7fh
- cmp ah,1
- jbe skp2
- mov cs:vga512flag,1
- skp2: cmp ah,3
- jbe skp3
- mov cs:vga1024flag,1
- skp3: jmp fini
-
- nov7: mov dx,3d4h ;Test for GENOA GVGA
- mov ax,032eh ;check for Herchi Register
- call _isport2
- jnz nogn
- mov dx,3c4h ;check for memory segment register
- mov ax,3f06h
- call _isport2
- jnz nogn
- mov cs:svgatype,x_genoa
- mov cs:vga512flag,1
- jmp fini
-
- nogn: call _cirrus ;Test for Cirrus
- cmp cs:svgatype,x_cirrus
- jne noci
- jmp fini
-
- noci: mov dx,3ceh ;Test for Paradise
- mov al,9 ;check Bank switch register
- out dx,al
- inc dx
- in al,dx
- dec dx
- or al,al
- jnz nopd
-
- mov ax,50fh ;turn off write protect on VGA registers
- out dx,ax
- mov cx,1
- mov dx,3ceh ;Test for Paradise
- call _chkbk
- jc nopd ;if bank 0 and 1 same not paradise
- mov cs:svgatype,x_paradise
- mov dx,3ceh
- mov al,0bh ;512k detect from Bob Berry
- out dx,al
- inc dx
- in al,dx
- test al,80h ;if top bit set then 512k
- jz nop512
- mov cs:vga512flag,1
- nop512: jmp fini
-
- nopd: mov ax,5f00h ;Test for Chips & Tech
- xor bx,bx
- cld
- int 10h
- cmp al,5fh
- jnz noct
- mov cs:svgatype,x_chipstech
- cmp bh,1
- jb skp4
- mov cs:vga512flag,1
- skp4: jmp fini
-
- noct: mov ch,0
- mov dx,3d4h ;check for Tseng 4000 series
- mov ax,0f33h
- call _isport2
- jnz not4
- mov ch,1
-
- mov dx,3bfh ;Enable access to extended registers
- mov al,3
- out dx,al
- mov dx,3d8h
- mov al,0a0h
- out dx,al
- jmp short yes4
-
- not4: mov dx,3d4h ;Test for Tseng 3000 or 4000
- mov ax,1f25h ;is the Overflow High register there?
- call _isport2
- jnz nots
- mov al,03fh ;bottom six bits only
- jmp short yes3
- yes4: mov al,0ffh
- yes3: mov dx,3cdh ;test bank switch register
- call _isport1
- jnz nots
- mov cs:svgatype,x_tseng
- cmp ch,0
- jnz t4mem
- mov cs:vga512flag,1
- jmp fini
-
- t4mem: mov dx,3d4h ;Tseng 4000 memory detect 1meg
- mov al,37h
- out dx,al
- inc dx
- in al,dx
- test al,1000b ;if using 64kx4 RAMs then no more than 256k
- jz nomem
- and al,3
- cmp al,1 ;if 8 bit wide bus then only two 256kx4 RAMs
- jbe nomem
- mov cs:vga512flag,1
- cmp al,2 ;if 16 bit wide bus then four 256kx4 RAMs
- je nomem
- mov cs:vga1024flag,1 ;full meg with eight 256kx4 RAMs
- nomem: mov cs:svgatype,x_tseng4
- jmp fini
-
- nots:
- mov dx,3ceh ;Test for Above A or B chipsets
- mov ax,200fh
- out dx,ax
- inc dx
- nojmp
- in al,dx
- cmp al,21h
- jz verb
- cmp al,20h
- jnz noab
- mov cs:svgatype,x_aheada
- mov cs:vga512flag,1
- jmp short fini
-
- verb: mov cs:svgatype,x_aheadb
- mov cs:vga512flag,1
- jmp short fini
-
- noab: mov dx,3deh ;Test for Oak Technology
- mov ax,0ff11h ;look for bank switch register
- call _isport2
- jz oakok
-
- push es
- push di
- push cx
-
- cld
- mov ax,0c000h
- mov es,ax
- xor di,di
- mov cx,256
-
- mov al,'O'
- findoak: repne scasb
- jcxz notoak
-
- cmp byte ptr es:[di],'A'
- jne findoak
-
- cmp byte ptr es:[di+1],'K'
- jne findoak
-
- pop cx
- pop di
- pop es
- jmp short oakok
-
-
- notoak: pop cx
- pop di
- pop es
- jmp short nooak
-
- oakok: mov cs:svgatype,x_oaktech
- mov al,0dh
- out dx,al
- inc dx
- nojmp
- in al,dx
- test al,80h
- jz no4ram
- mov cs:vga512flag,1
- no4ram: jmp short fini
-
- nooak: mov si,0
-
- fini: mov ax,si
- ret
- getvgatype endp
-
-
- _cirrus proc near
- mov dx,3d4h ; assume 3dx addressing
- mov al,0ch ; screen a start address hi
- out dx,al ; select index
- inc dx ; point to data
- mov ah,al ; save index in ah
- in al,dx ; get screen a start address hi
- xchg ah,al ; swap index and data
- push ax ; save old value
- push dx ; save crtc address
- xor al,al ; clear crc
- out dx,al ; and out to the crtc
-
- mov al,1fh ; Eagle ID register
- dec dx ; back to index
- out dx,al ; select index
- inc dx ; point to data
- in al,dx ; read the id register
- mov bh,al ; and save it in bh
-
- mov cl,4 ; nibble swap rotate count
- mov dx,3c4h ; sequencer/extensions
- mov bl,6 ; extensions enable register
-
- ror bh,cl ; compute extensions disable value
- mov ax,bx ; extensions disable
- out dx,ax ; disable extensions
- inc dx ; point to data
- in al,dx ; read enable flag
- or al,al ; disabled ?
- jnz exit ; nope, not an cirrus
-
- ror bh,cl ; compute extensions enable value
- dec dx ; point to index
- mov ax,bx ; extensions enable
- out dx,ax ; enable extensions
- inc dx ; point to data
- in al,dx ; read enable flag
- cmp al,1 ; enabled ?
- jne exit ; nope, not an cirrus
- mov cs:svgatype,x_cirrus
-
- exit: pop dx ; restore crtc address
- dec dx ; point to index
- pop ax ; recover crc index and data
- out dx,ax ; restore crc value
- ret
- _cirrus endp
-
- _chkbk proc near ;bank switch check routine
- push es
- mov di,0b800h
- mov es,di
- xor di,di
- mov bx,1234h
- call _gochk
- jnz badchk
- mov bx,4321h
- call _gochk
- jnz badchk
- clc
- pop es
- ret
- badchk: stc
- pop es
- ret
- _chkbk endp
-
- _gochk proc near
- push si
- push es
- mov si,bx
-
- mov al,cl
- call _pdrsub
- xchg bl,es:[di]
- mov al,ch
- call _pdrsub
- xchg bh,es:[di]
-
- xchg si,bx
-
- mov al,cl
- call _pdrsub
- xor bl,es:[di]
- mov al,ch
- call _pdrsub
- xor bh,es:[di]
-
- xchg si,bx
-
- mov al,ch
- call _pdrsub
- mov es:[di],bh
- mov al,cl
- call _pdrsub
- mov es:[di],bl
-
- mov al,0
- call _pdrsub
- or si,si
- pop es
- pop si
- ret
- _gochk endp
-
-
- _pdrsub proc near ;Paradise
- mov ah,al
- mov al,9
- out dx,ax
- ret
- _pdrsub endp
-
-
- _isport2 proc near
- push bx
- mov bx,ax
- out dx,al
- mov ah,al
- inc dx
- in al,dx
- dec dx
- xchg al,ah
- push ax
- mov ax,bx
- out dx,ax
- out dx,al
- mov ah,al
- inc dx
- in al,dx
- dec dx
- and al,bh
- cmp al,bh
- jnz noport2
- mov al,ah
- mov ah,0
- out dx,ax
- out dx,al
- mov ah,al
- inc dx
- in al,dx
- dec dx
- and al,bh
- cmp al,0
- noport2: pop ax
- out dx,ax
- pop bx
- ret
- _isport2 endp
-
- _isport1 proc near
- mov ah,al
- in al,dx
- push ax
- mov al,ah
- out dx,al
- in al,dx
- and al,ah
- cmp al,ah
- jnz noport1
- mov al,0
- out dx,al
- in al,dx
- and al,ah
- cmp al,0
- noport1: pop ax
- out dx,al
- ret
- _isport1 endp
-
- end
-