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 / CPM / ZCPR2 / MENU.MQC / MENU.MAC
Text File  |  2000-06-30  |  24KB  |  1,106 lines

  1. ;
  2. ;  PROGRAM:  MENU
  3. ;  AUTHOR:  RICHARD CONN
  4. ;  VERSION:  1.4
  5. ;  DATE:  16 Jan 83
  6. ;  PREVIOUS VERSIONS:  1.3 (9 Jan 83)
  7. ;  PREVIOUS VERSIONS:  1.2 (6 Jan 83), 1.1 (13 Dec 82), 1.0 (11 DEC 82)
  8. ;
  9. VERS    EQU    14
  10.  
  11. ;
  12. ;    This program is Copyright (c) 1982, 1983 by Richard Conn
  13. ;    All Rights Reserved
  14. ;
  15. ;    ZCPR2 and its utilities, including this one, are released
  16. ; to the public domain.  Anyone who wishes to USE them may do so with
  17. ; no strings attached.  The author assumes no responsibility or
  18. ; liability for the use of ZCPR2 and its utilities.
  19. ;
  20. ;    The author, Richard Conn, has sole rights to this program.
  21. ; ZCPR2 and its utilities may not be sold without the express,
  22. ; written permission of the author.
  23. ;
  24.  
  25.  
  26. ;
  27. ;    MENU is the ZCPR2 Menu Processor.  It loads, looks for the MENU.CPR
  28. ; file, and then displays it to the user (optionally) and prompts him for
  29. ; a single-character command.  The ZCPR2 Multiple Command Line Buffer must
  30. ; be installed for MENU to work, and MENU uses this buffer to chain to the
  31. ; programs selected by the user and return to itself at the proper place.
  32. ;
  33. ;    MENU supports multiple menus within one MENU.CPR file.  When a command
  34. ; is invoked, MENU returns to the menu the command came from.
  35. ;
  36. ;    MENU will ONLY RUN on ZCPR2 systems with the Multiple Command Line
  37. ; Buffer Option enabled.
  38. ;
  39.  
  40. ;
  41. ;  Menu Constants
  42. ;
  43.  
  44. ;  1 Special Menu Command Chars
  45. RNM        EQU    '>'        ;NEXT MENU
  46. RNMP        EQU    '.'        ;NEXT MENU PRIME (ALTERNATE)
  47. RLM        EQU    '<'        ;LAST MENU
  48. RLMP        EQU    ','        ;LAST MENU PRIME (ALTERNATE)
  49. RFM        EQU    '*'        ;FIRST MENU
  50. RSM        EQU    '$'        ;SYSTEM MENU (PASSWORD REQUIRED)
  51.                     ; THIS IS SAME AS CONTROL CHAR
  52. ;  2 Internal Menu Control Chars
  53. MCMD        EQU    ':'        ;COMMAND TO JUMP TO ANOTHER MENU
  54. PCHAR        EQU    '"'        ;INDICATES AUTO PROMPT FOR SPECIFIC CMD
  55. MINDIC        EQU    '#'        ;MENU SECTION INDICATOR
  56. MFIRST        EQU    '%'        ;FIRST MENU INDICATOR
  57. GOPTION        EQU    '-'        ;GLOBAL OPTION INDICATOR
  58. WOPTION        EQU    '!'        ;ACTIVATES WAIT UPON RETURN
  59. WAITCH        EQU    'W'        ;CHAR IN COMMAND LINE TO CAUSE WAIT
  60.  
  61. ;  3 Menu Option Chars
  62. COPTION        EQU    'C'        ;DISPLAY COMMAND LINE TO USER
  63. DOPTION        EQU    'D'        ;DISPLAY MENU TO USER
  64. POPTION        EQU    'P'        ;PAGE OUT MENU DISPLAY TO USER
  65. XOPTION        EQU    'X'        ;DISABLE CP/M RETURN
  66.  
  67. ;  4 Miscellaneous
  68. CMDSEP        EQU    ';'        ;ZCPR2 COMMAND SEPARATOR
  69. NLINES        EQU    24        ;NUMBER OF LINES ON USER'S CRT
  70.  
  71. ;
  72. ;  CP/M CONSTANTS
  73. ;
  74. wboot    equ    0
  75. bentry    equ    5
  76. fcb    equ    5ch
  77. tbuff    equ    80h
  78. CR    equ    0dh
  79. LF    equ    0ah
  80. CTRLC    equ    'C'-'@'
  81. TAB    equ    'I'-'@'
  82. CTRLZ    equ    'Z'-'@'
  83.  
  84. ;
  85. ;  Externals from SYSLIB
  86. ;
  87.     ext    print
  88.     ext    cin
  89.     ext    cout
  90.     ext    caps
  91.     ext    crlf
  92.     ext    madc
  93.     ext    bline
  94.     ext    initfcb
  95.     ext    f$open
  96.     ext    f$close
  97.     ext    f$read
  98.     ext    codend
  99.     ext    hmovb
  100. ;
  101. ;  Branch to Start of Program
  102. ;
  103.     .z80            ;Zilog Z80 Mnemonics
  104.     jp    start
  105.  
  106. ;
  107. ;******************************************************************
  108. ;
  109. ;  SINSFORM -- ZCPR2 Utility Standard General Purpose Initialization Format
  110. ;
  111. ;    This data block precisely defines the data format for
  112. ; initial features of a ZCPR2 system which are required for proper
  113. ; initialization of the ZCPR2-Specific Routines in SYSLIB.
  114. ;
  115.  
  116. ;
  117. ;  EXTERNAL PATH DATA
  118. ;
  119. EPAVAIL:
  120.     DB    0FFH    ; IS EXTERNAL PATH AVAILABLE? (0=NO, 0FFH=YES)
  121. EPADR:
  122.     DW    40H    ; ADDRESS OF EXTERNAL PATH IF AVAILABLE
  123.  
  124. ;
  125. ;  INTERNAL PATH DATA
  126. ;
  127. INTPATH:
  128.     DB    0,0    ; DISK, USER FOR FIRST PATH ELEMENT
  129.             ; DISK = 1 FOR A, '$' FOR CURRENT
  130.             ; USER = NUMBER, '$' FOR CURRENT
  131.     DB    0,0
  132.     DB    0,0
  133.     DB    0,0
  134.     DB    0,0
  135.     DB    0,0
  136.     DB    0,0
  137.     DB    0,0    ; DISK, USER FOR 8TH PATH ELEMENT
  138.     DB    0    ; END OF PATH
  139.  
  140. ;
  141. ;  MULTIPLE COMMAND LINE BUFFER DATA
  142. ;
  143. MCAVAIL:
  144.     DB    000H    ; IS MULTIPLE COMMAND LINE BUFFER AVAILABLE?
  145. MCADR:
  146.     DW    0FF00H    ; ADDRESS OF MULTIPLE COMMAND LINE BUFFER IF AVAILABLE
  147.  
  148. ;
  149. ;  DISK/USER LIMITS
  150. ;
  151. MDISK:
  152.     DB    4    ; MAXIMUM NUMBER OF DISKS
  153. MUSER:
  154.     DB    31    ; MAXIMUM USER NUMBER
  155.  
  156. ;
  157. ;  FLAGS TO PERMIT LOG IN FOR DIFFERENT USER AREA OR DISK
  158. ;
  159. DOK:
  160.     DB    0FFH    ; ALLOW DISK CHANGE? (0=NO, 0FFH=YES)
  161. UOK:
  162.     DB    0FFH    ; ALLOW USER CHANGE? (0=NO, 0FFH=YES)
  163.  
  164. ;
  165. ;  PRIVILEGED USER DATA
  166. ;
  167. PUSER:
  168.     DB    10    ; BEGINNING OF PRIVILEGED USER AREAS
  169. PPASS:
  170.     DB    'chdir',0    ; PASSWORD FOR MOVING INTO PRIV USER AREAS
  171.     DS    41-($-PPASS)    ; 40 CHARS MAX IN BUFFER + 1 for ending NULL
  172.  
  173. ;
  174. ;  CURRENT USER/DISK INDICATOR
  175. ;
  176. CINDIC:
  177.     DB    '$'    ; USUAL VALUE (FOR PATH EXPRESSIONS)
  178.  
  179. ;
  180. ;  DMA ADDRESS FOR DISK TRANSFERS
  181. ;
  182. DMADR:
  183.     DW    80H    ; TBUFF AREA
  184.  
  185. ;
  186. ;  NAMED DIRECTORY INFORMATION
  187. ;
  188. NDRADR:
  189.     DW    00000H    ; ADDRESS OF MEMORY-RESIDENT NAMED DIRECTORY
  190. NDNAMES:
  191.     DB    64    ; MAX NUMBER OF DIRECTORY NAMES
  192. DNFILE:
  193.     DB    'NAMES   '    ; NAME OF DISK NAME FILE
  194.     DB    'DIR'        ; TYPE OF DISK NAME FILE
  195.  
  196. ;
  197. ;  REQUIREMENTS FLAGS
  198. ;
  199. EPREQD:
  200.     DB    000H    ; EXTERNAL PATH?
  201. MCREQD:
  202.     DB    0FFH    ; MULTIPLE COMMAND LINE?
  203. MXREQD:
  204.     DB    000H    ; MAX USER/DISK?
  205. UDREQD:
  206.     DB    000H    ; ALLOW USER/DISK CHANGE?
  207. PUREQD:
  208.     DB    0FFH    ; PRIVILEGED USER?
  209. CDREQD:
  210.     DB    000H    ; CURRENT INDIC AND DMA?
  211. NDREQD:
  212.     DB    000H    ; NAMED DIRECTORIES?
  213. Z2CLASS:
  214.     DB    0    ; CLASS 0
  215.     DB    'ZCPR2'
  216.     DS    10    ; RESERVED
  217.  
  218. ;
  219. ;  END OF SINSFORM -- STANDARD DEFAULT PARAMETER DATA
  220. ;
  221. ;******************************************************************
  222. ;
  223.  
  224. ;
  225. ;  This is the FCB which defines the default name of the MENU.CPR file
  226. ;
  227. menufcb:
  228.     db    0        ;FCB for MENU.CPR
  229.     db    'MENU    '
  230.     db    'CPR'
  231.     ds    4
  232. scratch:            ;this doubles as a scratch area
  233.     ds    16        ;buffer definition is at end of program
  234.     ds    4        ;36 bytes total
  235.  
  236. ;
  237. ;  Start of Program
  238. ;
  239. start:
  240.     call    print
  241.     db    'MENU  Version '
  242.     db    (vers/10)+'0','.',(vers mod 10)+'0',0
  243.  
  244.     ld    a,(mcavail)    ;multiple command lines must be available
  245.     or    a        ;0=no
  246.     jr    nz,start0
  247.     call    print
  248.     db    ' - MC',0
  249.     ret
  250. start0:
  251.     ld    hl,fcb+1    ;check for menu number
  252.     ld    a,(hl)        ;check first char for delay
  253.     cp    WAITCH        ;wait?
  254.     jr    nz,start1    ;go ahead with number if no wait
  255.     call    sak        ;Strike Any Key
  256.     inc    hl        ;pt to char after W
  257. start1:
  258.     call    eval        ;extract number (will return 0 if none there)
  259.     ld    (reentry),a
  260.  
  261.     call    crlf        ;new line
  262.     ld    de,menufcb    ;pt to MENU.CPR FCB
  263.     call    initfcb        ;init fcb
  264.     call    f$open        ;open file
  265.     ret    nz        ;abort if no menu
  266.  
  267. ;
  268. ;  Load MENU.CPR from disk
  269. ;
  270.     call    codend        ;get address of buffer for menu load
  271.     ld    (mladr),hl    ;set menu load address ptr
  272.  
  273. mload:
  274.     ld    de,menufcb    ;pt to FCB
  275.     call    f$read        ;read in next block
  276.     or    a        ;error?
  277.     jr    nz,mloaddn    ;load done if error
  278.     ld    de,tbuff    ;copy from TBUFF into memory pted to by HL
  279.     ex    de,hl        ;HL is source, DE is dest
  280.     ld    b,128        ;128 bytes
  281.     call    hmovb
  282.     ld    hl,(bentry+1)    ;get address of top of TPA
  283.     ld    a,h        ;set to bottom of ZCPR2
  284.     sub    10
  285.     cp    d        ;about to overflow ZCPR2?
  286.     jr    nc,mload1    ;continue if not
  287.     call    print
  288.     db    cr,lf,'Full',0
  289.     ret
  290. mload1:
  291.     ex    de,hl        ;HL pts to next byte to load to
  292.     jr    mload        ;continue load
  293.  
  294.  
  295. ;
  296. ;  Init Flags and Clear MSB of all bytes in Menu File
  297. ;
  298. mloaddn:
  299.     call    f$close        ;close input file
  300.     ld    (hl),CTRLZ    ;ensure EOF mark
  301.     xor    a        ;A=0
  302.     ld    (cflag),a    ;turn off command display
  303.     ld    (dflag),a    ;turn off menu display
  304.     ld    (pflag),a    ;disallow paging
  305.     ld    (cpmok),a    ;turn off CP/M return flag
  306.     ld    (menuno),a    ;set menu number to start at
  307.     ld    hl,(mladr)    ;pt to beginning of file
  308.     push    hl        ;save ptr
  309. menul1:
  310.     ld    a,(hl)        ;get byte
  311.     and    7FH        ;mask out MSB
  312.     ld    (hl),a        ;put byte
  313.     inc    hl        ;pt to next
  314.     cp    CTRLZ        ;EOF?
  315.     jr    nz,menul1    ;continue if not
  316. ;
  317. ;  Mark all Menu Sections
  318. ;
  319.     pop    hl        ;HL pts to first byte of menu
  320.     ld    b,0FFH        ;set menu counter
  321. ;
  322. ;  Skip to Next Menu
  323. ;
  324. menul2:
  325.     ld    a,(hl)        ;get byte
  326.     cp    CTRLZ        ;error?
  327.     jp    z,mstrerr    ;structure error if so
  328.     cp    MINDIC        ;menu indicator (start of menu?)
  329.     jr    nz,menul4
  330.     or    80H        ;beginning of menu found -- set MSB
  331.     ld    (hl),a        ;put byte
  332.     inc    b        ;increment menu count
  333.     inc    hl        ;pt to next
  334.     ld    a,(hl)        ;get byte
  335.     cp    MINDIC        ;menu indicator (end of menu?)
  336.     jr    z,menul5    ;done if so
  337.     cp    CTRLZ        ;error?
  338.     jp    z,mstrerr
  339.     cp    RSM        ;system menu indicator?
  340.     jr    nz,menul3
  341.     ld    a,b        ;set system menu number
  342.     ld    (smeno),a
  343.     ld    a,0FFH        ;set flag
  344.     ld    (smenfl),a    ;system menu present
  345.     dec    hl        ;back up to beginning of menu
  346.     ld    (smenadr),hl    ;start address
  347.     inc    hl        ;pt to RSM
  348. ;
  349. ;  Skip out Menu Display
  350. ;
  351. menul3:
  352.     call    lskipt        ;skip to beginning of next line
  353.     jr    z,menul4    ;found menu indicator
  354.     cp    CTRLZ        ;error?
  355.     jp    z,mstrerr
  356.     jr    menul3        ;continue if not
  357. ;
  358. ;  Skip to Next Menu
  359. ;
  360. menul4:
  361.     call    lskip        ;skip to beginning of next menu
  362.     jr    menul2
  363. ;
  364. ;  Check Menu Options
  365. ;
  366. menul5:
  367.     ld    hl,(mladr)    ;pt to beginning of file
  368.     ld    a,(hl)        ;check for option
  369.     cp    goption        ;global option char?
  370.     jp    nz,mfile    ;if no global option, scan for menu files
  371.     inc    hl        ;pt to option char
  372. option:
  373.     ld    a,(hl)        ;get option char
  374.     call    caps        ;capitalize
  375.     inc    hl        ;pt to next
  376.     cp    cr        ;done?
  377.     jr    z,optdn
  378.     cp    COPTION        ;display command?
  379.     jr    z,optc
  380.     cp    DOPTION        ;display menu?
  381.     jr    z,optd
  382.     cp    POPTION        ;paging?
  383.     jr    z,optp
  384.     cp    XOPTION        ;exit OK?
  385.     jp    nz,mstrerr    ;option error if not
  386. ;
  387. ;  Disable Exit to CP/M
  388. ;
  389.     ld    a,0FFH        ;turn flag off
  390.     ld    (cpmok),a
  391.     jr    option
  392. ;
  393. ;  Process Paging Option
  394. ;
  395. optp:
  396.     ld    a,0FFH        ;set flag
  397.     ld    (pflag),a
  398.     jr    option
  399. ;
  400. ;  Process Display Menu Option
  401. ;
  402. optd:
  403.     ld    a,0FFH        ;set flag
  404.     ld    (dflag),a
  405.     jr    option
  406. ;
  407. ;  Process Display Command Option
  408. ;
  409. optc:
  410.     ld    a,0FFH        ;set flag
  411.     ld    (cflag),a
  412.     jr    option
  413.  
  414. ;
  415. ;  Option Processing Done
  416. ;
  417. optdn:
  418.     inc    hl        ;skip LF
  419.  
  420. ;
  421. ;  Check for Menu Display
  422. ;
  423. mfile:
  424.     ld    a,(hl)        ;get first byte
  425.     and    7FH        ;mask
  426.     cp    MINDIC        ;start of menu?
  427.     jp    nz,mstrerr
  428.  
  429. ;
  430. ;  Check and Set First Menu
  431. ;
  432.     ld    (mstart),hl    ;save start address of first menu item
  433.     ld    (hl),mfirst+80H    ;set first char of first menu
  434.  
  435. ;
  436. ;  Entry Point for Menu Display
  437. ;    On entry, HL pts to first byte of current menu
  438. ;
  439. dmenu:
  440.     ld    a,(reentry)    ;get reentry flag
  441.     or    a        ;0=no
  442.     jp    nz,mchc0    ;skip to proper menu
  443.     ld    (cstart),hl    ;save start address of current menu
  444.     ld    a,(cflag)    ;copy display command flag for temp use
  445.     ld    (cpflag),a
  446.     ld    a,(dflag)    ;copy display menu flag for temp use
  447.     ld    (dpflag),a
  448.     ld    a,(pflag)    ;copy paging flag for temp use
  449.     ld    (ppflag),a
  450.     inc    hl        ;pt to first char after menu indicator char
  451. dispm1:
  452.     ld    a,(hl)        ;get char
  453.     call    caps        ;capitalize
  454.     inc    hl        ;pt to next
  455.     cp    cr        ;end of options?
  456.     jr    z,dispm2
  457.     cp    RSM        ;system menu?
  458.     jr    z,dispm1    ;ok if so
  459.     cp    COPTION        ;command display?
  460.     jr    z,dispmc
  461.     cp    DOPTION        ;display?
  462.     jr    z,dispmd
  463.     cp    POPTION        ;paging?
  464.     jr    z,dispmp
  465.     cp    XOPTION        ;CP/M return?
  466.     jp    nz,mstrerr    ;error if not
  467. ;
  468. ;  Toggle CP/M Return Option
  469. ;
  470.     ld    a,(cpmok)    ;get flag
  471.     cpl            ;toggle
  472.     ld    (cpmok),a
  473.     jr    dispm1
  474. ;
  475. ;  Toggle Paging Option
  476. ;
  477. dispmp:
  478.     ld    a,(ppflag)    ;get flag
  479.     cpl            ;toggle
  480.     ld    (ppflag),a
  481.     jr    dispm1
  482. ;
  483. ;  Toggle Display Menu Option
  484. ;
  485. dispmd:
  486.     ld    a,(dpflag)    ;get flag
  487.     cpl            ;toggle
  488.     ld    (dpflag),a
  489.     jr    dispm1
  490. ;
  491. ;  Toggle Display Command Option
  492. ;
  493. dispmc:
  494.     ld    a,(cpflag)    ;get flag
  495.     cpl            ;toggle
  496.     ld    (cpflag),a
  497.     jr    dispm1
  498. ;
  499. ;  Done with Menu-Specific Option Processing
  500. ;
  501. dispm2:
  502.     call    lskip        ;skip to LF
  503.     ld    a,(dpflag)    ;display menu?
  504.     or    a        ;0=no
  505.     jr    z,dispm8    ;skip over menu if not
  506.     ld    a,NLINES-1    ;number of lines
  507.     ld    (pagcnt),a    ;set count
  508.     call    crlf        ;new line
  509. ;
  510. ;  Print Next Line of Menu if not Starting with ESCAPE Char (MINDIC)
  511. ;
  512. dispm3:
  513.     ld    a,(hl)        ;get first char of line
  514.     and    7FH        ;mask
  515.     cp    MINDIC        ;done?
  516.     jr    z,dispm4
  517.     call    lprintx        ;print line pted to by HL ending in <CR>
  518.     jr    dispm3
  519. ;
  520. ;  Done with Menu Display -- Page it out
  521. ;
  522. dispm4:
  523.     call    lskip        ;skip to first char of next line (option char)
  524.     ld    (optstrt),hl    ;set start address of options
  525.     ld    a,(pagcnt)    ;number of remaining lines
  526.     ld    b,a        ;count in B
  527.     or    a        ;ok?
  528.     jr    z,dispm6    ;don't do anything if already there
  529.     ld    a,(ppflag)    ;page?
  530.     or    a        ;0=No
  531.     jr    z,dispm6
  532. ;
  533. ;  Page Loop for Menu Display
  534. ;
  535. dispm5:
  536.     call    crlf        ;new line
  537.     djnz    dispm5
  538. ;
  539. ;  Determine if Another Menu Follows
  540. ;
  541. dispm6:
  542.     xor    a        ;A=0
  543.     ld    (nmenfl),a    ;set for no next menu
  544.     ld    a,(hl)        ;ok?
  545.     and    7FH        ;mask
  546.     cp    CTRLZ        ;error if EOF
  547.     jp    z,mstrerr
  548.     cp    MINDIC        ;next menu?
  549.     jr    nz,dispm7
  550.     inc    hl        ;double indicator if end
  551.     ld    a,(hl)
  552.     cp    MINDIC        ;end?
  553.     jr    z,dispm9
  554.     cp    RSM        ;system menu = no next menu
  555.     jr    z,dispm9
  556.     ld    a,0FFH        ;set next menu
  557.     ld    (nmenfl),a
  558.     jr    dispm9
  559. dispm7:
  560.     call    lskip        ;skip to next line
  561.     jr    dispm6
  562.  
  563. ;
  564. ;  Skip over current menu so it is not displayed
  565. ;
  566. dispm8:
  567.     call    lskipt        ;skip to beginning of command
  568.     jr    nz,dispm8
  569.     call    lskip        ;skip over end of display indicator
  570.     ld    (optstrt),hl    ;set pointer to options
  571.     jr    dispm6        ;determine if next menu available
  572. dispm9:
  573.  
  574. ;
  575. ;  Ready for Option Input
  576. ;    The following Flags/Values are now set:
  577. ;    CPFLAG -- Display Command Flag (0=No, 0FFH=Yes)
  578. ;    DPFLAG -- Display Menu Flag (0=No, 0FFH=Yes)
  579. ;    OPTSTRT -- Address of First Menu Option
  580. ;    NMENFL -- 0 if no next menu, 0FFH if next menu
  581. ;    MSTART -- Start Address of MINDIC Before Menu Display
  582. ;      (MSTART)=MFIRST with MSB Set
  583. prompt:
  584.     ld    a,0ffh
  585.     ld    (pagcnt),a    ;turn off paging
  586.     ld    (dpflag),a    ;turn on future menu displays
  587.     call    print
  588.     db    'Command (<CR>=Menu',0
  589.     ld    a,(cpmok)    ;OK to return to CP/M?
  590.     or    a        ;0=No
  591.     call    nz,prmptc
  592.     ld    hl,(cstart)    ;pt to first char
  593.     ld    a,(hl)        ;get it
  594.     and    7FH        ;mask
  595.     cp    MFIRST
  596.     call    nz,prmptf    ;print previous menu prompt if not first menu
  597.     ld    a,(nmenfl)    ;next menu available?
  598.     or    a        ;0=No
  599.     call    nz,prmptn        ;print next menu prompt
  600.     call    print
  601.     db    ') - ',0
  602.     call    cin        ;get response
  603.     call    caps        ;capitalize
  604.     call    cout        ;echo
  605.     ld    b,a        ;result in B
  606.  
  607. ;
  608. ;  Check for CR
  609. ;
  610.     cp    CR        ;<CR>?
  611.     jp    z,dispm2    ;reprint menu if so
  612.  
  613. ;
  614. ;  Check for Reboot
  615. ;
  616.     ld    a,(cpmok)    ;ok to abort?
  617.     or    a        ;0=No
  618.     jr    z,prmpt0
  619.     ld    a,b        ;get command
  620.     cp    CTRLC        ;reboot?
  621.     ret    z        ;return to CP/M if so
  622.  
  623. ;
  624. ;  Check for Command to Return to First Menu
  625. ;
  626. prmpt0:
  627.     ld    a,(hl)        ;get it
  628.     and    7FH        ;mask
  629.     cp    MFIRST
  630.     jr    z,prmpt1
  631.     ld    a,b        ;get command
  632.     cp    RFM        ;return to first menu?
  633.     jr    nz,prmpt1
  634.     ld    hl,(mstart)    ;pt to first menu
  635.     xor    a        ;A=0
  636.     ld    (menuno),a
  637.     jp    dmenu        ;resume processing
  638.  
  639. ;
  640. ;  Check for Command to go to Next Menu
  641. ;
  642. prmpt1:
  643.     ld    a,(nmenfl)    ;next menu available?
  644.     or    a        ;0=No
  645.     jr    z,prmpt2
  646.     ld    a,b        ;get command
  647.     cp    RNMP        ;goto next menu?
  648.     jr    z,rnmx
  649.     cp    RNM        ;goto next menu?
  650.     jr    nz,prmpt2
  651. rnmx:
  652.     ld    a,(menuno)    ;increment menu number
  653.     inc    a
  654.     ld    (menuno),a
  655.     ld    hl,(optstrt)    ;pt to first option
  656. nxtmnu:
  657.     ld    a,(hl)        ;get next char
  658.     and    80H        ;mask
  659.     jp    nz,dmenu    ;process next menu
  660.     call    lskip        ;goto beginning of next line
  661.     jr    nxtmnu
  662.  
  663. ;
  664. ;  Check for Command to go to Last Menu
  665. ;
  666. prmpt2:
  667.     ld    a,(hl)        ;get menu char
  668.     and    7FH        ;at first menu?
  669.     cp    MFIRST
  670.     jr    z,prmpt3    ;skip if at first menu
  671.     ld    a,b        ;get command
  672.     cp    RLMP        ;goto last menu?
  673.     jr    z,lstmnu
  674.     cp    RLM        ;goto last menu?
  675.     jr    nz,prmpt3
  676. lstmnu:
  677.     dec    hl        ;back up
  678.     ld    a,(hl)        ;get char
  679.     and    80H        ;look for MSB
  680.     jr    z,lstmnu
  681.     ld    a,(menuno)    ;decrement menu number
  682.     dec    a
  683.     ld    (menuno),a
  684.     jp    dmenu        ;process menu
  685.  
  686. ;
  687. ;  Check for Command to goto System Menu
  688. ;
  689. prmpt3:
  690.     ld    a,(smenfl)    ;system menu available?
  691.     or    a        ;0=No
  692.     jr    z,prmpt4
  693.     ld    a,b        ;get command
  694.     cp    RSM        ;system menu?
  695.     jr    nz,prmpt4
  696.     call    password    ;prompt for and get password
  697.     jp    nz,prompt    ;reprompt if error
  698.     ld    hl,(smenadr)    ;get address of system menu
  699.     ld    a,(smeno)    ;set system menu number
  700.     ld    (menuno),a
  701.     jp    dmenu        ;process menu
  702. ;
  703. ;  This is where additional functions may be added
  704. ;
  705. prmpt4:
  706.  
  707. ;
  708. ;  Check for Option Letter
  709. ;
  710.     ld    hl,(optstrt)    ;pt to first option char
  711. prmptx:
  712.     ld    a,(hl)        ;get it
  713.     call    caps        ;capitalize
  714.     cp    MINDIC        ;at next menu?
  715.     jr    z,prmpter
  716.     cp    b        ;match user selection?
  717.     jr    z,prmptd
  718.     call    lskip        ;skip to next line
  719.     jr    prmptx
  720.  
  721. ;
  722. ;  Invalid Option
  723. ;
  724. prmpter:
  725.     call    print
  726.     db    cr,lf,'Invalid Option',cr,lf,0
  727.     jp    prompt
  728.  
  729. ;
  730. ;  Process Option
  731. ;
  732. prmptd:
  733.     xor    a        ;set no wait
  734.     ld    (wait),a
  735.     inc    hl        ;pt to first letter of command
  736.     ld    a,(hl)        ;get it
  737.     cp    MCMD        ;invoke other menu?
  738.     jp    z,mchcmd    ;menu change command
  739.     cp    WOPTION        ;turn on wait?
  740.     jr    nz,prmptg
  741.     ld    a,0FFH        ;turn on wait
  742.     ld    (wait),a
  743.     inc    hl        ;skip option char
  744. prmptg:
  745.     ex    de,hl        ;DE pts to command letter
  746.     ld    hl,(mcadr)    ;get address of multiple command buffer
  747.     ld    b,h        ;... in BC also
  748.     ld    c,l
  749.     ld    a,4        ;HL=HL+4 for address of first char
  750.     add    a,l
  751.     ld    l,a
  752.     ld    a,h
  753.     adc    a,0
  754.     ld    h,a
  755.     ld    a,l        ;store address
  756.     ld    (bc),a
  757.     inc    bc
  758.     ld    a,h
  759.     ld    (bc),a
  760. cmdcpy:
  761.     ld    a,(de)        ;get command letter
  762.     call    caps        ;capitalize it
  763.     cp    cr        ;done?
  764.     jr    z,ccpyd
  765.     cp    PCHAR        ;prompt?
  766.     jr    z,ccpyp
  767.     ld    (hl),a        ;store it
  768.     inc    hl        ;pt to next
  769.     inc    de
  770.     jr    cmdcpy
  771. ccpyd:
  772.     ld    (hl),CMDSEP    ;store command separator
  773.     inc    hl        ;pt to next char
  774.     ld    de,menucmd    ;now store menu command to chain to when done
  775. ccpd:
  776.     ld    a,(de)        ;get char
  777.     or    a        ;done?
  778.     jr    z,ccpd1
  779.     ld    (hl),a        ;put char
  780.     inc    hl        ;pt to next
  781.     inc    de
  782.     jr    ccpd
  783. ccpd1:
  784.     ld    a,(wait)    ;wait upon return?
  785.     or    a        ;0=No
  786.     jr    z,ccpd2
  787.     ld    (hl),WAITCH    ;set letter in command line
  788.     inc    hl        ;pt to next char
  789. ccpd2:
  790.     ld    a,(menuno)    ;get number of current menu
  791.     ld    de,tnum        ;buffer for number
  792.     push    de        ;save ptr
  793.     call    madc        ;store number
  794.     pop    de
  795.     ld    b,3        ;3 chars max
  796. ccpd3:
  797.     ld    a,(de)        ;get char
  798.     inc    de        ;pt to next
  799.     cp    ' '        ;skip space
  800.     jr    z,ccpd4
  801.     ld    (hl),a        ;put char
  802.     inc    hl        ;pt to next
  803. ccpd4:
  804.     djnz    ccpd3        ;continue until all digits stored
  805.     ld    (hl),0        ;store ending zero
  806.     jp    cmddisp        ;optionally display command
  807. ;
  808. ;  Prompt User for Input and Accept It
  809. ;
  810. ccpyp:
  811.     inc    de        ;pt to first char of prompt
  812.     ex    de,hl        ;HL pts to prompt char, DE pts to buffer
  813.     call    crlf        ;new line
  814.     call    lprint        ;print prompt
  815.     ld    a,0ffh        ;capitalize input from user
  816.     ld    hl,ibuff    ;input line buffer
  817.     call    dots
  818.     call    bline        ;get input from user
  819.     ex    de,hl        ;HL pts to buffer, DE pts to user input
  820. cmdlp:
  821.     ld    a,(de)        ;get char from user
  822.     or    a        ;end of input?
  823.     jr    z,ccpyd        ;store rest of line
  824.     ld    (hl),a        ;store char
  825.     inc    hl        ;pt to next
  826.     inc    de
  827.     jr    cmdlp
  828.  
  829. ;
  830. ;  Check for Display of Loaded Command and Do So if Set
  831. ;
  832. cmddisp:
  833.     ld    a,(cpflag)    ;display command?
  834.     or    a        ;0=No
  835.     ret    z        ;return to OS if so to run command
  836.     call    crlf        ;new line
  837.     ld    hl,(mcadr)    ;pt to first char
  838.     ld    e,(hl)        ;get low-order address
  839.     inc    hl
  840.     ld    d,(hl)        ;get high-order address
  841.     ex    de,hl        ;HL pts to first char
  842. cmdd1:
  843.     ld    a,(hl)        ;get char
  844.     cp    CMDSEP        ;done if command separator
  845.     ret    z
  846.     inc    hl        ;pt to next
  847.     call    cout        ;print char
  848.     jr    cmdd1
  849.  
  850. ;
  851. ;  Menu Change Command -- Jump to Specified Menu
  852. ;
  853. mchcmd:
  854.     inc    hl        ;pt to menu number
  855.     call    eval        ;convert to decimal number in A
  856. ;
  857. ;  Entry Point if MENU is Reinvoked
  858. ;
  859. mchc0:
  860.     ld    (menuno),a
  861.     ld    b,a        ;menu number in B
  862.     xor    a        ;turn off reentry flag
  863.     ld    (reentry),a
  864.     inc    b        ;add 1 for initial offset
  865.     ld    hl,(mstart)    ;pt to first menu
  866. mchc1:
  867.     dec    b        ;count down
  868.     jp    z,dmenu        ;found menu -- process it
  869. mchc2:
  870.     call    lskipt        ;skip to next line
  871.     jr    nz,mchc2    ;continue if not end of menu display
  872. mchc3:
  873.     call    lskipt        ;skip to next line
  874.     jr    nz,mchc3    ;continue if not at end of menu commands
  875.     inc    hl        ;end of MENU.CPR?
  876.     ld    a,(hl)        ;yes if double MINDIC
  877.     and    7FH        ;mask
  878.     cp    MINDIC
  879.     jp    z,mstrerr    ;error if so
  880.     dec    hl        ;pt to first char
  881.     jr    mchc1        ;continue
  882.  
  883. ;
  884. ;  Print Line pted to by HL Ending in <CR>
  885. ;    Decrement PAGCNT
  886. ;
  887. lprintx:
  888.     call    lprint        ;print without <CR>
  889.     jp    crlf        ;do <CR> <LF>
  890. ;
  891. ;  Print Line Pted to by HL; Decrement PAGCNT
  892. ;
  893. lprint:
  894.     ld    b,0        ;set tab counter
  895. lprnt0:
  896.     ld    a,(hl)        ;get char
  897.     inc    hl        ;pt to next
  898.     and    7FH        ;mask MSB
  899.     cp    TAB        ;tabulate?
  900.     jr    z,lprnt2
  901.     cp    cr        ;done?
  902.     jr    z,lprnt1
  903.     call    cout        ;print
  904.     inc    b        ;incr tab counter
  905.     jr    lprnt0
  906. lprnt1:
  907.     inc    hl        ;pt to first char of next line
  908.     ld    a,(pagcnt)    ;count down pages
  909.     dec    a
  910.     ld    (pagcnt),a
  911.     ret    nz
  912.     ld    a,NLINES-1    ;reset paging count
  913.     ld    (pagcnt),a
  914.     call    print
  915.     db    cr,lf,'Pause -',0
  916.     jr    sak
  917. lprnt2:
  918.     ld    a,' '        ;print <SP>
  919.     call    cout
  920.     inc    b        ;incr tab counter
  921.     ld    a,b        ;done?
  922.     and    7        ;every 8
  923.     jr    nz,lprnt2
  924.     jr    lprnt0
  925.  
  926. ;
  927. ;  Strike Any Key Message
  928. ;
  929. sak:
  930.     call    print
  931.     db    ' Strike Any Key - ',0
  932.     call    cin        ;get response
  933.     ret
  934.  
  935. ;
  936. ;  Prompt for, input, and check password (only one chance)
  937. ;    If accepted, return with Zero Flag Set; if not, return with NZ
  938. ;
  939. password:
  940.     call    print
  941.     db    cr,lf,'Pass? ',0
  942.     ld    hl,ibuff    ;pt to input line buffer
  943.     call    dots
  944.     xor    a        ;don't capitalize user input
  945.     call    bline        ;get line from user
  946.     ld    de,ppass    ;pt to system password
  947. pass1:
  948.     ld    a,(de)        ;get sys pass char
  949.     cp    (hl)        ;ok?
  950.     jr    nz,passerr    ;error if no match
  951.     inc    hl        ;pt to next
  952.     inc    de
  953.     or    a        ;end of strings?
  954.     jr    nz,pass1
  955.     ret            ;return with zero set to show match
  956. passerr:
  957.     call    print
  958.     db    cr,lf,'Pass Err',0
  959.     call    sak        ;strike any key
  960.     call    crlf
  961.     ld    a,0FFH        ;set no zero
  962.     or    a
  963.     ret
  964.  
  965. ;
  966. ;  Skip to Beginning of Next Line and Test First Char for Menu Indicator
  967. ;
  968. lskipt:
  969.     call    lskip        ;skip
  970.     ld    a,(hl)        ;get char
  971.     and    7FH        ;mask
  972.     cp    MINDIC        ;test
  973.     ret
  974.  
  975. ;
  976. ;  Skip to Beginning of Next Line
  977. ;
  978. lskip:
  979.     ld    a,(hl)        ;get char
  980.     and    7FH        ;mask out MSB
  981.     inc    hl        ;pt to next
  982.     cp    lf
  983.     jr    nz,lskip
  984.     ret
  985.  
  986. ;
  987. ;  Print CP/M Return Prompt
  988. ;
  989. prmptc:
  990.     call    print
  991.     db    ', ^C=ZCPR2',0
  992.     ret
  993. ;
  994. ;  Print First/Last Menu Chars
  995. ;
  996. prmptf:
  997.     call    print
  998.     db    ', ',RFM,'=1st Menu, ',RLM,'=Prev Menu',0
  999.     ret
  1000. ;
  1001. ;  Print next menu message
  1002. ;
  1003. prmptn:
  1004.     call    print
  1005.     db    ', ',RNM,'=Next Menu',0
  1006.     ret
  1007.  
  1008. ;
  1009. ;  Menu Structure Error -- FATAL
  1010. ;    This message is printed to indicate an error in the structure of
  1011. ; the MENU.CPR file.
  1012. ;
  1013. mstrerr:
  1014.     call    print
  1015.     db    'Str Err',0
  1016.     ret
  1017.  
  1018. ;
  1019. ;  Convert char string pted to by HL into decimal number in A
  1020. ;    On Entry, HL pts to first digit char
  1021. ;    On Exit, HL pts to after last digit char and A=number
  1022. ;
  1023. eval:
  1024.     push    bc        ;save BC
  1025.     ld    b,0        ;set value
  1026. eval1:
  1027.     ld    a,(hl)        ;get digit
  1028.     sub    '0'        ;convert to binary
  1029.     jr    c,eval2
  1030.     cp    10        ;range?
  1031.     jr    nc,eval2
  1032.     inc    hl        ;pt to next digit
  1033.     ld    c,a        ;new digit in C
  1034.     ld    a,b        ;multiply B by 10
  1035.     add    a,a        ;*2
  1036.     add    a,a        ;*4
  1037.     add    a,b        ;*5
  1038.     add    a,a        ;*10
  1039.     add    a,c        ;add in new digit
  1040.     ld    b,a        ;result in B
  1041.     jr    eval1
  1042. eval2:
  1043.     ld    a,b        ;result in A
  1044.     pop    bc        ;restore ptr
  1045.     ret
  1046.  
  1047. ;
  1048. ;  Print Dots to Indicate Buffer Size
  1049. ;
  1050. dots:
  1051.     push    bc        ;save BC
  1052.     ld    a,(ibuff)    ;get count
  1053.     ld    b,a        ;... in B
  1054.     ld    c,a        ;... in C
  1055.     ld    a,'.'        ;dot
  1056. dots1:
  1057.     call    cout        ;print dot
  1058.     djnz    dots1
  1059.     ld    a,8        ;back space
  1060.     ld    b,c        ;count in B
  1061. dots2:
  1062.     call    cout        ;print back space
  1063.     djnz    dots2
  1064.     pop    bc        ;restore BC
  1065.     ret
  1066.  
  1067. ;
  1068. ;  Buffers
  1069. ;
  1070. menucmd:
  1071.     db    'MENU ',0    ;MENU command line
  1072. ;
  1073. ;  These buffers overlay the scratch area to save space
  1074. ;
  1075. wait    equ    scratch        ;Wait Upon Return Flag
  1076. optstrt    equ    wait+1        ;Address of First Option in Current Menu
  1077. mstart    equ    optstrt+2    ;Address of First Menu
  1078. cstart    equ    mstart+2    ;Address of Current Menu
  1079. smenfl    equ    cstart+2    ;System Menu Available Flag (0=No)
  1080. smeno    equ    smenfl+1    ;System Menu Number
  1081. smenadr    equ    smeno+1        ;Address of First Byte of System Menu
  1082. nmenfl    equ    smenadr+2    ;Next Menu Available Flag (0=No)
  1083. mladr    equ    nmenfl+1    ;Menu Load Address (1st byte of menu in memory)
  1084. menuno    equ    mladr+2        ;Number of Menu
  1085. pagcnt    equ    menuno+1    ;Paging Counter
  1086. cflag    equ    pagcnt+1    ;Display Command Line Flag
  1087. dflag    equ    cflag+1        ;Display Menu Flag
  1088. pflag    equ    dflag+1        ;Paging Flag
  1089. cpflag:
  1090.     ds    1        ;Temp Display Command Line Flag
  1091. dpflag:
  1092.     ds    1        ;Temp Display Menu Flag
  1093. ppflag:
  1094.     ds    1        ;Temp Paging Flag
  1095. reentry:
  1096.     ds    1        ;Menu Reentry Flag and Number
  1097. cpmok:
  1098.     ds    1        ;OK to Return to CP/M (0=No)
  1099. ibuff:
  1100.     db    40        ;40 chars in buffer
  1101.     db    0        ;buffer char count
  1102. tnum:
  1103.     ds    41        ;space for chars and ending 0
  1104.  
  1105.     end
  1106.