1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-05-31 22:41:37 +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.
///
/// 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>
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
// since this will often be used to call into external code. The easiest
// 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);
}
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
// when pushed onto the stack, but it doesn't affect the actual processor status
// flag in the code executed next.
//
// We don't set a StatusFlagUpdater because the flags are only changed for the
// software break handler function. If we could actually track this into that,
// we'd need to configure the flags appropriately based on CPU type.
FlagsAffected = FlagsAffected_DI
FlagsAffected = FlagsAffected_DI,
// We don't try to track execution into the software break routine, but we do
// handle operating system calls that return with the flags altered. So if BRK
// does continue, we want to mark NVZC as indeterminate, just like we would for
// a general subroutine call.
StatusFlagUpdater = FlagUpdater_Subroutine
};
private static OpDef OpBRL = new OpDef() {
Mnemonic = OpName.BRL,

View File

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

View File

@ -91,9 +91,18 @@ Next1 jsr L10BA
_L10CF sec
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
L1800 jsr PrintInlineNullString

View File

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

View File

@ -89,9 +89,18 @@ Next1 jsr L10BA
@L10CF sec
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 $1800 {

View File

@ -92,9 +92,18 @@ Next1: jsr L10BA
@L10CF: sec
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"
.org $1800

View File

@ -121,6 +121,18 @@ Next1 jsr TestNC1
PushThing
sec
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