ZXSimulator

Anything QL Software or Programming Related.
User avatar
bwinkel67
QL Wafer Drive
Posts: 1187
Joined: Thu Oct 03, 2019 2:09 am

Re: ZXSimulator

Post by bwinkel67 »

Another new version:
zx.zip
(34.67 KiB) Downloaded 144 times
So whenever I try out a new ZX81 BASIC program I find some small bug or idiosyncrasy. If you gave the ZX81 Vroom clone a try you might have noticed that during change of track you saw a white streak...well what I did, whenever printing out either a full black block or a quarter-, half-, or three-quarter block I would first clear the screen with a block inverted (so usually that means a full white block as circled in red in picture) but that caused this side effect, plus it was inefficient code.

I was doing this in both block and grey routines, passing in 1 or 0 for true and false and then figuring out what to plot.
before.png
Why not instead pass in the color/pattern that I need and get rid of all that conditional. Then, I never have to invert the entire screen and just plot each quater-block (or pixel as they are seen in ZX81) as white or black.
after.png
So in the end less code. Not clear if it's faster or slower since I always do 4 block calls now whereas before I may have only done at minimum 2 and at maximum 5. But in the latter case I also had to do 4 conditionals, so it depends on how slow the block call is and if doing an 8x8 block takes more time than a 4x4 block (Update: new code is faster...)

But now the flicker in the Vroom clone is gone and it behaves exactly like it does on the ZX81.

P.S. qlforum wouldn't let me insert the code this time so I had to use pictures...kept giving me this page:
403.png


User avatar
bwinkel67
QL Wafer Drive
Posts: 1187
Joined: Thu Oct 03, 2019 2:09 am

Re: ZXSimulator

Post by bwinkel67 »

Another bug fix, thanks to:
TMD2003 wrote:I call it Spectribution, and it features:
Here is the updated version:
zx.zip
(34.98 KiB) Downloaded 124 times
I tried one of Jim's programs called "Advanced Horseshoe Magnet Simulator" and not only did it crash, but it killed my heap. Turns out I had a major bug with how I was handling array substring assignments. If I tried to set a the middle of a string array (i.e. via LET A$(2)="X"), if the underlying string at location 2 was a graphic or inverted character, my code would not take care of it.

Imagine that A$ contained the inverted string "123" so it really contains:

"%1%2%3"

So setting the 3r'd character to "X" would change it to:

"%1X2%3"

It got worse if the underlying string was plain:

"123"

And you set it to an inverted string "%X" since you'd get:

"12%X"

And so it just ran beyond its memory allocation and caused a crash.


The buggy code, which was originally written for plain ASCII and not accounting for any special graphics characters, looked like this:

Code: Select all

 i=vl2_i;
 while (i<=vl3_i)
    { ìf ((ch=getchp(vl2_s,i-vl2_i))=='\0') break; setchp(val_s,i-1,ch); i++; }
I had to add over 500 bytes of compiled code to fix the problem...Ugh...not pretty:

Code: Select all

 i=0; j=1;
 while (j++<vl2_i) switch(getchp(val_s,i++)) { case '\\': i++; case '%': i++; }   /* here we skip past characters up to index  */

 j=0; vl3_i=vl3_i-vl2_i+1; vl2_i=i; g=0;
 while (vl4_i++<vl3_i) 
    { switch(getchp(val_s,i++)) { case '\\': g--; i++; case '%': g--; i++; }      /* now compute size of destination substring */
      switch(getchp(vl2_s,j++)) { case '\\': g++; j++; case '%': g++; j++; } }    /* ...and size of source substring (in g)    */
               
 memarg(&tmp_s,l+1); strcpy(tmp_s,val_s); free(val_s); memarg(&val_s,l+g+1);
 i=0; while (i<vl2_i) setchp(val_s,i,getchp(tmp_s,i++));                          /* copy characters before insertion at index */
 i+=vl3_i; while (i<=l) setchp(val_s,i+g,getchp(tmp_s,i++));                      /* copy characters after insertion at index  */

 i=0; while (i<j) setchp(val_s,vl2_i++,getchp(vl2_s,i++));
I should really have created a data structure that has each element of a string array allow for 1 to 3 characters but then I'd have to change it everywhere, so instead I wrote this complicated alignment code. It does work.


