 lib environment
 opt nol
 lib macdefs
 lib inttab
 lib /usr/gary/src/uni.config/structures/task
 lib tty
 opt lis
 lib fio
 lib iop/fio_codes
 sttl Z8038 FIO Handler
 pag

DEB_MSG set 0 Print IOP/CPU traffic
DEB_SLP set 0 Print tasking messages - sleeping
DEB_WAK set 0 Print tasking messages - waking up
DEB_REQ set 0 Print I/O requests (by task)
DEB_TAB set 0 Print IOP Control tables
DEB_USR set 0 Debug Unsolicited Responses
ACT_COST set 2 Activity cost for IOP transaction

 data
 global fio_put,fio_delay,fio_get
 global fio_send,fio_rcv
 global fio_int
 global iop_open,iop_close,iop_write,iop_read,iop_spcl,findBRG

iop_wait fcb 0 Count of tasks waiting for IOP access (global)

*
* fio_put - Set a FIO register
*   A - FIO register #
*   B - Value to store
*   U - FIO device address
*
fio_put pshs cc must mask interrupts
 seti
 sta FIOctl,u address register
 stb FIOctl,u set value
 puls cc,pc

*
* fio_get - Fetch the value of a FIO register
*   A - FIO register #
*   B - Returned value
*   U - FIO device address
*
fio_get pshs cc must mask interrupts
 seti
 sta FIOctl,u select register
 ldb FIOctl,u fetch value
 puls cc,pc return

*
* fio_send - Send a value via the FIO Mailbox
*   B - Value to send (one byte)
*   U - FIO device address
*
fio_send pshs b,x save register
 lda #msg_out select outgoing mailbox
 bsr fio_put
 ldx #$FFFF time-out counter
10 lda #ctl_reg1 wait till value consumed
 bsr fio_get
 bitb #$20 "mailbox full" flag
 beq 20f jump when consumed
 leax -1,x timed out?
 bne 10b
 ldx #00f
 jsr Pdata
 lda 0,s
 jsr Phex
 ldx #01f
 jsr Pdata
 lda #ctl_reg1 wait till value consumed
 bsr fio_get
 tfr b,a
 jsr Phex
 ldx #02f
 jsr Pdata
 lda #ist_reg0 wait till value consumed
 lbsr fio_get
 tfr b,a
 jsr Phex
 puls b,x try again
 bra fio_send
20 puls b,x
 rts
*
00 fcc $d,'IOP Time out - Sending $',0
01 fcc ', CTL1 = $',0
02 fcc ', ISR0 = $',0

*
* fio_rcv - Receive a value via the FIO Mailbox
*   B - Value received
*   U - FIO device address
*
fio_rcv lda #ist_reg0 check for mail ready
10 lbsr fio_get check status
 bitb #$20 "mailbox full"?
 beq 10b
 lda #msg_in pick up the mail
 jsr fio_get
 rts

*
* fio_delay - Delay an appropriate time for FIO reset
*
fio_delay bsr 00f -- Ask GIMIX about this!
00 rts

*
* fio_int - Process IOP interrupt
*   U - FIO address
*   Y - IOP Control structure
*
fio_int pshs x,y
 leax iop_Q+3,y copy input Q
 lda ,-x
 pshs a -- Transaction specific value
 clr ,-s ** Filler **
 lda ,-x
 pshs a -- Sequence #
 lda ,-x
 pshs a -- Response code
 if DEB_MSG
 pshs d,x
 ldx #00f
 jsr Pdata
 lda 4,s
 jsr Phex
 ldx #01f
 jsr Pdata
 lda 5,s
 jsr Phex
 ldx #01f
 jsr Pdata
 lda 7,s
 jsr Phex
 puls d,x
 endif
 lda 0,s get response code
 cmpa #R_INTRPT
 bne 10f
 ldb 1,s relative terminal #
 jsr find_dn compute absolute terminal #
 ldx ttytab compute TTY table address
 lda #TTYSIZ
 mul
 leax d,x
 clra
 ldb 3,s get interrupt code
 jsr UFE_017 intrpt send interrupt to this terminal
 leas 4,s clean up stack
 bra 99f exit
