home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpm / asmutl / asmlib1.lbr / CPMMPC.AYM / CPMMPC.AYM
Encoding:
Text File  |  1994-05-31  |  9.3 KB  |  351 lines

  1. ;****************************************************************
  2. ;*        This is a module in ASMLIB            *
  3. ;*                                *
  4. ;* This is the MPC-6 and CP/M super-duper all singing        *
  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    CP/M 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.       22/02/84    *
  32. ;****************************************************************
  33. ;
  34.     name    'CPMMPC'
  35.     public    coe,cie,cst,loe,lst,ionum
  36. ;
  37.     maclib    z80
  38. ;
  39. bdos    equ    5
  40. num    equ    3        ; 01 = cpmio, 02 = sbc800io, 03 = this
  41. in$off    equ    6        ; Bios table offset from entry 00
  42. ot$off    equ    9
  43. st$off    equ    3
  44. ;
  45. ; Equates for MPC-6 Card.
  46. ;
  47. mpcdat    equ    00        ; MPC-6 data port
  48. txstat    equ    01        ; MPC-6 transmitter status port
  49. rxstat    equ    02        ; MPC-6 receiver status port
  50. command    equ    txstat        ; MPC-6 command port
  51. reset    equ    03        ; MPC-6 reset port
  52. send    equ    010h        ; Opcode for sending a byte to MPC
  53. receive    equ    00        ; Opcode for receiving a byte from MPC
  54. ;
  55. ionum:
  56.     mvi    l,num
  57.     ret
  58. ;
  59. ;----------------------------------------------------------------
  60. ; Get the status of the currently selected I/O device
  61. ;
  62. ; Channel = 0 then CP/M
  63. ; Channel = 1 to 6 then MPC-6
  64. ;----------------------------------------------------------------
  65. ;
  66. cst:
  67.     lda    channel
  68.     ora    a            ; Channel 00 ?
  69.     jz    const            ; Get console status
  70. ; Here we get the status of the MPC-6 receiver stored in A.
  71.     dcr    a            ; make in the range 0..5
  72.     jr    mpcstat            ; Do the job and return to user
  73. ;
  74. ;----------------------------------------------------------------
  75. ;        Read A character
  76. ;        ----------------
  77. ;
  78. ; Use the channel number to select either the MPC-6 or the CP/M
  79. ; Channel allocations as before.
  80. ;----------------------------------------------------------------
  81. ;
  82. cie:
  83.     lda    channel
  84.     ora    a
  85.     jz    conin
  86.     dcr    a            ; make the channel number in range
  87.     jr    mpcread
  88. ;
  89. ;----------------------------------------------------------------
  90. ;        Output a character in A 
  91. ;        -----------------------
  92. ;
  93. ; Test if the character is a channel selector byte 
  94. ; Write character in A to MPC-6 or CP/M, again depending on 
  95. ; selected channel number.
  96. ; Before writing, we test if it is a channel selector byte as
  97. ; defined previously.
  98. ;----------------------------------------------------------------
  99. ;
  100. coe:
  101.     push    psw            ; save the character
  102.     ani    0f8h            ;
  103.     cpi    0f8h            ; Mask to test top 5 bits
  104.     jrnz    coe2
  105. ; Here the byte is a channel selector
  106.     pop    psw            ; restore the byte
  107.     ani    07h            ; leave only the channel number there
  108.     cpi    07
  109.     rz                ; Ignore out of range value
  110.     sta    channel            ; Save the number
  111.     ret
  112. ;
  113. ; Here and it is not a channel selector, but a valid ascii byte < 0f8h
  114. ;
  115. coe2:    ; Do the channel test and jump
  116.     lda    channel
  117.     ora    a
  118.     jz    conout            ; do the job via CP/M
  119. ;
  120.     jr    mpcsend            ; send it and return via MPC i/o driver
  121. ;
  122. ;----------------------------------------------------------------
  123. ;                     Get the MPC-6 status
  124. ;              --------------------
  125. ;
  126. ; Channel number is in the CHANNEL byte
  127. ; Return A = 00 = no character there all else = character there
  128. ;----------------------------------------------------------------
  129. ;
  130. mpcstat:
  131.     push    d
  132.     call    bitset            ; Get a channel mask into E
  133.     in    rxstat
  134. rdy:
  135.     ana    e            ; the desired channel ??
  136.     pop    d            ; restore register
  137.     rz
  138.     mvi    a,0ffh            ; load with 0ffh if not
  139.     ret
  140. ;
  141. ;----------------------------------------------------------------
  142. ;         Read an MPC-6 channel. 
  143. ;        ----------------------
  144. ;
  145. ; Channel number is in the CHANNEL byte
  146. ;----------------------------------------------------------------
  147. ;
  148. mpcread:
  149.     push    d
  150. ; Generate a channel mask in E 
  151.     call    bitset
  152. cari0:
  153.     in    txstat
  154.     ani    080h        ; we are truly busy, wait, if bit set
  155.     jrnz    cari0
  156. ;
  157. ; Wait till MPC-6 is ready with data for this channel
  158.     in    rxstat        ; channel mask
  159.     ana    e
  160.     jrz    cari0
  161. ;
  162.     in    txstat
  163.     ani    080h
  164.     jrnz    cari0
  165. ; Mask in the receive byte with the MPC-6 channel number
  166.     lda    channel        ; get the channel number
  167.     dcr    a        ; make it in range 0..5
  168.     ori    receive        ; Mask in the channel selected by the user
  169.     out    command
  170. cari1:
  171.     in    txstat
  172.     ani    080h
  173.     jrz    cari1
  174.     in    MPCDAT
  175. ; character is in A and ready for action
  176.     ani    07fh            ; mask off parity
  177. ;
  178.     pop    d            ; restore the register
  179.     ret
  180. ;
  181. ;----------------------------------------------------------------
  182. ;         Send data to the MPC-6 
  183. ;        ----------------------
  184. ;
  185. ; Data at stack TOP
  186. ; The channel number is saved in the CHANNEL byte and bitset uses
  187. ; this to generate channel mask bytes.
  188. ;----------------------------------------------------------------
  189. ;
  190. mpcsend:
  191.     pop    psw            ; get the character
  192.     push    b            ; save all user registers
  193.     push    d
  194. ;
  195.     mov    c,a            ; save the character for later
  196.     out    mpcdat            ; send the character to MPC-6
  197. caro0:
  198.     in    txstat
  199.     ani    080h
  200.     jrnz    caro0
  201. ; Get a channel mask into E
  202. ;
  203.     call    bitset
  204. ; Read status till MPC-6 accepts the character (mask in E)
  205. ;
  206. caro1:
  207.     in    txstat
  208.     ana    e
  209.     jrz    caro1
  210. ;
  211. ; Load the channel number, mask in the send command byte then send to MPC
  212. ;
  213.     lda    channel
  214.     dcr    a            ; make it in range 0..5
  215.     ori    send            ; tell MPC-6 we are sending data to it
  216.     out    command            ; send to command port
  217. ;
  218. ; A little delay for the MPC is done here to make sure it reads the byte
  219. ;
  220. delay:
  221.     mvi    a,030h
  222. del1:
  223.     dcr    a
  224.     jrnz    del1
  225. ; Restore the users character then his registers.
  226.     mov    a,c            ; restore the character
  227.     pop    d
  228.     pop    b
  229.     ret
  230. ;
  231. ;        ----------------
  232. ; Set bits to suit a selected MPC-6 channel.
  233. ; This is done by reading the channel byte to set a single bit
  234. ; in the byte returned in A
  235. ;        ----------------
  236. ;
  237. bitset:
  238.     push    b            ; save this
  239.     lda    channel            ; get channel number 1..6
  240.     mov    b,a            ; load into counter
  241.     xra    a            ; clear seed
  242.     stc                ; set carry
  243. ;
  244. ; Rotate the carry up the A register to generate a bit pattern
  245. ; for the required channel. Channel 0 -> 01, channel 4 -> 08 etc.
  246. ;
  247. bit0:
  248.     ral                ; rotate arith left thru carry
  249.     djnz    bit0            ; do for all bits
  250.     mov    e,a
  251.     pop    b            ; restore register
  252.     ret
  253. ;
  254. ;****************************************************************
  255. ;     CP/M    I/O drivers. Used when channel = 00        *
  256. ;          Send the accumulator to the screen            *
  257. ;****************************************************************
  258. ;
  259. conout:
  260. ;The character to send is on the stack 
  261.     pop    psw            ; get the output character
  262.     push    h
  263.     push    b
  264.     push    d            ; save all registers
  265.     push    psw            ; Save the character
  266.     mov    c,a            ; Load the character to be sent
  267.     lxi    d,ot$off        ; input offset
  268.     lxi    h,retadr1
  269.     jr    get$con$com
  270. ;
  271. ;----------------------------------------------------------------
  272. ;     Send the accumulator character to the list device
  273. ;----------------------------------------------------------------
  274. ;
  275. loe:
  276.     push    psw
  277.     push    h
  278.     push    b
  279.     push    d
  280.     mov    e,a            ; load the character to print
  281.     mvi    c,5              ; print list function
  282.     call    bdos
  283.     pop    d
  284.     pop    b
  285.     pop    h
  286.     pop    psw
  287.     ret
  288. ;
  289. ;----------------------------------------------------------------
  290. ;           Get a character from the console
  291. ;----------------------------------------------------------------
  292. ;
  293. conin:
  294.     push    h
  295.     push    b
  296.     push    d            ; save all registers
  297.     lxi    d,in$off        ; input offset
  298.     lxi    h,retadr2
  299. ;
  300. get$con$com:
  301.     push    h            ; Load a return address
  302.     lhld    1            ; get the warm boot vector
  303.     dad    d            ; Now hl = bios table address to use
  304.     pchl            ; do the routine
  305. ;
  306. ; Return here to restore all registers
  307. retadr1:
  308.     pop    psw        
  309. ; To skip PSW, return here
  310. retadr2:
  311.     pop    d
  312.     pop    b
  313.     pop    h
  314.     ora    a            ; Set flags, clear carry
  315.     ret
  316. ;
  317. ;----------------------------------------------------------------
  318. ; Get the console status. 00 = no character all else = read.
  319. ;----------------------------------------------------------------
  320. ;
  321. const:    ; Get the status
  322.     push    h
  323.     push    b
  324.     push    d            ; save all registers
  325.     lxi    d,st$off        ; input offset
  326.     lxi    h,retadr2        ; load the required return address
  327.     jr    get$con$com        ; read the console common code
  328. ;
  329. ;----------------------------------------------------------------
  330. ; Get the list output status. If = 00 then no character may be
  331. ; sent to the device.
  332. ;----------------------------------------------------------------
  333. ;
  334. lst:
  335.     mvi    a,0ffh            ; Not supported yet
  336.     ora    a
  337.     ret                ; return the device as ready
  338. ;
  339. ;
  340. ; Data storage is required to save the channel selection byte
  341. ; which is selected when the byte is sent to the COE driver
  342. ;
  343.     dseg
  344. channel    db    00            ; Holds the logged in channel number
  345.     end
  346.  
  347.  
  348.  
  349.