Saturday 30 April 2016

Your bullets cannot harm me...

... my wings are like a shield of steel! (Plus I haven't implemented the player blowing up!)

The invaders are firing back now - not fair!

Fixed the scoring and added the two object handlers for the two invader shots/bombs.

As-is, the invaders aren't shooting from the correct columns, and they're only shooting one type of bomb or the other at any one time, but it's close and gives an idea of how the game will play - which is, of course, very much like the arcade original! :)

There can't be too much code left to port - neither of the two new object handlers required any new subroutines to be coded! Most of what's left involves the player blowing up and the saucer.

I would probably have been more productive tonight, but I'm working on my laptop, perched on the breakfast bench whilst my wife makes a "camel" cake for my daughter's 4th birthday party tomorrow. We have absolutely no idea why she asked for a camel cake, but a camel cake it is. If you haven't guessed, she's not a fairy princess type of girl, which is pretty cool if you ask me!

Friday 29 April 2016

Like fish in a barrel

Managed to fix a few little bugs at lunchtime today. They've all been quite subtle; another carry flag bug plus a case of me using the 6809 TST instruction where the 8080 code expected A to hold the value after the test. Fortunately (well, in most cases it's fortunate) the 6809 LD instruction affects the zero flag so it was a simple case of changing the opcode.

Aside from the shot speed, one of the other bugs I fixed was the damage done to the shields when shot by the player. Turned out that I hadn't reversed the pixel data for the shot sprite or the explosion. That's sorted now and the shields are destroyed in exactly the same way - pixel-for-pixel - as the original.

Both the player laser base (object 0) and player shot (object 1) handlers are still incomplete; the player doesn't blow up and the shot doesn't affect the saucer score or timing. However I'll press on and implement the first of the alien bombs, the so-called "plunger" shot. Once that's done and I've implemented the player being hit, the game will be somewhat 'playable'.

EDIT: I've just realised that I'm not updating the score.. I might tackle that next.

UPDATE: Scoring happens (was implemented, but a bug meant nothing happened) but now you don't get the right score for each alien. It'll have to wait until another time.

Thursday 28 April 2016

Ready, Player One!

All the stub game object handler routines are in place so the game task scheduler can run.

Added game object #0 - the player. You can coin up, start a game and move left/right. For some reason the demo doesn't appear to be working properly yet - the laser base just moves to the right hand side of the screen - despite the code having being ported.

A game in action, sans bullets/bombs

I need to finish off the player handler (blowing up), then there's four more handlers; player shot, so-called alien rolling shot, so-called alien plunger shot, and finally the handler that does both the squiggly shot in attract mode and the saucer. And that's pretty much the bulk of the code ported!

Can you believe that there's only ever two (2) alien shots on the screen at any time!?! A far cry from the modern bullet-hell schmups - yet the game is still challenging!

UPDATE: You can shoot and destroy invaders. The player shots are too fast though, so they eat through the shields and fly up the screen about twice as fast as they should, by my reckoning.

Like shooting fish in a barrel - when they don't fire back!

Wednesday 27 April 2016

What a difference a flag makes.

When porting between CPUs, some differences are more subtle than others, and can be the cause of some hard-to-find bugs. A case in point is the routine that determines whether the invaders have reached the side of the screen, and need to drop down and change direction.

[An aside here: the game checks this by examining a scan line of pixels at the left or right edge of the screen; any non-zero pixels means the invaders have hit the edge. Tandy Invaders, written originally for the 4KB TRS-80 Model I, and which I reverse-engineered not too long ago to port to the Microbee, does exactly the same. I recall thinking at the time that it was a funny - if not slightly dodgy - way of doing things. Turns out the Real Deal uses exactly the same method. Oops!]

Back to subtle bugs - the routine that checks the above-mentioned line of pixels explicitly sets the carry flag if a non-zero pixel has been detected. Otherwise it simply returns once the scan line has been checked. It should be noted that each time through the loop, it executes the AND A instruction to test for pixels, which incidentally clears the carry flag.

In my porting, I negate the need to load and subsequently test the video memory byte by simply using TST ,X - a nice little 6809 optimisation - except for the fact that it doesn't affect the carry flag. In fact, none of the instructions in the entire routine affected the carry flag. So I was getting the invaders oscillating one step the the left, then right, as they quickly marched down the screen. Of course the fix was to simply clear the carry at the start of the routine.