* 0,s - response code
* 1,s - sequence #
* 3,s - transaction specific returned value
10 leay iop_tran,y point to transaction list
 ldb #MAX_TRAN # transactions
 pshs b
15 lda 2,s check transaction #
 cmpa tran_seq,y match?
 beq 20f yes - go
 leay TRAN_SIZ,y next transaction
 dec 0,s any more?
 bne 15b
* -- Unsolicited response!
 if DEB_USR
 ldx #02f
 jsr Pdata
 lda 1,s
 jsr Phex
 ldx #01f
 jsr Pdata
 ldd 2,s
 jsr Phex2
 ldx #01f
 jsr Phex
 lda 4,s
 jsr Phex
 ldx #03f
 jsr Pdata
 leas 5,s clean up stack
 ldy 2,s get IOP control address
 jsr dump_IOP go dump IOP control
 else
 leas 5,s clean up stack
 endif
 bra 99f exit
20 puls b clean up stack
 lda 0,s get response code
 sta tran_resp,y save response code
 lda 3,s get response value
 sta tran_val,y
 leas 4,s clean up stack
 jsr wakeup wake up sender
99 puls x,y,pc return
 if DEB_MSG
00 fcc $d,'FIO Int, Code = $',0
 endif
01 fcc "/",0
02 fcc $d,'Unsolicited response $',0
03 fcc ' - ignored',0

*
* fio_msg - Send a value via the FIO Mailbox & wait for response
*   D - Value to send (B = Command, A = Specific data)
*   U - FIO device address
*   Y - Interlock table
*   jsr fio_msg
*   D - Value returned (B = Error response, A = Specific data)
*
fio_msg pshs cc,d,x,y,u save registers
* -- Find an empty transaction box
10 seti turn off interrupts
 ldy 5,s get IOP control address
 jsr MBX_lock get access to IOP
 lbsr find_slot go find a slot
 beq 15f jump if one found
 ldy 5,s restore IOP structure pointer
 if DEB_SLP
 jsr p_slp_slot
 endif
 jsr MBX_unlock give up IOP until slot available
 lbsr find_slot make sure no slots available
 beq 10b jump if there is one
 ldy 5,s get IOP pointer
 leay iop_tflg,y sleep on transaction slots
 ldb #IOPPRI
 jsr Q_sleep wait for available message slot
 if DEB_SLP
 ldy 5,s
 jsr p_chk_slot
 endif
 bra 10b try for a transaction slot
15 ldb utask+1 set sequence # in slot
 orb #1
 stb tran_seq,y
 ldb 0,s enable interrupts
 tfr b,cc
 pshs y save transaction slot pointer
 ldy 7,s restore IOP structure pointer
 ldb 4,s restore message code
 if DEB_MSG
 pshs d,x
 ldx #00f
 jsr Pdata
 lda 1,s
 jsr Phex
 ldx #01f
 jsr Pdata
 ldx utask
 ldd tstid,x
 jsr Phex2
9 puls d,x
 endif
 lbsr fio_send
 ldb utask+1
 orb #1 set sequence #
 jsr fio_send
 ldb 3,s restore specific data
 jsr fio_send
 jsr MBX_unlock release mailbox
20 puls y get transaction slot address
 seti mask interrupts
 tst tran_resp,y any response yet?
 bne 30f yes - go process
 ldx 5,s get IOP control address
 ldd iop_fifo,x does this task own the FIFO?
 bne 25f yes - don't allow interrupts!
 pshs y,u save registers
 ldd umark1 set up to allow interruptable sleep
 pshs d
 ldx #27f interrupt handling label
 pshs x
 sts umark1
 ldb #TTYIPR set interruptable priority
 jsr A_sleep wait for IOP response
 puls d,x,y,u restore registers
 stx umark1 restore interrupt point
 bra 30f continue
