home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
progm
/
dpl.zip
/
SHADE.D
< prev
next >
Wrap
Text File
|
1988-07-11
|
13KB
|
539 lines
; Doug's Programming Language -- DPL, Version 2.22
; Copyright (c) 1988 Douglas S. Cody, All rights reserved.
;-----------------------------------------
; S H A D E -- Open a shade on the screen
;
; Entry Conditions:
; AX points to the control block
;
; Exit Conditions:
; AL contains the choosen option number
; AH contains the last key typed
; Assume all working registers modified
;
; Screen Control Block:
; DW Starting row
; DW Starting column
; DW Ending column
; DW Number of entries in the table
; DW Video buffer backup buffer
; DW Border display attribute
; DW Box display Attribute
; DW Last option choosen
; DW Shade is opened
; DW 1st string
; :
; DW Xth string
;
SUBPGM SHADE
;
; SHADE CONTROL BLOCK OFFSETS
;
SROW EQU 0 ; STARTING ROW
SCOL EQU 2 ; STARTING COLUMN
ECOL EQU 4 ; ENDING COLUMN
NUMENT EQU 6 ; NUMBER OF ENTRIES IN STRING LIST
VBOFF EQU 8 ; VIDEO BUFFER OFFSET
BDATT EQU 10 ; VIDEO BOARDER ATTRIBUTE
BXATT EQU 12 ; VIDEO BOX ATTRIBUTE
LSTOP EQU 14 ; LAST OPTION CHOOSEN BY OPERATOR
SHDFLG EQU 16 ; SHADE-IS-OPENED FLAG (0FFH=YES,00=NO)
STROFF EQU 18 ; START OF STRING LIST
;
; BOARDER CHARACTERS
;
LTC EQU 218 ; LEFT TOP CORNER
TPL EQU 196 ; TOP LINE
RTC EQU 183 ; RIGHT TOP CORNER
LVB EQU 179 ; LEFT VERTICAL BAR
RVB EQU 186 ; RIGHT VERITCAL BAR
LBC EQU 212 ; LEFT BOTTOM CORNER
BTL EQU 205 ; BOTTOM LINE
RBC EQU 188 ; RIGHT BOTTOM CORNER
;
; KEYBOARD SCAN CODES & MAIN KEY CODES
;
KEY_U EQU 048H ; UPWARD ARROW KEY
KEY_L EQU 04BH ; LEFT ARROW KEY
KEY_R EQU 04DH ; RIGHT ARROW KEY
KEY_D EQU 050H ; DOWNWARD ARROW KEY
KEY_ESC EQU 01BH ; ESCAPE KEY
KEY_SP EQU 020H ; SPACE KEY
KEY_CR EQU 00DH ; CARRIAGE RETURN
;
;-----------------------------====< EXECUTION >====----------------------------
;
BEGIN SHADE
PUBLIC SHADE, OPSHD, CLSHD
EXTRN VIDOFF:NEAR, VIDON:NEAR
;
PUSH DS ; SAVE THE CRITICALS
PUSH ES
PUSH SI
PUSH DI
;
CALL OPSHD ; OPEN THE SHADE ON THE SCREEN
;
PUSH AX
CALL SHDREG
;
PUSH ES ; SWAP SEGMENTS & POINTERS
PUSH DS
POP ES
POP DS
XCHG SI,DI ; ES:DI POINTS TO THE VIDEO BUFFER
;
MOV SI,AX ; SI POINTS TO THE CONTROL BLOCK
ADD DI,2 ; MOVE PAST THE BOARDER
SUB CX,2 ; DO NOT COUNT THE BOARDERS
SUB DX,2 ; DITTO, SO...
ADD BX,4 ; WE MUST ADJUST THE DISTANCE COUNT
PUSH DI ; BP+10 SAVE THE STARTING ADDRESS
PUSH CX ; BP+8 SAVE COLUMN WIDTH
PUSH DX ; BP+6 SAVE LINE COUNT
PUSH BX ; BP+4 SAVE DISTANCE TO NEXT LINE
XOR AX,AX
PUSH AX ; BP+2 SAVE CURRENT LINE #
PUSH BP ; +0
MOV BP,SP
;
SHD_05:
INKEY ,WAIT ; WAIT FOR TO CLOSE
OR AL,AL ; IS IT JUST A SCAN CODE?
JNZ SHD_06 ; NO, USE THE MAIN BYTE
MOV AL,AH ; YES, SO WE WILL CHECK THE SCAN AS WELL
;
SHD_06:
CMP AL,KEY_SP ; SPACE BAR?
JZ SHD_15 ; YES, ADVANCE THE PROMPT BAR
CMP AL,KEY_D ; DOWNWARD ARROW?
JZ SHD_15 ; YES, ADVANCE THE PROMPT BAR
CMP AL,KEY_CR ; CARRIAGE RETURN?
JZ SHD_10 ; NO, GO RE-ENTER THE KEY
CMP AL,KEY_U ; UPWARD ARROW KEY?
JZ SHD_20 ; YES, MOVE THE BAR UPWARD
CMP AL,KEY_ESC ; ESCAPE?
JZ SHD_07 ; YES, EXIT
CMP AL,KEY_L ; LEFT ARROW KEY?
JZ SHD_07 ; YES, EXIT
CMP AL,KEY_R ; RIGHT ARROW KEY?
JNZ SHD_05 ; NO, GO RE-ENTER THE KEY
;
SHD_07:
MOV WORD PTR [BP+2],00 ; FLUSH THE LINE #
;
SHD_10:
MOV CX,[BP+2] ; GET THE LINE SELECTED
POP BP ; RESTORE THE CRITICAL
ADD SP,10 ; TOSS OUT THE VARIABLES ON THE STACK
;
POP BX ; GET THE CONTROL BLOCK
;
PUSH AX ; SAVE THE LAST KEY
MOV [BX+LSTOP],CX ; SAVE IT
MOV AX,BX ; CLOSE THE SHADE NOW
CALL CLSHD
POP AX ; GET THE LAST KEY TYPED
;
POP DI
POP SI
POP ES
POP DS
RETURN
;
SHD_15:
CALL REST_BAR ; REMOVE THE CURRENT BAR
CALL DOWN_BAR ; CREATE THE NEW BAR
JMP SHORT SHD_05 ; & CONTINUE THE SELECTION
;
SHD_20:
CALL REST_BAR ; REMOVE THE CURRENT BAR
CALL UP_BAR ; MOVE THE BAR UPWARD
JMP SHORT SHD_05 ; & CONTINUE WITH THE SELECTION
;
;
;=====================
; ROUTINE SECTION
; LEVEL 1
;=====================
;
;
;----------------------------------------
; C L S H D -- Close the shade
;
; ENTRY CONDITIONS:
; BP POINTS TO THE SCREEN CONTROL BLOCK IN THE STACK SEGMENT
; EXTERNAL DS:CRTFLAG:BYTE
; 0 = MONOCHROME DISPLAY ADAPTER
; 1 = COLOR GRAPHICS ADAPTER
;
; EXIT CONDITIONS:
; ES,DS,BP INDEX REGISTER UNMODIFIED
; ASSUME ALL WORK REGISTERS MODIFIED
;
PUBLIC CLSHD
CLSHD PROC
PUSH SI
PUSH DI
PUSH DS
PUSH ES
PUSH AX
;
; SETUP THE REGISTERS
;
CALL SHDREG
PUSH DS ; SWAP SEGMENTS
PUSH ES
POP DS
POP ES
XCHG SI,DI ; SWAP THE OFFSETS
;
; TURN OFF THE VIDEO
;
CALL VIDOFF
;
CLSHD_05:
PUSH CX ; SAVE THE COLUMN WIDTH
REP MOVSW ; MOVE ONE LINE
ADD DI,BX ; MOVE TO THE NEXT VIDEO RAM LOCATION
POP CX
DEC DX ; HAVE WE MOVED IT ALL?
JNZ CLSHD_05 ; NOT YET...
;
; TURN ON THE VIDEO
;
CALL VIDON
;
; RESTORE & EXIT
;
POP AX
POP ES
POP DS
;
; CLEAR THE OPENED FLAG
;
MOV SI,AX
MOV BYTE PTR [SI+SHDFLG],00 ; CLEAR THE FLAG...
;
POP DI
POP SI
RETURN
CLSHD ENDP
;
;
;----------------------------------------
; O P S H D -- Open the video shade
;
; Entry conditions:
; AX holds the control block offset
;
; Exit conditions:
; ES,DS,BP,SI,DI registers unchanged
; Assume all other registers trashed
;
PUBLIC OPSHD
OPSHD PROC NEAR
PUSH BP ; DO NOT DISTURB THE CRITICALS
PUSH SI
PUSH DI
;
PUSH DS
PUSH ES
;
PUSH AX ; + 16 SAVE THE BLOCK ADDRESS
;
; SETUP THE VIDEO-TO-BUFFER REGISTERS
;
CALL SHDREG ; SETUP THE REGISTERS
;
PUSH ES ; + 14 SAVE THE DATA SEGMENT
PUSH DS ; + 12 SAVE THE VIDEO SEGMENT
PUSH SI ; + 10 SAVE THE VIDEO RAM POINTER
PUSH DI ; + 8 SAVE THE VIDEO BACKUP BUFFER
PUSH BX ; + 6 SAVE THE DISTANCE COUNT
PUSH CX ; + 4 SAVE THE COLUMN COUNT
PUSH DX ; + 2 SAVE THE LINE COUNT
PUSH BP ; + 0 SAVE BP...
MOV BP,SP
;
; TURN OFF THE VIDEO
;
CALL VIDOFF ; NO REGISTERS ARE DISTURBED
;
OPSHD_05:
REP MOVSW ; MOVE THE ENTIRE LINE TO THE BUFFER
MOV CX,[BP+4] ; GET THE COLUMN COUNT
ADD SI,BX ; MOVE TO THE NEXT VIDEO POSITION
DEC DX ; ARE WE DONE?
JNZ OPSHD_05 ; NO, CONTINUE THE BLOCK MOVE
;
MOV DI,[BP+10] ; POINT TO THE VIDEO BUFFER
MOV ES,[BP+12] ; & VIDEO SEGMENT
MOV DS,[BP+14] ; RESTORE THE DATA SEGMENT
MOV BX,[BP+16] ; GET THE CONTROL BLOCK ADDRESS
;
MOV DH,[BX+BDATT] ; FETCH THE BOARDER ATTRIBUTE (& CHEAT)
MOV AH,DH ; DH WILL HOLD THE BOARDER ATTRIBUTE
MOV AL,LTC ; LEFT TOP CORNER
STOSW ; SAVE IT IN RAM
SUB WORD PTR [BP+4],2 ; WE DON'T NEED THE BOARDER COUNT
MOV CX,[BP+4] ; GET THE COLUMN WIDTH
JCXZ OPSHD_10
MOV AL,TPL
REP STOSW ; GIVE THE ENTIRE LINE
;
OPSHD_10:
MOV AL,RTC
STOSW ; STORE RIGHT TOP CORNER
;
SUB WORD PTR [BP+2],2 ; WE DON'T NEED TO KNOW ABOUT THE BOARDER
MOV DL,[BX+BXATT] ; DL HOLDS THE BOX ATTRIBUTE (& CHEAT)
ADD BX,STROFF ; POINT TO THE STRING LIST
;
CMP WORD PTR [BP+2],00 ; ANY LINES FOR THE BOX?
JZ OPSHD_32 ; NO, GO CLOSE THE BOX
;
OPSHD_15:
ADD DI,[BP+6] ; MOVE TO THE NEXT LINE
MOV AH,DH ; FETCH THE BOARDER ATTRIBUTE
MOV AL,LVB
STOSW ; PLACE THE VERTICAL BAR
MOV SI,[BX] ; GET THE NEXT LINE ADDRESS
ADD BX,2 ; ADVANCE THE BLOCK POINTER
MOV AH,DL ; GET THE BOX ATTRIBUTE
MOV CX,[BP+4] ; FETCH THE COLUMN WIDTH
JCXZ OPSHD_30 ; DON'T DO NULL WIDTH
TEST BYTE PTR [SI],80H ; IS IT 8 BIT ASCII?
JZ OPSHD_20 ; NO, SKIP IT
LODSB ; FETCH THE CHARACTER AS THE ATTRIBUTE
MOV AH,7FH ; TRIM THE 8TH BIT
AND AH,AL
;
OPSHD_20:
LODSB ; FETCH THE NEXT CHARACTER
OR AL,AL ; END OF STRING?
JZ OPSHD_25 ; YES, CONTINUE ON...
STOSW ; NO, SAVE THE CHAR & ATTR
LOOP OPSHD_20 ; DO UNTIL STRING IS DONE
JMP SHORT OPSHD_30 ; GO DO THE NEXT STRING
;
OPSHD_25:
REP STOSW ; DO THE REST OF THE STRING
;
OPSHD_30:
MOV AH,DH ; FETCH THE BOARDER ATTRIBUTE
MOV AL,RVB ; RIGHT VERTICAL BAR
STOSW ; PLACE THE VERTICAL BAR
;
DEC WORD PTR [BP+2] ; DECREMENT THE LINE COUNT
JNZ OPSHD_15 ; DO THE REST OF THE STRINGS
;
OPSHD_32:
ADD DI,[BP+6] ; MOVE TO THE LAST LINE
MOV AH,DH ; FETCH THE BOARDER ATTRIBUTE
MOV AL,LBC ; LEFT BOTTOM CORNER
STOSW ; SAVE IT IN RAM
MOV CX,[BP+4] ; GET THE COLUMN WIDTH
JCXZ OPSHD_35
MOV AL,BTL ; BOTTOM LINE
REP STOSW ; GIVE THE ENTIRE LINE
;
OPSHD_35:
MOV AL,RBC ; RIGHT BOTTOM CORNER
STOSW ; WRITE THE LAST CHARACTER
;
; TURN ON THE VIDEO
;
CALL VIDON
;
; RETURN TO CALLING PROGRAM
;
ADD SP,16 ; DEFRAME THE STACK
POP AX ; SAVE THE CONTROL BLOCK POINTER
POP ES
POP DS
;
; SET THE OPENED FLAG
;
MOV SI,AX
MOV BYTE PTR [SI+SHDFLG],0FFH ; SET THE FLAG...
;
POP DI
POP SI
POP BP
RET
OPSHD ENDP
;
;
;----------------------------------------
; DOWN_BAR -- MOVE THE OPTION BAR DOWNWARD
;
DOWN_BAR PROC NEAR
INC WORD PTR [BP+2] ; INCREMENT THE CURRENT LINE #
MOV AX,[BP+2] ; GET THE CURRENT LINE
MOV CX,[BP+8] ; GET THE COLUMN COUNT
ADD DI,CX ; MOVE TO THE END OF THE LINE
ADD DI,CX ; (ACCOUNT FOR ATTRIBUTES)
ADD DI,[BP+4] ; MOVE TO THE NEXT LINE DOWN
CMP AX,[BP+6] ; ARE WE AT THE END?
JLE DNBR_05 ; NO, CONTINUE ON...
MOV WORD PTR [BP+2],00 ; YES, CLEAR OUT THE CURRENT LINE
MOV DI,[BP+10] ; AND POINT TO THE START...
RETURN
;
DNBR_05:
CMP BYTE PTR ES:[DI],00 ; IS THE 1ST CHARACTER A NULL?
JZ DOWN_BAR ; YES, SKIP THIS LINE...
MOV AL,[SI+BXATT] ; GET THE BOX ATTRIBUTE
CMP ES:[DI+1],AL ; IS THE ATTRIBUTE THE SAME?
JNZ DOWN_BAR ; NO, SKIP THIS LINE
PUSH DI ; DO NOT DISTURB THE STARTING ADDR
;
DNBR_10:
INC DI ; MOVE PAST THE CHARACTER
XOR BYTE PTR ES:[DI],0FFH ; REVERSE THE ATTRIBUTE
INC DI
LOOP DNBR_10 ; CONTINUE TILL DONE...
POP DI
RETURN
DOWN_BAR ENDP
;
;
;---------------------------------------
; R E S T _ B A R -- RESTORE THE BAR ON THE SCREEN
;
;
REST_BAR PROC NEAR
MOV AX,[BP+2] ; GET THE CURRENT LINE #
OR AX,AX ; IS IT THE NULL LINE?
JZ RSTBR_10 ; YES, EXIT
PUSH DI ; SAVE THE CURRENT RAM PTR
MOV CX,[BP+8] ; GET THE COLUMN COUNT
;
RSTBR_05:
INC DI ; MOVE PAST THE CHARACTER
XOR BYTE PTR ES:[DI],0FFH ; RESTORE THE ATTRIBUTE
INC DI ; MOVE PAST THE ATTRIBUTE
LOOP RSTBR_05 ; DO THE WHOLE LINE
POP DI
;
RSTBR_10:
RETURN
REST_BAR ENDP
;
;
;----------------------------------------
; UP_BAR -- MOVE THE OPTION BAR UPWARD
;
UP_BAR PROC NEAR
CMP WORD PTR [BP+2],00 ; ARE WE AT THE TOP?
JNZ UPBR_05 ; NO, CONTINUE ON...
MOV AX,[BP+6] ; YES, MOVE TO THE BOTTOM
INC AX
MOV [BP+2],AX
;
; CALCULATE THE BOTTOM ROW
;
MOV CX,AX
;
UPBR_02:
ADD DI,[BP+4] ; MOVES TO THE NEXT LINE
ADD DI,[BP+8] ; ADD IN THE BOX WIDTH
ADD DI,[BP+8]
LOOP UPBR_02
;
UPBR_05:
SUB DI,[BP+4] ; MOVE BACK TO THE PREVIOUS LINE
SUB DI,[BP+8]
SUB DI,[BP+8]
DEC WORD PTR [BP+2] ; DECREMENT THE CURRENT LINE #
JZ UPBR_15 ; EXIT IF AT 0
MOV CX,[BP+8] ; GET THE COLUMN COUNT
CMP BYTE PTR ES:[DI],00 ; IS THE 1ST CHARACTER A NULL?
JZ UP_BAR ; YES, SKIP THIS LINE...
MOV AL,[SI+BXATT] ; GET THE BOX ATTRIBUTE
CMP ES:[DI+1],AL ; IS THE ATTRIBUTE THE SAME?
JNZ UP_BAR ; NO, SKIP THIS LINE
PUSH DI ; DO NOT DISTURB THE STARTING ADDR
;
UPBR_10:
INC DI ; MOVE PAST THE CHARACTER
XOR BYTE PTR ES:[DI],0FFH ; REVERSE THE ATTRIBUTE
INC DI
LOOP UPBR_10 ; CONTINUE TILL DONE...
POP DI
;
UPBR_15:
RETURN
UP_BAR ENDP
;
;
;=====================
; ROUTINE SECTION
; LEVEL 2
;=====================
;
;
; S H D R E G -- SETUP THE PROPER REGISTERS
;
; Entry conditions:
; DS:AX holds the video control block
; Exit conditions:
; ES points to data segment
; DS points to video segment
; SI points to start of video buffer
; DI points to the buffer
; CX holds the length
; DX holds the # of lines to move
; BX holds the count of (80-cx)*2
; AX holds the video control block address
;
PUBLIC SHDREG
SHDREG PROC NEAR
PUSH AX
MOV AH,0FH
INT 10H ; GET THE VIDEO PAGE
MOV CX,0B000H ; MONO SEGMENT
TEST [CRTFLAG],01 ; MONO CARD?
JZ VBSU_05 ; YES, CONTINUE ON...
MOV CX,0B800H ; NO, SETUP FOR CGA
;
VBSU_05:
XCHG BH,BL
SUB BH,BH ; BX HOLDS THE PAGE #
MOV AX,1000H ; AX HOLDS THE FULL PAGE SIZE
MUL BX ; AX HOLDS THE PAGE STARTING ADDR
MOV SI,AX
POP BX ; GET THE CONTROL BLOCK ADDRESS
MOV AX,[BX+SROW]
MOV DX,80*2
MUL DX ; AX = ROW * 80*2
ADD SI,AX
ADD SI,[BX+SCOL] ; ADD IN THE COLUMNS
ADD SI,[BX+SCOL] ; ..TWICE FOR DOUBLE BYTE STORAGE
MOV DX,[BX+NUMENT] ; GET THE NUMBER OF LINE OF TEXT
ADD DX,2 ; ADJUST FOR BOX
MOV DI,[BX+VBOFF] ; GET THE BUFFER ADDRESS
PUSH DS
POP ES ; ES = DATA SEGMENT
MOV DS,CX ; DS = VIDEO SEGMENT
MOV CX,ES:[BX+ECOL] ; CALC THE NUMBER OF COLUMNS
SUB CX,ES:[BX+SCOL]
INC CX ; CX HOLDS THE TOTAL COLUMNS
MOV AX,BX ; MAKE SURE AX HOLDS THE BLOCK ADDRESS
MOV BX,80 ; CALC THE DISTANCE TO THE START OF
SUB BX,CX ; THE NEXT LINE
SHL BX,1 ; BX = BX * 2
RETURN
SHDREG ENDP
;
ENDPGM SHADE
;