Page 12 of 15

Re: ZXSimulator

Posted: Thu May 14, 2020 10:33 am
by Chr$
FYI

I ran it on a BBQL just now (the only thing non standard is the vDrive and vMAP. vDrive was attached but not initialised (I ran your bas prog from good ole mdv1_).

With MGG German ROM it was 162 +/- 1.5%
With JS ROM it was 159 +/- 3.05%

On my normal setup with Minerva and Gold Card it was 733 +/- 2.77%

Re: ZXSimulator

Posted: Thu May 14, 2020 7:21 pm
by bwinkel67
Just updated the table. So I doubt vDrive would change anything since it doesn't add to the ROM but vMap does I believe...I can try and put the test on an old MDV and then re-run it but it will still have the Hermes chip...not sure that would matter since it deals with I/O stuff.

Interesting that JSU ROM is faster. Perhaps difference between European and US clock rates to deal with PAL vs NTSC? Though at 50 vs 60 that should make the JS ROM come up at around 140, not 159...

Code: Select all

CONFIGURATION                   CYCLES/SEC     +/- %    SPEED      REMARKS
---------------------------     -----------    ------   ------     ------------------------------------------------------
Ql 128ko JSU                    168            .296     x1         BBQL JSU with Hermes & vDrive (no vMap)
Ql 128ko JS                     159            3.05     x1         BBQL JS with vDrive & vMap
Ql 128ko MGG                    162            1.5      x1         BBQL MGG with vDrive & vMap
GC QL under QDOS                733            2.77     x4.5       Minerva ROM with vDrive & vMap
SGC QL under QDOS               1864           .25      x11        No extra multitasking from me.
SGC QL with SMSQ/E              8440           .11      x50        " " ROMdisc and Hermes.
Compaq, 1core, QPC2, 2.8Ghz     173894         37.2     x1035      Very variable timings due to monocore multitasking.
Asus, 3core, QPC2, 1.9Ghz       138683         4.0      x825       Triple core means better variability when multitasking.
"     "      "     "            ?              ?        ?          C++ code runs 400 tmes faster than superbasic version !
QLAY2, iMac 2011/Win7           1431           .935     x8.5       Speed 1000 Delay 120
QLAY2, iMac 2011/Win7           30341          1.43     x180       Speed 100000 Delay 0

Re: ZXSimulator

Posted: Thu May 14, 2020 7:43 pm
by Chr$
bwinkel67 wrote:Just updated the table. So I doubt vDrive would change anything since it doesn't add to the ROM but vMap does I believe...I can try and put the test on an old MDV and then re-run it but it will still have the Hermes chip...not sure that would matter since it deals with I/O stuff.

Interesting that JSU ROM is faster. Perhaps difference between European and US clock rates to deal with PAL vs NTSC? Though at 50 vs 60 that should make the JS ROM come up at around 140, not 159...

Code: Select all

CONFIGURATION                   CYCLES/SEC     +/- %    SPEED      REMARKS
---------------------------     -----------    ------   ------     ------------------------------------------------------
Ql 128ko JSU                    168            .296     x1         BBQL JSU with Hermes & vDrive (no vMap)
Ql 128ko JS                     159            3.05     x1         BBQL JS with vDrive & vMap
Ql 128ko MGG                    162            1.5      x1         BBQL MGG with vDrive & vMap
GC QL under QDOS                733            2.77     x4.5       (not sure which ROM) with vDrive & vMap
SGC QL under QDOS               1864           .25      x11        No extra multitasking from me.
SGC QL with SMSQ/E              8440           .11      x50        " " ROMdisc and Hermes.
Compaq, 1core, QPC2, 2.8Ghz     173894         37.2     x1035      Very variable timings due to monocore multitasking.
Asus, 3core, QPC2, 1.9Ghz       138683         4.0      x825       Triple core means better variability when multitasking.
"     "      "     "            ?              ?        ?          C++ code runs 400 tmes faster than superbasic version !
QLAY2, iMac 2011/Win7           1431           .935     x8.5       Speed 1000 Delay 120
QLAY2, iMac 2011/Win7           30341          1.43     x180       Speed 100000 Delay 0
Yes, the vMaps would be a bit of a pain to remove! When I have another completely original QL on the go (I've got another MGG and a UK version but not sure what ROM it has) I'll try it again as I now have a cart with it on. The 733 GC result was with Minerva ROM.

Re: ZXSimulator

Posted: Fri May 22, 2020 5:46 am
by bwinkel67
Finally done with the semester so I can start adding more features. In the meantime, while I was stuck in grading purgatory I kept playing Minesweeper on the ZXSimulator. I tired of having to get up to hit "M" to mark a mine as I used a joystick otherwise. So I changed the interface making the fire button (space) change modes and then using left/right to mark mines and up/down to clear them. So when not in that mode you move the cursor. This way you can play the entire game sitting back and only using the joystick.

Here is the BASIC that will run on ZXSimulator (it won't run in SuperBASIC):

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 PRINT AT 13,7;"PCT BOMBS SET:     "
1120 FOR N=1 TO 70
1130 PRINT AT 13,22;INT (N*10/7);
1140 LET X=INT (RND*32)
1150 LET Y=INT (RND*21)
1160 LET E=21*(X)+Y+1
1170 IF F(E)=9 THEN GOTO 1140
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
1295 LET E=21*(X)+Y+1
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 X=1 TO 32
7020 FOR Y=1 TO 21
7025 LET E=21*(X-1)+Y
7030 LET C=F(E)
7040 IF C=19 THEN PRINT AT Y,X-1;"%*";
7041 IF C=29 THEN PRINT AT Y,X-1;"%*";
7042 IF C=40 THEN PRINT AT Y,X-1;"%*";
7050 NEXT Y
7060 NEXT X
7100 LET K$=" %B%O%O%M "
7110 PAUSE 50
7120 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
Here is the intro screen explaining it:
MineSweeper.png
MineSweeper.png (6.56 KiB) Viewed 4320 times
I think next will be to add planet hopping to Elite_bas to complete that demo game. Then on to add new features to ZXSimulator. The first task will be to figure out how to find the size of a file without wasting time and reading it twice.

Re: ZXSimulator

Posted: Mon May 25, 2020 10:11 am
by bwinkel67
I finally set up my TS1000. I had forgotten how bad the RF modulation on the old TS1000/ZX81's were. I had to do some adjustments to make it a clear as possible. The QL RF modulator is so much better. I may have to do the composite mod on the TS1000. The EightyOne emulator lets you simulate the old screen interference so I recreated something similar to what I'm getting. I also have my original ZX81 that I haven't unboxed and wondering if its screen will be better.
TS1000.png

In any case, I did some timings and had some surprising results. With this code, BBQL comes in 3rd about 2.7 time slower than actual TS1000. EightyOne is almost twice as fast as TS1000 which is surprising since I thought it is supposed to be pretty close to realtime esp since EightyOne is running at the lower frame-rate. This test is a bit contrived as I'm trying to squeeze the most out of the TS1000 speed-wise.

Code: Select all

10 PRINT "HELLO";
20 GOTO 10
  • EightyOne running at 50fps for the ZX81 - 2 second
  • Actual TS1000 w/16K Ram Pack - 3.5 seconds
  • QLAY2 running ZXSimulator (speed 120/delay 1200) - 10.5 seconds
  • Unexpanded QL running ZXSimulator - 9.5 seconds

This next example has different results, now BBQL is 2nd only to the EighyOne emulator and actually beats the TS1000 hardware.

Code: Select all

10 FOR I=1 TO 20
20 PRINT "HELLO"
30 NEXT I
  • EightyOne running at 50fps for the ZX81 - 1.30 second
  • Actual TS1000 w/16K Ram Pack - 2.15 seconds
  • QLAY2 running ZXSimulator (speed 120/delay 1200) - 1.70 seconds
  • Unexpanded QL running ZXSimulator - 1.60 seconds

I think ZXSimulator is slightly slower than the EightyOne emulator but it may now actually be on par with the actual hardware TS1000 when you start adding the various commands that make up most BASIC programs. Of course once I add floating point we will see how it fares.

Re: ZXSimulator

Posted: Mon May 25, 2020 11:57 am
by stephen_usher
bwinkel67 wrote:I finally set up my TS1000. I had forgotten how bad the RF modulation on the old TS1000/ZX81's were. I had to do some adjustments to make it a clear as possible. The QL RF modulator is so much better. I may have to do the composite mod on the TS1000. The EightyOne emulator lets you simulate the old screen interference so I recreated something similar to what I'm getting. I also have my original ZX81 that I haven't unboxed and wondering if its screen will be better.
It would depend upon the ULA version. The first version didn't have a "backporch" in the video signal which means that TVs can't determine the reference black-level correctly. In fact, because it doesn't put the signal to zero TVs take full brightness as being the black-level of the signal and adjust it appropriately, meaning that the display is extremely dim. You can either switch the ULA or there are modifications and boards available which will add a "backporch" to the signal, these generally fit in the modulator can and replace the insides, giving "composite"* video out.

*it's not really composite video as it's merely a luminance signal.

Re: ZXSimulator

Posted: Tue May 26, 2020 2:12 am
by bwinkel67
So I tried my old ZX81 and a broken TS1000 that I just kept the motherboard for parts and both have unusable screens where it's basically black on black. Without the RAM pack, the working TS1000 has almost a perfect picture on a Toshiba LCD monitor/TV. When adding the RAM pack it gets more distorted but definitely nice black on bright white. The cheap composite fix may not give me better than that but there is a more comprehensive one that might I think.

Re: ZXSimulator

Posted: Sat May 30, 2020 12:50 am
by bwinkel67
I was finally able to recover my ZX81/TS1000 game BATTLESHIP that I wrote as a teenager. I had submitted it for publication and Gladstone Electronics had sent me a reply that they were in the process of crafting a contract and boom, Timex pulled out of the US market (the whole process took 3-4 months so had I been a year earlier this might have appeared on Cassette's for the TS1000).

I made two small changes to work with the ZXSimulator. My PAUSE is uninterruptible, which I need to fix since you can break pausing with any keystroke on the ZX81/TS1000 so I removed it and replaced it with an IF/GOTO (line 90). Also, grabbing INKEY$ is better if you do it once and assign to a variable so I added that, although it was working without that fix (line 962). The one ZXSimulator bug is when comparing strings via = in an expression which turns + into concatenation of strings so had to add VAL (line 970 and 975). But that's it, otherwise it is unchanged.

Note that once I got it loaded into the TS1000 through an audacity captured wave file on my desktop, I took 30 screen shots with my iPhone and typed it in since the EightyOne emulator refused to read the actual audio (and the Java based conversion tool gave me endless errors with no hope in sight). So perhaps there are still a few typos that I need to fix but I did play through a few games (finding like half a dozen typos that caused the game to crash) and I beat the computer once and it beat me once. What's nice about this (and l likely why it was publishable) is that the game has a nice pace and the computer talks to you so there is a bit of a "script" that I created for the user. When I create stuff now, user experience be damned but I guess as a teenager I thought about it.

This game is almost 40 years old:

Code: Select all

1 REM **COMPUTER BATTLESHIP**
5 RAND
7 CLS
10 PRINT "    \"COMPUTER BATTLESHIP\""
15 PRINT ,,,,"        INSTRUCTIONS"
20 PRINT ,,"1)  TO PLACE YOUR FLEET, ENTER"
25 PRINT "\"V\" FOR VERTICAL OR \"H\" FOR"
30 PRINT "HORIZONTAL.  YOU CAN MOVE THE"
35 PRINT "CURSOR WITH THE \"5\", \"6\", \"7\","
40 PRINT "AND \"8\".  THE \"S\" KEY WILL SET"
45 PRINT "YOUR SHIP.  YOU CAN/T HAVE TWO"
50 PRINT "SHIPS CROSSING OR SIDE BY SIDE"
55 PRINT "EACH OTHER."
60 PRINT ,,"2)  TO ENTER YOUR MOVE, ENTER"
65 PRINT "LETTER (FROM A-J) FIRST AND"
70 PRINT "THEN THE NUMBER.  THE COMPUTER"
75 PRINT "WILL TELL YOU WHAT TO DO, OR"
80 PRINT "WHAT HAS HAPPENED."
85 PRINT ,,,,"   PRESS ENTER TO START."
90 IF CODE INKEY$=0 THEN GOTO 90
100 FAST
110 CLS
120 DIM A(10,10)
130 DIM B(10,10)
140 DIM C(18)
150 LET N1=5
160 LET N2=5
170 LET X=6
180 LET T1=6
190 LET U1=6
195 GOSUB 305
200 LET X=7
205 LET T1=5
215 LET U1=5
220 GOSUB 305
225 LET X=8
230 LET T1=4
240 LET U1=4
245 GOSUB 305
250 LET X=8
255 LET T1=4
265 LET U1=3
270 GOSUB 305
275 LET X=9
280 LET T1=3
290 LET U1=2
295 GOSUB 305
300 GOTO 465
305 LET D1=INT (RND*10)+1
310 LET E1=INT (RND*X)+1
314 LET T2=0
316 LET T3=0
318 LET C1=INT (RND*2)
320 IF C1=1 THEN GOTO 395
325 IF E1=1 THEN LET T3=1
330 IF E1=X THEN LET T2=1
335 FOR O=T3 TO (T1-T2)
340 IF B(D1,E1-1+O)<>0 THEN GOTO 305
345 IF O=0 OR O=T1 THEN GOTO 370
350 IF D1=1 THEN GOTO 360
355 IF B(D1-1,E1-1+O)<>0 THEN GOTO 305
360 IF D1=10 THEN GOTO 370
365 IF B(D1+1,E1-1+O)<>0 THEN GOTO 305
370 NEXT O
375 FOR O=0 TO (T1-2)
380 LET B(D1,E1+O)=U1
385 NEXT O
390 RETURN
395 IF E1=1 THEN LET T3=1
400 IF E1=X THEN LET T2=1
405 FOR O=T3 TO (T1-T2)
410 IF B(E1-1+O,D1)<>0 THEN GOTO 305
415 IF O=0 OR O=T1 THEN GOTO 440
420 IF D1=1 THEN GOTO 430
425 IF B(E1-1+O,D1-1)<>0 THEN GOTO 305
430 IF D1=10 THEN GOTO 440
435 IF B(E1-1+O,D1+1)<>0 THEN GOTO 305
440 NEXT O
445 FOR O=0 TO (T1-2)
450 LET B(E1+O,D1)=U1
455 NEXT O
460 RETURN
465 DIM E$(10)
467 GOSUB 1125
470 LET E$="%5%4%3%U%2"
475 LET F1=7
480 LET F2=19
485 PRINT AT 21,2;"PLACEMENT OF YOUR SHIPS.     "
490 SLOW
495 PAUSE 200
500 PRINT AT 21,2;"PLACE CARRIER - V/H ?        "
505 LET W1=12
510 LET Z1=24
515 LET R1=6
520 LET S1=6
530 LET V1=1
535 GOSUB 740
540 PRINT AT 21,2;"PLACE BATTLESHIP - V/H ?     "
545 LET W1=13
550 LET Z1=25
555 LET R1=5
560 LET S1=5
570 LET V1=2
575 GOSUB 740
580 PRINT AT 21,2;"PLACE CRUISER - V/H ?        "
585 LET W1=14
590 LET Z1=26
595 LET R1=4
600 LET S1=4
610 LET V1=3
615 GOSUB 740
620 PRINT AT 21,2;"PLACE SUBMARINE - V/H ?      "
625 LET W1=14
630 LET Z1=26
635 LET R1=3
640 LET S1=4
650 LET V1=4
655 GOSUB 740
660 PRINT AT 21,2;"PLACE DESTROYER - V/H ?      "
665 LET W1=15
670 LET Z1=27
675 LET R1=2
680 LET S1=3
690 LET V1=5
695 GOSUB 740
700 PRINT AT 21,2;"ALRIGHT, THEY ARE SET.       "
705 PAUSE 120
710 PRINT AT 21,2;"NOW LET/S BEGIN.             "
715 PAUSE 120
720 PRINT AT 21,2;"DO YOU WISH TO START - Y/N ? "
725 IF INKEY$="Y" THEN GOTO 1285
730 IF INKEY$="N" THEN GOTO 1390
735 GOTO 725
740 IF INKEY$="V" THEN GOTO 752
745 IF INKEY$="H" THEN GOTO 858
750 GOTO 740
752 LET S2=0
754 LET S3=0
756 GOSUB 965
760 GOSUB 1010
765 IF INKEY$="S" THEN GOTO 775
770 GOTO 756
775 IF F1>W1 THEN GOTO 756
780 IF F1=7 THEN LET S3=1
785 IF F1=W1 THEN LET S2=1
790 FOR P=S3 TO (S1-S2)
795 IF A(F1-7+P,F2-18)<>0 THEN GOTO 752
800 IF P=0 OR P=S1 THEN GOTO 825
805 IF F2=19 THEN GOTO 815
810 IF A(F1-7+P,F2-19)<>0 THEN GOTO 752
815 IF F2=28 THEN GOTO 825
820 IF A(F1-7+P,F2-17)<>0 THEN GOTO 752
825 NEXT P
830 FOR P=0 TO (S1-2)
835 LET A(F1-6+P,F2-18)=R1
840 PRINT AT F1+P,F2;E$(V1)
845 NEXT P
850 GOSUB 1010
855 RETURN
858 LET S2=0
860 LET S3=0
862 GOSUB 965
865 GOSUB 1010
870 IF INKEY$="S" THEN GOTO 880
875 GOTO 862
880 IF F2>Z1 THEN GOTO 862
885 IF F2=19 THEN LET S3=1
890 IF F2=Z1 THEN LET S2=1
895 FOR P=S3 TO (S1-S2)
900 IF A(F1-6,F2-19+P)<>0 THEN GOTO 858
905 IF P=0 OR P=S1 THEN GOTO 930
910 IF F1=7 THEN GOTO 920
915 IF A(F1-7,F2-19+P)<>0 THEN GOTO 858
920 IF F1=16 THEN GOTO 930
925 IF A(F1-5,F2-19+P)<>0 THEN GOTO 858
930 NEXT P
935 FOR P=0 TO (S1-2)
940 LET A(F1-6,F2-18+P)=R1
945 PRINT AT F1,F2+P;E$(V1)
950 NEXT P
955 GOSUB 1010
960 RETURN
965 PRINT AT F1,F2;"O"
967 LET K$=INKEY$
970 LET F2=F2+VAL (K$="8")-VAL (K$="5")
975 LET F1=F1+VAL (K$="6")-VAL (K$="7")
980 IF F1>16 THEN LET F1=7
985 IF F1<7 THEN LET F1=16
990 IF F2>28 THEN LET F2=19
995 IF F2<19 THEN LET F2=28
1000 PRINT AT F1,F2;"%K"
1005 RETURN
1010 IF A(F1-6,F2-18)<>0 AND A(1,1)=0 THEN GOTO 1065
1020 IF A(F1-6,F2-18)<>0 AND A(1,10)=0 THEN GOTO 1080
1030 IF A(F1-6,F2-18)<>0 AND A(10,1)=0 THEN GOTO 1095
1040 IF A(F1-6,F2-18)<>0 AND A(10,10)=0 THEN GOTO 1110
1045 IF A(F1-6,F2-18)<>0 THEN GOTO 1050
1047 RETURN
1050 LET F1=11
1055 LET F2=23
1060 RETURN
1065 LET F1=7
1070 LET F2=19
1075 RETURN
1080 LET F1=7
1085 LET F2=28
1090 RETURN
1095 LET F1=16
1100 LET F2=19
1105 RETURN
1110 LET F1=16
1115 LET F2=28
1120 RETURN
1125 PRINT AT 0,6;"\"COMPUTER BATTLESHIP\""
1130 PRINT AT 3,1;"YOUR HITS AND   COMPUTER/S HITS"
1135 PRINT AT 4,4;"MISSES:        AND MISSES:"
1140 PRINT AT 6,2;"\:'12345678910    \:'12345678910"
1145 LET E$="ABCDEFGHIJ"
1150 FOR R=1 TO 10
1155 PRINT AT 6+R,2;E$(R);"OOOOOOOOOO\ :    ";E$(R);"OOOOOOOOOO\ :"
1160 NEXT R
1165 PRINT AT 17,2;"\:.\..\..\..\..\..\..\..\..\..\..\.:    \:.\..\..\..\..\..\..\..\..\..\..\.:"
1170 PRINT AT 18,2;"NUMBER OF SHIPS REMAINING:"
1175 PRINT AT 19,2;"COMPUTER/S= ";N2;"   YOURS= ";N1
1180 RETURN
1185 LET L=L-1
1187 GOTO 1640
1190 LET L=L+1
1192 GOTO 1640
1195 LET K=K-1
1200 GOTO 1640
1205 LET K=K+1
1210 GOTO 1640
1215 IF C(12)>0 THEN GOTO C(12)
1220 IF C(11)>0 THEN GOTO C(11)
1225 LET K=INT (RND*10)+1
1230 LET L=INT (RND*10)+1
1235 IF A(K,L)=1 THEN GOTO 1225
1240 IF A(K,L)=2 THEN GOTO 1420
1245 IF A(K,L)=3 THEN GOTO 1455
1250 IF A(K,L)=4 THEN GOTO 1490
1255 IF A(K,L)=5 THEN GOTO 1525
1260 IF A(K,L)=6 THEN GOTO 1560
1265 IF A(K,L)=0 THEN LET A(K,L)=1
1270 PRINT AT K+6,L+18;"\@@"
1275 PRINT AT 21,2;"I MISSED.                    "
1280 PAUSE 100
1285 PRINT AT 21,2;"YOUR TURN.                   "
1290 INPUT M$
1292 IF LEN M$>1 THEN GOTO 1400
1295 LET M=CODE M$-37
1300 IF M<1 OR M>10 THEN GOTO 1400
1305 INPUT N$
1307 IF (CODE N$>28 AND CODE N$<38) AND (LEN N$=1) THEN GOTO 1317
1309 IF LEN N$<>2 THEN GOTO 1410
1311 IF CODE N$<>29 OR CODE N$(2)<>28 THEN GOTO 1410
1313 LET N=10
1315 GOTO 1320
1317 LET N=CODE N$-28
1320 IF B(M,N)<>1 THEN GOTO 1345
1325 PRINT AT 21,2;"YOU HAVE ALREADY PICKED THAT."
1330 PAUSE 100
1335 PRINT AT 21,2;"PLEASE TRY AGAIN.            "
1337 PAUSE 100
1340 GOTO 1280
1345 IF B(M,N)=2 THEN GOTO 2020
1350 IF B(M,N)=3 THEN GOTO 2060
1355 IF B(M,N)=4 THEN GOTO 2100
1360 IF B(M,N)=5 THEN GOTO 2140
1365 IF B(M,N)=6 THEN GOTO 2180
1370 IF B(M,N)=0 THEN LET B(M,N)=1
1375 PRINT AT M+6,N+2;"\@@"
1380 PRINT AT 21,2;"YOU MISSED.                  "
1385 PAUSE 100
1390 PRINT AT 21,2;"MY TURN.                     "
1392 PAUSE 100
1395 GOTO 1215
1400 PRINT AT 21,2;"LETTER IS OUT OF RANGE.      "
1405 GOTO 1330
1410 PRINT AT 21,2;"NUMBER IF OUT OF RANGE.      "
1415 GOTO 1330
1420 PRINT AT 21,2;"I HIT YOUR DESTROYER.        "
1425 LET C(6)=C(6)+1
1430 GOSUB 1595
1435 IF C(6)=2 THEN GOTO 1445
1440 GOTO 1285
1445 PRINT AT 21,2;"I SUNK YOUR DESTROYER.       "
1450 GOTO 1620
1455 PRINT AT 21,2;"I HIT YOUR SUBMARINE.        "
1460 LET C(7)=C(7)+1
1465 GOSUB 1595
1470 IF C(7)=3 THEN GOTO 1480
1475 GOTO 1285
1480 PRINT AT 21,2;"I SUNK YOUR SUBMARINE.       "
1485 GOTO 1620
1490 PRINT AT 21,2;"I HIT YOUR CRUISER.          "
1495 LET C(8)=C(8)+1
1500 GOSUB 1595
1505 IF C(8)=3 THEN GOTO 1515
1510 GOTO 1285
1515 PRINT AT 21,2;"I SUNK YOUR CRUISER.         "
1520 GOTO 1620
1525 PRINT AT 21,2;"I HIT YOUR BATTLESHIP.       "
1530 LET C(9)=C(9)+1
1535 GOSUB 1595
1540 IF C(9)=4 THEN GOTO 1550
1545 GOTO 1285
1550 PRINT AT 21,2;"I SUNK YOUR BATTLESHIP.      "
1555 GOTO 1620
1560 PRINT AT 21,2;"I HIT YOUR CARRIER.          "
1565 LET C(10)=C(10)+1
1570 GOSUB 1595
1572 IF C(10)=4 THEN LET C(18)=1
1575 IF C(10)=5 THEN GOTO 1585
1580 GOTO 1285
1585 PRINT AT 21,2;"I SUNK YOUR CARRIER.         "
1590 GOTO 1620
1595 PRINT AT K+6,L+18;"%H"
1600 LET A(K,L)=1
1605 LET C(11)=1640
1610 PAUSE 60
1615 RETURN
1620 FOR Q=11 TO 18
1625 LET C(Q)=0
1630 NEXT Q
1635 GOTO 2275
1640 LET C3=(INT (RND*4))*25
1645 GOTO 1650+C3
1650 IF L=10 THEN GOTO 1640
1652 IF C(14)=1 THEN GOTO 1640
1654 LET C(14)=1
1655 IF A(K,L+1)=1 THEN GOTO 1640
1660 LET L=L+1
1665 IF A(K,L)>1 THEN LET C(12)=1750
1667 IF A(K,L)=0 THEN LET C(12)=1185
1670 GOTO 1240
1675 IF L=1 THEN GOTO 1640
1677 IF C(15)=1 THEN GOTO 1640
1679 LET C(15)=1
1680 IF A(K,L-1)=1 THEN GOTO 1640
1685 LET L=L-1
1690 IF A(K,L)>1 THEN LET C(12)=1775
1692 IF A(K,L)=0 THEN LET C(12)=1190
1695 GOTO 1240
1700 IF K=10 THEN GOTO 1640
1702 IF C(16)=1 THEN GOTO 1640
1704 LET C(16)=1
1705 IF A(K+1,L)=1 THEN GOTO 1640
1710 LET K=K+1
1715 IF A(K,L)>1 THEN LET C(12)=1885
1717 IF A(K,L)=0 THEN LET C(12)=1195
1720 GOTO 1240
1725 IF K=1 THEN GOTO 1640
1727 IF C(17)=1 THEN GOTO 1640
1729 LET C(17)=1
1730 IF A(K-1,L)=1 THEN GOTO 1640
1735 LET K=K-1
1740 IF A(K,L)>1 THEN LET C(12)=1910
1742 IF A(K,L)=0 THEN LET C(12)=1205
1745 GOTO 1240
1750 IF L=10 THEN GOTO 1800
1755 IF A(K,L+1)=1 THEN GOTO 1800
1760 LET L=L+1
1765 LET C(12)=1825
1767 IF A(K,L)=0 THEN LET C(12)=1835
1770 GOTO 1240
1775 IF L=1 THEN GOTO 1815
1780 IF A(K,L-1)=1 THEN GOTO 1815
1785 LET L=L-1
1790 LET C(12)=1855
1792 IF A(K,L)=0 THEN LET C(12)=1865
1795 GOTO 1240
1800 LET L=L-2
1805 LET C(12)=1785
1810 GOTO 1240
1815 LET L=L+2
1820 LET C(12)=1760
1822 GOTO 1240
1825 IF L=10 THEN GOTO 1835
1827 IF A(K,L+1)=1 THEN GOTO 1835
1830 GOTO 1760
1835 IF A(K,L-3-C(18))=1 THEN LET C(13)=1
1840 LET L=L-3-C(13)-C(18)
1845 LET C(12)=1785
1850 GOTO 1240
1855 IF L=1 THEN GOTO 1865
1857 IF A(K,L-1)=1 THEN GOTO 1865
1860 GOTO 1785
1865 IF A(K,L+3+C(18))=1 THEN LET C(13)=1
1870 LET L=L+3+C(13)+C(18)
1875 LET C(12)=1760
1880 GOTO 1240
1885 IF K=10 THEN GOTO 1935
1890 IF A(K+1,L)=1 THEN GOTO 1935
1895 LET K=K+1
1900 LET C(12)=1960
1902 IF A(K,L)=0 THEN LET C(12)=1970
1905 GOTO 1240
1910 IF K=1 THEN GOTO 1950
1914 IF A(K-1,L)=1 THEN GOTO 1950
1920 LET K=K-1
1925 LET C(12)=1990
1927 IF A(K,L)=0 THEN LET C(12)=2000
1930 GOTO 1240
1935 LET K=K-2
1940 LET C(12)=1920
1945 GOTO 1240
1950 LET K=K+2
1955 LET C(12)=1895
1957 GOTO 1240
1960 IF K=10 THEN GOTO 1970
1962 IF A(K+1,L)=1 THEN GOTO 1970
1965 GOTO 1895
1970 IF A(K-3-C(18),L)=1 THEN LET C(13)=1
1975 LET K=K-3-C(13)-C(18)
1980 LET C(12)=1920
1985 GOTO 1240
1990 IF K=1 THEN GOTO 2000
1992 IF A(K-1,L)=1 THEN GOTO 2000
1995 GOTO 1920
2000 IF A(K+3+C(18),L)=1 THEN LET C(13)=1
2005 LET K=K+3+C(13)+C(18)
2010 LET C(12)=1895
2015 GOTO 1240
2020 PRINT AT 21,2;"YOU HIT MY DESTROYER.        "
2025 LET C(1)=C(1)+1
2030 PRINT AT M+6,N+2;"%2"
2035 LET B(M,N)=1
2040 IF C(1)=2 THEN GOTO 2050
2045 GOTO 1385
2050 PAUSE 100
2052 PRINT AT 21,2;"YOU SUNK MY DESTROYER.       "
2055 GOTO 2220
2060 PRINT AT 21,2;"YOU HIT MY SUBMARINE.        "
2065 LET C(2)=C(2)+1
2070 PRINT AT M+6,N+2;"%U"
2075 LET B(M,N)=1
2080 IF C(2)=3 THEN GOTO 2090
2085 GOTO 1385
2090 PAUSE 100
2092 PRINT AT 21,2;"YOU SUNK MY SUBMARINE.       "
2095 GOTO 2220
2100 PRINT AT 21,2;"YOU HIT MY CRUISER.          "
2105 LET C(3)=C(3)+1
2110 PRINT AT M+6,N+2;"%3"
2115 LET B(M,N)=1
2120 IF C(3)=3 THEN GOTO 2130
2125 GOTO 1385
2130 PAUSE 100
2132 PRINT AT 21,2;"YOU SUNK MY CRUISER.         "
2135 GOTO 2220
2140 PRINT AT 21,2;"YOU HIT MY BATTLESHIP.       "
2145 LET C(4)=C(4)+1
2150 PRINT AT M+6,N+2;"%4"
2155 LET B(M,N)=1
2160 IF C(4)=4 THEN GOTO 2170
2165 GOTO 1385
2170 PAUSE 100
2172 PRINT AT 21,2;"YOU SUNK MY BATTLESHIP.      "
2175 GOTO 2220
2180 PRINT AT 21,2;"YOU HIT MY CARRIER.          "
2185 LET C(5)=C(5)+1
2190 PRINT AT M+6,N+2;"%5"
2195 LET B(M,N)=1
2200 IF C(5)=5 THEN GOTO 2210
2205 GOTO 1385
2210 PAUSE 100
2215 PRINT AT 21,2;"YOU SUNK MY CARRIER.         "
2220 PAUSE 100
2225 LET N2=N2-1
2230 GOSUB 1175
2235 IF N2=0 THEN GOTO 2250
2240 GOTO 1390
2250 PRINT AT 21,2;"YOU HAVE JUST SUNK MY FLEET. "
2255 PAUSE 100
2260 PRINT AT 21,2;"YOU WIN.                     "
2265 PAUSE 100
2270 GOTO 2325
2275 PAUSE 100
2280 LET N1=N1-1
2285 GOSUB 1175
2290 IF N1=0 THEN GOTO 2305
2295 GOTO 1285
2305 PRINT AT 21,2;"I HAVE JUST SUNK YOUR FLEET. "
2310 PAUSE 100
2315 PRINT AT 21,2;"I WIN.                       "
2320 PAUSE 100
2325 PRINT AT 21,2;"DO YOU WISH TO TRY AGAIN-Y/N?"
2330 IF INKEY$="Y" THEN RUN
2335 IF INKEY$="N" THEN GOTO 2345
2340 GOTO 2330
2345 CLS
2350 PRINT AT 10,11;"\' THE END\ '"
Battleship.png
Update: fixed some typos but found no bugs. Also updated the picture since some of the text on the computer's end was off by 2 spaces.

Re: ZXSimulator

Posted: Sun May 31, 2020 12:49 am
by bwinkel67
Latest version of ZXSimulator. A few small but helpful changes:
  • Changed file reading to be a bit more efficient. It now determines size of file, allocates that memory, and reads it in
    • This has sped up file loading a lot
    • Before I was constantly resizing my internal store and copying from small to large which was mucking up the heap
    • Now I can load larger BASIC files with less memory (i.e. BBQL can load 13K Battleship_bas)
    • Need to figure out a better way to determine file size -- right now I read it twice (whats a good way to get file size via TRAPS?)
  • PAUSE now can be aborted. I basically pause for 5 milliseconds and check for key presses (should likely eat those presses as well but am not)
  • Listing was broken for rare case of double-wrap where the 3rd line left a single character
  • Display wasn't quite centered -- fixed
  • String concatenation and equality now works properly and won't muck up in lengthy expressions with mixed types
Here is the zip:
zx.zip
(33.12 KiB) Downloaded 149 times
You will see that the source file has been zipped as the distribution has gotten a bit too big to fit into 128KB of MDV storage. So you have a zip file inside of a zip file :-/ You'll have to unzip src_zip if you wanna take a look of the C code for the simulator.

Note that I added a 4th program, my Battleship_bas game that I wrote as a teenager in the early 80's on my ZX81. I reclaimed it and left it mostly as is. I had to type it in since I was only able to load the tape onto a TS1000 and then took screen shots. I think I fixed all the typos. I changed a few lines where I was doing this:

Code: Select all

100 IF INKEY$="A" THEN GOTO 1000
110 IF INKEY$="B" THEN GOTO 2000
120 GOTO 100
To the code below as it works better with how INKEY$ is implemented via a QL TRAP.

Code: Select all

100 LET K$=INKEY$
105 IF K$="A" THEN GOTO 1000
110 IF K$="B" THEN GOTO 2000
120 GOTO 100
So without this you can be pressing a key and it just doesn't always registers it, especially on a fast machine (QLAY2 for me). So assigning the INKEY$ to the K$ variable seems to capture more key presses. I did the same thing in the Ball_bas program previously. Note that INKEY$ isn't all that great on a ZX81/TS1000 either.

I may change the Battleship_bas program like I did with the minesweeper game and tie both setting ships and picking spots to joystick port 1 so you don't have to use the keyboard. Still, I designed it this way (I think -- been almost 40 years) because that's how battleship works, giving coordinates. I must have decided that being able to have a moving/blinking cursor was also cool since setup is done that way.

BTW, there is a bug during setup that when you cross an already placed ship, the cursor will overwrite it. Oh, and if you try to set a ship off the board nothing happens...sometimes that can be confusing -- I should have added an error message.

Re: ZXSimulator

Posted: Sun May 31, 2020 12:42 pm
by pjw
bwinkel67 wrote:(whats a good way to get file size via TRAPS?)
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.