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-CX02.Z80 < prev    next >
Text File  |  1991-02-02  |  19KB  |  873 lines

  1. ;-----------------------------------------------------------------------
  2. ;
  3. ;    Colex 8xx overlay for ZMP (Z-Modem Program)
  4. ;
  5. ;    Name  ZMO-CX02.Z80
  6. ;
  7. ;    Dated 12 November 1988
  8. ;
  9. ;    Written by - Jon Saxton +61-2-807-6746
  10. ;             Sydney, New South Wales.
  11. ;
  12. ;    Upgraded to v1.4 standard and renamed to ZMO-CX02.Z80
  13. ;        rjm 11/12/88
  14. ;
  15. ;    The Colex 850 is an STD Bus Z80 computer running CP/M Plus.
  16. ;    Serial I/O is driven by a Zilog 8530 SCC which is an extended
  17. ;    version of the Z80 SIO.
  18. ;
  19. ;    Whereas some of the code in this overlay is specific to the
  20. ;    Colex and the 8530, the baud rate setting is not hardware-
  21. ;    dependent and should work on any CP/M+ system which implements
  22. ;    character device control in the same manner as that published
  23. ;    by Digital Resarch in its sample CP/M+ BIOS.
  24. ;
  25. ;    I know that the Morrow MD-10 does NOT follow the standard.
  26. ;    This overlay will not work on a Colex 880 running TurboDOS.
  27. ;
  28. ;-----------------------------------------------------------------------
  29. ;
  30. ;    System-dependent code overlay for ZMODEM
  31. ;
  32. ; Insert your own code as necessary in this file.  Code contained
  33. ; herein  has been written in Z80 code for use with M80 or SLR.  Assemble
  34. ; as follows:
  35. ;
  36. ;    SLR ZMO-CLX+/h
  37. ;    MLOAD ZMP.COM=ZMPX.COM,ZMO-CLX+.HEX
  38. ;  or
  39. ;    M80 =ZMOCLX.Z80
  40. ;    RELHEX ZMOCLX
  41. ;    MLOAD ZMP=ZMPX.COM,ZMO-CLX+.HEX
  42. ;
  43. ;
  44. ; (Don't use L80 without changing the source for assembly as a CSEG
  45. ; file.)
  46. ;
  47. ;-----------------------------------------------------------------------
  48. ;
  49. ; Notes on modifying this file:
  50. ;
  51. ; C requires that functions do not change either index register (IX
  52. ; or IY).  If your overlay requires either of these to be changed, ensure
  53. ; they are restored to the original values on return.
  54. ;
  55. ; Since collecting parameters from C functions can be tricky, only
  56. ; change the parts marked 'Insert your own code here'.  Do NOT modify the
  57. ; jump table at the start.  Do NOT modify the entry/exit sections of each
  58. ; function.  Do NOT pass 'GO'.  Do NOT collect $200.
  59. ;
  60. ; Apart from defining modem functions, this file also defines
  61. ; terminal characteristics.  Examples provided are for ADM-3A (with a few
  62. ; of my own additions).  Modify to suit your own terminal.  An inline
  63. ; print routine is provided for printing strings in the usual way, usage
  64. ; is:
  65. ;
  66. ;              CALL    PRINT
  67. ;              DB    'required string',0
  68. ;
  69. ;-----------------------------------------------------------------------
  70. ;
  71. ;    Don't forget to set your clock speed at the clkspd variable.
  72. ;
  73. ; If you find your overlay exceeds the maximum size (currently 0400h)
  74. ; you will have to contact me for another version.  If too many people
  75. ; need to do it, we haven't allowed enough room.
  76. ;
  77. ; Ron Murray Aug 15, 88
  78. ;
  79. ;-----------------------------------------------------------------------
  80.  
  81. NO    EQU    0
  82. YES    EQU    NOT NO
  83.  
  84. ; Values shown are for a Z8530 SCC
  85.  
  86. PORT    equ    0H    ; Base port (data or status)
  87. MDCTL1    equ    PORT    ; Modem control port
  88. MDDATP    equ    PORT+2    ; Modem data port
  89. MDRCV    equ    01h    ; Modem receive ready
  90. MDSND    equ    04h    ; Modem send ready bit
  91. MDTXE    equ    01h    ; Modem send buffer empty, holding buffer empty
  92. MDERR    equ    70h    ; Modem error bits
  93.  
  94. ; User-set variables: ***********
  95.  
  96. ;Set the following two equates to the drive and user area which will contain
  97. ;   ZMP's .OVR files, .CFG file, .FON file and .HLP file. Set both to zero
  98. ;   (null) to locate them on the drive from which ZMP was invoked.
  99.  
  100. overdrive    equ    'A'    ; Drive to find overlay files on ('A'-'P')
  101. overuser    equ    0    ; User area to find files
  102.  
  103. CLKSPD    EQU    4        ; Processor clock speed in MHz
  104.  
  105. DEBUG    EQU    NO
  106.  
  107. USERDEF    EQU    0145H        ; Origin of this overlay.  This address
  108.                 ;   may change with subsequent revisions
  109. ; NOT user-set variables
  110.  
  111. MSPEED    EQU    03CH        ; Location of current baud rate.
  112. OVSIZE    EQU    0400H        ; Max size of this overlay
  113.  
  114.     .Z80            ; Use z80 code
  115.     ASEG            ; Absolute
  116.  
  117.      IF    DEBUG
  118.     ORG    100H        ; So you can debug it with CEBUG, ZSID,
  119.                 ;   etc.
  120.      ELSE
  121.     ORG    USERDEF
  122.      ENDIF            ; DEBUG
  123.  
  124. ESC    EQU    1BH
  125. CTRLQ    EQU    11H
  126. CR    EQU    0DH
  127. LF    EQU    0AH
  128. BDOS    EQU    5
  129.  
  130. ; Jump table for the overlay: do NOT change this
  131.  
  132. CODEBGN    EQU    $
  133.  
  134. JUMPTAB:JP    SCRNPR        ; Screen print
  135.     JP    MRD        ; Modem read with timeout
  136.     JP    MCHIN        ; Get a character from modem
  137.     JP    MCHOUT        ; Send a character to the modem
  138.     JP    MORDY        ; Test for tx buffer empty
  139.     JP    MIRDY        ; Test for character received
  140.     JP    SNDBRK        ; Send break
  141.     JP    CURSADD        ; Cursor addressing
  142.     JP    CLS        ; Clear screen
  143.     JP    INVON        ; Inverse video on
  144.     JP    INVOFF        ; Inverse video off
  145.     JP    HIDE        ; Hide cursor
  146.     JP    SHOW        ; Show cursor
  147.     JP    SAVECU        ; Save cursor position
  148.     JP    RESCU        ; Restore cursor position
  149.     JP    MINT        ; Service modem interrupt
  150.     JP    INVEC        ; Initialise interrupt vectors
  151.     JP    DINVEC        ; De-initialise interrupt vectors
  152.     JP    MDMERR        ; Test uart flags for error
  153.     JP    DTRON        ; Turn DTR on
  154.     JP    DTROFF        ; Turn DTR OFF
  155.     JP    INIT        ; Initialise uart
  156.     JP    WAIT        ; Wait seconds
  157.     JP    MSWAIT        ; Wait milliseconds
  158.     JP    USERIN        ; User-defined entry routine
  159.     JP    USEROUT        ; User-defined exit routine
  160.     jp    getvars        ; get system variables
  161.  
  162. ; Spare jumps for compatibility with future versions
  163.  
  164.     JP    SPARE        ; Spare for later use
  165.     JP    SPARE        ; Spare for later use
  166.     JP    SPARE        ; Spare for later use
  167.     JP    SPARE        ; Spare for later use
  168.     JP    SPARE        ; Spare for later use
  169.     JP    SPARE        ; Spare for later use
  170.  
  171.  
  172. ; Main code starts here
  173.  
  174. ; Screen print function
  175.  
  176. SCRNPR:    DS    0
  177.  
  178. ; <== Insert your own code here
  179.  
  180.     CALL    PRINT
  181.     DB    'This function not supported.',CR,LF,0
  182.  
  183. ; <== End of your own code
  184.  
  185. SPARE:    RET
  186.  
  187. ; User-defined entry routine: leave empty if not needed
  188.  
  189. USERIN:    RET
  190.  
  191. ; User-defined exit routine: leave empty if not needed
  192.  
  193. USEROUT:RET
  194.  
  195. ; Get a character from the modem: return in HL
  196.  
  197. MCHIN:    PUSH    BC
  198.  
  199. ; <== Insert your own code here
  200.  
  201. mchin2:
  202. ;    ld    a,10h        ;Select register 0
  203. ;    out    (MDCTL1),a
  204.     in    a,(MDCTl1)    ;Read register 0
  205.     and    MDRCV        ;Mask for receive data available
  206.     jr    z,mchin2    ;Loop until a character arrives
  207.     in    a,(MDDATP)    ;Receive the character
  208.  
  209. ; <== End of your own code
  210.  
  211.     LD    L,A        ; Put in HL
  212.     LD    H,0
  213.     OR    A        ; Set/clear Z
  214.     POP    BC
  215.     RET
  216.  
  217. ; Send a character to the modem
  218.  
  219. MCHOUT:    LD    HL,2        ; Get the character
  220.     ADD    HL,SP
  221. ;    LD    A,(HL)
  222.  
  223. ; <== Insert your own code here
  224.  
  225. mout2:
  226. ;    ld    a,10h        ;Select register 0
  227. ;    out    (MDCTL1),a
  228.     in    a,(MDCTl1)    ;Read register 0
  229.     and    MDSND        ;Mask for transmit buffer empty
  230.     jr    z,mout2
  231.  
  232.     LD    A,(HL)        ;Instruction moved from a few lines up
  233.  
  234.     out    (MDDATP),a
  235.  
  236. ; <== End of your own code
  237.  
  238.     RET            ; Done
  239.  
  240. ; Test for output ready: return YES (1) in HL if ok
  241.  
  242. MORDY:    DS    0
  243.  
  244. ; <== Insert your own code here
  245.  
  246.     ld    hl,0        ;Assume no character available
  247. ;    ld    a,10h        ;Select register 0
  248. ;    out    (MDCTL1),a
  249.     in    a,(MDCTl1)    ;Read register 0
  250.     and    MDSND        ;Mask for transmit buffer empty
  251.     jr    status
  252.  
  253. ; <== End of your own code
  254.  
  255. ; Test for character at modem: return YES (1) in HL if so
  256.  
  257. MIRDY:    DS    0
  258.  
  259. ; <== Insert your own code here
  260.  
  261.     ld    hl,0        ;Assume no character available
  262. ;    ld    a,10h        ;Select register 0
  263. ;    out    (MDCTL1),a
  264.     in    a,(MDCTl1)    ;Read register 0
  265.     and    MDRCV        ;Mask for receive data available
  266. status:
  267.     jr    z,noRDA
  268.     inc    hl
  269. noRDA:
  270.  
  271. ; <== End of your own code
  272.  
  273.     LD    A,L        ; Set/clear Z
  274.     OR    A
  275.     RET
  276.  
  277. ; Send a break to the modem: leave empty if your system can't do it
  278.  
  279. SNDBRK:    DS    0
  280.  
  281. ; <== Insert your own code here
  282.  
  283.     ld    a,5
  284.     out    (MDCTL1),a
  285.     ld    a,0F8H        ; Send break, 8 bits, DTR, etc.
  286.     out    (MDCTL1),a
  287.     LD    HL,300        ; Wait 300 mS
  288.     CALL    WAITHLMS
  289.     ld    a,5
  290.     out    (MDCTL1),a
  291.     ld    a,(wr5)        ; Restore preset parameters
  292.     out    (MDCTL1),a
  293.  
  294. ; <== End of your own code
  295.  
  296.     RET
  297.  
  298. ; Test UART flags for error: return YES (1) in HL if error
  299.  
  300. MDMERR:    DS    0
  301.  
  302. ; <== Insert your own code here
  303.  
  304.     ld    hl,0        ; Assume no error
  305.     ld    a,1        ; Select register 1
  306.     out    (MDCTL1),a
  307.     in    a,(MDCTL1)    ; Get error status bits
  308.     and    MDERR
  309.     jr    z,noErr
  310.     inc    hl
  311. noErr:
  312.  
  313. ; <== End of your own code
  314.  
  315.     LD    A,L        ; Set/clear Z
  316.     OR    A
  317.     RET
  318.  
  319. ; Turn DTR ON
  320.  
  321. DTRON:    DS    0
  322.  
  323. ; <== Insert your own code here
  324.  
  325.     ld    c,MDCTL1
  326.     ld    b,lenCtl
  327.     ld    hl,ctlStr
  328.     otir
  329.  
  330. ; <== End of your own code
  331.  
  332.     RET
  333.  
  334. ; Turn DTR OFF
  335.  
  336. DTROFF:    DS    0
  337.  
  338. ; <== Insert your own code here
  339.  
  340.     ld    a,5
  341.     out    (MDCTL1),a    ; Send to the status port
  342.     ld    a,68h        ; Turn off DTR, send break
  343.     out    (MDCTL1),a
  344.  
  345. ; <== End of your own code
  346.  
  347.     RET
  348.  
  349. ; Initialise the SCC
  350.  
  351. INIT:    LD    HL,2        ; Get parameters
  352.     ADD    HL,SP
  353.     EX    DE,HL
  354.     CALL    GETPARM        ; In HL
  355.     LD    (BRATE),HL    ; Baud rate
  356.     CALL    GETPARM
  357.     LD    (PARITY),HL    ; Parity
  358.     CALL    GETPARM
  359.     LD    (DATA),HL    ; Data bits (BINARY 7 or 8)
  360.     CALL    GETPARM
  361.     LD    (STOP),HL    ; Stop bits (BINARY 1 or 2)
  362.  
  363. ; <== Insert your own code here, using values below
  364.  
  365. ; Colex 850 initialization -- Calls BIOS routines to set baud rate
  366. ; then re-programs the SCC for selected framing.
  367. ;
  368. ; Generic CP/M+ method of setting baud rate.  This ONLY works if your
  369. ; CP/M+ BIOS follows the DRI model for character devices.  If not then
  370. ; this whole overlay is pretty useless to you.
  371.  
  372.     ld    a,(BRATE)    ; Get the selected value
  373.     cp    5            ; 1200 bps
  374.     jp    z,OK1200
  375.     cp    6            ; 2400 bps
  376.     jp    z,OK2400
  377.     cp    8            ; 9600 bps
  378.     jp    z,OK9600
  379.     cp    9            ; 19200 bps
  380.     jp    z,OK19200
  381.  
  382.     jr    SCC        ; Program the SCC even if baud rate is wrong
  383.  
  384. initRet:
  385.     ld    a,(BRATE)
  386.     LD    (MSPEED),A    ; Don't forget to load mspeed with the
  387.                 ;   current brate value if the new rate
  388.                 ;   is valid. See table of values below.
  389. SCC:
  390.  
  391. ; Set up data for SCC Write Register 4
  392.  
  393.     ld    b,44h        ; Clock 16, 1 stop, no parity
  394.     ld    a,(STOP)    ; Set stop bits
  395.     cp    2        ; Set 2 if required
  396.     jr    nz,chkOdd
  397.     set    3,b
  398. chkOdd:
  399.     ld    a,(PARITY)    ; Set parity bits
  400.     cp    'O'
  401.     jr    nz,chkEven
  402.     set    0,b        ; Odd
  403.     jr    setParity
  404. chkEven:
  405.     cp    'E'
  406.     jr    nz,setParity
  407.     set    0,b
  408.     set    1,b        ; EVEN
  409. setParity:
  410.     ld    a,b
  411.     ld    (wr4),a
  412.  
  413. ; Set up data for SCC Write Registers 5 and 3
  414.  
  415.     ld    b,0EAh        ; Assume DTR, transmit 8 bits, TxEn, RTS
  416.     ld    c,0C1h        ; Assume 8 bits on receive, RxEn
  417.     ld    a,(DATA)
  418.     cp    7
  419.     jr    nz,setDataBits
  420.     res    6,b        ; 7 bits
  421.     res    6,c
  422. setDataBits:
  423.     ld    a,b
  424.     ld    (wr5),a
  425.     ld    a,c
  426.     ld    (wr3),a
  427.  
  428.     ld    c,MDCTL1
  429.     ld    b,lenCtl
  430.     ld    hl,ctlStr
  431.     otir
  432.  
  433. ; <== End of your own code
  434.  
  435.     RET
  436.  
  437. ;-----------------------------------------------------------------------
  438.  
  439. STOP:    DW    1        ; Stop bits
  440. PARITY:    DW    'N'        ; Parity
  441. DATA:    DW    8        ; Data bits
  442. BRATE:    DW    6        ; Baud rate:
  443.  
  444. ;-----------------------------------------------------------------------
  445. ;
  446. ; Values of brate for each baud rate
  447. ;
  448. ; baud rate    brate
  449. ;
  450. ;    110     0
  451. ;    300     1
  452. ;    450     2
  453. ;    600     3
  454. ;    710     4
  455. ;   1200     5
  456. ;   2400     6
  457. ;   4800     7
  458. ;   9600     8
  459. ;  19200     9
  460. ;  38400    10
  461. ;  57600    11
  462. ;  76800    12
  463. ; 115200    13
  464. ;
  465. ;-----------------------------------------------------------------------
  466. ;
  467. ; Video terminal sequences: these are for Datapoint 8227.  Modify as you wish
  468. ;
  469. ; Cursor addressing:
  470.  
  471. CURSADD:LD    HL,2        ; Get parameters
  472.     ADD    HL,SP
  473.     EX    DE,HL
  474.     CALL    GETPARM        ; In HL
  475.     LD    (ROW),HL    ; Row
  476.     CALL    GETPARM
  477.     LD    (COL),HL    ; Column
  478.  
  479. ; <== Insert your own code here using values in row and column
  480.  
  481.     ld    a,9        ; 8227 leadin
  482.     call    rawOut        ; No interference from CP/M
  483.     ld    a,(col)        ; Column first
  484.     call    rawOut
  485.     ld    a,(row)        ; Row second
  486.     call    rawOut
  487.  
  488. ; <== end of your own code
  489.  
  490.     RET
  491.  
  492. rawOut:
  493.     ld    e,a
  494.     ld    c,6
  495.     jp    BDOS
  496.  
  497. ROW:    DS    2        ; Row
  498. COL:    DS    2        ; Column
  499.  
  500. ; Clear screen
  501.  
  502. CLS:    CALL    PRINT
  503.     DB    15h,17h,0
  504.     RET
  505.  
  506. ; Inverse video on
  507.  
  508. INVON:
  509.     CALL    PRINT
  510.     DB    ESC,5,0
  511.     RET
  512.  
  513. ;Inverse video off
  514.  
  515. INVOFF:    CALL    PRINT
  516.     DB    ESC,4,0
  517.     RET
  518.  
  519. ; Turn off cursor
  520.  
  521. HIDE:    ld    a,19h
  522.     call    rawOut
  523.     RET
  524.  
  525. ; Turn on cursor
  526.  
  527. SHOW:    ld    a,18h
  528.     call    rawOut
  529.     RET
  530.  
  531. ; Save cursor position
  532.  
  533. SAVECU:    RET
  534.  
  535. ; Restore cursor position
  536.  
  537. RESCU:    RET
  538.  
  539. ;-----------------------------------------------------------------------
  540. ;
  541. ; Service modem interrupt
  542.  
  543. MINT:    RET            ; My system doesn't need this
  544.  
  545. ; Initialise interrupt vectors
  546.  
  547. INVEC:    RET            ; Ditto
  548.  
  549. ; De-initialise interrupt vectors
  550.  
  551. DINVEC:    RET            ; Ditto
  552.  
  553. ;------------------- End of user-defined code --------------------------
  554. ;         Do not change anything below here
  555. ;
  556. ; Modem character test for 100 ms
  557.  
  558. MRD:    PUSH    BC        ; Save bc
  559.     LD    BC,100        ; Set limit
  560.  
  561. MRD1:    CALL    MIRDY        ; Char at modem?
  562.     JR    NZ,MRD2        ; Yes, exit
  563.     LD    HL,1        ; Else wait 1ms
  564.     CALL    WAITHLMS
  565.     DEC    BC        ; Loop till done
  566.     LD    A,B
  567.     OR    C
  568.     JR    NZ,MRD1
  569.     LD    HL,0        ; None there, result=0
  570.     XOR    A
  571.  
  572. MRD2:    POP    BC
  573.     RET
  574.  
  575. ; Inline print routine: destroys A and HL
  576.  
  577. PRINT:    EX    (SP),HL        ; Get address of string
  578.  
  579. PLOOP:    LD    A,(HL)        ; Get next
  580.     INC    HL        ; Bump pointer
  581.     OR    A        ; Done if zero
  582.     JR    Z,PDONE
  583.     CALL    COUT        ; Else print
  584.     JR    PLOOP        ; And loop
  585.  
  586. PDONE:    EX    (SP),HL        ; Restore return address
  587.     RET            ; And quit
  588.  
  589. ; Output a character in A to the console
  590.  
  591. COUT:    PUSH    BC        ; Save registers
  592.     PUSH    DE
  593.     PUSH    HL
  594.     LD    E,A        ; Character to E
  595.     LD    C,2
  596.     CALL    BDOS        ; Print it
  597.     POP    HL
  598.     POP    DE
  599.     POP    BC
  600.     RET
  601.  
  602. ; Wait(seconds)
  603.  
  604. WAIT:    LD    HL,2
  605.     ADD    HL,SP
  606.     EX    DE,HL        ; Get delay size
  607.     CALL    GETPARM
  608.                 ; Fall thru to...
  609. ; Wait seconds in HL
  610.  
  611. WAITHLS:PUSH    BC        ; Save BC
  612.     PUSH    DE        ; DE
  613.     PUSH    IX        ; And IX
  614.     LD    IX,0        ; Then point IX to 0
  615.                 ;   so we don't upset memory-mapped I/O
  616.  
  617. ; Calculate values for loop constants. Need to have two loops to avoid
  618. ; 16-bit overflow with clock speeds above 9 MHz.
  619.  
  620. OUTERVAL EQU    (CLKSPD    / 10) +    1
  621.  
  622. INNERVAL EQU    (6667 /    OUTERVAL) * CLKSPD
  623.  
  624. WAIT10:    LD    B,OUTERVAL
  625.  
  626. WAIT11:    LD    DE,INNERVAL
  627.  
  628. WAIT12:    BIT    0,(IX)        ; Time-wasters
  629.     BIT    0,(IX)
  630.     BIT    0,(IX)        ; 20 T-states each
  631.     BIT    0,(IX)
  632.     BIT    0,(IX)
  633.     BIT    0,(IX)
  634.     DEC    DE
  635.     LD    A,E
  636.     LD    A,D
  637.     OR    E
  638.     JR    NZ,WAIT12    ; 150 T-states per inner loop
  639.     DJNZ    WAIT11        ; Decrement outer loop
  640.     DEC    HL        ; Ok, decrement count in HL
  641.     LD    A,H
  642.     OR    L
  643.     JR    NZ,WAIT10
  644.     POP    IX        ; Done -- restore IX
  645.     POP    DE        ; DE
  646.     POP    BC        ; And BC
  647.     RET
  648.  
  649. ; Wait milliseconds
  650.  
  651. MSWAIT:    LD    HL,2
  652.     ADD    HL,SP
  653.     EX    DE,HL        ; Get delay size
  654.     CALL    GETPARM
  655.  
  656. ; Wait milliseconds in HL
  657.  
  658. WAITHLMS:
  659.     PUSH    DE
  660.  
  661. W1MS0:    LD    DE,39 *    CLKSPD
  662.  
  663. W1MS1:    DEC    DE
  664.     LD    A,D
  665.     OR    E
  666.     JR    NZ,W1MS1
  667.     DEC    HL
  668.     LD    A,H
  669.     OR    L
  670.     JR    NZ,W1MS0
  671.     POP    DE
  672.     RET
  673.  
  674. ; Get next parameter from (DE) into HL
  675.  
  676. GETPARM:EX    DE,HL        ; Get address into HL
  677.     LD    E,(HL)        ; Get low
  678.     INC    HL
  679.     LD    D,(HL)        ; Then hihi
  680.     INC    HL        ; Bump for next
  681.     EX    DE,HL        ; Result in HL, address still in DE
  682.     RET
  683.  
  684. OK300:
  685.     ld    e,BD300
  686.     jp    loadBd
  687. OK1200:
  688.     ld    e,BD1200
  689.     jp    loadBd
  690. OK2400:
  691.     ld    e,BD2400
  692.     jp    loadBd
  693. OK9600:
  694.     ld    e,BD9600
  695.     jp    loadbd
  696. OK19200:
  697.     ld    e,BD19200
  698. loadBd:
  699.     push    ix
  700.     push    iy
  701.     call    BRSET
  702.     pop    iy
  703.     pop    ix
  704.     jp    initRet
  705.  
  706. ;------------------------------------------------------------------------------
  707. ;
  708. ;    These routines set the baud rate for the SERIAL device.
  709. ;
  710. ;    Provided that your CP/M+ BIOS follows the DRI model with respect
  711. ;    to the character device table then you can very easily tailor
  712. ;    this routine to your own modem port.  The only thing you should
  713. ;    need to change is the device name....
  714. ;
  715. ;    Call BRSET with a baud rate selector in the E register and with
  716. ;    the name of the modem device set up at label devName:
  717. ;
  718. ;    Returns zero (and zero flag set) if no error.  Returns carry flag
  719. ;    true if device name is not in your BIOS's character device table.
  720. ;
  721. ;    Jon Saxton,
  722. ;    Tesseract RCPM+,
  723. ;    AUSTRALIA
  724. ;
  725. ;------------------------------------------------------------------------------
  726.  
  727. ; Baud rate selectors
  728.  
  729. bdNone    equ    0    ; no baud rate associated with this device
  730. bd50    equ    1    ; but don't use
  731. bd75    equ    2    ; 75 baud
  732. bd110    equ    3    ; 110 baud
  733. bd134    equ    4    ; 134.5 baud
  734. bd150    equ    5    ; 150 baud
  735. bd300    equ    6    ; 300 baud
  736. bd600    equ    7    ; 600 baud
  737. bd1200    equ    8    ; 1200 baud
  738. bd1800    equ    9    ; 1800 baud
  739. bd2400    equ    10    ; 2400 baud
  740. bd3600    equ    11    ; 3600 baud
  741. bd4800    equ    12    ; 4800 baud
  742. bd7200    equ    13    ; 7200 baud
  743. bd9600    equ    14    ; 9600 baud
  744. bd19200    equ    15    ; 19.2k baud
  745.  
  746. ; Enter with required baud rate selector in E register
  747.  
  748. DEVTBL    equ    20    ;BIOS function to return device table address
  749. DEVINI    equ    21    ;BIOS function to initialise a character device
  750.  
  751. BRSET:        
  752.  
  753. ; If we haven't already done so, find the address of the character device table
  754.  
  755.     ld    a,(gotIt)    ;Have we done this already?
  756.     or    a
  757.     jr    z,haveIt    ;Skip if we have been here already
  758.  
  759.     push    de        ;Save baud rate selector
  760.  
  761.     ld    a,DEVTBL    ;Get the device table address in HL
  762.     ld    (bpbFn),a
  763.     ld    de,bpb
  764.     ld    c,50
  765.     call    bdos
  766.  
  767.     ld    c,0FFh        ;Initialise device number
  768. dFind:
  769.     call    dMatch        ;Check current table entry
  770.     jp    c,notFound    ;Exit if device not listed
  771.     jp    nz,dFind    ;Continue if device not yet located
  772.  
  773.     ld    a,c        ;Store device number for re-entry
  774.     ld    (device),a
  775.     dec    hl        ;HL was pointing at the next device table
  776.                 ;entry so we step back to the baud rate
  777.                 ;field of the device we just scanned
  778.     ld    (baudByte),hl    ;and save the pointer for subsequent calls
  779.     xor    a        ;Signal that we have been here so we don't
  780.     ld    (gotIt),a    ;have to do this again
  781.     pop    de        ;Get new selector
  782. haveIt:
  783.     ld    hl,(baudByte)    ;Point at baud rate selector
  784.     ld    (hl),e        ;Stuff the new one in the table
  785.     ld    a,(device)    ;Pick up the device number
  786.     ld    (bpbC),a    ;Put it into the parameter block
  787.     ld    a,DEVINI    ;Set the BIOS function number
  788.     ld    (bpbFn),a
  789.     ld    c,50        ;Call the BIOS via the BDOS
  790.     ld    de,bpb
  791.     call    BDOS
  792.     xor    a        ;Clear the error flag
  793.     ret
  794.  
  795. notFound:
  796.     pop    de        ;Restore the stack
  797.     ret            ;Carry set, Zero reset
  798.  
  799. ; Compare the character device name in the table with that for which we
  800. ; are searching.  Return carry flag true if we are at the end of the
  801. ; device table.  Return zero flag true if we find the name we're looking
  802. ; for.  HL will be left pointing at the next device table entry. The
  803. ; current device number will be updated and returned in C.
  804.  
  805. dMatch:
  806.     inc    c        ;Step the device number
  807.     ld    a,(hl)        ;Check for end of table
  808.     or    a
  809.     scf            ;Exit with carry flag set if we have
  810.     ret    z        ;reached the end of the table
  811.     ld    de,devName    ;Point at the thing we're looking for
  812.     ld    b,6        ;Number of bytes to compare
  813.     push    hl        ;Save pointer to current entry
  814. dmLoop:
  815.     ld    a,(de)        ;Load byte from device name
  816.     sub    (hl)        ;Compare with byte from device table
  817.     jr    nz,dmExit    ;Break out if names are different
  818.     inc    hl        ;Step pointers
  819.     inc    de
  820.     dec    b
  821.     jr    nz,dmLoop    ;Loop until all bytes compared
  822. dmExit:
  823.     pop    hl        ;Recover table pointer
  824.     push    af        ;Save flags while we update the device
  825.     ld    de,8        ;table pointer
  826.     add    hl,de
  827.     pop    af        ;Recover result for caller
  828.     or    a        ;Ensure carry flag is off
  829.     ret
  830.  
  831. devName:
  832.     defm    'SERIAL'    ;Name of modem port device
  833. gotIt:
  834.     defb    0FFh        ;Initial entry flag
  835. device:
  836.     defs    1        ;Storage for device number
  837. baudByte:
  838.     defs    2        ;Holds pointer to baud rate selector
  839. bpb:
  840. bpbFn:    defs    1        ;BIOS parameter block - function number
  841.     defs    1        ;              - A register
  842. bpbC:    defs    6        ;              - BC, DE and HL
  843.  
  844. ctlStr:
  845.     db    0        ; Select register
  846.     db    18h        ; Throw out of mode
  847.     db    4        ; Select register
  848. wr4:    db    044h        ; Set ASCII parameters (44=1, 4C=2)
  849.     db    3        ; Select register
  850. wr3:    db    0C1h        ; Enable receive
  851.     db    5        ; Select register
  852. wr5:    db    0EAh        ; Enable send, DTR, RTS
  853. lenCtl    equ    $-ctlStr
  854.  
  855. ;-----------------------------------------------------------------------
  856.  
  857. ;Get address of user-defined variables
  858.  
  859. getvars:
  860.     ld    hl,uservars
  861.     ret
  862.  
  863. uservars:
  864.     dw    overdrive    ; .OVR etc. drive/user
  865.     dw    overuser
  866.  
  867.  
  868.      IF    ($ - CODEBGN) GT OVSIZE
  869. TOOBIG:    JP    ERRVAL        ; Overlay is too large
  870.      ENDIF
  871.  
  872.     END
  873.