ParaJVE : Parabellum's Java Vectrex Emulator   

Official Home of ParaJVE ... A travel through the programming of a freeware Vectrex emulator in java!

Tuesday, July 18, 2006  

Talking about history...

Here is a short description of the emulator's developement history so far :


  • 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 the instruction 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 optimisation

    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
    or 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).

    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 persistenceWithout persistence With persistenceWith persistence


Fixed a bug in Bedlam (the game loops forever just before the first level "maze" starts growing). It is somehow related to the 6809 CWAI instruction emulation. The fix is only temporary, and need more investigation to be handled properly.

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 :

    "LDD <VIA_port_b" at $1D1F returned <port_b in both registers A and B, instead of <port_b in register A and <port_a in 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
* 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 :
* launch_fireball:
* 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.



Post a Comment

<< Home