home *** CD-ROM | disk | FTP | other *** search
-
- ; FASTWR.ASM
- ; Fast screen writing routines
- ; By Brian Foley
- ; Last update: 11/08/87
-
-
- ;****************************************************** Equates
-
- Mono = 0
- CGA = 1
- EGA = 2
- MCGA = 3
- VGA = 4
-
- ;****************************************************** Data
-
- DATA SEGMENT BYTE PUBLIC
-
- EXTRN BaseOfScreen : WORD ;Pascal variables
- EXTRN WaitForRetrace : BYTE
-
- CurrentMode DB ? ;local variables
- Display DB ?
-
- DATA ENDS
-
- ;****************************************************** Code
-
- CODE SEGMENT BYTE PUBLIC
-
- ASSUME CS:CODE,DS:DATA
-
- PUBLIC FastWrite, FastWriteNA, ChangeAttribute, MoveFromScreen
- PUBLIC MoveToScreen, CurrentDisplay, CurrentVideoMode
-
- ;****************************************************** CalcOffset
-
- ;Calculates offset in video memory corresponding to Row,Column
- ;On entry, CH has Row, BX has Column (both 1-based)
- ;On exit, ES:DI points to proper address in video memory, AX = 0
-
- CalcOffset PROC NEAR
-
- XOR AX,AX ;AX = 0
- MOV CL,AL ;CL = 0
- MOV BH,AL ;BH = 0
- DEC CH ;Row (in CH) to 0..24 range
- SHR CX,1 ;CX = Row * 128
- MOV DI,CX ;Store in DI
- SHR DI,1 ;DI = Row * 64
- SHR DI,1 ;DI = Row * 32
- ADD DI,CX ;DI = (Row * 160)
- DEC BX ;Col (in BX) to 0..79 range
- SHL BX,1 ;Account for attribute bytes
- ADD DI,BX ;DI = (Row * 160) + (Col * 2)
- MOV ES,BaseOfScreen ;ES:DI points to BaseOfScreen:Row,Col
- RET ;Return
-
- CalcOffset ENDP
-
- ;****************************************************** FastWrite
-
- ;procedure FastWrite(St : String; Row, Col, Attr : Byte);
- ;Write St at Row,Col in Attr (video attribute) without snow
-
- ;equates for parameters:
- FWAttr EQU BYTE PTR [BP+6]
- FWCol EQU BYTE PTR [BP+8]
- FWRow EQU BYTE PTR [BP+10]
- FWSt EQU DWORD PTR [BP+12]
-
- FastWrite PROC FAR
-
- PUSH BP ;Save BP
- MOV BP,SP ;Set up stack frame
- PUSH DS ;Save DS
- MOV CH,FWRow ;CH = Row
- MOV BL,FWCol ;BL = Column
- CALL CalcOffset ;Call routine to calculate offset
- MOV CL,WaitForRetrace ;Grab this before changing DS
- LDS SI,FWSt ;DS:SI points to St[0]
- CLD ;Set direction to forward
- LODSB ;AX = Length(St); DS:SI -> St[1]
- XCHG AX,CX ;CX = Length; AL = WaitForRetrace
- JCXZ FWExit ;If string empty, exit
- MOV AH,FWAttr ;AH = Attribute
- RCR AL,1 ;If WaitForRetrace is False...
- JNC FWMono ; use "FWMono" routine
- MOV DX,03DAh ;Point DX to CGA status port
- FWGetNext:
- LODSB ;Load next character into AL
- ; AH already has Attr
- MOV BX,AX ;Store video word in BX
- CLI ;No interrupts now
- FWWaitNoH:
- IN AL,DX ;Get 6845 status
- TEST AL,8 ;Vertical retrace in progress?
- JNZ FWStore ;If so, go
- RCR AL,1 ;Else, wait for end of
- JC FWWaitNoH ; horizontal retrace
- FWWaitH:
- IN AL,DX ;Get 6845 status again
- RCR AL,1 ;Wait for horizontal
- JNC FWWaitH ; retrace
- FWStore:
- MOV AX,BX ;Move word back to AX...
- STOSW ; and then to screen
- STI ;Allow interrupts!
- LOOP FWGetNext ;Get next character
- JMP FWExit ;Done
- FWMono:
- LODSB ;Load next character into AL
- ; AH already has Attr
- STOSW ;Move video word into place
- LOOP FWMono ;Get next character
- FWExit:
- POP DS ;Restore DS
- MOV SP,BP ;Restore SP
- POP BP ;Restore BP
- RET 10 ;Remove parameters and return
-
- FastWrite ENDP
-
- ;****************************************************** FastWriteNA
-
- ;procedure FastWriteNA(St : String; Row, Col : Byte);
- ;Write St at Row,Col without snow, and don't change video attributes
-
- ;equates for parameters:
- FNCol EQU BYTE PTR [BP+6]
- FNRow EQU BYTE PTR [BP+8]
- FNSt EQU DWORD PTR [BP+10]
-
- FastWriteNA PROC FAR
-
- PUSH BP ;Save BP
- MOV BP,SP ;Set up stack frame
- PUSH DS ;Save DS
- MOV CH,FNRow ;CH = Row
- MOV BL,FNCol ;BL = Column
- CALL CalcOffset ;Call routine to calculate offset
- MOV CL,WaitForRetrace ;Grab this before changing DS
- LDS SI,FNSt ;DS:SI points to St[0]
- CLD ;Set direction to forward
- LODSB ;AX = Length(St); DS:SI -> St[1]
- XCHG AX,CX ;CX = Length; AL = Wait
- JCXZ FNExit ;If string empty, exit
- RCR AL,1 ;If WaitForRetrace is False...
- JNC FNNoWait ; use FNNoWait routine
- MOV DX,03DAh ;Point DX to CGA status port
- FNGetNext:
- LODSB ;Load next character into AL
- MOV AH,AL ;Store char in AH
- CLI ;No interrupts now
- FNWaitNoH:
- IN AL,DX ;Get 6845 status
- TEST AL,8 ;Check for vertical retrace
- JNZ FNStore ; In progress? go
- RCR AL,1 ;Else, wait for end of
- JC FNWaitNoH ; horizontal retrace
- FNWaitH:
- IN AL,DX ;Get 6845 status again
- RCR AL,1 ;Wait for horizontal
- JNC FNWaitH ; retrace
- FNStore:
- MOV AL,AH ;Move char back to AL...
- STOSB ; and then to screen
- STI ;Allow interrupts
- INC DI ;Skip attribute bytes
- LOOP FNGetNext ;Get next character
- JMP FNExit ;Done
- FNNoWait:
- MOVSB ;Move character to screen
- INC DI ;Skip attribute bytes
- LOOP FNNoWait ;Get next character
- FNExit:
- POP DS ;Restore DS
- MOV SP,BP ;Restore SP
- POP BP ;Restore BP
- RET 8 ;Remove parameters and return
-
- FastWriteNA ENDP
-
- ;****************************************************** ChangeAttribute
-
- ;procedure ChangeAttribute(Number : Word; Row, Col, Attr : Byte);
- ;Change Number video attributes to Attr starting at Row,Col
-
- ;equates for parameters:
- CAAttr EQU BYTE PTR [BP+6]
- CACol EQU BYTE PTR [BP+8]
- CARow EQU BYTE PTR [BP+10]
- CANumber EQU WORD PTR [BP+12]
-
- ChangeAttribute PROC FAR
-
- PUSH BP ;Save BP
- MOV BP,SP ;Set up stack frame
- MOV CH,CARow ;CH = Row
- MOV BL,CACol ;BL = Column
- CALL CalcOffset ;Call routine to calculate offset
- INC DI ;Skip character
- CLD ;Set direction to forward
- MOV CX,CANumber ;CX = Number to change
- JCXZ CAExit ;If zero, exit
- MOV AL,CAAttr ;AL = Attribute
- CMP WaitForRetrace,1 ;Get wait state
- JNE CANoWait ;If WaitForRetrace is False
- ; use CANoWait routine
- MOV AH,AL ;Store attribute in AH
- MOV DX,03DAh ;Point DX to CGA status port
- CAGetNext:
- CLI ;No interrupts now
- CAWaitNoH:
- IN AL,DX ;Get 6845 status
- TEST AL,8 ;Check for vert. retrace
- JNZ CAGo ;In progress? Go
- RCR AL,1 ;Wait for end of horizontal
- JC CAWaitNoH ; retrace
- CAWaitH:
- IN AL,DX ;Get 6845 status again
- RCR AL,1 ;Wait for horizontal
- JNC CAWaitH ; retrace
- CAGo:
- MOV AL,AH ;Move Attr back to AL...
- STOSB ; and then to screen
- STI ;Allow interrupts
- INC DI ;Skip characters
- LOOP CAGetNext ;Look for next opportunity
- JMP CAExit ;Done
- CANoWait:
- STOSB ;Change the attribute
- INC DI ;Skip characters
- LOOP CANoWait ;Get next character
- CAExit: ;Next instruction
- MOV SP,BP ;Restore SP
- POP BP ;Restore BP
- RET 8 ;Remove parameters and return
-
- ChangeAttribute ENDP
-
- ;****************************************************** MoveFromScreen
-
- ;procedure MoveFromScreen(var Source, Dest; Length : Word);
- ;Move Length words from Source (video memory) to Dest without snow
-
- ;equates for parameters:
- MFLength EQU WORD PTR [BP+6]
- MFDest EQU DWORD PTR [BP+8]
- MFSource EQU DWORD PTR [BP+12]
-
- MoveFromScreen PROC FAR
-
- PUSH BP ;Save BP
- MOV BP,SP ;Set up stack frame
- MOV BX,DS ;Save DS in BX
- MOV AL,WaitForRetrace ;Grab before changing DS
- LES DI,MFDest ;ES:DI points to Dest
- LDS SI,MFSource ;DS:SI points to Source
- MOV CX,MFLength ;CX = Length
- CLD ;Set direction to forward
- RCR AL,1 ;Check WaitForRetrace
- JNC MFNoWait ;False? Use MFNoWait routine
- MOV DX,03DAh ;Point DX to CGA status port
- MFNext:
- CLI ;No interrupts now
- MFWaitNoH:
- IN AL,DX ;Get 6845 status
- TEST AL,8 ;Check for vertical retrace
- JNZ MFGo ;In progress? go
- RCR AL,1 ;Wait for end of horizontal
- JC MFWaitNoH ; retrace
- MFWaitH:
- IN AL,DX ;Get 6845 status again
- RCR AL,1 ;Wait for horizontal
- JNC MFWaitH ; retrace
- MFGo:
- LODSW ;Load next video word into AX
- STI ;Allow interrupts
- STOSW ;Store video word in Dest
- LOOP MFNext ;Get next video word
- JMP MFExit ;All Done
- MFNoWait:
- REP MOVSW ;That's it!
- MFExit:
- MOV DS,BX ;Restore DS
- MOV SP,BP ;Restore SP
- POP BP ;Restore BP
- RET 10 ;Remove parameters and return
-
- MoveFromScreen ENDP
-
- ;****************************************************** MoveToScreen
-
- ;procedure MoveToScreen(var Source, Dest; Length : Word);
- ;Move Length words from Source to Dest (video memory) without snow
-
- ;equates for parameters:
- MTLength EQU WORD PTR [BP+6]
- MTDest EQU DWORD PTR [BP+8]
- MTSource EQU DWORD PTR [BP+12]
-
- MoveToScreen PROC FAR
-
- PUSH BP ;Save BP
- MOV BP,SP ;Set up stack frame
- PUSH DS ;Save DS
- MOV AL,WaitForRetrace ;Grab before changing DS
- LES DI,MTDest ;ES:DI points to Dest
- LDS SI,MTSource ;DS:SI points to Source
- MOV CX,MTLength ;CX = Length
- CLD ;Set direction to forward
- RCR AL,1 ;Check WaitForRetrace
- JNC MTNoWait ;False? Use MTNoWait routine
- MOV DX,03DAh ;Point DX to CGA status port
- MTGetNext:
- LODSW ;Load next video word into AX
- MOV BX,AX ;Store video word in BX
- CLI ;No interrupts now
- MTWaitNoH:
- IN AL,DX ;Get 6845 status
- TEST AL,8 ;Check for vertical retrace
- JNZ MTGo ;In progress? Go
- RCR AL,1 ;Wait for end of horizontal
- JC MTWaitNoH ; retrace
- MTWaitH:
- IN AL,DX ;Get 6845 status again
- RCR AL,1 ;Wait for horizontal
- JNC MTWaitH ; retrace
- MTGo:
- MOV AX,BX ;Move word back to AX...
- STOSW ; and then to screen
- STI ;Allow interrupts
- LOOP MTGetNext ;Get next video word
- JMP MTExit ;All done
- MTNoWait:
- REP MOVSW ;That's all!
- MTExit:
- POP DS ;Restore DS
- MOV SP,BP ;Restore SP
- POP BP ;Restore BP
- RET 10 ;Remove parameters and return
-
- MoveToScreen ENDP
-
- ;****************************************************** CurrentModePrim
-
- ;Returns current video mode in AL
-
- CurrentModePrim PROC NEAR
-
- MOV AH,0Fh ;Get video mode function
- INT 10h ;Call BIOS
- MOV CurrentMode,AL ;Save it
- RET ;Return
-
- CurrentModePrim ENDP
-
- ;****************************************************** CurrentDisplay
-
- ;function CurrentDisplay : DisplayType;
- ;Returns type of the currently active display.
-
- JunkValue = 0FFFFh
-
- CurrentDisplay PROC FAR
-
- ;get the current video mode
- CALL CurrentModePrim ;Call primitive routine
-
- ;test for VGA
- MOV Display,VGA ;Assume VGA
- MOV CX,JunkValue ;Load CX with junk value
- MOV AX,1C00h ;Save/Restore video state
- INT 10h
- CMP AL,1Ch ;AL = $1C signals valid call
- JE CDexit ;Adapter type known
-
- ;test for MCGA
- MOV Display,MCGA ;Assume MCGA
- MOV BL,32h ;Choose Enable
- MOV AX,1200h ;Enable/Disable video addressing
- INT 10h
- CMP AL,12h ;AL = $12 signals valid call
- JE CDexit ;Adapter type known
-
- ;test for EGA
- MOV Display,EGA ;Assume EGA
- MOV BX,0FF10h ;Return EGA information
- MOV CX,JunkValue ;Load CX with junk value
- MOV AX,1200h ;Alternate function select
- INT 10h
- XOR AL,AL ;AL = 0
- CMP CX,JunkValue ;CX unchanged?
- JE CDplain ;If so, not an EGA
- CMP BH,1 ;BH should be 0 or 1
- JA CDplain ;Mono or CGA if it isn't
-
- ;See if EGA is the active display
- CMP BH,1 ;mono display?
- JE CDegaMono ;If so, use mono check
- CMP CurrentMode,7 ;In mono mode?
- JE CDplain ;If so, we're not on the EGA
- JMP SHORT CDexit ;else, it's an EGA
-
- CDegaMono:
- CMP CurrentMode,7 ;Current mode = 7?
- JNE CDplain ;Exit if not
-
- CDexit:
- MOV AL,Display ;set return value
- RET ;Return
-
- CDplain:
- MOV Display,CGA ;Assume CGA
- CMP CurrentMode,7 ;Mono mode
- JNE CDexit ;Done if not
- MOV Display,Mono ;Else, Mono
- JMP SHORT CDexit ;Done
-
- CurrentDisplay ENDP
-
- ;****************************************************** CurrentVideoMode
-
- ;function CurrentVideoMode : Byte;
- ;Returns current video mode in AL
-
- CurrentVideoMode PROC FAR
-
- CALL CurrentModePrim ;Call primitive routine
- RET ;Return
-
- CurrentVideoMode ENDP
-
- CODE ENDS
-
- END