home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / mbug / mbug060.arc / CPM#005.LBR / MKWAIT20.ASM < prev    next >
Assembly Source File  |  1979-12-31  |  34KB  |  1,962 lines

  1. xVersion    equ    '2'
  2. yVersion    equ    '0'
  3. ;**** MKWAIT Version x.y ****
  4. ;
  5. ;Copyright (c) Peter C. Cole   July, 1985   Duncanville, TX
  6. ;All commercial rights reserved.
  7. ;Released for free distribution only. Not to be sold.
  8.  
  9.  
  10. ;**** Version Changes ****
  11. ;
  12. ;1.0  - Released 7-27-85
  13. ;
  14. ;1.1  -    Added feature to allow pushing any key to continue, not just <RETURN>.
  15. ;    Added flashing "READ NOTE:".
  16. ;    Added feature to terminate SUBMIT files.
  17. ;    Changed method on how CP/M command lines terminated.
  18. ;
  19. ;2.0  -    Added feature to "Check Line Above". (8-10-85)
  20. ;
  21.  
  22. PAGE
  23. ;**** Assembly Definations ****
  24. NL:    equ    0A0Dh    ;new line
  25. CPage:    equ    5A1Bh    ;clear page
  26. MsgEnd:    equ    0    ;message end flag
  27. Bdos:    equ    5    ;Bdos address
  28. Stack1:    equ    4000h    ;Location of MKWAIT and FileName stack
  29. Temp:    equ    Stack1+2 ;Location to store temp string for editing
  30. Existing: equ    4800h    ;Location to store existing FileName program
  31. MaxChar: equ    255    ;Maximum number of characters allowed in message
  32.             ;Also change number in message string EE2.
  33. Exit:    equ    0    ;Where to jmp to return to CP/M
  34. CurPos:    equ    0FD53h    ;Adr to find present position of cursor in Video Bank
  35.  
  36.     org    100h
  37. ;**** Start Program ****
  38. Start:    jmp    Start1
  39.  
  40. ;Set stack
  41. Start1:    lxi    sp,Stack1
  42.  
  43. ;Set output delimiter
  44.     mvi    c,110
  45.     mvi    d,0
  46.     mvi    e,MsgEnd
  47.     call    Bdos
  48.  
  49. ;Set Bdos error mode to "return and display error" 
  50.     mvi    c,45
  51.     mvi    e,0FEh
  52.     call    Bdos
  53.  
  54. ;Set number of read/write sectors to 8 (1k)
  55.     mvi    c,44
  56.     mvi    e,8
  57.     call    Bdos
  58.  
  59. PAGE
  60. ;**** Begin Message ****
  61. BeginMsg: lxi    d,BM2
  62.     call    Type
  63.     jmp    BM10
  64. èBM2:    dw    CPage
  65.     db    '****************************** MKWAIT Version '
  66.     db    xVersion,'.',yVersion,' ******************************'
  67.     db    'Copyright (c) 1985 by Peter C. Cole'
  68.     dw    NL
  69.     db    'Duncanville, Texas.'
  70.     dw    NL
  71.     db    'All commercial rights reserved.'
  72.     dw    NL
  73.     db    'Released for free distribution only. Not to be sold.'
  74.     dw    NL
  75.     db    '****************************************'
  76.     db    '****************************************'
  77.     dw    NL
  78.     db    'MKWAIT will create or edit a "Wait File" '    ;41
  79.     db    'on the disk drive of your choice.'        ;33
  80.     dw    NL
  81.     db    'MKWAIT will only run on the Osborne '        ;36
  82.     db    'Executive. '                    ;11
  83.     dw    NL,NL
  84.     db    MsgEnd
  85.  
  86.  
  87. ;**** Subroutine Type ****
  88. ;DE must already be loaded
  89.  
  90. Type:    mvi    c,9
  91.     call    Bdos
  92.     ret
  93.  
  94. PAGE
  95. ;**** Main Menu ****
  96. Begin:    call    HomeIt
  97. BM10:    lxi    d,BM11
  98.     call    Type
  99.     jmp    BM12
  100.  
  101. BM11:    db    'Please select:'
  102.     dw    NL
  103.     db    '  A,B,etc - Read this disk drive for an existing '
  104.     db    MsgEnd
  105.  
  106. BM12:    call    FileName
  107.     lxi    d,BM13
  108.     call    Type
  109.     jmp    BM14
  110.  
  111. BM13:    db    ' file.'
  112.     dw    NL
  113.     db    '  X - Exit to CP/M. Also can use ^C'
  114.     dw    NL
  115.     db    '  1 - Create a new '
  116.     db    MsgEnd
  117.  
  118. BM14:    call    FileName
  119.     lxi    d,BM15è    call    Type
  120.     jmp    BM17
  121.  
  122. BM15:    db    ' message.'
  123.     dw    NL
  124.     db    '  2 - Change to a different file name.'
  125.     dw    NL
  126.     db    '  3 - Create or Change "Check Line Above". '
  127.     db    'It is now '
  128.     db    MsgEnd
  129.  
  130. BM17:    lda    SkipFlag
  131.     ana    a
  132.     jz    BM30    ;jmp if disabled
  133.     call    BM18
  134.     jmp    BM40
  135.  
  136. BM18:    lxi    h,LinesUp
  137.     lxi    d,LineData
  138.     jmp    BM20
  139. PAGE
  140. ;**** Subroutine BM20 ****
  141. ;HL=where to find LinesUp
  142. ;DE=where to find LineData
  143.  
  144. BM20:    push    d
  145.     push    h
  146.  
  147.     lxi    d,BM21
  148.     call    Type
  149.     jmp    BM23
  150.  
  151. BM21:    db    '"activated".'
  152.     dw    NL
  153.     db    '       It will look '
  154.     db    MsgEnd
  155. BM22:    ds    1    ;to hold units digit below    
  156.  
  157. BM23:    pop    h    ;Displays number of lines up
  158.     mov    a,m
  159.     adi    0    ;daa doesn't seem to work on its own
  160.     daa
  161.     mov    b,a
  162.     ani    0F0h
  163.     mov    a,b
  164.     jz    BM24
  165.  
  166.     ani    0Fh    ;show two digits
  167.     ori    30h
  168.     sta    BM22
  169.     mvi    e,'1'
  170.     mvi    c,2
  171.     call    Bdos
  172.     lda    BM22
  173.     mov    e,a
  174.     mvi    c,2
  175.     call    Bdos
  176.     jmp    BM25
  177.  
  178. BM24:    ani    0Fh    ;shows one digit
  179.     ori    30h
  180.     mov    e,a
  181.     mvi    c,2
  182.     call    Bdos
  183.  
  184. BM25:    lxi    d,BM26
  185.     call    Type
  186.     jmp    BM27
  187.  
  188. BM26:    db    ' lines up for: '
  189.     db    MsgEnd
  190.  
  191. BM27:    pop    d    ;LineData
  192.     call    Type
  193.     ret
  194.  
  195. PAGE
  196. BM30:    lxi    d,BM31
  197.     call    Type
  198.     jmp    BM40
  199.  
  200. BM31:    db    '"disabled".'
  201.     db    MsgEnd
  202.  
  203.  
  204.  
  205. BM40:    lxi    d,BM41
  206.     call    Type
  207.     jmp    BM42
  208.  
  209. BM41:    dw    NL
  210.     db    '  W - Create a new '
  211.     db    MsgEnd
  212.  
  213. BM42:    call    FileName
  214.     lxi    d,BM43
  215.     call    Type
  216.     jmp    BM44
  217.  
  218. BM43:    db    ' file on a "to be selected" disk drive.'
  219.     dw    NL
  220.     db    '  <RETURN> - Edit the below message (if any).'
  221.     dw    NL,NL
  222.     db    MsgEnd
  223.  
  224. BM44:    lxi    d,String
  225.     call    Type
  226.  
  227.     lxi    d,BM45
  228.     call    Type
  229.     jmp    Wait
  230.  
  231. BM45:    dw    NL
  232.     db    MsgEnd
  233. PAGE
  234. ;**** Subroutine FileName ****
  235. ;Displays active file name
  236. FileName: lxi    d,FN1
  237.     call    Type
  238.     ret
  239.  
  240. FN1:    db    'WAIT',0,0,0,0    ;allow for max. of 8 characters
  241.     db    MsgEnd
  242.  
  243. ;**** Subroutine Create ****
  244. ;Creates a fresh FCB
  245. Create:    lxi    h,FcbRun
  246.     lxi    d,FcbNew
  247.     mvi    b,FcbEnd-FcbNew
  248. Create1: ldax    d
  249.     mov    m,a
  250.     inx    h
  251.     inx    d
  252.     dcr    b
  253.     jnz    Create1
  254.     ret
  255.  
  256. ;**** Subroutine HomeIt ****
  257. ;Homes cursor to just under Header and clears to end of page.
  258. HomeIt:    lxi    d,Clear
  259.     call    Type
  260.     ret
  261.  
  262. Clear:    db    1Bh,3Dh    ;move cursor
  263.     db    27h,20h    ;to just under header
  264.     db    1Bh,59h    ;clear from cursor to endè    db    MsgEnd
  265.  
  266. ;**** Subroutine ClearBuf ****
  267. ClearBuf: lxi    h,Buffer
  268.     lxi    b,EndBuffer-Buffer
  269. ClearB1: mvi    m,0
  270.     inx    h
  271.     dcx    b
  272.     mov    a,c
  273.     ora    b
  274.     jnz    ClearB1
  275.     ret
  276.  
  277. **** Subroutine ClearLD ****
  278. ClearLD: lxi    h,LineData0
  279.     lxi    b,EndData-LineData0
  280.     jmp    ClearB1
  281. PAGE
  282. ;**** Wait for key ****
  283. Wait:    mvi    c,6
  284.     mvi    e,0FDh
  285.     call    Bdos
  286.     cpi    3    ;test if ^C
  287.     jz    Exit
  288.     cpi    0Dh    ;<RETURN>
  289.     jz    ReEdit
  290.     cpi    '1'
  291.     jz    New
  292.     cpi    '2'
  293.     jz    Diff
  294.     cpi    '3'
  295.     jz    CLA    ;"Check Line Above"
  296.     ani    5Fh    ;convert if small to cap.
  297.     cpi    'X'    ;test if X
  298.     jz    Exit
  299.     cpi    'W'
  300.     jz    Write
  301.     cpi    'A'    ;is it less than 'A'?
  302.     jc    Wait    ;jmp if yes (not A to P)
  303.     cpi    'Q'    ;is it less than 'Q'?
  304.     jc    ExistFile ;jmp if yes
  305.     jmp    Wait    ;sorry, not A to P.
  306.  
  307. PAGE
  308. ;**** Work on "Check Line Above" ****
  309.  
  310. ;Clear Screen
  311. CLA:    call    HomeIt
  312.  
  313. ;Start screen message
  314.     lxi    d,CLA2
  315.     call    Type
  316.     jmp    CLA4
  317.  
  318. CLA2:    db    '"Check Line Above" is now '
  319.     db    MsgEnd
  320.  
  321. ;Is SkipFlag disabled?
  322. CLA4:    lda    SkipFlag
  323.     ana    a
  324.     jz    CLA30    ;jmp if disabled
  325.     call    BM18
  326.  
  327. ;Cont screen message
  328.     lxi    d,CLA6
  329.     call    Type
  330.     jmp    CLA7
  331.  
  332. CLA6:    dw    NL,NL
  333.     db    'Please push:'
  334.     dw    NL
  335.     db    '   <ESC> - Return to Main Menu with conditions as '
  336.     db    'shown above.'
  337.     dw    NL
  338.     db    '   D -    Disable "Check Line Above" and return to '
  339.     db    'Main Menu.'
  340.     dw    NL
  341.     db    '   E - Edit "Check Line Above" message.'
  342.     dw    NL
  343.     db    '   S - Set number of lines to look up.'
  344.     dw    NL,NL
  345.     db    MsgEnd
  346.  
  347. PAGE
  348. ;Wait for key
  349. CLA7:    mvi    c,6
  350.     mvi    e,0FDh
  351.     call    Bdos
  352.     cpi    1Bh    ;<ESC>
  353.     jz    Begin
  354.     cpi    'D'
  355.     jz    CLA10
  356.     cpi    'd'
  357.     jz    CLA10
  358.     cpi    'E'
  359.     jz    CLA20
  360.     cpi    'e'
  361.     jz    CLA20
  362.     cpi    'S'
  363.     jz    CLA15
  364.     cpi    's'
  365.     jz    CLA15
  366.     jmp    CLA7    ;Sorry none of the above
  367.  
  368. ;Clear "Skip Flag"
  369. CLA10:    mvi    a,0
  370.     sta    SkipFlag
  371.     jmp    Begin
  372.  
  373. ;Set number of lines to look above
  374. CLA15:    call    HomeIt
  375.     lxi    d,CLA16
  376.     call    Type
  377.     jmp    CLA17
  378.  
  379. CLA16:    db    'Please select the number of lines to look up. '
  380.     db    'For Example:'
  381.     dw    NL,NL
  382.     db    '----------'
  383.     dw    NL
  384.     db    'XXXX'
  385.     dw    NL,NL
  386.     db    'A>WAIT'
  387.     dw    NL
  388.     db    '----------'
  389.     dw    NL,NL,NL
  390.     db    'XXXX is 2 lines up. Select 0 to 9.'
  391.     dw    NL,NL
  392.     db    MsgEnd
  393.  
  394. CLA17:    mvi    c,6
  395.     mvi    e,0FDh
  396.     call    Bdos
  397.     ani    0Fh
  398.     sta    LinesUp
  399.     jmp    CLA
  400. PAGE
  401. ;Edit CLA
  402. ;Move message to new location
  403. CLA20:    lxi    h,Temp
  404.     lxi    d,LineData0
  405.     ldax    d    ;Load max char
  406.     mov    m,a
  407.     inx    h
  408.     inx    d
  409.     ldax    d    ;load char returned
  410.     mov    m,a
  411.     inx    h
  412.     inx    d
  413. CLA21: ldax    d
  414.     mov    m,a
  415.     inx    h
  416.     inx    d
  417.     ana    a
  418.     jnz    CLA21
  419.  
  420. ;Edit message string
  421. CLA22: call HomeIt
  422.     lxi    d,CLA23
  423.     call    Type
  424.  
  425.     lxi    h,Temp
  426.     mvi    m,31
  427.     xchg
  428.     call    LineEdit
  429.     cpi    0
  430.     jz    CLA25
  431.     cpi    1
  432.     jz    CLA
  433.     cpi    2
  434.     jz    BadWait
  435.     jmp    CLA
  436.  
  437. CLA23:    db    'Enter up to 31 characters for the '
  438.     db    '"Enter Line Above" message.'
  439.     db    MsgEnd    
  440.  
  441. ;Load new message line to LineData
  442. CLA25: call    ClearLD
  443.     lxi    h,LineData0
  444.     lxi    d,Temp
  445.     call    LB0
  446.     jmp    CLA
  447.  
  448. PAGE
  449. CLA30:    lxi    d,CLA31
  450.     call    Type
  451.     jmp    CLA34
  452.  
  453. CLA31:    db    '"disabled".'
  454.     dw    NL,NL
  455.     db    'Please push:'
  456.     dw    NL
  457.     db    '   <ESC> - Return to Main Menu without any changes.'
  458.     dw    NL
  459.     db    '   A - Activate "Check Line Above".'
  460.     dw    NL,NL
  461.     db    MsgEnd
  462.  
  463. ;Which key pushed?
  464. CLA34:    mvi    c,6
  465.     mvi    e,0FDh
  466.     call    Bdos
  467.     cpi    1Bh    ;<ESC>
  468.     jz    Begin
  469.     cpi    'A'
  470.     jz    CLA35
  471.     cpi    'a'
  472.     jz    CLA35
  473.     jmp    CLA34    ;Sorry none of the above
  474.  
  475. ;Set SkipFlag
  476. CLA35:    mvi    a,0FFh
  477.     sta    SkipFlag
  478.     jmp    CLA
  479.  
  480.  
  481. PAGE
  482. ;****  Open Existing File ****
  483.  
  484. ;Convert to drive code and store
  485. ExistFile: ani    1Fh
  486.     sta    FcbNew
  487.  
  488. ;Create FcbRun 
  489.     call    Create
  490.  
  491. ;Clear screen
  492.     call    HomeIt
  493.  
  494. ;Open Existing File
  495.     mvi    c,15
  496.     lxi    d,FcbRun
  497.     call    Bdos
  498. è;Test if file opened
  499.     ana    a
  500.     jz    FileExists    ;jmp if file opened with no problem
  501.     mov    a,h
  502.     cpi    0
  503.     jnz    BadWait
  504.  
  505. ;File not found. Give message.
  506.     lxi    d,NoFileMsg
  507.     call    Type
  508.     jmp    BadWait
  509.  
  510. NoFileMsg: dw    NL,NL
  511.     db    'File not found.'
  512.     dw    NL
  513.     db    MsgEnd
  514.  
  515.  
  516. ;Test Existing file
  517. FileExists: call TestFile
  518.     jnz    BadWait
  519.  
  520. ;MKWAIT file - give message
  521.     lxi    d,MSmsg1
  522.     call    Type
  523.     jmp    MS2
  524.  
  525. MSmsg1:    dw    NL,NL
  526.     db    'Do you want to use this file? (Y/N) '
  527.     db    MsgEnd
  528.  
  529. PAGE
  530. ;Wait for Answer
  531. MS2:    mvi    c,6
  532.     mvi    e,0FDh
  533.     call    Bdos
  534.  
  535.     cpi    'Y'
  536.     jz    LoadCLA
  537.     cpi    'y'
  538.     jz    LoadCLA
  539.     jmp    Begin
  540.  
  541. ;Edit existing message string
  542. ExistEdit: call    HomeIt
  543.     lxi    d,EE2
  544.     call    Type
  545.  
  546.     lxi    h,Existing+Buffer-Data
  547.     mvi    m,MaxChar    ;only allow max number of char
  548.     xchg
  549.     call    LineEdit
  550.     cpi    0
  551.     jz    LoadCLA
  552.     cpi    1
  553.     jz    Begin
  554.     cpi    2
  555.     jz    BadWait
  556.     jmp    Begin
  557.  
  558. EE2:    db    'Enter up to 255 characters. Messages will '
  559.     db    'automatically go to the next line'
  560.     dw    NL
  561.     db    'after every 80 characters. Therefore, '
  562.     db    'you may want to use spaces to finish'
  563.     dw    NL
  564.     db    'a line in the right place.'
  565.     db    MsgEnd
  566.  
  567. ;Load "Check Line Above" data
  568. LoadCLA: call ClearLD
  569.     lxi    h,SkipFlag
  570.     lxi    d, Existing+SkipFlag-Data
  571.     mvi    b,EndCLA-SkipFlag
  572. LdCLA1:    ldax    d
  573.     mov    m,a
  574.     inx    h
  575.     inx    d
  576.     dcr    b
  577.     jnz    LdCLA1
  578.  
  579.     lxi    h,LineData0
  580.     lxi    d,Existing+LineData0-Data
  581.     call    LB0
  582.  
  583. PAGE
  584. ;Load from MKWAIT file to "Buffer"
  585. LoadBuffer: call ClearBuf
  586.     lxi    h,Buffer
  587.     lxi    d,Existing+Buffer-Data
  588.     call    LB0
  589.     jmp    Begin
  590.  
  591. LB0:    ldax    d    ;load max char
  592.     mov    m,a
  593.     inx    h
  594.     inx    d
  595.     ldax    d    ;load char returned
  596.     mov    m,a
  597.     inx    h
  598.     inx    d
  599. LB1:    ldax    d    ;load data
  600.     mov    m,a
  601.     inx    h
  602.     inx    d
  603.     ana    a    ;is it end flag?
  604.     jnz    LB1    ;jmp if no
  605.     ret
  606.  
  607.  
  608.  
  609. ;**** Routine New ****
  610.  
  611. ;Create a string with no data
  612. New:    lxi    h,Temp
  613.     mvi    m,MaxChar
  614.     inx    h
  615.     mvi    m,0
  616.     inx    h
  617.     mvi    m,0
  618.     jmp    ReEdit2
  619.  
  620.  
  621. ;**** Routine BadWait ****
  622. ;Will wait for any key (sends message) and then jmp to Begin
  623.  
  624. BadWait: lxi    d,BadOpen1
  625.     call    Type
  626.  
  627.     mvi    e,0FDh    ;wait for key
  628.     mvi    c,6
  629.     call    Bdos
  630.     jmp    Begin
  631.  
  632. BadOpen1: dw    NL,NL
  633.     db    'Push <RETURN> to continue.'
  634.     dw    NLè    db    MsgEnd
  635. PAGE
  636. ;**** Routine ReEdit ****
  637.  
  638. ;Move Buffer to new location
  639. ReEdit:    lxi    h,Temp
  640.     lxi    d,Buffer
  641.     ldax    d    ;Load max char
  642.     mov    m,a
  643.     inx    h
  644.     inx    d
  645.     ldax    d    ;load char returned
  646.     mov    m,a
  647.     inx    h
  648.     inx    d
  649. ReEdit1: ldax    d
  650.     mov    m,a
  651.     inx    h
  652.     inx    d
  653.     ana    a
  654.     jnz    ReEdit1
  655.  
  656. ;Edit message string
  657. ReEdit2: call HomeIt
  658.     lxi    d,EE2
  659.     call    Type
  660.  
  661.     lxi    h,Temp
  662.     mvi    m,MaxChar
  663.     xchg
  664.     call    LineEdit
  665.     cpi    0
  666.     jz    ReEdit5
  667.     cpi    1
  668.     jz    Begin
  669.     cpi    2
  670.     jz    BadWait
  671.     jmp    Begin
  672.  
  673. ;Load new message line to Buffer
  674. ReEdit5: call    ClearBuf
  675.     lxi    h,Buffer
  676.     lxi    d,Temp
  677.     call    LB0
  678.     jmp    Begin
  679.  
  680. PAGE
  681. ;**** Subroutine TestFile ****
  682. ;Test existing file found on disk
  683. ;If MKWAIT file then return with Zero Flag set
  684.  
  685. ;Send message
  686. TestFile: 
  687.     call    FileName
  688.     lxi    d,FEmsg
  689.     call    Type
  690.     jmp    FEmsgOut
  691.  
  692. FEmsg:    db    ' exists on the selected drive.'
  693.     dw    NL
  694.     db    MsgEnd
  695. FEmsgOut: db    0
  696.  
  697. ;Clear area for existing FileName so that old end message destroyed.
  698.     lxi    h,Existing
  699.     lxi    b,400h    ;more than enough
  700. ClearArea: mvi    m,0
  701.     inx    h
  702.     dcx    b
  703.     mov    a,b
  704.     ora    c
  705.     jnz    ClearArea
  706.  
  707. ;Load existing file
  708.     mvi    c,26    ;set DMA address
  709.     lxi    d,Existing
  710.     call    Bdos
  711.  
  712.     mvi    c,15    ;open existing file
  713.     lxi    d,FcbRun
  714.     call    Bdosè
  715.     mvi    c,20    ;read sequential
  716.     lxi    d,FcbRun
  717.     call    Bdos
  718.  
  719.  
  720. ;Test if embedded "MKWAIT end message" is present
  721.     lxi    h,Existing+400h-(+EndS9-EndS8)
  722.     lxi    d,EndS8
  723.     mvi    b,EndS9-EndS8
  724. Test:    ldax    d
  725.     cmp    m
  726.     jnz    NotFile    ;jmp if embedded message not MKWAIT's
  727.     inx h !inx d
  728.     dcr    b
  729.     jnz    Test
  730.  
  731. PAGE
  732. ;This is a MKWAIT file - Send message
  733.     lxi    d,MF1
  734.     call    Type
  735.     jmp    MF2
  736.  
  737. MF1:    dw    NL
  738.     db    'This file was created by MKWAIT '
  739.     db    MsgEnd
  740.  
  741. MF2:    lxi    d,Existing+EndS7-Data    ;Send Version number
  742.     call    Type
  743.  
  744.     lxi    d,MF11
  745.     call    Type
  746.     jmp    MF12
  747.  
  748. MF11:    dw    NL,NL
  749.     db    '       "Check Line Above" is now '
  750.     db    MsgEnd
  751.  
  752. MF12:    lda    Existing+SkipFlag-Data
  753.     ana    a
  754.     jz    MF20    ;jmp if disabled
  755.     call    MF15
  756.     jmp    MF23
  757.  
  758. MF15:    lxi    h,Existing+LinesUp-Data
  759.     lxi    d,Existing+LineData-Data
  760.     jmp    BM20
  761.  
  762. MF20:    lxi    d,BM31
  763.     call    Type
  764.  
  765. MF23:    lxi    d,MF24
  766.     call    Type
  767.     jmp    MF25
  768.  
  769. MF24:    dw    NL,NL
  770.     db    'The file',39,'s message line is:'
  771.     dw    NL
  772.     db    MsgEnd
  773.  
  774. MF25:    lxi    d,Existing+String-Data    ;Send String message
  775.     call    Type
  776.  
  777.     xra    a    ;set zero flag
  778.     ret
  779. èPAGE
  780. ;Not a MKWAIT file - Send message
  781. NotFile: lxi    d,NMmsg
  782.     call    Type
  783.  
  784.     mvi    a,1    ;clear zero flag
  785.     ana    a
  786.     ret
  787.  
  788. NMmsg:    db    'This file was not made by MKWAIT. '
  789.     dw    NL
  790.     db    MsgEnd
  791.  
  792.  
  793. PAGE
  794. ;**** Write File to Disk ****
  795.  
  796. ;Ask which drive to select
  797. Write:    call HomeIt
  798.     lxi    d,Write2
  799.     call    Type
  800.     jmp    Write3
  801.  
  802. Write2:    db    'Which drive do you want to write '
  803.     db    MsgEnd
  804.  
  805. Write3:    call    FileName
  806.     lxi    d,Write5
  807.     call    Type
  808.     jmp    Write6
  809.  
  810. Write5:    db    ' to?'
  811.     dw    NL
  812.     db    'Select A,B,etc. or <ESC> to return to main menu.'
  813.     dw    NL
  814.     db    MsgEnd
  815.  
  816. ;Wait for key
  817. Write6:    mvi    c,6
  818.     mvi    e,0FDh
  819.     call    Bdos
  820.     cpi    1Bh    ;ESC
  821.     jz    Begin
  822.     ani    5Fh    ;convert from small to cap.
  823.     cpi    'A'    ;is it less than 'A'?
  824.     jc    Write6    ;jmp if yes
  825.     cpi    'Q'    ;is it less than 'Q'
  826.     jc    Write10    ;jmp if yes
  827.     jmp    Write6    ;sorry, not A to P
  828.  
  829. ;Convert to drive code and store
  830. Write10: sta    Write17    ;store drive letter
  831.     ani    1Fh
  832.     sta    FcbNew
  833.  
  834. ;Create FcbRun 
  835.     call    Create
  836.  
  837. PAGE
  838. ;Clear screen
  839. Write11: call    HomeIt
  840.  
  841. ;Open New File
  842.     mvi    c,22
  843.     lxi    d,FcbRun
  844.     call    Bdos
  845. è;Test if file opened
  846.     ana    a
  847.     jz    Write40    ;jmp if file opened with no problem
  848.     mov    a,h
  849.     cpi    8h
  850.     jz    Write15
  851.     cpi    0
  852.     jnz    BadWait
  853.  
  854. ;No directory space available
  855.     lxi    d,Write12
  856.     call    Type
  857.     jmp    BadWait
  858.  
  859. Write12: dw    NL,NL
  860.     db    'No directory space available.'
  861.     dw    NL
  862.     db    MsgEnd
  863.  
  864. ;Ask if file to be overwritten?
  865. Write15: call    HomeIt
  866.     call    FileName
  867.  
  868.     lxi    d,Write16
  869.     call    Type
  870.     jmp    Write20
  871.  
  872. Write16: db    ' already exists on drive '
  873. Write17: db    'A: '
  874.     dw    NL
  875.     db    'Do you wish to overwrite this file with your new '
  876.     db    '"wait" file? (Y/N) '    
  877.     db    MsgEnd
  878.  
  879. PAGE
  880. ;Wait for Erase Answer
  881. Write20: mvi    c,6
  882.     mvi    e,0FDh
  883.     call    Bdos
  884.  
  885.     cpi    'Y'
  886.     jz    Write22
  887.     cpi    'y'
  888.     jz    Write22
  889.     jmp    Begin
  890.  
  891. ;Erase fileèWrite22: mvi    c,19
  892.     lxi    d,FcbRun
  893.     call    Bdos
  894.  
  895.     ana    a    ;test if erased
  896.     jz    Write11    ;jmp if erased
  897.     mov    a,h    ;test if R/O
  898.     cpi    3
  899.     jz    Write30    ;jmp if R/O
  900.     jmp    BadWait
  901.  
  902. ;Ask About Read/Only
  903. Write30: lxi    d,Write31
  904.     call    Type
  905.     jmp    Write32
  906.  
  907. Write31: dw    NL,NL
  908.     db    'The file is Read/Only. Overwrite? (Y/N) '
  909.     db    MsgEnd
  910.  
  911. ;Wait for answer
  912. Write32: mvi    c,6
  913.     mvi    e,0FDh
  914.     call    Bdos
  915.  
  916.     cpi    'Y'
  917.     jz    Write35
  918.     cpi    'y'
  919.     jz    Write35
  920.     jmp    Begin
  921.  
  922. ;Erase Read/Only
  923. Write35:lda    FcbRun+9    ;set FCB to R/Wè    ani    7Fh
  924.     sta    FcbRun+9
  925.  
  926.     mvi    c,30    ;now set file on disk to R/W
  927.     lxi    d,FcbRun
  928.     call    Bdos
  929.     jmp    Write22
  930. PAGE
  931. ;**** Load End Flags into Data ****
  932.  
  933. ;Get next address after String
  934. Write40: mvi    b,0    ;load number of char to bc
  935.     lda    Buffer+1
  936.     mov    c,a
  937.     lxi    h,String ;load string start adr
  938.     dad    b    ;offset
  939.  
  940. ;add end flag of 0h
  941.     mvi    m,0
  942.     inx    h
  943.  
  944.  
  945.  
  946. ;**** Write Data to Disk ****
  947.     mvi    c,26    ;set DMA address
  948.     lxi    d,Data
  949.     call    Bdos
  950.  
  951.     mvi    c,21    ;write data
  952.     lxi    d,FcbRun
  953.     call    Bdos
  954.  
  955.     mvi    c,16    ;close file
  956.     lxi    d,FcbRun
  957.     call    Bdos
  958.  
  959.     jmp    Begin
  960.  
  961. **** FCB "to be run" location ***
  962. FcbRun:    ds    1
  963.     db    'WAIT    COM'
  964.     db    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  965.  
  966. **** FCB "to be read" location ****
  967. FcbNew:    ds    1
  968.     db    'WAIT    COM'
  969.     db    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  970. FcbEnd:    ds    1
  971.  
  972. PAGE
  973. **** Program Data Assembly Area ****
  974. ;Below is the program of the WAIT file. It always starts at 100h.
  975. Data:
  976.  
  977. OffSet:    equ    Data-100h
  978.  
  979. ;Set Stack
  980.     lxi    sp,Stack1
  981.  
  982. ;Set Output Delimiter to 0h.
  983.     mvi    c,110
  984.     mvi    e,0h
  985.     call    Bdos
  986.  
  987. ;Jmp one line down so cursor is always in far left column
  988.     mvi    c,9
  989.     lxi    d,DataNL-Offset
  990.     call    Bdos
  991.  
  992. ;Is SkipFlag set?
  993.     lda    SkipFlag-Offset
  994.     ana    a
  995.     jnz    TestLine-Offset
  996.  
  997. ;Skip another line on screen and send flashing message
  998. Data0:    mvi    c,9
  999.     lxi    d,Data1-OffSet
  1000.     call    Bdos
  1001.     jmp    Data2-OffSet
  1002.  
  1003. Data1:    dw    NL
  1004.     db    27,94    ;start flash
  1005.     db    'READ NOTE:'
  1006.     db    27,113    ;stop flash
  1007.     db    7    ;Beep
  1008. DataNL:    dw    NL
  1009.     db    0
  1010.  
  1011. ;Send message
  1012. Data2:    mvi    c,9
  1013.     lxi    d,String-OffSet
  1014.     call    Bdos
  1015.  
  1016. ;Send waiting message
  1017.     mvi    c,9
  1018.     lxi    d,Data4-OffSet
  1019.     call    Bdos
  1020.     jmp    Data5-OffSet
  1021.  
  1022. Data4:    dw    NL,NL
  1023.     db    'Push <RETURN> to continue or '
  1024.     db    '<ESC> to terminate command string.'
  1025.     dw    NL
  1026.     db    0
  1027. PAGE
  1028. ;Wait for key
  1029. Data5:    mvi    c,6
  1030.     mvi    e,0FDh
  1031.     call    Bdos
  1032.     cpi    1Bh    ;ESC
  1033.     jz    Data7-OffSet
  1034.     jmp    0    ;jmp to cp/m
  1035.  
  1036. ;Return to CP/M without finishing any command lines
  1037. ;Find and remove any SUBMIT RSX's
  1038. Data7:    mvi    c,60
  1039.     lxi    d,Data8-OffSet
  1040.     call    Bdos    ;will return code of FFh if none found.
  1041.     inr    a
  1042.     jnz    Data7-OffSet
  1043.     jmp    Data10-OffSet
  1044.  
  1045. ;RSX PB Address
  1046. Data8:    db    81h    ;Code to SUBMIT to terminate
  1047.     db    0
  1048.  
  1049. ;Find and remove any command RSX.
  1050. ;Test if another command
  1051. Data10:    mvi    c,49
  1052.     lxi    d,Data15-OffSet    ;Get High adr of next command
  1053.     call    Bdos
  1054.     ana    a    ;test if 0h
  1055.     jz    0    ;jmp if no next command
  1056.  
  1057. ;Set command RSX "remove flag"
  1058.     mov    h,a
  1059.     mvi    l,0Eh
  1060.     mvi    m,0FFh
  1061.  
  1062. ;Set next command address to 0000h
  1063. Data11:    mvi    c,49
  1064.     lxi    d,Data16-OffSet
  1065.     call    Bdos
  1066.     jmp    0
  1067.  
  1068. ;SCB PB Address for Data10
  1069. Data15:    db    16h    ;Offset to High adr of next command
  1070.     db    0    ;Get operation
  1071.  
  1072. ;SCB PB Address for Data11
  1073. Data16:    db    15h    ;Offset to adr of next command
  1074.     db    0FEh    ;Set word
  1075.     dw    0000h    ;The word value
  1076.  
  1077. PAGE
  1078. ;Activate Video Bank
  1079. TestLine: in    0
  1080.     sta    LineBank-Offset
  1081.     ori    40h
  1082.     out    0
  1083.  
  1084. ;Get present position of cursor
  1085.     lhld    CurPos
  1086.  
  1087. ;Go up so many lines
  1088.     lda    LinesUp-Offset
  1089.     adi    2    ;go up at least 2 lines
  1090.     mov    b,a
  1091.  
  1092. TL1:    mov    a,l
  1093.     cpi    80h
  1094.     jz    TL4-Offset    ;jmp if Low = 80h
  1095.     mvi    l,80h        ;Set Low to 80h
  1096.     dcr    h        ;Decrement High
  1097. TL2:    dcr    b
  1098.     jnz    TL1-Offset    ;jmp if not last line
  1099.     jmp    TL10-Offset
  1100.  
  1101. TL4:    mvi    l,0        ;Set Low to 00h
  1102.     jmp    TL2-Offset
  1103.  
  1104. ;Does data match?
  1105. TL10:    lxi    d,LineData-Offset
  1106. TL12:    ldax    d
  1107.     ana    a    ;is it end flag?
  1108.     jz    TL16-Offset ;jmp if end flag
  1109.     cmp    m
  1110.     jnz    TL14-Offset    ;jmp if no match
  1111.     inx    h
  1112.     inx    d
  1113.     jmp    TL12-Offset
  1114.  
  1115. ;Restore banks and show WAIT message
  1116. TL14:    lda    LineBank-Offset
  1117.     out    0
  1118.     jmp    Data0-Offset
  1119.  
  1120. ;Restore banks and return to CP/M
  1121. TL16:    lda    LineBank-Offset
  1122.     out    0
  1123.     jmp    Exit
  1124.  
  1125.  
  1126. PAGE
  1127. ;Skip space to 027Eh (allows extra program space if needed)
  1128.     ds    27Eh-100h-($-Data)
  1129.  
  1130.  
  1131. ;Development Area for Message. 
  1132. ;Message will be from 280h to 37Fh (up to 255 char's).
  1133. Buffer:    ds    2    ;2 bytes for number of characters in message    ;027Eh
  1134. String:    db    0    ;Start of string of characters in message.    ;0280h
  1135.     ds    0380h-100h-($-Data)    ;skip space to 0380h 
  1136. EndBuffer:        ;This label used by ClearBuf:
  1137.  
  1138.  
  1139.  
  1140. ;Storage for data bytes and words                    ;0380h
  1141. SkipFlag: db    0    ;Will test screen if this flag not zero
  1142. LineBank: ds    1    ;Temp storage of bank
  1143. LinesUp: db    0    ;Number of lines above CP/M command line
  1144.  
  1145. ;skip space to 038Eh
  1146. EndCLA:    ds    38Eh-100h-($-Data)
  1147.  
  1148. ;Storage for "Check Line Above" message    (up to 31 characters)        ;038Eh
  1149. LineData0: ds    2    ;2 bytes for number of characters in message    ;0390h
  1150. LineData: db    0
  1151.     ds    3B0h-100h-($-Data)    ;skip space to 03B0h
  1152. EndData:        ;This label used by ClearLD:
  1153.  
  1154.  
  1155.  
  1156. ;skip space to 04D2h (allows extra program or data space if needed)    ;03B0h
  1157.     ds    4D2h-100h-($-Data)
  1158.  
  1159. ;Version number
  1160. EndS7:    db    'Ver. ',xVersion,'.',yVersion,0,0,0            ;04D2h
  1161.  
  1162. ;Recognition message
  1163. EndS8:    db    'This WAIT.COM was created by MKWAIT'            ;04DDh
  1164. EndS9:    db    0                            ;0500h
  1165.  
  1166. PAGE
  1167. ;**** Routine Diff ****
  1168. ;Change to a different file name
  1169.  
  1170. ;Send message
  1171. Diff:    call HomeIt
  1172.     lxi    d,Diff1
  1173.     call    Type
  1174.     jmp    Diff2
  1175.  
  1176. Diff1:    db    'What is the new file name to be?'
  1177.     dw    NL
  1178.     db    'Enter up to an 8 character file name.'
  1179.     dw    NL
  1180.     db    MsgEnd
  1181.  
  1182. ;Setup NewName
  1183. Diff2:    lxi    h,NewName
  1184.     mvi    m,8    ;8 characters max
  1185.     inx    h
  1186.     inx    h
  1187.     mvi    m,0    ;no data to start
  1188.     jmp    Diff4
  1189.  
  1190. NewName: ds    15
  1191.  
  1192. ;Get file name
  1193. Diff4:    lxi    d,NewName
  1194.     call    LineEdit
  1195.     cpi    0
  1196.     jz    Diff10
  1197.     cpi    1
  1198.     jz    Begin
  1199.     cpi    2
  1200.     jz    BadWait
  1201.     jmp    Begin
  1202.  
  1203.  
  1204. PAGE
  1205. ;Test if no data
  1206. Diff10:    lda    NewName+1
  1207.     ana    a
  1208.     jz    Begin    ;Forget it if no data
  1209.  
  1210. ;Convert small letters to caps
  1211.     lxi    h,NewName+2
  1212. Diff11:    mov    a,m
  1213.     ana    a
  1214.     jz    Diff13
  1215.     cpi    'a'
  1216.     jc    Diff12    ;jmp if less than 'a'
  1217.     cpi    'z'+1
  1218.     jnc    Diff12    ;jmp if greater than 'z'
  1219.     sui    20h    ;convert
  1220.     mov    m,a
  1221. Diff12:    inx    h
  1222.     jmp    Diff11
  1223.  
  1224. ;Fill FcbRun file name with blanks
  1225. Diff13:    mvi    b,8
  1226.     mvi    a,' '
  1227.     lxi    h,FcbRun+1
  1228. Diff15:    mov    m,a
  1229.     inx    h
  1230.     dcr    b
  1231.     jnz    Diff15
  1232.  
  1233. ;Move new file name to FcbRun
  1234.     lxi    h,NewName+2
  1235.     lxi    d,FcbRun+1
  1236. Diff17:    mov    a,m
  1237.     ana    a
  1238.     jz    Diff20
  1239.     stax    d
  1240.     inx    h
  1241.     inx    d
  1242.     jmp    Diff17
  1243.  
  1244. PAGE
  1245. ;Fill FcbNew file name with blanks
  1246. Diff20:    mvi    b,8
  1247.     mvi    a,' '
  1248.     lxi    h,FcbNew+1
  1249. Diff21:    mov    m,a
  1250.     inx    h
  1251.     dcr    b
  1252.     jnz    Diff21
  1253.  
  1254. ;Move new file name to FcbNew
  1255.     lxi    h,NewName+2
  1256.     lxi    d,FcbNew+1
  1257. Diff23:    mov    a,m
  1258.     ana    a
  1259.     jz    Diff25
  1260.     stax    d
  1261.     inx    h
  1262.     inx    d
  1263.     jmp    Diff23
  1264.  
  1265. ;Fill FN1 file name with 0's
  1266. Diff25:    mvi    b,8
  1267.     mvi    a,0
  1268.     lxi    h,FN1
  1269. Diff27:    mov    m,a
  1270.     inx    h
  1271.     dcr    b
  1272.     jnz    Diff27
  1273.  
  1274. ;Move new file name to FN1
  1275.     lxi    h,NewName+2
  1276.     lxi    d,FN1
  1277. Diff30:    mov    a,m
  1278.     ana    a
  1279.     jz    Diff33
  1280.     stax    d
  1281.     inx    h
  1282.     inx    d
  1283.     jmp    Diff30
  1284.  
  1285. ;That's it. Lets go home.
  1286. Diff33:    jmp    Begin
  1287.  
  1288. PAGE
  1289. ;**** Subroutine LineEdit ****
  1290. ;
  1291. ;DE = Start address of string to edit (set by user)
  1292. ; 1st byte = maximum number of characters (set by user)
  1293. ;          Does not include end flag of 0.
  1294. ; 2nd byte = total number of characters returned (set by LineEdit)
  1295. ;         Does not include end flag of 0.
  1296. ; 3rd byte = zero if string has no data (set by user)
  1297. ; 3rd byte = not zero if string has data (string must end with 0)
  1298. ;
  1299. ;Preload "WhichRow" with the row number to be used for the displayed line.
  1300. ; 00h = 1st row (Top row of screen)
  1301. ; 01h = 2nd row
  1302. ;    etc
  1303. ; 17h = 24th row (Bottom row of screen)
  1304. ;
  1305. ;CP/M cursor is moved to far left so LineEdit can remove it.
  1306. ;LineEdit Cursor will start at far left.
  1307. ;Cursor will be inverse, blinking, full intensity.
  1308. ;Non-cursor characters will be black background, full intensity.
  1309. ;
  1310. ;Nonprintable characters will not be allowed in string.
  1311. ;
  1312. ;MsgEnd must be 0h.
  1313. ;
  1314. ;Returns with accumulator set to:
  1315. ; 0 - good edit. (2nd byte equals 0 to maximum characters in string)
  1316. ; 1 - edit not wanted (ESC pushed)
  1317. ; 2 - problem opening line (one line message given)
  1318. ;
  1319. ;"String" is location of data .
  1320. ;"Line" is location of video ram.
  1321. ;
  1322.  
  1323. LineMax: db    MaxChar    ;maximum number of characters allowed (max = 255)
  1324.             ;1st byte can be equal to or less than LineMax
  1325. WhichRow: db    17h    ;row that line editor will use
  1326. StringStart: ds    2    ;start address of string to edit
  1327. StringBegin: ds    2    ;First char of string
  1328. String1st: ds    2    ;Address of char in string that is 1st char in line
  1329. StringCursor: ds 2    ;cursor location in string
  1330. LineBegin: ds    2    ;start address of line
  1331. LineCursor: ds    2    ;cursor location in line
  1332.  
  1333.  
  1334.  
  1335. PAGE
  1336. ;Store start address of string
  1337. LineEdit: xchg
  1338.     shld    StringStart
  1339.  
  1340. ;Make CP/M cursor start location same as LineEdit location
  1341.     lda    WhichRow
  1342.     ani    24
  1343.     sta    CursorY
  1344.  
  1345. ;Send Edit header
  1346.     lxi    d,Edit1
  1347.     call    Type
  1348.     jmp    Edit3
  1349.  
  1350. Edit1:    dw    NL,NL
  1351.     db    'Use these keys for editing:'
  1352.     dw    NL,NL
  1353.     db    '  ^A - Go to far left.'
  1354.     dw    NL
  1355.     db    '  ^F - Go to far right.'
  1356.     dw    NL
  1357.     db    '  ^G or down arrow - delete character.'
  1358.     dw    NL
  1359.     db    '  ^- or ^left arrow - delete character on left.'
  1360.     dw    NL
  1361.     db    '  Use left and right arrow keys to move cursor.'
  1362.     dw    NL
  1363.     db    '  Only printable characters allowed.'
  1364.     dw    NL
  1365.     db    '  Push <ESC> to exit without new edit.'
  1366.     dw    NL
  1367.     db    '  Push <RETURN> when finished.'
  1368.     db    1Bh,3Dh        ;position cursor
  1369. CursorY    db    0+32
  1370. CursorX    db    0+32
  1371.     db    MsgEnd
  1372.  
  1373. PAGE
  1374. ;Create video bank start address
  1375. Edit3:    ora    a        ;clear carry
  1376.     lda    WhichRow    ;get row number
  1377.     lxi    h,0C000h    ;preload hl for video bank address
  1378.     rar            ;get LSB of WhichRow for MSB of reg l
  1379.     mov    b,a        ;store LSB's for reg h
  1380.     mov    a,l        ;move LSB of WhichRow into MSB of reg l
  1381.     rar
  1382.     mov    l,a
  1383.     mov    a,b        ;get LSB's for reg h
  1384.     ora    h        ;move MSB's of WhichRow into LSB's of reg h
  1385.     mov    h,a        ;
  1386.     shld    LineBegin    ;store line start address
  1387. PAGE
  1388. ;Test if max desired ok
  1389. Edit5:    lhld    StringStart
  1390.     mov    c,m    ;load max char's
  1391.     inx    h
  1392.     mvi    m,0    ;set to 0 char returned for now
  1393.     inx    h
  1394.     lda    LineMax    ;load max allowed
  1395.     cmp    c    ;test if equal to or less than
  1396.     jz    Edit8    ;ok (equal)
  1397.     jnc    Edit8    ;ok (less than)
  1398.     
  1399. ;Max desired not ok - send message
  1400.     lxi    d,Edit6
  1401.     call    Type
  1402.     mvi    a,2
  1403.     ret
  1404.  
  1405. Edit6:    db    'Maximum characters desired is more than that allowed.'
  1406.     db    MsgEnd
  1407.  
  1408. ;Test if any nonprintable char found
  1409. Edit8:    
  1410.     mvi    b,0    ;to keep track of number of char
  1411.     lda    LineMax    ;to test if max exceeded
  1412.     inr    a    ;account for end flag
  1413.     mov    c,a
  1414. Edit9:    mov    a,m
  1415.     ana    a
  1416.     jz    Edit20    ;jmp if end flag of 0 found
  1417.     cpi    ' '
  1418.     jc    Edit11    ;jmp if control char
  1419.     cpi    7Fh
  1420.     jnc    Edit11    ;jmp if equal to or greater than 7Fh
  1421.     inr    b
  1422.     dcr    c
  1423.     jz    Edit16    ;jmp if max exceeded
  1424.     inx    h
  1425.     jmp    Edit9
  1426.  
  1427. ;nonprintable char found
  1428. Edit11:    lxi    d,Edit12
  1429.     call    Type
  1430.     mvi    a,2
  1431.     ret
  1432.  
  1433. Edit12:    db    'Sorry, this string has a nonprintable character.'
  1434.     db    MsgEnd
  1435.  
  1436. PAGE
  1437. ;number of char's exceed limit
  1438. Edit16:    lxi    d,Edit17
  1439.     call    Type
  1440.     mvi    a,2
  1441.     ret
  1442.  
  1443. Edit17: db    'Sorry, this string is too long.'
  1444.     db    MsgEnd
  1445.     
  1446.  
  1447. ;does string given exceed its own limit?
  1448. Edit20:    lhld    StringStart
  1449.     mov    a,m
  1450.     cmp    b
  1451.     jnc    Edit25    ;jmp if ok
  1452.  
  1453. ;string given exceeds its own limit
  1454.     lxi    d,Edit22
  1455.     call    Type
  1456.     mvi    a,2
  1457.     ret
  1458.  
  1459. Edit22: db    'Sorry, this string exceeds its own maximum limit.'
  1460.     db    MsgEnd
  1461.     
  1462. ;Load number of char's found
  1463. Edit25:    lhld    StringStart
  1464.     inx    h
  1465.     mov    m,b
  1466.  
  1467. ;display line
  1468.     lhld    StringStart    ;preload start address of string
  1469.     inx    h
  1470.     inx    h
  1471.     shld    StringBegin
  1472.     shld    String1st
  1473.     shld    StringCursor
  1474.  
  1475.     lhld    LineBegin    ;preload start address of line
  1476.     shld    LineCursor
  1477.     shld    OldCursor
  1478.  
  1479.     call    Display
  1480.     jmp    Edit
  1481.  
  1482. PAGE
  1483. ;** Subroutine Display **
  1484. OldCursor: ds    2
  1485. Bank:    ds    1
  1486.  
  1487. ;Turn on Video Bank
  1488. Display: in    0
  1489.     sta    Bank
  1490.     ori    40h
  1491.     out    0
  1492.  
  1493. ;Turn off old cursor
  1494.     lhld    OldCursor
  1495.     mov    a,m
  1496.     ani    01111111b ;turn off reverse video
  1497.     mov    m,a
  1498.     mov    a,h    ;go to DXXX address
  1499.     adi    10h
  1500.     mov    h,a
  1501.     mov    a,m
  1502.     ani    11011111b ;turn off blink
  1503.     mov    m,a
  1504.  
  1505. ;Load new line data until end flag
  1506.     lhld    String1st
  1507.     xchg
  1508.     lhld    LineBegin
  1509.     mvi    b,80
  1510. Display1: ldax    d
  1511.     ana    a    ;test if 0 end flag
  1512.     jz    Display2 ;jmp if yes
  1513.     mov    m,a
  1514.     inx    h
  1515.     inx    d
  1516.     dcr    b
  1517.     jnz    Display1
  1518.  
  1519. ;Finish with blanks
  1520. Display2: mvi    a,' '
  1521. Display3: mov    m,a
  1522.     inx    h
  1523.     dcr    b
  1524.     jnz    Display3
  1525.  
  1526. PAGE
  1527. ;Turn on new cursor and store location as OldCursor
  1528.     lhld    LineCursor
  1529.     shld    OldCursor
  1530.     mov    a,m
  1531.     ori    10000000b ;turn on inverse video
  1532.     mov    m,a
  1533.     mov    a,h    ;go to DXXX address
  1534.     adi    10h
  1535.     mov    h,a
  1536.     mov    a,m
  1537.     ori    00100000b ;turn on blink
  1538.     mov    m,a
  1539.  
  1540. ;Turn off Video Bank
  1541.     lda    Bank
  1542.     out    0
  1543.     ret
  1544.  
  1545. PAGE
  1546. ;Wait for edit key
  1547. Edit:    mvi    c,6
  1548.     mvi    e,0FDh
  1549.     call    Bdos
  1550.     cpi    1Bh    ;ESC
  1551.     jz    ExitEdit
  1552.     cpi    01h    ;^A (CP/M to left edge)
  1553.     jz    LeftEdge
  1554.     cpi    06h    ;^F (CP/M to right edge)
  1555.     jz    RightEdge
  1556.     cpi    07h    ;^G (CP/M and WS delete character)
  1557.     jz    DeleteChar
  1558.     cpi    0Ah    ;^J (CP/M Arrow down)
  1559.     jz    DeleteChar
  1560.     cpi    18h    ;^X (WS Arrow down)
  1561.     jz    DeleteChar
  1562.     cpi    1Fh    ;^_ (WS delete character on left - also ^ arrow left) 
  1563.     jz    DeleteLeft
  1564.     cpi    7Fh    ;DEL
  1565.     jz    DeleteLeft
  1566.     cpi    04h    ;^D (WS arrow right)
  1567.     jz    Right
  1568.     cpi    0Ch    ;^L (CP/M arrow right)
  1569.     jz    Right
  1570.     cpi    13h    ;^S (WS arrow left)
  1571.     jz    Left
  1572.     cpi    08h    ;^H (CP/M arrow left)
  1573.     jz    Left
  1574.     cpi    0Dh    ;^M (Carriage Return)
  1575.     jz    DoneEdit
  1576.     cpi    ' '
  1577.     jc    Edit    ;jmp if control char
  1578.     cpi    80h
  1579.     jnc    Edit    ;jmp if equal to or greater than 80h
  1580.     jmp    EnterChar
  1581.  
  1582. ;Return from Edit with flag of abandon edit
  1583. ExitEdit: mvi    a,1
  1584.     ret
  1585.  
  1586. ;Return from Edit with flag of good new edit
  1587. DoneEdit: mvi    a,0
  1588.     ret
  1589.  
  1590. PAGE
  1591. ;**** Routine Right ****
  1592. ;move cursor right
  1593.  
  1594. ;can String move right?
  1595. Right:    lhld    StringCursor
  1596.     mov    a,m
  1597.     ana    a
  1598.     jz    Edit    ;jmp if no
  1599.  
  1600. ;move String right
  1601.     inx    h
  1602.     shld    StringCursor
  1603.  
  1604. ;can Line move right?
  1605.     lhld    LineCursor
  1606.     mov    a,l
  1607.     cpi    4Fh
  1608.     jz    RightMove ;jmp if no
  1609.     cpi    0CFh
  1610.     jz    RightMove ;jmp if no
  1611.  
  1612. ;move Line right
  1613.     inx    h
  1614.     shld    LineCursor
  1615.  
  1616. ;display new line
  1617. RightOut: call    Display
  1618.     jmp    Edit
  1619.  
  1620. ;move String right
  1621. RightMove: lhld    String1st
  1622.     inx    h
  1623.     shld    String1st
  1624.     jmp    RightOut
  1625.  
  1626. PAGE
  1627. ;**** Routine Left ****
  1628. ;moves cursor left
  1629.  
  1630. ;Can String move left?
  1631. Left:    lhld    StringBegin
  1632.     xchg
  1633.     lhld    StringCursor
  1634.     mov    a,d
  1635.     cmp    h
  1636.     jnz    Left1    ;jmp if yes
  1637.     mov    a,e
  1638.     cmp    l
  1639.     jnz    Left1    ;jmp if yes
  1640.     jmp    Edit    ;jmp if no
  1641.  
  1642. ;Move String left
  1643. Left1    dcx    h
  1644.     shld    StringCursor
  1645.  
  1646. ;Can Line move left?
  1647.     lhld    LineCursor
  1648.     mov    a,l
  1649.     cpi    0h
  1650.     jz    LeftMove ;jmp if no
  1651.     cpi    80h
  1652.     jz    LeftMove ;jmp if no
  1653.  
  1654. ;move Line left
  1655.     dcx    h
  1656.     shld    LineCursor
  1657.  
  1658. ;display new line
  1659. LeftOut: call    Display
  1660.     jmp    Edit
  1661.  
  1662. ;move String left
  1663. LeftMove: lhld    String1st
  1664.     dcx    h
  1665.     shld    String1st
  1666.     jmp    LeftOut
  1667.  
  1668. PAGE
  1669. ;**** Routine RightEdge ****
  1670. ;Moves cursor to far right edge
  1671.  
  1672. ;Can String move right?
  1673. RightEdge: lhld    LineCursor    ;for top
  1674.     push    h
  1675.     lhld    String1st    ;for de
  1676.     xchg
  1677.     lhld    StringCursor    ;for hl
  1678.     mov    a,m
  1679.     cpi    0h
  1680.     jz    REout    ;jmp if no
  1681.  
  1682. ;Move StringCursor and LineCursor right
  1683. ;Can LineCursor move right
  1684. RE1:    xthl
  1685.     mov    a,l
  1686.     cpi    4Fh
  1687.     jz    RE5    ;jmp if no
  1688.     cpi    0CFh
  1689.     jz    RE5    ;jmp if no
  1690.  
  1691. ;move LineCursor right
  1692.     inx    h
  1693. RE2:    xthl
  1694.  
  1695. ;move StringCursor right
  1696.     inx    h
  1697.  
  1698. ;can String move right
  1699.     mov    a,m
  1700.     cpi    0h
  1701.     jnz    RE1    ;jmp if yes
  1702.  
  1703. ;load new values
  1704. RE3:    shld    StringCursor
  1705.     xchg
  1706.     shld    String1st
  1707.     pop    h
  1708.     shld    LineCursor
  1709.  
  1710. ;display new line
  1711.     call    Display
  1712.     jmp    Edit
  1713.  
  1714. PAGE
  1715. ;Move StringCursor and String1st right
  1716. ;Return LineCursor
  1717. RE5:    xthl
  1718.  
  1719. ;move StringCursor and String1st right
  1720. RE6:    inx    h
  1721.     inx    d
  1722.  
  1723. ;can String move right
  1724.     mov    a,m
  1725.     cpi    0h
  1726.     jnz    RE6    ;jmp if yes
  1727.     jmp    RE3
  1728.  
  1729. REout:    pop    h
  1730.     jmp    Edit
  1731.  
  1732. PAGE
  1733. ;**** Routine LeftEdge ****
  1734. ;Moves cursor to far left edge
  1735.  
  1736. ;Can String move left?
  1737. LeftEdge: 
  1738.     lhld    StringBegin    ;for bc
  1739.     mov    b,h
  1740.     mov    c,l
  1741.     lhld    StringCursor
  1742.     mov    a,b
  1743.     cmp    h
  1744.     jnz    LE0    ;jmp if yes
  1745.     mov    a,c
  1746.     cmp    l
  1747.     jnz    LE0    ;jmp if yes
  1748.     jmp    Edit    ;jmp if no
  1749.  
  1750. LE0:    lhld    LineCursor    ;for top
  1751.     push    h
  1752.     lhld    String1st    ;for de
  1753.     xchg
  1754.     lhld    StringCursor    ;for hl
  1755.  
  1756. ;Move StringCursor and LineCursor left
  1757. ;Can LineCursor move left
  1758. LE1:    xthl
  1759.     mov    a,l
  1760.     cpi    0h
  1761.     jz    LE5    ;jmp if no
  1762.     cpi    80h
  1763.     jz    LE5    ;jmp if no
  1764.  
  1765. ;move LineCursor left
  1766.     dcx    h
  1767. LE2:    xthl
  1768.  
  1769. ;move StringCursor left
  1770.     dcx    h
  1771.  
  1772. ;can String move left
  1773.     mov    a,b
  1774.     cmp    h
  1775.     jnz    LE1    ;jmp if yes
  1776.     mov    a,c
  1777.     cmp    l
  1778.     jnz    LE1    ;jmp if yes
  1779.  
  1780. PAGE
  1781. ;load new values
  1782. LE3:    shld    StringCursor
  1783.     xchg
  1784.     shld    String1st
  1785.     pop    h
  1786.     shld    LineCursor
  1787.  
  1788. ;display new line
  1789.     call    Display
  1790.     jmp    Edit
  1791.  
  1792. ;Move StringCursor and String1st left
  1793. ;Return LineCursor
  1794. LE5:    xthl
  1795.  
  1796. ;move StringCursor and String1st left
  1797. LE6:    dcx    h
  1798.     dcx    d
  1799.  
  1800. ;can String move left
  1801.     mov    a,b
  1802.     cmp    h
  1803.     jnz    LE6    ;jmp if yes
  1804.     mov    a,c
  1805.     cmp    l
  1806.     jnz    LE6    ;jmp if yes
  1807.     jmp    LE3    ;jmp if no
  1808. PAGE
  1809. ;**** Routine DeleteChar ****
  1810. ;Deletes character cursor is on
  1811.  
  1812. ;Is StringCursor at end?
  1813. DeleteChar:
  1814.     lhld    StringCursor
  1815.     mov    a,m
  1816.     dcx    h
  1817.     ana    a
  1818.     jz    Edit    ;jmp if yes
  1819.  
  1820. ;Delete data at cursor
  1821. DelChar1: inx    h
  1822.     inx    h
  1823.     mov    a,m
  1824.     dcx    h
  1825.     mov    m,a
  1826.     ana    a    ;is it last char
  1827.     jnz    DelChar1 ;jmp if no
  1828.  
  1829. ;Decrement char count
  1830.     lhld    StringStart
  1831.     inx    h
  1832.     mov    a,m
  1833.     dcr    a
  1834.     mov    m,a
  1835.  
  1836. ;Display new line
  1837.     call    Display
  1838.     jmp    Edit
  1839. PAGE
  1840. ;**** Routine DeleteLeft ****
  1841. ;Delete character on left of cursor
  1842.  
  1843. ;Is StringCursor at end?
  1844. DeleteLeft:
  1845.     lhld    StringBegin
  1846.     xchg
  1847.     lhld    StringCursor
  1848.     mov    a,d
  1849.     cmp    h
  1850.     jnz    DelLeft1    ;jmp if no
  1851.     mov    a,e
  1852.     cmp    l
  1853.     jnz    DelLeft1    ;jmp if no
  1854.     jmp    Edit        ;jmp if yes
  1855.  
  1856. ;Is LineCursor at end?
  1857. DelLeft1:
  1858.     lhld    LineCursor
  1859.     mov    a,l
  1860.     cpi    0h
  1861.     jz    Edit    ;jmp if yes
  1862.     cpi    80h
  1863.     jz    Edit    ;jmp if yes
  1864.  
  1865. ;Decrement LineCursor position
  1866.     dcx    h
  1867.     shld    LineCursor
  1868.  
  1869. ;Decrement StringCursor position
  1870.     lhld    StringCursor
  1871.     dcx    h
  1872.     shld    StringCursor
  1873.  
  1874. ;Delete data at left of cursor
  1875.     dcx    h
  1876. DelLeft2: inx    h
  1877.     inx    h
  1878.     mov    a,m
  1879.     dcx    h
  1880.     mov    m,a
  1881.     ana    a    ;is it last char
  1882.     jnz    DelLeft2 ;jmp if no
  1883.  
  1884. ;Decrement char count
  1885.     lhld    StringStart
  1886.     inx    h
  1887.     mov    a,m
  1888.     dcr    a
  1889.     mov    m,a
  1890.  
  1891. ;Display new line
  1892.     call    Display
  1893.     jmp    Edit
  1894.  
  1895. PAGE
  1896. ;**** Routine EnterChar ****
  1897. ;Enter character at cursor position. 
  1898. ;Cursor and all to right moves right.
  1899.  
  1900. ;Store character
  1901. EnterChar:
  1902.     mov    c,a    ;char stored in c
  1903.  
  1904. ;Is String full?
  1905.     lhld    StringStart
  1906.     mov    a,m
  1907.     inx    h
  1908.     cmp    m
  1909.     jnz    Char1    ;jmp if no
  1910.  
  1911. ;Send bell
  1912.     mvi    c,2
  1913.     mvi    e,7h
  1914.     call    Bdos
  1915.     jmp    Edit
  1916.  
  1917. ;Increment String count
  1918. Char1:    mov    a,m
  1919.     inr    a
  1920.     mov    m,a
  1921.  
  1922. ;Increment StringCursor
  1923.     lhld    StringCursor
  1924.     inx    h
  1925.     shld    StringCursor
  1926.     dcx    h
  1927.  
  1928. ;Move in new data
  1929. Char2:    mov    a,m    ;get data for next
  1930.     mov    m,c    ;write data
  1931.     mov    c,a    ;set up for next
  1932.     inx    h
  1933.     ana    a    ;is it last
  1934.     jnz    Char2    ;jmp if no
  1935.     mov    m,c    ;write end flag
  1936.  
  1937. PAGE
  1938. ;Can LineCursor move right?
  1939.     lhld    LineCursor
  1940.     mov    a,l
  1941.     cpi    4Fh
  1942.     jz    Char5    ;jmp if no
  1943.     cpi    0CFh
  1944.     jz    Char5    ;jmp if no
  1945.  
  1946. ;move LineCursor right
  1947.     inx    h
  1948.     shld    LineCursor
  1949.  
  1950. ;Display line
  1951. Char4:    call    Display
  1952.     jmp    Edit
  1953.  
  1954. ;Increment String1st
  1955. Char5:    lhld    String1st
  1956.     inx    h
  1957.     shld    String1st
  1958.     jmp    Char4
  1959.  
  1960.  
  1961.     end    100h
  1962.