Knight Lore had a few routines that used the carry flag to signal various conditions, and I was careful to ensure that the 6809 code did the same. However for some reason I found this particular instance to be more subtle, and hence harder to debug.

So with the invaders marching in the demo now it's time to add the player. But first, there's the minor matter of the game crashing when you coin up and start an actual game...

UPDATE: You can now coin up and start a game; it draws the invaders and they start marching across the screen as they should. The main game (background) loop is running, albeit with a few subroutine calls commented-out as they have yet to be ported. Nothing particularly exciting in there.

Next step is to add the handlers for the missing game objects; first on the list is the player. The player laser base should then appear and be able to move and shoot! That'll be the next blog update.

Tuesday 26 April 2016

Invaders... from space...

Haven't been able to spend a lot of time on Space Invaders lately (long weekend here) but tonight I finally got the invaders displaying in the demo mode!

The demo mode display, finally. A lot of code ported to get here.

In the process I've had to add the 2nd interrupt - an 8.3ms timer that is started in the VBLANK interrupt - that should (in theory) interrupt somewhere around scan line 96. I haven't checked exactly where that's happening yet, due in part to the fact that the 'BEAMY' value in MESS at the start of the VBLANK ISR increments every frame!!! Taking that into consideration though, the TIMER interrupt appears to be happening around 120 scan lines earlier, which is a good thing.

Now if I could only get someone on MESSDEV to give two hoots about it...

Something else that only sunk in tonight... non-bit-shifted rendering routines use the CPU address map value of the target video byte when referencing display positions. Such values appear in tables and hard-coded throughout the code. OTOH, potentially bit-shifted routines use the pixel offset - but offset not from the start of the video memory as you'd expect, but rather from the start of all RAM. That threw me for a while when trying to work out how to get the invaders to display correctly. Not sure how I got the animated squigggly alien shot to work in the splash animation though...

And this coupled with the endianity changes can do your head in a bit when debugging.

The source file is around 3,300 lines now. Most of the core code has been ported and what remains is mostly concerned with the player movement & firing, invader bombs and the saucer. I've still got plenty of debugging to do in the code I have ported, let alone what's left. But with both ISR's in place, I'm not expecting any major roadblocks.

Sunday 24 April 2016

Feeling shifty...

Quick update. Splash animations both working. Hardware shift register emulated and working (using Knight Lore tables verbatim). Not much overhead doing it on the 6809, especially considering the shift value is only written once per sprite.

Working through the code that initialises the game for the demo mode. That will likely entail writing almost all the the remaining code once the demo is fully working. I'm not quite to the point where the rack (aliens) is displayed. I'll post some eye candy once I'm there.

On a side note; Brian White has confirmed the Lode Runner Demo cartridge image runs on a stock 128K Coco3. And Knight Lore has been seen - by some at least - at CocoFEST. It'll be time to whip those into shape for cartridge production in the not-too-distant future!

Friday 22 April 2016

Cosmetics

Again, I've been forging through the code to get the attract screens animated. The first one - where the invader replaces the upside-down 'Y' in 'PLAY' - is complete. The second - where the invader shoots the extra 'C' in 'COIN' - is (finally) coded but not debugged.

To give you an idea of how much code is involved just to get these animations done, the Coco3 ROM image is now more than half the size of the arcade ROM! The source file is now just shy of 3,000 lines, though it includes the comments from the Computer Archeology disassembly (for the code that has been ported) plus data. Taking a quick look at the listing though, I'd say I've definitely completed more than half of the code, if not somewhere approaching two-thirds!

Of course that's not to say that half of the code is concerned with attract screen animations. Aside from the expected low-level print/render routines etc, much of the framework needs to be in-place to allow the task scheduler to run - which controls the animations - and also control the alien shot (bomb) which is treated much like an in-game shot. So in theory, once I debug the 2nd attract animation, a lot of the hard work will have been done, and the rest of the port should go relatively smoothly.

An aside: it's funny how you don't notice things until you're developing/debugging... when the alien replaces the 'Y' it's actually 1 pixel too close to 'PLA' and once you are aware of it, it sticks out like a sore thumb!

