50 years of BASIC!

Wow time flies!

So if you are interested, TIME magazine has a fantastic article on the history of basic!

To celebrate, there is the GE simulator ‘true basic‘ on Dartmouth , and another more obscure (and seemingly deleted) simulator for MS-DOS.  Which is interesting at least for more demo programs.

There is even a ‘web‘ based simulator, but I haven’t tried it.

For the heck of it, I took an old ‘game’ taxman.bas (Downloaded from here, and which I extracted with SIMH) and with a couple of line changes, got it to run.

10 DIM T(10)
20 DIM L(50)
101 PRINT
104 PRINT”HI, I’M THE TAXMAN”
106 PRINT”DO YOU WANT THE REGULATIONS”
108 LET R = 1
110 IF R<>0 THEN 900
120 REM ***INITIALZATION
122 GOSUB 800
124 REM ***THE HUMAN TAKES A NUMBER
126 GOSUB 500
128 REM *** COMPUTE THE HUMAN’S AND TAXMANS TOTLES
130 GOSUB 570
132 REM *** PRINT THE NEW LIST
134 GOSUB 600
136 REM *** CHECK IF ANY NUMBERS STILL HAVE FACTORS
138 GOSUB 650
140 IF M=1 THEN 126
142 REM *** FIND THE WINNER
144 GOSUB 700
146 REM *** AGAIN?
148 GOTO 750
496 REM
497 REM *** THE HUMAN MOVES
498 REM
500 PRINT
502 PRINT
504 PRINT”YOU TAKE”;
506 INPUT K
508 LET K=INT(K)
510 IF K <= 0 THEN 750
512 IF K <=N THEN 518
514 PRINT K;”IS NOT IN THE LIST — TRY AGAIN.”
516 GOTO 502
518 IF L(K)=0 THEN 514
520 REM FIND ALL THE FACTORS
522 IF K>1 THEN 530
524 PRINT”THERE ARE NO FACTORS OF”;K;”FOR ME.”
526 PRINT”ARE YOU TRYING TO SHORT-CHANGE THE TAXMAN?”
528 GOTO 502
530 LET M=0
532 FOR I=1 TO K/2
534 IF L(I)=0 THEN 544
536 IF K <> I*INT(K/I) THEN 544
538 LET M=M+1
540 LET T(M)=I
542 LET L(I)=0
544 NEXT I
546 REM CHECK WETHER THERE WERE ANY FACTORS
548 IF M=0 THEN 524
550 LET L(K)=0
552 RETURN
566 REM
567 REM *** COMPUTE THE HUMAN’S AND TAXMAN’S TOTALS
568 REM
570 LET Y=Y+K
572 PRINT”YOUR TOTAL IS”;Y
574 PRINT”I GET”;
576 FOR I=1 TO M
578 PRINT T(I);
580 LET Z=Z+T(I)
582 NEXT I
584 PRINT
586 PRINT”MY TOTAL IS”;Z
588 RETURN
596 REM
597 REM *** PRINT THE NEW LIST
598 REM
600 PRINT
602 PRINT”NEW LIST:”;
604 LET M=0
606 FOR I=1 TO N
608 IF L(I)=0 THEN 614
610 PRINT I;
612 LET M=1
614 NEXT I
616 RETURN
646 REM
647 REM *** CHECK IF ANY NUMBERS STILL HAVE FACTORS
648 REM
649 REM CHECK IF THE LIST IS EMPTY
650 IF M=0 THEN 690
652 FOR I=N TO 4 STEP -1
654 FOR J=2 TO I/2
656 IF L(J)=0 THEN 664
658 IF I<> J*INT(I/J) THEN 664
660 LET M=1
662 RETURN
664 NEXT J
666 NEXT I
668 REM THE TAXMAN GETS THE REST OF THE NUMBERS
670 PRINT
672 PRINT”I GET”;
674 FOR I=1 TO N
676 IF L(I)=0 THEN 682
678 PRINT I;
680 LET Z=Z+I
682 NEXT I
684 PRINT”BECAUSE NO FACTORS OF ANY NUMBER ARE LEFT.”
686 PRINT”MY TOTAL IS”;Z
688 LET M=0
690 RETURN
696 REM
697 REM *** FIND THE WINNER
698 REM
700 PRINT
702 IF Z>Y THEN 708
704 PRINT”YOU”;Y;” TAXMAN”;Z;” YOU WIN!!!”
706 RETURN
708 PRINT”TAXMAN”;Z;” YOU”;Y;” THE TAXMAN WINS.”
710 RETURN
746 REM
747 REM *** AGAIN?
748 REM
750 PRINT
752 PRINT
754 PRINT”AGAIN (Type 0 for NO)”;
756 INPUT R
759 IF R=0 THEN 999
760 GOTO 122
796 REM
797 REM *** INITIALATION
798 REM
800 PRINT
802 PRINT”HOW MANY NUMBERS DO YOU WANT IN THE LIST”;
804 INPUT N
806 LET N=INT(N)
808 IF N <= 0 THEN 999
810 IF N=50 THEN 818
811 IF N<50 THEN 818
812 PRINT”AT THIS TIME, REGULATIONS ALLOW A MAXIMUM OF 50 NUMBERS.”
814 GOTO 800
818 LET Y=0
820 LET Z=0
822 PRINT
824 PRINT”THE LIST IS:”;
826 FOR I=1 TO N
828 PRINT I;
830 LET L(I)=1
832 NEXT I
834 IF N>1 THEN 844
836 PRINT
838 PRINT”HOW VERY GENEROUS OF YOU TO FORFEIT ALL TO THE TAXMAN.”
840 PRINT”TAXMAN 1 YOU 0 THE TAXMAN WINS.”
842 GOTO 750
844 RETURN
896 REM
897 REM *** INSTRUCTIONS
898 REM
900 PRINT
901 PRINT”YOU TRY TO BEAT THE TAXMAN.”
902 PRINT
904 PRINT”WE START WITH A LIST OF WHOLE NUMBERS IN NUMERICAL”
906 PRINT”ORDER (YOU DECIDE HOW MANY).”
908 PRINT
910 PRINT”YOU TAKE A NUMBER FROM THE LIST — THE TAXMAN GETS”
912 PRINT”ALL THE FACTORS OF YOUR NUMBER THAT ARE STILL LEFT”
914 PRINT”YOUR NUMBER AND ALL OF ITS FACTORS ARE THEN DELETED”
916 PRINT”FROM THE LIST.”
918 PRINT
920 PRINT”FOR EXAMPLE, SUPPOSE YOU WANT TEN NUMBERS TO BE IN THE LIST.”
922 PRINT”THEN THE LIST WOULD BE: 1 2 3 4 5 6 7 8 9 10″
924 PRINT
926 PRINT”IF YOU TOOK 8, THE TAXMAN WOULD GET: 1, 2, AND 4″
928 PRINT”AND THE NEW LIST WOULD BE: 3 5 6 7 9 10″
929 PRINT”TYPE <RETURN> TO GO ON”
932 PRINT”THE TAXMAN MUST GET SOMTHING EVERY TIME SO YOU CAN”
934 PRINT”ONLY PICK A NUMBER THAT HAS FACTORS LEFT,”
936 PRINT
938 PRINT”WHEN NONE OF THE REMAINING FACTORS,”
940 PRINT”THE TAXMAN GETS THEM!!!”
942 PRINT
944 PRINT”YOUR SCORE IS THE SUM OF NUMBERS YOU TAKE.”
946 PRINT”IF YOU WANT TO GIVE UP, TAKE 0.”
948 PRINT”GOOD LUCK !!!”
950 GOTO 122
999 END

