8302

Nagging hardware related question? Post here!
Post Reply
Nasta
Gold Card
Posts: 443
Joined: Sun Feb 12, 2012 2:02 am
Location: Zapresic, Croatia

8302

Post by Nasta »

Here is an attempt to systematize the information and internal workings of the 8302 ULA (also known as the Peripheral Chip).
I'll start with the addresses the 8302 uses and later fill in what i can surmise about the hardware based on this. I would be very thankful for anyone in the know to supply more data to fill out the unknowns that still remain (mostly marked with an asterisk * ).

First the addresses - keep in mind the 8302 has only address lines A0, A1 and A5, and a chip select called PCENL (or /PCEN). There is also DSMCL (or /DSMC) which is actually a copy of /DS. There is some redundancy here, which will be discussed later on. /PCEN is generated by the 8301 which is therefore responsible to decode the remaining address bits so that the 8302 ends up accessed at the addresses as outlined below. In reality, it aliases to many addresses (with some dependency to the actual 8301 version being used, and the motherboard issue). In any case, any OS uses the following addresses:
(Sorry, I can't seem to get the formatting to display properly for the table below)

Address A5 A1,0 Read; Write
$18000 0 00 RTC seconds HH; RTC set?
$18001 0 01 RTC seconds HL ; RTC set?
$18002 0 10 RTC seconds LH ; Transmit control
$18003 0 11 RTC seconds LL; IPC write
$18020 1 00 IPC/MDV/SER status; Microdrive control
$18021 1 01 Interrupt status; Interrupt mask and control
$18022 1 10 Microdrive read track 1; Transmit data
$18023 1 11 Microdrive read track 2; Not implemented?

Here is a breakdown of the control registers in detail, such as i have been able to gather:

$18000..3 READ RTC seconds timer

Reads the RTC 32-bit second counter as a long word.
Because the counter is read one byte at a time, it can get incremented between two bytes being read so the read can miss a carry between one byte and the next when the counter increments. The simple way to get around this is to check for two consecutive long word reads that return the same value.


EDITED:

$18000 WRITE RTC reset

Anything written here will reset the RTC counter back to $00000000


$18001 WRITE RTC set register

The top 4 bits are not implemented, and the bottom 4 bits are used to increment each byte in the 4-byte RTC second counter:

7..4 = don't care, normally written as 1111
3 = 0 written here will increment the top byte of the seconds counter
2 = 0 written here will increment the next lower significant byte, etc..
...
0 = 0 written here will increment the bottom byte of the seconds counter

That being said, there is a caveat: the logic has a bug which prevents next higher significance byte from being incremented further as soon as bit 7 of the next lower byte is set. Once this happens, it's only possible to increment it by carry propagation from incrementing the next lower byte.
There is also the problem of the seconds counter continuing to run while it is being set so there needs to be a strict order of the bytes being adjusted from the top to the bottom byte, plus the clock always needs to be reset first. The lowest significance byte then needs to be read before the last increment in order to prevent the current second elapsing from introducing an error (if one want's to be really exact).
Unfortunately, this slows down the process of adjustment but some cleverness can still be built in if the rules are followed.


$18002 WRITE Transmit control

Controls the baud rate and the device where serial data written (into $18022) is going to go.
As far as i can tell there is only one parallel to serial converter, and a multiplexer which routes the serialized output to various ports.

Bits used:

0..2 = encoded baud rate:
111=19200, 110=9600, 101=4800 and so on to 001=300. There is no 150, 000 sets 75 baud.
The setting is common for both serial channels (remember, there seems to be only one parallel to serial converter). The setting is also reflected on the BAUDX4 pin, where a clock signal at 4x the baud rate is produced. The top tier baud rate is generated by dividing the 7.5MHz input clock by 98, giving a ~76530.61Hz clock rate, which is about 0.4% slower than the exact 76800Hz (19200 x 4). The lower rates are generated by successive divisions by 2, down to 75. Bits 0..2 then drive a multiplexer which selects the appropriate divided output.

3..4 = serial data destination:
00=SER1, 01=SER2, 10=Microdrive, 11=Net
Bits 3 amd 4 must NOT be changed while data is being shifted out as a result of it being loaded into $18022. This can be checked for by reading the appropriate status bits from $18020.

5..6 = not implemented, or unknown?
* Appear to be unimplemented and should be written with 00

7 = direct output bit
Bit 7 performs a logical OR with the result of data being shifted out after the data has been loaded into $18022. Because of this, if one wants to use direct output, nothing must be loaded into $18022, as it's output defaults to logical 0.

* There are several unknowns here. For instance, if bit 3 is set to send serial data to the microdrives or the network, it remains unclear if the Net selection also results in data being serialized, and at what rate. I also have not been able to find exact data for the microdrive data rate.
In much the same venue, can bit 7 also force the microdrive read/write lines to a given state?


$18003 WRITE IPC Write:

Controls the IPC communication pin.
* There are several unknowns regarding this location. While only 1 bit is significant and used to drive the COMDATA line, the masks used by the OS suggest that 4 bits are used (bits 0..3).
Implemented bits:

0 = should be written as 0
1 = drives the COMDATA line. It also needs to be 1 to read IPC data
2 = should be written as 1
3 = should be written as 1

The COMDATA line itself is bidirectional and open collector so it can only be pulled low by either the 8302 or the IPC end, so if any end is keeping it low, further communication is impossible. Therefore, when the IPC needs to pass data to the 8302, xxxx1110 should be written here.
It is currently unknown what the other 3 bits do, again their function is inferred from IPC communications code. It is highly likely there is additional hardware here but it is not used, perhaps due to bugs in the implementation? One piece of data that strongly suggests this is that %00000001 is written here as initialization during OS boot - while bit 0 is otherwise always reset on write.


$18020 READ IPC/MDV/SER status

Returns the status of various hardware controlling IPC communication, microdrives and serial ports.

0 = NET data input
Returns the state of the NETIN pin

1 = transmit buffer full (when set)
* The documentation says 'microdrive transmit buffer is full' but since there is only one transmit register ($18022), this is probably a common 'transmit buffer full'. This should become 1 when the transmit register ($18022) is written, and return to 0 when all bits in it are converted to serial format.

2 = microdrive read data ready (when set)
* Again, there is some ambiguity because there are two read data registers (one for each of the two tracks on the tape) so more data is needed to explain when exactly the bit goes high and what returns it to zero (Reading any of the two microdrive read data registers, or a specific one?).

3 = microdrive data gap detected (when set)
This has to do with the formatting of the microdrive tape. A special signal is coded onto the tape as a gap between sectors in order to provide 'slack' space when the sector is over-written by new data. The microdrive has to be read to find the correct position on the tape and the gap, in order to know when to start writing. Again, some details would be nice.
* there is some ambiguity in the description of the function of this bit, which may mean that either this bit is set when the microdrive is not running but goes low whan the microdrive is running and pulses high when a gap is detected - or that it is normally set and goes to zero when a gap is detected. More research is needed...

4 = DTR1
Reflects the state of the DTR1L pin (pin 6), set when the serial port needs to stop transmitting

5 = CTS2
Reflects the state of the CTS2L pin (pin 7), set when the serial port needs to stop transmitting

6 = IPC acknowledge
This bit is zero when a data bit from the IPC is valid and can be read from bit 7 (see below) or the IPC is ready to receive a bit.
* Needs to be checked: this probably reflects the state of the COMCTL pin (pin 22)

7 = IPC data
This bit returns a data bit from the IPC. It should be considered valid only when bit 6 (above) is set. This probably reflects the state of the COMDATA pin (pin 35)


$18020 WRITE Microdrive control

Outputs bits that control the operation of the microdrives. The microdrives use 4 control signals, two to select the appropriate microdrive unit, and one each to select read or write mode, and activate the erase head. As far as I can see, 4 bits are implemented, corresponding to the relevant signals:

0 = microdrive select bit
Drives the MDSELDN output pin (pin 33)

1 = microdrive select clock bit
Drives the MDSELCKN output pin (pin 34)

These two bits work as an input and clock signal for a serial register that is formed by one bit in each microdrive unit. The driver clocks out 8 zero bits first to clear all the possible 8 microdrives, then clocks one single 1 bit and advances it along the chained microdrives to select one. A microdrive is selected when the 1 is present in it's one bit part of the total shift register chain formed by the chained microdrives, and this bit appears on the COMMSOUT pin on the microdrive ULA (pin 20), which is also used to switch on the motor for the selected unit.

2 = microdrive write
* Drives the MDRDWL output pin (pin 3)

3 = microdrive erase
Drives the ERASE output pin (pin 1). This is turn drives the erase head, through the write protect switch.

* Based on the schematics, this drives the aforementioned pin directly, but it is not completely clear what it does regarding the operation of the two microdrive data pins, except the obvious, that it changes the direction.


$18021 READ Interrupt status

Returns the interrupt status of each interrupt source. The 8302 generates a level 2 interrupt to the CPU by driving the IPL1L pin low (pin 26), whenever any interrupt source requests an interrupt. The purpose of this register is to return the interrupt request status of each source so that the level 2 interrupt service routine can execute the required interrupt handler code.
The 8 implemented bits return the following information:

0 = gap interrupt
Goes to 1 when a gap is detected on the microdrive tape when reading,

1 = interface interrupt
* This is the IPC communications interrupt. Minerva sources claim it is set whenever IPC communication is happening, but the actual details remain unclear. It is normally never enabled and always cleared (see below) but Hermes uses it. It may be generated from the two IPC comms pins but as I said, the details are not clear, more research is needed.

2 = transmit interrupt
* While this is not completely explained, the usual way it is used is for this bit to go to 1 when the data written into $18022 is finished being serialized (the last bit is serialized).

3 = frame interrupt
This will be set if the rising edge of VSYNCH has caused the interrupt.
* As far as I can tell, this is rising edge triggered.

4 = external interrupt
This will be set if EXTINTL went low and caused an interrupt
* There is some ambiguity on how this works, if it just an inverted copy of the EXTINTL pin or edge triggered. The normal logic would be to just monitor the level as the EXTINTL line is open collector and as long as it is low, a device needs to be serviced. Minerva clears it once the whole external interrupt linked list has been parsed.

5 = the state of the RTC clock crystal oscilator, cycles at 32768Hz (i.e. changes state every 1/65536 seconds)

6 = Normally 1 but goes to 0 when microdrives are running.
* This is as much as I have been able to glean as the function is reverse-engineered from the dissasembly of the ROMs as well as testing the registers under several conditions. It remains unclear what it's exact function is, it seems not to be used by the microdrive code.

7 = the state of the baud rate clock (NOTE: the true baud rate, not BAUDX4).

$18021 WRITE Interrupt mask and clear

Controls interrupt masking and clears interrupt bits once the relevant interrupt source has been serviced. Based on the Minerva sources, the interrupts are edge triggered and should be cleared by writing an appropriate bit with 1.
Since this register also contains 3 interrupt enable bits, but is write only, a copy of the data written needs to be kept in the SV_INTR system variable so that the proper enable bits can be appended to the clear interrupt bits when writing this register.
In any case, 8 bits are implemented:

0..4 clear the interrupt when written with 1.
The bit assignments correspond to the ones when the register is read:
0 = gap, 1 = interface, 2=transmit, 3=frame, 4=external

5 = gap mask, enables the gap interrupt if written as 1.
6 = interface mask, enables the interface interrupt if written as 1.
7 = transmit mask, enables the transmit interrupt if written

* Again, more data is needed. It is unclear if the interrupts are cleared by writing a 1 or a 0, as well as how the three maskable interrupts are masked (writing 1?), and if the mask bits can be read back.


$18022..3 READ Microdrive read data

Returns microdrive read data as two bytes corresponding to data read from the two tracks on the microdrive. $18022 returns data from track 1, $18023 returns data from track 2.

* More data is needed on microdrive operation and how data is mapped onto the two tracks, i.e. what these registers will return. Also (see below) there is the question of there being two read data registers but only one write data register.
It is also unclear which track is on which physical position - upper/lower head.


$18022 WRITE write data

Writing data to this location loads the parallel to serial converter with new data and then, based on the settings in $18002 shifts it out to a serial port, microdrive or perhaps the NETO pin. It also sets the transmit buffer full bit in $18020. While this bit is set, new data should not be written into this address.


$18023 WRITE not implemented?
On some versions of the 8301 address bit A6 is not used to decode the MC_STAT )display control) register, so it also appears in this location. This is again an indication that the 8301 and 8302 started life as one chip. In fact it is kind of a pity this address was not retained, and even more so that bits A0, A1 and A5, A6 were used to decode all control registers, using A0,1,2 would neatly compress them all into only 8 control bytes, leaving almost the entire $18000..1BFFF 16k area usable for other clever things.
Last edited by Nasta on Sun Sep 02, 2018 1:08 pm, edited 3 times in total.