UPDATE: First of all, I've (finally) fixed the timezone on the blog.

Tonight has been all about debugging the 2nd animation, and I've managed to more-or-less get it working. However it doesn't exit the task when the 'C' has been bombed, so it sits in a loop executing the same task, but doing nothing. At this point I can't find the code that exits the task or, more specifically, I can't find where it would be called from that task. For another day.

One issue that permeates the code is endianity. There's a bunch of tables that store 16-bit values, a lot of which are accessed via both 8-bit and 16-bit operations. And to further complicate matters, a lot of them are initialised from blocks of data in ROM - sometimes multiple blocks depending on game logic. I need to swap the byte order (labels) in the tables (for 16-bit accesses), adjust the ROM values accordingly, and then inspect each code reference to decide whether or not the code also needs to be modified. Note also that some of these data sections in the disassembly are not commented.

And as I've mentioned previously, the dependence on variable addresses is ghastly.

Once I debug this last animation, I'll need to implement a software emulation of the hardware shift register to see accurate graphics, even in the attract screens. Just like Knight Lore, I'll build shift tables in memory, though the layout will be optimised specifically for Space Invaders.

Wednesday 20 April 2016

Not winning any coding awards...

I've been forging through all the code that is called as part of the demo and/or attract modes from the main line execution path. The only trouble is, I can't actually test any of it because it's all kicked off by events created in the ISR's which currently don't exist except for a simple countdown timer used for delay loops. But at least I know it assembles.

Along the way I coded the attract mode Easter Egg, which I'd completely forgotten about; if you haven't seen it, it's not very exciting at all. I did read that you can't actually trigger it in MAME due to the manner in which the input controls are sampled - so that's one thing the Coco3 port will have over MAME!

As others have noted before me, I would have to agree that Space Invaders doesn't exactly showcase the highest quality of 8080 coding. For example, some of the logic depends on variables being at particular addresses, so simply changing the .org statement in the .ASM file, or even adding or moving variables around, would actually break the code! The dilemma for me is, do I fix these issues, or faithfully reproduce them? Right now my memory map is purposefully identical right down to the byte level, so it makes no difference. But I still have half a mind to do it properly, even if I document the way it was done originally in the source.

It's pretty obvious the assembler they used was quite primitive - if indeed they used one at all! In fact, it wouldn't surprise me if they didn't use one. There's certainly evidence that at least some of the code was patched, rather than re-assembled, although that could have been done only to negate the need to re-image all of the discrete ROM chips.

Now to the interrupts...

UPDATE: You can add a coin. Just one coin for some reason atm...

Tuesday 19 April 2016

One timely interruption

Not a lot of time to work on Space Invaders over the last few days, but coming along nicely. I definitely think I'd like to finish it now before returning to Knight Lore.

As-is it loops through the attract screens, complete with punctuated text rendering, although the animations (involving the little invader) are yet to be coded. The demo displays the shields and the line across the bottom of the screen before continuing onto the attract mode.

Source, including data, is around 1,500 lines already. In comparison, the IDA disassembly of the arcade original Z80 code is around 4,200 lines. The translation from 8080 to 6809 has been quite straightforward thus far; I'm using a fairly strict register mapping convention and I've only been forced to use shadow memory registers (for BC) once or twice.

The game uses interrupts heavily, having two (60Hz) interrupts on specific scan lines which drive most of the game logic. I've only enabled one of them - line 224 which is effectively the VBLANK interrupt - and it simply decrements a timer counter (used in the attract mode) at this point.

Rather than attempt to use a HBLANK interrupt and count scan lines for the other interrupt, I'll start the timer in the VBLANK interrupt. The exact timing of the second interrupt isn't critical so it should be accurate enough for the code to run without any noticeable difference.

Once I finish the portions of the attract mode that aren't interrupt-driven, I'll have to start fleshing out the ISR's to see anything else happen.

Sunday 17 April 2016

Space Invaders

And so it begins... with the Knight Lore ROM image emailed off to John for CocoFEST, I've decided to take a short break from filmation games until it's time to produce cartridges, in which case I'll need to look at code optimisation. However I've been in contact with another programmer who is in the final stages of porting Pentagram to the Atari 8-bit machines, and he's given me some invaluable insight into where the code can be improved. In fact, he has Pentagram running on the Atari slightly faster than the ZX Spectrum, and a lot of the code is still auto-generated from Z80 to 6502!