27 puls x,y,u Interrupt happened! - (D) already popped
 stx umark1 restore stack mark
 lda #E_ABORT aborted transaction!
 sta tran_resp,y
 ldb 2,s send "interrupt" message to IOP
 andb #$03 get terminal #
 orb #O_INTRPT
 pshs y save transaction slot pointer
 ldy 7,s restore IOP control pointer
 jsr MBX_lock get access to mailbox
 jsr fio_send
 jsr fio_send -- These fields are ignored
 jsr fio_send -- and there will be no response
 jsr MBX_unlock release mailbox
 puls y restore transaction slot pointer
 bra 30f
25 ldb #IOPPRI
 pshs x,y,u save registers
 jsr A_sleep
 puls x,y,u restore registers
30 ldx utask
 if DEB_MSG
 pshs d,x
 ldx #05f
 jsr Pdata
 lda tran_resp,y
 jsr Phex
 ldx #01f
 jsr Pdata
 ldd tran_seq,y
 jsr Phex2
9 puls d,x
 endif
 seti turn off interrupts while fiddling with transaction slots
* -- See if there is a response.  It is possible to
* -- get here without one if an interrupt happened which
* -- was being ignored.  In this case, the IOP doesn't
* -- need to be notified of any interrupt, but we must
* -- wait for the IOP response to actually arrive.
 ldb tran_resp,y get response code
 bne 35f jump if response present
 pshs y reset stack
 bra 20b wait for response
35 clra release transaction slot
 sta tran_seq,y
 clr tran_resp,y
 lda tran_val,y get response value
 std 1,s set return value
 ldy 5,s wake anybody waiting for this slot
 leay iop_tflg,y
 jsr wakeup
 lda 2,s interrupted transaction?
 cmpa #E_ABORT
 bne 50f no - continue
 lds umark1 yes - get out
 rts
50 puls cc,d,x,y,u,pc return
 if DEB_MSG
00 fcc $d,'FIO MSG = $',0
01 fcc "/",0
05 fcc $d,'MSG Response = $',0
 endif

*
* find_slot - find a transaction slot
*   Y - IOP control address
*   jsr find_slot
*   Y - Transaction slot
*   <NE> if none available
*
find_slot pshs x,y save register
 leay iop_tran,y point to transactions
 ldb #MAX_TRAN
 pshs b
10 lda utask+1 check for busy entries
 ora #1
 cmpa tran_seq,y
 beq 30f yes - use it!
 leay TRAN_SIZ,y
 dec 0,s any more?
 bne 10b
 ldy 3,s restore IOP pointer
 leay iop_tran,y point to transactions
 ldb #MAX_TRAN
 stb 0,s
20 lda tran_seq,y entry busy?
 beq 30f no - use it!
 leay TRAN_SIZ,y
 dec 0,s any more?
 bne 20b
 lda #1 return NE - no slot
 bra 99f
30 sty 3,s return value
 clra return EQ - slot found
99 puls b,x,y,pc clean stack & return

*
* fifo_out - Select outgoing FIFO mode
*   U - FIO address
*
fifo_out pshs d,x,y,u save registers
 lda #ctl_reg3 FIFO direction bit in reg 3
 jsr fio_get
 andb #!FIO_IN set direction = OUT
 jsr fio_put
99 puls d,x,y,u,pc return

*
* fifo_in - Select incoming FIFO mode
*   U - FIO address
*
fifo_in pshs d,x,y,u save registers
 lda #ctl_reg3 FIFO direction bit in reg 3
 jsr fio_get
 orb #FIO_IN set direction = IN
 jsr fio_put
99 puls d,x,y,u,pc return

*
*  get_F_S - Allocate a transaction slot and the FIFO
*    Y - IOP control
*
get_F_S pshs cc,d,x,y,u save registers
 seti mask interrupts
 jsr find_slot allocate transaction slot
 beq 10f jump if one found
 ldy 5,s wait for slot
 leay iop_tflg,y
 ldb #IOPPRI
 jsr Q_sleep
 puls cc,d,x,y,u restore registers
 bra get_F_S try again
