home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
turbodsg
/
menu.a
< prev
next >
Wrap
Text File
|
1994-07-13
|
10KB
|
430 lines
#TITLE "TURBODOS 1.4X MENU UTILITY"
#PAGE 132,66
MODULE "TDMENU"
;
; +----------------------------------+
; | MENU UTILITY FOR 16-BIT TURBODOS |
; +----------------------------------+
;
CFUNC == 0XE0 ; C-FUNCTION INTERRUPT
TFUNC == 0XDF ; T-FUNCTION INTERRUPT
;
LOC Data#
;
; +-----------------------+
; | TERMINAL CONFIG BLOCK |
; +-----------------------+
;
ESC == 0X1B
;
CCURUP:: BYTE 2,ESC,'A',0,0,0,0 ; CURSOR UP
CCURDN:: BYTE 2,ESC,'B',0,0,0,0 ; CURSOR DOWN
CCURLF:: BYTE 2,ESC,'D',0,0,0,0 ; CURSOR LEFT
CCURRT:: BYTE 2,ESC,'C',0,0,0,0 ; CURSOR RIGHT
CHOMEC:: BYTE 2,ESC,'H',0,0,0,0 ; HOME CURSOR
CURAD1:: BYTE 2,ESC,'F',0,0,0,0 ; CURSOR ADDRESSING STRING 1
CURAD2:: BYTE 0XFF ; FF=R/C, 00=C/R
CURAD3:: BYTE 0XFF ; FF=BINARY, 00=ASCII
CURAD4:: BYTE ' ' ; BINARY OFFSET
CDISON:: BYTE 3,ESC,"-1",0,0,0 ; CURSOR DISPLAY ON
CDISOF:: BYTE 3,ESC,"-0",0,0,0 ; CURSOR DISPLAY OFF
CLEOLN:: BYTE 2,ESC,'K',0,0,0,0 ; CLEAR TO END OF LINE
CLRSCR:: BYTE 2,ESC,'E',0,0,0,0 ; CLEAR SCREEN AND HOME
CINHIL:: BYTE 3,ESC,"dA",0,0,0 ; INTO HIGHLIGHTING
COTHIL:: BYTE 3,ESC,"d@",0,0,0 ; OUT OF HIGHLIGHTING
CINREV:: BYTE 3,ESC,"dP",0,0,0 ; INTO REVERSE
COTREV:: BYTE 3,ESC,"d@",0,0,0 ; OUT OF REVERSE
CLINES:: BYTE 24 ; NUMBER OF LINES
CCOLUM:: BYTE 80 ; NUMBER OF COLUMNS
KEYUP:: BYTE 'P'-0X40 ; KEY: CURSOR UP
KEYDN:: BYTE 'N'-0X40 ; KEY: CURSOR DOWN
KEYXIT:: BYTE 'X'-0X40 ; KEY: EXIT TO O/S
NPRIVX:: BYTE 0 ; NONPRIV MAY EXIT IF NZ
;
; +------------------------+
; | SYSTEM MESSAGE SECTION |
; +------------------------+
;
BANNER:: BYTE "YOUR MENU TITLE HERE$" ; CUSTOMIZABLE MENU HEADER
RES 60 ; UP TO 80 CHARS
CRLFLF: BYTE "\r\n"
CRLF: BYTE "\r\n$"
MENTER: BYTE "Enter selection [ ]\8\8$"
MINVME: BYTE "\r\n\n\7FATAL ERROR: Menu not "
BYTE "terminated or too large!\r\n\n$"
TOOMNL: BYTE "\R\N\NTESTING: TOO MANY LINES\R\N\N\N$"
SEP: BYTE " = $"
PRTC: BYTE "PRESS ANY KEY TO RETURN TO MENU:$"
;
; +----------------------+
; | DATA STORAGE SECTION |
; +----------------------+
;
NMBLNS: WORD 0 ; NUMBER OF MENU LINES
PRIV: BYTE 0 ; PRIVILEGE FLAG
;
CMDLN: BYTE 0,"\\"
RES 160
;
; +------------------------+
; | MENU SCREEN DEFINITION |
; +------------------------+
;
; THE FOLLOWING WORKSPACE CONTAINS THE SCREEN DEFINITIONS WHICH MUST
; BE DEFINED IN THE MENU.PAR FILE IN STRICT ACCORDANCE WITH THE
; SAMPLE PROVIDED BELOW. THE TOTAL CHARACTER COUNT MUST NEVER
; EXCEED 8K!
;
SCREEN::
BYTE "A|DISPLAY DIRECTORY|DIR\\MENU W",0
BYTE "B|DISPLAY DRIVE STATS|DRIVE\\MENU W",0
BYTE "C|DISPLAY DRIVE A DIRECTORY|DIR A:\\MENU W",0
BYTE "D|LOG ONTO MASTER|MASTER",0
BYTE 0XFF
RES 8192-(.-SCREEN)
;
; EXPLANATION OF EXAMPLE:
; THE VERTICAL BAR IS A FIELD DELIMITER, THE SINGLE QUOTE IS
; A PROMPT DELIMITER.
; A DEFINITION LINE MUST CONTAIN 4 FIELDS:
; 1. THE RESPONSE CHARACTER WHICH MUST BE ONE SINGLE CHARACTER
; AND MAY BE ANY CHARACTER OTHER THAN 0X00,"'",OR "|"
; 2. THE SELECTION TITLE, WHICH MAY BE A STRING OF UP TO 40
; CHARACTERS
; 3. THE COMMAND
; (THE COMMAND MAY BE FOLLOWED IMMEDIATELY BY A STRING ENCLOSED
; IN SINGLE QUOTES. IN SUCH A CASE, THE STRING WILL BE DISPLAYED
; BEFORE COMMAND EXECUTION AND A RESPONSE WILL BE SOLICITED FROM
; THE USER WHICH WILL BE PASSED ALONG WITH THE COMMAND.
; THE RESPONSE WILL ONLY BE PARSED FOR A BACKSLASH CHARACTER,
; WHICH IN THIS CONTEXT IS ILLEGAL AND WILL BE IGNORED.
; 4. THE ENDMARK, WHICH IS A NUL (0X00) AND DELIMITS DEFINITION
; LINES.
;
; THE SPECIAL DEFINITION LINE 0XFF DENOTES THE END OF ALL DEFINITIONS
; AND THUS THE END OF THE MENU AND MUST BE PRESENT.
;
RES 100 ; ENOUGH STACK SPACE
STACK == .
;
LOC Code#
;
; +------------------+
; | START OF PROGRAM |
; +------------------+
;
START: MOV AX,DS ; GET DATA SEGMENT
MOV SS,AX ; SET UP STACK SEGMENT
RESTRT: MOV SP,&STACK ; AND OFFSET
CALL INIPGM ; INITIALIZE THE PROGRAM
CMP 0X5D,=BYTE 'W' ; WAIT?
JNZ __NWT ; NO
MOV CX,=23*256+45 ; BOTTOM LINE, END OF LINE
CALL GOTOXY
CALL INREV ; REVERSE ON
MOV DX,&PRTC ; SEND MESSAGE
CALL PRINTM
CALL GETCH
CALL OUTREV ; REVERSE OFF
__NWT: CALL CLS ; CLEAR THE SCREEN
MOV DX,&CRLF ; SPACE DOWN A LINE
CALL PRINTM
MOV BX,&BANNER ; POINT TO BANNER
CALL CENTER ; PRINT CENTERED
CMP NMBLNS,=20 ; TESTING: OVER 20?
JNA __LO
MOV CX,=16*256+30
CALL GOTOXY
MOV DX,&TOOMNL
CALL PRINTM
JMP EXIT
;
__LO: CALL DSPMNU ; DISPLAY MENU SELECTIONS
MOV CX,=4*256+20 ; CURSOR POSITION
;
; THE FOLLOWING LOOP IS USED TO SELECT AN ITEM
; CX PRESERVED THROUGHOUT TO HOLD SCREEN ADDRESS
;
SELECT: CALL GOTOXY ; PLACE CURSOR ON SELECTION
CALL GETCH ; GET A CHARACTER
CMP AL,KEYUP ; KEY UP?
JZ __KUP ; YES
CMP AL,KEYDN ; KEY DOWN?
JZ __KDN ; YES
CMP AL,=0X0D ; RETURN?
JNZ __KER ; NO, ERROR
JMP EXECUT ; ELSE EXECUTE COMMAND
;
__KER: CMP AL,KEYXIT ; EXIT KEY?
JNZ __NXK ; NO
CMP NPRIVX,=0 ; CHECK NONPR FLAG
JNZ __EX1 ; EXIT IF SET
CMP PRIV,=0 ; PRIV FLAG SET?
JNZ __EX1 ; YES
__NXK: MOV AL,=0X07 ; BELL
CALL PUTCH
JMPS SELECT
;
__EX1: JMP EXIT ; SPRINGBOARD
;
; KEY UP
;
__KUP: DEC CH ; DECREMENT LINE COUNT
CMP CH,=3 ; PAST TOP?
JNZ SELECT ; NO, LOOP ON
MOV CH,BYTE NMBLNS ; ELSE LOAD MAXLINE
ADD CH,=3 ; ADD OFFSET
JMPS SELECT ; AND LOOP
;
; KEY DOWN
;
__KDN: INC CH ; INCREMENT LINE COUNT
MOV AX,NMBLNS ; GET LINE COUNT
ADD AL,=4 ; ADD OFFSET
CMP AL,CH ; BELOW BOTTOM?
JNZ SELECT ; NO, CONTINUE
MOV CH,=4 ; ELSE LOAD TOP
JMPS SELECT ; AND LOOP
;
; COME HERE TO EXECUTE A PROGRAM
;
EXECUT: SUB CH,=3 ; NORMALIZE COMMAND POINTER
MOV SI,&SCREEN ; POINT TO SCREEN STRING
__EXF: DEC CH ; DECREMENT COUNTER
JZ __FND ; EXIT LOOP IF FOUND
__F0: INC SI
CMP [SI],=BYTE 0
JZ __EXF
JMPS __F0
;
__FND: INC SI ; STEP PAST EOL
INC SI ; STEP PAST COMMAND BYTE
__FVB: INC SI
CMP [SI],=BYTE '|' ; STEP TO SECOND DELIMITER
JNZ __FVB ; LOOP TILL FOUND
INC SI ; POINT TO COMMAND STRING
MOV DI,&CMDLN+2 ; POINT TO COMMAND LINE
MOV AL,=1 ; CONSTRUCTION AREA
__ML: MOVS BYTE ; MOVE A BYTE
INC AL
CMP [SI],=BYTE 0 ; CHECK FOR END
JNZ __ML ; LOOP IF NOT
MOV CMDLN,AL
MOV CL,=18 ; ELSE SEND COMMAND LINE
MOV DX,&CMDLN
INT TFUNC ; DO IT
MOV CL,=17 ; ENABLE AUTOLOAD
MOV DL,=0XFF
INT TFUNC
CALL CLS ; CLEAR THE SCREEN
JMP EXITX ; EXIT AND EXECUTE
;
EXIT: MOV CX,=22*256+0 ; PLACE CURSOR ON BOTTON OF SCREEN
CALL GOTOXY
MOV CL,=17 ; DISABLE AUTOLOAD
MOV DL,=0
INT TFUNC
EXITX: MOV CL,=0
INT CFUNC
;
; +-------------+
; | SUBROUTINES |
; +-------------+
;
; DISPLAY MENU SCREEN
; -------------------
;
DSPMNU: MOV SI,&SCREEN ; POINT TO SELECTIONS
MOV CX,=4*256+20 ; CURSOR POSITION
__DSLP: CALL GOTOXY
MOV AL,[SI]
CMP AL,=0XFF ; END OF MENU?
JNZ __X
RET ; YES, RETURN
;
__X: CALL PUTCH ; DISPLAY RESPONSE CHARACTER
INC SI
INC SI ; POINT TO DESCRIPTION
MOV DX,&SEP ; DISPLAY SEPARATOR
CALL PRINTM
__DSDL: MOV AL,[SI]
CMP AL,='|' ; DELIMITER?
JZ __DSDX ; YES, EXIT
CALL PUTCH
INC SI
JMPS __DSDL
;
__DSDX: INC SI
CMP [SI],=BYTE 0
JNZ __DSDX
INC SI
INC CH ; NEXT LINE
JMPS __DSLP
;
; CENTER PRINT STRING AT BX
; -------------------------
;
CENTER: PUSH BX ; SAVE STRING POINTER
XOR CX,CX ; SET COUNTER TO 0
__CCL: CMP [BX],=BYTE '$' ; END MARK?
JZ __CCE ; YES
INC BX
INC CL
JMPS __CCL
;
__CCE: MOV AL,CCOLUM ; GET NUMBER OF COLUMNS
SUB AL,CL ; SUBTRACT NUMBER OF CHARACTERS
SHR AL,=1 ; DIVIDE BY 2
MOV CL,AL ; PUT INTO COUNTER REGISTER
MOV AL,=' ' ; SPACE
__CCS: CALL PUTCH ; PRINT A SPACE
LOOP __CCS ; UNTIL DONE
POP DX ; GET STRING POINTER
JMP PRINTM ; NOW PRINT IT
;
; POSITION CURSOR
; ---------------
;
GOTOXY: PUSH SI
MOV SI,&CURAD1 ; SEND LEAD-IN
CALL TERCMD
CMP CURAD2,=0 ; COL/ROW?
JNZ __NCR ; NO, ROW/COL
XCHG CH,CL ; ELSE SWAP
__NCR: MOV AL,CH ; GET ADDR
ADD AL,CURAD4 ; ADD OFFSET
CALL PUTCH ; OUTPUT IT
MOV AL,CL ; GET SECOND ADDR
ADD AL,CURAD4 ; ADD OFFSET
CALL PUTCH ; OUTPUT IT
POP SI
RET
;
; TURN REVERSE ON
; ---------------
;
INREV: MOV SI,&CINREV
JMPS TERCMD
;
; TURN REVERSE OFF
; ----------------
;
OUTREV: MOV SI,&COTREV
JMPS TERCMD
;
; CLEAR THE SCREEN
; ----------------
;
CLS: MOV SI,&CLRSCR ; POINT TO CLEAR SCREEN CODE
;
; SEND TERMINAL COMMAND
; ---------------------
;
TERCMD: PUSH AX ; SAVE ACCUMULATOR
PUSH CX ; SAVE COUNTER
MOV CL,[SI] ; GET NUMBER OF BYTES
XOR CH,CH ; MAKE 16 BITS
__TCL: INC SI ; POINT TO NEXT BYTE
MOV AL,[SI] ; GET BYTE
CALL PUTCH ; OUTPUT CHARACTER
LOOP __TCL ; REPEAT UNTIL DONE
POP CX ; RESTORE REGISTERS
POP AX
RET
;
; OUTPUT CHARACTER IN AL
; ----------------------
;
PUTCH: PUSH AX ; SAVE MOST REGISTERS
PUSH BX
PUSH CX
PUSH DX
PUSH SI
MOV CL,=2
MOV DL,AL
INT CFUNC
POP SI
POP DX
POP CX
POP BX
POP AX
RET
;
; GET CHARACTER INTO AL
;
GETCH: PUSH BX ; SAVE MOST REGISTERS
PUSH CX
PUSH DX
PUSH SI
MOV CL,=3
INT CFUNC
POP SI
POP DX
POP CX
POP BX
RET
;
; PRINT STRING AT DX
; ------------------
;
PRINTM: PUSH BX
PUSH CX
PUSH DX
PUSH SI
MOV CL,=9
INT CFUNC
POP SI
POP DX
POP CX
POP BX
RET
;
; INITIALIZE PROGRAM
; ------------------
;
INIPGM: MOV BX,CS ; SET UP REGISTERS
MOV DX,&ABORT ; FOR ABORT TRAP
MOV CL,=8
INT TFUNC
MOV CL,=12 ; GET PRIVILEGE STATUS
INT TFUNC
MOV PRIV,CH ; SAVE IT
MOV CL,=17 ; ENABLE AUTOLOAD
MOV DL,=0XFF
INT TFUNC
;
; NOW DETERMINE TOTAL NUMBER OF MENU SELECTIONS
; (SIMPLY COUNT NULL CHARACTERS IN THE DEFINITION SPACE)
;
MOV SI,&SCREEN ; POINT TO SCREEN DEF SPACE
XOR AX,AX ; CLEAR COUNTER
MOV CX,=8192 ; MAX NUMBER OF BYTES
__NCL: CMP [SI],=BYTE 0X00 ; DEF LINE END?
JZ __DLE ; YES
CMP [SI],=BYTE 0XFF ; SCREEN END?
JZ __SCE ; YES
__C: INC SI ; INCREMENT POINTER
LOOP __NCL ; AND CONTINUE
MOV DX,&MINVME ; COMPLAIN
CALL PRINTM
JMP EXIT ; AND QUIT
;
__DLE: INC AX ; BUMP COUNTER
JMPS __C
;
__SCE: MOV NMBLNS,AX ; STORE NUMBER OF LINES
RET ; AND RETURN
;
ABORT: RETF
END
RINTM: PUSH BX
PUSH CX
PUSH DX
PUSH SI
MOV CL,=9
INT CFUNC
POP SI
POP DX
P