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 / BEEHIVE / COMMS / ZMP-OV16.ARC / ZMO-R406.Z80 < prev    next >
Text File  |  1991-02-02  |  17KB  |  732 lines

  1. ;-----------------------------------------------------------------------------
  2. ;
  3. ;
  4. ;    Overlay for ZMP (Z-Modem Program)
  5. ;
  6. ;    Name    ZMO-R405.Z80
  7. ;
  8. ;    Dated   18 Sep 1988
  9. ;
  10. ;    Written by -
  11. ;      Ron Murray, c/o Z-Node 62, 061-9-450-0200, Perth, Western Australia.
  12. ;      Modified by Wayne Dowie for the TRS 80 Model 4/4p,  27 August 1988
  13. ;      Modified to v1.3 standard rjm 12/10/88
  14. ;      Modified to v1.4 standard rjm 4/11/88
  15. ;      Modified to v1.5 standard rjm 25/3/89
  16. ;
  17. ;
  18. ;    Rename subsequent versions as ZMO-R4xx.Z80 etc
  19. ;
  20. ;
  21. ;    This overlay is set up for the Tandy TRS 80 Model 4/4p
  22. ;     using the Western Digital type TR 1602B/1865 etc. and the BR 1941 
  23. ;     /BR 1943 baud rate generator.
  24. ;
  25. ;-----------------------------------------------------------------------------
  26. ;
  27. ;
  28. ;    System-dependent code overlay for ZMODEM
  29. ;
  30. ;
  31. ;
  32. ;    Insert your own code as necessary in this file. Code contained herein
  33. ; has been written in Z80 code for use with M80 or SLR. Assemble as follows:
  34. ;
  35. ;    SLR ZMO-R4xx/A
  36. ;    MLOAD ZMP.COM=ZMPX.COM,ZMO-R4XX
  37. ; or
  38. ;    M80 =ZMO-R4xx/z
  39. ;    RELHEX ZMO-R4xx
  40. ;    MLOAD ZMP.COM=ZMPX.COM,ZMO-R4xx
  41. ;
  42. ;
  43. ;       (Don't use L80 without changing the source for assembly as a
  44. ;         cseg file.)
  45. ;
  46. ;-----------------------------------------------------------------------------
  47. ;
  48. ;
  49. ; Notes on modifying this file:
  50. ;
  51. ;    C requires that functions do not change either index register
  52. ; (IX or IY), nor the BC register pair. If your overlay requires any of
  53. ; these to be changed, ensure they are restored to the original values
  54. ; on return.
  55. ;    Since collecting parameters from C functions can be tricky, only change
  56. ; the parts marked 'Insert your own code here'. Do NOT modify the jump
  57. ; table at the start. Do NOT modify the entry/exit sections of each
  58. ; function. Do NOT pass 'GO'. Do NOT collect $200.
  59. ;    Apart from defining modem functions, this file also defines terminal
  60. ; characteristics. Most have been set up for ADM-3A (with a few of my own
  61. ; additions). Modify to suit your own terminal. An inline print routine
  62. ; is provided for printing strings in the usual way: usage is
  63. ;
  64. ;    call    print
  65. ;    db    'required string',0
  66. ;
  67. ;-----------------------------------------------------------------------------
  68. ;
  69. ;
  70. ;    Don't forget to set your clock speed at the clkspd variable.
  71. ;
  72. ;
  73. ;    If you find your overlay exceeds the maximum size (currently 0400h),
  74. ; you will have to contact me for another version. If too many people need 
  75. ; to do it, we haven't allowed enough room.
  76. ;
  77. ; Ron Murray 15/8/88
  78. ;
  79. ;
  80. ;
  81. ;
  82. ;
  83. ;
  84. ;
  85. ;
  86. ;
  87. ;
  88. ;-----------------------------------------------------------------------------
  89.  
  90. false    equ    0
  91. true    equ    not false
  92.  
  93.  
  94. ; User-set variables: ***********
  95.  
  96. ;Set the following two equates to the drive and user area which will contain
  97. ;   ZMP's .OVR files, .CFG file, .FON file and .HLP file. Set both to zero
  98. ;   (null) to locate them on the drive from which ZMP was invoked.
  99.  
  100. overdrive    equ    'A'    ; Drive to find overlay files on ('A'-'P')
  101. overuser    equ    0    ; User area to find files
  102.  
  103. clkspd    equ    4        ; Processor clock speed in MHz
  104.  
  105. debug    equ    false
  106.  
  107.  
  108. ; NOT user-set variables
  109. mspeed    equ    003ch        ; baud rate id
  110. ovsize    equ    0400h        ; max size of this overlay
  111. userdef    equ    00145h        ; origin of this overlay
  112.                 ; This address should remain constant
  113.                 ; with subsequent revisions.
  114.  
  115.     .z80            ; use z80 code
  116.     aseg            ; absolute
  117.  
  118.      if    debug
  119.     org    100h        ; so you can debug it with cebug, zsid, etc
  120.      else
  121.     org    userdef
  122.      endif
  123.  
  124. esc    equ    1bh
  125. ctrlq    equ    11h
  126. cr    equ    0dh
  127. lf    equ    0ah
  128. bdos    equ    5
  129.  
  130.  
  131. ; Tandy specific equates  ***********************************************
  132. mdata    equ    0EBh    ;Modem data port
  133. mstat    equ    0EAh    ;Modem Status for BREAK,DTR,RTS
  134. mrset    equ    0E8h    ;Master Reset and Modem Status for CTS,DSR,CD,RI
  135. brg    equ    0E9h    ;Baud rate generator port BR 1943
  136. break    equ    2    ;BREAK bit 2, 0 = BREAK 1 = NO BREAK
  137. error    equ    38h    ;For bits 5,4,3 (any a 1)
  138. dtr    equ    1    ;DTR bit 1, 1=OFF, 0=ON
  139. nstp    equ    4    ;Bit 4 is No of STOP bits, 1=2 stop bits, 0=1 stop bit
  140. paroe    equ    7    ;Parity ODD/EVEN bit 7, 1=EVEN, 0=ODD  
  141. paron    equ    3    ;Parity ON/OFF bit 3, 1=OFF, 0=ON
  142. rda    equ    7    ;Bit 7 received byte available, 1=data available
  143. rts    equ    0    ;RTS bit 0, 1=OFF, 0=ON
  144. tbe    equ    6    ;Bit 6 transmit holding register empty, 1=empty
  145. wls1    equ    6    ;Word Length Select bit 6  (See explanation below)
  146. wls2    equ    5    ;Word Length Select bit 5
  147. ;
  148. ;    D6    D5
  149. ;    wls1    wls2    No of bits
  150. ;    0    0    5
  151. ;    1    0    6
  152. ;    0    1    7
  153. ;    1    1    8
  154. ;
  155. ;
  156. ;
  157. ;*************************************************************************
  158. ; Main code starts here
  159.  
  160. codebgn    equ    $
  161.  
  162. ;Jump table for the overlay: do NOT change this
  163. jump_tab:
  164.     jp    scrnpr        ; screen print
  165.     jp    mrd        ; modem read with timeout
  166.     jp    mchin        ; get a character from modem
  167.     jp    mchout        ; send a character to the modem
  168.     jp    mordy        ; test for tx buffer empty
  169.     jp    mirdy        ; test for character received
  170.     jp    sndbrk        ; send break
  171.     jp    cursadd        ; cursor addressing
  172.     jp    cls        ; clear screen
  173.     jp    invon        ; inverse video on
  174.     jp    invoff        ; inverse video off
  175.     jp    hide        ; hide cursor
  176.     jp    show        ; show cursor
  177.     jp    savecu        ; save cursor position
  178.     jp    rescu        ; restore cursor position
  179.     jp    mint        ; service modem interrupt
  180.     jp    invec        ; initialise interrupt vectors
  181.     jp    dinvec        ; de-initialise interrupt vectors
  182.     jp    mdmerr        ; test uart flags for error
  183.     jp    dtron        ; turn DTR on
  184.     jp    dtroff        ; turn DTR OFF
  185.     jp    init        ; initialise uart
  186.     jp    wait        ; wait seconds
  187.     jp    mswait        ; wait milliseconds
  188.     jp    userin        ; user-defined entry routine
  189.     jp    userout        ; user-defined exit routine
  190.     jp    getvars        ; get system variables
  191.     jp    setport        ; set port (1 or 2)
  192.  
  193. ; Spare jumps for compatibility with future versions
  194.     jp    spare        ; spare for later use
  195.     jp    spare        ; spare for later use
  196.     jp    spare        ; spare for later use
  197.     jp    spare        ; spare for later use
  198.     jp    spare        ; spare for later use
  199.     jp    spare        ; spare for later use
  200.  
  201.  
  202. spare:    ret
  203.  
  204. ;-------------------------------------------------------------------------
  205.  
  206.  
  207. ; Screen print function
  208. scrnpr:
  209.                 ; <== Insert your own code here
  210.     call    print
  211.     db    'This function not supported.',cr,lf,0
  212.                 ; <== End of your own code
  213.     ret
  214.  
  215.  
  216. ; Get a character from the modem: return in HL
  217. mchin:
  218.     push    bc
  219.                 ; <== Insert your own code here
  220.  
  221. mchin2:
  222.     in    a,(mstat)    ; check for char waiting
  223.     bit    rda,a
  224.     jr    z,mchin2
  225.  
  226.     in    a,(mdata)    ; read the char
  227.  
  228.  
  229.                 ; <== End of your own code
  230.  
  231.  
  232.     ld    l,a        ; put in HL
  233.     ld    h,0
  234.     or    a        ; set/clear Z
  235.     pop    bc
  236.     ret
  237.  
  238. ; Send a character to the modem
  239. mchout:
  240.     ld    hl,2        ; get the character
  241.     add    hl,sp
  242.     ld    a,(hl)
  243.                 ; <== Insert your own code here
  244.  
  245.     push    bc
  246.     ld    b,a        ; save the char
  247.  
  248. mchout2:
  249.     in    a,(mstat)    ; check for uart ready
  250.     bit    tbe,a
  251.     jr    z,mchout2
  252.  
  253.     ld    a,b        ; char in a
  254.     out    (mdata),a    ; send it
  255.     pop    bc
  256.  
  257.                 ; <== End of your own code
  258.     ret            ; done
  259.  
  260. ; Test for output ready: return TRUE (1) in HL if ok
  261. mordy:
  262.                 ; <== Insert your own code here
  263.  
  264.     ld    hl,0
  265.     in    a,(mstat)
  266.     bit    tbe,a        ; transmit buffer empty
  267.     jr    z,mordy1
  268.     inc    hl
  269. mordy1:
  270.  
  271.                 ; <== End of your own code
  272.  
  273.     ld    a,l        ; set/clear Z
  274.     or    a
  275.     ret
  276.  
  277. ; Test for character at modem: return TRUE (1) in HL if so
  278. mirdy:
  279.                 ; <== Insert your own code here
  280.  
  281.     ld    hl,0
  282.     in    a,(mstat)
  283.     bit    rda,a        ; received data available
  284.     jr    z,mirdy1
  285.     inc    hl
  286. mirdy1:
  287.  
  288.                 ; <== End of your own code
  289.     ld    a,l        ; set/clear Z
  290.     or    a
  291.     ret
  292.  
  293. ; Send a break to the modem: leave empty if your system can't do it
  294. sndbrk:
  295.                 ; <== Insert your own code here
  296.     ld    a,(combyt)    ;Get byte 
  297.     res    break,a        ; reset bit 2
  298.     out    (mstat),a    ; output to status register
  299.  
  300.     push    af        ; save it
  301.     ld    hl,300        ; 300 mS delay
  302.     call    waithlms
  303.     pop    af
  304.  
  305.     set    break,a        ; set bit 2
  306.     out    (mstat),a    ; output to status register
  307.                 ; <== End of your own code
  308.     ret
  309.  
  310.  
  311. ; Test UART flags for error: return TRUE (1) in HL if error.
  312. mdmerr:
  313.                 ; <== Insert your own code here
  314.     ld    hl,0
  315.     in    a,(mstat)
  316.     and    a,error        ; 38h for bits 5,4,3 (any a 1) 0011 1000
  317.     jr    z,mdmer2    ; Go if no errors
  318.     inc    hl
  319.     in    a,(mdata)    ;Throw away the byte
  320.     out    (mrset),a    ;Reset UART by outing anything to E8h
  321. mdmer2:
  322.                 ; <== End of your own code
  323.     ld    a,l        ; set/clear Z
  324.     or    a
  325.     ret
  326.  
  327. ; Turn DTR ON
  328. dtron:
  329.                 ; <== Insert your own code here
  330.  
  331.     ld    hl,combyt    ;Get current status
  332.     res    dtr,(hl)    ;Turn DTR ON bit 1 = 0
  333.     ld    a,(hl)        ;
  334.     out    (mstat),a    ;Write to status port
  335.                 ; <== End of your own code
  336.     ret
  337.  
  338. ; Turn DTR OFF
  339. dtroff:
  340.                 ; <== Insert your own code here
  341.  
  342.     ld    hl,combyt    ;Get current status
  343.     set    dtr,(hl)    ;Turn DTR OFF bit 1 = 1
  344.     ld    a,(hl)        ;
  345.     out    (mstat),a    ;Write to status port
  346.  
  347.                 ; <== End of your own code
  348.     ret
  349.  
  350. ; Initialise the UART +++
  351. ;
  352. ; Tandy information is incorrect where it states that an out to E8h with
  353. ; bit 1 set will allow subsequent outs to EAh to access the UART status 
  354. ; register while an out to E8h with say 0h will only access the various 
  355. ; RS 232 lines without affecting the UART set-up.  The reality is that 
  356. ; all outs to EAh will affect the UART settings so "combyt" is used to 
  357. ; hold the current settings so it can be modified and re-written to 
  358. ; EAh with the DTR, RTS or BREAK bits conditioned appropriately.  
  359. ; Wayne Dowie. VK 6WD.
  360. ;
  361. init:
  362.  
  363.     ld    hl,2        ; get parameters
  364.     add    hl,sp
  365.     ex    de,hl
  366.     call    getparm        ; in HL
  367.     ld    (brate),hl    ; baud rate
  368.     call    getparm
  369.     ld    (parity),hl    ; parity
  370.     call    getparm
  371.     ld    (data),hl    ; data bits
  372.     call    getparm
  373.     ld    (stop),hl    ; stop bits
  374.                 
  375.                 ; <== Insert your own code here
  376.                 ; using values below
  377.     push    bc
  378.  
  379.     
  380.     ld    a,02h        ;To access UART control reg. (02h)
  381.     out    (mrset),a    ; to port E8h (As per Tandy book 
  382.                 ; which is wrong).
  383.  
  384.     
  385.     ld    hl,combyt    ;Point to  current status byte
  386.     ld    a,06Ch        ;Assume 8,N,1, No BREAK and RTS ON
  387.     ld    (hl),a        ;Store current status
  388.     ld    a,(stop)    ; set stop bits
  389.     cp    2        ; set 2 if required
  390.     jr    nz,setpar    ;If 1 stop then go to parity set
  391.     set    nstp,(hl)    ;Otherwise set bit 4 for 2 stop bits
  392.  
  393. setpar:
  394.     ld    a,(parity)    ; set parity bits
  395.     cp    'O'
  396.     jr    nz,setpa2    ;If not ODD go to check for EVEN
  397.     res    paroe,(hl)    ;Reset bit 7 for ODD parity
  398.     res    paron,(hl)    ;Reset bit 3 to turn ON parity.
  399.     jr    setbits
  400.  
  401. setpa2:    cp    'E'        ;Check for EVEN parity
  402.     jr    nz,setbits    ; default to 'N'
  403.     set    paroe,(hl)    ;Set bit 7 for EVEN parity
  404.     res    paron,(hl)    ;Reset bit 3 to turn ON parity.
  405.  
  406. setbits:ld    a,(data)
  407.     cp    7        ; not an ascii '7'
  408.     jr    nz,setbi2    ;If not 7 write to port
  409.     res    wls1,(hl)    ;For 7 bit word length
  410.     set    wls2,(hl)    ;  "         "
  411.  
  412. setbi2:    
  413.  
  414.     ld    a,(hl)        ;Get current status 
  415.     out    (mstat),a    ;Write to status port
  416.  
  417. setbrate:
  418.     ld    de,(brate)    ; get baud rate value (0-10)
  419.     ld    hl,brval    ;Set-up pointer to baud rate value in table
  420.     add    hl,de        ;
  421.     ld    a,(hl)        ;
  422.     or    a        ; don't do if invalid
  423.     jr    z,setbrx
  424.     out    (brg),a        ;To port 0E9h
  425.     ld    a,(brate)    ; ok, tell zmp it's ok
  426.     ld    (mspeed),a
  427. setbrx:
  428.     pop    bc
  429.                 ; <== End of your own code
  430.     ret
  431.  
  432. brate:    dw    5        ; baud rate:
  433. parity:    dw    'N'        ; parity
  434. data:    dw    8        ; data bits
  435. stop:    dw    1        ; stop bits
  436. combyt:    db    06Ch        ;To store current set-up (init val = 8,1,n)
  437.  
  438.  
  439. ; Values for Western Digital BR1941/BR1943, for each baud rate: 0 if invalid
  440. ;
  441. brval:
  442.     db    22h    ;   110        0
  443.     db    55h    ;   300        1
  444.     db    0    ;   450        2
  445.     db    66h    ;   600        3
  446.     db    0    ;   710        4
  447.     db    77h    ;  1200        5
  448.     db    0AAh    ;  2400        6
  449.     db    0CCh    ;  4800        7
  450.     db    0EEh    ;  9600        8
  451.     db    0FFh    ; 19200        9
  452.     db    0    ; 38400        10
  453.     db    0    ; 57600        11
  454.     db    0    ; 76800        12
  455.  
  456. ;
  457. ; Set the port. ZMP supplies either 0 or 1 as a parameter. You're on your
  458. ; own here -- your system is bound to be different from any other! You may
  459. ; implement a software switch on all the modem-dependent routines, or perhaps
  460. ; you can have one or two centralised routines for accessing the UARTs and
  461. ; modify the code from this routine to select one or the other. (Who said
  462. ; there was anything wrong with self-modifying code?). If you have only one
  463. ; UART port, or if you don't want to go through all the hassles, just have
  464. ; this routine returning with no changes made. Note that ZMP calls this
  465. ; routine with both values for the port on initialisation.
  466. ;
  467. setport:
  468.     ld    hl,2        ; get port number
  469.     add    hl,sp
  470.     ex    de,hl
  471.     call    getparm        ; in HL (values are 0 and 1)
  472.  
  473.                 ; <== Insert your own code here
  474.  
  475.                 ; <== End of your own code
  476.     ret
  477.  
  478. port:    ds    1
  479.  
  480. ;--------------------------------------------------------------------------
  481.  
  482.  
  483. ;My system needs a BIOS call to access the UART. If yours doesn't, you don't
  484. ;  need anything here. Otherwise write your own.
  485. calmod:
  486.  
  487.             ; not required for most computers
  488.  
  489. ;****************************************************************************
  490. ;Video terminal sequences: these are for ADM-3A: Modify as you wish
  491. ; Cursor addressing: 
  492. cursadd:
  493.     ld    hl,2        ; get parameters
  494.     add    hl,sp
  495.     ex    de,hl
  496.     call    getparm        ; in HL
  497.     ld    (row),hl    ; row
  498.     call    getparm
  499.     ld    (col),hl    ; column
  500.                 ; <== Insert your own code here
  501.                 ; using values in row and col
  502.     call    print
  503.     db    esc,'=',0    ; ADM-3A leadin
  504.     ld    a,(row)        ; row first
  505.     add    a,' '        ; add offset
  506.     call    cout
  507.     ld    a,(col)        ; sane for column
  508.     add    a,' '
  509.     call    cout
  510.                 ; <== end of your own code
  511.     ret
  512.  
  513. row:    ds    2        ; row
  514. col:    ds    2        ; column
  515.  
  516.  
  517. ; Clear screen:
  518. cls:
  519.     call    print
  520.     db    0Eh,1Ah,0    ;CLS and turn inverse OFF  
  521.     ret
  522.  
  523. ; Inverse video on:
  524. invon:
  525.     ret    ;put in correct code
  526.     call    print
  527.     db    0Fh,0
  528.     ret
  529.  
  530. ; Inverse video off:
  531. invoff:
  532.     ret
  533.     call    print
  534.     db    0Eh,0
  535.     ret
  536.  
  537. ; Turn off cursor:
  538. hide:
  539.     call    print
  540.     db    esc,30h,0
  541.     ret
  542.  
  543. ; Turn on cursor:
  544. show:
  545.     call    print
  546.     db    esc,31h,0
  547.     ret
  548.  
  549. ; Save cursor position:
  550. savecu:
  551.     ret
  552.  
  553. ; Restore cursor position:
  554. rescu:
  555.     ret
  556.  
  557. ;****************************************************************************
  558.  
  559. ; Service modem interrupt:
  560. mint:
  561.     ret            ; my system doesn't need this
  562.  
  563. ; Initialise interrupt vectors:
  564. invec:
  565.     ret            ; ditto
  566.  
  567. ; De-initialise interrupt vectors:
  568. dinvec:
  569.     ret            ; ditto
  570.  
  571. ; User-defined entry routine: leave empty if not used
  572. userin:
  573.     ret
  574.  
  575. ; User-defined exit  routine: leave empty if not used
  576. userout:
  577.     ret
  578.  
  579.  
  580. ;****************** End of user-defined code ********************************
  581.  
  582. ;Modem character test for 100 ms
  583. mrd:
  584.     push    bc        ; save bc
  585.     ld    bc,100        ; set limit
  586. mrd1:
  587.     call    mirdy        ; char at modem?
  588.     jr    nz,mrd2        ; yes, exit
  589.     ld    hl,1        ; else wait 1ms
  590.     call    waithlms
  591.     dec    bc        ; loop till done
  592.     ld    a,b
  593.     or    c
  594.     jr    nz,mrd1
  595.     ld    hl,0        ; none there, result=0
  596.     xor    a
  597. mrd2:
  598.     pop    bc
  599.     ret
  600.  
  601. ; Inline print routine: destroys A and HL
  602.  
  603. print:
  604.     ex    (sp),hl        ; get address of string
  605. ploop:
  606.     ld    a,(hl)        ; get next
  607.     inc    hl        ; bump pointer
  608.     or    a        ; done if zero
  609.     jr    z,pdone
  610.     call    cout        ; else print
  611.     jr    ploop        ; and loop
  612. pdone:
  613.     ex    (sp),hl        ; restore return address
  614.     ret            ; and quit
  615.  
  616. ;
  617. ;Output a character in A to the console
  618. ;
  619. cout:
  620.     push    bc        ; save regs
  621.     push    de
  622.     push    hl
  623.     ld    e,a        ; character to E
  624.     ld    c,2
  625.     call    bdos        ; print it
  626.     pop    hl
  627.     pop    de
  628.     pop    bc
  629.     ret
  630.  
  631. ;Wait(seconds)
  632. wait:
  633.     ld    hl,2
  634.     add    hl,sp
  635.     ex    de,hl        ; get delay size
  636.     call    getparm
  637.                 ; fall thru to..
  638. ;Wait seconds in HL
  639. waithls:
  640.     push    bc        ; save bc
  641.     push    de        ; de
  642.     push    ix        ; and ix
  643.     ld    ix,0        ; then point ix to 0
  644.                 ; so we don't upset memory-mapped i/o
  645.  
  646. ;Calculate values for loop constants. Need to have two loops to avoid
  647. ;   16-bit overflow with clock speeds above 9 MHz.
  648.  
  649. outerval    equ    (clkspd / 10) + 1
  650. innerval    equ    (6667 / outerval) * clkspd
  651.  
  652. wait10:
  653.     ld    b,outerval
  654.  
  655. wait11:
  656.     ld    de,innerval
  657.  
  658. wait12:
  659.     bit    0,(ix)        ; time-wasters
  660.     bit    0,(ix)
  661.     bit    0,(ix)        ; 20 T-states each
  662.     bit    0,(ix)
  663.     bit    0,(ix)
  664.     bit    0,(ix)
  665.     dec    de
  666.     ld    a,e
  667.     ld    a,d
  668.     or    e
  669.     jr    nz,wait12    ; 150 T-states per inner loop
  670.     djnz    wait11        ; decrement outer loop
  671.     dec    hl        ; ok, decrement count in hl
  672.     ld    a,h
  673.     or    l
  674.     jr    nz,wait10
  675.     pop    ix        ; done -- restore ix
  676.     pop    de        ; de
  677.     pop    bc        ; and bc
  678.     ret
  679.  
  680. ;Wait milliseconds
  681. mswait:
  682.     ld    hl,2
  683.     add    hl,sp
  684.     ex    de,hl        ; get delay size
  685.     call    getparm
  686.                 ; fall thru to..
  687. ;Wait milliseconds in HL
  688. waithlms:
  689.     push    de
  690. w1ms0:
  691.     ld    de,39 * clkspd
  692. w1ms1:
  693.     dec    de
  694.     ld    a,d
  695.     or    e
  696.     jr    nz,w1ms1
  697.     dec    hl
  698.     ld    a,h
  699.     or    l
  700.     jr    nz,w1ms0
  701.     pop    de
  702.     ret
  703.  
  704. ;Get next parameter from (de) into hl
  705. getparm:
  706.     ex    de,hl        ; get address into hl
  707.     ld    e,(hl)        ; get lo
  708.     inc    hl
  709.     ld    d,(hl)        ; then hi
  710.     inc    hl        ; bump for next
  711.     ex    de,hl        ; result in hl, address still in de
  712.     ret
  713.  
  714. ;Get address of user-defined variables
  715.  
  716. getvars:
  717.     ld    hl,uservars
  718.     ret
  719.  
  720. uservars:
  721.     dw    overdrive    ; .OVR etc. drive/user
  722.     dw    overuser
  723.  
  724.  
  725.      if    ($ - codebgn) gt ovsize
  726. toobig:    jp    errval        ; Overlay too large!
  727.      endif
  728.  
  729.     end
  730.  
  731.  
  732.