10 ldb utask+1 "allocate" slot
 orb #1
 stb tran_seq,y
 puls cc,d,x,y,u restore interrupts/registers
 jmp FIFO_lock lock FIO access

*
* iop_open - Open a terminal on the IOP
*   D = Device #
*
 if DEB_REQ
00 fcc $d,'IOP Open, Device = $',0
01 fcc ', Task = $',0
 endif
iop_open pshs d,x,y,u
 if DEB_REQ
 pshs d,x
 ldx #00b
 jsr Pdata
 ldd 0,s
 jsr Phex2
 ldx #01b
 jsr Pdata
 ldx utask
 ldd tstid,x
 jsr Phex2
 puls d,x
 endif
 lbsr iop_fdv compute device #
 bcc 00f jump if OK to open
 ldb #TTYOPR hang up task
 ldy iop_open ** this will never happen! **
 jsr sleep
00 pshs d,u,y save IOP parameters
05 ldb 1,s get device code
 orb #O_OPEN send "open device" request
 jsr fio_msg
 cmpb #E_SYSBSY if IOP saturated, try again
 bne 10f
 jsr p_iop_bsy print message
 bra 05b
10 ldy utask set controlling terminal
 ldd tstty,y
 bne 20f jump if already set
 ldd 6,s restore device code
 ldx ttytab compute "TTY" table address
 lda #TTYSIZ
 mul
 leax d,x
 stx tstty,y set controlling terminal
 ldd 6,s restore device #
 std tdevic,x set fake entry in TTY table
20 puls d,u,y clean up stack
99 puls d,x,y,u,pc

*
* iop_close - Close a terminal at the IOP
*
 if DEB_REQ
00 fcc $d,'IOP Close, Device = $',0
01 fcc ', Task = $',0
 endif
iop_close pshs d,x,y,u
 lbsr iop_fdv compute device #
 if DEB_REQ
 pshs cc,d,x
 ldx #00b
 jsr Pdata
 ldd 1,s
 jsr Phex2
 ldx #01b
 jsr Pdata
 ldx utask
 ldd tstid,x
 jsr Phex2
 puls cc,d,x
 endif
 bcs 99f jump if error
 pshs d,u,y save IOP parameters
00 ldb 1,s get device code
 orb #O_CLOSE send "close device" request
 jsr fio_msg
 cmpb #E_SYSBSY if IOP saturated, try again
 bne 10f
 jsr p_iop_bsy print message
 bra 00b
10 puls d,u,y clean up stack
99 puls d,x,y,u,pc

*
* iop_write - Write data to a terminal on the IOP
*
 if DEB_REQ
00 fcc $d,'IOP Write, Device = $',0
01 fcc ', Task = $',0
 endif
iop_write pshs d,x,y,u
 if DEB_REQ
 pshs d,x
 ldx #00b
 jsr Pdata
 ldd 0,s
 jsr Phex2
 ldx #01b
 jsr Pdata
 ldx utask
 ldd tstid,x
 jsr Phex2
 puls d,x
 endif
 lbsr iop_fdv compute device #
 bcs 99f jump if error
 pshs d,u,y save IOP parameters
00 ldd uicnt any data left?
 beq 90f no - exit
 cmpd #1 single character write?
 beq 50f yes - special case
 ldb 1,s get device code
 orb #O_RQWR send "request write data" request
 jsr fio_msg
 cmpb #E_SYSBSY if IOP saturated, try again
 bne 05f
 jsr p_iop_bsy print message
 bra 00b
05 jsr get_F_S allocate FIFO and a transaction slot
 lda #0 start queueing characters
