mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-01-11 20:30:08 +00:00
Added support for clobber, registers, addressing modes and instructions in the 65CE02 instruction set.
This commit is contained in:
parent
1881fb17d0
commit
96cabc382f
@ -5,44 +5,77 @@ import java.io.Serializable;
|
||||
/** Information about what registers/flags of the CPU an ASM instruction clobbers */
|
||||
public class CpuClobber implements Serializable {
|
||||
|
||||
public static final CpuClobber CLOBBER_ALL = new CpuClobber(true, true, true, true, true, true, true, true, true, true, true);
|
||||
public static final CpuClobber CLOBBER_ALL = new CpuClobber(true, true, true, true, true, true, true, true, true, true, true, true, true, true);
|
||||
|
||||
public static final CpuClobber CLOBBER_NONE = new CpuClobber(false, false, false, false, false, false, false, false, false, false, false, false, false, false);
|
||||
|
||||
/** True if the A register is modified. */
|
||||
final boolean registerA;
|
||||
/** True if the X register is modified. */
|
||||
final boolean registerX;
|
||||
/** True if the Y register is modified. */
|
||||
final boolean registerY;
|
||||
/** True if the Z register is modified. (65ce02+). */
|
||||
final boolean registerZ;
|
||||
/** True if the carry flag is modified. */
|
||||
final boolean flagC;
|
||||
/** True if the negative flag is modified. */
|
||||
final boolean flagN;
|
||||
/** true if the zero (equals) flag is modified. */
|
||||
final boolean flagZ;
|
||||
/** True if the overflow flag is modified. */
|
||||
final boolean flagV;
|
||||
/** True if the interrupt flag is modified. */
|
||||
final boolean flagI;
|
||||
/** True if the decimal flag is modified. */
|
||||
final boolean flagD;
|
||||
/** True if the disable extended stack flag is modified. */
|
||||
final boolean flagE;
|
||||
/** true if the program counter is modified (not just incremented to the next instruction). */
|
||||
final boolean registerPC;
|
||||
/** true if the stack pointer is modified.*/
|
||||
/** true if the stack pointer is modified. */
|
||||
final boolean registerSP;
|
||||
/** true if the base page register is modified. (65ce02+)*/
|
||||
final boolean registerBP;
|
||||
|
||||
public CpuClobber(boolean registerA, boolean registerX, boolean registerY, boolean flagC, boolean flagN, boolean flagZ, boolean flagV, boolean flagI, boolean flagD, boolean registerPC, boolean registerSP) {
|
||||
public CpuClobber(boolean registerA, boolean registerX, boolean registerY, boolean registerZ, boolean flagC, boolean flagN, boolean flagZ, boolean flagV, boolean flagI, boolean flagD, boolean flagE, boolean registerPC, boolean registerSP, boolean registerBP) {
|
||||
this.registerA = registerA;
|
||||
this.registerX = registerX;
|
||||
this.registerY = registerY;
|
||||
this.registerZ = registerZ;
|
||||
this.flagC = flagC;
|
||||
this.flagN = flagN;
|
||||
this.flagZ = flagZ;
|
||||
this.flagV = flagV;
|
||||
this.flagI = flagI;
|
||||
this.flagD = flagD;
|
||||
this.flagE = flagE;
|
||||
this.registerPC = registerPC;
|
||||
this.registerSP = registerSP;
|
||||
}
|
||||
|
||||
public CpuClobber() {
|
||||
this(false, false, false, false, false, false, false, false, false, false, false);
|
||||
this.registerBP = registerBP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create clobber from a string containing the names of the clobbered registers/flags.
|
||||
* Registers are upper-case and flags are lower-case. (This is because the 65C02 has both a "Z" register and a "Z" flag. )
|
||||
* EG. "AXcz" means that the A and X registers a and the carry and zero flags are clobbered.
|
||||
* Here is the meaning of each name usable in the string
|
||||
* <ul>
|
||||
* <li> <b>A</b> A register </li>
|
||||
* <li> <b>X</b> X register </li>
|
||||
* <li> <b>Y</b> Y register </li>
|
||||
* <li> <b>Z</b> Z register </li>
|
||||
* <li> <b>c</b> carry flag </li>
|
||||
* <li> <b>v</b> overflow flag </li>
|
||||
* <li> <b>z</b> zero flag </li>
|
||||
* <li> <b>n</b> negative flag </li>
|
||||
* <li> <b>i</b> interrupt flag </li>
|
||||
* <li> <b>d</b> decimal flag </li>
|
||||
* <li> <b>e</b> extended stack disable flag </li>
|
||||
* <li> <b>S</b> stack pointer </li>
|
||||
* <li> <b>B</b> base page register is modified. </li>
|
||||
* <li> <b>P</b> program counter is modified (not just incremented to the next instruction). </li>
|
||||
* </ul>
|
||||
*
|
||||
* @param clobberString The clobber string.
|
||||
*/
|
||||
@ -51,14 +84,17 @@ public class CpuClobber implements Serializable {
|
||||
clobberString.contains("A"),
|
||||
clobberString.contains("X"),
|
||||
clobberString.contains("Y"),
|
||||
clobberString.contains("Z"),
|
||||
clobberString.contains("c"),
|
||||
clobberString.contains("n"),
|
||||
clobberString.contains("z"),
|
||||
clobberString.contains("v"),
|
||||
clobberString.contains("i"),
|
||||
clobberString.contains("d"),
|
||||
clobberString.contains("e"),
|
||||
clobberString.contains("P"),
|
||||
clobberString.contains("S")
|
||||
clobberString.contains("S"),
|
||||
clobberString.contains("B")
|
||||
);
|
||||
}
|
||||
|
||||
@ -73,17 +109,38 @@ public class CpuClobber implements Serializable {
|
||||
clobber1.registerA | clobber2.registerA,
|
||||
clobber1.registerX | clobber2.registerX,
|
||||
clobber1.registerY | clobber2.registerY,
|
||||
clobber1.registerZ | clobber2.registerZ,
|
||||
clobber1.flagC | clobber2.flagC,
|
||||
clobber1.flagN | clobber2.flagN,
|
||||
clobber1.flagZ | clobber2.flagZ,
|
||||
clobber1.flagV | clobber2.flagV,
|
||||
clobber1.flagI | clobber2.flagI,
|
||||
clobber1.flagD | clobber2.flagD,
|
||||
clobber1.flagE | clobber2.flagE,
|
||||
clobber1.registerPC | clobber2.registerPC,
|
||||
clobber1.registerSP | clobber2.registerSP
|
||||
clobber1.registerSP | clobber2.registerSP,
|
||||
clobber1.registerBP | clobber2.registerBP
|
||||
);
|
||||
}
|
||||
|
||||
private String toClobberString() {
|
||||
return
|
||||
(registerA ? "A" : "") +
|
||||
(registerX ? "X" : "") +
|
||||
(registerY ? "Y" : "") +
|
||||
(registerZ ? "Z" : "") +
|
||||
(flagC ? "c" : "") +
|
||||
(flagN ? "n" : "") +
|
||||
(flagZ ? "z" : "") +
|
||||
(flagV ? "v" : "") +
|
||||
(flagI ? "i" : "") +
|
||||
(flagD ? "d" : "") +
|
||||
(flagE ? "e" : "") +
|
||||
(registerPC ? "P" : "") +
|
||||
(registerSP ? "S" : "") +
|
||||
(registerBP ? "B" : "") ;
|
||||
}
|
||||
|
||||
|
||||
public boolean isRegisterA() {
|
||||
return registerA;
|
||||
@ -97,6 +154,10 @@ public class CpuClobber implements Serializable {
|
||||
return registerY;
|
||||
}
|
||||
|
||||
public boolean isRegisterZ() {
|
||||
return registerY;
|
||||
}
|
||||
|
||||
public boolean isFlagC() {
|
||||
return flagC;
|
||||
}
|
||||
@ -121,6 +182,10 @@ public class CpuClobber implements Serializable {
|
||||
return flagD;
|
||||
}
|
||||
|
||||
public boolean isFlagE() {
|
||||
return flagE;
|
||||
}
|
||||
|
||||
public boolean isRegisterPC() {
|
||||
return registerPC;
|
||||
}
|
||||
@ -129,21 +194,13 @@ public class CpuClobber implements Serializable {
|
||||
return registerSP;
|
||||
}
|
||||
|
||||
public boolean isRegisterBP() {
|
||||
return registerBP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return
|
||||
(registerA ? "A" : "") +
|
||||
(registerX ? "X" : "") +
|
||||
(registerY ? "Y" : "") +
|
||||
(flagC ? "c" : "") +
|
||||
(flagN ? "n" : "") +
|
||||
(flagZ ? "z" : "") +
|
||||
(flagV ? "v" : "") +
|
||||
(flagI ? "i" : "") +
|
||||
(flagD ? "d" : "") +
|
||||
(registerPC ? "P" : "") +
|
||||
(registerSP ? "S" : "") ;
|
||||
|
||||
return toClobberString();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -65,12 +65,10 @@ public class Cpu65C02 extends Cpu65xx {
|
||||
addOpcode(0xB7,"smb3", CpuAddressingMode.ZP,5,"");
|
||||
addOpcode(0xBF,"bbs3", CpuAddressingMode.REZ,5,"");
|
||||
addOpcode(0xC7,"smb4", CpuAddressingMode.ZP,5,"");
|
||||
addOpcode(0xCB,"wai", CpuAddressingMode.NON,3,"");
|
||||
addOpcode(0xCF,"bbs4", CpuAddressingMode.REZ,5,"");
|
||||
addOpcode(0xD2,"cmp", CpuAddressingMode.INZ,5,"cnz");
|
||||
addOpcode(0xD7,"smb5", CpuAddressingMode.ZP,5,"");
|
||||
addOpcode(0xDA,"phx", CpuAddressingMode.NON,3,"");
|
||||
addOpcode(0xDB,"stp", CpuAddressingMode.NON,3,"");
|
||||
addOpcode(0xDF,"bbs5", CpuAddressingMode.REZ,5,"");
|
||||
addOpcode(0xE7,"smb6", CpuAddressingMode.ZP,5,"");
|
||||
addOpcode(0xEF,"bbs6", CpuAddressingMode.REZ,5,"");
|
||||
@ -79,7 +77,12 @@ public class Cpu65C02 extends Cpu65xx {
|
||||
addOpcode(0xFA,"plx", CpuAddressingMode.NON,4,"Xnz");
|
||||
addOpcode(0xFF,"bbs7", CpuAddressingMode.REZ,5,"");
|
||||
|
||||
// TODO: Cycle differences for ASL LSR ROL ROR abs,X - http://6502.org/tutorials/65c02opcodes.html
|
||||
// TODO: Cycle differences for ASL LSR ROL ROR abs,X - http://6502.org/tutorials/65c02opcodes.html
|
||||
|
||||
// TODO: Maybe add the 65C02S CPU - which adds the following 2 instructions
|
||||
//addOpcode(0xCB,"wai", CpuAddressingMode.NON,3,"");
|
||||
//addOpcode(0xDB,"stp", CpuAddressingMode.NON,3,"");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package dk.camelot64.cpufamily6502.cpus;
|
||||
|
||||
import dk.camelot64.cpufamily6502.Cpu65xx;
|
||||
import dk.camelot64.cpufamily6502.CpuAddressingMode;
|
||||
|
||||
/**
|
||||
* The 65CE02 instruction set.
|
||||
@ -16,7 +17,64 @@ public class Cpu65CE02 extends Cpu65xx {
|
||||
|
||||
public Cpu65CE02() {
|
||||
super(NAME, Cpu65C02.INSTANCE);
|
||||
// TODO: Add 65CE02 instructions
|
||||
addOpcode(0x2, "cle", CpuAddressingMode.NON, 2, "e");
|
||||
addOpcode(0x3, "see", CpuAddressingMode.NON, 2, "e");
|
||||
addOpcode(0xB, "tsy", CpuAddressingMode.NON, 1, "Ynz");
|
||||
addOpcode(0x12, "ora", CpuAddressingMode.IZZ, 5, "Anz");
|
||||
addOpcode(0x13, "lbpl", CpuAddressingMode.REL, 3, "P");
|
||||
addOpcode(0x1B, "inz", CpuAddressingMode.NON, 1, "Znz");
|
||||
addOpcode(0x22, "jsr", CpuAddressingMode.IND, 7, "PS");
|
||||
addOpcode(0x23, "jsr", CpuAddressingMode.IAX, 7, "PS");
|
||||
addOpcode(0x2B, "tys", CpuAddressingMode.NON, 1, "S");
|
||||
addOpcode(0x32, "and", CpuAddressingMode.IZZ, 5, "Anz");
|
||||
addOpcode(0x33, "lbmi", CpuAddressingMode.REL, 3, "P");
|
||||
addOpcode(0x3B, "dez", CpuAddressingMode.NON, 1, "Znz");
|
||||
addOpcode(0x42, "neg", CpuAddressingMode.NON, 2, "Anz");
|
||||
addOpcode(0x43, "asr", CpuAddressingMode.NON, 2, "Anzc");
|
||||
addOpcode(0x44, "asr", CpuAddressingMode.ZP, 4, "nzc");
|
||||
addOpcode(0x4B, "taz", CpuAddressingMode.NON, 1, "Znz");
|
||||
addOpcode(0x52, "eor", CpuAddressingMode.IZZ, 5, "Anz");
|
||||
addOpcode(0x53, "lbvc", CpuAddressingMode.REL, 3, "P");
|
||||
addOpcode(0x54, "asr", CpuAddressingMode.ZPX, 4, "nzc");
|
||||
addOpcode(0x5B, "tab", CpuAddressingMode.NON, 1, "B");
|
||||
addOpcode(0x5C, "map", CpuAddressingMode.NON, 2, "");
|
||||
addOpcode(0x62, "rtn", CpuAddressingMode.IMM, 7, "P");
|
||||
addOpcode(0x63, "lbsr", CpuAddressingMode.REL, 3, "P");
|
||||
addOpcode(0x6B, "tza", CpuAddressingMode.NON, 1, "Anz");
|
||||
addOpcode(0x72, "adc", CpuAddressingMode.IZZ, 5, "Anzvc");
|
||||
addOpcode(0x73, "lbvs", CpuAddressingMode.REL, 3, "P");
|
||||
addOpcode(0x7B, "tba", CpuAddressingMode.NON, 1, "Anz");
|
||||
addOpcode(0x82, "sta", CpuAddressingMode.ISY, 6, "");
|
||||
addOpcode(0x83, "lbra", CpuAddressingMode.REL, 3, "P");
|
||||
addOpcode(0x8B, "sty", CpuAddressingMode.ABS, 4, "");
|
||||
addOpcode(0x92, "sta", CpuAddressingMode.IZZ, 5, "");
|
||||
addOpcode(0x93, "lbcc", CpuAddressingMode.REL, 3, "P");
|
||||
addOpcode(0x9B, "stx", CpuAddressingMode.ABS, 4, "");
|
||||
addOpcode(0xA3, "ldz", CpuAddressingMode.IMM, 2, "Znz");
|
||||
addOpcode(0xAB, "ldz", CpuAddressingMode.ABS, 4, "Znz");
|
||||
addOpcode(0xB2, "lda", CpuAddressingMode.IZZ, 5, "Anz");
|
||||
addOpcode(0xB3, "lbcs", CpuAddressingMode.REL, 3, "P");
|
||||
addOpcode(0xBB, "ldz", CpuAddressingMode.ABS, 4, "Znz");
|
||||
addOpcode(0xC2, "cpz", CpuAddressingMode.IMM, 2, "nzc");
|
||||
addOpcode(0xC3, "dew", CpuAddressingMode.ABS, 5, "nz");
|
||||
addOpcode(0xCB, "asw", CpuAddressingMode.ABS, 7, "nzc");
|
||||
addOpcode(0xD2, "cmp", CpuAddressingMode.IZZ, 5, "nzc");
|
||||
addOpcode(0xD3, "lbne", CpuAddressingMode.REL, 3, "P");
|
||||
addOpcode(0xD4, "cpz", CpuAddressingMode.ZP, 3, "nzc");
|
||||
addOpcode(0xDB, "phz", CpuAddressingMode.NON, 3, "S");
|
||||
addOpcode(0xDC, "cpz", CpuAddressingMode.ABS, 4, "nzc");
|
||||
addOpcode(0xE2, "lda", CpuAddressingMode.ISY, 6, "Anz");
|
||||
addOpcode(0xE3, "inw", CpuAddressingMode.ABS, 5, "nz");
|
||||
addOpcode(0xEA, "eom", CpuAddressingMode.NON, 1, "");
|
||||
addOpcode(0xEB, "row", CpuAddressingMode.ABS, 6, "nzc");
|
||||
addOpcode(0xF2, "sbc", CpuAddressingMode.IZZ, 5, "Anzcv");
|
||||
addOpcode(0xF3, "lbeq", CpuAddressingMode.REL, 3, "P");
|
||||
addOpcode(0xF4, "phw", CpuAddressingMode.IMM, 5, "S");
|
||||
addOpcode(0xFB, "plz", CpuAddressingMode.NON, 3, "ZnzS");
|
||||
addOpcode(0xFC, "phw", CpuAddressingMode.ABS, 7, "S");
|
||||
|
||||
// TODO: Instruction Cycle changes on 65CE02
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ public class AsmChunk {
|
||||
if(clobberOverwrite != null) {
|
||||
return clobberOverwrite;
|
||||
}
|
||||
CpuClobber chunkClobber = new CpuClobber();
|
||||
CpuClobber chunkClobber = CpuClobber.CLOBBER_NONE;
|
||||
for(AsmLine line : lines) {
|
||||
if(line instanceof AsmInstruction) {
|
||||
AsmInstruction asmInstruction = (AsmInstruction) line;
|
||||
|
@ -229,7 +229,7 @@ public class AsmProgram {
|
||||
* @return The clobbered registers
|
||||
*/
|
||||
public CpuClobber getClobber() {
|
||||
CpuClobber programClobber = new CpuClobber();
|
||||
CpuClobber programClobber = CpuClobber.CLOBBER_NONE;
|
||||
for(AsmChunk chunk : chunks) {
|
||||
programClobber = new CpuClobber(programClobber, chunk.getClobber());
|
||||
}
|
||||
|
@ -176,7 +176,8 @@ ASM_MNEMONIC:
|
||||
'cpy' | 'cmp' | 'cpx' | 'dcp' | 'dec' | 'inc' | 'axs' | 'bne' | 'cld' | 'sbc' | 'isc' | 'inx' | 'beq' | 'sed' | 'dex' | 'iny' | 'ror' | 'bbr0'| 'bbr1'|
|
||||
'bbr2'| 'bbr3'| 'bbr4'| 'bbr5'| 'bbr6'| 'bbr7'| 'bbs0'| 'bbs1'| 'bbs2'| 'bbs3'| 'bbs4'| 'bbs5'| 'bbs6'| 'bbs7'| 'bra' | 'phx' | 'phy' | 'plx' | 'ply' |
|
||||
'rmb0'| 'rmb1'| 'rmb2'| 'rmb3'| 'rmb4'| 'rmb5'| 'rmb6'| 'rmb7'| 'smb0'| 'smb1'| 'smb2'| 'smb3'| 'smb4'| 'smb5'| 'smb6'| 'smb7'| 'stp' | 'stz' | 'trb' |
|
||||
'tsb'| 'wai'
|
||||
'tsb' | 'wai' | 'cle' | 'see' | 'tsy' | 'lbpl'| 'inz' | 'tys' | 'lbmi'| 'dez' | 'neg' | 'asr' | 'taz' | 'lbvc'| 'tab' | 'map' | 'rtn' | 'lbsr'| 'tza' |
|
||||
'lbvs'| 'tba' | 'lbra'| 'lbcc'| 'ldz' | 'lbcs'| 'cpz' | 'dew' | 'asw' | 'lbne'| 'phz' | 'inw' | 'row' | 'lbeq'| 'phw' | 'plz' | 'eom'
|
||||
;
|
||||
|
||||
ASM_IMM : '#' ;
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -70,7 +70,7 @@ public class Pass4InterruptClobberFix extends Pass2Base {
|
||||
|
||||
private CpuClobber getProcedureClobber(Procedure procedure) {
|
||||
AsmProgram asm = getProgram().getAsm();
|
||||
CpuClobber procClobber = new CpuClobber();
|
||||
CpuClobber procClobber = CpuClobber.CLOBBER_NONE;
|
||||
for(AsmChunk asmChunk : asm.getChunks()) {
|
||||
if(procedure.getFullName().equals(asmChunk.getScopeLabel())) {
|
||||
if(asmChunk.getSource().contains(Procedure.InterruptType.HARDWARE_CLOBBER.name())) {
|
||||
|
@ -42,6 +42,11 @@ public class TestPrograms {
|
||||
public TestPrograms() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCpu65CE02AddressingModes() throws IOException, URISyntaxException {
|
||||
compileAndCompare("cpu-65ce02-addressing-modes.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCpu65C02AddressingModes() throws IOException, URISyntaxException {
|
||||
compileAndCompare("cpu-65c02-addressing-modes.c");
|
||||
|
61
src/test/kc/cpu-65ce02-addressing-modes.c
Normal file
61
src/test/kc/cpu-65ce02-addressing-modes.c
Normal file
@ -0,0 +1,61 @@
|
||||
// Tests the different ASM addressing modes
|
||||
|
||||
#pragma cpu(csg65ce02)
|
||||
|
||||
void main() {
|
||||
|
||||
asm {
|
||||
// 6502:impl
|
||||
inx
|
||||
// 6502:imm
|
||||
lda #$12
|
||||
// 65CE02:immword
|
||||
phw #$1234
|
||||
// 6502:zp
|
||||
lda $12
|
||||
// 6502:zp,x
|
||||
lda $12,x
|
||||
// 6502:zp,y
|
||||
ldx $12,y
|
||||
// 65C02: (zp)
|
||||
//ora ($12)
|
||||
// 6502:(zp,x)
|
||||
lda ($12,x)
|
||||
// 6502:(zp),y
|
||||
lda ($12),y
|
||||
// 65CE02: (zp),z
|
||||
ora ($12),z
|
||||
// 65CE02: Stack Pointer Indirect Indexed
|
||||
lda ($12,sp),y
|
||||
// 6502:absolute
|
||||
lda $1234
|
||||
// 6502:abs,x
|
||||
lda $1234,x
|
||||
// 6502:abs,y
|
||||
lda $1234,y
|
||||
// 6502:relative
|
||||
beq lbl1
|
||||
// 65CE02:word relative
|
||||
lbeq far
|
||||
// 65C02: $12, rel
|
||||
bbr0 $12,lbl2
|
||||
lbl1:
|
||||
// 6502:(abs)
|
||||
jmp ($1234)
|
||||
lbl2:
|
||||
// 65C02: ($1234,X)
|
||||
jmp ($1234,x)
|
||||
|
||||
// TODO Indirect Long,Z
|
||||
//lda (($12)),z
|
||||
|
||||
// TODO Indirect Long
|
||||
//lda (($12))
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
__address(0x2000) char far[] = { 0x60 };
|
31
src/test/ref/cpu-65ce02-addressing-modes.asm
Normal file
31
src/test/ref/cpu-65ce02-addressing-modes.asm
Normal file
@ -0,0 +1,31 @@
|
||||
// Tests the different ASM addressing modes
|
||||
.cpu _65ce02
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
main: {
|
||||
// asm
|
||||
inx
|
||||
lda #$12
|
||||
phw #$1234
|
||||
lda.z $12
|
||||
lda.z $12,x
|
||||
ldx.z $12,y
|
||||
lda ($12,x)
|
||||
lda ($12),y
|
||||
ora.z ($12),z
|
||||
lda.z ($12,sp),y
|
||||
lda $1234
|
||||
lda $1234,x
|
||||
lda $1234,y
|
||||
beq lbl1
|
||||
lbeq far
|
||||
bbr0 $12,lbl2
|
||||
lbl1:
|
||||
jmp ($1234)
|
||||
lbl2:
|
||||
jmp ($1234,x)
|
||||
// }
|
||||
}
|
||||
.pc = $2000 "far"
|
||||
far: .byte $60
|
8
src/test/ref/cpu-65ce02-addressing-modes.cfg
Normal file
8
src/test/ref/cpu-65ce02-addressing-modes.cfg
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
(void()) main()
|
||||
main: scope:[main] from
|
||||
asm { inx lda#$12 phw#$1234 lda$12 lda$12,x ldx$12,y lda($12,x) lda($12),y ora($12),z lda($12,sp),y lda$1234 lda$1234,x lda$1234,y beqlbl1 lbeqfar bbr0$12,lbl2 lbl1: jmp($1234) lbl2: jmp($1234,x) }
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[1] return
|
||||
to:@return
|
210
src/test/ref/cpu-65ce02-addressing-modes.log
Normal file
210
src/test/ref/cpu-65ce02-addressing-modes.log
Normal file
@ -0,0 +1,210 @@
|
||||
Resolved forward reference far to (const byte*) far
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
|
||||
(void()) main()
|
||||
main: scope:[main] from __start
|
||||
asm { inx lda#$12 phw#$1234 lda$12 lda$12,x ldx$12,y lda($12,x) lda($12),y ora($12),z lda($12,sp),y lda$1234 lda$1234,x lda$1234,y beqlbl1 lbeqfar bbr0$12,lbl2 lbl1: jmp($1234) lbl2: jmp($1234,x) }
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
return
|
||||
to:@return
|
||||
|
||||
(void()) __start()
|
||||
__start: scope:[__start] from
|
||||
call main
|
||||
to:__start::@1
|
||||
__start::@1: scope:[__start] from __start
|
||||
to:__start::@return
|
||||
__start::@return: scope:[__start] from __start::@1
|
||||
return
|
||||
to:@return
|
||||
|
||||
SYMBOL TABLE SSA
|
||||
(void()) __start()
|
||||
(label) __start::@1
|
||||
(label) __start::@return
|
||||
(const byte*) far[] = { (byte) $60 }
|
||||
(void()) main()
|
||||
(label) main::@return
|
||||
|
||||
Removing unused procedure __start
|
||||
Removing unused procedure block __start
|
||||
Removing unused procedure block __start::@1
|
||||
Removing unused procedure block __start::@return
|
||||
Successful SSA optimization PassNEliminateEmptyStart
|
||||
CALL GRAPH
|
||||
|
||||
Created 0 initial phi equivalence classes
|
||||
Coalesced down to 0 phi equivalence classes
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
|
||||
(void()) main()
|
||||
main: scope:[main] from
|
||||
asm { inx lda#$12 phw#$1234 lda$12 lda$12,x ldx$12,y lda($12,x) lda($12),y ora($12),z lda($12,sp),y lda$1234 lda$1234,x lda$1234,y beqlbl1 lbeqfar bbr0$12,lbl2 lbl1: jmp($1234) lbl2: jmp($1234,x) }
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[1] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(void()) main()
|
||||
|
||||
Initial phi equivalence classes
|
||||
Complete equivalence classes
|
||||
|
||||
INITIAL ASM
|
||||
Target platform is c64basic / CSG65CE02
|
||||
// File Comments
|
||||
// Tests the different ASM addressing modes
|
||||
// Upstart
|
||||
.cpu _65ce02
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
// main
|
||||
main: {
|
||||
// asm { inx lda#$12 phw#$1234 lda$12 lda$12,x ldx$12,y lda($12,x) lda($12),y ora($12),z lda($12,sp),y lda$1234 lda$1234,x lda$1234,y beqlbl1 lbeqfar bbr0$12,lbl2 lbl1: jmp($1234) lbl2: jmp($1234,x) }
|
||||
inx
|
||||
lda #$12
|
||||
phw #$1234
|
||||
lda.z $12
|
||||
lda.z $12,x
|
||||
ldx.z $12,y
|
||||
lda ($12,x)
|
||||
lda ($12),y
|
||||
ora.z ($12),z
|
||||
lda.z ($12,sp),y
|
||||
lda $1234
|
||||
lda $1234,x
|
||||
lda $1234,y
|
||||
beq lbl1
|
||||
lbeq far
|
||||
bbr0 $12,lbl2
|
||||
lbl1:
|
||||
jmp ($1234)
|
||||
lbl2:
|
||||
jmp ($1234,x)
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [1] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
.pc = $2000 "far"
|
||||
far: .byte $60
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement asm { inx lda#$12 phw#$1234 lda$12 lda$12,x ldx$12,y lda($12,x) lda($12),y ora($12),z lda($12,sp),y lda$1234 lda$1234,x lda$1234,y beqlbl1 lbeqfar bbr0$12,lbl2 lbl1: jmp($1234) lbl2: jmp($1234,x) } always clobbers reg byte a reg byte x
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 86 combination
|
||||
Uplifting [] best 86 combination
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
// File Comments
|
||||
// Tests the different ASM addressing modes
|
||||
// Upstart
|
||||
.cpu _65ce02
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
// main
|
||||
main: {
|
||||
// asm { inx lda#$12 phw#$1234 lda$12 lda$12,x ldx$12,y lda($12,x) lda($12),y ora($12),z lda($12,sp),y lda$1234 lda$1234,x lda$1234,y beqlbl1 lbeqfar bbr0$12,lbl2 lbl1: jmp($1234) lbl2: jmp($1234,x) }
|
||||
inx
|
||||
lda #$12
|
||||
phw #$1234
|
||||
lda.z $12
|
||||
lda.z $12,x
|
||||
ldx.z $12,y
|
||||
lda ($12,x)
|
||||
lda ($12),y
|
||||
ora.z ($12),z
|
||||
lda.z ($12,sp),y
|
||||
lda $1234
|
||||
lda $1234,x
|
||||
lda $1234,y
|
||||
beq lbl1
|
||||
lbeq far
|
||||
bbr0 $12,lbl2
|
||||
lbl1:
|
||||
jmp ($1234)
|
||||
lbl2:
|
||||
jmp ($1234,x)
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [1] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
.pc = $2000 "far"
|
||||
far: .byte $60
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp __breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction __breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Removing unreachable instruction rts
|
||||
Succesful ASM optimization Pass5UnreachableCodeElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(const byte*) far[] = { (byte) $60 }
|
||||
(void()) main()
|
||||
(label) main::@return
|
||||
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 77
|
||||
|
||||
// File Comments
|
||||
// Tests the different ASM addressing modes
|
||||
// Upstart
|
||||
.cpu _65ce02
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
// main
|
||||
main: {
|
||||
// asm
|
||||
// asm { inx lda#$12 phw#$1234 lda$12 lda$12,x ldx$12,y lda($12,x) lda($12),y ora($12),z lda($12,sp),y lda$1234 lda$1234,x lda$1234,y beqlbl1 lbeqfar bbr0$12,lbl2 lbl1: jmp($1234) lbl2: jmp($1234,x) }
|
||||
inx
|
||||
lda #$12
|
||||
phw #$1234
|
||||
lda.z $12
|
||||
lda.z $12,x
|
||||
ldx.z $12,y
|
||||
lda ($12,x)
|
||||
lda ($12),y
|
||||
ora.z ($12),z
|
||||
lda.z ($12,sp),y
|
||||
lda $1234
|
||||
lda $1234,x
|
||||
lda $1234,y
|
||||
beq lbl1
|
||||
lbeq far
|
||||
bbr0 $12,lbl2
|
||||
lbl1:
|
||||
jmp ($1234)
|
||||
lbl2:
|
||||
jmp ($1234,x)
|
||||
// main::@return
|
||||
// }
|
||||
// [1] return
|
||||
}
|
||||
// File Data
|
||||
.pc = $2000 "far"
|
||||
far: .byte $60
|
||||
|
4
src/test/ref/cpu-65ce02-addressing-modes.sym
Normal file
4
src/test/ref/cpu-65ce02-addressing-modes.sym
Normal file
@ -0,0 +1,4 @@
|
||||
(const byte*) far[] = { (byte) $60 }
|
||||
(void()) main()
|
||||
(label) main::@return
|
||||
|
Loading…
x
Reference in New Issue
Block a user