Wednesday, 24 February 2016

More bugs and back to the Amiga

I've completed the pickup/drop hardware sprite logic and so Neo Geo is now on par with the other ports, except for the Z-order issue.

In the process of testing I found another bug in my Knight Lore core C implementation; dropping objects sometimes causes those objects to disappear. I've added this to the to-fix list along with a couple of other bugs I've seen infrequently; one room always kills you when you first walk into it and walking into a room from a raised arch will leave you suspended in mid-air.

But for now I'm going to return to the Amiga port and get CPC graphics working. Once that's complete I should only have the above-mentioned core issues to resolve, which will of course affect all ports. I've spent far too long on this aspect of the project and really want to put the C ports to bed - make the ports playable and release the source before moving on to the original goal of this whole project!

This weekend I'm off the the US again for two weeks for work. That's another two weeks of lonely nights in a hotel room, and although last trip I didn't get much done on the project, the novelty of it all has definitely worn off and I'll make a concerted effort this time 'round.

To this end I'll be making sure my laptop has all the Coco 3 technical documentation, development toolchains and emulation environments that I'll need for the rather daunting task that lays ahead. I still don't have a feel for how I'll mirror the heavy use of the Z80 IX & IY registers on the 6809, but I'm sure I'll work out something.

Phase one will be glorious monochrome, to get an idea of how the 1.89MHz 6809 is going to handle what was being done by a 3.5MHz Z80. I'm sure it'll compare favourably, especially given the fact that the Coco 3 doesn't have the issue of video memory contention like the ZX Spectrum. Hopefully there's enough headroom for a more colourful version down the track!?! If not, it's not going to be any worse than the BBC Micro port! ;)

UPDATE: CPC graphics on the Amiga. Not as painful as I first feared. Funnily enough I had exactly the same bug as the Neo Geo port, in that the orange rooms were actually red. Of course I couldn't for the life of me recall what the issue was for at least 5 minutes - then it came to me.


CPC graphics mode on the Amiga

Still a few palette issues to sort as the palette must be programmed on-the-fly, unlike the PC and Neo Geo ports. However I'll likely back-port the Amiga palette changes to the PC as most retro ports won't be in 256-colour mode.

UPDATE#2: Fixed the remaining palette issues on the Amiga. The border colour for the main menu and game over message screens will never be correct when running CPC graphics, as the CPC sprite routines only support 4 colours. Not exactly a deal-breaker...

3 comments:

  1. Things like LDr n,X ; LDr n,Y or LDr n,U are pretty good replacements for IX and IY instructions.

    I also find myself putting a lot of variables on the stack, to cover for the lack of registers compared to the Z80. It does slow things down, but it makes life easier.

    While I have limited experience in directly converting Z80 to 6809 (Deathchase), I'd say that 1.8 Mhz should be ample when running in a 6K video mode. I found the 0.9 Mhz CoCo CPU to run code a little slower than I'd expect from the 3.5 Mhz Z80, although I could've optimised it a bit for the target CPU.

    Are you interested in making a version for the standard CoCo or Dragon?

    ReplyDelete
  2. Thanks for your advice. I've just started on the Coco3 port last night and this morning, if only to get my toolchain and process underway before I leave for work OS this weekend.

    I was thinking that I'd more-or-less have to use X,Y for IX,IY given the copious use in the original code. However that doesn't leave much else on the 6809 for AF,BC,DE,HL and their alternate counterparts. Even in this very early stage of the port I'm undecided on a strategy moving forward, and I don't want to get too far into it and have to rework large amounts of code.

    I'm wondering whether I should use DP registers for shadow Z80 registers, at least when used as parameters for subroutines? Unfortunately my experience in 6809 is limited to porting 6502 (Lode Runner) and that was simply instruction-for-instruction translation for the most part. I haven't written much in the way of my own code so unsure of best-6809-practices as it were.

    As for Coco/Dragon - the code I'm writing should run with very few changes, but the limiting factors will be CPU speed and free memory. The ZX Spectrum version uses almost all of the available 48KB memory for example. IIRC there's about 16KB of sprite memory alone! But if someone can suggest ways around these issues, I'd be happy to attempt a port.

    ReplyDelete
  3. Using DP for registers is a fair idea. It's certainly a fast way to access memory. I particularly like using it to speed up access to regularly used <=256 byte tables, like masks. Also, it can be very useful to reduce code size.

    My stack technique works like this, say you have B, C, D, E set up in your routine, but no spare registers to store them as the function goes on.

    Routine:
    PSHS U
    LEAS -4,S
    TFR S,U
    LDA #$00 ; B
    STA 0,U
    LDA #$01 ; C
    STA 1,U
    LDA #$02 ; D
    STA 2,U
    LDA #$03 ; E
    STA 3,U

    ...
    ; when you want to use them...

    LDA 2,U ; D
    ADD A,4 ;do something
    STA 2,U ; D

    ; Finally, on exit...
    LEAS 4,S
    PULS U
    RTS

    Also, you can save a byte (and a cycle, I think) by doing PULS U,PC instead of the separate PULS U and RTS. You can also make it much more readable by using EQUs for the offsets and the LEAS value.

    Obviously, this is quite a bit slower than setting aside some space in your DP and works better in longer routines where the set up is a small part of it, but sometimes you have no space, the routine doesn't have to be particularly optimal or it needs to be re-entrant.

    You can also use this technique (if a function has an awful lot of parameters) by setting up the stack outside the function and passing U in. Again, DP is faster.

    In my case, I used the stack technique where number of registers were an issue and then optimised it to quicker code where I had to. Otherwise converting complicated routines can become pretty hard.

    I was recently asked if I would release the source code for my two 6809 games (to see if they were suitable for conversion to the 6803 CPU of the MC-10), so maybe I should do that and it'll be an easier way to show the techniques I used.

    The CoCo/Dragon with 64K would definitely have enough space for a 48K Z80 game. I find that I only use the ROM routines for things like tape access and joystick reading, so that can be paged out and accessed through a little routine held in lower memory, leaving a contiguous block of over 60K free for the game.

    Speed would be the issue for the CoCo/Dragon. You might end up with something at 3/4s speed without optimising it.

    I certainly hope you'll consider it, or maybe leave it available for others to try.

    ReplyDelete