P.S. the code tag in the forum is still broken...looks like it crashes when you use an "if" in the code listing. I substituted the character "i" with the ASCII character with code 141 and that worked.


User avatar
TMD2003
Trump Card
Posts: 168
Joined: Sat Oct 10, 2020 12:18 pm

Re: ZXSimulator

Post by TMD2003 »

Crikey o'blimey!

Who'd ever have thought that a sort-of-joke program written after an actual-joke thread on World of Spectrum 16 years ago would actually be of use!

I award myself the corned beef sandwich I already ate for lunch. And I dedicate this programming Oscar to Jim Langmead, who was running the CSSCGC the year I submitted that program, and who's been dead for 13 years but I'll bet he'd have liked to know.


Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
bwinkel67
QL Wafer Drive
Posts: 1187
Joined: Thu Oct 03, 2019 2:09 am

Re: ZXSimulator

Post by bwinkel67 »

TMD2003 wrote:Who'd ever have thought that a sort-of-joke program written after an actual-joke thread on World of Spectrum 16 years ago would actually be of use!
I get excited when I find a BASIC program that doesn't use any machine code or Peeks/Pokes and that I don't have to type in and can try on my emulator...helps me debug it a bit. I still don't have DIM working for multidimensional string arrays so I did have to change your code in a few places and do the math of a single dimensional string array. But when I got a heap error I had to investigate and voila, it was a much more complicated error to fix.

Here is the slightly changed version (all reference to A$ is where it was changed). I played it briefly and in accelerated mode (about 5 times faster) it is hard to win. I'm guessing you have to hit 50 T's before the clock expires.

Code: Select all

   8 CLS
   9 PRINT AT 0,3;"ADVANCED HORSESHOE MAGNET              SIMULATOR"
  10 DIM A$(600)
  20 FOR N=1 TO 50
  30 LET X=INT (RND*20)+1
  40 LET Y=INT (RND*30)+1
  45 IF X=11 AND Y=16 THEN GOTO 30
  50 IF A$((X-1)*20+Y)="T" THEN GOTO 30
  60 LET A$((X-1)*20+Y)="T"
  70 NEXT N
  80 CLS
  90 LET X=11
 100 LET Y=16
 120 PRINT AT 0,0;"\::%T%I%M%E%:\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::%N%A%I%L%S%:\::\::\::\::"
 122 FOR N=1 TO 20
 124 PRINT AT N,0;"\::";A$((N-1)*30+1 TO (N-1)*30+30);"\::"
 126 NEXT N
 128 PRINT AT 21,0;"\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::"
 130 LET S=0
 200 FOR N=200 TO 0 STEP -1
 210 GOSUB 600
 230 PRINT AT X,Y;"U"
 240 LET I$=INKEY$ 
 250 IF I$="" THEN GOTO 300
 255 PRINT AT X,Y;" "
 260 LET X=X+(I$="A" AND X<20)-(I$="Q" AND X>1)
 270 LET Y=Y+(I$="P" AND Y<30)-(I$="O" AND Y>1)
 280 PRINT AT X,Y;"U"
 290 IF A$((X-1)*20+Y)="T" THEN GOSUB 500
 300 NEXT N
 310 PRINT AT 21,7;"%B%A%H%.%.%.\::%Y%O%U\::%F%A%I%L%E%D"
 320 STOP
 500 LET S=S+1
 510 LET A$((X-1)*20+Y)=" "
 520 LET S$=STR$ S
 530 FOR M=1 TO LEN S$
 540 LET S$(M)=CHR$ (CODE S$(M)+128)
 550 NEXT M
 560 PRINT AT 0,29;S$
 570 IF S=50 THEN GOTO 700
 590 RETURN
 600 LET N$=STR$ N
 610 FOR M=1 TO LEN N$
 620 LET N$(M)=CHR$ (CODE N$(M)+128)
 630 NEXT M
 640 LET N$=N$+"\::"
 650 PRINT AT 0,7;N$
 660 RETURN
 700 FOR N=1 TO 5
 710 PRINT AT 0,22;"NAILS: 50"
 720 PAUSE 25
 730 PRINT AT 0,22;"%N%A%I%L%S%:\::%5%0"
 740 PAUSE 25
 750 NEXT N
 760 PRINT AT 0,1;"\::\::\::\::\::%W%O%O%H%O%O%.%.%.\::%Y%O%U\::%D%I%D\::%I%T\::\::\::\::\::"