I was just playing around with the arcade version of Space Invaders, seeing how that would look on the Coco3. I fired up MAME and took a memory dump mid-game, played with the layout a bit, and then loaded it into the Coco3 under MESS.

Space Invaders (mock up) on the Coco3 under MESS

It looks pretty good to me, and tonight I couldn't resist starting on an actual port. Whether or not I decide to see it through just now will depend on how quickly it proceeds in the initial stages, but if my experience with Knight Lore is any indication, it might not take long to get things well along.

I'll retain the original video memory mapping (including rotated screen) until the game is all-but-ported, to simplify the process. I've done rotation on-the-fly in my TRS-80 Model 4 'bootleg', so it's not a big deal. Running MESS with the 'rol' option will give me the correct display during development. One thing I do need to do though is bit-reverse all the graphics data, as the pixels are laid out in the reverse order within each video RAM byte.

Space Invaders in 6809 (WIP)

I've also decided to work with the disassembly on Computer Archeology, rather than my own reverse-engineering,  for reasons I won't bother to explain.

I'm hoping to knock this one over fairly quickly, given all the reverse-engineering has already been done and it's a relatively small - and simple - program. I'm not going to bother producing a cartridge for Space Invaders; rather I'll make disk and ROM images freely available for download.

Friday 15 April 2016

Bit Rot?

I thought I should bring all the C ports up-to-date today; Amiga is there and Neo Geo is all there bar the new (Mick Farrow graphics) sprite tiles being generated (ie. it has the dip-switch setting and the code just needs a simple tile bank offset to be added).

It wasn't all plain sailing though, the Neo Geo port gave me a bit of grief. Not having touched this in months, I just needed to add a few stubs for new palette routines so it would link and fire up MAME. I was a little surprised to be greeted by the cross-hatch screen. I generated a clean build, fired it up again, and same thing. The dreaded bit-rot... hmm...

After checking that the files were all being generated, and grasping at a few other straws, I decided to find out exactly what the cause of a cross-hatch screen is on the MVS. Turns out they're colour-coded, and my blue border meant that a cartridge could not be found! The only thing that could explain that under emulation would be a corrupt P1 (program) ROM.

Loading the P1 ROM into a hex editor revealed immediately that the file was all-but-blank! Time to go back and take a closer look at the compilation output. It's not easy to maintain a clean build on a multi-platform project, especially retro platforms with development toolchains that can be rather old, and as it turns out, the Neo Geo gcc (v2.95.2 circa 1999) complains quite a bit. So much so, that you tend to ignore it after a while. Examining the output more carefully revealed an assembler warning about incorrect attributes being set for .rodata in the newly-added Mick Farrow sprite graphics data arrays.

Without going into too much detail, I have needed to use section attributes to force gcc to place certain data structures into ROM - const just hasn't worked in some instances (yes I know the differences of placement). The confusing thing is, it was never an issue with the original ZX or CPC graphics arrays, and they're not significantly different to the new file. After using some Google Fu it seemed it was a known gcc bug at various times in the past, however the work-around didn't assemble in my toolchain. Again, grasping at straws, having noticed that the existing graphics files had additional arrays defined before the sprite arrays, I instantiated a dummy 1-byte array at the top of the new file and - viola - it worked! And for the record, exactly the same section attributes were still being set for the sprite data!

The whole process was probably a good hour or so.

I'm not about to ponder any further on this issue - it's not broke (anymore) so I won't fix it!

UPDATE: Mick Farrow's graphics on the Neo Geo port.

Mick Farrow's modified graphics on the Neo Geo

Incredibly the game now uses no less than six (6) sprite tile ROM's, not quite full but in the order of 40,000 tiles. In reality, at least half are never used by Knight Lore (ie. the VFLIP'ped versions, with the exception of a few border sprites) but at least the framework is there for the other filmation titles that may use them.

As a result, I had to find a larger host game, this time pspikes2. Basically each sprite tile ROM pair holds the sprites for an entire graphical variation. Note that Mick's panel graphics are not available (yet) as the panel is rendered on the FIX layer. I'd need to rip them and allocate another bank in the FIX ROM, which I will probably do soon.

