home *** CD-ROM | disk | FTP | other *** search
- ;
- ; PROGRAM: VMENUCK
- ; AUTHOR: RICHARD CONN
- ; VERSION: 1.0
- ; DATE: 22 July 84
- ; PREVIOUS VERSIONS: None
- ; DERIVATION: MENUCK 1.0 (18 May 84)
- ;
- VERS EQU 10 ;VERSION NUMBER
- z3env SET 0f400h
-
- ;
- ; VMENUCK is used to check the syntax of a MENU.VMN file for the ZCPR3
- ; menu processor, VMENU. VMENU was optimized for size and runtime speed, and
- ; I tried to keep the size under 2K (and succeeded, for that matter). In
- ; keeping VMENU small, the error diagnostics it gives are quite limited, with
- ; a variety of errors producing the message "Str Err" for MENU.VMN
- ; structure error.
- ;
- ; VMENUCK is intended to be used to check the syntax and other features
- ; of a user's MENU.VMN before allowing VMENU to run with it. In this way,
- ; many errors may be caught before the MENU.VMN file comes into common use,
- ; and there is plenty of space for informative diagnostics.
- ;
-
- ;
- ; MENU Constants
- ;
- MCMD EQU ':' ;Menu Jump Command
- MINDIC EQU '#' ;Menu Indic
- GOPTION EQU '-' ;Global Option Indic
- XOPTION EQU 'X'
- VARFLAG EQU '$' ;Variable Flag
-
- ;
- ; CP/M Constants
- ;
- bentry equ 5 ;BDOS Entry
- fcb equ 5ch ;FCB
- tbuff equ 80h ;Temp I/O Buffer
- cr equ 0dh
- lf equ 0ah
- EOF equ 'Z'-'@' ;^Z=EOF
-
- ;
- ; Externals
- ;
- ext z3init,zfname,z3log
-
- ext caps,crlf,eval10,retud
- ext f$open,f$close,f$read
- ext print,cout
- ext moveb
- ext phldc,padc,pfn2,pafdc
- ext codend
-
- ;
- ; 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 Z3BASE.LIB
- MACLIB SYSENV.LIB
- z3eadr:
- jmp start
- SYSENV
- start:
- lxi h,z3eadr ;pt to ZCPR3 environment
- endif
-
- ;
- ; Start of Program -- Initialize ZCPR3 Environment
- ;
- call z3init ;initialize the ZCPR3 Env and the VLIB Env
-
- call print
- db 'VMENUCK Version '
- db (vers/10)+'0','.',(vers mod 10)+'0',0
-
- lda fcb+1 ;get first char
- cpi ' ' ;no file name?
- jz help
- cpi '/' ;option?
- jnz start1
- ;
- ; Print Help Message
- ;
- help:
- call print
- db cr,lf,'Syntax:'
- db cr,lf,' VMENUCK dir:filename.typ <-- Check File'
- db cr,lf,' VMENUCK dir:filename <-- Check filename.VMN'
- db 0
- ret
-
- ;
- ; Begin serious processing -- locate the file pted to by HL
- ;
- start1:
- lxi d,fcb ;pt to FCB
- call z3log ;log into indicated FCB
-
- ;
- ; Set File Type to MNU if not specified
- ;
- start2:
- lxi h,fcb+9 ;pt to file type
- mov a,m ;get first char
- cpi ' ' ;set type if <SP>
- jnz start3
- push b ;save BC
- lxi d,mnutyp ;set type to MNU
- xchg
- mvi b,3 ;3 bytes
- call moveb
- pop b ;get BC
- ;
- ; Try to Open the File
- ;
- start3:
- lxi d,fcb ;prepare to open file
- xra a ;A=0 to select current disk
- stax d
- call f$open ;open file
- jz readfile ;read in file if OK
- call print
- db cr,lf,' File Not Found',0
- ret
- ;
- ; Read in File
- ;
- readfile:
- call codend ;get address of first block
- readloop:
- lxi d,fcb ;read block
- call f$read ;do it
- ora a ;check for error
- jnz readdone
- lxi d,tbuff ;pt to block just read in
- mvi b,128 ;128 bytes
- readmove:
- ldax d ;get byte
- ani 7fh ;mask MSB
- mov m,a ;put byte
- inx h ;pt to next
- inx d
- dcr b ;count down
- jnz readmove
- xchg ;DE pts to next block
- lhld bentry+1 ;get address of BDOS
- mov a,h ;check for possible overflow
- sui 10 ;10 pages below BDOS is limit
- cmp d ;within range?
- xchg ;HL pts to next block
- jnc readloop ;continue read if within range
- call print
- db cr,lf,' TPA Overflow -- VMENU File is Too Big',0
- ret
- ;
- ; Read is Done -- Store Ending ^Z and Set Initial Values
- ;
- readdone:
- mvi m,EOF ;Store ^Z to ensure EOF
- lxi d,fcb ;Close File
- call f$close
- mvi a,0ffh ;A = -1
- sta menunum ;set menu number
- sta maxnum ;set max number of all menus
- lxi h,0 ;HL=0
- shld errors ;Set Error Count to 0
- inx h ;HL=1
- shld linenum ;Set Line Number to 1
- ;
- ; Count Number of Menus
- ;
- call codend ;Pt to First Byte
- mov a,m ;get first byte
- ;
- ; Skip to Beginning of Menu Display
- ;
- mdskip:
- cpi EOF ;EOF?
- jz mdone
- cpi MINDIC ;beginning of display?
- jz mcgo ;now go skip commands
- call lskip ;skip to next line
- jmp mdskip
- mcgo:
- inx h ;pt to char after MINDIC
- mov a,m ;another MINDIC?
- cpi MINDIC
- jz mdone ;done if 2 in a row
- lda maxnum ;get menu number count
- inr a ;found another one
- sta maxnum
- mcskip:
- call lskip ;skip to next line
- jz mdone ;done if premature EOF
- cpi MINDIC ;end of display?
- jnz mcskip
- inx h ;pt to char after MINDIC
- mov a,m ;get it
- jmp mdskip
- ;
- ; Check for Valid First Character
- ;
- mdone:
- call print
- db cr,lf,'VMenu Syntax Check on ',0
- call retud ;get dir
- mov a,b ;get disk
- adi 'A'
- call cout
- mov a,c ;get user
- call pafdc
- mvi a,':'
- call cout
- lxi d,fcb+1 ;pt to FCB
- call pfn2
- call print ;Print Header
- db cr,lf
- db cr,lf,' Line Comment/Error Message'
- db cr,lf,' ---- ---------------------',0
-
- xra a ;set no global option
- sta gopt
- call codend ;get address of first byte
- mov a,m ;get first char
- cpi GOPTION ;global options?
- jnz newmenu ;process globals
- mvi a,0ffh ;set global option
- sta gopt
- call lprint
- db '** Global Options Detected **',0
- call optchk ;check options
- xra a ;set no global option
- sta gopt
- call nxtline ;advance to next line
- ;
- ; This is the main entry point for processing a menu
- ;
- newmenu:
- mov a,m ;get Menu Indicator
- cpi MINDIC ;must be MINDIC
- jz nm1
- call newerr ;add to error count
- call lprint
- db ' New Menu Expected, But ',MINDIC,' NOT Found -- '
- db 'Aborting',0
- jmp errxit
- ;
- ; Print that we have a new menu
- ;
- nm1:
- call lprint
- db '** Menu Number ',0
- lda menunum ;increment menu number
- inr a
- sta menunum
- call padc
- call optchk ;check options
- ;
- ; Skip Thru Display
- ;
- nm2:
- call nxtline ;skip to next line
- jnz nm2a ;continue if no EOF
- earlyeof:
- call newerr ;add to error count
- call lprint
- db ' Premature EOF Encountered',0
- jmp errxit
- nm2a:
- cpi MINDIC ;Menu Indicator?
- jnz nm2 ;Continue
- ;
- ; Move Thru Menu Commands
- ;
- nm3:
- call mcmd1 ;check Menu Command Line
- jz earlyeof
- call lcheck ;check line
- cpi MINDIC ;check for menu indicator
- jnz nm3 ;continue until menu indicator encountered
- inx h ;check for 2 indicators in a row for end
- mov a,m ;get 2nd char
- dcx h ;back up in case it is not
- cpi MINDIC ;2 in a row?
- jnz newmenu ;process as new menu if not
- errxit:
- call lprint
- db '** End of Menu Check **',cr,lf,' ',0
- lhld errors ;check error count
- mov a,h ;check for Zero
- ora l
- jnz err1
- call print
- db 'No',0
- jmp err2
- err1:
- call phldc ;print as decimal
- err2:
- call print
- db ' Errors Detected',0
- ret
-
- ;
- ; Utilities
- ;
-
- ;
- ; LPRINT -- Print "Line # "+text
- ;
- lprint:
- call crlf ;new line
- push h ;save HL
- lhld linenum ;get line number
- call phldc ;print as decimal
- pop h ;restore HL
- mvi a,' ' ;print <sp>
- call cout
- jmp print ;print text
- ;
- ; NXTLINE -- Advance to next line, check for EOF, and increment Line Number
- ; LSKIP -- Advance to next line and check for EOF
- ; Return with HL pting to first char of next line and Z Set if EOF
- ;
- nxtline:
- push h ;increment line count
- lhld linenum ;add 1
- inx h
- shld linenum
- pop h ;fall thru to skipping
- lskip:
- mov a,m ;get char
- cpi EOF ;EOF?
- rz
- inx h ;pt to next
- cpi lf ;line feed?
- jnz lskip ;continue if not
- mov a,m ;get first char of next line
- cpi EOF ;check for EOF
- ret
- ;
- ; MCMD1 -- Check Menu Line, check for EOF, and increment Line Number
- ; Return with HL pting to first char of next line and Z Set if EOF
- ;
- mcmd1:
- mov a,m ;get char
- cpi EOF ;EOF?
- jz mcmdx
- inx h ;pt to next
- cpi VARFLAG ;variable?
- jz mcmd2
- cpi lf ;line feed?
- jnz mcmd1 ;continue if not
- mcmdx:
- push h ;increment line count
- lhld linenum ;add 1
- inx h
- shld linenum
- pop h ;fall thru to skipping
- mov a,m ;get first char of next line
- cpi EOF ;check for EOF
- ret
- ;
- ; Check Variable
- ;
- mcmd2:
- mov a,m ;get char
- ani 7fh ;mask
- call caps ;capitalize
- inx h ;pt to next
- cpi VARFLAG ;OK if double VARFLAG
- jz mcmd1
- cpi 'D' ;OK if D
- jz mcmd1
- cpi 'U' ;OK if U
- jz mcmd1
- cpi 'F' ;filename.typ?
- jz mcmd3
- cpi 'N' ;filename?
- jz mcmd3
- cpi 'T' ;filetype?
- jz mcmd3
- cpi 'P' ;pointed-to file?
- jz mcmd6
- ;
- ; Invalid Variable
- ;
- dcx h ;pt to previous (bad char)
- push psw ;save char
- call lprint
- db ' Variable Error (Not $, D, U, F, N, or T) - ',0
- pop psw ;get char
- call cout ;print it
- call newerr ;increment error count
- jmp mcmd1
- ;
- ; Digit from 1 to 4 should follow
- ;
- mcmd3:
- mov a,m ;get next char
- inx h ;pt to next
- ani 7fh ;mask and cap
- call caps
- cpi '1' ;must be from 1 to 4
- jc mcmd4
- cpi '5'
- jc mcmd1
- ;
- ; Invalid Digit
- ;
- mcmd4:
- push psw
- call lprint
- db ' Invalid Digit for F, N, or T Variable (not 1-4) - ',0
- mcmd5:
- pop psw
- dcx h ;pt to invalid char
- call cout
- call newerr ;increment error count
- jmp mcmd1
-
- ;
- ; Check for Pointed to File
- ;
- mcmd6:
- mov a,m ;get next char
- inx h ;pt to next
- ani 7fh ;mask
- call caps
- cpi 'F'
- jz mcmd1
- cpi 'N'
- jz mcmd1
- cpi 'T'
- jz mcmd1
- push psw ;save char
- call lprint
- db ' Invalid Pointed-to File Option (not F, N, or T) - ',0
- jmp mcmd5 ;process error and back up ptr
-
- ;
- ; OPTCHK -- Check Line Pted to by HL for Valid GOPTION and MINDIC options
- ; Do Not Affect HL
- ; Print Error Message and Character if Invalid Option Found
- ;
- optchk:
- push h ;save HL
- push b
- inx h ;skip indicator
- optclp:
- mov a,m ;get char
- call caps ;capitalize
- inx h ;pt to next
- cpi cr ;EOL?
- jz optcdn
- mov b,a ;char in B
- cpi XOPTION ;only exit option allowed
- jz optclp
- call newerr ;increment error count
- call lprint
- db ' Invalid Option: ',0
- mov a,b ;get char
- call cout ;print char
- jmp optclp
- optcdn:
- pop b
- pop h ;restore ptr
- ret
- ;
- ; Increment Error Count
- ;
- newerr:
- push h ;save HL
- lhld errors ;increment error count
- inx h
- shld errors
- pop h ;restore HL
- ret
- ;
- ; Check Line, especially looking for Menu Jump
- ;
- lcheck:
- push h ;save ptr to first char
- inx h ;pt to 2nd char
- mov a,m ;get it
- cpi MCMD ;menu jump?
- jnz lchk1
- inx h ;pt to menu number
- call eval10 ;convert to binary in DE
- mov a,d ;D must be 0
- ora a ;check
- jz lchk0
- lchker:
- call newerr ;increment error count
- call lprint
- db ' Menu Number Out of Range',0
- jmp lchk1
- lchk0:
- lda maxnum ;get max menu number
- cmp e ;check for range
- jc lchker
- lchk1:
- pop h ;restore ptr
- mov a,m ;get first char in line
- ret
- ;
- ; Skip HL over Blanks
- ;
- sblank:
- mov a,m ;get char
- inx h ;pt to next
- cpi ' ' ;blank?
- jz sblank ;continue skipping
- dcx h ;pt to non-blank
- ret
-
- ;
- ; Buffers
- ;
- mnutyp:
- db 'VMN'
- errors:
- ds 2 ;error count
- linenum:
- ds 2 ;current line number
- menunum:
- ds 1 ;current menu number
- maxnum:
- ds 1 ;max menu number
- gopt:
- ds 1 ;global option flag
-
- end