Taxman!

Taxman!

It’s not much to look at, but it is kinda neat to see it run.

But really, read the Time article!

Star Traders

While looking for various source code for TradeWars, I did stumble upon The Mushroom Cloud BBS which has source for the ancient Basic and Pascal versions.  They also have Star Traders & Star Traders 2 which apparently were some kind of inspiration to Trade Wars.  Those two were written for the HP 2100 times haring basic system which is… incredibly complicated… Or too much so for my poor brain.

Some more searching did reveal STAR TRADERS, a port to Altair BASIC 4.0 by – S J Singer.  Now Altair BASIC, is Microsoft Basic!  So, I figured I could probably try it with Quick Basic, and see if it runs, which it surprisingly did!  I went for the next step to compile it, and it snagged on a few things.  There is about 4 things to correct and then I’ve got a MS-DOS executable!  But while this is all fun in emulation, It’d be far cooler, say if I could build a Win32 executable… Enter QB64!

The best thing is that it looks and feels just like QuickBASIC!

And while I did have to make a few more minor changes, I had it running as a 32bit exe in a few minutes!

For the two or three people who care, you can download the source & Win32 exe here.  QB64 supports Linux & OS X so you can run it on those platforms as well!

Here is the Altair Basic Source:

5 REM STAR TRADERS
10 REM - MODIFIED FOR 'ALTAIR BASIC 4.0' BY - S J SINGER
20 REM
30 REM
35 DEFINT C
36 DEFINT I
40 DIM M(10,13),S(5,4),N$(5),D1(5),S1(5),Q(5),M$(12),C$(25)
50 DIM C1$(25),C2$(25)
60 DATA 1,"'ALTAIR STARWAYS'"
70 DATA 2,"'BETELGEUSE,LTD.'"
80 DATA 3,"'CAPELLA FREIGHT CO.'"
90 DATA 4,"'DENEBOLA SHIPPERS'"
100 DATA 5,"'ERIDANI EXPEDITERS'"
110 Z1$=CHR$(26)+CHR$(0)
120 CLS
130 FOR I=1 TO 5
140 FOR J=1 TO 4
150 S(I,J)=0: D1(I)=0: S1(I)=100: Q(I)=0: B(I)=6000
160 NEXT J
170 NEXT I
180 L$=".+*ABCDE"
190 M$="ABCDEFGHIJKL"
195 PRINT" ********** STAR TRADERS **********":PRINT
197 PRINT:PRINT
200 INPUT "TYPE A 3 DIGIT NUMBER ";R1
220 R1=RND(-R1/1000)
230 FOR I=1 TO 9
240 FOR J=1 TO 12
250 IF INT(20*RND(R1)+1)<>10 THEN M(I,J)=1 ELSE M(I,J)=3
260 NEXT J
270 NEXT I
280 CLS
290 INPUT "HOW MANY PLAYERS (2-4) ";P1
300 PRINT:PRINT
310 INPUT "DOES ANY PLAYER NEED INSTRUCTIONS ";Q$
320 IF Q$ ="Y" THEN GOSUB 3410
330 CLS
340 FOR I=1 TO P1
350 PRINT "PLAYER",I,
370 INPUT " WHAT IS YOUR NAME ";P$
380 IF I=1 THEN P1$=P$
390 IF I=2 THEN P2$=P$
400 IF I=3 THEN P3$=P$
410 IF I=4 THEN P4$=P$
420 NEXT I
430 CLS
440 PRINT TAB(10),"...NOW I WILL DECIDE WHO GOES FIRST...":: PRINT:PRINT
445 PRINT:PRINT
450 PRINT:PRINT:PRINT
460 I=INT(P1*RND(R1)+1)
470 GOSUB 490
480 GOTO 550
490 PRINT
500 ON I GOTO 510,520,530,540: REM - IDENTIFY PLAYER
510 PRINT P1$;:P5$=P1$: RETURN
520 PRINT P2$;:P5$=P2$: RETURN
530 PRINT P3$;:P5$=P3$: RETURN
540 PRINT P4$;:P5$=P4$: RETURN
550 PRINT " IS THE FIRST PLAYER TO MOVE."
560 FOR W=1 TO 2000: NEXT
570 K=0
580 P=I:GOTO 610
590 K=K+1: IF K=48 THEN 4450
600 P=P+1: IF P=P1+1 THEN P=1
610 FOR I=1 TO 5: REM SELECT 5 LEGAL MOVES
620 R(I)=INT(9*RND(R1)+1)
630 C(I)=INT(12*RND(R1)+1)
640 FOR I1=I-1 TO 0 STEP -1
650 IF R(I)=R(I1) AND C(I)=C(I1) THEN 620
660 NEXT I1
670 IF M(R(I),C(I))>1 THEN 620
680 FOR I1=1 TO 5
690 IF Q(I1)=0 THEN 870
700 NEXT I1
710 IF M(R(I),C(I)+1)>3 THEN 870
720 IF M(R(I),C(I)-1)>3 THEN 870
730 IF M(R(I)+1,C(I))>3 THEN 870
740 IF M(R(I)-1,C(I))>3 THEN 870
750 A1=M(R(I),C(I)+1)
760 A2=M(R(I),C(I)-1)
770 A3=M(R(I)+1,C(I))
780 A4=M(R(I)-1,C(I))
790 IF A1=2 AND A2<4 AND A3<4 AND A4<4 THEN 620
800 IF A2=2 AND A1<4 AND A3<4 AND A4<4 THEN 620
810 IF A3=2 AND A1<4 AND A2<4 AND A4<4 THEN 620
820 IF A4=2 AND A1<4 AND A2<4 AND A3<4 THEN 620
830 IF A1=3 AND A2<4 AND A3<4 AND A4<4 THEN 620
840 IF A2=3 AND A1<4 AND A3<4 AND A4<4 THEN 620
850 IF A3=3 AND A1<4 AND A2<4 AND A4<4 THEN 620
860 IF A4=3 AND A1<4 AND A2<4 AND A3<4 THEN 620
870 NEXT I
880 GOSUB 2060
890 PRINT
900 I=P
910 GOSUB 490
920 PRINT ", HERE ARE YOUR LEGAL MOVES FOR THIS TURN"
930 PRINT
940 FOR I=1 TO 5
950 PRINT R(I);MID$(M$,C(I),1);" ";
960 NEXT I
970 PRINT:PRINT
980 INPUT "WHAT IS YOUR MOVE ";R$
990 IF LEN(R$)=0 THEN R$="S"
1000 IF LEFT$(R$,1)="M" THEN R$="" ELSE 1030
1010 GOSUB 2060
1020 GOTO 900
1030 IF LEFT$(R$,1)="S" THEN R$="" ELSE 1060
1040 GOSUB 3230
1050 GOTO 900
1060 IF LEN(R$)<>2 THEN 1110
1070 IF ASC(MID$(R$,2,1))-64<1 THEN 1110
1080 IF ASC(MID$(R$,2,1))-64>12 THEN 1110 ELSE 1120
1090 IF VAL(R$)<1 THEN 1110
1100 IF VAL(R$)>9 THEN 1110
1110 PRINT "I DIDN'T UNDERSTAND THAT - TRY AGAIN ": GOTO 980
1120 R=VAL(LEFT$(R$,1))
1130 C=ASC(RIGHT$(R$,1))-64
1140 FOR I= 1 TO 5
1150 IF R=R(I) AND C=C(I) THEN 1190
1160 NEXT I
1170 PRINT "THAT SPACE WAS NOT INCLUDGD IN THE LIST..."
1180 GOTO 980
1190 A1=M(R-1,C)
1200 A2=M(R+1,C)
1210 A3=M(R,C+1)
1220 A4=M(R,C-1)
1230 IF A1<=1 AND A2<=1 AND A3<=1 AND A4<=1 THEN M(R,C)=2 ELSE 1250
1240 GOTO 1760
1250 IF A1>3 AND A2>3 AND A2<>A1 THEN GOSUB 2220:REM - LINE 2090 IS
1260 IF A1>3 AND A3>3 AND A3<>A1 THEN GOSUB 2220:REM THE MERGER SUB.
1270 IF A1>3 AND A4>3 AND A4<>A1 THEN GOSUB 2220
1280 IF A2>3 AND A3>3 AND A3<>A2 THEN GOSUB 2220
1290 IF A2>3 AND A4>3 AND A4<>A2 THEN GOSUB 2220
1300 IF A3>3 AND A4>3 AND A4<>A3 THEN GOSUB 2220
1310 IF A1<4 AND A2<4 AND A3<4 AND A4<4 THEN 1410
1320 IF M(R,C)>3 THEN 1760
1330 IF A1>3 THEN I=A1-3
1340 IF A2>3 THEN I=A2-3
1350 IF A3>3 THEN I=A3-3
1360 IF A4>3 THEN I=A4-3
1370 Q(I)=Q(I)+1
1380 S1(I)=S1(I)+100
1390 M(R,C)=I+3
1400 GOTO 1570
1410 FOR I=1 TO 5
1420 IF Q(I)=0 THEN 1460
1430 NEXT I
1440 IF M(R,C)<3 THEN M(R,C)=2
1450 GOTO 1760
1460 CLS
1470 GOSUB 3370
1480 PRINT "A NEW SHIPPING COMPANY HAS BEEN FORMED !"
1490 PRINT "IT'S NAME IS ",
1500 RESTORE
1510 READ N,C$
1520 IF I<>N THEN 1510
1530 PRINT C$
1540 S(I,P)=S(I,P)+5
1550 Q(I)=1
1560 PRINT:PRINT:PRINT:PRINT
1570 IF A1=3 THEN S1(I)=S1(I)+500
1580 IF A2=3 THEN S1(I)=S1(I)+500
1590 IF A3=3 THEN S1(I)=S1(I)+500
1600 IF A4=3 THEN S1(I)=S1(I)+500
1610 IF A1=2 THEN S1(I)=S1(I)+100 ELSE 1640
1620 Q(I)=Q(I)+1
1630 M(R-1,C)=I+3
1640 IF A2=2 THEN S1(I)=S1(I)+100 ELSE 1670
1650 Q(I)=Q(I)+1
1660 M(R+1,C)=I+3
1670 IF A3=2 THEN S1(I)=S1(I)+100 ELSE 1700
1680 Q(I)=Q(I)+1
1690 M(R,C+1)=I+3
1700 IF A4=2 THEN S1(I)=S1(I)+100 ELSE 1730
1710 Q(I)=Q(I)+1
1720 M(R,C-1)=I+3
1730 IF S1(I)>=3000 THEN T1=I ELSE 1750
1740 GOSUB 3100
1750 M(R,C)=I+3
1760 FOR I=1 TO 5
1770 B(P)=B(P)+INT(.05*S(I,P)*S1(I))
1780 NEXT I
1790 FOR I=1 TO 5
1800 IF Q(I)=0 THEN 2040
1810 PRINT:PRINT "YOUR CURRENT CASH= $";B(P)
1820 PRINT:PRINT "BUY HOW MANY SHARES OF ";
1830 RESTORE
1840 READ N,C$
1850 IF I<>N THEN 1840
1860 PRINT C$;
1870 PRINT " AT $";S1(I)
1880 PRINT TAB(5); "YOU NOW OWN ";S(I,P);
1890 INPUT R3$:IF LEN(R3$)=0 THEN R3$="0"
1900 IF R3$(1,1)="M" THEN R3$="" ELSE 1930
1910 GOSUB 2060
1920 GOTO 1810
1930 IF R3$(1,1)="S" THEN R3$="" ELSE 1960
1940 GOSUB 3230
1950 GOTO 1810
1960 R3=VAL(R3$)
1970 R3$=""
1980 IF R3*S1(I)<=B(P) THEN 2010
1990 PRINT "YOU ONLY HAVE $";B(P);" - TRY AGAIN"
2000 GOTO 1810
2010 IF R3=0 THEN 2040
2020 S(I,P)=S(I,P)+R3
2030 B(P)=B(P)-(R3*S1(I))
2040 NEXT I
2050 GOTO 590
2060 CLS: REM SUBROUTINE - PRINT MAP
2070 PRINT TAB(22);"MAP OF THE GALAXY"
2080 PRINT TAB(21);"*******************"
2090 PRINT TAB(13);" A B C D E F G H I J K L"
2100 FOR R2=1 TO 9
2110 PRINT" ";R2;" ";
2120 FOR C2=1 TO 12
2130 PRINT" ";
2140 Z2=M(R2,C2)
2150 IF Z2=0 THEN Z2=Z2+1
2160 PRINT MID$(L$,Z2,1)" ";
2180 NEXT
2190 PRINT
2200 NEXT
2210 RETURN
2220 F1=A1-3: IF F1<0 THEN F1=0:REM SUBROUTINE - CALCULATES THE
2230 F2=A2-3: IF F2<0 THEN F2=0:REM SURVIVOR IN THE EVENT
2240 F3=A3-3: IF F3<0 THEN F3=0:REM OF A MERGER
2250 F4=A4-3: IF F4<0 THEN F4=0
2260 T=Q(F1)
2270 T1=F1
2280 IF Q(F2)>Q(F1) THEN T=Q(F2) ELSE 2300
2290 T1=F2
2300 IF Q(F3)>T THEN T=Q(F3) ELSE 2320
2310 T1=F3
2320 IF Q(F4)>T THEN T=Q(F4) ELSE 2340
2330 T1=F4
2340 IF F1=T1 OR A1<4 THEN 2370
2350 X=F1
2360 GOSUB 2470
2370 IF F2=T1 OR A2<4 THEN 2400
2380 X=F2
2390 GOSUB 2470
2400 IF F3=T1 OR A3<4 THEN 2430
2410 X=F3
2420 GOSUB 2470
2430 IF F4=T1 OR A4<4 THEN 2460
2440 X=F4
2450 GOSUB 2470
2460 RETURN
2470 CLS
2480 GOSUB 3370: REM SUBROUTINE - PERFORMS CALCULATIONS
2490 RESTORE: REM TO ACCOMPLISH A MERGER
2500 READ N,C$
2510 IF X<>N THEN 2500
2520 C1$=C$
2530 PRINT C1$;
2540 PRINT " HAS JUST BEEN MERGED INTO ";
2550 RESTORE
2560 READ N,C$
2570 IF T1<>N THEN 2560
2580 C2$=C$
2590 PRINT C2$;"!"
2610 PRINT "PLEASE NOTE THE FOLLOWING TRANSACTIONS."
2620 PRINT
2630 PRINT TAB(3);"OLD STOCK = ";C1$;" NEW STOCK = ";
2640 PRINT C2$
2650 PRINT
2660 PRINT "PLAYER";TAB(10);"OLD STOCK";TAB(22);"NEW STOCK";
2670 PRINT TAB(34);"TOTAL HOLDINGS";TAB(53);"BONUS PAID"
2680 FOR I=1 TO P1
2690 GOSUB 490
2700 PRINT TAB(10);S(X,I);TAB(22);INT((.5*S(X,I))+.5);
2710 PRINT TAB(34);S(T1,I)+INT((.5*S(X,I))+.5);
2720 X1=0
2730 FOR I1=1 TO P1
2740 X1=X1+S(X,I1)
2750 NEXT
2760 PRINT TAB(53);" $";INT(10*((S(X,I)/X1)*S1(X)))
2770 NEXT I
2780 FOR I=1 TO P1
2790 S(T1,I)=S(T1,I)+INT((.5*S(X,I))+.5)
2800 B(I)=B(I)+INT(10*((S(X,I)/X1)*S1(X)))
2810 NEXT I
2820 FOR I=1 TO 9
2830 FOR J=1 TO 12
2840 IF M(I,J)=X+3 THEN M(I,J)=T1+3
2850 NEXT J
2860 NEXT I
2870 A1=M(R-1,C)
2880 A2=M(R+1,C)
2890 A3=M(R,C+1)
2900 A4=M(R,C-1)
2910 F1=A3-3
2920 IF F1<0 THEN F1=0
2930 F2=A2-3
2940 IF F2<0 THEN F2=0
2950 Q(T1)=Q(T1)+Q(X)
2960 S1(T1)=S1(T1)+S1(X)
2970 IF S1(T1)=>3000 THEN GOSUB 3100
2980 F3=A3-3
2990 IF F3<0 THEN F3=0
3000 F4=A4-3
3010 IF F4<0 THEN F4=0
3020 S1(X)=100
3030 Q(X)=0
3040 FOR I=1 TO P1
3050 S(X,I)=0
3060 NEXT I
3070 PRINT:PRINT
3080 M(R,C)=T1+3
3090 RETURN
3100 GOSUB 3370: REM SUBROUTINE - CALCULATES STOCK SPLITS
3110 PRINT "THE STOCK OF ",
3120 RESTORE
3130 READ N,C$
3140 IF T1<>N THEN 3130
3150 PRINT C$,
3160 PRINT " HAS SPLIT 2 FOR 1 !"
3170 S1(T1)=INT(S1(T1)/2)
3180 PRINT:PRINT
3190 FOR I1=1 TO P1
3200 S(T1,I1)=2*S(T1,I1)
3210 NEXT I1
3220 RETURN
3230 CLS
3240 PRINT
3250 PRINT "STOCK";TAB(30);"PRICE PER SHARE";
3260 PRINT TAB(50);"YOUR HOLDINGS"
3270 FOR I3=1 TO 5
3280 IF S1(I3)=100 THEN 3340
3290 RESTORE
3300 READ N,C$
3310 IF I3<>N THEN 3300
3320 PRINT C$,
3330 PRINT TAB(30);S1(I3);TAB(50);S(I3,P)
3340 NEXT I3
3350 RESTORE
3360 RETURN
3370 PRINT CHR$(7)
3380 PRINT TAB(22);"SPECIAL ANNOUNCEMENT !!!":PRINT
3390 PRINT
3400 RETURN
3410 CLS
3420 PRINT " STAR LANES IS A GAME OF INTERSTELLAR TRADING."
3430 PRINT "THE OBJECT OF THE GAME IS TO AMASS THE GREATEST AMOUNT"
3440 PRINT "OF MONEY. THIS IS ACCOMPLISHED BY ESTABLISHING VAST,"
3450 PRINT "INTERSTELLAR SHIPPING LANES, AND PURCHASING STOCK IN"
3460 PRINT "THE COMPANIES THAT CONTROL THOSE TRADE ROUTES. DURING"
3470 PRINT "THE COURSE OF THE GAME, STOCK APPRECIATES IN VALUE AS"
3480 PRINT "THE SHIPPING COMPANIES BECOME LARGER. ALSO, SMALLER"
3490 PRINT "COMPANIES CAN BE MERGED INTO LARGER ONES, AND STOCK"
3500 PRINT "IN THE SMALLER FIRM IS CONVERTED INTO STOCK IN THE"
3510 PRINT "LARGER ONE AS DESCRIBED BELOW.":PRINT
3520 PRINT "EACH TURN, THE COMPUTER WILL PRESENT THE PLAYER WITH"
3530 PRINT "FIVE PROSPECTIVE SPACES TO OCCUPY ON A 9X12 MATRIX"
3540 PRINT "(ROWS 1-9, COLUMNS A-L). THE PLAYER, AFTER EXAMINING"
3550 PRINT "THE MAP OF THE GALAXY TO DECIDE WHICH SPACE HE WISHES"
3560 PRINT "TO OCCUPY, RESPONDS WITH THE ROW AND COLUMN OF THAT"
3570 PRINT "SPACE, I.E., 7E, 8A, ETC. THERE ARE FOUR POSSIBLE"
3580 PRINT "MOVES A PLAYER CAN MAKE.":PRINT:PRINT
3590 PRINT
3600 GOSUB 3620
3610 GOTO 3660
3620 INPUT "PRESS RETURN TO CONTINUE";X2$
3650 RETURN
3660 CLS
3670 PRINT " 1. HE CAN ESTABLISH AN UNATTACHED OUTPOST- IF HE"
3680 PRINT "SELECTS A SPACE THAT IS NOT ADJACENT TO A STAR, ANOTHER"
3690 PRINT "UNATTACHED OUTPOST, OR AN EXISTING SHIPPING LANE, THIS"
3700 PRINT "SPACE WILL BE DESIGNATED WITH A '+'. HE WILL THEN PROCEED"
3710 PRINT "WITH STOCK TRANSACTIONS, AS LISTED BELOW.":PRINT
3720 PRINT " 2. HE CAN ADD TO AN EXISTING LANE- IF HE SELECTS A"
3730 PRINT "SPACE THAT IS ADJACENT TO ONE - AND ONLY ONE EXISTING"
3740 PRINT "SHIPPING LANE, THE SPACE HE SELECTS WILL BE ADDED TO"
3750 PRINT "THAT SHIPPING LANE AND WILL BE DISIGNATED WITH THE FIRST"
3760 PRINT "LETTER OF THE COMPANY THAT OWNS THAT LANE. IF THERE ARE"
3770 PRINT "ANY STARS OR UNATTACHED OUTPOSTS ALSO ADJACENT TO THE"
3780 PRINT "SELECTED SPACE, THEY, TOO, WILL BE INCORPORATED INTO THE"
3790 PRINT "EXISTING LANE. EACH NEW SQUARE ADJACENT TO A STAR ADDS"
3800 PRINT "$500 PER SHARE, AND EACH NEW OUTPOST ADDS $100 PER SHARE"
3810 PRINT "TO THE MARKET VALUE OF THE STOCK OF THAT COMPANY."
3820 PRINT:PRINT
3830 GOSUB 3620
3840 CLS
3850 PRINT " 3. HE MAY ESTABLISH A NEW SHIPPING LANE- IF THERE"
3860 PRINT "ARE FIVE OR LESS EXISTING SHIPPING LANES ESTABLISHED,"
3870 PRINT "THE PLAYER MAY, GIVEN THE PROPER SPACE TO PLAY, ESTABLISH"
3880 PRINT "A NEW SHIPPING LANE. HE MAY DO THIS BY OCCUPYING A SPACE"
3890 PRINT "ADJACENT TO A STAR OR ANOTHER UNATTACHED OUTPOST, BUT"
3900 PRINT "NOT ADJACENT TO AN EXISTING SHIPPING LANE. IF HE"
3910 PRINT "ESTABLISHES A NEW SHIPPING LANE, HE IS AUTOMATICALLY"
3920 PRINT "ISSUED 5 SHARES KN THE NEW COMPANY AS A REWARD. HE"
3930 PRINT "MAY THEN PROCEED TO BUY STOCK IN ANY ACTIVE COMPANY,"
3940 PRINT "INCLUDKNG THE ONE JUST FORMED, AS DESCRIBED BELOW."
3950 PRINT "THG MARKET VALUE OF THE NEW STOCK IS ESTABLISHED BY"
3960 PRINT "THE NUMBER OF STARS AND OCCUPIED SPACES AS DESCRIBED"
3970 PRINT "IN #2 ABOVE."
3980 PRINT:PRINT
3990 GOSUB 3620
4000 CLS
4010 PRINT " 4. HE MAY MERGE TWO EXISTING COMPANIES- IF A PLAYER"
4020 PRINT "SELECTS A SPACE ADJACENT TO TWO EXISTING SHIPPING"
4030 PRINT "LANES, A MERGER OCCURS. THE LARGER COMPANY TAKES OVER THE"
4040 PRINT "SMALLER COMPANY - (IF BOTH COMPANIES ARE THE SAME SIZE"
4050 PRINT "PRIOR TO THE MERGER, THEN THE SURVIVOR IS DETERMINED BY"
4060 PRINT "ALPHABETICAL ORDER OF THE TWO COMPANY NAMES - THE EARLIER"
4070 PRINT "SURVIVES). THE STOCK OF THE SURVIVING COMPANY IS"
4080 PRINT "INCREASED IN VALUE ACCORDING TO THE NUMBER OF SPACES"
4090 PRINT "AND STARS ADDED TO ITS LANE. EACH PLAYERS STOCK IN"
4100 PRINT "THE DEFUNCT COMPANY IS EXCHANGED FOR SHARES KN THE"
4110 PRINT "SURVIVOR ON A RATIO OF 2 FOR 1. ALSO, EACH PLAYER"
4120 PRINT "IS PAID A CASH BONUS PROPORTIONAL TO THE PERCENTAGE"
4130 PRINT "OF OUTSTANDING STOCK HE HELD IN THE DEFUNCT COMPANY."
4140 PRINT "NOTE: AFTER A COMPANY BECOMES DEFUNCT THROUGH THE"
4150 PRINT "MERGER PROCESS, IT CAN REAPPEAR ELSEWHERE ON THE"
4160 PRINT "BOARD WHEN, AND IF, A NEW COMPANY IS ESTABLISHED."
4170 PRINT:PRINT
4180 GOSUB 3620
4190 CLS
4200 PRINT " NEXT THE COMPUTER CDDS STOCK DIVIDENDS TO THE PLAYER'S"
4210 PRINT "CASH ON HAND (5% OF THE MARKET VALUE OF THE STOCK IN HIS"
4220 PRINT "POSSESSION), AND OFFERS HIM THE OPPORTUNITY TO PURCHASE"
4230 PRINT "STOCK KN ANY OF THE ACTIVE COMPANIES ON THE BOARD."
4240 PRINT "STOCK MAY NOT BE SOLD, BUT THE MARKET VALUE OF EACH"
4250 PRINT "PLAYER'S STOCK IS TAKEN INTO ACCOUNT AT THE END OF THE"
4260 PRINT "GAME TO DETERMINE THE WINNER. IF THE OARKET VALUE OF A GIVEN"
4270 PRINT "STOCK EXCEEDS $3000 AT ANY TIME DURING THE GAME, THAT"
4280 PRINT "STOCK SPLITS 2 FOR 1. THE PRICE IS CUT IN HALF, AND"
4290 PRINT "THE NUMBER OF SHARES OWNED BY GACH PLAYER IS DOUBLED."
4300 PRINT
4310 PRINT "NOTE: THE PLAYER MAY LOOK AT HIS PORTFOLIO AT ANY TIME"
4320 PRINT "DURING THE COURSE OF HIS TURN BY RESPONDING WITH 'STOCK'"
4330 PRINT "TO AN INPUT STATEMENT. LIKEWISE, HE CAN REVIEW THE MAP"
4340 PRINT "OF THE GALAXY BY TYPING 'MAP' TO AN INPUT STATEMENT."
4350 PRINT:PRINT
4360 GOSUB 3620
4370 CLS
4380 PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT
4390 PRINT TAB(16);"** GAME ENDS AFTER 48 MOVES **"
4400 PRINT:PRINT:PRINT:PRINT
4410 PRINT "PLAYER WITH THE GREATEST NET WORTH AT THAT POINT IS THE WINNER."
4420 PRINT:PRINT
4430 FOR W=1 TO 2000:NEXT W
4440 RETURN
4450 CLS
4460 GOSUB 3370
4470 FOR W=1 TO 500:NEXT W:PRINT CHR$(7)
4480 FOR W=1 TO 500:NEXT W:PRINT CHR$(7)
4490 PRINT TAB(10)," THE GAME IS OVER - HERE ARE THE FINAL STANDINGS"
4500 PRINT:PRINT:PRINT:PRINT
4510 PRINT CHR$(7)
4520 PRINT "PLAYER";TAB(10);"CASH VALUE OF STOCK";TAB(33);"CASH ON HAND",
4530 PRINT TAB(50);"NET WORTH"
4540 PRINT
4550 FOR I=1 TO P1
4560 FOR J=1 TO 5
4570 D1(I)=D1(I)+(S1(J)*S(J,I))
4580 NEXT J
4590 NEXT I
4600 FOR I=1 TO P1
4610 GOSUB 490
4620 PRINT TAB(10);"$";D1(I);TAB(33);"$";B(I);
4630 PRINT TAB(50);"$";D1(I)+B(I)
4640 NEXT I
4650 PRINT:PRINT:PRINT:PRINT
4660 END

