Tuesday 25 September 2018

Working .... ish

Running on Zesarux ; just typed 42 1 + .
The current version is working in that you can type (in yellow) 42 10 * . and it will print out 420, define basic words and so on. However, a few things are missing, no title text, if you make a mistake it dies completely, and it doesn't reset compilation stuff if you don't compile a red word.

But it does work :)

L8R: Also seems to work fine on the latest Zesarux (a beta 7.1). This is fiddlier to get going, copy the zrun.bat file, and the boot.img and bootloader.sna files into the zesarux directory , change to it, and run zrun.bat and it should start without the setup the zesarux defaults to.

Editor up and running

Virtually all the code I wrote before worked straight off ; the main thing was changing the dictionary selector word from mwords to words.

So the new version is now useable. It can be downloaded from here https://github.com/paulscottrobson/mnext/tree/master/release

It runs on cspect.exe (it might run on Zesarux, I just haven't tried it yet !) ; to make it run start the emulator with the -zxnext and load the .sna file in using F2. It should briefly display booting (at this point it is compiling the bootstrap code) and then display an editable area.

You can run it with the SNA file as a parameter to cspect.exe but if you do this boot.img has to be in the same directory.

This contains two files ; a .sna file "bootloader.sna". It loads the file boot.img into $8000-$BFFF and pages 32..95 of $C000-$FFFF ; it has no other purpose (except it can save it as well :))

I also did some speed testing of the cross page calling mechanism. I put two nested loops, one of 64 and one of 50000, so about 3.2 million in total and ran it first calling a routine on the same page, and then calling it on a different page ; all the code was fudged into the page area $C000-$FFFF and to different pages.

So without page switching it took 19s ; with it, it took 1'03s ; which I'm quite pleased with, I though it it would be much much slower.

This is running at 14Mhz, of course.

And another version

I've actually rewritten it all, again. I like the bootstrapping version, but not the way it's implemented. So I've rewritten the kernel (a few core functions and the compiler) but for the Next not the Spectrum ; it now won't run on a Spectrum, except maybe a Spectrum 128.

This gives vastly more space to work with. I'm using 16k paging, largely with the 128 in mind, so it pages 16k chunks in and out at $C000-$FFFF. Two 16k pages are dedicated to the now physically seperate dictionaries, and cross page calling is now working.

This is okay, except that it's much slower, because it has to switch pages then switch to the routine and then switch back again. It's best really to write in modules that perform specific tasks - which is what you do anyway, rather than having monolithic code bases and relying on the compiler (which figures out when it does CALL and when it page swaps).

But you should do this anyway.

Otherwise it's the same, except the C register is now IX not BC (I wanted BC for the cross page calling mechanism), so the code tried to date just pings into place. It's actually pretty easy to bootstrap this system, even by FORTH standards.

Not quite done, not coded 'variable' yet (it would be possible to do this in M and it would work fine but its cleaner just to code it seperately) and a few other bits and pieces, but then the other modules I wrote should just ping into place. Hopefully :)

It now has a seperate home at https://github.com/paulscottrobson/mnext

Wednesday 19 September 2018

Something that works

I've written the editor now, which means that something can be downloaded that actually works, rather than just displays things.

I've only tried it on Fuse and CSpect emulators, but it should run on anything.

So, you want this file https://github.com/paulscottrobson/m8/blob/master/system/test.sna which is the test.sna file in the master system directory in the github.

If you download this file which is a standard 48k Spectrum SNA file and run it it should display a screen of what looks like random data but is actually part of the boot code for the system (with all the comments removed !). It will flash for a few seconds a bit like the tape loading but more erratically (this is compiling the boot code) and the the screen will clear and display something like this, which is part of the boot code dumped into the edit buffer so there's something to edit.

