VOGONS


Reply 20 of 23, by reenigne

User metadata
Rank Oldbie
Rank
Oldbie

There's a subtle issue with relying on the memory-to-memory copy DMA to do the refresh: suppose the low 8 bits of the refresh address are 0xFE when the memory-to-memory copy starts, and the memory-to-memory copy does a copy from address 0x00-0xFF. The address 0xFF goes unrefreshed for almost twice as long as normal, which would be running it out-of-spec and could cause DRAM decay in some machines. The "sped up refresh" protocol before and after doing anything else with DMA channel 0 avoids this.

Another subtlety is that you can't do anything else with the machine while a memory-to-memory copy is going on: the DMAC forces block mode on when memory-to-memory mode is enabled, so the CPU doesn't get access to the bus again until it completes. So not useful for parallelising a memory fill with non-CPU-bound tasks either I'm afraid!

Reply 21 of 23, by mkarcher

User metadata
Rank l33t
Rank
l33t
reenigne wrote on 2022-05-31, 16:51:

Another subtlety is that you can't do anything else with the machine while a memory-to-memory copy is going on: the DMAC forces block mode on when memory-to-memory mode is enabled, so the CPU doesn't get access to the bus again until it completes. So not useful for parallelising a memory fill with non-CPU-bound tasks either I'm afraid!

My main thought is: Comparing memory-to-memory DMA to REP MOVSW: The CPU is prevented to do anything else in either task (whether it's starved on fetching instructions or busy running the REP MOSVW microcode). The DMAC should be able to saturate the ISA bus (doing 4-cycle reads and 4-cycle writes), whereas the 8088 is unable to do that (a moving word takes 25 clocks, but only 16 clocks of that are spent on bus access (extra waitstates will slow down REP MOVSW), so we lose 9 processor clocks per word (or 4.5 processor clocks per byte) transferred by REP MOVSW compared to memory-to-memory DMA. I hope I didn't misremember things about mem2mem timing. The DMAC has to update the high-8 latch register for every read and every write cycle, so I'm not 100% positive that 4 clocks per read or write is correct.

Reply 22 of 23, by FrankieKat

User metadata
Rank Newbie
Rank
Newbie
reenigne wrote on 2022-05-31, 16:51:

There's a subtle issue with relying on the memory-to-memory copy DMA to do the refresh: suppose the low 8 bits of the refresh address are 0xFE when the memory-to-memory copy starts, and the memory-to-memory copy does a copy from address 0x00-0xFF. The address 0xFF goes unrefreshed for almost twice as long as normal, which would be running it out-of-spec and could cause DRAM decay in some machines. The "sped up refresh" protocol before and after doing anything else with DMA channel 0 avoids this.

Another subtlety is that you can't do anything else with the machine while a memory-to-memory copy is going on: the DMAC forces block mode on when memory-to-memory mode is enabled, so the CPU doesn't get access to the bus again until it completes. So not useful for parallelising a memory fill with non-CPU-bound tasks either I'm afraid!

Oh, to be sure that hypothetical example is neither practical nor something you'd want to do in stable code. More of just an amusement or a "can I do this" or a "solution in search of a problem" kind of thing. 😀

If you were to just do a mem-to-mem bus request, block mode write on channel 1 while refresh was running normally (like the example code I posted earlier where it will write whatever value might be on the bus at that time), would it be the case that refresh will always complete since DMA 0 has (unless specified otherwise) higher priority than DMA 1? If DMA 1 is doing a block copy, and DMA 0's timer interrupt occurs, will that "interrupt" DMA 1's write? In other words, assuming you don't reprogram PIT timer 1 or DMA 0, you wouldn't have to worry about loss of refresh right?

FK

Reply 23 of 23, by reenigne

User metadata
Rank Oldbie
Rank
Oldbie
mkarcher wrote on 2022-05-31, 17:57:

The DMAC should be able to saturate the ISA bus (doing 4-cycle reads and 4-cycle writes),

I checked my notes from when I played with this a few years ago, and it seemed that the read part of the transfer was 5 cycles rather than 4 for some reason (not sure why - something internal to the DMAC I think).

FrankieKat wrote on 2022-05-31, 18:25:

If you were to just do a mem-to-mem bus request, block mode write on channel 1 while refresh was running normally (like the example code I posted earlier where it will write whatever value might be on the bus at that time), would it be the case that refresh will always complete since DMA 0 has (unless specified otherwise) higher priority than DMA 1? If DMA 1 is doing a block copy, and DMA 0's timer interrupt occurs, will that "interrupt" DMA 1's write? In other words, assuming you don't reprogram PIT timer 1 or DMA 0, you wouldn't have to worry about loss of refresh right?

Going from memory here, I think block and demand transfers aren't interrupted - the DMAC's priority logic is only invoked at the start of a DMA service, and block/demand transfers each count as one service. The datasheet says "After the recognition of one channel for service, the other channels are prevented from interfering with that service until it is completed." This simplifies the logic of devices using DMAs for bulk IO - they don't have to be concerned with "losing" the DMA part-way through.