1  REM ***  HP BASIC PROGRAM LIBRARY  *****************************
2  REM
3  REM      BRAIN:  BRAIN SIMULATOR PROGRAM
4  REM
5  REM      36219  REV A
6  REM
7  REM ***  CONTRIBUTED PROGRAM ***********************************
11  GOTO 1020
12  FOR I=9 TO 1 STEP -1
13  PRINT #1,I
14  NEXT I
15  FOR I=1 TO 256
16  PRINT #1;0
17  NEXT I
18  PRINT #1;0
19  PRINT "MEMORY HAS BEEN CLEARED"
1010  DIM M[256],R[16],A$[4],H$[16],I$[64]
1020  H$="0123456789ABCDEF"
1100  PRINT 
1101  PRINT "TYPE 'LOAD' OR 'START' OR 'STOP'"
1110  INPUT I$
1120  IF I$="LOAD" THEN 2110
1130  IF I$="START" THEN 3010
1140  IF I$ <> "STOP" THEN 1100
1160  STOP 
2000  REM   ***   LOAD   ***
2110  PRINT 
2120  GOSUB 9800
2140  PRINT "ADDRESS  INSTRUCTIONS/DATA  COMMENTS"
2210  N=A
2220  GOSUB 9100
2225  PRINT A$[3,4];"      ";
2230  INPUT I$
2240  A1=A
2250  IF I$[1,3]="SEE" THEN 2810
2260  IF I$[1,3]="SET" THEN 2910
2270  IF I$[1,3]="END" THEN 2960
2310  FOR L=1 TO LEN(I$)
2320  IF I$[L,L]=" " THEN 2440
2330  NEXT L
2440  L=L-1
2450  IF L/4=INT(L/4) THEN 2610
2460  PRINT "NUMBER OF DIGITS IS NOT A MULTIPLE OF FOUR"
2510  PRINT "PLEASE RETYPE INSTRUCTION"
2520  A=A1
2530  GOTO 2210
2610  FOR I=1 TO L STEP 4
2620  A$=I$[I,I+3]
2630  GOSUB 9200
2640  IF N>1.E+08 THEN 2710
2650  M[A+1]=N
2660  A=A+1
2670  IF A<256 THEN 2680
2675  A=0
2680  NEXT I
2690  GOTO 2210
2710  PRINT "ILLEGAL CHARACTER IN INSTRUCTION ";A$
2720  GOTO 2510
2810  GOSUB 9400
2820  IF N>255 THEN 2510
2830  A=N
2840  I$=I$[5,6]
2845  I$[3,8]="      "
2850  M7=7
2851  IF A<249 THEN 2860
2852  M7=255-A
2860  FOR I=0 TO M7
2861  I5=I*5
2862  I$[9+I5,9+I5]=" "
2863  N=M[A+I+1]
2864  GOSUB 9100
2865  I$[10+I5,13+I5]=A$
2866  NEXT I
2870  PRINT I$
2880  GOTO 2210
2910  GOSUB 9400
2920  IF N>255 THEN 2510
2930  A=N
2940  GOTO 2210
2960  GOSUB 9400
2970  IF N>255 THEN 2510
2980  A=N
2990  GOSUB 9900
2995  GOTO 1100
3000  REM   ***   START   ***
3010  PRINT 
3012  GOSUB 9800
3016  N=A
3017  GOSUB 9100
3018  PRINT "EXECUTION BEGINS WITH INSTRUCTION AT ADDRESS ";A$[3,4]
3019  PRINT 
3020  MAT R=ZER
3025  T=0
3029  FOR Q=1 TO 10000
3030  R0=INT(M[A+1]/256)
3040  REM  E IS THE ADDRESS PORTION OF THE INSTRUCTION
3041  E=M[A+1]-256*R0
3050  REM  C IS THE OPERATION CODE
3051  C=INT(R0/16)
3060  REM  R0 IS THE REGISTER NUMBER IN THE INSTRUCTION
3061  R0=R0-16*C
3070  IF C >= 0 THEN 3090
3080  C=C+16
3090  IF C>7 THEN 3095
3091  GOTO C+1 OF 4000,4100,4200,4300,4400,4500,4600,4700
3095  GOTO C-7 OF 4800,4900,5000,5100,5200,5300,5400,5500
4000  REM  **  OUTPUT
4010  PRINT " ";M[E+1]
4020  GOTO 6210
4100  REM  **  INPUT
4110  INPUT N
4120  REM  IF N=INT(N) AND N>=-32768 AND N<=32767 THEN 4160
4121  IF N-INT(N)+SGN(32767.6-ABS(N+.5))=1 THEN 4160
4130  PRINT "INPUT MUST BE AN INTEGER BETWEEN -32768 AND 32767"
4140  PRINT "PLEASE RETYPE INPUT"
4150  GOTO 4110
4160  M[E+1]=N
4170  GOTO 6210
4200  REM  **  SUBTRACT
4210  R1=INT(E/16)
4220  T=R[R1+1]-R[E-R1*16+1]
4230  GOTO 6110
4300  REM  **  LOAD
4310  R[R0+1]=M[E+1]
4320  GOTO 6210
4400  REM  **  UNLOAD(STORE)
4410  M[E+1]=R[R0+1]
4420  GOTO 6210
4500  REM  **  MULTIPLY
4510  R1=INT(E/16)
4520  T=R[R1+1]*R[E-R1*16+1]
4530  GOTO 6110
4600  REM  **  OP-CODE 6 NOT USED
4700  REM  **  OP-CODE 7 NOT USED
4800  REM  **  OP-CODE 8 NOT USED
4900  REM  **  OP-CODE 9 NOT USED
4901  N=A
4902  GOSUB 9100
4903  PRINT "ILLEGAL OP-CODE IN INSTRUCTION AT ADDRESS ";A$[3,4]
4904  GOTO 8110
5000  REM  **  ADD
5010  R1=INT(E/16)
5020  T=R[R1+1]+R[E-R1*16+1]
5030  GOTO 6110
5100  REM  **  BRANCH
5110  N=INT(R0/2^(SGN(T)+1))
5120  REM  IF N IS EVEN AND R0<7 THEN 6210
5121  IF N/2-INT(N/2)+SGN(7-R0)=1 THEN 6210
5130  A=E
5140  GOTO 6220
5200  REM  **  COUNT
5210  N=R[R0+1]
5220  IF N=-32768. THEN 6140
5230  R[R0+1]=N-1
5240  IF N=1 THEN 6210
5250  A=E
5260  GOTO 6220
5300  REM  **  DIVIDE
5310  R1=INT(E/16)
5320  N=R[E-R1*16+1]
5330  IF N=0 THEN 5360
5340  T=INT(R[R1+1]/N)
5350  GOTO 6110
5360  N=A
5370  GOSUB 9100
5380  PRINT "ATTEMPT TO DIVIDE BY ZERO AT ADDRESS ";A$[3,4]
5390  GOTO 8110
5400  REM  **  ENTER
5410  IF E<128 THEN 5430
5420  E=E-256
5430  R[R0+1]=E
5440  GOTO 6210
5500  REM  **  HALT
5510  PRINT 
5520  N=A
5530  GOSUB 9100
5540  PRINT "HALT INSTRUCTION AT ADDRESS ";A$[3,4];" EXECUTED"
5550  GOTO 1100
6100  REM  **  CHECK FOR OVERFLOW
6110  REM  IF T>=-32768 AND T<=32767 THEN 6160
6111  IF ABS(T+.5)<32767.6 THEN 6160
6120  N=A
6130  GOSUB 9100
6140  PRINT "OVERFLOW RESULTED FROM INSTRUCTION AT ADDRESS ";A$[3,4]
6150  GOTO 8110
6160  R[R0+1]=T
6210  A=A+1
6211  IF A<256 THEN 6220
6212  A=0
6220  NEXT Q
6230  PRINT "10000 INSTRUCTIONS HAVE BEEN EXECUTED"
8100  REM  **  MEMORY DUMP
8110  PRINT 
8120  PRINT "CONTENTS OF REGISTERS"
8130  PRINT "REG   HEX   DECIMAL           REG   HEX   DECIMAL"
8140  FOR I=1 TO 8
8150  REM  IF R[I]=0 AND R[I+8]=0 THEN 8220
8151  IF ABS(R[I])+ABS(R[I+8])=0 THEN 8220
8160  N=R[I]
8170  GOSUB 9100
8180  I$=A$
8190  N=R[I+8]
8200  GOSUB 9100
8210  PRINT I-1;I$;"  ";R[I],I+7;A$;"  ";R[I+8]
8220  NEXT I
8230  PRINT 
8240  PRINT "CONTENTS OF MEMORY IN HEXADECIMAL"
8250  FOR A=0 TO 255 STEP 8
8260  FOR J=A+1 TO A+8
8270  IF M[J] <> 0 THEN 8300
8280  NEXT J
8290  GOTO 8410
8300  N=A
8310  GOSUB 9100
8320  I$=A$[3,4]
8330  I$[3,8]="      "
8340  FOR K=0 TO 7
8350  J5=K*5
8360  N=M[A+K+1]
8370  GOSUB 9100
8380  I$[9+J5,9+J5]=" "
8390  I$[10+J5,13+J5]=A$
8395  NEXT K
8400  PRINT I$
8410  NEXT A
8420  GOTO 1100
9100  REM  ***  CONVERTS N INTO 4 HEX DIGITS A$  ***
9101  A$="    "
9110  FOR J=4 TO 2 STEP -1
9111  N1=INT(N/16)
9112  H=N-N1*16+1
9113  N=N1
9114  A$[J,J]=H$[H,H]
9115  NEXT J
9120  IF N >= 0 THEN 9140
9130  N=N+16
9140  A$[1,1]=H$[N+1,N+1]
9150  RETURN 
9200  REM  ***  CONVERTS 4 HEX DIGITS A$ INTO N  ***
9210  C$=A$[1,1]
9220  GOSUB 9300
9230  IF H<0 THEN 9280
9240  IF H<8 THEN 9260
9250  H=H-16
9260  N=H
9270  FOR J=2 TO 4
9271  C$=A$[J,J]
9272  GOSUB 9300
9273  IF H<0 THEN 9280
9274  N=N*16+H
9275  NEXT J
9276  RETURN 
9280  N=1.E+09
9290  RETURN 
9300  REM  ***  CONVERTS CHARACTER C$ INTO HEX DIGIT H  ***
9310  FOR H=1 TO 16
9320  IF H$[H,H]=C$ THEN 9350
9330  NEXT H
9340  H=0
9350  H=H-1
9360  RETURN 
9400  REM  ***  SETS N TO NEW ADDRESS BY I$[4,6]
9410  IF LEN(I$)=3 THEN 9450
9420  IF I$[4,4]=" " THEN 9450
9430  IF LEN(I$)<6 THEN 9440
9431  IF I$[4,4]="-" THEN 9460
9440  N=999
9441  GOTO 9480
9450  I$[4,6]="-00"
9460  N=0
9461  A$[1,2]="00"
9462  A$[3,4]=I$[5,6]
9463  GOSUB 9270
9470  IF N<256 THEN 9490
9480  PRINT "AFTER THE THREE LETTER COMMAND SHOULD BE"
9481  PRINT "     EITHER NOTHING OR ELSE '-HH' WHERE"
9482  PRINT "     EACH H IS A HEXADECIMAL DIGIT"
9490  RETURN 
9800  REM  ***  READ M AND A FROM DISC  ***
9810  FILES MEM
9820  READ #1,1
9830  MAT  READ #1;M
9840  READ #1;A
9850  RETURN 
9900  REM  ***   PUT M AND A ONTO DISC  ***
9910  FOR I=9 TO 1 STEP -1
9920  PRINT #1,I
9930  NEXT I
9940  MAT  PRINT #1;M
9950  PRINT #1;A
9960  RETURN 
9990  END 