I'll probably try the other ZX81 programs on your site when I get some time as there is usually a twist on my assumptions with BASIC that gets clarified when I hit an error. I also found another site that had some cool programs by Steven Reid -- his night driver one, flywheel, also had caused an error since the AND does funky stuff when leading with a string. That one is impossible to play in accelerated mode:-/

When I'm done with it I may look into adding a delay mechanism. Presently, on an actual unexpanded QL, it runs pretty close to real-time for a TS1000 so there is no need (and that was the goal of this fun side project). When run on an emulator, or a faster machine (i.e. QL with a Gold Card, etc...) things speed up, which is good for some programs but not so much for others.


User avatar
bwinkel67
QL Wafer Drive
Posts: 1187
Joined: Thu Oct 03, 2019 2:09 am

Re: ZXSimulator

Post by bwinkel67 »

Fixed a few issues...all Jim's fault as I tried to run his Hex/Doz-idecmial Fraction Converter programs and had, after some debugging, finally figured out my indexing was completely wrong (though it worked for single dimensional arrays just fine):
  • I was computing multi-dimensional array indices for numeric arrays incorrectly...works now
  • I had a bug in my RND and PI functions where I was freeing memory from heap that was never allocated.
  • I didn't allow for 0 in destination range in substring access: i.e. "ABCD"( TO 0)
  • sped up and reduced the executable size a little
zx.zip
(35.02 KiB) Downloaded 129 times


User avatar
bwinkel67
QL Wafer Drive
Posts: 1187
Joined: Thu Oct 03, 2019 2:09 am

Re: ZXSimulator

Post by bwinkel67 »

An itsy bitsy bug that I had added when I fixed AND and OR. I didn't allow for:

Code: Select all

IF I>10 AND A$<>"Q" THEN
or

Code: Select all

IF A$="C" AND I<100 THEN
So if an equality had a string in it I'd flag it as incorrect...fixed now...
zx.zip
(35.03 KiB) Downloaded 126 times
I found the bug because I finally was able to retrieve an old ZX81 BASIC chess program I typed in and got to work when I was a kid. I had to modify it a lot from the original Tim Harnell version that came from his Giant Book of Computer Games book since the ZX81 didn't have DATA statements and his game used upper/lower characters for the pieces and scrolled the board up the screen each time.
chess.png
Here is the ZX81 BASIC for Chess:
chess.zip
(3.82 KiB) Downloaded 133 times
Note that when I tried including it as a code listing, it once again caused qlforum to hit the 403 page (and perhaps crash as well). This was the problematic line (note I replaced the IF with ?? to get it to work):

Code: Select all

590 ?? (A(AX)=K OR A(AX)=P) AND RND*10>1 THEN RETURN
Also curious is that if I rearrange it and put the RND first then it doesn't crash qlforum:

Code: Select all

590 IF RND*10>1 AND (A(AX)=K OR A(AX)=P) THEN RETURN


User avatar
bwinkel67
QL Wafer Drive
Posts: 1187
Joined: Thu Oct 03, 2019 2:09 am

Re: ZXSimulator

Post by bwinkel67 »

Been a long while since I posted on my ZX81 ROM emulator. Still not complete but earlier this summer I did update it and add support for 2D string arrays. That will likely go up to 4 or 5D when I add floating point but for now 2D is pretty useful and I haven't seen much use beyond that (maybe 3D for different image scenes).

