Showing posts with label ZX Spectrum. Show all posts
Showing posts with label ZX Spectrum. Show all posts

Monday, 2 September 2024

With TheSpectrum launching in November 2024, the famous magazine Your Sinclair should relaunch too

The one thing that is sadly lacking is a good Sinclair ZX Spectrum magazine (yikes!). Your Sinclair should relaunch to provide a bit of colour to the Speccy community.

Starting out as a publication called Your Spectrum, which was relaunched in 1986 as Your Sinclair (YS), this magazine became iconic and a huge influence on the Speccy community, both then and now; it was certainly one of the best gaming magazines that one could purchase in the 1980s. It lasted through until 1993 ending with its famous Big Final Issue, signalling the end of commercial 8-bit gaming software in general, with the Commodore C64 being the last 8-bit home computer platform to have a significant release[1] (which was Psygnosis's Lemmings, published in February 1994).

YS was skilfully archived by the The Your Sinclair Rock 'n' Roll Years website, something now that only the WayBack Machine can tell. Such was the appeal and legend of YS, Retro Gamer Magazine paid tribute to it in 2004 with issue 94, niftily edited by Dan Whitehead, who is by far one of the best writers I've ever worked with, and certainly one of the most perspicacious.

Almost 20 years after Retro Gamer's aforementioned issue 94 and Retro Games Limited have announced TheSpectrum, and after something of a lull in the mid to late 1990s, and the early part of the 2000s, the Speccy community has grown into something of a monolith. There isn't the unity that there might have been in the early days, when the independent 8-bit publisher Cronosoft launched, for instance. As communities grow, they can become more fractured. And the lies and propaganda over the Vega+ hand-held console certainly didn't help, causing more fracturing. The liars and charlatans were backing Retro Computers Ltd (RCL) propaganda even though it was clear to anyone paying any attention that there were quite severe issues with RCL's management, especially after two of its directors (namely Paul Andrews and Chris Smith) were illegally removed by the fraudsters who remained to drive the Vega+ into its grave. I remember before this time when the once great World of Spectrum website was a bouyant and well respected home for all Speccy fans, and anyone else who was curious about the rubber keyed wonder. Now, sensible people avoid it.

Even with all of the apparent issues in the Speccy community there is certainly enough going on for at least a bi-monthly printed matter periodical to launch. There is an abundance of new Spectrum software; there is the Omni platform and several other popular clones; there is the Sinclair ZX Spectrum Next; and there are loads of emulators to choose from. And now, at a good price point, TheSpectrum is happening just in time for Christmas 2024. And although I find it odd that computering and gaming magazines still exist in printed form, people certainly seem to want them. Your Sinclair, with it's vibrant and rich history, with its mix of gaming and humour, and being crap (in a funky skillo sort of way) is what I think is needed right now, isn't it? Although, getting the tone of YS right may be a tough ask. But it's been done once before. Bring on issue 95 for a Spec-chums reunion for us old gals and geezers. You all know that you need this in your life again.

[1] I know since this time, there has been a lot of new 8-bit games, and one might consider today to be a second commercial era for many 8-bit computers.

A small note, this is my 50th published blog post. Huzzah!

Saturday, 24 August 2024

Retro Games Ltd next computer will be TheSpectrum, a recreation of the Sinclair ZX Spectrum 16k/48k models

42 years after the launch of the Sinclair ZX Spectrum, news has leaked that Retro Games Ltd (RGL) will release TheSpectrum on 22nd November 2024, and will initially retail at under £90.

The Sinclair ZX Spectrum, colloquially and affectionately known as the "Speccy" or the "rubber-keyed wonder" to many, will live again thanks to RGL, building on a strong portfolio of machines from the British-based company.

Chris Smith is the main technical lead at RGL, and one of its directors, and is best known for his excellent book The ZX Spectrum ULA: How to Design a Microcomputer. Chris and his small team have undoubtedly put a lot of effort into this new machine, and it will very likely use Chris's own Speccy emulator at its core to play the 48 included games. It is also likely to have some shared architecture with the Sinclair branded ZX Spectrum Vega and the ill-fated Vega+.

The 48 properly licenced games that will be included on this machine are as follows:

  1. Alien Girl (Skirmish Edition), published 2021.
  2. Ant Attack, published 1983.
  3. Army Moves, published 1987.
  4. Auf Wiedersehen Monty, published 1987.
  5. Avalon, published 1984.
  6. Bobby Bearing, published 1986.
  7. Cosmic Payback, published 2020.
  8. Devwill Too ZX, published 2020.
  9. Exolon, published 1987.
  10. Fairlight, published 1985.
  11. Firelord, published 1986.
  12. Football Manager 2, published 1988.
  13. Freddy Hardest, published 1987.
  14. The Great Escape, published 1986.
  15. Head Over Heels, published 1987.
  16. Highway Encounter, published 1985.
  17. The Hobbit, published 1982.
  18. Horace Goes Skiing, published 1983.
  19. Jack The Nipper, published 1986.
  20. Knot in 3D, published 1983.
  21. The Lords of Midnight, published 1984.
  22. Manic Miner, published 1983.
  23. Match Day II, published 1987.
  24. Movie, published 1986.
  25. Nodes of Yesod, published 1985.
  26. Penetrator, published 1982.
  27. Phantis, published 1987.
  28. Pheenix, published 1983.
  29. Pyracurse, published 1986.
  30. Quazatron, published 1986.
  31. Robin of the Wood, published 1985.
  32. Saboteur! Remastered, published 1985, though unknown year for this remastered edition.
  33. Shovel Adventure, published 2021.
  34. Skool Daze, published 1984.
  35. Snake Escape, published 2016.
  36. Spellbound, which could be one of two games, either from 1984 or 1985; my guess is that it will be the latter.
  37. Starquake, published 1985.
  38. Starstrike II, published 1986.
  39. El Stompo, published 2014.
  40. Stonkers, published 1983.
  41. Target Renegade, published 1988.
  42. /\O[] (known as TCQ or Triangle, Circle, Square), published 2022.
  43. Technician Ted: The Megamix, published 1986.
  44. Tenebra, published 2022.
  45. Trashman, published 1984.
  46. The Way of the Exploding Fist, published 1985.
  47. Wheelie, published 1983.
  48. Where Time Stood Still, published 1988.

My initial thoughts about this is that "TheSpeccy" will be a good seller for RGL, at least in the UK and Ireland, and in some other parts of Europe. I'm not sure the Spectrum platform is as well loved in North America or in Australia, and is probably unheard of in much of the rest of the world. Although because of the sheer number of commercial games that were available for the ZX, there will certainly be interest outside of Europe for this not-mini but small form factor recreated 8-bit wonder machine.

With the release being November, this is ideally timed for the run up to Christmas 2024, with many of us who are at least as old as the Speccy itself putting it on their Chrimbo list for Santa Claus, hoping that we've been good enough to get one. It might be the first time in ages that some of us old guys are actually looking forward to Christmas like we used to in the 1980s.

Obviously, there will be some negative reactions to TheSpectrum; firstly because it's from RGL, and as I've said previously, it seems that it's the thing to hate on RGL, or one or more of its directors. Because: "reasons".

The second reason for some negativity towards it is because TheSpeccy is doing what the Sinclair ZX Spectrum Next could not do, in that it is going to be a commercial success that is bigger than the die-hard online Spectrum community. It's important to remember that you are only allowed to say nice things about the ZX Spectrum Next, but as I've pointed out above, it's cool to hate on RGL. Again, because... "reasons".

Now, if only we could have another batch of THEC64s produced (not the Mini editions, the Classic editions) for November 2024, that'd be a Christmas to remember. Not only would those people who missed THEC64 be able to ask Santa for one, they could also add TheSpeccy to their lists as well, and if they've been very good, get both.

As someone who has had something of a keen interest in 8-bit technologies for a long time (dating back to the 1990s), I'm delighted that an entry-level and consumer-friendly ZX Speccy machine, which works with "modern-days" television sets, is going to be available at a reasonable price. This is kind of what I dreamt of in 2002, when I first started writing my column for Micro Mart magazine, and shortly after became Retro Gamer's first in-house staff writer. One might say that I was ahead of the curve, as I knew that because machines like the Commodore C64 and ZX Spectrum were so life changing, they would be back in style again at some point. It's a shame though that it took so long. So let us enjoy it whilst it lasts.

Saturday, 12 November 2022

Do younger video game enthusiasts get the Commodore C64?

One thing that has become apparent to me over the years is that Commodore C64 games, and entertainment software on other 8-bit home computer systems like the Sinclair ZX Spectrum, are often abstract and usually quite difficult. At least the ones worth playing fall into this category.

I first realised this some time when I started my University Degree in Enterprise Computing. I was in my early 30s and it was around 2009 or 2010. At the time, I was still writing my weekly column for Micro Mart magazine (published here in the UK by Dennis Publishing Ltd I think, and previously under the Trinity Mirror group). I was one of the oldest people on the course, though not the oldest, and my friend Peter, who is interested in media and a part-time radio host on a local station, had something of a curiosity in 1980s technologies. Though he was probably interested because of Nintendo's enduring name, and was also an avid Apple user then (probably still is), with the latter monolith tech company rumoured to have "invented the personal computer", which we all know is false. The first real personal computer, at least at a consumer level, was the Commodore PET, being by far the most usuable, stable and complete machine of 1977. Right?

Anyway, it was around this time that a truly great ZX Spectrum programmer Jonathan Smith aka Joffa Smiff, passed away. I had met Joffa and even somehow got an interview out of him for Micro Mart. He was an extreme introvert, and I found him to be a complete genius, and thoroughly nice chap. Unfortunately, he had suffered with his mental health and this, along with other factors, lead to his passing at just 43 years old (RIP Joffa). I spoke with his sister shortly after his passing to offer my condolences whilst writing his obituary.

I already knew of some of Joffa's work as he was developing a Spectrum game before his passing, and I had played some of his games in the 1980s and early 1990s. But I'd never played all of his games until then. I can honestly say that I've never seen such consistent quality from a single 1980s games developer. I don't think there was one game that I didn't like, and I still play Hyper Active to this day. But it was his first game, Pud Pud that got me thinking about this question: "how would I explain this game to my daughter?"

For those who don't know Pud Pud, you take control of a flying Christmas Pudding-alike creature which must eat other creatures (which ones you have to figure out yourself) and find 10 other puddings whilst avoid being kissed by the evil Mrs Pud. It's fair to say that this game is a little out there and pretty abstract though not to the level of some Jeff Minter games. I got the feeling that younger game players wouldn't get it; those who have been born into a digitally saturated world, with if not instant but pretty quick on demand digital assets at your fingertips. Many of today's games, especially for younger players, have tutorial modes and on-screen prompts. And waiting to load for more than a few seconds in this world is unusual and may often lead to younger people to grow quickly impatient. In fact a recent television advert has people destroying their wifi routers because everything has to be now, and that's okay in the 2020s. It also shows the throw-away society that we have become in my view.

Those of us who grew up with machines like the C64, we generally didn't have games in an instant. Games consoles would load in seconds, but most people in the 1980s - at least most people in the UK - opted for a home computer for their main entertainment system even if we conned our parents into the myth that "it'll help with School homework" - well in the long run it helped anyway.

Home computers might have been as expensive as an equivalent video games console, but games were usually much cheaper for computers. Doing a quick search the Internet tells me that Atari VCS-2600 games would cost around $30 USD or more, so if we assume that those same games wouldn't have been cheaper than £20 GPB, you could have purchased 10 individual C64 games on cassette for that, thanks to budget publishers like Mastertronics. Also, cassette games were much easier to copy, you only needed a blank cassette tape and a tape-to-tape hifi system.

Anyway, C64 games were limited by the times and technology. Very few games had the luxury of having explainers, so if you didn't read the manual first (and very few of us did) nor the game reviews in various popular publications of the day, you wouldn't necessarily know what you were supposed to do on your first few plays. Magazines would have hints and tips to games, but those were generally published monthly. So if you were stuck on a new game and none of your friends had worked it out either, you'd have to hope that the next issue of your favourite printed periodical would have some hints for you, in the form of hand-drawn maps, or even cheats such as POKEs that would modify the game code to provide for infinite lives, time or other cheats.

Why do I mention all of this? Well, after my recent overview THEC64 Collection 1 for the Evercade I found a video from an upcoming YouTube channel which had some pretty pejorative and I think unfair veiws on the collection. The reviewer starts out by stating that he never had a Commodore C64 and all of the games on the collection were new to him. Fair enough, but in this particular review, he ranked the game "Lee", which is actually "Bruce Lee" as 13th out of the 14 games, in other words one of the worst on the collection. More on this later.

To be fair, this guy is of a younger generation. For various reasons, even games that I wasn't good at back in the 1980s (which was most of them), I'd still replay again several times after my first try. Maybe there was something that I'd missed as I hardly ever read the manual for any software. Each binary game world was an exploration and sometimes I'd actually progress a little further. Even if that didn't happen, I could listen to the music, or wonder how the programmer made that happen inside a television screen. As I was a programmer first (albeit BASIC), seeing different game ideas was as fun to me as playing them. Also, I didn't have games on tap, I might only get one new game a month. Something less frequently. And loading times would be at least three minutes, or ages as I thought back then. So if I was going to wait for something to load, I wouldn't want to switch it off after my first go, would I?

All of this nuance, this exploration, having patience and so on, something that is in my gaming DNA if you like, tends to be lost on younger game players. This lack of patience likely started in the 1990s, when machines like the Amiga started to become more common, with its pretty fast disk loading and relatively good amount of storage per disk, and powerful processor with pre-emptive multi-tasking capabilities. But more so with consoles. Cartridges could not only allow for more instant loading, but meant the game could be as big as the developer or publisher wanted it to be. Activision was one of the first to make a game seemingly exceed the capabilities of the host hardware with Pitfall II for the Atari VCS-2600, and this certainly happened with many Nintendo titles on both the Famicom/NES and Super Famicom/SNES.

So back to Lee, how could this be the second worst game on this Evercade collection? Well, the reviewer in question made some assumptions because it isn't instantly obvious that this isn't just a beat-em up with some platforms to navigate, and some lanterns to collect. A lack of patience, lack of exploration, and no background reading, meant that he abandoned this game before even opening the trapdoor on the second screen in. He didn't see the expanding gameplay elements, increasing difficulty and puzzle elements to the plaforms and so on. The review doesn't get much better from there, and again I see the same issue repeated in each subsequent overview of each of the titles included. Things aren't always instantly obvious especially to someone with nearly no experience with the C64 or its entertainment software. Although it's not all bad, some extra play time and a bit of background research would have helped ranking the games more accurately, especially if you're not going to persist with exploration.

As the YouTube reviewer in question has a negative feeling towards THEC64 Collection 1 for the Evercade, it turned into a bit of a pile-on by either people who don't like the C64 platform, or (I suspect) those who don't have anything good to say about Retro Games Ltd, because in some parts, you are one of the Kool Kids if you hate RGL. Because reasons.

One of the commentators in the YouTube comments section even went as far to suggest that the 1988 release of Impossible Mission for the Sega Master System was better because it was made by a "professional software development house" that "streamlined" the gameplay. I don't have a problem with the suggestion that a Master System game is better than the C64 version that it is based upon. It's the implication that Epyx in 1984 wasn't a professional software development house. Epyx probably had some of the very best video games designers and developers in the whole world in 1984. By the end of 1984, Epyx had published around 20 games including Impossible Mission, Gateway to Apshai, Pitstop and Pitstop II. I can vouch for how good these games are, and I'm sure many people will agree with me on those four titles. Its not just that these are great titles, but in 1984, each game would have been amazing. Add in that the video games industry wasn't yet 10 years old if you count from the launch of the VCS-2600, and that the C64 was only just 2 years old with many of its secrets yet to be discovered. This guy may be a Sega fanboy, but possibly also one of the RGL haters.

Anyway, that's my rant over. But it's worth noting that if the C64 platform, or for that matter any other 8-bit platform, is unfamiliar to you then often the games worth playing are difficult, sometimes abstract and many times unforgiving. Some games are limited by the way that the tile mapping works, for instance, or the limitations of sprite multiplexing, and there are other quirks that you'll get used to. But if you have a bit of patience, and maybe do some exploration, or some background reading, it'll all be worth it. Probably.

Monday, 11 April 2022

Are you only allowed to say nice things about the ZX Spectrum Next?

A few years back, after ordering on Omni 128 HD, I had the opportunity to procure a Sinclair-branded ZX Spectrum Next. The Omni is made-to-order by one guy as far as I can tell, whilst the ZX Next was a KickStarter campaign. I had to wait for both machines to turn up. And it was the Omni that turned up first, although the screen arrived before the main unit. I'm not complaining about the delays here; I'd rather get something than nothing, and I was very happy to receive my Omni and ZX Next.

The Omni itself looks like a truly authentic ZX Spectrum if viewed from the front. The video output is different, and it has an SD card slot on the side with some dip switches to configure the device. It allows the addition of rechargeable batteries, so that it can be truly portable, and once configured and running, loading games via the cassette and/or from SD card is pretty painless. It is able to load TR-DOS images too, and as we know, any Spectrum clone already has plenty of software. I was very impressed. Forget your Apple something or other; not only have I never been a fan of Apple products, I think its historical devices are considered in higher esteem than cheaper machines (such as Sinclair and Commodore computers) for no good reason. I mean, who could afford an Apple ][, with Apple itself doing not much more that pioneering the high price point. I would say that though, wouldn't I?

Anyway, everything about the Omni felt right; the keyboard, the faceplate and the flat screen is good. The only issue really is that the hand-made plastic legs to fit the screen to the computer are a little brittle, and it could do with a bit more weight in the computer itself to counter the weight of the screen. Other than this, the Omni is a great device. You switch it on. It works. It's easy to use. And it can be used anywhere with some good battery life. It feels like a proper end-user product in the Sinclair tradition. Overall, I was and am very happy with it.

Getting my ZX Next some months later was slightly disappointing. The excitement when the box arrived, and seeing it for the first time, soon led to an anti-climax. Plugging in the device and testing it was good. Then I read online that I needed to update the firmware, which I did. I tested some games, and then unplugged the unit. The power cable was removed but I still saw what looked like a crashed Spectrum screen. I panicked as I thought I'd broken it somehow, but it turns out that using the HMDI port has its issues and you must remember to unplug the HDMI cable before unplugging the power cable. Well, at least I hadn't broken anything.

Next, I noticed that there was a CP/M mode, so I thought I'd try it. I had to get online to get CP/M working in the form of downloading some binaries. Once it was up and running, I was able to load some compatible software. Now, never using CP/M before put me at a disadvantage, but something happened where I couldn't get CP/M working at all anymore. I couldn't work out what I'd done, so I didn't know how to undo it. It wasn't until some months later before I could get it working again, but I don't know how I have, so any fix is purely accidental.

Some time after buying the Omni, I found some games that use the Nirvana engine; this allows ZX Spectrum games to be much more colourful, meaning that software sprites are not limited to two colours per 8x8 character cell as usual. One of the best examples of this is Pietro Bros by Cristian M. Gonzalez, Alvin Albrecht, and Einar Saukas. This works beautifully on the Omni, so I decided to give it a try on my Next. For some reason, it wasn't working, in that the Nirvana engine didn't seem to be working. It might have played the same, but it looked woeful and there was blatant colour clash everywhere. I know the ZX Next has more precise timings than the Omni, and clearly a better specification. So, what was going wrong here?

It turned out that the RGB output wasn't supported via HDMI, only by VGA. So, in order to play this and other Nirvana engine games on the ZX Next, I had to obtain a VGA monitor. As I didn't have one spare, this meant purchasing one. My monitor arrived, and I eagerly plugged in my ZX Next to my VGA VDU. And... Nothing. No video. Had I broken it again? Okay, so I tried the HDMI and got a picture. More searching the Internet and I found out that I needed to configure the machine to the screen it was using, especially if I changed screens for some reason. Well, luckily it wasn't too difficult, and the Next would run through its screen modes with a test card until you get one that fits. All good then, right?

Now my final gripe. I know that the ZX Spectrum never had a good keyboard, but a cheap one. The Speccy+ and 128+ also had cheap keyboards. I have aging models of these that still work today. Most importantly, the keys are still in place. On my ZX Next, however, I've had two keys somehow become detached from the keyboard, and I have to be very wary about using it and travelling with it. This is hardly convenient as I now take this and other machines to show to people, and to let others play on it.

With exception to the cheap keyboard, I think the issue with the ZX Next really is this: feature creep. I was happy when I heard about the original plans for the ZX Next. I think had the original specification and scope been adhered to more strictly, it would have been a cracking machine. But it seems like, maybe due to delays, and maybe trying to please too many people at once, the machine was released in an unfinished state. The HDMI is one pointer to this. The manual is another.

I know that this feature creep has meant a more powerful machine, but why did it need to be more powerful? Why wasn't the original specification enough? For most users I suspect, they will be playing original Spectrum games on reliable, modern hardware. So all of the nice extras, and some of which I haven't even used, are for limited use-cases where no more than 10 - 15% of the userbase will ever benefit. That's fine if you're planning to make a million machines, but this is a machine which exists in the thousands, so these limited use-cases should have been ignored in my view, and any of the extra goodies that were proposed along the journey should have been dropped, like the "SID chip" support, which isn't worth the PI Zero installation really, as it doesn't handle SID files very well. I guess this is what happens when enthusiasts are leading the development of a product, rather than a singular and more realistic and hard-nosed visionary. The ZX Spectrum Next is the Snakes on a plane of "new retro".

Here is the question? If I had to choose only one, which would it be? The Next or the Omni? Well, the Omni has been much less problematic, and once set up, it works perfectly well. I would choose that over the ZX Next. Of course, the Omni doesn't have the same exact timings of the ZX Next. And the ZX Next has a far superior specification, but that doesn't mean it plays my favourite Spectrum games any better. And those games that don't load on the Omni aren't significant in number enough for me to be worried about it.

The Omni plays enough of my favourites, and I don't have to mess about just because I use a different screen as there is only one video output to worry about, and the keyboard feels really authentic. It also works with the original Mic and Ear cables, whilst the ZX Next opted - for no good reason - for the Spectrum +3 tape leads.

Don't get me wrong. I do like my ZX Next. It's just not the finished product that I was hoping for. And in conclusion, I do hope that the next ZX Next irons out these issues with the next Next Kickstarter, especially to do with the keyboard, and as I am one of the backers of it. Anyway, I'm going to give Target Renegade a quick blast. Who wouldn't, eh?

Tuesday, 21 February 2012

Introduction to Z80 assembly part III.

Here are the final four instalments of the Z80 assembly language tutorials that I wrote for Micro Mart magazine [now defunct] (www.micromart.co.uk) that were printed a couple of years ago now. Thanks for all of the kind comments about these articles here and elsewhere. Lets get on with it, shall we?

Return of the bedroom programmer

Part IX: Buzzer

You'll may recall from previous tutorials that we've spent a lot of time looking at how the screen works, and in the most recent part, there was the concept of the two 'channels' (of which there are three) used by the Sinclair ZX Spectrum to decide where to display or output your text. Other basic concepts have been gently introduced that will hopefully help you in building your project in the months to come, such as adding delays, moving bytes around and doing a basic keyboard scan. I know it has been at a rather sedate pace which may annoy some people, but the whole point is for those people who have been frustrated by assembly language tutorials in the past (including me) to try the now ancient art of programming at the machine's level. If you would like to move much quicker than this then please join the Spectrum Computing community forums at spectrumcomputing.co.uk/forums/ and look in the 'Development' sub-forums. If you're perfectly happy with this series so far then point your web browser at the Micro Mart forums (the specific thread is at tinyurl.com/Speccy-Coding a secret that only Archive.org can reveal) if you require help, but right now lets get coding.

This week, we'll move on to looking at the Speccy's infamous beeper. Don't worry to much about musical theory for now. Here is a quick example to play one note.

    org $8000       ; As usual, our code will
                    ; begin at 32768 (8*4096)
    ld hl,262       ; This is the pitch for
                    ; our note
    ld de,255       ; This will be the duration
                    ; it will play
    call 949        ; Play the note by calling
                    ; the relevant ROM routine
    ret             ; Return to BASIC
  

I'll apologies now because I'm delving into the world of mathematics again. If this isn't your strong point then don't worry about it, just concern yourself with the code and experiment, or use the built-in calculator on the 128K Spectrum.

As you can see from the above small routine, the pitch of the note that you want to play along with the duration it is to be played is set up using the register pairs hl and de respectively. On the Sinclair, when the beeper is accessed, all other processing is halted until the note has finished, but fortunately you are working in machine language rather than BASIC, which is many times quicker.

What you will need to know is the 'Hertz' value for the frequency of note that the beeper is to play, or more accurately 'emit'. This is the number of times the internal loudspeaker needs to be toggled each second to produce the desired pitch. This is your base line for working out each note:

  • Middle C is 261.63Hz
  • C# 277.18Hz
  • D 293.66Hz
  • D# 311.13Hz
  • E 329.63Hz
  • F 349.23Hz
  • F# 369.99Hz
  • G 392.00Hz
  • G# 415.30Hz
  • A 440.00Hz
  • A# 466.16Hzm
  • and finally B 493.88Hz

If you want to go an octave lower than this then you must halve the value, and to go an octave higher, it should be doubled.

So far, so good? Well, now comes the difficult bit. You've worked out what note or notes you want to hear, so now you need to calculate how long you should play it, remembering that the longer it is played, the less processor time you will have to do anything else. Lets say you want to play G for 0.2 seconds, well we look up the value of G and times that by 0.2, so we have 392.00*0.2, which equals 78.4. Now divide 437500 by 392.00 (the G note), which will give you 1116.07 (roughly). Now subtract 30.125 and you get approximately 1085.94, and round this to the nearest whole number, which is 1086. To put it another way, the register pair de is our duration, which is equal to Frequency*Seconds and hl is used for the pitch, which has an equation of 437500/Frequency-30.125. Each time, you should round to the nearest whole number, so in this instance, hl should be 1086 and de should be 78.

I urge you not to worry too much about this as it's fairly easy to accomplish simple sound effects for your project without doing much maths at all, but this certainly worth knowing so have a play and see if you can write a simple tune. See you next week.

Part X: A MOB

Let's be honest, most of you that have been following this series will have in the back of their minds creating a 'commercial-quality' game for the old Sinclair ZX Spectrum, using '100% machine code', and if you look at the software released for the 8-bit home computer, not just during the 1980s but to date, then the vast majority of it falls into this category. So, the most obvious thing to do is to draw, animate and control graphics. I've covered writing text to the screen fairly extensively, so with any luck you've had a program proclaiming that you are ace, or perhaps a similar message in a 'scrolly text'. Maybe you've played about with last weeks example too and played a tune along with your message. Now you can add to the mix some user defined graphics. Let's have a look at this little routine:

    org $9000       ; Our program will
                    ; start at 9*4096 (36864)
    ld hl,GFX       ; Points the HL register
                    ; at the area of memory
                    ; called GFX
    ld (23675),hl   ; Initialized system for
                    ; user defined graphics
    ld a,2          ; We want channel two
                    ; (upper screen)
    call 5633       ; Open channel two
                    ; (ie, write to screen)
    ld a,12
    ld (XCOORD),a   ; We'll put our graphic
                    ; character on row 12
LOOP
    call INITXY     ; This will set up the
                    ; X (row) and Y (column)
                    ; co-ordinates
    ld a,144
    rst 16          ; Display character 144 
                    ; (our UDG)
    call DELAY      ; Let's slow things down
                    ; a little
    ld hl,XCOORD    ; Get the current position
                    ; and store into HL
    dec (hl)        ; Decrease HL by one
    ld a,(XCOORD)   ; Store new co-ordinate
    cp 255          ; Is it at the top line
                    ; of the screen yet?
    jr nz,LOOP      ; If not, then jump
                    ; back to LOOP
    ret
DELAY
    ld b,12         ; Delay length
DELAYLOOP
    halt            ; Stop everything
                    ; temporarily
    djnz DELAYLOOP  ; Decrease B by one
                    ; and repeat until B
                    ; is zero
    ret
INITXY
    ld a,22
    rst 16          ; Calls the Sinclair
                    ; PRINT AT routine
    ld a,(XCOORD)   ; Gets the X co-ordinate
    rst 16
    ld a,(YCOORD)   ; and the Y co-ordinate
    rst 16          ; So, essentially
                    ; PRINT AT X,Y; like in BASIC
    ret
XCOORD
    defb 0
YCOORD
    defb 15
GFX
    defb %00111100
    defb %01011010
    defb %01111110
    defb %01011010
    defb %01100110
    defb %00111100
    defb %00000000
  

Once it's compiled, run it and see what happens. As you will notice, the redefined character cell is represented in binary at the end of the program, with each '1' representing the bits that are 'on', and '0' [the bits that] are off. There is a deliberate fault in the program though, which you will realise soon enough. How can this be fixed? And can you make your UDG travel on the horizontal and vertical plane, or start from a different part of the screen? How about replacing the delay routine with a piece of code that will play a note, or perhaps wait for a key to be pressed on the keyboard before continuing with the main routine? The more you experiment, the more you will learn, so now is a good time to get your hands dirty by trying to sellotape together previous examples with this one. Don't worry about errors as it's all part of the process.

If you would like some theory as to what is happening and why, then pop along to the Micro Mart forums (the specific thread is at tinyurl.com/Speccy-Coding), or leave any questions that you have here.

Part XI: Chunky chars

Before I proceed, I'd just like to mention one of the most useful sources of reference for any budding Sinclair ZX Spectrum programmer, and that's the original 'Sinclair ZX Spectrum BASIC Programming' manual that was bundled with the original rubber-clad machines. This has also been archived online if you want to search for it, but with the sheer amount of Spectrum's sold during the early years of the 8-bit, a physical copy shouldn't be difficult to source second hand. I don't know about you, but I prefer printed books over electronic versions.

If you refer to chapters 23 and 24, you'll find a rather handy keyboard and memory map. As you're using assembly, and not BASIC, you have direct control over the memory usage, within the limitations of the available 41K or so available to you (which is about 9K if you're trying to squeeze something into 16K).

Something else I've found very useful for programming is a pencil and paper, to draw a scheme of the whole project. Breaking down the program into logical steps and solving problems is what it's really all about. To do this, you may use traditional methods, like flow charts or pseudo-code. The former is good for small routines and the latter for bigger chunks of code. There is a new kid on the block too, which is Test Driven Development, in which you write a test first that will check if your code works to the bare minimum that you need it to do. This might seem counter-intuitiave as the test will automatically fail until you've written the code that you want, but prevents unnecessary programming and Keeps It Simple and Stupid (KISS), which should be easy to maintain. The trick is to find what works for you, especially for personal development like programming 8-bits.

Last time, we looked at moving a simple redefined character cell. We did this by changing the Sinclair's two-byte system variable at location 23675 to point specifically at our character cell, which was a smiley face if you entered the bianry correctly. You could have easily redefined your own UDG (User Defined Graphic, sometimes referred to as MOBs or Movable Object Blocks) if you wanted to.

From BASIC, you have 21 UDGs (or 19 on 128K machines, at least in the 128's native mode). You may change the system variable at 23675 for each sets of UDGs you define but although it's quite easy to implement, things can become quite messy.

You will have noticed that the routine left it's trail as it moved up the screen. This was the deliberate bug that I left in for you to sort out. To stop this from happening (if you haven't worked it out), you would need to write the character 32 (space) after calling the DELAY routine and before moving one row up, or something like this. Try it yourself to see what produces the best results, trying to avoid any annoying flickering along the way. Here is a routine that will copy the ROM font into another part of RAM and manipulated it to make it look chunky:

    org $9000       ; Our program will
                    ; start at 9*4096 (36864)
    ld hl,15616     ; HL will point at
                    ; the ROM char set
    ld de,60000     ; Here is were in RAM
                    ; we will store it
    ld bc,96*8      ; We have 96 chars
                    ; times 8 rows
NEWFONT
    ld a,(hl)           
    rrca            ; Here's something new,
                    ; it 'rotates' each bit
                    ; in the accumulator
    or (hl)         ; Logical or, which will
                    ; combine the two sets of
                    ; bits (non-rotated and
                    ; rotated right)
    ld (de),a       ; Store the new bits
                    ; into RAM
    inc hl
    inc de
    dec bc          ; bc is used as a
                    ; counter here
    ld a,b          ; get the high byte in
                    ; the register pair (b)
                    ; in bc
    or c            ; and combine with the
                    ; low byte (c)
    jr nz,NEWFONT   ; Repeat until bc is zero
    ld hl,60000-256 ; font minus 32*8
    ld (23606),hl   ; Point to new font
    ret
  

Part XII: And finally...

They say all good things come to an end, though whether this series has been good or not is up to you. This will be the last of the tutorials for the old Sinclair ZX Spectrum for now. I plan to move onto the 6502-based processor next (this is now available through the pages of Commodore FREE magazine at https://archive.org/details/commodorefree). Let's get straight into the coding then, have a look at this routine.

    org 32768       ; This is where we'll
                    ; start our program
    call PRINTINIT
    ld bc,10010
    call DISPNUM
    ld a,13
    rst $10
    ret
PRINTINIT
    ld a,2
    call 5633       ; open channel
                    ; two (upper screen)
    ld a,22
    rst $10
    ld a,0
    rst $10
    rst $10         ; This is equivalent
                    ; to PRINT AT 0,0;
    ld de,STRING
    ld bc,EOS-STRING; Length of STRING
                    ; to print
    call 8252       ; Throws our STRING
                    ; out via channel two
    ret
DISPNUM
    call 11563      ; We'll push the BC
                    ; register onto the
                    ; calculator stack
    call 11747      ; and then output that
                    ; number to the screen
                    ; by calling this routine
    ret
STRING 
    defb 83,127,111,114,101,$3a
EOS
    defb 0
  

Run it (with RANDOMIZE USR 32768) and see what happens. Basically, as the comments within the DISPNUM routine suggests, it's pushing the BC register onto the Sinclair calculator stack, then displaying that next to the last character printed. This allows whole integer numbers between zero and 65535, which once you run the code, you'll see its' intended usage. There are some drawbacks to this method, but for now it will be good enough.

Here's another routine to mull over.

    org 32768       ; This is where our
                    ; program begins in RAM
INFINITE            ; Our main marker
    ld bc,63486     ; Listen for keys
                    ; 1 to 5, also Sinclair
                    ; Joystick port 2
    in a,(c)        ; What key has been
                    ; pressed?
    rra             ; Rotates the accumulator
    push af         ; Preserves AF register
                    ; (most importantly the A bit)
    call nc,LEFT    ; If left is being pressed,
                    ; call relevant routine
    pop af          ; restore accumulator.
    rra             ; The process repeats to
                    ; see what other bits
                    ; have been set
    push af
    call nc,RIGHT 
    pop af
    rra   
    push af
    call nc,DOWN 
    pop af     
    rra        
    call nc,UP  
    jp INFINITE     ; Unconditional jump
                    ; back to repeat process
LEFT
    ld a,0
    out (254),a     ; Okay, so what happens here?
    ret
RIGHT
    ld a,2
    out (254),a     ; And here?
    ret
DOWN
    ld a,4
    out (254),a     ; etc...
    ret
UP
    ld a,6
    out (254),a
    ret
  

Well, you can guess from the comments we're doing here. If you have a Sinclair joystick interface, or an Amstrad-made Spectrum, connect a compatible joystick (which can be emulated too) and see what happens. Checking for the fire button is missing, but I didn't want to make it too easy for you. Well, that's all for now, but it need not end here as the Micro Mart forums Spectrum Computing Development Forums are always open. Before I go, I think there's just enough space to thank Bob Smith and Jonathan Cauldwell for their help over the series, as well as everyone who endured it!

Thursday, 5 January 2012

Introduction to Z80 assembly part II.

Due to popular demand (well, by my standards), here's the second instalment of my exciting 'Return of the Bedroom Programmer' series that I wrote for Micro Mart magazine in the Summer of 2010. Part one is here: Introduction to Z80 assembly part I so if you've missed it, please read through. Note that this is only intended as a guide for beginners and not intermediate or advanced programmers.

Return of the bedroom programmer

Part V: More on Colour

Before we delve into the code, let's quickly recap on where we are up to (see the above link if needed). We've briefly looked at what the Sinclair ZX Spectrum was capable of, and how much RAM is available on the different models. RAM is important because the more of it we have, the bigger our program can be and, in many ways, the more we can do.

You should now be proficient at writing to the screen as what we've been doing in our code is defining an area of memory (called 'STRING'), putting some text there and then reading each byte into the accumulator (a) and outputting that to the screen using the Sinclair ROM 'PRINT' routine (by rst $10). If you look back on the examples, you'll notice that at the end of the text was two values, 13 is a new line (or carriage return) and zero was the marker for the end of the text. When you get into more advanced programming, you may want to know that using rst $10 affects the af register, but for now, this is not going to concern us.

In the last part of the first instalment, we looked at how the colour attribute worked for each character cell and I set you a challenge to change the colours in the code. To do this, you need to change the values of 'a' (the accumulator) before you store it at 23693 and call 3503, and [for the border] change 'a' before calling 8859. If you wanted 'BRIGHT' red text on white 'PAPER' without 'FLASH', the equation would be (0x128)+(1x64)+(7x8)+2, or 122. If you wanted to set the 'FLASH', then you would add 128 to this, totalling 250. Deducting 64 will turn off 'BRIGHT'. As for the border, it can only be one of eight colours, so simply 'load a' with the corresponding colour from zero to seven before you call 8859.

Of course, because we clear the screen by calling 3503, anything you set will then be the default value for the text area, therefore if you have set the 'FLASH' value then everything you see will flash.

Writing directly to the colour RAM is a better way of doing things, especially if you're having different areas of the screen using the various possibilities available. This area of memory is mapped at 22528 to 23296, with each byte holding the colour information to the corresponding 8x8 character cell. The colour RAM is therefore 768 bytes in total.

Let's say we want the first row to flash and the second row not to, here's a quick example:

COLRAM equ 22528
    org $8000     ; We'll start our program at
    			  ; 8x4096, or 32768
    ld de,COLRAM  ; Let's point the register de
                  ; at the start of the colour RAM
    ld a,129      ; Flash on, blue text on a
                  ; black background
    ld h,32       ; We'll use the register h for
                  ; a counter
LINE1
    ld (TEMP),a   ; Temporarily store a
    ld (de),a     ; Store a at location bc
    inc de        ; Increase de by one
    dec h         ; Decrease h by one
    ld a,h        ; Transfer h to a
    cp 0          ; Compare a to zero
    jr z,NEXTROW  ; Go to NEXTROW when a is zero
    ld a,(TEMP)   ; Get a back from TEMP
    jr LINE1      ; Jump to LINE1
NEXTROW
    ld a,80       ; Flash off, Bright on, red
                  ; paper, black text
    ld h,32       ; h is a counter again
LINE2
    ld (TEMP),a   ; Temporarily store a
    ld (de),a     ; Store a at location de
    inc de        ; Increase de by one
    dec h         ; Decrease h by one
    ld a,h        ; Transfer h to a
    cp 0          ; Compare a to zero
    jr z,BACK     ; Jump to BACK when a is zero
    ld a,(TEMP)   ; Get a from TEMP
    jr LINE2      ; Jump to LINE2
BACK
    ret           ; Return to BASIC
TEMP
    defb %11111111; Temporary storage area for a
  

Two things to note: firstly, the program will be stored at 32768, so it will not work on a 16K machine unless you relocate it. Secondly, it's a rather linear and inefficient way of doing things. As you progress, you'll want to be as efficient as possible, which will free up more memory for you. Think about this for a moment, as this is your next challenge: you could set some parameters (de and h) and then call this as a sub-routine from your main code. This will free up some memory for you and make your source code tidier at the same time.

Part VI: The screen

If you've been paying attention to these tutorials then you'll have started to develop a fairly good understanding of how the screen works, especially the colour attribute cells and where each is mapped in memory and how that corresponds the the character cell. Think of the screen as having two layers, the pixels and the colour attributes, if that helps.

If you're following this as I intended, I set you a challenge in part five to alter the example so that you could 'call' a subroutine from the main routine, and gave you a hint as to how this could happen. I think the answer is archived at tinyurl.com/Speccy-Coding, but feel free to ask here if you're struggling.

You now know how to colour in each character cell on the old Spectrum (which comprises of 8 x 8 pixels), but we've only touched on writing to the screen using the handy ROM routine. As you may recall, the screen RAM starts at 16,384, and each byte represents eight pixels in a row. The screen's resolution is 256 pixels across by 192 down (referred to as 'scan-lines'). You therefore have 32 bytes per scan-line, 192 times, meaning that the screen takes up a massive 6,144 bytes in total, or 6K out of the 48 available. The screen RAM ends at location 22527, with the colour attributes taking another 768 bytes after that.

What I found interesting about the Spectrum is how the screen RAM (excluding colour attribute) is mapped. If you haven't seen how the loading screen is drawn, or at least not seen one recently, then do so as that is exactly how the memory relates to the pixels on the screen. To demonstrate this more clearly, type in the following BASIC (not assembly) program to your Speccy or emulator and RUN it:

    1 LET a=16384 : REM Start of screen RAM
    2 POKE a , BIN 10101010 : IF INKEY$ = ""
        THEN PAUSE 4e4
    3 IF INKEY$ = "n" THEN PRINT AT 0 , 0 ; a
    4 LET a=a+1 : IF a = 22528 THEN STOP
    5 GO TO 2
  

Hold down any key and the screen should draw the bit pattern defined after POKE a in line 2 to the screen. You can try changing this bit pattern and see what happens. If you want to find out where exactly you are in RAM then press n at any time. The screen isn't mapped in a linear or logical manner, is it? Or is it?

As you will notice, the screen is drawn in three zones, starting at 16,384 to 18,431 (zone zero), representing the first 32 x 8 character cells (rows zero to seven), or 256 pixels by 64 scan-lines, and so 18,432 to 20,479 is the next 32 x 8 cells, and 20,480 to 22,527 is the final zone. In the Spectrum's memory, a binary representation of this is: 010B BSSS LLLC CCCC, worked out as follows:

  • BB = Block (zones 0-2), being either the top third, middle third or bottom third of the screen.
  • SSS = Scan-line (0-7), which relates to the vertical row in the character cell.
  • LLL = Vertical character line (0-7) within the block.
  • CCCCC = Horizontal character co-ordinates (0-31).

There is a short-hand way of working this out, as follows:

PRINT 16384+(x0*32)+x1+(y+(z*7)*256)

What this means is that if you're in zone zero (the first third of the screen), then x0 must be between zero and seven and z must also be zero, and the range for the scan-line (y) in each character cell is zero to seven, with x1 representing the column from zero to 31. This might be a lot to take in, especially if you're rubbish at maths like me.

In BASIC, we're only able to 'PRINT AT' to row 21 in BASIC, so with this in mind, here is another demonstrate:

    1 REM Change the parameters by
        the following:
    2 REM zone zero : x0=0 to 7, z1=0
    3 REM zone one  : x0=8 to 15, z1=1
    4 REM zone two  : x0=16 to 21, z1=2
    5 CLS : LET x0 = 0 : LET x1 = 1 : LET z1 = 0
    6 FOR z = (7*b) TO ((7*b)+7) :
        POKE (16384)+(x*32)+(x1)+(z*256),255
    7 NEXT z : PAUSE 4e4
    8 PRINT AT x,y ; FLASH 1 ; " " : PAUSE 4e4
  

I remember being totally confused by the memory lay out of the screen when I first wrote these tutorials, so I hope that these BASIC examples have helped. Thankfully, our saviour comes in the form of the Sinclair ROM as this will handle everything for us. Give your brain a rest for a while and make a refreshing cup of tea* before continuing.

* Coffee and other refreshments also available.

Part VII: Pushing and popping

I bet you're really getting to grips with programming the Sinclair ZX Spectrum, aren't you? That game you've always wanted to create, boasting 100% machine code on the cassette label can't be far away now, and I hope you're having fun along the way.

One thing you will have noticed is that most of the routines that have appeared so far have used the accumulator (a) and a register pair (bc or de, for instance). You've then typically stored bytes into the accumulator, to set a colour attribute cell directly in RAM, or to write characters to the screen. As we use the registers and the accumulator so often (in fact, we couldn't do much without them), you may occasionally need to temporarily store value, write a new value to do something else, and then restore the old one again. There are two instructions called 'push' and 'pop' which will do this for you, but only work with register pairs. Here's a quick example with the bc register:

    org $8000       ; Code begins at 8*4096
    ld bc,DATA1     ; Point bc at DATA1
    ld a,(bc)       ; Put it into the Accumulator
    push bc         ; Temporarily stores bc
    ld bc,DATA2     ; New value for bc (DATA2)
    ld (bc),a       ; Overwrites first byte in DATA2
    pop bc          ; Restore bc to old value
    ret             ; Return to BASIC
DATA1
    defb 0          ; zero not '0'
DATA2
    defb 255
  

What it's doing is storing the byte at DATA1 into the accumulator, pushing bc to the stack before pointing it at DATA2, writing the accumulator there and then restoring the old value to bc before exiting to BASIC. The assembler will make the two bytes at DATA1 and DATA2 read zero and 255 respectively. After executing the routine, they will both be zero. You can see for yourself by PEEKing at the memory locations from BASIC or using a disassembler or monitor from your emulator.

If we needed to temporarily store the accumulator (or any unpaired register) we can't use push, but we can declare a single byte of memory in our program as TEMP and put a null byte there; ld (TEMPA),a will save the value, which is then restored by ld a,(TEMPA). Here's an example of this in action (you may want to set your own colours and clear the screen first):

    org $8000     ; Store our program at 8*4096
INFINITE
    ld a,22       ; 22 is the Sinclair ROM value
                  ; for PRINT AT
    rst $10       ; Call the ROM PRINT routine
    ld a,0        ; We need an x and y co-ord for
                  ; PRINT AT, so a=0
    rst $10
    rst $10       ; We call it twice
                  ; (PRINT AT 0,0;)
    ld bc,STRING  ; Points the register bc
                  ; to STRING
LOOP
    ld a,(bc)     ; Puts the current byte at bc
                  ; into a
    cp 0          ; Compares a to zero
    jr z,MOVEBYTE ; If equal to zero, jump to
                  ; MOVEBYTE
    rst $10       ; Outputs a to the screen
    inc bc        ; Increases bc by one
    jr LOOP       ; Goes back to LOOP
MOVEBYTE
    ld bc,STRING  ; Let's point bc at the start
                  ; of STRING again
    ld de,TEMP    ; And de at TEMP, one byte
                  ; before STRING
    ld a,(bc)     ; Get the first byte at bc and
                  ; put into a
    ld (de),a     ; Store a at TEMP
SCROLL
    inc bc        ; Increase bc by one
    inc de        ; Increase de by one
    ld a,(bc)     ; Get the current byte at bc,
                  ; store in a
    cp 0          ; Compare to zero
    jr z,AGAIN    ; We'll jump to AGAIN if a=0
    ld (de),a     ; Store a at de (one byte
                  ; before bc)
    jr SCROLL     ; Jumps to SCROLL
AGAIN
    ld a,(TEMP)   ; a=TEMP
    ld (de),a     ; Store a at location de
                  ; (end of STRING before zero)
    ld b,8        ; Now we're using the b register
DELAY
    halt          ; Stop everything temporarily
    djnz DELAY    ; Counts down b register until zero
    jr INFINITE   ; Jump back to INFINITE
TEMP
    defb %11111111; byte used in MOVEBYTE and AGAIN
STRING
    defb " Micro Mart Rulez! "
                  ; 32 characters in total
    defb 0        ; End of string
  

I'll let you find out what this routine does (a hint is in the labels though). The challenge for this instalment was at tinyurl.com/Speccy-Coding, though you'll have to plough through and find it.

Part VIII: Changing channels

Those of you who tried last week's main routine will have noticed two things: firstly, it was moving the bytes about to do what was once called a 'scrolly text' (now referred to as an 'animated marquee'), and secondly it introduced a rather handy delay routine. Even though the Z80 inside the Sinclair ZX Spectrum is 'only' clocked at around 3.5Mhz (by today's standards, this is nothing), you may still need to slow things down a little sometimes. Additionally, if you ran the routine with PRINT USR 32768, it will have scrolled on the top line of the screen, whereas if you used RANDOMIZE USR 32768 then it would have appeared on the next to last row unless you set your own default colours and cleared the screen first.

As I have said previously, the Spectrum's screen is mapped logically in memory in three zones, but the Sinclar ROM sees it as two channels. The lower two rows of text are usually reserved for BASIC entries, and the 'user' screen is therefore everything above that. Of course, you can write anywhere to the screen by storing the relevant bytes you like, bypassing the ROM entirely, but this requires some maths as demonstrated above.

Thankfully, the boffins at Sinclair were kind enough to allow us to select what part of the screen we're writing to, and here's a quick example:

    ORG $8000     ; Put the program into
                  ; 8*4096 (32768)
    ld a,2        ; 2 opens the channel for
                  ; the upper screen
    call MAIN     ; Let's call the main sub-routine
    ld a,1        ; Okay, now we want to write to
                  ; the BASIC area
    call MAIN     ; Let's write some text again
    ld hl,23560   ; This is part of the keyboard buffer
    ld (hl),0     ; We'll clear it
LOOP
    ld a,(hl)     ; Put the current value of
                  ; hl into a
    cp 0          ; Compare it to zero
    jr z,LOOP     ; If equal to zero, go back
                  ; to loop
    ret           ; Key pressed, so return to BASIC
MAIN
    call 5633     ; Open channel set
                  ; by accumulator
    ld de,STRING  ; Point de to the start of
                  ; the STRING data
    ld bc,EOS-STRING
                  ; Tells the program how long
                  ; the STRING data is
    call 8252     ; Print the STRING out to the
                  ;selected screen channel
    ret           ; Return from sub-routine
STRING            ; Here's the string data
    defb "http://www.micromart.co.uk/"
EOS
    defb 0
  

Okay, so that's a bit different to how we've been doing things, and you may notice that we've got a fairly rudimentary keyboard reader in there too, like using PAUSE 4e4 in BASIC when you tell the user to "Press the any key" or something similar.

What's happening by calling 5633 is telling the ROM where to write the text to; channel two is for the upper area of the screen, channel one is for the lowest two lines of text, and there's also a channel three for the Sinclair printer too, should you ever need to use it.

The register pairs de and bc are then telling the routine at 8252 where in memory the data is to 'write' to the currently open channel, (de is the start of memory, and bc is the end). You'll notice that the text is written to the very bottom line for channel one, so have a think about pushing it up one line.

This technique is very handy as it uses a small amount of code. It's time for a break again. Keep on coding over the next few weeks until I sort out the final exciting* instalment.

* It might not be that exciting.

Monday, 2 January 2012

Starting with C

What starts with C and works on the Sinclair ZX Spectrum? Well, thanks to z88dk - available from z88dk.org - it's C.

I've been playing around with this and, I have to say, the Wiki is useful but not very helpful, and I can't find many clear examples that'd be good for beginners to get their teeth into. This, in my opinion, is due to lack of good commenting in the source code examples, and also it being written by many technically minded people who forget that sometimes things need to be explained in English, which is a language that I'm quite fond of as it can be very clear and concise if used well. So, I intend to write a beginners guide to C programming for the ZX Spectrum in the near future.

Anyway, after scratching my head for a few hours, I wrote a simple 'Hello World!' type program. This isn't a challenge, of course, but I wanted to change the colours of the text and bypass the 64-column mode which is what the z88dk compiler defaults to when you use it. I also got it to drop down to assembly for a short routine which sets up the default colours for the whole screen. Anyway, more importantly, I've commented it quite well so even if you're a complete novice at programming and would struggle with something simple, it should be straight forward enough. Note that there is a much simpler way to do the same thing, but simple doesn't always tell you everything that you need to know. Oh, and it also uses a look-up table, something that I always find myself building even if it's not always strictly necessary.

Here's the code:

/**
 * This does something similar
 * to the classic "Hello World!"
 * code that's a popular starting
 * point for learning programming.
 */
#include <stdio.h>

// Here are our default colour
// attributes
#define INK     7
#define PAP     2
#define FLA     0
#define BRI     1
#define INV     0
#define BOR     5

// This is used in the setup function,
// which drops into machine code -
// see my blog for more information:
#define COL     128*FLA+64*BRI+8*PAP+INK

// Forward declarations of functions:
static void main(void);
static void setup(void);
static void hello(void);
static void magazine(void);

// Global variables:
static int i=0;

// Here is an array which will set up
// the default colour attributes for
// printing our message to the screen,
// 255 is used as a 'terminator' to
// say "we've finished here"
static int screensetup[]=
{
     1, 32, 16, 48+INK, 17, 48+PAP,
     18, 48+FLA, 19, BRI, 20, 48+INV,
     12, 255
};

/**
 * This is the 'entry point' of our program:
 */
void main(void)
{
     // This will call a routine to
     // set the default colour
     // arrtibutes for the whole screen
     // as defined above:
     setup();
     // This does the same for outputting
     // out character see
     // http://www.z88dk.org/wiki/doku.php?id=platform:zx
     // for more information under the
     // heading "The standard ZX Spectrum
     // console driver" - hopefully, these
     // numbers will now make more sense!
     while(screensetup[i] != 255)
     {
          // The %c means 'print character code'
          // or something similar
          printf("%c",screensetup[i]);
          // Increase i to read the next element
          // of the array:
          i = i + 1;
     }
     // Calls our functions, firstly hello:
     hello();
     // and now magazine:
     magazine();
}

/**
 * This function sets up the default colours
 * for our screen as defined above:
 */
void setup(void)
{
     #asm
     // Sets default ink and paper colour,
     // then clears screen
     ld a,COL
     ld (23693),a
     call 3503
     // Sets border colour
     ld a,BOR
     call 8859
     #endasm
}

void hello(void)
{
     // Here is where the magic happens,
     // can you tell what it does?
     printf("Hello ");
}

void magazine(void)
{
     // And what about this bad boy then?
     printf("Magazine!\n");
}
  

Call the source code "HelloMagazine.c" (obviously without the quotation marks) and place it in the same directory as the z88dk 'bin' folder, go to your command line prompt and compile it with:

zcc +zx -lndos -create-app -o hello HelloMagazine.c

it should create a file called "hello.tap", simply load this into your emulator and watch with amazement as the magic actually happens!

PS, I'm certainly not endorsing any printed-matter publication which has all of the latest celeb goss or whatever - it's a joke as I've read too many times about "Hello World!" being the default starting point, so I always try to avoid it.

Sunday, 18 December 2011

Introduction to Z80 assembly Part I.

Foreword

Return of the bedroom programmer was a tutorial series that I started in Micro Mart magazine in the Summer of 2010 with the aim of getting people to experiment with the sorcery which is assembly language. The target machine here is the popular Sinclair ZX Spectrum.

It was never intended for intermediate or advanced programmers, but those people who may have been utterly confused or scared off by good old 'machine code' during their youth, but always wanted to write a professional game on the Speccy anyway.

Those who followed this series found it very useful. In fact, I've never had as much positive feedback about anything I've written since I started writing back in February 2002, and this is still the case today.

So, if you've always wondered about the magic of low-level programming, but didn't like the explanations in the books and magazines of the 1980s, here is the edited and hopefully slightly improved series, split into three parts. First, we look at the basics of our target machine, so without further ado, let's get started.

Return of the bedroom programmer

Part I: Our target machine

These tutorials are inspired by Andrew Unsworth's programming series which started in Micro Mart magazine issue 1109. Andrew's excellent features looked at the popular C programming language, and I therefore decided to start a series about programming an old 8-bit computer, using Z80 assembly language (also known as machine code). It was something that I always wanted to write for Micro Mart, and finally got around to it in the Summer of 2010. I'm going to assume that you have some knowledge of programming at least in an 8-bit variant of BASIC, but this is not necessary as programming is more about problem solving than remembering exact the syntax and commands of a particular language, be that BASIC, Pascal, C or Java. Our target machine (which of course can easily and accurately emulated nowadays) is the popular Sinclair ZX Spectrum.

With a modern-days PC providing a powerful development environment, you'll need some text editing interface (Notepad will do fine) for writing the code, an assembler and an emulator. I'll be giving examples using the cross-platform Pasmo (tinyurl.com/pasmo-z80), and recommend the emulator SPIN, but use any that you are comfortable with. There is also the Windows utility WinTZX for testing on a real machine. You'll need a 2.5mm mono jack to go from your audio output on your PC to the Speccy as well, but other good solutions are available and can be found by a quick search of the Internet. Many resources are listed at https://spectrumcomputing.co.uk.

First though let's look at some basic technical information about the Speccy before we get stuck into coding. There are three main variants of the 8-bit, the initial models launched in 1982 had either 16 or 48KB of on-board RAM and a 16KB ROM, running at approximately 3.54Mhz. The sound was handled by an internal one channel 'speaker', known as the beeper, and the screen is built of 32 x 22 8-bit character cells from BASIC, on 32 x 24 with machine code trickery, giving a total of 256 by 192 pixels with eight RGB colours which have two brightness levels in each cell, except for black which is the same colour whether the 'bright' is set or not.

This means that you have a whole 15 colours in total, with two being available per eight by eight attribute cell (unless you delve into advanced graphics programming). The bits set to off colour the 'paper' (background) and the bits set to on the 'ink' (foreground) on the ZX. Unlike many other machines, everything is bit-mapped to the screen regardless of whether you are actually drawing, using 'software sprites' or the pre-defined character set. This means that the screen RAM is reserved at 6,912 bytes, or about 6.75KB. System variables take up another 738 bytes (0.73KB approximately), so just over 7KB is used by the computer, leaving around 9 or 41KB respectively free for programming either the 16K or 48K model.

The 128K machines, from 1985 onwards, had a built-in sound chip providing three channel sound plus the beeper for compatibility with earlier software. Around 104KB is available on these machines, but we won't worry about this now as the code throughout these tutorials will run on the standard 48K model.

The Speccy's Spec

It sounds really primitive by today's standards, and in truth the Speccy wasn't exactly the most sophisticated 8-bit computer on the market even when it was launched in April 1982, but that's missing the point as Sinclair Research's head honcho Clive Sinclair (later Sir Clive) envisaged a computer in every household, and at the time he made such a prediction many homes didn't even have a colour television set. The Spectrum was a major price breakthrough like it's predecessors the ZX80 and ZX81 but with more features, giving the average family the possibility of owning a colour computer with high resolution graphics and sound for under £100 [for the 16K model].

This aggressive price point put computers into the hands of hundreds of thousands and eventually millions of families. With many early magazines printing full games in BASIC and occasionally assembly along with games reviews and news, this helped the UK to become a world leader in the now lucrative video games industry, and it is largely thanks to Sir Clive's endeavours that Britain became a nation of computing enthusiasts.

Part II: First steps

Like almost everything in programming, there is more than one way to do things, and using assembly isn't the only way to make the Sinclair ZX Spectrum do exciting (or sometimes not so exciting) stuff. You could enter the op-codes directly into memory with Sinclair BASIC, using a FOR/NEXT loop reading a typically long list of DATA statements into an variable of integer type and then POKEing each into RAM. This is handy for small routines, but anything more substantial will be no good for your sanity. If you were going to go down this route, then you may consider writing your whole program in BASIC and use a compiler to speed things up. Some professionally produced games were compiled BASIC, but these did not generally require the speed of a typical arcade game.

Another way of programming would be to use a machine code monitor. A monitor can disassemble all of the computer's memory into either the code and mnemonics and/or ASCII (well, the Sinclair equivalent). This is good for debugging your program, and it's possible to write low-level code with a monitor. Again, if you value your sanity, stay away from monitors but for debugging.

If you haven't already done so, download Pasmo assembler (tinyurl.com/pasmo-z80) and assuming you've got a Speccy emulator, we're ready to go.

To write your code, you can use Notepad or any text editor (Notepad++ might be worth a look if you use other languages), although from the Windows command prompt I've found 'edit' just as good as anything else. You should save your code with '.asm' file extension at the end of the file name. Open your text editor and first enter:

org $6000

The dollar sign tells the assembler that we're dealing in hexadecimal (referred to as hex, see below) and the 'org' command tells the assembler where to place the code, so we're starting our short program at memory location $6000. There's three more lines we want, as follows:

    ld bc,DATA
    ld a,(bc)
    ret
  

Note the spaces after the 'ld' command. The command ld tells the processor to load a register or accumulator ('bc' and 'a' in this case) with a number or memory location. So, here we're using the register pair BC to point at the area of memory we're calling DATA, and then loading the first byte in DATA into the accumulator (A). Note that the label doesn't take up any of the Spectrum's memory, it's simply used by the assembler when it compiles our code so it knows where everything is. This also makes programming a little easier than it would be, as otherwise you would have to hard-code the DATA pointer yourself, which would mean manually working out where in memory it resides. So, if you add code which moves the DATA area to another address, you'll need to work this out again.

The above routine is the equivalent to LET bc=(start of DATA) and then LET a=PEEK (bc) in BASIC, whilst the command 'ret' will return to BASIC this time around.

Now we want to define our data block, so enter the following lines and then save your file, and call it First.asm or whatever you like. The data block is simply as follows:

DATA
    defb 0    ; Zero not 'o'
  

As I've already said, we have defined an area in RAM called 'DATA' and the 'defb' command has a byte there – so our first (and only) data item is a zero. There's also a comment after the semi-colon to clarify that we need a number. We'll talk more about labels and comments later.

Providing you're in the same directory as the Pasmo program (it's a good idea to have your code and Pasmo in the same place), from the command prompt, enter:

