Diary of a Game
Mental Procreation Part 2
Like all good prospective fathers, Andrew Braybrook finally decides upon a name for the new offspring. Uncle Steve continues counselling the Opus and the 64 in the hope that they will start talking to each other, and a program to double the speed of the C64 is written. There’s more drama to writing a game than you find in an average episode of EASTENDERS, as the second part of Andrew Braybrook’s diary reveals...
Friday 16th January
ST (Steve Turner) has been setting up the operating system on the Opus (called MSDOS) ready for our cross-assemblers, which assemble either Z80 or 6502 on a machine not running under those chips. Having obtained various library books on 8086 (the PC processor) and communications, we are hopeful that communications between our computers will be easy to set up. We just need to set up some leads from the Opus Centronics printer output (non-standard socket of course, courtesy of IBM), to the C64 and Spectrum. Two PCs running at the same time make a lot of noise with their cooling fans.
Monday 19th January
Did a nice sequence of eight sprites which fit on top of each other. They look very swish when colours are faded through them. Bit expensive on sprite usage though, maybe I can come up with a way of running something similar with characters.
Having seen Gary Liddon’s sprite multiplexor on Saturday, I can’t understand why his runs faster. Committed a no-no by using his method of building a table in the system stack so I can use faster instructions to read the table. It would have been very messy if it hadn’t worked. Don’t tell ST, I’d get the sack for misuse of the computer. It still isn’t as fast as Mr Liddon’s system, but his isn’t doing as much yet... I hope!
Tuesday 20th January
Discussed the possibilities of a game where the enemy show a bit of evolutionary behaviour, as the weaker ones get destroyed they are never replaced, but ones that get away grow stronger and randomly mutate, as featured on Horizon yesterday. Maybe even the graphics could be generated too, giving every game a different look, depending on the performance of the player in the particular game.
Scribbled some code for the moving back ground - looks like a lot of code with not much time to execute it in. I may have to use a 24 line screen rather than 25 to buy myself some extra time with the raster off the screen.
Also keyed in a machine code Centronics output routine for faster communication to the Spectrum. We’re still awaiting the data sheets for the chip in the Spectrum interface, so it wasn’t working too well - the Spectrum’s a little slow at noticing that a byte has arrived.
Wednesday 21st January
Keyed in the moving background system and it worked almost perfectly, except one set of lumps kept stepping backwards every now and again and some others left trails of debris behind them. Didn’t take long to fix though. This screen updating of thirty objects just about takes place while the raster is off-screen, so no flicker can possibly happen.
I’ve also been wondering whether to display the score on-screen and if so, how. Then I realised that I could just write the score in standard characters - I’ve always assumed that I’d have to do it with Sprites. Sprites may still cross the score but they will be on the move, I’m unhappy about using sprites in the border as it could be exploiting a video-chip bug. This may not work on some machines or it could cause damage.
Thursday 22nd January
Flushed with the success of yesterday’s background routine, I set about defining what I want to see on the screen, the control mode required to run it, and how I’m going to achieve this. I need to be able to move in all directions, fire in all directions, dematerialise, and select quickly which of these! want to do, all from an eight directional joystick and one fire button. I shall attempt to put this multitude of functions into the game without the use of windows, icons or mice, and only quietly muttering at the lack of foresight to put two independent buttons on a joystick.
Designed some more of the character set to show these various systems, I also think I’ve come up with the game name. As I was flipping through the dictionary for inspiration I came across ‘Morpheus - God of Dreams’. It’s about the right length, sounds nice, easy for advertisers to misspell and generally mysterious, so that’s what the game will be called, Morpheus.
I’m also conscious that the on-screen display must be kept moving and changing to maintain interest. I think I’ll need a more complex than average character update system to animate parts of the display with lots of frames of animation.
Friday 23rd January
No progress on Morpheus today, battled with US Uridium.
Monday 26th January
Spent much of the weekend working on US Uridium, and today I’m getting Uridium+ ready for going to the US too: I’m sure it’ll enjoy it there, it could do with a holiday.
It looks like the designers of the 8086 chip in the PCs are going for the January Mickey Mouse award, with its sixteen byte segmented memory arrangement. Any byte in memory can have thousands of different addresses. Very confusing.
Tuesday 27th January
Back to the real business of Morpheus. I want lots of different ‘meanies’, whatever they turn out to be, animal vegetable, mineral or atomic. What I want to do is build objects from lots of source objects, like building a sprite house from sprite bricks and sprite windows. By using X and Y reflections and specifying an artificial ‘depth’ or ‘priority’ for each image, I should be able to get proper animation with objects passing behind others in the same sprite. It will have to build the images in advance, say between levels rather than immediately as required - as combining up to eight images per frame of a sixteen frame sequence could take a lot of CPU wellie.
Wednesday 28th January
Been thinking about yesterday’s sprite combining system. It’s important to think through the limitations of a system before writing it, in case it won’t do what you want. It also gives me an opportunity to expand on the idea to explore what the system will do. I’ll have to resurrect my sprite reversal routine from Paradroid which produces the large robot pictures. Reflecting multi-coloured images is not as straightforward as reflecting hi-res sprites.
ST and I battled with some parallel communications this afternoon to get the Opus talking to the C64. We had a rare collection of errors, including the C64 missing out bytes because it wasn’t fast enough, the C64 duplicating bytes because it was too fast, total lock-outs where both machines were waiting for each other, and the C64 only receiving one byte per millennium. With the aid of a mega-soldering iron, pliers and our frustration brick we cracked it. We can transfer data at about one and a half kilobytes per second, which is the fastest the Opus will currently do. We should get it faster with our own dedicated routine, if ST wants to learn 8086, I don’t.
Apparently on the Opus you can print in foreground (ie everything stops until it’s finished) or in background, that is you can carry on as normal and the interrupts routines just get on with it. MSDOS takes the January Mickey Mouse award for its idea of background printing, it accepts keyboard input at a magnificent rate of one character every three seconds while background printing. Not what I’d call user transparent.
Thursday 29th January
Wrote a utility to read data from the Opus in ASCII format and convert it to machine-code as it reads it. Since it keeps getting checksum errors because it is missing bytes, I can only assume that I’m not getting back to read the next byte quickly enough. The Opus is like a machine gun and I don’t have time to catch each bullet, polish it and place it neatly, I’ll have to catch them all in a bucket and tidy them up while it’s reloading. Most frustrating because it very nearly works.
Friday 30th January
Monday 2nd February
Re-arranged my Centronics receive code to read a series of bytes at a time, stop transmission and decode them. It still occasionally ‘misses’ six or seven bytes. It either works perfectly or misses a whole lot, nothing in between - this is suspicious. Further investigations reveal that a certain C64 operating system delights in polling the keyboard every 60th of a second, despite being told not to by me. This has only started since I’ve been calling the write character to screen kernal routine, CHROUT, which must be enabling the interrupts again. How good of it to take this decision all by itself! Thus my receiving success or failure depends on whether I get interrupted while reading data. The interrupt lasts for so long that I lose about six bytes. With a very small test file it seems about an evens chance, but a larger file would never get across intact. I can soon fix this, just tell the timer chip (the CIA) to stop screaming blue murder every 60th of a second, rather than just sticking cheese in the system’s ears to stop it hearing and responding.
Now that it appears to be working it also explains why it didn’t work last Thursday, which was a better system. Now I’ve changed it I’m not going back. Just like my macro assembler loaders, it’ll type out full-stops as it loads, except mine will allow loading in RAM under the ROMs and protect against overwriting Certain delicate areas in the machine.
The Opus is now playing up, it refuses to link some Z80 code for my test file: it just crashes the whole machine. Perhaps it knows that the C64 wouldn’t know what to do with it anyway. That’s it, the Opus is emulating the C64 perfectly, it crashes! I only wanted to use Z80 because ST has already keyed in some Spectrum routines.
Tuesday 3rd February
Completed work on my parallel data receiving program and tested it out by passing a test file down from the Opus. All appears good. Right, time to take the plunge, retire the old C64, to be replaced by the new Opus PC, (I’ve been using ST’s Opus thus far), and connect it to the C128. The MPS801 printer will have to go as well since there just isn’t room, Opae are big beasties indeed. The 1570 disk drive can sit on top of the Opus, connect it all together, light the blue touch paper and bingo, a Graftgold Development System.
Got a quick tutorial from ST on using the text editor and MSDOS in general. So begins the task of rekeying all that I’ve done on Morpheus so far into the Opus. It’s nice talking to a man’s computer where software is written with no space constraints -a mere 492K spare for editing files, another 392K on the RAM disk, two disk drives with about 360K each, and an operating system that does what you want, when you want - with no fuss! Brings back memories of the old IBM mainframe (when it was running full tilt after five o’clock with decent IBM terminals and CMS).
Three problems have since reared their ugly heads, Easyscript won’t load, so I can’t see what I’m going to type in on the Opus, and the old 1541 won’t read any disks at all. It knows it’s being retired to the great disk drive home in the sky, to become just another ordinary breeze-block. The third problem is the most serious though, the fanheater’s bust so it’s blowing cold air all round the room, just like the Opae! Anything they can do...
Wednesday 4th February
One quick amendment to the receiver system, don’t allow it to load data over itself and crash, I’ve done that with my C64 assembler loaders a few times this week.
Some people may he saying -How can it take these people so long just to connect two computers together? "Whilst appreciating that it’s not exactly on the forefront of technology and one of the selling points of computers is the ability to interface them to anything - just you try and find someone who’ll stand up and admit that they’ve connected two different computers together in parallel. Many people ‘in the business’ seem to use serial links, but if God had intended us to use serial data, he’d have only put one bit in every byte. As we’ve already discovered, serial linkage is no easier than parallel, is slower, and has a worse-defined standard. We have connected an Opus PC-II to a C128 in parallel using only information in the Programmers Reference Guide, some timing and circuit diagrams of a Centronics printer and applied logic. We’ve now probably got one of the more advanced development kits in the country for micro software.
Thursday 5th February
Continued keying in my source code to the new assembler. It’s mostly much more versatile then the CBM one, but it does have one or two inefficiencies. Whereas I used to type < or > signs for low or high bytes, I now have to key ‘low’ or ‘High’ in full, not even ‘Lo’ or ‘Hi’ will do. I’m also learning to use the new proper fullscreen editor. Imagine a delete key that actually deletes the character under the cursor, not the one before it: how revolutionary, it’ll never catch on! I remember the IBM mainframe that I used to work on did that - a real home from home this is. Finally got my utilities all keyed in and my variables and macros. I made some improvements to some tacky bits of code whilst rekeying it so I wouldn’t be able to check it against the original version when it’s done, very clever I don’t think. If anything goes wrong it’ll be harder to find the errors. It’s great being able to put huge comments in the code - on an 80 column screen it still looks tidy. It was impractical to get carried away on the C64 as it hampered loading time and took up too much space. All the source for one game used to take over 500 blocks on a disk, or about 120K.
Initial timing tests show that to assemble and download my utilities takes about half a minute, not fast by any means, but compared to about five minutes on the C64 it’s great. It’ll be interesting to see how long it takes on a finished program, which used to take the best part of half an hour on the C64. If it’s still ten times faster it’ll only take three minutes.
One thing about the assembler is that it really goes to town if it finds an error. It usually manages to find at least five things wrong on the line, just from one letter being mis-keyed. If it only printed four error messages it’d probably print a fifth moaning that it could only find four things wrong!
A final piece of good news, the fan heater is working again.
Friday 6th February
Feeling rather ill today, but it only hurts when I move. Struggled in to work and keyed in all the remaining source code to the Opus, assembled it, corrected all the typing errors, assembled it again and booted it down to the C128. It all ticks over very nicely.
Spent much of the afternoon looking for the bug that caused the sprites to flicker horrendously. Finally found it, I’d just mis-read one character from one screen while typing on the other.
ST found out why the Spectrum won’t listen to the Opus whereas the C128 will, it’s a good one this. Since the Opus thinks it is printing to a printer, and our micros are impersonating printers, due to a certain wire not being connected at the Spectrum end, the Opus thought that the Spectrum had run out of paper! Thus it wasn’t sending data across. A simple soldering job cured that and the two are now happily communicating.
Hopefully by now some of you will have played the Competition Edition of Paradroid in the Christmas double pack. Being 50% faster than the standard edition, it certainly plays a lot more furiously. I discovered how to make Paradroid run fast after I finished Alleykat. I was experimenting with the double-speed CPU in the C128 which is an adaptation of the 6510, called the 8510. It can run at a clock speed of 2MHZ if required, but normally it runs at 1MHz for C64 compatibility.
Upon further investigation, I realised that the 6510 present in all C64s could also be encouraged to run at this higher speed by use of software. I have produced a BASIC listing to allow you to apply this discovery to your own software. Just key in the program and save it to tape or disk, RUN it, and then NEW it. Finally load in any game from cassette. Once loaded, it will run at up to double normal speed, prepare for a mega-fast game! Since the 6510 Accelerator upsets disk loading speeds, it cannot be used to speed up disk-based software yet, but I am working on a solution to this.
By the way, line 90 contains some cursor commands in quotes. The PRINTed line is 3 cursor downs, then NEW, then three cursor ups to put the word NEW on the CURRENT line just to remind you to NEW the program. All you do is press ENTER.
Monday 9th February
It’s been a slow day. Began by writing some more notes on the sprite combining system. I suppose the idea came from reading about ‘Blitter’ chips, the way you just point them at up to three sources of data, one destination for the finished data and tell it what logical operations to perform, and it does it. It can do anything from simple data copies to complex object plotting. Wish there was a blitter in the C64.
Now that I have a game name I can begin thinking about title screens. I’ve re-arranged some of my large character set to allow it to be used with my moving background system.! shall also need a snazzy high-score table of some kind.
Tuesday 10th February
Got to grips with the multi-layered grid that moves at different speeds, done with characters. Sadly it doesn’t have CPU time to build and dis play it in real time, and not even at half-speed, doing half of the grid on each cycle. It is a nice effect though, so I’ll have to work out another way of displaying it. It’s a lot faster to debug with the source code in front of you on one screen and the game running on another.
Redrew the small-lettered character set and the game logo that will appear on-screen during the game to make them easier to read. It’s the first multi-colour resolution character set that I’ve ever done, Alleykat was in hi-res but with a fancy Atari-emulation system to make it look like more colours.
Wednesday 11th February
Re-organised yesterday’s grid-drawing routine so that it calculates all the animation frames in advance and can then display them at any speed. Thus it takes very little CPU time to display and gives me time to run the moving blobfield and thirty-two sprites. Of course it does take an extra 4K of memory - you don’t get something for nothing. The constant battle is always time against memory; you can write a routine that’s fast but takes a lot of memory, or write it to take less memory but it executes a lot slower.
Re-arranged the character set (again) to group together all the pieces that are similar in what they will do. This is so that anything such as collision detection needs only to check a range of codes, not a series of individual codes dotted around all over the place.
Tried to think of a neat way of dematerialising the character set that hasn’t been used... failed. I could switch in a new character set,or a new screen, or both. Maybe a Uridium dreadnought dissolve would look nice.
One thing about our new Opae, the editor has no line numbers. Great. I hate line numbers! They were only invented for punch cards so that if somebody shuffled them you could sort them out again. This is the 1980s, and we don’t use punch cards on the C64, so why do we have to suffer line numbers? Mickey Mouse award for the Thirteenth Century goes to the inventor of line numbers, especially in BASIC programs.
Thursday 12th February
Wrote (on paper) and keyed in an object block plotter, which plots blocks of characters on screen with which I shall build a sort of mini-dreadnought. This is the ship that the player will fly. At biggest it could be twenty-seven characters wide by n-n-n-nineteen high! Should give the player a feeling of superiority. I’ve got the ’Player X’ words and the game logo put on screen using this block plotter, as well. Looking at it now I reckon I should put the moving grids up using the same plotter, which will save on code. However it can only handle the first 128 characters, because I use the top bit as an end-of-column flag. The grid uses higher character codes.
Took some screen shots this week, but the processor always takes at least a week to do black and white so I’ll send them to ZZAP! next month.
Since our printer has been disconnected for taking up too much room on the desk, this diary will have to go home for printing.
To be continued...
6510 Accelerator listing
10 B=0 20 FOR X=49152 TO 49463 30 READ C 40 B=B+C 50 POKE X,C 60 NEXT X 70 IF B<>44878 THEN PRINT "ERROR": END 80 SYS 49152 90 PRINT "<CD><CD><CD>NEW<CU><CU><CU>" 100 END 200 DATA 174,48,3,172,49,3,142,46 210 DATA 3,140,47,3,162,74,160,192 220 DATA 142,48,3,140,49,3,162,245 230 DATA 160,192,32,188,192,162,6,160 240 DATA 193,32,188,192,169,128,141,225 250 DATA 192,160,3,202,208,253,136,208 260 DATA 250,206,32,208,173,225,192,56 270 DATA 233,1,72,238,32,208,104,141 280 DATA 225,192,208,229,169,37,141,5 290 DATA 220,96,201,0,208,8,165,186 300 DATA 201,1,240,5,169,0,108,46 310 DATA 3,32,23,248,162,26,160,193 320 DATA 32,188,192,169,11,141,17,208 330 DATA 169,48,141,225,192,160,0,202 340 DATA 208,253,136,208,250,206,225,192 350 DATA 208,245,169,34,133,192,169,55 360 DATA 133,1,169,27,141,17,208,173 370 DATA 134,2,41,15,168,172,134,2 380 DATA 185,36,193,141,243,192,162,226 390 DATA 160,192,32,188,192,165,197,201 400 DATA 64,240,250,174,46,3,172,47 410 DATA 3,142,48,3,140,49,3,169 420 DATA 27,141,17,208,169,64,141,5 430 DATA 220,76,116,164,142,203,192,140 440 DATA 204,192,160,0,140,225,192,172 450 DATA 225,192,185,226,192,73,255,72 460 DATA 238,225,192,240,11,32,210,255 470 DATA 104,201,13,240,3,76,199,192 480 DATA 96,19,185,176,170,177,187,223 490 DATA 250,190,175,173,182,179,223,185 500 DATA 176,176,179,101,242,201,202,206 510 DATA 207,223,190,188,188,186,179,186 520 DATA 173,190,171,176,173,242,189,166 530 DATA 223,190,177,187,173,186,168,223 540 DATA 189,173,190,166,189,173,176,176 550 DATA 180,242,172,186,190,173,188,183 560 DATA 182,177,184,242,111,250,227,96 570 DATA 99,225,224,97,126,106,105,104 580 DATA 103,102,101,100,0,0,0,0
If you have any idea what should go in this box, please let me know! :)