(You don't have to do this boot compile every time, you can just save it as a .SNA file)

Shift and keys 1-4 recolours words (sadly not the colours shown on the Speccy Keyboard ....) , 5 6 7 8 move the cursor about, 0 backspaces, the shift keys roughly do the same thing (I use 6 bit ASCII with lower case text, so you can't do capitals), Enter does a CR, and shift and Enter exits (it displays the debug information on the bottom line).

It's useable at 3.5Mhz though the screen displaying is a little bit sluggish, not unsurprisingly, but it works fine. In a Next, running at 7 or 14 Mhz, it's much zippier.

To get a working system there isn't that much left to actually do, though there is plenty of stuff to add.

Sunday 16 September 2018

Catching up

for next and i macro definitions
The current M8 has nearly caught up with the old version of M8. It's acquired structures, the code on the right is for for ... i .... next. Like ColorForth you can't nest them, so break up your code :)

Most of the standard vocabulary is there now (all ?) so I can compile some of the libraries I wrote previously, the Console I/O and memory dumper ran straight off. 

"M" is now fairly standardised.

By FORTH standards it's quite rapid ; for example for 10000 for next it compiles the following (you can probably see the pattern in the for and next words defined in the picture). It keeps the loop value on the top of the stack and also puts it in A at the start of every loop (this is an optimisation that became a language feature, fun when you write your own language ....)

 ex de,hl
 ld hl,10000
loop:
 dec hl
 push hl
 pop hl
 ld a,h
 or l
 jr nz,loop

which isn't amazingly efficient by pure Z80 stanrds, but isn't bad. As far as I can see once you get used to the slight oddities, it's much quicker than writing Z80 assembler and it's quicker than Z80 FORTHs, even the multitasking one which works in Z80 code.

So next up, the editor. It would probably port straight off, but I've decided to rewrite it. The major change to the language involves the use of register known as 'C' (actually Z80 BC register) (A is HL and B is DE), which is used as a temporary register, which should hopefully cut a lot of the pushing and pulling of stack values the original had.

Once the editor is working it's a short step to it working interactively.

The variables thing is quite like Color FORTHs but takes it a stage further ; declaring variable FRED creates three words FRED& (get address) FRED@ (get value) FRED! (store) which cuts out a lot of stack work and the work is handled by the compiler. I really wanted this because I thought limiting the 'stack' - e.g. workspace to 2 (now 3) registers would mean an explosion of variables. The odd thing is it hasn't ; you could make a pretty good case that the variables actually are cleaner code that faffing around trying to remember what is where on FORTHs stack, do I do OVER ROT or something, which always annoyed me.

Saturday 15 September 2018

Time for an update ....

Well , it is. Partly because I have been away for a few days, mind.

Anyway, while I was away I decided to redesign the whole thing backwards to fit a more ColorForth style design. So what I have now is a 'kernel' Spectrum .SNA file, which contains the (simple) compiler and a bit of support stuff.

So the way it works now ; the boot code, which is written in a textified Color Forth, is converted to the 8 bit characters I use - 6 bit ASCII plus 2 colour bits, and stored in the screen space. The compiler then compiles it or executes it from there (at the same time outputting the source in ColorForth format).

This is very much like Chuck Moore's ColorForth source, in style ; except rather than use constants I've bodged a five minute assembler into it. The two pictures are roughly the same bit of code - I couldn't find a decent colouring editor.

While I was away I was having difficulty sleeping, so I read the Spectrum Next's technical documents to try to get some shut-eye. This worked quite well, but not before I noticed that in the Low-Resolution (128x96x256 colours) mode the Next uses memory from 6000-7FFF as well as the usual screen RAM area. So additionally I've made it a bit more flexible in that it can be build anywhere.

I plan to page the top 16k ala Spectrum 128 to extend memory, but the 16k between there has to host the dictionary and common code ; otherwise it will go mad with task switching.

I'm also back on Arch Linux, fortunately for my sanity.

Wednesday 5 September 2018

Plodding along

Didn't do a lot yesterday. Decided to make that change to (effectively) lose the requirement for the coded swap - so you can now code 4 1 + rather than 4 , 1 + and changed most of the code.

Also completed the editor and the debug loader (this bit of code loads coloured text in easily for debugging purposes).

I wrote some code to parse out words and search the dictionary for them. In the end I decided to write it in Z80 assembler. Not because the benefits of M8 coding aren't there ; it's definitely simpler, but I wanted things to go as fast as possible on the "interactive recompile".

Monday 3 September 2018

To Swap or not to Swap that is the question.....

On changing a language which already has code written for it

Having written a few bits of code in M8, I'm beginning to wonder if I've made a mistake.  I've written a Console I/O module, a Text-loading module for debugging to easily load in Color text* and most of a colourising screen editor.

I originally changed the language design so that the "stack pushing" so to speak was manual ; so to calculate 2 + 3 you would do 2 , 3 +

I think perhaps for readability the old system worked better. This was based around the concept of a loader ; constants, load variables and load addresses (and nothing else) all did a A<->B swap prior to loading their value into A.

So 4, rather than being simply ld hl,4 , was ex de,hl ; ld hl,4.  This had a slight problem in that there was a tendency to produce too many ex de,hl instructions, but it did actually make the code look clearer. Current code seems to be full of commas and you can't really read it.

M8 , especially with this, really does look like FORTH. The only time it matters is when you get loops where you are manhandling two values, and you need to track what is in A and what is in B.

But even then, this is much simpler than remembering what is where on the stack.

Colouring

One thing I didn't mention ; this system has two compilers. The first is a cross compiler in Python, which already exists, which generates code from ASCII text that looks like FORTH : increment 1 + ; ; the other is an interactive one that will run on the actual target uses the color format increment 1 + ;

The interactive one is extensible in the way FORTH is, in that you can add new loops and so on ; to do this in the Python one you have to write them in Python

Platform

I can finally switch back to Linux :) Zesarux has now reached a stage where it is useable as a development target viz you can run Spectrum SNA files from the command line without going through 27 button presses each time.

