1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-07-02 04:29:28 +00:00

Treat BRK as a 1-byte instruction

The 65816 definition makes it a two-byte instruction, like COP.  On
the 6502 it acted like a two-byte instruction, but in practice very
few assemblers treat it that way.  Very few humans, for that matter.
So it's now treated as a single byte instruction, with the following
byte encoded as a data value.
This commit is contained in:
Andy McFadden 2019-08-02 17:21:50 -07:00
parent 0616e4e4a4
commit 98914e9f80
30 changed files with 88 additions and 39 deletions

View File

@ -409,7 +409,7 @@ namespace Asm65 {
private static CpuDef Cpu6502 { get; } = new CpuDef("MOS 6502", (1 << 16) - 1, false) {
Type = CpuType.Cpu6502,
mOpDefs = new OpDef[] {
OpDef.OpBRK_StackInt, // 0x00
OpDef.OpBRK_Implied, // 0x00
OpDef.OpORA_DPIndexXInd,
OpDef.GenerateUndoc(0x02, OpDef.OpJAM_Implied),
OpDef.OpSLO_DPIndexXInd,
@ -673,7 +673,7 @@ namespace Asm65 {
private static CpuDef Cpu65C02 { get; } = new CpuDef("WDC W65C02S", (1 << 16) - 1, false) {
Type = CpuType.Cpu65C02,
mOpDefs = new OpDef[] {
OpDef.OpBRK_StackInt, // 0x00
OpDef.OpBRK_Implied, // 0x00
OpDef.OpORA_DPIndexXInd,
OpDef.GenerateUndoc(0x02, OpDef.OpLDD_Imm),
OpDef.GenerateUndoc(0x03, OpDef.OpNOP_65C02),
@ -937,7 +937,7 @@ namespace Asm65 {
private static CpuDef Cpu65816 { get; } = new CpuDef("WDC W65C816S", (1 << 24) - 1, true) {
Type = CpuType.Cpu65816,
mOpDefs = new OpDef[] {
OpDef.OpBRK_StackInt, // 0x00
OpDef.OpBRK_Implied, // 0x00
OpDef.OpORA_DPIndexXInd,
OpDef.OpCOP_StackInt,
OpDef.OpORA_StackRel,

View File

@ -543,7 +543,7 @@ namespace Asm65 {
case AddressMode.DP:
case AddressMode.PCRel:
case AddressMode.PCRelLong: // BRL
case AddressMode.StackInt: // BRK/COP
case AddressMode.StackInt: // COP
case AddressMode.StackPCRelLong: // PER
case AddressMode.WDM:
fmt = wdisStr + "{0}";

View File

@ -1444,9 +1444,13 @@ namespace Asm65 {
AddrMode = AddressMode.Unknown
};
public static readonly OpDef OpBRK_StackInt = new OpDef(OpBRK) {
public static readonly OpDef OpBRK_Implied = new OpDef(OpBRK) {
Opcode = 0x00,
AddrMode = AddressMode.StackInt,
// There should arguably be OpBRK_Implied for 6502/65C02 and OpBRK_StackInt for
// 65816, but in practice hardly any assemblers prefer (or even allow) it to be
// a two-byte instruction. The BRK does *act* like a two-byte instruction, but
// code rarely reflects this usage.
AddrMode = AddressMode.Implied,
CycDef = 7 | (int)(CycleMod.OneIfE0)
};
public static readonly OpDef OpORA_DPIndexXInd = new OpDef(OpORA) {

View File

@ -321,7 +321,7 @@ namespace SourceGen.AsmGen {
// IGenerator
public string ModifyOpcode(int offset, OpDef op) {
if ((op == OpDef.OpWDM_WDM || op == OpDef.OpBRK_StackInt) && mAsmVersion <= V2_17) {
if ((op == OpDef.OpWDM_WDM) && mAsmVersion <= V2_17) {
// cc65 v2.17 doesn't support WDM, and assembles BRK <arg> to opcode $05.
// https://github.com/cc65/cc65/issues/715
// https://github.com/cc65/cc65/issues/716

View File

@ -276,8 +276,7 @@ namespace SourceGen.AsmGen {
return null;
}
}
if (op == OpDef.OpBRK_StackInt || op == OpDef.OpCOP_StackInt ||
op == OpDef.OpWDM_WDM) {
if (op == OpDef.OpCOP_StackInt || op == OpDef.OpWDM_WDM) {
// 64tass doesn't like these to have an operand. Output as hex.
return null;
}

View File

@ -646,8 +646,12 @@ namespace SourceGen {
// On first visit, check for BRK inline call.
if (firstVisit) {
if (op == OpDef.OpBRK_StackInt) {
CheckForInlineCall(op, offset, out bool unused);
if (op == OpDef.OpBRK_Implied) {
bool noContinue = CheckForInlineCall(op, offset, !doContinue);
if (!noContinue) {
// We're expected to continue execution past the BRK.
doContinue = true;
}
}
}
@ -675,7 +679,7 @@ namespace SourceGen {
if (firstVisit) {
// Currently ignoring OpDef.OpJSR_AbsIndexXInd
if (op == OpDef.OpJSR_Abs || op == OpDef.OpJSR_AbsLong) {
CheckForInlineCall(op, offset, out bool noContinue);
bool noContinue = CheckForInlineCall(op, offset, false);
if (noContinue) {
LogD(offset, "Script declared inline call no-continue");
mAnattribs[offset].DoesNotContinue = true;
@ -902,8 +906,7 @@ namespace SourceGen {
/// <param name="op">Instruction being examined.</param>
/// <param name="offset">File offset of start of instruction.</param>
/// <param name="noContinue">Set if any plugin declares the call to be no-continue.</param>
private void CheckForInlineCall(OpDef op, int offset, out bool noContinue) {
noContinue = false;
private bool CheckForInlineCall(OpDef op, int offset, bool noContinue) {
for (int i = 0; i < mScriptArray.Length; i++) {
IPlugin script = mScriptArray[i];
if (op == OpDef.OpJSR_Abs && script is IPlugin_InlineJsr) {
@ -912,11 +915,12 @@ namespace SourceGen {
} else if (op == OpDef.OpJSR_AbsLong && script is IPlugin_InlineJsl) {
((IPlugin_InlineJsl)script).CheckJsl(offset, out bool noCont);
noContinue |= noCont;
} else if (op == OpDef.OpBRK_StackInt && script is IPlugin_InlineBrk) {
} else if (op == OpDef.OpBRK_Implied && script is IPlugin_InlineBrk) {
((IPlugin_InlineBrk)script).CheckBrk(offset, out bool noCont);
noContinue &= noCont;
}
}
return noContinue;
}
private bool SetOperandFormat(int offset, DataSubType subType, string label) {

View File

@ -15,7 +15,9 @@
nop
nop
nop
.byte $00,$ff
brk
.byte $ff
L101F ora ($ff,x)
.byte $02,$ff

View File

@ -12,7 +12,9 @@
nop
nop
nop
brk $ff
brk
dfb $ff
L101F ora ($ff,x)
cop $ff

View File

@ -16,7 +16,9 @@
nop
nop
nop
.byte $00,$ff
brk
.byte $ff
L101F: ora ($ff,x)
cop $ff

View File

@ -15,7 +15,9 @@
nop
nop
nop
.byte $00,$00
brk
.byte $00
L101F ora ($00,x)
.byte $02,$00

View File

@ -12,7 +12,9 @@
nop
nop
nop
brk $00
brk
dfb $00
L101F ora ($00,x)
cop $00

View File

@ -16,7 +16,9 @@
nop
nop
nop
.byte $00,$00
brk
.byte $00
L101F: ora ($00,x)
cop $00

View File

@ -22,7 +22,7 @@ L101C sep #$30
lda $00
beq L1025
lda #$00
.byte $00
brk
L1025 sta $012345
rts

View File

@ -19,7 +19,7 @@ L101C sep #$30
lda $00
beq L1025
lda #$00
dfb $00
brk
L1025 stal $012345
rts

View File

@ -23,7 +23,7 @@ L101C: sep #$30
lda $00
beq L1025
lda #$00
.byte $00
brk
L1025: sta $012345
rts

View File

@ -19,7 +19,9 @@
nop
nop
nop
.byte $00,$ff
brk
.byte $ff
L1035 ora ($ff,x)
jam

View File

@ -18,7 +18,9 @@
nop
nop
nop
brk $ff
brk
dfb $ff
L1035 ora ($ff,x)
dfb $02

View File

@ -20,7 +20,9 @@
nop
nop
nop
.byte $00,$ff
brk
.byte $ff
L1035: ora ($ff,x)
jam

View File

@ -19,7 +19,9 @@
nop
nop
nop
.byte $00,$00
brk
.byte $00
L1035 ora ($00,x)
jam

View File

@ -18,7 +18,9 @@
nop
nop
nop
brk $00
brk
dfb $00
L1035 ora ($00,x)
dfb $02

View File

@ -20,7 +20,9 @@
nop
nop
nop
.byte $00,$00
brk
.byte $00
L1035: ora ($00,x)
jam

View File

@ -8,7 +8,9 @@
nop
nop
nop
.byte $00,$ff
brk
.byte $ff
L1014 ora ($ff,x)
.byte $02,$ff

View File

@ -7,7 +7,9 @@
nop
nop
nop
brk $ff
brk
dfb $ff
L1014 ora ($ff,x)
dfb $02,$ff

View File

@ -9,7 +9,9 @@
nop
nop
nop
.byte $00,$ff
brk
.byte $ff
L1014: ora ($ff,x)
.byte $02,$ff

View File

@ -8,7 +8,9 @@
nop
nop
nop
.byte $00,$00
brk
.byte $00
L1014 ora ($00,x)
.byte $02,$00

View File

@ -7,7 +7,9 @@
nop
nop
nop
brk $00
brk
dfb $00
L1014 ora ($00,x)
dfb $02,$00

View File

@ -9,7 +9,9 @@
nop
nop
nop
.byte $00,$00
brk
.byte $00
L1014: ora ($00,x)
.byte $02,$00

View File

@ -16,7 +16,9 @@
nop
nop
nop
.byte $00,$80
brk
.byte $80
L101F ora (L0080,x)
.byte $02,$80

View File

@ -13,7 +13,9 @@
nop
nop
nop
brk $80
brk
dfb $80
L101F dfb $01,$80
cop $80

View File

@ -17,7 +17,9 @@
nop
nop
nop
.byte $00,$80
brk
.byte $80
L101F: ora (L0080,x)
cop $80