10 pshs a,x,y,u save registers
 lbsr cpass get character
 puls a,x,y,u restore registers
 bmi 20f jump if no more
 stb FIOdata,u place character in FIFO
 inca update count
 cmpb #$09 TAB character?
 bne 15f
 adda #8 yes - assume 8 characters result
15 cmpa #FIO_SIZE
 blo 10b
20 tsta anything in FIFO?
 beq 30f no - exit
25 ldb 1,s get device code
 orb #O_WRITE set Write code
 jsr fio_msg signal IOP
 cmpb #E_SYSBSY if IOP saturated, try again
 bne 27f
 jsr p_iop_bsy print message
 bra 25b
27 jsr FIFO_unlock release interlock
 bra 00b continue
30 jsr FIFO_unlock release FIFO
 bra 90f exit
* -- Special case for single character write
50 pshs x,y,u save registers
 lbsr cpass fetch character from user
 puls x,y,u restore registers
 lda 1,s set up command
 ora #O_WRC write single character
 exg a,b a=data, b=command
 jsr fio_msg issue command
90 puls d,u,y clean up stack
99 puls d,x,y,u,pc

*
* iop_read - Read data from a terminal at the IOP
*
 if DEB_REQ
00 fcc $d,'IOP Read, Device = $',0
 endif
iop_read pshs d,x,y,u
 if DEB_REQ
 pshs d,x
 ldx #00b
 jsr Pdata
 ldd 0,s
 jsr Phex2
 puls d,x
 endif
 lbsr iop_fdv get IOP params
 lbcs 99f exit if error
 pshs d,y,u save IOP params
00 ldd uicnt how many more characters needed
 beq 90f exit if none
 ldb 1,s inform IOP we want data
 orb #O_RQRD
 jsr fio_msg
 cmpb #R_RD1C single character returned?
 beq 50f yes - go process it
 jsr get_F_S allocate FIFO
 jsr fifo_in allow IOP to send data
 ldd uicnt how much data to read?
 cmpd #FIO_SIZE can move no more than FIFO
 blo 05f
 ldd #FIO_SIZE
05 tfr b,a set request max size
 ldb 1,s tell IOP to send data
 orb #O_SEND
 pshs a save size of request
 jsr fio_msg
 cmpa #0 EOF?
 beq 20f yes - go process it
 pshs a,b save input count, response type
10 pshs a,x,y,u save registers
 ldb FIOdata,u get character
 lbsr UFE_016 passc send to user
 puls a,x,y,u restore registers
 deca any more this load?
 bne 10b yes - go get 'em
 jsr fifo_out restore FIFO mode
 jsr FIFO_unlock & release it to world
 puls a,b a=size returned, b=response code
 cmpa ,s+ less than requested amount
 bne 90f exit if not the same (must be less)
 cmpb #R_SNDMC Make sure there are more chars available
 beq 00b
 bra 90f exit
* -- IOP returned EOF
20 jsr fifo_out clean up FIFO
 jsr FIFO_unlock
 puls a clean up stack
 bra 90f exit
* -- Single character returned
50 tfr a,b get character
 pshs x,y,u save registers
 lbsr UFE_016 passc move to user
 puls x,y,u restore registers
90 puls d,y,u clean up stack
* -- Try to even loading
 ldy utask
 clr tsact,y
* --
99 puls d,x,y,u,pc

*
* iop_spcl - Perform TTYSET/TTYGET for an IOP terminal
*  X - =0 if doing ttyset
*     <>0 if ttyget
*
 if DEB_REQ
00 fcc $d,'IOP Special, Device = $',0
 endif
iop_spcl pshs d,x,y,u
 if DEB_REQ
 pshs cc,d,x
 ldx #00b
 jsr Pdata
 ldd 1,s
 jsr Phex2
 ldx #01b
 jsr Pdata
 ldx utask
 ldd tstid,x
 jsr Phex2
 puls cc,d,x
 endif
 lbsr iop_fdv compute device #
 bcs 99f jump if error
