home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / a / cpxsb.asm < prev    next >
Assembly Source File  |  2020-01-01  |  15KB  |  697 lines

  1. IF NOT lasm
  2. .printx * CPXSB.ASM *
  3. ENDIF    ;NOT lasm
  4. ;       KERMIT - (Celtic for "FREE")
  5. ;
  6. ;       This is the CP/M-80 implementation of the Columbia University
  7. ;       KERMIT file transfer protocol.
  8. ;
  9. ;       Version 4.0
  10. ;
  11. ;       Copyright June 1981,1982,1983,1984,1985
  12. ;       Columbia University
  13. ;
  14. ; Originally written by Bill Catchings of the Columbia University Center for
  15. ; Computing Activities, 612 W. 115th St., New York, NY 10025.
  16. ;
  17. ; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
  18. ; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
  19. ; others.
  20. ;
  21. ;    This file created 16 July, 1987 by OBSchou from code submitted
  22. ;    by William Rose for the Micromint SB180 systems (as featured in
  23. ;    BYTE magazine, 1986).  This file has been modified to fit in with
  24. ;    Kermit-80 V4.08 etc.  His file KERSYS.ASM is a stripped down version
  25. ;    of CPXSYS.ASM (formerly CP4SYS.ASM).
  26. ;
  27. ; revision history:
  28. ; KERSYS.ASM - version 0.8 dated 13 Jul 87.
  29. ;
  30. ; Cutdown CP4SYS.ASM for SB-180/Ampro 230.
  31. ;
  32. ;
  33. ; While this is a single CPU version (to ease editing) the assembler
  34. ; conditionals have been kept to identify machine specific code.
  35. ;
  36. ; Note that the baud setting routine also sets parity, but this does not
  37. ; change the parity given by Kermit's 'stat' command.  I assume that the
  38. ; main body of the program does its own parity check.
  39. ;
  40. ; Revision history (last entry first)
  41. ;
  42. ; edit 2, 22 July by OBSchou to massage file to fit with CPXCOM.ASM.
  43. ;
  44. ; edit 1, 15 July, 1987 by OBSchou for William Rose who submitted
  45. ;    the code for Kermit-80 V 4.05.  Modified code as appropriate 
  46. ;    for 4.08 compatability.
  47. ;
  48.  
  49. delfac    EQU    150    ; Delay factor in SB-180 input loop - a fudge
  50.  
  51. ;
  52. ; Keep module name, edit number, and last revision date in memory.
  53. ;
  54. ;sysedt:    db    'KERSYS.ASM (03) 12-FEB-87 $'    ; last SB-180 revision
  55. ;sysedt:    db    'KERSYS.ASM (04) 12-APR-87 $'    ; Telecom Merlin added
  56. ;sysedt:    db    'KERSYS.ASM (5)  9-May-87 $'    ; Minor tidying
  57. ;sysedt:    db    'KERSYS.ASM (6A) 17-Jun-87 $'    ; BT Merlin M2215 only
  58. ;sysedt:    db    'KERSYS.ASM (7)  19-Jun-87 $'    ; SB-180 only
  59. ;sysedt:    db    'KERSYS.ASM (8)  13-Jul-87 $'    ; 6/9 MHz version
  60. family:    db    'CPXSB.ASM (2)  22-Jul-87$'    ; First entry for V4.08/9
  61.  
  62. ;
  63. ; Assembly time message to let me know I'm building the right version.
  64. ;
  65.  
  66. IF sb180
  67. .printx * Assembling Kermit-80 for Micromint SB-180 *
  68. ENDIF
  69.  
  70.  
  71. IF sb180
  72. mnctrla    EQU    000H    ;Modem control port - CNTLA0
  73. mnctrlb    EQU    002H    ;Modem control port - CNTLB0
  74. mnstat    EQU    004H    ;Modem status port - STAT0
  75. mntxdat    EQU    006H    ;Modem output port - TDR0
  76. mnrddat    EQU    008H    ;Modem input port - RDR0
  77. output    EQU    002H    ;Transmit data register empty mask - TDRE
  78. input    EQU    080H    ;Receive data register full mask - RDRF
  79. z80    EQU    TRUE    ;This one's an HD64180, but Z80 will do 
  80. ENDIF
  81.  
  82.  
  83. sysxin:        ; continuation of system initialisation from sysinit
  84.  
  85. IF sb180
  86.     lxi    h, porbuf    ; park the original settings
  87.     db    0EDh, 038h, mnctrla    ; HD64180 code IN0 g,(m)
  88.     mov    m, a
  89.     inx    h
  90.     db    0EDh, 038h, mnctrlb
  91.     mov    m, a
  92.     inx    h
  93.     db    0EDh, 038h, mnstat
  94.     mov    m, a
  95. ENDIF
  96.                 ; re-initialise for KERMIT
  97. IF sb6
  98.     mvi    h, 08h        ; 0000$1001 - 9600 baud, (even) parity
  99.     mvi    l, 08h        ; 'speed' is two bytes
  100. ENDIF
  101.  
  102. IF sb9
  103.     mvi    h, 21h        ; 0010$0001 - 9600 baud, (even) parity
  104.     mvi    l, 21h        ; 'speed' is two bytes
  105. ENDIF
  106.  
  107. IF sb180
  108.     shld    speed
  109.     lxi    h, parind
  110.     mvi    m, 8        ; index for 8 bits, no parity, 2 stop
  111.     call    setpor
  112. ENDIF
  113.  
  114.     ret
  115.  
  116. porbuf:    ds    3        ; original port settings
  117.    
  118. ;
  119. ;    system-dependent KERMIT termination processing
  120. ;    If we've changed anything, this is our last chance to put it back.
  121. ;
  122. sysexit:
  123.  
  124. IF sb180
  125.     lxi    h, porbuf
  126.     mov    a, m        ; output parity
  127.     db    0EDh, 039h, mnctrla    ; HD64180 code OUT0 (m),g
  128.     inx    h
  129.     mov    a, m        ; output baud rate
  130.     db    0EDh, 039h, mnctrlb
  131.     inx    h
  132.     mov    a, m        ; output to clear error flags 
  133.     db    0EDh, 039h, mnstat
  134.                 ; read twice to reset DCD0 ?
  135.     db    0EDh, 038h, mnstat
  136.     db    0EDh, 038h, mnstat
  137. ENDIF
  138.  
  139.     ret
  140.  
  141. ;
  142. ;    system-dependent processing for start of CONNECT command
  143. ;
  144. syscon:
  145.     ret
  146.  
  147. conmsg:        ; Messages printed when entering transparent (CONNECT) mode:
  148.  
  149.     db    '$'
  150.  
  151. ;
  152. ;    syscls - system-dependent close routine
  153. ;    called when exiting transparent session.
  154. ;
  155. syscls:
  156.     ret
  157.  
  158. ;
  159. ;    sysinh - help for system-dependent special functions.
  160. ;    called in response to <escape>?, after listing all the
  161. ;    system-independent escape sequences.
  162. ;
  163. sysinh:
  164.  
  165. IF sb180 
  166.     lxi    d, inhlps
  167.     call    prtstr
  168. ENDIF
  169.  
  170.     ret
  171.  
  172. ; Additional, system-dependent help for transparent mode
  173. ; (two-character escape sequences)
  174. inhlps:
  175.  
  176. IF sb180
  177.     db    cr, lf, 'V  Cycle port parameters'
  178. ENDIF
  179.  
  180.     db    '$'            ; string terminator
  181.  
  182. ;
  183. ;    sysint - system dependent special functions
  184. ;    called when transparent escape character has been typed;
  185. ;    the second character of the sequence is in A (and in B).
  186. ;    returns:
  187. ;    non-skip: sequence has been processed
  188. ;    skip:    seqence was not recognized
  189. ;
  190. sysint:
  191. ;    ani    137O        ; convert lower case to upper, for testing...
  192.                 ; does this work?
  193. IF sb180
  194.     cpi    'V'        ; cycle port ?
  195.     jz pcycl
  196.     cpi    'v'
  197.     jz pcycl
  198. ENDIF
  199.  
  200.     jmp    rskp        ; take skip return - command not recognised
  201.  
  202. ; Actual commands
  203.  
  204. IF sb180
  205. pcycl:
  206.     lxi    h, parind    ; increment parval, modulo 12
  207.     mov    a, m
  208.     adi    1
  209.     cpi    13
  210.     jnz    pcy1
  211.     mvi    a, 1
  212. pcy1:    mov    m, a        ; update the storage
  213.                 ; get index of name in parstr
  214.     ora    a        ; clear flags
  215.     dcr    a
  216.     rlc
  217.     rlc
  218.     mov    c, a
  219.     mvi    b, 0
  220.     lxi    h, parstr
  221.     inx    h
  222.     dad    b
  223.     push    h
  224.     lxi    d, cgmsg1
  225.     call    prtstr
  226.     pop    d
  227.     call    prtstr
  228.     lxi    d, cgmsg2
  229.     call    prtstr
  230.     call    setpor        ; reset the port
  231.  
  232.     ret
  233.  
  234. cgmsg1:    db    '<$'
  235. cgmsg2: db    '>$'
  236. ENDIF
  237.  
  238.     ret
  239.  
  240. ;
  241. ;    Delay routine.  Called with time (hundredths of seconds) in A.
  242. ;    The inner loop delays 1001 T-states, assuming no wait states are
  243. ;    inserted; this is repeated CPUSPD times, for a total delay of just
  244. ;    over 0.01 second. (CPUSPD should be set to the system clock rate,
  245. ;    in units of 100KHz: for an unmodified Kaypro II, that's 25 for
  246. ;    2.5 MHz.  Some enterprising soul could determine whether or not the
  247. ;    Kaypro actually inserts a wait state on instruction fetch (a common
  248. ;    practice); if so, the magic number at delay2 needs to be decreased.
  249. ;    (We also neglect to consider time spent at interrupt level).
  250. ;
  251. ;    called by: sendbr
  252. ;    destroys BC
  253. ;
  254. ;delay:    mvi    c,cpuspd    ; Number of times to wait 1000 T-states to
  255. ;                ;  make .01 second delay
  256. ;delay2:    mvi    b,70        ; Number of times to execute inner loop to
  257. ;                ;  make 1000 T-state delay
  258. ;delay3:    dcr    b        ; 4 T-states (* 70 * cpuspd)
  259. ;    jnz    delay3        ; 10 T-states (* 70 * cpuspd)
  260. ;    dcr    c        ; 4 T-states (* cpuspd)
  261. ;    jnz    delay2        ; 10 T-states (* cpuspd)
  262. ;                ; total delay: ((14 * 70) + 14) * cpuspd
  263. ;                ;  = 1001 * cpuspd
  264. ;    dcr    a        ; 4 T-states
  265. ;    jnz    delay        ; 10 T-states
  266. ;
  267. ;    ret            ; grand total: ((1001 * cpuspd) + 14) * a
  268.  
  269. ;
  270. ;    sysflt - system-dependent filter
  271. ;    called with character in E.
  272. ;    if this character should not be printed, return with A = zero.
  273. ;    preserves bc, de, hl.
  274. ;    note: <xon>,<xoff>,<del>, and <nul> are always discarded.
  275. ;
  276. sysflt:
  277.     mov    a,e        ; get character for testing
  278.     ret
  279.  
  280. ;
  281. ;    mdmflt - modem filter
  282. ;    called with character to be sent to printer in E
  283. ;    with parity set as appropriate.
  284. ;    return with accumulator = 0 do do nothing,
  285. ;                <> 0 to send char in E.
  286. mdmflt:
  287.     mov    a,e        ; get character to test
  288.     ret
  289.  
  290. ;
  291. ;    prtflt - printer filter
  292. ;    called with character to be sent to printer in E
  293. ;    returns with a = 0 to do nothing
  294. ;             a <> 0 to print it.
  295. ;
  296. ;    this routine for those printer that automatically insert
  297. ;    a lf on cr, or cr for lf.  Should this be shifted to 
  298. ;    the system indep. stuff, in say 4.06?
  299. ;
  300. prtflt:
  301.     mov    a,e        ; get character to test
  302.  
  303. IF FALSE            ; strip out lf from printer stream
  304.     ani    7fh        ; make sure it is parity less
  305.     cpi    lf        ; is it a line feed?
  306.     rnz            ; no, print it
  307. ;    xra    a        ; yes, don't.
  308.     
  309. ENDIF
  310.  
  311.     ret
  312.  
  313. ;
  314. ; system-dependent processing for BYE command.
  315. ;
  316. sysbye:
  317.     ret
  318.  
  319. ;
  320. ;    This is the system-dependent command to change the baud rate.
  321. ;    DE contains the two-byte value from the baud rate table; both
  322. ;    bytes of this value are also stored in 'speed'.
  323. ;
  324. sysspd:
  325.  
  326. IF sb180
  327.     lxi    d, prtmsg    ; ask for variables
  328.     call    prtstr
  329.  
  330.     lxi    d, tbuf        ; get suitable string
  331.     mvi    c, 10
  332.     call    bdos
  333.  
  334.     lxi    h, tbuf1
  335.     mov    a, m
  336.     ora    a
  337.     jz    setpor        ; leave unchanged if string zero length
  338.  
  339.     cpi    3        ; check given length
  340.     jnz    spd1        ; error - wrong length
  341.     inx    h
  342.     inx    h
  343.     mov    a, m
  344.     ani    137O        ; convert parity code to upper case
  345.     mov    m, a
  346.  
  347.     lxi    d, tbuf1    ; get index of given parameter
  348.     lxi    h, parstr
  349.     call    sposn
  350.     ora    a
  351.     jnz    spd2        ; or fall through if error
  352. spd1:    lxi    d, invmsg    ; invalid input - try again
  353.     call    prtstr
  354.     jmp    sysspd
  355.  
  356. spd2:    adi    3        ; get index to parval table
  357.     rrc            ; by dividing by 4 
  358.     rrc
  359.     ani    15        ; mask out high bits
  360.     lxi    h, parind
  361.     mov    m, a        ; and store it
  362.     call    setpor        ; set up port iaw index and speed bytes
  363.  
  364.     ret
  365.  
  366. prtmsg:    db    cr,lf,'Enter bit/char, parity, and stop bits required.'
  367.     db    cr,lf,'(Bit 7/8   Parity N/O/E   Stop 1/2  - CR same) : $'
  368. invmsg: db    cr,lf,'Invalid parameters$'
  369.  
  370. parind:    db    8        ; default <8N2> index
  371. parstr:    db    48,'7N1$7N2$7O1$7O2$7E1$7E2$'
  372.     db       '8N1$8N2$8O1$8O2$8E1$8E2$'
  373. parval:    db    0,1,16+2,16+3,2,3
  374.     db    4,5,16+6,16+7,6,7
  375. tbuf    db    6
  376. tbuf1    db    3,'8N2','$$$$'
  377.  
  378. ;
  379. ; Set up the port using the table index in parind and the speed byte
  380. ;
  381. setpor:
  382.     lxi    h, parind
  383.     mov    a, m
  384.     dcr    a
  385.     lxi    h, parval    ; table base
  386.     mvi    b, 0
  387.     mov    c, a
  388.     dad    b        ; HL points at parameter value
  389.     mov    a, m
  390.     mov    b, a        ; park parval
  391.  
  392.     ani    16        ; the parity switch bit
  393.     lxi    h, speed
  394.     add    m        ; this is now the baud rate byte
  395.     mov    c, a        ; park it
  396.  
  397.     mov    a, b        ; sort out the parameter byte
  398.     ani    7        ; b/p/s only wanted
  399.     adi    96        ; RE, TE enable
  400.     db    0EDh,039h,mnctrla    ; output parity etc.
  401.     mov    a, c
  402.     db    0EDh,039h,mnctrlb    ; output baud rate
  403.     mvi    a, 0
  404.     db    0EDh,039h,mnstat    ; clear status
  405.     db    0EDh,038h,mnstat    ; read twice to reset DCD0
  406.     db    0EDh,038h,mnstat
  407.     ret
  408.  
  409. ;
  410. ; Find substring position - Leventhal page 293, modified
  411. ; enter with subtring in DE and string in HL
  412. ; returns index in A or 0 for failure
  413. ;
  414. sposn:
  415.     mov    a, m        ; exit if either string length zero
  416.     ora     a
  417.     jz    notfnd
  418.     sta    slen
  419.     mov    b, a
  420.     inx    h
  421.     shld    string
  422.     xchg
  423.     mov    a, m
  424.     ora     a
  425.     jz    notfnd
  426.     sta    sublen
  427.     mov    c, a
  428.     inx    h
  429.     shld    substg
  430.     mov    a, b
  431.  
  432. ; no of searches = stringlen - substrlen + 1
  433. ; if substr longer than string quit immediately
  434.  
  435.     sub    c
  436.     jc    notfnd
  437.     inr    a
  438.     mov    c, a
  439.     xra    a
  440.     sta    index
  441.  
  442. ; search until remaining string shorter than substring
  443.  
  444. slp1:    lxi    h, index
  445.     inr    m
  446.     lda    sublen
  447.     mov    b, a
  448.     lhld    substg
  449.     xchg
  450.     lhld    string
  451.  
  452. ; try to match substring starting at index
  453.  
  454. cmplp:    ldax    d
  455.     cmp    m
  456.     jnz    slp2
  457.     dcr    b
  458.     jz    found
  459.     inx    h
  460.     inx    d
  461.     jmp    cmplp
  462.  
  463. ; arrive here if match fails
  464.  
  465. slp2:    dcr    c
  466.     jz    notfnd
  467.     lhld    string
  468.     inx    h
  469.     shld    string
  470.     jmp    slp1
  471.  
  472. ; found, return index
  473.  
  474. found:    lda    index
  475.     ret
  476.  
  477. ; not found, return zero
  478.  
  479. notfnd:    sub    a
  480.     ret
  481.  
  482. string:    ds    2
  483. substg:    ds    2
  484. slen:    ds    1
  485. sublen:    ds    1
  486. index:    ds    1
  487. ENDIF
  488.  
  489.     ret
  490.  
  491. ;
  492. ;    Speed tables
  493. ; (Note that speed tables MUST be in alphabetical order for later
  494. ; lookup procedures, and must begin with a value showing the total
  495. ; number of entries.  The speed help tables are just for us poor
  496. ; humans.
  497. ;
  498. ;     db    string length, string, divisor (2 bytes or 1 word, ab)
  499. ;        the data byte a is return in A and E, and b in D
  500. ;        only byte 'a' is the key for the table
  501.  
  502. IF sb6
  503. spdtbl:    db    9            ; 9 entries
  504.     db    04h,'1200$',    0Bh,0Bh
  505.     db    03h,'150$',    0Eh,0Eh
  506.     db    05h,'19200$',    01h,01h
  507.     db    04h,'2400$',    0Ah,0Ah
  508.     db    03h,'300$',    0Dh,0Dh
  509.     db    05h,'38400$',    00h,00h
  510.     db    04h,'4800$',    09h,09h
  511.     db    03h,'600$',    0Ch,0Ch
  512.     db    04h,'9600$',    08h,08h
  513.  
  514. sphtbl: db    cr,lf
  515.     db '   150  300  600  1200  2400  4800  9600  19200  38400$'
  516. ENDIF
  517.  
  518. IF sb9
  519. spdtbl:    db    7            ; 7 entries
  520.     db    04h,'1200$',    24h,24h
  521.     db    05h,'19200$',    20h,20h
  522.     db    04h,'2400$',    23h,23h
  523.     db    03h,'300$',    26h,26h
  524.     db    04h,'4800$',    22h,22h
  525.     db    03h,'600$',    25h,25h
  526.     db    04h,'9600$',    21h,21h
  527.  
  528. sphtbl: db    cr,lf
  529.     db '   300  600  1200  2400  4800  9600  19200$'
  530. ENDIF
  531.  
  532.  
  533. ;
  534. ;    This is the system-dependent SET PORT command.
  535. ;    HL contains the argument from the command table.
  536. ;
  537. sysprt:
  538.     ret
  539.  
  540. IF sb180
  541. prttbl EQU    0        ; SET PORT is not supported
  542. prhtbl EQU    0
  543. ENDIF
  544.  
  545. ;
  546. ;    selmdm - select modem port
  547. ;    selcon - select console port
  548. ;    selmdm is called before using inpmdm or outmdm;
  549. ;    selcon is called before using inpcon or outcon.
  550. ;    For iobyt systems, diddle the I/O byte to select console or comm port;
  551. ;    For the rest, does nothing.
  552. ;    preserves bc, de, hl.
  553. ;
  554. selmdm:
  555.     ret
  556.  
  557. selcon:
  558.     ret
  559.  
  560. ;
  561. ;    Get character from console, or return zero.
  562. ;    result is returned in A.  destroys bc, de, hl.
  563. ;
  564. inpcon:
  565.     mvi    c,dconio    ;Direct console I/O BDOS call.
  566.     mvi    e,0FFH        ;Input.
  567.     call    BDOS
  568.  
  569.     ret
  570.  
  571. ;
  572. ;    Output character in E to the console.
  573. ;    destroys bc, de, hl
  574. ;
  575. outcon:
  576.     mvi    c,dconio    ;Console output bdos call.
  577.     call    bdos        ;Output the char to the console.
  578.  
  579.     ret
  580.  
  581. ;
  582. ;    outmdm - output a char from E to the modem.
  583. ;        the parity bit has been set as necessary.
  584. ;    returns nonskip; bc, de, hl preserved.
  585. ;
  586. outmdm:
  587.  
  588. IF sb180
  589.     db    0EDh,038h,mnstat
  590.     ani    output        ; check status
  591.     jz    outmdm        ; wait until port is available
  592.     mov    a, e
  593.     db    0EDh,039h,mntxdat    ; transmit
  594. ENDIF
  595.  
  596.     ret
  597.  
  598. ;
  599. ;    get character from modem; return zero if none available.
  600. ;    for IOBYT systems, the modem port has already been selected.
  601. ;    destroys bc, de, hl.
  602. ;
  603. inpmdm:
  604.  
  605. IF sb180
  606.     lxi    h, delfac    ; loops to give delay
  607. inpm1:    db    0EDh,038h,mnstat
  608.     ani    input        ; check status    
  609.     jz    inpm2
  610.     db    0EDh,038h,mnrddat    ; get a byte
  611.     ret
  612.  
  613. inpm2:    dcx    h        ; no data
  614.     mov    h, a
  615.     ora    l
  616.     jnz    inpm1        ; still tries left
  617.     ret            ; with zero in A
  618. ENDIF
  619.  
  620.     ret
  621.  
  622. ;
  623. ;    flsmdm - flush comm line.
  624. ;    Modem is selected.
  625. ;    Currently, just gets characters until none are available.
  626. ;
  627. flsmdm:
  628.     call    inpmdm        ; Try to get a character
  629.     ora    a        ; Got one?
  630.     jnz    flsmdm        ; If so, try for another
  631.     ret            ; Receiver is drained.  Return.
  632.  
  633. ;
  634.  
  635. ;
  636. ;       lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
  637. lptstat:
  638. IF iobyte       ;[33]
  639.         call    bprtst          ; get status
  640. ENDIF   ;iobyte[33]
  641. IF NOT iobyte   ;[33]
  642.         xra     a               ; assume it is ok.. this may not be necessary
  643. ENDIF   ;iobyte [33]
  644.         ret
  645. ;
  646. ;    outlpt - output character in E to printer
  647. ;    console is selected.
  648. ;    preserves de.
  649. ;
  650. outlpt:
  651.     push    d        ; save DE in either case
  652.     call    prtflt        ; go through printer filter [30]
  653.     ana    a        ; if A = 0 do nothing,
  654.     jz    outlp1        ; if a=0 do nothing
  655.  
  656. outlp1:    pop    d        ; restore saved register pair
  657.     ret
  658.  
  659. ; delchr - make delete look like a backspace.  Unless delete is a printing
  660. ;    character, we just need to print a backspace. (we'll output clrspc
  661. ;    afterwards)
  662. delchr:
  663.  
  664.     mvi    e,bs        ;get a backspace
  665.     jmp    outcon
  666.  
  667. ; erase the character at the current cursor position
  668. clrspc:    mvi    e,' '
  669.     call    outcon
  670.     mvi    e,bs        ;get a backspace
  671.     jmp    outcon
  672.  
  673. ; erase the current line
  674. clrlin:    lxi    d,eralin
  675.     jmp    prtstr
  676.  
  677. ; erase the whole screen, and go home. preserves b (but not c)
  678. clrtop:    lxi    d,erascr
  679.     jmp    prtstr
  680.  
  681. IF sb180
  682. sysver:    db    'MicroMint SB 180 '
  683. ENDIF
  684.  
  685. IF sb6
  686.     db    ' (6 MHz)'
  687. ENDIF
  688.  
  689. IF sb9
  690.     db    ' (9 MHz)'
  691. ENDIF
  692.     db    '$'
  693.  
  694. IF lasm
  695. LINK CPXVDU.ASM        ; get terminal defs etc
  696. ENDIF    ;lasm
  697.