home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol100 / mcheck.mac < prev    next >
Encoding:
Text File  |  1984-04-29  |  12.4 KB  |  634 lines

  1. ;
  2. ;  PROGRAM:  MCHECK
  3. ;  AUTHOR:  RICHARD CONN
  4. ;  VERSION:  1.1
  5. ;  DATE:  6 Jan 83
  6. ;  PREVIOUS VERSIONS:  1.0 (12 Dec 82)
  7. ;
  8. VERS    EQU    11    ;VERSION NUMBER
  9.  
  10. ;
  11. ;    This program is Copyright (c) 1982, 1983 by Richard Conn
  12. ;    All Rights Reserved
  13. ;
  14. ;    ZCPR2 and its utilities, including this one, are released
  15. ; to the public domain.  Anyone who wishes to USE them may do so with
  16. ; no strings attached.  The author assumes no responsibility or
  17. ; liability for the use of ZCPR2 and its utilities.
  18. ;
  19. ;    The author, Richard Conn, has sole rights to this program.
  20. ; ZCPR2 and its utilities may not be sold without the express,
  21. ; written permission of the author.
  22. ;
  23.  
  24.  
  25. ;
  26. ;    MCHECK is used to check the syntax of a MENU.CPR file for the ZCPR2
  27. ; menu processor, MENU.  MENU was optimized for size and runtime speed, and
  28. ; I tried to keep the size under 2K (and succeeded, for that matter).  In
  29. ; keeping MENU small, the error diagnostics it gives are quite limited, with
  30. ; a variety of errors producing the message "Str Err" for MENU.CPR
  31. ; structure error.
  32. ;
  33. ;    MCHECK is intended to be used to check the syntax and other features
  34. ; of a user's MENU.CPR before allowing MENU to run with it.  In this way,
  35. ; many errors may be caught before the MENU.CPR file comes into common use,
  36. ; and there is plenty of space for informative diagnostics.
  37. ;
  38.  
  39. ;
  40. ;  MENU Constants
  41. ;
  42. MCMD    EQU    ':'    ;Menu Jump Command
  43. RSM    EQU    '$'    ;System Menu Indic
  44. MINDIC    EQU    '#'    ;Menu Indic
  45. GOPTION    EQU    '-'    ;Global Option Indic
  46. COPTION    EQU    'C'    ;Option chars
  47. DOPTION    EQU    'D'
  48. POPTION    EQU    'P'
  49. XOPTION    EQU    'X'
  50.  
  51. ;
  52. ;  CP/M Constants
  53. ;
  54. bentry    equ    5    ;BDOS Entry
  55. fcb    equ    5ch    ;FCB
  56. tbuff    equ    80h    ;Temp I/O Buffer
  57. cr    equ    0dh
  58. lf    equ    0ah
  59. EOF    equ    'Z'-'@'    ;^Z=EOF
  60.  
  61. ;
  62. ;  SYSLIB Externals
  63. ;
  64.     ext    caps
  65.     ext    crlf
  66.     ext    eval10
  67.     ext    f$open
  68.     ext    f$close
  69.     ext    f$read
  70.     ext    print
  71.     ext    zgpins
  72.     ext    zfname
  73.     ext    retud
  74.     ext    logud
  75.     ext    moveb
  76.     ext    cout
  77.     ext    phldc
  78.     ext    padc
  79.     ext    codend
  80.  
  81. ;
  82. ;  Branch to Start of Program
  83. ;
  84.     jmp    start
  85.  
  86. ;
  87. ;******************************************************************
  88. ;
  89. ;  SINSFORM -- ZCPR2 Utility Standard General Purpose Initialization Format
  90. ;
  91. ;    This data block precisely defines the data format for
  92. ; initial features of a ZCPR2 system which are required for proper
  93. ; initialization of the ZCPR2-Specific Routines in SYSLIB.
  94. ;
  95.  
  96. ;
  97. ;  EXTERNAL PATH DATA
  98. ;
  99. EPAVAIL:
  100.     DB    0FFH    ; IS EXTERNAL PATH AVAILABLE? (0=NO, 0FFH=YES)
  101. EPADR:
  102.     DW    40H    ; ADDRESS OF EXTERNAL PATH IF AVAILABLE
  103.  
  104. ;
  105. ;  INTERNAL PATH DATA
  106. ;
  107. INTPATH:
  108.     DB    0,0    ; DISK, USER FOR FIRST PATH ELEMENT
  109.             ; DISK = 1 FOR A, '$' FOR CURRENT
  110.             ; USER = NUMBER, '$' FOR CURRENT
  111.     DB    0,0
  112.     DB    0,0
  113.     DB    0,0
  114.     DB    0,0
  115.     DB    0,0
  116.     DB    0,0
  117.     DB    0,0    ; DISK, USER FOR 8TH PATH ELEMENT
  118.     DB    0    ; END OF PATH
  119.  
  120. ;
  121. ;  MULTIPLE COMMAND LINE BUFFER DATA
  122. ;
  123. MCAVAIL:
  124.     DB    0FFH    ; IS MULTIPLE COMMAND LINE BUFFER AVAILABLE?
  125. MCADR:
  126.     DW    0FF00H    ; ADDRESS OF MULTIPLE COMMAND LINE BUFFER IF AVAILABLE
  127.  
  128. ;
  129. ;  DISK/USER LIMITS
  130. ;
  131. MDISK:
  132.     DB    4    ; MAXIMUM NUMBER OF DISKS
  133. MUSER:
  134.     DB    31    ; MAXIMUM USER NUMBER
  135.  
  136. ;
  137. ;  FLAGS TO PERMIT LOG IN FOR DIFFERENT USER AREA OR DISK
  138. ;
  139. DOK:
  140.     DB    0FFH    ; ALLOW DISK CHANGE? (0=NO, 0FFH=YES)
  141. UOK:
  142.     DB    0FFH    ; ALLOW USER CHANGE? (0=NO, 0FFH=YES)
  143.  
  144. ;
  145. ;  PRIVILEGED USER DATA
  146. ;
  147. PUSER:
  148.     DB    10    ; BEGINNING OF PRIVILEGED USER AREAS
  149. PPASS:
  150.     DB    'chdir',0    ; PASSWORD FOR MOVING INTO PRIV USER AREAS
  151.     DS    41-($-PPASS)    ; 40 CHARS MAX IN BUFFER + 1 for ending NULL
  152.  
  153. ;
  154. ;  CURRENT USER/DISK INDICATOR
  155. ;
  156. CINDIC:
  157.     DB    '$'    ; USUAL VALUE (FOR PATH EXPRESSIONS)
  158.  
  159. ;
  160. ;  DMA ADDRESS FOR DISK TRANSFERS
  161. ;
  162. DMADR:
  163.     DW    80H    ; TBUFF AREA
  164.  
  165. ;
  166. ;  NAMED DIRECTORY INFORMATION
  167. ;
  168. NDRADR:
  169.     DW    00000H    ; ADDRESS OF MEMORY-RESIDENT NAMED DIRECTORY
  170. NDNAMES:
  171.     DB    64    ; MAX NUMBER OF DIRECTORY NAMES
  172. DNFILE:
  173.     DB    'NAMES   '    ; NAME OF DISK NAME FILE
  174.     DB    'DIR'        ; TYPE OF DISK NAME FILE
  175.  
  176. ;
  177. ;  REQUIREMENTS FLAGS
  178. ;
  179. EPREQD:
  180.     DB    0FFH    ; EXTERNAL PATH?
  181. MCREQD:
  182.     DB    000H    ; MULTIPLE COMMAND LINE?
  183. MXREQD:
  184.     DB    000H    ; MAX USER/DISK?
  185. UDREQD:
  186.     DB    000H    ; ALLOW USER/DISK CHANGE?
  187. PUREQD:
  188.     DB    000H    ; PRIVILEGED USER?
  189. CDREQD:
  190.     DB    000H    ; CURRENT INDIC AND DMA?
  191. NDREQD:
  192.     DB    0FFH    ; NAMED DIRECTORIES?
  193. Z2CLASS:
  194.     DB    0    ; CLASS 0
  195.     DB    'ZCPR2'
  196.     DS    10    ; RESERVED
  197.  
  198. ;
  199. ;  END OF SINSFORM -- STANDARD DEFAULT PARAMETER DATA
  200. ;
  201. ;******************************************************************
  202. ;
  203.  
  204. ;
  205. ;  Start of Program
  206. ;
  207. start:
  208.     call    zgpins    ;init ZCPR2 buffers
  209.     lxi    h,tbuff    ;place zero at end of input buffer
  210.     mov    a,m    ;get char count
  211.     inx    h    ;pt to first char
  212.     push    h    ;save ptr
  213.     add    l
  214.     mov    l,a
  215.     mov    a,h
  216.     aci    0
  217.     mov    h,a
  218.     mvi    m,0    ;store ending zero
  219.     pop    h    ;pt to first char
  220.     call    sblank    ;skip over blanks
  221.     lxi    d,inbuf    ;copy into input line buffer
  222.     push    d    ;save ptr to first char
  223. start0:
  224.     mov    a,m    ;get byte
  225.     stax    d    ;put it
  226.     inx    h    ;pt to next
  227.     inx    d
  228.     ora    a    ;end of string?
  229.     jnz    start0
  230.  
  231.     call    print
  232.     db    'MCHECK  Version '
  233.     db    (vers/10)+'0','.',(vers mod 10)+'0',0
  234.  
  235.     pop    h    ;HL pts to first non-blank char
  236.     mov    a,m    ;get it
  237.     ora    a    ;EOL?
  238.     jz    help
  239.     cpi    '/'    ;option?
  240.     jnz    start1
  241. ;
  242. ;  Print Help Message
  243. ;
  244. help:
  245.     call    print
  246.     db    cr,lf,'    MCHECK is used to perform a syntax check on a MENU.CPR'
  247.     db    cr,lf,'file.  It is invoked with the following forms:'
  248.     db    cr,lf,'        MCHECK or MCHECK //    <-- Print this Help'
  249.     db    cr,lf,'        MCHECK dir:filename.typ    <-- Check File'
  250.     db    cr,lf,'        MCHECK dir:filename    <-- Check filename.CPR'
  251.     db    cr,lf,0
  252.     ret
  253.  
  254. ;
  255. ;  Begin serious processing -- locate the file pted to by HL
  256. ;
  257. start1:
  258.     call    retud        ;get current user/disk
  259.     mov    a,b        ;save disk
  260.     sta    cdisk
  261.     mov    a,c        ;save user
  262.     sta    cuser
  263.     lxi    d,mfcb        ;pt to FCB
  264.     call    zfname        ;look for file
  265.     jnz    start2
  266.     call    print
  267.     db    cr,lf,'Error in Disk or User Number -- Aborting',0
  268.     ret
  269. ;
  270. ;  Set File Type to CPR if not specified
  271. ;
  272. start2:
  273.     lxi    h,mtyp        ;pt to file type
  274.     mov    a,m        ;get first char
  275.     cpi    ' '        ;set type if <SP>
  276.     jnz    start3
  277.     push    b        ;save BC
  278.     lxi    d,cprtyp    ;set type to CPR
  279.     xchg
  280.     mvi    b,3        ;3 bytes
  281.     call    moveb
  282.     pop    b        ;get BC
  283. ;
  284. ;  Set User and Disk in C and B
  285. ;
  286. start3:
  287.     mvi    a,0ffh        ;get current disk indicator
  288.     cmp    b        ;B=indicator?
  289.     jnz    start4
  290.     lda    cdisk        ;select current disk
  291.     mov    b,a        ;... in B
  292.     inr    b        ;in range 1-16
  293. start4:
  294.     dcr    b        ;adjust disk to 0-15
  295.     mvi    a,0ffh        ;get current user indicator
  296.     cmp    c        ;C=indicator?
  297.     jz    start5
  298.     mvi    a,'?'        ;if C=All Users, default to current
  299.     cmp    c
  300.     jnz    start6
  301. start5:
  302.     lda    cuser        ;select current user
  303.     mov    c,a
  304. start6:
  305.     call    logud        ;log in user and disk
  306.     lxi    d,mfcb        ;prepare to open file
  307.     xra    a        ;A=0 to select current disk
  308.     stax    d
  309.     call    f$open        ;open file
  310.     jz    readfile    ;read in file if OK
  311.     call    print
  312.     db    cr,lf,'Error in Opening File -- Aborting',0
  313.     ret
  314. ;
  315. ;  Read in File
  316. ;
  317. readfile:
  318.     call    codend        ;get address of first block
  319. readloop:
  320.     lxi    d,mfcb        ;read block
  321.     call    f$read        ;do it
  322.     ora    a        ;check for error
  323.     jnz    readdone
  324.     lxi    d,tbuff        ;pt to block just read in
  325.     mvi    b,128        ;128 bytes
  326. readmove:
  327.     ldax    d        ;get byte
  328.     ani    7fh        ;mask MSB
  329.     mov    m,a        ;put byte
  330.     inx    h        ;pt to next
  331.     inx    d
  332.     dcr    b        ;count down
  333.     jnz    readmove
  334.     xchg            ;DE pts to next block
  335.     lhld    bentry+1    ;get address of BDOS
  336.     mov    a,h        ;check for possible overflow
  337.     sui    10        ;10 pages below BDOS is limit
  338.     cmp    d        ;within range?
  339.     xchg            ;HL pts to next block
  340.     jnc    readloop    ;continue read if within range
  341.     call    print
  342.     db    cr,lf,'TPA Overflow -- MENU.CPR File is Too Big -- Aborting',0
  343.     ret
  344. ;
  345. ;  Read is Done -- Store Ending ^Z and Set Initial Values
  346. ;
  347. readdone:
  348.     mvi    m,EOF    ;Store ^Z to ensure EOF
  349.     lxi    d,mfcb        ;Close File
  350.     call    f$close
  351.     mvi    a,0ffh        ;A = -1
  352.     sta    menunum        ;set menu number
  353.     sta    maxnum        ;set max number of all menus
  354.     lxi    h,0        ;HL=0
  355.     shld    errors        ;Set Error Count to 0
  356.     inx    h        ;HL=1
  357.     shld    linenum        ;Set Line Number to 1
  358. ;
  359. ;  Count Number of Menus
  360. ;
  361.     call    codend        ;Pt to First Byte
  362.     mov    a,m        ;get first byte
  363. ;
  364. ;  Skip to Beginning of Menu Display
  365. ;
  366. mdskip:
  367.     cpi    EOF        ;EOF?
  368.     jz    mdone
  369.     cpi    MINDIC        ;beginning of display?
  370.     jz    mcgo        ;now go skip commands
  371.     call    lskip        ;skip to next line
  372.     jmp    mdskip
  373. mcgo:
  374.     inx    h        ;pt to char after MINDIC
  375.     mov    a,m        ;another MINDIC?
  376.     cpi    MINDIC
  377.     jz    mdone        ;done if 2 in a row
  378.     lda    maxnum        ;get menu number count
  379.     inr    a        ;found another one
  380.     sta    maxnum
  381. mcskip:
  382.     call    lskip        ;skip to next line
  383.     jz    mdone        ;done if premature EOF
  384.     cpi    MINDIC        ;end of display?
  385.     jnz    mcskip
  386.     inx    h        ;pt to char after MINDIC
  387.     mov    a,m        ;get it
  388.     jmp    mdskip
  389. ;
  390. ;  Check for Valid First Character
  391. ;
  392. mdone:
  393.     call    print        ;Print Header
  394.     db    cr,lf
  395.     db    cr,lf,' Line Comment/Error Message'
  396.     db    cr,lf,' ---- ---------------------',0
  397.  
  398.     xra    a        ;set no global option
  399.     sta    gopt
  400.     call    codend        ;get address of first byte
  401.     mov    a,m        ;get first char
  402.     cpi    GOPTION        ;global options?
  403.     jnz    newmenu        ;process globals
  404.     mvi    a,0ffh        ;set global option
  405.     sta    gopt
  406.     call    lprint
  407.     db    '** Global Options Detected **',0
  408.     call    optchk        ;check options
  409.     xra    a        ;set no global option
  410.     sta    gopt
  411.     call    nxtline        ;advance to next line
  412. ;
  413. ;  This is the main entry point for processing a menu
  414. ;
  415. newmenu:
  416.     mov    a,m        ;get Menu Indicator
  417.     cpi    MINDIC        ;must be MINDIC
  418.     jz    nm1
  419.     call    newerr        ;add to error count
  420.     call    lprint
  421.     db    'Error -- New Menu Expected, But ',MINDIC,' NOT Found -- '
  422.     db    'Aborting',0
  423.     jmp    errxit
  424. ;
  425. ;  Print that we have a new menu
  426. ;
  427. nm1:
  428.     call    lprint
  429.     db    '** Menu Number ',0
  430.     lda    menunum        ;increment menu number
  431.     inr    a
  432.     sta    menunum
  433.     call    padc
  434.     call    optchk        ;check options
  435. ;
  436. ;  Skip Thru Display
  437. ;
  438. nm2:
  439.     call    nxtline        ;skip to next line
  440.     jnz    nm2a        ;continue if no EOF
  441. earlyeof:
  442.     call    newerr        ;add to error count
  443.     call    lprint
  444.     db    'Error -- Premature EOF Encountered -- Aborting',0
  445.     jmp    errxit
  446. nm2a:
  447.     cpi    MINDIC        ;Menu Indicator?
  448.     jnz    nm2        ;Continue
  449. ;
  450. ;  Move Thru Menu Commands
  451. ;
  452. nm3:
  453.     call    nxtline        ;skip to next line
  454.     jz    earlyeof
  455.     call    lcheck        ;check line
  456.     cpi    MINDIC        ;check for menu indicator
  457.     jnz    nm3        ;continue until menu indicator encountered
  458.     inx    h        ;check for 2 indicators in a row for end
  459.     mov    a,m        ;get 2nd char
  460.     dcx    h        ;back up in case it is not
  461.     cpi    MINDIC        ;2 in a row?
  462.     jnz    newmenu        ;process as new menu if not
  463. errxit:
  464.     call    lprint
  465.     db    '** End of Menu Check **',cr,lf,'    ',0
  466.     lhld    errors        ;check error count
  467.     mov    a,h        ;check for Zero
  468.     ora    l
  469.     jnz    err1
  470.     call    print
  471.     db    'No',0
  472.     jmp    err2
  473. err1:
  474.     call    phldc        ;print as decimal
  475. err2:
  476.     call    print
  477.     db    ' Errors Detected',0
  478.     ret
  479.  
  480. ;
  481. ;  Utilities
  482. ;
  483.  
  484. ;
  485. ;  LPRINT -- Print "Line # "+text
  486. ;
  487. lprint:
  488.     call    crlf        ;new line
  489.     push    h        ;save HL
  490.     lhld    linenum        ;get line number
  491.     call    phldc        ;print as decimal
  492.     pop    h        ;restore HL
  493.     mvi    a,' '        ;print <sp>
  494.     call    cout
  495.     jmp    print        ;print text
  496. ;
  497. ;  NXTLINE -- Advance to next line, check for EOF, and increment Line Number
  498. ;  LSKIP -- Advance to next line and check for EOF
  499. ;    Return with HL pting to first char of next line and Z Set if EOF
  500. ;
  501. nxtline:
  502.     push    h        ;increment line count
  503.     lhld    linenum        ;add 1
  504.     inx    h
  505.     shld    linenum
  506.     pop    h        ;fall thru to skipping
  507. lskip:
  508.     mov    a,m        ;get char
  509.     cpi    EOF        ;EOF?
  510.     rz
  511.     inx    h        ;pt to next
  512.     cpi    lf        ;line feed?
  513.     jnz    lskip        ;continue if not
  514.     mov    a,m        ;get first char of next line
  515.     cpi    EOF        ;check for EOF
  516.     ret
  517. ;
  518. ;  OPTCHK -- Check Line Pted to by HL for Valid GOPTION and MINDIC options
  519. ;    Do Not Affect HL
  520. ;    Print Error Message and Character if Invalid Option Found
  521. ;
  522. optchk:
  523.     push    h        ;save HL
  524.     push    b
  525.     inx    h        ;skip indicator
  526. optclp:
  527.     mov    a,m        ;get char
  528.     call    caps        ;capitalize
  529.     inx    h        ;pt to next
  530.     cpi    cr        ;EOL?
  531.     jz    optcdn
  532.     mov    b,a        ;char in B
  533.     lda    gopt        ;global option?
  534.     ora    a        ;0=no
  535.     mov    a,b        ;get char
  536.     jnz    optcl1        ;skip RSM test if it is global
  537.     cpi    RSM        ;System Menu?
  538.     jz    optclp
  539. optcl1:
  540.     cpi    COPTION        ;check options
  541.     jz    optclp
  542.     cpi    DOPTION
  543.     jz    optclp
  544.     cpi    POPTION
  545.     jz    optclp
  546.     cpi    XOPTION
  547.     jz    optclp
  548.     call    newerr        ;increment error count
  549.     call    lprint
  550.     db    'Error -- Invalid Option: ',0
  551.     mov    a,b        ;get char
  552.     call    cout        ;print char
  553.     jmp    optclp
  554. optcdn:
  555.     pop    b
  556.     pop    h        ;restore ptr
  557.     ret
  558. ;
  559. ;  Increment Error Count
  560. ;
  561. newerr:
  562.     push    h    ;save HL
  563.     lhld    errors    ;increment error count
  564.     inx    h
  565.     shld    errors
  566.     pop    h    ;restore HL
  567.     ret
  568. ;
  569. ;  Check Line, especially looking for Menu Jump
  570. ;
  571. lcheck:
  572.     push    h    ;save ptr to first char
  573.     inx    h    ;pt to 2nd char
  574.     mov    a,m    ;get it
  575.     cpi    MCMD    ;menu jump?
  576.     jnz    lchk1
  577.     inx    h    ;pt to menu number
  578.     call    eval10    ;convert to binary in DE
  579.     mov    a,d    ;D must be 0
  580.     ora    a    ;check
  581.     jz    lchk0
  582. lchker:
  583.     call    newerr    ;increment error count
  584.     call    lprint
  585.     db    'Error -- Menu Number Out of Range',0
  586.     jmp    lchk1
  587. lchk0:
  588.     lda    maxnum    ;get max menu number
  589.     cmp    e    ;check for range
  590.     jc    lchker
  591. lchk1:
  592.     pop    h    ;restore ptr
  593.     mov    a,m    ;get first char in line
  594.     ret
  595. ;
  596. ;  Skip HL over Blanks
  597. ;
  598. sblank:
  599.     mov    a,m    ;get char
  600.     inx    h    ;pt to next
  601.     cpi    ' '    ;blank?
  602.     jz    sblank    ;continue skipping
  603.     dcx    h    ;pt to non-blank
  604.     ret
  605.  
  606. inbuf:
  607.     ds    250    ;input line buffer
  608. cdisk:
  609.     ds    1    ;current disk
  610. cuser:
  611.     ds    1    ;current user
  612. mfcb:
  613.     db    0
  614.     ds    8    ;file name
  615. mtyp:
  616.     ds    3    ;file type
  617.     ds    4
  618.     ds    16
  619.     ds    4
  620. cprtyp:
  621.     db    'CPR'
  622. errors:
  623.     ds    2    ;error count
  624. linenum:
  625.     ds    2    ;current line number
  626. menunum:
  627.     ds    1    ;current menu number
  628. maxnum:
  629.     ds    1    ;max menu number
  630. gopt:
  631.     ds    1    ;global option flag
  632.  
  633.     end
  634.