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-R415.Z80 < prev    next >
Text File  |  2000-06-30  |  16KB  |  710 lines

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