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