1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-10-10 04:23:44 +00:00

Mark flags as indeterminate for inline BRK

We weren't altering the status flags after a BRK because of the
assumption that a BRK was a crash.  For an inline BRK, such as a SOS
call, execution continues.  We need to mark NVZC indeterminate or
we may incorrectly handle conditional branches that follow.

The BRK instruction now uses the same flag updater as JSR, since it's
effectively a subroutine call to unknown code.  If execution doesn't
continue across the BRK then the flags don't matter.

Updated 20182-extension-scripts to exercise this.
This commit is contained in:
Andy McFadden 2020-08-22 08:56:38 -07:00
parent 30cb96f737
commit ba35f88d02
8 changed files with 69 additions and 15 deletions

View File

@ -162,7 +162,8 @@ namespace Asm65 {
/// will have the value TriState16.UNSPECIFIED. /// will have the value TriState16.UNSPECIFIED.
/// ///
/// This is not equivalent to the code flow status flag updater -- this just notes which /// This is not equivalent to the code flow status flag updater -- this just notes which
/// flags are modified directly by the instruction. /// flags are modified directly by the instruction. This is used for display in the
/// info window and instruction chart, not analysis.
/// </summary> /// </summary>
public StatusFlags FlagsAffected { get; private set; } public StatusFlags FlagsAffected { get; private set; }
@ -661,6 +662,10 @@ namespace Asm65 {
// that RTS/RTLs back to here, but that's generally hard to do, especially // that RTS/RTLs back to here, but that's generally hard to do, especially
// since this will often be used to call into external code. The easiest // since this will often be used to call into external code. The easiest
// thing to do is scramble CZVN and leave IDXM alone. // thing to do is scramble CZVN and leave IDXM alone.
//
// We also use this for BRK, because it either halts execution, in which
// case the flags don't matter, or it's performing some sort of special action
// (e.g. Apple /// SOS call) and the flags are altered.
return FlagUpdater_NVZC(flags, immVal, ref condBranchTakenFlags); return FlagUpdater_NVZC(flags, immVal, ref condBranchTakenFlags);
} }
private static StatusFlags FlagUpdater_Z(StatusFlags flags, int immVal, private static StatusFlags FlagUpdater_Z(StatusFlags flags, int immVal,
@ -1003,11 +1008,12 @@ namespace Asm65 {
// The processor status flags have the 'B' flag set on 6502/65C02/65816 emu mode // The processor status flags have the 'B' flag set on 6502/65C02/65816 emu mode
// when pushed onto the stack, but it doesn't affect the actual processor status // when pushed onto the stack, but it doesn't affect the actual processor status
// flag in the code executed next. // flag in the code executed next.
// FlagsAffected = FlagsAffected_DI,
// We don't set a StatusFlagUpdater because the flags are only changed for the // We don't try to track execution into the software break routine, but we do
// software break handler function. If we could actually track this into that, // handle operating system calls that return with the flags altered. So if BRK
// we'd need to configure the flags appropriately based on CPU type. // does continue, we want to mark NVZC as indeterminate, just like we would for
FlagsAffected = FlagsAffected_DI // a general subroutine call.
StatusFlagUpdater = FlagUpdater_Subroutine
}; };
private static OpDef OpBRL = new OpDef() { private static OpDef OpBRL = new OpDef() {
Mnemonic = OpName.BRL, Mnemonic = OpName.BRL,

View File

@ -2,7 +2,7 @@
{ {
"_ContentVersion":3, "_ContentVersion":3,
"FileDataLength":544, "FileDataLength":544,
"FileDataCrc32":118019308, "FileDataCrc32":787264196,
"ProjectProps":{ "ProjectProps":{
"CpuName":"65816", "CpuName":"65816",
"IncludeUndocumentedInstr":false, "IncludeUndocumentedInstr":false,

View File

@ -91,9 +91,18 @@ Next1 jsr L10BA
_L10CF sec _L10CF sec
jsr L10BF jsr L10BF
rts clc
brk #$02
.word data02
bcc _L10DE
bcs _L10DE
.fill 300,$00 .byte $00
.byte $80
_L10DE rts
.fill 289,$00
.logical $1800 .logical $1800
L1800 jsr PrintInlineNullString L1800 jsr PrintInlineNullString

View File

@ -83,9 +83,18 @@ Next1 jsr L10BA
:L10CF sec :L10CF sec
jsr L10BF jsr L10BF
rts clc
brk $02
dw data02
bcc :L10DE
bcs :L10DE
ds 300 dfb $00
dfb $80
:L10DE rts
ds 289
org $1800 org $1800
L1800 jsr PrintInlineNullString L1800 jsr PrintInlineNullString

View File

@ -89,9 +89,18 @@ Next1 jsr L10BA
@L10CF sec @L10CF sec
jsr L10BF jsr L10BF
rts clc
!byte $00,$02
!word data02
bcc @L10DE
bcs @L10DE
!fill 300,$00 !byte $00
!byte $80
@L10DE rts
!fill 289,$00
} ;!pseudopc } ;!pseudopc
!pseudopc $1800 { !pseudopc $1800 {

View File

@ -92,9 +92,18 @@ Next1: jsr L10BA
@L10CF: sec @L10CF: sec
jsr L10BF jsr L10BF
rts clc
brk $02
.word data02
bcc @L10DE
bcs @L10DE
.res 300,$00 .byte $00
.byte $80
@L10DE: rts
.res 289,$00
; .segment "SEG001" ; .segment "SEG001"
.org $1800 .org $1800

View File

@ -121,6 +121,18 @@ Next1 jsr TestNC1
PushThing PushThing
sec sec
jsr TestNC2 jsr TestNC2
; Make sure flags get marked as indeterminate across inline BRK.
; Also exercises formatting the same block twice.
clc
brk $02
dw data02
bcc :BrkNext
bcs :BrkNext
brk $80
:BrkNext
rts rts