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 / TURBODS / MENU.MAC < prev    next >
Text File  |  2000-06-30  |  24KB  |  1,112 lines

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