123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836 |
- ;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-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
- ;
- ; $Source: f:/miner/source/2d/rcs/modex.asm $
- ; $Revision: 1.19 $
- ; $Author: john $
- ; $Date: 1995/03/01 15:37:46 $
- ;
- ; Routines to access ModeX VGA memory
- ;
- ; $Log: modex.asm $
- ; Revision 1.19 1995/03/01 15:37:46 john
- ; Better ModeX support.
- ;
- ; Revision 1.18 1994/11/24 13:24:20 john
- ; Made sure that some rep movs had the cld set first.
- ; Took some unused functions out.
- ;
- ; Revision 1.17 1994/09/22 18:15:02 john
- ; Made flip page wait for retrace.
- ;
- ; Revision 1.16 1994/09/22 16:08:27 john
- ; Fixed some palette stuff.
- ;
- ; Revision 1.15 1994/07/13 12:03:05 john
- ; Added assembly modex line-drawer.
- ;
- ; Revision 1.14 1994/05/06 12:50:34 john
- ; Added supertransparency; neatend things up; took out warnings.
- ;
- ; Revision 1.13 1994/05/03 19:39:04 john
- ; *** empty log message ***
- ;
- ; Revision 1.12 1994/02/18 15:32:32 john
- ; *** empty log message ***
- ;
- ; Revision 1.11 1993/12/21 11:40:36 john
- ; *** empty log message ***
- ;
- ; Revision 1.10 1993/12/09 15:02:26 john
- ; Changed palette stuff majorly
- ;
- ; Revision 1.9 1993/12/03 12:11:32 john
- ; fixed cx/ecx loop bugs.
- ;
- ; Revision 1.8 1993/11/16 11:28:18 john
- ; *** empty log message ***
- ;
- ; Revision 1.7 1993/10/15 16:23:23 john
- ; y
- ;
- ; Revision 1.6 1993/09/28 19:07:19 john
- ; stripped the waitforretrace out of fade to speed things up.
- ;
- ; Revision 1.5 1993/09/26 18:58:58 john
- ; fade stuff
- ;
- ; Revision 1.4 1993/09/21 14:01:15 john
- ; turned off video before mode set to reduce flicker.
- ;
- ; Revision 1.3 1993/09/08 11:38:36 john
- ; changed rcs stuff at beginning.
- ;
- ;
- ;
- .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
|