Oregon Trail

Oh noes!

I had just found out that the Oregon Trail game is a LOT older than the Apple II version that infested schools in the 1980’s and gave us the infamous broken axle. As a matter of fact it was first written for the HP 2100, in BASIC.

Yes the computer was the size of a wagon!

There is a most excellent blog, The Digital Antiquarian that goes over the restoration of this old gem.  Even better they managed to get it loaded up onto a timesharing image, on the internet so you can play it! (it’s been since taken offline. sorry).

You can download the source here/mirror, along with a revised 1978 version.

Directions from the site:

1. Telnet to mickey.ath.cx. (Telnet, mind you. None of that newfangled SSH!)
2. Slowly alternate CTL-J and CTL-M until you see a “PLEASE LOG IN” message.
3. Enter “HEL-T001,HP2000,1″. Without the quotes, of course — and note that those are zeroes. Oh, and the system isn’t case-sensitive, but for the authentic experience you might want to have your caps lock on.
4. Enter “GET-OREGON” to load the 1975 version, “GET-ORE2″ to load the 1978 version.
5. “LIST” the program if you like, or just “RUN” it.

You can download a working disk for the SIMH HP-2100 emulator(mirror) here/mirror.  This comes pre-loaded with the 1978 version.

HP-2100 menu

HP-2100 menu

