1 REM================================== 2 REM MINI-COMP 3 REM RUPERT REPORT #58 4 REM A MINIMAL COMPILER FOR THE C-64 5 REM================================== 6 REM RUN 2000 TO COMPILE 7 REM================================== 8 REM 9 REM LINES 1 THROUGH 999 ARE EXAMPLES OF ALL STATEMENTS ALLOWED BY MINI-COMP 10 A=50 20 B=-10 30 C=A 40 D=A+B 50 IF A=B THEN 60 60 GOTO 70 70 PRINT 80 PRINT A 90 PRINT B; 100 PRINT CHR$(C) 110 PRINT CHR$(D); 999 END 1000 REM --- COMMON ROUTINES --- 1100 C=PEEK(M): M=M+1: PRINT C,: IF C=32 THEN 1100: REM IGNORE SPACES 1110 IF C=0 THEN PRINT 1120 RETURN 1300 VF=TRUE: IF C<65 OR C>90 THEN VF=FALSE: RETURN 1310 AD=(C-65)*2 + VM 1320 NX=AD: GOSUB 1400: A0=NL: A1=NH : REM VAR LSB 1330 NX=AD+1: GOSUB 1400: A2=NL: A3=NH : REM VAR MSB 1340 RETURN 1400 NH=INT(NX/256) 1410 NL=NX-256*NH 1420 RETURN 1500 FOR KK=1 TO N 1510 IF CM>EM THEN PRINT"OUT OF MEMORY - COMPILED PRGM TOO LARGE": END 1520 POKE CM,C(KK) 1530 PRINT CM;":";C(KK) 1540 CM=CM+1: NEXT 1550 RETURN 2000 REM ====== INITIALIZATION ========= 2010 DIM LL(50,2) :REM LL(N,1)=LINE # OF NTH LINE 2015 :REM LL(N,2)=COMPILED MEM LOCATION OF THIS LINE 2020 DIM C(50) :REM STORES OBJECT CODE BYTES 2030 FALSE=0: TRUE=NOT FALSE 2040 DEF FNPTR(M)=PEEK(M)+256*PEEK(M+1) 2050 VM=49152 :REM $C000 START OF VARIABLE MEM 2060 PM=49408 :REM $C100 START OF OBJECT MEMORY 2070 EM=53247 :REM $CFFF END OF OBJECT MEMORY 2080 BT=2049 :REM $0800 START OF BASIC TEXT 2085 GOSUB 11000 :REM PUT PRINT RTN IN MEM 2090 M=BT :REM NEXT SOURCE MEMORY TO PEEK 2100 SN=1 :REM CURRENT SOURCE STATEMENT NUMBER 2110 CM=PM :REM NEXT OBJECT MEMORY TO POKE 2120 FOR N=VM TO VM+51: POKE N,0: NEXT : REM CLR VAR'S 2125 REM ============= MAIN ============ 2130 PTR=FNPTR(M): M=M+2 :REM NEXT LINE PTR 2140 LN=FNPTR(M): M=M+2 :REM CURRENT LINE # 2150 IF LN>999 THEN PRINT "=== END OF PASS 1 ===": GOTO 2400 2160 PRINT " CURRENT LINE # ="; LN 2170 LL(SN,1)=LN :REM CURRENT LINE # 2180 LL(SN,2)=CM :REM START OBJ MEM LOC 2190 SN=SN+1 :REM # SOURCE STATEMENTS 2200 REM --- GET BYTE --- 2210 GOSUB 1100 :REM FETCH NEXT BYTE 2220 GOSUB 1300: IF VF THEN GOSUB 3000 : GOTO 2290: REM 'VARIABLE 2230 IF C=139 THEN GOSUB 4000: GOTO 2290: REM 'IF 2240 IF C=137 THEN GOSUB 5000: GOTO 2290: REM 'GOTO 2250 IF C=153 THEN GOSUB 6000: GOTO 2290: REM 'PRINT 2260 IF C=128 THEN GOSUB 7000: GOTO 2290: REM 'END 2270 IF C=143 THEN GOSUB 8000: GOTO 2290: REM 'REM 2280 PRINT "UNKNOWN COMMAND CODE";C;"IN LINE";LL(SN,1):STOP 2290 IF C>0 THEN EC=0: GOSUB 10000: STOP :REM 'EOL 2300 GET K$:IF K$="" THEN 2130 :REM BACK FOR MORE 2310 GET K$:IF K$="" THEN 2310 2320 GOTO 2130 2400 REM - PASS 2 - FIX JUMP ADDRESSES 2410 IF JI=0 THEN 2570 :REM NO JUMPS 2420 FOR N=1 TO JI :REM CHECK ITEMS IN JUMP TABLE 2430 :MM=JT(N,1) :REM REFERENCED LINE # 2440 :FOR J=1 TO SN :REM CHECK ACTUAL LINE #S 2445 :REM - GET OBJ MEM TARGET ADDRESS AND JMP ADDRESS: 2450 :IF MM=LL(J,1) THEN TADDR=JT(N,2): JADDR=LL(J,2): GOTO 2490 2460 :NEXT J 2470 :REM NO MATCH FOUND 2480 :EC=1: LN=JT(N,0): GOSUB 10000:STOP 2490 :NX=JADDR :REM ADDR OF LINE # MM 2530 :GOSUB 1400 :REM CONVERT LINE # 2540 :POKE TADDR,NL :REM USE ADDR IN JUMP TABLE 2550 :POKE TADDR+1,NH 2560 NEXT N :REM NEXT JUMP TABLE ITEM 2570 PRINT"=== END OF PASS 2 ===" 2580 PRINT"TO EXECUTE THE COMPILED PROGRAM, ENTER" 2590 PRINT" SYS"; PM 2595 PRINT"OBJECT CODE RESIDES FROM";PM;"TO";CM-1 2600 END 3000 REM <<< A=(-)NN, A=B, A=B+C >>> 3010 D0=A0: D1=A1 :REM ADDR OF A'S LSB 3020 D2=A2: D3=A3 :REM A'S MSB 3030 GOSUB 1100: IF C<>178 THEN EC=178: EC$=" = ": GOSUB 10000: STOP :REM '= 3040 GOSUB 1100 :REM '-, NN, OR B 3050 GOSUB 1300: IF VF THEN 3400 :REM 'B 3055 REM <<< A=(-)NN >>> 3060 IF C=171 THEN C$="-" :REM '- 3065 IF C<>171 THEN C$=" "+CHR$(C) :REM '0-9 3070 GOSUB 1100 :REM GET DIGITS OF NN 3080 IF C=0 THEN 3120 3085 IF CHR$(C)<"0" OR CHR$(C)>"9" THEN EC=48: GOSUB 10000: STOP 3090 C$=C$+CHR$(C) 3100 GOTO 3070 3120 NN=VAL(C$) 3130 NN%=NN :REM ERROR CHECK 3140 IF NN<0 THEN NN=NN+65536 :REM CONVERT (-32768,32767) TO (0,65535) 3150 NX=NN: GOSUB 1400 3170 MSB=NH: LSB=NL 3175 :REM LDA #NN(LSB), STA A(LSB), LDA #NN(MSB), STA A(MSB) 3180 N=10: C(1)=169: C(2)=LSB: C(3)=141: C(4)=D0: C(5)=D1 3190 C(6)=169: C(7)=MSB: C(8)=141: C(9)=D2: C(10)=D3 3200 GOSUB 1500 :REM POKE VALUES INTO OBJECT MEMORY 3210 RETURN 3400 REM <<< A=B OR A=B+C >>> 3410 S0=A0: S1=A1 :REM B'S LSB ADDR 3420 S2=A2: S3=A3 :REM B'S MSB 3430 GOSUB 1100 3440 IF C=0 THEN 3600 :REM A=B 3450 REM <<< A=B+C >>> 3460 IF C<>170 THEN EC=170: EC$=" + ": GOSUB 10000: STOP :REM TEST '+ 3470 GOSUB 1100: GOSUB 1300: IF NOT VF THEN EC=65: GOSUB 10000: STOP: REM 'C 3480 GOSUB 1100: IF C>0 THEN EC=0: GOSUB 10000: STOP :REM 'EOL 3490 S4=A0: S5=A1 :REM ADDR C'S LSB 3500 S6=A2: S7=A3 :REM C'S MSB 3530 REM CLC, LDA B(LSB), ADC C(LSB),STA A(LSB) 3535 REM LDA B(MSB), ADC C(MSB), STA A(MSB) 3540 N=19: C(1)=24: C(2)=173: C(3)=S0: C(4)=S1 3550 C(5)=109: C(6)=S4: C(7)=S5: C(8)=141: C(9)=D0: C(10)=D1 3560 C(11)=173: C(12)=S2: C(13)=S3: C(14)=109: C(15)=S6: C(16)=S7 3570 C(17)=141: C(18)=D2: C(19)=D3 3580 GOSUB 1500 3590 RETURN 3600 REM <<< A=B >>> 3610 REM LDA B(LSB), STA A(LSB), LDA B(MSB), STA A(MSB) 3620 N=12: C(1)=173: C(2)=S0: C(3)=S1: C(4)=141: C(5)=D0: C(6)=D1 3630 C(7)=173: C(8)=S2: C(9)=S3: C(10)=141: C(11)=D2: C(12)=D3 3640 GOSUB 1500 3650 RETURN 4000 REM <<< IF A=B THEN MM >>> 4010 GOSUB 1100 :REM 'A 4020 GOSUB 1300: IF NOT VF THEN EC=65: GOSUB 10000: STOP 4030 S0=A0: S1=A1: S2=A2: S3=A3 4040 GOSUB 1100: IF C<>178 THEN EC=178: GOSUB 10000: STOP :REM '= 4050 GOSUB 1100 :REM 'B 4060 GOSUB 1300: IF NOT VF THEN EC=65: GOSUB 10000: STOP 4070 GOSUB 1100 :REM 'THEN 4080 IF C<>167 THEN EC=167: GOSUB 10000: STOP 4090 C$="" 4100 GOSUB 1100: IF C=0 THEN 4120 :REM GET MM 4110 C$=C$+CHR$(C): GOTO 4100 4120 MM=VAL(C$) 4130 IF MM<0 OR MM>999 THEN EC=1: GOSUB 10000: STOP 4140 JI=JI+1 :REM JUMP TABLE INDEX 4150 JT(JI,0)=LN :REM CURRENT LINE # 4160 JT(JI,1)=MM :REM TARGET LINE # 4170 JT(JI,2)=CM+17 :REM MEM LOC AFTER 'JMP 4180 REM LDA A(MSB), CMP B(MSB), BNE EXIT, 4185 REM LDA A(LSB), CMP B(LSB), BNE EXIT, JMP MM 4190 N=19: C(1)=173: C(2)=S2: C(3)=S3 4200 C(4)=205: C(5)=A2: C(6)=A3 4210 C(7)=208: C(8)=11: C(9)=173: C(10)=S0: C(11)=S1 4220 C(12)=205: C(13)=A0: C(14)=A1 4230 C(15)=208: C(16)=3: C(17)=76: C(18)=0: C(19)=0 4240 GOSUB 1500 4250 RETURN 5000 REM <<< GOTO MM >>> 5010 C$="" 5020 GOSUB 1100: REM GET DIGITS OF MM 5030 IF C=0 THEN 5060 5040 C$=C$+CHR$(C) 5050 GOTO 5020 5060 MM=VAL(C$) 5070 IF MM<0 OR MM>999 THEN EC=1: GOSUB 10000: STOP 5080 JI=JI+1 :REM JUMP TABLE INDEX 5085 JT(JI,0)=LN :REM SOURCE LINE# 5090 JT(JI,1)=MM :REM TARGET LINE# 5100 JT(JI,2)=CM+1 :REM OBJ MEM LOCATION AFTER 'JMP' 5110 REM JMP MM 5120 N=3: C(1)=76: C(2)=0: C(3)=0 5130 GOSUB 1500 5140 RETURN 6000 REM <<< PRINT, PRINT A[;], OR PRINT CHR$(A)[;] >>> 6010 GOSUB 1100: IF C=199 THEN 6300 :REM 'CHR$ 6020 IF C=0 THEN PC=13: GOSUB 6200: RETURN: REM 'PRINT 6030 GOSUB 1300: IF NOT VF THEN EC=65: GOSUB 10000: STOP 6040 REM <<< PRINT A >>> 6050 REM LDX $A(MSB), LDY $A(LSB), JSR $C0E0 6060 PRINT: N=9: C(1)=174: C(2)=A0: C(3)=A1 6070 C(4)=172: C(5)=A2: C(6)=A3 6080 C(7)=32: C(8)=224: C(9)=192 6090 GOSUB 1500 6095 PC=32: GOSUB 6200 :REM ADD SPACE AFTER DIGITS 6100 GOSUB 1100: IF C=0 THEN PC=13: GOSUB 6200: RETURN :REM PRINT CR 6110 IF C<>59 THEN EC=59: GOSUB 10000: STOP :REM ' ; 6120 GOSUB 1100: IF C>0 THEN EC=0: GOSUB 10000: STOP 6130 RETURN 6200 REM --- PRINT CHARACTER PC --- 6210 REM LDA #PC, JSR $FFD2 6220 PRINT:N=5: C(1)=169: C(2)=PC: C(3)=32 6230 C(4)=210: C(5)=255: GOSUB 1500 6240 RETURN 6300 REM <<< PRINT CHR$(A) [;] >>> 6310 GOSUB 1100: IF C<>40 THEN EC=40: GOSUB 10000: STOP :REM '( 6320 GOSUB 1100: GOSUB 1300: IF NOT VF THEN EC=65: GOSUB 10000: STOP 6330 REM LDA A(LSB), JSR $FFD2 6340 PRINT: N=6: C(1)=173: C(2)=A0: C(3)=A1 6350 C(4)=32: C(5)=210: C(6)=255 6360 GOSUB 1500 6370 GOSUB 1100: IF C<>41 THEN EC=41: GOSUB 10000: STOP : REM ') 6380 GOSUB 1100: IF C>0 THEN 6400 6390 PRINT: PC=13: GOSUB 6200: RETURN 6400 IF C<>59 THEN EC=59: GOSUB 10000: STOP :REM '; 6410 GOSUB 1100: IF C<>0 THEN EC=0:GOSUB 10000: STOP 6420 RETURN 7000 REM <<< END >>> 7005 REM RTS 7010 N=1: C(1)=96: GOSUB 1500 7020 GOSUB 1100: IF C<>0 THEN EC=0:GOSUB 10000: STOP 7030 RETURN 8000 REM <<< REM >>> 8010 GOSUB 1100: IF C>0 THEN 8010 8020 RETURN 10000 PRINT:PRINT"SYNTAX ERROR IN LINE[146]";LN 10010 IF EC=0 THEN PRINT"EXPECTED END-OF-LINE NOT FOUND":RETURN 10020 IF EC=1 THEN PRINT"INVALID LINE NUMBER":RETURN 10030 IF EC=48 THEN PRINT"NUMERIC VALUE 0-9 EXPECTED": RETURN 10040 IF EC=65 THEN PRINT"VARIABLE A-Z EXPECTED": RETURN 10050 IF EC>127 THEN PRINT"EXPECTED BASIC KEYWORD ";EC$: RETURN 10060 PRINT"EXPECTED CHARACTER ";CHR$(EC);" WITH ASCII VALUE"EC :RETURN 11000 REM -- PUT M.L. PRINT ROUTINE INTO MEMORY -- 11010 M=49376 :REM $C0E0 11020 CS=3319 :REM CHECKSUM 11030 READ B: IF B<0 THEN 11060 11040 POKE M,B: M=M+1: CK=CK+B 11050 GOTO 11030 11060 IF CK<>CS THEN PRINT"ERROR IN DATA STATEMENTS STARTING AT 11120":STOP 11070 RETURN 11080 DATA 169, 32, 200, 136, 16, 2 11090 DATA 169, 45, 32, 210, 255, 152, 16, 12 11100 DATA 138, 73, 255, 24, 105, 1, 170, 152 11110 DATA 73, 255, 105, 0, 32, 205, 189, 96 11120 DATA -1