home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QBasic & Borland Pascal & C
/
Delphi5.iso
/
C
/
Samples
/
C-ASM_VI.ARJ
/
PROGASM.ZIP
/
PROG088.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-05-25
|
12KB
|
327 lines
;************************************************************************
; Set Cursor: *
; This procedure will expand the two cursor masks into *
; four planes. The expanded masks will be stored *
; after the last visible scan line at A000:(640/8*350). *
; Entry: AND_Mask - 2x16 bytes with AND mask *
; XOR_Mask - 2x16 bytes with XOR mask *
; BG_Color - Foreground color *
; FG_Color - Background color *
;************************************************************************
YSIZE EQU 350
HBYTES EQU 80
CUR_HEIGHT EQU 16
GRFSEG EQU 0A000H
AND_SAVE EQU (YSIZE*HBYTES+0)
XOR_SAVE EQU (YSIZE*HBYTES+2)
CUR_SAVE EQU (YSIZE*HBYTES+4)
AND_Mask EQU [BP+4]
XOR_Mask EQU [BP+6]
BG_Color EQU [BP+8]
FG_Color EQU [BP+10]
Last_Cursor DW 0
PUBLIC _Set_Cursor
_Set_Cursor PROC NEAR
PUSH BP
MOV BP,SP
PUSH SI
PUSH DI
PUSH ES ; always save seg regs
PUSH DS
MOV AX,GRFSEG ;Point ES to video ram.
MOV ES,AX
;Set EGA to use SET/RESET register to fill with background color
MOV DX,3CEH ; enable use of reset register
MOV AL,1
OUT DX,AL
INC DX
MOV AL,0Fh
OUT DX,AL
DEC DX ; move color into reset register
XOR AL,AL
OUT DX,AL
INC DX
MOV AX,BG_Color
OUT DX,AL
; Fill with background
MOV DI,AND_SAVE ;Pointer to save area (AND and XOR)
MOV CX,CUR_HEIGHT ;Number of scanlines to do
Back_Loop1:
STOSW ;16 bits for AND mask
STOSW ;16 bits for XOR mask
ADD DI,HBYTES-4 ;Point to next scanline
LOOP Back_Loop1
; Change foreground bits for the AND mask save area
MOV AX,FG_Color ;Load SET/RESET with foreground color
OUT DX,AL
DEC DX ;Select BIT MASK register
MOV AL,8
OUT DX,AL
INC DX
MOV CX,CUR_HEIGHT ;Initialize counter
MOV DI,AND_Save ;Get pointer to AND save area
MOV SI,AND_Mask ;Get pointer to AND mask
Fore_Loop1:
LODSB ;Fetch next byte from the mask
OUT DX,AL ;Set BIT MASK REGISTER using cursor mas
MOV AH,ES:[DI] ;Latch data
STOSB ;Write next 8 bits
LODSB ;Fetch next byte from the mask
OUT DX,AL ;Set BIT MASK REGISTER using cursor mas
MOV AH,ES:[DI] ;Latch data
STOSB ;Write next 8 bits
ADD DI,HBYTES-2
LOOP Fore_Loop1
; Change foreground bits for the XOR mask save area
MOV CX,CUR_HEIGHT ;Initialize counter
MOV DI,XOR_Save ;Get pointer to XOR save area
MOV SI,XOR_Mask ;Get pointer to XOR mask
Fore_Loop2:
LODSB ;Fetch next byte from the mask
OUT DX,AL ;Set BIT MASK REGISTER using cursor mas
MOV AH,ES:[DI] ;Latch data
STOSB ;Write next 8 bits
LODSB ;Fetch next byte from the mask
OUT DX,AL ;Set BIT MASK REGISTER using cursor mas
MOV AH,ES:[DI] ;Latch data
STOSB ;Write next 8 bits
ADD DI,HBYTES-2
LOOP Fore_Loop2
;Setup EGA registers for data copy (WRITE LATCH write mode)
MOV DX,3CEH ;Restore graphics controller
MOV AL,1 ;Disable use of SET/RESET
OUT DX,AL
INC DX
XOR AL,AL
OUT DX,AL
DEC DX
MOV AL,8 ;Enable all 8 bits for write
OUT DX,AL
INC DX
MOV AL,0FFH
OUT DX,AL
DEC DX
MOV AL,5 ;Select WRITE LATCH write mode
OUT DX,AL
INC DX
MOV AL,1
OUT DX,AL
;Copy upper left corner into save area (this is needed for first
;call to Move_Cursor procedure, because it always restores and
;we need meaningfull data for the first restore).
MOV SI,0 ;Copy from upper left
MOV CS:Last_Cursor,SI ;Keep where it came from
MOV DI,CUR_SAVE ;Copy to cursor save area
MOV AX,ES ;Point DS to display buffer
MOV DS,AX
MOV CX,CUR_HEIGHT ;Number of lines to copy
Set_Copy_Loop:
MOVSB ;Copy 24 bits from next raster
MOVSB
MOVSB
ADD DI,HBYTES-3 ;Update pointers to next raster
ADD SI,HBYTES-3
LOOP Set_Copy_Loop
;Restore normal write mode
XOR AL,AL ;WRITE MODE register is still selected
OUT DX,AL ;so load it with value 0
;Clean up and return
POP DS ;Restore segment registers
POP ES
POP DI
POP SI
MOV SP,BP
POP BP
RET
_Set_Cursor ENDP
;************************************************************************
; Move_Cursor: *
; This procedure is used to move the cursor from one *
; location to another. *
; Entry: Curs_X - Position of the new cursor *
; Curs_Y *
;************************************************************************
FUNC_AND EQU 1
FUNC_XOR EQU 3
Curs_X EQU [BP+4]
Curs_Y EQU [BP+6]
PUBLIC _Move_Cursor
_Move_Cursor PROC NEAR
PUSH BP
MOV BP,SP
PUSH SI
PUSH DI
PUSH ES ; always save seg regs
PUSH DS
CALL _Remove_Cursor ;Restore last location
;Setup EGA registers for data copy (WRITE LATCH write mode)
MOV DX,3CEH ;Address of GRAPICS controller
MOV AL,5 ;Select WRITE LATCH write mode
OUT DX,AL
INC DX
MOV AL,1
OUT DX,AL
;Copy next location of the cursor to the save area
MOV AX,Curs_Y ;Convert cursor X,Y to offset
MOV BX,HBYTES
MUL BX
MOV SI,Curs_X
SHR SI,1
SHR SI,1
SHR SI,1
ADD SI,AX
MOV CS:Last_Cursor,SI ;Keep location so we can restore later
MOV AX,GRFSEG ;Point ES and DS to display buffer
MOV DS,AX
MOV ES,AX
MOV DI,CUR_SAVE ;Pointer to save area
MOV CX,CUR_HEIGHT ;Number of lines to copy
Move_Copy_Loop:
MOVSB ;Copy 16 bits from next raster
MOVSB
MOVSB
ADD DI,HBYTES-3 ;Update pointers to next raster
ADD SI,HBYTES-3
LOOP Move_Copy_Loop
;Restore normal write mode
MOV DX,3CFH
MOV AL,0 ;WRITE MODE register is still selected
OUT DX,AL ;so load it with value 0
;Use BITBLT procedure to copy AND and XOR masks of the cursor
MOV AX,FUNC_AND ;Push function on the stack
PUSH AX
MOV AX,CUR_HEIGHT ;Push width and height
PUSH AX
PUSH AX
PUSH WORD PTR Curs_Y ;Push x and y of destination
PUSH WORD PTR Curs_X
MOV AX,YSIZE ;Push x and y of source
PUSH AX
MOV AX,0
PUSH AX
CALL _BitBlt
ADD SP,14
MOV AX,FUNC_XOR ;Push function on the stack
PUSH AX
MOV AX,CUR_HEIGHT ;Push width and height
PUSH AX
PUSH AX
PUSH WORD PTR Curs_Y ;Push x and y of destination
PUSH WORD PTR Curs_X
MOV AX,YSIZE ;Push x and y of source
PUSH AX
MOV AX,16
PUSH AX
CALL _BitBlt
ADD SP,14
;Clean up and return
POP DS ;Restore segment registers
POP ES
POP DI
POP SI
MOV SP,BP
POP BP
RET
_Move_Cursor ENDP
;************************************************************************
; Remove_Cursor: *
; This procedure is used to remove the cursor from the screen *
; and to restore the screen to its original appearance *
;************************************************************************
PUBLIC _Remove_Cursor
_Remove_Cursor PROC NEAR
PUSH BP
MOV BP,SP
PUSH SI
PUSH DI
PUSH ES ; always save seg regs
PUSH DS
;Setup EGA registers for data copy (WRITE LATCH write mode)
MOV DX,3CEH ;Address of GRAPICS controller
MOV AL,5 ;Select WRITE LATCH write mode
OUT DX,AL
INC DX
MOV AL,1
OUT DX,AL
;Copy save area back to last location of the cursor
MOV AX,0A000H ;Set up segment pointers
MOV ES,AX
MOV DS,AX
MOV DI,CS:Last_Cursor ;Copy to last X,Y of cursor
MOV SI,CUR_SAVE ;Copy form cursor save area
MOV CX,CUR_HEIGHT ;Number of lines to copy
Rest_Copy_Loop:
MOVSB ;Copy 16 bits from next raster
MOVSB
MOVSB
ADD DI,HBYTES-3 ;Update pointers to next raster
ADD SI,HBYTES-3
LOOP Rest_Copy_Loop
;Restore normal write mode
MOV AL,0 ;WRITE MODE register is still selected
OUT DX,AL ;so load it with value 0
;Clean up and return
POP DS ;Restore segment registers
POP ES
POP DI
POP SI
MOV SP,BP
POP BP
RET
_Remove_Cursor ENDP