User avatar
janbredenbeek
Super Gold Card
Posts: 629
Joined: Wed Jan 21, 2015 4:54 pm
Location: Hilversum, The Netherlands

Re: 8302

Post by janbredenbeek »

Thank you Nasta for this very exhaustive description!

The answer to most of the remaining questions can be found in the Minerva source code (notably the inc/pc include file).
For instance, the Interface interrupt calls a routine which reads the keyboard and serial input data, but the same routine also gets called from the polled list (initiated by the frame interrupt). It appears that the Interface interrupt is never actioned by the 8049 so all the input has to be done by the polled routine, which probably explains why serial input is not possible above 9600 baud (at this speed, bytes come in at 960 per second or 19.2 per frame interrupt and the 8049's buffers are only 23 bytes in size). Hermes does use the interface interrupt and has slightly larger buffers so input at 19200 is possible using Hermes.

Similarly, the transmit interrupt handler is also called from the scheduler linked list (because at some point it must release memory used by serial buffers which cannot be done from interrupt code).

A copy of the data written to the PC.INTR register is stored in SV.PCINT system variable at $28035.

Jan.


Nasta
Gold Card
Posts: 443
Joined: Sun Feb 12, 2012 2:02 am
Location: Zapresic, Croatia

Re: 8302

Post by Nasta »

Thanks for the pointers, Jan - I have updated the post above with added data I found.


User avatar
tofro
Font of All Knowledge
Posts: 2685
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: 8302

Post by tofro »

It might be useful to mention that microdrives writes apparently use the/some baud rate generator (a byte is written to the drive by placing it in the transmit register, then the status register is polled until the byte is completely ticked out). This means the transfer rate to the tape must be controlled by the hardware. With a nominal transfer rate of 120kbps, it obviously must be the 8302 that generates that timing as an additional bit rate.

The QL network is instead bit-banged and thus produces the nominal transfer rate of (~)87.5kbps (that's what I measured, opposing the 100kbps Sinclair put into their early QL documentation) purely in 68k software. It also generates the network scout that way, which is the equivalent of a BREAK on a classic serial port.

Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
Nasta
Gold Card
Posts: 443
Joined: Sun Feb 12, 2012 2:02 am
Location: Zapresic, Croatia

Re: 8302

Post by Nasta »

tofro wrote:It might be useful to mention that microdrives writes apparently use the/some baud rate generator (a byte is written to the drive by placing it in the transmit register, then the status register is polled until the byte is completely ticked out). This means the transfer rate to the tape must be controlled by the hardware. With a nominal transfer rate of 120kbps, it obviously must be the 8302 that generates that timing as an additional bit rate.

The QL network is instead bit-banged and thus produces the nominal transfer rate of (~)87.5kbps (that's what I measured, opposing the 100kbps Sinclair put into their early QL documentation) purely in 68k software. It also generates the network scout that way, which is the equivalent of a BREAK on a classic serial port.

Tobias
Thanks for the info.

The definition of the functions of the bits in various registers suggests that hardware is being internally reused. So:

1) Are the baud rate bits "don't care" when the mode is set to 'MDV/NET'

2) What is the exact MDV data rate - given that 120kbps is 7.5MHz divided by 62.5. This can actually be done but then has to use separate dividing hardware compared to the serial port mode. Or, the closest integer is used, either 62 or 63. Obviously, 64 is also interesting as the divider is simply a string of 6 flip-flops. In any case the data rates would then be ~120968, ~119048, 117187.5.
Also, if the MDV input is treated as asynchronous, then it has to be oversampled, at least by a factor of 4, which essentially gets us to a 64 divisor, sampled at 4x, which is 7500000Hz/16.

3) Given that hardware is reused, is it possible that the MDV data rate is used when network mode is selected and a byte is written into the transmit register (rather than bit-banged)?

