10 ;VERSION OF OHIO SCIENTIFIC 6500 ASSEMBLER/EDITOR 20 ;WITH MODIFICATION TO REDUCE MEMORY USAGE, BUT 30 ;WITH P-CODE INTERPRETER WRITTEN IN 6502 CODE. 40 ; 50 ;UK101 MONITOR SUBROUTINES USED BY ASSEMBLER: 60 CIN = $FFEB ;GET CHARACTER FROM KEYBOARD 70 COUT = $FFEE ;PRINT CHARACTER 80 LOAD = $FFF4 ;SET LOAD FLAG 90 SAVE = $FFF7 ;SET SAVE FLAG 100 ; 110 ;VARIABLES IN ZERO PAGE ;16 BITS 120 ;UNLESS STATE OTHERWISE 130 ;"*" INDICATES THAT LABEL UPDATED IN PROG BODY 140 LABTBL = $0A ;START OF LABEL TABLE 150 TXTPOS = $10 ;CURRENT POSITION IN TEXT 160 LINLEN = $12 ;LENGTH OF CURRENT SOURCE LINE 170 LINENO = $14 ;LINE NUMBER DURING ASSEMBLY 180 STTEXT = $16 ;START OF TEXT MEMORY 190 ENDMEM = $18 ;END OF AVAILABLE MEMORY 200 ENDTXT = $1A ;END OF SOURCE TEXT 210 ;DRTYPE USED FOR OTHER FUNCTIONS THAN DIRECTIVES 220 DRTYPE = $1E ;(8 BITS) 0=.END, 1=.BYT, 2=.WOR, 3= 230 IP = $24 ;INTERPRETIVE POINTER FOR P-CODE 240 INSLEN = $2A ;PCODE INSTR LEN (8-BIT) 250 CONST0 = $2C ;PERMANENTLY SET TO ZERO 260 CNST14 = $38 ;PREMANENTLY SET TO $0014 270 CNST10 = $3C ;PERMANENTLY SET TO 10 280 ASMBRK = $3E ;SET TO 1 IF ASM ADDR CHANGES 290 PASS = $40 ;ASSEMBLY PASS (1 OR 2) 300 CONST1 = $42 ;PERMANENTLY SET TO 1 310 ASMADR = $44 ;ASSEMBLY ADDRESS 320 ASMOPT = $48 ;ASSEMBLY OPTION (0, 1, 2 OR 3) 330 CONST3 = $4A ;PERMANENTLY SET TO 3 340 INSTLN = $4C ;NUMBER OF BYTES IN CURRENT INSTRUCT 350 NOPBYT = $4E ;PERMANENTLY SET TO $EAEA 360 INSTRN = $50 ;CURRENT INSTRUCTION (3 BYTES) 370 CNST80 = $58 ;PERMANENTLY SET TO $80 380 BUFADR = $68 ;START ADDR OF CODE IN A2 BUFFER 390 NUMVAL = $6A ;NUMERIC VALUE FROM EXPRESSION 400 LABL40 = $6C ;LABEL IN BASE-40 (4 BYTES) 410 ASMOFS = $70 ;OFFSET FOR ASSEMBLY TO MEMORY 420 CNST50 = $72 ;PERMANENTLY SET TO $0050 430 CONST2 = $74 ;PERMANENTLY SET TO 2 440 CNST12 = $76 ;PERMANENTLY SET TO 12 450 CNST7E = $78 ;PERMANENTLY SET TO $007E 460 CNST6C = $7A ;PERMANENTLY SET TO $006C 470 LABVAL = $7E ;VALUE OF LABEL 480 A2BUFF = $B8 ;18 BYTES BUFFER FOR A2 (TO $CF) 490 A2BLEN = $D1 ;LENGTH OF BUFFER FOR A2 500 CHKSUM = $D2 ;CHECKSUM FOR A2 OPTION 510 CNST44 = $D4 ;PERMANENTLY SET TO $0044 520 NUMERR = $E2 ;NUMBER OF CURRENT ERRORS 530 TMPLOC = $E6 ;TEMPORARY STORAGE 540 CONST4 = $EA ;PERMANENTLY SET TO 4 550 PRFLAG = $F0 ;IF 1, SOURCE LINE WAS PRINTED 560 CONST5 = $F2 ;PERMANENTLY SET TO 5 570 CONST6 = $F4 ;PERMANENTLY SET TO 6 580 ERRMSG = $F6 ;CURRENT ERRORS (4 BYTES) 590 CALADR = $FA ;ADDRESS OF CALLING INSTR 600 ; 610 ;DEFINITIONS OF P-CODE MNEMONICS 620 NXLN = $00 ;USED BY LINE EDITOR 630 BMOV = $01 ;XX=LEN, YY=SRC, ZZ=DST 640 LIN1 = $02 ;USED BY LINE EDITOR 650 CLAS = $03 ;CLASSIFY CHARACTER 660 LRAN = $04 ;DECODE LINE NUMBER RANGE 670 SKIP = $05 ;SKIP SPACES 680 LVAL = $06 ;LOOK UP LABEL AS LVALUE 690 LEXP = $07 ;LOOK UP LABEL IN EXPRESSION 700 OUTP = $08 ;OUTPUT ASSEMBLER INSTRUCTION 710 EXPR = $09 ;EVALUATE EXPRESSION 720 RLBL = $0A ;READ LABEL 730 BRGR = $2B ;BRANCH IF XX>YY 740 BEQU = $4B ;BRANCH IF XX=YY 750 BGEQ = $6B ;BRANCH IF XX>=YY 760 BLES = $8B ;BRANCH IF XXYY 780 BLEQ = $CB ;BRANCH IF XX<=YY 790 COMP = $0C ;COMPRESS SOURCE CODE 800 KBLN = $0D ;READ LINE FROM KEYBOARD 810 RET4 = $0E ;RETURN USING OFFSET IN 4TH BYTE 820 SET0 = $0F ;SET XX TO 0 830 DCIN = $10 ;INPUT DECIMAL NUMBER 840 RETN = $11 ;RETURN FROM P-CODE SUBROUTINE 850 RET2 = $12 ;RETURN USING OFFSET IN 2ND BYTE 860 INCR = $13 ;INCREMENT XX 870 DECR = $14 ;DECREMENT XX 880 EX65 = $15 ;EXECUTE 6502 CODE 890 COPY = $16 ;COPY XX TO YY 900 PHEX = $17 ;PRINT XX AS HEX NUMBER 910 RERR = $18 ;RECORD ERROR XX 920 PDEC = $19 ;PRINT DECIMAL NUMBER IN XX 930 PLIN = $1B ;PRINT LINE POINTED TO BY XX 940 GERR = $1C ;GET ERROR CODE AND PUT IT IN XX 950 PERR = $1D ;PRINT PTR TO ERROR PLUS MESSAGE 960 MSLN = $1E ;PRINT NEW LINE PLUS MESSAGE 970 PER6 = $1F ;AS FOR PERR BUT INCR $06 FIRST 980 SUBZ = $20 ;SUBTRACT: ZZ = XX - YY 990 ADDZ = $21 ;ADD: ZZ = XX + YY 1000 MOVB = $22 ;MOVE BYTE IN (00) TO (XX) 1010 DCMP = $23 ;DECOMP LINE AT (10); STORE IN (02) 1020 MESG = $24 ;PRINT MESSAGE WITHOUT NEW LINE 1030 RET3 = $25 ;RETURN USING OFFTSET IN 3RD BYTE 1040 CHK0 = $65 ;CHECK CHAR WITH PTR AT 00/01 1050 CHK6 = $10 ;CHECK CHAR WITH PTR AT 06/07 1060 INC0 = $28 ;INCREMENT 00/01 1070 SET1 = $29 ;SET XX TO 1 1080 ; 1090 ;CODES FOR USE WITH CHK0 OPCODE: 1100 CAP = $80 1110 DCM = $81 1120 SPC = $82 1130 ; 1140 HIMEM = $1FFF ;TOP OF AVAILABLE MEMORY 1150 ;MAIN ENTRY POINT FOR ASSEMBLER 1160 *=$0240 ;START AT $0240 FOR UK101 1170 ;INITIALISE STACK POINTER 1180 LDX #$FF 1190 TXS 1200 ; 1210 ;SET ALL OF ZERO PAGE TO 00 1220 INX ;X = 0 1230 TXA ;A = 0 1240 INITZP STA $00,X 1250 INX 1260 BNE INITZP 1270 ; 1280 ;INITIALISE LOCATIONS IN ZERO PAGE, USING 1290 ;ADDRESSES STARTING AT ZPADDR AND CONTENTS 1300 ;STARTING AT ZPCONT 1310 L1168 LDY ZPADDR,X 1320 LDA ZPCONT,X 1330 STA $0000,Y 1340 INX 1350 CPX #ZPCONT-ZPADDR ;LENGTH OF TABLE 1360 BNE L1168 1370 ; 1380 ;MAIN P-CODE INSTRUCTION EXECUTION LOOP 1390 L1179 LDA ENDTXT ;UPDATE RECORD OF END OF TEXT 1400 STA ENDIMG 1410 LDA ENDTXT+1 1420 STA ENDIMG+1 1430 ;GET OPCODE - X IS OPCODE ACTUALLY EXECUTED 1440 LDY #$00 1450 LDA (IP),Y 1460 LDX #$1A 1470 CMP #$E8 1480 BCS LDADDR 1490 LDX #$0B 1500 AND #$1F 1510 CMP #$0B 1520 BEQ LDADDR 1530 LDA (IP),Y 1540 LDX #$26 1550 CMP #$72 1560 BCS LDADDR 1570 INX 1580 CMP #$3A 1590 BCS LDADDR 1600 TAX 1610 ; 1620 ;X NOW CONTAINS OPCODE TO EXECUTE, SO 1630 ;SET TMPLOC/TMPLOC+1 TO OPCODE ROUTINE 1640 LDADDR LDA ADDRLO,X 1650 STA TMPLOC 1660 LDA ADDRHI,X 1670 PHA 1680 AND #%00001111 1690 CLC 1700 ADC #OF6502/256 1710 STA TMPLOC+1 1720 ; 1730 ;PUT LENGTH OF INSTRUCTION INTO INSLEN 1740 PLA 1750 LSR A 1760 LSR A 1770 LSR A 1780 LSR A 1790 STA INSLEN 1800 ; 1810 ;GO TO L11B7 IF OPCODE IS ITSELF WRITTEN IN 1820 ;P-CODE (OPCODES 00,...,0A) 1830 CPX #$0B 1840 BCC L11B7 1850 INY ;Y = 1 1860 LDA (IP),Y ;A = 2ND BYTE OF INSTRUCTION 1870 LDX #0 ;X = 0 1880 ;EXECUTE OPCODE ;A = 2ND BYTE OF INSTRUCTION 1890 ;X=0, Y=1, C=1, AND Z=1 1900 JMP (TMPLOC) 1910 ; 1920 ;OPCODE IS LESS THAN $0B, SO THE ROUTINE IS 1930 ;NOT IN 6502 MACHINE CODE, BUT IN P-CODE. 1940 L11B7 LDA INSLEN 1950 PHA ;PUSH LENGTH OF INSTRUCTION 1960 LDA IP+1 ;AND PUSH RETURN ADDRESS 1970 ;STORE CALL ADDRESS 1980 STA CALADR+1 1990 PHA 2000 LDA IP 2010 STA CALADR 2020 PHA 2030 LDX TMPLOC 2040 LDA TMPLOC+1 2050 L11CA STX IP 2060 STA IP+1 2070 BNE L1179 ;ALWAYS BRANCHES - GO BACK TO EXE 2080 ; 2090 OF6502=*/256*256 2100 ;OPCODE $14 XX 2110 ;DECREMENT 16-BIT VALUE IN XX/XX+1 2120 L02DC LDY #$FF 2130 CLC 2140 .BYTE $2C 2150 ; 2160 ;OPCODE $13 XX 2170 ;INCREMENT 16-BIT VALUE IN XX/XX+1 2180 L02D0 TAX 2190 ; 2200 ;OPCODE $28 2210 ;INCREMENT 16-BIT VALUE IN 00/01 2220 L11CE DEY 2230 TYA 2240 ADC $00,X 2250 PHA 2260 TYA 2270 ADC $01,X 2280 PULLZP STA $01,X 2290 PLA 2300 STA $00,X 2310 ;ADD INSTRUCTION LENGTH ONTO INTERPRETIVE POINTER 2320 ;THEN EXECUTE NEXT INSTRUCTION 2330 L11CF LDA INSLEN 2340 BNE L02AA ;ALWAYS BRANCHES 2350 ;EXECUTE P-CODE - PULL ADDRESS OFF STACK 2360 L11DC PLA 2370 STA IP 2380 PLA 2390 STA IP+1 2400 LDA #$01 2410 BNE L02AA 2420 DELCHR TYA 2430 BEQ L020C 2440 LDA #$08 2450 JSR COUT 2460 LDA #$20 2470 JSR COUT 2480 LDA #$08 2490 JSR COUT 2500 ; 2510 ;OPCODE $0D 2520 ;INPUT LINE OF TEXT FROM THE KEYBOARD. 2530 ;START ADDRESS OF LINE IS HELD IN $02/$03, 2540 ;AND MAXIMUM LENGTH OF LINE IS 56 CHARACTERS 2550 L0205 DEY 2560 ;GET A CHARACTER FROM THE KEYBOARD 2570 L020C JSR CIN 2580 CMP #$1C 2590 BEQ DELCHR 2600 STA ($02),Y 2610 CMP #$0D 2620 BEQ L0235 2630 CPY #$37 2640 BEQ L020C 2650 CMP #$20 2660 BMI L020C 2670 JSR COUT 2680 L0229 INY 2690 BNE L020C 2700 L0235 JSR COUT 2710 LDA $02 2720 STA $00 2730 BNE JL11CF ;ALWAYS BRANCHES 2740 ; 2750 ;OPCODE $27 YY 2760 ;CHECKS NEXT CHARACTER IN TEXT, 2770 ;USING POINTER AT $06/$07 2780 ;THE OPCODE $27 DOES NOT APPEAR IN THE CODE 2790 ;XX IS THE OPCODE MINUS $10 FOR OPCODE $27, 2800 ;AND THE OPCODE MINUS $65 FOR OPCODE $26 2810 ;IF XX < $80 IT CHECKS FOR CHARACTER XX 2820 ;IF XX = $80 (CAP), CHECKS FOR A CAPITAL LETTER 2830 ;IF XX = $81 (DEC), CHECKS FOR A DECIMAL DIGIT 2840 ;IF XX = $82 (SPC), CHECKS FOR CONTROL CHAR OR SP 2850 ;THE SECOND BYTE, YY, IS THE BRANCH OFFSET 2860 L0244 LDX #$06 ;X IDENTIFIES TEXT POINTER 2870 ;$EF IS THE COMPLEMENT OF $10, BUT MINUS 2880 ;1 BECAUSE THE CARRY FLAG IS ALWAYS SET 2890 LDA #$EF 2900 .BYTE $2C 2910 ; 2920 ;OPCODE $26 - INSTRUCTION LENGTH = 2 2930 ;SAME AS OPCODE $27 BUT USES POINTER AT $00/$01 2940 ;X HAS BEEN SET TO ZERO ANYWAY 2950 ;SECOND BYTE IS RELATIVE BRANCH OFFSET 2960 ;THE OPCODE $26 DOES NOT APPEAR IN THE CODE 2970 ;$9A IS THE COMPLEMENT OF $65, BUT MINUS 2980 ;1 BECAUSE THE CARRY FLAG IS ALWAYS SET 2990 L0240 LDA #$9A 3000 DEY 3010 ADC (IP),Y 3020 BMI L0256 3030 EOR ($00,X) 3040 BNE JL11CF ;GO ON TO NEXT INSTRUCTION 3050 ;BRANCH USING SECOND BYTE OF INSTRUCTION 3060 L0251 LDY #$01 3070 BNE L0284 ;ALWAYS BRANCHES 3080 ; 3090 ;OPCODES $0E, $25 AND $12 - INSTR LEN = 1 3100 OP1203 INY ;4TH BYTE OF CALL IS BRANCH OFFSET 3110 OP1202 INY ;3RD BYTE OF CALL IS BRANCH OFFSET 3120 OP1201 INX ;2ND BYTE OF CALL IS BRANCH OFFSET 3130 ; 3140 ;OPCODE $11 - INSTRUCTION LENGTH = 1 3150 ;RETURN FROM P-CODE SUBROUTINE 3160 L02BC PLA 3170 STA IP 3180 PLA 3190 STA IP+1 3200 PLA 3210 DEX 3220 BMI L02AA ;NEXT INSTRUCTION IF NO BRANCH 3230 ;RELATIVE BRANCH, WHERE Y INDEXES THE SIGNED 3240 ;8-BIT OFFSET 3250 L0284 LDA (IP),Y 3260 TAX 3270 CLC 3280 ADC IP 3290 STA IP 3300 TXA 3310 AND #$80 3320 BEQ L0295 3330 LDA #$FF 3340 L0295 ADC IP+1 3350 STA IP+1 3360 ;ADD Y REGISTER ONTO INTERPRETIVE POINTER 3370 ;THEN CONTINUE WITH P-CODE EXECUTION 3380 L02A9 TYA 3390 L02AA CLC 3400 ADC IP 3410 STA IP 3420 BCC L1220 3430 INC IP+1 3440 L1220 JMP L1179 ;GO TO EXECUTE NEXT INSTRUCTION 3450 ;SEE IF THE NEXT CHARACTER FORM THE SOURCE CODE I 3460 ;A=$80 = CAPITAL LETTER 3470 ;A=$81 = DECIMAL DIGIT 3480 ;A=$82 = CONTROL CHARACTER (LESS THAN $20) OR SPA 3490 L0256 TAY 3500 LDA ($00,X) 3510 CMP L0267-$80,Y 3520 BMI JL11CF 3530 CMP L026B-$80,Y 3540 BMI L0251 3550 BPL JL11CF 3560 L0267 .BYTE $41,$30,$00 3570 L026B .BYTE $5B,$3A,$21 3580 ; 3590 ;OPCODE $16 XX YY 3600 ;COPY 16-BIT NUMBER FROM XX/XX+1 TO YY/YY+1 3610 ;IF MSB OF XX IS SET, IT INDEXES CALLING P-CODE 3620 L0270 JSR L04A0 ;GET NEXT ARGUMENT IN LIST 3630 BCS COPY16 ;ALWAYS BRANCHES 3640 ; 3650 ;OPCODES $0F YY AND $29 FF 3660 ;LOCATIONS CONST0 AND CONST01 ARE PERMANENTLY 3670 ;TO 0 AND 1 RESPECTIVELY 3680 CODE0F LDX #CONST0 3690 .BYTE $2C 3700 CODE29 LDX #CONST1 3710 TAY ;2ND BYTE OF INSTR TO Y 3720 COPY16 LDA $00,X 3730 STA $0000,Y 3740 LDA $01,X 3750 STA $0001,Y 3760 JL11CF JMP L11CF ;EXECUTE NEXT INSTRUCTION 3770 ; 3780 ;OPCODE $1A 3790 ;P-CODE JUMP INSTRUCTION ;REPRESENTED IN THE CODE 3800 ;ITSELF AS JUMP ADDRESS MINUS START OF ASSEMBLER 3810 ;$E800, IN THE FORMAT OF HIGH BYTE FOLLOWED BY LO 3820 L029C TAX 3830 DEY 3840 LDA (IP),Y 3850 CMP #$FA 3860 BCC LITAD 3870 TAY 3880 LDX ADRLO-$FA,Y 3890 LDA ADRHI-$FA,Y 3900 SCONST = OFFSET/256-1 3910 LITAD SBC #SCONST 3920 LSTAD JMP L11CA 3930 ADRLO .BYTE L08B7,L0CDC,L0D11 3940 .BYTE L0620,L08E6,LINOUT 3950 ADRHI .BYTE L08B7/256+SCONST 3960 .BYTE L0CDC/256+SCONST 3970 .BYTE L0D11/256+SCONST 3980 .BYTE L0620/256+SCONST 3990 .BYTE L08E6/256+SCONST 4000 .BYTE LINOUT/256+SCONST 4010 ; 4020 ;OPCODE $15 - INSTRUCTION LENGTH = 1 4030 ;RETURN TO EXECUTING 6502 MACHINE CODE 4040 ;X=0, Y=1 AND C=1 4050 EX6502 INC IP 4060 BNE L02EA 4070 INC IP+1 4080 L02EA JMP (IP) 4090 ; 4100 ;OPCODE $22 XX 4110 ;MOVE SINGLE BYTE POINTED TO BY 00/01 4120 ;TO LOCATION POINTED TO BY XX/XX+1 4130 L04AF TAX 4140 DEY 4150 LDA ($00),Y 4160 STA ($00,X) 4170 ;ALWAYS BRANCHES - ADVANCE 4180 ;INTERPRETIVE POINTER AND CONTINUE 4190 BCS JL11CF 4200 ; 4210 ;OPCODE $10 XX BB 4220 ;INPUT A 16-BIT DECIMAL NUMBER INTO XX/XX+1 4230 ;WITH BB BEING A BRANCH OFFSET IN CASE OF OVERFLO 4240 ;(I.E. RESULT > 65535). THE TEXT FOR THE NUMBER 4250 ;ITSELF STARTS AT LOCATION POINTED TO BY $06-$07, 4260 ;AND $08 CONTAINS THE NUMBER OF DIGITS. ALL THE 4270 ;DIGITS HAVE BEEN CONFIRMED TO BE DECIMAL DIGITS 4280 ;ALREADY. THE ASSEMBLER ITSELF DOES NOT USE THIS 4290 ;OPCODE ;IT IS ONLY USED BY THE LINE EDITOR. 4300 L0300 STX $26 4310 STX $EC 4320 TAX 4330 LDA #$00 4340 STA $00,X 4350 STA $01,X 4360 L030D LDY $26 4370 LDA ($06),Y 4380 AND #$0F 4390 STA TMPLOC+1 4400 TXA 4410 TAY 4420 LDA #CNST10 4430 JSR L0A84 4440 BNE L0327 ;BRANCH IF OVERFLOW 4450 INC $26 4460 DEC $08 4470 BNE L030D 4480 L3980 BEQ JL11CF ;ADVANCE IP AND EXECUTE 4490 ; 4500 ;OPCODE $1C XX BB 4510 ;REMOVE ERROR NUMBER AND TEXT POINTER FROM STACK 4520 ;BRANCH BB IS TAKEN IF STACK IS EMPTY 4530 L0BC5 TAY 4540 STX $01,Y 4550 LDX NUMERR 4560 BEQ L0327 4570 LDA ERRMSG+1,X 4580 STA $06 4590 LDA ERRMSG-1,X 4600 STA $0000,Y 4610 DEC NUMERR 4620 BPL JL11CF ;ALWAYS BRANCHES 4630 ;BRANCH, USING 3RD BYTE OF INSTR 4640 L0327 LDY #$02 4650 JMP L0284 4660 ;PRINT NEW LINE 4670 NEWLIN LDA #$0D 4680 L033E JSR COUT ;PRINT CHARACTER IN ACC 4690 L0341 LDA #$0A 4700 ;PRINT CHARACTER IN ACCUMULATOR 4710 CHROUT JMP COUT 4720 ;OPCODE $1F - INSTRUCTION LENGTH VARIABLE 4730 L03EC INC $06 4740 JSR L0341 4750 ; 4760 ;OPCODE $1D - INSTRUCTION LENGTH VARIABLE 4770 ;PRINT POINTER TO ERROR IN LINE OF TEXT, PLUS 4780 ;ERROR MESSAGE. START BY PRINTING LINE OF DASHES 4790 ;UP TO CURRENT POINT IN TEXT. 4800 L0363 ;CARRY SET BY DEFAULT 4810 LDA $06 4820 SBC $02 4830 BEQ L0373 4840 TAX 4850 LDA #$2D 4860 L036D JSR COUT ;PRINT CHARACTER IN ACC 4870 DEX 4880 BNE L036D 4890 ;PRINT UP-ARROW 4900 L0373 LDA #$5E 4910 JSR COUT ;PRINT CHARACTER IN ACC 4920 ;PRINT CARRIAGE RETURN 4930 LDA #$0D 4940 JSR COUT ;PRINT CHARACTER IN ACC 4950 ;OPCODE $1E - INSTRUCTION LENGTH VARIABLE 4960 ;PRINT MESSAGE, TERMINATED WITH $00, BUT PRINT 4970 ;LINE FEED FIRST. 4980 L037D JSR L0341 4990 ; 5000 ;OPCODE $24 - INSTRUCTION LENGTH VARIABLE 5010 ;PRINT MESSAGE, TERMINATED WITH #$00 OR #$0D (CR) 5020 L0380 LDA (IP),Y 5030 INY 5040 TAX ;CHECK FOR END OF MESSAGE 5050 BEQ L0391 5060 JSR COUT ;PRINT CHARACTER IN ACC 5070 CMP #$0D 5080 BNE L0380 5090 JSR L0341 5100 L0391 JMP L02A9 5110 ; 5120 ;OPCODE $0B - 0B XX YY BB 5130 ;THIS WORKS FOR OPCODES 0B, 2B, 4B, 6B, 8B, AB, 5140 ;CB AND EB, ALTHOUGH 0B AND EB NEVER OCCUR. 5150 ;COMPARES 16-BIT QUANTITIES IN ZERO PAGE AT 5160 ;LOCATIONS XX/XX+1 AND .BYTE SET1,/.BYTE SET1,+1, 5170 ;ON BB IF APPROPRIATE 5180 ;2B: BRANCHES IF XX > YY 5190 ;4B: BRANCHES IF XX = YY 5200 ;6B: BRANCHES IF XX >= YY 5210 ;8B: BRANCHES IF XX < YY 5220 ;AB: BRANCHES IF XX <> YY 5230 ;CB: BRANCHES IF XX <= YY 5240 L03A0 JSR L04A0 5250 ;CARRY SET IMPLICITLY 5260 LDA $00,X 5270 SBC $0000,Y 5280 STA $E5 5290 LDA $01,X 5300 SBC $0001,Y 5310 ORA $E5 5320 BEQ L03C4 5330 LDA #%01100000 5340 BCS L03C4 5350 ASL A ;A = $C0 5360 L03C4 EOR #%01000000 5370 LDY #$00 5380 AND (IP),Y 5390 L4820 BEQ L3980 ;EXECUTE NEXT INSTRUCTION 5400 L03CE LDY #$03 5410 JMP L0284 ;EXECUTE RELATIVE BRANCH 5420 ; 5430 ;OPCODE $20 - 20 XX YY ZZ 5440 ;SUBTRACT 16-BIT QUANTITY IN YY FROM XX 5450 ;AND PUT RESULT IN ZZ 5460 L0419 DEX ;FLAG = $FF TO SUBTRACT 5470 .BYTE $24 ;KEEP CARRY SET 5480 ; 5490 ;OPCODE $21 - 21 XX YY ZZ 5500 ;ADD TOGETHER 16-BIT QUANTITIES AT XX AND .BYTE S 5510 ;PUT RESULT IN ZZ 5520 L0400 CLC 5530 STX $E4 5540 JSR L04A0 5550 LDA $0000,Y 5560 EOR $E4 5570 ADC $00,X 5580 PHA 5590 LDA $0001,Y 5600 EOR $E4 5610 ADC $01,X 5620 PHA 5630 LDY #$03 5640 LDA (IP),Y 5650 TAX 5660 PLA 5670 JMP PULLZP 5680 ; 5690 ;OPCODE $0C - INSTRUCTION LENGTH = 1 5700 ;COMPRESS LINE OF ASSEMBLER SOURCE CODE 5710 L0440 STX $28 5720 STX $0E 5730 STX $27 5740 L0446 STX $26 5750 L0448 LDY $28 5760 LDA ($00),Y 5770 CMP $27 5780 BNE L0456 5790 DEC $26 5800 INC $28 5810 BNE L0448 5820 L0456 TAX 5830 LDY $0E 5840 LDA $26 5850 BEQ L0460 5860 STA ($00),Y 5870 INY 5880 L0460 TXA 5890 STA ($00),Y 5900 STA $27 5910 INC $28 5920 INY 5930 STY $0E 5940 LDX #$00 5950 CMP #$0D 5960 BNE L0446 5970 STX $0F 5980 BEQ L4820 ;ALWAYS BRANCHES 5990 ; 6000 ;CALLED BY BLOCK MOVE SUBROUTINE 6010 ;RETURN WITH Z FLAG SET IF TRANSFERRED 6020 ;LAST BYTE OF BLOCK 6030 L03F2 LDA ($26),Y 6040 STA ($28),Y 6050 INC $FE 6060 BNE L03F6 6070 INC $FF 6080 L03F6 RTS 6090 ; 6100 ;************************************** 6110 ;THE FOLLOWING DECLARATIONS PRECEDE THE 6120 ;FIRST PIECE OF PSEUDOCODE 6130 ;************************************** 6140 OFS=*/256*256 6150 OFFSET = $E800-OFS 6160 ; 6170 ;OPCODE $00 - INSTRUCTION LENGTH = 2 6180 ;STEP ON TO NEXT LINE OF SOURCE FILE - 6190 ;PUT LOCATION IN TXTPOS, AND 6200 ;PUT LENGTH IN LINLEN 6210 ;PUT LINE NUMBER IN $38 6220 ;TAKE RELATIVE BRANCH IN 2ND BYTE IF END 6230 L047C .BYTE ADDZ,TXTPOS,LINLEN,TXTPOS 6240 .BYTE ADDZ,LINENO,CONST1,LINENO 6250 .BYTE SET0,LINLEN 6260 .BYTE BNEQ,TXTPOS,ENDTXT,L048E-* 6270 .BYTE RET2 ;RETURN - 2ND BYTE OF CALL IS BR 6280 ; 6290 ;OPCODE $02 - INSTRUCTION LENGTH = 1 6300 ;FETCH FIRST LINE OF SOURCE FILE - 6310 ;PUT LOCATION IN TXTPOS, AND 6320 ;PUT LENGTH IN LINLEN 6330 ;PUT LINE NUMBER IN $38 6340 L03D4 .BYTE COPY,STTEXT,TXTPOS 6350 .BYTE BEQU,TXTPOS,ENDTXT,L04E6-* ;RET 6360 L048E .BYTE BMOV,CONST2,TXTPOS,$38 6370 ;AND PUT LENGTH OF LINE IN LINLEN 6380 .BYTE EX65 6390 ;SKIP OVER 2 BYTES LINE NUMBER 6400 L0493 INY 6410 LDA (TXTPOS),Y 6420 CMP #$0D 6430 BNE L0493 6440 INY 6450 STY LINLEN 6460 JMP L02BC ;RETURN FROM P-CODE SUBROUTINE 6470 ;GET NEXT ARGUMENT IN LIST. 6480 ;LOOK AT NEXT ARGUMENT FOR P-CODE INSTRUCTION. 6490 ;IF THAT ARGUMENT IS NEGATIVE, USE IT TO INDEX 6500 ;CALLING INSTRUCTION. 6510 L04A0 LDA (IP),Y 6520 BPL L04AD 6530 AND #$7F 6540 TAY 6550 LDA (CALADR),Y 6560 L04AD TAX 6570 LDY #$02 6580 LDA (IP),Y 6590 TAY 6600 RTS 6610 ; 6620 ;OPCODE $01 XX YY, ZZ - MEMORY BLOCK MOVE 6630 ;XX IS LENGTH OF BLOCK (IN $46/$47) 6640 ;YY IS START OF SOURCE (IN $26/$27) 6650 ;ZZ IS START OF DESTINATION (IN $28/$29) 6660 L04C0 .BYTE COPY,$81,$46 ;STORE LENGTH 6670 ;EXIT IF LENGTH IS ZERO 6680 .BYTE BEQU,$46,CONST0,L04E6-* 6690 .BYTE SUBZ,CONST0,$46,$FE 6700 .BYTE COPY,$82,$26 ;STORE SOURCE 6710 .BYTE COPY,$83,$28 ;STORE DESTINATION 6720 ;BRANCH IF DESTINATION HIGHER THAN SOURCE 6730 .BYTE BLES,$26,$28,L04E7-* 6740 ;SOURCE ADDRESS HIGHER THAN DEST ADDRESS 6750 ;START BLOCK MOVE FROM LOWEST ADDRESS 6760 .BYTE EX65 6770 DEY 6780 BEQ L04DE ;ALWAYS BRANCHES 6790 L04D7 INY 6800 BNE L04DE 6810 INC $27 6820 INC $29 6830 L04DE JSR L03F2 6840 BNE L04D7 6850 L04E3 JSR L11DC ;EXECUTE P-CODE 6860 L04E6 .BYTE RETN 6870 ;DEST ADDRESS HIGHER THAN SOURCE ADDRESS 6880 ;START BLOCK MOVE FROM HIGHEST ADDRESS 6890 L04E7 .BYTE EX65 6900 CLC 6910 LDA $47 6920 ADC $27 6930 STA $27 6940 LDA $47 6950 ADC $29 6960 STA $29 6970 LDY $46 6980 L04F1 TYA 6990 BNE L04F8 7000 DEC $27 7010 DEC $29 7020 L04F8 DEY 7030 JSR L03F2 7040 BNE L04F1 7050 BEQ L04E3 7060 ; 7070 ;OPCODE $1B - INSTRUCTION LENGTH = 2 7080 ;PRINT LINE POINTED TO BY LOCATION XX/XX+1 7090 ;CARRIES OUT DECOMPRESSION OF TEXT 7100 L0500 TAX 7110 LDA $00,X 7120 STA $26 7130 LDA $01,X 7140 STA $27 7150 DEY 7160 L050C LDX #$FF 7170 LDA ($26),Y 7180 BPL L0515 7190 TAX 7200 LDA $28 7210 L0515 JSR COUT ;PRINT CHARACTER IN ACC 7220 INX 7230 BMI L0515 7240 STA $28 7250 INY 7260 CMP #$0D 7270 BNE L050C 7280 LDA #$00 7290 JSR L033E 7300 L6610 JMP L11CF ;ADVANCE INTERPRETIVE POINTER AND 7310 ;OPCODE 19 XX 7320 ;PRINT DIGIT DECIMAL NUMBER IN LOCATIONS XX 7330 ;AND XX+1, RIGHT-JUSTIFIED IN A FIELD OF 5 7340 ;CHARACTERS 7350 L0590 TAX 7360 LDA $00,X 7370 STA $26 7380 LDA $01,X 7390 STA $27 7400 LDA #$05 7410 STA $46 7420 LDX #$26 7430 LDY #CNST10 7440 LDA #$28 7450 L05A5 JSR L052A 7460 STA $47 7470 LDA $00,X 7480 PHA 7490 TXA 7500 LDX $47 7510 DEC $46 7520 BNE L05A5 7530 LDX #$80 7540 L05B6 PLA 7550 BEQ L05BE 7560 TAX 7570 ORA #$30 7580 BNE L05C5 7590 L05BE ORA #$30 7600 INX 7610 BPL L05C5 7620 LDA #$20 7630 L05C5 JSR COUT ;PRINT CHARACTER IN ACC 7640 INC $46 7650 LDA $46 7660 CMP #$05 7670 BNE L05B6 7680 BEQ L6610 ;ADVANCE INTERPRETIVE POINTER AND 7690 ;DIVISION SUBROUTINE: 7700 ;(A) = (X) / (Y) 7710 L052A STA $E4 7720 STX $E5 7730 STY TMPLOC 7740 LDX TMPLOC 7750 LDY #$01 7760 LDA $01 7770 BMI L0543 7780 L0538 INY 7790 ASL $00,X 7800 ROL $01,X 7810 BMI L0543 7820 CPY #$11 7830 BNE L0538 7840 L0543 STY TMPLOC+1 7850 LDY $E4 7860 LDX #$00 7870 STX $00,Y 7880 STX $01,Y 7890 LDY TMPLOC 7900 L054F LDX $E5 7910 SEC 7920 LDA $00,X 7930 SBC $0000,Y 7940 STA $EC 7950 LDA $01,X 7960 SBC $0001,Y 7970 BCC L0566 7980 STA $01,X 7990 LDA $EC 8000 STA $00,X 8010 L0566 LDX $E4 8020 ROL $00,X 8030 ROL $01,X 8040 DEC TMPLOC+1 8050 BEQ L0583 8060 LDX TMPLOC 8070 LSR $01,X 8080 ROR $00,X 8090 SEC 8100 BCS L054F 8110 L0583 LDA $E4 8120 LDX $E5 8130 RTS 8140 ;'R' COMMAND 8150 L066C .BYTE COPY,CNST10,$36 8160 .BYTE LIN1 8170 L0831 .BYTE BEQU,TXTPOS,ENDTXT,L0842-* 8180 .BYTE BMOV,CONST2,$3A,TXTPOS 8190 .BYTE ADDZ,CNST10,$36,$36 8200 .BYTE NXLN,L0842-* 8210 .DBYTE L0831+OFFSET 8220 L0842 .BYTE MSLN,$00 8230 .BYTE LIN1 8240 .BYTE PDEC,$36 8250 .DBYTE PSTART+OFFSET 8260 ;LINE NUMBER FOUND 8270 L0663 .DBYTE L0690+OFFSET 8280 ;'P' COMMAND 8290 L0666 .DBYTE L0750+OFFSET 8300 ;'D' COMMAND 8310 L0669 .DBYTE L07D0+OFFSET 8320 ;*********************************** 8330 ;ENTRY POINT FOR P-CODE UPON STARTUP 8340 PINIT .BYTE COPY,STTEXT,TXTPOS 8350 PSTART .BYTE MESG,$0D ;PRINT NEW LINE 8360 ;************************************ 8370 L0601 .BYTE CLAS,L0663-*,L0605-*,L0620-* 8380 L0605 .BYTE CHK6+'A,L0660-* ;TEST FOR 'A' COMMAN 8390 .BYTE CHK6+'P,L0666-* ;TEST FOR 'P' COMMAN 8400 .BYTE CHK6+'I,LICMD-* ;TEST FOR 'I' COMMAN 8410 .BYTE CHK6+'D,L0669-* ;TEST FOR 'D' COMMAN 8420 .BYTE CHK6+'R,L066C-* ;TEST FOR 'R' COMMAN 8430 L0614 .BYTE CHK6+'S,L130C-* ;'S' COMMAND 8440 .BYTE CHK6+'L,L1316-* ;'L' COMMAND 8450 CMDERR .BYTE PER6,'CMD ERR',$0D 8460 L0620 .BYTE MSLN,'.',$00 ;PRINT FULL STOP 8470 .BYTE KBLN ;GET LINE OF KEYBOARD INPUT 8480 .DBYTE L0601+OFFSET 8490 ; 8500 ;'S' AND 'L' COMMANDS FOR UK101 VERSION 8510 ;'S' COMMAND 8520 L130C .BYTE EX65 ;EXECUTE 6502 MACHINE CODE 8530 JSR SAVE ;TURN ON SAVE FLAG 8540 JMP L1310 8550 ;'L' COMMAND 8560 L1316 .BYTE EX65 ;EXECUTE 6502 MACHINE CODE 8570 JSR LOAD 8580 L1310 JSR L11DC ;RETURN TO P-CODE 8590 .BYTE $FD ;JMP TO L0620 8600 ;'A' COMMAND 8610 L0660 .BYTE MSLN,$0D 8620 .BYTE BEQU,STTEXT,ENDTXT,L0620-* 8630 .BYTE SET1,ASMBRK 8640 .BYTE SET0,ASMOPT 8650 .BYTE SET0,A2BLEN-1 ;SET NO. BYTES FOR A2 T 8660 .BYTE CLAS,L112A-*,CMDERR-*,L112D-* 8670 .DBYTE CMDERR+OFFSET 8680 L112A .BYTE DCIN,ASMOPT,CMDERR-* 8690 L112D .DBYTE L0850+OFFSET 8700 ; 8710 ;OPCODE $03 XX YY ZZ 8720 ;XX IS RELATIVE BRANCH FOR DECIMAL NUMBER 8730 ;YY IS RELATIVE BRANCH FOR NOT DECIMAL 8740 ;NUMBER, NOT CAPITAL LETTER, AND NOT 8750 ;END OF LINE 8760 ;ZZ IS RELATIVE BRANCH FOR END OF LINE 8770 ;NO BRANCH TAKEN IF CAPITAL LETTER 8780 L0626 .BYTE COPY,$00,$04 ;COPY POINTER 8790 .BYTE DECR,$00 ;DECREMENT POINTER AT $00/$0 8800 L062B .BYTE INC0 ;INC POINTER AT $00/$01 8810 .BYTE CHK0+$20,L062B-* ;SKIP SPACES 8820 .BYTE SET0,$08 ;SET CHAR CHOUNT TO ZERO 8830 .BYTE COPY,$00,$06 ;COPY POINTER TO $06/$07 8840 .BYTE CHK0+CAP,L0649-* ;BRANCH IF CAPITAL 8850 .BYTE CHK0+DCM,L0651-* ;BRANCH IF DECIMAL 8860 .BYTE CHK0+$0D,L065A-* ;BRANCH IF END OF L 8870 .BYTE COPY,$00,$06 ;COPY POINTER TO $06/$07 8880 ;THE FOLLOWING LINE IS ALMOST CERTAINLY ANOMOLOUS 8890 ;SO IT HAS BEEN COMMENTED OUT. 8900 ;.BYTE COPY,PRFLAG,$08 ;COPY FROM $F0/$F1 TO $08/$ 8910 .BYTE INC0 ;INCREMENT POINTER AT $00/$01 8920 .BYTE RET3 ;RETURN - 3RD BYTE OF CALL IS OF 8930 ;CAPITAL LETTER FOUND 8940 L0649 .BYTE INC0 8950 .BYTE INCR,$08 8960 .BYTE CHK0+CAP,L0649-* 8970 .BYTE RETN 8980 ;DECIMAL DIGIT FOUND 8990 L0651 .BYTE INC0 9000 .BYTE INCR,$08 9010 .BYTE CHK0+DCM,L0651-* 9020 .BYTE RET2 ;2ND BYTE OF CALL IS OFFSET 9030 ;END OF LINE FOUND 9040 L065A .BYTE RET4 ;4TH BYTE OF CALL IS OFFSET 9050 ;'I' COMMAND 9060 LICMD .BYTE MSLN,'INIZ?',$00 9070 .BYTE KBLN ;GET LINE OF KEYBOARD INPUT 9080 .BYTE COPY,STTEXT,$10 9090 .BYTE SET0,LINLEN 9100 .BYTE CHK0+'Y,L068A-* 9110 .BYTE $FD ;JMP TO L0620 9120 L068A .BYTE COPY,STTEXT,ENDTXT 9130 .BYTE $FD ;JMP TO L0620 9140 ;**************************** 9150 ;LINE NUMBER FOUND ON COMMAND LINE. 9160 ;INPUT DECIMAL NUMBER TO $36/$37. 9170 ;GO TO L06F3 IF TOO BIG. 9180 L0690 .BYTE DCIN,$36,L06F3-* 9190 .BYTE COMP ;COMPRESS REST OF LINE 9200 .BYTE ADDZ,$0E,CONST2,$0E 9210 .BYTE BEQU,$36,CONST0,L06B1-* 9220 .BYTE BGEQ,$36,LINENO,L06A3-* 9230 .BYTE LIN1 9240 L06A3 .BYTE BGEQ,LINENO,$36,L06AC-* 9250 .BYTE NXLN,L06B1-* 9260 .DBYTE L06A3+OFFSET 9270 L06AC .BYTE BEQU,LINENO,$36,L06B4-* 9280 L06B1 .BYTE SET0,LINLEN 9290 L06B4 .BYTE ADDZ,TXTPOS,$0E,$1C 9300 .BYTE ADDZ,TXTPOS,LINLEN,DRTYPE 9310 .BYTE SUBZ,ENDTXT,DRTYPE,$20 9320 .BYTE ADDZ,$1C,$20,$22 9330 .BYTE BRGR,$22,ENDMEM,L06EA-* 9340 .BYTE BMOV,$20,DRTYPE,$1C 9350 .BYTE SUBZ,$0E,CONST2,$1C 9360 .BYTE ADDZ,TXTPOS,CONST2,DRTYPE 9370 .BYTE BMOV,$1C,$00,DRTYPE 9380 .BYTE BEQU,$36,CONST0,L05DB-* 9390 .BYTE COPY,$36,LINENO 9400 L05DB .BYTE BMOV,CONST2,$3A,TXTPOS 9410 .BYTE COPY,$0E,LINLEN 9420 .BYTE COPY,$22,ENDTXT 9430 .BYTE NXLN,L06E8-* 9440 L06E8 .BYTE $FD ;JMP TO L0620 9450 L06EA .BYTE MSLN,'*FULL',$0D 9460 .BYTE $FD ;JMP TO L0620 9470 L06F3 .BYTE PER6,'#TOO BIG',$0D 9480 .BYTE $FD ;JMP TO L0620 9490 ; 9500 ;OPCODE $04 - INSTRUCTION LENGTH = 2 9510 ;SECOND BYTE IS AN OFFSET 9520 L0700 .BYTE SET0,$1C 9530 .BYTE COPY,$2E,DRTYPE 9540 .BYTE CLAS,L070C-*,L071C-*,L074E-* 9550 .BYTE COPY,$04,$00 9560 .BYTE RET2 ;2ND BYTE OF CALL IS BRANCH 9570 L070C .BYTE DCIN,$1C,L0741-* 9580 .BYTE CLAS,L073B-*,L0721-*,L0718-* 9590 .BYTE COPY,$1C,DRTYPE ;COPY $1C/$1D INTO D 9600 L0716 .BYTE COPY,$04,$00 9610 L0717 .BYTE RETN 9620 L0718 .BYTE COPY,$1C,DRTYPE 9630 .BYTE RETN 9640 L071C .BYTE CHK6+'-,L0729-* 9650 .DBYTE L073B+OFFSET 9660 L0721 .BYTE CHK6+'-,L0729-* ;GO TO L0729 IF DAS 9670 .BYTE CHK6+',,L0718-* ;GO TO L0718 IF COM 9680 .DBYTE L073B+OFFSET 9690 L0729 .BYTE CLAS,L072F-*,L0738-*,L0717-* 9700 .DBYTE L0716+OFFSET 9710 L072F .BYTE DCIN,DRTYPE,L0741-* ;READ DECIMAL N 9720 .BYTE CLAS,L073B-*,L0738-*,L0717-* 9730 .DBYTE L0716+OFFSET 9740 L0738 .BYTE CHK6+',,L0717-* 9750 L073B .BYTE PER6,'??',$0D 9760 .BYTE RET2 9770 L0741 .BYTE PER6,'#TOO BIG',$0D 9780 L074E .BYTE RET2 ;2ND BYTE OF CALL IS BRANCH 9790 ;'P' COMMAND 9800 L0750 .BYTE LRAN,L0752-* 9810 L0752 .BYTE MSLN,$0D 9820 L0754 .BYTE LIN1 9830 .BYTE BEQU,TXTPOS,ENDTXT,L0778-* 9840 L075A .BYTE BGEQ,LINENO,$1C,L0763-* 9850 .BYTE NXLN,L0768-* 9860 .DBYTE L075A+OFFSET 9870 L0763 .BYTE BLEQ,LINENO,DRTYPE,L076C-* 9880 L0768 .BYTE LRAN,L0778-* 9890 .DBYTE L0754+OFFSET 9900 L076C .BYTE PDEC,LINENO 9910 .BYTE ADDZ,TXTPOS,CONST2,$20 9920 .BYTE PLIN,$20 9930 .BYTE NXLN,L0768-* 9940 .DBYTE L0763+OFFSET 9950 LEN1=$1000-OF6502 9960 LEN2=$2000-OF6502 9970 LEN3=$3000-OF6502 9980 LEN4=$4000-OF6502 9990 LENF=$F000-OF6502 10000 OP00=L047C+LEN2 10010 OP01=L04C0+LEN4 10020 OP02=L03D4+LEN1 10030 OP03=L0626+LEN4 10040 OP04=L0700+LEN2 10050 OP05=L0961+LEN1 10060 OP06=L0989+LEN4 10070 OP07=L0985+LEN4 10080 OP08=L10B3+LEN1 10090 OP09=L0C30+LEN2 10100 OP0A=L0AF0+LEN2 10110 OP0B=L03A0+LEN4 10120 OP0C=L0440+LEN1 10130 OP0D=L0205+LEN1 10140 OP0E=OP1203+LEN1 10150 OP0F=CODE0F+LEN2 10160 OP10=L0300+LEN3 10170 OP11=L02BC+LEN1 10180 OP12=OP1201+LEN1 10190 OP13=L02D0+LEN2 10200 OP14=L02DC+LEN2 10210 OP15=EX6502+LEN1 10220 OP16=L0270+LEN3 10230 OP17=L0BE5+LEN2 10240 OP18=L0965+LEN2 10250 OP19=L0590+LEN2 10260 OP1A=L029C+LEN3 10270 OP1B=L0500+LEN2 10280 OP1C=L0BC5+LEN3 10290 OP1D=L0363+LENF 10300 OP1E=L037D+LENF 10310 OP1F=L03EC+LENF 10320 OP20=L0419+LEN4 10330 OP21=L0400+LEN4 10340 OP22=L04AF+LEN2 10350 OP23=L0A60+LEN1 10360 OP24=L0380+LENF 10370 OP25=OP1202+LEN1 10380 OP26=L0240+LEN2 10390 OP27=L0244+LEN2 10400 OP28=L11CE+LEN1 10410 OP29=CODE29+LEN2 10420 ;ADDRESSES FOR OPCODE ROUTINES 10430 ;OPCODES ALLOWED ARE 00 TO 27 INCLUSIVE 10440 ;MSB MAY BE SET, INDICATING P-CODE SUBROUTINE 10450 ADDRLO .BYTE OP00,OP01,OP02,OP03 10460 .BYTE OP04,OP05,OP06,OP07 10470 .BYTE OP08,OP09,OP0A,OP0B 10480 .BYTE OP0C,OP0D,OP0E,OP0F 10490 .BYTE OP10,OP11,OP12,OP13 10500 .BYTE OP14,OP15,OP16,OP17 10510 .BYTE OP18,OP19,OP1A,OP1B 10520 .BYTE OP1C,OP1D,OP1E,OP1F 10530 .BYTE OP20,OP21,OP22,OP23 10540 .BYTE OP24,OP25,OP26,OP27 10550 .BYTE OP28,OP29 10560 ADDRHI .BYTE OP00/256,OP01/256 10570 .BYTE OP02/256,OP03/256 10580 .BYTE OP04/256,OP05/256 10590 .BYTE OP06/256,OP07/256 10600 .BYTE OP08/256,OP09/256 10610 .BYTE OP0A/256,OP0B/256 10620 .BYTE OP0C/256,OP0D/256 10630 .BYTE OP0E/256,OP0F/256 10640 .BYTE OP10/256,OP11/256 10650 .BYTE OP12/256,OP13/256 10660 .BYTE OP14/256,OP15/256 10670 .BYTE OP16/256,OP17/256 10680 .BYTE OP18/256,OP19/256 10690 .BYTE OP1A/256,OP1B/256 10700 .BYTE OP1C/256,OP1D/256 10710 .BYTE OP1E/256,OP1F/256 10720 .BYTE OP20/256,OP21/256 10730 .BYTE OP22/256,OP23/256 10740 .BYTE OP24/256,OP25/256 10750 .BYTE OP26/256,OP27/256 10760 .BYTE OP28/256,OP29/256 10770 L0778 .DBYTE L0601+OFFSET 10780 L07D0 .BYTE LRAN,L0807-* 10790 L07D2 .BYTE SET0,$22 10800 .BYTE LIN1 10810 L07DB .BYTE BGEQ,LINENO,$1C,L07E4-* 10820 .BYTE NXLN,L0811-* 10830 .DBYTE L07DB+OFFSET 10840 L07E4 .BYTE COPY,TXTPOS,$1C 10850 L07E7 .BYTE BRGR,LINENO,DRTYPE,L07F0-* 10860 .BYTE INCR,$22 10870 .BYTE ADDZ,TXTPOS,LINLEN,$20 10880 .BYTE NXLN,L07F0-* 10890 .DBYTE L07E7+OFFSET 10900 L07F0 .BYTE SUBZ,ENDTXT,$20,DRTYPE 10910 .BYTE BEQU,$22,CONST0,L0811-* 10920 .BYTE BMOV,DRTYPE,$20,$1C 10930 .BYTE ADDZ,$1C,DRTYPE,ENDTXT 10940 .BYTE LIN1 10950 .BYTE LRAN,L0778-* 10960 .DBYTE L07D2+OFFSET 10970 L0807 .BYTE PER6,'LINES?',$0D 10980 .DBYTE L0822+OFFSET 10990 L0811 .BYTE PER6,'NO SUCH LINE(S)',$0D 11000 L0822 .BYTE $FD ;JMP TO L0620 11010 L084A .BYTE INC0 11020 .BYTE RLBL,L1153-* 11030 ;ERROR 26 - ILLEGAL DIRECTIVE 11040 L114F .BYTE RERR,$1A 11050 .DBYTE L10A7+OFFSET 11060 L1153 .DBYTE L104E+OFFSET 11070 L084D .BYTE SET0,INSTLN 11080 .BYTE INC0 11090 .BYTE SKIP ;SKIP SPACES 11100 .BYTE CHK0+'=,L100C-* 11110 .BYTE $FA ;JMP TO L08B7 11120 L100C .BYTE INC0 11130 .BYTE SKIP ;SKIP SPACES 11140 .BYTE EXPR,L1023-* 11150 .BYTE CHK0+SPC,L1017-* 11160 .BYTE $FE ;JMP TO L08E6 11170 L1017 .BYTE EX65 11180 LDA #$3F 11190 BIT $ED 11200 BEQ L1025 11210 JSR L11DC ;EXECUTE P-CODE 11220 ;ERROR 4 - FWD REF IN EQUATE DIRECTIVE 11230 .BYTE RERR,$84 11240 L1023 .BYTE $FF ;JMP TO LINOUT 11250 L1025 JSR L11DC ;EXECUTE P-CODE 11260 .BYTE SET1,ASMBRK 11270 .BYTE COPY,NUMVAL,ASMADR 11280 .BYTE $FF ;JMP TO LINOUT 11290 ; 11300 ;'A' COMMAND - ASMOPT HAS ALREADY BEEN 11310 ;SET UP. 11320 L0850 .BYTE SET0,$7C 11330 .BYTE COPY,ENDMEM,LABTBL ;CLEAR LABEL TABL 11340 .BYTE SET1,PASS 11350 ;START NEXT PASS OF ASSEMBLY 11360 NXTPAS .BYTE SET0,ASMADR 11370 .BYTE LIN1 ;GET FIRST LINE OF SOURCE CODE 11380 L085D .BYTE SET0,PRFLAG ;LINE NOT YET PRINTED 11390 .BYTE SET0,NUMERR ;NO ERRORS SO FAR 11400 .BYTE DCMP ;DECOMPRESS TEXT AT TXTPOS/TXTP 11410 .BYTE COPY,$02,$00 ;MOVE POINTER FOR LINE 11420 ;SET DEFAULT INSTRUCTION TO 3 NOP BYTES 11430 .BYTE COPY,CONST3,INSTLN 11440 .BYTE COPY,NOPBYT,INSTRN 11450 .BYTE COPY,NOPBYT,INSTRN+2 11460 .BYTE SET0,$54 11470 .BYTE SKIP ;SKIP SPACES 11480 .BYTE CHK0+$0D,L08C6-* 11490 .BYTE CHK0+';,L08AD-* 11500 .BYTE CHK0+'*,L084D-* 11510 .BYTE CHK0+'.,L084A-* ;PROCESS DIRECTIVE 11520 .BYTE RLBL,L0887-* 11530 ;ERROR 9 - LABEL DOESN'T BEGIN WITH LETTER 11540 .BYTE RERR,$09 11550 .BYTE $FF ;JMP TO LINOUT 11560 L0887 .BYTE LVAL,L08AB-*,L08BB-*,L088C-* 11570 L088C .BYTE SET1,$54 11580 .BYTE CHK0+$20,L0894-* 11590 .DBYTE L089A+OFFSET 11600 L0894 .BYTE SKIP ;SKIP SPACES 11610 .BYTE RLBL,L08B2-* 11620 .BYTE CHK0+'.,L084A-* 11630 L089A .BYTE CHK0+'*,L084D-* 11640 .BYTE CHK0+'=,L08A8-* 11650 .BYTE CHK0+';,L08AD-* 11660 .BYTE CHK0+$0D,L08AD-* 11670 .BYTE $FA ;JMP TO L08B7 11680 L08A8 .DBYTE L1028+OFFSET 11690 ;ERROR 1 - 'A' IS A RESERVED NAME 11700 L08AB .BYTE RERR,$01 11710 L08AD .BYTE SET0,INSTLN 11720 .BYTE $FF ;JMP TO LINOUT 11730 L08B2 .BYTE LEXP,L08B7-*,L08BB-*,L08B7-* 11740 ;ERROR 6 - ILLEGAL OR MISSING OPCODE 11750 L08B7 .BYTE RERR,$06 11760 .BYTE $FF ;JMP TO LINOUT 11770 L08BB .BYTE CHK0+SPC,L08C0-* 11780 .BYTE $FA ;JMP TO L08B7 11790 L0EBC .BYTE SET1,INSTLN 11800 .BYTE COPY,$20,INSTRN 11810 .BYTE $FF ;JMP TO LINOUT 11820 L08C0 .BYTE BEQU,DRTYPE,CONST0,L0EBC-* 11830 .BYTE SKIP ;SKIP SPACES 11840 L08C6 .BYTE CHK0+$0D,L090C-* 11850 .BYTE CHK0+'#,IMMADR-* 11860 .BYTE CHK0+'(,INDADR-* 11870 .BYTE COPY,CNST80,$56 11880 .BYTE CHK0+'A,L0950-* 11890 L08D5 .BYTE EXPR,L08F4-* 11900 .BYTE CHK0+',,L0934-* 11910 .BYTE COPY,$5A,$56 11920 .DBYTE L0948+OFFSET 11930 ; 11940 ;PROCESS IMMEDIATE ADDRESSING 11950 IMMADR .BYTE INC0 11960 .BYTE EXPR,L08F4-* ;GET EXPRESSION 11970 .BYTE CHK0+SPC,L08EA-* 11980 ;ERROR 7 - INVALID EXPRESSION 11990 L08E6 .BYTE RERR,$07 12000 .BYTE $FF ;JMP TO LINOUT 12010 L08EA .BYTE COPY,$5C,$56 12020 .BYTE DECR,INSTLN ;INSTR LEN = 2 12030 .DBYTE L0D3D+OFFSET 12040 L08F4 .BYTE $FF ;JMP TO LINOUT 12050 INDADR .BYTE INC0 12060 .BYTE EXPR,L08F4-* 12070 .BYTE CHK0+',,L0902-* 12080 .BYTE CHK0+'),L0920-* 12090 .BYTE $FE ;JMP TO L08E6 12100 L0902 .BYTE INC0 12110 .BYTE CHK0+'X,L0909-* 12120 .BYTE $FE ;JMP TO L08E6 12130 L0909 .BYTE COPY,$5E,$56 12140 .BYTE INC0 12150 .BYTE CHK0+'),L0910-* 12160 .BYTE $FE ;JMP TO L08E6 12170 ;ERROR 15 - RAN OFF END OF LINE 12180 L090C .BYTE RERR,$0F 12190 .BYTE $FF ;JMP TO LINOUT 12200 L0910 .BYTE INC0 12210 .BYTE CHK0+SPC,L0917-* 12220 .BYTE $FE ;JMP TO L08E6 12230 L0917 .BYTE BLES,NUMVAL,CONST1-1,L094D-* 12240 ;ERROR 13 - OUT OF BOUND INDIRECT ADDR 12250 .BYTE RERR,$0D 12260 .BYTE $FF ;JMP TO LINOUT 12270 L0920 .BYTE INC0 12280 .BYTE CHK0+',,L092A-* 12290 .BYTE COPY,$62,$56 12300 .DBYTE L0948+OFFSET 12310 L092A .BYTE INC0 12320 .BYTE COPY,$60,$56 12330 .BYTE CHK0+'Y,L0910-* 12340 .BYTE $FE ;JMP TO L08E6 12350 L0934 .BYTE INC0 12360 .BYTE COPY,$64,$56 12370 .BYTE CHK0+'X,L0946-* 12380 .BYTE COPY,$66,$56 12390 .BYTE CHK0+'Y,L0946-* 12400 ;ERROR 8 - INVALID INDEX - NOT X OR Y 12410 .BYTE RERR,$08 12420 .BYTE $FF ;JMP TO LINOUT 12430 L0946 .BYTE INC0 12440 L0948 .BYTE CHK0+SPC,L094D-* 12450 .BYTE $FE ;JMP TO L08E6 12460 L094D .DBYTE L0D3D+OFFSET 12470 L0950 .BYTE INC0 12480 .BYTE CHK0+SPC,L094D-* 12490 .BYTE DECR,$00 12500 .DBYTE L08D5+OFFSET 12510 ; 12520 ;OPCODE $05 - INSTRUCTION LENGTH = 1 12530 ;SKIP SPACES IN INPUT STREAM 12540 ;ENTRY POINT IS AT L0961 12550 L095F .BYTE INC0 ;INCREMENT CHARACTER POINTER 12560 L0961 .BYTE CHK0+$20,L095F-* 12570 .BYTE RETN 12580 ; 12590 ;OPCODE $18 XX 12600 ;TAKE RECORD OF ERROR NO XX PLUS TEXT POINTER ; 12610 ;A MAXIMUM OF TWO SUCH RECORDS CAN BE KEPT 12620 L0965 LDX NUMERR 12630 CPX #2 12640 BEQ L0982 12650 ASL A 12660 LDY PASS 12670 DEY 12680 BNE L0975 12690 BCC L0982 12700 L0975 LSR A 12710 STA ERRMSG,X 12720 LDA $00 12730 STA ERRMSG+2,X 12740 INC NUMERR 12750 L0982 JMP L11CF ;ADVANCE INTERPRETIVE POINTER AN 12760 ; 12770 ;ENTRY FOUND IN TABLE 12780 L0A20 TXA 12790 LSR A 12800 TAY 12810 LDA INSTYP,Y 12820 BCS NOLSR 12830 LSR A 12840 LSR A 12850 LSR A 12860 LSR A 12870 NOLSR AND #$0F 12880 TAY 12890 CPY #$0F 12900 BNE L0A2D ;BRANCH IF OPCODE MNEMONIC 12910 JSR L11DC ;EXECUTE P-CODE 12920 .BYTE RET2 ;2ND BYTE OF CALL IS BRANCH 12930 ;OPCODE MNEMONIC FOUND 12940 ;LOAD DRTYPE ACCORDING TO INSTR TYPE 12950 L0A2D LDA L0DD5,Y 12960 STA DRTYPE 12970 LDA L0DE3,Y 12980 STA DRTYPE+1 12990 LDA INSBAS-2,X ;GET OPCODE BASE 13000 STA $20 13010 JSR L11DC ;EXECUTE P-CODE 13020 .BYTE RET3 ;3RD BYTE OF CALL IS BRANCH 13030 ; 13040 ;OPCODE $07 - INSTRUCTION LENGTH = 5 13050 ;SEARCH FOR LABEL, AS PART OF EXPRESSION 13060 ;BYTES 2, 3, AND 4 ARE RELATIVE BRANCH OFFSETS 13070 ;NO BRANCH: LABEL FOUND ;VALUE IN LABVAL 13080 ;BYTE 2: A, X, Y, S, OR P HAS BEEN FOUND 13090 ;BYTE 3: OPCODE MNEMONIC FOUND 13100 ;BYTE 4: UNDEFINED LABEL 13110 L0985 .BYTE EX65 13120 DEY 13130 .BYTE $24 13140 ; 13150 ;OPCODE $06 - INSTRUCTION LENGTH = 5 13160 ;SEARCH FOR LABEL, AS L-VALUE 13170 ;BYTES 2, 3, AND 4 ARE RELATIVE BRANCH OFFSETS 13180 ;NO BRANCH: LABEL FOUND ;VALUE IN LABVAL 13190 ;BYTE 2: A, X, Y, S, OR P HAS BEEN FOUND 13200 ;BYTE 3: OPCODE MNEMONIC FOUND 13210 ;BYTE 4: UNDEFINED LABEL 13220 L0989 .BYTE EX65 13230 STY $30 ;1 FOR INSTRUCTION $06 AND 0 FOR $ 13240 STX $32 ;ASSUME LABEL DEFINED BY DEFAULT 13250 ;LABEL IS STORED IN 4 BYTES STARTING AT LABL40 13260 LDA LABL40+2 13270 ORA LABL40+3 13280 BNE L09B9 ;BRANCH IF LABEL 4 CHARS OR LONG 13290 ;USE BINARY SEARCH TO FIND OPCODE 13300 ;RECORDS ARE 4 BYTES EACH 13310 ;TABLE HAS 63 RECORDS, ALTHOUGH NOT ALL ARE 13320 ;PRESENT IN MNEMLO, INSBAS AND INSTYP. 13330 ;$E4 CONTAINS CURRENT CHOP SIZE 13340 LDA #$20 13350 STA $E4 13360 ;ACC IS THE CURRENT INDEX INTO TABLE 13370 ;$00 CANNOT OCCUR 13380 L0997 LSR $E4 13390 TAX 13400 LDY MNEMHI-1,X 13410 CPY LABL40+1 13420 BCC L09AE 13430 BNE L09AA 13440 LDY MNEMLO-1,X 13450 CPY LABL40 13460 BCC L09AE 13470 BEQ L0A20 ;ENTRY FOUND IN TABLE 13480 L09AA SBC $E4 13490 .BYTE $2C 13500 L09AE ADC $E4 13510 LDX $E4 13520 BNE L0997 13530 ;LABEL IDENTIFIED - NOT OPCODE MNEMONIC 13540 L09B9 JSR L11DC ;EXECUTE P-CODE 13550 ;SUBTRACT CONSTANT OF 5 IN CONST5 13560 ;FROM END OF AVAILABLE MEMORY IN ENDMEM 13570 ;TO PRODUCE POINTER TO NEXT LABEL IN $0C/$0D 13580 .BYTE SUBZ,ENDMEM,CONST5,$0C 13590 .BYTE EX65 13600 L09C1 LDA $0C 13610 CMP LABTBL 13620 LDA $0D 13630 SBC LABTBL+1 13640 BCC L0A41 ;BRANCH IF OFF END OF LABEL TABL 13650 LDA LABL40+1 13660 CMP ($0C),Y 13670 BNE L09F3 ;GO TO NEXT ENTRY IF NO MATCH 13680 LDA LABL40 13690 CMP ($0C,X) 13700 BNE L09F3 ;GO TO NEXT ENTRY IF NO MATCH 13710 LDY #$03 13720 LDA ($0C),Y 13730 CMP #$FE 13740 BCC L09E8 13750 ;LABEL NOT COMPLETELY DEFINED 13760 STA $32 13770 LDY #$05 13780 LDA ($0C),Y 13790 LDY #$03 13800 L09E8 CMP LABL40+3 13810 BNE L09F3 ;GO TO NEXT ENTRY IF NO MATCH 13820 DEY 13830 LDA LABL40+2 13840 CMP ($0C),Y 13850 BEQ L0A02 13860 ;GO TO PREVIOUS ENTRY IN LABEL TABLE 13870 ;CONST6/$F5 CONTAINS CONSTANT OF 6 13880 L09F3 JSR L11DC ;EXECUTE P-CODE 13890 .BYTE SUBZ,$0C,CONST6,$0C 13900 .BYTE EX65 13910 STX $32 ;ASSUME LABEL DEFINED BY DEFAULT 13920 BNE L09C1 ;ALWAYS BRANCHES 13930 ; 13940 L0A02 LDA $32 13950 BNE L0A47 ;BRANCH IF LABEL UNDEFINED 13960 ;BRANCH IF LABEL IS PART OF R-VALUE 13970 LDA $30 13980 BEQ L0A44 13990 ; 14000 ;LABEL FOUND AND IT'S AN L-VALUE 14010 ;IF IT'S NOT FOLLOWED BY AN '=' SIGN, 14020 ;CHECK ITS VALUE AGAINST PRESENT LOCATION 14030 JSR L11DC ;EXECUTE P-CODE 14040 .BYTE ADDZ,$0C,CONST4,$0C ;$0C/$0D POINTS 14050 L113C .BYTE CLAS,L1140-*,L1140-*,L1140-* 14060 L1140 .BYTE COPY,$04,$00 14070 .BYTE CHK6+'=,L0A1F-* 14080 .BYTE BMOV,CONST2,$0C,CNST7E ;MOVE ADDR FI 14090 L0A18 .BYTE BEQU,ASMADR,LABVAL,L0A1F-* 14100 ;ERROR IF ADDRESS FIELD NOT EQUAL TO ASMADR/ASMAD 14110 ;"LABEL PREVIOUSLY DEFINED" 14120 ;ERROR 12 - LABEL PREVIOUSLY DEFINED 14130 .BYTE RERR,$0C 14140 L0A1F .BYTE RETN 14150 ; 14160 ;CREATE NEW SYMBOL TABLE ENTRY OR 14170 ;RECORD SYMBOL TABLE OVERFLOW 14180 L0A41 LDA $7C 14190 BNE L05F5 ;BRANCH IF TABLE ALREADY OVERFLO 14200 JSR L11DC ;EXECUTE P-CODE 14210 .BYTE BGEQ,$0C,ENDTXT,L0C22-* ;CHECK FOR 14220 ;ERROR 25 - SYMBOL TABLE OVERFLOW 14230 .BYTE RERR,$99 14240 .BYTE SET1,$7C ;SET SYM TABLE OVERFLOW FLA 14250 .BYTE RET4 ;RETURN - 4TH BYTE OF CALL IS O 14260 L0C22 .BYTE COPY,$0C,LABTBL ;UPDATE START OF TAB 14270 .BYTE BMOV,CONST4,CNST6C,$0C ;COPY UP BASE 14280 .BYTE ADDZ,$0C,CONST4,$32 14290 .BYTE BMOV,CONST2,CNST44,$32 ;COPY UP VALU 14300 .BYTE EX65 14310 LDA $30 14320 BNE L05F5 ;RETURN IF L-VALUE ; 14330 ;LABEL IS PART OF R-VALUE SO MARK IT AS 14340 ;BEING UNDEFINED 14350 LDA LABL40+3 14360 LDY #$05 14370 STA ($0C),Y 14380 LDA #$FF 14390 LDY #$03 14400 STA ($0C),Y 14410 L05F5 JSR L11DC ;EXECUTE P-CODE 14420 .BYTE RET4 ;RETURN - 4TH BYTE OF CALL IS O 14430 ;LABEL DEFINED, AND IS PART OF R-VALUE 14440 ;MOVE ADDRESS FIELD TO LABVAL 14450 L0A44 JSR L11DC ;EXECUTE P-CODE 14460 .BYTE ADDZ,$0C,CONST4,$0C 14470 .BYTE BMOV,CONST2,$0C,CNST7E 14480 .BYTE RETN 14490 ;UNDEFINED LABEL FOUND IN LABEL TABLE 14500 L0A47 LDY #$04 14510 LDX $30 14520 BEQ L0A50 ;BRANCH IF PART OF R-VALUE 14530 ;LABEL IS BEING CONSIDERED AS L-VALUE 14540 EOR #$FE 14550 ;BRANCH IF UNDEFINED AND IT WAS PREVIOUSLY ONLY R 14560 BNE L1210 14570 ;OTHERWISE IT'S IN ZERO PAGE 14580 STA $7F 14590 LDA ($0C),Y 14600 STA LABVAL 14610 JSR L11DC ;EXECUTE P-CODE 14620 .DBYTE L0A18+OFFSET ;CHECK IT'S NOT BEEN R 14630 L1210 LDA ASMADR+1 14640 BEQ L1224 ;BRANCH TO MARK IT AS ZERO PAGE 14650 INY 14660 STA ($0C),Y 14670 DEY 14680 LDA ASMADR 14690 STA ($0C),Y 14700 LDA LABL40+3 14710 L121E DEY 14720 STA ($0C),Y 14730 JMP L0B7B 14740 L1224 LDA ASMADR 14750 STA ($0C),Y 14760 LDA #$FE 14770 BNE L121E 14780 ;UNDEFINED LABEL IS R-VALUE 14790 L0A50 EOR #$FE 14800 BNE L05F5 ;EXIT IF IT'S NEVER BEEN R-VALUE 14810 STA $7F ;PUT ITS PAGE ZERO ADDRESS INTO $7 14820 LDA ($0C),Y 14830 STA LABVAL 14840 LDA $ED ;SET FLAG TO INDICATE THAT THIS HA 14850 ORA #%01000000 14860 STA $ED 14870 JMP L02BC ;RETURN FROM P-CODE SUBROUTINE 14880 ; 14890 ;OPCODE $23 - INSTRUCTION LENGTH = 1 14900 ;DECOMPRESS TEXT POINTED TO BY TXTPOS/TXTPOS+1, 14910 ;AND STORE IT STARTING FROM $02/$03 14920 L0A60 STX $E4 14930 INY 14940 L0A63 LDX #$FF 14950 LDA (TXTPOS),Y 14960 BPL L0A6C 14970 TAX 14980 LDA $28 14990 L0A6C STY $E5 15000 LDY $E4 15010 L0A70 STA ($02),Y 15020 INY 15030 INX 15040 BMI L0A70 15050 STA $28 15060 STY $E4 15070 LDY $E5 15080 INY 15090 CMP #$0D 15100 BNE L0A63 15110 JMP L11CF ;GO TO NEXT INSTRUCTION 15120 ;*********************************** 15130 ;MULTIPLY SUBROUTINE 15140 ;16-BIT QUANTITIES IN ZERO PAGE POINTED TO 15150 ;BY A AND Y ARE MULTIPLIED TOGETHER, AND 15160 ;THE 16-BIT RESULT IS PUT INTO THE TWO 15170 ;LOCATIONS POINTED TO BY X. ALSO, THE 15180 ;16-BIT QUANTITY SPECIFIED BY TMPLOC+1(LO) AND 15190 ;$EC(HI) IS ADDED ON. Z FLAG CLEARED IF RESULT 15200 ;IS GREATER THAN $FFFF. 15210 L0A84 STX $E5 15220 TAX 15230 LDA $00,X 15240 STA $E8 15250 LDA $01,X 15260 LSR A 15270 STA $E9 15280 LDA #$10 15290 STA TMPLOC 15300 LSR $E8 15310 L0AA0 BCC L0AB1 15320 CLC 15330 LDA TMPLOC+1 15340 ADC $0000,Y 15350 STA TMPLOC+1 15360 LDA $EC 15370 ADC $0001,Y 15380 STA $EC 15390 L0AB1 ROR $EC 15400 ROR TMPLOC+1 15410 ROR $E9 15420 ROR $E8 15430 DEC TMPLOC 15440 BNE L0AA0 15450 LDX $E5 15460 LDA $E8 15470 STA $00,X 15480 LDA $E9 15490 STA $01,X 15500 ;CLEAR Z FLAG IF OVERFLOW 15510 LDA TMPLOC+1 15520 ORA $EC 15530 RTS 15540 ; 15550 ;OPCODE $0A - 2ND BYTE IS BRANCH OFFSET 15560 L0AF0 .BYTE EX65 15570 TXA 15580 LDX #$04 15590 L0AF4 STA $6B,X 15600 DEX 15610 BNE L0AF4 15620 STA $27 15630 STA $29 15640 INY 15650 STY $46 15660 LDA #LABL40 15670 STA $47 15680 L0B08 LDY #$00 15690 LDA ($00),Y 15700 L0B0C CMP L0B80,X 15710 BMI L0B14 15720 CMP L0B85,X 15730 BPL L0B14 15740 LDY $27 15750 CPY #$06 15760 BCS L0B61 15770 SBC L0B8A,X 15780 STA $28 15790 LDX $47 15800 LDY $46 15810 BNE L0B48 15820 CLC 15830 ADC $00,X 15840 STA $00,X 15850 BCC L1264 15860 INC $01,X 15870 L1264 INC $47 15880 INC $47 15890 LDA #$02 15900 STA $46 15910 BNE L0B61 15920 L0B48 LDA $00,X ;SET UP EXISTING TOTAL 15930 STA TMPLOC+1 15940 LDA $01,X 15950 STA $EC 15960 LDA L0B8F-1,Y ;SET UP MULTIPLIER (Y=1 OR 2 15970 STA $E8 15980 LDA L0B91-1,Y 15990 STA $E9 16000 LDA #$E8 ;POINTER TO MULTIPLIER 16010 LDY #$28 ;POINTER TO ENCODED CHARACTER 16020 JSR L0A84 ;MULTIPLY 16030 DEC $46 16040 L0B61 INC $00 16050 BNE L0B67 16060 INC $01 16070 L0B67 INC $27 16080 LDX #$03 16090 BNE L0B08 ;ALWAYS BRANCHES 16100 L0B6B CMP #$07 16110 BPL L0B74 16120 JSR L11DC ;EXECUTE P-CODE 16130 .BYTE RET2 ;RETURN - 2ND BYTE OF CALL IS O 16140 L0B74 JSR L11DC 16150 ;ERROR 10 - LABEL LONGER THAN 6 CHARS 16160 .BYTE RERR,$0A 16170 .BYTE RET2 ;RETURN - 2ND BYTE OF CALL IS O 16180 L0B14 DEX 16190 BPL L0B0C 16200 LDA $27 16210 BNE L0B6B 16220 L0B7B JSR L11DC 16230 .BYTE RETN 16240 L0B80 .BYTE $41,$30,$2E,$24 16250 L0B85 .BYTE $5B,$3B,$2F,$25 16260 L0B8A .BYTE $3F,$14,$07,$FC 16270 L0B8F .BYTE $28,$40 16280 L0B91 .BYTE $00,$06 16290 ; 16300 ;OPCODE $17 XX - PRINT CONTENTS OF LOCATION 16310 ;XX AS 2-DIGIT HEX NUMBER 16320 L0BE5 TAX 16330 LDA $00,X 16340 JSR HEXOUT 16350 ;ADVANCE IP AND MOVE TO NEXT INSTR 16360 JMP L11CF 16370 ; 16380 ;OPCODE $09 - INSTRUCTION LENGTH = 2 16390 ;EVALUATE EXPRESSION - RESULT IN LABVAL 16400 ;BRANCH ON SECOND BYTE IF ERROR 16410 L0C30 .BYTE SET0,$EC ;SET TO ZERO 16420 .BYTE SET0,$36 16430 .BYTE SET0,NUMVAL ;SET TO ZERO 16440 L0C39 .BYTE CHK0+SPC,L0CB4-* ;ERROR IF CR OR SP 16450 .BYTE RLBL,L0C5D-* ;BRANCH IF LABEL FOUND 16460 .BYTE ADDZ,CNST10,CONST6,$34 ;$34/$35 IS B 16470 .BYTE CHK0+'$,L0C64-* ;BRANCH IF HEX NUMB 16480 .BYTE ADDZ,CONST3,CONST5,$34 ;BASE = 8 16490 .BYTE CHK0+'@,L0C64-* ;BRANCH IF OCTAL NU 16500 .BYTE COPY,CONST2,$34 ;BASE = 2 16510 .BYTE CHK0+'%,L0C64-* ;BRANCH IF BINARY N 16520 .BYTE CHK0+$27,L0CBD-* ;BRANCH IF QUOTE 16530 .BYTE CHK0+'*,L0EFD-* ;BRANCH IF CURRENT 16540 .BYTE COPY,CNST10,$34 ;OTHERWISE ASSUME BA 16550 .DBYTE L0C66+OFFSET 16560 ;HANDLE '*' - LOCATION COUNTER 16570 L0EFD .BYTE COPY,ASMADR,LABVAL 16580 .DBYTE L0EDE+OFFSET 16590 ;LOOK UP VALUE OF LABEL - BRANCH IF ERROR 16600 L0C5D .BYTE LEXP,L0CD6-*,L0CD6-*,L0CD6-* 16610 .BYTE $FB ;JMP TO L0CDC 16620 ;PROCESS NUMERIC LITERAL 16630 L0C64 .BYTE INC0 ;GO TO NEXT CHAR IF NOT DECI 16640 L0C66 .BYTE SET0,LABVAL ;SET RESULT TO ZERO 16650 .BYTE SET0,LABL40 ;LABL40 AND LABL40+1 USE 16660 .BYTE EX65 16670 L0C6D LDY #$00 16680 LDA ($00),Y ;GET NEXT CHARACTER 16690 SEC 16700 LDX $34 16710 SBC #$30 16720 BMI L0CA2 ;BRANCH IF NOT VALID 16730 CMP $34 16740 BPL L0C95 ;BRANCH IF OUT OF RANGE 16750 L0C78 INC LABL40 ;CHAR COUNT 16760 STA TMPLOC+1 16770 LDA #$00 16780 STA $EC 16790 LDX #LABVAL 16800 LDY #LABVAL 16810 LDA #$34 16820 ;MULTIPLY RESULT IN LABVAL BY 10 AND 16830 ;ADD ON NEW DIGIT 16840 JSR L0A84 16850 BEQ L0C8D ;BRANCH IF NO OVERFLOW 16860 INC LABL40+1 ;OVERFLOW COUNT 16870 L0C8D INC $00 ;INCREMENT POINTER 16880 BNE L0C6D 16890 INC $01 16900 BNE L0C6D ;THEN DO NEXT DIGIT 16910 ;DIGIT SEEMS TO BE OUT OF RANGE, BUT 16920 ;CHECK FIRST TO SEE IF IT IS VALID HEX 16930 L0C95 CPX #$10 16940 BNE L0CA2 16950 ;CARRY IS SET ANYWAY AFTER CPX 16960 SBC #$07 16970 BMI L0CA2 16980 CMP #$10 16990 BMI L0C78 17000 ;DIGIT DEFINITELY OUT OF RANGE 17010 L0CA2 LDA LABL40 ;CHECK IF IT'S FIRST CHARACTER 17020 BEQ L0CB1 ;IF SO, "INVALID EXPRESSION" 17030 LDA LABL40+1 ;CHECK IF OVERFLOW HAS OCCURR 17040 BEQ L0CB8 ;IF NOT, VALID TERMINATION OF NU 17050 JSR L11DC ;EXECUTE P-CODE 17060 ;ERROR 3 - ADDRESS NOT VALUD 17070 .BYTE RERR,$03 17080 .BYTE $FB ;JMP TO L0CDC 17090 L0CB1 JSR L11DC ;EXECUTE P-CODE 17100 ;ERROR 7 - INVALID EXPRESSION 17110 L0CB4 .BYTE RERR,$07 17120 .BYTE RET2 ;RETURN - 2ND BYTE OF CALL IS O 17130 L0CB8 JSR L11DC ;EXECUTE P-CODE 17140 .BYTE $FB ;JMP TO L0CDC 17150 ;PROCESS SINGLE QUOTE CHARACTER 17160 L0CBD .BYTE INC0 17170 .BYTE SET0,LABVAL ;SET LABVAL TO ZERO 17180 .BYTE MOVB,CNST7E ;AND PUT BYTE INTO LABVA 17190 L0EDE .BYTE INC0 ;MOVE ON TO NEXT CHAR 17200 .BYTE $FB ;JMP TO L0CDC 17210 ;PROCESS UNDEFINED LABEL 17220 L0CD6 .BYTE ADDZ,CONST1,$ED,$ED 17230 ;ERROR 18 - UNDEFINED LABEL 17240 .BYTE RERR,$12 17250 .BYTE $FC ;JMP TO L0D11 17260 ;LOOK TO SEE IF THERE'S AN OPERATOR 17270 ;SET UP $06/$07 TO POINT TO PREVIOUS OPERATOR 17280 L0CDC .BYTE COPY,$3A,$06 17290 .BYTE CHK6+'/,L0D07-* ;DIVIDE 17300 .BYTE CHK6+'*,L0CF4-* ;MULTIPLY 17310 .BYTE CHK6+'-,L0CEE-* ;SUBTRACT 17320 ;MUST BE '+' - ADD LABVAL TO NUMVAL 17330 .BYTE ADDZ,NUMVAL,LABVAL,NUMVAL 17340 .BYTE $FC ;JMP TO L0D11 17350 ;SUBTRACT - SUBTRACT LABVAL FROM NUMVAL 17360 L0CEE .BYTE SUBZ,NUMVAL,LABVAL,NUMVAL 17370 .BYTE $FC ;JMP TO L0D11 17380 ;MULTIPLY NUMVAL BY LABVAL 17390 L0CF4 .BYTE EX65 17400 LDA #NUMVAL 17410 LDY #LABVAL 17420 STX TMPLOC+1 17430 STX $EC 17440 TAX 17450 JSR L0A84 ;MULTIPLY 17460 JMP L0D02 17470 ;DIVIDE NUMVAL BY LABVAL 17480 L0D07 .BYTE COPY,NUMVAL,$26 17490 .BYTE EX65 17500 LDX #$26 17510 LDY #LABVAL 17520 LDA #NUMVAL 17530 JSR L052A 17540 L0D02 JSR L11DC ;EXECUTE P-CODE 17550 ;LOOK FOR NEXT OPERATOR - 17560 ;GO TO L0D1F IF FOUND 17570 L0D11 .BYTE CHK0+'+,L0D1F-* 17580 .BYTE CHK0+'-,L0D1F-* 17590 .BYTE CHK0+'*,L0D1F-* 17600 .BYTE CHK0+'/,L0D1F-* 17610 ;OTHERWISE, EXIT 17620 ;SET TOP BIT OF $ED TO 1 17630 ;IF RESULT $0100 OR GREATER. 17640 .BYTE BLES,NUMVAL,CONST1-1,L0D30-* 17650 .BYTE ADDZ,CNST80,$ED,$ED 17660 L0D30 .BYTE RETN 17670 ;OPERATOR FOUND - SO MOVE IT INTO 17680 ;LOCATION POINTED TO BY $3A/$3B 17690 L0D1F .BYTE MOVB,$3A 17700 .BYTE INC0 17710 .DBYTE L0C39+OFFSET ;MOVE ON TO NEXT CHARA 17720 L0D34 JSR L11DC ;EXECUTE P-CODE 17730 ;ERROR 5 - ILLEGAL OPERAND TYPE FOR THIS INSTR 17740 .BYTE RERR,$05 17750 .BYTE $FF ;JMP TO LINOUT 17760 L0D3D .BYTE EX65 17770 LDY #$FF 17780 LDA DRTYPE+1 17790 AND $57 17800 BNE L0D4F 17810 LDY #$07 17820 LDA DRTYPE 17830 AND $56 17840 BEQ L0D34 17850 L0D4F ROL A 17860 INY 17870 BCC L0D4F 17880 CPY #$08 17890 BPL L0DB1 17900 LDA L0DFD,Y 17910 AND #$2A 17920 BNE L0D90 17930 TYA 17940 BNE L0DB1 17950 LDA #$3F 17960 BIT $ED 17970 BNE L0DB1 17980 JSR L11DC ;EXECUTE P-CODE 17990 .BYTE SUBZ,NUMVAL,ASMADR,NUMVAL 18000 .BYTE SUBZ,NUMVAL,CONST2,NUMVAL 18010 .BYTE BLES,NUMVAL,CNST80,L0D8C-* 18020 .BYTE ADDZ,NUMVAL,CNST80,$1C 18030 .BYTE BLES,$1C,CNST80,L0D8C-* 18040 ;ERROR 16 - RELATIVE BRANCH OUT OF RANGE 18050 .BYTE RERR,$10 18060 .BYTE DECR,INSTLN 18070 .BYTE $FF ;JMP TO LINOUT 18080 L0D90 LDA $ED 18090 ASL A 18100 BNE L0DA6 18110 BCC L0DB1 18120 INY 18130 LDA L0DFD,Y 18140 AND DRTYPE+1 18150 BNE L0DB1 18160 JSR L11DC ;EXECUTE P-CODE 18170 ;ERROR 3 - ADDRESS NOT VALID 18180 .BYTE RERR,$03 18190 .BYTE $FF ;JMP TO LINOUT 18200 L0DA6 INY 18210 LDA L0DFD,Y 18220 STY DRTYPE 18230 AND DRTYPE+1 18240 BNE L0DCE 18250 .BYTE $24 18260 L0D8C .BYTE EX65 18270 DEY 18280 L0DB1 LDA $20 18290 LSR A 18300 LDA L0E0D,Y 18310 BCS L0DBC 18320 LDA L0E19,Y 18330 L0DBC CLC 18340 ADC $20 18350 STA INSTRN 18360 LDA L0DF1,Y 18370 STA INSTLN 18380 JSR L11DC ;EXECUTE P-CODE 18390 .BYTE COPY,NUMVAL,INSTRN+1 18400 .BYTE $FF ;JMP TO LINOUT 18410 L0DCE JSR L11DC ;EXECUTE P-CODE 18420 ;ERROR 19 - FWD REF TO PAGE ZERO MEMORY 18430 .BYTE RERR,$13 18440 .BYTE EX65 18450 LDY DRTYPE 18460 JMP L0DB1 18470 L0DD5 .BYTE $60,$60,$00,$80,$00,$00,$00 18480 .BYTE $00,$00,$00,$10,$00,$00,$00 18490 L0DE3 .BYTE $7D,$3D,$3C,$3C,$73,$32,$7C 18500 .BYTE $38,$70,$30,$10,$10,$00,$80 18510 L0DF1 .BYTE $02,$02,$02,$03,$02 18520 .BYTE $03,$02,$03,$01,$02,$02,$03 18530 L0DFD .BYTE $80,$40,$20,$10 18540 .BYTE $08,$04,$02,$01 18550 L0E0D .BYTE $00,$08,$04,$0C,$14,$1C 18560 .BYTE $00,$18,$00,$10,$00,$00 18570 L0E19 .BYTE $00,$00,$04,$0C,$14,$1C 18580 .BYTE $14,$1C,$08,$00,$00,$2C 18590 ; 18600 ;OUTPUT ACCUMLATOR AS HEX NUMBER, BUT 18610 ;ADD ONTO CHKSUM FIRST 18620 HEXCHK PHA 18630 CLC 18640 ADC CHKSUM 18650 STA CHKSUM 18660 BCC L1942 18670 INC CHKSUM+1 18680 L1942 PLA 18690 ;OUTPUT ACCUMLATOR AS HEX NUMBER 18700 HEXOUT PHA 18710 LSR A 18720 LSR A 18730 LSR A 18740 LSR A 18750 JSR HEXDIG ;PRINT SINGLE HEX DIGIT IN ACCU 18760 PLA 18770 AND #$0F 18780 ;PRINT SINGLE HEX DIGIT IN ACCUMULATOR 18790 HEXDIG ORA #'0 18800 CMP #'9+1 18810 BCC L132E 18820 ADC #6 18830 L132E JMP COUT 18840 ;A2 - ASSEMBLE TO HEX FILE 18850 A2OUT .BYTE EX65 18860 DEY ;Y = 0 18870 LSR ASMBRK 18880 LDA INSTLN 18890 STA $E4 18900 BCS FLUSHB 18910 L10DA DEC $E4 18920 BMI ADDLNP 18930 LDX A2BLEN 18940 LDA INSTRN,Y 18950 STA A2BUFF,X 18960 INY 18970 INX 18980 STX A2BLEN 18990 CPX #24 ;BUFFER IS MAX 24 CHARS 19000 BNE L10DA 19010 ;FLUSH THE BUFFER FOR A2 OPTION 19020 FLUSHB LDX A2BLEN 19030 BEQ L126A 19040 LDA #'; 19050 JSR COUT ;PRINT CHARACTER IN ACC 19060 ;PRINT NUMBER OF BYTES AND START ADDR 19070 TXA 19080 JSR HEXCHK 19090 LDX #2 19100 L10FF LDA BUFADR-1,X 19110 JSR HEXCHK 19120 DEX 19130 BNE L10FF 19140 ;PRINT DATA BYTES 19150 L1107 LDA A2BUFF,X 19160 JSR HEXCHK 19170 INX 19180 DEC A2BLEN 19190 BNE L1107 19200 ;PRINT CHECKSUM 19210 LDA CHKSUM+1 19220 JSR HEXOUT 19230 LDA CHKSUM 19240 JSR HEXOUT 19250 JSR NEWLIN 19260 ;PRINT SIX NULL CHARACTERS 19270 LDX #$06 19280 L1262 LDA #$00 19290 JSR COUT ;PRINT CHARACTER IN ACC 19300 DEX 19310 BNE L1262 19320 L126A STX CHKSUM 19330 STX CHKSUM+1 19340 ;SET START ADDRESS OF NEXT BLOCK 19350 CLC 19360 TYA 19370 ADC ASMADR 19380 STA BUFADR 19390 LDA #$00 19400 ADC ASMADR+1 19410 STA BUFADR+1 19420 JMP L10DA 19430 ; 19440 ADDLNP JSR L11DC ;EXECUTE P-CODE 19450 ;ADD INSTRUCTION LENGTH ONTO CURRENT 19460 ;LOCATION THEN EXIT 19470 ADDLEN .BYTE ADDZ,ASMADR,INSTLN,ASMADR 19480 .BYTE RETN 19490 ; 19500 ;A2 OR A3 OPTIONS 19510 A2ORA3 .BYTE BEQU,ASMOPT,CONST2,A2OUT-* 19520 ; 19530 ;A3 - ASSEMBLE TO MEMORY 19540 .BYTE ADDZ,ASMADR,ASMOFS,$1C ;ADD OFFSET 19550 .BYTE BMOV,INSTLN,CNST50,$1C ;COPY INSTR T 19560 .DBYTE L0E34+OFFSET ;CHECK FOR ASM ERRORS 19570 ; 19580 ;OPCODE $08 - INSTRUCTION LENGTH = 1 19590 ;OUTPUT CURRENT ASSEMBLER INSTRUCTION 19600 ;RELEVANT LOCATIONS: 19610 ;NUMERR = ZERO IF NO ERRORS ON THIS LINE 19620 ; 19630 ;GO TO A2ORA3 IF A2/A3 OPTION, AND PASS 2 19640 L10B3 .BYTE BNEQ,PASS,CONST2,L10BD-* 19650 .BYTE BGEQ,ASMOPT,CONST2,A2ORA3-* 19660 ; 19670 ;GO TO ADDLEN IF ERROR, OR IF IT'S BOTH PASS 2 AN 19680 ;A LISTING IS REQUIRED. 19690 L10BD .BYTE BEQU,PASS,CONST1,L0E34-* ;BR IF PAS 19700 .BYTE BEQU,ASMOPT,CONST0,L0E39-* ;BR IF L 19710 ;GO TO ADDLEN IF NO ERRORS 19720 L0E34 .BYTE BEQU,CONST0,NUMERR,ADDLEN-* 19730 ; 19740 ;OUTPUT LINE OF ASSEMBLY LISTING 19750 L0E39 .BYTE PDEC,LINENO ;PRINT LINE NO 19760 .BYTE BEQU,PASS,CONST1,L0E6A-* ;BRANCH IF 19770 .BYTE MESG,' ',$00 ;PRINT SPACE 19780 .BYTE PHEX,ASMADR+1 ;PRINT CURRENT ADDRESS 19790 .BYTE PHEX,ASMADR 19800 .BYTE MESG,' ',$00 ;PRINT SPACE 19810 ; 19820 ;PRINT 0, 1, 2 OR 3 BYTES OF OBJECT CODE, 19830 ;PLUS SPACES TO PAD IT OUT 19840 .BYTE BNEQ,INSTLN,CONST0,PRINST-* 19850 .BYTE MESG,' ',$00 19860 TWOSPC .BYTE MESG,' ',$00 19870 ONESPC .BYTE MESG,' ',$00 19880 ; 19890 ;IF PRFLAG IS SET THEN THE LINE HAS ALREADY 19900 ;BEEN PRINTED - APPLIES FOR DIRECTIVES, WHICH 19910 ;MAY PRODUCE MORE THAN ONE LINE OF OUTPUT. 19920 L0E6A .BYTE BEQU,CONST1,PRFLAG,L0EC5-* 19930 .BYTE MESG,' ',$00 19940 .BYTE PLIN,$02 ;PRINT OUT LINE OF TEXT 19950 .BYTE SET1,PRFLAG ;SET PRFLAG 19960 ; 19970 ;PROCESS ASSEMBLY ERRORS 19980 L0E77 .BYTE GERR,$20,ADDLEN-* ;BR IF NO ERRORS 19990 .BYTE ADDZ,$06,CONST6,$06 ;ADD 6 TO $06/$0 20000 .BYTE BEQU,PASS,CONST1,L0E9E-* ;BRANCH IF 20010 .BYTE ADDZ,$06,CNST12,$06 ;ADD 12 TO $06/$ 20020 L0E9E .BYTE PERR,'E#',$00 20030 .BYTE PDEC,$20 ;PRINT ERROR NUMBER 20040 L0EC5 .BYTE MESG,$0D ;END OF LINE 20050 .DBYTE L0E77+OFFSET ;LOOK FOR NEXT ERROR 20060 ; 20070 PRINST .BYTE PHEX,INSTRN 20080 .BYTE BEQU,INSTLN,CONST1,TWOSPC-* 20090 .BYTE PHEX,INSTRN+1 20100 .BYTE BEQU,INSTLN,CONST2,ONESPC-* 20110 .BYTE PHEX,INSTRN+2 20120 .DBYTE L0E6A+OFFSET 20130 ; 20140 ;TABLE OF OPCODE MNEMONICS 20150 ;LOW BYTE OF MNEMONIC IN BASE-40 20160 MNEMLO .BYTE $40 ;A 20170 .BYTE $E3 ;ADC 20180 .BYTE $74 ;AND 20190 .BYTE $44 ;ASL 20200 .BYTE $FB ;BCC 20210 .BYTE $0B ;BCS 20220 .BYTE $59 ;BEQ 20230 .BYTE $FC ;BIT 20240 .BYTE $91 ;BMI 20250 .BYTE $B5 ;BNE 20260 .BYTE $0C ;BPL 20270 .BYTE $5B ;BRK 20280 .BYTE $F3 ;BVC 20290 .BYTE $03 ;BVS 20300 .BYTE $A3 ;CLC 20310 .BYTE $A4 ;CLD 20320 .BYTE $A9 ;CLI 20330 .BYTE $B6 ;CLV 20340 .BYTE $D8 ;CMP 20350 .BYTE $58 ;CPX 20360 .BYTE $59 ;CPY 20370 .BYTE $CB ;DEC 20380 .BYTE $E0 ;DEX 20390 .BYTE $E1 ;DEY 20400 .BYTE $AA ;EOR 20410 .BYTE $73 ;INC 20420 .BYTE $88 ;INX 20430 .BYTE $89 ;INY 20440 .BYTE $98 ;JMP 20450 .BYTE $8A ;JSR 20460 .BYTE $A1 ;LDA 20470 .BYTE $B8 ;LDX 20480 .BYTE $B9 ;LDY 20490 .BYTE $0A ;LSR 20500 .BYTE $E8 ;NOP 20510 .BYTE $91 ;ORA 20520 .BYTE $41 ;PHA 20530 .BYTE $50 ;PHP 20540 .BYTE $E1 ;PLA 20550 .BYTE $F0 ;PLP 20560 .BYTE $E4 ;ROL 20570 .BYTE $EA ;ROR 20580 .BYTE $A9 ;RTI 20590 .BYTE $B3 ;RTS 20600 .BYTE $13 ;SBC 20610 .BYTE $8B ;SEC 20620 .BYTE $8C ;SED 20630 .BYTE $91 ;SEI 20640 .BYTE $E1 ;STA 20650 .BYTE $F8 ;STX 20660 .BYTE $F9 ;STY 20670 .BYTE $40 ;TAX 20680 .BYTE $41 ;TAY 20690 .BYTE $10 ;TSX 20700 .BYTE $C1 ;TXA 20710 .BYTE $D3 ;TXS 20720 .BYTE $E9 ;TYA 20730 ;THESE LAST SIX BYTES ARE NOT NEEDED 20740 ;BECAUSE NO BASE-40 ENCODING CAN 20750 ;EXCEED $FF00. 20760 ;.BYTE $FF ;NULL 20770 ;.BYTE $FF ;NULL 20780 ;.BYTE $FF ;NULL 20790 ;.BYTE $FF ;NULL 20800 ;.BYTE $FF ;NULL 20810 ;.BYTE $FF ;NULL 20820 ; 20830 ;TABLE OF OPCODE MNEMONICS 20840 ;HIGH BYTE OF MNEMONIC IN BASE-40 20850 MNEMHI .BYTE $06 ;A 20860 .BYTE $06 ;ADC 20870 .BYTE $08 ;AND 20880 .BYTE $09 ;ASL 20890 .BYTE $0C ;BCC 20900 .BYTE $0D ;BCS 20910 .BYTE $0D ;BEQ 20920 .BYTE $0D ;BIT 20930 .BYTE $0E ;BMI 20940 .BYTE $0E ;BNE 20950 .BYTE $0F ;BPL 20960 .BYTE $0F ;BRK 20970 .BYTE $0F ;BVC 20980 .BYTE $10 ;BVS 20990 .BYTE $14 ;CLC 21000 .BYTE $14 ;CLD 21010 .BYTE $14 ;CLI 21020 .BYTE $14 ;CLV 21030 .BYTE $14 ;CMP 21040 .BYTE $15 ;CPX 21050 .BYTE $15 ;CPY 21060 .BYTE $19 ;DEC 21070 .BYTE $19 ;DEX 21080 .BYTE $19 ;DEY 21090 .BYTE $21 ;EOR 21100 .BYTE $3A ;INC 21110 .BYTE $3A ;INX 21120 .BYTE $3A ;INY 21130 .BYTE $40 ;JMP 21140 .BYTE $41 ;JSR 21150 .BYTE $4B ;LDA 21160 .BYTE $4B ;LDX 21170 .BYTE $4B ;LDY 21180 .BYTE $4E ;LSR 21190 .BYTE $59 ;NOP 21200 .BYTE $60 ;ORA 21210 .BYTE $65 ;PHA 21220 .BYTE $65 ;PHP 21230 .BYTE $65 ;PLA 21240 .BYTE $65 ;PLP 21250 .BYTE $72 ;ROL 21260 .BYTE $72 ;ROR 21270 .BYTE $73 ;RTI 21280 .BYTE $73 ;RTS 21290 .BYTE $77 ;SBC 21300 .BYTE $77 ;SEC 21310 .BYTE $77 ;SED 21320 .BYTE $77 ;SEI 21330 .BYTE $79 ;STA 21340 .BYTE $79 ;STX 21350 .BYTE $79 ;STY 21360 .BYTE $7D ;TAX 21370 .BYTE $7D ;TAY 21380 .BYTE $80 ;TSX 21390 .BYTE $80 ;TXA 21400 .BYTE $80 ;TXS 21410 .BYTE $80 ;TYA 21420 .BYTE $FF ;NULL 21430 .BYTE $FF ;NULL 21440 .BYTE $FF ;NULL 21450 ;LAST THREE ENTRIES CAN BE REMOVED 21460 ;BECAUSE THEY WILL NEVER BE REACHED BY 21470 ;THE BINARY SEARCH ALGORITHM 21480 ;.BYTE $FF ;NULL 21490 ;.BYTE $FF ;NULL 21500 ;.BYTE $FF ;NULL 21510 ; 21520 ;TABLE OF OPCODE MNEMONICS 21530 ;INSTRUCTION BASE: 21540 INSBAS .BYTE $61 ;ADC 21550 .BYTE $21 ;AND 21560 .BYTE $02 ;ASL 21570 .BYTE $90 ;BCC 21580 .BYTE $B0 ;BCS 21590 .BYTE $F0 ;BEQ 21600 .BYTE $20 ;BIT 21610 .BYTE $30 ;BMI 21620 .BYTE $D0 ;BNE 21630 .BYTE $10 ;BPL 21640 .BYTE $00 ;BRK 21650 .BYTE $50 ;BVC 21660 .BYTE $70 ;BVS 21670 .BYTE $18 ;CLC 21680 .BYTE $D8 ;CLD 21690 .BYTE $58 ;CLI 21700 .BYTE $B8 ;CLV 21710 .BYTE $C1 ;CMP 21720 .BYTE $E0 ;CPX 21730 .BYTE $C0 ;CPY 21740 .BYTE $C2 ;DEC 21750 .BYTE $CA ;DEX 21760 .BYTE $88 ;DEY 21770 .BYTE $41 ;EOR 21780 .BYTE $E2 ;INC 21790 .BYTE $E8 ;INX 21800 .BYTE $C8 ;INY 21810 .BYTE $40 ;JMP 21820 .BYTE $14 ;JSR 21830 .BYTE $A1 ;LDA 21840 .BYTE $A2 ;LDX 21850 .BYTE $A0 ;LDY 21860 .BYTE $42 ;LSR 21870 .BYTE $EA ;NOP 21880 .BYTE $01 ;ORA 21890 .BYTE $48 ;PHA 21900 .BYTE $08 ;PHP 21910 .BYTE $68 ;PLA 21920 .BYTE $28 ;PLP 21930 .BYTE $22 ;ROL 21940 .BYTE $62 ;ROR 21950 .BYTE $40 ;RTI 21960 .BYTE $60 ;RTS 21970 .BYTE $E1 ;SBC 21980 .BYTE $38 ;SEC 21990 .BYTE $F8 ;SED 22000 .BYTE $78 ;SEI 22010 .BYTE $81 ;STA 22020 .BYTE $82 ;STX 22030 .BYTE $80 ;STY 22040 .BYTE $AA ;TAX 22050 .BYTE $A8 ;TAY 22060 .BYTE $BA ;TSX 22070 .BYTE $8A ;TXA 22080 .BYTE $9A ;TXS 22090 .BYTE $98 ;TYA 22100 ; 22110 ;TABLE OF OPCODE MNEMONICS 22120 ;INSTRUCTION TYPE: 22130 INSTYP .BYTE $0F ;A 22140 .BYTE $00 ;ADC, AND 22150 .BYTE $3D ;ASL, BCC 22160 .BYTE $DD ;BCS, BEQ 22170 .BYTE $9D ;BIT, BMI 22180 .BYTE $DD ;BNE, BPL 22190 .BYTE $CD ;BRK, BVC 22200 .BYTE $DC ;BVS, CLC 22210 .BYTE $CC ;CLD, CLI 22220 .BYTE $C0 ;CLV, CMP 22230 .BYTE $88 ;CPX, CPY 22240 .BYTE $2C ;DEC, DEX 22250 .BYTE $C0 ;DEY, EOR 22260 .BYTE $2C ;INC, INX 22270 .BYTE $CA ;INY, JMP 22280 .BYTE $B0 ;JSR, LDA 22290 .BYTE $46 ;LDX, LDY 22300 .BYTE $3C ;LSR, NOP 22310 .BYTE $0C ;ORA, PHA 22320 .BYTE $CC ;PHP, PLA 22330 .BYTE $C3 ;PLP, ROL 22340 .BYTE $3C ;ROR, RTI 22350 .BYTE $C0 ;RTS, SBC 22360 .BYTE $CC ;SEC, SED 22370 .BYTE $C1 ;SEI, STA 22380 .BYTE $57 ;STX, STY 22390 .BYTE $CC ;TAX, TAY 22400 .BYTE $CC ;TSX, TXA 22410 .BYTE $CC ;TXS, TYA 22420 ; 22430 L1028 .BYTE SET0,INSTLN 22440 .BYTE INC0 22450 .BYTE SKIP ;SKIP SPACES 22460 .BYTE EXPR,LINOUT-* 22470 .BYTE CHK0+SPC,L1036-* 22480 .BYTE $FE ;JMP TO L08E6 22490 L1036 .BYTE COPY,$02,$00 22500 .BYTE SKIP ;SKIP SPACES 22510 .BYTE RLBL,L103D-* 22520 L103D .BYTE LVAL,L104C-*,L104C-*,L104C-* 22530 .BYTE COPY,NUMVAL,LABVAL 22540 .BYTE BMOV,CONST2,CNST7E,$0C 22550 .BYTE GERR,DRTYPE,L104C-* 22560 L104C .BYTE $FF ;JMP TO LINOUT 22570 L104E .BYTE EX65 22580 STX DRTYPE+1 22590 LDX #$03 22600 L1051 LDA LABL40+1 22610 CMP DIRHI,X 22620 BEQ L1062 22630 L105D DEX 22640 BPL L1051 22650 JSR L11DC ;EXECUTE P-CODE 22660 .DBYTE L114F+OFFSET 22670 DIRHI .BYTE ADDZ,TXTPOS,$92,$19 22680 L10A7 .BYTE SET0,INSTLN 22690 ;OUTPUT LINE OF ASSEMBLED CODE THEN 22700 ;MOVE ON TO NEXT LINE 22710 LINOUT .BYTE OUTP ;OUTPUT ASSEMBLED LINE 22720 ;GET NEXT LINE AND GO TO L10B0 IF END 22730 L10AB .BYTE NXLN,L10B0-* 22740 .DBYTE L085D+OFFSET ;PROCESS NEXT LINE 22750 L1062 STX DRTYPE 22760 CPX #3 22770 BNE STDRLN 22780 DEX 22790 STDRLN STX INSTLN 22800 JSR L11DC ;EXECUTE P-CODE 22810 .BYTE SKIP ;SKIP SPACES 22820 ;IF .BYT, .WOR, OR .DBY, GO TO L1230 22830 .BYTE BNEQ,DRTYPE,CONST0,L1230-* 22840 .BYTE OUTP 22850 ;END OF SOURCE FILE REACHED 22860 L10B0 .BYTE BNEQ,ASMOPT,CONST2,L0E8A-* 22870 ;IF DOING 'A2', FLUSH BUFFER 22880 .BYTE SET1,ASMBRK 22890 .BYTE OUTP 22900 L0E8A .BYTE INCR,PASS ;NEXT PASS 22910 ;GO BACK TO NXTPAS TO START NEXT PASS 22920 .BYTE BRGR,PASS,CONST2,L0E94-* 22930 .DBYTE NXTPAS+OFFSET 22940 L0E94 .BYTE $FD ;JMP TO L0620 22950 L123B .BYTE BEQU,DRTYPE,CONST1,L1244-* 22960 L1241 .BYTE $FE ;JMP TO L08E6 22970 L1246 .BYTE CHK0+$0D,L1098-* 22980 .BYTE MOVB,$72 22990 .BYTE OUTP 23000 L1244 .BYTE INC0 23010 .BYTE CHK0+$27,L1251-* ;SINGLE QUOTE CHAR 23020 .DBYTE L1246+OFFSET 23030 L1251 .BYTE INC0 23040 .BYTE CHK0+$27,L1246-* ;SINGLE QUOTE CHAR 23050 L1098 .DBYTE L108E+OFFSET 23060 L109A .BYTE INC0 23070 ;PROCESS .BYTE, .WORD OR .DBYTE 23080 L1230 .BYTE CHK0+$27,L123B-* ;SINGLE QUOTE 23090 .BYTE EXPR,L1241-* 23100 .BYTE COPY,NUMVAL,INSTRN 23110 .BYTE BNEQ,DRTYPE,CONST3,L108A-* 23120 .BYTE EX65 23130 LDA INSTRN 23140 LDY INSTRN+1 23150 STA INSTRN+1 23160 STY INSTRN 23170 JSR L11DC ;EXECUTE P-CODE 23180 L108A .BYTE OUTP 23190 L108E .BYTE CHK0+',,L109A-* 23200 .BYTE CHK0+SPC,L10AB-* 23210 ;ERROR 7 - INVALID EXPRESSION 23220 .BYTE RERR,$07 23230 .BYTE $FF ;JMP TO LINOUT 23240 ; 23250 ;ZERO PAGE LOCATIONS TO BE UPDATED UPON STARTUP 23260 ZPADDR .BYTE $02,IP,IP+1,$2E 23270 .BYTE $2F,CNST14,$3A,CNST10 23280 .BYTE CONST1,CONST3,NOPBYT,NOPBYT+1 23290 .BYTE CNST80,$5B,$5D,$5E 23300 .BYTE $60,$62,$65,$67 23310 .BYTE CNST50,CONST2,CNST12,CNST7E 23320 .BYTE CNST6C,CNST44,CONST4,$EE 23330 .BYTE CONST5,CONST6,$00,$80 23340 .BYTE ASMOFS,ASMOFS+1,STTEXT,STTEXT+1 23350 .BYTE ENDMEM,ENDMEM+1,ENDTXT,ENDTXT+1 23360 ; 23370 ;VALUES TO BE PUT IN THESE MEMORY LOCATIONS 23380 ZPCONT .BYTE $80 23390 .WORD PINIT 23400 .BYTE $FF 23410 .BYTE $FF,LINENO,$36,10 23420 .BYTE 1,3,$EA,$EA ;$EA IS A NOP INSTRUCTIO 23430 .BYTE $80,$B0,$40,$20 23440 .BYTE $40,$10,$0C,$03 23450 .BYTE INSTRN,2,12,LABVAL 23460 .BYTE LABL40,ASMADR,4,$37 23470 .BYTE 5,6,$80,$0D 23480 ;LAST 8 BYTES OF ASSEMBLER CODE: 23490 ;2 BYTES OFFSET FOR A3 ASSEMBLE TO MEMORY 23500 ;2 BYTES START OF AVAILABLE MEMORY 23510 ;2 BYTES END OF AVAILABLE MEMORY 23520 ;2 BYTES END OF ASSEMBLER SOURCE TEXT 23530 .WORD 0,LOMEM,HIMEM 23540 ENDIMG .WORD LOMEM 23550 LOMEM ;BOTTOM OF AVAILABLE MEMORY