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 »

pjw wrote:Read the file header into a buffer with trap #3, d0 = $47. You only need to load the first 14 bytes (16 for DDL2). If you use the SuperBASIC buffer then precede the trap #3 with a trap #4 to make it a6 relative. The file length is the first item in the buffer. It includes the 64 byte header length so youll need to subtract this for the net file length. Check out the Technical guide for the exact details.
Oh good. I will take a look at it. I actually cut file reading by almost in half (from 2 1/4 minutes to about 1 1/4 for a 13K file) by using fseek to more efficiently look for the end of file...

From this:

Code: Select all

   size = BLKLEN;
   while (fgetc(fp) != EOF) size++;
   fseek(fp, 0L, 0);
To this:

Code: Select all

   size = BLKLEN;
   while (fseek(fp, size, 0) == 0) size+=BLKLEN;
   fseek(fp, 0L, 0);
On a BBQL it seems to only add about 10% to the overall file read.

Here is the latest with that change:
zx.zip
(33.15 KiB) Downloaded 169 times


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

Re: ZXSimulator

Post by bwinkel67 »

Latest version:
zx.zip
(33.67 KiB) Downloaded 145 times
This one speeds up GOTO and GOSUB as I no longer do a linear search. This speeds things up nicely for longer listings that jump around a lot. Minesweeper runs a minute or two faster for long clear-outs on a BBQL.

Code: Select all


   while ((ch=str[sp]) != EOP)
   {
      sp++;
      if (ch == EOL)
         if (linenum(&lnum) == NOERR)
         {
            if (num < lnum)
               return NOVAL;
            else if (num == lnum)
               return NOERR;
         }
   }
changed to a binary search:

Code: Select all

   while (beg < end)
   {
      sp = (beg + end) >> 1;   /* divide by 2 */

      getline (sp, &bp, &ep); sp=bp;

      if (linenum(&lnum) != NOERR)
         break;

      if (num == lnum)
         return NOERR;

      if (num < lnum)
         end = bp-1;
      else 
      {
         beg = ep+1;
         sp = beg;
      }
   }
I also updated the Battleship game. It is now fully joystick playable (besides direction, use down for vertical and right for horizontal) and added a "battle" mode where, whenever you sink a ship, you get an extra turn. Makes the game more fun.


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

Re: ZXSimulator

Post by bwinkel67 »

Small memory issue fix. I wasn't always catching NULL returned pointer when loading in file which caused an intenral ZXSimulator "SYSTEM ERROR" that you couldn't recover from. If you get a "BAD HEAP QUERY" error, those you can recover from (note I changed that message form the former "MAX HEAP SPACE" since it is more descriptive).
zx.zip
(33.67 KiB) Downloaded 145 times


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

Re: ZXSimulator

Post by bwinkel67 »

For those QL'ers who love games, besides the two already included int the ZXSimulator distribution above: Elite_bas and Battleship_bas, here's an updated version of Minesweeper, which now shows mines faster when you accidentally hit one...in the past it took a long time. Note, this only runs on ZXSimulator (or ZX81/TS1000 equivalent) and is pretty playable on BBQL (aside from a bit of a wait for setup or large clear-outs).

BTW, I need to add a README file in my distribution but you load programs via the LOAD command with file name in quotes and break a running program via Ctl-S.

Example of loading: LOAD "MDV2_MINESWEEPER_BAS"

Code: Select all

10 REM  MINESWEEPER
20 REM  (C)1999 BODO WENZEL
30 REM  SPEED UP AND I/O BY MIKE JONAS
100 REM  START
110 GOSUB 500
120 PRINT AT 0,26;T
130 LET T=T+1
140 PRINT AT Y,X-1;"\::"
150 LET KEY=CODE INKEY$
160 PRINT AT Y,X-1;F$(F(21*(X-1)+Y)+1);
170 IF KEY=0 THEN GOTO 140 
180 IF KEY=LEFT AND X>1 THEN LET X=X-1
190 IF KEY=RIGHT AND X<32 THEN LET X=X+1
200 IF KEY=DOWN AND Y<21 THEN LET Y=Y+1
210 IF KEY=UP AND Y>1 THEN LET Y=Y-1
220 IF KEY<>MODE THEN GOTO 120
230 PRINT AT Y,X-1;"%O"
240 LET KEY=CODE INKEY$
250 PRINT AT Y,X-1;F$(F(21*(X-1)+Y)+1);
260 IF KEY=0 THEN GOTO 230 
270 IF KEY=UP OR KEY=DOWN THEN GOSUB 5000
280 IF KEY=LEFT OR KEY=RIGHT THEN GOSUB 6000
290 IF BM=1 THEN GOTO 7700
300 IF N<>0 THEN GOTO 120
310 FOR I=1 TO 32
320 FOR J=1 TO 21
330 LET E=21*(I-1)+J
340 LET K= F(E)
350 IF K>=10 AND K<=19 THEN GOTO 120
360 IF K>=30 THEN GOTO 120
370 NEXT J
380 NEXT I
400 REM  READY
410 LET K$="READY "
420 GOTO 7500
500 REM  SETUP KEYS AND DATA
510 DIM F(672)
520 CLS 
530 PRINT AT 0,10;"%M%I%N%E%S%W%E%E%P%E%R"
540 PRINT AT 5,7;"MOVE W/CURSOR KEYS"
550 PRINT AT 7,7;"SPACE TO CHANGE MODE"
560 PRINT AT 9,7;"  MARK - LEFT/RIGHT"
570 PRINT AT 11,7;"  OPEN - UP/DOWN"
580 PRINT AT 13,7;"HIT %R%E%T%U%R%N TO START"
590 INPUT A
600 PRINT AT 21,7;"PLEASE WAIT...";
610 LET BM=0
620 GOSUB 1100
630 PRINT AT 0,0;N
640 LET F$=" 12345678%*\##\##\##\##\##\##\##\##\##\##%#%#%#%#%#%#%#%#%#%#%?%?%?%?%?%?%?%?%?%?%?"
650 LET LEFT=192
660 LET RIGHT=200
670 LET UP=208
680 LET DOWN=216
690 LET MODE=252
700 LET X=1
710 LET Y=1
720 LET T=0
730 RETURN
1100 REM  PREPARE FIELD,SET BOMBS
1110 DIM B(70)
1120 PRINT AT 13,7;"PCT BOMBS SET:     "
1130 FOR N=1 TO 70
1140 PRINT AT 13,22;INT (N*10/7);
1150 LET X=INT (RND*32)
1160 LET Y=INT (RND*21)
1170 LET E=21*(X)+Y+1
1180 IF F(E)=9 THEN GOTO 1150
1200 FOR I=X TO X+2
1210 FOR J=Y TO Y+2
1220 IF I<1 THEN GOTO 1270
1225 IF I>32 THEN GOTO 1270
1230 IF J<1 THEN GOTO 1260
1235 IF J>21 THEN GOTO 1260
1236 LET E=21*(I-1)+J
1240 IF F(E)=9 THEN GOTO 1260
1250 LET F(E)=F(E)+1
1260 NEXT J
1270 NEXT I
1280 LET E=21*X+Y+1
1290 LET B(N)=E
1300 LET F(E)=9
1310 NEXT N
1320 LET N=N-1
1400 PRINT AT 1,0;
1405 FOR X=1 TO 32
1410 FOR Y=1 TO 21
1415 LET E=21*(X-1)+Y
1420 LET F(E)=F(E)+10
1425 PRINT "\##";
1430 NEXT Y
1440 NEXT X
1990 RETURN 
5000 REM  OPEN FIELD
5010 IF X<1 THEN RETURN 
5015 IF X>32 THEN RETURN 
5020 IF Y<1 THEN RETURN 
5024 IF Y>21 THEN RETURN 
5025 LET E=21*(X-1)+Y
5030 IF F(E)=19 THEN GOTO 7000
5040 IF F(E)<10 THEN RETURN 
5045 IF F(E)>19 THEN RETURN 
5050 LET F(E)=F(E)-10
5060 PRINT AT Y,X-1;F$(F(E)+1);
5070 IF F(E)<>0 THEN RETURN 
5100 LET X=X-1
5110 LET Y=Y-1
5120 GOSUB 5000
5130 LET Y=Y+1
5140 GOSUB 5000
5150 LET Y=Y+1
5160 GOSUB 5000
5170 LET X=X+1
5180 GOSUB 5000
5190 LET Y=Y-1
5200 GOSUB 5000
5210 LET Y=Y-1
5220 GOSUB 5000
5230 LET X=X+1
5240 GOSUB 5000
5250 LET Y=Y+1
5260 GOSUB 5000
5270 LET Y=Y+1
5280 GOSUB 5000
5290 LET X=X-1
5300 LET Y=Y-1
5990 RETURN 
6000 REM  MARK FIELD
6005 LET E=21*(X-1)+Y
6010 LET C=F(E)
6020 IF C<10 THEN RETURN 
6030 IF C>=30 THEN GOTO 6100
6040 LET N=N+1
6050 IF C<20 THEN LET N=N-2
6060 LET F(E)=C+10
6070 PRINT AT 0,0;N;" "
6090 RETURN 
6100 LET F(E)=C-20
6190 RETURN 
7000 REM  HIT BOMB
7010 FOR N=1 TO 70
7020 LET E=B(N)
7030 LET X=INT ((E-1)/21)
7040 LET Y=E-(X*21)
7050 PRINT AT Y,X;"%*"
7060 NEXT N
7070 LET K$=" %B%O%O%M "
7080 PAUSE 50
7090 LET BM=1
7500 PRINT AT 10,11;"\:'\''\''\''\''\''\''\''\''\':"
7510 PRINT AT 11,11;"\:  ";K$;" \ :"
7520 PRINT AT 12,11;"\:.\..\..\..\..\..\..\..\..\.:"
7530 PAUSE 100
9000 CLS 
9005 CLEAR 
9010 PRINT AT 0,0;"  MINESWEEPER BY BODO WENZEL"
9015 PRINT "TRANSLATED AND MCODER BY PETER"
9020 PRINT "       HTTP://WWW.ZX81.DE"
9025 PRINT "ZXSIMULATOR KEY MAP: MIKE JONAS"
9030 PRINT 
9040 PRINT "CHOOSE %RESTART OR %QUIT"
9050 INPUT I$
9060 IF LEN I$<>1 THEN GOTO 9050
9070 IF I$="R" THEN RUN 
9080 STOP


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