Select option J and away you go.

It seems easier then I recall as a kid, not to mention I won the first time I played it!

Victory!

Duke 3d & the Build engine

Well I was looking at some stuff on old games, and naturally everyone always did love Duke Nukem 3D!

Now what is really cool, is that that the guy behind the build engine, Ken Silverman released the source to the ‘build’ engine, but also some of the builds of build as it progressed.

Ken is a big fan of QuickBasic, so to compile his earliest version, you’ll need QuickBasic 4.5, or the QBasic that came with MS-DOS 5.0 and above.

Download picrot4.bas, and run it through basic, and you’ll get this:

Qbasic 'Build'

Qbasic ‘Build’

Under some emulators (Virtual PC) you’ll get a corrupted screen at first, hit any of the arrow keys, and it’ll redraw the screen into what it should look like. Considering the 8kb of basic code includes the engine, and the map it’s pretty snazzy!

You can find the timeline, and other versions of the build engine as it progressed on Ken’s web page.

As the engine improved, and was ported into C, it only got better! Then it was sold and licensed out, which gave rise to great games like 3D Realms Duke Nukem!

Notice the similarities?

Notice the similarities?

After the build engine went open, 3D realms followed up, in releasing their extensive modifications to build which can be found here.

In the off chance you don’t have the game, you can still get the shareware version of it from 3D Realms here, and of course the full version on Good Old Games for $5.99 USD.

