home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Supreme Volume 6 #1
/
swsii.zip
/
swsii
/
099
/
TGE101.ZIP
/
320X240.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-02-04
|
15KB
|
885 lines
; 320x240x256 (requires register-compatible VGA+)
; loadable driver for The Graphics Engine
; Copyright (c) 1993 by Matthew Hildebrand
; Turbo Assembler syntax
IDEAL
P286
MODEL LARGE
CODESEG
ORG 0
db 'GRAP'
dw initGraphics ; initGraphics
dw ?
dw deInitGraphics ; deInitGraphics
dw ?
dw 0 ; putImage
dw ?
dw 0 ; putImageInv
dw ?
dw 0 ; getImage
dw ?
dw putLine ; putLine
dw ?
dw getLine ; getLine
dw ?
dw 0 ; imageSize
dw ?
dw putPixel ; putPixel
dw ?
dw getPixel ; getPixel
dw ?
dw 0 ; line
dw ?
dw horizLine ; horizLine
dw ?
dw 0 ; drawRect
dw ?
dw 0 ; filledRect
dw ?
dw setPaletteReg ; setPaletteReg
dw ?
dw getPaletteReg ; getPaletteReg
dw ?
dw setBlockPalette ; setBlockPalette
dw ?
dw getBlockPalette ; getBlockPalette
dw ?
dw clearGraphics ; clearGraphics
dw ?
dw 319
dw 239
dw 255
LABEL output DATAPTR
dw 0
dw 0A000h
db 'The Graphics Engine -- Copyright (c) 1993 by Matthew Hildebrand'
inited db 0
colourPalette db 768 DUP(?)
lineOffs dw 240 DUP(?)
; Plane masks for horizLine
leftEdgeMask db 1111b, 1110b, 1100b, 1000b
rightEdgeMask db 0001b, 0011b, 0111b, 1111b
SC_INDEX EQU 3C4h ; Sequence Controller Index
GC_INDEX EQU 3CEh ; Graphics Controller Index register
CRTC_INDEX EQU 3D4h ; CRT Controller Index
MISC_OUTPUT EQU 3C2h ; Miscellaneous Output register
SCREEN_SEG EQU 0A000h ; segment of display memory in mode X
MAP_MASK EQU 02h ; index in SC of Map Mask register
READ_MAP EQU 4 ; Read Map register index in GC
SCREEN_WIDTH EQU 320 ; width of screen in bytes from one scan line
; to the next
INPUT_STATUS_1 EQU 03DAh ; Input Status 1 register
START_ADDR_HIGH EQU 0Ch ; start address high byte
START_ADDR_LOW EQU 0Dh ; start address low byte
WORD_OUTS_OK EQU 1 ; Set to 0 for VGAs that can't handle
; word OUTs to indexed VGA registers
MACRO GETPALETTE
mov ax,1017h
xor bx,bx
mov cx,256
mov dx,cs
mov es,dx
mov dx,OFFSET colourPalette
int 10h
ENDM
MACRO SETPALETTE
mov ax,1012h
xor bx,bx
mov cx,256
mov dx,cs
mov es,dx
mov dx,OFFSET colourPalette
int 10h
ENDM
MACRO OUT_WORD
if WORD_OUTS_OK
out dx,ax
else
out dx,al
inc dx
xchg ah,al
out dx,al
dec dx
xchg ah,al
endif
ENDM
PUBLIC C initGraphics
PROC C initGraphics
push si di
mov ax,0013h ; set mode 13h
int 10h
mov dx,SC_INDEX
mov ax,0604h
out dx,ax ; disable chain4 mode
mov ax,0100h
out dx,ax ; synchronous reset while setting
; Misc Output for safety, even
; though clock unchanged
mov dx,MISC_OUTPUT
mov al,0E3h
out dx,al ; select 25 MHz dot clock & 60 Hz
; scanning rate
mov dx,SC_INDEX
mov ax,0300h
out dx,ax ; undo reset (restart sequencer)
mov dx,CRTC_INDEX ; reprogram the CRT Controller
mov al,11h ; VSync End reg contains register
out dx,al ; write protect bit
inc dx ; CRT Controller Data register
in al,dx ; get current VSync End register setting
and al,7Fh ; remove write protect on various
out dx,al ; CRTC registers
dec dx ; CRT Controller Index
mov ax,00D06h ; set CRT parameters
out dx,ax
mov ax,03E07h
out dx,ax
mov ax,04109h
out dx,ax
mov ax,0EA10h
out dx,ax
mov ax,0AC11h
out dx,ax
mov ax,0DF12h
out dx,ax
mov ax,00014h
out dx,ax
mov ax,0E715h
out dx,ax
mov ax,00616h
out dx,ax
mov ax,0E317h
out dx,ax
mov dx,SC_INDEX
mov ax,0F02h
out dx,ax ; enable writes to all four planes
mov ax,SCREEN_SEG ; now clear all display memory, 8
mov es,ax ; pixels at a time
xor di,di ; point ES:DI to display memory
xor ax,ax ; clear to zero-value pixels
mov cx,8000h ; # of words in display memory
rep stosw ; clear all of display memory
cmp [inited],0 ; restore palette if necessary
je @@notInited
SETPALETTE
pop di si
mov ax,1
retf
@@notInited:
mov [inited],1
mov si,OFFSET lineOffs
mov cx,240
xor bx,bx
@@LLoop:
mov ax,SCREEN_WIDTH/4
mul bx
mov [cs:si],ax
add si,2
inc bx
loop @@LLoop
pop di si
mov ax,1
retf
ENDP
PUBLIC C deInitGraphics
PROC C deInitGraphics
GETPALETTE
mov ax,0003
int 10h
retf
ENDP
PUBLIC C putLine
PROC C putLine
ARG lineNum:WORD, xOff:WORD, lineLen:WORD, buf:DATAPTR
LOCAL x2:WORD
push ds si di
mov bx,[lineNum] ; start address in ES:DI
shl bx,1
mov di,[lineOffs+bx]
mov dx,[xOff]
shr dx,2
add di,dx
mov ax,SCREEN_SEG
mov es,ax
lds si,[buf] ; source in DS:SI
cld
mov bx,[xOff]
add bx,[lineLen] ; calculate x2
dec bx
mov [x2],bx
mov cx,[lineLen] ; line is short
cmp cx,4
JUMPS
jle @@ShortLine
NOJUMPS
mov cx,[xOff] ; calculate starting plane
mov bx,cx
mov ax,0102h
and cl,3
shl ah,cl
mov dx,SC_INDEX
OUT_WORD
push si
mov bx,[x2]
mov cx,[xOff]
@@Loop1:
cmp cx,bx
jg @@Loop1Done
lodsb
stosb
add cx,4
add si,3
jmp short @@Loop1
@@Loop1Done:
pop si
inc si
push si
mov bx,[xOff]
inc bx
mov cx,bx
mov ax,0102h
and cl,3
shl ah,cl
mov dx,SC_INDEX
OUT_WORD
mov cx,bx
mov bx,[lineNum] ; start address in ES:DI
shl bx,1
mov di,[lineOffs+bx]
shr cx,2
add di,cx
mov bx,[x2]
mov cx,[xOff]
inc cx
@@Loop2:
cmp cx,bx
jg @@Loop2Done
lodsb
stosb
add cx,4
add si,3
jmp short @@Loop2
@@Loop2Done:
pop si
inc si
push si
mov bx,[xOff]
add bx,2
mov cx,bx
mov ax,0102h
and cl,3
shl ah,cl
mov dx,SC_INDEX
OUT_WORD
mov cx,bx
mov bx,[lineNum]
shl bx,1
mov di,[lineOffs+bx]
shr cx,2
add di,cx
mov bx,[x2]
mov cx,[xOff]
add cx,2
@@Loop3:
cmp cx,bx
jg @@Loop3Done
lodsb
stosb
add cx,4
add si,3
jmp short @@Loop3
@@Loop3Done:
pop si
inc si
mov bx,[xOff]
add bx,3
mov cx,bx
mov ax,0102h
and cl,3
shl ah,cl
mov dx,SC_INDEX
OUT_WORD
mov cx,bx
mov bx,[lineNum]
shl bx,1
mov di,[lineOffs+bx]
shr cx,2
add di,cx
mov bx,[x2]
mov cx,[xOff]
add cx,3
@@Loop4:
cmp cx,bx
jg @@Exit
lodsb
stosb
add cx,4
add si,3
jmp short @@Loop4
@@ShortLine:
mov cx,[xOff]
mov bx,cx
and cl,3
mov ax,0102h
shl ah,cl
mov dx,SC_INDEX
OUT_WORD
mov cx,bx
shr bx,2
mov di,bx
mov bx,[lineNum]
shl bx,1
add di,[lineOffs+bx]
movsb
cmp cx,[x2]
jge @@Exit
inc [xOff]
jmp short @@ShortLine
@@Exit:
pop di si ds
leave
retf
ENDP
PUBLIC C getLine
PROC C getLine
ARG lineNum:WORD, xOff:WORD, lineLen:WORD, buf:DATAPTR
LOCAL x2:WORD
push ds si di
mov bx,[lineNum] ; start address in ES:DI
shl bx,1
mov si,[lineOffs+bx]
mov dx,[xOff]
shr dx,2
add si,dx
mov ax,SCREEN_SEG
mov ds,ax
les di,[buf] ; buffer addr in DS:SI
cld
mov bx,[xOff]
add bx,[lineLen] ; calculate x2
dec bx
mov [x2],bx
mov cx,[lineLen] ; line is short
cmp cx,4
JUMPS
jle @@ShortLine
NOJUMPS
mov ax,[xOff] ; calculate starting plane
mov bx,ax
and al,3
mov ah,al
mov al,READ_MAP
mov dx,GC_INDEX
OUT_WORD
push di
mov bx,[x2]
mov cx,[xOff]
@@Loop1:
cmp cx,bx
jg @@Loop1Done
lodsb
stosb
add cx,4
add di,3
jmp short @@Loop1
@@Loop1Done:
pop di
inc di
push di
mov bx,[xOff]
inc bx
mov ax,bx
and al,3
mov ah,al
mov al,READ_MAP
mov dx,GC_INDEX
OUT_WORD
mov cx,bx
mov bx,[lineNum] ; start address in ES:DI
shl bx,1
mov si,[lineOffs+bx]
shr cx,2
add si,cx
mov bx,[x2]
mov cx,[xOff]
inc cx
@@Loop2:
cmp cx,bx
jg @@Loop2Done
lodsb
stosb
add cx,4
add di,3
jmp short @@Loop2
@@Loop2Done:
pop di
inc di
push di
mov bx,[xOff]
add bx,2
mov ax,bx
and al,3
mov ah,al
mov al,READ_MAP
mov dx,GC_INDEX
OUT_WORD
mov cx,bx
mov bx,[lineNum]
shl bx,1
mov si,[lineOffs+bx]
shr cx,2
add si,cx
mov bx,[x2]
mov cx,[xOff]
add cx,2
@@Loop3:
cmp cx,bx
jg @@Loop3Done
lodsb
stosb
add cx,4
add di,3
jmp short @@Loop3
@@Loop3Done:
pop di
inc di
mov bx,[xOff]
add bx,3
mov ax,bx
and al,3
mov ah,al
mov al,READ_MAP
mov dx,GC_INDEX
OUT_WORD
mov cx,bx
mov bx,[lineNum]
shl bx,1
mov si,[lineOffs+bx]
shr cx,2
add si,cx
mov bx,[x2]
mov cx,[xOff]
add cx,3
@@Loop4:
cmp cx,bx
jg @@Exit
lodsb
stosb
add cx,4
add di,3
jmp short @@Loop4
@@ShortLine:
mov ax,[xOff]
mov bx,ax
and al,3
mov ah,al
mov al,READ_MAP
mov dx,GC_INDEX
OUT_WORD
mov cx,bx
shr bx,2
mov si,bx
mov bx,[lineNum]
shl bx,1
add si,[lineOffs+bx]
movsb
cmp cx,[x2]
jge @@Exit
inc [xOff]
jmp short @@ShortLine
@@Exit:
pop di si ds
leave
retf
ENDP
PUBLIC C putPixel
PROC C putPixel
ARG x:WORD, y:WORD, colour:BYTE
push di
mov ax,SCREEN_SEG
mov es,ax
mov bx,[y] ; point to start of desired row
shl bx,1
mov bx,[lineOffs+bx]
mov dx,[x]
mov cx,dx ; store x coord
shr dx,2
add bx,dx
mov di,bx ; ES:DI points to pixel
and cl,3 ; get the plane # of the pixel
mov ax,102h
shl ah,cl ; set the bit corresponding to plane
mov dx,SC_INDEX
OUT_WORD
mov bl,[colour]
mov [es:di],bl
pop di
leave
retf
ENDP
PUBLIC C getPixel
PROC C getPixel
ARG x:WORD, y:WORD
push di
mov ax,SCREEN_SEG
mov es,ax
mov bx,[y] ; point to start of desired row
shl bx,1
mov bx,[lineOffs+bx]
mov dx,[x]
mov cx,dx ; store x coord
shr dx,2
add bx,dx
mov di,bx ; ES:DI points to pixel
and cl,3 ; get the plane # of the pixel
mov al,READ_MAP
mov ah,cl
mov dx,GC_INDEX ; set the bit corresponding to plane
OUT_WORD
xor ax,ax
mov al,[es:di]
pop di
leave
retf
ENDP
PUBLIC C horizLine
PROC C horizLine
ARG y:WORD, x1:WORD, x2:WORD, colour:BYTE
LOCAL adj1:WORD, adj2:WORD
push si di
cld
mov ax,[x1] ; set up adj1
and ax,3
jz @@adj1A
mov bx,4
sub bx,ax
mov ax,[x1]
add ax,bx
mov [adj1],ax
jmp short @@adj1B
@@adj1A:
mov ax,[x1]
mov [adj1],ax
@@adj1B:
mov ax,[x2] ; set up adj2
mov [adj2],ax
and ax,3
sub [adj2],ax
mov ax,[x1] ; ensure x1 <= x2
cmp ax,[x2]
jbe @@setup
mov bx,[x2]
mov [x1],bx
mov [x2],ax
@@setup:
mov ax,SCREEN_SEG ; set ES:DI to line start address
mov es,ax
mov bx,[y]
shl bx,1
mov di,[lineOffs+bx]
mov bx,[x1] ; current x counter
shr bx,2
add di,bx
mov cx,[adj2] ; CX = # of 4-pixel sets starting
shr cx,2 ; on plane 0
mov bx,[adj1]
shr bx,2
sub cx,bx
cmp cx,1
jl @@shortLine
; Draw the left edge
mov ax,[x1] ; get plane number of pixel #1
and ax,3
jz @@planeZeroStart ; starts at plane zero
mov si,ax ; set for pixels
mov ah,[leftEdgeMask+si]
mov al,MAP_MASK
mov dx,SC_INDEX
OUT_WORD
mov al,[colour]
stosb
; Draw the interior stretch
@@planeZeroStart:
mov ax,0F02h ; enable writes to all planes
mov dx,SC_INDEX
OUT_WORD
mov al,[colour]
mov ah,al
shr cx,1
jc @@Odd
rep stosw ; even number of pixels
jmp short @@rightEdge
@@Odd:
rep stosw ; odd number of pixels
stosb
; Draw the right edge
@@rightEdge:
mov ax,[x2] ; get plane number of last pixel
and ax,3
mov si,ax ; set for pixels
mov ah,[rightEdgeMask+si]
mov al,MAP_MASK
mov dx,SC_INDEX
OUT_WORD
mov al,[colour]
stosb
@@Exit:
pop di si ; clean up and go home
leave
retf
@@shortLine: ; for very small lines
mov al,[colour]
mov cx,[x1]
mov dx,[y]
@@Loop:
push ax cx dx ; slow loop until done
call putPixel C, cx, dx, ax
pop dx cx ax
inc cx
cmp cx,[x2]
jle @@Loop
pop di si
leave
retf
ENDP
PUBLIC C setPaletteReg
PROC C setPaletteReg
ARG palNum:WORD,red:BYTE,green:BYTE,blue:BYTE
mov bx,[palNum]
mov dx,3C8h ; set for the right palette register
mov ax,[palNum]
out dx,al
inc dx
mov al,[red] ; red
shr al,2
jnc @@L1
cmp al,63
je @@L1
inc al
@@L1:
out dx,al
mov al,[green] ; green
shr al,2
jnc @@L2
cmp al,63
je @@L2
inc al
@@L2:
out dx,al
mov al,[blue] ; blue
shr al,2
jnc @@L3
cmp al,63
je @@L3
inc al
@@L3:
out dx,al
leave
retf
ENDP
PUBLIC C getPaletteReg
PROC C getPaletteReg
ARG palNum:WORD,red:DATAPTR,green:DATAPTR,blue:DATAPTR
push ds si
mov dx,3C7h ; set for right palette register
mov ax,[palNum]
out dx,al
mov dx,3C9h
in al,dx ; red
lds si,[red]
shl al,2
mov [ds:si],al
in al,dx ; green
lds si,[green]
shl al,2
mov [ds:si],al
in al,dx ; blue
lds si,[blue]
shl al,2
mov [ds:si],al
pop si ds
leave
retf
ENDP
PUBLIC C setBlockPalette
PROC C setBlockPalette
ARG firstReg:WORD,numRegs:WORD,paletteData:DATAPTR
push ds si
lds si,[paletteData]
mov cx,[numRegs]
jcxz @@LExit
cld
mov dx,3C8h ; set for right first pal reg
mov ax,[firstReg]
out dx,al
inc dx
@@LLoop:
lodsb ; red
shr al,2
jnc @@L1
cmp al,63
je @@L1
inc al
@@L1:
out dx,al
lodsb ; green
shr al,2
jnc @@L2
cmp al,63
je @@L2
inc al
@@L2:
out dx,al
lodsb ; blue
shr al,2
jnc @@L3
cmp al,63
je @@L3
inc al
@@L3:
out dx,al
loop @@LLoop
@@LExit:
pop si ds
leave
retf
ENDP
PUBLIC C getBlockPalette
PROC C getBlockPalette
ARG firstReg:WORD,numRegs:WORD,paletteData:DATAPTR
push di
mov cx,[numRegs]
jcxz @@LExit
les di,[paletteData]
cld
mov dx,3C7h ; set for right first pal reg
mov ax,[firstReg]
out dx,al
mov dx,3C9h
@@L1:
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 @@L1
@@LExit:
pop di
leave
retf
ENDP
PUBLIC C clearGraphics
PROC C clearGraphics
ARG colour:BYTE
mov dx,SC_INDEX
mov ax,0F02h
out dx,ax ; enable writes to all four planes
mov ax,SCREEN_SEG
mov es,ax
xor di,di
cld
mov cx,9600
mov al,[colour]
mov ah,al
rep stosw
leave
retf
ENDP
ENDS
END