00 pshs d,y,u save registers
 jsr get_F_S allocate FIFO and a transaction slot
 ldx 6+2,s get ttyset/get parameter
 cmpx #0 ttyset?
 bne 50f no - do ttyget
 lda #6 move ttyset data into FIFO
 ldx #usarg0
10 ldb ,x+ move data
 stb FIOdata,u into FIFO
 deca
 bne 10b
 ldb 1,s get device code
 orb #O_TTYS send "ttyset" request
 jsr fio_msg
 bra 90f exit
50 jsr fifo_in set FIFO = IN mode
 ldb 1,s get device code
 orb #O_TTYG send "ttyget" request
 jsr fio_msg
 lda #6 move data from FIFO into buffer
60 ldb FIOdata,u get data from FIFO
 stb ,x+
 deca
 bne 60b
 jsr fifo_out reset FIFO direction
90 jsr FIFO_unlock release FIFO buffer
 puls d,u,y clean up stack
99 puls d,x,y,u,pc

*
* findBRG - Find Baud rate generators
*
findBRG rts

*
* MBX_lock - Lock the IOP interface
*    Y - IOP Control address
*
MBX_lock pshs cc,d,x,y,u save registers
 seti mask interrupts
 ldx utask get task pointer
 ldd iop_mbx,y mailbox already locked?
 beq 10f no - go check FIFO
 cmpd tstid,x locked by me?
 bne 20f no - must wait
10 ldd iop_fifo,y FIFO locked?
 beq 50f no - go lock mailbox
 cmpd tstid,x locked by me?
 beq 50f yes - still OK
20 inc iop_wait
 ldb #IOPPRI
 pshs y preserve register
 if DEB_SLP
 jsr p_slp_mbx
 if DEB_TAB
 jsr dump_IOP
 endif
 endif
 jsr Q_sleep yes - sleep until available
 puls y restore register
 if DEB_SLP
 jsr p_chk_mbx
 if DEB_TAB
 jsr dump_IOP
 endif
 endif
 dec iop_wait
 puls cc,d,x,y,u restore environ
 bra MBX_lock try again
50 ldd tstid,x lock mailbox
 std iop_mbx,y
 clr iop_int,y no missed interrupts
99 puls cc,d,x,y,u,pc return

*
* MBX_unlock - unlock the IOP interface
*
*    Y - IOP Control address
*
MBX_unlock pshs cc,d,x,y,u
 seti turn off interrupts
 lda iop_int,y did we miss an interrupt?
 beq 05f no - continue
 jsr fio_int yes - pretend we're seeing it now!
05 clr iop_int,y reset flag
 ldd #0
 std iop_mbx,y reset lock
 jsr wakeup wake up anybody waiting on this IOP
 ldy 5,s restore pointer
 lda iop_wait was anybody waiting?
 beq 10f no - exit
 if DEB_WAK
 jsr p_wak_mbx
 if DEB_TAB
 jsr dump_IOP
 endif
 endif
 ldx utask reset priority
 jsr fixpri
 jsr change let somebody else run
10 puls cc,d,x,y,u,pc return

*
* FIFO_lock - Lock the IOP FIFO buffer
*    Y - IOP Control address
*
FIFO_lock pshs cc,d,x,y,u save registers
 seti mask interrupts
 ldx utask get task pointer
 ldd iop_fifo,y FIFO locked?
 beq 10f no - go check mailbox
 cmpd tstid,x locked by me?
 bne 20f no - must wait
10 ldd iop_mbx,y mailbox already locked?
 beq 50f no - go lock FIFO
 cmpd tstid,x locked by me?
 beq 50f yes - still OK
20 ldb #IOPPRI
 inc iop_wait mark somebody waiting
 pshs y save pointer
 if DEB_SLP
 jsr p_slp_fifo
 if DEB_TAB
 jsr dump_IOP
 endif
 endif
 jsr Q_sleep yes - sleep until available
 puls y restore pointer
 if DEB_SLP
 jsr p_chk_fifo
 if DEB_TAB
 jsr dump_IOP
 endif
 endif
 dec iop_wait
 puls cc,d,x,y,u restore environ
 bra FIFO_lock try again