UPDATE #2: Speaking of bit rot, in attempting to add another set of panel tiles for the Mick Farrow graphics, I've broken what was already there. I can't coax my tool into reproducing the existing panel data, let-alone a new one. Annoying...

I 'C' no more bugs!

Continuing on with testing the C port, and you can complete the game and see the end-of-game animation and messages. There were a few more bugs, but none too nasty. For the record, most bugs in the C port have been signed/unsigned issues.

I've also added Mick Farrow's modified graphics as a run-time option.

I need to propagate the changes through to the Amiga and Neo Geo ports. The latter will be more fiddly as it will require the generation of another few thousand sprite tiles, but the tool is already there.

I realised recently it would (probably) be relatively trivial to add an Atari ST port - then I could add another target platform to my CV! I'm also still deciding whether I have the motivation left in me to attempt a Sega Genesis port as well, or whether I'm well-and-truly over Knight Lore by now.

Thursday 14 April 2016

On optimisations

Over on the AtariAge forums, user mariuszw has been porting the ZX Spectrum version of Pentagram (the 3rd filmation title) to the 6502-based Atari 8-bit computers. He started with an automated translation of Z80 to 6502 which he got running but, not surprisingly, was too slow.

He has spent some time both profiling and analysing the code, and aside from actual pixel rendering has identified areas in the Z-order rendering logic that can be significantly optimised. I was aware that it took a rather brute force approach and that it spent quite a while in there, but was surprised to learn that the code can spend up to 40% of CPU time in that routine!

And to give some idea of the effect of these optimisations, one user observes that the code now runs as least as fast as the Spectrum version, if not slightly faster. And keep in mind that significant portions of the code are still implemented from the auto-translation process. Impressive!

The dilemma I face now is how far do I go with implementing any optimisations on the Coco3? The original intention was to port the game faithfully, warts-and-all. I have no issue rewriting the platform-specific portions of the game - such as rendering routines - but re-implementing the sorting logic encroaches on modifying the way the game works. You could argue that if it doesn't change the outcome (ie. the same objects are rendered each frame) then it's still the same, but the purist in me is struggling with that argument regardless.

Either way, I'll study the code for interest's sake, if nothing else, then make a judgement call. I guess more people are likely to play it if it runs smoothly, and won't really care what's going on underneath the hood.

Wednesday 13 April 2016

Back to C

I've managed to find and fix the three known bugs in the C port.

I expect there to be a few more as I continue testing.

Monday 11 April 2016

Use The Source, Luke

I've just uploaded the disassemblies - those of which I am entitled to - of the remaining projects to the download page, with the exception of Donkey Kong, which is very much WIP and I have every intention of completing it.

A few of the earlier projects are rather incomplete, and will probably remain so.

I do have a handful of diassemblies - all very much incomplete - that were used when reverse-engineering the hardware in order to assist with an FPGA implementation. Since they're not really part of any (software) porting project, I won't include them here.

Enjoy.

Finally! Joy after getting past my sticking point!

To say that adding joystick support was frustrating is an understatement!

There's not a whole lot of information on the net about sampling the joysticks, less still about reading the buttons, and some of the information that is available is, well, wrong. And to confuse matters further, I was having issues in MESS with the 2nd joystick button. Not having a physical 2-button joystick to test on real hardware is fraught with impediments to success.

Still at this point unable to test on real hardware, I at least seem to have sorted out the details and MESS finally behaves as I'd expect, given the Coco 3 schematics. I guess I should have gone to them in the first place, rather than as a last resort.

I thought I'd post my joystick code here on the off chance that someone else has similar issues in the future.

Let's define some useful constants.

PIA0        .equ    0xFF00
PIA1        .equ    0xFF20
DATAA       .equ    0x00
DDRA        .equ    DATAA
CRA         .equ    0x01
DATAB       .equ    0x02
DDRB        .equ    DATAB
CRB         .equ    0x03

; equates to keyboard rows
; - phantom keys appear accordingly
RJOY_BTN1   .equ    (1<<0)
LJOY_BTN1   .equ    (1<<1)
RJOY_BTN2   .equ    (1<<2)
LJOY_BTN2   .equ    (1<<3)

