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 / MODEMS / ZMODEM / ZMO-KP12.ZZ0 / ZMO-KP12.Z80
Text File  |  2000-06-30  |  18KB  |  696 lines

  1. ;
  2. ;    Overlay to ZMP (Z-Modem Program), for the Kaypro CP/M computers.
  3. ;        (Z80 SIO and 8116 baudrate generator.)
  4. ;
  5. ;    Name:  zmo-kp07.z80
  6. ;
  7. ;    Dated: 10 April 1989
  8. ;
  9. ;    Written by -
  10. ;      Ron Murray, c/o Z-Node 62, 061-9-450-0200, Perth, Western Australia.
  11.  
  12. ;    kp07 - April 89.  Updated "my" 06 (which had been a simple change of
  13. ;        video code from Duerr's 05) to run on ZMP version 1.5.
  14. ;        This version does not implement the dual port option.  If 
  15. ;        any Kaypro owner has use of this option (it would have to 
  16. ;        take over the serial printer port), drop me a "line."
  17. ;        In addition, the equate for RTS/CTS has been set at 'false'
  18. ;        for the COM file included with this file.  Tests have suggested
  19. ;        that the Kaypro 2X/4/10/1 series' problems with dropping char-
  20. ;        acters in terminal mode have to do with the inability of the 
  21. ;        Z80 to perform both its video and CPU functions in those machines
  22. ;        at baud rates above 1200.  The character dropping does not
  23. ;        affect the quality of non-ASCII file transfers.
  24. ;            Michael Broschat, GEnie address: M.BROSCHAT; also,
  25. ;                Adam's RiBBS: Seattle WA area (206) 882-3684
  26.  
  27. ;    KP05 - Nov. 24, 88. Updated for ZMP version 1.4 (overlay drive/user
  28. ;            equates).  Added conditional to check RTS/CTS signals.
  29. ;            Bill Duerr, GEnie ID: B.DUERR
  30. ;                    DKUG RBBS [313] 772-0522
  31. ;
  32. ;    KP04 - Oct. 22, 88. Updated to allow program to be reentered properly,
  33. ;            for 8-N-1 only -- still problems with even/odd parity.
  34. ;            Bill Duerr, GEnie ID: B.DUERR
  35. ;                    DKUG RBBS [313] 772-0522
  36. ;
  37. ;    KP03 - Oct. 12, 88 Modified to ZMP v1.3 standard rjm
  38. ;
  39. ;
  40. ;    Insert your own code as necessary in this file. Code contained herein
  41. ; has been written in Z80 code for use with M80. Once assembled,
  42. ; convert to hex with RELHEX and use MLOAD to overlay it over the main
  43. ; ZMPX.COM file to produce your very own ZMP.COM.
  44. ;
  45. ; Notes on modifying this file:
  46. ;    Hi-Tech C requires that functions do not change either index register
  47. ; (IX or IY). If your overlay requires either of these to be changed, ensure
  48. ; they are restored to their original values on return.
  49. ;    Since collecting parameters from C functions can be tricky, only change
  50. ; the parts marked 'Insert your own code here'. Do NOT modify the jump
  51. ; table at the start. Do NOT modify the entry/exit sections of each
  52. ; function. Do NOT pass 'GO'. Do NOT collect $200.
  53. ;    Apart from defining modem functions, this file also defines terminal
  54. ; characteristics. Most have been set up for ADM-3A (with a few of my own
  55. ; additions). Modify to suit your own terminal. An inline print routine
  56. ; is provided for printing strings in the usual way: usage is
  57. ;
  58. ;    call    print
  59. ;    db    'required string',0
  60. ;
  61. ;    Don't forget to set your clock speed at the clkspd variable.
  62. ;
  63. ;    If you find your overlay exceeds the maximum size (currently 0400h),
  64. ; you will have to re-compile the whole thing. Good luck. You might try
  65. ; informing us if you need to do this: if too many people need to do it, we
  66. ; haven't allowed enough room.
  67. ;
  68. ; Ron Murray 15/8/88
  69. ;
  70. ;
  71. false    equ    0
  72. true    equ    not false
  73. ;
  74. ; If the following equate is set to true, code will be added to set
  75. ; the RTS modem signal, telling the modem not to send any characters
  76. ; till RTS is reset, and also to check CTS if characters may be sent.
  77. ; This allows the Kaypro screen to keep up with the characters sent
  78. ; over the modem lines at higher speeds.  (The modem must be able to
  79. ; recognize RTS and set CTS for this to work.)
  80. ;
  81. rtscts    equ    false
  82. ;
  83. ;Set the following two equates to the drive and user area which will contain
  84. ;   ZMP's .OVR files, .CFG file, .FON file and .HLP file.  Set both to zero
  85. ;   (null) to locate them on the drive from which ZMP was invoked.
  86.  
  87. overdrive    equ    'A'    ; Drive to find overlay files on ('A'-'P')
  88. overuser    equ    0    ; User area to find files
  89.  
  90. ;------------------------------------------------------------------------------
  91.  
  92. ;User-set variables:
  93. clkspd    equ    4        ; Processor clock speed in MHz
  94. mspeed    equ    003ch        ; Current baud rate: as used by BYE etc
  95.                 ; This MUST be the same as Mspeed in
  96.                 ; ZMP.H
  97.  
  98.  
  99. dport    equ    04h        ; Kaypro SIO data port
  100. sport    equ    dport+2        ; Modem control port
  101. mdrcv    equ    01h        ; Modem receive ready
  102. mdsnd    equ    04h        ; Modem send ready bit
  103. mdtxe    equ    01h        ; Modem send buffer empty, holding buffer empty
  104. rsterr    equ    30h        ; Reset parity and overrun flags - register 0
  105. reg1ins    equ    0        ; No interrupts - register 1
  106. reg3ins    equ    0c1h        ; 8 Rx bits, Rx enable
  107. reg4ins    equ    44h        ; 16X baud rate, 1 stop bit, no parity
  108. reg5ins    equ    0eah        ; 8 Tx bits, Tx enable, RTS, DTR
  109.  
  110. bauda    equ    00h        ; 8116 port for baudrate
  111. rstsio    equ    18h        ; Reset the SIO
  112. dcd    equ    08h        ; Data Carrier Detect
  113. dtr    equ    80h        ; Data Terminal Ready
  114. rts    equ    02h        ; Request to send
  115. cts    equ    20h        ; Clear to send
  116. brk    equ    10h        ; SIO Break
  117. sioerr    equ    70h        ; SIO error
  118.  
  119. userdef    equ    00145h        ; origin of this overlay: get this value
  120.                 ; from the .SYM file produced when ZMP.COM
  121.                 ; is linked
  122. ovsize    equ    0400h        ; max size of this overlay
  123.  
  124.     org    userdef
  125.  
  126. esc    equ    1bh
  127. ctrlq    equ    11h
  128. cr    equ    0dh
  129. lf    equ    0ah
  130. bdos    equ    5
  131.  
  132. ;Jump table for the overlay: do NOT change this
  133.  
  134. jump_tab:
  135.     jp    scrnpr        ; screen print
  136.     jp    mrd        ; modem read with timeout
  137.     jp    mchin        ; get a character from modem
  138.     jp    mchout        ; send a character to the modem
  139.     jp    mordy        ; test for tx buffer empty
  140.     jp    mirdy        ; test for character received
  141.     jp    sndbrk        ; send break
  142.     jp    cursadd        ; cursor addressing
  143.     jp    cls        ; clear screen
  144.     jp    invon        ; inverse video on
  145.     jp    invoff        ; inverse video off
  146.     jp    hide        ; hide cursor
  147.     jp    show        ; show cursor
  148.     jp    savecu        ; save cursor position
  149.     jp    rescu        ; restore cursor position
  150.     jp    mint        ; service modem interrupt
  151.     jp    invec        ; initialise interrupt vectors
  152.     jp    dinvec        ; de-initialise interrupt vectors
  153.     jp    mdmerr        ; test uart flags for error
  154.     jp    dtron        ; turn DTR on
  155.     jp    dtroff        ; turn DTR OFF
  156.     jp    init        ; initialise uart
  157.     jp    wait        ; wait seconds
  158.     jp    mswait        ; wait milliseconds
  159.     jp    userin        ; user-defined entry routine
  160.     jp    userout        ; user-defined exit routine
  161.     jp    getvars        ; get system variables
  162.     jp    setport        ; choose one of two (not implemented)
  163.  
  164. ; Spare jumps for compatibility with future versions
  165.  
  166.     jp    spare        ; spare for later use
  167.     jp    spare        ; spare for later use
  168.     jp    spare        ; spare for later use
  169.     jp    spare        ; spare for later use
  170.     jp    spare        ; spare for later use
  171.  
  172. ; Main code starts here
  173. ;
  174. codebgn    equ    $
  175. ;
  176. ;Screen print function
  177. scrnpr:
  178.                 ; <== Insert your own code here
  179.     call    print
  180.     db    'This function not supported.',cr,lf,0
  181.                 ; <== End of your own code
  182. spare:
  183.     ret
  184.  
  185. ; User-defined entry routine
  186. userin:
  187.     ret
  188. ; User-defined exit routine
  189. userout:            ; Leave RTS off
  190.     if    rtscts
  191.     ld    a,05h        ; Select register 5
  192.     out    (sport),a    ; Send to the status port
  193.     ld    a,(reg5)    ; Get register 5 settings
  194.     and    255-rts        ; Turn off RTS
  195.     out    (sport),a    ; Send to the status port
  196.     endif            ; rtscts
  197.     ret
  198.  
  199. ;Get a character from the modem: return in HL
  200. ; It is not necessary to test for status
  201. mchin:
  202. ;-- Code added specific to Kaypro
  203.     in    a,(dport)    ; get the character in A
  204. ;
  205. ; This routine checks parity, and if parity is not "none", strips high bit.
  206. ; This is needed, even if the filter is turned on, because CONNECT message
  207. ; is not filtered.
  208. ;
  209.     ld    l,a        ; Save in L
  210.     ld    a,(parity)    ; Check parity
  211.     cp    'N'        ; No parity?
  212.     ld    a,l        ; Get the character back
  213.     jr    z,mchin1    ; Bypass following kludge
  214.     and    7fh
  215.     ld    l,a        ; put in HL
  216. mchin1:
  217.     if    rtscts
  218.     ld    a,05h        ; Select register 5
  219.     out    (sport),a    ; Send to the status port
  220.     ld    a,(reg5)    ; Get register 5 settings
  221.     and    255-rts        ; Turn off RTS
  222.     out    (sport),a    ; Send to the status port
  223.     endif            ; rtscts
  224. ;-- End of this block of machine specific code
  225.     ld    a,l        ; get character from HL
  226.     ld    h,0
  227.     or    a        ; set/clear Z
  228.     ret
  229.  
  230. ;Send a character to the modem
  231. mchout:
  232.     ld    hl,2        ; Get the character
  233.     add    hl,sp
  234.     ld    a,(hl)        ; in A
  235. ;-- Code added specific to Kaypro
  236.     out    (dport),a    ; Put the character to the serial port
  237. ;-- End of this block of machine specific code
  238.     ret            ; done
  239.  
  240. ;Test for output ready: return TRUE (1) in HL if ok
  241. mordy:
  242. ;-- Code added specific to Kaypro
  243.     ld    hl,0        ; Assume not ready
  244. ;
  245.     if    rtscts
  246.     ld    a,10h        ; Reset register 0
  247.     out    (sport),a    ; Send to the status port
  248.     in    a,(sport)    ; read status port
  249.     and    cts        ; Is clear to send up
  250.     jr    z,mordy1    ; Branch if not clear to send
  251.     endif            ; rtscts
  252. ;
  253.     ld    a,10h        ; Reset register 0
  254.     out    (sport),a    ; Send to the status port
  255.     in    a,(sport)    ; Read status port
  256.     and    mdsnd        ; Isolate transmit empty bit
  257.     jr    z,mordy1    ; Branch if not ready
  258.     inc    hl        ; otherwise set HL to indicate ready
  259. mordy1:
  260. ;-- End of this block of machine specific code
  261.     ld    a,l
  262.     or    a        ; set/clear Z
  263.     ret
  264.  
  265. ;Test for character at modem: return TRUE (1) in HL if so
  266. mirdy:
  267. ;-- Code added specific to Kaypro
  268.     ld    a,05h        ; Select register 5
  269.     out    (sport),a    ; Send to the status port
  270.     ld    a,(reg5)    ; Get register 5 settings
  271.     or    rts        ; Turn on RTS
  272.     out    (sport),a    ; Send to the status port
  273.     ld    hl,0        ; Assume not ready
  274.     ld    a,10h        ; Reset register 0
  275.     out    (sport),a    ; Send to the status port
  276.     in    a,(sport)    ; Get the status
  277.     and    mdrcv        ; Isolate receive ready bit
  278.     jr    z,mirdy1    ; Branch if not ready
  279.     inc    hl        ; otherwise set HL to indicate ready
  280. mirdy1:
  281. ;-- End of this block of machine specific code
  282.     ld    a,l
  283.     or    a        ; set/clear Z
  284.     ret
  285.  
  286. ;Send a break to the modem: leave empty if your system can't do it
  287. sndbrk:
  288. ;-- Code added specific to Kaypro
  289.     ld    a,5        ; Select register 5
  290.     out    (sport),a    ; Send to the status port
  291.     ld    a,(reg5)    ; Get parameters for register 5
  292.     or    brk        ; Set the break tone
  293.     out    (sport),a    ; Send to the status port
  294. ;-- End of this block of machine specific code
  295.     ld    hl,300
  296.     call    waitms        ; wait 300 mS
  297. ;-- Code added specific to Kaypro
  298.     ld    a,5        ; Select register 5
  299.     out    (sport),a    ; Send to the status port
  300.     ld    a,(reg5)    ; Restore register 5 settings
  301.     out    (sport),a    ; Send to the status port
  302. ;-- End of this block of machine specific code
  303.     ret
  304.  
  305. ;Test UART flags for error: return TRUE (1) in HL if error
  306. mdmerr:
  307. ;-- Code added specific to Kaypro
  308.     ld    hl,0        ; Assume no error
  309.     ld    a,011h        ; Select read register 1
  310.     out    (sport),a    ; Send to the status port
  311.     in    a,(sport)    ; Get error status
  312.     and    sioerr        ; Mask all but error bits
  313.     ret    z        ; Return zeor in HL if no error
  314.     inc    hl        ; Otherwise set HL to indicate error
  315.     ret            ; Return
  316.  
  317.  
  318. ;Turn DTR (and optionally RTS) ON.
  319. dtron:
  320. ;-- Code added specific to Kaypro
  321.     ld    a,05h        ; Select register 5
  322.     out    (sport),a    ; Send to the status port
  323.     ld    a,(reg5)    ; Get register 5 settings
  324.     out    (sport),a    ; Send to the status port
  325. ;-- End of this block of machine specific code
  326.     ret
  327.  
  328. ;Turn DTR ( and RTS?) OFF
  329. dtroff:
  330. ;-- Code added specific to Kaypro
  331.     ld    a,05h        ; Select register 5
  332.     out    (sport),a    ; Send to the status port
  333.     ld    a,(reg5)    ; Get register 5 settings
  334.     and    255-dtr        ; Turn off DTR
  335.     out    (sport),a    ; Send to the status port
  336. ;-- End of this block of machine specific code
  337.     ret
  338.  
  339. ;Initialise the UART
  340. init:
  341.     ld    hl,2        ; get parameters
  342.     add    hl,sp
  343.     ld    a,(hl)        ; get lo
  344.     ld    (mspeed),a    ; save in baud rate low memory
  345.     inc    hl
  346.     inc    hl        ; bump for next
  347.     ld    a,(hl)        ; get lo
  348.     and    5Fh        ; Convert to upper case
  349.     ld    (parity),a    ; parity
  350.     inc    hl
  351.     inc    hl        ; bump for next
  352.     ld    a,(hl)        ; get lo
  353.     and    0fh        ; Make sure binary
  354.     ld    (data),a    ; Save data bits
  355.     cp    7        ; but 7 if required
  356.     ld    a,reg5ins    ; 8 Tx bits, Tx enable, RTS, DTR
  357.     jr    nz,setbs
  358.     ld    a,reg5ins-040h    ; Turn bit off
  359. setbs:
  360.     ld    (reg5),a
  361.     inc    hl
  362.     inc    hl        ; bump for next
  363.     ld    a,(hl)        ; get lo
  364.     and    0fh        ; Make sure binary
  365.     ld    (stop),a    ; stop bits
  366.                 ; <== Insert your own code here
  367. ;-- Code added specific to Kaypro
  368.     ld    a,10h        ; Reset register 0
  369.     out    (sport),a    ; Send to the status port
  370.     in    a,(sport)    ; read status port
  371.     and    DCD        ; Is carrier up
  372.     jr    nz,initr    ; Branch if carrier already there
  373.     ld    A,0        ; Select register 0
  374.     out    (sport),a    ; Send to status port
  375.     ld    a,rstsio    ; Reset SIO - 18h
  376.     out    (sport),a    ; Send to status port
  377. ;
  378.     ld    A,4        ; Select register 4
  379.     out    (sport),a    ; Send to status port
  380.     ld    a,(parity)    ; do parity
  381.     ld    e,003h        ; assume even parity
  382.     cp    'E'        ; even?
  383.     jr    z,setstop    ; yes
  384.     ld    e,001h        ; try odd
  385.     cp    'O'
  386.     jr    z,setstop
  387.     ld    e,0        ; Indicate no parity
  388. setstop:
  389.     ld    a,(stop)    ; set stop bits
  390.     cp    2
  391.     ld    a,reg4ins    ; 16X baud rate, 1 stop bit, no parity
  392.     jr    nz,onestop
  393.     or    00ch        ; set bits 2 and 3
  394. onestop:
  395.     or    e        ; put parity bits in the register
  396. ;
  397.     out    (sport),a    ; Send to status port
  398. ;
  399.     ld    a,3        ; Select register 3
  400.     out    (sport),a    ; Send to status port
  401. ;
  402.     ld    a,(data)    ; get data bits parameter field
  403.     cp    7        ; is 7 required
  404.     ld    a,reg3ins    ; 8 Rx bits, Rx enable
  405.     jr    nz,setbr
  406.     and    07fh
  407. setbr:
  408.     out    (sport),a    ; Set Rx bits
  409.     ld    a,5        ; Select register 5
  410.     out    (sport),a    ; Send to status port
  411.     ld    a,(reg5)    ; Get register 5 settings
  412.     out    (sport),a    ; Set tx bits
  413. ;
  414.     ld    a,1        ; Select register 1
  415.     out    (sport),a
  416.     ld    a,reg1ins    ; No interrupts
  417.     out    (sport),a    ; Send to status port
  418. ;
  419.     ld    a,(mspeed)    ; set baud rate: get index
  420.     ld    hl,brval
  421.     ld    e,a        ; rate to DE
  422.     ld    d,0
  423.     add    hl,de
  424.     ld    a,(hl)        ; get baud rate value
  425.     out    (bauda),a
  426.                 ; <== End of your own code
  427. initr:    ret
  428.  
  429. ;
  430. ; Baud rate factors, output to bauda to select baud rate
  431. ;
  432. bd10    equ    02h        ; 110 baud rate     0
  433. bd30    equ    05h        ; 300 baud rate     1
  434. bd12    equ    07h        ; 1200 baud rate    5
  435. bd24    equ    0ah        ; 2400 baud rate    6
  436. bd48    equ    0ch        ; 4800 baud rate    7
  437. bd96    equ    0eh        ; 9600 baud rate    8
  438. bd19k    equ    0fh        ; 19.2k baud rate    9
  439.  
  440.  
  441. ;Values for control reg for each baud rate: 0 if invalid
  442. brval:
  443. ;         0, 1, 2, 3, 4, 5, 6, 7, 8, 9
  444.     db    00,01,00,00,00,07,10,12,14,15
  445.  
  446.                 ; <== End of your own code
  447.     ret
  448.  
  449. brate:    db    6,0        ; baud rate:
  450.                 ; 0 = 110 baud    1 = 300 baud    2 = 450 baud
  451.                 ; 3 = 600 baud    4 = 710 baud    5 = 1200 baud
  452.                 ; 6 = 2400 baud 7 = 4800 baud    8 = 9600 baud
  453.                 ; 9 = 19200 baud
  454. parity:    db    'N',0        ; parity (will be 'N', 'E' or 'O')
  455. data:    db    8,0        ; data bits (will be 7 or 8)
  456. stop:    db    1,0        ; stop bits (will be 1 or 2)
  457. reg5:    db    reg5ins
  458.  
  459. ;****************************************************************************
  460. ;Video terminal sequences: these are for ADM-3A: Modify as you wish
  461. ;Cursor addressing:
  462. cursadd:
  463.     ld    hl,2        ; get parameters
  464.     add    hl,sp
  465.     ex    de,hl
  466.     call    getparm        ; in HL
  467.     ld    (row),hl    ; row
  468.     call    getparm
  469.     ld    (col),hl    ; column
  470.                 ; <== Insert your own code here
  471.                 ; using values in row and col
  472.     call    print
  473.     db    esc,'=',0    ; ADM-3A leadin
  474.     ld    a,(row)        ; row first
  475.     add    a,' '        ; add offset
  476.     call    cout
  477.     ld    a,(col)        ; sane for column
  478.     add    a,' '
  479.     call    cout
  480.                 ; <== end of your own code
  481.     ret
  482.  
  483. row:    ds    2        ; row
  484. col:    ds    2        ; column
  485.  
  486.  
  487. ;Clear screen:
  488. cls:
  489.     call    print
  490.     db    01ah,0
  491.     ret
  492.  
  493. ;Inverse video on:
  494. invon:
  495.     call    print
  496.     db    esc,'B','0',esc,'B','1',0
  497.     ret
  498.  
  499. ;Inverse video off:
  500. invoff:
  501.     call    print
  502.     db    esc,'C','0',esc,'C','1',0
  503.     ret
  504.  
  505. ;Turn off cursor:
  506. hide:
  507.     call    print
  508.     db    esc,'C','4',0
  509.     ret
  510.  
  511. ;Turn on cursor:
  512. show:
  513.     call    print
  514.     db    esc,'B','4',0
  515.     ret
  516.  
  517. ;Save cursor position:
  518. savecu:
  519.     call    print
  520.     defb    esc,'B','6',0
  521.     ret
  522.  
  523. ;Restore cursor position:
  524. rescu:
  525.     call    print
  526.     defb    esc,'C','6',0
  527.     ret
  528.  
  529. ;****************************************************************************
  530.  
  531. ;Service modem interrupt:
  532. mint:
  533.     ret            ; my system doesn't need this
  534.  
  535. ;Initialise interrupt vectors:
  536. invec:
  537.     ret            ; ditto
  538.  
  539. ;De-initialise interrupt vectors:
  540. dinvec:
  541.     ret            ; ditto
  542.  
  543. ;****************** End of user-defined code ********************************
  544. ; Don't change anything below this point. We needed some assembly language
  545. ; stuff for speed, and this seemed like a good place to put it.
  546.  
  547. ;Modem character test for 100 ms
  548. mrd:
  549.     push    bc        ; save bc
  550.     ld    bc,100        ; set limit
  551. mrd1:
  552.     call    mirdy        ; character at modem?
  553.     jr    nz,mrd2        ; yes, exit
  554.     ld    hl,1        ; else wait 1ms
  555.     call    waitms
  556.     dec    bc        ; loop till done
  557.     ld    a,b
  558.     or    c
  559.     jr    nz,mrd1
  560.     ld    hl,0        ; none there, result=0
  561.     xor    a
  562. mrd2:
  563.     pop    bc
  564.     ret
  565.  
  566. ; Inline print routine: destroys A and HL
  567.  
  568. print:
  569.     ex    (sp),hl        ; get address of string
  570. ploop:
  571.     ld    a,(hl)        ; get next
  572.     inc    hl        ; bump pointer
  573.     or    a        ; done if zero
  574.     jr    z,pdone
  575.     call    cout        ; else print
  576.     jr    ploop        ; and loop
  577. pdone:
  578.     ex    (sp),hl        ; restore return address
  579.     ret            ; and quit
  580.  
  581. ;
  582. ;Output a character in A to the console
  583. ;
  584. cout:
  585.     push    bc        ; save regs
  586.     push    de
  587.     push    hl
  588.     ld    e,a        ; Save the character to E for BDOS routine
  589.     ld    c,2        ; BDOS conout routine
  590.     call    bdos        ; print it
  591.     pop    hl
  592.     pop    de
  593.     pop    bc
  594.     ret
  595.  
  596. ;Wait(seconds)
  597. wait:
  598.     ld    hl,2
  599.     add    hl,sp
  600.     ex    de,hl        ; get delay size
  601.     call    getparm
  602.                 ; fall thru to..
  603. ;Wait seconds in HL
  604. waits:
  605.     push    bc        ; save bc
  606.     push    de        ; de
  607.     push    ix        ; and ix
  608.     ld    ix,0        ; then point ix to 0
  609.                 ; so we don't upset memory-mapped i/o
  610.  
  611. ;Calculate values for loop constants. Need to have two loops to avoid
  612. ;   16-bit overflow with clock speeds above 9 MHz.
  613.  
  614. outerval    equ    (clkspd    / 10) +    1
  615. innerval    equ    (6667 /    outerval) * clkspd
  616.  
  617. wait10:
  618.     ld    b,outerval
  619.  
  620. wait11:
  621.     ld    de,innerval
  622.  
  623. wait12:
  624.     bit    0,(ix)        ; time-wasters
  625.     bit    0,(ix)
  626.     bit    0,(ix)        ; 20 T-states each
  627.     bit    0,(ix)
  628.     bit    0,(ix)
  629.     bit    0,(ix)
  630.     dec    de
  631.     ld    a,e
  632.     ld    a,d
  633.     or    e
  634.     jr    nz,wait12    ; 150 T-states per inner loop
  635.     djnz    wait11        ; decrement outer loop
  636.     dec    hl        ; ok, decrement count in hl
  637.     ld    a,h
  638.     or    l
  639.     jr    nz,wait10
  640.     pop    ix        ; done -- restore ix
  641.     pop    de        ; de
  642.     pop    bc        ; and bc
  643.     ret
  644.  
  645. ;Wait milliseconds
  646. mswait:
  647.     ld    hl,2
  648.     add    hl,sp
  649.     ex    de,hl        ; get delay size
  650.     call    getparm
  651.                 ; fall thru to..
  652. ;Wait milliseconds in HL
  653. waitms:
  654.     push    de
  655. w1ms0:
  656.     ld    de,39 *    clkspd
  657. w1ms1:
  658.     dec    de
  659.     ld    a,d
  660.     or    e
  661.     jr    nz,w1ms1
  662.     dec    hl
  663.     ld    a,h
  664.     or    l
  665.     jr    nz,w1ms0
  666.     pop    de
  667.     ret
  668.  
  669. ;Get next parameter from (de) into hl
  670. getparm:
  671.     ex    de,hl        ; get address into hl
  672.     ld    e,(hl)        ; get lo
  673.     inc    hl
  674.     ld    d,(hl)        ; then hi
  675.     inc    hl        ; bump for next
  676.     ex    de,hl        ; result in hl, address still in de
  677.     ret
  678.  
  679. ;Get address of user-defined variables
  680.  
  681. getvars:
  682.     ld    hl,uservars
  683.     ret
  684.  
  685. uservars:
  686.     dw    overdrive    ; .OVR etc. drive/user
  687.     dw    overuser
  688. setport:
  689.     ret
  690.  
  691.      if    ($ - codebgn) gt ovsize
  692. toobig:    jp    errval        ; Overlay too large!
  693.      endif
  694.  
  695.     end
  696.