Well, as promised - I'm back!
Some success with my project, there are still a few gotchas I need to iron-out, but I thought that I'd publish here anyway to (hopefully) help a few others.
Resume: my goal is to have one programmable device to handle a few 'trick' features :
- Add a user ZP residing in page 2
- Add a user STACK residing in page 3
- Using 3 "undocumented NOP" instructions as triggers
The ZP2 logic is fairly easy, and it actually fits in a 22V10 device, but the logic for the STACK is more challenging and the stack UP/DOWN counter itself won't fit in a small device. So the target, for the moment, is an ATF1504 (if possible a 44plcc with jtag still enabled) to test the concept.
How it (should) work :Three NOP opcodes (0x0B, 0x1B, 0x2B) are used to trigger ZP2, stack PUSH, stack POP respectively. The actual reading/writing is performed using normal ZP instructions, the CPLD logic handles the address 'phishing' and the stack load/save/increment/decrement stuff. The logic became VERY complex if I tried to include the load/save logic in the state machine - so I've reverted to using a single register to read/write the value as an I/O location.
Now I need to add the rest of the logic to cope with load/save, and look at the *REAL* timing in real life...
(EDIT: added some info on the workings)
Here is how I hope the system will work :
Code:
PUSH (value on stack)
State cycles uP Data Bus Signals uP Addr Bus Next State
==================================================================
Push0 1cyc Magic Opcode SYNC R N/A Push1
Push1 1cyc Opcode (*) SYNC R N/A Push2 (*) STA, STX, STY : ZP
- decrement stack counter
Push2 1cyc ZP Address N/A R N/A Push3
- substitute Addr A9=1, A8=1, + Low byte from stack pointer [b]
Push3 1cyc data value N/A W (stack ptr) Idle
- data is written to ZP3 location. [c]
POP (value from stack)
State cycles uP Data Bus Signals uP Addr Bus Next State
==================================================================
Pop0 1cyc Magic Opcode SYNC R N/A Pop1
Pop1 1cyc Opcode (*) SYNC R N/A Pop2 (*) LDA, LDX, LDY : ZP
Pop2 1cyc ZP Address N/A R N/A Pop3
- substitute Addr A9=1, A8=1, + Low byte from stack pointer [b]
Pop3 1cyc Mem. data N/A R ZP Address Idle
- data is read from ZP3 address. Increment stack counter. [c]
ZP2 (user zero page)
State cycles uP Data Bus Signals uP Addr Bus Next State
==================================================================
Zp0 1cyc Magic Opcode(s) SYNC R N/A Zp1
Zp1 1cyc Opcode (*) SYNC R N/A Zp2 (*) any ZP instruction ?
Zp2 1cyc ZP Address N/A R N/A Zp3
- substitute A9=1 on the system AB. [d]
Zp3 ?cycles : Actual execution, but in "false" ZP Idle
[a] Isolate system DB from uP, place CPLD data on uP DB. ( CPLD <= DB => uP )
[b] The uP adress bus is piped through the CPLD. ( CPLD >= AB => System (+ A9, A8) )
[c] No isolation required, the LDx/STx will read/write from/to the 'false' address in ZP3.
[d] Force just A9, hold in place for ?? cycles (depends on the instruction !) use SYNC ?
... and I know that I have also to make sure that I avoid interrupts happening, and all sorts of other gotchas... but a few months ago I didn't have a clue about even SPLDs!