1
0
mirror of https://github.com/livingcomputermuseum/UniBone.git synced 2026-05-03 06:29:28 +00:00

Rewrote lower-level DMA and IRQ handling: DMA and IRQ requests are now queued and will run to completion on their own

without help from the device code (just call request_DMA and when it returns the DMA transfer is complete.)  Fixed
request_DMA to chunk DMA transfers larger than 1024 bytes to avoid overrunning the mailbox's shared memory.  Fixed
concurrency issues with DMA requests -- a race condition could cause DMA request data to get clobbered.

RT-11 now boots, MSCP behavior is now very reliable.
This commit is contained in:
Josh Dersch
2019-05-04 03:30:26 +02:00
parent e0aabf2197
commit 8eff2a4e10
10 changed files with 484 additions and 298 deletions

View File

@@ -88,6 +88,8 @@ rk11_c::rk11_c() :
RKDB_reg->reset_value = 0;
RKDB_reg->writable_bits = 0x0000; // read only
_rkda_drive = 0;
//
// Drive configuration: up to eight drives.
//
@@ -127,8 +129,7 @@ void rk11_c::dma_transfer(DMARequest &request)
{
// Write FROM buffer TO unibus memory, IBA on:
// We only need to write the last word in the buffer to memory.
unibusadapter->request_DMA(
this,
request.timeout = !unibusadapter->request_DMA(
UNIBUS_CONTROL_DATO,
request.address,
request.buffer + request.count - 1,
@@ -139,8 +140,7 @@ void rk11_c::dma_transfer(DMARequest &request)
// Read FROM unibus memory TO buffer, IBA on:
// We read a single word from the unibus and fill the
// entire buffer with this value.
unibusadapter->request_DMA(
this,
request.timeout = !unibusadapter->request_DMA(
UNIBUS_CONTROL_DATI,
request.address,
request.buffer,
@@ -153,8 +153,7 @@ void rk11_c::dma_transfer(DMARequest &request)
if (request.write)
{
// Write FROM buffer TO unibus memory
unibusadapter->request_DMA(
this,
request.timeout = !unibusadapter->request_DMA(
UNIBUS_CONTROL_DATO,
request.address,
request.buffer,
@@ -163,8 +162,7 @@ void rk11_c::dma_transfer(DMARequest &request)
else
{
// Read FROM unibus memory TO buffer
unibusadapter->request_DMA(
this,
request.timeout = !unibusadapter->request_DMA(
UNIBUS_CONTROL_DATI,
request.address,
request.buffer,
@@ -172,20 +170,6 @@ void rk11_c::dma_transfer(DMARequest &request)
}
}
// And wait for completion.
while(true)
{
timeout.wait_us(50); // Stolen from RL11
uint32_t last_address = 0;
if (unibusadapter->complete_DMA(
this,
&last_address,
&request.timeout))
{
break;
}
}
// If an IBA DMA read from memory, we need to fill the request buffer
// with the single word returned from memory by the DMA operation.
if (request.iba && !request.write)