4) Given that bit 7 over-rides the output of the serializer, does it do so in all 4 modes (ser1, ser2, mdv, net), rather than just for the network mode (special casing just that would require extra logic).

5) do the MDV read registers only work when MDV mode is selected? Given that the logic is reused and tends to be the simples possible, I wonder if NETIN is de-serialized into these two registers when NET mode is selected, but ignored as bit-banging is being used instead. Namely, we do know net has to wait if microdrives are in use.


User avatar
tofro
Font of All Knowledge
Posts: 2685
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: 8302

Post by tofro »

Nasta wrote: The definition of the functions of the bits in various registers suggests that hardware is being internally reused. So:

1) Are the baud rate bits "don't care" when the mode is set to 'MDV/NET'
They seem to. I didn't find anything in the Minerva sources that touches the baud rate bits when switching between mdv/NET and serial. For NET, they are irrelevant anyhow.
Nasta wrote: 2) What is the exact MDV data rate - given that 120kbps is 7.5MHz divided by 62.5. This can actually be done but then has to use separate dividing hardware compared to the serial port mode. Or, the closest integer is used, either 62 or 63. Obviously, 64 is also interesting as the divider is simply a string of 6 flip-flops. In any case the data rates would then be ~120968, ~119048, 117187.5.
The pictures here suggest pretty exactly 100kbps. (That thread has some more good information on microdrive hardware, BTW)


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
User avatar
M68008
Trump Card
Posts: 223
Joined: Sat Jan 29, 2011 1:55 am
Contact:

