Tuesday 5 May 2020

Breaking change

We all make mistakes. One early mistake I made was copying (partly) the old thing in Microsoft BASIC where you didn't have to declare variables at all.

If you do this in Microsoft BASIC it will just print "0" ; the default value, as do versions prior to 0.93

It now requires you to declare variables. There are three ways to do this - an assignment statement, a LOCAL statement, and as a procedure parameter. (Well, four if you include DIM, but that's something different).

Running the games so far shows why. Most worked fine. Asteroids didn't, because the RPL code that does the movement and collision checks accessed variables that didn't exist. There were a couple of mistakes - a game that should have been a game.score , but didn't matter because it was initialised to zero. Pacman had one mistake. Everything else works ... I think :)

I might make it optional again, but I probably won't. It's like GOTO GOSUB and RETURN. They're there ; RENUM ignores them to discourage you, really it's just for type-ins. I seriously considered disable the tokeniser code for those three.

So next up ; the Sprite microlanguage, a sort of high level compiler, and inline documentation for RPL words. The high level compiler is based something I've done before, it's very simple and clean and designed round the architecture of the machine.

Sunday 3 May 2020

Game#10 : Lunar Jetman

So the completely original arcade adventure is now working except for sound effects.

I think the next thing I'll do is this sort of "Micro sprite language" ; no use for main objects, but useful for twiddly things.  When bad guys die on this game, they just vanish, and it would be good to have a little, simple , animation for that.

Saturday 2 May 2020

Game#10 : Sabre Wulf

So, after a quiet day or two, more work on the new game. This is still all in BASIC.

Ganes do look very Spectrum-like I think, mainly because of the single colour sprites. The sprites are all done in software and are part of the kernel ROM, so there's no actual reason why they have to be single colour. At present, they just are.

Thursday 30 April 2020

Game#10a :Atac Atic (no relation)

This game is not slightly based on "Sabre Wulf"
So this is coming along okay though I haven't done a huge amount on it yet. It's still all done in BASIC (the text on the right isn't a bug and I do write comments in the source but they're filtered out in cross development usually).

However, I did find a bug this morning. I have a command SPRITE 1 END which kills Sprite 1. Which didn't actually work. So the completely original non derivative game shot the spell out but didn't actually remove the spell graphic when it had finished.

So fixed that.

One of the things I've considered, which I first saw on STOS I think, was the idea of being able to attach a background program to a sprite. Simple sequences - move here, change to this graphic, fade out. I'm very tempted to implement this (will finish this game first). It wouldn't be much use here, because it wouldn't be able to bounce of the walls, but it'd be quite handy for simple things ; like in arcade games where you shoot something and it puts up a little "100" in colour which disappears, or explosions. To do those requires the use of timers/events or AFTER. Could use a syntax like SPRITE 4 RUN "xxxxx" though you'd probably need some way of stopping it, and testing status as well.

True story. I've actually visited Ultimate, when they were in Ashby de la Zouch (ACG = Ashby Computers and Graphics) and I was at Keele University (both in central England). I pulled this trick on more than on occasion ; if some game is unavailable due to demand (in the case, the BBC Micro version of "Alien 8") I managed to sort of buy it direct. I tried it with Revs at Acornsoft's HQ in Wellingborough, as well. They think you're mad, but it worked :)

Spent a whole day removing the copy protection to put it on disk. You had to , because it was XORed with the free running timer in the 6522, so you either had to do cycle perfect emulation (non starter in 1985) or add in code and add in enough dummy code so the counter looped back round back to where it would have been anyway. This worked fine, but of course introduced a slow down factor of 65,536, which meant the second or so it spent unscrambling it padded out to about 20 hours. I didn't distribute it though :)

Wednesday 29 April 2020

Game # 10a ... quiz of the week.

As I got fed up just porting someone else's work, this game is under way. This weeks CoronaQuiz is "guess what it is ?" (modelled on). Nearly as hard as those phone in quizzes which charge £2 / minute when you enter.

It's not the derivativeness (real word ?) that's the problem, it's the tedium of line by line translation. If you've ever read a Jilly Cooper book (it was the only thing left) you'll have some idea.

Confession time. I've done this before. I wrote this 35 years ago and it was published in the "BBC Micro User" as a type in. I found it poking round the BBC Micro archives a few days ago.  I've never been able to draw. I still can't. I think it's why I liked coding for the RCA Studio 2 ; at 64x32 resolution you can't actually do much with graphics.

Annoyingly when ever so slightly derivative game was published they got my name wrong ; I became "Hobson" :(


Not the best thing I ever wrote for the BBC Micro. My favourite thing was a derivative of Galaxians that was a multiprocessing tutorial (or just fun). Every enemy was a process running its own script, but it was massively accessible.  Learning through play. I also wrote a hacking game (I got the idea from a Spectrum game System 15000) where my pupils had to use various systems (no internet then) to change the exam results on exam board computers to all A's. It was a simulation, of course, but probably some idiot from OFSTED would accuse me of teaching them to be criminals these days.


Game # 10 : On hold

I'm quite surprised. I actually am finding doing this rather, well, boring.

It's a bit like manually translating a foreign language using an encylopaedia. It's not particularly difficult, it won't come out that well, and in this situation I don't think it's really worth it.

So Game#10, which is basically a Port of the game, is being dropped. Not quite sure what I'm doing yet, but I might actually produce something which is a homage to it or similar ARPGs, but not actually the same game literally. Either way, it's time for a rethink.

The one upside is that as you can probably guess, this is produced randomly. And I hadn't realised quite how dreadful the LFSR based random number generator I was using is. So that's been thrown away and replaced by one I found on the net based on shift-XOR ing which seems way way better. The Random generator is actually part of the Kernel, so this is not a big deal.

Tuesday 28 April 2020

Game #10 : Sword of Fargoal

Game#10 is going to be Sword of Fargoal, which is a C64 classic from 1982.

This is chosen largely because I already have reverse engineered it, so I know exactly how it works.

It's an early wander through the dungeons action RPG.

This is assuming I can find the reverse engineered version and it's not lost on a damaged CD or something like that.

Compiler

So, I've fixed SYS to work better. I've also made a tweak involving program line zero.

I didn't even realise that you could have a program line zero, but you can. Program line zero has one huge advantage, it is always in the same place.

So this is now hidden (lines 32768-65535 are also hidden). The idea behind this is if I ever get round to writing programming tutorials for it, support routines can be placed in higher line numbers (Basic) or line 0 (Machine code) and effectively hidden. This allows effective libraries, or code to be written that allows a tutorial to experiment with simple programs without having to have all the confusing visible boilerplate.

Line zero was prompted because I'm planning a compiler. A fairly simple one, called ECPL (not like BCPL). I'm a great believer in that you should tailor your compiler to your hardware, where possible - (so running C on a 6502 isn't a good idea for example) and it will pinch some ideas from a Z80 compiler I wrote called SCPL.  But I had to find somewhere to put the code. Basically there are three options. One is to move PAGE up (so that BASIC runs up at &5000 and &4300-&4FFF is code, say). Another is to move Himem down, which is messier, but could be done as part of CLEAR perhaps, though there are processor stack issues. Relocatable code isn't practical, so that leaves loading it in as line zero. Because it's a 16 bit machine, the offset to next line is 16 bits, so you can have one line with 10k of code in it. It should work. (I haven't actually tried this). The only problem with entering a 10 line BASIC competition is that PROCedures have to be at the start of the line. It won't do anything except occupy space, editing/running won't be affected at all. It's not listed so it really is almost irrelevant what's there. The only problem with it might be OLD. OLD recovers a program that's been NEWed but it does so by scanning forward, so this may well involve the creation of a new token type which allocates data randomly. I'll have to think about it a bit.

Monday 27 April 2020

Connectivity II

So, after rewriting it twice (!) I finally got the HTTP download working reliably. It's fairly simple ; it just downloads a file from a URL and stores it in SPIFFS on an ESP32. This can be done programatically.

Another issue, again specific with the ESP32 is transmission the other way. I don't know if anyone will ever actually write any code on the machine itself for real, as opposed to cross development, but if so a form of backup is required.

I've added (another) hack which allows data to be sent back via the serial debugging port. A BASIC program reads the directory and then sends the data back through that port in a text format, a bit like Intel's Hex format, which can be captured and converted back to the actual files.

I've also decided that SYS should be redesigned. At present it just passes the address of variable A in R0 (as well as the RPL stack pointer in R8). I found that accessing routines using RPL is messy - it works fine RPL(#file$ 7 2 &10 sys ^size) but it's not that clear. and I'd like to be able to do SYS &10,7,@file$ . I haven't written any code that uses the A passing and RPL makes it a moot point anyway. ($0010 is the File handler vector). The idea being that &10 is the call address, R0 = 7, R1 = address of file$. The RPL does the same thing (the 2 is a parameter count).

Though there will have to be two forms of SYS, because it quite often returns a value in R0. So there'll be a Unary call =SYS(&10,7,@file$) which uses the same code.

Thursday 23 April 2020

Connectivity

No idea who AZ Delivery are
Okay, so I've been tinkering around with connectivity today (and tweaked odd bits, the main thing is adding RANDOMISE). Been busy the last couple of days (annual follow up test in hospital).

So there are two basic issues. Getting stuff in and getting stuff out. Out is system specific ; ESP32 stores files in SPIFFS, in unused Flash memory. So I need a way of getting that out. I think I'll just dump the lot to the serial port as a debug option for the time being.

Not that I'm actually doing any real development on the actual machine, it's all done cross platform.

The other thing is downloading stuff. I want to do this over Wifi, I mean the ESP32 (pictures) has Wifi so why not (the problem with doing it the other way is I don't really want to use Server. There's a thing with FABGL where it really doesn't get on with SPIFFS. It used to randomly bork ; it's something to do with the interrupts, you have to turn them off to access SPIFFS)

So having waded through mountains of C of varying incomprehensibility, I've now got it downloading an arbitrary file. So next thing is to patch it into the ESP32 version. The emulator version is easy (for now), there'll just be two directories, one is the web directory, the other represents local storage. If I ever get around to doing a Pi version (I know it works) I'll have to figure that out.

Monday 20 April 2020

Game #9 : Asteroids

Asteroids is now working (no flying saucer).

As you can see from the demo here, the collision detection isn't great. I really wanted to avoid square root calculations and can't do pixel collision so its a simple box, and because of the shapes it is fairly generous with the collision detection.

Note, running the emscripten version does occasionally require a reload ignoring cache (Ctrl+Shift+R on Firefox) . I've just had it not work on me , nothing worked apparently, but reloading it fixed it.

Game # 9: Asteroids

Didn't do anything yesterday, but a bit more coding this morning has lots of asteroids flying round the screen.

Quite pleased with this integrated FORTH compiler. It's a bit odd to get used to, but it works quite well. This is still only about 10 lines or so.

It will actually go faster than this (there's a line if event(e.move,6) then ...  which fires every 6/100 of a second) and the large asteroids are moving max 1 pixel per frame. You could say every 6,0 call move.everything() as well.

(The ship is wiped out because it's not redrawn in the main move cycle. The drawing works by writing and erasing bitmaps in black and white in a sprite fashion (e.g. only writing the pixels that are on) but when an asteroid is erased to move it takes the ship with it)

Saturday 18 April 2020

Game # 9 ?????? : RPL In Action

You can probably guess what the game is :)

So I thought I'd use this built in compiler and see what it could do. I'd do two things with it, move the objects on the screen, and collision detection. Steering code and so on can be BASIC.

This is doing about 30fps with 25 asteroids, and it's 9 lines of actual code. A fair amount of that time is the actual drawing bit. Code could definitely be clearer, but still getting a feel for it. It's pretty ineffecient code ; (it assembles to about 300 words), because the CPU isn't really designed for Threaded Languages ; it can do it fine ; it doesn't have a push/pop or a load/save with auto increment. At the moment it's using one register for TOS and keeping the rest on the stack ; that was probably a mistake. I'll probably rewrite the library at some time (there's not very much of it).

These are bitmaps. The blitter isn't great at drawing lines ; it's not terrible by any means (especially when parallel to an axis), but it's not really its strong point.

Friday 17 April 2020

Insert

Something I should have done ages ago, to allow the screen editor to insert spaces, at present it operates in overwrite mode.

This doesn't matter too much because spaces are not tokenised, except in string constants, so if you put 100 X =                42 into it it will list it as 100 x=42

But it was a pain when editing programs.

READ/DATA/RESTORE belong with GOSUB and GOTO

....are not implemented. Deliberately. I did implement GOSUB GOTO and RETURN but under protest :) and it's bad, the RENUM command ignores them so if you renumber a program with GOTO and GOSUB in it won't work. There is actually an ON token but it doesn't do anything other than generate a syntax error.

But still one needs data. So I borrowed a concept from AppGameKit BASIC, which has substring functions, so that you can pass in CSV data (or seperated with any single character) e.g.

12/23/42/61

and there are two functions to split it up. One returns the number of substrings, sub.count(a$,"/") (obviously 4) and one extracts a substring sub.get$(a$,"/",2) so you can store your data in strings (or just in the program code) and access it this way.


Thursday 16 April 2020

RPL , working towards 0.80

So, this morning I've written all the words except the variable access words and the structure words. Onwards and upwards.

After that I will write another game from my list and try using it in the wild. Something that moves quite a lot of individual things very quickly.  None of the games have done yet - Frogger / Invaders probably look as if they do but it's a cheat :) Anything with regimented groups uses tilemaps.

L8R: Added the variable access, still no structures. You can see what it looks like in this picture, this code is equivalent to the following FORTH. 

: star 42 emit ;
: demo star star cr test @ . 23456 test ! cr ;

The variables are different. The ^test and &test refer to specific operators.
SYS has been amended so that as well as assinging to CPU register R0 the address of the A-Z variable block, it also initialises R8 to the to of the small stack allocated for RPL.

Which reminds me. A big missing thing that I keep meaning to fix is the insert space on the screen , at present you can only overtype. This won't be full insertion, probably, but it will allow the use of a key (probably Ctrl+E) to make space in the current line.

L88R: Changed & for technical reasons. It's a special token that is connected to the constant, confusing the lister/tokeniser So it is now '^' ... except that didn't work either. Discovered a bug in the tokeniser where it was thinking ASCII codes higher than 'Z' were numbers.

L888R: RPL is done, probably add a few words here and there, but as originally designed , it works.

Wednesday 15 April 2020

FORTH yet not FORTH

Have a working RPL compiler as a unary function, but not a dictionary yet. Just a few test words. It's very , but not exactly like FORTH. The main obvious difference is in the variables - these are prefixed with ^ and & ; so &count is the same as count @ and ^count is the same as count ! in FORTH. This is because it has to work with the BASIC variable system.

You also have a static read-only dictionary - word addresses are stored in BASIC variables (hence the ^ and & operators !), and can't (at the moment anyway) define immediate words. The structures will be simplified. But it is recognisably the same.

One thing which is actually a plus point is it can't split a definition over two lines of code (you can have a very long screen line). This has the benefit that it almost forces you to break up definitions into smaller ones rather than writing whole page definitions, which I kinda think you should be doing anyway.

There is a comma, because the syntax parser and lister is designed to deal with BASIC and the comma compiles nothing but can be used to clarify the syntax e.g. do you want +! or + ! ; by writing +,! it becomes simpler. It is an issue because the spacing is done entirely by the lister, no spaces are stored in the tokenised code. It's not like Microsoft BASIC, if you look at it as characters it's largely unreadable.

Doing things as and when.

Well, every, after and cancel work as the gif on the right shows. They seem to be fairly reliable, though I haven't bullied it too much yet.

It's deliberately made not reentrant, so if you call a routine it can't call another one until you return from that. If you delay it while it does a lot of work it just queues the events up for later. I thought that was safer rather than just letting it do what it wants, which the Amstrad version does, as far as I can see. The underlying code allows any number of repeats, so I may extend it so you can say "after 150,2,5 call code.routine()" which will call it 5 times at 1.5 second intervals.

I also added @ as an operator returning a variable data address, because I'd added it as a token for RPL which I want to keep as FORTHesque as possible.

Tuesday 14 April 2020

New commands

I want to add 3 commands, which I think are quite neat, and I've only ever seen on this machine (the British machine, the CPC464).

They are EVERY AFTER and a means for resetting them. They are timers, that call a procedure either on a regular basis, or after a one off event. So on a CPC you'd write something like

EVERY 40,0 GOSUB 1000

Which would GOSUB 1000 every 40 ticks, which on the CPC is 50th of a second using timer 0. AFTER does the same thing, except it just fires once. I'll probably use CLEAR <n> to reset/clear the timer. You do have to be quite careful because of problems with code not being predictable. But it'll be quite useful.

So adding this will push it from version 0.69b to 0.70 and then I'll add the RPL() compiler which will push it to 0.80

Game 8 : Space Invaders

So, Space Invaders is now working. Not authentic (it's not colour in real life, it has cellophane on the screen). The obvious other differences are the shields, which are reduced to an 8x8 block array - because the one thing that you can't do on the computer is read the screen. So it disintegrates in small blocks.

Monday 13 April 2020

Game #7 : Frogger II

So, done a bit of work on Frogger, and it now mostly works. You can play the game, there are just no sound effects and the turtles don't dive.

So I'll finish that this morning, and will do Space Invaders (aahhh the classics :) ).

Then I will spec this quasi FORTH that's been bouncing round my head for a few days, and write that.

Hopefully makes the assembler almost null and void. Though it's only a small amount of code, having an orthogonal instruction set gives you a simple assembler.

Most of the work is actually macros like push and pop (you can write push r0,r1,r2,r3,link and it generates 6 instructions in the right order) which are very useful, and some clarifying ones. For example carry testing is done using the "skip if carry matches operand bit 0" instruction (this sounds completely insane but it actually works very well) but you almost never use that because macros make the far clear skc sknc sklt skge, for carry testing and subtraction comparisons. There's a similar thing for register sign/value test skz sknz skp skm. Jumps branches and Returns are all done with the same instruction (branch-link which does Rx = PC, PC = operand) but it's completely unreadable in source, so there are jmp, jsr, ret instructions which compile to the relevant opcodes.

Saturday 11 April 2020

Game # 7 : Frogger

Busy today, so just done the background for Frogger. This is probably most of the work though. It already scrolls, though just one way one speed as a bodge, at about 20 frames per second which is plenty. (Later: ESP32 it's more like 11-12 so that's something I'll have to work towards)

A couple of notes. Firstly, in real Frogger the top half, the river, is blue not black (it's near a chemical plant in this game). The system is perfectly capable of this, but at present the lanes are actually a 1 character high tilemap, there's 10 of them. This works quite well but the tilemap implementation currently has the problem that it can only do one background colour for a tilemap. I designed it that way. I might extend it to allow a different colour background but it isn't done this way. I could just write a routine to blit it out, but that would be cheating really. I'm trying to do as much as possible in straightforward BASIC. Just because.

Second point is the sprites are all monochrome. This is a limitation of the current sprite system, but I will probably extend it to do multi colour sprites at some time. The downside is because the blitter only blits one colour at a time, two colours requires twice as many blits.

I'll probably use the same trick for Space Invaders - the invaders will be a tilemap, so I can just scroll it or update it with one command.

A hack

I've added a Turbo mode to the emulator. Not for running the actual game ; that is still limited to the reference implementations approximate 0.95 MIPS. It's for testing ; if I have code that spends a while setting up, it means it just skips that bit more quickly, and on non Windows/Linux emulation or slow hardware, it doesn't matter.

Friday 10 April 2020

Nitwit bug of the week.

I've got a 6 digit score .... and it uses 16 bit integers .....

Pacman working and 0.68

So Pacman is working ; though I think I've set the default speed a bit slow. This isn't because it can't go faster, it's just an arbitrary choice.

Definitely will fix that because I've just realised I forgot to decrement the life counter when you lose a life. Which makes it a bit easy.

I'll fix that for the next upload though.

This is version 0.68. One bug fix ; there was a gap between sounds in the queue which threw timing and the sound effects out. I've also add min() max() and quiet() to the keywords.

Thursday 9 April 2020

Pacman mostly working

It now far more resembles the finished product. In actual game elements, you can play it .... there just are no collisions so it's not particularly challenging. There's no sound either, or the bonus. But you can play most of it.

Shopping day today - treat of the week ! So not done a huge amount today.

Wednesday 8 April 2020

Bug fixed.

Line editing now works properly. The kernel code which worked out where the line started and ended was a disaster. I'm amazed it ever worked at all :) However v0.67 now works.

Pacman under way but ...

Found a bug. Well, a couple of bugs, one silly, one not. The silly one was an error in the tile command, but the not silly one is to do with editing long lines of code, which has stopped working. It's generating a syntactic error.

So I'll have to fix that one before continuing with Pacman which is fairly advanced. Most of the plumbing is there, there's just the movement of the game objects, scoring, sound effects and bonus left to do. Which isn't too much. (the top line isn't an error, I ran it and broke it, so it's printed "break error" on the top line

Tuesday 7 April 2020

More ideas.

While lounging in the bath this morning I remembered this language I'd found a while back ; it was called RPL, and it was for the Commodore PET. It was very similar to FORTH ; same basic idea, different syntax. It used the tokenising system as a sort of virtual machine code. Problem was the 6502 is great at one thing, being cheap, and not very good at many other things, so it was a bit limited.

Had the idea of doing a similar sort of thing here. I was going to do FORTH anyway, but I thought if I used an inlined FORTH I could take advantage of some of the things already there - for example variables and have a fixed dictionary. Then you could add quasi-FORTH using this sort of syntax

new.word = RPL(40 2 + dup . . )

So RPL would be a unary function that returned it's call address. Dup and + could either be in a fixed dictionary, or variables themselves. You could have immediate variables and so on as well. Implicit semicolon at the end. Once you've defined it you can just call it with sys new.word and it already knows about the variables. Arrays wouldn't work, but indirection would be fine a la structures in BCPL.

Now, to fix actual variables - there is a problem if you have a word in FORTH it 'knows' what it is. This doesn't. So the idea is something like - a variable compiles its address , so you could write

another.word = RPL(new.word new.word)

Variables would track the reference of the last compiled address, and use two operates to back patch. These couldn't be @ ! so I have used @@ and !! in the past e.g.

another.word = RPL(count @@)

would initially compile jsr #<whatever value count is> but in this case it would back patch and replace that with push r0 ; ldm r0,#<address of count>

I will give it more consideration.

Game #4/5 - Dodge ' Em

So this is game 4/5, modelled on Atari's VCS chasing game. It's actually a complete rewrite from the ground up, I wasn't happy with the first one. What I find with this sort of thing is you get a feel as you go.

So the next games are planned to be Frogger, Pacman and Space Invaders.

Now BASIC has its limitations, and the main one is being interpreted. In this you can write code in Assembler but that's quite heavy

Sunday 5 April 2020

Game #3 ... sort of ... Maze

It's not really a game. I did think about making it into a 2D or 3D chase game, but it's just a maze generator at the moment. I do plan to do "Sword of Fargoal" , the old Commodore game (partly because I've already reverse engineered it so I know how it works).

It's a hunt and kill algorithm. What I really wanted to do was bully the core a bit - things like the loops, local variables, arrays and so on to see how it coped.

Fairly well (the code is here). It's a 20x20 maze, and hunts maybe 20 times , and it takes about 13 seconds.

More to the point, it seems fairly reliable, doesn't crash, and ports okay. I've been tinkering a bit today, I found for some reason it built on Raspian before but it doesn't now, so I've changed things so that all the python xxx are python3 xxxx (python 2.7 doesn't work) and changed the screen layout so it fits on the screen.

As always, if you do run the javascript one, reload it, otherwise it might grab it from the cache. 

Saturday 4 April 2020

Tweaking the Emulator

When I wrote the original emulator, it was meant to be just that ; and it is actually the basis for all implementations. Some things are just inconsistent, e.g. Ctrl+Escape doesn't work across platforms. So I've been tinkering with that this morning - the Javascript version no longer has the debugger code, and Ctrl+Esc should reset everywhere.

I built it on an emulator framework that's at least six years old and has been used for several emulators of various types, which doesn't help either.

On a related matter, the six function keys which you can program with the fkey BASIC command (e.g. fkey 1,"Hello world"+chr$(13) ) won't work on many implementations because F1-F6 are coopted for something else in the browser or whatever. It is a system standard that these can be done with Ctrl+1 .. Ctrl+6 as well as F1-F6.

Game #2 : Breakout

Gotta start somewhere.

So I decided with a very simple game which doesn't need anything difficult - Breakout. It's modelled on the "Video Pinball" machine's version, which is fairly close to the original arcade.

It's entirely BASIC. The only change I made to the BASIC interpreter/Kernel is to allow the text drawer to scale, so I can do big letters easily .... admittedly they look a little blocky.

I did find a bug though, not fixed yet. You can't use Ctrl+Space , which is the break combination, to break out of a get$() (and probably not WAIT, INPUT, GET() as well).

I'm going to build and upload at the end of the day, UK time, as there are now four versions ; Windows, Linux, ESP32, emscripten . Most of the work is actually done on Linux and the other two are just built occasionally.

Friday 3 April 2020

A game and some progress.

So, a game does finally exist and works, but it's just a basic squash. It yielded an actual bug, a dumb one. The sound channels have a queue of sound events, you can queue up to 32 sounds or slides. These go in the tail of the queue, and are popped from the head of the queue. Unfortunately the head of the queue wasn't wrapping round (careless), so on the 32nd beep the sound stopped working.

It also now runs in Javascript. Quite well, seemingly, though I don't know how it works on a slower PC yet. Anyway, you can run the Javascript port here.

Thursday 2 April 2020

Still no games.

Didn't work on it much yesterday, and fixed a few bugs. One was to do with rounding and conversion in the SDL tone generator code ; I was using (int) as a cast but casting it too early, and the consequence was that sound stopped playing after about 3 seconds on the tone channels. Another was the latency of sound, it was starting after a slight pause, so if you say hit something and had a sound effect it was slightly too late. I wrote this beeper code something like ten years ago and never noticed this before, probably because it was barely used.

Having been experimenting though I'm quite pleased. I made some mistakes, mostly due to language switching, so I'd write a != 3 rather than a <> 3 and it would barf. I thought I'd discovered half a dozen bugs when writing test code, but it turns out all of them were errors on my part, and the interpreter was doing exactly what it should, even when it crashed. One advantage of the VM design is it's almost uncrashable - some of these retro designs write the code in the target machines compiler, which means bugs can appear there. I'd forgotten that in SAVE "filename",a,b the second b was a length not an address, so I was writing out a 35k data file not a 5k one in the file I/O testing code. So when it was loaded back in - I can't check the size because it's perfectly legitimate to load into some areas - it overwrote the return stack and gave unmatched loop errors.

There is one log term bug. If I power up the ESP32 and leave it overnight it starts keyboard repeating at some point - it's after several hours. It starts typing on its own, and only a reset of the ESP32 itself fixes it. I'll code read the ESP32 interface code, but it's so simple I think it might be a fabgl bug, memory leakage maybe ?

A couple of minor tweaks to be added today ; I want to write a couple of functions to get sprite information, and add a command to kill a Sprite. Then it will be 0.61 which will hopefully be fairly stable. The token table has been changed rather a lot, which gives odd results if you load an old tokenised program in. But I reserved a group for extensions - case , input/output ports and so on, so it should now be fairly static. Being slightly pedantic I liked to keep them in order, although apart from the first 16 which are the assembler mnemonics it doesn't matter.

How to work it

As the github is actually just a live build tree, it's not obvious how to make it work. The executables are in the emulator directory ; they should work straight off (they're built on Windows 8.1 in Virtualbox) and they store their files in the storage directory.

Building requires SDL2, Python and command line Zip, and either gcc or mingw. On Windows I recommend chocolatey which does all of them and sets them up, except SDL2 which you can download (the mingw development one), extract it and put the x64 directory in C:\ renamed SDL2.

You don't need to do this to run it. It should just run. If not, let me know :)

When you run it what happens depends on what I was working on. If there's a program "autoexec.prg" in storage it auto runs this. At the time of writing it shows two overlapping rectangles in purple.

If it's running a program and doesn't seem to stop (you can tell when it's stopped by the flashing cursor) then either press Ctrl+Space to break it, or reset it while holding shift down.

Reset is Ctrl+Escape on the hardware, and F1 on the emulator. This will boot it in normal mode displaying Basic/Kernel versions and playing its startup beep, half inched from my much loved BBC Micro.

Wednesday 1 April 2020

Tile mapping working

So you can now do tilemaps from BASIC ; the picture shows a testing tilemap.

It's quite efficient, this tilemap goes at 28fps on the ESP32, and it's doing quite a lot of work on repainting the screen.

The downside is the borders ; the purple bars are covering them up :) This is because to scroll a tilemap at pixel level you have to draw it back a bit. My blitter only draws in 16x16 chunks. I could theoretically process every tile to clip it, but this would be very slow. Or I could uprate the blitter, but I really didn't want to cheat by producing something that was 2020 technology, say a hardware clip. Of course, one way to clip it is to tile the whole screen. Also, the simpler the hardware the easier it is to implement.

Also fixed a bug in the palette code which was a hangover from the original which emulate a real hardware palette. It actually now does it, but it's really slow, because hardware palettes are not a feature of the blitter driver - so changing a palette involves repainting the whole of the display. This actually is fairly quick on the ESP32 , but not enough to use palette effects in games.

No actual Retrochallenge work done today. I have one more thing I want to do, though this isn't necessary initially. The graphics is a bitplane design, and the blitter basically selectively writes bitmaps into planes. So you can say have 2 sprite planes, and 2 background planes, giving 3 sprite colours and 4 background colours (one sprite colour is for transparent), or you can have 3 sprite planes, or 1, or none at all, or no background if you really want (There is only enough memory in an ESP32 for 4 320x240 bit planes). It would be handy though to be able to draw on the sprite plane, and it isn't difficult to change the graphics routines to do this, as they all use the same routine anyway. I drew the purple bars in the picture using the BLIT command, which directly hits the blitter, whereas it would be much easier to do RECT/FRAME/ELLIPSE/CURVE/LINE etc.

Retrochallenge 2020/04

Running on ESP32
Hi. This is my entry for Retrochallenge April 2020. It isn't actually Eris itself, as you can see from the pictures, that's actually fairly advanced.

The R/C will be to implement some BASIC games on it, in a "Game a day" format. This is partly to check the BASIC interpreter works. It take pretty much everything I've thrown at it so far, but there's bound to be some small bugs in there. Day 1 is not going to have a game, probably, because the BASIC TILE command (which draws scrolling tilemaps) is the last thing on the TODO list.

So, what is Eris ? Well it was originally going to be called Pluto, but there's a SPARC machine called that, so ... Eris instead. Eris is also the God of Chaos and Discord, so that's ... saying something about the project.

It came out of a dissatisfaction with the Retro Computer projects that are out there. They either tended to be too complex or wildly expensive, or have other faults which appear to be plain idiocy. I also wanted to produce a learning tool - I plan to write some tutorial stuff to go with it.
Running on a PC

So the design is a bit of a compromise. The full description is on the github ; but in outline it's a 16 bit CPU which is 100% orthogonal and RISC like, that runs at about 1 MIPS on the reference (which is the ESP32 design) ; it has a 320x240x8 colour display, 2 square wave tone channels, 1 noise channel, uses appropriate backup storage. It has a 64k x 16 memory space, which is currently 16k ROM and 20k RAM (this is because of SRAM on the ESP32). It runs at present on the ESP32, emulation on PC/Linux and Raspbian. I haven't tried a Pi Zero because I don't have one. It's very easy to port. The ESP32 is built ontop of the fabgl library and the glue logic is straightforward.

It has a Kernel/OS ROM and a structured BASIC. Yes, it does have line numbers but these are used for editing (at the moment), it has named procedures, while loops, locals, parameters and so on. There is an inline assembler which is what's running in both pictures. Editing is like the Commodore machines, you can edit in situ.

To give some idea of speed I ran the old PCW benchmarks on it, and it came out at about 12 to 13 times faster than a C64

It's also cheap. The board you can see at the bottom of the picture is a TTGO VGA32 1.2 board (the 1.1 doesn't have sound but works fine), they're less than £10/$10 each, and apart from a keyboard and cables you don't need anything else. The Raspi Zero version will end up the same sort of cost. It runs fine on an old Raspi, and comfortably on PCs. I'll probably do an emscripten port when I figure it out.

It's not running BASIC in 'C'. The interpreter is actually written in the assembler of the machine, so it's a simple virtual machine. This has the advantage that porting the virtual machine is almost bulletproof - the CPU is so orthogonal it's comical - things you can see on the screen like jmp #loop3 skz r5 and clr r1 are actually syntactic sugar by the assembler - every instruction either has the form <operation> <reg>,<reg>,<short constant> or <operation> <reg>,<constant>. It also means an FPGA version would be fairly easy to do.

The other thing is that I'll probably write some variant of Chuck Moore's Color Forth for it. Which is great, even if he can't spell "colour".

Breaking change

We all make mistakes. One early mistake I made was copying (partly) the old thing in Microsoft BASIC where you didn't have to declare ...