Changes

Jump to: navigation, search

Albireo

5,461 bytes removed, 12:43, 28 October 2020
/* Hardware */ Removed a lot of old information and updated link to Shinra website where I keep the info up to date. Having old info here just confuse people trying to use the board.
* When this switch is ON, the DTR signal from the remote side of the serial link is plugged to the DSR line of the UART controller. It then generates an interrupt which the CPC can process.
 
=== Detecting the hardware ===
 
==== Detecting the CH376 ====
 
You can use the CHECK_EXIST command for this. It gets one byte as argument, and returns the negation of it.
<pre>
CH376_CMD EQU 0xFE81
CH376_DATA EQU 0xFE80
 
CMD_CHECK_EXIST EQU 0X06
 
; Send the command
LD BC, CH376_CMD
LD E, CMD_CHECK_EXIST
OUT (C), E
 
; Send one data byte
LD BC, CH376_DATA
OUT (C), E
 
; Get the result
IN A, (C)
 
; Check that the result is the same as what we sent
XOR E
INC A
JR NC, ERROR_NOT_DETECTED
 
; Here, we know that the CH376 is present!</pre>
 
==== Detecting the TL16C550D ====
 
The T16C550D can be detected using its scratch register. This is a read/write register with no effect on the chip. We can check that writing a value there and reading it back works.
 
<pre>
SCR EQU 0xFEB7
 
LD BC, SCRATCH
LD A, 0x55
OUT (C), A
IN A, (C)
CP 0x55
JP NZ, ERROR_NOT_DETECTED
 
; Here, we know the TL16C550D is present!</pre>
 
=== Interrupts ===
 
All interrupts on the board are handled by the TL16C550D. They can be configured to trigger either an INT or an NMI, or nothing at all.
 
==== Individual interrupts control ====
 
The SC16C650B manages several different interrupt sources. These can be individually configured using the interrupt enable register.
 
* Bit 0: data receive interrupt, triggered whenever a byte is received on the serial line
* Bit 1: TX register empty, when the UART has nothing to send.
* Bit 2: receiver line status, to detect RTS/CTS handshaking
* Bit 3: modem status, used for all other interrupts (CH376, remote control, raster interrupt from CRTC cursor)
 
==== Interrupt routing ====
 
The interrupts can also be routed to NMI or INT, or none of them if you don't want your code to be interrupted. This is done using the OUT1 and OUT2 bits of the modem control register (MCR).
 
* OUT1 (MCR bit 2) must be set to 0 to enable INT.
* OUT2 (MCR bit 3) must be set to 0 to enable NMI.
* If both bits are set to 1, interrupts are disabled.
* If both bits are set to 0, both INT and NMI will be triggered, which is probably useless.
 
==== Interrupt identification ====
 
When an interrupt occurs, the first step in the interrupt handler is to identify where it comes from. This board provides support only for Z80 interrupt mode 1.
 
You get information about interrupts by first reading the IIR register. If bit 0 is set, it means Albireo is not the one which generated the interrupt. You should turn to other hardware plugged to your CPC, or, if all else fails, to the gate array interrupt.
 
If the bit is cleared, there is a pending interrupt from Albireo. You then look at bits 1-3 of IIR to determine which interrupt it is.
 
* 3: Receive line interrupt, read the LSR register for more details and to clear the interrupt.
* 2: RX data waiting, read the RX register to get the data and clear the interrupt.
* 6: RX timeout, read the RX register as soon as possible to get the data and clear the interrupt.
* 1: TX register empty, this is cleared by reading the IIR or writing more data bytes.
* 0: "modem status", means one of the external interrupts was triggered, read the MSR to learn more and clear the interrupt.
 
 
==== External interrupts ====
 
The identification of the external interrupts in the MSR is as follows:
 
* Bit 0: CTS, used for flow control of serial line. It is recommended to use automatic flow control, in that case this bit is unused and can be ignored.
* Bit 1: Remote control interrupt, when it is enabled using switch S4. This can be triggered from the other side of the serial link using the DTR pin.
* Bit 2: CRTC CURSOR raster interrupt. This is triggered when the CRTC CURSOR signal is activated. When not in use, it is recommended to disable the CURSOR signal using CRTC register 10 to avoid parasite interrupts coming from here.
* Bit 3: Interrupt request from the CH376. Note that this bit will be set both when the CH376 triggers an interrupt, and also when the interrupt is acknowledged on the CH376 side. This means a double-acknowledge scheme is required.
 
===== Double acknowledge of interrupts =====
Due to the way the interrupts are wired, the TL16C550D will trigger an interrupt both when the CH376 triggers one, but also when it is cleared by software. This means after clearing the CH376 interrupt, the interrupt flags of the TL16C550D should be checked again to make sure there isn't any other pending interrupt.
 
This is not a problem when using the INT pin, because everything will happen with interrupts masked by the z80. However, when using the NMI, there is no masking and this would trigger a new entry into the NMI routine, which is probably not what you want.
 
To avoid this problem in NMI mode, it is recommended that the NMI handler masks the NMI by using the OUT2 bit in MCR, while it processes the interrupt. This allows to perform all tasks as required. Once all interrupts have been cleared (IIR bit 0 is set again), it is safe to enable the NMI again.
 
The same applies for the remote control interrupt, when clearing it on the remote side a new interrupt will be triggered. A similar approach can be used: mask out the NMI, tell the remote side the interrupt is handled and let it clear the bit, acknowledge that with the TL16C550D, and finally enable the NMI again.
 
The CURSOR interrupt is not subject to this, because it is edge triggered. You can use it as an NMI source without such problems. The interrupt is cleared simply by reading the MSR register.
[http://pulkomandy.github.io/shinra.github.io/albireo.html Albireo interface homepage]
1,144
edits