Clock Takes Its Time

By Robert Sprowson

Originally published in EUG #62

I looked at the Clock utility in EUG #61 and with regard to wanting to be able to run it in tandem with Frak (I'm quite sure I couldn't put up with Frak for more than a couple of minutes!) here is what I think:

In short, no. The program won't run with Frak since it currently assumes it is running in Mode 7 and in doing so it writes directly to the screen memory. In other Modes not only is the memory in a different place but also in a completely different format.

Poking the ASCII value into screen memory appears directly on screen as that character, whereas in graphics Modes you need to construct a bitmap of the letter from the font that you want to use. This is further complicated by the non-linear way in which bits appear in the byte, especially in multi-colour Modes.

As an aside, you can't call OSWriteCharacter from within an event handler, which is why it all has to be done the hard way as I just described. I suspect Frak probably uses the spare interval timer for the game, which would mean the Clock program couldn't.

The code also currently runs from &D00, which is used by the Disc Filing System to load Frak Though this isn't too hard to alter, I think the extra code required to implement all of this would mean it would no longer fit in memory at the same time as a large game.

Looking at the program itself though, I can see a large number of optimistations and one howling bug I assume is a typo:


      610 TYA
      620 TYA

should be:


      610 PHA
      620 TYA

The bug results in one byte too many being left on the stack every second so the foreground crashes every second!

Other things to note, other than the evil use of GOTOs:


      540 JMP&D6F

Why? Use the power of two pass assembly and "JMP out" instead.

      580 .timer SEI

There's no need to disable interrupts. They're already disabled during an event handler so that instruction can go. This does impact the *KEY10 definition earlier on (This should really be done at the end after the code has been started), which would be better if it created the key definition dynamically so it doesn't matter what instruction is at &D00.


      670 JSR&FFF1

You can't call OSWord during an event. Well, in the case of OSWord A=4 you get away with it provided you preserve &EF, &F0, &F1 first in case OSWord or OSByte were being performed by the foreground task.


     1250 CLI

Not needed. See earlier comment on SEI.

      120 LDA#&0
      130 STA&220
      140 LDA#&0D
      150 STA&221

This needs an SEI before it and a CLI after it as it needs to be atomic (in case another event fires somewhere in the system having only done the first STA).

There are a few JMPs later in the program which could be swapped for branches given a knowledge of some flags - a whopping one byte saving per change!

That'll do. I don't want to dwell on it too long, especially given there are even fewer comments than I use!

Robert Sprowson, EUG #61