Thank you for all of the helpful replies! I didn't get any notifications from the site so I had no idea there were so many responses
I did a little bit of research over the weekend and I've came to the conclusion that the RDY/BE halting (and Apple 2) approach would be helpful it I was going to share the same physical memory on the same bus.
I had look through my old Vic 20 books to get an idea of what the most complex 6502 instruction would be (as far as RAM access is concerned), and I think INC $xxxx,Y is a good example. This is an instruction that reads from RAM, increments and then writes back to RAM in 7 CPU cycles.
My VGAController reads my RAM and buffers a line of pixel data - and the buffer is more or less full during the horizontal porch and ready to be emptied during the horizontal active display time. For a 640 pixel display, it takes 800 pixel clocks to do a line. 160 of these clocks I am filling up my buffer and roughly 640 clocks I am emptying the buffer. There is a slight overlap where I'm reading from the buffer at the same that I'm writing but that's no big deal. What I'm trying to convey here is that I'm only reading my RAM for 1/5th of the time during one horizontal scan line, so I have plenty of time to do other things.
Tell me if I'm crazy, but I'm thinking I should be able to easily clock the CPU by generating a 5MHz clock - basically allowing the 6502 to have a fifth of the VGA clock (5 lots of 200ns per line) to do it's thing. The VGA display will be asynchronously popping pixel data from the FIFO so it shouldn't be affected by the 6502's time slices. The only difference for me is that instead of reading 320 words in one go, I'll be interleaving the VGA framebuffer reads with 6502 RAM access.
Currently:Code:
0.......porch..........159 | 160.....................................active.....................................................800
(read 320 VGA words) |
.....FIFO full
| pull word (2 pixels) every even X position from FIFO
Rather than providing direct connection between the 6502 and my RAM (in the classic sense), I'm thinking of exposing an "emulated" interface to the 6502 so that it thinks it is talking directly to RAM but will in fact be talking to my SRAM Controller inside the FPGA. This way I can receive read/write requests from the 6502 and process them when a time slice becomes available. Likewise, I should be able to read RAM when the 6502 requests it, throw the result into a data register and continue processing the VGA framebuffer reads.
Proposed:Code:
0.......porch..........159 | 160.....................................active.....................................................800
(read 80 VGA words)
| (6502 slice)
| (read 80 VGA words)
| (6502 slice)
| (read 80 VGA words)
| (6502 slice)
| (read 80 VGA words)
| (6502 slice)
| (6502 slice)
| pull word (2 pixels) every even X position from FIFO
Above diagram is not "to scale" lol but hopefully it will give everyone (including me) and idea of what I'm doing. If I'm right, the 6502 will not need to halt or yield at all - it will get its dedicated cycles and these time slots will allow suffcient time for a RAM read or write via my SRAM Controller.