The Tube hardware provides 4 independent bi-directional comminication paths. Each consists of a one byte control register and a one byte data register (which may have multibyte buffering). The characterstics of each register set are decribed below, in the descriptions RnSTAT refers to status register n and RnDATA refers to its corresponding data register. Register Set 1 Host address Parasite address R1DATA write FEE1 FEF9 read (reading clears irq) R1STAT bit 7 data available/irq FEE0 FEF8 bit 6 not full In the parasite to host direction this register set is used for the OSWRCH call. The data register is a FIFO big enough to enable the longest VDU command (10 bytes) to reside within it. In the host to parasite direction the data register provides a 1 byte buffer. When the host writes to it an IRQ is generated to the parasite. It is used to pass on event interrupts and the escape operation. Register Set 2 Host address Parasite address R2DATA write FEE3 FEFB read R2STAT bit 7 data available FEE2 FEFA bit 6 not full This register set is used to implement long (in machine time used) OS calls, or those which (RDCH) cannot interrupt the WRCH host background task. The parasite passes a byte to describe the required action. The two machines then co-operate in passing data across R2DATA until the job is done. Register Set 3 Host address Parasite address R3DATA write read FEE5 FEFD R3STAT bit 7 data available/nmi FEE4 FEFC bit 6 not full R3DATA is programmeable (from the host) to be either a 1 or 2 byte FIFO. This register set is used for the background task of block data transfer between the two machines (cf register set 4). For higher performance applications this register may actually interface to a DMA controller. Register Set 4 Host address Parasite address R4DATA write (writing sets irq) FEE7 FEFF read (reading clears irq) R4STAT bit 7 data available/irq FEE6 FEFE bit 6 not full/irq This register set is used as a control channel for block transfers carried out across R3. The host interrupts the parasite by writing a byte describing the required action into R4DATA. The two machines then co-operate in passing data across register 4 [? sic - ed] until the job is done. The register set is also used to initiate the passing of an error string from host to parasite. The host interrupts the parasite by writing an error code into R4DATA, the two machines then cooperate in passing the error string across R2DATA. Notes: (i) The BBC machine operates by polling the tube registers for work. (ii) In all the transactions which may generate errors it is important to realise that if the error is reported by the BBC machine under interrupt (i.e. it was generated by a 6502 BRK sequence), the protocol which generated the error is abandoned. Non Interrupt protocols (parasite-side) OSWRCH Wait until R1DATA not full, write character into R1DATA. OSRDCH Wait until R2DATA not full, write RDCHNO (&00) to R2DATA Wait for data in R2DATA, top bit of R2DATA is 6502 C bit Wait for data in R2DATA, this is 6502 A register OSCLI Wait until R2DATA not full, write CLINO (&02) to R2DATA FOR all characters in the command string (including terminating CR) DO [ Wait until R2DATA not full, write character to R2DATA ] Wait for data in R2DATA and read it IF this byte =&80 THEN [ code has been loaded into the parasite by an interrupt protocol and it should be entered at the address given by the last R4 protocol type 4 address. ] OSBYTE IF osbyte < &80 THEN [ Wait until R2DATA not full, write SBYTNO (&04) to R2DATA Wait until R2DATA not full, write parameter for 6502 X register to R2DATA Wait until R2DATA not full, write osbyteno to R2DATA Wait for data in R2DATA, read R2DATA which is 6502 X register ] ELSEIF osbyteno = &82 THEN [ resultis machine high order address ] ELSEIF osbyteno = &83 THEN [ resultis low memory value ] ELSEIF osbyteno = &84 THEN [ resultis high memory value ] ELSE [ Wait until R2DATA not full, write SBYTNO (&04) to R2DATA Wait until R2DATA not full, write parameter for 6502 X register to R2DATA Wait until R2DATA not full, write parameter for 6502 Y register to R2DATA Wait until R2DATA not full, write osbyteno to R2DATA IF osbyteno = &9D THEN RETURN from protocol (no reply) Wait for data in R2DATA, bit 7 is 6502 C flag Wait for data in R2DATA, byte read is 6502 Y register Wait for data in R2DATA, byte read is 6502 X register ] OSWORD IF oswordno = &00 THEN [ Wait until R2DATA not full, write RDLNNO (&0A) to R2DATA Wait until R2DATA not full, write upper bound char to R2DATA Wait until R2DATA not full, write lower bound char to R2DATA Wait until R2DATA not full, write length allowed to R2DATA Wait until R2DATA not full, write &07 allowed to R2DATA Wait until R2DATA not full, write &00 allowed to R2DATA Wait for data in R2DATA IF this data > &7F THEN [ RETURN from protocol, escape was pressed ] Read a CR terminated string from R2DATA ] ELSE [ Wait until R2DATA not full, write WORDNO (&08) to R2DATA Wait until R2DATA not full, write oswordno to R2DATA Wait until R2DATA not full, write #params to send to R2DATA Wait parameter block to R2DATA, last byte first Wait until R2DATA not full, write #params to receive to R2DATA Read bytes back from R2DATA into parameter block, last byte first ] The number of parameters to send/receive is determined by: IF oswordno < &14 THEN [ oswordno parameters to send parameters to receive 1 0 5 2 5 0 3 0 5 4 5 0 5 2 5 6 5 0 7 8 0 8 14 0 9 4 5 10 1 9 11 1 5 12 5 0 13 0 8 14 16 16 15 16 16 16 16 13 17 13 1 18 0 128 19 8 8 20 128 128 ] ELSEIF oswordno < &80 THEN [ #params to send = 16 #params to receive = 16 ] ELSE [ byte 0 of transfer block = #params to send byte 1 of transfer block = #params to receive ] OSBPUT Wait until R2DATA not full, write BPUTNO (&10) to R2DATA Wait until R2DATA not full, write file handle to R2DATA Wait until R2DATA not full, write 6502 A to R2DATA (byte to write) Wait for data in R2DATA, discard it OSBGET Wait until R2DATA not full, write BGETNO (&0E) to R2DATA Wait until R2DATA not full, write file handle to R2DATA Wait for data in R2DATA, top bit of byte is 6502 C flag Wait for data in R2DATA, this is byte read from file OSFIND Wait until R2DATA not full, write FINDNO (&12) to R2DATA Wait until R2DATA not full, write type of open to R2DATA IF type = 0 THEN [ Wait until R2DATA not full, write file handle to R2DATA Wait for data in R2DATA, read result ] ELSE [ Wait until R2DATA not full, write file name string to R2DATA including CR Wait for data in R2DATA, read handle from R2DATA ] OSARGS Wait until R2DATA not full, write ARGSNO (&0C) to R2DATA Wait until R2DATA not full, write file handle to R2DATA Wait until R2DATA not full, write 4 bytes osarg_data to R2DATA (most significant byte first) Wait until R2DATA not full, write operation code to R2DATA Wait for data in R2DATA, read fs type from R2DATA Wait for data in R2DATA, read 4 bytes osarg_fs type from R2DATA (most significant byte first) Note: osarg_data is file sequential pointer or length depending on the type of OSARGS call. OSFILE Wait until R2DATA not full, write FILENO (&14) to R2DATA Wait until R2DATA not full, write 16 byte OSFILE control block to R2DATA (last byte written first) Wait until R2DATA not full, write filename to R2DATA including CR Wait until R2DATA not full, write type of transfer to R2DATA (transfer is completed under interrupt using R3, R4) Wait for data in R2DATA, low 7 bits is filing system type Wait for data in R2DATA, read 16 byte OSFILE control block (last byte first) OSGBPB Wait until R2DATA not full, write GBPBNO (&16) to R2DATA Wait until R2DATA not full, write 13 byte OSGBPB control block to R2DATA (last byte written first) Wait until R2DATA not full, write type of transfer to R2DATA (transfer is completed under interrupt using R3, R4) Wait for data in R2DATA, read 13 byte OSGBPB control block (last byte first) Wait for data in R2DATA, bit 7 is 6502 C flag Wait for data in R2DATA, read 6502 A register Interrupt driven operations In addition to thes parasite initiated activities the parasite is also required to respond to interrupts from registers 1, 3 and 4. The determine the source of an interrupt it is important to follow the order: 1. Check for register 4 interrupt 2. Check for register 1 interrupt Register 1 interrupts These occur only in the host to parasite direction. The interrupt sequence is: Read type byte from R1DATA IF type < 0 THEN [ ; Escape flag update Replace the escape flag with bit 6 of type RETURN from servicing interrupt ] ELSE [ ; Event signal Interrupt_R1_read 6502_Y event parameter Interrupt_R1_read 6502_X event parameter Interrupt_R1_read 6502_A event parameter ; BBC machine will now continue processing ; actions to service event can now be taken ] Where Interrupt_R1_read is: UNTIL data ready in R1 DO [ IF data ready in R4 THEN CALL R4_interrupt_service ] RETURN read R1DATA Register 5 interrupts Read type byte from R4DATA IF type < 0 THEN [ ; BBC machine is reporting an error Wait for data in R2DATA, read and discard it Wait for data in R2DATA, read error number from R2DATA Read a zero byte terminated string from R2DATA ] ELSE [ ; type is a command to initiate a register 3 block transfer Wait for data in register 4, read claimer identity from R4DATA CASE type OF [ 0 : ; Single byte transfer parasite to host Read 4 byte base address for transfer from R4DATA, msb first Set NMI routine for this transfer type Wait for and remove synchronising byte from R4DATA 1 : ; Single byte transfer host to parasite Read 4 byte base address for transfer from R4DATA, msb first Set NMI routine for this transfer type Wait for and remove synchronising byte from R4DATA 2 : ; Double byte transfer parasite to host Read 4 byte base address for transfer from R4DATA, msb first Set NMI routine for this transfer type Wait for and remove synchronising byte from R4DATA 3 : ; Double byte transfer host to parasite Read 4 byte base address for transfer from R4DATA, msb first Set NMI routine for this transfer type Wait for and remove synchronising byte from R4DATA 4 : ; No transfer (pass address host to parasite only) Read 4 byte base address for transfer from R4DATA, msb first Wait for data in R4DATA, discard it 5 : ; No transfer (filing system release) 6 : ; 256 byte transfer parasite to host without interrupt Read 4 byte base address for transfer from R4DATA, msb first Wait for data in R4DATA, discard it Transfer 256 bytes to host via R3DATA Write a byte into R4DATA to stop unwanted interrupts on host 7 : ; 256 byte transfer host to parasite without interrupt Read 4 byte base address for transfer from R4DATA, msb first Wait for data in R4DATA, discard it Transfer 256 bytes from host via R3DATA ] RETURN from interrupt ] Notes: (i) For type 0-3: As soon as the synchronising byte is removed register 3 transfer requests (NMIs) will start to occur. When the interrupt occurs 1 or 2 bytes are transferred (depending on the current mode). (ii) A release (type 5) is a guarantee that no more register 3 NMIs will occur for the current transfer. (iii) The transfers must take place within the following times: Type Max Service Time Delay between sync and transfer start 0 24uS per byte 24uS 1 24uS per byte 24uS 2 26uS per byte 24uS 3 26uS per byte 24uS 6 10uS per byte 19uS 7 10uS per byte 19uS END