--Not sure why the STIC has any connection to the SST, but the docs on the SST are virtually non-existent from what I could find.
--I took advantage of Func and Action instead of passing bool references to both devices. I think this makes sense.
-Added reset functions for both devices.
My comparison log for INTRM is still weird because it says it is true initially (Expected) and remains as such after the first instruction (A bit odd). I think this happens because the STIC is supposed to "tick" and shift SR1 to false immediately, but the STIC tick happens after the CPU tick, and the CPU tick is where the logging happens. I need to find a better place to put this logging, and I need to implement the STIC ticking for IntelliHawk. I'm not positive how to approach the latter issue as I assume a tick means one instruction execution, and my executions happen in a loop on the CPU, which has no reference to the STIC, so I'm not sure where this fits into the equation.
-Foreground / Background | Color Stack Mode
--Actually made a boolean for it (FGBG).
--Reading from a write-only STIC alias of $21 does change the STIC into Color Stack mode, but it doesn't actually read.
--Color stack mode is enabled when $21 or its alias is read and it is disabled (FGBG) when written its written, both having to occur during VBlank Period 1.
---This is what I gathered from the wiki, but I'm confused as to why it says that "The STIC stays in this mode until the program accesses location $21 again." I'm assuming this doesn't mean the mode changes on every access because then I don't understand why a read would change to a different mode than a write.
--FGBG is disabled by default. I don't think it matters.
-I will now assume that 0x7000 is not mapped for the sake of continuing on. I will need to implement a mapper system shortly though.
--Did the same thing for 0x4800.
-AND@, MOVR, CMP enabled.
-Made the logging separator generate before an instruction instead of after the register states. This is quite petty, but I don't like the separator at the end of the file.
I hit an infinite loop, and I'm very very certain it's happening because I don't have an interrupt system yet. Time to stop avoiding that!
-Separated cartridge logic into a separate ICart named Cartridge.cs.
-Made WriteMemory return a bool to match ICart.Write. It currently returns true if either the cart or the core responded.
TODO: Parse the vanilla Intellivision ROM, which will hopefully include the read / writability of the data segments. adelikat seems to think that I just need to send the bytes to $5000, but I'm not convinced.
-Applied to the old Gameboy core. Why not? It at least fixes that annoying bug from before if we ever care to use it again.
-Both logs are now written to different files.
--It now just builds a strings and writes on finalization.
-Fixed up format strings.
-As RegisterPC already increments upon reading the third decle, I now just store PC as the return address for jumping instead of PC + 1.
-Disabled Intellicart hook for ReadMemory, which seemed to be interfering.
-Implemented MVO@.
-Several instructions are now executed in succession until it hits the unimplemented "XORR R5, R5".
I should probably refactor Disassemble and Execute to label registers as source / destination to avoid further confusion at some point. My disassembly might have the source / destination registers flipped as well.
-Fixed disassembly for JMP:
--Now it uses the parameter pc, not RegisterPC.
--I was loading both the second and third value from the second's address.
--Casting the calculated addresses to bytes when addresses are 16-bit was a bad idea.
--Removed a closing parenthesis I accidentally stuck in the formatting.
It seems that I've gotten far enough to use the Executive ROM as a test case! Now to go instruction by instruction and see if they work as planned and hope this will all eventually make something.
--Afterwards, the data is reconciled, right now by chucking out the core value if the cart responded.
-WriteMemory now writes to both the core and the cart unconditionally.
--Each case now breaks out of the switch statement in case we want to do more complex things at the end of the function later on.
-All default paths in both functions now throw an exception.
-Implemented the final CRC check.
I didn't get around to implementing bank-switched ranges, but I don't think it's worth worrying about that right now considering that the Intellicart is not marked as readable at the initial PC, so something is either wrong or I need to implement more things before this will work. I think I'll put Intellicarts on hold and try to get a .int / .bin to run in the meantime.
--In my test case, only a few segments were set to readable and nothing else was set. 0x1000, which is where the PC is initialized to, certainly isn't in a writable page.
--Although I've read that these memory attributes affect the Intellivision and not the Intellicart, I'm pretty sure this has to be implemented in the Intellicart so that my Read/WriteCart functions can choose to respond / not respond depending on these attributes. I very well could be wrong.
-Hooked Read/WriteCart into Read/WriteMemory.
-Implemented memory attributes into Read/WriteCart.
--TODO: Bank-switching.
TODO: Fine address table and memory attribute / fine address checksums.
-Initialized the memory devices with a tentative size that ignores the unofficial ranges.
-Masked addresses to match those sizes (That's my understanding of what the memory map needs to do based on other examples).
-Added the ICart interface.
-Started the Intellicart parser; got far enough to know that the files I'm working with are not Intellicarts. ^_^
-Fixed JMP disassembly; I need to return on an invalid opcode because I was breaking out of the inner switch statement, not both that and the outer one.
-Set up the "official" memory map - see http://wiki.intellivision.us/index.php?title=Memory_Map
--Things I didn't do:
---Accessibility.
---Additional Occupied Memory Ranges.
---Addresses Available to Cartridges
---Initialize any of the byte arrays.
--Not sure which of these I need to do, but clearly the byte arrays have to be initialized somewhere to something and there's a lot of gaps in this memory map.
--It's going to be based heavily based on Imran Nazar's "GameBoy Emulation in Javascript" series. I figure it's better that I learn by emulation (Har har) instead of spending more time reading references than programming.
--Finished the memory management (Part 2).
--adelikat:
---Do I implement the required functions for IEmulator and IVideoProvider now, do it later, or is this something you or zeromus would do (Like for the API)?
---At what point should we have the emulator actually use this core instead of zeromus'? As terrible as he says his is, this one doesn't do anything yet. Still, I need some mechanism of testing it.
-Made it so that the log only opens when logging is true and that the file closes upon destruction.
--Still, BizHawk says that it can't open the file again when I load a game again. This is because the emulator class gets recreated without deleting the original one every time you load a game.
---adelikat convinced me not to care about this.
-Fixed the initial state of the GB CPU:
--It was setting AF to 0x01, not A. This is effectively setting F to 0x01, which gets overwritten later anyway.
--Two BIOS flags were used in different places; merging them gets the PC to start in the right place.
-By fixing the initial state, most of the log now matches up.
--The only differences are the VBA has some repeated records (Where all of the registers, including PC, are the same as the previous record) whereas BizHawk doesn't.
--This very well might be an issue with how I'm logging it
--Alternatively, it could be some kind of lagging mechanism.
--I'm not sure which version is even correct...VBA is far from accruate.
--All in all, considering that the vast majority of the diff comes out as the same, I think I fixed the biggest CPU related bug. Will investigate more later.
--Gets worse as the scale increases.
--For x3, the box doesn't increase size, but the box still changes position. I think there might be a difference between the TargetZoomFactor and the actual screen size, so perhaps we should tie this to something else.
-Working on very small optimizations to the NES PPU with CorruptedSyntax...this is more fun, so we'll do this first.
--Eliminated an entire loop.
--Branched to two loops instead of branching for every iteration in one loop.
--Got rid of some redundant instructions using temporary variables.
--This may be completely premature, but I seem to have gained a few FPS from doing this. For me, I get 38-39 FPS where I'd previously get 33-34.