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 / ZMO180F1.Z80 < prev    next >
Text File  |  1991-02-02  |  25KB  |  908 lines

  1. ; ZMO180F1.Z80  -- SB180FX computer overlay file for ZMP 1.5 -- 
  2.  
  3. ; September 24 1989  - by Simeon Cran
  4.  
  5. ; This file adapts ZMP1.5 to the SB180-FX computer; HD64180 ASCI port 0
  6.  
  7. ; This file has only been tested on a 9 MHz FX
  8.  
  9. ; Based on Bill Biersdorf's  ZMP180B1.Z80 of September 1988
  10.  
  11. ; Assemble with ZAS.
  12.  
  13. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  14. ;        NOTES:
  15.  
  16. ;    Credit must be given to Bill Biersdorf who got the thing running
  17. ; in the first place.  I have retained some of his original code.
  18.  
  19. ;    This version solves the problem of high speed transfers referred to
  20. ; by Ron Murray in ZMP.DOC.  Two schemes have been implemented to make this
  21. ; possible.  One: the unused programmable reload timer on the 64180 has been
  22. ; pressed into service to do all timing.  This is not interrupt driven, but
  23. ; rather polled.  Two:  if the "modints" equate is set to true, the modem
  24. ; port is interrupt driven for receive.  Be warned however if you are using
  25. ; a bios which executes out of the normal 64k CP/M bank.  If an interrupt
  26. ; occurs during that time, it could end up anywhere.  If possible, you
  27. ; should modify your bios to prevent this happening.  If you need ideas, let
  28. ; me know.
  29.  
  30. ;    With "modints" set true, I can now run my modem faster that my
  31. ; terminal.  This may not seem all that useful, but for use with a packet
  32. ; radio TNC or high speed buffered modem, it is worthwhile.  Note that when
  33. ; the receive buffer gets full, it controls DTR and RTS to stop the sender.
  34. ; If the sender doesn't recognise these signals, buffer overrun will occur.
  35. ; Thankfully most high speed peripherals do respond as expected.
  36.  
  37. ;    Also, DTR and RTS are turned off on exit.  That means that the 
  38. ; sender will buffer it's data until ZMP is running again.  Useful if
  39. ; you want to go and run some ordinary CP/M command and then return: the
  40. ; data should be there waiting for you.  DTR and RTS are of course turned
  41. ; back on on entry.
  42.  
  43. ;    Everything appears to work properly.  Don't forget to change the
  44. ; terminal routines to suit your own terminal or it will do some very strange
  45. ; things on the screen (mine is a little unusual).
  46.  
  47. ;    The break routine is of necessity, a bit of a kludge.  It may
  48. ; sometimes throw up some garbage on the screen, but mostly it doesn't.
  49. ; The point is, it works.
  50.  
  51. ;    I have marked the parts that you will probably have to change, with
  52. ; "*****".  This should make it easier to find your way around (use the
  53. ; find function of your word processor).
  54.  
  55. ;    This is my version 1.0
  56.  
  57. ;    Simeon Cran  VK4ASJ/KF7QL Brisbane Australia
  58. ;    (any queries via Z-NODE 62 or VK4ASJ@VK4KJB)
  59.  
  60. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  61. ; System-dependent installation overlay for ZMP
  62. ; Author: Ron Murray
  63. ;
  64. ;    Insert your own code as necessary in this file. Code contained herein
  65. ; has been written in HD64180 code for use with ZAS.  Assemble with the h
  66. ; option to create a .HEX file, and use MLOAD to overlay it over the main
  67. ; ZMPX.COM file to produce your very own ZMP.COM.
  68. ;
  69. ; Notes on modifying this file:
  70. ;    Hi-Tech C requires that functions do not change either index register
  71. ; (IX or IY). If your overlay requires either of these to be changed, ensure
  72. ; they are restored to their original values on return.
  73. ;    Since collecting parameters from C functions can be tricky, only change
  74. ; the parts marked 'Insert your own code here'. Do NOT modify the jump
  75. ; table at the start. Do NOT modify the entry/exit sections of each
  76. ; function. Do NOT pass 'GO'. Do NOT collect $200.
  77. ;    Apart from defining modem functions, this file also defines terminal
  78. ; characteristics. Most have been set up for ADM-3A (with a few of my own
  79. ; additions). Modify to suit your own terminal. An inline print routine
  80. ; is provided for printing strings in the usual way: usage is
  81. ;
  82. ;    call    print
  83. ;    db    'required string',0
  84. ;
  85. ;
  86. ;    If you find your overlay exceeds the maximum size (currently 0400h),
  87. ; you will have to re-compile the whole thing. Good luck. You might try
  88. ; informing us if you need to do this: if too many people need to do it, we
  89. ; haven't allowed enough room.
  90. ;
  91. ; Ron Murray 15/8/88
  92. ;
  93. ;=============================================================================
  94. ;Some fundamental truths
  95.  
  96. true    equ    0ffh
  97. false    equ    not true
  98.  
  99. ;------------------------------------------------------------------------------
  100. ;        OPTION CONFIGURATION SECTION
  101. ;
  102. ;Interrupt driven modem input option
  103. ;
  104. modints    equ    true        ; true=use interrupts for modem receive*****
  105.  
  106.  
  107. ;Select-a-speed            ; NOTE: set only ONE of the following to true*****
  108. ;
  109. cpu12    equ    false        ; 12.288 MHz HD64180
  110. cpu9    equ    true        ; 9.216 MHz HD64180
  111. cpu6    equ    false        ; 6.144 MHz HD64180
  112.  
  113.  
  114. mspeed    equ    003ch        ; Current baud rate: as used by BYE etc
  115.                 ; This MUST be the same as Mspeed in
  116.                 ; ZMP.H
  117.  
  118.  
  119. ;Set the following two equates to the drive and user area which will contain
  120. ;   ZMP's .OVR files, .CFG file, .FON file and .HLP file. Set both to zero
  121. ;   (null) to locate them on the drive from which ZMP was invoked.
  122.  
  123. overdrive    equ    'B'    ; Drive to find overlay files on ('A'-'P')*****
  124. overuser    equ    0    ; User area to find files*****
  125.  
  126. ;----------------------------------------------------------------------------
  127.  
  128. ;User-set variables:
  129.  
  130. iport    equ    08h        ; MODEM data in port
  131. oport    equ    06h        ; MODEM data out port
  132. cport    equ    00h        ; MODEM control port
  133. mstat    equ    04h        ; MODEM status port
  134. bport    equ    02h        ; MODEM baudrate port
  135. mdrcv    equ    80h        ; receive ready bit
  136. mdsnd    equ    02h        ; send ready bit
  137. TCR    equ    010h        ; timer control register
  138. TMDR1L    equ    014h        ; timer data registers
  139. TMDR1H    equ    015h
  140. RLDR1L    equ    016h        ; timer reload registers
  141. RLDR1H    equ    017h
  142.  
  143.  
  144. userdef    equ    00145h        ; origin of this overlay: get this value
  145.                 ; from the .SYM file produced when ZMP.COM
  146.                 ; is linked
  147. ovsize    equ    0400h        ; max size of this overlay
  148.  
  149.  
  150. esc    equ    1bh
  151. ctrlq    equ    11h
  152. cr    equ    0dh
  153. lf    equ    0ah
  154. bdos    equ    5
  155.  
  156. ;=============================================================================
  157. ;        CODE STARTS HERE
  158.  
  159.     .hd64            ; use HD64180 code
  160. ;;    aseg            ; absolute
  161.  
  162.     org    userdef
  163.  
  164.  
  165. ;Jump table for the overlay: do NOT change this
  166. jump_tab:
  167.     jp    scrnpr        ; screen print
  168.     jp    mrd        ; modem read with timeout
  169.     jp    mchin        ; get a character from modem
  170.     jp    mchout        ; send a character to the modem
  171.     jp    mordy        ; test for tx buffer empty
  172.     jp    mirdy        ; test for character received
  173.     jp    sndbrk        ; send break
  174.     jp    cursadd        ; cursor addressing
  175.     jp    cls        ; clear screen
  176.     jp    invon        ; highlight (inverse video) on
  177.     jp    invoff        ; highlight (inverse video) off
  178.     jp    hide        ; hide cursor
  179.     jp    show        ; show cursor
  180.     jp    savecu        ; save cursor position
  181.     jp    rescu        ; restore cursor position
  182.     jp    mint        ; service modem interrupt
  183.     jp    invec        ; initialise interrupt vectors
  184.     jp    dinvec        ; de-initialise interrupt vectors
  185.     jp    mdmerr        ; test uart flags for error
  186.     jp    dtron        ; turn DTR (and RTS) ON
  187.     jp    dtroff        ; turn DTR (and RTS) OFF
  188.     jp    init        ; initialise uart
  189.     jp    wait        ; wait seconds
  190.     jp    mswait        ; wait milliseconds
  191.     jp    userin        ; user-defined entry routine
  192.     jp    userout        ; user-defined exit routine
  193.     jp    getvars        ; get system variables
  194.     jp    setport        ; Set the modem port being used
  195.  
  196. ;Spare jumps for compatibility with future versions
  197.     jp    spare        ; spares for later use
  198.     jp    spare        ; spares for later use
  199.     jp    spare        ; spares for later use
  200.     jp    spare        ; spares for later use
  201.     jp    spare        ; spares for later use
  202.     jp    spare        ; spares for later use
  203.     jp    spare        ; spares for later use
  204.     jp    spare        ; spares for later use
  205.  
  206. ;=============================================================================;
  207. ; Main code starts here
  208. ;
  209. codebgn    equ    $
  210.  
  211. ;
  212. ;Screen print function
  213. scrnpr:
  214.                 ; <== Insert your own code here
  215.     call    print
  216.     db    cr,lf
  217.     db    'Screen-print function not supported.',cr,lf,lf
  218.     db    0
  219.                 ; <== End of your own code
  220. spare:
  221.     ret
  222.  
  223. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  224. ;User-defined entry routine: leave empty if not used
  225. userin:
  226.     jp    dtron
  227. ;    ret
  228.  
  229. ;User-defined exit routine: leave empty if not used
  230. userout:
  231.     jp    dtroff
  232. ;    ret
  233.  
  234. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  235.  
  236. ;Get a character from the modem: return in HL
  237. ; It is not necessary to test for status
  238. mchin:
  239.     if    modints
  240.     push    bc
  241.     xor    a
  242.     ld    hl,buffer    ; Point to the buffer
  243.     out0    (mstat),a    ; turn off the interrupts
  244.     dec    (hl)        ; Update the character count (this sets flags)
  245.     ld    c,(hl)        ; Start putting character count in BC
  246.     inc    hl
  247.     ld    a,(hl)        ; Get the next character
  248.     jr    z,mchin1    ; Exit if that was the last character
  249.     ld    b,0        ; Now set up to update the buffer positions
  250.     ld    d,h
  251.     ld    e,l
  252.     inc    hl
  253.     ldir            ; Update the buffer
  254. mchin1:
  255.     ld    l,a
  256.     ld    a,08h
  257.     out0    (mstat),a    ; Turn interrupts on
  258.     pop    bc
  259.     ld    h,0
  260.     ld    a,l
  261.     or    a
  262.     ret
  263.     
  264.  
  265.     else
  266. ;    push    bc
  267.                 ; <== Insert your own code here
  268.     in0    a,(iport)    ; to get the character in A
  269.                 ; <== End of your own code
  270.     ld    l,a        ; put in HL
  271.     ld    h,0
  272.     or    a        ; set/clear Z
  273. ;    pop    bc
  274.     ret
  275.     endif    ;modints
  276. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  277.  
  278. ;Send a character to the modem
  279. mchout:
  280.     ld    hl,2        ; get the character
  281.     add    hl,sp
  282.     ld    a,(hl)        ; in A
  283.                 ; <== Insert your own code here
  284.     out0    (oport),a
  285.                 ; <== End of your own code
  286.     ret            ; done
  287.  
  288. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  289. ;Test for output ready: return TRUE (1) in HL if ok
  290. mordy:
  291.                 ; <== Insert your own code here
  292.  
  293.     ld    hl,00h        ; assume not ready for now
  294.     in0    a,(mstat)    
  295.     and    mdsnd
  296.     jr    z,mordy1    ; still not ready
  297.     inc    hl        ; ready, so set HL
  298.  
  299. mordy1:                ; <== End of your own code
  300.     ld    a,l        ; set/clear Z
  301.     or    a
  302.     ret
  303. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  304. ;Test for character at modem: return TRUE (1) in HL if so
  305. mirdy:
  306.     if    modints
  307.     ld    hl,1        ; assume character there
  308.     ld    a,(buffer)
  309.     or    a
  310.     ret    nz        ; return showing character there
  311.     ld    a,(dtrflg)
  312.     or    a
  313.     call    z,dtron        ; turn on DTR if it's off
  314.     xor    a
  315.     ld    h,a
  316.     ld    l,a
  317.     ret
  318.     else
  319.                 ; <== Insert your own code here
  320.  
  321.     ld    hl,00h        ; assume not ready for now
  322.     in0    a,(mstat)    
  323.     and    mdrcv
  324.     jr    z,mirdy1    ; still not ready
  325.     inc    hl        ; ready, so set HL
  326.  
  327. mirdy1:                ; <== End of your own code
  328.     ld    a,l        ; set/clear Z
  329.     or    a
  330.     ret
  331.     endif    ;modints
  332. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  333. ;Send a break to the modem
  334. sndbrk:
  335.     in0    a,(bport)
  336.     push    af
  337.     ld    a,02eh        ; Slow port down to slowest speed to
  338.     out0    (bport),a    ; force a framing error
  339.     xor    a
  340.     out0    (oport),a    ; send a 0
  341.     ld    hl,100
  342.     call    waithlms    ; wait for a moment
  343.     pop    af
  344.     if    cpu9
  345.     or    020h
  346.     else
  347.     and    0d0h
  348.     endif    ;cpu9
  349.     out0    (bport),a    ; restore the baudrate
  350.     ret
  351. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  352. ;Test UART flags for error: return TRUE (1) in HL if error
  353. mdmerr:
  354.                 ; <== Insert your own code here
  355.  
  356.     xor    a        ; not yet implemented
  357.  
  358.                 ; <== End of your own code
  359.     ld    a,l        ; set/clear Z
  360.     or    a
  361.     ret
  362.  
  363. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  364. ;Turn DTR (and RTS) ON. (reset)
  365. dtron:
  366.                 ; <== Insert your own code here
  367.     ld    a,1
  368.     ld    (dtrflg),a    ; Show other routines that DTR is on
  369.     in0    a,(cport)
  370.     and    0efh        ; RTS on
  371.     out0    (cport),a
  372.     call    dtrstat        ; pull control latch
  373.     ld    a,10111111b    ; mask off DTR bit
  374.     and    b        ; and it out
  375.     jr    dtrnxt
  376.                 ; <== End of your own code
  377.  
  378. ;Turn DTR (and RTS) OFF. (set)
  379. dtroff:
  380.                 ; <== Insert your own code here
  381.     xor    a
  382.     ld    (dtrflg),a    ; Show other routines that DTR is off
  383.     in0    a,(cport)
  384.     or    10h        ; RTS off
  385.     out0    (cport),a
  386.     call    dtrstat        ; pull control latch
  387.     ld    a,01000000b    ; mask off DTR bit
  388.     or    b        ; or it in
  389. dtrnxt:    ld    b,a
  390.     ld    a,0ffh        ; set up for write
  391. dtrnxt1:
  392.     ld    hl,(1)        ; get address of BIOS
  393.     ld    l,3fh        ; add offset for control latch
  394.     jp    (hl)        ; go to the latch routine and return from there
  395.                 ; <== End of your own code
  396.  
  397. ;Needed to prevent changes to other control latch registers.
  398.  
  399. dtrstat:
  400.     xor    a
  401.     jr    dtrnxt1
  402.  
  403. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  404. ;Initialise the UART
  405. init:
  406.     ld    hl,2        ; get parameters
  407.     add    hl,sp
  408.     ex    de,hl
  409.     call    getparm        ; in HL
  410.     ld    (brate),hl    ; baud rate
  411.     call    getparm
  412.     ld    (parity),hl    ; parity
  413.     call    getparm
  414.     ld    (data),hl    ; data bits
  415.     call    getparm
  416.     ld    (stop),hl    ; stop bits
  417.  
  418.                 ; <== Insert your own code here
  419.  
  420.     call    setprty        ; set parity
  421.     call    setbaud        ; set baud
  422.     call    setstop        ; set stop bits
  423.                 ; set word length and return from there
  424. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  425. wlength:
  426.     ld    a,(data)    ; get word length
  427.     cp    7
  428.     jr    z,wlen7        ; 7
  429.  
  430.                 ; assume 8
  431. wlen8:    in0    a,(cport)
  432.     or    04h        ; set bit 2
  433.     jr    wlnxt
  434.  
  435. wlen7:    in0    a,(cport)
  436.     and    0fbh        ; reset bit 2
  437.  
  438. wlnxt:    out0    (cport),a
  439.     jr    initsio        ; and reset any errors
  440.  
  441.                 ; <== End of your own code
  442.  
  443. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  444.  
  445. ;
  446. ; Set the port. ZMP supplies either 0 or 1 as a parameter. You're on your
  447. ; own here -- your system is bound to be different from any other! You may
  448. ; implement a software switch on all the modem-dependent routines, or perhaps
  449. ; you can have one or two centralised routines for accessing the UARTs and
  450. ; modify the code from this routine to select one or the other. (Who said
  451. ; there was anything wrong with self-modifying code?). If you have only one
  452. ; UART port, or if you don't want to go through all the hassles, just have
  453. ; this routine returning with no changes made. Note that ZMP calls this
  454. ; routine twice -- once for each port value -- on initialisation.
  455. ;
  456. setport:
  457.     ld    hl,2        ; get port number
  458.     add    hl,sp
  459.     ex    de,hl
  460.     call    getparm        ; in HL (values are 0 and 1)
  461.  
  462.                 ; <== Insert your own code here
  463.  
  464.                 ; <== End of your own code
  465.     ret
  466.  
  467.  
  468.  
  469. setbaud:      
  470.     ld    a,(brate)    ; get BRATE into A
  471.     ld    (mspeed),a    ; store the value in low memory for reentry
  472.     ld    e,a        ; and DE
  473.     ld    d,0
  474.     ld    hl,divisors    ; get offset into baudrate divisor table
  475.     add    hl,de
  476.     ld    a,(hl)        ; fetch code
  477.     inc    a        ; 0FFh means upsupported code
  478.     ret    z        ; exit if bad
  479.     in0    a,(bport)    ; get the current BPORT setting
  480.     and    0d0h        ; clear out the current baudrate
  481.     or    (hl)        ; get the new baudrate
  482.     out0    (bport),a    ; and set the port
  483.  
  484. initsio:            ; using values below
  485.     in0    a,(cport)
  486.     and    0f7h        ; reset errors
  487.     or    60h        ; enable xmit, receive; clear errors
  488.     out0    (cport),a
  489.     ret
  490.  
  491. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  492. setprty:
  493.     ld    a,(parity)    ; get parity into A
  494.     cp    'E'
  495.     jr    z,prevn        ; even
  496.     cp    'O'
  497.     jr    z,prodd        ; odd
  498.                 ; else assume none
  499. proff:    in0    a,(cport)
  500.     and    0fdh        ; reset bit 1
  501.     out0    (cport),a
  502.     jr    initsio        ; to reset errors
  503.  
  504. prevn:    in0    a,(cport)
  505.     or    02h        ; set bit 1
  506.     out0    (cport),a    ; send it to the port
  507.     in0    a,(bport)    ; get the current BPORT
  508.     and    0cfh        ; clear PEO
  509.     if    cpu9
  510.     or    020h
  511.     endif    ;cpu9
  512.     jr    prnxt
  513.  
  514. prodd:    in0    a,(cport)
  515.     or    02h        ; set bit 1
  516.     out0    (cport),a
  517.     in0    a,(bport)    ; get current BPORT
  518.     if    cpu9
  519.     or    030h        ; set PEO
  520.     else
  521.     and    0d0h
  522.     or    010h        ; set PEO
  523.     endif    ;cpu9
  524. prnxt:    out0    (bport),a
  525.     jr    initsio        ; reset errors
  526.  
  527. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  528. setstop:
  529.     ld    a,(stop)    ; get stopbits into A
  530.     cp    2
  531.     jr    z,stop2        ; two
  532.  
  533.                 ; assume one
  534. stop1:    in0    a,(cport)
  535.     and    0feh        ; reset bit 0
  536.     jr    ssnxt
  537.  
  538. stop2:    in0    a,(cport)
  539.     or    01h        ; set bit 0
  540.  
  541. ssnxt:    out0    (cport),a
  542.     jr    initsio        ; and reset errors
  543.  
  544.  
  545. ;****************************************************************************
  546. ; Video terminal sequences: these are for FALCO TS-1 -- Modify as you wish
  547.  
  548. ;Cursor addressing: 
  549. cursadd:
  550.     ld    hl,2        ; get parameters
  551.     add    hl,sp
  552.     ex    de,hl
  553.     call    getparm        ; in HL
  554.     ld    a,020h
  555.     add    a,l
  556.     ld    (cursr),a    ; put row value in
  557.     call    getparm
  558.     ld    a,020h
  559.     add    a,l
  560.     ld    (cursc),a    ; put column value in
  561.     call    print
  562.     db    esc,'='        ; Cursor address: leadin
  563. cursr:    db    0        ;                 row
  564. cursc:    db    0        ;                 column
  565.     db    0
  566.     ret
  567.  
  568.  
  569. ;Clear screen:
  570. cls:
  571.     call    print
  572.     db    01ah,0
  573.     ret
  574.  
  575. ;Highlight on:
  576. invon:
  577.     call    print
  578.     db    esc,')',0
  579.     ret
  580.  
  581. ;Highlight off:
  582. invoff:
  583.     call    print
  584.     db    esc,'(',0
  585.     ret
  586.  
  587. ;Turn off cursor:
  588. hide:
  589.     call    print
  590.     db    esc,'d0',0
  591.     ret
  592.  
  593. ;Turn on cursor:
  594. show:
  595.     call    print
  596.     db    esc,'d4',0
  597.     ret
  598.  
  599. ;Save cursor position:
  600. savecu:
  601. ;    ret
  602.  
  603. ;Restore cursor position:
  604. rescu:
  605.     ret
  606.  
  607. ;****************************************************************************
  608.  
  609. ;Service modem interrupt:
  610. mint:
  611.     if    modints
  612.     ld    (locstk),sp
  613.     ld    sp,locstk
  614.     push    hl
  615.     push    de
  616.     push    bc
  617.     push    af        ; Save the registers
  618.     in0    a,(mstat)
  619.     tst    070h        ; See if it was a receive error
  620.     jr    nz,minterr    ; It was a receive error, so go fix it
  621.     in0    c,(iport)    ; Get the character in C
  622.     ld    hl,buffer    ; Point to character count
  623.     inc    (hl)        ; Update it
  624.     ld    a,(hl)
  625.     cp    buflen
  626.     jr    nc,minterr    ; If buffer is full, then we won't put it in
  627.     ld    e,a        ; Get the new character count
  628.     ld    d,0        ; Character count in DE
  629.     add    hl,de        ; Point to character position
  630.     ld    (hl),c        ; Stick it in
  631.     cp    buflen-2    ; a still has the buffer length in it
  632.     call    nc,dtroff    ; Turn off DTR if buffer almost full
  633.     jr    mintex
  634.  
  635. minterr:
  636.     in0    a,(cport)    ; Control register A
  637.     and    0f7h        ; Ensure EFR=0
  638.     out0    (cport),a    ; Reset EFR
  639.     in0    a,(iport)    ; Throw the character away
  640. mintex:
  641.     pop    af
  642.     pop    bc
  643.     pop    de
  644.     pop    hl        ; Restore the registers
  645.     ld    sp,(locstk)
  646.     ei            ; Enable interrupts for the ASCI
  647.     endif    ;modints
  648.     ret
  649.  
  650. ;Initialise interrupt vectors:
  651. invec:
  652.     if    modints
  653.     in0    a,(033h)    ; get low byte of interrupt vector
  654.     or    0eh        ; add the bits for ASCI0
  655.     ld    (vecstore),a    ; put in buffer
  656.     ld    a,i
  657.     ld    (vecstore+1),a
  658.     ld    hl,(vecstore)
  659.     ld    e,(hl)        ; get old vector address
  660.     inc    hl
  661.     ld    d,(hl)
  662.     ld    (vecstore+2),de    ; save it
  663.     ld    de,mint
  664.     ld    (hl),d
  665.     dec    hl
  666.     ld    (hl),e
  667.     ld    a,08h
  668.     out0    (mstat),a    ; turn on the interrupts
  669.     ei
  670.     endif    ;modints
  671.     ret
  672.  
  673. ;De-initialise interrupt vectors:
  674. dinvec:
  675.     if    modints
  676.     xor    a
  677.     out0    (mstat),a    ; turn off interrupts
  678.     ld    hl,(vecstore)
  679.     ld    de,(vecstore+2)
  680.     ld    (hl),e
  681.     inc    hl
  682.     ld    (hl),d        ; and restore the vector
  683.     endif    ;modints
  684.     ret
  685.  
  686. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  687. ;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
  688. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  689. ;    GENERAL DATA AREA
  690.  
  691. dtrflg:    db    0        ; NZ if DTR is on
  692. port:    db    1        ; Holds the currently selected port number
  693. brate:    ds    2        ; baud rate:
  694.                 ; 0 = 110 baud    1 = 300 baud    2 = 450 baud
  695.                 ; 3 = 600 baud    4 = 710 baud    5 = 1200 baud
  696.                 ; 6 = 2400 baud    7 = 4800 baud    8 = 9600 baud
  697.                 ; 9 = 19200 baud
  698. parity:    ds    2        ; parity (will be 'N', 'E' or 'O')
  699. data:    ds    2        ; data bits (will be 7 or 8)
  700. stop:    ds    2        ; stop bits (will be 1 or 2)
  701.  
  702. divisors:
  703.       if cpu12        ; 12.288 MHz clock
  704. PRTrl    equ    61440
  705.     db    0ffh,0eh,0ffh    ; 0 = 110 baud    1 = 300 baud    2 = 450 baud
  706.     db    0dh, 0ffh,06h    ; 3 = 600 baud    4 = 710 baud    5 = 1200 baud
  707.     db    05h, 04h, 03h    ; 6 = 2400 baud    7 = 4800 baud    8 = 9600 baud
  708.     db    02h,01h,0ffh,0h    ; 9 = 19200 baud  10 = 38400 baud
  709.                 ; 11 = 57600 baud  12 = 76800 baud
  710.       endif
  711.  
  712.       if cpu9        ; 9.216 MHz clock
  713. PRTrl    equ    46080        ; PRT reload value for 100ms clock
  714.     db    0ffh,26h,0ffh    ; 0 = 110 baud    1 = 300 baud    2 = 450 baud
  715.     db    25h, 0ffh,24h    ; 3 = 600 baud    4 = 710 baud    5 = 1200 baud
  716.     db    23h, 22h, 21h    ; 6 = 2400 baud    7 = 4800 baud    8 = 9600 baud
  717.     db    20h,0ffh,0ffh    ; 9 = 19200 baud  10 = 38400 baud
  718.     db    0ffh        ; 11 = 57600 baud  12 = 76800 baud
  719.       endif
  720.  
  721.       if cpu6        ; 6.144 MHz clock
  722. PRTrl    equ    30720
  723.     db    0ffh,0dh,0ffh    ; 0 = 110 baud    1 = 300 baud    2 = 450 baud
  724.     db    06h, 0ffh,05h    ; 3 = 600 baud    4 = 710 baud    5 = 1200 baud
  725.     db    04h, 03h, 02h    ; 6 = 2400 baud    7 = 4800 baud    8 = 9600 baud
  726.     db    01h,0ffh,0ffh    ; 9 = 19200 baud  10 = 38400 baud
  727.     db    0ffh        ; 11 = 57600 baud  12 = 76800 baud
  728.       endif
  729.     if    modints
  730. vecstore:            ; storage for interrupt vector
  731.     dw    0        ; this is where it goes,
  732. vecs1:    dw    0        ; this is what it is
  733.     ds    16
  734. locstk:    ds    2        ; Interrupt stack
  735.     endif    ;modints
  736.  
  737.  
  738. ;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
  739. ;****************** End of user-defined code ********************************
  740. ; Don't change anything below this point.  We needed some assembly language
  741. ; stuff for speed, and this seemed like a good place to put it.
  742. ; Note by Simeon.... I have indeed changed this code... It has been done
  743. ; to allow high speed transfers, and uses the 64180 PRT1 as a timer.  Will
  744. ; definitely not work on a Z80 computer.
  745.  
  746. ;Modem character test for 100 ms
  747. mrd:
  748.     ld    de,PRTrl    ; 100 ms time constant
  749.     call    PRTset        ; Set up the timer
  750.     ld    l,c        ; Save c
  751.     ld    c,TCR        ; Point to timer control register
  752. mrd1:    call    mirdy        ; See if there is a character at the modem
  753.     jr    nz,mrd2        ; Exit if there is
  754.     TSTIO    080h        ; See if timer has overflowed yet
  755.     jr    z,mrd1        ; Keep checking modem if not
  756.     ld    hl,0
  757.     xor    a        ; Show no character
  758. mrd2:    ld    c,l        ; Restore C
  759.     ret
  760.  
  761. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  762.  
  763. ; Inline print routine: destroys A and HL
  764.  
  765. print:
  766.     ex    (sp),hl        ; get address of string
  767. ploop:
  768.     ld    a,(hl)        ; get next
  769.     inc    hl        ; bump pointer
  770.     or    a        ; done if zero
  771.     jr    z,pdone
  772.     call    cout        ; else print
  773.     jr    ploop        ; and loop
  774. pdone:
  775.     ex    (sp),hl        ; restore return address
  776.     ret            ; and quit
  777.  
  778. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  779. ;
  780. ;Output a character in A to the console
  781. ;
  782. cout:
  783.     push    bc        ; save regs
  784.     push    de
  785.     push    hl
  786.     ld    e,a        ; character to E
  787.     ld    c,2
  788.     call    bdos        ; print it
  789.     pop    hl
  790.     pop    de
  791.     pop    bc
  792.     ret
  793.  
  794. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  795. ;Wait(seconds)
  796. wait:
  797.     ld    hl,2
  798.     add    hl,sp
  799.     ex    de,hl        ; get delay size
  800.     call    getparm
  801.                 ; fall thru to..
  802. ;Wait seconds in HL
  803. waithls:
  804.     push    bc
  805.     ld    b,10        ; Do ten times
  806.     ld    de,PRTrl    ; time constant for 100ms
  807.     call    PRTset        ; Set up the registers
  808. ws3:    push    hl
  809. ws1:    in0    a,(TCR)
  810.     and    080h        ; See if timer has overflowed yet
  811.     jr    z,ws1
  812.     dec    hl
  813.     ld    a,l
  814.     or    h
  815.     jr    z,ws2    
  816.     in0    a,(TMDR1L)    ; Read the timer data register to reset flag
  817.     jr    ws1        ; And loop around again
  818.     
  819. ws2:
  820.     pop    hl    
  821.     dec    b    
  822.     jr    nz,ws3
  823.     pop    bc
  824.     ret
  825.  
  826. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  827. ;Wait milliseconds
  828. mswait:
  829.     ld    hl,2
  830.     add    hl,sp
  831.     ex    de,hl        ; get delay size
  832.     call    getparm
  833.                 ; fall thru to..
  834. ;Wait milliseconds in HL
  835. waithlms:
  836.     ld    de,[PRTrl]/100    ; time constant for 1ms
  837.     call    PRTset        ; Set up the registers
  838. wms1:    in0    a,(TCR)
  839.     and    080h        ; See if timer has overflowed yet
  840.     jr    z,wms1        ; Keep waiting until it does
  841.     dec    hl
  842.     ld    a,l
  843.     or    h
  844.     ret    z
  845.     in0    a,(TMDR1L)    ; Read the timer data register to reset flag
  846.     jr    wms1        ; And loop around again
  847.  
  848. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  849. PRTset:    ; Set up PRT1 with the time constant in DE (including reload registers)
  850.     ; Clear the interrupt flag, and start the counter
  851.     in0    a,(TCR)
  852.     and    0ddh
  853.     out0    (TCR),a        ; Inhibit down counting for PRT1
  854.     ld    a,e
  855.     out0    (TMDR1L),a
  856.     out0    (RLDR1L),a
  857.     ld    a,d
  858.     out0    (TMDR1H),a
  859.     out0    (RLDR1H),a    ; Set up the data and reload registers
  860.     in0    a,(TCR)
  861.     or    02h
  862.     out0    (TCR),a        ; Start the counter
  863.     in0    a,(TMDR1L)    ; Reset the interrupt flag
  864.     ret            ; And return
  865.  
  866. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  867. ;Get next parameter from (de) into hl
  868. getparm:
  869.     ex    de,hl        ; get address into hl
  870.     ld    e,(hl)        ; get lo
  871.     inc    hl
  872.     ld    d,(hl)        ; then hi
  873.     inc    hl        ; bump for next
  874.     ex    de,hl        ; result in hl, address still in de
  875.     ret
  876. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  877. ;Get address of user-defined variables
  878.  
  879. getvars:
  880.     ld    hl,uservars
  881.     ret
  882.  
  883. uservars:
  884.     dw    overdrive    ; .OVR etc. drive/user
  885.     dw    overuser
  886.  
  887. ;------------------------------------------------------------------------------
  888.     if    modints
  889. ; This is the buffer for the interrupt driven modem routines.  It will take
  890. ; up all the space to the end of the overlay if possible
  891.     if    [(ovsize + codebgn) - $] gt 0ffh
  892. buflen    equ    0ffh        ; Buffer length must be eight bits only
  893.     else
  894. buflen    equ    (ovsize + codebgn) - $
  895.     endif
  896. buffer:                ; Interrupt driven ASCI input buffer
  897.     db    0
  898.     ds    buflen-1
  899.     endif    ;modints
  900. ;------------------------------------------------------------------------------
  901.  
  902.      if    ($ - codebgn) gt ovsize
  903. toobig:    jp    errval        ; Overlay too large!
  904.      endif
  905.  
  906.  
  907.     end
  908.