Re: 8302

Post by M68008 »

Nasta wrote:$18003 WRITE IPC Write:

Controls the IPC communication pin.
* There are several unknowns regarding this location. While only 1 bit is significant and used to drive the COMDATA line, the masks used by the OS suggest that 4 bits are used (bits 0..3).
Implemented bits:

0 = should be written as 0
1 = drives the COMDATA line. It also needs to be 1 to read IPC data
2 = should be written as 1
3 = should be written as 1
I was looking again at the IPC sources and noticed that for each bit sent to the IPC, the IPC expects to see the sequence 0, <bit>, 1 (the first 0 on COMDATA is used by the ZX8302 to start communication, after that the IPC asserts COMCTL first to signal it's ready for the data bit, then to signal it's done reading it and the COMDATA should go back to 1) and this corresponds to the first three bits written by QDOS to $18003. So it's possible the ZX8302 acts as a shift register, or at least early QL prototypes had a shift register to allow tweaking the IPC link protocol in software. Perhaps that could explain why four bits are written to $18003 even though only one is really needed and the others never change (?).


martyn_hill
Aurora
Posts: 909
Joined: Sat Oct 25, 2014 9:53 am

Re: 8302

Post by martyn_hill »

Hi everyone

I have been exploring the link between the 8302 ('PC') and the 8049 ('IPC') recently myself and thought to share the following analysis - which effectively supports what Daniele uncovered earlier.

