home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
ZSYS
/
SIMTEL20
/
ZCPR3
/
MENU.MAC
< prev
next >
Wrap
Text File
|
2000-06-30
|
31KB
|
1,510 lines
;
; PROGRAM: MENU
; AUTHOR: RICHARD CONN
; VERSION: 3.2
; DATE: 10 June 84
; PREVIOUS VERSIONS: 3.1 (28 Mar 84), 3.0 (18 Mar 84)
; DERIVATION. MENU 1.4 for ZCPR2
;
VERS EQU 32
;
; MENU is the ZCPR3 Menu Processor. It loads, looks for the MENU.MNU
; file, and then displays it to the user (optionally) and prompts him for
; a single-character command. The ZCPR3 Multiple Command Line Buffer must
; be installed for MENU to work, and MENU uses this buffer to chain to the
; programs selected by the user and return to itself at the proper place.
;
; MENU supports multiple menus within one MENU.MNU file. When a command
; is invoked, MENU returns to the menu the command came from.
;
; MENU will ONLY RUN on ZCPR3 systems with the Multiple Command Line
; Buffer Option enabled.
;
;
; Menu Constants
;
sysmenu equ 0 ;System Menu Enabled? 0=no, 1=yes
; 1 Special Menu Command Chars
RNM EQU '>' ;NEXT MENU
RNMP EQU '.' ;NEXT MENU PRIME (ALTERNATE)
RLM EQU '<' ;LAST MENU
RLMP EQU ',' ;LAST MENU PRIME (ALTERNATE)
RFM EQU '*' ;FIRST MENU
;
if sysmenu
RSM EQU '$' ;SYSTEM MENU (PASSWORD REQUIRED)
; THIS IS SAME AS CONTROL CHAR
endif ;sysmenu
; 2 Internal Menu Control Chars
MCMD EQU ':' ;COMMAND TO JUMP TO ANOTHER MENU
PCHAR EQU '"' ;INDICATES AUTO PROMPT FOR SPECIFIC CMD
MINDIC EQU '#' ;MENU SECTION INDICATOR
MFIRST EQU '%' ;FIRST MENU INDICATOR
GOPTION EQU '-' ;GLOBAL OPTION INDICATOR
WOPTION EQU '!' ;ACTIVATES WAIT UPON RETURN
; 3 Menu Option Chars
COPTION EQU 'C' ;DISPLAY COMMAND LINE TO USER
DOPTION EQU 'D' ;DISPLAY MENU TO USER
POPTION EQU 'P' ;PAGE OUT MENU DISPLAY TO USER
XOPTION EQU 'X' ;DISABLE ZCPR3 RETURN
; 4 Miscellaneous
IBUFSZ EQU 254 ;SIZE OF INPUT LINE BUFFER
VARFLAG EQU '$' ;VARIABLE FLAG
;(FOLLOWED BY D,U,Fn,Nn,Tn)
CMDSEP EQU ';' ;ZCPR3 COMMAND SEPARATOR
;
; Enter/Exit Standout Mode (Recommended that these values not be changed)
;
DIM EQU 'A'-'@' ; ^A TO ENTER STANDOUT
NOTDIM EQU 'B'-'@' ; ^B TO EXIT STANDOUT
;
; MACRO Library of Definitions
;
MACLIB Z3BASE.LIB
;
; ZCPR3 CONSTANTS
;
wboot equ 0
bentry equ 5
fcb equ 5ch
tbuff equ 80h
BEL equ 7
CR equ 0dh
LF equ 0ah
CTRLC equ 'C'-'@'
TAB equ 'I'-'@'
CTRLZ equ 'Z'-'@'
;
; MACROS TO PROVIDE Z80 EXTENSIONS
; MACROS INCLUDE:
;
; BR - JUMP RELATIVE
; BRC - JUMP RELATIVE IF CARRY
; BRNC - JUMP RELATIVE IF NO CARRY
; BRZ - JUMP RELATIVE IF ZERO
; BRNZ - JUMP RELATIVE IF NO ZERO
; BJNZ - DECREMENT B AND JUMP RELATIVE IF NO ZERO
; PUTRG - SAVE REGISTERS
; GETRG - RESTORE REGISTERS
;
;
;
; Z80 MACRO EXTENSIONS
;
BR MACRO ?N ;;JUMP RELATIVE
IF I8080 ;;8080/8085
JMP ?N
ELSE ;;Z80
.Z80
JR ?N
.8080
ENDIF ;;I8080
ENDM
;
BRC MACRO ?N ;;JUMP RELATIVE ON CARRY
IF I8080 ;;8080/8085
JC ?N
ELSE ;;Z80
.Z80
JR C,?N
.8080
ENDIF ;;I8080
ENDM
;
BRNC MACRO ?N ;;JUMP RELATIVE ON NO CARRY
IF I8080 ;;8080/8085
JNC ?N
ELSE ;;Z80
.Z80
JR NC,?N
.8080
ENDIF ;;I8080
ENDM
;
BRZ MACRO ?N ;;JUMP RELATIVE ON ZERO
IF I8080 ;;8080/8085
JZ ?N
ELSE ;;Z80
.Z80
JR Z,?N
.8080
ENDIF ;;I8080
ENDM
;
BRNZ MACRO ?N ;;JUMP RELATIVE ON NO ZERO
IF I8080 ;;8080/8085
JNZ ?N
ELSE ;;Z80
.Z80
JR NZ,?N
.8080
ENDIF ;;I8080
ENDM
;
BJNZ MACRO ?N ;;DECREMENT B AND JUMP RELATIVE ON NO ZERO
IF I8080 ;;8080/8085
DCR B
JNZ ?N
ELSE ;;Z80
.Z80
DJNZ ?N
.8080
ENDIF ;;I8080
ENDM
;
PUTRG MACRO
PUSH H ;;SAVE REGISTERS IN ORDER
PUSH D
PUSH B
ENDM
;
GETRG MACRO
POP B ;;RESTORE REGISTERS IN ORDER
POP D
POP H
ENDM
;
; END OF Z80 MACRO EXTENSIONS
;
;
; Externals from SYSLIB
;
ext z3vinit,cls,stndout,stndend
ext getcl1,putcl,getsh2,qshell,retud,getefcb,shpush,shpop
ext getshm,putshm,moveb,getfn2,pfn1,getcrt,getzrun,putzex,putcst
ext eprint,cin,cout,caps,crlf,pafdc,madc,bline,initfcb,sksp
ext f$open,f$close,f$read,codend,hmovb
;
; Environment Definition
;
if z3env ne 0
;
; External ZCPR3 Environment Descriptor
;
jmp start
db 'Z3ENV' ;This is a ZCPR3 Utility
db 1 ;External Environment Descriptor
z3eadr:
dw z3env
start:
lhld z3eadr ;pt to ZCPR3 environment
;
else
;
; Internal ZCPR3 Environment Descriptor
;
MACLIB SYSENV.LIB
z3eadr:
jmp start
SYSENV
start:
lxi h,z3eadr ;pt to ZCPR3 environment
endif
;
; Start of Program -- Initialize ZCPR3 Environment
;
call z3vinit ;initialize the ZCPR3 Env and the VLIB Env
jmp strt
;
; This is the FCB which defines the default name of the MENU.MNU file
;
if sysmenu
ppass:
db 'SYSTEM ',0 ;system password
endif ;sysmenu
;
menufcb:
db 0 ;FCB for MENU.MNU
db 'MENU '
db 'MNU'
ds 4
scratch: ;this doubles as a scratch area
ds 16 ;buffer definition is at end of program
ds 4 ;36 bytes total
;
; Start of Program
;
strt:
;
; Check for Shell Stack
;
call getsh2 ;get shell status
brnz strt0 ;skip over shell init
call eprint
db ' No Shell Stack',0
ret
;
; See if Command Line Available
;
strt0:
call getcl1 ;get line
brnz strt01
call eprint
db ' No Command Line',0
ret
;
; See if this program was invoked as a shell
;
strt01:
call qshell ;find out from ZCPR3 environment
push psw ;save status
xra a ;A=0
call putcst ;put command status (normal = 0)
pop psw ;restore status
jz menu ;do not push onto stack if invoked as a shell
;
; Set Name of Shell from External FCB if Possible or From Default if Not
;
setshn:
call retud ;get run address
lxi h,shdisk ;pt to shell disk
mov a,b ;get disk
adi 'A' ;convert to letter
mov m,a ;set disk letter
inx h ;pt to user 10's
mov a,c ;get user number
mvi b,10 ;subtract 10's
mvi d,'0' ;set char
setshn1:
sub b ;subtract
brc setshn2
inr d ;increment digit
br setshn1
setshn2:
add b ;get 1's
mov m,d ;set 10's digit for user
inx h ;pt to 1's digit
adi '0' ;compute 1's digit
mov m,a ;set 1's digit
call getefcb ;get ptr to external fcb
brz strt02 ;no external FCB, so use default name
inx h ;pt to program name
lxi d,shname ;pt to string
mvi b,8 ;8 chars
call moveb ;copy into buffer
;
; Check for File Name and Set It If Given
;
strt02:
lxi h,fcb+1 ;pt to file name
lxi d,menufcb+1
mvi b,11 ;11 chars
mov a,m ;get first char
cpi ' '
cnz moveb ;copy if one present
;
; Set File Name in MENUFCB into Line
;
lxi h,menufcb+1 ;set shell file name
lxi d,shfile ;pt to shell file
mvi b,8 ;8 chars
strt03:
mov a,m ;get next char
cpi ' ' ;done?
brz strt04
stax d ;put char
inx d ;pt to next
strt04:
inx h ;pt to next
bjnz strt03
mvi a,'.' ;put dot
stax d
inx d ;pt to next
mvi b,3 ;file type
strt05:
mov a,m ;copy
stax d
inx h ;pt to next
inx d
bjnz strt05
xra a ;store zero
stax d
;
; Set Menu Number
;
mvi b,1 ;shell message 1
xra a ;menu 0
call putshm ;set message
;
; Push Name of Shell onto Stack
;
lxi h,shdisk ;pt to name of shell
call shpush ;push shell onto stack
brnz strt2
;
; Shell Successfully Installed
;
call eprint
db ' Shell Installed',0
ret
;
; Shell Stack Push Error
;
strt2:
cpi 2 ;shell stack full?
brnz strt3
;
; Shell Stack is Full
;
call eprint
db ' Shell Stack Full',0
ret
;
; Shell Stack Entry Size is too small for command line
;
strt3:
call eprint
db ' Shell Stack Entry Size',0
ret
;
; Check for ZEX Execution and Pass ZEX if So
;
menu:
call getzrun ;is ZEX running?
brz runmenu ;process menu if not
br menuz1 ;skip new line
menuzex:
call crlf ;new line
menuz1:
call eprint
db 'Menu> ',0
mvi a,1 ;tell ZEX that it is prompted
call putzex
call codend ;set up buffer
mvi m,ibufsz ;set size
mvi a,0FFH ;capitalize
call bline ;get line from ZEX
xra a ;A=0
call putzex ;resume ZEX normally
call sksp ;skip over leading spaces
mov a,m ;check for comment
cpi ';'
brz menuzex
xchg ;DE pts to command line
xra a ;don't display command
sta cpflag
jmp runcmnd ;run command pted to by DE
;
; Begin Menu Processing
;
runmenu:
call eprint
db 'MENU Version '
db (vers/10)+'0','.',(vers mod 10)+'0',0
;
; Check for Wait Flag and Wait if So
;
mvi b,0 ;get shell message 0
call getshm
ani 80h ;check for wait flag
cnz sak ;Strike Any Key
;
; Open Menu File
;
lxi h,fcb ;copy FCB into MENU FCB
lxi d,menufcb
mvi b,36 ;36 bytes
push d ;save ptr
call moveb
pop d ;pt to MENU.MNU FCB
call initfcb ;init fcb
call f$open ;open file
brz menu1 ;abort if no menu
call eprint
db CR,LF,' File ',0
lxi d,menufcb+1
call pfn1
call eprint
db ' Not Found',0
jmp shpop
;
; Load MENU.MNU from disk
;
menu1:
call codend ;get address of buffer for menu load
mload:
lxi d,menufcb ;pt to FCB
call f$read ;read in next block
ora a ;error?
brnz mloaddn ;load done if error
lxi d,tbuff ;copy from TBUFF into memory pted to by HL
xchg ;HL is source, DE is dest
mvi b,128 ;128 bytes
call hmovb
lhld bentry+1 ;get address of top of TPA
mov a,h ;set to bottom of ZCPR3
sui 10
cmp d ;about to overflow ZCPR3?
brnc mload1 ;continue if not
call eprint
db CR,LF,' TPA Full',0
ret
mload1:
xchg ;HL pts to next byte to load to
br mload ;continue load
;
; Init Flags and Clear MSB of all bytes in Menu File
;
mloaddn:
call f$close ;close input file
mvi m,CTRLZ ;ensure EOF mark
lxi d,80H ;pt to next block
dad d
shld ibuff ;set ptr to input line buffer
mvi m,ibufsz ;set size
dad d ;allow 256 bytes
dad d
shld expline ;set ptr to expand line
xra a ;A=0
sta cflag ;turn off command display
sta dflag ;turn off menu display
sta pflag ;disallow paging
sta cpmok ;turn off ZCPR3 return flag
call codend ;pt to beginning of file
push h ;save ptr
menul1:
mov a,m ;get byte
ani 7FH ;mask out MSB
mov m,a ;put byte
inx h ;pt to next
cpi CTRLZ ;EOF?
brnz menul1 ;continue if not
;
; Mark all Menu Sections
;
pop h ;HL pts to first byte of menu
mvi b,0FFH ;set menu counter
;
; Skip to Next Menu
;
menul2:
mov a,m ;get byte
cpi CTRLZ ;error?
jz mstrerr ;structure error if so
cpi MINDIC ;menu indicator (start of menu?)
brnz menul4
ori 80H ;beginning of menu found -- set MSB
mov m,a ;put byte
inr b ;increment menu count
inx h ;pt to next
mov a,m ;get byte
cpi MINDIC ;menu indicator (end of menu?)
brz menul5 ;done if so
cpi CTRLZ ;error?
jz mstrerr
;
if sysmenu
cpi RSM ;system menu indicator?
brnz menul3
mov a,b ;set system menu number
sta smeno
mvi a,0FFH ;set flag
sta smenfl ;system menu present
dcx h ;back up to beginning of menu
shld smenadr ;start address
inx h ;pt to RSM
endif ;sysmenu
;
; Skip out Menu Display
;
menul3:
call lskipt ;skip to beginning of next line
brz menul4 ;found menu indicator
cpi CTRLZ ;error?
jz mstrerr
br menul3 ;continue if not
;
; Skip to Next Menu
;
menul4:
call lskip ;skip to beginning of next menu
br menul2
;
; Check Menu Options
;
menul5:
call codend ;pt to beginning of file
mov a,m ;check for option
cpi GOPTION ;global option char?
jnz mfile ;if no global option, scan for menu files
inx h ;pt to option char
option:
mov a,m ;get option char
call caps ;capitalize
inx h ;pt to next
cpi CR ;done?
brz optdn
cpi COPTION ;display command?
brz optc
cpi DOPTION ;display menu?
brz optd
cpi POPTION ;paging?
brz optp
cpi XOPTION ;exit OK?
jnz mstrerr ;option error if not
;
; Disable Exit to ZCPR3
;
mvi a,0FFH ;turn flag off
sta cpmok
br option
;
; Process Paging Option
;
optp:
mvi a,0FFH ;set flag
sta pflag
br option
;
; Process Display Menu Option
;
optd:
mvi a,0FFH ;set flag
sta dflag
br option
;
; Process Display Command Option
;
optc:
mvi a,0FFH ;set flag
sta cflag
br option
;
; Option Processing Done
;
optdn:
inx h ;skip LF
;
; Check for Menu Display
;
mfile:
mov a,m ;get first byte
ani 7FH ;mask
cpi MINDIC ;start of menu?
jnz mstrerr
;
; Check and Set First Menu
;
shld mstart ;save start address of first menu item
mvi m,MFIRST+80H ;set first char of first menu
;
; Entry Point for Menu Display
; On entry, HL pts to first byte of current menu
;
dmenu:
mvi b,1 ;shell message 1 contains menu number
call getshm ;get menu number flag
cnz mchc0 ;skip to proper menu
shld cstart ;save start address of current menu
lda cflag ;copy display command flag for temp use
sta cpflag
lda dflag ;copy display menu flag for temp use
sta dpflag
lda pflag ;copy paging flag for temp use
sta ppflag
inx h ;pt to first char after menu indicator char
dispm1:
mov a,m ;get char
call caps ;capitalize
inx h ;pt to next
cpi CR ;end of options?
brz dispm2
;
if sysmenu
cpi RSM ;system menu?
brz dispm1 ;ok if so
endif ;sysmenu
;
cpi COPTION ;command display?
brz dispmc
cpi DOPTION ;display?
brz dispmd
cpi POPTION ;paging?
brz dispmp
cpi XOPTION ;ZCPR3 return?
jnz mstrerr ;error if not
;
; Toggle ZCPR3 Return Option
;
lda cpmok ;get flag
cma ;toggle
sta cpmok
br dispm1
;
; Toggle Paging Option
;
dispmp:
lda ppflag ;get flag
cma ;toggle
sta ppflag
br dispm1
;
; Toggle Display Menu Option
;
dispmd:
lda dpflag ;get flag
cma ;toggle
sta dpflag
br dispm1
;
; Toggle Display Command Option
;
dispmc:
lda cpflag ;get flag
cma ;toggle
sta cpflag
br dispm1
;
; Done with Menu-Specific Option Processing
;
dispm2:
call lskip ;skip to LF
lda dpflag ;display menu?
ora a ;0=no
brz dispm8 ;skip over menu if not
call getnlines ;get line count in A
sta pagcnt ;set count
lda ppflag ;paging?
ora a ;0=no
push psw ;save flag
cnz cls ;clear screen if so
pop psw ;get flag
cz crlf ;else new line
;
; Print Next Line of Menu if not Starting with ESCAPE Char (MINDIC)
;
dispm3:
mov a,m ;get first char of line
ani 7FH ;mask
cpi MINDIC ;done?
brz dispm4
call expand ;expand line pted to by HL
push h ;save ptr to next line
xchg ;HL pts to expanded line
call lprintx ;print line pted to by HL ending in <CR>
pop h ;pt to next line
br dispm3
;
; Done with Menu Display -- Page it out
;
dispm4:
call lskip ;skip to first char of next line (option char)
shld optstrt ;set start address of options
lda pagcnt ;number of remaining lines
mov b,a ;count in B
ora a ;ok?
brz dispm6 ;don't do anything if already there
lda ppflag ;page?
ora a ;0=No
brz dispm6
;
; Page Loop for Menu Display
;
dispm5:
call crlf ;new line
bjnz dispm5
;
; Determine if Another Menu Follows
;
dispm6:
xra a ;A=0
sta nmenfl ;set for no next menu
mov a,m ;ok?
ani 7FH ;mask
cpi CTRLZ ;error if EOF
jz mstrerr
cpi MINDIC ;next menu?
brnz dispm7
inx h ;double indicator if end
mov a,m
cpi MINDIC ;end?
brz dispm9
;
if sysmenu
cpi RSM ;system menu = no next menu
brz dispm9
endif ;sysmenu
;
mvi a,0FFH ;set next menu
sta nmenfl
br dispm9
dispm7:
call lskip ;skip to next line
br dispm6
;
; Skip over current menu so it is not displayed
;
dispm8:
call lskipt ;skip to beginning of command
brnz dispm8
call lskip ;skip over end of display indicator
shld optstrt ;set pointer to options
br dispm6 ;determine if next menu available
dispm9:
;
; Ready for Option Input
; The following Flags/Values are now set:
; CPFLAG -- Display Command Flag (0=No, 0FFH=Yes)
; DPFLAG -- Display Menu Flag (0=No, 0FFH=Yes)
; OPTSTRT -- Address of First Menu Option
; NMENFL -- 0 if no next menu, 0FFH if next menu
; MSTART -- Start Address of MINDIC Before Menu Display
; (MSTART)=MFIRST with MSB Set
prompt:
call stndout ;begin standout
mvi a,0ffh
sta pagcnt ;turn off paging
sta dpflag ;turn on future menu displays
call retud ;get DU
mov a,b ;print D
adi 'A'
call cout
mov a,c ;print U
call pafdc
call eprint
db '> Command (CR=Menu',0
lda cpmok ;OK to return to ZCPR3?
ora a ;0=No
cnz prmptc
lhld cstart ;pt to first char
mov a,m ;get it
ani 7FH ;mask
cpi MFIRST
cnz prmptf ;print previous menu prompt if not first menu
lda nmenfl ;next menu available?
ora a ;0=No
cnz prmptn ;print next menu prompt
call eprint
db ') - ',0
call stndend ;end standout
prompt1:
call cin ;get response
call caps ;capitalize
mov b,a ;result in B
;
; Check for CR
;
cpi CR ;<CR>?
jz dispm2 ;reprint menu if so
;
; Check for Reboot
;
lda cpmok ;ok to abort?
ora a ;0=No
brz prmpt0
mov a,b ;get command
cpi CTRLC ;reboot?
jz shpop ;pop shell stack and return to OS if so
;
; Check for Command to Return to First Menu
;
prmpt0:
mov a,m ;get it
ani 7FH ;mask
cpi MFIRST
brz prmpt1
mov a,b ;get command
cpi RFM ;return to first menu?
brnz prmpt1
lhld mstart ;pt to first menu
mvi b,1 ;shell message 1 is menu number
xra a ;A=0=menu 0
jmp putshm ;reenter shell at first menu
;
; Check for Command to go to Next Menu
;
prmpt1:
lda nmenfl ;next menu available?
ora a ;0=No
brz prmpt2
mov a,b ;get command
cpi RNMP ;goto next menu?
brz rnmx
cpi RNM ;goto next menu?
brnz prmpt2
rnmx:
mvi b,1 ;shell message 1 is menu number
call getshm ;increment menu number
inr a
jmp putshm ;reenter menu system at new menu
;
; Check for Command to go to Last Menu
;
prmpt2:
mov a,m ;get menu char
ani 7FH ;at first menu?
cpi MFIRST
brz prmpt3 ;skip if at first menu
mov a,b ;get command
cpi RLMP ;goto last menu?
brz lstmnu
cpi RLM ;goto last menu?
brnz prmpt3
lstmnu:
mvi b,1 ;shell message 1 is menu number
call getshm ;decrement menu number
dcr a
jmp putshm ;reenter shell at last menu
;
; Check for Command to goto System Menu
;
prmpt3:
if sysmenu
;
lda smenfl ;system menu available?
ora a ;0=No
brz prmpt4
mov a,b ;get command
cpi RSM ;system menu?
brnz prmpt4
call password ;prompt for and get password
jnz prompt ;reprompt if error
lhld smenadr ;get address of system menu
lda smeno ;set system menu number
mvi b,1 ;shell message 1 is menu number
jmp putshm ;reenter shell at system menu
;
endif ;sysmenu
;
; This is where additional functions may be added
;
prmpt4:
;
; Check for Option Letter
;
lhld optstrt ;pt to first option char
prmptx:
mov a,m ;get it
call caps ;capitalize
cpi MINDIC ;at next menu?
brz prmpter
cmp b ;match user selection?
brz prmptd
call lskip ;skip to next line
br prmptx
;
; Invalid Option
;
prmpter:
call eprint
db BEL,0
jmp prompt1
;
; Process Option
;
prmptd:
mov a,b ;output user selection
call cout
mvi b,0 ;shell message 0, bit 7 = wait flag
call getshm
ani 7FH ;set no wait
call putshm
inx h ;pt to first letter of command
mov a,m ;get it
cpi MCMD ;invoke other menu?
jz mchcmd ;menu change command
cpi WOPTION ;turn on wait?
brnz prmptg
mvi b,0 ;shell message 0, bit 7 = wait flag
call getshm
ori 80h ;set wait flag
call putshm ;set shell message
inx h ;skip option char
prmptg:
call expand ;expand line, DE pts to result
;
; Run Command Pted to by DE
;
runcmnd:
call getcl1 ;get address of command buffer
mov b,h ;... in BC also
mov c,l
mvi a,4 ;HL=HL+4 for address of first char
add l
mov l,a
mov a,h
aci 0
mov h,a
mov a,l ;store address
stax b
inx b
mov a,h
stax b
;
; Copy Command Line in DE into Buffer in HL
;
cmdcpy:
ldax d ;get command letter
call caps ;capitalize it
ora a ;done?
brz ccpyd
cpi CR ;done?
brz ccpyd
cpi PCHAR ;prompt?
brz ccpyp
mov m,a ;store it
inx h ;pt to next
inx d
br cmdcpy
ccpyd:
mvi m,0 ;store ending 0
jmp cmddisp ;optionally display command
;
; Prompt User for Input and Accept It
;
ccpyp:
inx d ;pt to first char of prompt
call crlf ;new line
ccpyp1:
ldax d ;get char
cpi PCHAR ;end of prompt?
brz ccpyp2
cpi CR ;new line?
brz ccpyp3
call cout ;echo char
inx d ;pt to next char
br ccpyp1 ;continue looping
ccpyp2:
inx d ;pt to char after closing PCHAR
ccpyp3:
push d ;save ptr to next char
xchg ;DE pts to buffer
mvi a,0FFH ;capitalize input from user
lhld ibuff ;input line buffer
call bline ;get input from user
xchg ;HL pts to buffer, DE pts to user input
cmdlp:
ldax d ;get char from user
ora a ;end of input?
brz cmdlp1 ;store rest of line
mov m,a ;store char
inx h ;pt to next
inx d
br cmdlp
cmdlp1:
pop d ;DE pts to next char, HL pts to buffer
br cmdcpy ;resume copying
;
; Check for Display of Loaded Command and Do So if Set
;
cmddisp:
lda cpflag ;display command?
ora a ;0=No
rz ;return to OS if so to run command
call crlf ;new line
call getcl1 ;pt to first char
mov e,m ;get low-order address
inx h
mov d,m ;get high-order address
xchg ;HL pts to first char
cmdd1:
mov a,m ;get char
cpi CMDSEP ;done if command separator
rz
inx h ;pt to next
call cout ;print char
br cmdd1
;
; Menu Change Command -- Jump to Specified Menu
;
mchcmd:
inx h ;pt to menu number
call eval ;convert to decimal number in A
sta menuno ;save menu number
call mchc0 ;skip to desired menu to check for it
lda menuno ;get menu number
mvi b,1 ;menu number is shell message 1
jmp putshm ;set message and reenter shell
;
; Entry Point if MENU is Reinvoked
;
mchc0:
mov b,a ;menu number in B
inr b ;add 1 for initial offset
lhld mstart ;pt to first menu
mchc1:
dcr b ;count down
rz ;done if found
mchc2:
call lskipt ;skip to next line
brnz mchc2 ;continue if not end of menu display
mchc3:
call lskipt ;skip to next line
brnz mchc3 ;continue if not at end of menu commands
inx h ;end of MENU.MNU?
mov a,m ;yes if double MINDIC
ani 7FH ;mask
cpi MINDIC
brz mchcerr ;error if so
dcx h ;pt to first char
br mchc1 ;continue
;
; Premature End of Menu File
;
mchcerr:
pop psw ;clear stack
jmp mstrerr ;menu structure error
;
; Print Line pted to by HL Ending in <CR>
; Decrement PAGCNT
;
lprintx:
call lprint ;print without <CR>
jmp crlf ;do <CR> <LF>
;
; Print Line Pted to by HL; Decrement PAGCNT
;
lprint:
mvi b,0 ;set tab counter
lprnt0:
mov a,m ;get char
inx h ;pt to next
ani 7FH ;mask MSB
cpi DIM ;goto standout mode?
brz lprnt3
cpi NOTDIM ;end standout mode?
brz lprnt4
cpi TAB ;tabulate?
brz lprnt2
cpi CR ;done?
brz lprnt1
call cout ;print
inr b ;incr tab counter
br lprnt0
lprnt1:
inx h ;pt to first char of next line
lda pagcnt ;count down pages
dcr a
sta pagcnt
rnz
call getnlines ;get line count in A
sta pagcnt
call eprint
db CR,LF,'Pause -',0
br sak1
lprnt2:
mvi a,' ' ;print <SP>
call cout
inr b ;incr tab counter
mov a,b ;done?
ani 7 ;every 8
brnz lprnt2
br lprnt0
lprnt3:
call stndout ;enter standout mode
br lprnt0
lprnt4:
call stndend ;end standout mode
br lprnt0
;
; Strike Any Key Message
;
sak:
mvi b,0 ;clear any pending wait
call getshm
ani 7FH ;mask MSB
call putshm
sak1:
call stndout ;goto standout
call eprint
db ' Strike Any Key - ',0
call stndend ;exit standout
call cin ;get response
call crlf ;new line
ret
;
; Prompt for, input, and check password (only one chance)
; If accepted, return with Zero Flag Set; if not, return with NZ
;
if sysmenu
password:
call eprint
db CR,LF,'Pass? ',0
lhld ibuff ;pt to input line buffer
xra a ;don't capitalize user input
call bline ;get line from user
lxi d,ppass ;pt to system password
pass1:
ldax d ;get sys pass char
cmp m ;ok?
brnz passerr ;error if no match
inx h ;pt to next
inx d
ora a ;end of strings?
brnz pass1
ret ;return with zero set to show match
passerr:
call eprint
db CR,LF,' Password Error',0
call sak1 ;strike any key
call crlf
mvi a,0FFH ;set no zero
ora a
ret
endif ;sysmenu
;
; Skip to Beginning of Next Line and Test First Char for Menu Indicator
;
lskipt:
call lskip ;skip
mov a,m ;get char
ani 7FH ;mask
cpi MINDIC ;test
ret
;
; Skip to Beginning of Next Line
;
lskip:
mov a,m ;get char
ani 7FH ;mask out MSB
inx h ;pt to next
cpi LF
brnz lskip
ret
;
; Print ZCPR3 Return Prompt
;
prmptc:
call eprint
db ', ^C=Z3',0
ret
;
; Print First/Last Menu Chars
;
prmptf:
call eprint
db ', ',RFM,'=1st Menu, ',RLM,'=Prev Menu',0
ret
;
; Print next menu message
;
prmptn:
call eprint
db ', ',RNM,'=Next Menu',0
ret
;
; Menu Structure Error -- FATAL
; This message is printed to indicate an error in the structure of
; the MENU.MNU file.
;
mstrerr:
call eprint
db CR,LF,' Structure Error',0
jmp shpop
;
; Expand Line Pted to by HL into Scratch Area
; Return with HL pting to next line, DE pting to current line
;
expand:
xchg
lhld expline ;pt to buffer
xchg
exp1:
mov a,m ;get next char
ani 7fh ;mask MSB
stax d ;store char
cpi CR ;end of line?
jz expx
inx h ;pt to next
inx d
cpi VARFLAG ;variable follows?
brnz exp1
;
; Variable Identified - Process it
;
mov a,m ;get next char
inx h ;pt to next
cpi VARFLAG ;one variable char?
brz exp1 ;resume if double VARFLAG
dcx d ;pt to variable position
call caps ;capitalize variable
cpi 'D' ;current disk?
brz expdisk
cpi 'U' ;current user?
brz expuser
cpi 'F' ;filename.typ?
brz expfile
cpi 'N' ;filename?
brz expname
cpi 'T' ;filetype?
brz exptype
br exp1 ;resume expansion
;
; Expand Exit
;
expx:
inx h ;pt to line feed
mov a,m ;get it
cpi LF ;line feed?
brnz expx1
inx h ;pt to char after line feed
expx1:
xchg ;DE pts to next line
lhld expline ;pt to expanded line
xchg ;HL pts to next line, DE pts to expanded line
ret
;
; Expand Disk
;
expdisk:
call retud ;get disk in B
mov a,b ;get disk number (A=0)
adi 'A' ;convert to ASCII
stax d ;store letter
inx d ;pt to next
br exp1 ;resume expansion
;
; Expand User
;
expuser:
call retud ;get user in C
mov a,c ;get user number
mvi b,10 ;subtract 10's
mvi c,'0' ;set char
expu1:
sub b ;-10
brc expu2
inr c ;increment digit
br expu1
expu2:
add b ;+10
adi '0' ;convert 1's to ASCII
mov b,a ;B=1's
mov a,c ;get 10's
stax d ;store 10's
inx d
mov a,b ;get 1's
stax d ;store 1's
inx d ;pt to next
br exp1 ;resume
;
; Expand File
;
expfile:
call getfnum ;get file number
jz exp1 ;resume if error
push h ;save ptr to next char
call ptfn ;set ptr to file name
call putn ;put file name
mvi a,'.'
stax d ;store dot
inx d ;pt to next
call putt ;put file type
pop h ;restore ptr
jmp exp1 ;resume
;
; Expand Name
;
expname:
call getfnum ;get file number
jz exp1 ;resume if error
push h ;save ptr to next char
call ptfn ;set ptr to file name
call putn ;put file name
pop h ;restore ptr
jmp exp1 ;resume
;
; Expand Type
;
exptype:
call getfnum ;get file number
jz exp1 ;resume if error
push h ;save ptr to next char
call ptfn ;set ptr to file name
mvi a,8 ;add 8
add l
mov l,a
mov a,h
aci 0
mov h,a
call putt ;put file type
pop h
jmp exp1 ;resume
;
; Pt to File Name whose Number (1-4) is in A
;
ptfn:
mov b,a ;get number in B
call getfn2 ;pt to file name 2
push d ;save DE
mov a,b ;file 0?
ora a
brz ptfnx
lxi d,11 ;size of file name and type
ptfn1:
dad d ;pt to next
bjnz ptfn1
ptfnx:
pop d ;restore DE
ret
;
; Put File Name pted to by HL
;
putn:
mvi b,8 ;8 chars
br putc
;
; Put File Type pted to by HL
;
putt:
mvi b,3 ;3 chars
;
; Copy Chars from HL to DE for up to B bytes -- flush if space
;
putc:
mov a,m ;get next char
cpi ' ' ;skip spaces
brz putc1
stax d ;put next char
inx d ;pt to next
putc1:
inx h ;pt to next
bjnz putc
ret
;
; Get File Number (1 to 4)
; If valid number, return with value in A and HL pting to next char
; If not valid, return with Z and HL pting to last char (F, N, T)
;
getfnum:
mov a,m ;get char
sui '1' ;convert
brc getfne ;error
cpi 4 ;range?
brnc getfne
inx h ;pt to next char
ret ;NZ from CPI 4
getfne:
dcx h ;error return
xra a
ret
;
; Return Number of Lines on CRT in A
;
getnlines:
push h ;save HL
call getcrt ;get CRT info
inx h ;pt to number of lines
mov a,m ;get count
pop h ;restore HL
dcr a ;subtract 1 for footer
ret
;
; Convert char string pted to by HL into decimal number in A
; On Entry, HL pts to first digit char
; On Exit, HL pts to after last digit char and A=number
;
eval:
push b ;save BC
mvi b,0 ;set value
eval1:
mov a,m ;get digit
sui '0' ;convert to binary
brc eval2
cpi 10 ;range?
brnc eval2
inx h ;pt to next digit
mov c,a ;new digit in C
mov a,b ;multiply B by 10
add a ;*2
add a ;*4
add b ;*5
add a ;*10
add c ;add in new digit
mov b,a ;result in B
br eval1
eval2:
mov a,b ;result in A
pop b ;restore ptr
ret
;
; These buffers overlay the scratch area to save space
;
optstrt equ scratch ;Address of First Option in Current Menu
mstart equ optstrt+2 ;Address of First Menu
cstart equ mstart+2 ;Address of Current Menu
smenfl equ cstart+2 ;System Menu Available Flag (0=No)
smeno equ smenfl+1 ;System Menu Number
smenadr equ smeno+1 ;Address of First Byte of System Menu
nmenfl equ smenadr+2 ;Next Menu Available Flag (0=No)
menuno equ nmenfl+1 ;Number of Menu
pagcnt equ menuno+1 ;Paging Counter
cflag equ pagcnt+1 ;Display Command Line Flag
dflag equ cflag+1 ;Display Menu Flag
pflag equ dflag+1 ;Paging Flag
;
; Buffers
;
ibuff:
ds 2 ;input line buffer
expline:
ds 2 ;scratch area to expand lines in
cpflag:
ds 1 ;Temp Display Command Line Flag
dpflag:
ds 1 ;Temp Display Menu Flag
ppflag:
ds 1 ;Temp Paging Flag
cpmok:
ds 1 ;OK to Return to ZCPR3 (0=No)
tnum:
ds 41 ;space for chars and ending 0
shdisk:
db 'A' ;disk to return to
db '00' ;user to return to
db ':;' ;log in and next command
shname:
db 'MENU ' ;program name (filled in at installation)
shfile:
ds 13 ;file name (12) and ending 0
end