hmm, i agree tepples. plus implementing a per-instruction solution would clutter up my already not-so-pretty CPU core...
the problem is how to cleanly and efficiently handle read/writes to these special areas of memory. currently my brain contains the following overall methods:
1) Per-Instruction - For each instruction that could potentially affect the registers, put in code to 'inform' the PPU/I/O/Whatever handlers that a read or write has occured... probably implemented as a seperate function from the CPU-core itself, and it could handle setting up things like the 'strobe' effect neccessary to read data from the controller(s) ... This has the advantage that it won't waste as much (x86) CPU time as my other ideas, but it wouldn't be as accurate to what the hardware is doing, and would be intensive on my time to hand re-code each of the relevant instructions.
2) The way my program currently evaluates CPU instructions is that it reads the byte in memory the Program Counter points to, then uses a gigantor switch statement to switch to all possible opcodes - undocumented or erronous opcodes are dumped to a text error message with the code listed... so before i check the switch (each statement locally returns the CPU cycles involved back to the main function) i could run a subroutine that checks the opcode against a look-up table of sorts, and then if the opcode could potentially affect the registers, and if it could, it checks to see if that opcode is dealing with the registers or somewhere else in memory... and if this is true as well, then it executes another subroutine to handle whatever needs to be handled - emulating the 'strobe' effect, or informing the PPU that the CPU is trying to write to it, or what-have-you. This has the advantage of being cleaner for me to write, and also that it won't be as instruction specific, but it will load down the machine with another layer of programming to execute.
3) I can jury-rig writes to registers, by having my event handler (this is an OS-events handler, so reading keyboard/mouse input) check first for keyboard events, then only writing them once each CPU loop after a strobe has been received - it could write directly to CPU memory. Something similar for the PPU. reads would have to be jury rigged at the CPU end - neccesitating either a partial part 1 or part 2, if you see what im saying...? i like this method, because i think its closer to the hardware, but i dont know the hardware well enough to be confident to emulate it correctly this way. for example, my eventhandler function, after seeing a strobe, would write to the CPU memory once per (main) program loop, meaning it would write every 3 or 4 or 5 or 6 CPU cycles - essentially once per opcode - meaning that the program would lose data, because one couldn't transfer the data away fast enough, but i wouldn't know exactly how many cycles to wait to write more.
Hmm, so what do you guys think? I guess I found another important question - how exactly are multiple reads/writes handled? i mean i understand, that, for example, to read I/O data you strobe $4006 then read from $4007, but what happens if you say, read $4007 three times, then execute some other code for awhile, then come back? is the rest of the data still 'there', waiting to be read, or will its status be unknown? and if so, when does the register 'lose' the data?