pasmo First.asm First.bin

This creates the binary file. Now enter:

pasmo --tapbas First.asm First.tap

and this will create a tape image for your emulator. Set your Speccy to the 48K model and load your newly created tap file (a tape image). Once loaded, you should see three lines of BASIC, which is automatically generated by PASMO. Now type:

PRINT USR 24576

directly (as you'll be using the one-touch entry system, refer to the help file on your emulator, or the original BASIC programming manual that came with the machine) and press ENTER. A number will appear on the screen. This is the value in the register bc, which is the start of your DATA memory block in your code. This is because we've asked the computer to 'PRINT' our routine, so the Sinclair ROM knows it needs to output something to the screen area on returning to BASIC.

Go back into your code to edit it, add the following lines before the 'ret' instruction:

    nop
    nop
  

This means 'no operation', so the CPU basically does nothing when for those lines. Not that you will notice as each will take just a fraction of a second. This is a useful instruction if you ever need exact timing in your code.

Re-assemble and load it back into the emulator, and call the routine as above. You'll notice that the number printed has increased. The assembler has automatically relocated the block of memory we've called DATA for you. Good, eh? But not very exciting either. But hey, you've written your first piece of machine code!

Hex to decimal

Computers do everything in binary, a number system to the the power of base two. This can be difficult to read for our human brains used to dealing in 10s. For instance, our program is located at $6000 in hex or 24576 in decimal. In binary, this would be 110000000000000. Imagine if we had to call the program with binary and missed a zero out? It could crash the ZX Spectrum or cause all kinds of unexpected results.

Hexadecimal works to the power of base 16, and fits binary really well. As we don't have a single numeric digit to represent 10 through to 15, we substitute these for the first five letters of the alphabet, therefore A in hex is 10 and F is 15, and hex 10 is 16. To convert any 16-bit hex number, use the following formula: (X3x4096)+(X2x256)+(X1x16)+X, so $FEDC is (15x4096)+(14x256)+(13x16)+12, or 65244.

It's even easier to convert any binary number into hex. Split each octet (8-bit number) into 4-bit 'nybbles' (note the spelling), let's say 01101101, for instance. So, we split like this:

0110 – 1101

We can now convert this directly into hex, so:

0110 = $6

and

1101 = $D

Therefore, our binary number represented in hex is $6D. This works for any length binary number providing that you break it down each octet correctly. If we look at a 16-bit binary number, like:

1110101110011011

break it down into 4-bit nybbles, we get:

1110 – 1011 – 1001 - 1010

and this into hex is:

1110 = $E
1011 = $B
1001 = $9 and finally
1010 = $A

So our number is $EB9A. We can then use the above method to convert this hexadecimal into decimal using the above formula. But if maths isn't your strong suit, cheat and use an online converter.

Part III: Introducing the screen

The Sinclair ZX Spectrum's screen is built up of two main areas; the border, which, unless you're loading from tape, is usually one solid colour from the eight available, and the 'paper' in Sinclair terminology is where we draw and write to.

The paper area consists of 256 by 192 pixels, residing in RAM at location 16384 ($4000 in hex) onwards. Each eight pixels are represented by one byte, and the screen memory excluding colour ends at 22527, and from 22528 to 23296 we have the colour attribute data for each 8x8 character cell. More about this in the next instalment.

Open your preferred text editor and let's get cracking with the code. Our first lines are:

SCR equ 16384    ; Sets a constant
org $6000        ; Where our program
                 ; will being in the
                 ; computer's memory
    ld bc,STRING
    ld de,SCR
  

The first line sets up a constant reference equal to [memory location] 16384, the start of the screen RAM. As you might recall, org is where our program starts in RAM, and ld bc is our point of reference for a block of data we're going to call STRING later in the code. The register pair de is set to the value in SCR, or 16384, like saying LET de=SCR in BASIC. Now here's the main bit code, which will be a loop:

LOOP             ; Loop marker
    ld a,(bc)
    cp 0         ; zero not 'o'
    jr z,EXIT    ; Goto EXIT if zero
    rst $10
    inc bc
    inc de
    jr LOOP      ; Goto LOOP
  

What it's does is reads the current location held in bc and puts it into the accumulator, like saying LET a=PEEK (bc). This is then compared to the value zero, and if equal, it jumps to the code held in the area of memory called EXIT. Next, rst $10, calls the part of the Sinclair ROM to print out the contents of 'a' (the accumulator - similar to PRINT CHR$ a), then bc is increased by one to read the next memory location, and we increase de to keep track on where we are up to on the screen. Here's the rest of the code:

EXIT
    ret
STRING
    defb "Your Name rulez!"
    defb 13,0 ; zero not 'o'
  

The code in the bit of memory we've called EXIT will simply return to BASIC. In STRING we have all of our data. We can define blocks of memory as bytes, bits or character strings. For the latter, we need to use quotes around the text, like in BASIC (DATA "Dave Jones rulez!" or LET a$="Dave Jones rulez!" for instance). In our program, we are passing one byte at a time into the accumulator (as 'a' can only hold one byte at a time), which is why we need a loop until we hit zero, whereas we could use a single line of code in BASIC like PRINT a$ or PRINT "Hello Mum!". Before the zero, the value 13 is equivalent of a carriage return. There's also a couple of comments for some clarity after the semi-colon, but these are ignored by the assembler. A comment is equivalent to the REM statement for remarks in BASIC.

Comments are very useful for explaining your code and/or for placing markers, handy if you have a large project on the go, or you are working with other programmers on one project.

For readability, I tend to put labels in capitals, tabulate the code and use lower-case letters for the commands and tabulate again for comments. Of course, you do what you think will make your programs more readable, as you are the one who is writing and maintaining them.

Assemble your code with Pasmo (see the previous instalment if you've forgot), load and execute it with PRINT USR 24576. You should see Your Name rulez! at the top of the screen and on the next line, the value of bc will also appear. We'll find a way of getting rid of the bc memory pointer being outputted in the next instalment, and look changing the text colour too. For now, experiment with the code to see if you can get an extra space in between each character, or move the text onto another line.

Bits and bobs

There are eight binary bits to the byte, and each memory location holds one byte. As I pointed out in the last instalment, binary works to the power of base two; every time we move left one place, the number is doubled from the place to the right. To convert an 8-bit binary number to decimal, you can first convert each 4-bit nybble to hex and then convert that to decimal, as stated last time, or you could use the following formula: (X7x128)+(X6x64)+(X5x32)+(X4x16)+(X3x8)+(X2x4)+(X1x2)+X0. That's a bit long winded, so as each place represents one or zero, we add the relevant number were we see a 'one' and ignore any place where there is a zero, for instance:

10110010

will be

128+32+16+2

Obviously, if bit zero, the least significant bit, is set (or one) – this is the bit furthest to the right as we look at our binary octet - then the number is odd and if it's unset (zero) the number is even [as long as the byte represents a positive integer number between zero and 255 inclusive]. There is a way to represent negative numbers in binary too, which we'll come onto in due course.

You can use an [online] converter if you're really stuck though, or the standard calculator on Windows in 'Programmer' mode, or whatever is installed on your operating system.

Part IV: Colour

Look back and you'll notice from the last instalment, I set a little challenge for you to see if you could get the code to add extra spaces between each character as it was displayed, and whether you could get the text to appear on a new line. There are many ways of doing this. You could have just added character spaces in the text in the data block, as follows:

STRING
    defb " Y o u r   N a m e   r u l e z !"
  

Knowing that the screen has 32 columns (or 32 characters) per line, you could also have added this number (or multiples thereof) of spaces before the text to get it written on a new line. This adds one byte per character space to the size of your overall code, and as you don't have limitless resources on a Spectrum, a more efficient way should be considered. We know the value 13 is the Sinclair equivalent of a carriage return. We could add this to the beginning of the data, as follows:

    defb 13,"Your Name rules!"
  

As for adding spaces between the characters, unless you manually did this as above, you might have tried to add inc de before the line jr LOOP, increasing the screen pointer twice. This wouldn't have had the desired effect though as we were using the register pair DE simply to keep track to which character we're writing to. More will be explained about the screen in later instalments.

What we need to find out is the code for a single space, like 13 is a carriage return. Here's how it's done. Before the line jr LOOP (and after the rst $10 line), enter the following:

    ld a,32        ; 32 is a character space
    rst $10        ; print the contents of 'a'
  

That said, there isn't really a correct answer in either case, but it's how I would have done it. Now we can output text to the screen, let's have a look at adding colour. I've included comments on each line for further clarity, but if you are unsure about anything, pop over to tinyurl.com/Speccy-Coding and feel free to ask any questions. Here's the example:

org $6000        ; Start of code
                 ; (6x4096 in decimal)
    ld a,7       ; Colour seven is white
                 ; ink and black paper
    ld (23693),a ; This sets the screen
                 ; colour as defined by
                 ; the accumulator (a)
    call 3503    ; Calls a routine to
                 ; clear the screen
    ld a,1       ; One is blue
    call 8859    ; We'll set the border
                 ; colour to blue
    ld bc,STRING ; bc points to the
                 ; string data in memory
LOOP             ; Here's our main loop
    ld a,(bc)    ; Load a with the byte
                 ; in location bc
    cp 0         ; Compare a to zero
                 ; (end of STRING data)
    jr z,EXIT    ; If equal to zero then
                 ; jump to EXIT
    rst $10      ; Output a to screen
    inc bc       ; Increase bc by one
                 ; to get next byte
    jr LOOP      ; Jump back to loop
                 ; label to do it all
                 ; again
EXIT                    
    ret          ; This will return us
                 ; to BASIC
STRING           ; This is our main
                 ; data block:
    defb "Your Name rules!"
    defb 13,0    ; 13 is a new line and
                 ; 0 is the end of data
  

Assemble and load this program into the emulator. To execute this code, we can now use:

RANDOMIZE USR 24576

And as you will see, the value of bc isn't printed when you return to BASIC. For our next challenge, see if you can change the colours of the text and border. For a handy reference, look in the old ZX Spectrum BASIC programming manual, but there are plenty of online resources which are a simple search away.

Colour handling

The Spectrum's colour handling for the screen is worked out with the following formula: (128xFLASH)+(64xBRIGHT)+(8xPAPER)+INK. The border can only be one of eight colours, as follows, 0=black.1=blue, 2=red, 3=magenta, 4=green, 5=cyan, 6=yellow, 7=white. If you want any INK (or foreground) colour on a black background, it's simply the colours as above, because zero is black and 0x8 will always be naught. If you want yellow text on a blue background, it'll be (1x8)+6, or 14. The attributes FLASH and BRIGHT can only be one or zero. To set them, just add 128 and/or 64 as needed. This concludes are first instalment, more will follow soon so keep an eye on this blog.

Saturday, 17 December 2011

An entry into Spectrum Computing.

During the Summer of 2010, I spent some time as a volunteer at the National Museum of Computing (www.tnmoc.org) which went towards my Foundation Degree in Enterprise Computing as part of my 'Professional Development' module.

As I knew that I didn't have much time to get anything substantial done during the Summer break, I designed two games based on actual locations at the Museum; one was for the Commodore PET, working in just 4K of RAM, which was a text adventure (now known as 'Interactive Fiction', because all games now officially have to be interactive or something), and the other was for the 48K Sinclair ZX Spectrum.

After drawing out the game map on the back of a time sheet, and writing out most of the game logic and puzzles, I put these into digital form and politely asked Jonathan Cauldwell if he could make my game - this was especially important as I'd used his famous EggHead character as the hero. Jonathan duly oblidged and added his own wizardry to it.

Unfortunately, my Commodore PET adventure didn't see the light of day (although I still have the source code), because there were concerns that children might end up using the Commodore PET. I thought that was the whole reason for a 'hands-on' area, but never mind. I did think up with a handy compression technique which can recycle though.

As for the Speccy game - A Cracking Day Out, Starring EggHead - well it was finished but I'm not sure if it was ever released by the museum even though I provided the files, emulator and instructions for them. The idea was that they could include all of this on TNMoC pen drives and that people could look at the source code and hack it apart to make their own EggHead game, and basically learn Z80 assembly language in the process.

At long last, it has an entry into the famous Spectrum Computing archives at https://spectrumcomputing.co.uk/entry/27236/ZX-Spectrum/A_Cracking_Day_Out-Starring_EggHead, and the .tap file might be available soon - watch this space. I certainly hope that it could be released into the public domain because it's frustrating to design or develop a game that no one ever sees.

Here's a screen-shot:

Tuesday, 6 July 2010

Update.

Well, at least the weather has been good, and I've passed the first year of my University studies (phew!) - it was a close call on at least one unit anyway.

So, what's been going on? Well, I've been looking a little more into the wonderful world of assembly code on the Sinclair ZX Spectrum. Making things happen inside a television screen has never been so much fun - or so quirky. Interesting the way the screen is built up anyway. On the gaming front, I had the sad news of the passing of a true legend from the 'bedroom coding' generation, Jonathan 'Joffa' Smith who was just 43. I wrote a tribute to the modest and extremely talented guy for Micro Mart, coming up in the next couple of weeks. Since, I've been trying out some of his games again, especially those that I missed. I'd recommend to you all a Sinclair User cover tape game Hyper Active, which is a neat defender clone with great graphics and scrolly-type things.

Aside from games, things are slowly moving along and hopefully getting a little easier on a personal level. I *think* I can continue my studies into next year on a full-time basis. I had considered taking a year out or part-time studying - fingers crossed that this won't have to happen.

This weekend, I'll be going to Northampton to catch up with an old mate of mine who's a big TI99/4a. So, it should be a good weekend all round.