50 ldd tstid,x lock FIFO
 std iop_fifo,y
99 puls cc,d,x,y,u,pc return

*
* FIFO_unlock - unlock the IOP FIFO buffer
*
*    Y - IOP Control address
*
FIFO_unlock pshs cc,d,x,y,u
 seti turn off interrupts
 ldd #0
 std iop_fifo,y reset lock
 jsr wakeup wake up anybody waiting on this FIFO
 ldy 5,s restore pointer
 lda iop_wait was anybody waiting?
 beq 10f no - exit
 if DEB_WAK
 jsr p_wak_fifo
 if DEB_TAB
 jsr dump_IOP
 endif
 endif
 ldx utask reset priority
 jsr fixpri
 jsr change let somebody else run
10 puls cc,d,x,y,u,pc return

*
* Q_sleep - Sleep until event with decreased activity
*
Q_sleep jmp sleep

*
* A_sleep - Sleep until event with no decrease in activity
*
A_sleep jsr sleep wait for event
 pshs a,x upgrade activity
 ldx utask
 lda tsact,x
 adda #ACT_COST
 bcc 00f
 lda #$FF
00 sta tsact,x
 puls a,x,pc

*
* iop_fdv - Find device info for IOP terminal
*    D - device #
*    jsr iop_fdv
*    B - device # (0..2)
*    U - FIO base address
*    Y - FIO interlock
*    <Carry> if illegal device #
*
iop_fdv pshs d save device #
 ldx #inttab
 lda ,x+ get length of table
 pshs a
 ldd 1,s restore device #
00 cmpd indev,x device # match?
 beq 10f yes - continue
 leax INTSIZ,x
 dec 0,s no - any more in table?
 bne 00b yes - keep looking
 puls a clean up stack
 bra 90f exit
10 puls a clean up stack
 ldu instat,x get FIO address
 lda intype,x make sure this is an IOP terminal
 cmpa #2
 bne 90f bad device if not
 ldb inmask,x was it there (at initialization time)?
 beq 90f no - illegal device
 ldb inspcl,x get device #
 ldy intbrg,x get interlock address
 std 0,s return parameters
 clc no error
 bra 99f
90 lda #EBDEV illegal device #
 sta uerror
 sec
99 puls d,pc return

*
* find_dn - compute device # for a terminal on an IOP
*   B - relative device #
*   Y - IOP control address
*   jsr find_dn
*   D - absolute device #
*
find_dn pshs d,x,y,u save registers
 ldx #inttab search interrupt table
 lda ,x+ get length of table
10 cmpy intbrg,x This IOP?
 bne 20f no - continue
 cmpb inspcl,x device match?
 beq 30f yes - found it!
20 leax INTSIZ,x next entry please
 deca end of table?
 bne 10b
* -- Bad owies - couldn't find it!
 ldx #00f
 jsr Pdata
 lda 1,s
 jsr Phex
 ldx #01f
 jsr Pdata
 tfr y,d
 jsr Phex2
 ldd #0 return terminal 0
 bra 40f
30 ldd indev,x get device #
40 std 0,s set return value
 puls d,x,y,u,pc return
00 fcc $d,"Couldn't find device $",0
01 fcc ', on IOP $',0

*
* dump_IOP - Print IOP control info
*   Y - IOP control structure
*
dump_IOP pshs d,x,y,u
 ldx #00f
 jsr Pdata
 ldx #01f
 jsr Pdata
 ldd iop_mbx,y
 jsr Phex2
 ldx #02f
 jsr Pdata
 ldd iop_fifo,y
 jsr Phex2
 ldx #07f
 jsr Pdata
 lda iop_wait
 jsr Phex
 leay iop_tran,y
 ldb #MAX_TRAN
 pshs b
 ldx #03f
 jsr Pdata