I also reduced the code size a bit so there is a net reduction, which is always good after adding a bunch of new code (a bit complex to do 2D string array subscripting in ZX81 BASIC since it's so flexible) -- it did slow down slightly but that's to be expected when adding more features that add more capabilities (we're talking about 2-3 seconds over 90 second test though that's testing that specific feature...i.e. it's not an across the board slowdown, just with subscripting).

Here is the latest version. If you take a look at it you will also note that the source (src_zip) is no longer one long file but made up of 5 since I finally figured out again how to do multi-file compiles:
zx.zip
(37.36 KiB) Downloaded 77 times
I've also been playing around with various chess programs so I updated Tim Hartnell's chess to give it a better board. It's not included in the zip since I didn't author it, but you can play it on the http://ZXSimulator.orgfree.com website.
chss.png
chss.png (10.73 KiB) Viewed 1963 times
...and here is the ZX81 BASIC chess program you can either run in ZXSimulator or convert to a .p file and laod into another ZX81 emulator or real machine.
chess.zip
(3.89 KiB) Downloaded 69 times
It was fun converting the chess program to ZX81 BASIC -- still a fun language to program in IMO.


User avatar
bwinkel67
QL Wafer Drive
Posts: 1187
Joined: Thu Oct 03, 2019 2:09 am

Re: ZXSimulator

Post by bwinkel67 »

Found a cool Star Trek game for the ZX81 (Bug-Byte version) and so I adjusted it to run on My QL ZXSimulator. It's been uploaded to the website:

http://zxsimulator.orgfree.com/

To run just type LOAD "WIN1_TREK_BAS" followed by RUN to try out. It's a slightly simpler version of David Ahl's Super Star Trek game from the book BASIC Computer Games that one of the two on the QL is a direct conversion of. I did try the other, more sophisticated QL version and it looks like it adds a few more features, though is based of the same game engine that all of them seem to be.

This ZX81 version (Bug-Byte) plays well, esp on the ZXSimulator. It comes with pretty easy to understand instructions and its game-play is pretty intuitive (i.e. moving north is direction 0, north east at 1, east at 2, etc...some others have very weird directional systems that were hard to remember). I tried a whole bunch of the other ZX81-based ones and was disappointed in them, even the all-machine code versions that had some cool graphics. I was surprised by how well the Bug-Byte one played and it was mostly written in BASIC (one set PEEK/POKE). The only thing that's missing is the galactic map feature, where it remembers where you've been beyond the 8 quadrants around you...I may add that in eventually to make it more complete.

Here's a screen shot:
trek.png
trek.png (9.87 KiB) Viewed 1166 times
I did have to do a few mods since my emulator is still not complete and doesn't yet support floating point operations...I haven't worked on it since last July but may look at it again this summer. So I had to make a few minor revisions to the BASIC code of the Star Trek game, some simpler than others, but they all perform as the original game did (ran it first on my actual ZX81 before trying it on the ZXSimulator).

The most interesting was having to approximate the square-root. The original call for firing phasers and figuring out how much damage the enemy sustained was this:

Code: Select all

7995 REM **CAL. KLINGON DIST.**
8000 LET Z=A-G(I)
8010 LET Y=B-H(I)
8020 LET D=INT SQR (Z*Z+Y*Y)
8030 RETURN
The approximation code was this:

Code: Select all

7995 REM **CAL. KLINGON DIST.**
8000 LET Z=A-G(I)
8010 LET Y=B-H(I)
8020 LET D=INT (Z*Z+Y*Y)
8022 LET J=Z*(Z>=Y)+Y*(Z<Y)
8024 LET J=J+1
8026 IF J*J<=D THEN GOTO 8024
8028 LET D=J-1
8030 RETURN
...a lot of work to do a simple math function. I really need to implement floating point in ZXSimulator as it would make life so much easier.
Last edited by bwinkel67 on Sat Jul 09, 2022 12:55 pm, edited 4 times in total.


User avatar
bwinkel67
QL Wafer Drive
Posts: 1187
Joined: Thu Oct 03, 2019 2:09 am

Re: ZXSimulator

Post by bwinkel67 »

This zip contains the original Bug-Byte version (StarTrek-orig.p) as well as my modified version (both StarTrek.p and StarTrek_bas).
StarTrek.zip
(13.66 KiB) Downloaded 40 times


User avatar
Chr$
QL Wafer Drive
Posts: 1304
Joined: Mon May 27, 2019 10:03 am
Location: Sachsen, Germany
Contact:

Re: ZXSimulator

Post by Chr$ »

Talking of Startrek clones on the ZX81, many years ago a chap called Kilian Schlaich made a version that was retailed by ISS in Germany. I found a copy in 2019 and was able to digitise it, then track down Mr Schlaich. He gave me permission to share it freely and because the cassette contained no instructions (I don't know if it ever did) he wrote some for me, 38 years later.

Here it as as a zipped .p file, with text file instructions (all in German).
20190905_140618_resizedm.jpg
Attachments
Enterprise Schlaich 1982 DE.zip
(6.79 KiB) Downloaded 35 times


https://QXL.WIN
Collector of QL related computers, accessories and QL games/software.
Ask me about felt pads - I can cut them to size and they have proved excellent for mdv data recovery.
Post Reply