home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / asmutl / asmlib.lbr / SBCMPC.AZM / SBCMPC.ASM
Assembly Source File  |  1991-06-25  |  8KB  |  315 lines

  1. ;****************************************************************
  2. ;*        This is a module in ASMLIB            *
  3. ;*                                *
  4. ;* This is the MPC-6  and SBC-800 console I/O super          *
  5. ;* re-directable I/O driver module for ASMLIB and the MPC-6.    *
  6. ;* This module is linked into  ASMLIB  in-place of the      *
  7. ;* original COE, CIE, CST drivers.                *         
  8. ;*                                *
  9. ;* This module supports the following devices and is selected   *
  10. ;* by sending the following codes to the console driver COE     *
  11. ;* which intercepts the code and directs the output to the     *
  12. ;* following devices.                        *
  13. ;*                                *
  14. ;*   Code        --- Device ---                *
  15. ;*    F8    SBC-800 standard I/O drivers. Standard default. *
  16. ;*                                    *
  17. ;*    F9    MPC-6 Channel 0                    *
  18. ;*    FA              1                    *
  19. ;*    FB              2                    *
  20. ;*    FC              3                    *
  21. ;*    FD              4                    *
  22. ;*    FE              5                    *
  23. ;*                                *
  24. ;* When the above codes are sent to the COE routine, they are   *
  25. ;* intercepted and used to SWITCH all further I/O to the     *
  26. ;* selected device from this point on.                *
  27. ;* This is extremely handy for having multiple I/O devices in a *
  28. ;* program selected chain.                    *
  29. ;*                                *
  30. ;*            Written        R.C.H.      14/11/83    *
  31. ;*            Last Update    R.C.H.       14/12/83    *
  32. ;****************************************************************
  33. ;
  34.     name    'SBCMPC'
  35.     public    coe,cie,cst,loe,lst,ionum
  36. ;
  37.     maclib    z80
  38. ;
  39. ;
  40. ; Equates for SBC-800 I/O addresses and device masks
  41. ;
  42. rxmsk    equ    1        ; For DART chips this applies
  43. txmsk    equ    4
  44. codat    equ    88h        ; Console ports on sbc800
  45. costat    equ    89h
  46. sestat    equ    8bh        ; Serial status port on SBC800
  47. serdat    equ    8ah        ; Serial data port on SBC800
  48. ; Equates for MPC-6 Card.
  49. ;
  50. mpcdat    equ    00        ; MPC-6 data port
  51. txstat    equ    01        ; MPC-6 transmitter status port
  52. rxstat    equ    02        ; MPC-6 receiver status port
  53. command    equ    txstat        ; MPC-6 command port
  54. reset    equ    03        ; MPC-6 reset port
  55. send    equ    010h        ; Opcode for sending a byte to MPC
  56. receive    equ    00        ; Opcode for receiving a byte from MPC
  57. ;
  58. num    equ    04        ; 0 = cpmio,2=sbc800io,3=cpmmpc,4=sbcmpc
  59. ;
  60. ionum:
  61.     mvi    l,num
  62.     ret
  63. ;
  64. ;----------------------------------------------------------------
  65. ; Get the status of the currently selected I/O device
  66. ;
  67. ; Channel = 0 then SBC-800
  68. ; Channel = 1 to 6 then MPC-6
  69. ;----------------------------------------------------------------
  70. ;
  71. cst:
  72.     lda    channel
  73.     ora    a            ; Channel 00 ?
  74.     jz    const            ; Get SBC-800 console status
  75. ; Here we get the status of the MPC-6 receiver stored in A.
  76.     dcr    a            ; make in the range 0..5
  77.     jr    mpcstat            ; Do the job and return to user
  78. ;
  79. ;----------------------------------------------------------------
  80. ;        Read A character
  81. ;        ----------------
  82. ;
  83. ; Use the channel number to select either the MPC-6 or the SBC-800 
  84. ; Channel allocations as before.
  85. ;----------------------------------------------------------------
  86. ;
  87. cie:
  88.     lda    channel
  89.     ora    a
  90.     jz    conin
  91.     dcr    a            ; make the channel number in range
  92.     jr    mpcread
  93. ;
  94. ;----------------------------------------------------------------
  95. ;        Output a character in A 
  96. ;        -----------------------
  97. ;
  98. ; Test if the character is a channel selector byte 
  99. ; Write character in A to MPC-6 or SBC-800, again depending on 
  100. ; selected channel number.
  101. ; Before writing, we test if it is a channel selector byte as
  102. ; defined previously.
  103. ;----------------------------------------------------------------
  104. ;
  105. coe:
  106.     push    psw            ; save the character
  107.     ani    0f8h            ;
  108.     cpi    0f8h            ; Mask to test top 5 bits
  109.     jrnz    coe2
  110. ; Here the byte is a channel selector
  111.     pop    psw            ; restore the byte
  112.     ani    07h            ; leave only the channel number there
  113.     cpi    07
  114.     rz                ; Ignore out of range value
  115.     sta    channel            ; Save the number
  116.     ret
  117. ;
  118. ; Here and it is not a channel selector, but a valid ascii byte < 0f8h
  119. ;
  120. coe2:    ; Do the channel test and jump
  121.     lda    channel
  122.     ora    a
  123.     jz    conout            ; do the job via SBC-800
  124. ;
  125.     jr    mpcsend            ; send it and return via MPC i/o driver
  126. ;
  127. ;----------------------------------------------------------------
  128. ;                     Get the MPC-6 status
  129. ;              --------------------
  130. ;
  131. ; Channel number is in the CHANNEL byte
  132. ; Return A = 00 = no character there all else = character there
  133. ;----------------------------------------------------------------
  134. ;
  135. mpcstat:
  136.     push    d
  137.     call    bitset            ; Get a channel mask into E
  138.     in    rxstat
  139. rdy:
  140.     ana    e            ; the desired channel ??
  141.     pop    d            ; restore register
  142.     rz
  143.     mvi    a,0ffh            ; load with 0ffh if not
  144.     ret
  145. ;
  146. ;----------------------------------------------------------------
  147. ;         Read an MPC-6 channel. 
  148. ;        ----------------------
  149. ;
  150. ; Channel number is in the CHANNEL byte
  151. ;----------------------------------------------------------------
  152. ;
  153. mpcread:
  154.     push    d
  155. ; Generate a channel mask in E 
  156.     call    bitset
  157. cari0:
  158.     in    txstat
  159.     ani    080h        ; we are truly busy, wait, if bit set
  160.     jrnz    cari0
  161. ;
  162. ; Wait till MPC-6 is ready with data for this channel
  163.     in    rxstat        ; channel mask
  164.     ana    e
  165.     jrz    cari0
  166. ;
  167.     in    txstat
  168.     ani    080h
  169.     jrnz    cari0
  170. ; Mask in the receive byte with the MPC-6 channel number
  171.     lda    channel        ; get the channel number
  172.     dcr    a        ; make it in range 0..5
  173.     ori    receive        ; Mask in the channel selected by the user
  174.     out    command
  175. cari1:
  176.     in    txstat
  177.     ani    080h
  178.     jrz    cari1
  179.     in    MPCDAT
  180. ; character is in A and ready for action
  181.     ani    07fh            ; mask off parity
  182. ;
  183.     pop    d            ; restore the register
  184.     ret
  185. ;
  186. ;----------------------------------------------------------------
  187. ;         Send data to the MPC-6 
  188. ;        ----------------------
  189. ;
  190. ; Data at stack TOP
  191. ; The channel number is saved in the CHANNEL byte and bitset uses
  192. ; this to generate channel mask bytes.
  193. ;----------------------------------------------------------------
  194. ;
  195. mpcsend:
  196.     pop    psw            ; get the character
  197.     push    b            ; save all user registers
  198.     push    d
  199. ;
  200.     mov    c,a            ; save the character for later
  201.     out    mpcdat            ; send the character to MPC-6
  202. caro0:
  203.     in    txstat
  204.     ani    080h
  205.     jrnz    caro0
  206. ; Get a channel mask into E
  207. ;
  208.     call    bitset
  209. ; Read status till MPC-6 accepts the character (mask in E)
  210. ;
  211. caro1:
  212.     in    txstat
  213.     ana    e
  214.     jrz    caro1
  215. ;
  216. ; Load the channel number, mask in the send command byte then send to MPC
  217. ;
  218.     lda    channel
  219.     dcr    a            ; make it in range 0..5
  220.     ori    send            ; tell MPC-6 we are sending data to it
  221.     out    command            ; send to command port
  222. ;
  223. ; A little delay for the MPC is done here to make sure it reads the byte
  224. ;
  225. delay:
  226.     mvi    a,030h
  227. del1:
  228.     dcr    a
  229.     jrnz    del1
  230. ; Restore the users character then his registers.
  231.     mov    a,c            ; restore the character
  232.     pop    d
  233.     pop    b
  234.     ret
  235. ;
  236. ;        ----------------
  237. ; Set bits to suit a selected MPC-6 channel.
  238. ; This is done by reading the channel byte to set a single bit
  239. ; in the byte returned in A
  240. ;        ----------------
  241. ;
  242. bitset:
  243.     push    b            ; save this
  244.     lda    channel            ; get channel number 1..6
  245.     mov    b,a            ; load into counter
  246.     xra    a            ; clear seed
  247.     stc                ; set carry
  248. ;
  249. ; Rotate the carry up the A register to generate a bit pattern
  250. ; for the required channel. Channel 0 -> 01, channel 4 -> 08 etc.
  251. ;
  252. bit0:
  253.     ral                ; rotate arith left thru carry
  254.     djnz    bit0            ; do for all bits
  255.     mov    e,a
  256.     pop    b            ; restore register
  257.     ret
  258. ;
  259. ;****************************************************************
  260. ;     SBC-800 i/o drivers. Used when channel = 00        *
  261. ;****************************************************************
  262. ;
  263. const:    in    costat            ; sbc status port
  264.     ani    rxmsk
  265.     rz
  266.     mvi    a,0ffh
  267.     ret                ; exit valid
  268. ;
  269. conin:    call    const
  270.     jrz    conin            
  271.     in    codat            ; character available
  272.     ani    7fh
  273.     ret
  274. ;
  275. conout: in    costat
  276.     ani    txmsk
  277.     jrz    conout
  278.     pop    psw            ; restore the character
  279.     out    codat            ; data port for SBC400
  280.     ret
  281. ;
  282. ; The line printer is assumed here to be the SBC-800 second
  283. ; serial port.
  284. ;
  285. loe:
  286.     push    psw
  287. loe1:
  288.            in    sestat
  289.     ani    txmsk
  290.     jrz    loe1
  291.     pop    psw
  292.     out    serdat            ; data port for SBC400
  293.     ret
  294. ;
  295. ; Get the serial output status.
  296. ;
  297. lst:
  298.           in    sestat            ; sbc status port
  299.     ani    txmsk
  300.     rz
  301.     mvi    a,0ffh
  302.     ret                ; exit valid
  303. ;
  304. ; Data storage is required to save the channel selection byte
  305. ; which is selected when the byte is sent to the COE driver
  306. ;
  307.     dseg
  308. channel    db    00            ; Holds the logged in channel number
  309.     end
  310.  
  311.  
  312.  
  313.