Re: ZXSimulator

Post by bwinkel67 »

So I had to do some grading today for my summer class since grades are due soon. What better way to avoid that then to do some work on the ZXSimulator.

Speaking of avoiding stuff, the last big thing is to add floating point and then I'm close to being done (there are some weirndesses with how AND and OR work on the ZX81 which I need to address). Then it'll just be running more programs and finding and fixing bugs. I recorded a video on its use and how it compares to an actual ZX81, and am building a website to post all this stuff on so stay tuned for the site.

Here it is:
zx.zip
(34.21 KiB) Downloaded 143 times
The latest version has the following additions:
  • Variables are all now dynamically allocated (before it was maxed at 37)
  • Loop nesting is also dynamic now (it was maxed at 10)
  • Reduced code size by replacing all 'for' with 'while' (Digital C is more efficient with it)
  • Also removed the 'unplot' parse code and just added flag and jump (since it's basically the same as 'plot')
My testing was basically to run my four included BASIC demo programs and games (I played Battleship and Elite and both worked). It may have a few more bugs than usually since I touched a lot of code, so those hundreds, err dozens, err one maybe, that has been using it, please post if you find anything.

Also, this little program runs through 16 nestings of for loops in ZX81 BASIC to test the dynamic memory assignment for loops. It basically generates all 16 bit binary values (very slowly).

Code: Select all

100 REM FOR LOOP TEST 16 DIGITS
110 FOR I=0 TO 1
120 FOR J=0 TO 1
130 FOR K=0 TO 1
140 FOR L=0 TO 1
150 FOR M=0 TO 1
160 FOR N=0 TO 1
170 FOR O=0 TO 1
180 FOR P=0 TO 1
190 FOR Q=0 TO 1
200 FOR R=0 TO 1
210 FOR S=0 TO 1
220 FOR T=0 TO 1
230 FOR U=0 TO 1
240 FOR V=0 TO 1
250 FOR W=0 TO 1
260 FOR X=0 TO 1
270 PRINT AT 10,8;I;J;K;L;M;N;O;P;Q;R;S;T;U;V;W
280 NEXT X
290 NEXT W
300 NEXT V
310 NEXT U
320 NEXT T
330 NEXT S
340 NEXT R
350 NEXT Q
360 NEXT P
370 NEXT O
380 NEXT N
390 NEXT M
400 NEXT L
410 NEXT K
420 NEXT J
430 NEXT I
Remember, this code runs within the ZXSimulator not in SuperBASIC :P


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

Re: ZXSimulator

Post by bwinkel67 »

BTW, here is another Bodo Wenzel game for the ZX81, a German classic called "Mench Aergere Dich Nicht" (I think there is an English equivalent but don't know its name, thought it was Frustration). Part of the purpose of the ZXSimulator is to allow for more access to (albeit simple) games for any QL out there (and yes, Xtricator already gives you that for expanded machines but I wanted unexpanded ones to be able to participate as well :D )

Bodo has a website where he has some of his stuff (and I did get permission to distribute it as he was very excited people would use his software -- recall he also wrote Minesweeper):

http://bodo4all.fortunecity.ws

I grew up in Germany and used to play that board game as a kid. I believe the computer is player A and you can be either player B, B & C, or B & C & D (I guess if you are bored or want to improve your chances of winning). If you make an illegal move (i.e. you pick a piece that's not on the board) it just ignores it and skips your turn which I think is not actually allowed in the real game -- I still have mine from childhood so I'll have to check.

I improved the graphics a bit (really just centering the board and letting you know what the range of values are) but left the text as German and made it work with the ZXSimulator since it relied in one place on some floating point math where it was subtracting a fraction:

INT(N/4-.25)

..so I just modified it to:

INT((N*100/4-25)/100)

...which achieves the same thing in the integer world. Obviously my INT function doesn't really do anything and currently just returns the integer that is sent to it but will eventually truncate a fraction when I implement floating point.

Code: Select all

10 REM MADN
15 REM (C) 1981-87 BODO WENZEL
16 REM UPDATE: 2020 MIKE JONAS
20 CLS
22 PRINT TAB 3;"MENSCH AERGERE DICH NICHT";AT 20,0;"WIEVIELE SPIELER (1-4)?"
23 INPUT SP
24 PRINT AT 20,0;"STEHEN ZU...           "
25 DIM S(4,4)
26 DIM T(4,4)
30 REM ANFANG
40 PRINT AT 14,0
41 DIM P(4)
50 FOR J=1 TO SP
51 GOSUB 1300
52 LET P(J)=W
53 NEXT J
60 LET J=0
61 LET K=J
70 FOR I=1 TO SP
71 IF P(I)=K THEN GOTO 30
80 IF P(I)>K THEN LET J=I
81 IF P(I)>K THEN LET K=P(I)
85 FOR N=1 TO 4
86 LET S(I,N)=1
87 NEXT N
90 NEXT I
91 FOR Z=0 TO 99
92 NEXT Z
93 GOSUB 1000
95 PRINT AT 14,0
96 FOR L=1 TO SP
97 PRINT "                  "
98 NEXT L
100 REM SCHLEIFE
110 LET Z=3
120 IF S(J,1)>48 THEN GOTO 180
130 GOSUB 1200
131 FOR K=1 TO 4
132 LET PO=S(J,K)
133 IF PO>0 AND PO<40+4*J+K+16*(J=1) THEN LET Z=1
134 REM \F5\C117,0;"J=";J;" K=";K;" PO=";PO;
135 GOSUB 400
136 REM \F5" ADD=";PO;" Z=";Z;"  ";\C120,0
137 IF PO<>S(J,K) THEN GOTO 140
138 NEXT K
139 GOTO 170
140 LET Z=1
141 IF J=1 THEN GOTO 200
150 PRINT "WELCHER STEIN (1-4)?"
151 INPUT K
160 LET PO=S(J,K)
161 GOSUB 400
162 PRINT AT 21,0;"                    "
163 GOSUB 500
170 LET Z=Z-1
171 IF W=6 OR Z>0 THEN GOTO 120
180 LET J=J*(J<SP)+1
181 GOTO 100
200 REM COMP
210 PRINT "ACHTUNG"
220 FOR K=1 TO 4
221 LET PO=S(J,K)
222 LET P(K)=K
223 GOSUB 700
230 LET P(K)=P(K)-PR
231 GOSUB 400
232 GOSUB 700
240 LET P(K)=P(K)+PR
241 IF PO=S(J,K) THEN LET P(K)=-30
250 NEXT K
300 REM ZUG
310 LET K=1
311 FOR I=2 TO 4
312 IF P(I)>=P(K) THEN LET K=I
320 NEXT I
321 GOTO 160
400 REM ADD
410 IF PO<>0 THEN GOTO 430
420 LET PO=(12*J-11)*(W=6)
421 GOTO 470
430 LET PO=PO+W
431 IF J<>1 AND S(J,K)<49 AND PO>48 THEN LET PO=PO-48
440 IF PO<12*J-12+48*(J=1) THEN GOTO 470
441 REM VOR HAUS
450 IF S(J,K)<12*J-12+48*(J=1) THEN LET PO=PO-J*8+53-32*(J=1)
451 REM IN HAUS
460 IF PO>J*4+44+16*(J=1) THEN LET PO=S(J,K)
470 FOR I=1 TO 4
471 IF PO=S(J,I) AND I<>K THEN LET PO=S(J,K)
472 REM SELBSTSCHLAG
480 NEXT I
481 RETURN
500 REM KO
510 LET T(J,K)=PO
511 FOR I=1 TO SP
512 FOR K=1 TO 4
513 IF I<>J AND PO=S(I,K) THEN LET T(I,K)=0
520 NEXT K
521 NEXT I
550 REM SORT
560 FOR I=1 TO 3
561 FOR K=I TO 4
562 IF T(J,K)>=T(J,I) THEN GOTO 570
563 LET PO=T(J,I)
564 LET T(J,I)=T(J,K)
565 LET T(J,K)=PO
570 NEXT K
571 NEXT I
600 REM ENDE
610 FOR I=1 TO SP
611 FOR K=1 TO 4
612 IF T(I,K)<49 THEN RETURN
620 NEXT K
621 NEXT I
622 RUN 
700 REM PRIO
710 LET PR=0
720 FOR J=2 TO SP
721 FOR I=1 TO 4
722 IF PO=0 THEN GOTO 800
730 IF S(J,I)=0 OR S(J,I)>48 THEN GOTO 900
740 REM VERFOLGEN
741 IF PO+6<S(J,I) THEN LET PR=PR-2
750 REM UEBERRUNDEN
751 IF PO>S(J,I) THEN LET PR=PR-3
760 REM FLUECHTEN
761 IF PO<S(J,I)+7-48*(S(J,I)>42 AND PO<13) THEN LET PR=PR-6
770 REM SCHLAGEN
771 IF PO=S(J,I) THEN LET PR=PR+30
810 REM VORRAT
811 IF PO=0 AND W=6 THEN LET PR=PR-8
820 REM EIGENER START
821 IF PO<>1 AND S(1,K)=1 THEN LET PR=PR+9
830 REM INS HAUS
831 IF PO>60 THEN LET PR=PR+10
900 REM FREMDER START
901 IF PO<>J*12-11 THEN LET PR=PR+4
910 NEXT I
911 NEXT J
912 LET J=1
913 RETURN
1000 REM BILD
1005 PRINT AT 2,3;"%B%B%B%B    ()()()()%C%C    %C%C%C%C",
1010 PRINT TAB 3;"%B%B%B%B    ()  %C%H  ()    %C%C%C%C",
1015 PRINT TAB 11;"()  %C%H  ()",TAB 11;"()  %C%H  ()"
1020 PRINT TAB 3;"%B%B()()()()  %C%H  ()()()()()",TAB 3;"()";
1025 PRINT TAB 27;"()",TAB 3;"()%B%H%B%H%B%H%B%H      %D%H%D%H%D%H%D%H()",TAB 3;"()";
1030 PRINT TAB 27;"()",TAB 3;"()()()()()  %A%H  ()()()()%D%D"
1035 PRINT TAB 11;"()  %A%H  ()",TAB 11;"()  %A%H  ()",
1040 PRINT TAB 3;"%A%A%A%A    ()  %A%H  ()    %D%D%D%D",
1045 PRINT TAB 3;"%A%A%A%A    %A%A()()()()    %D%D%D%D"
1050 RETURN
1200 REM NEUES BILD
1210 FOR I=1 TO SP
1211 FOR K=1 TO 4
1212 IF S(I,K)=T(I,K) THEN GOTO 1280
1220 LET W=S(I,K)
1221 FOR N=5 TO I*4+K
1222 IF W<>0 AND W=T(INT ((N*100/4-25)/100),N-4*INT ((N*100/4-25)/100)) THEN GOTO 1261
1223 NEXT N
1224 GOSUB 1500
1230 IF W<>0 THEN GOTO 1235
1231 LET N=I
1232 GOTO 1237
1235 FOR N=1 TO 4
1236 IF W<>12*N-11 THEN GOTO 1240
1237 LET P$=CHR$ (165+N)+CHR$ (165+N)
1238 GOTO 1260
1240 NEXT N
1241 IF W<49 THEN GOTO 1250
1242 LET P$=CHR$ (165+I)+"%H"
1243 GOTO 1260
1250 LET P$="()"
1260 PRINT AT PR+2,2*PO+3;P$
1261 LET S(I,K)=T(I,K)
1262 LET W=S(I,K)
1263 GOSUB 1500
1270 PRINT AT PR+2,2*PO+3;CHR$ (37+I);K
1280 NEXT K
1281 NEXT I
1290 PRINT AT 19,0
1300 REM WUERFEL
1310 LET W=INT (RND*6)+1
1320 PRINT "SPIELER ";CHR$ (37+J);", WURF: ";W
1330 RETURN
1550 IF W<>0 THEN GOTO 1560
1551 LET PO=11*(I>2)+(K=2 OR K=4)
1552 LET PR=11*(I=1 OR I=4)+(K>2)
1553 RETURN
1560 IF W>4 THEN GOTO 1570
1561 LET PO=4
1562 LET PR=13-W
1563 RETURN
1570 IF W>8 THEN GOTO 1580
1571 LET PO=9-W
1572 LET PR=8
1573 RETURN
1580 IF W>12 THEN GOTO 1590
1581 LET PO=0
1582 LET PR=17-W
1583 RETURN
1590 IF W>16 THEN GOTO 1600
1591 LET PO=W-13
1592 LET PR=4
1593 RETURN
1600 IF W>20 THEN GOTO 1610
1601 LET PO=4
1602 LET PR=21-W
1603 RETURN
1610 IF W>24 THEN GOTO 1620
1611 LET PO=W-17
1612 LET PR=0
1613 RETURN
1620 IF W>28 THEN GOTO 1630
1621 LET PO=8
1622 LET PR=W-25
1623 RETURN
1630 IF W>32 THEN GOTO 1640
1631 LET PO=W-21
1632 LET PR=4
1633 RETURN
1640 IF W>36 THEN GOTO 1650
1641 LET PO=12
1642 LET PR=W-29
1643 RETURN
1650 IF W>40 THEN GOTO 1660
1651 LET PO=49-W
1652 LET PR=8
1653 RETURN
1660 IF W>44 THEN GOTO 1670
1661 LET PO=8
1662 LET PR=W-33
1663 RETURN
1670 IF W>48 THEN GOTO 1680
1671 LET PO=53-W
1672 LET PR=12
1673 RETURN
1680 IF W>52 THEN GOTO 1690
1681 LET PO=W-48
1682 LET PR=6
1683 RETURN
1690 IF W>56 THEN GOTO 1700
1691 LET PO=6
1692 LET PR=W-52
1693 RETURN
1700 IF W>60 THEN GOTO 1710
1701 LET PO=68-W
1702 LET PR=6
1703 RETURN
1710 LET PO=6
1711 LET PR=72-W
1712 RETURN
To run on ZXSimulator (use the one I just posted above), just save to a BASIC file (madn_bas) on QL accessible media and load from ZXSimulator via: LOAD "mdv2_madn_bas" or create .p file for a ZX81 emulator for PC like EightyOne.

P.S. If you choose 1 player you basically just get to see the computer play on its own...kind of weird but neat.


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

Re: ZXSimulator

Post by bwinkel67 »

I posted the link on another thread where I got the idea to do this. So you can now try out ZXSimulator online similar to the JtyOne Online ZX81 emulator.

Simply click on the link below and wait for it to start up and then press F2. Note that, like the movie Inception, we've got some nesting going on as we are running a ROM emulator (ZXSimulator) inside of a Sinclair QL emulator (QLAY) inside of a DOS emulator (DOSBox) within the JavaScript interpreter running in your browser. Whew, that's some nesting.

http://zxsimulator.epizy.com

You can run/play the provided ZX81 programs below or code up your own -- though it does not do keyword entries so you get to touch-type.
  • ball_bas - bouncing ball demo for ZXSimulator
  • bann_bas - banner demo for ZXSimulator (normally named banner_bas)
  • elit_bas - Elite game, playable but not complete (normally named elite_bas)
  • batt_bas - Battlship game (normally named battleship_bas)
  • mine_bas - Minesweeper game by Bodo Wenzel (normally named minesweeper_bas)
  • madn_bas - Mench Aergere Dich Nicht, famous German board game by Bodo Wenzel
  • drac_bas - Dragon fractal by Bodo Wenzel (normally named drachen_bas)


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

Re: ZXSimulator

Post by bwinkel67 »

Newest version of ZXSimulator (updated webpage as well: http://zxsimulator.epizy.com).
zx.zip
(34.53 KiB) Downloaded 130 times
Changed the following:
  • Updated AND and OR to follow ZX81 BASIC which deviates from norm (see below)
  • Further refined PRINT to fix some nuanced issues (i.e. printing empty string, for one, didn't work)
  • Found cool vinyl demo (Camouflage) that I saw on Nostalgia Nerd and got it to work (but had a bug with strings where inverse strings were ending a string too soon)
  • PAUSE now works properly in removing previous input.

Here is the Camouflage demo from 1983, which is unchanged with the exception of PAUSE 32769 since I still haven't implemented real numbers and my integer values range from 1 to 32767 and so I changed it to PAUSE 32767 (will get fixed eventually).

This was the YouTube video I learned of the vinyl demo: https://www.youtube.com/watch?v=3zJWU1IR544

Code: Select all

   1 REM "CAMOUFLAGE"
   3 PRINT AT 0,0;"FIRST,  YOU MUST PLACE YOUR COPYOF CHRIS SIEVEY,S  CAMOUFLAGE ONYOUR RECORD PLAYER.                                             THEN,   PUT THE PLAYING ARM DOWNINTO THE GROOVE TO PLAY THE SONG" 
   4 PRINT AT 8,0;"THE MOMENT YOU HEAR THE OPENING NOTE OF MUSIC..."
   5 PRINT AT 14,0;"PRESS \"ANY KEY\" (EXCEPT \"BREAK\")"
   6 PRINT AT 18,0;"...ON YOUR ZX81 AND THE PROGRAM WILL THEN RUN IN SYNCHRONIZATIONWITH THE SONG."
   7 PAUSE 32767
   8 CLS
   9 PRINT AT 16,0;" \"CAMOUFLAGE\"  BY CHRIS SIEVEY "
  10 PAUSE 415
  11 PRINT AT 16,0;"THE WORLD,S FIRST COMPUTER PROMO"
  12 PAUSE 167
  13 PRINT AT 16,0;" HISTORY IN THE MAKING - 1 C.V. "
  14 PAUSE 99
  15 PRINT AT 16,0;" READY.....STEADY.....GOTO......"
  16 PAUSE 54
  17 CLS
  18 LET A$="\:'\': \.'\'. \:. \.: \:'\': \: \ : \:'\'' \:   \.'\'. \:'\': \:'\''  \:   \:'\': \: \''\ : \: \ : \: \ : \:'\'  \:   \:'\': \: \.. \:'\'   \:.\.: \: \ : \:  \ : \:.\.: \:.\.: \:   \:.\.. \: \ : \:.\.: \:.\.."
  19 LET Q$=" "
  20 PRINT "I FIND IT HARD"
  21 FOR F=1 TO 62
  22 NEXT F
  23 PRINT "PICKING UP"
  24 FOR F=1 TO 45
  25 NEXT F
  26 PRINT "ON THE THINGS YOU DO             "
  27 FOR F=1 TO 173
  28 NEXT F
  29 PRINT "IT DOESN,T DO IT FOR ME"
  30 FOR F=1 TO 50
  31 NEXT F
  32 PRINT "BUT IT,S NO DIFFERENCE TO YOU    "
  33 FOR F=1 TO 208
  34 NEXT F
  35 PRINT "IT REALLY HURT,S ME"
  36 FOR F=1 TO 53
  37 NEXT F
  38 PRINT "IT TENDS TO CUT..." 
  39 FOR F=1 TO 55
  40 NEXT F
  41 PRINT "...AND LACERATE"
  42 FOR F=1 TO 57
  43 NEXT F
  44 PRINT "YOU,RE BREAKING ME UP WITH YOUR"
  45 FOR F=1 TO 65
  46 NEXT F
  47 PRINT AT 16,0;A$
  48 FOR F=1 TO 51
  49 NEXT F
  51 PRINT AT 20,1;"YOU KEEP PUTTING THE WALLS UP"
  52 FOR F=1 TO 82
  53 NEXT F
  54 CLS
  55 LET T$="                                \@@\@@\@@\@@ \@@\@@\@@\@@ \@@\@@\@@\@@ \@@\@@\@@\@@ \@@\@@\@@\@@ \@@\@@\@@\@@ \@@\@@\@@\@@\@@\@@ \@@\@@\@@\@@ \@@\@@\@@\@@ \@@\@@\@@\@@ \@@\@@\@@\@@ \@@\@@\@@\@@ \@@\@@                                \@@\@@ \@@\@@\@@\@@ \@@\@@\@@\@@ \@@\@@\@@\@@ \@@\@@\@@\@@ \@@\@@\@@\@@ \@@\@@\@@\@@\@@\@@ \@@\@@\@@\@@ \@@\@@\@@\@@ \@@\@@\@@\@@ \@@\@@\@@\@@ \@@\@@\@@\@@ \@@\@@\@@\@@"
  56 PRINT AT 3,0;T$;T$;T$
  57 FOR F=1 TO 48
  58 NEXT F
  59 PRINT AT 0,1;A$
  60 FOR F=1 TO 50
  61 NEXT F
  62 PRINT AT 15,3;"I  N T TRA K NG  OU  LI E        M  O     C I   Y  R   N S   "
  63 FOR F=1 TO 48
  64 NEXT F
  65 PRINT AT 18,12;"%S %R %I%G  "
  66 PRINT AT 19,12;" %T %A  %H%T"
  67 FOR F=1 TO 28
  68 NEXT F
  69 LET X$="\!!\;;\,,\':\!!\;;\::\;;\;;\::\:: \;;\!!\':\':\!!\@@\@@\@@\~~\,,\,,\!!\:'\. \: \. \;;\;;\;;\@@\::\::\!!\,,\##\:.\~~\,,\!!\':\.'\;;\@@\'.\;;\@@\'.\.'\. \,,\.:\##\;;\@@\;;\;;\.'\::\::\@@\.'\!!\;;\':\::\::\!!  \@@\.'\;;\!!\::\::\@@\@@\::\.'\':\':\::\::\::\##\;;\!!   \ '\@@\@@\@@\~~\;;\::\::\;;\,,\::\~~\:.\:'\.:\::\::\::\;;\::\::\':\':\::\::\::\::\!!\;;\;;  \..\::\::\,,\::\::\::\;;\@@\@@\;;\@@  \:'\':\,,\.'\!!\':\.:\ .\@@\;;\~~\':\##\.:\'.\:'\'.\: \' \,,\.'\:'\:.\::\@@\@@\@@\@@\~~\':\@@\!!\':\::\@@\ .\@@\@@\@@\::\;;\,,\'.\,,\::\::\::\::\::\::    \::\::\::\@@\@@\@@\!!\;;\@@\@@\':\@@\'.\@@\::  \::\::\::\.'\::\::\::\::\::    \@@\;;\::\::\;;\;;\@@\:'\':\':\::\::\::\@@\@@\@@\@@\;;\@@\@@\::\'.\::\::\::\::\::\::\;;    \@@\##\@@\##\~~\':\::\::\::\::\::\::\::\!!\!!\@@\##\@@\@@\@@\::\::\::\::\::   \@@\::   \@@\.'\!!\::\::\::\::\::\::\::\::  \ .\@@\,,\:'\;;\':\.:\::\::\;;\@@\,,\@@\,,\##\##\;; \@@\;;\@@\@@\@@\~~\::\::\::\::\@@   \@@\::\::\::\~~\':\;;\!!\::\@@\##\@@\!!\;;\!!\@@\:.\~~\;;\!!\,,\,,\:'\: \::\::\::\!!      \.'\;;\,,\':\!!\@@\@@\@@\@@\~~\##\@@\:'\##\@@\':\.'\!!\@@\'.\~~\,,\.:\::\::\' \@@   \:  \@@\@@\,,\##\@@\##\@@\~~\@@\.'\.:\:.\ .\@@\##\~~\::\::\;;\@@ \:.\::\::\::\:.\@@\~~\,,   \::\@@\##\##\':\!!\;;\':\@@\##     \,,\::\:'\!!\;;\@@\!!\::\:'\::\;;\##\@@\@@  \##\@@\@@\!!\##\~~\@@\##\@@\##\@@\::    \ '\::\::\::\::\;;\@@\##\@@\;;\##\@@\~~\@@  \'.\##\::\::\::\,,\':\@@\@@\@@\!!\@@\!!   \::\::\::\::\::\::\@@\@@\##\##\##\@@\##\,,\,,  \ .\':\::\::\::\::\::\@@\##\@@\@@\@@\@@ \ '\':\::\::\::\::\::\::\;;\@@\##\@@\.'\@@\##\@@\,,\@@\@@\':\: \~~\##\::\::\::\@@\!!\@@\##\~~  \':\::\::\::  \;;\@@\##\@@\@@\!!\@@\'.\@@\~~    \::\::\::\::\::\:'\@@\@@\,,\##\@@\##\'.\::\::\:'  \,,\@@\##\##\##\##\##\##\:'\##  \'.\::\::\::\::\::\::\::\::\::\:.\@@\'.\!!\;;\::\::\!! \!!\;;\@@\##\@@\@@\!!\@@\!!\'.\@@\.  \:'\::\::\::\::\::\::\::\::\::  \':\@@\ '\##\::\:. \'.\:'\@@\;;\!!\##\##\!!\;;\::\::\::\..\''\::\::\::\,,\!!\: \##\':\@@\:'\!!\;;\,,\!!\!!"
  71 CLS
  72 PRINT X$
  73 FOR F=1 TO 20
  74 NEXT F
  75 PRINT AT 1,5;"%NO%T\;;%TH%AT\':%YO%U\~~%SE%E\.'%T%HI%S"
  76 FOR F=1 TO 65
  77 NEXT F
  78 PRINT AT 4,4;",CAUSE IT MIRRORS ON YOU"
  79 FOR F=1 TO 90
  80 NEXT F
  81 LET M$="BUT"
  82 LET N$="%B%U%T"
  83 PRINT AT 10,14;M$;AT 10,14;N$;AT 10,14;M$;AT 10,14;N$;AT 10,14;M$;AT 10,14;N$;AT 10,14;M$;AT 10,14;N$;AT 10,14;M$;AT 10,14;N$
  85 PRINT AT 14,7;"\@@%I,M\.'%SE%EIN%G\;;%NOT%H%IN%G\'."
  86 FOR F=1 TO 75
  87 NEXT F
  88 PRINT AT 18,4;"SO PLEASE LET ME THROUGH"
  89 PAUSE 208
  91 CLS
  92 LET Z$="\@@\@@\@@\@@\::\:'\: \::%T%I%M%E\::%A%F%T%E%R\::%T%I%M%E\::\ :\':\::\@@\@@\@@\@@"
  95 PRINT Z$
  96 FOR F=1 TO 74
  97 NEXT F
  98 PRINT Z$
  99 FOR F=1 TO 74
 101 NEXT F
 102 PRINT Z$
 103 FOR F=1 TO 17
 104 NEXT F
 105 PRINT Z$
 106 FOR F=1 TO 17
 107 NEXT F
 108 PRINT Z$
 109 FOR F=1 TO 17
 110 NEXT F
 111 PRINT Z$
 112 FOR F=1 TO 17
 113 NEXT F
 114 PRINT Z$
 115 FOR F=1 TO 7
 116 NEXT F
 117 PRINT Z$
 118 FOR F=1 TO 7
 119 NEXT F
 120 PRINT Z$
 121 FOR F=1 TO 7
 122 NEXT F
 123 PRINT Z$
 124 FOR F=1 TO 7
 125 NEXT F
 126 PRINT Z$
 127 FOR F=1 TO 3
 128 NEXT F
 129 PRINT Z$
 130 FOR F=1 TO 3
 131 NEXT F
 132 PRINT Z$
 133 FOR F=1 TO 3
 134 NEXT F
 135 PRINT Z$
 136 FOR F=1 TO 3
 137 NEXT F
 138 PRINT Z$
 139 FOR F=1 TO 3
 140 NEXT F
 141 PRINT Z$;Q$;Z$;Q$;Z$;Q$;Z$
 145 CLS
 146 LET G$=" %A%A%A%A%A  %G%G%G%G%G  %A%A%A%A%A  %I  %N    %N  %A   %A  %G   %G  %A   %A  %I  %N%N   %N  %A%A%A%A%A  %G      %A%A%A%A%A  %I  %N %N  %N  %A   %A  %G  %G%G  %A   %A  %I  %N  %N %N  %A   %A  %G   %G  %A   %A  %I  %N   %N%N  %A   %A  %G%G%G%G%G  %A   %A  %I  %N    %N"
 147 PRINT AT 15,0;G$
 148 PRINT AT 13,15;"%A%N%D"
 149 PRINT AT 6,0;G$
 152 SCROLL
 153 SCROLL
 154 SCROLL
 155 SCROLL
 156 SCROLL
 157 SCROLL
 158 SCROLL
 159 SCROLL
 160 SCROLL
 161 SCROLL
 162 SCROLL
 163 SCROLL
 164 SCROLL
 165 SCROLL
 166 SCROLL
 167 SCROLL
 168 SCROLL
 169 SCROLL
 170 SCROLL
 171 SCROLL
 172 SCROLL
 175 PRINT AT 14,8;"\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@                  \@@INSTRUMENTAL\@@                  \@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@"
 178 PRINT AT 21,6;"(JUMP IF YOU WISH)"
 179 PRINT AT 5,5;"\:  \:'\''"
 180 PRINT AT 6,5;"\:  \:'\' "
 181 PRINT AT 7,5;"\: \. \:.\..\ ."
 182 PRINT AT 9,13;"                                  O                              \.'\::\'.                              %:                              \ .%:\. "
 183 LET H$="                                                                  O                              \''\::\''                             \.:\''\:."
 184 LET I$="                                  O                              \.'\::\'.                              %:                              \ .%:\. "
 185 LET J$="  O                              \''\::\''                             \ .\''\.                             \ '\'  \ '\'                                 "
 186 LET K$=" \'.O\.'                            \ . \:: \.                            \ '\''\''\''\'                                 "
 187 PRINT AT 9,13;H$;AT 9,13;I$;AT 9,13;J$;AT 9,13;K$;AT 9,13;J$;AT 9,13;H$;AT 9,13;I$
 190 LET B$="%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%""
 191 PRINT AT 0,0;B$;"%"%"%"%"%"%"%"%"%"%"%W%H%A%T%"%A%"%W%O%R%L%D%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%I%,%M%"%U%P%"%A%G%A%I%N%S%T%"%"%"%"%"%"%"%"%"%"%"%"%"%"%C%A%N%"%Y%O%U%"%F%E%E%L%"%T%H%A%T%"%?%?%?%?%"%"%"%"%"";B$;"%"%"%"%O%N%E%"%"%"%R%E%Q%U%E%S%T%"%"%"%O%F%"%"%"%H%E%L%P%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%I%"%"%N%E%E%D%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%B%E%"%S%T%R%A%I%G%H%T%"%W%I%T%H%"%M%E%"%"%"%"%"%"";B$;B$;B$;B$;B$;B$;B$;B$;B$;"%"%"%"%"%"%"%"%"%"%I%"%W%O%R%K%"%F%O%R%"%Y%O%U%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%Y%O%U%"%W%O%R%K%"%A%G%A%I%N%S%T%"%M%E%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%I%"%A%S%K%"%F%O%R%"%T%E%N%"%"%"%"%"%"%"%"%"%"%"%"%"%"%"%F%I%V%E%,%S%"%W%H%A%T%"%Y%O%U%"%G%I%V%E%"%M%E%"";B$
 192 PRINT AT 21,29;"%"%"%"";AT 11,12;"CAMOUFLAGE"
 193 PAUSE 85
 194 CLS
 195 LET D$="\::  \:  \ :  \:  \ :  \:  \ :  \:  \ :  \:  \ :  \:  \ :\: \::  \:  \ :  \:  \ :  \:  \ :  \:  \ :  \:  \ :  \:  \ :\: "
 196 LET E$="\::\''\''\:'\''\':\''\''\:'\''\':\''\''\:'\''\':\''\''\:'\''\':\''\''\:'\''\':\''\''\:'\''\':\: "
 197 PRINT AT 0,0;"%Y%O%U\::%K%E%E%P\::%P%U%T%T%I%N%G\::%T%H%E\::%S%C%R%E%E%N%S\::%U%P\: ";D$;E$;D$;E$;D$;E$;D$;E$;D$;E$;D$;E$;D$;"\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\: "
 198 GOSUB 915
 201 PRINT AT 7,4;"W"
 202 PRINT AT 7,9;"H"
 203 PRINT AT 7,14;"Y"
 204 GOSUB 915
 205 PRINT AT 11,9;"O"
 206 PRINT AT 11,14;"H"
 207 GOSUB 915
 208 PRINT AT 16,14;"W"
 209 PRINT AT 16,19;"H"
 210 PRINT AT 16,24;"Y"
 212 PAUSE 99
 213 CLS
 214 PRINT X$
 216 PRINT AT 3,1;A$
 217 FOR F=1 TO 21
 218 NEXT F
 219 PRINT AT 19,0;"\!!\':\.'%I%,M\@@%N%OT\##%SE%E%IN%G\!!%YO%U\;;%C%LEA%RL%Y\!!\'.\@@"
 220 PAUSE 240
 221 CLS
 222 LET L$="\:  \:'\'.\ :\''\: \:. \ :\ '\':\'' \ :\''\' \:'\''\ :\''\'  \:.\ .\: \:'\':\ : \:  \:  \: \ :\ : \: \: \'.\ : \ :  \ '\''\: \:'\' \ :\''  \ '\:' \: \ :\ : \:  \:  \:.\.'\ :\..\: \:  \': \ :  \ .\..\: \:.\..\ :\..\.   \:  \:.\.:\ :\..\: "
 223 LET P$="I DONT SEE YOU"
 225 PRINT P$
 226 PAUSE 85
 227 PRINT P$
 228 PAUSE 85
 229 PRINT P$
 230 PAUSE 85
 231 PRINT P$
 232 PAUSE 85
 233 PRINT P$
 234 PAUSE 85
 235 PRINT P$
 236 PAUSE 85
 237 PRINT P$
 238 PAUSE 85
 239 PRINT P$
 240 PAUSE 70
 249 CLS
 255 GOSUB 940
 265 CLS
 275 PRINT X$
 285 GOSUB 940
 295 CLS
 301 LET F$="%*\::%*\::%*\::%*\::%*\::%*\::%*\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\::%*\::%*\::%*\::%*\::%*\::%*\::                   "
 302 LET G$="\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@                                "
 303 GOSUB 920
 304 PAUSE 50
 305 PRINT AT 16,1;A$
 306 GOSUB 915
 311 GOSUB 848
 312 GOSUB 848
 313 GOSUB 848
 314 GOSUB 848
 316 GOSUB 915
 320 CLS
 325 GOSUB 920
 326 PAUSE 50
 327 PRINT AT 16,1;A$
 328 GOSUB 915
 331 GOSUB 848
 332 GOSUB 848
 333 GOSUB 848
 334 GOSUB 848
 335 GOSUB 915
 339 CLS
 340 GOSUB 920
 341 PAUSE 50
 351 PRINT AT 16,1;A$
 352 GOSUB 915
 364 GOSUB 848
 365 GOSUB 848
 368 PAUSE 205
 701 CLS
 710 PRINT AT 0,0;"DRUMS--------------MIKE DOHERTEY"
 711 FOR F=1 TO 15
 712 NEXT F
 713 PRINT AT 3,0;"BACKING VOCALS---------PAULA AND                        WINIFRED            (THE VIZZABLE GIRLS)" 
 714 FOR F=1 TO 15
 715 NEXT F
 716 PRINT AT 8,0;"THE REST------------CHRIS SIEVEY"
 717 FOR F=1 TO 18
 718 NEXT F
 719 PRINT AT 11,0;"PRODUCER-----------MARTIN HANNET"
 720 FOR F=1 TO 15
 721 NEXT F
 722 PRINT AT 14,0;"ENGINEER------------CHRIS NEAGLE"
 723 FOR F=1 TO 15
 724 NEXT F
 725 PRINT AT 17,0;"EDITING-----------LAWRENCE DIANA"
 726 FOR F=1 TO 20
 727 NEXT F
 728 PRINT AT 20,0;"RECORDED-STRAWBERRY-APRIL 1 C.V."
 729 FOR F=1 TO 20
 730 NEXT F
 740 PRINT AT 19,0;"LYRICS PUBLISHED BY CVSONGS/ATV.COPYRIGHT COMP-U-RECORDS/RANDOM RECORDS/CHRIS SIEVEY 1 CV(1983)"
 741 FOR F=1 TO 20
 742 NEXT F
 775 CLS
 776 PRINT AT 0,11;"HELLO TOSH"
 777 CLS
 778 PRINT AT 21,6;"DEDICATED TO PAULA"
 780 PAUSE 99
 785 PRINT AT 21,0;"HHMMM, THINK I,LL RUN THAT AGAIN"
 786 PAUSE 99
 798 CLS
 799 RUN 
 848 PRINT AT 2,3;"S%IN%KI%NG"
 849 PRINT AT 5,2;"A%ME%RI%CA%NS"
 850 PRINT AT 2,3;"%SI%NK%IN%G"
 851 PRINT AT 5,2;"%AM%ER%IC%AN%S"
 852 PRINT AT 2,3;"S%IN%KI%NG"
 853 PRINT AT 5,2;"A%ME%RI%CA%NS"
 854 PRINT AT 2,3;"%SI%NK%IN%G"
 855 PRINT AT 5,2;"%AM%ER%IC%AN%S"
 856 PRINT AT 2,3;"S%IN%KI%NG"
 857 PRINT AT 5,2;"A%ME%RI%CA%NS"
 858 PRINT AT 2,3;"%SI%NK%IN%G"
 859 PRINT AT 5,2;"%AM%ER%IC%AN%S"
 866 RETURN
 915 FOR F=1 TO 5
 916 NEXT F
 917 RETURN
 920 PRINT F$;F$;F$;F$;G$;G$;G$;G$;G$;G$;G$
 921 RETURN
 940 PRINT AT 2,1;L$
 941 PAUSE 85
 942 PRINT AT 7,1;L$
 943 PAUSE 85
 944 PRINT AT 12,1;L$
 945 PAUSE 85
 946 PRINT AT 17,1;L$
 947 PAUSE 42
 948 RETURN
 998 SAVE "CAMOUFLAG%E"
 999 GOTO 2

...and here is a previous post regarding the crazy way ZX81 BASIC does AND's and OR's which I now follow:
bwinkel67 wrote:Wow, so ZX81 BASIC is just plain weird.

This on the QL works as advertised resulting in either 1 when true or 0 when false. However, on ZX81 we get this:

PRINT 2 AND 17 -> results in 2
PRINT 17 AND 2 -> results in 17
PRINT 0 AND 17 -> results in 0
PRINT 17 AND 0 -> results in 0
PRINT 0 AND 0 -> results in 0

So if it's false it prints 0 but if it's true it takes the first argument.


With OR, the ZX81 is even less consistent (works as it should on the QL):

PRINT 2 OR 17 -> results in 1
PRINT 17 OR 2 -> results in 1
PRINT 0 OR 17 -> results in 1
PRINT 17 OR 0 -> results in 17
PRINT 0 OR 0 -> results in 0

So, OR results in 1 for all cases of true unless the second argument is false, then instead of 1 it results in the first argument???

Mind numbingly insane.

In code it actually looks sane and has symmetry, which was surprising:

Code: Select all

      if (getkey("AND") == NOERR) {
         if (evaleql(&right_i,&right_s) != NOERR) { free(*left_s); return BADARG; }
         if (!right_i) *left_i = 0;  /* ZX81 BASIC returns first arg if both true */
      }
      else if (getkey("OR") == NOERR) {
         if (evaleql(&right_i,&right_s) != NOERR) { free(*left_s); return BADARG; }
         if (right_i) *left_i = 1;   /* ZX81 BASIC returns 1 if right arg true, else left arg */ 
      }
Addendum...this is what it looked like before the change and how "normal" conditionals are evaluated:

Code: Select all

      if (getkey("AND") == NOERR) {
         if (evaleql(&right_i,&right_s) != NOERR) { free(*left_s); return BADARG; }
         *left_i = *left_i && right_i;
      }
      else if (getkey("OR") == NOERR) {
         if (evaleql(&right_i,&right_s) != NOERR) { free(*left_s); return BADARG; }
         *left_i = *left_i || right_i;
      }


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

Re: ZXSimulator

Post by bwinkel67 »

So a new version of ZXSimulator after a long hiatus:
zx.zip
(34.74 KiB) Downloaded 128 times
Only one mod as I had an important inconsistency. ZX81 BASIC has AND and OR deal with strings uniquely:
  • "A" AND 1 -> "A"
  • "A" AND 0 -> ""
All other combinations are a syntax errors -- i.e. you can only have a string lead a single two-argument AND, while an OR cannot have a string in it anywhere.

I still haven't implemented floating point and I just realized I also punted on multi-dimensional string arrays (only allow a single dimension DIM statement) whereas for number arrays I allow as many as you want.

BTW, it was this Vroom like game for the ZX81 that made me realize my error. I had to change two things from the original as it had DIM B$(2,4) which I changed to just a single DIM B$(8) and then use some math to get to the 1st vs the 2nd (i.e. using the TO substring function) and the game used exponentiation for PAUSE (i.e. 4E4) that I maxed out to 32767 instead.

Code: Select all

  10 REM **FLYWHEEL**SLR/1985***
  20 LET S=0
  30 PRINT AT 2,15;"\,,\##\,,";AT 3,0;"\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\@@\::\@@\@@\@@\@@\@@\@@\@@\@@\::\@@\@@\@@\@@\@@\::\@@\@@\@@\@@\@@\@@\@@\@@\::\@@\@@\::\@@\@@\@@\@@\::\::\@@\@@\::\@@\@@\::\@@\::\::\@@\@@\@@\::\::\@@\::\@@\@@\@@\::\@@\::\::\@@\@@\::\::\@@\::\@@"
  40 FOR A=8 TO 21
  50 PRINT AT A,0;"\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::"
  60 NEXT A
  70 GOSUB 1000
  80 FOR A=10 TO 20 STEP 2
  90 PRINT AT A,15-(A-10)+(A-(5+A/2));"\: ";AT A,A/2+11;"\ :"
 100 PRINT AT A+1,15-(A-10)+(A-(5+A/2));"\ :";AT A+1,A/2+11;"\: "
 110 NEXT A
 120 PRINT AT 20,14;A$;AT 21,14;B$(1+(P-1)*4 TO 4+(P-1)*4)
 130 PRINT AT 16,10;"\@@\@@\@@START*\@@\@@\@@"
 140 FOR A=15 TO 21
 150 PRINT AT A,10;"\@@";TAB 21;"\@@"
 160 NEXT A
 170 FOR G=13 TO 17
 180 PRINT AT 16,G;"*"
 190 FOR A=1 TO 20
 200 NEXT A
 210 NEXT G
 220 FOR G=1 TO R1
 230 GOSUB 1000*Z(G)+1000
 240 NEXT G
 260 PRINT AT 16,10;"\@@\@@\@@FINISH\@@\@@\@@"
 270 FOR A=15 TO 21
 280 PRINT AT A,10;"\@@";TAB 21;"\@@"
 290 NEXT A
 300 LET S=S+500+INT (500*RND+1)
 310 PRINT AT 0,0;"SCORE:";S;"    KEEP IT UP**"
 320 FOR A=1 TO 300
 330 NEXT A
 340 GOTO 30
 400 PRINT AT 0,0;"SCORE:";S;"    YOU CRASHED**";AT 20,C;D$;AT 20,X;"\.'\'.\.'\:.";AT 21,C;D$;AT 21,C;"\ .\' \'.\:'"
 410 PRINT AT 2,0;"PRESS ENTER TO BEGIN AGAIN..."
 420 PAUSE 32767
 430 CLS
 440 RUN 
 500 FOR A=10 TO 20 STEP 2
 510 PRINT AT A,0;"\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::"
 520 PRINT AT A,15-(A-10)+(A-(5+A/2));"\: ";AT A,A/2+11;"\ :"
 530 PRINT AT A+1,15-(A-10)+(A-(5+A/2));"\ :";AT A+1,A/2+11;"\: "
 540 NEXT A
 550 RETURN
 600 FOR A=10 TO 20 STEP 2
 610 PRINT AT A,0;"\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::"
 620 PRINT AT A,7;"\: \.'\''" AND A=10;AT A+1,7;"\: \::\::\.'" AND A=10;AT A,8;"\ :\::\::\.'" AND A=12;AT A+1,8;"\ :\::\::\::\.'" AND A=12;AT A,8;"\: \::\::\::\::\.'" AND A=14;AT A+1,8;"\: \::\::\::\::\::\.'" AND A=14
 630 PRINT AT A,9;"\ :\::\::\::\::\::\..\''" AND A=16;AT A+1,9;"\ :\::\::\::\::\::\::\::\.'" AND A=16;AT A,9;"\: \::\::\::\::\::\::\::\::\.'" AND A=18;AT A+1,9;"\: \::\::\::\::\::\::\::\::\::\.'" AND A=18;AT A,10;"\ :\::\::\::\::\::\::\::\::\::\.'" AND A=20;AT A+1,10;"\ :\::\::\::\::\::\::\::\::\::\::\.'" AND A=20
 640 NEXT A
 650 RETURN
 700 FOR A=10 TO 20 STEP 2
 710 PRINT AT A,0;"\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::"
 720 PRINT AT A,22;"\''\'.\ :" AND A=10;AT A+1,21;"\'.\::\::\ :" AND A=10;AT A,20;"\'.\::\::\: " AND A=12;AT A+1,19;"\'.\::\::\::\: " AND A=12;AT A,18;"\'.\::\::\::\::\ :" AND A=14;AT A+1,17;"\'.\::\::\::\::\::\ :" AND A=14
 730 PRINT AT A,15;"\''\..\::\::\::\::\::\: " AND A=16;AT A+1,14;"\'.\::\::\::\::\::\::\::\: " AND A=16;AT A,13;"\'.\::\::\::\::\::\::\::\::\ :" AND A=18;AT A+1,12;"\'.\::\::\::\::\::\::\::\::\::\ :" AND A=18;AT A,11;"\'.\::\::\::\::\::\::\::\::\::\: " AND A=20;AT A+1,10;"\'.\::\::\::\::\::\::\::\::\::\::\: " AND A=20
 740 NEXT A
 750 RETURN
1000 LET X=14
1010 LET A$="\..\ '\' \.."
1030 LET R1=10+INT (RND*10+1)
1040 DIM Z(R1)
1050 FOR A=1 TO R1
1060 LET Z(A)=INT (RND*3+1)
1070 NEXT A
1080 LET B$="\##\..\..\##\@@\..\..\@@"
1100 LET P=1
1110 LET C=X
1120 LET D$="\::\::\::\::"
1130 LET Z(1)=1
1140 RETURN
2000 IF Z(G-(G>1))<>1 OR G=1 THEN GOSUB 500
2010 FOR A=1 TO 2+INT (RND*4)
2020 PRINT AT 20,X;A$;AT 21,X;B$(1+P*4 TO 4+P*4)
2030 LET R2=INT (RND*2)
2040 FOR V=14 TO 22
2050 PRINT AT 20,C;D$;AT 20,X;A$;AT 21,C;D$;AT 21,X;B$(1+P*4 TO 4+P*4)
2060 LET C=X
2070 LET P=NOT P
2080 LET X=X-(INKEY$ ="Z" AND X>11)+(INKEY$ ="." AND X<17)
2090 GOSUB 2400+200*R2+20*(V-14)
2100 NEXT V
2120 IF (R2=0 AND X+3<19) OR (R2=1 AND X>12) THEN GOTO 400
2130 LET S=S+10
2140 NEXT A
2150 RETURN
2400 PRINT AT V,15;"\:'"
2410 RETURN
2420 PRINT AT V,15;"\''";AT V-1,15;"\::"
2430 RETURN
2440 PRINT AT V,14;"\:'\''";AT V-1,15;"\::"
2450 RETURN
2460 PRINT AT V,14;"\''\''";AT V-1,14;"\::\::"
2470 RETURN
2480 PRINT AT V,13;"\:'\':\''";AT V-1,14;"\::\::"
2490 RETURN
2500 PRINT AT V,13;" \:: ";AT V-1,13;"\::\::\::"
2510 RETURN
2520 PRINT AT V,12;"\: \ :\:: ";AT V-1,13;"\::\::\::"
2530 RETURN
2540 PRINT AT V,12;" \::\:: ";AT V-1,12;"\::\::\::\::"
2550 RETURN
2560 PRINT AT V-1,12;"\::\::\::\::"
2570 RETURN
2600 PRINT AT V,16;"\':"
2610 RETURN
2620 PRINT AT V,16;"\''";AT V-1,16;"\::"
2630 RETURN
2640 PRINT AT V,16;"\''\':";AT V-1,16;"\::"
2650 RETURN
2660 PRINT AT V,16;"\''\''";AT V-1,16;"\::\::"
2670 RETURN
2680 PRINT AT V,16;"\''\:'\':";AT V-1,16;"\::\::"
2690 RETURN
2700 PRINT AT V,16;" \:: ";AT V-1,16;"\::\::\::"
2710 RETURN
2720 PRINT AT V,16;" \::\: \ :";AT V-1,16;"\::\::\::"
2730 RETURN
2740 PRINT AT V,16;" \::\:: ";AT V-1,16;"\::\::\::\::"
2750 RETURN
2760 PRINT AT V-1,16;"\::\::\::\::"
2770 RETURN
3000 IF Z(G-1)<>2 THEN GOSUB 600
3005 LET X=X-(X=17)
3008 LET C=X
3010 FOR A=1 TO 2+INT (RND*4)
3020 PRINT AT 20,X;A$;AT 21,X;B$(1+P*4 TO 4+P*4)
3030 LET R2=INT (RND*2)
3040 FOR V=14 TO 22
3050 PRINT AT 20,C;D$;AT 20,X;A$;AT 21,C;D$;AT 21,X;B$(1+P*4 TO 4+P*4)
3060 LET C=X
3070 LET P=NOT P
3080 LET X=X-(INKEY$ ="Z" AND X>11)+(INKEY$ ="." AND X<16)
3090 GOSUB 3400+200*R2+20*(V-14)
3100 LET S=S+1
3110 NEXT V
3120 IF (R2=0 AND X+3<18) OR (R2=1 AND X>12) THEN GOTO 400
3130 LET S=S+10
3140 NEXT A
3150 RETURN
3400 PRINT AT V,9;"\:'"
3410 RETURN
3420 PRINT AT V,10;"\''";AT V-1,9;"\::"
3430 RETURN
3440 PRINT AT V,10;"\:'\''";AT V-1,10;"\::"
3450 RETURN
3460 PRINT AT V,10;"\:'\''\':";AT V-1,10;"\::\::"
3470 RETURN
3480 PRINT AT V,11;"\''\:'\':";AT V-1,10;"\::\::\::"
3490 RETURN
3500 PRINT AT V,11;" \:: ";AT V-1,11;"\::\::\::"
3510 RETURN
3520 PRINT AT V,11;" \::\: \ :";AT V-1,11;"\::\::\::"
3530 RETURN
3540 PRINT AT V,11;" \::\:: ";AT V-1,11;"\::\::\::\::"
3550 RETURN
3560 PRINT AT V-1,11;"\::\::\::\::"
3570 RETURN
3600 PRINT AT V,11;"\':"
3610 RETURN
3620 PRINT AT V,12;"\''";AT V-1,11;"\::"
3630 RETURN
3640 PRINT AT V,13;"\''\':";AT V-1,12;"\::"
3650 RETURN
3660 PRINT AT V,14;"\''\''";AT V-1,13;"\::\::"
3670 RETURN
3680 PRINT AT V,14;"\:'\':\''";AT V-1,14;"\::\::"
3690 RETURN
3700 PRINT AT V,15;" \:: ";AT V-1,14;"\::\::\::"
3710 RETURN
3720 PRINT AT V,15;"\: \ :\:: ";AT V-1,15;"\::\::\::"
3730 RETURN
3740 PRINT AT V,16;" \::\:: ";AT V-1,15;"\::\::\::\::"
3750 RETURN
3760 PRINT AT V-1,16;"\::\::\::\::"
3770 RETURN
4000 IF Z(G-1)<>3 THEN GOSUB 700
4005 LET X=X+(X=11)
4008 LET C=X
4010 FOR A=1 TO 2+INT (RND*4)
4020 PRINT AT 20,X;A$;AT 21,X;B$(1+P*4 TO 4+P*4)
4030 LET R2=INT (RND*2)
4040 FOR V=14 TO 22
4050 PRINT AT 20,C;D$;AT 20,X;A$;AT 21,C;D$;AT 21,X;B$(1+P*4 TO 4+P*4)
4060 LET C=X
4070 LET P=NOT P
4080 LET X=X-(INKEY$ ="Z" AND X>12)+(INKEY$ ="." AND X<17)
4090 GOSUB 4400+200*R2+20*(V-14)
4100 LET S=S+1
4110 NEXT V
4120 IF (R2=0 AND X+3<19) OR (R2=1 AND X>13) THEN GOTO 400
4130 LET S=S+10
4140 NEXT A
4150 RETURN
4400 PRINT AT V,20;"\:'"
4410 RETURN
4420 PRINT AT V,19;"\''";AT V-1,20;"\::"
4430 RETURN
4440 PRINT AT V,17;"\:'\''";AT V-1,19;"\::"
4450 RETURN
4460 PRINT AT V,16;"\''\''";AT V-1,17;"\::\::"
4470 RETURN
4480 PRINT AT V,15;"\''\:'\':";AT V-1,16;"\::\::"
4490 RETURN
4500 PRINT AT V,14;" \:: ";AT V-1,15;"\::\::\::"
4510 RETURN
4520 PRINT AT V,13;" \::\: \ :";AT V-1,14;"\::\::\::"
4530 RETURN
4540 PRINT AT V,12;" \::\:: ";AT V-1,13;"\::\::\::\::"
4550 RETURN
4560 PRINT AT V-1,12;"\::\::\::\::"
4570 RETURN
4600 PRINT AT V,22;"\':"
4610 RETURN
4620 PRINT AT V,21;"\''";AT V-1,22;"\::"
4630 RETURN
4640 PRINT AT V,20;"\''\':";AT V-1,21;"\::"
4650 RETURN
4660 PRINT AT V,19;"\:'\''\':";AT V-1,20;"\::\::"
4670 RETURN
4680 PRINT AT V,18;"\:'\':\''";AT V-1,19;"\::\::\::"
4690 RETURN
4700 PRINT AT V,18;" \:: ";AT V-1,18;"\::\::\::"
4710 RETURN
4720 PRINT AT V,17;"\: \ :\:: ";AT V-1,18;"\::\::\::"
4730 RETURN
4740 PRINT AT V,17;" \::\:: ";AT V-1,17;"\::\::\::\::"
4750 RETURN
4760 PRINT AT V-1,17;"\::\::\::\::"
4770 RETURN
5000 CLS
5010 CLEAR
5020 SAVE "F%W"
5030 PRINT "%*%*%F%L%Y\::%W%H%E%E%L%*%*%B%Y\::%S%T%E%V%E%N\::%R%E%I%D%/%1%9%8%5\::\::\!!\!!\!!\!!\!!\!!\!!\!!\!!\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::%3%D\::%C%A%R\::%D%R%I%V%I%N%G\::%P%R%O%G%R%A%M%.\::%U%S%E\::%"%Z%"\::%F%O%R\::%L%E%F%T\::%A%N%D\::%"%.%"\::%F%O%R\::%R%I%G%H%T%.\::\::\::\::\::%G%O%O%D\::%D%R%I%V%I%N%G%*%*%*%*\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::"
5040 PRINT AT 21,0;"%P%R%E%S%S\::%E%N%T%E%R\::%T%O\::%B%E%G%I%N\::%G%A%M%E\::%P%L%A%Y%.%."
5050 GOTO 420


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

Re: ZXSimulator

Post by bwinkel67 »

I posted on a separate topic to also hi-lite the new free hosting service that I found : I moved the website for ZXSimulator. Adding it here as I have a few links to this thread from other sites.

http://zxsimulator.orgfree.com/

Here's a pic of it running the ZX81 Vroom clone (I just crashed :-/)
ZXSimulator.png
Note that if you have an accelerated machine this game gets out of hand quickly.


Post Reply