The windows only CSpect emulator (these are the only two working Spectrum Next emulators) sort of works under Wine (the cursor keys don't seem to work ....) but it is the only one with a decent debugger.

Sunday 2 September 2018

A little bit of M8

So, some actual code from the console library I wrote yesterday.

: con.print.digit private
    , 15 and , 10 >= if 7 + swap then 48 + con.emit    
;


What this bit of code does is to take the value passed in A and print out 0-9a-f based on the lower 4 bits of A.

, 15 and

, is a bit like Enter in RPN, it swaps A and B. This puts A into B, 15 into A and then ands B into A.

, 10 >=

is very similar, it puts the anded value into B, and 10 into A. >= sets A to -1 if B >= A and 0 otherwise. This is deliberately the wrong way round so it is FORTH like, so to calculate 3 - 2 you do 3 , 2 - (M7 allowed you to just write 3 2 - which made it even more Forth like but it was a bit inefficient)

if  7 + swap then

If tests the current value of A, so if true (e.g. >= 10) then it puts 7 in A, adds B into A and puts the result back in B - 7 is the offset to display hex in ASCII correctly.

Note that neither >= or if is destructive of the value in B.

48 + con emit 

The value is still in B, possibly modified by the previous instructions. 48 is put into A, B is added into A, giving the ASCII value in A, which is then printed using con.emit

;

Compiles ret.

It looks a bit horrible but it works quite well once  you are used to it. Rather than remembering what's on the stack, you have to remember what is in A and B (and sometimes, the top of the return stack, which is used as an interim store). 

When I first wrote an early version I thought this would lead to an explosion in variables (replacing stack based elements) but this doesn't seem to have happened.

It gains its efficiency from not having a data stack which is changed all the time , even when you aren't really doing anything. The call stack stays as the call stack.  Nothing changes unless you ask it to, so you can use all kinds of operations on A and B just stays as it is, as in this example.

Saturday 1 September 2018

Retrochallenge September 2018

This is my blog for Retrochallenge for September 2018. I plan to develop and implement code for my M8 language.

M8 is a language I devised with this machine in mind, the Spectrum Next, though it should be convertible to any Z80 based machine or indeed pretty much any 8 or 16 bit machine.

It is neither a high level language, or a low level one ; it belongs in the middle somewhere. It's closest ancestors are Forth and Colour Forth, and it does look very much like Forth ; but it's much closer to the Z80 hardware than Forth is.

It has a github at https://github.com/paulscottrobson/m8 ; which already contains a runtime and a simple cross compiler.

This was partly done yesterday (tut tut....) but mainly exists because a fair chunk of the code base has been borrowed from its predecessor, unsurprisngly called M7.