S-C Macro Assembler 3.0 -- ASM65816/X.ASM.65816.1
1000 *SAVE X.ASM.65816.1
1010 *--------------------------------
1020 ASM.INIT
1030 LDA #0 MASK FOR 6502
1040 STA LEVEL.MASK
1050 LDA #15 MARGIN FOR 6502
1060 STA EMIT.MARGIN
1070 RTS
1080 *--------------------------------
1090 ASM.LINE
1100 LDA SEARCH.KEY 1ST LETTER
1110 CMP #'A'
1120 BCC .5 ...NOT A LETTER, SO BADOP
1130 CMP #'Z'+1
1140 BCS .5 ...NOT A LETTER, SO BADOP
1150 AND #$1F MAKE 01...1A
1160 TAX
1170 LDA FIRST.LETTER.TABLE-1,X
1180 BNE .8 ...UNUSED LETTER
1190 .5 JMP BADOPERR
1200 *---BUILD OPTBL.PNTR INTO TABLE--------
1210 .8 ADC #OPCODE.TABLE CARRY CLEAR ALREADY
1220 STA OPTBL.PNTR
1230 LDY /OPCODE.TABLE
1240 BCC .1
1250 INY
1260 .1 CPX #'R'-$40 WHICH HALF OF TABLE?
1270 BCC .2 ...FIRST HALF
1280 INY ...SECOND HALF
1290 .2 CLC INITIAL SEARCH
1300 .3 JSR SEARCH.COMPRESSED.TABLE
1310 BCC .5 ...NOT FOUND
1320 *---FOUND IT!--------------------
1330 LDA (OPTBL.PNTR),Y
1340 STA OPBASE
1350 INY
1360 LDA (OPTBL.PNTR),Y
1370 AND #$E1 ISOLATE LEVEL BITS
1380 BEQ .7 ...PLAIN 6502 LEVEL
1390 AND LEVEL.MASK
1400 BNE .7 ...ALLOWS 'STP' FOR BOTH 65816 & SWEET-16
1410 SEC CONTINUE SEARCH
1420 BCS .3 ...ALWAYS
1430 *---BRANCH TO PROCESS OPCODE-----
1440 .7 LDA (OPTBL.PNTR),Y
1450 AND #$1E
1460 TAY
1470 LDA OP.MODE+1,Y
1480 PHA
1490 LDA OP.MODE,Y
1500 PHA
1510 RTS
1520 *--------------------------------
1530 .MA MODE
1540 O..]1 .EQ *-OP.MODE
1550 .DA OP.]1-1
1560 .EM
1570 *--------------------------------
1580 OP.MODE
1590 >MODE SNGL 0 -- SINGLE BYTE OPCODES
1600 >MODE COPS 2 -- LDA GROUP
1610 >MODE SHIFTS 4 -- ASL GROUP
1620 >MODE REL16 6 -- BRL & PER
1630 >MODE REL8 8 -- RELATIVE BRANCHES
1640 >MODE BITS A -- BIT GROUP
1650 >MODE MOVES C -- MVP & MVN
1660 >MODE JUMPS E -- JUMP GROUP
1670 >MODE ROCKB 10 -- ROCKWELL BIT OPS
1680 >MODE ROCKC 12 -- ROCKWELL BIT OPS
1690 >MODE XN 14 -- SWEET 16 REGISTER OPS
1700 >MODE POP 16 -- SWEET 16 POP & POPD
1710 >MODE SET 18 -- SWEET 16 SET
1720 >MODE CRS 1A -- COP, REP, SEP
1730 *--------------------------------
1740 OP.SNGL
1750 EMIT.OPBASE
1760 LDA OPBASE
1770 JMP EMIT
1780 *--------------------------------
1790 OP.CRS JSR GNNB
1800 CMP #'#'
1810 BNE ERBA.E2
1820 JSR EXP1
1830 JMP EMIT.OP.AND.EXP.BYTE
1840 ERBA.E2
1850 JMP ERBA.EMIT.TWO
1860 *--------------------------------
1870 OP.COPS
1880 JSR GENERAL.OPERAND
1890 JSR SEE.IF.MODE.LEGAL.AT.LEVEL
1900 LDA MODE.BYTE ALL INDIRECT MODES <<<12-16-85>>>
1910 AND #$04 REQUIRE ZP VALUE <<<12-16-85>>>
1920 BEQ .1 ...NOT INDIRECT <<<12-16-85>>>
1930 CPY #14
1940 BCC .4 ...MODES 0...13
1950 DEC ADDR.LENGTH SHORTEN >(ZP) AND >(ZP),Y
1960 .4 JSR TEST.EXP.VALUE.ZP
1970 BNE ERBA.E2 ...MUST BE DIRECT VALUE
1980 .1 LDA ADDR.MODE.BITS.CLASS.1,Y
1990 BPL .2 VALID MODE
2000 INC ADDR.LENGTH ...DIRECT,Y NOT VALID
2010 LDA ADDR.MODE.BITS.CLASS.1+1,Y
2020 .2 EOR OPBASE
2030 CMP #$89 STA IMMED?
2040 BEQ ERBA.E2 ...YES, NO SUCH ANIMAL
2050 * FALL INTO EMIT.OP.AND.VALUE ***
2060 *--------------------------------
2070 EMIT.OP.AND.VALUE
2080 JSR EMIT
2090 EMIT.VALUE
2100 JSR EMIT.EXP.BYTE
2110 DEC ADDR.LENGTH
2120 BEQ .2
2130 LDA EXP.VALUE+1
2140 JSR EMIT
2150 DEC ADDR.LENGTH
2160 BEQ .2
2170 LDA EXP.VALUE+2
2180 JSR EMIT
2190 DEC ADDR.LENGTH
2200 BEQ .2
2210 LDA EXP.VALUE+3
2220 JSR EMIT
2230 .2 RTS
2240 *--------------------------------
2250 OP.BITS
2260 JSR GENERAL.OPERAND
2270 JSR SEE.IF.MODE.LEGAL.AT.LEVEL
2280 CPY #7 ONLY MODES 0...6 LEGAL
2290 BCS .2 ...NOT VALID MODE
2300 LDX OPBASE
2310 BNE .0 ...NOT BIT OPCODE
2320 LDA LEVEL.MASK
2330 AND #$20
2340 BNE .0 ...AT LEAST 65C02
2350 LDA #$60 ONLY ZP AND ABS LEGAL
2360 BNE .7 ...ALWAYS
2370 .0 LDA CLASS.5.LEGAL.MODES,X
2380 .7 AND CLASS.5.MODE.MASKS,Y
2390 BNE .4 ...LEGAL
2400 LDA PASS
2410 BEQ .1 ...IN PASS 1
2420 JSR TEST.EXP.VALUE.ZP
2430 BNE .2 ...TOO BIG FOR ZP
2440 .1 DEY CHANGE ABS TO ZP MODE
2450 BMI .2 ...WASN'T ABS
2460 TYA
2470 LSR
2480 BCC .2 ...WASN'T ABS
2490 LDA CLASS.5.LEGAL.MODES,X
2500 AND CLASS.5.MODE.MASKS,Y
2510 BNE .3 ...LEGAL AFTERALL
2520 .2 JMP ERBA.EMIT.TWO INVALID ADDRESS MODE
2530 .3 DEC ADDR.LENGTH
2540 *---FORM OPCODE------------------
2550 .4 LDA ADDR.MODE.BITS.CLASS.5,Y
2560 EOR CLASS.5.OPS,X
2570 LDY #$89
2580 CMP #$20
2590 BEQ .5
2600 LDY #$9C
2610 CMP #$6C
2620 BEQ .5
2630 LDY #$9E
2640 CMP #$7C
2650 BNE .6
2660 .5 TYA
2670 .6 JMP EMIT.OP.AND.VALUE
2680 *--------------------------------
2690 OP.SHIFTS
2700 JSR GNC CHECK FOR ACCUMULATOR MODE
2710 BNE .2 NOT ACCUM MODE
2720 JSR GNC
2730 BNE .2 NOT ACCUM MODE
2740 *---ACCUMULATOR MODE-------------
2750 LDA OPBASE
2760 EOR #$08 MAKE ACCUM MODE OPCODE
2770 BPL .1 NOT INC OR DEC
2780 PHA
2790 LDA LEVEL.MASK
2800 AND #$20 ONLY IN 65C02 AND ABOVE
2810 BEQ .5
2820 PLA
2830 EOR #$F0 CHANGE EA-->1A, CA-->3A
2840 .1 JMP EMIT
2850 *---MODES WITH OPERAND FIELD-----
2860 .2 DEC CHAR.PNTR
2870 JSR GENERAL.OPERAND
2880 JSR SEE.IF.MODE.LEGAL.AT.LEVEL
2890 CPY #5 ONLY MODES 1...4 LEGAL
2900 BCS .5
2910 TYA
2920 BEQ .5 ...NO IMMEDIATE MODE ALLOWED
2930 LDA ADDR.MODE.BITS.CLASS.1,Y
2940 EOR OPBASE
2950 JMP EMIT.OP.AND.VALUE
2960 .5 JMP ERBA.EMIT.TWO INVALID ADDRESS MODE
2970 *--------------------------------
2980 OP.REL8
2990 .DO SWEET.16
3000 LDA OPBASE CHECK FOR 'BNM1' SWEET-16 OP
3010 CMP #$09
3020 BNE .1 ...NOT 'BNM1'
3030 JSR GNC CHECK FOR '1'
3040 CMP #'1'
3050 BNE BADOPERR ...NO, SO BAD OP
3060 .FIN
3070 .1 JSR EXPR
3080 LDA OPBASE
3090 OP.REL8.A
3100 JSR EMIT EMIT OPCODE
3110 LDA EXP.UNDEF
3120 BMI GOEMIT ...UNDEFINED
3130 LDY EXP.VALUE+1
3140 CLC COMPUTE RELATIVE OFFSET
3150 LDA EXP.VALUE
3160 SBC ORGN
3170 STA EXP.VALUE
3180 BPL .2
3190 INY
3200 .2 TYA
3210 SBC ORGN+1
3220 BNE ERR.RANGE.EMIT.ONE
3230 EMIT.EXP.BYTE
3240 LDA EXP.VALUE
3250 GOEMIT JMP EMIT
3260 *--------------------------------
3270 BADOPERR
3280 LDA #ERR.BAD.OPCODE
3290 JMP ASM.ERROR
3300 *--------------------------------
3310 * BRL & PER, 16-bit relative
3320 *--------------------------------
3330 OP.REL16
3340 JSR EXPR Get value of expression
3350 JSR EMIT.OPBASE Emit the opcode, bumping origin once
3360 LDA EXP.UNDEF If undefined, say so
3370 BMI .3 (If we didn't, might be RANGE ERR)
3380 CLC ADD 2 MORE TO ORIGIN
3390 LDY ORGN+2
3400 LDA ORGN
3410 ADC #2
3420 STA EXP.VALUE+3 (TEMP)
3430 LDA ORGN+1
3440 ADC #0
3450 BCC .2
3460 INY BANK BYTE
3470 .2 CPY EXP.VALUE+2 IN SAME BANK AS TARGET?
3480 BNE ERR.RANGE.EMIT.TWO ...NO, ERR RANGE
3490 STA EXP.VALUE+2 YES, SAVE IN ANOTHER TEMP
3500 LDA EXP.VALUE TARGET-ORGN+3
3510 SBC EXP.VALUE+3
3520 STA EXP.VALUE
3530 LDA EXP.VALUE+1
3540 SBC EXP.VALUE+2
3550 STA EXP.VALUE+1
3560 .3 LDA #2
3570 STA ADDR.LENGTH
3580 JMP EMIT.VALUE
3590 *--------------------------------
3600 ERR.RANGE.EMIT.TWO
3610 JSR EMIT.ZERO
3620 ERR.RANGE.EMIT.ONE
3630 JSR EMIT.ZERO
3640 RAER LDA #ERR.RANGE
3650 JMP ASM.ERROR
3660 *--------------------------------
3670 OP.MOVES
3680 JSR EMIT.OPBASE
3690 JSR EXPR GET SOURCE BANK
3700 LDA EXP.VALUE+2
3710 PHA
3720 JSR GNC
3730 CMP #',' MUST HAVE COMMA HERE
3740 BNE .1 ...ILLEGAL
3750 JSR EXP1 GET DESTINATION BANK
3760 LDA EXP.VALUE+2
3770 JSR EMIT
3780 PLA
3790 JMP EMIT
3799 .1 JMP ERBA.EMIT.TWO
3800 *--------------------------------
3810 OP.JUMPS
3820 JSR GENERAL.OPERAND
3830 LDA LEGAL.JUMP.MODES,Y
3840 BMI .4 ...ILLEGAL
3850 ORA OPBASE
3860 TAY
3870 LDA LEVEL.MASK
3880 BMI .1 65816, ALLOW ALL MODES
3890 CPY #5 DISALLOW JML, JSL, AND PEA
3900 BCS .4 ...ONE OF THOSE
3910 CPY #1 DISALLOW JMP LONG
3920 BEQ .4
3930 AND #$20 SEE IF 65C02
3940 BNE .1 ...YES
3950 CPY #3 ...NO, DISALLOW JMP (ABS,X)
3960 BEQ .4 ...THAT'S WHAT IT IS...
3970 .1 LDA JUMP.OPCODES,Y
3980 BEQ .4 ...ILLEGAL
3990 LDY #2 ASSUME TWO BYTE ADDRESS
4000 CMP #$5C CHECK FOR "JMP LONG"
4010 BEQ .2 ...YES, 3 BYTES OF ADDRESS
4020 CMP #$22 CHECK FOR "JSL"
4030 BNE .3 ...NO, ONLY 2 BYTES OF ADDRESS
4040 .2 INY 3 BYTE ADDRESS
4050 .3 STY ADDR.LENGTH
4060 JMP EMIT.OP.AND.VALUE
4066 .4 JMP ERBA.EMIT.TWO
4070 *--------------------------------
4080 TEST.EXP.VALUE.ZP
4090 LDA EXP.VALUE+1
4100 ORA EXP.VALUE+2
4110 ORA EXP.VALUE+3
4120 RTS
4130 *--------------------------------