dxx-rebirth/unused/vga/modex.asm
Bradley Bell f05dc678f0 This commit was generated by cvs2svn to compensate for changes in r5,
which included commits to RCS files with non-trunk default branches.
2001-01-19 03:34:09 +00:00

771 lines
14 KiB
NASM

; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
.386
_DATA SEGMENT BYTE PUBLIC USE32 'DATA'
INCLUDE psmacros.inc
INCLUDE TWEAK.INC
INCLUDE VGAREGS.INC
extd _gr_var_bwidth
extd _modex_line_vertincr
extd _modex_line_incr1
extd _modex_line_incr2
_modex_line_routine dd ?
extd _modex_line_x1
extd _modex_line_y1
extd _modex_line_x2
extd _modex_line_y2
extb _modex_line_Color
SavedColor db ?
LEFT_MASK1 = 1000b
LEFT_MASK2 = 1100b
LEFT_MASK3 = 1110b
RIGHT_MASK1 = 0001b
RIGHT_MASK2 = 0011b
RIGHT_MASK3 = 0111b
ALL_MASK = 1111b
tmppal db 768 dup (0)
fb_pal dd ?
fb_add dw ?
fb_count dd ?
MaskTable1 db ALL_MASK AND RIGHT_MASK1,
ALL_MASK AND RIGHT_MASK2,
ALL_MASK AND RIGHT_MASK3,
ALL_MASK,
LEFT_MASK3 AND RIGHT_MASK1,
LEFT_MASK3 AND RIGHT_MASK2,
LEFT_MASK3 AND RIGHT_MASK3,
LEFT_MASK3,
LEFT_MASK2 AND RIGHT_MASK1,
LEFT_MASK2 AND RIGHT_MASK2,
LEFT_MASK2 AND RIGHT_MASK3,
LEFT_MASK2,
LEFT_MASK1 AND RIGHT_MASK1,
LEFT_MASK1 AND RIGHT_MASK2,
LEFT_MASK1 AND RIGHT_MASK3,
LEFT_MASK1,
MaskTable2 db ALL_MASK,RIGHT_MASK1,
ALL_MASK,RIGHT_MASK2,
ALL_MASK,RIGHT_MASK3,
ALL_MASK,ALL_MASK,
LEFT_MASK3,RIGHT_MASK1,
LEFT_MASK3,RIGHT_MASK2,
LEFT_MASK3,RIGHT_MASK3,
LEFT_MASK3,ALL_MASK,
LEFT_MASK2,RIGHT_MASK1,
LEFT_MASK2,RIGHT_MASK2,
LEFT_MASK2,RIGHT_MASK3,
LEFT_MASK2,ALL_MASK,
LEFT_MASK1,RIGHT_MASK1,
LEFT_MASK1,RIGHT_MASK2,
LEFT_MASK1,RIGHT_MASK3,
LEFT_MASK1,ALL_MASK
DrawTable dd DrawMR,
DrawMR,
DrawMR,
DrawM,
DrawLMR,
DrawLMR,
DrawLMR,
DrawLM,
DrawLMR,
DrawLMR,
DrawLMR,
DrawLM,
DrawLMR,
DrawLMR,
DrawLMR,
DrawLM
_DATA ENDS
DGROUP GROUP _DATA
_TEXT SEGMENT BYTE PUBLIC USE32 'CODE'
ASSUME DS:_DATA
ASSUME CS:_TEXT
PUBLIC gr_sync_display_
gr_sync_display_:
push ax
push dx
mov dx, VERT_RESCAN
VS2A: in al, dx
and al, 08h
jnz VS2A ; Loop until not in vertical retrace
VS2B: in al, dx
and al, 08h
jz VS2B ; Loop until in vertical retrace
pop dx
pop ax
ret
PUBLIC gr_modex_uscanline_
gr_modex_uscanline_:
push edi
; EAX = X1 (X1 and X2 don't need to be sorted)
; EDX = X2
; EBX = Y
; ECX = Color
mov SavedColor, cl
;mov ebx, _RowOffset[ebx*4]
mov edi, _gr_var_bwidth
imul edi, ebx
add edi, 0A0000h
cmp eax, edx
jle @f
xchg eax, edx
@@: mov bl, al
shl bl, 2
mov bh, dl
and bh, 011b
or bl, bh
and ebx, 0fh
; BX = LeftRight switch command. (4bit)
shr eax, 2
shr edx, 2
add edi, eax
; EDI = Offset into video memory
mov ecx, edx
sub ecx, eax
; ECX = X2/4 - X1/4 - 1
jnz LargerThan4
;======================= ONE GROUP OF 4 OR LESS TO DRAW ====================
mov dx, SC_INDEX
mov al, SC_MAP_MASK
out dx, al
inc dx
mov al, MaskTable1[ebx]
out dx, al
mov al, SavedColor
mov [edi], al ; Write the one pixel
pop edi
ret
LargerThan4:
dec ecx
jnz LargerThan8
;===================== TWO GROUPS OF 4 OR LESS TO DRAW ====================
mov cx, WORD PTR MaskTable2[ebx*2]
mov bl, SavedColor
mov dx, SC_INDEX
mov al, SC_MAP_MASK
out dx, al
inc dx
mov al, cl
out dx, al
mov [edi], bl ; Write the left pixel
mov al, ch
out dx, al
mov [edi+1], bl ; Write the right pixel
pop edi
ret
;========================= MANY GROUPS OF 4 TO DRAW ======================
LargerThan8:
mov dx, SC_INDEX
mov al, SC_MAP_MASK
out dx, al
inc dx
; DX = SC_INDEX
mov al, SavedColor
mov ah, al
; AL,AH = color of pixel
jmp NEAR32 PTR DrawTable[ebx*4]
DrawM: ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index
mov al, ALL_MASK
out dx, al
mov al, ah
cld
add ecx, 2
shr ecx, 1
rep stosw ; Write the middle pixels
jnc @F
stosb ; Write the middle odd pixel
@@: pop edi
ret
DrawLM:
;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index
mov al, BYTE PTR MaskTable2[ebx*2]
out dx, al
mov [edi], ah ; Write leftmost pixels
inc edi
mov al, ALL_MASK
out dx, al
mov al, ah
cld
inc ecx
shr ecx, 1
rep stosw ; Write the middle pixels
jnc @F
stosb ; Write the middle odd pixel
@@: pop edi
ret
DrawLMR: ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index
mov bx, WORD PTR MaskTable2[ebx*2]
mov al, bl
out dx, al
mov [edi], ah ; Write leftmost pixels
inc edi
mov al, ALL_MASK
out dx, al
mov al, ah
cld
shr ecx, 1
rep stosw ; Write the middle pixels
jnc @F
stosb ; Write the middle odd pixel
@@: mov al, bh
out dx, al
mov [edi], ah ; Write the rightmost pixels
pop edi
ret
DrawMR: ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index
mov bx, WORD PTR MaskTable2[ebx*2]
mov al, ALL_MASK
out dx, al
mov al, ah
cld
inc ecx
shr ecx, 1
rep stosw ; Write the middle pixels
jnc @F
stosb ; Write the middle odd pixel
@@: mov al, bh
out dx, al
mov [edi], ah ; Write the rightmost pixels
pop edi
ret
PUBLIC gr_modex_setmode_
gr_modex_setmode_:
push ebx
push ecx
push edx
push esi
push edi
mov ecx, eax
dec ecx
cmp ecx, LAST_X_MODE
jbe @f
mov ecx, 0
@@:
;call turn_screen_off
push ecx ; some bios's dont preserve cx
;mov ax, 1201h
;mov bl, 31h ; disable palette loading at mode switch
;int 10h
mov ax,13h ; let the BIOS set standard 256-color
int 10h ; mode (320x200 linear)
;mov ax, 1200h
;mov bl, 31h ; enable palette loading at mode switch
;int 10h
pop ecx
mov dx,SC_INDEX
mov ax,0604h
out dx,ax ; disable chain4 mode
mov dx,SC_INDEX
mov ax,0100h
out dx,ax ; synchronous reset while setting Misc
; Output for safety, even though clock
; unchanged
mov esi, dword ptr ModeTable[ecx*4]
lodsb
or al,al
jz DontSetDot
mov dx,MISC_OUTPUT
out dx,al ; select the dot clock and Horiz
; scanning rate
;mov dx,SC_INDEX
;mov al,01h
;out dx,al
;inc dx
;in al, dx
;or al, 1000b
;out dx, al
DontSetDot:
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 write
out dx,al ; protect bit
inc dx ; CRT Controller Data register
in al,dx ; get current VSync End register setting
and al,07fh ; remove write protect on various
out dx,al ; CRTC registers
dec dx ; CRT Controller Index
cld
xor ecx,ecx
lodsb
mov cl,al
SetCRTParmsLoop:
lodsw ; get the next CRT Index/Data pair
out dx,ax ; set the next CRT Index/Data pair
loop SetCRTParmsLoop
mov dx,SC_INDEX
mov ax,0f02h
out dx,ax ; enable writes to all four planes
mov edi, 0A0000h ; point ES:DI to display memory
xor ax,ax ; clear to zero-value pixels
mov ecx,8000h ; # of words in display memory
rep stosw ; clear all of display memory
; Set pysical screen dimensions
xor eax, eax
lodsw ; Load scrn pixel width
mov cx, ax
shl eax, 16
mov dx,CRTC_INDEX
mov al,CRTC_OFFSET
out dx,al
inc dx
mov ax,cx
shr ax,3
out dx,al
;mov si, 360
;@@:
;mov ax, 04f06h
;mov bl, 0
;mov cx, si
;int 10h
;cmp cx, si
;je @f
;inc si
;jmp @B
;@@:
;movzx eax, si
lodsw ; Load Screen Phys. Height
;call turn_screen_on
pop edi
pop esi
pop edx
pop ecx
pop ebx
ret
PUBLIC gr_modex_setplane_
gr_modex_setplane_:
push cx
push dx
mov cl, al
; SELECT WRITE PLANE
and cl,011b ;CL = plane
mov ax,0100h + MAP_MASK ;AL = index in SC of Map Mask reg
shl ah,cl ;set only the bit for the required
; plane to 1
mov dx,SC_INDEX ;set the Map Mask to enable only the
out dx,ax ; pixel's plane
; SELECT READ PLANE
mov ah,cl ;AH = plane
mov al,READ_MAP ;AL = index in GC of the Read Map reg
mov dx,GC_INDEX ;set the Read Map to read the pixel's
out dx,ax ; plane
pop dx
pop cx
ret
PUBLIC gr_modex_setstart_
gr_modex_setstart_:
; EAX = X
; EDX = Y
; EBX = Wait for retrace
push ebx
push ecx
push ebx
mov ecx, _gr_var_bwidth
imul ecx, edx
shr eax, 2
add eax, ecx
mov ch, ah
mov bh, al
mov bl, CC_START_LO
mov cl, CC_START_HI
cli
mov dx, VERT_RESCAN
WaitDE: in al, dx
test al, 01h
jnz WaitDE
mov dx, CRTC_INDEX
mov ax, bx
out dx, ax ; Start address low
mov ax, cx
out dx, ax ; Start address high
sti
pop ebx
cmp ebx, 0
je NoWaitVS
mov dx, VERT_RESCAN
WaitVS: in al, dx
test al, 08h
jz WaitVS ; Loop until in vertical retrace
NoWaitVS:
pop ecx
pop ebx
ret
ModeXAddr macro
; given: ebx=x, eax=y, return cl=plane mask, ebx=address, trash eax
mov cl, bl
and cl, 3
shr ebx, 2
imul eax, _gr_var_bwidth
add ebx, eax
add ebx, 0A0000h
endm
;-----------------------------------------------------------------------
;
; Line drawing function for all MODE X 256 Color resolutions
; Based on code from "PC and PS/2 Video Systems" by Richard Wilton.
PUBLIC gr_modex_line_
gr_modex_line_:
pusha
mov dx,SC_INDEX ; setup for plane mask access
; check for vertical line
mov esi,_gr_var_bwidth
mov ecx,_modex_line_x2
sub ecx,_modex_line_x1
jz VertLine
; force x1 < x2
jns L01
neg ecx
mov ebx,_modex_line_x2
xchg ebx,_modex_line_x1
mov _modex_line_x2,ebx
mov ebx,_modex_line_y2
xchg ebx,_modex_line_y1
mov _modex_line_y2,ebx
; calc dy = abs(y2 - y1)
L01:
mov ebx,_modex_line_y2
sub ebx,_modex_line_y1
jnz short skip
jmp HorizLine
skip: jns L03
neg ebx
neg esi
; select appropriate routine for slope of line
L03:
mov _modex_line_vertincr,esi
mov _modex_line_routine,offset LoSlopeLine
cmp ebx,ecx
jle L04
mov _modex_line_routine,offset HiSlopeLine
xchg ebx,ecx
; calc initial decision variable and increments
L04:
shl ebx,1
mov _modex_line_incr1,ebx
sub ebx,ecx
mov esi,ebx
sub ebx,ecx
mov _modex_line_incr2,ebx
; calc first pixel address
push ecx
mov eax,_modex_line_y1
mov ebx,_modex_line_x1
ModeXAddr
mov edi,ebx
mov al,1
shl al,cl
mov ah,al ; duplicate nybble
shl al,4
add ah,al
mov bl,ah
pop ecx
inc ecx
jmp [_modex_line_routine]
; routine for verticle lines
VertLine:
mov eax,_modex_line_y1
mov ebx,_modex_line_y2
mov ecx,ebx
sub ecx,eax
jge L31
neg ecx
mov eax,ebx
L31:
inc ecx
mov ebx,_modex_line_x1
push ecx
ModeXAddr
mov ah,1
shl ah,cl
mov al,MAP_MASK
out dx,ax
pop ecx
mov ax, word ptr _modex_line_Color
; draw the line
L32:
mov [ebx],al
add ebx,esi
loop L32
jmp Lexit
; routine for horizontal line
HorizLine:
mov eax,_modex_line_y1
mov ebx,_modex_line_x1
ModeXAddr
mov edi,ebx ; set dl = first byte mask
mov dl,00fh
shl dl,cl
mov ecx,_modex_line_x2 ; set dh = last byte mask
and cl,3
mov dh,00eh
shl dh,cl
not dh
; determine byte offset of first and last pixel in line
mov eax,_modex_line_x2
mov ebx,_modex_line_x1
shr eax,2 ; set ax = last byte column
shr ebx,2 ; set bx = first byte column
mov ecx,eax ; cx = ax - bx
sub ecx,ebx
mov eax,edx ; mov end byte masks to ax
mov dx,SC_INDEX ; setup dx for VGA outs
mov bl,_modex_line_Color
; set pixels in leftmost byte of line
or ecx,ecx ; is start and end pt in same byte
jnz L42 ; no !
and ah,al ; combine start and end masks
jmp short L44
L42: push eax
mov ah,al
mov al,MAP_MASK
out dx,ax
mov al,bl
stosb
dec ecx
; draw remainder of the line
L43:
mov ah,0Fh
mov al,MAP_MASK
out dx,ax
mov al,bl
rep stosb
pop eax
; set pixels in rightmost byte of line
L44:
mov al,MAP_MASK
out dx, ax
mov byte ptr [edi],bl
jmp Lexit
; routine for dy >= dx (slope <= 1)
LoSlopeLine:
mov al,MAP_MASK
mov bh,byte ptr _modex_line_Color
L10:
mov ah,bl
L11:
or ah,bl
rol bl,1
jc L14
; bit mask not shifted out
or esi,esi
jns L12
add esi,_modex_line_incr1
loop L11
out dx,ax
mov [edi],bh
jmp short Lexit
L12:
add esi,_modex_line_incr2
out dx,ax
mov [edi],bh
add edi,_modex_line_vertincr
loop L10
jmp short Lexit
; bit mask shifted out
L14: out dx,ax
mov [edi],bh
inc edi
or esi,esi
jns L15
add esi,_modex_line_incr1
loop L10
jmp short Lexit
L15:
add esi,_modex_line_incr2
add edi,_modex_line_vertincr
loop L10
jmp short Lexit
; routine for dy > dx (slope > 1)
HiSlopeLine:
mov ebx,_modex_line_vertincr
mov al,MAP_MASK
L21: out dx,ax
push eax
mov al,_modex_line_Color
mov [edi],al
pop eax
add edi,ebx
L22:
or esi,esi
jns L23
add esi,_modex_line_incr1
loop L21
jmp short Lexit
L23:
add esi,_modex_line_incr2
rol ah,1
adc edi,0
lx21: loop L21
; return to caller
Lexit:
popa
ret
_TEXT ENDS
END