;.define LEFT_JOYSTICK
.ifdef LEFT_JOYSTICK
  JOY_BTN1  .equ    LJOY_BTN1
  JOY_BTN2  .equ    LJOY_BTN2
.else
  .define RIGHT_JOYSTICK
  JOY_BTN1  .equ    RJOY_BTN1
  JOY_BTN2  .equ    RJOY_BTN2
.endif
; high and low thresholds
; for 'digital' operation
JOY_LO_TH   .equ    0x64                ; ~40%
JOY_HI_TH   .equ    0x98                ; ~60%


First up, the one-off initialisation, which sets all the appropriate PIA data-direction registers. Bear in mind that Knight Lore takes full control of the Coco 3 hardware, swapping out ROM and disabling all interrupts except a simple (F)ISR used to emulate the Z80 Refresh register. So the PIA's are immune to any reconfiguration behind-the-scenes.

  ; configure joystick axis selection as outputs
  ; and also select left/right joystick
        lda     PIA0+CRA
        ldb     PIA0+CRB
        ora     #(1<<5)|(1<<4)          ; CA2 as output
        orb     #(1<<5)|(1<<4)          ; CB2 as output
.ifdef LEFT_JOYSTICK
        orb     #(1<<3)                 ; CB2=1 left joystick
.else
        andb    #~(1<<3)                ; CB2=0 right joystick
.endif
        sta     PIA0+CRA
        stb     PIA0+CRB
  ; configure comparator as input
        lda     PIA0+CRA
        anda    #~(1<<2)                ; select DDRA
        sta     PIA0+CRA
        lda     PIA0+DDRA
        anda    #~(1<<7)                ; PA7 as input
        sta     PIA0+DDRA
        lda     PIA0+CRA
        ora     #(1<<2)                 ; select DATAA
        sta     PIA0+CRA
  ; configure sound register as outputs
        lda     PIA1+CRA
        anda    #~(1<<2)                ; select DDRA
        sta     PIA1+CRA
        lda     PIA1+DDRA
        ora     #0xfc                   ; PA[7..2] as output
        sta     PIA1+DDRA
        lda     PIA1+CRA
        ora     #(1<<2)                 ; select DATAA
        sta     PIA1+CRA


Now the joystick and button sampling. Note that Knight Lore uses a 'digital' joystick so it's only concerned with checking the position on each axis within three zones - left, middle and right.

        ; select hoizontal axis
        lda     PIA0+CRA
        anda    #~(1<<3)                ; CA2=0 horizontal
        sta     PIA0+CRA
        ; set comparator value to 40%
        lda     PIA1+DATAA
        anda    #0x03                   ; clear value
        ora     #JOY_LO_TH              ; low threshold
        sta     PIA1+DATAA
        lda     PIA0+DATAA              ; comparator
        bita    #(1<<7)                 ; joystick greater?
        bne     1$                      ; yes, skip
        orb     #INP_LEFT               ; aka #INP_W
        bra     2$
        ; set comparator value to 60%
1$:     lda     PIA1+DATAA
        anda    #3                      ; clear value
        ora     #JOY_HI_TH              ; high threshold
        sta     PIA1+DATAA
        lda     PIA0+DATAA              ; comparator
        bita    #(1<<7)                 ; joystick greater?
        beq     2$                      ; no, skip
        orb     #INP_RIGHT              ; aka #INP_E
        ; select vertical axis
2$:     lda     PIA0+CRA
        ora     #(1<<3)                 ; CA2=1 vertical
        sta     PIA0+CRA
        ; set comparator value to 40%
        lda     PIA1+DATAA
        anda    #0x03                   ; clear value
        ora     #JOY_LO_TH              ; low threshold
        sta     PIA1+DATAA
        lda     PIA0+DATAA              ; comparator
        bita    #(1<<7)                 ; joystick greater?
        bne     3$                      ; yes, skip
        orb     #INP_FORWARD            ; aka #INP_N
        bra     4$
        ; set comparator value to 60%
3$:     lda     PIA1+DATAA
        anda    #3                      ; clear value
        ora     #JOY_HI_TH              ; hi threshold
        sta     PIA1+DATAA
        lda     PIA0+DATAA              ; comparator
        bita    #(1<<7)                 ; joystick greater?
        beq     4$                      ; no, skip
        orb     #INP_PICKUP_DROP        ; aka #INP_S
        ; read joystick buttons