With the release of Build & Duke 3D, it’s only natural that they shed their humble MS-DOS beginnings and found their way onto Windows as full Win32 applications taking advantage of the hardware. Thanks to the work of Ken & Jonathon. You can find the results on Jonathon Fowler’s page here.

I suppose later I’ll have to see if it’ll build with the win64 tools… It’s be neat for a 64bit version of Duke!

Bywater basic

bwbasic and life.bas

bwbasic and life.bas

Well I forget what it was I was looking for, but I came across this great site, all about Vintage BASIC, and some various GAMES!

Now back in the 1970’s and early 1980’s BASIC was quite different then it is in it’s current Microsoft incarnation as Visual Basic .NET. But not all that surprising is that Microsoft was a popular BASIC distributor to the microcomputers of the time, supplying BASIC for Commodore, among others, wikipedia has a great list of all the variants of their 8 bit rommable basic.

Back in college a friend was just a little obsessed with basic (he probably still is) and he was all happy as hell to have found this little interpreter written in C, that we could run on the RS/6000 called Bywater BASIC.

Now while vintage-basic has this basic interpreter written in Haskell to run the programs, I thought I’d see if I could get some to run on Bywater.

First was picking a version, and building it. I found that version of 2.5 was the easiest to build on my NeXT, and with a minor amount of hacking, even windows.. bwbasic needs a BIG stack… so 16bit stuff is out, but I guess it doesn’t matter as they had Quick Basic, and the old MS basic so this would be redundant.

