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-CP05.Z80 < prev    next >
Text File  |  2000-06-30  |  14KB  |  725 lines

  1. ;  PROGRAM: ZMO-CP05.Z80
  2. ;  AUTHOR:  Bruce Dudley
  3. ;  VERSION: 1.5
  4. ;  DATE:  19 Sept, 1988
  5. ;-----------------------------------------------------------------------
  6. ;    This overlay is set up for an Amstrad CPC6128 under CPM Plus,
  7. ;    with a Zenith Z19/Z29 terminal emulation and a Z80SIO and 8253
  8. ;    counter.
  9. ;-----------------------------------------------------------------------
  10. ; 89/04/12 - Modified to ZMP v1.5        - George Conover
  11. ; 89/03/15 - Removed the beginning remarks to make the file
  12. ;            smaller. If you need the remarks there are in the
  13. ;            file ZMP-BLNK.Z80             - George Conover
  14. ; 89/03/14 - Modified to ZMP v1.4        - George Conover
  15. ; 88/10/12 - Modified to ZMP v1.3        - Ron Murray
  16. ; 88/09/15 - Modified to ZMP v1.2        - Ron Murray
  17. ; 88/08/28 - First version of this file        - Bruce Dudley
  18. ;
  19. ;    Written by -
  20. ;      Ron Murray, c/o Z-Node 62, 061-9-450-0200, Perth, Western Australia.
  21. ;-----------------------------------------------------------------------
  22. ;
  23. NO    EQU    0
  24. YES    EQU    NOT NO
  25. ;
  26. ; User-set variables
  27. ;
  28. CLKSPD    EQU    4        ; Processor clock speed in MHz
  29. ;
  30. DEBUG    EQU    NO
  31.  
  32. ;Set the following two equates to the drive and user area which will contain
  33. ;   ZMP's .OVR files, .CFG file, .FON file and .HLP file. Set both to zero
  34. ;   (null) to locate them on the drive from which ZMP was invoked.
  35.  
  36. OVERDRIVE    EQU    'A'    ; Drive to find overlay files on ('A'-'P')
  37. OVERUSER    EQU    0    ; User area to find files
  38.  
  39. ;------------------------------------------------------------------------------
  40. ;
  41. ; NOT user-set variables
  42. ;
  43. USERDEF    EQU    0145H        ; Origin of this overlay.  This address
  44. ;                ;   may change with subsequent revisions
  45. MSPEED    EQU    05CH        ; Location of current baud rate.
  46. OVSIZE    EQU    0400H        ; Max size of this overlay
  47. ;
  48.     .Z80            ; Use z80 code
  49.     ASEG            ; Absolute
  50. ;
  51.      IF    DEBUG
  52.     ORG    100H        ; So you can debug it with CEBUG, ZSID,
  53. ;                ;   etc.
  54.      ELSE
  55.     ORG    USERDEF
  56.      ENDIF            ; DEBUG
  57. ;
  58. ESC    EQU    1BH
  59. CTRLQ    EQU    11H
  60. CR    EQU    0DH
  61. LF    EQU    0AH
  62. BDOS    EQU    5
  63. ;
  64. ; Amstrad CPC6128 specific equates
  65. ;
  66. MDATA    EQU    0FADCH        ; Data port
  67. MSTAT    EQU    0FADDH        ; Status port
  68. RDA    EQU    0        ; Received data available
  69. TBE    EQU    2        ; Tx ready
  70. ONHOOK    EQU    7FH
  71. ONLINE    EQU    80H
  72. ERROR    EQU    70H
  73. BREAK    EQU    0F8H
  74. ;
  75. ; 8253 Counter equates
  76. ;
  77. CTCONT    EQU    0FBDFH        ; Control register of the 8253
  78. CTC0    EQU    0FBDCH        ; Counter # 0 of the 8253
  79. CTC1    EQU    0FBDDH        ; Counter # 1 of the 8253
  80. ;
  81. ;-----------------------------------------------------------------------
  82. ;
  83. ; Main code starts here
  84. ;
  85. ;Jump table for the overlay: do NOT change this
  86. ;
  87. CODEBGN    EQU    $
  88. ;
  89. JUMPTAB:
  90.     JP    SCRNPR        ; Screen print
  91.     JP    MRD        ; Modem read with timeout
  92.     JP    MCHIN        ; Get a character from modem
  93.     JP    MCHOUT        ; Send a character to the modem
  94.     JP    MORDY        ; Test for tx buffer empty
  95.     JP    MIRDY        ; Test for character received
  96.     JP    SNDBRK        ; Send break
  97.     JP    CURSADD        ; Cursor addressing
  98.     JP    CLS        ; Clear screen
  99.     JP    INVON        ; Inverse video on
  100.     JP    INVOFF        ; Inverse video off
  101.     JP    HIDE        ; Hide cursor
  102.     JP    SHOW        ; Show cursor
  103.     JP    SAVECU        ; Save cursor position
  104.     JP    RESCU        ; Restore cursor position
  105.     JP    MINT        ; Service modem interrupt
  106.     JP    INVEC        ; Initialise interrupt vectors
  107.     JP    DINVEC        ; De-initialise interrupt vectors
  108.     JP    MDMERR        ; Test uart flags for error
  109.     JP    DTRON        ; Turn DTR on
  110.     JP    DTROFF        ; Turn DTR OFF
  111.     JP    INIT        ; Initialise uart
  112.     JP    WAIT        ; Wait seconds
  113.     JP    MSWAIT        ; Wait milliseconds
  114.     JP    USERIN        ; User-defined entry routine
  115.     JP    USEROUT        ; User-defined exit routine
  116.     JP    GETVARS        ; get system variables
  117.       JP    SETPORT        ; Set port (0 or 1)
  118. ;
  119. ; Spare jumps for compatibility with future versions
  120. ;
  121.     JP    SPARE        ; Spares for later use
  122.     JP    SPARE        ; Spares for later use
  123.     JP    SPARE        ; Spares for later use
  124.     JP    SPARE        ; Spares for later use
  125.     JP    SPARE        ; Spares for later use
  126.     JP    SPARE        ; Spares for later use
  127. ;
  128. SPARE:    RET
  129. ;
  130. ;-----------------------------------------------------------------------
  131. ;
  132. ; Screen print function
  133. ;
  134. SCRNPR:    DS    0
  135. ;
  136. ; <== Insert your own code here
  137. ;
  138.     CALL    PRINT
  139.     DB    'This function not supported.',CR,LF
  140.     DB    0
  141. ;
  142. ; <== End of your own code
  143. ;
  144.     RET
  145. ;
  146. ; Get a character from the modem: return in HL
  147. ;
  148. MCHIN:    PUSH    BC
  149. ;
  150. ; <== Insert your own code here
  151. ;
  152.     LD    BC,MSTAT
  153. ;
  154. MCHIN2:    IN    A,(C)        ; Check for char waiting
  155.     BIT    RDA,A
  156.     JR    Z,MCHIN2
  157.     LD    BC,MDATA
  158.     IN    A,(C)        ; Read the character
  159. ;
  160. ; <== End of your own code
  161. ;
  162.     LD    L,A        ; Put in HL
  163.     LD    H,0
  164.     OR    A        ; Set/clear Z
  165.     POP    BC
  166.     RET
  167. ;
  168. ; Send a character to the modem
  169. ;
  170. MCHOUT:    LD    HL,2        ; Get the character
  171.     ADD    HL,SP
  172.     LD    A,(HL)
  173. ;
  174. ; <== Insert your own code here
  175. ;
  176.     PUSH    BC
  177.     PUSH    AF        ; Save the character
  178.     LD    BC,MSTAT
  179. ;
  180. MCHOUT2:IN    A,(C)        ; Check for UART ready
  181.     BIT    TBE,A
  182.     JR    Z,MCHOUT2
  183.     POP    AF        ; Character in a
  184.     LD    BC,MDATA
  185.     OUT    (C),A        ; Send it
  186.     POP    BC
  187. ;
  188. ; <== End of your own code
  189. ;
  190.     RET            ; Done
  191. ;
  192. ; Test for output ready: return YES (1) in HL if ok
  193. ;
  194. MORDY:    DS    0
  195. ;
  196. ; <== Insert your own code here
  197. ;
  198.     PUSH    BC
  199.     LD    BC,MSTAT
  200.     LD    HL,0
  201.     IN    A,(C)
  202.     BIT    TBE,A        ; Transmit buffer empty
  203.     JR    Z,MORDY1
  204.     INC    HL
  205. ;
  206. MORDY1:    DS    0
  207. ;
  208. ; <== End of your own code
  209. ;
  210.     POP    BC
  211.     LD    A,L        ; Set/clear Z
  212.     OR    A
  213.     RET
  214. ;
  215. ;-----------------------------------------------------------------------
  216. ;
  217. ; Test for character at modem: return YES (1) in HL if so
  218. ;
  219. MIRDY:    DS    0
  220. ;
  221. ; <== Insert your own code here
  222. ;
  223.     PUSH    BC
  224.     LD    BC,MSTAT
  225.     LD    HL,0
  226.     IN    A,(C)
  227.     BIT    RDA,A        ; Received data available
  228.     JR    Z,MIRDY1
  229.     INC    HL
  230. ;
  231. MIRDY1:    DS    0
  232. ;
  233. ; <== End of your own code
  234. ;
  235.     POP    BC
  236.     LD    A,L        ; Set/clear Z
  237.     OR    A
  238.     RET
  239. ;
  240. ;Send a break to the modem: leave empty if your system can't do it
  241. ;
  242. SNDBRK:    DS    0
  243. ;
  244. ; <== Insert your own code here
  245. ;
  246.     PUSH    BC
  247.     LD    BC,MSTAT
  248.     LD    A,5
  249.     OUT    (C),A
  250.     LD    A,BREAK        ; F8h
  251.     OUT    (C),A
  252.     LD    HL,300        ; A 300 mS break
  253.     CALL    WAITHLMS
  254.     LD    A,5
  255.     OUT    (C),A
  256.     LD    A,ONLINE    ; 68h
  257.     OUT    (C),A
  258.     LD    A,3
  259.     OUT    (C),A
  260.     LD    A,0E1H        ; E1h
  261.     OUT    (C),A
  262.     POP    BC
  263. ;
  264. ; <== End of your own code
  265. ;
  266.     RET
  267. ;
  268. ; Test UART flags for error: return YES (1) in HL if error.
  269. ;
  270. MDMERR:    DS    0
  271. ;
  272. ; <== Insert your own code here
  273. ;
  274.     PUSH    BC
  275.     LD    BC,MSTAT
  276.     LD    HL,0
  277.     IN    A,(C)
  278.     AND    A,ERROR
  279.     JR    Z,MDMER2
  280.     INC    HL
  281. ;
  282. MDMER2:    DS    0
  283. ;
  284. ; <== End of your own code
  285. ;
  286.     POP    BC
  287.     LD    A,L        ; Set/clear Z
  288.     OR    A
  289.     RET
  290. ;
  291. ; Turn DTR ON
  292. ;
  293. DTRON:    DS    0
  294. ;
  295. ; <== Insert your own code here
  296. ;
  297.     PUSH    BC
  298.     LD    BC,MSTAT
  299.     LD    A,5
  300.     OUT    (C),A
  301.     LD    A,(COMBYT)    ; Get the one we used last time
  302.     OR    A,ONLINE    ; 80h - set bit 7 high
  303.     LD    (COMBYT),A    ; Save it for next time
  304.     OUT    (C),A        ; Go
  305.     POP    BC        ;
  306. ;
  307. ; <== End of your own code
  308. ;
  309.     RET
  310. ;
  311. ; Turn DTR OFF
  312. ;
  313. DTROFF:    DS    0
  314. ;
  315. ; <== Insert your own code here
  316. ;
  317.     PUSH    BC
  318.     LD    BC,MSTAT
  319.     LD    A,5
  320.     OUT    (C),A
  321.     LD    A,(COMBYT)    ; Get the one we used last time
  322.     AND    ONHOOK        ; 7Fh - clear bit 7
  323.     LD    (COMBYT),A    ; Save it for next time
  324.     OUT    (C),A        ; Go
  325.     POP    BC
  326. ;
  327. ; <== End of your own code
  328. ;
  329.     RET
  330. ;
  331. ; Initialise the SIO +++
  332. ; The SIO is set up in four steps:
  333. ;
  334. ;    1)  Reset
  335. ;    2)  Reg 4 - clock, stop bits, parity
  336. ;    3)  Reg 5 - dtr, Tx bits, Brk, TxEn, rts
  337. ;    4)  Reg 3 - Rx bits, RxEn
  338. ;
  339. INIT:    LD    HL,2        ; Get parameters
  340.     ADD    HL,SP
  341.     EX    DE,HL
  342.     CALL    GETPARM        ; In HL
  343.     LD    (BRATE),HL    ; Baud rat
  344.     CALL    GETPARM
  345.     LD    (PARITY),HL    ; Parity
  346.     CALL    GETPARM
  347.     LD    (DATA),HL    ; Data bits
  348.     CALL    GETPARM
  349.     LD    (STOP),HL    ; Stop bits
  350. ;
  351. ; <== Insert your own code here, using values below
  352. ;
  353.     PUSH    BC
  354.     LD    BC,MSTAT
  355.     LD    A,0
  356.     OUT    (C),A        ; Point to reg 0
  357.     LD    A,18H        ; Reset
  358.     OUT    (C),A        ; *** step 1
  359.     LD    A,4        ; Point to wrt reg 4
  360.     OUT    (C),A
  361.     LD    E,44H        ; Assume  x16, 1 stop, No parity
  362.     LD    A,(STOP)    ; Set stop bits
  363.     CP    2        ; Set 2 if required
  364.     JR    NZ,SETPAR
  365.     LD    A,08H        ; 0000 1000
  366.     OR    E
  367.     LD    E,A
  368. ;
  369. SETPAR:    LD    A,(PARITY)    ; Set parity bits
  370.     CP    'O'
  371.     JR    NZ,SETPA2
  372.     LD    D,01H        ; 0000 0001    ODD
  373.     JR    SETPA3
  374. ;
  375. SETPA2:    CP    'E'
  376.     JR    NZ,SETPA4
  377.     LD    D,03H        ; 0000 0011    EVEN
  378. ;
  379. SETPA3:    LD    A,E
  380.     OR    A,D
  381.     LD    E,A
  382. ;
  383. SETPA4:    LD    A,E
  384.     OUT    (C),A        ; *** step 2
  385.     LD    A,5        ; Point to wrt reg 5 - dtr, Tx bits, etc
  386.     OUT    (C),A
  387.     LD    E,0EAH        ; Assume dtr, TX 8 bits, TxEn, rts
  388.     LD    A,(DATA)
  389.     CP    7
  390.     JR    NZ,SETBI2
  391.     LD    D,0BFH        ; 1011 1111    7 bits
  392.     LD    A,E
  393.     AND    A,D
  394.     LD    E,A
  395. ;
  396. SETBI2:    LD    A,E
  397.     OUT    (C),A        ; *** step3
  398.     LD    A,3        ; Point to wrt reg 3
  399.     OUT    (C),A
  400.     LD    E,0C1H        ; Assume 8 bits
  401.     LD    A,(DATA)
  402.     CP    7
  403.     JR    NZ,SETBI3
  404.     LD    D,07FH        ; 0111 1111    7 bits
  405.     LD    A,E
  406.     AND    A,D
  407.     LD    E,A
  408. ;
  409. SETBI3:    LD    A,E
  410.     OUT    (C),A        ; *** step 4
  411. ;
  412. SETBRATE:
  413.     PUSH    IX        ; Save IX
  414.     LD    DE,(BRATE)    ; Get baud rate value (0-10)
  415.     LD    IX,BRVAL
  416.     ADD    IX,DE
  417.     ADD    IX,DE        ; IX now points to the 2-byte value
  418.     LD    A,(IX)        ; If zero,
  419.     OR    (IX+1)
  420.     JR    Z,SETBRX    ; It's not valid
  421.     LD    BC,CTCONT
  422.     LD    A,36H
  423.     OUT    (C),A
  424.     LD    BC,CTC0
  425.     LD    A,(IX)
  426.     OUT    (C),A        ; Low byte
  427.     LD    A,(IX+1)
  428.     OUT    (C),A        ; High byte
  429.     LD    BC,CTCONT
  430.     LD    A,76H
  431.     OUT    (C),A
  432.     LD    BC,CTC1
  433.     LD    A,(IX)
  434.     OUT    (C),A        ; Low byte
  435.     LD    A,(IX+1)
  436.     OUT    (C),A        ; High byte
  437.     LD    A,(BRATE)    ; Tell ZMP it's valid
  438.     LD    (MSPEED),A
  439. ;
  440. SETBRX:    POP    IX
  441.     POP    BC
  442. ;
  443. ; <== End of your own code
  444. ;
  445.     RET
  446. ;
  447. BRATE:    DW    5        ; Baud rate
  448. PARITY:    DW    'N'        ; Parity
  449. DATA:    DW    8        ; Data bits
  450. STOP:    DW    1        ; Stop bits
  451. COMBYT:    DB    0EAH        ; Save here
  452. ;
  453. ; Values for 8253 control reg for each baud rate: 0 if invalid
  454. ;
  455. BRVAL:    DW    470H        ; 110         0
  456.     DW    1A1H        ; 300         1
  457.     DW    116H        ; 450         2
  458.     DW    0D0H        ; 600         3
  459.     DW    0B0H        ; 710         4
  460.     DW    068H        ; 1200         5
  461.     DW    034H        ; 2400         6
  462.     DW    01AH        ; 4800         7
  463.     DW    00DH        ; 9600         8
  464.     DW    007H        ; 19200      9
  465.     DW    0        ; 38400     10
  466.     DW    0        ; 57600     11
  467.     DW    0        ; 76800     12
  468.     DW    0        ; 115200    13
  469. ;
  470. ; Set the port. ZMP supplies either 0 or 1 as a parameter.
  471. ;
  472. setport:
  473.     ld    hl,2        ; get port number
  474.     add    hl,sp
  475.     ex    de,hl
  476.     call    getparm        ; in HL (values are 0 and 1)
  477.  
  478.                 ; <== Insert your own code here
  479.  
  480.                 ; <== End of your own code
  481.     ret
  482. ;
  483. ;-----------------------------------------------------------------------
  484. ;
  485. ; Video terminal sequences: these are for Zenith Z19/Z29: Modify as you
  486. ; wish.
  487. ;
  488. ; Cursor addressing
  489. ;
  490. CURSADD:LD    HL,2        ; Get parameters
  491.     ADD    HL,SP
  492.     EX    DE,HL
  493.     CALL    GETPARM        ; In HL
  494.     LD    (ROW),HL    ; Row
  495.     CALL    GETPARM
  496.     LD    (COL),HL    ; Column
  497. ;
  498. ; <== Insert your own code here, using values in row and column
  499. ;
  500.     CALL    PRINT
  501.     DB    ESC,'Y',0    ; Leadin
  502.     LD    A,(ROW)        ; Row first
  503.     ADD    A,' '        ; Add offset
  504.     CALL    COUT
  505.     LD    A,(COL)        ; Sane for column
  506.     ADD    A,' '
  507.     CALL    COUT
  508. ;
  509. ; <== End of your own code
  510. ;
  511.     RET
  512. ;
  513. ROW:    DS    2        ; Row
  514. COL:    DS    2        ; Column
  515. ;
  516. ; Clear screen
  517. ;
  518. CLS:    CALL    PRINT
  519.     DB    ESC,'E',ESC,'H',0
  520.     RET
  521. ;
  522. ; Inverse video on
  523. ;
  524. INVON:    CALL    PRINT
  525.     DB    ESC,'p',0
  526.     RET
  527. ;
  528. ; Inverse video off
  529. ;
  530. INVOFF:    CALL    PRINT
  531.     DB    ESC,'q',0
  532.     RET
  533. ;
  534. ; Turn off cursor
  535. ;
  536. HIDE:    CALL    PRINT
  537.     DB    ESC,'f',0
  538.     RET
  539. ;
  540. ; Turn on cursor
  541. ;
  542. SHOW:    CALL    PRINT
  543.     DB    ESC,'e',0
  544.     RET
  545. ;
  546. ; Save cursor position
  547. ;
  548. SAVECU:    CALL    PRINT
  549.     DB    ESC,'j',0
  550.     RET
  551. ;
  552. ; Restore cursor position
  553. ;
  554. RESCU:    CALL    PRINT
  555.     DB    ESC,'k',0
  556.     RET
  557. ;
  558. ;-----------------------------------------------------------------------
  559. ;
  560. ; Service modem interrupt
  561. ;
  562. MINT:    RET
  563. ;
  564. ; Initialise interrupt vectors
  565. ;
  566. INVEC:    RET
  567. ;
  568. ; De-initialise interrupt vectors
  569. ;
  570. DINVEC:    RET
  571. ;
  572. ; User-defined entry routine: leave empty if not used
  573. ;
  574. USERIN:    RET
  575. ;
  576. ; User-defined exit routine: leave empty if not used
  577. ;
  578. USEROUT:RET
  579. ;
  580. ;------------------- End of user-defined code --------------------------
  581. ;         Do not change anything below here
  582. ;
  583. ; Modem character test for 100 ms
  584. ;
  585. MRD:    PUSH    BC        ; Save BC
  586.     LD    BC,100        ; Set limit
  587. ;
  588. MRD1:    CALL    MIRDY        ; Char at modem?
  589.     JR    NZ,MRD2        ; Yes, exit
  590.     LD    HL,1        ; Else wait 1 ms
  591.     CALL    WAITHLMS
  592.     DEC    BC        ; Loop till done
  593.     LD    A,B
  594.     OR    C
  595.     JR    NZ,MRD1
  596.     LD    HL,0        ; None there, result=0
  597.     XOR    A
  598. ;
  599. MRD2:    POP    BC
  600.     RET
  601. ;
  602. ; Inline print routine: destroys A and HL
  603. ;
  604. PRINT:    EX    (SP),HL        ; Get address of string
  605. ;
  606. PLOOP:    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. ;
  613. PDONE:    EX    (SP),HL        ; Restore return address
  614.     RET            ; And quit
  615. ;
  616. ; Output a character in A to the console
  617. ;
  618. COUT:    PUSH    BC        ; Save registers
  619.     PUSH    DE
  620.     PUSH    HL
  621.     LD    E,A        ; Character to E
  622.     LD    C,2
  623.     CALL    BDOS        ; Print it
  624.     POP    HL
  625.     POP    DE
  626.     POP    BC
  627.     RET
  628. ;
  629. ; Wait(seconds)
  630. ;
  631. WAIT:    LD    HL,2
  632.     ADD    HL,SP
  633.     EX    DE,HL        ; Get delay size
  634.     CALL    GETPARM
  635. ;                ; Fall thru to...
  636. ; Wait seconds in HL
  637. ;
  638. WAITHLS:PUSH    BC        ; Save BC
  639.     PUSH    DE        ; DE
  640.     PUSH    IX        ; And IX
  641.     LD    IX,0        ; Then point IX to 0
  642. ;                ;   so we don't upset memory-mapped I/O
  643. ;
  644. ; Calculate values for loop constants. Need to have two loops to avoid
  645. ; 16-bit overflow with clock speeds above 9 MHz.
  646. ;
  647. OUTERVAL EQU    (CLKSPD    / 10) +    1
  648. ;
  649. INNERVAL EQU    (6667 /    OUTERVAL) * CLKSPD
  650. ;
  651. WAIT10:    LD    B,OUTERVAL
  652. ;
  653. WAIT11:    LD    DE,INNERVAL
  654. ;
  655. WAIT12:    BIT    0,(IX)        ; Time-wasters
  656.     BIT    0,(IX)
  657.     BIT    0,(IX)        ; 20 T-states each
  658.     BIT    0,(IX)
  659.     BIT    0,(IX)
  660.     BIT    0,(IX)
  661.     DEC    DE
  662.     LD    A,E
  663.     LD    A,D
  664.     OR    E
  665.     JR    NZ,WAIT12    ; 150 T-states per inner loop
  666.     DJNZ    WAIT11        ; Decrement outer loop
  667.     DEC    HL        ; Ok, decrement count in HL
  668.     LD    A,H
  669.     OR    L
  670.     JR    NZ,WAIT10
  671.     POP    IX        ; Done -- restore IX
  672.     POP    DE        ; DE
  673.     POP    BC        ; And BC
  674.     RET
  675. ;
  676. ; Wait milliseconds
  677. ;
  678. MSWAIT:    LD    HL,2
  679.     ADD    HL,SP
  680.     EX    DE,HL        ; Get delay size
  681.     CALL    GETPARM
  682. ;
  683. ; Wait milliseconds in HL
  684. ;
  685. WAITHLMS:
  686.     PUSH    DE
  687. ;
  688. W1MS0:    LD    DE,39 *    CLKSPD
  689. ;
  690. W1MS1:    DEC    DE
  691.     LD    A,D
  692.     OR    E
  693.     JR    NZ,W1MS1
  694.     DEC    HL
  695.     LD    A,H
  696.     OR    L
  697.     JR    NZ,W1MS0
  698.     POP    DE
  699.     RET
  700. ;
  701. ; Get next parameter from (DE) into HL
  702. ;
  703. GETPARM:EX    DE,HL        ; Get address into HL
  704.     LD    E,(HL)        ; Get low
  705.     INC    HL
  706.     LD    D,(HL)        ; Then hihi
  707.     INC    HL        ; Bump for next
  708.     EX    DE,HL        ; Result in HL, address still in DE
  709.     RET
  710. ;
  711. ;Get address of user-defined variables
  712. ;
  713. GETVARS:
  714.     LD    HL,USERVARS
  715.     RET
  716. USERVARS:
  717.     DW    OVERDRIVE    ; .OVR etc. drive/user
  718.     DW    OVERUSER
  719. ;
  720.      IF    ($ - CODEBGN) GT OVSIZE
  721. TOOBIG:    JP    ERRVAL        ; Overlay is too large
  722.      ENDIF
  723. ;
  724.     END
  725.