4$:     lda     #0xff                   ; no keys, only buttons
        jsr     read_port
        bita    #JOY_BTN1
        beq     5$
        orb     #INP_JUMP
5$:     bita    #JOY_BTN2
        beq     6$
        orb     #INP_DIR_PICKUP_DROP
6$:     bra     finished_input               


I haven't done any timing nor studied the BASIC joystick routines but short of hand-picking registers and instructions that minimise clock cycles, I don't think there's much you could do to get a faster sampling routine. Happy to be proven wrong by any astute reader.

Waiting for a 2-button adapter to turn up; hopefully that'll arrive in time for me to test before sending the final version off to John for demonstrating at the CocoFEST. I was going to try to experiment with some optimisation to speed up the rendering, but I think I'll take a short break from Knight Lore - or the 6809 port at least - until after CocoFEST.

I'm already thinking about the next port, which is dangerous before finishing off Knight Lore completely. But I've got a couple of new ideas which I need to investigate further. One is an actual arcade port; not a new game for the Coco (or any platform really) but it would be cool to have the actual arcade code and graphics, effectively, running on the Coco3. And reverse-engineering is already complete, so the port would be relatively quick. We'll see...

Saturday 9 April 2016

Phantom keys

No updates reflect the fact that I've had very little time to work on Knight Lore, and even less time to blog about it. I can say that I've got (2-button) joystick input working, after rolling my own joystick routines.

I've been optimising the code from the cocopedia article, moving much of it into a one-off initialisation. In fact it makes supporting either the left or the right joystick at run-time trivial (as-is it's a simple .define build option). The sampling routine now only needs to select the axis, write the sound register (twice) and read back the comparator output (twice). Repeat for 2nd axis.

One issue is the button reading, and the phantom key presses that result. I've still got some research on that to do, and I think I know how to avoid the problem (in Knight Lore) whilst retaining the current key mapping. Once it's all working I'll post my joystick initialisation and sampling routines and (hopefully) explain how I negated the phantom key press issue.

Tuesday 5 April 2016

No real joy... yet!

Added support for directional controls. Joystick is still emulated with arrows plus two extra keys, but it has allowed me to test the directional code. All that remains now is to change the emulated joystick routine to read the real Coco3 joystick.

After having been sent some sample code with explanation from James, and reading up on a few blogs, most notably John Linville's The Making of Fahrfall: Reading The Joystick, it's clear that I only need to sample each of the two axes twice in order to obtain a digital reading - something best done internally in my Knight Lore code.

I haven't really looked into joystick support for the Coco3 in MESS, so I have no idea if I can even test it under emulation, but I do have a pair of the standard single-button Tandy joysticks. In the interests of productivity, the best option is probably Drivewire or, failing that, CocoSDC (which I've yet to use). Either of those options is certainly better than erasing and programming EEPROMs...

UPDATE: Was hoping I'd get time to implement reading the joysticks tonight, but after reading a great article on coco3.com that details everything I need to know, it's become apparent that it's a little more involved than I first thought. I'm sure at least some of the PIA configuration need only be done once for Knight Lore, since I have total control over the machine, but it will take some analysis to determine exactly which bits. For another night...

FORGOT TO MENTION: I have it reading the joystick buttons now at least.

Monday 4 April 2016

CPC and fake joysticks

I couldn't resist starting to add support for CPC graphics. First task was to reorganise the memory map to cater for the 2BPP video display and buffer; it was a tight fit and for a few minutes I thought it wasn't going to work. But all good.

Ripping and adding the CPC sprite data was trivial. Adding support, however, won't be. The nature of the changes for the Coco3 are actually quite different to both the Amiga (planar bitmap memory) and the Neo Geo (hardware sprites pre-rendered in ROM). In addition, the panel sprites are quite different so there's a fair bit of work to do - likely too much to do before CocoFEST.

And so I returned to the issue of joystick - and directional - support. Since there was no code behind the main menu for input method selection, I added support for selecting Keyboard, Joystick and Directional Control, removing the other two ZX Spectrum-specific joystick options in the process.

The Main Menu is now tailored specifically for the Coco3 port