Anyways out of the examples I chose the life program, and with a few changes it’ll run on QuickBASIC as a test, and bwbasic 2.5

2 PRINT TAB(34);"LIFE"
4 PRINT TAB(15);"CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
6 PRINT: PRINT: PRINT
8 PRINT "ENTER YOUR PATTERN:"
9 X1=1: Y1=1: X2=24: Y2=70
10 DIM A(24,70),B$(24)
20 C=1
30 INPUT B$(C)
40 IF B$(C)="DONE" THEN B$(C)="": GOTO 80
50 IF LEFT$(B$(C),1)="." THEN
B$(C)=" "+RIGHT$(B$(C),LEN(B$(C))-1)
END IF
60 C=C+1
70 GOTO 30
80 C=C-1: L=0
90 FOR X=1 TO C-1
100 IF LEN(B$(X))>L THEN L=LEN(B$(X))
110 NEXT X
120 X1=11-C/2
130 Y1=33-L/2
140 FOR X=1 TO C
150 FOR Y=1 TO LEN(B$(X))
160 IF MID$(B$(X),Y,1)<>" " THEN A(X1+X,Y1+Y)=1:P=P+1
170 NEXT Y
180 NEXT X
200 PRINT: PRINT: PRINT
210 PRINT "GENERATION:";G,"POPULATION:";P;:
IF I9 THEN
PRINT "INVALID!";
END IF
215 X3=24:Y3=70:X4=1: Y4=1: P=0
220 G=G+1
225 FOR X=1 TO X1-1:
PRINT:
NEXT X
230 FOR X=X1 TO X2
240 PRINT
250 FOR Y=Y1 TO Y2
253 IF A(X,Y)=2 THEN A(X,Y)=0:GOTO 270
256 IF A(X,Y)=3 THEN A(X,Y)=1:GOTO 261
260 IF A(X,Y)<>1 THEN 270
261 PRINT TAB(Y);"*";
262 IF X<X3 THEN X3=X
264 IF X>X4 THEN X4=X
266 IF Y<Y3 THEN Y3=Y
268 IF Y>Y4 THEN Y4=Y
270 NEXT Y
290 NEXT X
295 FOR X=X2+1 TO 24:
PRINT:
NEXT X
299 X1=X3: X2=X4: Y1=Y3: Y2=Y4
301 IF X1<3 THEN X1=3:I9=-1
303 IF X2>22 THEN X2=22:I9=-1
305 IF Y1<3 THEN Y1=3:I9=-1
307 IF Y2>68 THEN Y2=68:I9=-1
309 P=0
500 FOR X=X1-1 TO X2+1
510 FOR Y=Y1-1 TO Y2+1
520 C=0
530 FOR I=X-1 TO X+1
540 FOR J=Y-1 TO Y+1
550 IF A(I,J)=1 OR A(I,J)=2 THEN C=C+1
560 NEXT J
570 NEXT I
580 IF A(X,Y)=0 THEN 610
590 IF C<3 OR C>4 THEN A(X,Y)=2: GOTO 600
595 P=P+1
600 GOTO 620
610 IF C=3 THEN A(X,Y)=3:P=P+1
620 NEXT Y
630 NEXT X
635 X1=X1-1:Y1=Y1-1:X2=X2+1:Y2=Y2+1
640 GOTO 210
650 END

