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-XER2.Z80 < prev    next >
Text File  |  1991-02-02  |  18KB  |  726 lines

  1. ;-----------------------------------------------------------------------------
  2. ;
  3. ;    Overlay for ZMP (Z-Modem Program)
  4. ;
  5. ;    Name    ZMO-XER2.Z80
  6. ;
  7. ;    Dated Sep 14, 1988
  8. ;
  9. ;    Written by -
  10. ;      Ron Murray, c/o Z-Node 62, 061-9-450-0200, Perth, Western Australia.
  11. ;
  12. ;    Modified to ZMP v1.2 standard rjm 15/9/88
  13. ;    Modified to ZMP v1.3 standard rjm 11/10/88
  14. ;    Modified to ZMP v1.4 standard rjm 20/11/88
  15. ;
  16. ;       Modified to Xerox ZMP v1.2  S.V. Hovater  Houston Z-Node 713-937-8886
  17. ;       Modified to Xerox ZMP v1.4  Foster Schucker PO Box 385 Eagle PA 19480
  18. ;          Added parity, 7 and 8 bit data selection and Screen Print
  19. ;
  20. ;       Last Modification  January 7, 1989 
  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-xx01/h
  33. ;    MLOAD ZMP.COM=ZMODEM.COM,ZMO-xx01.HEX
  34. ; or
  35. ;    M80 =ZMO-xx01.Z80
  36. ;    RELHEX ZMO-xx01
  37. ;    MLOAD ZMP.COM=ZMODEM.COM,ZMO-xx01.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 (IX or IY).
  49. ; If your overlay requires either of these to be changed, ensure they are
  50. ; restored to the original values on return.
  51. ;    Since collecting parameters from C functions can be tricky, only change
  52. ; the parts marked 'Insert your own code here'. Do NOT modify the jump
  53. ; table at the start. Do NOT modify the entry/exit sections of each
  54. ; function. Do NOT pass 'GO'. Do NOT collect $200.
  55. ;    Apart from defining modem functions, this file also defines terminal
  56. ; characteristics. Examples provided are for ADM-3A (with a few of my own
  57. ; additions). Modify to suit your own terminal. An inline print routine
  58. ; is provided for printing strings in the usual way: usage is
  59. ;
  60. ;    call    print
  61. ;    db    'required string',0
  62. ;
  63. ;-----------------------------------------------------------------------------
  64. ;
  65. ;
  66. ;    Don't forget to set your clock speed at the clkspd variable.
  67. ;
  68. ;
  69. ;    If you find your overlay exceeds the maximum size (currently 0400h),
  70. ; you will have to contact me for another version. If too many people need 
  71. ; to do it, we haven't allowed enough room.
  72. ;
  73. ; Ron Murray 15/8/88
  74. ;
  75. ;
  76. ;
  77. ;---------------------------------------------------------------------------
  78.  
  79. false    equ    0
  80. true    equ    not false
  81.  
  82. ;------------------------------------------------------------------------------
  83.  
  84. ; User-set variables: 
  85.  
  86. clkspd    equ    4        ; Processor clock speed in MHz
  87. debug    equ    false        ; to allow debugging of overlay with Z8E etc.
  88.  
  89. ;Set the following two equates to the drive and user area which will contain
  90. ;   ZMP's .OVR files, .CFG file, .FON file and .HLP file. Set both to zero
  91. ;   (null) to locate them on the drive from which ZMP was invoked.
  92.  
  93. overdrive    equ    'A'    ; Drive to find overlay files on ('A'-'P')
  94. overuser    equ    0    ; User area to find files
  95.  
  96. ;------------------------------------------------------------------------------
  97.  
  98. ; Modem vars for Xerox UART
  99. PORT    equ     04H             ; Xerox Serial Port (data or status)
  100. MDCTL1  equ     PORT+2          ; Modem control port
  101. MDDATP  equ     PORT            ; Modem data port
  102. MDRCV   equ     01H             ; Modem receive ready bit
  103. MDSND   equ     04H             ; Modem send ready bit   
  104. MDTXE   equ     01H             ; Modem send buffer empty, holding buffer empty
  105. BRPORT  equ     00H             ; 8116 timer port for baudrate selection
  106.  
  107. ;------------------------------------------------------------------------------
  108.  
  109. ; NOT user-set variables
  110.  
  111. userdef    equ    0145h        ; origin of this overlay
  112.                 ; This address should not change with
  113.                 ; subsequent revisions.
  114. mspeed    equ    03ch        ; location of current baud rate. 
  115. ovsize    equ    0400h        ; max size of this overlay
  116.  
  117.     .z80            ; use z80 code
  118.     aseg            ; absolute
  119.  
  120.      if    debug
  121.     org    100h        ; so you can debug it with cebug, zsid, etc
  122.      else
  123.     org    userdef
  124.      endif
  125.  
  126.  
  127. esc    equ    1bh
  128. ctrlq    equ    11h
  129. cr    equ    0dh
  130. lf    equ    0ah
  131. bdos    equ    5
  132.  
  133.  
  134. codebgn    equ    $
  135.  
  136. ;Jump table for the overlay: do NOT change this
  137. jump_tab:
  138.     jp    scrnpr        ; screen print
  139.     jp    mrd        ; modem read with timeout
  140.     jp    mchin        ; get a character from modem
  141.     jp    mchout        ; send a character to the modem
  142.     jp    mordy        ; test for tx buffer empty
  143.     jp    mirdy        ; test for character received
  144.     jp    sndbrk        ; send break
  145.     jp    cursadd        ; cursor addressing
  146.     jp    cls        ; clear screen
  147.     jp    invon        ; inverse video on
  148.     jp    invoff        ; inverse video off
  149.     jp    hide        ; hide cursor
  150.     jp    show        ; show cursor
  151.     jp    savecu        ; save cursor position
  152.     jp    rescu        ; restore cursor position
  153.     jp    mint        ; service modem interrupt
  154.     jp    invec        ; initialise interrupt vectors
  155.     jp    dinvec        ; de-initialise interrupt vectors
  156.     jp    mdmerr        ; test uart flags for error
  157.     jp    dtron        ; turn DTR on
  158.     jp    dtroff        ; turn DTR OFF
  159.     jp    init        ; initialise uart
  160.     jp    wait        ; wait seconds
  161.     jp    mswait        ; wait milliseconds
  162.     jp    userin        ; user-defined entry routine
  163.     jp    userout        ; user-defined exit routine
  164.     jp    getvars        ; get system variables
  165.  
  166. ; Spare jumps for compatibility with future versions
  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.     jp    spare        ; spare for later use
  172.     jp    spare        ; spare for later use
  173.  
  174. ;
  175. ; Main code starts here
  176. ;
  177. ;Screen print function
  178. scrnpr:
  179.                 ; <== Insert Xerox specific code here
  180.         in      a,(01CH)        ; get current value of system port
  181.         push    af              ; save it so we can come back
  182.         res     7,a             ; turn on the system ROM
  183.         out     (01CH),a        ; and zap the pio
  184.         call    0F045H          ; call screen print
  185.         pop     af              ; back to the real world
  186.         out     (01CH),a        ; zap pio again
  187.                 ; <== End of Xerox specific code
  188. spare:
  189.     ret
  190.  
  191. ; User-defined entry routine: leave empty if not needed
  192. userin:
  193.     ret
  194.  
  195. ; User-defined exit routine: leave empty if not needed
  196. userout:
  197.     ret
  198.  
  199.  
  200. ;Get a character from the modem: return in HL
  201. mchin:
  202.     push    bc
  203.                 ; <== Inserted Xerox specific code here
  204.         in      a,(MDDATP)      ; get character in A
  205.                 ; <== End of Xerox specific code
  206.  
  207.     ld    l,a        ; put in HL
  208.     ld    h,0
  209.     or    a        ; set/clear Z
  210.     pop    bc
  211.     ret
  212.  
  213. ;Send a character to the modem
  214. mchout:
  215.     ld    hl,2        ; get the character
  216.     add    hl,sp
  217.     ld    a,(hl)
  218.                 ; <== Inserted Xerox specific code here
  219.         push    bc
  220.         ld      c,a
  221. mchout1:
  222.         in      a,(MDCTL1)
  223.         and     MDSND
  224.         jr      z,mchout1
  225.         ld      a,c
  226.         out     (MDDATP),a
  227.         pop     bc
  228.                 ; <== End of Xerox specific code
  229.     ret            ; done
  230.  
  231. ;Test for output ready: return TRUE (1) in HL if ok
  232. mordy:
  233.                 ; <== Inserted Xerox specific code here
  234.         in      a,(MDCTL1)
  235.         and     MDTXE
  236.         jr      z,mordy1
  237.         ld      l,1
  238.         ld      h,0
  239. mordy1:
  240.                 ; <== End of Xerox specific code
  241.     ld    a,l        ; set/clear Z
  242.     or    a
  243.     ret
  244.  
  245. ;Test for character at modem: return TRUE (1) in HL if so
  246. mirdy:
  247.                 ; <== Inserted Xerox specific code here
  248.         in      a,(MDCTL1)
  249.         and     MDRCV
  250.         jr      z,mirdy1
  251.         ld      l,1
  252.         jr      mirdy2
  253. mirdy1:
  254.         ld      l,0
  255. mirdy2:
  256.         ld      h,00H
  257.                 ; <== End of Xerox specific code
  258.     ld    a,l        ; set/clear Z
  259.     or    a
  260.     ret
  261.  
  262. ;Send a break to the modem: leave empty if your system can't do it
  263. sndbrk:
  264.                 ; <== Inserted Xerox specific code here
  265.         ld      a,5
  266.         out     (MDCTL1),a      ; Send to the status port
  267.         ld      a,(WORD5)
  268.         set     4,a             ; DTR Normal, send break tone
  269.         out     (MDCTL1),a
  270.     ld    hl,600        ; wait 600 ms
  271.     call    waithlms
  272.         ld      a,5             ; Restore normal operation
  273.         out     (MDCTL1),a
  274.         ld      a,(WORD5)       ; Get orginal value of WORD5
  275.         out     (MDCTL1),a
  276.                 ; <== End of Xerox specific code
  277.     ret
  278. ;
  279. ;Test UART flags for error: return TRUE (1) in HL if error.
  280. mdmerr:
  281.                 ; <== Inserted Xerox specific code here
  282.         ld      a,010H          ; register 0, reset interupts                ; <== End of Xerox specific code
  283.         out     (MDCTL1),a
  284.         in      a,(MDCTL1)
  285.                 ; <== End of Xerox specific code
  286.     ld    a,l        ; set/clear Z
  287.     or    a
  288.     ret
  289.  
  290.  
  291.  
  292. ;Turn DTR on
  293. dtron:
  294.                 ; <== Inserted Xerox specific code here
  295.         ld      a,05H
  296.         out     (MDCTL1),a
  297.         ld      a,(WORD5)       ; Get UART WORD 5
  298.         set     7,a             ; DTR ON
  299.         ld      (WORD5),a       ; save it for later
  300.         out     (MDCTL1),a
  301.                        ; <== End of Xerox specific code
  302.     ret
  303.  
  304.  
  305.  
  306. ;Turn DTR and RTS off
  307. dtroff:
  308.                 ; <== Inserted Xerox specific code here
  309.         ld      a,05H
  310.         out     (MDCTL1),a
  311.         ld      a,(WORD5)       ; Get UART WORD 5
  312.         res     7,a             ; DTR off
  313.         res     1,a             ; RTS off also for the modem 
  314.         ld      (WORD5),a       ; save it for later
  315.         out     (MDCTL1),a
  316.                 ; <== End of Xerox specific code
  317.     ret
  318.  
  319.  
  320.  
  321. ;Initialise the uart
  322.  
  323. init:
  324.  
  325.     ld    hl,2        ; get parameters
  326.     add    hl,sp
  327.     ex    de,hl
  328.     call    getparm        ; in HL
  329.     ld    (brate),hl    ; baud rate
  330.         ld      a,l             ; only one byte
  331.         ld      (mspeed),a
  332.     call    getparm
  333.     ld    (parity),hl    ; parity
  334.     call    getparm
  335.     ld    (data),hl    ; data bits (BINARY 7 or 8)
  336.     call    getparm
  337.     ld    (stop),hl    ; stop bits (BINARY 1 or 2)
  338.  
  339.  
  340.                 ; <== Inserted Xerox specific code here
  341.                 ; using values below
  342.         push    bc
  343. ;-----  Register 0
  344.         ld      a,0             ; select register 0
  345.         out     (MDCTL1),a
  346.         ld      a,018H          ; Throw out of mode
  347.         out     (MDCTL1),a
  348.  
  349. ;-----  Register 4
  350.         ld      a,04H           ; select register 4
  351.         out     (MDCTL1),a
  352.                                 ; First set up stop bits
  353.         ld      a,(stop)
  354.         cp      1
  355.         jp      z,onestop       ; One stop bit? 
  356.         ld      a,08H
  357.         ld      (stopmask),a    ; Must be two stop bits
  358.         jp      parityck        ; Ok look at parity
  359. onestop:
  360.         ld      a,04H
  361.         ld      (stopmask),a    ; set for one stop bit
  362.  
  363. parityck:
  364.         ld      a,(parity)      ; Now the parity bit
  365.         cp      'N'             ; None?
  366.         jp      z,noparity      ;
  367.         cp      'O'             ; Odd parity?
  368.         jp      z,oddparity     ;
  369.         ld      a,03H 
  370.         ld      (parmask),a     ; Ok make it even parity
  371.         jp      load4
  372. noparity:
  373.         ld      a,00
  374.         ld      (parmask),a     ;
  375.         jp      load4
  376. oddparity:
  377.         ld      a,01H 
  378.         ld      (parmask),a     ;
  379.  
  380. load4:
  381.         ld      b,040H          ; x16 cloc rate
  382.         ld      a,(parmask)     ; Parity
  383.         or      b  
  384.         ld      b,a
  385.         ld      a,(stopmask)    ; Stop bits
  386.         or      b
  387.         out     (MDCTL1),a
  388.  
  389. ;-----  Register 3
  390.         ld      a,03H           ; select register 3
  391.         out     (MDCTL1),a
  392.         ld      a,(data)        ; Number of bits in word
  393.         cp      8               ; 8 bits?
  394.         jp      z,eightbitrec   ; 
  395.         ld      b,040H          ; Must be 7 data bits
  396.         jp      load3
  397. eightbitrec:
  398.         ld      b,0C0H          ; set for 8
  399.  
  400. load3:  ld      a,01H           ; Enable receiver
  401.         or      b               ; Mash them        
  402.         out     (MDCTL1),a
  403.  
  404. ;-----  Register 5
  405.         ld      a,05H           ; select register 5
  406.         out     (MDCTL1),a
  407.         ld      a,(data)        ; Number of bits in word
  408.         cp      8               ; 8 bits?
  409.         jp      z,eightbitxmit  ; 
  410.         ld      b,0A0H          ; Must be 7 data bits
  411.         jp      load5
  412. eightbitxmit:
  413.         ld      b,0E0H          ; set for 8
  414.  
  415. load5:  ld      a,0AH           ; set RTS   
  416.         or      b               ; Mash them
  417.         ld      (WORD5),a       ; Save for later
  418.         out     (MDCTL1),a
  419.  
  420. ;-----  Timer setup
  421.         ld      b,0             ; Ok, now set the baud rate
  422.         ld      a,(mspeed)
  423.         cp      1
  424.         jp      z,S300
  425.         cp      5
  426.         jp      z,S1200
  427.         cp      6
  428.         jp      z,S2400
  429.         cp      7
  430.         jp      z,S4800
  431.         cp      8
  432.         jp      z,S9600
  433.         cp      9
  434.         jp      z,S19200
  435.         jp      S1200         ;did not find one, default is 1200
  436.  
  437. S300:   ld      b,BD300 
  438.         jp      loaded
  439. S1200:  ld      b,BD1200
  440.         ld      a,5
  441.         jp      loaded
  442. S2400:  ld      b,BD2400
  443.         ld      a,6
  444.         jp      loaded
  445. S4800:  ld      b,BD4800
  446.         jp      loaded
  447. S9600:  ld      b,BD9600
  448.         jp      loaded
  449. S19200: ld      b,BD19200
  450.  
  451. loaded:
  452.         ld      (brate),a      ; set up brate and mspeed 
  453.         ld      (mspeed),a   
  454.         ld      a,b
  455.         out     (BRPORT),a
  456.         pop     bc
  457.                 ; <== End of Xerox specific code
  458.     ret
  459. ;--------------------------------------------------------------------------
  460.  
  461. stop:      dw    1        ; stop bits
  462. stopmask: db    4               ; one stop bit
  463. parity:      dw    'N'        ; parity
  464. parmask:  db    0               ; no parity
  465. data:     dw    8        ; data bits
  466. brate:      dw    7        ; baud rate:
  467. WORD5:    db    0EAH            ; Uart WORD 5 storage
  468.  
  469. ;--------------------------------------------------------------------------
  470. ;Values of brate for each baud rate
  471. ;
  472. ; baud rate    brate
  473. ;
  474. ;   110         0
  475. ;   300         1
  476. BD300   equ      5  ; timer number  
  477. ;   450         2
  478. ;   600         3
  479. ;   710         4
  480. ;  1200         5
  481. BD1200  equ      7  ; timer number
  482. ;  2400         6
  483. BD2400  equ     10  ; timer number 
  484. ;  4800         7
  485. BD4800  equ     12  ; timer number   
  486. ;  9600         8
  487. BD9600  equ     14  ; timer number
  488. ; 19200         9
  489. BD19200 equ     15  ; timer number
  490. ; 38400        10
  491. ; 57600         11
  492. ; 76800         12
  493. ;
  494.  
  495. ;****************************************************************************
  496. ;Video terminal sequences: these are for Xerox 820
  497. ;Cursor addressing: 
  498. cursadd:
  499.     ld    hl,2        ; get parameters
  500.     add    hl,sp
  501.     ex    de,hl
  502.     call    getparm        ; in HL
  503.     ld    (row),hl    ; row
  504.     call    getparm
  505.     ld    (col),hl    ; column
  506.                 ; <== Inserted Xerox specific code here
  507.                 ; using values in row and col
  508.     call    print
  509.     db    esc,'=',0    ; leadin
  510.     ld    a,(row)        ; row first
  511.     add    a,' '        ; add offset
  512.     call    cout
  513.     ld    a,(col)        ; same for column
  514.     add    a,' '
  515.     call    cout
  516.                 ; <== end of Xerox specific code
  517.     ret
  518.  
  519. row:    ds    2        ; row
  520. col:    ds    2        ; column
  521.  
  522.  
  523. ;Clear screen:
  524. cls:   
  525.     call    print
  526.     db    1ah,0
  527.     ret
  528.  
  529. ;Inverse video on:
  530. invon:
  531.     call    print
  532.     db    esc,')',0
  533.     ret
  534.  
  535. ;Inverse video off:
  536. invoff:
  537.     call    print
  538.     db    esc,'(',0
  539.     ret
  540.  
  541. ;Turn off cursor:
  542. hide:
  543.     call    print
  544.     db    esc,'z',0
  545.     ret
  546.  
  547. ;Turn on cursor:
  548. show:
  549.     call    print
  550.     db    esc,'v',0
  551.     ret
  552.  
  553. ;Save cursor position:
  554. savecu:
  555.     ret
  556.  
  557. ;Restore cursor position:
  558. rescu:
  559.     ret
  560.  
  561. ;****************************************************************************
  562.  
  563. ;Service modem interrupt:
  564. mint:
  565.     ret            ; my system doesn't need this
  566.  
  567. ;Initialise interrupt vectors:
  568. invec:
  569.     ret            ; ditto
  570.  
  571. ;De-initialise interrupt vectors:
  572. dinvec:
  573.     ret            ; ditto
  574.  
  575. ;****************** End of user-defined code ********************************
  576. ;        Do not change anything below here.
  577.  
  578. ;Modem character test for 100 ms
  579. mrd:
  580.     push    bc        ; save bc
  581.     ld    bc,100        ; set limit
  582. mrd1:
  583.     call    mirdy        ; char at modem?
  584.     jr    nz,mrd2        ; yes, exit
  585.     ld    hl,1        ; else wait 1ms
  586.     call    waithlms
  587.     dec    bc        ; loop till done
  588.     ld    a,b
  589.     or    c
  590.     jr    nz,mrd1
  591.     ld    hl,0        ; none there, result=0
  592.     xor    a
  593. mrd2:
  594.     pop    bc
  595.     ret
  596.  
  597. ; Inline print routine: destroys A and HL
  598.  
  599. print:
  600.     ex    (sp),hl        ; get address of string
  601. ploop:
  602.     ld    a,(hl)        ; get next
  603.     inc    hl        ; bump pointer
  604.     or    a        ; done if zero
  605.     jr    z,pdone
  606.     call    cout        ; else print
  607.     jr    ploop        ; and loop
  608. pdone:
  609.     ex    (sp),hl        ; restore return address
  610.     ret            ; and quit
  611.  
  612. ;
  613. ;Output a character in A to the console
  614. ;
  615. cout:
  616.     push    bc        ; save regs
  617.     push    de
  618.     push    hl
  619.     ld    e,a        ; character to E
  620.     ld    c,2
  621.     call    bdos        ; print it
  622.     pop    hl
  623.     pop    de
  624.     pop    bc
  625.     ret
  626.  
  627. ;Wait(seconds)
  628. wait:
  629.     ld    hl,2
  630.     add    hl,sp
  631.     ex    de,hl        ; get delay size
  632.     call    getparm
  633.                 ; fall thru to..
  634. ;Wait seconds in HL
  635. waithls:
  636.     push    bc        ; save bc
  637.     push    de        ; de
  638.     push    ix        ; and ix
  639.     ld    ix,0        ; then point ix to 0
  640.                 ; so we don't upset memory-mapped i/o
  641.  
  642. ;Calculate values for loop constants. Need to have two loops to avoid
  643. ;   16-bit overflow with clock speeds above 9 MHz.
  644.  
  645. outerval    equ    (clkspd / 10) + 1
  646. innerval    equ    (6667 / outerval) * clkspd
  647.  
  648. wait10:
  649.     ld    b,outerval
  650.  
  651. wait11:
  652.     ld    de,innerval
  653.  
  654. wait12:
  655.     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. mswait:
  678.     ld    hl,2
  679.     add    hl,sp
  680.     ex    de,hl        ; get delay size
  681.     call    getparm
  682.                 ; fall thru to..
  683. ;Wait milliseconds in HL
  684. waithlms:
  685.     push    de
  686. w1ms0:
  687.     ld    de,39 * clkspd
  688. w1ms1:
  689.     dec    de
  690.     ld    a,d
  691.     or    e
  692.     jr    nz,w1ms1
  693.     dec    hl
  694.     ld    a,h
  695.     or    l
  696.     jr    nz,w1ms0
  697.     pop    de
  698.     ret
  699.  
  700. ;Get next parameter from (de) into hl
  701. getparm:
  702.     ex    de,hl        ; get address into hl
  703.     ld    e,(hl)        ; get lo
  704.     inc    hl
  705.     ld    d,(hl)        ; then hi
  706.     inc    hl        ; bump for next
  707.     ex    de,hl        ; result in hl, address still in de
  708.     ret
  709.  
  710. ;Get address of user-defined variables
  711.  
  712. getvars:
  713.     ld    hl,uservars
  714.     ret
  715.  
  716. uservars:
  717.     dw    overdrive    ; .OVR etc. drive/user
  718.     dw    overuser
  719.  
  720.  
  721.      if    ($ - codebgn) gt ovsize
  722. toobig:    jp    errval        ; Overlay too large!
  723.      endif
  724.  
  725.     end
  726.