Talking about history...
Fixed the never ending loop bug in Spike at $0721. It turned out to be a bug in the 6522 emulation code :
the bit 7 of PortB was not always controlled by the CIA Timer1 when the Timer was running in "One shot mode" (as specified in the ACR register).
The only game that doesn't work as expected now is clean-sweep : it crashes the VM when executing theinstruction at $002B : "CMPX [D,X]", with D=$CAB5 and X=$C9EA, wich refers to an invalid address ($989f).
I guess I'll have to trace from where the D / X values come from to locate the error...
I played a bit with the vectoring/rendering part...
Dots optimisationor next line to be drawn. This effectively remove nearly all useless dots between linked segments (eg. for instance, the segments that draw the montain in pole position). Standalone dots are still displayed (the inactive mines in Minestorm, for instance).
Tested some heuristics to remove the parasite dots from the vector lists. The best algorithm so far is removing a dot from the display list if it corresponds to one end of the previous
The ultimate algorithm would be to remove any dot that matches any segment ends coordinate. There will be a problem with the non-moving dot in the cosmic-chasm caves plan, though (as it will be removed since it's on a segment end)...
Made a few tests to implement Screen Persistence :
.1. By keeping the lines/dots in N history buffers (N=20) and drawing the oldest first, with a brilliance factor going from 0 (oldest) to 1 (new frame). This gives nice result but slows the emulation quite a bit on slower machines.
.2. (OpenGL feature) saving the new frame primitives in an openGL display list while rendering them, allowing them to be redrawn at the next frame at a lower cost. I used a glFog with a depth depending on the display list age, so that the list brigthness depends on the lists age. This method should be faster than the previous one (and does not need java objects buffering), but gives less visually attractive results.
|Without persistence||With persistence|
Here is the comment added to the CWAI emulation method:
* According to the 6809 docs, it seems that the CWAI mask should
* be applied to the CC register before saving it onto the stack;
* but for some reason it prevents Bedlam from working properly
* (the only game around that makes use the CWAI instruction).
* unless it becomes a problem with another game, it is likely
* to stay this way until I've got the time to check it out!
* BEDLAM problem (when CWAI is implemented properly) :
* the main game loop at $00FD starts with "CWAI #$EF" that in
* fact waits for the refresh timeout to occur on T2. Before the
* program is resumed at $00FF, the IRQ routine at $09B9 is
* called. This routine is the rendering code, as it seems to
* draw everything. When this routine is done, it ends with an
* RTI (at $0C1D) that will return the control to the main loop,
* just after the CWAI. The problem is that when the main loop
* gains control, a T2 timeout already occured, and the next IRQ
* is pending (and handled since CC now has the I bit reset).
* Thus the main loop code is NEVER executed because the CPU is
* constantly executing the IRQ routine!
* Maybe the problem is not in the CPU emul code, but in the VIA
* T2 handling and IRQ handling instead...
* TODO - When things have settled down, investigate for this bug
- Fixed a bug in Solar Quest : the ship was rotating to the left when the joystick was centered.
It was due to an error in several instructions of the 6809 emulation, that ended with the CC register
containing wrong condition flags. Most of the condition flags update code rewritten.
- Fixed a bug in Web Wars : the joystick, when centered, was acting as if it was in the top-right corner.
Was due to an error in the 16 bits read access to the VIA address space :
<port_bin both registers A and B, instead of
<port_bin register A and
<port_ain register B.
Doh!!! I had just forgot to add 1 to the address of the second byte for 16 bits access in the VIA6522 memory mapper... :)
Finally located the bug in MineStorm that drew garbage vectors for a few seconds when a fireball mine was shot before it became active.
It was in fact an error in the original code of minestorm, not in the emulator : In the mines rendering code, drawing an inactive fireball mine that was destroyed ended up in rendering a list that was located in the cartridge rom space (which is empty, since Minestorm is running)!
Once the bug was identified, the cure was extremely easy : initialising the cartridge rom space with $01, so that every location in this space is an empty Vector List.
Here is the comment added to the removeCartridge() method in VectrexMemory.java:
* We fill with $01 to bypass a bug in MineStorm (invalid
* reference to the ROM area, when a fireball mine is hit by
* a bullet while it is not yet moving). This could be fixed
* around here in the ROM :
* EC17 [86.04.........] LDA #4
* EC19 [A7.41.........] STA 1,U
* EC1B [0A.EA.........] DEC <$EA ; $C8EA
* EC1D [7E.EB.53......] JMP check_next_bullet ; $EB53
* Somewhere in this routine there should have been :
* LDA #8 ; mark fireball as active
* STA ,U ; store mine state (if it wasn't moving, state was $10)
* Actually, when a stationnary fire mine is hit, the program ends
* up drawing a VL located at $3408 (because it assumes that an
* object that's not moving is either a dumb / fire / magnet /
* magnet+fire mine, whereas here it's a fireball!
* So to fix this we just fill the ROM with ones so that it
* becomes a big empty vector list.