The ZX Spectrum uses flashing attributes to denote options selected in the menu - noticeably absent on the Coco3. Instead, I modified the text display routine to simply invert the character if the flash attribute was set, then added a blit to update the relevant lines on the menu each iteration through the main menu loop. Later I may invoke a timer and actually have it flash, but there's more important things to do first and CocoFEST is fast approaching.

Finally, I added a fake joystick read routine that - for now - simply reads an alternate set of keys from the keyboard. This will facilitate adding directional controls without complicating the issue with untried joystick code. I would expect that I'll have directional control working next session, which means all that remains is to replace the fake joystick read routine with the real one.

Saturday 2 April 2016

Shady dealings

I've had no luck getting my Coco 3 hooked up to anything other than the lounge room TV; none of my monitors like 50Hz composite and I can't get my fancy pants video converter to recognise the Coco RGB output either (though that's entirely my fault, I haven't modified the software to do it yet!) So no pictures of Knight Lore running on real hardware just yet unfortunately.

During the development of Knight Lore I've referenced many different resources on the net, one being the Knight Lore Walkthrough, ZX Spectrum video found on YouTube. A similar video by the same author caught my eye; Knight Lore (Graphics Mod) Walkthrough, ZX Spectrum. A chap by the name of Mick Farrow enhanced the original ZX Spectrum graphics back in 2002, adding more shading (via dithering) and sharpening the outline of some sprites. Unable to locate a binary of this version, I contacted both the video author and then eventually Mick himself, and received helpful responses from both - thanks again guys!

I received a .TAP file first, but couldn't for the life of me work out how to execute it in MESS. Before resorting to asking for help, Mick sent me a .Z80 which I had running in MESS a few moments later. After giving the game a quick spin, I restarted MESS with the debugger enabled, and dumped the entire 64KB to a binary file.

During development I wrote a utility that read the .SNA file and (besides a lot of other things) produced a text file with C data declarations (with nice names) for all the data structures in the game, figuring it would come in handy for the other filmation games as well (it did/will). When I started on the Coco3 port, I extended the utility to also produce a 2nd text file with the respective ASM data declarations. I had to add literally 3 lines of code - to instead read the above-mentioned 64KB memory dump of Mick's version - and seconds later had the modified graphics ready to compile/assemble. And as it just so happens, the sprite data resides in a separate .ASM file that is .included in the main .ASM file, so using alternate graphics is a matter of simply .including a different file. And now with a build option using a .define it's very easy to select which version to build.

So as of now, the Coco3 port has two build options - Original or Mick Farrow graphics. And to give you a taste of what they look like on the Coco3, I've got a couple of screen shots.

The splash screen, with an acknowledgement to Mick

A sample of Mick's shaded and sharpened graphics

I should hasten to add that Mick was nice enough to grant me permission to use his graphics mods. A Coco3 cartridge with at least 128KB capacity could theoretically contain versions with Original, Mick Farrow and Amstrad CPC graphics! It will be equally as trivial to add them to the C ports (Amiga, Neo Geo) as well (binaries will support all graphics options in the one build).

But for now, I should start looking at Coco joystick support!

UPDATE: I have one, really crappy, photo of Mick's graphics running on a real Coco3!


Friday 1 April 2016

The Real Deal!

I was hoping to have some accompanying photos to commemorate the occasion, but circumstances didn't allow it. On the plus side, I got to sample the Firefly board game, which is pretty cool!

In short, my Knight Lore cartridge boots up and plays fine on a real Coco 3. A few artifacts that aren't apparent on the emulator are noticeable, though very minor and perhaps I'll ignore them as they don't really affect the finished product. I only got to play it for about 5 minutes before I had to shut it down, but it was enough to prove that it's basically working.

The version I have now is definitely sufficient to demonstrate at CocoFEST, even with the lack of code optimisation. I'm undecided whether I'll press on and try to squeeze a few more features in before then, or take a short break and continue after CocoFEST is over.

I'm tempted to add joystick support, especially since I've had an offer of assistance with the code. Might be nice to show off the newly-designed Sega gamepad adapter that I believe will also be debuted at the 'fest. Though of course I probably won't have one in time to test with...

I'll update this post with some pictures ASAP.

The world's first Coco3 Knight Lore cartridge