Using MCoder2 in EightyOne

Anything Sinclair ZX Basic related; history, development, tips - differences between BASIC on the ZX80 and ZX81
bwinkel67
Posts: 150
Joined: Mon Mar 23, 2020 2:38 am

Re: Using MCoder2 in EightyOne

Post by bwinkel67 »

Fruitcake wrote: Tue Mar 15, 2022 2:23 pm I've reproduced the issue you were seeing and so understand where the confusion is coming from.
Thank you for the detailed description, I cannot wait to give that a go as it will make the game a bit better. I used the feature to save .b81 code constantly in my technique, plus cutting and pasting REM statements, so I'm very familiar with how to do that...I had to discover that feature in EightyOne since zxtext2p.exe couldn't handle the long REM's that p2text.exe gave -- I am used to using those tools with the ZXSimulator and in fact, it won't be able to read .b81 output with it's \?? format since I didn't implement it.

I do have an Elite.bas version that has fixed MCODER2's idiosyncrasies. The Elite.p that is included in the zip is the original version that I developed as a demo BASIC for the ZXSimulator (to make sure it behaved like a ZX81) and it uses OR's, STOP, and inequalities in assignments, etc... all things that won't work in MCODER2.
Fruitcake wrote: Tue Mar 15, 2022 2:23 pm When I used MCODER2 back in the 80s I only had 16K RAM and so also struggled to get a good sized BASIC program to compile in one hit. Trying to split it into chunks was painful and so I never really pursued this, so it's interesting to read you've been having success using that approach. Good work! It's nice to see these original utilities still being used.
First off, my experience with MCODER2 really left me impressed, esp with it only being about 5K in size. I recently played around with SuperCharge on the QL and that also worked pretty well, but is much larger in size. Both have a similar approach with SuperCharge using the QL's screen memory to stick the compiled code and MCODER2 using REM statements. Back in the 80's I wrote an assembler (still need to get it successfully off a tape) that had to generate a REM statement and size it to put the assembled code into, so I kind of know how MCODER2 is generating those new "2 REM" statements after the first pass to store its compiled code into.

The way I ended up constructing my compiled version of Elite was definitely an interesting approach that forced me to think about how my game was developed. I can imagine if I were to write it from scratch in machine code, I may actually divide it up that way but with BASIC, you can just be a bit lazy where you place things and when you call things.

However, the steps you laid out to get it to work in 32K+ memory are also pretty neat. I love discovering those approaches to get around system limitations. I had planned to do a video on my process and now I'll fold in both processes since it might be useful to see both ways -- well, my way really only for those that want to see how it would have been done back in the days if you only had 16K. I'm imagining lots of pen to paper, and having to save each iteration, load it back in, and type in new code... I'll be sure to reference your help for the second approach...much appreciated.
bwinkel67
Posts: 150
Joined: Mon Mar 23, 2020 2:38 am

Re: Using MCoder2 in EightyOne

Post by bwinkel67 »

bwinkel67 wrote: Tue Mar 15, 2022 2:53 am Here it is...starting to play pretty well. Again, EliteMC.p is the machine code version compiled with MCODER2 and Elite.p is the original BASIC version that has a few more features.


Elite.zip
I actually played it on a real TS1000 and the speed is perfect. It currently has good game play making it winnable.

Edit: yes, I know that I'm quoting myself...it feels a bit weird :shock:
bwinkel67
Posts: 150
Joined: Mon Mar 23, 2020 2:38 am

Re: Using MCoder2 in EightyOne

Post by bwinkel67 »

Fruitcake wrote: Tue Mar 15, 2022 2:23 pm To get MCODER2 working with more than 16K RAM, do the following:
- In EightyOne set the RAM to 48K RAM
- LOAD MCODER2
- Using EightyOne's BASIC Listing window, save out as MCODER2.B81
- Reset the ZX81
- LOAD in your BASIC program
- Using EightyOne's BASIC Listing window, save out your program, e.g. YOURPROGRAM.B81
- Using a text editor on your PC, copy the contents MCODER2.B81 and paste it at the start of YOURPROGRAM.B81
- Save the updated YOURPROGRAM.B81 file
- Reset the ZX81
- Type POKE 16389,255
- Type POKE 16388,255
- Type NEW
- Load in YOURPROGRAM.B81 file, e.g. drag/drop into EightyOne or the Tape Manager, etc
- You now have a ZX81 with 48K and your BASIC program with MCODER2 loaded in
- Type RAND USR 17300 to compile

This did the trick. Got my game fully compiled now. Had to make some code tweaks because keyboard input was too fast. Turns out I also had a bug in my original. In any case, here it is in all its glory. Still missing planet hopping but now at least I know i can add it and compile it. The compiled code is about 10.5K so I have room to add to it. It can now assign keys and will give a score at the end.

Again, I'm including the original (with fixed bugs) and the compiled. Note that the original cannot be compiled as is since it contains OR, STOP, and uses inequalities in assignments. Plus it expects RND to give a value between 0 and 1 not 0 and 32767. This plays a bit fast on EightyOne but on a real TS1000/ZX81 it has a nice feel to it.

Elite.zip
(9.07 KiB) Downloaded 107 times

Note: Something else I learned. When compiling in 16K (maybe on an actual machine) if you load MCODER2, then load your program, then attach it, via LET L=USR 32462...if it attaches (sometimes it doesn't if the BASIC program takes up too much RAM) then save it and re-load it, you can compile larger files. MCODER2 seems to take up more memory on initial load, but once attached, it can handle slightly larger programs -- bigger than that 4100 byte limit but not sure how much bigger though I kept trying to find its limit and was unable to. Obviously not necessary to do on an emulator which can easily add extra memory, but if anyone is interested in how much it could compile on your trusty ZX81 with 16K RAM pack, this is a way to squeeze more out of it.
Fruitcake
Posts: 351
Joined: Wed Sep 01, 2010 10:53 pm

Re: Using MCoder2 in EightyOne

Post by Fruitcake »

bwinkel67 wrote: Thu Mar 17, 2022 7:47 am This did the trick.
Glad it helped! :)

