After fixing #178 and doing more testing, it looks like there is an issue with the parasite flags in two-byte mode.
This is used by ANFS type=2 transfers (parasite-to-host, i.e. *SAVE)
I believe it only affects the RISC-V Co Processor, because all the other Co Processor use pace the transfer using the NMI interrupt (which I think is correct), where as the RISC-V Co Processor is unique in that it polls the flags in R3 status:
Type2:
lb t0, R4STATUS(gp) # Test for an pending interrupt signalling end of transfer
bltz t0, Release
lb t0, R3STATUS(gp)
andi t0, t0, 0x40
beqz t0, Type2
lh t0, (t2) # load half word from memory
sb t0, R3DATA(gp) # store lo byte to tube
srli t0, t0, 8
sb t0, R3DATA(gp) # store hi byte to tube
addi t2, t2, 2
j Type2
Register 3 Operation
Register 3 is intended to enable high speed transfers of large blocks of data across the tube. It can operate
in one or two byte mode, depending on the V flag. In one byte mode the status bits make each FIFO appear
to be a single byte latch - after one byte is written the register appears to be full. In two byte mode the data
available flag will only be asserted when two bytes have been entered, and the not full flag will only be
asserted when both bytes have been removed. Thus data available going active means that two bytes are
available, but it will remain active until both bytes have been removed. Not full going active means that the
register is empty, but it will remain active until both bytes have been entered. PNMI, N and DRQ also
remain active until the full two byte operation is completed.
In both one-byte and two byte-mode, the behaviour should be the same: the not full flag (bit 6) should only be asserted when the FIFO is empty.
That's not what the current tube_host_read() code does:
case 5: /*Register 3*/
if (ph3pos > 0)
{
PH3_0 = BYTE_TO_WORD(PH3_1);
ph3pos--;
PSTAT3 |= 0xC0;
if (!ph3pos) HSTAT3 &= (uint32_t)~HBIT_7;
if ((HSTAT1 & HBIT_3) && (ph3pos == 0)) tube_irq|=NMI_BIT;
//tube_updateints_NMI();
}
break;
Currently not full flag is asserted when host reads the first of the two bytes. The Co Processer then quickly deposits two more bytes, the second of these overflowing the FIFO and being dropped.
I think the code should be changed to:
case 5: /*Register 3*/
if (ph3pos > 0)
{
PH3_0 = BYTE_TO_WORD(PH3_1);
ph3pos--;
if (!ph3pos) { // Test if PH3 empty
HSTAT3 &= (uint32_t)~HBIT_7; // Clear host "available" flag
PSTAT3 |= 0xC0; // Set parasite "Not Full" flag (and NMI flag)
if (HSTAT1 & HBIT_3) tube_irq|=NMI_BIT; // Raise NMI interrupt if enabled
}
//tube_updateints_NMI();
}
break;
We should carefully review the rest of the code, so see if there are any similar errors elsewhere.
After fixing #178 and doing more testing, it looks like there is an issue with the parasite flags in two-byte mode.
This is used by ANFS type=2 transfers (parasite-to-host, i.e. *SAVE)
I believe it only affects the RISC-V Co Processor, because all the other Co Processor use pace the transfer using the NMI interrupt (which I think is correct), where as the RISC-V Co Processor is unique in that it polls the flags in R3 status:
App Note 004 says the following:
In both one-byte and two byte-mode, the behaviour should be the same: the not full flag (bit 6) should only be asserted when the FIFO is empty.
That's not what the current tube_host_read() code does:
Currently not full flag is asserted when host reads the first of the two bytes. The Co Processer then quickly deposits two more bytes, the second of these overflowing the FIFO and being dropped.
I think the code should be changed to:
We should carefully review the rest of the code, so see if there are any similar errors elsewhere.