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 / ZMOH89.ZZ0 / ZMOH89.Z80
Text File  |  2000-06-30  |  14KB  |  661 lines

  1. ;-----------------------------------------------------------------------------
  2. ;
  3. ;    Heath-89 Overlay for ZMP15 (Z-Modem Program)
  4. ;       modifications by Howard Dutton
  5. ;
  6. ;
  7. ;       BE SURE TO CHANGE THE USER SET VARS: clkspd + overdrive + overuser
  8. ;       ******************************************************************
  9. ;
  10. ;    Name    ZMOH89.Z80 
  11. ;
  12. ;    Dated Sep 14, 1988
  13. ;
  14. ;    Written by -
  15. ;      Ron Murray, c/o Z-Node 62, 061-9-450-0200, Perth, Western Australia.
  16. ;
  17. ;    Modified to ZMP v1.2 standard rjm 15/9/88
  18. ;    Modified to ZMP v1.3 standard rjm 11/10/88
  19. ;    Modified to ZMP v1.4 standard rjm 20/11/88
  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-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. ;    Don't forget to set your clock speed at the clkspd variable.
  47. ;
  48. ;
  49. ;    If you find your overlay exceeds the maximum size (currently 0400h),
  50. ; you will have to contact me for another version. If too many people need 
  51. ; to do it, we haven't allowed enough room.
  52. ;
  53. ; Ron Murray 15/8/88
  54. ;
  55. ;
  56. ;
  57. ;---------------------------------------------------------------------------
  58.  
  59. false    equ    0
  60. true    equ    not false
  61.  
  62. ;------------------------------------------------------------------------------
  63.  
  64. ; User-set variables:
  65.  
  66. clkspd    equ    6        ; Processor clock speed in MHz
  67. debug    equ    false        ; to allow debugging of overlay with Z8E etc.
  68.  
  69. ;Set the following two equates to the drive and user area which will contain
  70. ;   ZMP's .OVR files, .CFG file, .FON file and .HLP file. Set both to zero
  71. ;   (null) to locate them on the drive from which ZMP was invoked.
  72.  
  73. overdrive    equ    'A'    ; Drive to find overlay files on ('A'-'P')
  74. overuser    equ    0    ; User area to find files
  75.  
  76. ;------------------------------------------------------------------------------
  77.  
  78.  
  79. ; NOT user-set variables
  80.  
  81. userdef    equ    0145h        ; origin of this overlay
  82.                 ; This address should not change with
  83.                 ; subsequent revisions.
  84. mspeed    equ    03ch        ; location of current baud rate. 
  85. ovsize    equ    0400h        ; max size of this overlay
  86.  
  87.     .z80            ; use z80 code
  88.     aseg            ; absolute
  89.  
  90.      if    debug
  91.     org    100h        ; so you can debug it with cebug, zsid, etc
  92.      else
  93.     org    userdef
  94.      endif
  95.  
  96.  
  97. mport    equ    0d8h        ; the modem port on a h88-3 serial card
  98. conport    equ    0e0h        ; the console serial port on a H89
  99.  
  100. esc    equ    1bh
  101. ctrlq    equ    11h
  102. cr    equ    0dh
  103. lf    equ    0ah
  104. bdos    equ    5
  105.  
  106.  
  107. codebgn    equ    $
  108.  
  109. ;Jump table for the overlay: do NOT change this
  110. jump_tab:
  111.     jp    scrnpr        ; screen print
  112.     jp    mrd        ; modem read with timeout
  113.     jp    mchin        ; get a character from modem
  114.     jp    mchout        ; send a character to the modem
  115.     jp    mordy        ; test for tx buffer empty
  116.     jp    mirdy        ; test for character received
  117.     jp    sndbrk        ; send break
  118.     jp    cursadd        ; cursor addressing
  119.     jp    cls        ; clear screen
  120.     jp    invon        ; inverse video on
  121.     jp    invoff        ; inverse video off
  122.     jp    hide        ; hide cursor
  123.     jp    show        ; show cursor
  124.     jp    savecu        ; save cursor position
  125.     jp    rescu        ; restore cursor position
  126.     jp    mint        ; service modem interrupt
  127.     jp    invec        ; initialise interrupt vectors
  128.     jp    dinvec        ; de-initialise interrupt vectors
  129.     jp    mdmerr        ; test uart flags for error
  130.     jp    dtron        ; turn DTR on
  131.     jp    dtroff        ; turn DTR OFF
  132.     jp    init        ; initialise uart
  133.     jp    wait        ; wait seconds
  134.     jp    mswait        ; wait milliseconds
  135.     jp    userin        ; user-defined entry routine
  136.     jp    userout        ; user-defined exit routine
  137.     jp    getvars        ; get system variables
  138.     jp    setport        ; set port #0 or #1
  139.  
  140. ; Spare jumps for compatibility with future versions
  141.     jp    spare        ; spare for later use
  142.     jp    spare        ; spare for later use
  143.     jp    spare        ; spare for later use
  144.     jp    spare        ; spare for later use
  145.     jp    spare        ; spare for later use
  146.  
  147. ;
  148. ; Main code starts here
  149. ;
  150. ;Screen print function
  151. scrnpr:
  152.                 ; <== Insert your own code here
  153.     call    print
  154.     db    'This function not supported.',cr,lf,0
  155.                 ; <== End of your own code
  156. spare:
  157.     ret
  158.  
  159. ; User-defined entry routine: leave empty if not needed
  160. userin:
  161.     ret
  162.  
  163. ; User-defined exit routine: leave empty if not needed
  164. userout:
  165.     ret
  166.  
  167.  
  168. ;Get a character from the modem: return in HL
  169. mchin:
  170.     push    bc
  171.     in    a,(mport)
  172.     ld    l,a        ; put in HL
  173.     ld    h,0
  174.     or    a        ; set/clear Z
  175.     pop    bc
  176.     ret
  177.  
  178. ;Send a character to the modem
  179. mchout:
  180.     ld    hl,2        ; get the character
  181.     add    hl,sp
  182.     ld    a,(hl)
  183.     out    (mport),a
  184.     ret            ; done
  185.  
  186. ;Test for output ready: return TRUE (1) in HL if ok
  187. mordy:
  188.     ld    hl,0        ;
  189.     in    a,(mport+5)    ;
  190.     bit    5,a        ; bit 5 is set if uart is ready for a char
  191.     jp    z,mordy1    ;
  192.     ld    hl,1
  193.  
  194. mordy1:    ld    a,l        ; set/clear Z
  195.     or    a
  196.     ret
  197.  
  198. ;Test for character at modem: return TRUE (1) in HL if so
  199. mirdy:
  200.     ld    hl,0        ;
  201.     in    a,(mport+5)    ;
  202.     bit    0,a        ; bit 0 is set if data is ready
  203.     jp    z,mirdy1    ;
  204.     ld    hl,1
  205.  
  206. mirdy1:    ld    a,l        ; set/clear Z
  207.     or    a
  208.     ret
  209.  
  210. ;Send a break to the modem: leave empty if your system can't do it
  211. sndbrk:
  212.  
  213.     in    a,(mport+3)    ;
  214.     set    6,a        ; set break bit
  215.     out    (mport+3),a    ;
  216.  
  217.     push    af
  218.     ld    hl,300        ; wait 300 mS
  219.     call    waithlms
  220.     pop    af
  221.  
  222.     res    6,a        ; reset break bit
  223.     out    (mport+3),a    ;
  224.  
  225.     ret
  226. ;
  227. ;Test UART flags for error: return TRUE (1) in HL if error.
  228. mdmerr:
  229.     ld    hl,0
  230.     in    a,(mport+5)    ; get line status
  231.     and    00001110B    ; mask
  232.     jp    z,mdmer1    ; a should = 0 if everything is ok
  233.     ld    hl,1        ;
  234.  
  235. mdmer1:    ld    a,l        ; set/clear Z
  236.     or    a
  237.     ret
  238.  
  239.  
  240. ;Turn DTR ON
  241. dtron:
  242.     in    a,(mport+4)    ;
  243.     set    0,a        ; set the DTR bit
  244.     out    (mport+4),a    ;
  245.  
  246.     ret
  247.  
  248.  
  249.  
  250. ;Turn DTR OFF
  251. dtroff:
  252.     in    a,(mport+4)    ;
  253.     res    0,a        ; reset the DTR bit
  254.     out    (mport+4),a    ;
  255.  
  256.     ret
  257.  
  258.  
  259. ;
  260. ; Set the port. ZMP supplies either 0 or 1 as a parameter. You're on your
  261. ; own here -- your system is bound to be different from any other! You may
  262. ; implement a software switch on all the modem-dependent routines, or perhaps
  263. ; you can have one or two centralised routines for accessing the UARTs and
  264. ; modify the code from this routine to select one or the other. (Who said
  265. ; there was anything wrong with self-modifying code?). If you have only one
  266. ; UART port, or if you don't want to go through all the hassles, just have
  267. ; this routine returning with no changes made. Note that ZMP calls this
  268. ; routine twice -- once for each port value -- on initialisation.
  269. ;
  270. setport:
  271.     ld    hl,2        ; get port number
  272.     add    hl,sp
  273.     ex    de,hl
  274.     call    getparm        ; in HL (values are 0 and 1)
  275.  
  276.                 ; <== Insert your own code here
  277.  
  278.                 ; <== End of your own code
  279.     ret
  280.  
  281. port:    ds    1
  282.  
  283.  
  284. ;Initialise the uart
  285.  
  286. init:    ld    hl,2        ; get parameters
  287.     add    hl,sp
  288.     ex    de,hl
  289.     call    getparm        ; in HL
  290.     ld    (brate),hl    ; baud rate
  291.     call    getparm
  292.     ld    (parity),hl    ; parity
  293.     call    getparm
  294.     ld    (data),hl    ; data bits (BINARY 7 or 8)
  295.     call    getparm
  296.     ld    (stop),hl    ; stop bits (BINARY 1 or 2)
  297.  
  298. ; get the 8250 ready for programming
  299.     ld    a,0        ; clear interrupts
  300.     out    (mport+1),a    ;
  301.  
  302.     ld    a,00010000B    ; set to loop-back mode
  303.     out    (mport+4),a    ;
  304.  
  305. ; program the baud-rate (if it's valid)
  306.     ld    hl,(brate)    ; check to see if baud-rate is valid
  307.     ld    de,12        ;
  308.     or    a        ; clear carry
  309.     sbc    hl,de        ; hl=brate-12
  310.     jp    p,prb1        ; negitive if brate is 0..11
  311.  
  312.     ld    a,l        ;
  313.     ld    (mspeed),a    ; let zmp know it's valid
  314.  
  315.     ld    a,10000000B    ; set divisor latch access bit
  316.     out    (mport+3),a    ;
  317.  
  318.     ld    hl,(brate)    ; compute offset to baud-rate divisor
  319.     add    hl,hl        ;
  320.     ex    de,hl        ;
  321.     ld    hl,brtbl    ;
  322.     add    hl,de        ; HL now has address of divisor
  323.     ld    a,(hl)        ; get the low-order byte
  324.     out    (mport),a    ;
  325.     inc    hl        ;
  326.     ld    a,(hl)        ;
  327.     out    (mport+1),a    ;
  328.  
  329. ; program the: type of parity / # data bits / # stop bits
  330. prb1:    ld    b,0        ; set the LCR value (in B for now) to 0
  331.     ld    a,(parity)    ; set bits in B to type of parity
  332.     cp    'N'        ;
  333.     jp    z,parN        ;
  334.     cp    'E'        ;
  335.     jp    z,ParE         ;
  336.     cp    'O'        ;
  337.     jp    z,ParO        ;
  338. Skip3:    ld    a,(Data)    ; set bits in B to # of data bits
  339.     cp    7        ;
  340.     jp    z,data7        ;
  341.     cp    8        ;
  342.     jp    z,data8        ;
  343. Skip4:    ld    a,(Stop)    ;
  344.     cp    1        ;
  345.     jp    z,Stop1        ;
  346.     cp    2        ;
  347.     jp    z,Stop2        ;
  348. Skip5:    ld    a,b        ; get 'LCR' value
  349.     out    (mport+3),a    ; (also de-selects divisor access)
  350.  
  351. ; take 8250 out of loop-back mode
  352.     in    a,(mport)    ; read a char
  353.     add    hl,hl        ; waste some time
  354.     add    hl,hl        ;
  355.     in    a,(mport)    ; read another char
  356.     ld    a,0        ;
  357.     out    (mport+4),a    ; take 8250 out of loop-back mode
  358.  
  359.     ret
  360.  
  361. ; Types of parity
  362. ParN:
  363.     jp    Skip3
  364. ParE:
  365.     set    3,b
  366.     set    4,b
  367.     jp    Skip3
  368. ParO:
  369.     set    3,b
  370.     jp    Skip3
  371. ; Number of data bits
  372. Data7:
  373.     set    1,b
  374.     jp    Skip4
  375. Data8:
  376.     set    0,b
  377.     set    1,b
  378.     jp    Skip4
  379. ; Number of stop bits
  380. Stop1:
  381.     jp    Skip5
  382. Stop2:    
  383.     set    2,b
  384.     jp    Skip5
  385.  
  386. ; baud rate divisor table for 8250
  387. brtbl:    dw    1047        ; 110     0
  388.     dw    384        ; 300     1
  389.     dw    256        ; 450     2
  390.     dw    192        ; 600     3
  391.     dw    162        ; 710     4
  392.     dw    96        ; 1200    5
  393.     dw    48        ; 2400    6
  394.     dw    24        ; 4800    7
  395.     dw    12        ; 9600    8
  396.     dw    6        ; 19200   9
  397.     dw    3        ; 38400  10
  398.     dw    2        ; 57600  11
  399.  
  400. ;--------------------------------------------------------------------------
  401.  
  402. stop:    dw    1        ; stop bits
  403. parity:    dw    'N'        ; parity
  404. data:    dw    8        ; data bits
  405. brate:    dw    5        ; baud rate: 1200
  406.  
  407. ;--------------------------------------------------------------------------
  408. ;Values of brate for each baud rate
  409. ;
  410. ; baud rate    brate
  411. ;
  412. ;   110         0
  413. ;   300         1
  414. ;   450         2
  415. ;   600         3
  416. ;   710         4
  417. ;  1200         5
  418. ;  2400         6
  419. ;  4800         7
  420. ;  9600         8
  421. ; 19200         9
  422. ; 38400        10
  423. ; 57600         11
  424. ;
  425.  
  426. ;****************************************************************************
  427. ;Video terminal sequences: these are for the H19
  428. ;Cursor addressing:
  429. cursadd:
  430.     ld    hl,2        ; get parameters
  431.     add    hl,sp
  432.     ex    de,hl
  433.     call    getparm        ; in HL
  434.     ld    (row),hl    ; row
  435.     call    getparm
  436.     ld    (col),hl    ; column
  437.  
  438.                 ; using values in row and col
  439.     call    print
  440.     db    esc,'Y',0    ; H19 leadin
  441.     ld    a,(row)        ; row first
  442.     add    a,' '        ; add offset
  443.     call    cout
  444.     ld    a,(col)        ; sane for column
  445.     add    a,' '
  446.     call    cout
  447.  
  448.     ret
  449.  
  450. row:    ds    2        ; row
  451. col:    ds    2        ; column
  452.  
  453.  
  454. ;Clear screen:
  455. cls:
  456.     call    print
  457.     db    esc,'E',0
  458.     ret
  459.  
  460. ;Inverse video on:
  461. invon:
  462.     call    print
  463.     db    esc,'p',0
  464.     ret
  465.  
  466. ;Inverse video off:
  467. invoff:
  468.     call    print
  469.     db    esc,'q',0
  470.     ret
  471.  
  472. ;Turn off cursor:
  473. hide:
  474.     call    print
  475.     db    esc,'x5',0
  476.     ret
  477.  
  478. ;Turn on cursor:
  479. show:
  480.     call    print
  481.     db    esc,'y5',0
  482.     ret
  483.  
  484. ;Save cursor position:
  485. savecu:
  486.     call    print
  487.     db    esc,'j',0
  488.     ret
  489.  
  490. ;Restore cursor position:
  491. rescu:
  492.     call    print
  493.     db    esc,'k',0
  494.     ret
  495.  
  496. ;****************************************************************************
  497.  
  498. ;Service modem interrupt:
  499. mint:
  500.     ret            ; my system doesn't need this
  501.  
  502. ;Initialise interrupt vectors:
  503. invec:
  504.     ret            ; ditto
  505.  
  506. ;De-initialise interrupt vectors:
  507. dinvec:
  508.     ret            ; ditto
  509.  
  510. ;****************** End of user-defined code ********************************
  511. ;        Do not change anything below here.
  512.  
  513. ;Modem character test for 100 ms
  514. mrd:
  515.     push    bc        ; save bc
  516.     ld    bc,100        ; set limit
  517. mrd1:
  518.     call    mirdy        ; char at modem?
  519.     jr    nz,mrd2        ; yes, exit
  520.     ld    hl,1        ; else wait 1ms
  521.     call    waithlms
  522.     dec    bc        ; loop till done
  523.     ld    a,b
  524.     or    c
  525.     jr    nz,mrd1
  526.     ld    hl,0        ; none there, result=0
  527.     xor    a
  528. mrd2:
  529.     pop    bc
  530.     ret
  531.  
  532. ; Inline print routine: destroys A and HL
  533.  
  534. print:
  535.     ex    (sp),hl        ; get address of string
  536. ploop:
  537.     ld    a,(hl)        ; get next
  538.     inc    hl        ; bump pointer
  539.     or    a        ; done if zero
  540.     jr    z,pdone
  541.     call    cout        ; else print
  542.     jr    ploop        ; and loop
  543. pdone:
  544.     ex    (sp),hl        ; restore return address
  545.     ret            ; and quit
  546.  
  547. ;
  548. ;Output a character in A to the console
  549. ;
  550. cout:
  551.     push    bc        ; save regs
  552.     push    de
  553.     push    hl
  554.     ld    e,a        ; character to E
  555.     ld    c,2
  556.     call    bdos        ; print it
  557.     pop    hl
  558.     pop    de
  559.     pop    bc
  560.     ret
  561.  
  562. ;Wait(seconds)
  563. wait:
  564.     ld    hl,2
  565.     add    hl,sp
  566.     ex    de,hl        ; get delay size
  567.     call    getparm
  568.                 ; fall thru to..
  569. ;Wait seconds in HL
  570. waiths:
  571.     push    bc        ; save bc
  572.     push    de        ; de
  573.     push    ix        ; and ix
  574.     ld    ix,0        ; then point ix to 0
  575.                 ; so we don't upset memory-mapped i/o
  576.  
  577. ;Calculate values for loop constants. Need to have two loops to avoid
  578. ;   16-bit overflow with clock speeds above 9 MHz.
  579.  
  580. outerval    equ    (clkspd / 10) + 1
  581. innerval    equ    (6667 / outerval) * clkspd
  582.  
  583. wait10:
  584.     ld    b,outerval
  585.  
  586. wait11:
  587.     ld    de,innerval
  588.  
  589. wait12:
  590.     bit    0,(ix)        ; time-wasters
  591.     bit    0,(ix)
  592.     bit    0,(ix)        ; 20 T-states each
  593.     bit    0,(ix)
  594.     bit    0,(ix)
  595.     bit    0,(ix)
  596.     dec    de
  597.     ld    a,e
  598.     ld    a,d
  599.     or    e
  600.     jr    nz,wait12    ; 150 T-states per inner loop
  601.     djnz    wait11        ; decrement outer loop
  602.     dec    hl        ; ok, decrement count in hl
  603.     ld    a,h
  604.     or    l
  605.     jr    nz,wait10
  606.     pop    ix        ; done -- restore ix
  607.     pop    de        ; de
  608.     pop    bc        ; and bc
  609.     ret
  610.  
  611. ;Wait milliseconds
  612. mswait:
  613.     ld    hl,2
  614.     add    hl,sp
  615.     ex    de,hl        ; get delay size
  616.     call    getparm
  617.                 ; fall thru to..
  618. ;Wait milliseconds in HL
  619. waithlms:
  620.     push    de
  621. w1ms0:
  622.     ld    de,39 * clkspd
  623. w1ms1:
  624.     dec    de
  625.     ld    a,d
  626.     or    e
  627.     jr    nz,w1ms1
  628.     dec    hl
  629.     ld    a,h
  630.     or    l
  631.     jr    nz,w1ms0
  632.     pop    de
  633.     ret
  634.  
  635. ;Get next parameter from (de) into hl
  636. getparm:
  637.     ex    de,hl        ; get address into hl
  638.     ld    e,(hl)        ; get lo
  639.     inc    hl
  640.     ld    d,(hl)        ; then hi
  641.     inc    hl        ; bump for next
  642.     ex    de,hl        ; result in hl, address still in de
  643.     ret
  644.  
  645. ;Get address of user-defined variables
  646.  
  647. getvars:
  648.     ld    hl,uservars
  649.     ret
  650.  
  651. uservars:
  652.     dw    overdrive    ; .OVR etc. drive/user
  653.     dw    overuser
  654.  
  655.  
  656.      if    ($ - codebgn) gt ovsize
  657. toobig:    jp    errval        ; Overlay too large!
  658.      endif
  659.  
  660.     end
  661.