10 ldx #04f
 jsr Pdata
 tfr y,d
 jsr Phex2
 ldx #05f
 jsr Pdata
 ldd tran_seq,y
 jsr Phex2
 ldx #06f
 jsr Pdata
 lda tran_resp,y
 jsr Phex
 leay TRAN_SIZ,y
 dec 0,s
 bne 10b
 puls b clean up stack
99 puls d,x,y,u,pc return
00 fcc $d,'IOP Control:',0
01 fcc $d,'   Mailbox lock = ',0
02 fcc $d,'   FIFO lock    = ',0
07 fcc $d,'   Waiting      = ',0
03 fcc $d,'   Slot   Sequence #   Response code',0
04 fcc $d,'   ',0
05 fcc '   ',0
06 fcc '         ',0
*
 if DEB_SLP
p_slp_slot pshs d,x,y,u
 ldx #00f
 jsr Pdata
 ldx utask
 ldd tstid,x
 jsr Phex2
 ldx #01f
 jsr Pdata
 puls d,x,y,u,pc return
00 fcc $d,'Task ',0
01 fcc ' waiting for a transaction slot',0
*
p_chk_slot pshs d,x,y,u
 ldx #00f
 jsr Pdata
 ldx utask
 ldd tstid,x
 jsr Phex2
 ldx #01f
 jsr Pdata
 puls d,x,y,u,pc return
00 fcc $d,'Task ',0
01 fcc ' retry on a transaction slot',0
*
p_slp_mbx pshs d,x,y,u
 ldx #00f
 jsr Pdata
 ldx utask
 ldd tstid,x
 jsr Phex2
 ldx #01f
 jsr Pdata
 tfr y,d
 jsr Phex2
 puls d,x,y,u,pc return
00 fcc $d,'Task $',0
01 fcc ' sleeping on Mailbox at $',0
*
p_chk_mbx pshs d,x,y,u
 ldx #00f
 jsr Pdata
 ldx utask
 ldd tstid,x
 jsr Phex2
 ldx #01f
 jsr Pdata
 tfr y,d
 jsr Phex2
 puls d,x,y,u,pc return
00 fcc $d,'Task $',0
01 fcc ' retry on Mailbox at $',0
*
p_slp_fifo pshs d,x,y,u
 ldx #00f
 jsr Pdata
 ldx utask
 ldd tstid,x
 jsr Phex2
 ldx #01f
 jsr Pdata
 tfr y,d
 jsr Phex2
 puls d,x,y,u,pc return
00 fcc $d,'Task $',0
01 fcc ' sleeping on FIFO at $',0
*
p_chk_fifo pshs d,x,y,u
 ldx #00f
 jsr Pdata
 ldx utask
 ldd tstid,x
 jsr Phex2
 ldx #01f
 jsr Pdata
 tfr y,d
 jsr Phex2
 puls d,x,y,u,pc return
00 fcc $d,'Task $',0
01 fcc ' retry on FIFO at $',0
 endif
 if DEB_WAK
*
p_wak_mbx pshs d,x,y,u
 ldx #00f
 jsr Pdata
 ldx utask
 ldd tstid,x
 jsr Phex2
 ldx #01f
 jsr Pdata
 tfr y,d
 jsr Phex2
 puls d,x,y,u,pc return
00 fcc $d,'Task $',0
01 fcc ' waking up Mailbox at $',0
*
p_wak_fifo pshs d,x,y,u
 ldx #00f
 jsr Pdata
 ldx utask
 ldd tstid,x
 jsr Phex2
 ldx #01f
 jsr Pdata
 tfr y,d
 jsr Phex2
 puls d,x,y,u,pc return
00 fcc $d,'Task $',0
01 fcc ' waking up FIFO at $',0
 endif
*
p_iop_bsy pshs d,x,y,u
 ldx #00f
 jsr Pdata
 ldx #$FFFF
10 leax -1,x
 bne 10b
99 puls d,x,y,u,pc
00 fcc $d,'IOP Saturated!',0
 end
