SIO/2 and Interrupts

55 views
Skip to first unread message

Jon Jones

unread,
Apr 10, 2026, 7:01:10 PM (13 days ago) Apr 10
to retro...@googlegroups.com
I'm trying to use a SIO/2 with interrupts. I can get an interrupt triggered when there are characters to receive, but for anything else (Empty TX buffer, CTS change, break received) I get no interrupt. I've verified that things such as CTS change are happening with a 'scope so I know the hardware side is fine.

Below is the core of my setup code. Can anyone point me in a direction of what I might be doing wrong with the SIO/2 ?

Ta.

JJ


Start:
LD A, high interruptTable ; Configure interrupts
LD I,A
IM 2
EI ; And enable them.

CALL SerialSetup
CALL SerialInteruptInitalise
[Wait Loop]
RET

SerialSetup:
LD C, SerialPortAControl
LD HL,_serialSetupData
LD B, _serialSetupDataEnd - _serialSetupData
OTIR
RET

_serialSetupData:
BYTE 0b00011000 ; Wr0 Channel reset
BYTE 0b00010100 ; Wr0 Pointer R4 + reset ex st int
BYTE 0b11000100 ; Wr4 /64, async mode, no parity
BYTE 0b00000011 ; Wr0 Pointer R3
BYTE 0b11000001 ; Wr3 Receive enable, 8 bit
BYTE 0b00000101 ; Wr0 Pointer R5
BYTE 0b11101000 ; Wr5 Transmit enable, 8 bit, DTR
BYTE 0b00010001 ; Wr0 Pointer R1 + reset ex st int
BYTE 0b00000000 ; Wr1 No Tx interrupts
_serialSetupDataEnd:

SerialInteruptInitalise:
; Interrupt vector configuration must be done on Channel B
LD A, 0b00000010 ; Wr0 Pointer R2
OUT (SerialPortBControl), A
LD A, low serialInterruptTable ; Wr2 Interrupt vector
OUT (SerialPortBControl), A
LD A, 0b00000001 ; Wr0 Pointer R1
OUT (SerialPortBControl), A
LD A, 0b00000100 ; Register 1: Status Affects Vector
OUT (SerialPortBControl), A

; The rest can be done on the correct channel
LD C, SerialPortAControl
LD HL,_interruptSetupData
LD B, _interruptSetupDataEnd - _interruptSetupData
OTIR

RET

_interruptSetupData:
BYTE 0b00000001 ; Select Register 1
BYTE 0b00010010 ; TX Int En, Receive Int on 1st Char
BYTE 0b00100000 ; Register 0 Enable Int on next Rx
BYTE 0b00000101 ; Select Register 5
BYTE 0b11101010 ; Wr5 Transmit enable, 8 bit, DTR & RTS
BYTE 0b00000011 ; Select Register 3
BYTE 0b11000001 ; Register 3: 8 Bits, RX Enable - Must be last command
_interruptSetupDataEnd:

serialInterruptTable: ; The order of this table is defined by the SIO/2
WORD emptyInterruptHandler ; Channel B Transmit Buffer Empty
WORD emptyInterruptHandler ; Channel B External Status Change
WORD emptyInterruptHandler ; Channel B Receive Character Available
WORD emptyInterruptHandler ; Channel B Special Receive Condition
WORD serialATXReadyInterrupt ; Channel A Transmit Buffer Empty
WORD serialAStatusChange ; Channel A External Status Change
WORD serialARxReadyInterrrupt ; Channel A Receive Character Available
WORD serialASpecialRx ; Channel A Special Receive Condition

Wayne Hortensius

unread,
Apr 10, 2026, 8:01:04 PM (13 days ago) Apr 10
to retro...@googlegroups.com
A few things:

1. Is your interrupt table address a multiple of 16 (ie. xxx0)?
2. You're probably better disabling interrupts while programming the
SIO and enabling them afterwards.
3. This looks to me like you're not actually enabling any SIO
interrupts. Yes, the status will affect the vector, but I don't see how
you could get any interrupts called, because none of the enable bits
are set.

> LD A, 0b00000001 ; Wr0 Pointer R1
> OUT (SerialPortBControl), A
> LD A, 0b00000100 ; Register 1: Status Affects Vector
> OUT (SerialPortBControl), A

Regards,
Wayne

Ed Silky

unread,
Apr 11, 2026, 1:14:31 AM (13 days ago) Apr 11
to retro-comp
Hi Jon,

I agree with Wayne on #1. I would DI and put the first 4 lines that you have in 'start:' after you've initialized the SIO.
Next, although the 'status affects vector' bit is only in the CH-B WR1, the rest of the bits in WR1 need to be programmed (as desired) for both channels.

Also, for most operations you will want 'Rx Int on All Chars'. The interrupt on 1st char is typically used for block oriented protocols.
Finally, be aware that the TX interrupt only occurs when the TX buffer goes empty. That means that it must have not been empty first. So, you'll need to put a character in the TX buffer (to send) before you'll get that interrupt.

-Ed
Reply all
Reply to author
Forward
0 new messages