NEW AUTO 3,1 *-------------------------------------- .DUMMY .OR $A700 ASM65816.SEARCH.TABLE .BS 3 ASM65816.GNC .BS 3 ASM65816.GNC.UC .BS 3 ASM65816.GNNB .BS 3 ASM65816.EXPR .BS 10 ASM65816.EXP1 .BS 10 ASM65816.ASM.ERROR .BS 3 ASM65816.EMIT .BS 10 *-------------------------------- .OR $F0 F0-FF is ASM private ZeroPage LEVEL.MASK .BS 1 OPBASE .BS 1 MODE.BYTE .BS 1 FORCE.ADDR.SIZE .BS 1 .ED *-------------------------------- ERR.BAD.OPCODE .EQ 0 ERR.BAD.ADDRESS .EQ 1 ERR.RANGE .EQ 2 ERR.UNDEFINED .EQ 3 *-------------------------------- JMP ASM65816.ASM.INIT JMP ASM65816.ASM.LINE JMP ASM65816.EMIT.VALUE JMP DIR.OP *-------------------------------- .AS -/FOR THE 6502, 65C02, 65R02, 65816/ .HS 00 *-------------------------------- ASM65816.ASM.INIT LDA #0 MASK FOR 6502 STA LEVEL.MASK LDA #15 MARGIN FOR 6502 STA EMIT.MARGIN RTS *-------------------------------- ASM65816.ASM.LINE LDA SEARCH.KEY 1ST LETTER CMP #'A' BCC .5 ...NOT A LETTER, SO BADOP CMP #'Z'+1 BCS .5 ...NOT A LETTER, SO BADOP AND #$1F MAKE 01...1A TAX LDA FIRST.LETTER.TABLE-1,X BNE .8 ...UNUSED LETTER .5 JMP BADOPERR *---BUILD OPTBL.PNTR INTO TABLE-------- .8 ADC #OPCODE.TABLE CARRY CLEAR ALREADY STA OPTBL.PNTR LDY /OPCODE.TABLE BCC .1 INY .1 CPX #'R'-$40 WHICH HALF OF TABLE? BCC .2 ...FIRST HALF INY ...SECOND HALF .2 CLC INITIAL SEARCH .3 JSR ASM65816.SEARCH.TABLE BCC .5 ...NOT FOUND *---FOUND IT!-------------------- LDA (OPTBL.PNTR),Y STA OPBASE INY LDA (OPTBL.PNTR),Y AND #$E1 ISOLATE LEVEL BITS BEQ .7 ...PLAIN 6502 LEVEL AND LEVEL.MASK BNE .7 ...ALLOWS 'STP' FOR BOTH 65816 & SWEET-16 SEC CONTINUE SEARCH BCS .3 ...ALWAYS *---BRANCH TO PROCESS OPCODE----- .7 LDA (OPTBL.PNTR),Y AND #$1E TAY LDA OP.MODE+1,Y PHA LDA OP.MODE,Y PHA RTS *-------------------------------- .MA MODE O..]1 .EQ *-OP.MODE .DA OP.]1-1 .EM *-------------------------------- OP.MODE >MODE SNGL 0 -- SINGLE BYTE OPCODES >MODE COPS 2 -- LDA GROUP >MODE SHIFTS 4 -- ASL GROUP >MODE REL16 6 -- BRL & PER >MODE REL8 8 -- RELATIVE BRANCHES >MODE BITS A -- BIT GROUP >MODE MOVES C -- MVP & MVN >MODE JUMPS E -- JUMP GROUP >MODE ROCKB 10 -- ROCKWELL BIT OPS >MODE ROCKC 12 -- ROCKWELL BIT OPS >MODE XN 14 -- SWEET 16 REGISTER OPS >MODE POP 16 -- SWEET 16 POP & POPD >MODE SET 18 -- SWEET 16 SET >MODE CRS 1A -- COP, REP, SEP *-------------------------------- OP.SNGL EMIT.OPBASE LDA OPBASE JMP ASM65816.EMIT *-------------------------------- OP.CRS JSR ASM65816.GNNB CMP #'#' BNE ERBA.E2 JSR ASM65816.EXP1 JMP EMIT.OP.AND.EXP.BYTE ERBA.E2 JMP ERBA.EMIT.TWO *-------------------------------- OP.COPS JSR GENERAL.OPERAND JSR SEE.IF.MODE.LEGAL.AT.LEVEL LDA MODE.BYTE ALL INDIRECT MODES <<<12-16-85>>> AND #$04 REQUIRE ZP VALUE <<<12-16-85>>> BEQ .1 ...NOT INDIRECT <<<12-16-85>>> CPY #14 BCC .4 ...MODES 0...13 DEC ADDR.LENGTH SHORTEN >(ZP) AND >(ZP),Y .4 JSR ASM65816.TEST.EXP.VALUE.ZP BNE ERBA.E2 ...MUST BE DIRECT VALUE .1 LDA ADDR.MODE.BITS.CLASS.1,Y BPL .2 VALID MODE INC ADDR.LENGTH ...DIRECT,Y NOT VALID LDA ADDR.MODE.BITS.CLASS.1+1,Y .2 EOR OPBASE CMP #$89 STA IMMED? BEQ ERBA.E2 ...YES, NO SUCH ANIMAL * FALL INTO EMIT.OP.AND.VALUE *** *-------------------------------- EMIT.OP.AND.VALUE JSR ASM65816.EMIT ASM65816.EMIT.VALUE JSR EMIT.EXP.BYTE DEC ADDR.LENGTH BEQ .2 LDA EXP.VALUE+1 JSR ASM65816.EMIT DEC ADDR.LENGTH BEQ .2 LDA EXP.VALUE+2 JSR ASM65816.EMIT DEC ADDR.LENGTH BEQ .2 LDA EXP.VALUE+3 JSR ASM65816.EMIT .2 RTS *-------------------------------- OP.BITS JSR GENERAL.OPERAND JSR SEE.IF.MODE.LEGAL.AT.LEVEL CPY #7 ONLY MODES 0...6 LEGAL BCS .2 ...NOT VALID MODE LDX OPBASE BNE .0 ...NOT BIT OPCODE LDA LEVEL.MASK AND #$20 BNE .0 ...AT LEAST 65C02 LDA #$60 ONLY ZP AND ABS LEGAL BNE .7 ...ALWAYS .0 LDA CLASS.5.LEGAL.MODES,X .7 AND CLASS.5.MODE.MASKS,Y BNE .4 ...LEGAL LDA PASS BEQ .1 ...IN PASS 1 JSR ASM65816.TEST.EXP.VALUE.ZP BNE .2 ...TOO BIG FOR ZP .1 DEY CHANGE ABS TO ZP MODE BMI .2 ...WASN'T ABS TYA LSR BCC .2 ...WASN'T ABS LDA CLASS.5.LEGAL.MODES,X AND CLASS.5.MODE.MASKS,Y BNE .3 ...LEGAL AFTERALL .2 JMP ERBA.EMIT.TWO INVALID ADDRESS MODE .3 DEC ADDR.LENGTH *---FORM OPCODE------------------ .4 LDA ADDR.MODE.BITS.CLASS.5,Y EOR CLASS.5.OPS,X LDY #$89 CMP #$20 BEQ .5 LDY #$9C CMP #$6C BEQ .5 LDY #$9E CMP #$7C BNE .6 .5 TYA .6 JMP EMIT.OP.AND.VALUE *-------------------------------- OP.SHIFTS JSR ASM65816.GNC CHECK FOR ACCUMULATOR MODE BNE .2 NOT ACCUM MODE JSR ASM65816.GNC BNE .2 NOT ACCUM MODE *---ACCUMULATOR MODE------------- LDA OPBASE EOR #$08 MAKE ACCUM MODE OPCODE BPL .1 NOT INC OR DEC PHA LDA LEVEL.MASK AND #$20 ONLY IN 65C02 AND ABOVE BEQ .5 PLA EOR #$F0 CHANGE EA-->1A, CA-->3A .1 JMP ASM65816.EMIT *---MODES WITH OPERAND FIELD----- .2 DEC CHAR.PNTR JSR GENERAL.OPERAND JSR SEE.IF.MODE.LEGAL.AT.LEVEL CPY #5 ONLY MODES 1...4 LEGAL BCS .5 TYA BEQ .5 ...NO IMMEDIATE MODE ALLOWED LDA ADDR.MODE.BITS.CLASS.1,Y EOR OPBASE JMP EMIT.OP.AND.VALUE .5 JMP ERBA.EMIT.TWO INVALID ADDRESS MODE *-------------------------------- OP.REL8 .DO SWEET.16 LDA OPBASE CHECK FOR 'BNM1' SWEET-16 OP CMP #$09 BNE .1 ...NOT 'BNM1' JSR ASM65816.GNC CHECK FOR '1' CMP #'1' BNE BADOPERR ...NO, SO BAD OP .FIN .1 JSR ASM65816.EXPR LDA OPBASE OP.REL8.A JSR ASM65816.EMIT EMIT OPCODE LDA EXP.UNDEF BMI GOEMIT ...UNDEFINED LDY EXP.VALUE+1 CLC COMPUTE RELATIVE OFFSET LDA EXP.VALUE SBC ORGN STA EXP.VALUE BPL .2 INY .2 TYA SBC ORGN+1 BNE ERR.RANGE.EMIT.ONE EMIT.EXP.BYTE LDA EXP.VALUE GOEMIT JMP ASM65816.EMIT *-------------------------------- BADOPERR LDA #ERR.BAD.OPCODE JMP ASM65816.ASM.ERROR *-------------------------------- * BRL & PER, 16-bit relative *-------------------------------- OP.REL16 JSR ASM65816.EXPR Get value of expression JSR EMIT.OPBASE Emit the opcode, bumping origin once LDA EXP.UNDEF If undefined, say so BMI .3 (If we didn't, might be RANGE ERR) CLC ADD 2 MORE TO ORIGIN LDY ORGN+2 LDA ORGN ADC #2 STA EXP.VALUE+3 (TEMP) LDA ORGN+1 ADC #0 BCC .2 INY BANK BYTE .2 CPY EXP.VALUE+2 IN SAME BANK AS TARGET? BNE ERR.RANGE.EMIT.TWO ...NO, ERR RANGE STA EXP.VALUE+2 YES, SAVE IN ANOTHER TEMP LDA EXP.VALUE TARGET-ORGN+3 SBC EXP.VALUE+3 STA EXP.VALUE LDA EXP.VALUE+1 SBC EXP.VALUE+2 STA EXP.VALUE+1 .3 LDA #2 STA ADDR.LENGTH JMP ASM65816.EMIT.VALUE *-------------------------------- ERR.RANGE.EMIT.TWO JSR ASM65816.EMIT.ZERO ERR.RANGE.EMIT.ONE JSR ASM65816.EMIT.ZERO ASM65816.RAER LDA #ERR.RANGE JMP ASM65816.ASM.ERROR *-------------------------------- OP.MOVES JSR EMIT.OPBASE JSR ASM65816.EXPR GET SOURCE BANK LDA EXP.VALUE+2 PHA JSR ASM65816.GNC CMP #',' MUST HAVE COMMA HERE BNE .1 ...ILLEGAL JSR ASM65816.EXP1 GET DESTINATION BANK LDA EXP.VALUE+2 JSR ASM65816.EMIT PLA JMP ASM65816.EMIT .1 JMP ERBA.EMIT.TWO *-------------------------------- OP.JUMPS JSR GENERAL.OPERAND LDA LEGAL.JUMP.MODES,Y BMI .4 ...ILLEGAL ORA OPBASE TAY LDA LEVEL.MASK BMI .1 65816, ALLOW ALL MODES CPY #5 DISALLOW JML, JSL, AND PEA BCS .4 ...ONE OF THOSE CPY #1 DISALLOW JMP LONG BEQ .4 AND #$20 SEE IF 65C02 BNE .1 ...YES CPY #3 ...NO, DISALLOW JMP (ABS,X) BEQ .4 ...THAT'S WHAT IT IS... .1 LDA JUMP.OPCODES,Y BEQ .4 ...ILLEGAL LDY #2 ASSUME TWO BYTE ADDRESS CMP #$5C CHECK FOR "JMP LONG" BEQ .2 ...YES, 3 BYTES OF ADDRESS CMP #$22 CHECK FOR "JSL" BNE .3 ...NO, ONLY 2 BYTES OF ADDRESS .2 INY 3 BYTE ADDRESS .3 STY ADDR.LENGTH JMP EMIT.OP.AND.VALUE .4 JMP ERBA.EMIT.TWO *-------------------------------- ASM65816.TEST.EXP.VALUE.ZP LDA EXP.VALUE+1 ORA EXP.VALUE+2 ORA EXP.VALUE+3 RTS *-------------------------------- LONG.INDIRECT JSR ASM65816.EXP1 JSR ASM65816.GNC CMP #']' BNE ERBA.EMIT.TWO JSR ASM65816.GNC BEQ .1 ...[EXP] CMP #',' BNE ERBA.EMIT.TWO JSR ASM65816.GNC.UC CMP #'Y' BNE ERBA.EMIT.TWO LDA #$47 ...[EXP],Y .HS 2C .1 LDA #$44 ...[EXP],Y STA MODE.BYTE LDA #2 STA ADDR.LENGTH JMP CHECK.IF.SUFFIX.LEGAL *-------------------------------- IMMEDIATE JSR ASM65816.GNC.UC CMP DLIM 16-BIT IMMEDIATE? BNE .1 ...NO, BACKUP LDA LEVEL.MASK 16-BIT IMMEDIATE OKAY? BPL ERBA.EMIT.TWO ...NOT AT 65816 LEVEL INC ADDR.LENGTH ...YES, INCREASE LENGTH BNE .2 ...ALWAYS .1 DEC CHAR.PNTR .2 JSR ASM65816.EXP1 JSR ASM65816.GNC BNE ERBA.EMIT.TWO ILLEGAL LDA DLIM CMP #'/' #=23, /=2F, ^=5E BCC .4 ...# BEQ .3 .../ JSR ASM65816.EXP.OVER.256 ...^ .3 JSR ASM65816.EXP.OVER.256 .4 LDY #0 SIGNAL IMMEDIATE MODE STY MODE.BYTE COPS NEEDS THIS <<<12-16-85>>> RTS *-------------------------------- ERBA.EMIT.THREE JSR ASM65816.EMIT.ZERO ERBA.EMIT.TWO JSR ASM65816.EMIT.ZERO JSR ASM65816.EMIT.ZERO ASM65816.ERBA LDA #ERR.BAD.ADDRESS JMP ASM65816.ASM.ERROR ASM65816.EMIT.ZERO LDA #0 JMP ASM65816.EMIT *-------------------------------- * RETURN: * # BYTES IN ADDRESS IN ADDR.LENGTH * (Y) = INDEX TO ADDR.MODE.BITS *-------------------------------- GENERAL.OPERAND JSR ASM65816.GNNB GET NEXT NON-BLANK BCS ERBA.EMIT.TWO ...NO OPERAND *---PARSE PREFIX----------------- LDY #1 STY ADDR.LENGTH STA DLIM CMP #'(' BEQ .3 ...indirect, must be ZP CMP #'[' BEQ LONG.INDIRECT CMP #'#' BEQ IMMEDIATE CMP #'/' BEQ IMMEDIATE CMP #'^' BEQ IMMEDIATE CMP #'<' BEQ .3 MAKE FORCE SIZE = 1 DEY Y=0 CMP #'>' BNE .2 ...SIZE NOT FORCED JSR ASM65816.GNC LDY #3 Y=3 CMP DLIM IS IT ">>"? BEQ .3 ...YES DEY Y=2 STA DLIM CHANGE DLIM TO NEW VALUE CMP #'(' IS IT (? BEQ .3 ...YES, >( .2 DEC CHAR.PNTR ...NO, SO BACKUP .3 STY FORCE.ADDR.SIZE *---PARSE THE EXPRESSION--------- JSR ASM65816.EXP1 *---FIGURE # OF BYTES------------ LDX FORCE.ADDR.SIZE BNE .6 ...FORCED WITH <, >, OR >> LDX #2 ASSUME 2-BYTE ADDRESS LDA EXP.UNDEF BMI .6 LDA PASS IGNORE FWD REF FLAG IN PASS 1 BEQ .4 ...PASS 1 LDA EXP.FWDREF ...PASS 2, DEFINED BNE .4 ...BUT NOT FWD REF LDA EXP.VALUE+3 ...FWD REF MUST BE ONLY ORA EXP.VALUE+2 16 BITS BEQ .6 ...IT FITS! BNE ERBA.1 ...ALWAYS, ERBA .4 LDA EXP.VALUE+3 DO NOT ALLOW 32-BITS BNE ERBA.1 ...BAD ADDR LDA EXP.VALUE+2 BNE .5 ...3-BYTE ADDRESS DEX X=1 LDA EXP.VALUE+1 BEQ .6 ...ZP .5 INX .6 STX ADDR.LENGTH *---PARSE SUFFIX----------------- DEX MAKE 0, 1, OR 2 STX MODE.BYTE LDX #6 .7 JSR ASM65816.GNC.UC .8 CMP MODE.CHARS,X BEQ .9 CLC ROL MODE.BYTE DEX BPL .8 BMI ERBA.1 .9 CMP #' ' BLANK? BEQ CHECK.IF.SUFFIX.LEGAL ...YES, END OF OPERAND CMP #')' RIGHT PAREN? BNE .10 ...NO LDA DLIM WAS THERE A LEFT PAREN? CMP #'(' BNE ERBA.1 ...NO .10 SEC ROL MODE.BYTE DEX BPL .7 ERBA.1 JMP ERBA.EMIT.TWO ILLEGAL *-------------------------------- CHECK.IF.SUFFIX.LEGAL LDY #0 SEARCH FORWARD FOR VARIOUS REASONS LDA MODE.BYTE .13 INY CPY #MODE.TABLE.SIZE+1 BCS ERBA.1 ...END OF TABLE CMP MODE.TABLE-1,Y BNE .13 ...KEEP LOOKING RTS *-------------------------------- SEE.IF.MODE.LEGAL.AT.LEVEL LDA LEVEL.MASK BMI .15 ...65816 LEVEL, ALL LEGAL CPY #9 BCC .15 ...6502 MODES BEQ .14 ...65C02 MODE CPY #16 BNE ERBA.1 .14 AND #$20 AT C02 LEVEL? BEQ ERBA.1 ...NO .15 RTS *-------------------------------- ASM65816.EXP.OVER.256 LDA EXP.VALUE+1 STA EXP.VALUE LDA EXP.VALUE+2 STA EXP.VALUE+1 LDA EXP.VALUE+3 STA EXP.VALUE+2 LDA #0 STA EXP.VALUE+3 RTS .DO ROCKWELL *-------------------------------- * ROCKWELL 65C02 EXCLUSIVES * * RMB bit#,zp * SMB bit#,zp * BBR bit#,zp,reladdr * BBS bit#,zp,reladdr *-------------------------------- OP.ROCKB JSR OP.ROCKWELL JSR ASM65816.GNC REQUIRE A COMMA CMP #',' BNE .1 ...NO COMMA LDA EXP.VALUE PHA SAVE ZP VALUE JSR ASM65816.EXP1 GET BRANCH EXPRESSION JSR EMIT.OPBASE <<<12-16-85>>> PLA JMP OP.REL8.A .1 JMP ERBA.EMIT.THREE *-------------------------------- OP.ROCKC JSR OP.ROCKWELL .FIN EMIT.OP.AND.EXP.BYTE JSR EMIT.OPBASE <<<12-16-85>>> JMP EMIT.EXP.BYTE <<<12-16-85>>> *-------------------------------- .DO ROCKWELL OP.ROCKWELL JSR ASM65816.EXPR GET BIT # JSR ASM65816.TEST.EXP.VALUE.ZP BNE .1 ...MUST BE SMALL NUMBER! LDA EXP.VALUE CMP #8 MUST BE 0...7 BCS .1 ...TOO LARGE ASL ASL ASL ASL ORA OPBASE MERGE INTO OPCODE STA OPBASE JSR ASM65816.GNC NEED A COMMA NOW CMP #',' BNE .1 JSR ASM65816.EXP1 GET ZP VALUE JSR ASM65816.TEST.EXP.VALUE.ZP BNE .1 MUST BE ZERO PAGE RTS .1 JMP ERBA.EMIT.TWO *-------------------------------- .ELSE OP.ROCKB OP.ROCKC JMP BADOPERR .FIN .DO SWEET.16 *-------------------------------- * SWEET-16 OPCODES *-------------------------------- OP.POP JSR ASM65816.GNC.UC SEE WHICH: POP OR POPD BEQ OP.XN ...POP CMP #'D' BEQ .1 JMP BADOPERR .1 LDA #$A2 ...POP STA OPBASE *-------------------------------- OP.XN JSR ASM65816.GNNB BCS SWEET.ERBA CMP #'@' BNE .1 ...NOT '@N' LDA OPBASE ...'@N', SEE IF LEGAL AND #2 BEQ SWEET.ERBA ...NOT LEGAL WITH THIS OP LDA OPBASE ...LEGAL, ADD $20 ADC #$1F .CS., SO 1F IS 20 BNE .2 ...ALWAYS .1 DEC CHAR.PNTR Backup character pointer LDA OPBASE LSR BCC SWEET.ERBA 'N' NOT LEGAL FOR THIS OP LDA OPBASE .2 AND #$F0 CLEAR AWAY LEGALITY FLAGS STA OPBASE JSR ASM65816.EXP1 GET REGISTER NUMBER JSR ASM65816.TEST.EXP.VALUE.ZP BNE SWEET.RAER LDA EXP.VALUE CMP #$10 BCS SWEET.RAER ORA OPBASE JMP ASM65816.EMIT *-------------------------------- SWEET.ERBA JMP ASM65816.ERBA SWEET.RAER JMP ASM65816.RAER *-------------------------------- OP.SET JSR OP.XN JSR ASM65816.GNC CMP #',' BNE SWEET.ERBA JSR ASM65816.EXP1 LDA #2 STA ADDR.LENGTH JMP ASM65816.EMIT.VALUE *-------------------------------- .ELSE OP.POP OP.XN OP.SET JMP BADOPERR .FIN *-------------------------------- LEGAL.JUMP.MODES .HS FF.00.00.FF.FF.FF .HS FF.FF.03.02.FF.FF .HS 01.FF.02.FF.03 *-------------------------------- JUMP.OPCODES .HS 4C.5C.6C.7C JMP .HS 20.22.00.FC JSR .HS 00.00.DC.00 JML .HS 22.22.00.00 JSL .HS F4.00.00.00 PEA *-------------------------------- MODE.CHARS .AS / Y,)SX,/ *-------------------------------- MODE.TABLE .HS 00 1 -- DIRECT .HS 40 2 -- ABSOLUTE .HS 30 3 -- DIRECT,X .HS 70 4 -- ABSOLUTE,X .HS 21 5 -- DIRECT,Y .HS 61 6 -- ABSOLUTE,Y .HS 07 7 -- (DIRECT),Y .HS 34 8 -- (DIRECT,X) *---IN 65C02, 802, 816----------- .HS 04 9 -- (DIRECT) *---IN 65802, 816---------------- .HS 28 A -- ...,S .HS 2F B -- (...,S),Y *---ONLY IN 65816---------------- .HS 80 C -- LONG .HS B0 D -- LONG,X .HS 44 E -- >(DIRECT) .HS 47 F -- >(DIRECT),Y *---SPECIAL FOR JMP,JSR (A,X)---- .HS 74 10 -- (ABSOLUTE,X) MODE.TABLE.SIZE .EQ *-MODE.TABLE *-------------------------------- ADDR.MODE.BITS.CLASS.1 .HS 08 0 -- IMMEDIATE .HS 04 1 -- DIRECT .HS 0C 2 -- ABSOLUTE .HS 14 3 -- DIRECT,X .HS 1C 4 -- ABSOLUTE,X .HS FF 5 -- DIRECT,Y <<>> .HS 18 6 -- ABSOLUTE,Y .HS 10 7 -- (DIRECT),Y .HS 00 8 -- (DIRECT,X) *---IN 65C02, 802, 816----------- .HS 13 9 -- (DIRECT) *---IN 65802, 816---------------- .HS 02 A -- ...,S .HS 12 B -- (...,S),Y *---ONLY IN 65816---------------- .HS 0E C -- LONG .HS 1E D -- LONG,X .HS 06 E -- >(DIRECT) .HS 16 F -- >(DIRECT),Y *-------------------------------- ADDR.MODE.BITS.CLASS.5 .HS 00 0 -- IMMEDIATE .HS 04 1 -- DIRECT .HS 0C 2 -- ABSOLUTE .HS 14 3 -- DIRECT,X .HS 1C 4 -- ABSOLUTE,X .HS 14 5 -- DIRECT,Y .HS 1C 6 -- ABSOLUTE,Y *-------------------------------- CLASS.5.MODE.MASKS .HS 80.40.20.10.08.04.02 *-------------------------------- FIRST.LETTER.TABLE .DA #LTR.A-OPCODE.TABLE .DA #LTR.B-OPCODE.TABLE .DA #LTR.C-OPCODE.TABLE .DA #LTR.D-OPCODE.TABLE .DA #LTR.E-OPCODE.TABLE .DA #LTR.F-OPCODE.TABLE .DA #LTR.G-OPCODE.TABLE .DA #LTR.H-OPCODE.TABLE .DA #LTR.I-OPCODE.TABLE .DA #LTR.J-OPCODE.TABLE .DA #LTR.K-OPCODE.TABLE .DA #LTR.L-OPCODE.TABLE .DA #LTR.M-OPCODE.TABLE .DA #LTR.N-OPCODE.TABLE .DA #LTR.O-OPCODE.TABLE .DA #LTR.P-OPCODE.TABLE .DA #LTR.Q-OPCODE.TABLE .DA #LTR.R-OPCODE.TABLE .DA #LTR.S-OPCODE.TABLE .DA #LTR.T-OPCODE.TABLE .DA #LTR.U-OPCODE.TABLE .DA #LTR.V-OPCODE.TABLE .DA #LTR.W-OPCODE.TABLE .DA #LTR.X-OPCODE.TABLE .DA #LTR.Y-OPCODE.TABLE .DA #LTR.Z-OPCODE.TABLE *-------------------------------- * TWO KINDS OF ENTRIES, DISTINGUISHED BY FIRST BIT: * 8-BIT ENTRIES: FIRST BIT = 0 * 24-BIT ENTRIES: FIRST BIT = 1 * * FIRST ENTRY AT EACH LETTER IS AN 8-BIT ENTRY. * EACH 8-BIT ENTRY IS FOLLOWED BY ONE OR MORE * 24-BIT ENTRIES. * THE SUB-LIST OF 24-BIT ENTRIES IS TERMINATED * BY THE NEXT 8-BIT ENTRY. * THE LIST OF 8-BIT ENTRIES IS TERMINATED BY * AN 8-BIT ENTRY WITH BIT 6 = 1. * * THE VALUE OF BITS 5-0 IN AN 8-BIT ENTRY * IS THE DIMINISHED ASCII CODE FOR THE * SECOND LETTER OF AN OPCODE. * THE VALUE OF BITS 5-0 OF A 24-BIT ENTRY * IS THE DIMINISHED ASCII CODE FOR THE * THIRD LETTER OF AN OPCODE. * A...Z = $81...9A * BLANK = $E0 * '1' = $F1 * THE VALUE OF THE SECOND BYTE OF A 24-BIT * ENTRY IS AN OPCODE BASE. * THE THIRD BYTE OF A 24-BIT ENTRY HAS TWO PARTS: * BITS 4-1 ARE AN INDEX TO THE OP.MODE * JUMP TABLE IN ASM.65816 * BITS 7-5 AND 0 ARE LEVEL MASK BITS. * 000XXXX0 = 6502 OPCODE * 000XXXX1 = SWEET-16 * 001XXXX0 = 65C02 * 010XXXX0 = ROCKWELL SPECIALS * 100XXXX0 = 65816 * * LEVEL.MASK = $00 FOR 6502 * = $20 FOR 65C02 * = $60 FOR ROCKWELL C02 * = $A0 FOR 65816 *-------------------------------- OP..1 .SE 0 OP..2 .SE 0 .MA OP .DO "]1"=OP..1=0 LTR.]1 .DA #"]2"-$80 bits 76 = 01 OP..1 .SE "]1" OP..2 .SE "]2" .ELSE .DO "]2"=OP..2=0 .DA #"]2"-$C0 bits 76 = 00 OP..2 .SE "]2" .FIN .FIN .DA #"]3"^$40,#$]4,#O..]5!O..]6 bits 76 = 10 or 11 .EM *-------------------------------- O..65816 .EQ $80 O..65R02 .EQ $40 O..65C02 .EQ $20 O..SWEET .EQ $01 O.. .EQ $00 *-------------------------------- OPCODE.TABLE LTR.F LTR.G LTR.H LTR.K LTR.Q LTR.U LTR.V LTR.Y LTR.Z .HS 00 *-------------------------------- >OP A,D,C,61,COPS >OP A,D,D,A1,XN,SWEET >OP A,N,D,21,COPS >OP A,S,L,02,SHIFTS >OP B,C,C,90,REL8 >OP B,C,S,B0,REL8 >OP B,C," ",03,REL8,SWEET >OP B,E,Q,F0,REL8 >OP B,G,E,B0,REL8 >OP B,I,T,00,BITS >OP B,L,T,90,REL8 >OP B,M,I,30,REL8 >OP B,M," ",05,REL8,SWEET >OP B,M,1,08,REL8,SWEET >OP B,N,E,D0,REL8 >OP B,N,C,02,REL8,SWEET >OP B,N,M,09,REL8,SWEET (BNM1) >OP B,N,Z,07,REL8,SWEET >OP B,P,L,10,REL8 >OP B,P," ",04,REL8,SWEET >OP B,R,A,80,REL8,65C02 >OP B,R,K,00,SNGL >OP B,R,L,82,REL16,65816 >OP B,R," ",01,REL8,SWEET >OP B,V,C,50,REL8 >OP B,V,S,70,REL8 >OP B,B,R,0F,ROCKB,65R02 >OP B,B,S,8F,ROCKB,65R02 >OP B,K," ",0A,SNGL,SWEET >OP B,S," ",0C,REL8,SWEET >OP B,Z," ",06,REL8,SWEET >OP C,L,C,18,SNGL >OP C,L,D,D8,SNGL >OP C,L,I,58,SNGL >OP C,L,V,B8,SNGL >OP C,M,P,C1,COPS >OP C,O,P,02,CRS,65816 >OP C,P,X,04,BITS >OP C,P,Y,03,BITS >OP C,P,R,D1,XN,SWEET >OP D,E,C,C2,SHIFTS >OP D,E,X,CA,SNGL >OP D,E,Y,88,SNGL >OP D,C,R,F1,XN,SWEET >OP E,O,R,41,COPS >OP I,N,C,E2,SHIFTS >OP I,N,X,E8,SNGL >OP I,N,Y,C8,SNGL >OP I,N,R,E1,XN,SWEET >OP J,M,L,08,JUMPS,65816 >OP J,M,P,00,JUMPS >OP J,S,L,0C,JUMPS,65816 >OP J,S,R,04,JUMPS >OP L,D,A,A1,COPS >OP L,D,X,02,BITS >OP L,D,Y,01,BITS >OP L,D," ",23,XN,SWEET >OP L,D,D,42,XN,SWEET >OP L,S,R,42,SHIFTS >OP M,V,N,54,MOVES,65816 >OP M,V,P,44,MOVES,65816 >OP N,O,P,EA,SNGL >OP O,R,A,01,COPS >OP P,E,A,10,JUMPS,65816 >OP P,E,I,0A,BITS,65816 >OP P,E,R,62,REL16,65816 >OP P,H,A,48,SNGL >OP P,H,B,8B,SNGL,65816 >OP P,H,D,0B,SNGL,65816 >OP P,H,K,4B,SNGL,65816 >OP P,H,P,08,SNGL >OP P,H,X,DA,SNGL,65C02 >OP P,H,Y,5A,SNGL,65C02 >OP P,L,A,68,SNGL >OP P,L,B,AB,SNGL,65816 >OP P,L,D,2B,SNGL,65816 >OP P,L,P,28,SNGL >OP P,L,X,FA,SNGL,65C02 >OP P,L,Y,7A,SNGL,65C02 >OP P,O,P,62,POP,SWEET (POP,POPD) >OP R,E,P,C2,CRS,65816 >OP R,O,L,22,SHIFTS >OP R,O,R,62,SHIFTS >OP R,T,I,40,SNGL >OP R,T,L,6B,SNGL,65816 >OP R,T,S,60,SNGL >OP R,T,N,00,SNGL,SWEET >OP R,M,B,07,ROCKC,65R02 >OP R,S," ",0B,SNGL,SWEET >OP S,B,C,E1,COPS >OP S,E,C,38,SNGL >OP S,E,D,F8,SNGL >OP S,E,I,78,SNGL >OP S,E,P,E2,CRS,65816 >OP S,E,T,11,SET,SWEET >OP S,T,A,81,COPS >OP S,T,P,DB,SNGL,65816 >OP S,T,P,72,XN,SWEET >OP S,T,X,06,BITS >OP S,T,Y,05,BITS >OP S,T,Z,07,BITS,65C02 >OP S,T," ",33,XN,SWEET >OP S,T,D,52,XN,SWEET >OP S,U,B,B1,XN,SWEET >OP S,M,B,87,ROCKC,65R02 >OP T,A,X,AA,SNGL >OP T,A,Y,A8,SNGL >OP T,C,D,5B,SNGL,65816 >OP T,C,S,1B,SNGL,65816 >OP T,D,C,7B,SNGL,65816 >OP T,R,B,09,BITS,65C02 >OP T,S,B,08,BITS,65C02 >OP T,S,C,3B,SNGL,65816 >OP T,S,X,BA,SNGL >OP T,X,A,8A,SNGL >OP T,X,S,9A,SNGL >OP T,X,Y,9B,SNGL,65816 >OP T,Y,A,98,SNGL >OP T,Y,X,BB,SNGL,65816 >OP W,A,I,CB,SNGL,65816 >OP W,D,M,42,SNGL,65816 >OP X,B,A,EB,SNGL,65816 >OP X,C,E,FB,SNGL,65816 .HS 40 <<>> *-------------------------------- CLASS.5.OPS * BIT LDY LDX CPY CPX STY STX STZ .HS 20..A0..A2..C0..E0..80..82..60 * * TSB TRB PEI .HS 00..10..D0 * CLASS.5.LEGAL.MODES .HS F8..F8..E6..E0..E0..70..64..78 .HS 60..60..40 * * 80 -- IMMEDIATE * 40 -- DIRECT * 20 -- ABSOLUTE * 10 -- DIRECT,X * 08 -- ABSOLUTE,X * 04 -- DIRECT,Y * 02 -- ABSOLUTE,Y * 01 -- <<>> *-------------------------------- * OPCODE TABLE SELECTION * .OP 6502/65C02/R65C02/65816/SWEET16,... *-------------------------------- DIR.OP LDA #0 STA LEVEL.MASK LDA #15 STA EMIT.MARGIN .1 JSR ASM65816.GNC.UC GET NEXT CHARACTER BCS .5 END LDY #-2 .2 INY INY LDA PSOP.TABLE,Y BEQ .1 ...END OF TABLE, TRY NEXT CHARACTER CMP CURRENT.CHAR BNE .2 ...NOT THIS ONE .3 LDA PSOP.TABLE+1,Y STA LEVEL.MASK BPL .5 LDA #18 STA EMIT.MARGIN .5 RTS RETURN TO ASSEMBLER *-------------------------------- PSOP.TABLE .DA #'8',#$A0 65816 = $A0 .DA #'C',#$20 65C02 = $20 .DO ROCKWELL .DA #'R',#$60 ROCKWELL= $60 .FIN .DO SWEET.16 .DA #'S',#$01 SWEET-16= $01 .FIN .DA #0 *-------------------------------------- MAN SAVE usr/src/scmasm.30/asm65816.s LOAD usr/src/scmasm.30/scmasm.s ASM