My own interest was driven by an idea to enhance the basic IPC capability by leveraging an EPROM equivalent I found on eBay (the 8749) and for that I needed to understand the effective bandwidth available between the two devices via that 'arcane' link/protocol. As it happens, the link speed seriously limits what I had in mind, but it was an interesting excursion, none the less.

So, my primary source was the original 8049 disassembly as posted on Dilwyn's site. Would be great to get a hold of the source code for HERMES, but that's a different matter!

The relevant routines/primitives on the IPC to read and write down the 2-wire link to the 8302 are copied below, which I've annotated - and, with reference to the 8049 Datasheet, added timing data (at 11MHz IPC clock). Whilst the basic unit of transmission is a 4-bit nibble, 8-bit bytes are transferred by simply calling these two primitives sequentially as needed to support the available IPC commands.

I have not yet verified the assessment below - my attempts to attach a little logic probe to 'comdata' and 'comctrl' kept shorting neighbouring pins, but I'm fairly confident in the conclusions I've drawn based purely off the disassembly.

Code: Select all

; get 4bit data from ZX8302, ret A.lsb
074F: BE 00   MOV  R6,#00        initialise R6 ready to hold the nibble from the ZX8302
0751: BF 04   MOV  R7,#04        4xbit count
0753: 0A      IN   A,P2      (2) read P2 (checking for ZX8302 ACK - ready to send next bit???)
0754: 53 80   ANL  A,#80     (2) mask-off all but P2.7 (comdata)
0756: 96 53   JNZ  #0753     (2) loop UNTIL comdata=L (when we first arrived here, comdata=L anyway)
0758: 90      MOVX @R0,A     (2) low-going WR pulse to ZX8302 (480ns) to send next bit
0759: 0A      IN   A,P2      (2) read P2 again, this time to capture the actual data-bit
075A: 90      MOVX @R0,A     (2) pulse WR again - flagging that we have captured this bit and ready for next
075B: F7      RLC  A         (1) store latest comdata bit in C flag
075C: FE      MOV  A,R6      (1) reload A with accumulated nibble in R6
075D: F7      RLC  A         (1) rotate-in the stored C flag
075E: AE      MOV  R6,A      (1) copy-back to R6
075F: EF 53   DJNZ R7,#0753  (2) go back for next bit, or drop out after 4xbit nibble
0761: 93      RETR            R6=A = 4bit cmd
;
; Sequence seems to be:
; 1. IPC awaits comdata=L
; 2. ZX8302 lowers comdata signalling that next bit is Ready To Send (RTS)
; 3. IPC pulses WR to signal to ZX8302 that IPC is Ready to Receive (ala CTS)
; 4. IPC immediately captures next bit from comdata
; 5. IPC pulses WR again to signal ZX8302 that last bit is now stored
; (6. IPC rotates recent bit in to accumulated nibble in R6)
; 7. Repeat at 1. until 4xbit nibble received
; Loop time is 18 IPC cycles = 18 * 5 * 3 * (1/11MHz) = 24.5us == 40.740 KHz == 5.092 KB ps
;
; send 4bit data to ZX8302, ent A.msb=data
0762: BF 04   MOV  R7,#04        4xbit count
0764: AE      MOV  R6,A          preserve A in R6
0765: 0A      IN   A,P2      (2) read P2 
0766: 53 80   ANL  A,#80     (2) mask-off all but P2.7 (comdata)
0768: 96 65   JNZ  #0765     (2) loop UNTIL comdata=L 
076A: FE      MOV  A,R6      (1) reload A from R6 
076B: 90      MOVX @R0,A     (2) low-going WR pulse to ZX8302 (480ns)
076C: F2 72   JB7  #0772     (2) Jump IF 1-bit is next to send to ZX8302
076E: 9A 7F   ANL  P2,#7F      (2) make comdata=L
0770: E4 74   JMP  $774        (2) continue... 
0772: 8A 80   ORL  P2,#80     (2) make comdata=H 
0774: 90      MOVX @R0,A     (2) low-going WR pulse to ZX8302 (480ns)
0775: E7      RL   A         (1) get next bit of nibble in to A.7
0776: AE      MOV  R6,A      (1) store shifted nibble back in to R6 
0777: 8A 80   ORL  P2,#80    (2) make comdata=H (again, if last bit was H) 
0779: EF 65   DJNZ R7,#0765  (2) go back for next bit, or drop out after 4xbit nibble
077B: 93      RETR            
;
; 1. IPC awaits comdata=L
; 2. ZX8302 lowers comdata signalling that it is ready to Receive the next bit (CTS)
; 3. IPC pulses WR to signal to ZX8302 that IPC is Ready to Send (RTS)
; 4. IPC immediately sends next bit on comdata
; 5. IPC pulses WR again to signal ZX8302 that next bit ready to be sent
; (6. IPC prepares next bit from the nibble )
; 7. Repeat at 1. until 4xbit nibble sent
; Loop time is 23c (0-bit) or 21c (1-bit) == 3.985 KB ps or 4.365 KB ps resp.
;
Enjoy :-)


