|
Post by c128old on Nov 29, 2020 20:35:12 GMT
Trying to use the REU via Z80. Well, it doesn't work.
This prompted me to check the source code of CP/M (which does use the REU). And indeed, the actual transfer is executed on the 8502 side! So all registers are set-up on Z80 side and then the writing of the command DF01-register to execute the transfer requires a rather lengthy action.
So: it is pretty clear that commodore didn't solve the case where Z80 is active during REU.
I was wondering if anyone has references / documentation of even explanations as to why this would be! Edit: the REU booklet from the 1750 (See www.zimmers.net/anonftp/pub/cbm/manuals/peripherals/1700-1750_Ram_Expansion_Module_Users_Guide.pdf ) Lists under “Important operating notes” 1. The Z80 must not be in control. What in the REC chip design causes the problem?
|
|
|
Post by oziphantom on Nov 30, 2020 5:44:21 GMT
The DMA pin is not connected to the Z80 only the 8502, thus you can not stall the Z80 from the expansion port.
|
|
|
Post by c128old on Nov 30, 2020 18:23:29 GMT
Wow thanks! That explains it.
So when the REU 'takes over the bus' the Z80 would not 'see' anything, perhaps something the REU was writing at that cycle. I tried with a series of NOP but that would still try to access the bus. I thought interrupt, the REU can create an interrupt on completion (interrupt on end), I suppose the Z80 would see that. A 'HALT' on Z80 would stall,
But its mood, since how to get that halt-instruction into the Z80 without using the bus after spurring the REU into action.
|
|
|
Post by c128old on Dec 4, 2020 19:02:38 GMT
So, I'm now trying with a HALT instruction, on the UII+ that works with Z80 for a few bytes (255) Who has a (real) REU and willing to help me with this Z80 experiment? I am using an UltimateII+ and that has a pretend REU. The real REC chip may be different, something here isn't adding up. The problem is the following: - Z80 does not have a DMA line to keep it
- Z80 and REU would try to operate the bus at the same time (chaos)
- Z80 could in theory use a HALT instruction to wait for an interrupt
- Z80 cannot read HALT from memory when the REU is operating the BUS
So, I try these steps: - setup DF02-DF0A registers to transfer REU 00000 to 5000 (bank1), len FF - disable interrupts (bios would fail) - select IO1 (to access D506) - switch VIC to bank 1 for the test (bit 6 D506 on) - select ram1 - print just before kicking REU... farewell - execute immediate move - HALT The Z80 cannot, should not, return now. It is waiting for an interrupt that CANNOT happen This code is not reachable: - select io1 - restore vic bank in d506 - select bank1 - enable interrupts - end I've checked! If you do "di ! halt ! ei" the Z80 hangs. It should. Yet the code below will return at the halt, I do not get it. Why?What is causing the Z80 to continue where it was? I've verified the contents of 5000 with zsid, and it is correct. (d5000) and the REU content is there ("ERWINE VON.. etc") I am inclined to believe this is a Uii fakeREC thing. But how? What is the U2 doing to the bus to cause the Z80 wake up? It cannot be an interrupt. Setup: Old plain C128-flat international, PAL, VDC16k, (old CIA etc) The CP/M version is a much edited version, but I am convinced that is irrelevant. If you need a .d64 with the CP/M on it, ask! Here's the code for ASM, to make REUTST.COM add code in a file on C128 CP/M, reutst.asm ASM reutst load reutst reutst.com ------------------------------------------------------ OUTP MACRO ?R DB 0EDH,?R*8+41H ; OUT (C),reg ENDM
; CPM: bdos EQU 0005h strout EQU 9
ORG 100h
; --------------- Main lxi d,bla$msg ; print Hello mvi c,strout call bdos
; --------------- prep df02-03 lxi b,0DF02h lxi d,5000h ; c128 base 5000 outp e ; DF02 L inx b outp d ; DF03 H inx b ; reu base 0 outp e ; DF04 L inx b outp e ; DF05 H inx b outp e ; DF06 bnk inx b ; len 50 mvi d,255 outp d ; DF07 low 255 inx b outp e ; DF08 inx b ; interrupt bit 6 end of block mask mvi a,01000000b outp a ; DF09 inx b ; adress ctrl outp e ; DF0A ; stop interrupts because ; set D506 to vic bank 1 di sta 0ff04h ; 01=bnk0 02=bnk1 03=io0 04=io1 (normal=02) lda 0d506h ; 0ah push psw mvi a,4ah ; bit6 enable vic ram1 sta 0d506h sta 0ff02h ; ram 1
lxi d,bla$msg ; print Hello mvi c,strout call bdos ; exec move lxi b,0DF01h ; cmd 7=ex 6 5 4=ff 3 2 10=type ; 7 = 1 exec ; 4 = 1 no wait ff00 ; 1 = 0 ; 0 = 1 reu to c128 ; 76543210 mvi a,10010001b outp a hlt ; no interrupt, should stop sta 0ff04h ; io1 pop psw sta 0d506h sta 0ff02h ; bnk1 ei
; --------------- End ret
bla$msg: DB 'REU Test$' end 100h
|
|
|
Post by oziphantom on Dec 6, 2020 4:23:31 GMT
my guess, is the HALT never happens, the UII kicks in and forces the bus more and hence you don't actually get a HALT appear at the Z80.
|
|
|
Post by c128old on Dec 6, 2020 11:33:01 GMT
That makes sense. The Z80 keeps going, using whatever it finds on the bus.
|
|
|
Post by oziphantom on Dec 7, 2020 5:45:38 GMT
make the first 1~3 bytes of the DMA transfer 'HALT' as well and see if that fixes it.
|
|
|
Post by c128old on Dec 18, 2020 22:04:05 GMT
make the first 1~3 bytes of the DMA transfer 'HALT' as well and see if that fixes it. I've tried quite a number of things. Putting the HALT once or a few times into the REU is simply not doing the same each time. It is (well, for me) too hard a nut to crack, I wouldn't be able to trace this with a scope (not sure it would help even).
I had hoped perhaps cycle exact Z64K would help, but alas it doesn't (appear to) handle the bus-contention that must be happening. (then again how to simulate a random event)
The single stepping of Z64K with its really great monitor feature shows the four clocks per each of three M1/M2/M3 states that make up the OUT. At end of Z80 two clocks, with the 'end' of the 1Mhz DMA clock of VIC the REU probably determines the bus and data but this appears to be not in sync. I image the result would differ for the '1st' or '2nd' of 2 clock steps of Z80 but it's getting foggy for me at that level.
If I take the cycle exact behavior of Z64K as a lead, the REU part isn't visible in Z80 mode (in itself correct), on real C128 I do see REU is make its transfer for the time it doesn't crash. If you are right the REU (well, U2 in my case which might make a difference) overrules the address, but not always.
To narrow the equation down I've kept the VIC/DMA bank0 and transfer only 1 byte to FE00 (the page CP/M uses for buffer).
Still the results are unpredictable. I end up with a reboot roughly half the time. I've still to try IM0 (designed to get an auxiliary byte, after all), but the "goal" to use REU without the 8502 side is slipping away. So, I will leave this be (open to suggestions though!)
I'm going to have a look at a more dedicated 8502 hook-up: if the cp/m sector count > 1 then prep 8502 first time around and then the overhead of switching can be limited.
Currently the time CP/M is spending to load a 16k program from REU is not so great: - calc sectors buffers and all - program all reu registers - set up 8502 'read reu' and jump there, wait interrupts, disable, switch, check cmd, disable interupts and check everything, some more, finally do the move cmd, return all, set tesults and go back to z80 - switch and copy in high mem to target in bank1 - repeat
Note that all of the above gets worse if one would attempt to load 1 128byte record.
|
|