Post by turboxray on Jan 2, 2020 18:03:44 GMT
This was over in the personal project threads:
Nintendo was always the king of mappers and extra memory and chips on carts, but even Sega dabbles lightly in that space. And now there are “home brew” carts with those kinds of augmented capabilities for hobbyists. Has anyone considered doing this for PCE, aside from tapping into the Turbo Everdrive? An extra 128k or RAM and a little CPLD with some additional functions? I know the CD units and system cards help the PCE put a bit, but I like the idea of having something available for programmers aiming for a Core or Turbo but who still want some extra tools or extra oomph.
It reminded me of something I read over on the 6502.org forums years ago. There was a company that made a 'co-processor' for the original 6502. It basically monitored the bus and address lines of the 6502, and when it encountered an illegal opcode, it would insert some other legal opcodes in its place. But the key part, was that it did operations based on its own assignment mapped to those illegal opcodes. This wasn't something new, but in the 80s!
On the PCE, it could work like this:
Take opcode 0x0B, which is treated as a NOP on the PCE. Make a macro that outputs 0x0B, addr (two bytes), addr (two bytes). The bus monitoring logic would see this opcode and inject 5 NOPs. But behind the scenes, it could do a RMW of the two addresses. Something like ADD source, destination. That's 10 cycles. Not a whole lot of savings compared to doing it with normal opcodes, but 0x1B could be the 16bit version, 0x2B being the 24bit version, and 0x3B the 32bit version.
There are 22 total illegal opcodes on the PCE. The above would use 4 of them.
Here's some more:
move source(16bit), destination(16bit): byte, word, long word(24bit), double word(32bit).
If you mapped in ram from the cart to $2000 range, instead of the internal 8k ram bank, then you have control over ZP stuff.
You could do something like:
lda long_addr (24bit direct)
nop, low byte, mid byte, high byte => cpu sees nop, nop, lda #imm. 6 cycles
lda (long addr) (24bit indirect from 16bit addr)
nop low, high => nop, lda #imm. 4 cycles
lda (zp long) (24bit indirect from zp)
nop zp => lda #imm. 2 cycles
lda (zp long)+ (24bit indirect from zp with auto-increment)
nop zp => lda #imm. 2 cycles
lda (zp long),idx (24bit indirect+ index from zp. ZP index is 16bit)
nop zp, zp => nop, lda #imm. 4 cycles
lda (zp long),idx+ (24bit indirect+ index from zp with auto-increment on the ZP index. ZP index is 16bit)
nop zp, zp => nop, lda #imm. 4 cycles
Same for STA.
What about from ST1/ST2 love?
st1 (zp) (16bit indirect address)
nop zp => st1 #imm.
st1 (zp) (24bit indirect address)
nop zp => st1 #imm.
st1 (zp)+ (16bit indirect address, auto increment)
nop zp => st1 #imm.
st1 (zp)+ (24bit indirect address, auto increment)
nop zp => st1 #imm.
Same for ST2.
The 16bit address modes (direct or indirect) would be for the logical CPU space, and 24bit would be full range of ram/rom (from the co-processor layout; so 24bit addressing on the cart basically).