You just type in some stuff as a starting pattern, then type in “DONE” on it’s own on a single line, and it’ll animate the sequence…

I should also add that the history of Bywater basic is kind of interesting it was started by Verda Spell, the grandmother of Ted Campbell who released it into the public domain.

From the original documentation:

Her (Verda’s) programming efforts were cut
tragically short when she was thrown from a Beaumont to Port
Arthur commuter train in the summer of 1986. I found the source
code to bwBASIC on a single-density Osborne diskette in her knitting
bag and eventually managed to have it all copied over to a PC
diskette. I have revised it slightly prior to this release.

NeXTSTEP audio & mod files…

Well I’ve been looking for a way to get some audio out of Quake for NeXTSTEP… and it’s incredibly complicated. I found some ‘smallish’ program for the m68k black hardware that is a MOD player, modPlayer 2.5 which also included source!

However, for me I can’t run it as the monitor to my cube is busted… But I was able to compile it to verify the source ‘works’. I then built it on my white box (P4 2.4Ghz 1GB of ram, and a real soundblaster 16!) and, after removing the reference to the decrunch routine it produced.. noise, and lots of it. But I did feel like I was getting *somewhere*.

I figure the main reason it’s exploding is that the m68k port uses the same CPU as the Amiga for these MOD files, so no doubt there is some bit flipping needed to go from big endian to little endian, but I know *nothing* about the MOD format.. So after a quick google search on basic mod players, I found qmod, a module player written in Quick Basic!!

