home *** CD-ROM | disk | FTP | other *** search
- .MODEL HUGE, C
-
- .486
-
- .CODE
-
- ; XMODE routines by Kaos (a.k.a. Bruno Carlos) of Black Magic
-
- ; Mode 0 -> 320x200 4 pages
- ; Mode 1 -> 320x240 3 pages
- ; Mode 2 -> 320x400 2 pages
- ; Mode 3 -> 320x480 1 page
- ; Mode 4 -> 360x200 3 pages
- ; Mode 5 -> 360x240 3 pages
- ; Mode 6 -> 360x400 1 page
- ; Mode 7 -> 360x480 1 page
-
- ; If you use this code in any of your
- ; productions give us the proper credits...
-
- ;****************************************************************************
-
- out_16 MACRO register, value
-
- ifdifi <register>,<dx> ; if dx not setup
- mov dx,register ; then select register
- endif
- ifdifi <value>,<ax> ; if ax not setup
- mov ax,value ; then get data value
- endif
- out dx,ax ; set i/o register(s)
- ENDM
-
- ;****************************************************************************
-
- out_8 MACRO register, value
-
- ifdifi <register>,<dx> ; if dx not setup
- mov dx,register ; then select register
- endif
- ifdifi <value>,<al> ; if al not setup
- mov al,value ; then get data value
- endif
- out dx,al ; set i/o register
- ENDM
-
- ;******************************************************************************
-
- vwait MACRO
- local Vertout,Vertin
-
- mov dx,03DAh
- Vertout:
- in al,dx
- test al,8
- jnz Vertout ; wait Until out of vertical retrace
- Vertin:
- in al,dx
- test al,8
- jz Vertin ; wait Until inside vertical retrace
- ENDM
-
- ;******************************************************************************
-
- hwait MACRO
- local Horzout,Horzin
-
- mov dx,03DAh
- Horzout:
- in al,dx
- test al,1
- jnz Horzout ; wait Until out of horizontal retrace
- Horzin:
- in al,dx
- test al,1
- jz Horzin ; wait Until inside horizontal retrace
- ENDM
-
- ;****************************************************************************
-
- xmode:
- dw offset X320x200
- dw offset X320x240
- dw offset X320x400
- dw offset X320x480
- dw offset X360x200
- dw offset X360x240
- dw offset X360x400
- dw offset X360x480
-
- ;****************************************************************************
-
- X320x200:
-
- db 063h ; 400 scan lines & 25 mhz clock
- dw 05f00h ; horz total
- dw 04f01h ; horz displayed
- dw 05002h ; start horz blanking
- dw 08203h ; end horz blanking
- dw 05404h ; start h sync
- dw 08005h ; end h sync
- dw 0bf06h ; vertical total
- dw 01f07h ; overflow
- dw 09c10h ; v sync start
- dw 08e11h ; v sync end/prot cr0 cr7
- dw 08f12h ; vertical displayed
- dw 09615h ; v blank start
- dw 0b916h ; v blank end
- dw 04109h ; cell height (2 scan lines)
- dw 00014h ; dword mode off
- dw 0e317h ; turn on byte mode
- dw 16000/4 ; page size (dwords)
- dw 320 ; xmax
- dw 200 ; ymax
- dw 0 ; page 1 offset
- dw 16000 ; page 2 offset
- dw 32000 ; page 3 offset
- dw 48000 ; page 4 offset
-
- ;****************************************************************************
-
- X320x240:
-
- db 0e3h ; 480 scan lines & 25 mhz clock
- dw 05f00h ; horz total
- dw 04f01h ; horz displayed
- dw 05002h ; start horz blanking
- dw 08203h ; end horz blanking
- dw 05404h ; start h sync
- dw 08005h ; end h sync
- dw 00d06h ; vertical total
- dw 03e07h ; overflow
- dw 0ea10h ; v sync start
- dw 08c11h ; v sync end/prot cr0 cr7
- dw 0df12h ; vertical displayed
- dw 0e715h ; v blank start
- dw 00616h ; v blank end
- dw 04109h ; cell height (2 scan lines)
- dw 00014h ; dword mode off
- dw 0e317h ; turn on byte mode
- dw 19200/4 ; page size (dwords)
- dw 320 ; xmax
- dw 240 ; ymax
- dw 0 ; page 1 offset
- dw 19200 ; page 2 offset
- dw 38400 ; page 3 offset
- dw 0 ; page 4 offset (same as page 1)
-
- ;****************************************************************************
-
- X320x400:
-
- db 063h ; 400 scan lines & 25 mhz clock
- dw 05f00h ; horz total
- dw 04f01h ; horz displayed
- dw 05002h ; start horz blanking
- dw 08203h ; end horz blanking
- dw 05404h ; start h sync
- dw 08005h ; end h sync
- dw 0bf06h ; vertical total
- dw 01f07h ; overflow
- dw 09c10h ; v sync start
- dw 08e11h ; v sync end/prot cr0 cr7
- dw 08f12h ; vertical displayed
- dw 09615h ; v blank start
- dw 0b916h ; v blank end
- dw 04009h ; cell height (1 scan line)
- dw 00014h ; dword mode off
- dw 0e317h ; turn on byte mode
- dw 32000/4 ; page size (dwords)
- dw 320 ; xmax
- dw 400 ; ymax
- dw 0 ; page 1 offset
- dw 32000 ; page 2 offset
- dw 0 ; page 3 offset (same as page 1)
- dw 32000 ; page 4 offset (same as page 2)
-
- ;****************************************************************************
-
- X320x480:
-
- db 0e3h ; 480 scan lines & 25 mhz clock
- dw 05f00h ; horz total
- dw 04f01h ; horz displayed
- dw 05002h ; start horz blanking
- dw 08203h ; end horz blanking
- dw 05404h ; start h sync
- dw 08005h ; end h sync
- dw 00d06h ; vertical total
- dw 03e07h ; overflow
- dw 0ea10h ; v sync start
- dw 08c11h ; v sync end/prot cr0 cr7
- dw 0df12h ; vertical displayed
- dw 0e715h ; v blank start
- dw 00616h ; v blank end
- dw 04009h ; cell height (1 scan line)
- dw 00014h ; dword mode off
- dw 0e317h ; turn on byte mode
- dw 38400/4 ; page size (dwords)
- dw 320 ; xmax
- dw 480 ; ymax
- dw 0 ; page 1 offset
- dw 0 ; page 2 offset (same as page 1)
- dw 0 ; page 3 offset (same as page 1)
- dw 0 ; page 4 offset (same as page 1)
-
- ;****************************************************************************
-
- X360x200:
-
- db 067h ; 400 scan lines & 28 mhz clock
- dw 06b00h ; horz total
- dw 05901h ; horz displayed
- dw 05a02h ; start horz blanking
- dw 08e03h ; end horz blanking
- dw 05e04h ; start h sync
- dw 08a05h ; end h sync
- dw 0bf06h ; vertical total
- dw 01f07h ; overflow
- dw 09c10h ; v sync start
- dw 08e11h ; v sync end/prot cr0 cr7
- dw 08f12h ; vertical displayed
- dw 09615h ; v blank start
- dw 0b916h ; v blank end
- dw 04109h ; cell height (2 scan lines)
- dw 00014h ; dword mode off
- dw 0e317h ; turn on byte mode
- dw 18000/4 ; page size (dwords)
- dw 360 ; xmax
- dw 200 ; ymax
- dw 0 ; page 1 offset
- dw 18000 ; page 2 offset
- dw 36000 ; page 3 offset
- dw 0 ; page 4 offset (same as page 1)
-
- ;****************************************************************************
-
- X360x240:
-
- db 0e7h ; 480 scan lines & 28 mhz clock
- dw 06b00h ; horz total
- dw 05901h ; horz displayed
- dw 05a02h ; start horz blanking
- dw 08e03h ; end horz blanking
- dw 05e04h ; start h sync
- dw 08a05h ; end h sync
- dw 00d06h ; vertical total
- dw 03e07h ; overflow
- dw 0ea10h ; v sync start
- dw 08c11h ; v sync end/prot cr0 cr7
- dw 0df12h ; vertical displayed
- dw 0e715h ; v blank start
- dw 00616h ; v blank end
- dw 04109h ; cell height (2 scan lines)
- dw 00014h ; dword mode off
- dw 0e317h ; turn on byte mode
- dw 21600/4 ; page size (dwords)
- dw 360 ; xmax
- dw 240 ; ymax
- dw 0 ; page 1 offset
- dw 21600 ; page 2 offset
- dw 43200 ; page 3 offset
- dw 0 ; page 4 offset (same as page 1)
-
- ;****************************************************************************
-
- X360x400:
-
- db 067h ; 400 scan lines & 28 mhz clock
- dw 06b00h ; horz total
- dw 05901h ; horz displayed
- dw 05a02h ; start horz blanking
- dw 08e03h ; end horz blanking
- dw 05e04h ; start h sync
- dw 08a05h ; end h sync
- dw 0bf06h ; vertical total
- dw 01f07h ; overflow
- dw 09c10h ; v sync start
- dw 08e11h ; v sync end/prot cr0 cr7
- dw 08f12h ; vertical displayed
- dw 09615h ; v blank start
- dw 0b916h ; v blank end
- dw 04009h ; cell height (1 scan line)
- dw 00014h ; dword mode off
- dw 0e317h ; turn on byte mode
- dw 36000/4 ; page size (dwords)
- dw 360 ; xmax
- dw 400 ; ymax
- dw 0 ; page 1 offset
- dw 0 ; page 2 offset (same as page 1)
- dw 0 ; page 3 offset (same as page 1)
- dw 0 ; page 4 offset (same as page 1)
-
- ;****************************************************************************
-
- X360x480:
-
- db 0e7h ; 480 scan lines & 28 mhz clock
- dw 06b00h ; horz total
- dw 05901h ; horz displayed
- dw 05a02h ; start horz blanking
- dw 08e03h ; end horz blanking
- dw 05e04h ; start h sync
- dw 08a05h ; end h sync
- dw 00d06h ; vertical total
- dw 03e07h ; overflow
- dw 0ea10h ; v sync start
- dw 08c11h ; v sync end/prot cr0 cr7
- dw 0df12h ; vertical displayed
- dw 0e715h ; v blank start
- dw 00616h ; v blank end
- dw 04009h ; cell height (1 scan line)
- dw 00014h ; dword mode off
- dw 0e317h ; turn on byte mode
- dw 43200/4 ; page size (dwords)
- dw 360 ; xmax
- dw 480 ; ymax
- dw 0 ; page 1 offset
- dw 0 ; page 2 offset (same as page 1)
- dw 0 ; page 3 offset (same as page 1)
- dw 0 ; page 4 offset (same as page 1)
-
- ;****************************************************************************
-
- attrib_ctrl equ 03c0h ; vga attribute controller
- gc_index equ 03ceh ; vga graphics controller
- sc_index equ 03c4h ; vga sequencer controller
- sc_data equ 03c5h ; vga sequencer data port
- crtc_index equ 03d4h ; vga crt controller
- crtc_data equ 03d5h ; vga crt controller data
- misc_output equ 03c2h ; vga misc register
- input_1 equ 03dah ; input status #1 register
-
- dac_write_addr equ 03c8h ; vga dac write addr register
- dac_read_addr equ 03c7h ; vga dac read addr register
- pel_data_reg equ 03c9h ; vga dac/pel data register r/w
-
- pixel_pan_reg equ 033h ; attrib index: pixel pan reg
- map_mask equ 002h ; sequ index: write map mask reg
- read_map equ 004h ; gc index: read map register
- start_disp_hi equ 00ch ; crtc index: display start hi
- start_disp_lo equ 00dh ; crtc index: display start lo
-
- map_mask_plane1 equ 00102h ; map register + plane 1
- map_mask_plane2 equ 01102h ; map register + plane 1
- all_planes_on equ 00f02h ; map register + all bit planes
-
- chain4_off equ 00604h ; chain 4 mode off
- async_reset equ 00100h ; (a)synchronous reset
- sequ_restart equ 00300h ; sequencer restart
-
- latches_on equ 00008h ; bit mask + data from latches
- latches_off equ 0ff08h ; bit mask + data from cpu
-
- vert_retrace equ 08h ; input_1: vertical retrace bit
- plane_bits equ 03h ; bits 0-1 of xpos = plane #
- all_planes equ 0fh ; all bit planes selected
- char_bits equ 0fh ; bits 0-3 of character data
-
- ;****************************************************************************
-
- PUBLIC rows
- PUBLIC pages
- PUBLIC xmax
- PUBLIC ymax
- PUBLIC vxmin
- PUBLIC vymin
- PUBLIC vxmax
- PUBLIC vymax
-
- ;****************************************************************************
-
- rows dw 800 dup(0) ; addresses to all rows in the screen
- pages dw 4 dup(0) ; offsets of all video pages
- scr_width dw ? ; screen width in pixels
- pagesize dw ?
- xmax dw ?
- ymax dw ?
- vxmin dw ?
- vymin dw ?
- vxmax dw ?
- vymax dw ?
-
- ;****************************************************************************
-
- PUBLIC xinitvideo
-
- xinitvideo PROC mode:word
-
- push ds
- push es
- push si
- push di
-
- and mode,00000111b ; make sure mode is in range 0->7
-
- cli
- vwait ; wait for start of vertical retrace
- mov dx,3c8h ; clear palette to remove flicker
- xor al,al
- out dx,al
- inc dx
- mov cx,768
- xcp1:
- out dx,al
- loop xcp1
- vwait
- sti
- mov ax,0013h ; set normal 320x200 graphics mode
- int 10h
- cli
- mov dx,3c8h ; clear palette again
- xor al,al
- out dx,al
- inc dx
- mov cx,768
- xcp2:
- out dx,al
- loop xcp2
- vwait
-
- out_16 sc_index,chain4_off ; disable chain 4 mode
- out_16 sc_index,async_reset ; (a)synchronous reset
- mov bx,mode ; get xmode
- shl bx,1 ; multiply it by 2
- mov si,word ptr xmode[bx] ; point to Xmode table
- mov al,byte ptr cs:[si] ; get crtc data from table
- out_8 misc_output,al ; set new timing/size
- out_16 sc_index,sequ_restart ; restart sequencer ...
-
- out_8 crtc_index,11h ; select vert retrace end register
- inc dx ; point to data
- in al,dx ; get value, bit 7 = protect
- and al,7fh ; mask out write protect
- out dx,al ; and send it back
-
- mov dx,crtc_index ; vga crtc registers
- add si,1 ; advance pointer
- mov cx,16 ; we are going to send out 16 words
- xiv1:
- mov ax,word ptr cs:[si] ; get crtc data from table
- add si,2 ; advance pointer
- out dx,ax ; reprogram vga crtc reg
- loop xiv1 ; do it 16 times
-
- mov ax,word ptr cs:[si] ; get pagesize from table
- mov pagesize,ax ; update pagesize var
- mov ax,word ptr cs:[si+2] ; get xmax from table
- mov xmax,ax ; update xmax var
- mov vxmax,ax
- mov ax,word ptr cs:[si+4] ; get ymax from table
- mov ymax,ax ; update ymax var
- mov vymax,ax
- mov ax,xmax ; get xmax
- shr ax, 2 ; bytes = pixels / 4
- mov scr_width, ax ; save width in bytes
- shr ax,1 ; offset value = bytes / 2
- mov ah,13h ; crtc offset register index
- xchg al,ah ; switch format for out
- out dx,ax ; set vga crtc offset reg
-
- mov cx,800 ; get # of rows
- mov bx,offset rows ; point to rows table
- xor ax,ax ; clear ax
- xiv2:
- mov cs:[bx],ax ; put row offset in table
- add ax,scr_width ; get next row offset
- add bx,2 ; advance pointer
- loop xiv2 ; loop until i'ts done
-
- mov ax,cs ; get code segment
- mov ds,ax ; load ds with it
- mov es,ax ; and es too
- mov cx,4 ; cx=counter=4
- add si,6 ; point si to xmode specific pages
- mov di,offset pages ; point di to pages table
- rep movsw ; move 4 words from ds:si to es:di
-
- mov vxmin,0
- mov vymin,0
-
- sti
-
- pop di
- pop si
- pop es
- pop ds
-
- ret
-
- xinitvideo ENDP
-
- ;****************************************************************************
-
- PUBLIC xclrvram
-
- xclrvram PROC
-
- push es
- push di
-
- mov dx,003c4h ; update all 4 bit-planes at the same time
- mov ax,00f02h
- out dx,ax
-
- cld ; block fill forwards
- mov ax,0a000h ; clear vram (all planes)
- mov es,ax
- xor di,di
- mov cx,16384
- xor eax,eax
- rep stosd
-
- pop di
- pop es
-
- ret
-
- xclrvram ENDP
-
- ;****************************************************************************
-
- PUBLIC xclrvpage
-
- xclrvpage PROC vpage:word
-
- push es
- push di
-
- mov ax,0a000h
- mov es,ax ; point to vga memory segment
- mov bx,vpage ; get page #
- and bx,00000011b ; make sure page # is in range 0->3
- shl bx,1 ; scale bx
- mov di,cs:pages[bx] ; get page offset
- out_16 sc_index,all_planes_on ; select all planes
- xor eax,eax ; fill page with color 0
- cld ; block fill forwards
- mov cx,pagesize ; get size of page
- rep stosd ; block fill vga memory
-
- pop di
- pop es
-
- ret
-
- xclrvpage ENDP
-
- ;****************************************************************************
-
- PUBLIC xsetvpage
-
- xsetvpage PROC vpage:word
-
- mov bx,vpage ; get page #
- and bx,00000011b ; make sure page # is in range 0->3
- shl bx,1 ; scale bx
- mov bx,cs:pages[bx] ; get page offset
-
- mov dx,03d4h ; we change the vga sequencer
-
- mov al,00ch ; display start high register
- mov ah,bh ; high 8 bits of start addr
- out dx,ax ; set display addr high
-
- mov al,00dh ; display start low register
- mov ah,bl ; low 8 bits of start addr
- out dx,ax ; set display addr low
-
- ret
-
- xsetvpage ENDP
-
- ;****************************************************************************
-
- PUBLIC xplot
-
- xplot PROC x:word, y:word, color:byte, vpage:word
-
- push es
- push di
-
- mov ax,0a000h
- mov es,ax ; point to vga memory segment
-
- mov bx,vpage ; get page #
- and bx,00000011b ; make sure page # is in range 0->3
- shl bx,1 ; scale bx
- mov di,cs:pages[bx] ; get page offset
-
- mov bx,y ; get y coord
- shl bx,1 ; y=y*2
- add di,cs:rows[bx] ; get offset to start of line
-
- mov bx,x ; get x
- mov cx,bx ; copy to extract plane # from
- shr bx,2 ; x offset (bytes) = x/4
- add di,bx ; offset = width*y + x/4
-
- mov ax,map_mask_plane1 ; map mask & plane select register
- and cl,plane_bits ; get plane bits
- shl ah,cl ; get plane select value
- out_16 sc_index,ax ; select plane
-
- mov al,byte ptr color ; get pixel color
- mov byte ptr es:[di],al ; draw pixel
-
- pop di
- pop es
-
- ret
-
- xplot ENDP
-
- ;****************************************************************************
-
- PUBLIC xget
-
- xget PROC x:word, y:word, vpage:word
-
- push es
- push di
-
- mov ax,0a000h
- mov es,ax ; point to vga memory segment
-
- mov bx,vpage ; get page #
- and bx,00000011b ; make sure page # is in range 0->3
- shl bx,1 ; scale bx
- mov di,cs:pages[bx] ; get page offset
-
- mov bx,y ; get y coord
- shl bx,1 ; y=y*2
- add di,cs:rows[bx] ; get offset to start of line
-
- mov bx,x ; get x
- mov cx,bx ; copy to extract plane # from
- shr bx,2 ; x offset (bytes) = x/4
- add di,bx ; offset = width*y + x/4
-
- mov ax,read_map ; read map register
- and cl,plane_bits ; get plane bits
- out_16 gc_index,ax ; select plane
-
- mov al,byte ptr es:[di] ; get pixel color
-
- pop di
- pop es
-
- ret
-
- xget ENDP
-
- ;****************************************************************************
-
- bmpx dw ?
- bmpy dw ?
- skew dw ?
- offi dw ?
- paste dw ?
-
- ;****************************************************************************
-
- PUBLIC ximageput ; for now ignores remaining 4 or less pixels
-
- ximageput PROC bitmap:dword, x:word, y:word, vpage:word
-
- push ds
- push es
- push si
- push di
-
- mov ds,offset bitmap+2 ; get bitmap data segment
- mov si,offset bitmap ; get bitmap data offset
- mov ax,0A000h ;
- mov es,ax ; point to vga memory segment
-
- mov bx,vpage ; get page #
- and bx,00000011b ; make sure page # is in range 0->3
- shl bx,1 ; scale bx
- mov di,cs:pages[bx] ; get page offset
-
- mov bx,y ; get y coord
- shl bx,1 ; y=y*2
- add di,cs:rows[bx] ; add offset to start of line
- mov bx,x ; get x
- mov cx,bx ; copy to extract plane # from
- xor ch,ch ; ignore high word
- shr bx,2 ; x offset (bytes) = x/4
- add di,bx ; add x offset
- mov offi,di ; keep di in var offi for later use
-
- xor bx,bx ; clear bx
-
- lodsw ; get bitmap width
- mov skew,ax ; keep it in var skew
- and skew,00000011b ; skew now has # of remaining pixels
- shr ax,2 ; ax=ax/4
- mov bmpx,ax ; bmpx=bitmap width/4
- lodsw ; get bitmap height
- mov bmpy,ax ; keep it in var bmpy
- add bitmap,4 ; point to bitmap data
- mov paste,0 ; clear paste var
- xdbmp1:
- inc ch ; ch will be used as a counter (4)
- mov ax,map_mask_plane1 ; map mask & plane select register
- and cl,plane_bits ; get plane bits
- shl ah,cl ; get plane select value
- out_16 sc_index,ax ; select plane
- push cx
- call xdb ; draw in it
- pop cx
- cmp ch,4 ; all planes done ?
- je xdbmp3 ; if so, end
- cmp paste,0 ; are we in a new video ram offset ?
- je xdbmp2 ; if not, continue
- add di,1 ; if so, inc destination index
- xdbmp2:
- add cl,1 ; next plane(cl will have plane bits)
- cmp cl,4 ; inc plane
- jne xdbmp1 ;
- xor cl,cl
- mov paste,1
- add di,1
- jmp xdbmp1
- xdbmp3:
- pop di
- pop si
- pop es
- pop ds
-
- ret
-
- xdb PROC NEAR
-
- mov cx,bmpy ; loop bmpy times
- xdb1:
- push cx
- mov cx,bmpx ; loop bmpx times
- xdb2:
- movsb ; plot pixel (and advance 1 pixel)
- add si,3 ; advance 3 pixels
- loop xdb2
- pop cx
- add si,skew ; step over bitmap skew times
- add di,scr_width ; goto next line
- sub di,bmpx
- loop xdb1
- mov di,offi ; goto begining vram offset
- inc bx
- mov si,offset bitmap ; point to bitmap data
- add si,bx ; plus bx
-
- ret
-
- xdb ENDP
-
- ximageput ENDP
-
- ;****************************************************************************
-
- PUBLIC ximageadd ; for now ignores remaining 4 or less pixels
-
- ximageadd PROC bitmap:dword, x:word, y:word, vpage:word
-
- push ds
- push es
- push si
- push di
-
- mov ds,offset bitmap+2 ; get bitmap data segment
- mov si,offset bitmap ; get bitmap data offset
- mov ax,0A000h ;
- mov es,ax ; point to vga memory segment
-
- mov bx,vpage ; get page #
- and bx,00000011b ; make sure page # is in range 0->3
- shl bx,1 ; scale bx
- mov di,cs:pages[bx] ; get page offset
-
- mov bx,y ; get y coord
- shl bx,1 ; y=y*2
- add di,cs:rows[bx] ; add offset to start of line
- mov bx,x ; get x
- mov cx,bx ; copy to extract plane # from
- xor ch,ch ; ignore high word
- shr bx,2 ; x offset (bytes) = x/4
- add di,bx ; add x offset
- mov offi,di ; keep di in var offi for later use
-
- xor bx,bx ; clear bx
-
- lodsw ; get bitmap width
- mov skew,ax ; keep it in var skew
- and skew,00000011b ; skew now has # of remaining pixels
- shr ax,2 ; ax=ax/4
- mov bmpx,ax ; bmpx=bitmap width/4
- lodsw ; get bitmap height
- mov bmpy,ax ; keep it in var bmpy
- add bitmap,4 ; point to bitmap data
- mov paste,0 ; clear paste var
- xia1:
- inc ch ; ch will be used as a counter (4)
- mov ax,map_mask_plane1 ; map mask & plane select register
- and cl,plane_bits ; get plane bits
- shl ah,cl ; get plane select value
- out_16 sc_index,ax ; select plane
-
- mov al,read_map ; read map register
- mov ah,cl
- out_16 gc_index,ax ; select plane
-
- push cx
- call xadd ; draw in it
- pop cx
- cmp ch,4 ; all planes done ?
- je xia3 ; if so, end
- cmp paste,0 ; are we in a new video ram offset ?
- je xia2 ; if not, continue
- add di,1 ; if so, inc destination index
- xia2:
- add cl,1 ; next plane(cl will have plane bits)
- cmp cl,4 ; inc plane
- jne xia1 ;
- xor cl,cl
- mov paste,1
- add di,1
- jmp xia1
- xia3:
- pop di
- pop si
- pop es
- pop ds
-
- ret
-
- xadd PROC NEAR
-
- mov cx,bmpy ; loop bmpy times
- xadd1:
- push cx
- mov cx,bmpx ; loop bmpx times
- xadd2:
- mov al,es:[di]
- add al,ds:[si]
- mov es:[di],al ; plot pixel
- add si,4 ; advance 3 pixels
- add di,1
- loop xadd2
- pop cx
- add si,skew ; step over bitmap skew times
- add di,scr_width ; goto next line
- sub di,bmpx
- loop xadd1
- mov di,offi ; goto begining vram offset
- inc bx
- mov si,offset bitmap ; point to bitmap data
- add si,bx ; plus bx
-
- ret
-
- xadd ENDP
-
- ximageadd ENDP
-
- ;****************************************************************************
-
- PUBLIC xresize
-
- xresize PROC x:word, y:word
-
- mov ax,x ; get new screen width
- mov vxmax,ax ; save new screen width
- shr ax,2 ; bytes = pixels / 4
- mov scr_width, ax ; save width in bytes
-
- mov ax,y ; get new screen height
- mov vymax,ax ; save new screen height
- mov cx,800
- mov bx,offset rows ; point to rows table
- xor ax,ax ; clear ax
- xr1:
- mov cs:[bx],ax ; put row offset in table
- add ax,scr_width ; get next row offset
- add bx,2 ; advance pointer
- loop xr1 ; loop until i'ts done
-
- mov bx,8 ; bx = 8 pixels wide
- mov ax,x ; ax = number of pixels per row
- div bl ; al = number of character columms
- xchg ah,al ; ah = number of character columms
-
- mov al,13h ; CRTC offset register number
- out_16 crtc_index,ax
-
- ret
-
- xresize ENDP
-
- ;****************************************************************************
-
- PUBLIC xpanscr
-
- xpanscr PROC x:word, y:word
-
- mov dx,3dah ; video status port
- in al,dx ; reset flip-flop
- mov dx,3c0h ; attribute controller port
- mov al,13h or 20h ; horiz pel pan reg number OR 0x20
- out dx,al ; write attribute controller address reg
- mov al,byte ptr x ; get pixel x coordinate
- and al,3 ; value for horiz pel pan reg
- shl al,1
- out dx,al ; write horiz pel pan reg
-
- mov bx,y ; get pixel y coordinate
- xor dx,dx
- mov ax,x ; get pixel x coordinate
- div vxmax
- add bx,ax
- mov vymin,bx ; save new virtual minimum x
- shl bx,1 ; scale bx
- mov bx,cs:rows[bx] ; get row offset from table
- mov vxmin,dx ; save new virtual minimum x
- mov ax,dx
- shr ax,2 ; divide by 4 (for X-mode)
- add bx,ax ; save it for later use
-
- mov dx,03d4h ; vga crt controller
- mov al,0ch ; start address high reg number
- mov ah,bh ; get start address high
- out dx,ax ; write start address high
-
- mov al,0dh ; start address low reg number
- mov ah,bl ; get start address low
- out dx,ax ; write start address low
-
- ret
-
- xpanscr ENDP
-
- ;****************************************************************************
-
- PUBLIC xsplit
-
- xsplit PROC n:word
-
- mov dx,3d4h
- mov ax,n
- mov vymax,ax
- mov bh,ah
- mov bl,bh
- and bx,0201h
- mov cl,4
- shl bx,cl
- shl bh,1
- mov ah,al
- mov al,18h
- out dx,ax
- mov al,7
- out dx,ax
- inc dx
- in al,dx
- dec dx
- mov ah,al
- and ah,11101111b
- or ah,bl
- mov al,7
- out dx,ax
- mov al,9
- out dx,al
- inc dx
- in al,dx
- dec dx
- mov ah,al
- and ah,10111111b
- or ah,bh
- mov al,9
- out dx,ax
-
- ret
-
- xsplit ENDP
-
- ;****************************************************************************
-
- PUBLIC xlineputcy
-
- xlineputcy PROC pointer:dword, ya:word, x:word, y:word, vpage:word
-
- push ds
- push es
- push si
- push di
-
- mov ax,0a000h
- mov es,ax
-
- mov bx,vpage ; get page #
- and bx,00000011b ; make sure page # is in range 0->3
- shl bx,1 ; scale bx
- mov di,cs:pages[bx] ; get page offset
-
- mov bx,y ; get y coord
- shl bx,1 ; y=y*2
- add di,cs:rows[bx] ; get offset to start of line
-
- mov bx,x ; get x
- mov cx,bx ; copy to extract plane # from
- shr bx,2 ; x offset (bytes) = x/4
- add di,bx ; offset = width*y + x/4
-
- mov ax,map_mask_plane1 ; map mask & plane select register
- and cl,plane_bits ; get plane bits
- shl ah,cl ; get plane select value
- out_16 sc_index,ax ; select plane
-
- mov si,offset pointer
- mov ds,offset pointer+2
-
- xor bx,bx
- xor dx,dx
- xor cx,cx
- plcy1:
- mov cl,byte ptr ds:[si]
- add bx,cx
- mov al,byte ptr ds:[si+1]
- plcy2:
- mov byte ptr es:[di],al
- add di,scr_width
- loop plcy2
- add si,2
- add dx,2
- cmp bx,ya
- jl plcy1
- mov ax,dx
-
- pop di
- pop si
- pop es
- pop ds
-
- ret
-
- xlineputcy ENDP
-
- ;****************************************************************************
-
- PUBLIC xblock
-
- xblock PROC x1:word, y1:word, count:word, y2:word, color:byte, vpage:word
-
- push es
- push di
-
- mov ax,0a000h
- mov es,ax
-
- mov bx,vpage ; get page #
- and bx,00000011b ; make sure page # is in range 0->3
- shl bx,1 ; scale bx
- mov di,cs:pages[bx] ; get page offset
-
- mov bx,y1 ; get y coord
- shl bx,1 ; y=y*2
- add di,cs:rows[bx] ; get offset to start of line
-
- mov bx,x1 ; get x
- shr bx,2 ; x offset (bytes) = x/4
- add di,bx ; offset = width*y + x/4
-
- mov dx,003c4h ; update all 4 bit-planes at the same time
- mov ax,00f02h
- out dx,ax
-
- mov al,color
- mov cx,count
- xb1:
- push di
- push cx
- mov cx,y2
- sub cx,y1
- xb2:
- mov byte ptr es:[di],al
- add di,scr_width
- loop xb2
- pop cx
- pop di
- inc di
- loop xb1
-
- pop di
- pop es
-
- ret
-
- xblock ENDP
-
- ;****************************************************************************
-
- PUBLIC xvwait
-
- xvwait PROC
-
- mov dx,03DAh
- xvw1:
- in al,dx
- test al,8
- jnz xvw1 ; wait Until out of vertical retrace
- xvw2:
- in al,dx
- test al,8
- jz xvw2 ; wait Until inside vertical retrace
-
- ret
-
- xvwait ENDP
-
- ;****************************************************************************
-
- PUBLIC xhwait
-
- xhwait PROC
-
- mov dx,03DAh
- xhw1:
- in al,dx
- test al,1
- jnz xhw1 ; wait Until out of vertical retrace
- xhw2:
- in al,dx
- test al,1
- jz xhw1 ; wait Until inside vertical retrace
-
- ret
-
- xhwait ENDP
-
- ;******************************************************************************
-
- PUBLIC xsetborder
-
- xsetborder PROC color:byte
-
- push ax
- push dx
- cli
- mov dx,3dah
- in al,dx
- mov dx,3c0h
- mov al,11h+32
- out dx,al
- mov al,color
- out dx,al
- sti
- pop dx
- pop ax
-
- ret
-
- xsetborder ENDP
-
- ;******************************************************************************
-
- PUBLIC xsetborder2
-
- xsetborder2 PROC red:byte, green:byte, blue:byte
-
- push ax
- push dx
- cli
- mov dx,3c8h
- mov al,0
- out dx,al
- mov dx,3c9h
- mov al,red
- out dx,al
- mov al,green
- out dx,al
- mov al,blue
- out dx,al
-
- sti
- pop dx
- pop ax
-
- ret
-
- xsetborder2 ENDP
-
- ;******************************************************************************
-
- PUBLIC xscreenoff
-
- xscreenoff PROC mode:byte
-
-
- mov dx,3dah ; reset flip-flop
- in al,dx
- out_8 attrib_ctrl,0 ; disable screen
-
- out_8 sc_index,1 ; vga sequencer, index 1
- inc dx ; vga sequencer data port
- in al,dx ; get previous settings
- or al,00100000b ; set bit 5 (turn off screen)
- out dx,al ; restore new settings
-
- ret
-
- xscreenoff ENDP
-
- ;******************************************************************************
-
- PUBLIC xscreenon
-
- xscreenon PROC mode:byte
-
- mov dx,3dah ; reset flip-flop
- in al,dx
- out_8 attrib_ctrl,20h ; enable screen
-
- out_8 sc_index,1 ; vga sequencer, index 1
- inc dx ; vga sequencer data port
- in al,dx ; get previous settings
- and al,11011111b ; reset bit 5 (turn on screen)
- out dx,al ; restore new settings
-
- ret
-
- xscreenon ENDP
-
- ;******************************************************************************
-
- PUBLIC xsetpalette
-
- xsetpalette PROC FAR pointer: dword
-
- push ds
- push si
-
- cli
- mov cx,256
- mov ds,word ptr pointer+2
- mov si,word ptr pointer
- mov dx,03c8h
- mov al,0
- out dx,al
- inc dx
- sp1:
- lodsb
- out dx,al
- lodsb
- out dx,al
- lodsb
- out dx,al
- loop sp1
- sti
-
- pop si
- pop ds
-
- ret
-
- xsetpalette ENDP
-
- ;******************************************************************************
-
- PUBLIC xgetpalette
-
- xgetpalette PROC FAR firstreg:word, numregs:word, palette:dword
-
- push es
- push di
-
- mov cx,numregs
- jcxz xgp2
- les di,palette
- cld
-
- mov dx,03C7h
- mov ax,firstreg
- out dx,al
- mov dx,03C9h
-
- xgp1:
- in al,dx
- shl al,2
- stosb ; red
- in al,dx
- shl al,2
- stosb ; green
- in al,dx
- shl al,2
- stosb ; blue
- loop xgp1
-
- xgp2:
- pop di
- pop es
-
- ret
-
- xgetpalette ENDP
-
- ;******************************************************************************
-
- PUBLIC xsetrgb
-
- xsetrgb PROC FAR color:byte, red:byte, green:byte, blue:byte
-
- cli
- mov dx,03c8h
- mov al,color
- out dx,al
- inc dx
-
- mov al,red
- out dx,al
- mov al,green
- out dx,al
- mov al,blue
- out dx,al
- sti
-
- ret
-
- xsetrgb ENDP
-
- ;******************************************************************************
-
- PUBLIC xtextmode
-
- xtextmode PROC FAR mode:byte
-
- mov ax,03h ; set text mode
- int 10h
-
- cmp mode,25 ; 50 lines mode ?
- je no50
-
- mov ax,1112h ; set font height to 8 pixels
- xor bx,bx
- int 10h
- no50:
- ret
-
- xtextmode ENDP
-
- ;******************************************************************************
-
- apage dw ?
-
- ;******************************************************************************
-
- PUBLIC movewin
-
- movewin PROC buffer1:dword, buffer2:dword, vpage:word
-
- push ds
- push si
- push es
- push di
-
- mov ax,0a000h
- mov es,ax
-
- mov bx,vpage ; get page #
- and bx,00000011b ; make sure page # is in range 0->3
- shl bx,1 ; scale bx
- mov ax,pages[bx]
- add ax,9
- mov apage,ax
-
- lds si,buffer1
- lfs bx,buffer2
-
- mov dx,003c4h
- mov ax,0102h
- mw1:
- push ax
- mov di,apage ; get page offset
- out dx,ax
- mov cx,200
- mw0:
- push cx
- mov cx,15
- mw2:
- mov eax,dword ptr ds:[si]
- and eax,dword ptr fs:[bx]
- mov dword ptr es:[di],eax
- add si,4
- add bx,4
- add di,4
- loop mw2
- pop cx
- add di,20
- add si,20
- add bx,20
- loop mw0
- mov ax,ds
- add ax,405
- mov ds,ax
- mov ax,fs
- add ax,405
- mov fs,ax
- pop ax
- shl ah,1
- cmp ah,8
- jbe mw1
-
- pop di
- pop es
- pop si
- pop ds
-
- ret
-
- movewin ENDP
-
-
- END
-