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 / HAMRADIO / MORSETXT.LBR / MORSETXT.AZM / MORSETXT.ASM
Assembly Source File  |  2000-06-30  |  51KB  |  2,365 lines

  1. .he MORSETXT.* v1.0     de WB1HKU/6 --CHR$(13)24AUG85         -#-
  2. .po2
  3. ;
  4. ;Assemble with ASM.
  5. ;
  6. BDOS    equ    5
  7. LF    equ    10
  8. CR    equ    13
  9. FCB    equ    5Ch
  10. DMA    equ    80h
  11. FX    equ    0FFh
  12. FOXES    equ    0FFFFh
  13. ;
  14. CLOCK    equ    40    ;CPU clockspeed in hundreds of kilohertz
  15. ;
  16. FALSE    equ    0
  17. TRUE    equ    NOT FALSE
  18. ;
  19. ;
  20. CONDBUG    equ    FALSE    ;assembles in debugging tracers for
  21.             ;console interactions if true, 
  22.             ;including all ditrate controls
  23. BIGDBUG    equ    FALSE    ;assembles in debugging tracers for
  24.             ;wildcard filename expansions and 
  25.             ;command-line controls if true
  26. DEBUG    equ    FALSE    ;assembles in debugging tracers for
  27.             ;single-file buffer refresh if true
  28. ;
  29. NODBUG    equ    NOT (CONDBUG OR BIGDBUG OR DEBUG)
  30. ;
  31. ;tracing messages mess up your screen, but I needed 'em...
  32. ;
  33. ;
  34. PORTAS    equ    84h    ;console status and control port
  35. PORTAD    equ    80h    ;console data port
  36. CINMSK    equ    1    ;character-is-input mask
  37. CINMCH    equ    1    ;character-is-input match
  38. PORTBS    equ    8Ch    ;port B status and control port
  39. PORTBD    equ    88h    ;port B data port (not presently used)
  40. ;
  41. RECORD    equ    4000h    ;start-point of read-in records
  42.             ;--must be on a page boundary
  43. ;
  44. ;
  45.     org    100h
  46. ;
  47.     call    ILPRT
  48. ;
  49. ;Sign on at the console. 
  50. ;
  51. ;             0123456789012345678901234567890123
  52. ;
  53.     db    CR,LF,9,'***----MORSETXT.COM v1.0-----***'
  54.     db    CR,LF,9,'*                              *'
  55.     db    CR,LF,9,'*   International Morse Code   *'
  56.     db    CR,LF,9,'*  transmitter for text files  *'
  57.     db    CR,LF,9,'*  Ampro Little Board version  *'
  58.     db    CR,LF,9,'*    via Port B''s HSO line     *'
  59.     db    CR,LF,9,'*                              *'
  60.     db    CR,LF,9,'***-- --CHR$(13)23AUG85------***'
  61.     db    CR,LF,LF,0,1Ah
  62. ;
  63. ;
  64.     lxi    h,0
  65.     dad    sp
  66.     shld    STAKS
  67.     lxi    sp,STAKS
  68.     call    MULTD    ;Correct delay constant for clockrate.
  69.     call    START    ;Now earn your disk space.
  70. EXIT:    lhld    STAKS
  71.     sphl
  72.     ret
  73. ;
  74. ;These storage cells are down here where it's easy to get to
  75. ;them with DDT. For ROMming, copy 'em up back, in RAM, and
  76. ;work on 'em there.
  77. ;
  78. DELCON:    db    0,0    ;32-bit value stored in byte-serial
  79.     db    4,0A6h    ;form. Delay constant for 0.1 wpm
  80.             ;when running a Z80 at 0.1 MHz. This
  81.             ;value is adjusted for declared
  82.             ;clockrate in the first routine 
  83.             ;called.
  84. DITCNT:    ds    2    ;the key delay variable.
  85. ;
  86. DAHCNT:    ds    2    ;no longer directly used by program.
  87. ;
  88. CLKBYT:    db    CLOCK    ;clock frequency in 100 KHz increments
  89. WSPACE:    db    0    ;if true, space out the characters.
  90. XTNFLG:    db    0    ;if true, only ARRL characters. 
  91. PRETTY:    db    0    ;if 0, excess period becomes <bt>, and
  92.             ;only one <space> in a row is sent.
  93. ;
  94. ;WSPACE, XTNFLG and PRETTY are copied into WSPBYT, XTNBYT and
  95. ; PRYBYT just before each command line's arguments are brought
  96. ; down. Thus (last-minute change) the defaults may be set by
  97. ; overlay.
  98. ;
  99. KEY:    jmp    KEYR
  100. UNKEY:    jmp    UNKEYR     ;Hooks for the three hardware-dependent
  101. CONSEN:    jmp    CSEN    ;routines, allowing for overlays.
  102. SEIKON:    jmp    CONSAY
  103. ;
  104. ;These are the hardware-specific sending routines.
  105. ;As written, KEYSTB works with the Ampro's DART.
  106. ;The callers, KEY and UNKEY, differ in that KEY
  107. ;calls with A=0FFh, while UNKEY calls with A=0.
  108. ;The Ampro initialization routines set the HSO line
  109. ; on serial-B, so this routine-set resets that line
  110. ;in order to key the oscillator.
  111. ;Don't trash anything but A, and be as quick as you
  112. ;can. The massive delays in KEY and UNKEY will mask
  113. ;a lot of fixed delay, but you want to be able to 
  114. ;really hear an honest 45 wpm, don't you?  
  115. ;
  116. ;
  117. KEYR:    mvi    a,FX    ;delay-count is in hl
  118.     call    KEYSTB
  119. KELP:    nop! nop! nop! nop! nop    ;If you mess with these
  120.     nop! nop! nop! nop! nop    ;delays, you'll have to
  121.     nop! nop! nop! nop! nop    ;retune the master delay
  122.     nop! nop! nop! nop! nop    ;count. Try to put it in
  123.     nop! nop! nop! nop! nop    ;the same general range.
  124.     nop! nop         ;Otherwise, you'll run
  125.     mov    a,a        ;out of arithmetic range
  126.     dcx    h        ;one way or the other.
  127.     mov    a,l
  128.     ora    h
  129.     jnz    KELP
  130.     ret
  131. ;
  132. UNKEYR:    xra    a    ;ditto
  133.     call    KEYSTB
  134. UKELP:    nop! nop! nop! nop! nop
  135.     nop! nop! nop! nop! nop
  136.     nop! nop! nop! nop! nop
  137.     nop! nop! nop! nop! nop
  138.     nop! nop! nop! nop! nop
  139.     nop! nop
  140.     mov    a,a
  141.     dcx    h
  142.     mov    a,l
  143.     ora    h
  144.     jnz    UKELP
  145.     ret
  146. ;
  147. KEYSTB:    cma
  148.     push    psw
  149.     mvi    a,5
  150.     out    PORTBS
  151.     pop    psw
  152.     push    b
  153.     mvi    b,68h
  154.     ani    2
  155.     add    b
  156.     out    PORTBS
  157.     pop    b
  158.     ret
  159. ;
  160. ;This is the direct port status call. It is called by
  161. ; ILMORS and GOCHAR on their way back from sending a
  162. ; character. If CON: has a freshly typed character,
  163. ; go play with it. Otherwise, as you were.   
  164. ;
  165. CSEN:    in    PORTAS    ;console port
  166.     ani    CINMSK
  167.     cpi    CINMCH    ;Here's where we break off if
  168.     cz    SEIKON    ;CON: is sending.
  169.     ret
  170. ;
  171. ;
  172. ;I trust this is enough room for whatever you have to do.
  173.     org    400h
  174. ;
  175. START:    lxi    h,200    ;wpm * 10
  176.     shld    RESULT
  177.     call    CONVRT    ;set up a 20 wpm coderate
  178. ;
  179.     IF    DEBUG
  180.     ;
  181.     call    ILPRT
  182.     db    CR,LF,'default baudrate set.',0
  183.     ;
  184.     ENDIF    ;DEBUG
  185. ;
  186. ;
  187. ;Copy the single filename, if there is one, into NAMBUF
  188. ;and cap it with a <crlf> and an EOF, so we've got 
  189. ;someplace to go if we get ^X'd out of the test string.
  190. ;
  191. COPYUP:    lxi    h,DMA
  192.     mvi    b,0    ;pick up the extended-argument
  193.     mov    c,m    ;bytecount left by CCP
  194.     inx    h
  195.     inx    h    ;skip over the inevitable space
  196.     dcr    c    ;...and knock it off the count.
  197.     lxi    d,NAMBUF
  198.     call    M2D4B
  199.     mvi    a,CR
  200.     stax    d
  201.     inx    d
  202.     mvi    a,LF
  203.     stax    d
  204.     inx    d
  205.     mvi    a,1Ah
  206.     stax    d
  207. ;
  208.     IF    DEBUG
  209.     ;
  210.     call    ILPRT
  211.     db    CR,LF,'Entry string copied up.',0
  212.     ;
  213.     ENDIF    ;DEBUG
  214. ;
  215. ;
  216. ;Send 'test' out at the morse line. With no sending-rate yet
  217. ; sought, that'll be at the default rate. 
  218. ;
  219.     lhld    DITCNT    ;DAHCNT = 3 * DITCNT
  220.     push    h
  221.     pop    b
  222.     dad    h
  223.     dad    b
  224.     shld    DAHCNT
  225. ;
  226.     IF    DEBUG
  227.     ;
  228.     call    ILPRT
  229.     db    CR,LF,'DAHCNT expanded.',0
  230.     ;
  231.     ENDIF    ;DEBUG
  232. ;
  233.     lda    FCB+1
  234.     cpi    '$'
  235.     jz    INLIST
  236. ;
  237.     IF    DEBUG
  238.     ;
  239.     call    ILPRT
  240.     db    CR,LF,'call ILMORS',0
  241.     ;
  242.     ENDIF    ;DEBUG
  243. ;
  244.     call    ILMORS
  245.     db    'TEST DE WB1HKU/6 @',0
  246. ;
  247.     IF    DEBUG
  248.     ;
  249.     call    ILPRT
  250.     db    CR,LF,'TEST de WB1HKU/6 *',CR,LF,0
  251.     ;
  252.     ENDIF    ;DEBUG
  253. ;
  254. ;Empty argument string, or just hashes or query? Then the user
  255. ; was just kerchunking. Go home.
  256. ;
  257.     lda    FCB+1    ;all the well-known ways to
  258.     cpi    ' '    ;tell a program "just kidding".
  259.     rz
  260.     cpi    '/'
  261.     rz
  262.     cpi    '?'
  263.     jnz    BIZNES
  264.     lda    FCB+2
  265.     cpi    ' '
  266.     rz
  267.     cpi    '/'
  268.     jnz    BIZNES
  269.     lda    FCB+3
  270.     cpi    ' '
  271.     rz
  272. ;
  273.     IF    DEBUG
  274.     ;
  275.     call    ILPRT
  276.     db    CR,LF,'BIZNESS',0
  277.     ;
  278.     ENDIF    ;DEBUG
  279. ;
  280. ;
  281. ;Nope, the user means  business.  Get to work.  First,  we've
  282. ;already gotten the opening parameters  up out of harm's way.
  283. ;Now copy it right back down, but formatted. Clumsy, you say?
  284. ;Maybe, but it lets you use (rather than send) a SUBfile from
  285. ;the console, without restart.
  286. ;
  287. BIZNES:    mvi    a,0h        ;the filename isn't preformatted...
  288.     sta    USEMOV        ;use M2D4BF to move it down again.
  289.  
  290. ;
  291. ;At this point  there is a list  of one or more filenames  in
  292. ;the names buffer at NAMBUF, perhaps with trailing arguments,
  293. ;each line demarcated by <crlf>, the list terminated with ^Z. 
  294. ;Now,  one at a time,  those filenames  are brought down into
  295. ;the FCB at 5Ch,  brought in and sent.  Any  command switches
  296. ;in the line  are asserted.  Any not present  are deasserted.
  297. ;The ditrate  remains  the same  unless  there is  a  numeric
  298. ;argument in the line.
  299. ;
  300. ;Go get the first filename. 
  301. ;
  302. SETUP:    lhld    NAMPTR    ;if that's a control Z you've got
  303. UPEND:    mov    a,m    ;there, I'm going home.
  304.     ani    7Fh
  305.     cpi    1Ah    ;(Will never be seen if '&' switch
  306.     rz        ;is used.)
  307.     cpi    CR
  308.     jz    UPSET
  309.     cpi    ' '
  310.     jz    UPSET
  311.     cpi    LF
  312.     jz    UPSET
  313.     cpi    '$'
  314.     jz    INLIST
  315.     cpi    '!'
  316.     jnz    NOKEY
  317.     inx    h
  318.     shld    NAMPTR
  319.     call    MORKY
  320.     jmp    SETUP
  321. NOKEY:    cpi    '&'    ;Ampersand means, loop forever.
  322.     jnz    NOTUPS    ;Sorry, you can't use that as the
  323.             ;first character in a filename.
  324.     lxi    h,NAMBUF
  325.     shld    NAMPTR
  326.     call    CONSEN    ;Lockup-proofing for the idiots.
  327.     jmp    SETUP
  328. UPSET:    inx    h
  329.     jmp    UPEND
  330. ;
  331. NOTUPS:    inx    h    ;If that's a letter between A and P
  332.     mov    a,m    ;inclusive, and what follows it is
  333.     dcx    h    ;a colon, it's a drive spec. Put it
  334.     cpi    ':'    ;in and pray.
  335.     jnz    NOTSPE    ;Either way, HL ends up pointing at
  336.     mov    a,m    ;the first letter of the filename.
  337.     inx    h
  338.     inx    h
  339.     ani    5Fh
  340.     sui    40h
  341.     jc    NOTSPE
  342.     cpi    17
  343.     jnc    NOTSPE
  344.     sta    FCB    ;Never mind that null, son, we've
  345.     jmp    SPECD    ;already got our drivespec.
  346. ;
  347. NOTSPE:    xra    a    ;No? Okay, then, go ahead and 
  348.     sta    FCB    ;zero out the drivespec.
  349. ;
  350. ; +++ COPY DOWN THE FIRST LINE'S FILENAME.TYP +++
  351. ;
  352. SPECD:    lxi    d,FCB+1
  353.     mvi    c,11
  354.     lda    USEMOV
  355.     ora    a
  356.     jz    OTHRMV    ;If USEMOV is NOT ZERO, use the
  357.     call    M2D4B    ;regular filename mover, well-behaved 
  358.     jmp    M2OVDN    ;If USEMOV is ZERO, use the
  359. OTHRMV:    call    M2D4BF    ;special filename mover, pads names
  360.             ;and ambiguities (frightening thought,
  361.             ;eh? They call that "fashion".)
  362. M2OVDN:    shld    NAMPTR    ;Now store the pointer for next time,
  363.             ;suitably advanced.
  364.  
  365. ;
  366. ;First, arguments are brought down from NAMBUF and plugged
  367. ; in as initial parameters. We'll stop trying when we hit
  368. ; the <crlf>.
  369. ;
  370. GETARG:    lda    WSPACE    ;Turn 'em to default. This way, if we
  371.     sta    WSPBYT    ;toggle, MAYBE it's to assert.
  372.     lda    XTNFLG
  373.     sta    XTNBYT
  374.     lda    PRETTY
  375.     sta    PRYBYT
  376.     lhld    NAMPTR
  377. GARGLP:    mov    a,m
  378.     ani    7Fh
  379.     cpi    1Ah
  380.     rz
  381.     cpi    ' '
  382.     jz    GARGSP
  383. ;
  384. ;Inspect argument for numbers.
  385. ;
  386.     cpi    '0'    ;This means '$', bang will be
  387.     jc    GARGDN    ;noticed as soon as the file is
  388.             ;sent.
  389.     cpi    ':'
  390.     jc    GARGNM
  391. ;
  392.     ani    5Fh    ;No numbers? Mask for letters.
  393.     cpi    'W'    ;Any letter switches not found
  394.     cz    WTOG    ;on a submitted line are presumed
  395.     cpi    'X'    ;deasserted.
  396.     cz    XTOG
  397.     cpi    'P'
  398.     cz    PTOG
  399.     jmp    GARGSP
  400. ;
  401. ;Found any? Then pointer is at the most-significant one.
  402. ; Beginning there, convert into hex. The numbers are the
  403. ; nominal desired words-per-minute rate times 10. Put 'em
  404. ; into the furnace for CONVRT and DIVI to work on.
  405. ;
  406. ;These subsidiary labels sure read like Orkish, don't they?
  407. ; Or R'Lyehn...
  408. ;
  409. GARGNM:    call    ILPRT
  410.     db    CR,LF,'[No','w'+80h,0
  411.     lxi    b,0        ;prepare count
  412.     lxi    d,CONBUF+2    ;point for copying
  413. GRGNLP:    mov    a,m    ;hl points into NAMBUF
  414.     push    psw
  415.     call    PCHAR
  416.     pop    psw
  417.     stax    d    ;de points into CONBUF
  418.     inr    c    ;count the passed byte
  419.     mov    a,c    ;...but don't allow more
  420.     cpi    16    ;than 16. You don't have to
  421.     jz    GRGNDN    ;type silly. BDOS'll getcha.
  422.     inx    d    ;Bump the pointers and check
  423. GRS:    inx    h     ;the next byte: number?
  424.     mov    a,m    ;I'll do you a favor: any
  425.     cpi    '.'    ;dots, we'll simply skip.
  426.     jz    GRS    ;Anything else, though, and
  427.     cpi    '0'    ;that's it for the number.  
  428.     jc    GRGNDN
  429.     cpi    ':'
  430.     jc    GRGNLP
  431. GRGNDN:    mov    a,c
  432.     sta    CONBUF+1
  433.     push    h    
  434.     call    ASDEC
  435.     call    CONVRT
  436.     pop    h
  437.     call    ILPRT
  438.     db    '/1','0'+80h,'wpm.]',0
  439.     jmp    GARGLP
  440. ;
  441. GARGSP:    inx    h
  442.     jmp    GARGLP
  443. GARGDN:    shld    NAMPTR
  444.  
  445. ;
  446. ;Inspect filename for *.SUB. If so, pull it in, record
  447. ;by record, verbatim into NAMBUF.  If not, go test for
  448. ;wildcards.
  449. ;
  450. ISSUB:    lxi    h,FCB+9    
  451.     mov    a,m
  452.     cpi    'S'
  453.     jnz    NOTSUB    ;wildcard test next.
  454.     inx    h
  455.     mov    a,m
  456.     cpi    'U'
  457.     jnz    NOTSUB
  458.     inx    h
  459.     mov    a,m
  460.     cpi    'B'
  461.     jnz    NOTSUB
  462. ;
  463. ;It's a SUB file.
  464. ;
  465.     xra    a        ;We'll use M2D4BF to bring down
  466.     sta    USEMOV        ;virtual (unformatted) console
  467.                 ;input at SETUP. SUBfiles aren't
  468.                 ;formatted by CCP.
  469.     lxi    d,NAMBUF
  470.     mvi    c,1Ah    ;set DMA
  471.     call    BDOS
  472. ;
  473.     mvi    a,1Ah    ;Insert an end-of-list marker.
  474.     sta    NAMBUF    ;if nothing gets copied (empty
  475.             ;directory entry), we'll just
  476.             ;shut down on finding it. 
  477.     xra    a
  478.     sta    FCB+32
  479.     sta    FCB+12
  480.     lxi    d,FCB
  481.     mvi    c,0Fh    ;open file
  482.     call    BDOS
  483.     inr    a
  484.     jnz    SUBOPN
  485.     call    ILPRT
  486.     db    'BDOS can''t find that SUB file.',0
  487.     ret
  488. ;
  489. SUBOPN:    lxi    d,NAMBUF
  490.     shld    DMADR
  491. SBOPLP:    lxi    d,FCB
  492.     mvi    c,14h    ;read sequential
  493.     call    BDOS
  494.     ora    a
  495.     jz    SBOPDN
  496.     lhld    DMADR
  497.     lxi    b,80h
  498.     dad    b
  499.     shld    DMADR
  500.     xchg
  501.     mvi    c,1Ah    ;set DMA (80h up)
  502.     call    BDOS
  503.     jmp    SBOPLP
  504. ;
  505. SBOPDN:    lxi    h,NAMBUF
  506.     shld    NAMPTR    ;Reset the pointer to Go.
  507.     jmp    SETUP    ;go pull down the first line for use.
  508.             ;If you're clever, the first filetype
  509.             ;in your SUB file isn't SUB or some-
  510.             ;thing ambiguous... otherwise, we'll
  511.             ;just go around again until we do get
  512.             ;a file we can send.
  513. ;
  514. ;Inspect filename for '?'. Any? Then do search-for-first, then
  515. ; search-for-next, to collect all the filenames that match into
  516. ; a names buffer. The buffer will be capped with ^Z; when all
  517. ; the names are serviced, there'll be ^Z instead of a name, the 
  518. ; signal to go home.
  519. ;Of course, any ambiguous filename.typ will be expanded out right
  520. ; on top of anything you might have had in NAMBUF...
  521. ;
  522. ;If no '?', use the lone filename.typ into the filenames
  523. ; buffer and proceed.
  524. ;
  525. NOTSUB:    call    ISAMBG
  526.     jz    ISNOT    ;go open and send the file.
  527. ;
  528.     IF    BIGDBUG
  529.     ;
  530.     call    ILPRT
  531.     db    CR,LF,'Enter EXPAN.',0
  532.     ;
  533.     ENDIF    ;BIGDBUG
  534. ;
  535.     lxi    d,DMA
  536.     mvi    c,1Ah    ;set DMA address to 80h
  537.     call    BDOS
  538.     lxi    h,NAMBUF    ;reset the NAMBUF pointer here
  539.     shld    NAMPTR
  540. ;
  541. ;
  542. ;
  543. ;-------<EXPANSION MODULE>--------START
  544. ;
  545. EXPAN:    mvi    a,0FFh    ;pop the MOV flag --this stuff'll
  546.     sta    USEMOV    ;be preformatted when it's used.
  547.     xra    a
  548.     sta    FIRSTM    ;set the FIRST TIME flag
  549. ;
  550.     IF    BIGDBUG
  551.     ;
  552.     call    ILPRT
  553.     db    CR,LF,'FCB: ',CR,LF,0
  554.     mvi    a,8
  555.     sta    DMPCTR
  556.     lxi    h,FCB
  557.     call    DUMPR
  558.     call    ILPRT
  559.     db    CR,LF,'DRIVE CODE: ',0
  560.     lda    USRDRV
  561.     call    PHEX
  562.     call    ILPRT
  563.     db    CR,LF,'[SEARCH FOR FIRST] ',0
  564.     ;
  565.     ENDIF    ;BIGDBUG
  566. ;
  567.     lxi    d,FCB
  568.     mvi    c,11h    ;search for first
  569.     call    BDOS
  570. EXPLP:
  571. ;
  572.     IF    BIGDBUG
  573.     ;
  574.     sta    STASH
  575.     call    ILPRT
  576.     db    'result code: ',0
  577.     lda    STASH
  578.     call    PHEX
  579.     call    ILPRT
  580.     db    CR,LF,0
  581.     lda    STASH
  582.     ;
  583.     ENDIF    ;BIGDBUF
  584. ;
  585.     cpi    0FFh    ;FF? No more matches. We're done.
  586.     jz    EXPDUN
  587.     add    a    ;rotate returned code
  588.     add    a    ;to be an offset
  589.     add    a
  590.     add    a
  591.     add    a
  592.     mvi    d,0
  593.     mov    e,a
  594.     lxi    h,DMA+1    ;step across user number
  595.     dad    d    ;now points to directory entry
  596.     shld    STASHW    ;save a pointer copy for later
  597. ;
  598.     IF    BIGDBUG
  599.     ;
  600.     push h! push d! push b
  601.     push psw
  602.     mvi    a,0Eh
  603.     sta    DMPCTR
  604.     call    DUMPR
  605.     pop psw
  606.     pop b! pop d! pop h
  607.     ;
  608.     ENDIF    ;BIGDBUG
  609. ;
  610.     xchg
  611.     lhld    NAMPTR    ;first time, @ NAMBUF.
  612.     xchg        ;hl @ 80h+, de @ NAMBUF+
  613.     lda    FIRSTM    ;If this is the first time
  614.     ora    a    ;through, don't preface new
  615.     jz    SKIPCR    ;name with <crlf> or look 
  616.             ;for duplication of entry.
  617.     call    CHEK11    ;test for redundance
  618.     mov    a,b    ;Zero? Matches previous entry.
  619.     ora    a
  620.     jz    REDUND
  621. ;
  622.     IF    BIGDBUG
  623.     ;
  624.     call    ILPRT
  625.     db    '(not redundant) ',0
  626.     ;
  627.     ENDIF    ;BIGDBUG
  628. ;
  629.     xchg        ;hl @ last NAMBUF entry +1
  630.     mvi    m,CR    ;put in EOL marker
  631.     inx    h
  632.     mvi    m,LF
  633.     inx    h
  634.     shld    NAMPTR    ;advance the stored pointer now
  635.     xchg        ;put it back into de
  636. SKIPCR:    lhld    STASHW    ;rewind input pointer to start of name
  637.     lxi    b,11
  638.     call    M2D4B    ;NOW copy the filename up.
  639.     mvi    a,0FFh    ;And reset the flag: we're in
  640.     sta    FIRSTM    ;and running.
  641. ;
  642.     IF    BIGDBUG
  643.     ;
  644.     call    ILPRT
  645.     db    9,7,'-------<<<<< COPY >>>>-------',CR,LF,0
  646.     mvi    a,0Eh
  647.     sta    DMPCTR
  648.     lhld    NAMPTR
  649.     call    DUMPR    
  650.     call    BDWAIT
  651.     call    BDWAIT
  652.     ;
  653.     ENDIF    ;BIGDBUG
  654. ;
  655. REDUND:    lxi    d,FCB
  656.     mvi    c,12h    ;search for next
  657.     call    BDOS
  658. ;
  659.     IF    BIGDBUG
  660.     ;
  661.     call    ILPRT
  662.     db    CR,LF,'[SEARCH FOR NEXT]',0
  663.     ;
  664.     ENDIF    ;BIGDBUG
  665. ;
  666.     jmp    EXPLP
  667. ;
  668. EXPDUN:    lhld    NAMPTR    ;BDOS can't find any more matches.
  669.     lxi    d,11    ;Put a line-end <crlf> after the
  670.     dad    d    ;last entry and go on.
  671.     mvi    m,CR
  672.     inx    h
  673.     mvi    m,LF
  674.     inx    h
  675.     mvi    m,1Ah    ;cap it with EOF
  676.     lxi    h,NAMBUF
  677.     shld    NAMPTR    ;Reset the pointer to Go.
  678. ;
  679.     IF    BIGDBUG
  680.     ;
  681.     call    ILPRT
  682.     db    CR,LF,'EXPDUN. Now jmp SETUP.',CR,LF,0
  683.     ;
  684.     ENDIF    ;BIGDBUG
  685. ;
  686.     jmp    SETUP    ;Still inline. A return here would
  687.             ;be to EXIT. 'Course, it IS a
  688.             ;back-jump... Go pull down the first
  689.             ;line for use.
  690. ;
  691. ;11-character filenam.typ ambiguity test for 
  692. ;initial argument
  693. ;
  694. AMBIG:    lxi    b,11    ;c is counter, b is flag
  695.     mvi    a,'?'    ;Assuming that CCP put together
  696. AMBGLP:    cmp    m    ;this filename.typ, the only
  697.             ;ambiguous character is '?'.
  698.             ;If it came out of a console
  699.     jnz    NOAM    ;string or a SUBfile, though,
  700.     mov    b,a    ;the string may include '*'.
  701. NOAM:    inx    h    ;That'll have to be handled
  702.     dcr    c    ;gently, since it'll throw
  703.     jnz    AMBGLP    ;off the character count.
  704.     ret            
  705. ;
  706. ;Check two eleven character strings for duplication.
  707. ;On return, b = 0 if they match.
  708. ;On return, hl and de point once beyond their strings.
  709. ;
  710. CHEK11:    lxi    b,11    ;set up loop-counter and flag.
  711. CHK11L:    ldax    d    ;get byte from NAMBUF.
  712.     cmp    m    ;Match? Fall out if not: the name
  713.     jnz    CHKOUT    ;is not redundant.
  714.     inx    h    ;Keep looping. When c = 0, we'll
  715.     inx    d    ;blindly copy it into b, indicating
  716.     dcr    c    ;a true compare. If we fall out,
  717.     jnz    CHK11L    ;though, that'll be a nonzero
  718. CHKOUT:    mov    b,c    ;loopcount we copy into b.
  719.     xra    a
  720.     cmp    c
  721.     rz
  722. CHKOLP:    inx    h
  723.     inx    d
  724.     dcr    c
  725.     jnz    CHKOLP
  726.     ret
  727. ;
  728.     IF    BIGDBUG
  729.     ;
  730. BDWAIT:    push    h    ;This waitloop gives me time
  731.     push    psw    ;to see what the filename lines
  732.     lxi    h,0    ;are up to, without sending CQ
  733. BDWALP:    dcx    h    ;on the ^S key.
  734.     mov    a,l
  735.     ora    h
  736.     jnz    BDWALP
  737.     pop    psw
  738.     pop    h
  739.     ret
  740.     ;
  741.     ENDIF    ;BIGDBUG
  742. ;
  743. ;
  744. ;-------<EXPANSION MODULE>--------END
  745. ;
  746. ISNOT:
  747. ;
  748.     IF    BIGDBUG
  749.     ;
  750.     call    ILPRT
  751.     db    CR,LF,'Next file, according to NAMPTR: ',CR,LF,0
  752.     lhld    NAMPTR
  753.     lxi    b,-16    ;back it off to include present line
  754.     dad    b
  755.     mvi    a,0Eh    ;two lines, please.
  756.     sta    DMPCTR
  757.     call    DUMPR
  758.     ;
  759.     ENDIF    ;DEBUG
  760. ;
  761.     xra    a
  762.     sta    FCB+12    ;and et cetera
  763.     sta    FCB+32    ;and et cetera.
  764. ;
  765.     IF    BIGDBUG
  766.     ;
  767.     call    ILPRT
  768.     db    CR,LF,'Check this out. Did I fill out the '
  769.     db    'FCB okay?',CR,LF,7,0
  770.     mvi    a,8
  771.     sta    DMPCTR    ;I only wanna see one record, honest.
  772.     lxi    h,FCB
  773.     call    DUMPR
  774.     ;
  775.     ENDIF    ;BIGDBUG
  776. ;
  777.     lxi    d,FCB
  778.     mvi    c,0Fh    ;open file
  779.     call    BDOS
  780.     inr    a
  781.     jnz    ISOPEN
  782.     call    ILPRT
  783.     db    CR,LF,9,'BDO','S'+80h,'can''','t'+80h
  784.     db    'fin','d'+80h,'m','y'+80h,'file',':'+80h,0
  785.     jmp    WIMPER
  786. ;
  787. ;Pull the first two records of the file into the file buffer.
  788. ;From here until file end, program flow should be relatively
  789. ;linear unless pestered. At file end, it'll pull down the next
  790. ;line in NAMBUF and play with that.
  791. ;
  792. ISOPEN:    lxi    d,RECORD
  793.     mvi    c,1Ah    ;set DMA address
  794.     call    BDOS
  795.     lxi    d,FCB
  796.     mvi    c,14h    ;read sequential
  797.     call    BDOS
  798.     lxi    d,RECORD+80h
  799.     mvi    c,1Ah    ;set DMA up a record
  800.     call    BDOS
  801.     lxi    d,FCB
  802.     mvi    c,14h    ;read sequential
  803.     call    BDOS
  804. ;
  805. ; Set the record toggle, indicating that the second record was
  806. ; the last one loaded. Set the record pointer to the byte previous 
  807. ; to the first byte of the first record. Because of how we
  808. ; increment the pointer, that means setting it to the last byte
  809. ; of the records page.
  810. ;
  811.     mvi    a,FX
  812.     sta    RECTGL
  813.     lxi    h,RECORD+255
  814.     shld    RECPTR
  815.     xra    a    ;Reset the EXHAUST flag too.
  816.     sta    XHAUST
  817.     call    CRLF    ;Start a new screen line
  818. ;
  819.     call    LOOP    ;Now send the file.
  820.     jmp    SETUP    
  821. ;
  822. ;Loop.
  823. ;Advance the pointer. Ani 7Fh. Zero? Reset the high byte to 
  824. ; wrap around. Then test the record pointer.
  825. ;For this to work as is, the record buffers must be on even
  826. ; page boundaries. That's why I put 'em someplace up high,
  827. ; where I could define the edges in isolation.
  828. ;
  829. LOOP:    lhld    RECPTR    ;advance the character pointer here...
  830.     inr    l    ;but don't let it out of the page.
  831.     shld    RECPTR    ;store it immediately.
  832.     mov    a,l
  833.     ani    7Fh    ;Did we just walk across the border
  834.     jnz    INREC    ;into another record?
  835. ;
  836.     IF    DEBUG
  837.     ;
  838.     call    ILPRT
  839.     db    '7Fh hit.',8,8,8,8,8,8,8,8,LF,0
  840.     ;
  841.     ENDIF    ;DEBUG
  842. ;
  843. ;
  844. ;Ani 80h. Are the exposed bit and the record toggle now
  845. ; in the same state? Then set the record-exhausted flag, so
  846. ; it'll be noticed next time there's a sentence end.
  847. ;
  848.     lda    RECPTR    ;pick up lobyte of record pointer,
  849.     ani    80h    ; and mask. Now it's either 80h 
  850.     jz    NOFF    ; or 00. If it's 00, leave it. If
  851.     mvi    a,FX    ; it's 80h, turn it into 0FFh.
  852. NOFF:    lxi    h,RECTGL    ;repoint to the record-toggle
  853.     cmp    m    ;...and compare. Match? Then we just
  854.     jnz    INREC    ;walked into the last record loaded.
  855.     mvi    a,FX    ;That means the one we left is 
  856.     sta    XHAUST    ;exhausted. Flag for a refresher.
  857. ;
  858.     IF    DEBUG
  859.     ;
  860.     call    ILPRT
  861.     db    'XHAUST set.',8,8,8,8,8,8,8,8,8,8,8,LF,0
  862.     ;
  863.     ENDIF    ;DEBUG
  864. ;
  865. ;Get the character. EOF? We done.
  866. ;
  867. INREC:    lda    RECPTR
  868.     ani    7Fh
  869.     cpi    7Fh
  870.     jnz    SOKAY
  871. ;
  872. ;Test for emergency fetch. Pointer at end of record? 
  873. ; Record-exhausted flag raised? Then Thomas Hardy has struck. 
  874. ;Obtrusive or not, fetch the next record NOW.
  875. ;
  876. MRGNC:    lda    XHAUST
  877.     ora    a
  878.     jz    SOKAY
  879.     call    GETIT
  880. ;
  881. SOKAY:    lhld    RECPTR
  882.     mov    a,m
  883.     ani    7Fh    ;WS top bits drive it crazy.
  884.     sta    STASH
  885.     cpi    1Ah
  886.     rz
  887. ;
  888. ;Show it at the console.
  889. ;
  890.     mov    e,a
  891.     mvi    c,6
  892.     call    BDOS
  893. ;
  894. ; Is it a period? Then increment the period-count.
  895. ; Query? Ditto, then send.
  896. ; Bang? Ditto. 
  897. ; Semicolon? Ditto.
  898. ; Comma? Ditto. (I hate to do it, but it seems I write
  899. ; longer sentences than I thought. Even this might not
  900. ; be enough for Thomas Hardy texts.)
  901. ;
  902.     lda    STASH
  903.     cpi    '.'
  904.     jz    PERIOD
  905.     cpi    '?'
  906.     jz    PERIOD
  907.     cpi    '!'
  908.     jz    PERIOD
  909.     cpi    ';'
  910.     jz    PERIOD
  911.     cpi    ','
  912.     jnz    CNTPER
  913. PERIOD:    lda    PERCNT
  914.     inr    a
  915.     sta    PERCNT
  916. ;
  917.     IF    DEBUG
  918.     ;
  919.     call    ILPRT
  920.     db    'up PERCNT.',8,8,8,8,8,8,8,8,8,8,LF,0
  921.     ;
  922.     ENDIF    ;DEBUG
  923. ;
  924. ;
  925. ;  Then test the period count... two or more? Then reset
  926. ;   the period count to one, change the character-to-send
  927. ;   to double-dash (three periods sent as: . = =). If that
  928. ;   default flag is reset. (0=pretty it up. Else, don't get
  929. ;   cute.)
  930. ;
  931. CNTPER:    lda    PRYBYT
  932.     ora    a
  933.     lda    STASH
  934.     jnz    NOPER
  935. ;
  936.     lda    PERCNT
  937.     cpi    2
  938.     lda    STASH
  939.     jc    NOPER
  940.     cpi    '.'
  941.     jnz    NOPER
  942.     mvi    a,'='
  943.     sta    STASH
  944.     mvi    a,1
  945.     sta    PERCNT
  946.     lda    STASH
  947. ;
  948. ; Is it <lf>? Throw it away. <cr>? Turn it into a space.
  949. ;
  950. NOPER:    cpi    LF
  951.     jz    LOOP
  952.     cpi    CR
  953.     jnz    NOTCR
  954.     mvi    a,' '
  955.     sta    STASH
  956. ;
  957. ; Is it none of the above? Then reset the period-count.
  958. ;
  959. NOTCR:    lda    STASH
  960.     cpi    '.'
  961.     jz    NORST
  962.     cpi    '?'
  963.     jz    NORST
  964.     cpi    '!'
  965.     jz    NORST
  966.     cpi    '='
  967.     jz    NORST
  968.     xra    a
  969.     sta    PERCNT
  970.     lda    STASH
  971. ;
  972. ; Is it <space>?  Test the space-count. Zero? Then 
  973. ; send  a  seven-dit  period  of rest.  Otherwise,
  974. ; throw it away. This checking is to eliminate the
  975. ; lumpiness of word-spacing that otherwise results
  976. ; from sending a WordStar document-mode file.  The 
  977. ; spaces  still show up  on the screen,  they just 
  978. ; don't occupy time now.  Turning a  <cr> into one
  979. ; nominally guarantees an  interword space  in  WS
  980. ; wordwraps.
  981. ; Tabs get the same treatment.
  982. NORST:    cpi    ' '
  983.     jz    ISP
  984.     cpi    9    ;tab
  985.     jnz    NSP
  986. ISP:    lda    PRYBYT
  987.     ora    a
  988.     jnz    NOPRET
  989.     lda    SPACNT
  990.     ora    a
  991.     jnz    LOOP
  992.     inr    a
  993.     sta    SPACNT
  994. NOPRET:    call    SPACE
  995.     jmp    LOOP
  996. ;
  997. ;Ampsersand, <es>, is handled as a special case,  because
  998. ; of the timing. It is the only prosign that requires it.
  999. ; This character is a holdout from Telegraph Morse. 
  1000. ;
  1001. NSP:    mov    e,a    ;stash it quick
  1002.     xra    a    ;reset space-count
  1003.     sta    SPACNT
  1004.     mov    a,e    ;get it back
  1005.     cpi    '&'    ;NOW the ampsersand...
  1006.     jnz    NES
  1007.     call    ES    ;jumps through to MORSER
  1008.     jmp    LOOP
  1009. ;
  1010. ;Here's the ARRL/full International Morse filter.
  1011. ;First, test: if XTNFLG = 0, we're running wide open.
  1012. ;No?  Then we gotta slog.  We gotta find out if  the character
  1013. ;is on the short list, and there's no simple mathematic test I
  1014. ;know for that.
  1015. ;
  1016. ;
  1017. NES:    sta    STASH    ;put character someplace safe
  1018.     lda    XTNBYT    ;now, about that flag...
  1019.     ora    a
  1020.     jz    GOCHAR    ;Zero? Never mind long involved test, then.
  1021.     lda    STASH    ;No? Okay, slog time. First, split things
  1022.     sui    41h    ;down the middle. No jump if it might be a
  1023.     jc    ISANUM    ;letter. Now mask off uppercasing. Z or
  1024.     ani    1Fh    ;below? Then it is a letter, otherwise it's
  1025.     cpi    1Ah    ;extended-set punctuation, which we don't
  1026.     jc    GOCHAR    ;want to send just now.
  1027.     jmp    OGO
  1028. ;
  1029. ISANUM:    lda    STASH    
  1030.     cpi    '?'    
  1031.     jz    GOCHAR    
  1032.     cpi    '='    
  1033.     jz    GOCHAR
  1034.     cpi    ':'
  1035.     jnc    OGO
  1036.     cpi    '+'    ;<ar>?
  1037.     jz    GOCHAR    
  1038.     cpi    '#'    ;<sk>?
  1039.     jz    GOCHAR
  1040.     cpi    ','    
  1041.     jz    GOCHAR    
  1042.     cpi    '.'    
  1043.     jz    GOCHAR    
  1044.     cpi    '/'
  1045.     jz    GOCHAR
  1046.     cpi    '0'
  1047.     jc    OGO
  1048. ;
  1049. GOCHAR:    lda    STASH    ;pick up the character...
  1050.     call    MORSER    ;send it out...
  1051.     call    CONSEN    ;now see if CON: said anything.
  1052. ;
  1053. OGO:    lda    PERCNT
  1054.     ora    a
  1055.     jz    LOOP
  1056.     lda    XHAUST
  1057.     ora    a
  1058.     jz    LOOP
  1059. ;
  1060.     IF    DEBUG
  1061.     ;
  1062.     call    ILPRT
  1063.     db    'found XHAUST.',8,8,8,8,8,8,8,8,8,8,8,8,8,LF,0
  1064.     ;
  1065.     ENDIF    ;DEBUG
  1066. ;
  1067.     call    GETIT
  1068. ;
  1069.     jmp    LOOP
  1070. ;
  1071. ;Look up the character in the table. Each table entry is
  1072. ; two bytes, a baud-count nibble plus up to the remainder
  1073. ; of two bytes to be shifted rightwards out the door. 
  1074. ; The character symbols algorithm is from a message keyer
  1075. ; program in 73 by VE3CWY, originally written for the 
  1076. ; CDP1802, which I used in the Morse-code readout for TSCRT.
  1077. ;
  1078. MORSER:    lxi    d,TABLE    ;character brought in in a
  1079.     mvi    h,0
  1080.     mov    l,a    ;character into hl
  1081.     dad    h    ;shift it left
  1082.     dad    d    ;add in the table base
  1083.     mov    e,m    ;pick up lobyte
  1084.     inx    h
  1085.     mov    d,m    ;pick up hibyte
  1086.     mvi    a,FX
  1087.     cmp    d
  1088.     jnz    OK    ;empty entry = foxes, 0FFFFh . 
  1089.     cmp    e
  1090.     jnz    OK
  1091.     ret
  1092. OK:    call    IAMBIC
  1093.     ret
  1094. ;
  1095. SPACE:    lda    SPACNT
  1096.     dcr    a    ;Including what DIT or DAH and IAMB
  1097.     jz    NUTHRS    ;have already provided, provide        
  1098.     call    DAHSP    ;seven dit-counts of unkeyed time
  1099.             ;between words. If WSPACE is true,
  1100. NUTHRS:    call    DAHSP    ;twice that. It's handled this
  1101.     lhld    DITCNT    ;way because 16 bits of delay can     
  1102.     call    UNKEY   ;only be so long, and there might 
  1103.     lda    WSPBYT  ;otherwise be rollover irregularities 
  1104.     ora    a         ;at slow speeds. If this is an
  1105.     rz        ;additional space, send the whole
  1106.     lda    SPACNT    ;thing from here... nobody began it
  1107.     dcr    a    ;for us.
  1108.     jz    NUTHRW
  1109.     call    DAHSP
  1110. NUTHRW:    call    DAHSP
  1111.     lhld    DITCNT
  1112.     call    UNKEY
  1113.     ret
  1114. ;
  1115. DAHSP:    lhld    DITCNT
  1116.     call    UNKEY
  1117.     lhld    DITCNT
  1118.     call    UNKEY
  1119.     lhld    DITCNT
  1120.     call    UNKEY
  1121.     ret
  1122. ;
  1123. ES:    lhld    DITCNT
  1124.     call    KEY
  1125.     lhld    DITCNT
  1126.     call    UNKEY
  1127.     lhld    DITCNT
  1128.     call    UNKEY
  1129.     mvi    a,'S'
  1130.     sta    STASH
  1131.     jmp    MORSER
  1132. ;
  1133. ;One element at a time, shift the bits right and out.
  1134. ; A hi is a dah, a lo is a dit. Each is followed by
  1135. ; a dit of quiet. The character is followed by a dah
  1136. ; of quiet, double that if WhiteSPACE is set.
  1137. ;
  1138. IAMBIC:    mov    a,d
  1139.     cpi    FX
  1140.     jnz    BIGGIE
  1141.     mov    a,e
  1142. BIGGIE:    rrc    ;highest nibl is the length-count
  1143.     rrc    ;isolate it and stash it in counter.
  1144.     rrc
  1145.     rrc
  1146.     ani    0Fh
  1147.     mov    b,a
  1148. IAMLUP:    mov    a,e    ;now rightshift-with-carry loop...
  1149.     rrc        ;if cy=0, DIT. if cy=1, DAH.
  1150.     mov    e,a
  1151.     jnc    DODIT
  1152. DODAH:    call    DAH
  1153.     jmp    IAMDEC
  1154. DODIT:    call    DIT
  1155. IAMDEC:    dcr    b    ;countdown: done?
  1156.     jnz    IAMLUP
  1157.     lhld    DITCNT    ;two dits of additional space.
  1158.     call    UNKEY    ;the third, DIT or DAH provided.
  1159.     lhld    DITCNT
  1160.     call    UNKEY
  1161.     lda    WSPBYT
  1162.     ora    a
  1163.     rz    
  1164.     call    DAHSP
  1165.     ret
  1166. ;
  1167. DIT:    lhld    DITCNT    ;ditcount
  1168.     call    KEY
  1169.     lhld    DITCNT
  1170.     call    UNKEY
  1171.     ret
  1172. ;
  1173. DAH:    lhld    DITCNT
  1174.     call    KEY    ;All of this boring duplication,
  1175.     lhld    DITCNT
  1176.     call    KEY    ;just to allow for a large DITCNT... 
  1177.     lhld    DITCNT
  1178.     call    KEY    ;
  1179.     lhld    DITCNT
  1180.     call    UNKEY
  1181.     ret
  1182. ;-----------------------------
  1183. ;
  1184. ; filename ambiguity test.
  1185. ; On return, zero flag is SET if there are no question-
  1186. ; marks or asterisks in the filename.
  1187. ; Uses all but de.
  1188. ;
  1189. ISAMBG:    lxi    h,FCB+1
  1190.     mvi    b,11
  1191.     mvi    c,0
  1192. ISALP:    mov    a,m
  1193.     cpi    '*'
  1194.     jz    YESAM
  1195.     cpi    '?'
  1196.     jnz    NOISA
  1197. YESAM:    inr    c
  1198. NOISA:    inx    h
  1199.     dcr    b
  1200.     jnz    ISALP
  1201.     xra    a
  1202.     cmp    c
  1203.     ret
  1204. ;
  1205. ;Go find out what CON: has to say.
  1206. ;
  1207. CONSAY:    push h! push d! push b
  1208.     call    CMENU
  1209.     call    FLOOSH
  1210.     pop b! pop d! pop h
  1211.     ret
  1212. ;
  1213. FLOOSH:    mvi    c,6    ;use direct console calls to
  1214.     mvi    e,FX    ;flush the CON: port of any
  1215.     call    BDOS    ;backed-up characters
  1216.     ani    7Fh
  1217.     ora    a
  1218.     jnz    FLOOSH
  1219.     ret
  1220. ;
  1221. CRLF:    push h! push d! push b
  1222.     push    psw
  1223.     mvi    e,CR
  1224.     mvi    c,6
  1225.     call    BDOS
  1226.     mvi    e,LF
  1227.     mvi    c,6
  1228.     call    BDOS
  1229.     pop    psw
  1230.     pop b! pop d! pop h
  1231.     ret
  1232. ;
  1233. CMENU:    mvi    c,6    ;direct-console-input BDOS call.
  1234.     mvi    e,FX
  1235.     call    BDOS
  1236.     ani    7Fh
  1237.     cpi    '!'
  1238.     jz    MORKY
  1239.     cpi    '&'
  1240.     jz    LOOPME    ;Convert to continuous operation.
  1241.     cpi    '$'
  1242.     jz    INLIST    ;Flush old list, get new one. Start over.
  1243.     cpi    'C'-40h    ;Go home. Right now.
  1244.     jz    EXIT
  1245.     cpi    'X'-40h    ;go play with next file, or leave.
  1246.     jz    INSHIN
  1247.     cpi    'T'-40h    ;go send dits until asked to <esc>.
  1248.     jz    DITEST
  1249.     ani    5Fh
  1250.     cpi    'W'
  1251.     jz    WTOG
  1252.     cpi    'X'
  1253.     jz    XTOG
  1254.     cpi    'P'
  1255.     jz    PTOG
  1256. ;
  1257.     call    FLOOSH
  1258.     call    ILPRT
  1259.     db    CR,LF,LF
  1260.     db    9,'***------CONSOL'
  1261.     db    'E'+80h,'COMMAND------***',CR,LF
  1262.     db    9,'*'+80h,'Optio','n'+80h,'Switche','s'+80h
  1263.     db    'supported:',1Fh,4,'*',CR,LF
  1264.     db    9,'*',1Fh,3,'X'+80h,'='+80h
  1265.     db    'Extende','d'+80h
  1266.     db    'Internationa','l'+80h,' *',CR,LF
  1267.     db    9,'*',1Fh,8,'Mors','e'+80h
  1268.     db    'Alphabe','t'+80h
  1269.     db    'on/of','f'+80h,' *',CR,LF
  1270.     db    9,'*',1Fh,3,'W'+80h,'='+80h
  1271.     db    'Extende','d'+80h,'intercharacte'
  1272.     db    'r'+80h,'*',CR,LF
  1273.     db    9,'*',1Fh,8,'(white',')'+80h,'spac','e'+80h
  1274.     db    'on/off',1Fh,3,'*',CR,LF
  1275.     db    9,'*',1Fh,3,'P'+80h,'='+80h
  1276.     db    'Multiple-spac','e'+80h
  1277.     db    'and',1Fh,6,'*',CR,LF
  1278.     db    9,'*',1Fh,8,'ellipsi','s'+80h
  1279.     db    'mask','s'+80h,'on/of','f'+80h,' *',CR,LF
  1280.     db    9,'*',1Fh,3,'!'+80h,'='+80h,'Ente'
  1281.     db    'r'+80h,'Mors','e'+80h
  1282.     db    'keyboard',1Fh,4,'*',CR,LF
  1283.     db    9,'*',1Fh,8,'loop',1Fh,19,'*',CR,LF
  1284.     db    9,'*',1Fh,3,'&'+80h,'='+80h
  1285.     db    'Loo','p'+80h,'o','n'+80h
  1286.     db    'presen','t'+80h,'list',1Fh,4,'*',CR,LF
  1287.     db    9,'*',1Fh,8,'unti','l'+80h
  1288.     db    'interrupted',1Fh,6,'*',CR,LF
  1289.     db    9,'*',1Fh,3,'$'+80h,'='+80h
  1290.     db    'Loa','d'+80h,'ne','w'+80h,'lis'
  1291.     db    't'+80h,'from',1Fh,6,'*',CR,LF
  1292.     db    9,'*',1Fh,8,'console',1Fh,16,'*',CR,LF
  1293.     db    9,'***-------MORSETX','T'+80h
  1294.     db    'v1.0-------***',CR,LF,LF
  1295.     db    9,'Ente','r'+80h,'eithe','r'+80h
  1296.     db    'ne','w'+80h 
  1297.     db    'coderate-times-te','n'+80h
  1298.     db    'o','r'+80h,'optio','n'+80h
  1299.     db    'switch:___',8,8,8,0
  1300. ;
  1301.     lxi    d,CONBUF
  1302.     call    LINEUP
  1303.     call    CRLF
  1304. ;
  1305.     lda    CONBUF+2
  1306.     cpi    '!'
  1307.     jz    MORKY
  1308.     cpi    '$'
  1309.     jz    INLIST
  1310.     cpi    '&'
  1311.     jz    LOOPME    ;Convert to continuous operation.
  1312.     ani    5Fh
  1313.     cpi    'W'
  1314.     jz    WTOG
  1315.     cpi    'X'
  1316.     jz    XTOG
  1317.     cpi    'P'
  1318.     jz    PTOG
  1319. ;
  1320.     IF    CONDBUG
  1321.     ;
  1322.     lxi    h,CONBUF
  1323.     call    DUMPR
  1324.     ;
  1325.     ENDIF    ;CONDBUG
  1326. ;
  1327.     call    ASDEC    ;ASCII-decimal conversion
  1328.     jnz    PUI    ;lousy input? Punk typists...
  1329.     call    CONVRT
  1330. ;
  1331.     IF    CONDBUG
  1332.     ;
  1333.     call    ILPRT
  1334.     db    CR,LF,'DITCNT now is: ',0
  1335.     lhld    DITCNT
  1336.     call    PHL
  1337.     call    ILPRT
  1338.     db    ',',CR,LF,'DAHCNT now is: ',0
  1339.     lhld    DAHCNT
  1340.     call    PHL
  1341.     call    ILPRT
  1342.     db    '.',CR,LF,0
  1343.     ;
  1344.     ENDIF    ;CONDBUG
  1345. ;
  1346. PUI:    call    CRLF
  1347.     ret
  1348. ;
  1349. DITEST:    call    ILPRT
  1350.     db    CR,LF
  1351.     db    9,'***----DITRAT','E'+80h,'TES','T'+80h
  1352.     db    'MODE-----***',CR,LF
  1353.     db    9,'*'+80h,'Cleartex','t'+80h
  1354.     db    'Words-Per-Minute',':'+80h,' *',CR,LF
  1355.     db    9,'*'+80h,' dit','s'+80h,'pe','r'+80h
  1356.     db    'mi','n'+80h,'/'+80h
  1357.     db    '25','.'+80h,'(PARIS',')'+80h,' *',CR,LF
  1358.     db    9,'* Rando','m'+80h,'group','s'+80h
  1359.     db    'abou','t'+80h,'5/','6'+80h,'tha'
  1360.     db    't'+80h,'*',CR,LF
  1361.     db    9,'*',1Fh,3,'rat','e'+80h,'(o','r'+80h
  1362.     db    'us','e'+80h,'CODE','X'+80h,'test)'
  1363.     db    '.'+80h,' *',CR,LF
  1364.     db    9,'*'+80h,'T','o'+80h,'exit',','+80h
  1365.     db    'hi','t'+80h
  1366.     db    '<escape>.',1Fh,7,'*',CR,LF
  1367.     db    9,'***-------MORSETX'
  1368.     db    'T'+80h,'v1.0------***',CR,LF,0
  1369.     call    FLOOSH
  1370. ;
  1371. DTESTD:    call    DIT
  1372.     mvi    c,6
  1373.     mvi    e,FX
  1374.     call    BDOS
  1375.     ora    a
  1376.     jz    DTESTD
  1377.     ani    7Fh
  1378.     cpi    'C'-40h
  1379.     jz    EXIT
  1380.     cpi    'X'-40h
  1381.     jz    INSHIN
  1382.     cpi    1Bh    ;<escape>
  1383.     cnz    CONSAY
  1384.     xra    a
  1385.     ret
  1386.  
  1387. ;
  1388. LOOPME:    call    ILPRT
  1389.     db    '-<&>-',8,8,8,8,8,LF,0
  1390.     lxi    h,NAMBUF
  1391.     mvi    a,1Ah    ;^Z
  1392. LOPLUP:    inx    h
  1393.     cmp    m
  1394.     jnz    LOPLUP
  1395.     mvi    m,'&'
  1396.     inx    h
  1397.     mvi    m,1Ah
  1398.     ret
  1399.     
  1400. ;
  1401. MORKY:    call    FLOOSH
  1402.     call    ILPRT
  1403.     db    CR,LF,9,'***---MORS','E'+80h
  1404.     db    'KEYBOAR','D'+80h,' LOOP---***'
  1405.     db    9,'PROSIGNS:',9,'[ar]',9,'@'+80h,'+'
  1406.     db    CR,LF,9,'*'+80h,' N','o'+80h
  1407.     db    'softwar','e'+80h
  1408.     db    ' type-ahea','d'+80h,'i','s'+80h,' *'
  1409.     db    9,9,9,'[bt]',9,'='
  1410.     db    CR,LF,9,'*'+80h,' provided','.'+80h
  1411.     db    'Hi','t'+80h,'<esc','>'+80h
  1412.     db    '(^[',')'+80h,'t','o'+80h,'*'
  1413.     db    9,9,9,'[bk]',9,'\'
  1414.     db    CR,LF,9,'*'+80h,' retur','n'+80h,' t'
  1415.     db    'o'+80h,' file-sending.',1Fh,3,'*'
  1416.     db    9,9,9,'[kn]',9,'('+80h,'~'
  1417.     db    CR,LF,9,'***------MORSETX'
  1418.     db    'T'+80h,'v1.0-------***'
  1419.     db    9,9,9,'[sk]',9,'#'
  1420.     db    CR,LF,1Fh,64,'[as]',9,'*'+80h,'!'
  1421.     db    CR,LF,1Fh,64,'[hh]',9,'<bs>'
  1422.     db    CR,LF,1Fh,64,'[sn]',9,'{'+80h,'^'
  1423.     db    CR,LF,0
  1424. MORKLP:    mvi    c,6
  1425.     mvi    e,FX
  1426.     call    BDOS
  1427.     sta    STASH
  1428.     ora    a
  1429.     jz    MORKLP
  1430.     cpi    CR
  1431.     jnz    ICTL
  1432.     call    CRLF
  1433.     jmp    MORKLP
  1434. ICTL:    cpi    20h
  1435.     jnc    EKO
  1436.     mvi    e,'^'
  1437.     mvi    c,6
  1438.     call    BDOS
  1439.     lda    STASH
  1440.     adi    40h    
  1441. EKO:    mov    e,a
  1442.     mvi    c,6
  1443.     call    BDOS
  1444.     lda    STASH
  1445.     cpi    'X'-40h
  1446.     jz    INSHIN
  1447.     cpi    'C'-40h
  1448.     jz    EXIT
  1449.     cpi    'T'-40h
  1450.     cz    DITEST
  1451.     cpi    1Bh    ;esc
  1452.     rz
  1453.     lxi    h,MORKLP
  1454.     push    h
  1455.     lxi    h,SPACE
  1456.     cpi    ' '
  1457.     jz    JOUT
  1458.     cpi    9
  1459.     jz    JOUT
  1460.     lxi    h,ES
  1461.     cpi    '&'
  1462.     jz    JOUT
  1463.     jmp    MORSER
  1464. JOUT:    pchl
  1465. ;
  1466. ;The following is a buffered-console routine that doesn't
  1467. ; use the BDOS call. The buffer it uses must look like 
  1468. ; the one in function 10, though, with:
  1469. ; CONBUF:     db     MAX ;where MAX is the maximum 
  1470. ;                ;character count the buffer
  1471. ;                ;can hold
  1472. ;        ds    1   ;byte counter
  1473. ;        ds    MAX
  1474. ;call with de-->CONBUF
  1475. ;
  1476. LINEUP:    push d! pop h    ;now hl points there too.
  1477.     shld    STASHW    ;save me one. Other user of this is DIV.
  1478.     mov    c,m
  1479.     inx h! inx h    ;repoint to first storage byte
  1480.     mvi    b,0    ;set up the counter
  1481. LINLUP:    call    GETCHR    ;stack-shielded conin call
  1482.     cpi    20h
  1483.     jc    DCIN
  1484.     mov    m,a
  1485.     inx    h
  1486.     inr    b
  1487.     mov    a,c
  1488.     cmp    b
  1489.     jnz    LINLUP
  1490. LINDUN:    lhld    STASHW    ;CONBUF...
  1491.     inx    h    ;+1.
  1492.     mov    m,b
  1493.     ret
  1494. ;
  1495. DCIN:    cpi    CR
  1496.     jz    LINDUN
  1497.     cpi    LF
  1498.     jz    LINDUN
  1499.     cpi    'C'-40h
  1500.     jz    EXIT
  1501.     cpi    'T'-40h
  1502.     jz    DITEST
  1503.     cpi    'X'-40h
  1504.     jz    INSHIN
  1505.     cpi    'H'-40h
  1506.     jnz    FLUSH        ;match? backspace.
  1507.     push h! push d! push b
  1508.     call    ILPRT
  1509.     db    ' ',8,0        ;first bs already echoed by BDOS
  1510.     pop b! pop d! pop h
  1511.     mov    a,b
  1512.     ora    a
  1513.     jz    FLUSH
  1514.     dcx    h
  1515.     mvi    m,0
  1516.     dcr    b
  1517.     jnz    LINLUP
  1518. FLUSH:    cpi    'U'-40h
  1519.     jnz    LINLUP
  1520.     call    ILPRT
  1521.     db    CR,LF,'# ',0
  1522.     jmp    LINEUP
  1523. ;
  1524. GETCHR:    push h! push d! push b    ;uses direct-console call.
  1525. GCRL:    mvi    e,FX
  1526.     mvi    c,6
  1527.     call    BDOS
  1528.     ora    a
  1529.     jz    GCRL
  1530.     push    psw
  1531.     cpi    20h
  1532.     jnc    GCROK
  1533.     cpi    CR
  1534.     jz    GCROK
  1535.     cpi    LF
  1536.     jz    GCROK
  1537.     cpi    8
  1538.     jz    GCROK
  1539.     mvi    e,'^'
  1540.     mvi    c,6
  1541.     call    BDOS
  1542.     pop psw! push psw
  1543.     adi    40h
  1544. GCROK:    mov    e,a
  1545.     mvi    c,6
  1546.     call    BDOS
  1547.     pop    psw
  1548.     pop b! pop d! pop h
  1549.     ret
  1550. ;
  1551. ;The following converts up to the last four decimal digit (0-9)
  1552. ;characters typed to a console-buffer line into an absolute
  1553. ;binary value. On return, the zero flag is set if there's a
  1554. ;worthwhile value stored in RESULT. If the buffer contains no
  1555. ;ASCII numeric bytes, the zero flag is reset and a = 0FFh.
  1556. ;
  1557. ASDEC:    lda    CONBUF+1
  1558.     ora    a
  1559.     jz    NOBUF
  1560.     mvi    d,0
  1561.     lxi    h,0
  1562.     shld    RESULT
  1563.     lxi    h,CONBUF+2
  1564.     lda    CONBUF+1
  1565.     mov    c,a
  1566.     mvi    b,0
  1567. ASDLP:    mov    a,m
  1568.     sui    30h
  1569.     jc    NODEC
  1570.     cpi    0Ah
  1571.     jnc    NODEC
  1572.     mov    e,a
  1573.     push    h
  1574.     lhld    RESULT
  1575.     call    MULTEN
  1576.     dad    d
  1577.     shld    RESULT
  1578.     pop    h
  1579.     inr    b
  1580. NODEC:    inx    h
  1581.     dcr    c
  1582.     jnz    ASDLP
  1583.     mov    a,b
  1584.     ora    a
  1585.     jz    NOBUF
  1586.     xra    a
  1587.     ret
  1588. ;
  1589. MULTEN:    push    d
  1590.     push    h
  1591.     pop    d
  1592.     dad    h
  1593.     dad    h
  1594.     dad    d
  1595.     dad    h
  1596.     pop    d
  1597.     ret
  1598. ;
  1599. NOBUF:    mvi    a,0FFh
  1600.     ora    a
  1601.     ret
  1602. ;
  1603. ;
  1604. CONVRT:    lhld    DELCON+2    ;bring in a fresh copy of
  1605.     shld    DIV+4        ;the (clockrate-corrected)
  1606.     lhld    DELCON        ;0.1 wpm delay constant.
  1607.     shld    DIV+2
  1608.     xra    a
  1609.     sta    DIV+1
  1610.     sta    DIV
  1611. ;
  1612.     IF    CONDBUG
  1613.     ;
  1614.     call    ILPRT
  1615.     db    CR,LF,'Binary equivalent of that:',9,0
  1616.     lhld    RESULT    ;
  1617.     call    PHL
  1618.     call    ILPRT
  1619.     db    CR,LF,'Starting delay constant'
  1620.     db    CR,LF,'  (32-bit value)--',9,0
  1621.     call    SHOW32
  1622.     ;
  1623.     ENDIF    ;CONDBUG
  1624. ;
  1625.     call    DIVI
  1626. ;
  1627.     IF    CONDBUG
  1628.     ;
  1629.     call    ILPRT            
  1630.     db    CR,LF,'Division results:',9,0
  1631.     call    SHOW32
  1632.     call    ILPRT
  1633.     db    CR,LF,'Remainder:',9,9,0
  1634.     lda    DIV
  1635.     call    PHEX
  1636.     lda    DIV+1
  1637.     call    PHEX
  1638.     db    CR,LF,LF,0
  1639.     ;
  1640.     ENDIF    ;CONDBUG
  1641. ;
  1642.     lhld    DIV+2
  1643.     mov    a,l
  1644.     ora    h
  1645.     jz    SMALL
  1646. ;
  1647.     IF    CONDBUG
  1648.     ;
  1649.     call    ILPRT
  1650.     db    CR,LF,'Ditdelay too big: 0FFFFh substituted.',CR,LF,0
  1651.     ;
  1652.     ENDIF    ;CONDBUG
  1653. ;
  1654.     lxi    h,FOXES
  1655.     shld    DIV+4
  1656. SMALL:    lxi    h,DIV+5
  1657.     mov    e,m
  1658.     dcx    h
  1659.     mov    d,m
  1660.     xchg
  1661.     shld    DITCNT
  1662.     push    h
  1663.     pop    b
  1664.     dad    h
  1665.     dad    b
  1666.     shld    DAHCNT
  1667.     ret
  1668. ;
  1669.     IF    CONDBUG
  1670.     ;
  1671. SHOW32:    lda    DIV+2
  1672.     call    PHEX
  1673.     lda    DIV+3
  1674.     call    PHEX
  1675.     lda    DIV+4
  1676.     call    PHEX
  1677.     lda    DIV+5
  1678.     call    PHEX
  1679.     ret
  1680.     ;
  1681.     ENDIF    ;CONDBUG
  1682. ;
  1683. DIVI:    mvi    a,33
  1684.     sta    SHCNT
  1685.     xra    a
  1686.     jmp    SHIN
  1687. DIVLP:    sta    SHCNT    ;shift count. 
  1688.     call    SUBT    ;
  1689. SHIN:    call    SHIFT    ;48-bit leftshift, carry-in.
  1690.     lda    SHCNT
  1691.     dcr    a
  1692.     jnz    DIVLP
  1693.     ret
  1694. ;
  1695. SUBT:    lhld    DIV    ;keep a copy for the restore
  1696.     shld    STASHW    ;(need not be saved in order)
  1697.     lhld    RESULT    ;16-bit divisor stored as a word
  1698.     xchg
  1699.     lxi    h,DIV+1    ;to 32-bit dividend stored byte-serial
  1700.     mov    a,m
  1701.     sub    e
  1702.     mov    m,a
  1703.     dcx    h    ;go down
  1704.     mov    a,m
  1705.     sbb    d
  1706.     mov    m,a    ;Now. Carry? Undo the subtract.
  1707.     cmc        ;SHIFT will need the carry the other
  1708.     rc        ;way, so react based on that.
  1709.     lhld    STASHW
  1710.     shld    DIV
  1711.     ret
  1712. ;
  1713. ;++ CARRY BIT AT ENTRY WILL BE SHIFTED INTO LSB ++
  1714. ;
  1715. SHIFT:    mvi    b,6    ;bytes to be rotated
  1716.     lxi    h,DIV+5    ;start at the least byte
  1717. SHILUP:    mov    a,m    ;get it...
  1718.     ral        ;roll it left. Hibit into carry, 
  1719.     mov    m,a    ;carry into lobit. Store it.
  1720.     push    psw    ;Save the flags (especially carry) 
  1721.     dcx    h    ;repoint to more significant byte
  1722.     dcr    b    ;tick off one pass. Done?
  1723.     jz    SHIDUN
  1724.     pop    psw    ;Nope. Gimme back my flags.
  1725.     jmp    SHILUP
  1726. ;
  1727. SHIDUN:    pop    psw    ;Done. Unplug the stack and leave.
  1728.     ret        ;Anybody want a used carry flag?
  1729. ;
  1730. ;
  1731. ;
  1732. WTOG:    call    ILPRT
  1733.     db    '-<W>-',8,8,8,8,8,LF,0
  1734.     lda    WSPBYT
  1735.     cma
  1736.     sta    WSPBYT
  1737.     ret
  1738. ;
  1739. XTOG:    call    ILPRT
  1740.     db    '-<X>-',8,8,8,8,8,LF,0
  1741.     lda    XTNBYT
  1742.     cma
  1743.     sta    XTNBYT
  1744.     ret
  1745. ;
  1746. PTOG:    call    ILPRT
  1747.     db    '-<P>-',8,8,8,8,8,LF,0
  1748.     lda    PRYBYT
  1749.     cma
  1750.     sta    PRYBYT
  1751.     ret
  1752. ;
  1753. ;Bring in a list of files to send from the console. Use the
  1754. ;buffered console function for each line. Stop looping when
  1755. ;the linebuffer's character count reads zero.
  1756. ;
  1757. ;1. Sign on, announce the game rules.
  1758. ;2. Point to beginning of NAMBUF. Set up controls in NAMBEL.
  1759. ;3. Bring in a line using the BDOS buffered line function.
  1760. ;4. Test: line had zero characters? Then wrap it up.
  1761. ;5. Repoint to next free space.
  1762. ;6. Convert previous line's control bytes to <crlf>.
  1763. ;7. Goto 3.
  1764. ;
  1765. ;The input line will be evaluated when it's acted upon. 
  1766. ;
  1767. INLIST:    call    FLOOSH
  1768.     call    ILPRT
  1769.     db    CR,LF,LF,LF
  1770.     db    9,'***--CONSOL','E'+80h
  1771.     db    'FILENAM','E'+80h,'ENTRY--***',CR,LF
  1772.     db    9,'*'+80h,'Ente','r'+80h,'on','e'+80h
  1773.     db    'dr:filename.ty','p'+80h,'o'
  1774.     db    'n'+80h,'*',CR,LF
  1775.     db    9,'*'+80h,' eac','h'+80h,'line',','+80h
  1776.     db    'followe','d'+80h,'b','y'+80h
  1777.     db    'an','y'+80h,' *',CR,LF
  1778.     db    9,'*'+80h,'optio','n'+80h
  1779.     db    'switche','s'+80h,'o','r'+80h,'ne'
  1780.     db    'w'+80h,'spee','d'+80h,'*',CR,LF
  1781.     db    9,'*'+80h,'a','s'+80h,'wp'
  1782.     db    'm'+80h,'time','s'+80h
  1783.     db    'ten','.'+80h,' N','o'+80h
  1784.     db    '*.SUB','s'+80h,'*',CR,LF
  1785.     db    9,'*'+80h,'o','r'+80h,'ambiguou','s'+80h
  1786.     db    'filenames',':'+80h,'the','y'+80h,'*',CR,LF
  1787.     db    9,'*'+80h,'overwrit','e'+80h,'followin'
  1788.     db    'g'+80h,' entrie','s'+80h,'*',CR,LF
  1789.     db    9,'*'+80h,'a','t'+80h,'expansion','.'+80h
  1790.     db    'A','n'+80h,'extr','a'+80h,'<cr'
  1791.     db    '>'+80h,' *',CR,LF
  1792.     db    9,'*  end','s'+80h,'entry.',1Fh,17,'*',CR,LF
  1793.     db    9,'***-------MORSETX'
  1794.     db    'T'+80h,'v1.0------***',CR,LF,LF,0
  1795.     lxi    h,NAMBEL
  1796.     shld    NAMPTR
  1797.     xra    a    ;Console (unformatted) entries---
  1798.     sta    USEMOV    ;use M2D4BF to move 'em down.
  1799. ;
  1800.     lxi    h,32h
  1801.     shld    NAMBEL
  1802. INLILP:    lhld    NAMPTR    ;first time, this points to NAMBEL.
  1803.     xchg        ;After that, we move it up.
  1804.             ;buffered console string
  1805.     call    LINEUP    ;homebrew function 10
  1806.     mvi    e,LF
  1807.     mvi    c,6    ;BDOS echos only what it gets. That
  1808.     call    BDOS    ;means, send your own linefeed.
  1809. ;
  1810.     lhld    NAMPTR    ;Point to the maximum-count byte.
  1811.     inx    h    ;Now point to character count. Is it
  1812.     xra    a    ;zero? Then that's it for the console
  1813.     ora    m    ;entry schtick. Go cap off the list
  1814.     dcx    h    ;and get busy. No? Continue.
  1815.     jz    SHINIT    ;Back to the maximum-count byte.
  1816.     mvi    m,CR    ;Convert the 32h we wrote to <cr>.
  1817.     inx    h    ;This is the character count. That we
  1818.     mov    e,m    ;want. Put it in de. Replace it with 
  1819.     mvi    d,0    ;<lf>. Bump. Now we point at the first
  1820.     mvi    m,LF    ;string byte. Add the bytecount, and we
  1821.     inx    h    ;point to the first free location past
  1822.     dad    d    ;the string. This is where the new
  1823.     shld    NAMPTR    ;string will go. Set up control bytes.
  1824.     mvi    m,32h
  1825.     inx    h    ;I don't know that this pre-nulling is
  1826.     mvi    m,0    ;really necessary, but...
  1827. ;
  1828.     jmp    INLILP    ;one more time, with feeling...    
  1829. ;
  1830. SHINIT:    mvi    m,CR    ;Back to our max-count. One more <crlf>
  1831.     inx    h    ;to keep the list handler happy, then
  1832.     mvi    m,LF    ;put a ^Z where the list handler will
  1833.     inx    h    ;find it instead of a name, to tell it  
  1834.     mvi    m,1Ah    ;to go home.
  1835. ;
  1836.     lxi    h,NAMBUF    ;repoint to the beginning
  1837.     shld    NAMPTR        ;of the list...
  1838. INSHIN:    lxi    sp,STAKS
  1839.     lxi    h,EXIT    ;This bit restarts the whole program,
  1840.     push    h    ;flushing the stack of old (dead)
  1841.     jmp    SETUP    ;saves and returns. The other visitor
  1842.             ;here is the ^X response at CONSAY.
  1843.             ;You think this is dirty? I'd rather
  1844.             ;design this for humans to use. 
  1845. ;
  1846. ;
  1847. ILPRT:    xthl        ;In-Line Printer, as kind to
  1848.     push    psw    ;registers as I could make it.
  1849. ILLUP:    mov    a,m    ;I've commented out the copy
  1850.     inx    h    ;in TRACEPKG, while preserving
  1851.     ora    a    ;TRACEPKG as a transplant 
  1852.     jz    ILDUN    ;module, because of the filler.
  1853.     cpi    1Fh    ;^_, record separator. In MONITOR,
  1854.     jz    FILTHM    ;I use TAB the same way.
  1855.     call    PCHAR
  1856.     jmp    ILLUP
  1857. ILDUN:    pop    psw
  1858.     xthl
  1859.     ret
  1860. ;
  1861. FILTHM:            ;We've bumped across the 1Fh,
  1862.     mov    a,m    ;the process flag. Now pick up the
  1863.     inx    h    ;space count that follows, and
  1864. FLTHLP:    push    psw    ;step over that too. Save the
  1865.     mvi    a,' '    ;count. Now, until it drops to
  1866.     call    PCHAR    ;zero, send out spaces. Then
  1867.     pop    psw    ;jump back into action, pointing
  1868.     dcr    a    ;at the next printable byte.
  1869.     jnz    FLTHLP
  1870.     jmp    ILLUP
  1871.  
  1872. ;
  1873. ;
  1874. ;This inline Morse string-sender also has machine-specific
  1875. ; details, though not so rigorously defined. If you can
  1876. ; adapt the program by merely changing the equates, you
  1877. ; can use the routine as-is.
  1878. ;
  1879. ILMORS:    pop    h    ;Get the pointer...
  1880.     mov    a,m    ;get the byte... 
  1881.     inx    h    ;bump the pointer...
  1882.     ora    a
  1883.     jz    MORDUN    ;...and, assuming we're not done,
  1884.     push    h    ;put the pointer away.
  1885.     cpi    ' '
  1886.     jz    MOSP
  1887.     cpi    '&'
  1888.     jz    MOES
  1889.     call    MORSER
  1890.     call    CONSEN    ;CON: sensing. Calls CONSAY if true.
  1891.     in    PORTAS    ;console port
  1892.     ani    CINMSK
  1893.     cpi    CINMCH    ;Here's where we break off if
  1894.     cz    CONSAY    ;CON: is sending.
  1895.     jmp    ILMORS
  1896. MOSP:    call    SPACE    ;7 dits of silence.
  1897.     jmp    ILMORS
  1898. MOES:    call    ES    ;'&'
  1899.     jmp    ILMORS
  1900. MORDUN:    pchl        ;We're done? Oh. Bye.
  1901. ;
  1902. ;
  1903. ;Short-haul (256 bytes) 8080 equivalent to LDIR.
  1904. ;
  1905. M2D4B:    mov    a,m
  1906.     inx    h
  1907.     stax    d
  1908.     inx    d
  1909.     dcr    c
  1910.     jnz    M2D4B
  1911.     ret
  1912. ;
  1913. ;The following is designed to do what CCP does to
  1914. ;a filename.typ, in copying a virtual line of
  1915. ;console input into an FCB. 
  1916. ;
  1917. M2D4BF:    mov    a,m    ;until c decrements to 0, copy @ hl
  1918.     cpi    '.'    ;to @ de. BUT:
  1919.     jz    DOTTY    ;--if the source byte is a period,
  1920.     cpi    '*'    ;pad out the target subsection
  1921.     jz    FILAMB    ;(name, type) with spaces. 
  1922.     cpi    CR    ;--Space? Pad with spaces all the way.
  1923.     jz    PADIT    ;--if it's an asterisk, pad out the
  1924.     cpi    ' '    ;section with '?'.
  1925.     jz    PADIT    ;--if it's a space, go pad with spaces.
  1926.     cpi    'a'    ;'a'-'z'? Uppercase 'em.
  1927.     jc    UPPRC
  1928.     cpi    '{'
  1929.     jnc    UPPRC
  1930.     ani    5Fh
  1931. UPPRC:    stax    d
  1932.     inx    h
  1933.     inx    d
  1934.     dcr    c
  1935.     jnz    M2D4BF
  1936.     ret
  1937. ;
  1938. FILAMB:    inx    h    ;step across the *.
  1939. FLAMBP:    mvi    a,'?'    ;Now fill out whichever slot
  1940.     stax    d    ;we're in (filename or .typ)
  1941.     inx    d    ;with '?'.
  1942.     dcr    c
  1943.     mov    a,c
  1944.     cpi    3    ;Dot's right---
  1945.     jz    M2D4BF    ;Let DOTTY handle the dot. 
  1946.     ora    a    ;If the party's over, though,
  1947.     rz        ;go home.
  1948.     jmp    FLAMBP
  1949. ;
  1950. DOTTLE:    mvi    a,' '    ;We found a dot, but the count 
  1951.     stax    d    ;wasn't down to 3. Until it is,
  1952.     inx    d    ;pad out the target with spaces.
  1953.     dcr    c
  1954. DOTTY:    mov    a,c    ;If the dot in 'FILENAME.TYP' is 
  1955.     cpi    4    ;what we found, we should jump
  1956.     jnc    DOTTLE    ;across it and continue, ending
  1957.     ora    a    ;up with 'FILENAMETYP'.
  1958.     rz        ;...and this here is partial 
  1959.     inx    h    ;idiotproofing, to deal with
  1960.     jmp    M2D4BF    ;multiple dots. Let the caller
  1961.             ;complain-- at least we don't
  1962.             ;lock up.
  1963. ;
  1964. PADIT:    mvi    a,' '
  1965.     stax    d
  1966.     inx    d
  1967.     dcr    c
  1968.     jnz    PADIT
  1969.     ret
  1970. ;
  1971. PCHAR:    push h! push d! push b! push psw
  1972.     push    psw
  1973.     cpi    CR
  1974.     jz    NULCRL
  1975.     cpi    LF
  1976.     jz    NULCRL
  1977.     cpi    9
  1978.     jnz    OUTPCR
  1979.     jmp    MAKTAB    
  1980. NULCRL:    push    psw
  1981.     mvi    a,FX
  1982.     sta    CRLIN
  1983.     pop    psw    
  1984. OUTPCR:    ani    7Fh
  1985.     mov    e,a
  1986.     mvi    c,6
  1987.     call    BDOS
  1988.     pop    psw
  1989.     ani    80h
  1990.     jz    PCRDUN
  1991.     lda    CRLIN
  1992.     inr    a
  1993.     sta    CRLIN
  1994. DNTB:    mvi    a,' '
  1995.     push    psw
  1996.     jmp    OUTPCR
  1997. PCRDUN:    lda    CRLIN
  1998.     inr    a
  1999.     sta    CRLIN
  2000.     pop psw! pop b! pop d! pop h
  2001.     ret
  2002. ;
  2003. MAKTAB:    pop    psw
  2004. MKTB:    mvi    e,' '
  2005.     mvi    c,6
  2006.     call    BDOS
  2007.     lda    CRLIN
  2008.     inr    a
  2009.     sta    CRLIN
  2010.     ani    7
  2011.     cpi    7
  2012.     jnz    MKTB
  2013.     jmp    DNTB    
  2014. ;
  2015. ;This routine's  only purpose in life is to show
  2016. ; you what  weird filename.typ you typed in when
  2017. ; you thought were naming something. Perhaps you
  2018. ; put in a user code...  V1.0 doesn't understand
  2019. ; such things.  I'm not really up on  writing it
  2020. ; yet either,  since  I  keep everything down at
  2021. ; 0: where  I can keep an eye on who's eating up
  2022. ; all my disk space.
  2023. ;
  2024. WIMPER:    lxi    h,0C900h    ;when stored, that'll be
  2025.                 ;<null>, ret.
  2026.     shld    FCB+12
  2027.     lxi    h,FCB+1
  2028.     push    h
  2029.     jmp    ILPRT
  2030. ;
  2031. GETIT:    lda    RECTGL
  2032.     ora    a
  2033.     lxi    d,RECORD+80h
  2034.     jz    DOTOP
  2035.     lxi    d,RECORD
  2036. DOTOP:    mvi    c,1Ah    ;set DMA
  2037.     call    BDOS
  2038.     lxi    d,FCB
  2039.     mvi    c,14h    ;read sequential
  2040.     call    BDOS
  2041.     ora    a
  2042.     jnz    INSHIN    ;if he's had us reading a file without
  2043.     sta    XHAUST    ;a ^Z, this could be EOF. Go reloop to
  2044.             ;SETUP via a stack flush... let him
  2045.             ;handle it.
  2046.     lda    RECTGL
  2047.     cma
  2048.     sta    RECTGL
  2049. ;
  2050.     IF    DEBUG
  2051.     ;
  2052.     call    ILPRT
  2053.     db    'DID READSEQ.',8,8,8,8,8,8,8,8,8,8,8,8,LF,0
  2054.     ;
  2055.     ENDIF    ;DEBUG
  2056. ;
  2057.     ret
  2058. ;
  2059. ;This routine corrects the 32-bit dit-delay constant for
  2060. ;the declared CPU clockrate.  The initial delay value as
  2061. ;assembled  is  the  empirically-determined extrapolated
  2062. ;dit delay  for a 0.1 wpm coderate  with  a 100 KHz  Z80
  2063. ;clock (as determined by  the PARIS test).  The  routine
  2064. ;itself is a  32-bit by 8-bit unsigned multiply, done in
  2065. ;longhand.  It is executed  once,  when  the program  is 
  2066. ;first loaded.
  2067. ;
  2068. MULTD:    lxi    h,DELCON
  2069.     lxi    d,RECORD    ;we're not using it yet...
  2070.     lxi    b,4
  2071.     call    M2D4B    ;copy a unity image up where it's safe
  2072.     lda    CLKBYT
  2073.     mov    b,a    ;INT(crystal frequency * 10) 
  2074.     mvi    c,8    ;bit-count of that value
  2075. MLDLP:    lxi    h,DELCON+3
  2076.     mov    a,m    ;maybe it's funky, but I need the
  2077.     rlc        ;flag and the initial non-carry.
  2078.     mov    m,a    ;Later I'll get real clever about
  2079.     dcx    h    ;stashing the CPU's flags, but right
  2080.     mov    a,m    ;now this one-time linear code is 
  2081.     ral        ;all right by me. Don't like it here?
  2082.     mov    m,a    ;Put it up in NAMBUF.
  2083.     dcx    h
  2084.     mov    a,m
  2085.     ral
  2086.     mov    m,a
  2087.     dcx    h
  2088.     mov    a,m
  2089.     ral
  2090.     mov    m,a
  2091. ;
  2092.     mov    a,b
  2093.     rlc
  2094.     mov    b,a
  2095.     jnc    NOADD
  2096. ;
  2097.     lxi    h,DELCON+3    ;add the initial value to
  2098.     lxi    d,RECORD+3    ;the developing product.
  2099.     ldax    d
  2100.     add    m
  2101.     mov    m,a
  2102.     dcx    h
  2103.     dcx    d
  2104.     ldax    d
  2105.     adc    m
  2106.     mov    m,a
  2107.     dcx    h
  2108.     dcx    d
  2109.     ldax    d
  2110.     adc    m
  2111.     mov    m,a
  2112.     dcx    h
  2113.     dcx    d
  2114.     ldax    d
  2115.     adc    m
  2116.     mov    m,a
  2117. NOADD:    dcr    c
  2118.     jnz    MLDLP
  2119.     ret
  2120. ;
  2121.     IF    NOT (NODBUG)
  2122. ;
  2123. ;========== TRACER PACKAGE ======================START 
  2124. ;
  2125. ;ILPRT:    xthl        ;In-Line Printer, as kind to
  2126. ;    push    psw    ;registers as I could make it.
  2127. ;ILLUP:    mov    a,m
  2128. ;    inx    h
  2129. ;    ora    a
  2130. ;    jz    ILDUN
  2131. ;    call    TRACER
  2132. ;    jmp    ILLUP
  2133. ;ILDUN:    pop    psw
  2134. ;    xthl
  2135. ;    ret
  2136. ;
  2137. DMPCTR:    db    0    ;Dumps a DDT-style display of two
  2138. DMPTIC:    db    0    ;records of memory, starting where
  2139. DUMPHL:    dw    0    ;hl points at entry. DMPCTR counts
  2140. DUMPR:    push b! push d    ;the lines up to 16. Stuff it nonzero
  2141. DUMPIN:    shld    DUMPHL    ;before calling, if you want fewer
  2142.     call    PHL    ;lines.
  2143.     call    ILPRT
  2144.     db    ': ',0
  2145.     lhld    DUMPHL
  2146.     mvi    e,16
  2147. DUMPHX:    mov    a,m
  2148.     inx    h
  2149.     push h! push d
  2150.     call    PHEX
  2151.     mvi    a,' '
  2152.     call    TRACER
  2153.     pop d! pop h
  2154.     dcr    e
  2155.     jnz    DUMPHX
  2156.     lhld    DUMPHL
  2157.     mvi    e,16
  2158. DUMPAS:    mov    a,m
  2159.     inx    h
  2160.     push h! push d
  2161.     ani    7Fh
  2162.     cpi    ' '
  2163.     jnc    ASOK
  2164.     mvi    a,'.'
  2165. ASOK:    call    TRACER
  2166.     pop d! pop h
  2167.     dcr    e
  2168.     jnz    DUMPAS
  2169.     mvi    a,CR
  2170.     call    TRACER
  2171.     mvi    a,LF
  2172.     call    TRACER
  2173. ;
  2174.     lxi    d,16
  2175.     lhld    DUMPHL
  2176.     dad    d
  2177.     shld    DUMPHL
  2178.     lda    DMPCTR
  2179.     inr    a
  2180.     sta    DMPCTR
  2181.     ani    0Fh
  2182.     jz    DUMPUP
  2183.     cpi    8
  2184.     jnz    DUMPIN
  2185.     mvi    a,CR
  2186.     call    TRACER
  2187.     mvi    a,LF
  2188.     call    TRACER
  2189.     jmp    DUMPIN
  2190. DUMPUP:    pop d! pop b
  2191.     xra    a    ;zero the counter for next time.
  2192.     sta    DMPCTR
  2193.     sta    DMPTIC
  2194.     ret
  2195. ;
  2196. PHL:    push    h
  2197.     mov    a,h
  2198.     call    PHEX
  2199.     pop    h
  2200.     mov    a,l
  2201. PHEX:    push    psw
  2202.     rrc
  2203.     rrc
  2204.     rrc
  2205.     rrc
  2206.     call    PNIB
  2207.     pop    psw
  2208. PNIB:    ani    0Fh
  2209.     adi    90h
  2210.     daa
  2211.     aci    40h
  2212.     daa
  2213. TRACER:    push b! push d! push h
  2214.     push    psw
  2215.     mov    e,a
  2216.     mvi    c,6
  2217.     call    BDOS
  2218.     mvi    c,0Bh
  2219.     call    BDOS
  2220.     ora    a
  2221.     jz    NOCSN
  2222. CSN:    mvi    e,0FFh
  2223.     mvi    c,6
  2224.     call    BDOS
  2225.     cpi    'S'-40h
  2226.     jz    CSN
  2227.     cpi    'C'-40h
  2228.     jz    0
  2229. NOCSN:    pop    psw
  2230.     pop h! pop d! pop b
  2231.     ret
  2232. ;
  2233. ;======= TRACER PACKAGE ============================END
  2234. ;
  2235.     ENDIF    ;NOT NODBUG
  2236. ;
  2237. ;
  2238. TABLE:    db    FX,FX,FX,FX    ;NUL SOH
  2239.     db    FX,FX,FX,FX    ;STX ETX
  2240.     db    FX,FX,FX,FX    ;EOT ENQ
  2241.     db    8,50h,FX,FX    ;ACK...<sn> BEL
  2242.     db    0,80h,FX,FX    ;BS...<hh> HT
  2243.     db    0Bh,60h,FX,FX    ;LF...<al> VT
  2244.     db    15h,50h,51h,70h    ;FF...<ka> CR...<bk> 
  2245.     db    FX,FX,FX,FX    ;SO SI
  2246.     db    FX,FX,FX,FX    ;DLE DC1
  2247.     db    FX,FX,FX,FX    ;DC2 DC3
  2248.     db    FX,FX,FX,FX    ;DC4 NAK
  2249.     db    FX,FX,0Ah,50h    ;SYN ETB...<ar>
  2250.     db    FX,FX,FX,FX    ;CAN EM
  2251.     db    FX,FX,FX,FX    ;SUB ESC
  2252.     db    FX,FX,FX,FX    ;FS GS
  2253.     db    FX,FX,FX,FX    ;RS US
  2254.     db    FX,FX,2,50h    ;<space> bang...<as>
  2255.     db    2Dh,60h,28h,60h    ;" #...<sk>
  2256.     db    84h,70h,21h,50h    ;$...<sx: dollarsign> 
  2257.                 ;%...<au: fractions follow>
  2258.     db    FX,FX,1Eh,60h    ;&...set up ES in a sub
  2259.                  ;'
  2260.     db    0Dh,50h,2Dh,60h    ;( )
  2261.     db    2,50h,0Ah,50h    ;+...<ar> *...<as>
  2262.     db    33h,60h,21h,60h    ;, -
  2263.     db    2Ah,60h,9,50h    ;. /...<fraction bar>
  2264.     db    1Fh,50h,1Eh,50h    ;0 1
  2265.     db    1Ch,50h,18h,50h    ;2 3
  2266.     db    10h,50h,0,50h    ;4 5
  2267.     db    1,50h,3,50h    ;6 7
  2268.     db    7,50h,0Fh,50h    ;8,9
  2269.     db    7,60h,15h,60h    ;: ;
  2270.     db    FX,FX,11h,50h    ;< =...<doubledash>
  2271.     db    FX,FX,0Ch,60h    ;> ?
  2272.     db    0Ah,50h,22h,FX    ;@...<ar> A
  2273.     db    41h,FX,45h,FX    ;B C
  2274.     db    31h,FX,10h,FX    ;D E
  2275.     db    44h,FX,33h,FX    ;F G
  2276.     db    40h,FX,20h,FX    ;H I
  2277.     db    4Eh,FX,35h,FX    ;J K
  2278.     db    42h,FX,23h,FX    ;L M
  2279.     db    21h,FX,37h,FX    ;N O
  2280.     db    46h,FX,4Bh,FX    ;P Q
  2281.     db    32h,FX,30h,FX    ;R S
  2282.     db    11h,FX,34h,FX    ;T U
  2283.     db    48h,FX,36h,FX    ;V W
  2284.     db    49h,FX,4Dh,FX    ;X Y
  2285.     db    43h,FX,FX,FX    ;Z [
  2286.     db    51h,70h,FX,FX    ;\...<bk> ]
  2287.     db    8,50h,2Ch,60h    ;^ _
  2288.     db    FX,FX,22h,FX    ;accent grave, a
  2289.     db    41h,FX,45h,FX    ;b c
  2290.     db    31h,FX,10h,FX    ;d e
  2291.     db    44h,FX,33h,FX    ;f g
  2292.     db    40h,FX,20h,FX    ;h i
  2293.     db    4Eh,FX,35h,FX    ;j k
  2294.     db    42h,FX,23h,FX    ;l m
  2295.     db    21h,FX,37h,FX    ;n o
  2296.     db    46h,FX,4Bh,FX    ;p q
  2297.     db    32h,FX,30h,FX    ;r s
  2298.     db    11h,FX,34h,FX    ;t u
  2299.     db    48h,FX,36h,FX    ;v w
  2300.     db    49h,FX,4Dh,FX    ;x y
  2301.     db    43h,FX,8,50h    ;z {
  2302.     db    FX,FX,FX,FX    ;| }
  2303.     db    0Dh,50h,0,80h    ;~...<kn> DEL...<hh>
  2304. ;
  2305. ;Prosigns:
  2306. ;         SIGN      KEY USED  MEANING
  2307. ;    au    %    fractions follow
  2308. ;    sx    $    dollar-sign
  2309. ;    ar    +,@,ETB    end of message or cross
  2310. ;    bk    \,CR    "over."
  2311. ;    sn    ACK,{    understand
  2312. ;    as    *,!    wait
  2313. ;    hh    BS,DEL    error
  2314. ;    sk    #    QSO END
  2315. ;    kn    (,~    go only
  2316. ;
  2317. ;'&', <es>, is best handled as an exception.
  2318. ; Inter-letter space is dah = 3 dits... space needed is 2 dits.
  2319. ;
  2320. ;----------
  2321. CURDRV:    ds    1
  2322. USRDRV:    ds    1    ;
  2323. USEMOV:    db    0    ;flag, which MOV routine to use.
  2324. FIRSTM:    db    0
  2325. WSPBYT:    db    0
  2326. XTNBYT:    db    0
  2327. PRYBYT:    db    0
  2328. STASH:    ds    1
  2329. STASH2:    ds    1
  2330. SHCNT:    db    0    ;shiftcounter for division routines
  2331. DIV:    db    0,0        ;32 bit 0.1 wpm delay constant,
  2332.     db    1,0,0,0        ;stored in STRAIGHT ASCENDING
  2333.                 ;BYTES, MSBy first. Plus some
  2334.                 ;operating room for the division.
  2335. DMADR:    dw    0
  2336. STASHW:    dw    0
  2337. RESULT:    dw    0
  2338. CRLIN:    db    0    ;characters/line counter for Function 6 
  2339. SPACNT:    db    0
  2340. PERCNT:    db    0
  2341. RECPTR:    ds    2
  2342. XHAUST:    db    0
  2343. RECTGL:    db    0
  2344. CONBUF:    db    8,0
  2345.     ds    10h
  2346.     dw    1A1Ah    ;...safety
  2347.     ds    100h
  2348. STAKS:    ds    2
  2349. NAMPTR:    dw    NAMBUF
  2350. NAMBEL:    ds    2    ;room for the first buffered line's controls. 
  2351. NAMBUF:    ds    100h
  2352.  
  2353. ;
  2354.     end
  2355. ;
  2356. ;Westlink Inc. News Report POBox 463 Pasadena CA 91102 
  2357. ;monday, 8PM  Santa Clarita ARC Net @ KB6C 147.735- Magic Mtn Rptr
  2358. ;
  2359. eof MORSTXT.ASM/Ampro[stuff.933]--CHR$(13)25JUN85
  2360. 02 
  2361. ;monday, 8PM  Santa Clarita ARC Net @ KB6C 147.735- Magic Mtn Rptr
  2362. ;
  2363. eof MORSTX