bwinkel67 wrote: Thu Mar 17, 2022 7:47 am This plays a bit fast on EightyOne but on a real TS1000/ZX81 it has a nice feel to it.
Are you taking into account that a TS1000 / ZX81 configured to run at 60Hz will inherently run slower than one configured for 50Hz operation? There is a setting in EO to select between 50Hz and 60Hz operation. You might wish to PEEK system variable MARGIN to determine whether 50Hz or 60Hz and introduce a delay if running at 50Hz.
bwinkel67
Posts: 150
Joined: Mon Mar 23, 2020 2:38 am

Re: Using MCoder2 in EightyOne

Post by bwinkel67 »

Fruitcake wrote: Thu Mar 17, 2022 1:44 pm Are you taking into account that a TS1000 / ZX81 configured to run at 60Hz will inherently run slower than one configured for 50Hz operation? There is a setting in EO to select between 50Hz and 60Hz operation. You might wish to PEEK system variable MARGIN to determine whether 50Hz or 60Hz and introduce a delay if running at 50Hz.
That's part of it, but also that EightyOne runs about 15% faster than stock, so that combined with the 50Hz machines running faster speeds things up. I think on a real 50Hz ZX81 it might be ok too, albeit a tad faster. It's playable on EightyOne in 50Hz mode, just a bit more challenging.

The mods I made to keyboard input has helped so now, you have to lift your finger off a key and put it back in order to have it repeat the same key, so you no longer have direction constantly going into neutral and back eating up your fuel. Plus, it's easier now going into neutral so you can keep the enemy within the target.
Fruitcake
Posts: 351
Joined: Wed Sep 01, 2010 10:53 pm

Re: Using MCoder2 in EightyOne

Post by Fruitcake »

bwinkel67 wrote: Thu Mar 17, 2022 11:25 pm EightyOne runs about 15% faster than stock
What version of EightyOne are you running?
bwinkel67
Posts: 150
Joined: Mon Mar 23, 2020 2:38 am

Re: Using MCoder2 in EightyOne

Post by bwinkel67 »

Fruitcake wrote: Thu Mar 17, 2022 11:30 pm What version of EightyOne are you running?
I was running 1.16 and just moved to 1.26.

I got that number from the wiki...

https://emulation.gametechwiki.com/inde ... iveSpeed-1

Edit: it does look like 1.26 in TS1000 mode is about 10% slower than 1.16 so perhaps it is close to real-time. I think I did notice that even compiled, my Elite game became more playable so maybe I was initially running it in 1.16 and then switched to 1.26 before realizing the speed had changed.
bwinkel67
Posts: 150
Joined: Mon Mar 23, 2020 2:38 am

Re: Using MCoder2 in EightyOne

Post by bwinkel67 »

Fruitcake wrote: Thu Mar 17, 2022 1:44 pm Are you taking into account that a TS1000 / ZX81 configured to run at 60Hz will inherently run slower than one configured for 50Hz operation?
So having used the older version of EightyOne -- I only upgraded to v2.26 this weekend -- and comparing that to my actual TS1000, I kept thinking that EightyOne seemed to run almost twice as fast. Part of the issue was my ignorance to the fact that, as pointed out above, that the ZX81 mode runs differently from TS1000 mode (I never knew my US ZX81/TS1000 was slower :( )

I don't presently have my TS1000 handy but did this brief test, running my ZXSimulator banner program, with surprising results (change to .b81 for v1.16):

banner.bas
(1.02 KiB) Downloaded 106 times
  • v1.16 in ZX81 mode running "1-square" pattern through regular and inverse in 51 seconds
  • v1.26 in TS1000 mode running "1-square" pattern through regular and inverse in 1:38 seconds
With v1.26 in ZX81 mode the same run takes 1:04 seconds...but it was the comparison between v1.16 and my TS1000 that got me confused. Looks like you spent time working on getting it closer to real-time.
Fruitcake
Posts: 351
Joined: Wed Sep 01, 2010 10:53 pm

Re: Using MCoder2 in EightyOne

Post by Fruitcake »

bwinkel67 wrote: Fri Mar 18, 2022 2:44 am I never knew my US ZX81/TS1000 was slower :( )
Afraid so. A user's program is run whilst the top and border lines are being rendered. Running at 60Hz, there are 48 fewer border lines. Hence a lower percentage of the time is spent running the user's program compared to outputting the main picture area.

bwinkel67 wrote: Fri Mar 18, 2022 2:44 am Looks like you spent time working on getting it closer to real-time.
EightyOne never accurately emulated the ZX81's display hardware, resulting in the faster speed you observed. Improvements were made in v1.18 to try and compensate for this, bringing it down to 1-2%, so the emulation is still not 100% accurate but it would require quite a bit of reworking to obtain this.
bwinkel67
Posts: 150
Joined: Mon Mar 23, 2020 2:38 am

Re: Using MCoder2 in EightyOne

Post by bwinkel67 »

One more question. Looking at each compiled line, MCCODER2 does the following (in hex):

Code: Select all

2 REM \76\76\21...
So it seems to do two consecutive HALTs before doing a LD. The pointer to the entry of the compiled routine is the LD (let's assume 20500 since that's for the first compiled module). If you do LET L=USR 20499 or LET L=USR 20498, both still cause the program to run as normal. What does the ZX81 do when it sees a HALT instruction?
Post Reply