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 / ZMOBEE.MAC < prev    next >
Text File  |  1991-02-02  |  16KB  |  932 lines

  1. ;-----------------------------------------------------------------------------
  2. ;
  3. ;
  4. ;    Overlay for ZMP (Z-Modem Program)
  5. ;
  6. ;    Name    ZMO-MB01.Z80
  7. ;
  8. ;    Dated Aug 23, 1988
  9. ;
  10. ;    Written by -
  11. ;      Ron Murray, c/o Z-Node 62, 061-9-450-0200, Perth, Western Australia.
  12. ;      Modified for the BBII by Lindsay Allen, sysop, Z-Node 62.
  13. ;
  14. ;
  15. ;    Rename subsequent versions as ZMO-MB02.Z80 etc
  16. ;
  17. ;
  18. ;    This overlay is set up for a Microbee 128k with a Z8530 SCC.
  19. ;
  20. ;
  21. ;
  22. ;-----------------------------------------------------------------------------
  23. ;
  24. ;
  25. ;    System-dependent code overlay for ZMODEM
  26. ;
  27. ;
  28. ;
  29. ;    Insert your own code as necessary in this file. Code contained herein
  30. ; has been written in Z80 code for use with M80 or SLR. Assemble as follows:
  31. ;
  32. ;    SLR ZMO-MB01/h
  33. ;    MLOAD ZMP.COM=ZMODEM.COM,ZMO-MB01.HEX
  34. ; or
  35. ;    M80 =ZMO-MB01.Z80
  36. ;    RELHEX ZMO-MB01
  37. ;    MLOAD ZMP.COM=ZMODEM.COM,ZMO-MB01.HEX
  38. ;
  39. ;
  40. ;       (Don't use L80 without changing the source for assembly as a
  41. ;         cseg file.)
  42. ;
  43. ;-----------------------------------------------------------------------------
  44. ;
  45. ;
  46. ; Notes on modifying this file:
  47. ;
  48. ;    C requires that functions do not change either index register
  49. ; (IX or IY), nor the BC register pair. If your overlay requires any of
  50. ; these to be changed, ensure they are restored to the original values
  51. ; on return.
  52. ;    Since collecting parameters from C functions can be tricky, only change
  53. ; the parts marked 'Insert your own code here'. Do NOT modify the jump
  54. ; table at the start. Do NOT modify the entry/exit sections of each
  55. ; function. Do NOT pass 'GO'. Do NOT collect $200.
  56. ;    Apart from defining modem functions, this file also defines terminal
  57. ; characteristics. Most have been set up for ADM-3A (with a few of my own
  58. ; additions). Modify to suit your own terminal. An inline print routine
  59. ; is provided for printing strings in the usual way: usage is
  60. ;
  61. ;    call    print
  62. ;    db    'required string',0
  63. ;
  64. ;-----------------------------------------------------------------------------
  65. ;
  66. ;
  67. ;    Don't forget to set your clock speed at the clkspd variable.
  68. ;
  69. ;
  70. ;    If you find your overlay exceeds the maximum size (currently 0400h),
  71. ; you will have to contact me for another version. If too many people need 
  72. ; to do it, we haven't allowed enough room.
  73. ;
  74. ; Ron Murray 15/8/88
  75. ;
  76. ;
  77. ;
  78. ;
  79. ;
  80. ;
  81. ;
  82. ;
  83. ;
  84. ;
  85. ;-----------------------------------------------------------------------------
  86. ;
  87. ; This overlay has been written by Cameron Hutchison to work on a microbee
  88. ; with a Z8530 SCC installed. I have no plans in writing one for the standard
  89. ; serial port. There is a version of ZMP which has been modified to run on
  90. ; a 56k machine using the standard serial port. If you are interested then
  91. ; contact me.
  92. ;
  93. ; I am in sort of direct contact with Ron Murray (the author of ZMP) so if you
  94. ; have any suggestions for any improvements or know of any bugs then let me
  95. ; know and I will pass it on.
  96. ;
  97. ; Some of the code and ideas for this overlay has been taken from Tony Ellis's
  98. ; BYE510 insert. My thanks go to him.
  99. ;
  100. ; Cameron Hutchison
  101. ;
  102. ; I can be contacted on SMUG opus on (02) 476-6396 or via
  103. ; netmail at 711/417. I also sometimes usually attend most smug meetings
  104. ; (sort of).
  105. ;
  106. ;-----------------------------------------------------------------------------
  107.     .z80
  108.     aseg
  109.  
  110.  
  111.  
  112. false    equ    0
  113. true    equ    not false
  114.  
  115.  
  116. ; User-set variables: ***********
  117.  
  118. clkspd    equ    4        ; Processor clock speed in MHz
  119.  
  120. debug    equ    false
  121.  
  122. overdrive    equ    'A'
  123. overuser    equ    5
  124.  
  125. userdef    equ    0145h        ; origin of this overlay
  126.                 ; This address may change with subsequent
  127.                 ;  revisions.
  128.  
  129. ovsize    equ    0400h        ; max size of this overlay
  130.  
  131.  
  132.      if    debug
  133.     org    100h        ; so you can debug it with cebug, zsid, etc
  134.      else
  135.     org    userdef
  136.      endif
  137.  
  138.  
  139. esc    equ    1bh
  140. ctrlq    equ    11h
  141. cr    equ    0dh
  142. lf    equ    0ah
  143. bdos    equ    5
  144.  
  145.  
  146. ; Microbee specific equates  ******************************************
  147.  
  148. mdata    equ    06bh
  149. mstata    equ    069h
  150. mstatb    equ    068h
  151. mdrcv    equ    1
  152. mdsnd    equ    4
  153. onhook    equ    07Fh
  154. online    equ    080h
  155. error    equ    070h
  156. break    equ    0FAh
  157. reset    equ    030h
  158. ;            ******************************************
  159.  
  160.  
  161. ;Jump table for the overlay: do NOT change this
  162. jump_tab:
  163.     jp    scrnpr        ; screen print
  164.     jp    mrd        ; modem read with timeout
  165.     jp    mchin        ; get a character from modem
  166.     jp    mchout        ; send a character to the modem
  167.     jp    mordy        ; test for tx buffer empty
  168.     jp    mirdy        ; test for character received
  169.     jp    sndbrk        ; send break
  170.     jp    cursadd        ; cursor addressing
  171.     jp    cls        ; clear screen
  172.     jp    invon        ; inverse video on
  173.     jp    invoff        ; inverse video off
  174.     jp    hide        ; hide cursor
  175.     jp    show        ; show cursor
  176.     jp    savecu        ; save cursor position
  177.     jp    rescu        ; restore cursor position
  178.     jp    mint        ; service modem interrupt
  179.     jp    invec        ; initialise interrupt vectors
  180.     jp    dinvec        ; de-initialise interrupt vectors
  181.     jp    mdmerr        ; test uart flags for error
  182.     jp    dtron        ; turn DTR on
  183.     jp    dtroff        ; turn DTR OFF
  184.     jp    init        ; initialise uart
  185.     jp    wait        ; wait seconds
  186.     jp    mswait        ; wait milliseconds
  187.     jp    userin        ; Initialize routine
  188.     jp    userout        ; De-initialize routine
  189.     jp    getvars
  190.     jp    setport        ; set the serial port
  191.  
  192.     jp    spare        ; Spare for future modifications
  193.     jp    spare        ; Spare for future modifications
  194.     jp    spare        ; Spare for future modifications
  195.     jp    spare        ; Spare for future modifications
  196.     jp    spare        ; Spare for future modifications
  197.     jp    spare        ; Spare for future modifications
  198.  
  199. ;
  200. ; Main code starts here
  201. ;
  202. codebgn    equ    $
  203. ;
  204. ; Screen print function
  205. scrnpr:
  206.     call    print
  207.     db    'This function not supported.',cr,lf,0
  208.     ret
  209.  
  210. ; user initialization routine
  211. userin:
  212.     ret
  213.  
  214. ; User de-initialization routine
  215. userout:
  216.     ret
  217.  
  218. ; For spare jump vectors
  219. spare:
  220.     ret
  221.  
  222. ;Get a character from the modem: return in HL
  223. mchin:
  224.     push    bc
  225. mchin2:
  226.     ld    a,(port)
  227.     ld    c,a
  228.  
  229.     ld    a,reset
  230.     out    (c),a
  231.     in    a,(c)        ; check for char waiting
  232.     and    mdrcv
  233.     jr    z,mchin2
  234.  
  235.     ld    a,(port+1)
  236.     ld    c,a
  237.  
  238.     in    a,(c)        ; read the char
  239.     ld    l,a        ; put in HL
  240.     ld    h,0
  241.     or    a        ; set/clear Z
  242.     pop    bc
  243.     ret
  244.  
  245. ;Send a character to the modem
  246. mchout:
  247.     ld    hl,2        ; get the character
  248.     add    hl,sp
  249.     ld    a,(hl)
  250.  
  251.     push    bc
  252.     ld    b,a        ; save the char
  253.     ld    a,(port)
  254.     ld    c,a
  255.  
  256. mchout2:
  257.     in    a,(c)        ; check for uart ready
  258.     and    mdsnd
  259.     jr    z,mchout2
  260.  
  261.     ld    a,(port+1)
  262.     ld    c,a
  263.  
  264.     ld    a,b        ; char in a
  265.     out    (c),a        ; send it
  266.     pop    bc
  267.  
  268.     ret            ; done
  269.  
  270. ;Test for output ready: return TRUE (1) in HL if ok
  271. mordy:
  272.     push    bc
  273.  
  274.     ld    a,(port)
  275.     ld    c,a
  276.  
  277.     ld    hl,0
  278.     in    a,(c)
  279.     and    mdsnd
  280.     jr    z,mordy1
  281.     inc    hl
  282. mordy1:
  283.     ld    a,l        ; set/clear Z
  284.     or    a
  285.     pop    bc
  286.     ret
  287.  
  288. ;Test for character at modem: return TRUE (1) in HL if so
  289. mirdy:
  290.     push    bc
  291.     ld    a,(port)
  292.     ld    c,a
  293.  
  294.     ld    hl,0
  295.     in    a,(c)
  296.     and    mdrcv
  297.     jr    z,mirdy1
  298.     inc    hl
  299. mirdy1:
  300.     ld    a,l        ; set/clear Z
  301.     or    a
  302.     pop    bc
  303.     ret
  304.  
  305. ;Send a break to the modem: leave empty if your system can't do it
  306. sndbrk:
  307.     push    bc
  308.     ld    a,(port)
  309.     ld    c,a
  310.  
  311.     ld    a,5
  312.     out    (c),a
  313.     ld    a,break        ; FA
  314.     out    (c),a
  315.  
  316.     ld    hl,300        ; 300 msecs
  317.     call    waithls
  318.  
  319.     ld    a,5
  320.     out    (c),a
  321.     ld    a,0eah
  322.     out    (c),a
  323.  
  324.     pop    bc
  325.     ret
  326. ;
  327. ;Test UART flags for error: return TRUE (1) in HL if error.
  328. mdmerr:
  329.     push    bc
  330.     ld    a,(port)
  331.     ld    c,a
  332.  
  333.     ld    hl,0
  334.     in    a,(c)
  335.     and    error
  336.     jr    z,mdmer2
  337.     inc    hl
  338. mdmer2:
  339.     ld    a,l        ; set/clear Z
  340.     or    a
  341.     pop    bc
  342.     ret
  343.  
  344.  
  345. ;Turn DTR ON
  346. dtron:
  347.     push    bc
  348.     ld    a,(port)
  349.     ld    c,a
  350.  
  351.     ld    a,5
  352.     out    (c),a
  353.     ld    a,0eah        ; DTR and RTS on
  354.     out    (c),a
  355.  
  356.     pop    bc
  357.     ret
  358.  
  359. ;Turn DTR OFF
  360. dtroff:
  361.     push    bc
  362.     ld    a,(port)
  363.     ld    c,a
  364.  
  365.     ld    a,5
  366.     out    (c),a
  367.     ld    a,068h        ; DTR and RTS off
  368.     out    (c),a
  369.  
  370.     pop    bc
  371.     ret
  372.  
  373.  
  374. ;Initialise the SCC +++
  375. ; The SCC is set up in four steps:
  376. ;     1)  Reset
  377. ;       2)  Reg 4 - clock, stop bits, parity
  378. ;    3)  Reg 5 - dtr, Tx bits, Brk, TxEn, rts
  379. ;    4)  Reg 3 - Rx bits, RxEn
  380. ; leave the bit before the ******
  381. init:
  382. ;    call    dtron
  383. ;    ret
  384.  
  385.     ld    hl,2        ; get parameters
  386.     add    hl,sp
  387.     ex    de,hl
  388.     call    getparm        ; in HL
  389.     ld    (brate),hl    ; baud rate
  390.     ld    a,l
  391.     ld    (003Ch),a    ; save the baud rate in 3C for later as per IMP
  392.     call    getparm
  393.     ld    (parity),hl    ; parity
  394.     call    getparm
  395.     ld    (databits),hl    ; data bits
  396.     call    getparm
  397.     ld    (stop),hl    ; stop bits
  398. ; ******
  399.  
  400.     push    bc
  401.  
  402.     ld    c,mstatb
  403.     ld    b,6        ; table1end-table1
  404.     ld    hl,table1
  405.     otir
  406.     ld    a,(port)
  407.     cp    068h
  408.     jr    nz,xt1pa
  409.     ld    hl,tab1b
  410.     ld    b,4
  411.     otir
  412.     jr    drob
  413. xt1pa:
  414.     ld    hl,tab1a
  415.     ld    b,4
  416.     otir
  417. drob:
  418.     ld    b,14
  419.     ld    hl,table1+6
  420.     otir
  421. dtpa:
  422.     ld    c,mstata
  423.     ld    b,4        ; table2end-table2
  424.     ld    hl,table2
  425.     otir
  426.     ld    a,(port)
  427.     cp    068h
  428.     jr    nz,xt2pa
  429.     ld    hl,tab2b
  430.     ld    b,4
  431.     otir
  432.     jr    droa
  433. xt2pa:    
  434.     ld    hl,tab2a
  435.     ld    b,4
  436.     otir
  437. droa:
  438.     ld    hl,table2+4
  439.     ld    b,14
  440.     otir
  441.  
  442. susp:
  443.     ld    a,(port)
  444.     ld    c,a
  445.  
  446.     ld    a,4        ; point to wrt reg 4
  447.     out    (c),a
  448.     ld    e,44h        ; assume  x16, 1 stop, No parity
  449.     ld    a,(stop)    ; set stop bits
  450.     cp    2        ; set 2 if required
  451.     jr    nz,setpar
  452.     set    3,e
  453.  
  454. setpar:
  455.     ld    a,(parity)    ; set parity bits
  456.     cp    'O'
  457.     jr    nz,setpa2
  458.     set    0,e        ; ODD
  459.     jr    setpa3
  460.  
  461. setpa2:    cp    'E'
  462.     jr    nz,setpa3
  463.     set    0,e
  464.     set    1,e        ; EVEN
  465.  
  466. setpa3:    ld    a,e
  467.     out    (c),a        ;                *** step 2
  468.  
  469.     ld    a,5        ; point to wrt reg 5 - dtr, Tx bits, etc
  470.     out    (c),a
  471.     ld    e,0EAh        ; assume dtr, TX 8 bits, TxEn, rts
  472.     ld    a,(databits)
  473.     cp    7
  474.     jr    nz,setbi2
  475.     res    6,e        ; 7 bits
  476.  
  477. setbi2:    ld    a,e
  478.     out    (c),a        ;                *** step 3
  479.  
  480.     ld    a,3        ; point to wrt reg 3
  481.     out    (c),a
  482.     ld    e,0C1h        ; assume 8 bits
  483.     ld    a,(databits)
  484.     cp    7
  485.     jr    nz,setbi3
  486.     res    7,e        ; 7 bits
  487.  
  488. setbi3:    ld    a,e
  489.     out    (c),a        ;                *** step 4
  490.  
  491.  
  492. setbrate:
  493.     ld    de,(brate)    ; get baud rate value (0-10)
  494.     dec    e
  495.     jr    z,set300
  496.     dec    e    
  497.     dec    e
  498.     dec    e
  499.     dec    e
  500.     jr    z,set1200
  501.     dec    e
  502.     jr    z,set2400
  503.     dec    e
  504.     jr    z,set4800
  505.     dec    e
  506.     jr    z,set9600
  507.  
  508. ; Falls through to SET2400 if invalid value (i.e. not supported one)
  509. set2400:
  510.     push    bc
  511.     push    de
  512.     ld    de,002eh
  513.     ld    bc,028h
  514.     jr    setbaud
  515. set300:
  516.     push    bc
  517.     push    de
  518.     ld    de,017eh
  519.     ld    bc,028h
  520.     jr    setbaud
  521. set1200:
  522.     push    bc
  523.     push    de
  524.     ld    de,005eh
  525.     ld    bc,028h
  526.     jr    setbaud
  527. set4800:
  528.     push    bc
  529.     push    de
  530.     ld    de,0016h
  531.     ld    bc,028h
  532.     jr    setbaud
  533. set9600:
  534.     push    bc
  535.     push    de
  536.     ld    de,000ah
  537.     ld    bc,028h
  538.  
  539. setbaud:
  540.     ld    a,0bh
  541.     out    (mstata),a
  542.     ld    a,c
  543.     out    (mstata),a
  544.     ld    a,0dh
  545.     out    (mstatb),a
  546.     ld    a,d
  547.     out    (mstatb),a
  548.     ld    a,0ch
  549.     out    (mstatb),a
  550.     ld    a,e
  551.     out    (mstatb),a
  552.     pop    de
  553.     pop    bc
  554.  
  555.     ld    a,(port)
  556.     ld    c,a
  557.     ld    a,05h
  558.     out    (c),a
  559.     ld    a,0eah
  560.     out    (c),a
  561.  
  562.     call    dtron
  563.     pop    bc
  564.     ret
  565.  
  566. ;
  567. ; Set the port. ZMP supplies either 0 or 1 as a parameter. You're on your
  568. ; own here -- your system is bound to be different from any other! You may
  569. ; implement a software switch on all the modem-dependent routines, or perhaps
  570. ; you can have one or two centralised routines for accessing the UARTs and
  571. ; modify the code from this routine to select one or the other. (Who said
  572. ; there was anything wrong with self-modifying code?). If you have only one
  573. ; UART port, or if you don't want to go through all the hassles, just have
  574. ; this routine returning with no changes made. Note that ZMP calls this
  575. ; routine with both values for the port on initialisation.
  576. ;
  577. setport:
  578.     ld    hl,2        ; get port number
  579.     add    hl,sp
  580.     ex    de,hl
  581.     call    getparm        ; in HL (values are 0 and 1)
  582.  
  583.     ld    a,h        ; 0 - port a
  584.     or    l        ; 1 - port b
  585.     jr    nz,spb
  586.     ld    a,69h
  587.     ld    (port),a
  588.     ld    a,6bh
  589.     ld    (port+1),a
  590.     ret
  591. spb:
  592.     ld    a,68h
  593.     ld    (port),a
  594.     ld    a,6ah
  595.     ld    (port+1),a
  596.     ret
  597.  
  598. brate:
  599.     dw    6        ; baud rate:
  600. parity:
  601.     dw    'N'        ; parity
  602. databits:
  603.     dw    8        ; data bits
  604. stop:
  605.     dw    1        ; stop bits
  606. port:
  607.     db    069h        ; This is the port used. It can be changed
  608.                 ; from the program
  609.     db    06bh        ; This is the data port used. Make sure it
  610.                 ; corresponds with the control port or
  611.                 ; anything could happen.
  612.  
  613. table1:
  614.     db    09h
  615.     db    0c0h
  616.  
  617.     db    04h
  618.     db    044h
  619.  
  620.     db    01h
  621.     db    00h
  622.  
  623.     db    09h
  624.     db    00h
  625.  
  626.     db    0bh
  627.     db    0d6h
  628.  
  629.     db    0eh
  630.     db    061h
  631.  
  632.     db    0fh
  633.     db    00h
  634.  
  635.     db    0ch
  636.     db    02eh and 0ffh
  637.  
  638.     db    0dh
  639.     db    02eh shr 8
  640.  
  641.     db    00h
  642.     db    030h
  643. table1end:
  644.  
  645. tab1a:
  646.     db    03h
  647.     db    0c0h
  648.  
  649.     db    05h
  650.     db    060h
  651. tab1b:
  652.     db    03h
  653.     db    0c1h
  654.  
  655.     db    05h
  656.     db    068h
  657.  
  658. table2:
  659.     db    04h
  660.     db    044h
  661.  
  662.     db    01h
  663.     db    00h
  664.  
  665.     db    0bh
  666.     db    028h
  667.  
  668.     db    0eh
  669.     db    061h
  670.  
  671.     db    0fh
  672.     db    00h
  673.  
  674.     db    0ch
  675.     db    06h
  676.  
  677.     db    0dh
  678.     db    00h
  679.  
  680.     db    00h
  681.     db    038h
  682.  
  683.     db    00h
  684.     db    030h
  685. table2end:
  686. tab2a:
  687.     db    03h
  688.     db    0c1h
  689.  
  690.     db    05h
  691.     db    068h
  692. tab2b:
  693.     db    03h
  694.     db    0c0h
  695.  
  696.     db    05h
  697.     db    060h
  698.  
  699.  
  700. ;****************************************************************************
  701. ;Video terminal sequences: these are for ADM-3A: Modify as you wish
  702. ;Cursor addressing: 
  703. cursadd:
  704.     ld    hl,2        ; get parameters
  705.     add    hl,sp
  706.     ex    de,hl
  707.     call    getparm        ; in HL
  708.     ld    (row),hl    ; row
  709.     call    getparm
  710.     ld    (col),hl    ; column
  711.  
  712.     call    print
  713.     db    esc,'=',0    ; ADM-3A leadin
  714.     ld    a,(row)        ; row first
  715.     add    a,' '        ; add offset
  716.     call    cout
  717.     ld    a,(col)        ; sane for column
  718.     add    a,' '
  719.     call    cout
  720.  
  721.     ret
  722.  
  723. row:    ds    2        ; row
  724. col:    ds    2        ; column
  725.  
  726.  
  727. ;Clear screen:
  728. cls:
  729.     call    print
  730.     db    1ah,0
  731.     ret
  732.  
  733. ;Inverse video on:
  734. invon:
  735.     call    print
  736.     db    esc,')',0
  737.     ret
  738.  
  739. ;Inverse video off:
  740. invoff:
  741.     call    print
  742.     db    esc,'(',0
  743.     ret
  744.  
  745. ;Turn off cursor:
  746. hide:
  747.     call    print
  748.     db    esc,'}',0
  749.     ret
  750.  
  751. ;Turn on cursor:
  752. show:
  753.     call    print
  754.     db    esc,'{',0
  755.     ret
  756.  
  757. ;Save cursor position:
  758. savecu:
  759.     call    print
  760.     db    esc,'[s',0
  761.     ret
  762.  
  763. ;Restore cursor position:
  764. rescu:
  765.     call    print
  766.     db    esc,'[u',0
  767.     ret
  768.  
  769. ;****************************************************************************
  770.  
  771. ;Service modem interrupt:
  772. mint:
  773.     ret            ; my system doesn't need this
  774.  
  775. ;Initialise interrupt vectors:
  776. invec:
  777.     ret            ; ditto
  778.  
  779. ;De-initialise interrupt vectors:
  780. dinvec:
  781.     ret            ; ditto
  782.  
  783. ;****************** End of user-defined code ********************************
  784. ;        Do not change anything below here.
  785.  
  786. ;Modem character test for 100 ms
  787. mrd:
  788.     push    bc        ; save bc
  789.     ld    bc,100        ; set limit
  790. mrd1:
  791.     call    mirdy        ; char at modem?
  792.     jr    nz,mrd2        ; yes, exit
  793.     ld    hl,1        ; else wait 1ms
  794.     call    waithlms
  795.     dec    bc        ; loop till done
  796.     ld    a,b
  797.     or    c
  798.     jr    nz,mrd1
  799.     ld    hl,0        ; none there, result=0
  800.     xor    a
  801. mrd2:
  802.     pop    bc
  803.     ret
  804.  
  805. ; Inline print routine: destroys A and HL
  806.  
  807. print:
  808.     ex    (sp),hl        ; get address of string
  809. ploop:
  810.     ld    a,(hl)        ; get next
  811.     inc    hl        ; bump pointer
  812.     or    a        ; done if zero
  813.     jr    z,pdone
  814.     call    cout        ; else print
  815.     jr    ploop        ; and loop
  816. pdone:
  817.     ex    (sp),hl        ; restore return address
  818.     ret            ; and quit
  819.  
  820. ;
  821. ;Output a character in A to the console
  822. ;
  823. cout:
  824.     push    bc        ; save regs
  825.     push    de
  826.     push    hl
  827.     ld    e,a        ; character to E
  828.     ld    c,2
  829.     call    bdos        ; print it
  830.     pop    hl
  831.     pop    de
  832.     pop    bc
  833.     ret
  834.  
  835. ;Wait(seconds)
  836. wait:
  837.     ld    hl,2
  838.     add    hl,sp
  839.     ex    de,hl        ; get delay size
  840.     call    getparm
  841.                 ; fall thru to..
  842. ;Wait seconds in HL
  843. waithls:
  844.     push    bc        ; save bc
  845.     push    de        ; de
  846.     push    ix        ; and ix
  847.     ld    ix,0        ; then point ix to 0
  848.                 ; so we don't upset memory-mapped i/o
  849.  
  850. ;Calculate values for loop constants. Need to have two loops to avoid
  851. ;   16-bit overflow with clock speeds above 9 MHz.
  852.  
  853. outerval    equ    (clkspd / 10) + 1
  854. innerval    equ    (6667 / outerval) * clkspd
  855.  
  856. wait10:
  857.     ld    b,outerval
  858.  
  859. wait11:
  860.     ld    de,innerval
  861.  
  862. wait12:
  863.     bit    0,(ix)        ; time-wasters
  864.     bit    0,(ix)
  865.     bit    0,(ix)        ; 20 T-states each
  866.     bit    0,(ix)
  867.     bit    0,(ix)
  868.     bit    0,(ix)
  869.     dec    de
  870.     ld    a,e
  871.     ld    a,d
  872.     or    e
  873.     jr    nz,wait12    ; 150 T-states per inner loop
  874.     djnz    wait11        ; decrement outer loop
  875.     dec    hl        ; ok, decrement count in hl
  876.     ld    a,h
  877.     or    l
  878.     jr    nz,wait10
  879.     pop    ix        ; done -- restore ix
  880.     pop    de        ; de
  881.     pop    bc        ; and bc
  882.     ret
  883.  
  884. ;Wait milliseconds
  885. mswait:
  886.     ld    hl,2
  887.     add    hl,sp
  888.     ex    de,hl        ; get delay size
  889.     call    getparm
  890.                 ; fall thru to..
  891. ;Wait milliseconds in HL
  892. waithlms:
  893.     push    de
  894. w1ms0:
  895.     ld    de,39 * clkspd
  896. w1ms1:
  897.     dec    de
  898.     ld    a,d
  899.     or    e
  900.     jr    nz,w1ms1
  901.     dec    hl
  902.     ld    a,h
  903.     or    l
  904.     jr    nz,w1ms0
  905.     pop    de
  906.     ret
  907.  
  908. ;Get next parameter from (de) into hl
  909. getparm:
  910.     ex    de,hl        ; get address into hl
  911.     ld    e,(hl)        ; get lo
  912.     inc    hl
  913.     ld    d,(hl)        ; then hi
  914.     inc    hl        ; bump for next
  915.     ex    de,hl        ; result in hl, address still in de
  916.     ret
  917.  
  918. getvars:
  919.     ld    hl,usevars
  920.     ret
  921. usevars:
  922.     dw    overdrive
  923.     dw    overuser
  924.  
  925.  
  926.      if    ($ - codebgn) gt ovsize
  927. toobig:    jp    errval        ; Overlay too large!
  928.      endif
  929.  
  930.     end
  931.  
  932.