nichtsnutz
ROM Dongle
Posts: 24
Joined: Wed Apr 13, 2011 6:33 pm

Re: 8302

Post by nichtsnutz »

Hello all,

first of all, thank you for keeping this forum running and the people here that contributed
so much to this small QL community.

it is some years ago that I have used my QL.Back then, I had tried to understand the mdv
functions of the 8302 especially the GAP hardware, but had not entirely suceeded.

But I had also taken a look at the IPC hardware interface and had found out
the following things, maybe they could be useful.

I have not read all the posts in the forum concerning the hardware registers,
so please forgive me if this details have been posted before.Also I have not
my QL setup at the moment.I just found some hand written notes.


1. I had put the 8302 on a breadboard and had wired some switches and pushbuttons
to it.The chip seems to have static latch logic for the ipc interface.

2. The data of the 0x18003 register are latched into the chip when PIN_9_RW is low
with the rising edge of the PCENL signal.

3. Writing 0x0C or 0x0E to 0x18003 has the following effects:

3.1 The PIN_35_COMDATA leaves the HIGH-Z state and goes '0'. COMDATA can
not be driven ACTIVE HIGH, only tristate and low. The pullup in the
port of the IPC drives the COMDATA pin high when it is in the HIGH-Z state.

3.2 BIT.6 of the 0x18020 register is set to '1'.

3.3 If 0x0C was written in 0x18003, then the SECOND falling edge of the PIN_29_COMCTL
(that is wired to the /WR signal of the IPC) will return COMDATA from '0' to HIGH_Z.

3.4 If 0x0E was written then the FIRST falling edge of COMCTL will return COMDATA
from '0' to HIGH-Z.

3.5 BIT.6 of the 0x18020 register is always cleared after the SECOND falling edge
of COMCTL.

3.6 Every falling edge on COMCTL latches whatever state the COMDATA line has into
BIT.7 of 0x18020. This bit of cource makes only sense when 0x0E was written
into 0x18003 because the first falling edge on COMCTL will release COMDATA into
the tristate so the IPC can set the P2 port pin to '0' to '1' that will then be
latched with the next falling edge of the COMCTL into BIT.7.
(That is why they do two times MOVX @R0,A)


I think with this informations and the IPC and QL rom source the complete communication
can be understood.

Maybe someone can confirm these findings?

Greetings,
Vas


Post Reply