|
Post by mirkosoft on Mar 19, 2019 11:26:15 GMT
Hi!
I want to switch to Z80 from 8502 and registers + PC exchange or better send them to Z80 and vice versa. Of course registers which can have their alternative in both CPUs, but most important is program counter (PC).
Is it possible? Or needs it to do it manually? If only manually I know that's possible to store and read all registers. But if exist any very quick way it is great.
Main problem is PC - but this can be used in program flow.
Thank you for all. Miro
|
|
|
Post by bjonte on Mar 19, 2019 21:11:02 GMT
I don’t think that’s possible. I think a better way to utilize both CPUs would be to let the Z80 do one specific thing where most of its state can be held in registers and stack. That way you can switch to it to execute and when it’s done, loop back and yield by switching back to 8502.
|
|
|
Post by mirkosoft on Mar 19, 2019 23:11:51 GMT
I know this way, only sometimes I need this and I always tried to do it with fast and minimal subroutines.
Miro
|
|
|
Post by oziphantom on Apr 2, 2019 12:54:53 GMT
The Z80 will wake up exactly where it left off, you can't prod the PC while it is asleep. So you you have a known place you get the Z80 to switch back. ie you have code that looks like this
switch to 8500 ------- this is where the Z80 halts restore from 6502 jp XXXX
so what you do is you poke the XXXX with the 8500, then wake it up, so it will wake up and jp to wherever you told it to go. if you want do register settings for things ld A,YY ld B,ZZ ld C,.... jp XXXX
so you poke the YY,ZZ etc with the values you want into regs, then set the jump address and enable the z80. A faster way might be to set the Stack to a specific point, then POP AF POP BC POP DE RET then restore the stack point to somewhere sensible, in your routines.
You then do a similar thing for the 8500 as it will stop exactly where you tell it to stop.
|
|
|
Post by mirkosoft on Apr 3, 2019 11:58:26 GMT
This I know, also Z80 inside C128 can be activated with direct jump to entered address directly from 8502 system routine. This is the feature which is available - I mean if is there anything similar for registers. Z80 inside CP/M Cartridge works like we all know - when is activated it jumps into address inside PC, what is expected. So, I mean if C128 engineers did not something similar like C128's Z80 like jump directly to entered address, for registers.
Miro
|
|
|
Post by oziphantom on Apr 3, 2019 14:41:54 GMT
how do you inject an address to the PC on the Z80? How would you expect it be possible to change the state of the Z80 registers externally?
|
|
|
Post by bjonte on Apr 3, 2019 16:35:05 GMT
It just won’t work. The Z80 doesn’t expose access to the registers from the outside of the chip. So it is impossible to change them unless you run some code on the Z80 itself that triggers the change internally.
|
|
|
Post by bjonte on Apr 3, 2019 16:40:34 GMT
Having the Z80 jump somewhere is at least possible even if it doesn’t mean setting the program counter directly. The trick with a jump instruction when going back to Z80 is one, manipulating stack and reenter at a ret instruction is a variant. Perhaps an interrupt can be used to make the Z80 jump on entry, but still not really setting the program counter since the jump consume cycles.
|
|
|
Post by mirkosoft on Apr 3, 2019 22:47:15 GMT
Z80 inside C128 has default address of PC $ffee - but only for 1st call, then is accepted only true PC of Z80. Really don't know how this did engineers 'cause default Z80 address is $0000. I think it is maybe for C128 startup routine 'cause C128 starts with active Z80, checks disk and then switches to 8502 - there it can set Z80's PC to $ffee, other way I don't know.
Else one Q is how CMD engineers overrided Z80 startup of C128 - SuperCPU128 totally replaces 8502 and Z80 is not accessible - it takes control over all - maybe there's any way...
Simply first Z80 call is possible easiest this way:
activateZ80: lda $ff00 ; pha ; store RAM config to stack sei ; disable interrupts lda #$c3 ; sta $ffee ; store JP instruction for Z80 mode start lda #<z80start ; sta $ffef ; store lo-byte address lda #>z80start ; sta $fff0 ; store hi-byte address lda #$3e ; sta $ff00 ; select RAM config for Z80 lda $d505 ; pha ; store mode to stack lda #$b0 ; sta $d505 ; set Z80 mode - this instruction deactivates 8502 and jumps by Z80 PC to $ffee
|
|
|
Post by willymanilly on Apr 4, 2019 4:13:56 GMT
There is no trickery by the engineers with Z80. Z80 in C128 always starts at address $0000 when the machine is reset. If you go to Z64K's machine monitor and type the following you will see the sequence of c128 boot instructions including where it switches to 8502
reset z b0 The Z80 sets the 8502 reset pointer at $fffc to $1100 which is why the 8502 starts there. (See output 1 below) The Z80 PC is at $ffed when it switched to 8502. The instruction at that location is a NOP by default. (See output 2 below) In summary the Z80 will always resume at the next instruction after it was switched to 8502 when it is switched back. The 8502 cannot directly change the Z80 PC as far as I'm aware.
Output 1
1534 < 1 > 00a2: LD HL,$1100 0001 cf 3f 0000 ffef 0f04 ffff sZ-h-pnc --- 1 0 ffff,ffff ffff,ffff 1544 < 1 > 00a5: LD ($fffa),HL 00a4 11 3f 0000 ffef 1100 ffff sZ-h-pnc --- 1 0 ffff,ffff ffff,ffff 1557 < 1 > 00a8: LD ($fffc),HL fffb 11 3f 0000 ffef 1100 ffff sZ-h-pnc --- 1 0 ffff,ffff ffff,ffff 1570 < 1 > 00ab: LD ($fffe),HL fffd 11 3f 0000 ffef 1100 ffff sZ-h-pnc --- 1 0 ffff,ffff ffff,ffff 1583 < 1 > 00ae: LD ($ffdd),HL ffff 11 3f 0000 ffef 1100 ffff sZ-h-pnc --- 1 0 ffff,ffff ffff,ffff 1596 < 1 > 00b1: JP $ffe0 ffde 11 3f 0000 ffef 1100 ffff sZ-h-pnc --- 1 0 ffff,ffff ffff,ffff 1606 < 1 > ffe0: DI 00b3 ff 3f 0000 ffef 1100 ffff sZ-h-pnc --- 1 0 ffff,ffff ffff,ffff 1610 < 1 > ffe1: LD A,$3e ffe0 f3 3f 0000 ffef 1100 ffff sZ-h-pnc --- 1 0 ffff,ffff ffff,ffff 1617 < 1 > ffe3: LD ($ff00),A ffe2 3e 3e 0000 ffef 1100 ffff sZ-h-pnc --- 1 0 ffff,ffff ffff,ffff 1630 < 1 > ffe6: LD BC,$d505 ff00 3e 3e 0000 ffef 1100 ffff sZ-h-pnc --- 1 0 ffff,ffff ffff,ffff 1640 < 1 > ffe9: LD A,$b1 ffe8 d5 3e d505 ffef 1100 ffff sZ-h-pnc --- 1 0 ffff,ffff ffff,ffff 1647 < 1 > ffeb: OUT (C),A ffea b1 b1 d505 ffef 1100 ffff sZ-h-pnc --- 1 0 ffff,ffff ffff,ffff 1671: 1100:LDA #$00 1100 a9 a9 37 03 fd nV1BdIzC ffff,ffff ffff,ffff 1675: 1102:STA $ff00 1102 8d 00 37 03 fd nV1BdIZC ffff,ffff ffff,ffff 1683: 1105:JMP ($fffc) 1105 6c 00 37 03 fd nV1BdIZC ffff,ffff ffff,ffff 1693: ff3d:LDA #$00 ff3d a9 00 37 03 fd nV1BdIZC ffff,ffff ffff,ffff 1697: ff3f:STA $ff00 ff3f 8d 00 37 03 fd nV1BdIZC ffff,ffff ffff,ffff 1705: ff42:JMP $e000 ff42 4c 00 37 03 fd nV1BdIZC ffff,ffff ffff,ffff 1711: e000:LDX #$ff e000 a2 00 37 03 fd nV1BdIZC ffff,ffff ffff,ffff 1715: e002:SEI e002 78 00 ff 03 fd NV1BdIzC ffff,ffff ffff,ffff
Output 2
>reset >bk ffe0 >x >d ffe0
ffe0: f3 DI ffe1: 3e 3e LD A,$3e ffe3: 32 00 ff LD ($ff00),A ffe6: 01 05 d5 LD BC,$d505 ffe9: 3e b1 LD A,$b1 ffeb: ed 79 OUT (C),A ffed: 00 NOP ffee: cf RST 08
|
|