home *** CD-ROM | disk | FTP | other *** search
- ;
- ; PROGRAM: MCHECK
- ; AUTHOR: RICHARD CONN
- ; VERSION: 1.1
- ; DATE: 6 Jan 83
- ; PREVIOUS VERSIONS: 1.0 (12 Dec 82)
- ;
- VERS EQU 11 ;VERSION NUMBER
-
- ;
- ; This program is Copyright (c) 1982, 1983 by Richard Conn
- ; All Rights Reserved
- ;
- ; ZCPR2 and its utilities, including this one, are released
- ; to the public domain. Anyone who wishes to USE them may do so with
- ; no strings attached. The author assumes no responsibility or
- ; liability for the use of ZCPR2 and its utilities.
- ;
- ; The author, Richard Conn, has sole rights to this program.
- ; ZCPR2 and its utilities may not be sold without the express,
- ; written permission of the author.
- ;
-
-
- ;
- ; MCHECK is used to check the syntax of a MENU.CPR file for the ZCPR2
- ; menu processor, MENU. MENU was optimized for size and runtime speed, and
- ; I tried to keep the size under 2K (and succeeded, for that matter). In
- ; keeping MENU small, the error diagnostics it gives are quite limited, with
- ; a variety of errors producing the message "Str Err" for MENU.CPR
- ; structure error.
- ;
- ; MCHECK is intended to be used to check the syntax and other features
- ; of a user's MENU.CPR before allowing MENU to run with it. In this way,
- ; many errors may be caught before the MENU.CPR file comes into common use,
- ; and there is plenty of space for informative diagnostics.
- ;
-
- ;
- ; MENU Constants
- ;
- MCMD EQU ':' ;Menu Jump Command
- RSM EQU '$' ;System Menu Indic
- MINDIC EQU '#' ;Menu Indic
- GOPTION EQU '-' ;Global Option Indic
- COPTION EQU 'C' ;Option chars
- DOPTION EQU 'D'
- POPTION EQU 'P'
- XOPTION EQU 'X'
-
- ;
- ; 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
-
- ;
- ; SYSLIB Externals
- ;
- ext caps
- ext crlf
- ext eval10
- ext f$open
- ext f$close
- ext f$read
- ext print
- ext zgpins
- ext zfname
- ext retud
- ext logud
- ext moveb
- ext cout
- ext phldc
- ext padc
- ext codend
-
- ;
- ; Branch to Start of Program
- ;
- jmp start
-
- ;
- ;******************************************************************
- ;
- ; SINSFORM -- ZCPR2 Utility Standard General Purpose Initialization Format
- ;
- ; This data block precisely defines the data format for
- ; initial features of a ZCPR2 system which are required for proper
- ; initialization of the ZCPR2-Specific Routines in SYSLIB.
- ;
-
- ;
- ; EXTERNAL PATH DATA
- ;
- EPAVAIL:
- DB 0FFH ; IS EXTERNAL PATH AVAILABLE? (0=NO, 0FFH=YES)
- EPADR:
- DW 40H ; ADDRESS OF EXTERNAL PATH IF AVAILABLE
-
- ;
- ; INTERNAL PATH DATA
- ;
- INTPATH:
- DB 0,0 ; DISK, USER FOR FIRST PATH ELEMENT
- ; DISK = 1 FOR A, '$' FOR CURRENT
- ; USER = NUMBER, '$' FOR CURRENT
- DB 0,0
- DB 0,0
- DB 0,0
- DB 0,0
- DB 0,0
- DB 0,0
- DB 0,0 ; DISK, USER FOR 8TH PATH ELEMENT
- DB 0 ; END OF PATH
-
- ;
- ; MULTIPLE COMMAND LINE BUFFER DATA
- ;
- MCAVAIL:
- DB 0FFH ; IS MULTIPLE COMMAND LINE BUFFER AVAILABLE?
- MCADR:
- DW 0FF00H ; ADDRESS OF MULTIPLE COMMAND LINE BUFFER IF AVAILABLE
-
- ;
- ; DISK/USER LIMITS
- ;
- MDISK:
- DB 4 ; MAXIMUM NUMBER OF DISKS
- MUSER:
- DB 31 ; MAXIMUM USER NUMBER
-
- ;
- ; FLAGS TO PERMIT LOG IN FOR DIFFERENT USER AREA OR DISK
- ;
- DOK:
- DB 0FFH ; ALLOW DISK CHANGE? (0=NO, 0FFH=YES)
- UOK:
- DB 0FFH ; ALLOW USER CHANGE? (0=NO, 0FFH=YES)
-
- ;
- ; PRIVILEGED USER DATA
- ;
- PUSER:
- DB 10 ; BEGINNING OF PRIVILEGED USER AREAS
- PPASS:
- DB 'chdir',0 ; PASSWORD FOR MOVING INTO PRIV USER AREAS
- DS 41-($-PPASS) ; 40 CHARS MAX IN BUFFER + 1 for ending NULL
-
- ;
- ; CURRENT USER/DISK INDICATOR
- ;
- CINDIC:
- DB '$' ; USUAL VALUE (FOR PATH EXPRESSIONS)
-
- ;
- ; DMA ADDRESS FOR DISK TRANSFERS
- ;
- DMADR:
- DW 80H ; TBUFF AREA
-
- ;
- ; NAMED DIRECTORY INFORMATION
- ;
- NDRADR:
- DW 00000H ; ADDRESS OF MEMORY-RESIDENT NAMED DIRECTORY
- NDNAMES:
- DB 64 ; MAX NUMBER OF DIRECTORY NAMES
- DNFILE:
- DB 'NAMES ' ; NAME OF DISK NAME FILE
- DB 'DIR' ; TYPE OF DISK NAME FILE
-
- ;
- ; REQUIREMENTS FLAGS
- ;
- EPREQD:
- DB 0FFH ; EXTERNAL PATH?
- MCREQD:
- DB 000H ; MULTIPLE COMMAND LINE?
- MXREQD:
- DB 000H ; MAX USER/DISK?
- UDREQD:
- DB 000H ; ALLOW USER/DISK CHANGE?
- PUREQD:
- DB 000H ; PRIVILEGED USER?
- CDREQD:
- DB 000H ; CURRENT INDIC AND DMA?
- NDREQD:
- DB 0FFH ; NAMED DIRECTORIES?
- Z2CLASS:
- DB 0 ; CLASS 0
- DB 'ZCPR2'
- DS 10 ; RESERVED
-
- ;
- ; END OF SINSFORM -- STANDARD DEFAULT PARAMETER DATA
- ;
- ;******************************************************************
- ;
-
- ;
- ; Start of Program
- ;
- start:
- call zgpins ;init ZCPR2 buffers
- lxi h,tbuff ;place zero at end of input buffer
- mov a,m ;get char count
- inx h ;pt to first char
- push h ;save ptr
- add l
- mov l,a
- mov a,h
- aci 0
- mov h,a
- mvi m,0 ;store ending zero
- pop h ;pt to first char
- call sblank ;skip over blanks
- lxi d,inbuf ;copy into input line buffer
- push d ;save ptr to first char
- start0:
- mov a,m ;get byte
- stax d ;put it
- inx h ;pt to next
- inx d
- ora a ;end of string?
- jnz start0
-
- call print
- db 'MCHECK Version '
- db (vers/10)+'0','.',(vers mod 10)+'0',0
-
- pop h ;HL pts to first non-blank char
- mov a,m ;get it
- ora a ;EOL?
- jz help
- cpi '/' ;option?
- jnz start1
- ;
- ; Print Help Message
- ;
- help:
- call print
- db cr,lf,' MCHECK is used to perform a syntax check on a MENU.CPR'
- db cr,lf,'file. It is invoked with the following forms:'
- db cr,lf,' MCHECK or MCHECK // <-- Print this Help'
- db cr,lf,' MCHECK dir:filename.typ <-- Check File'
- db cr,lf,' MCHECK dir:filename <-- Check filename.CPR'
- db cr,lf,0
- ret
-
- ;
- ; Begin serious processing -- locate the file pted to by HL
- ;
- start1:
- call retud ;get current user/disk
- mov a,b ;save disk
- sta cdisk
- mov a,c ;save user
- sta cuser
- lxi d,mfcb ;pt to FCB
- call zfname ;look for file
- jnz start2
- call print
- db cr,lf,'Error in Disk or User Number -- Aborting',0
- ret
- ;
- ; Set File Type to CPR if not specified
- ;
- start2:
- lxi h,mtyp ;pt to file type
- mov a,m ;get first char
- cpi ' ' ;set type if <SP>
- jnz start3
- push b ;save BC
- lxi d,cprtyp ;set type to CPR
- xchg
- mvi b,3 ;3 bytes
- call moveb
- pop b ;get BC
- ;
- ; Set User and Disk in C and B
- ;
- start3:
- mvi a,0ffh ;get current disk indicator
- cmp b ;B=indicator?
- jnz start4
- lda cdisk ;select current disk
- mov b,a ;... in B
- inr b ;in range 1-16
- start4:
- dcr b ;adjust disk to 0-15
- mvi a,0ffh ;get current user indicator
- cmp c ;C=indicator?
- jz start5
- mvi a,'?' ;if C=All Users, default to current
- cmp c
- jnz start6
- start5:
- lda cuser ;select current user
- mov c,a
- start6:
- call logud ;log in user and disk
- lxi d,mfcb ;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,'Error in Opening File -- Aborting',0
- ret
- ;
- ; Read in File
- ;
- readfile:
- call codend ;get address of first block
- readloop:
- lxi d,mfcb ;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 -- MENU.CPR File is Too Big -- Aborting',0
- ret
- ;
- ; Read is Done -- Store Ending ^Z and Set Initial Values
- ;
- readdone:
- mvi m,EOF ;Store ^Z to ensure EOF
- lxi d,mfcb ;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 ;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 'Error -- 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 'Error -- Premature EOF Encountered -- Aborting',0
- jmp errxit
- nm2a:
- cpi MINDIC ;Menu Indicator?
- jnz nm2 ;Continue
- ;
- ; Move Thru Menu Commands
- ;
- nm3:
- call nxtline ;skip to next 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
- ;
- ; 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
- lda gopt ;global option?
- ora a ;0=no
- mov a,b ;get char
- jnz optcl1 ;skip RSM test if it is global
- cpi RSM ;System Menu?
- jz optclp
- optcl1:
- cpi COPTION ;check options
- jz optclp
- cpi DOPTION
- jz optclp
- cpi POPTION
- jz optclp
- cpi XOPTION
- jz optclp
- call newerr ;increment error count
- call lprint
- db 'Error -- 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 'Error -- 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
-
- inbuf:
- ds 250 ;input line buffer
- cdisk:
- ds 1 ;current disk
- cuser:
- ds 1 ;current user
- mfcb:
- db 0
- ds 8 ;file name
- mtyp:
- ds 3 ;file type
- ds 4
- ds 16
- ds 4
- cprtyp:
- db 'CPR'
- 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
-