So I looked around for a copy of Quick Basic 4.5, and tried to build the program, and it was all crash & burn.

At work we have a copy of PDS, the Professional Development System, also known as Basic 7.1 .. This thing is still useful, it will target OS/2 so you can write these massive programs (and run them under Windows 2000). So I figured I could use that to get the thing to build.. And I ran into the same errors about overflows, and all kinds of crap.

So the next thing to try was a copy of Visual Basic 1.0 for DOS that I got from ebay a while back.. I made images of the disks, which was fun, installed the thing to get.. the exact same errors. But I have to say VB for DOS was cool in that the output window can be in a windows (although text one) and you can trace and see at the same time… If only this was on store shelves in 1992!!!!

Anyways after looking at the command line options for VB for dos, I spotted this…

/Ah Enable huge dynamic arrays

I was surprised! So it would seem the answer was in the compiler, not the nice interface.. I just has ‘assumed’ that the interface would provide all the options.. Not so.

So I re-extracted the qmod source as I’d hopelessly altered it, then ‘fixed’ the one line that prevented compilation…

DEF SEG = VARSEG(mixarea(0))

I just removed that line, and ran the compiler & linker.. and it runs!

C:\TEMP>bc /Ah /O qmod.bas

Microsoft (R) Visual Basic (TM) for MS-DOS (R)
Compiler – Professional Edition Version 1.00
Copyright (C) 1982-1992 Microsoft Corporation. All rights reserved.

Object Filename [qmod.obj]:

Source Listing [nul.lst]:

42555 Bytes Available
33278 Bytes Free

0 Warning Error(s)
0 Severe Error(s)

C:\TEMP>link qmod.obj

Microsoft (R) Segmented Executable Linker Version 5.31.009 Jul 13 1992
Copyright (C) Microsoft Corp 1984-1992. All rights reserved.

Run File [qmod.exe]:
List File [nul.map]:
Libraries [.lib];
Definitions File [nul.def]:

C:\TEMP>

Now this program does require a sound blaster card, and it also requires the blaster environment variable set properly… So for Virtual PC it’s simply

SET BLASTER=A220 I5 D1 H5 T4

Then run qmod and the supplied mod file, and away it goes!

Qmod under Virtual PC

Qmod under Virtual PC

And I have to say it’s really cool to listen to this thing work, only using peek/poke (ok it’s inp/out in the new syntax…) but it’s playing the soundblaster, and it sounds GREAT.

So going back to PDS & Quick Basic 4.5 they all support the /Ah flag.. So it’ll build on any of them.

So for those who aren’t inclined to play compiler games, here is a pre-built version of Qmod, and it includes a mod file.

Now for those of you who don’t have Virtual PC, or not running on Windows, the program will run on DOSBox as well!

I just found I had to tweak the cpu config a little to make it run.. This is my CPU block in the configuration file.

[cpu]
#core=auto
core=simple
#cputype=auto
cputype=486_slow
cycles=auto
cycleup=500
cycledown=500

Now when you launch DOSBox, it’ll pick some low cpu cycle number and stay there when you launch qmod.. And it’s too low so it’ll sound horrible. So hitting CTRL+F12 will increase the cycles. Set it to 25000, and it’ll run fine. If you set it too high, CTRL+F11 will bring it down. DOSBox already sets the blaster environment variable for you, so it should ‘just work’.

From there I’d recommend sites like Amiga Music Preservation, or Mod Archive. Qmod can play quite a few of the files with the MOD extension, but not all.. But it’s a great small example program.

As luck would have it, my whitebox is having some weird boot issue, so I can’t go any further on this… But I figure I’d share this much with the world…