qdosmsq:memory:sdrives

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
qdosmsq:memory:sdrives [2010/10/27 16:46]
george.gwilt 2nd draft
qdosmsq:memory:sdrives [2010/10/27 17:16] (current)
george.gwilt Complete 1st go for the moment
Line 1: Line 1:
 +====== Simple Device Drivers ======
  
 +A simple device driver can be added by linking a block in the common heap by means of [[qdosmsq:​traps:​trap_1:​lexi|MT_LIOD]].
 +
 +The block must have at least four long words.
 +
 +^Address^Item^
 +|$00|Space for link|
 +|$04|Address of I/O routine|
 +|$08|Address of OPEN routine|
 +|$0C|Address of CLOSE routine|
 +
 +The I/O sub system (IOSS) accesses these routines, in supervisor mode, to satisfy requests to use the device. That's probably why the block is called the access layer.
 +
 +Of course the I/O, OPEN and CLOSE routines have to be written.
 +==== OPEN Routine ====
 +
 +On entry to the OPEN routine the IOSS has set the registers as follows. The requirement on exit is also shown.
 +
 +^On entry^^On exit^
 +|D3.L|Open type| - |
 +|A0.L|Pointer to device name|Address of channel definition block|
 +|A3.L|Assumed start of driver definition block| - |
 +|A6.L|System variables| - |
 +
 +The OPEN routine must first check the device name and then set up the channel block. The device name should be checked by [[qdosmsq:​vectors:​dnam|IO_NAME]]. If all is well space for the channel block should be allocated by the vector [[qdosmsq:​vectors:​achp|MM_ALCHP]]. THe IOSS will fill in the first $18 bytes of this block and will also set the entry in the Channel Table.
 +==== CLOSE Routine ====
 +
 +On entry to the CLOSE routine the IOSS has set the registers as follows.
 +
 +|A0.L|Start of channel definition block|
 +|A3.L|Assumed start of driver definition block|
 +|A6.L|System variables|
 +
 +The space allocated for the channel block must be returned to the heap by the vector [[qdosmsq:​vectors:​rchp|MM_RECHP]].
 +==== I/O Routine ====
 +On entry to the I/O routine the registers are set by the IOSS as shown.
 +
 +|D0.L|Operation type|
 +|D1.L|Parameter|
 +|D2.L|Parameter|
 +|D3.L|0 on 1st entry, 1 on subsequent entries|
 +|A0.L|Channel definition block|
 +|A1.L|Parameter|
 +|A2.L|Parameter|
 +|A3.L|Assumed start of driver definition block|
 +|A6.L|System variables|
 +=== Notes ===
 +
 +  *The parameters in D1, D2, A1 and A2 as well as the value in D0 are what you would expect for a Trap #3 call.
 +  *Registers D2-7/A2-5 can be used as required.
 +  *D1 and A1 can be set for convenience on re-entry if needed.
 +
 +The device driver need only have three routines, test for pending input, read a byte and send a byte. The more complex operations can be covered by the vector [[qdosmsq:​vectors:​ssio|IO_SERIO]]. ​
 +
 +
 +
 +==== The MIM Device ====
 +Here is an example of the coding for a very simple device which just accesses RAM.
 +
 + This device has no parameters. Thus OPEN#​3,​MIM ​                            is all that is needed. (All types of open will work. Ie OPEN_IN, OPEN_NEW ​       ​
 + ​OPEN_OVER and even OPEN_DIR operate just like OPEN.) ​      
 +First set the addresses for [[qdosmsq:​vectors:​ssio|IO_SERIO]].
 +<​code>​
 +          lea       ​ptrs,​a0
 +          lea       ​io_ready,​a2
 +          move.l ​   a2,(a0)+
 +          lea       ​fetch,​a2
 +          move.l ​   a2,(a0)+
 +          lea       ​send,​a2
 +          move.l ​   a2,(a0)
 +</​code>​
 +Now set the addresses in the linkage block and link it in
 +<​code>​
 +          lea       ​linkage+4,​a0
 +          lea       IO,a2
 +          move.l ​   a2,(a0)+
 +          lea       ​open,​a2
 +          move.l ​   a2,(a0)+
 +          lea       ​close,​a2
 +          move.l ​   a2,(a0)
 +          lea       ​linkage,​a0
 +          moveq     #​mt_liod,​d0 ​        link in MIM
 +          trap      #1
 +          moveq     #0,d0
 +bad_exit ​ rts
 +</​code>​
 +== Linkage Block ==
 + This linkage block consists of 4 long words:
 +
 +|$00|Link to next device|
 +|$04|Pointer to IO routine|
 +|$08|Pointer to OPEN routine|
 +|$0C|Pointer to CLOSE routine|
 +<​code>​
 +linkage ​  ​dcb.l ​    ​4,​0 ​                4 long zeros
 +*
 +* This gets space from the heap for the 24 bytes needed for the minimum
 +* channel block plus 4 bytes to hold the address to which MIM currently
 +* points.
 +*
 +open      movea.w ​  ​io_name,​a4
 +          jsr       (a4)
 +          bra       ​bad_exit ​ ---->
 +          bra       ​bad_exit ​ ---->
 +          bra       ok
 +          dc.w      3
 +          dc.b      '​MIM',​0
 +          dc.w      0                   No parameters
 +ok        moveq     #​$1c,​d1 ​            get 28 bytes for . .
 +          movea.w ​  ​mm_alchp,​a4 ​        . . the channel block
 +          jmp       (a4)
 +*
 +close     ​movea.w ​  ​mm_rechp,​a4 ​        ​return to heap
 +          jmp       (a4)
 +*
 +IO        cmpi.b ​   #​fs_posab,​d0
 +          beq       posab
 +          cmpi.b ​   #​fs_posre,​d0
 +          beq       posre
 +          movea.w ​  ​io_serio,​a4 ​        Deal with other trap #3 . .
 +          jsr       ​(a4) ​               . . calls by IO.SERIO
 +*
 +* These three pointers are to:
 +*
 +*         io ready - here does nothing
 +*         fetch a byte to D1
 +*         send a byte from D1
 +*
 +* NOTE D1 has to end up containing the current position of the file
 +*      which is at $18(A0)
 +*
 +ptrs      dcb.l     3,0
 +          rts
 +*
 +fetch
 +          movea.l ​  ​$18(a0),​a1
 +          move.b ​   (a1),​d1 ​            Set the next byte to D1.B
 +fetch_1 ​  ​addq.l ​   #​1,​$18(a0) ​         Increment the current address
 +io_ready ​ moveq     #0,d0
 +          rts
 +*
 +send
 +          movea.l ​  ​$18(a0),​a0
 +          move.b ​   d1,(a0)
 +          bra       ​fetch_1
 +*
 +posab     ​move.l ​   d1,​$18(a0) ​         Set the current address
 +          bra       ​io_ready
 +*
 +posre     ​add.l ​    ​d1,​$18(a0) ​         Increment the current address . .
 +          move.l ​   $18(a0),​d1 ​         . . and set this in D1.L
 +          bra       ​io_ready
 +</​code>​
  • qdosmsq/memory/sdrives.txt
  • Last modified: 2010/10/27 17:16
  • by george.gwilt