mirror of
https://github.com/fadden/6502bench.git
synced 2025-01-04 01:29:55 +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:
parent
30cb96f737
commit
ba35f88d02
@ -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,
|
||||
|
Binary file not shown.
@ -2,7 +2,7 @@
|
||||
{
|
||||
"_ContentVersion":3,
|
||||
"FileDataLength":544,
|
||||
"FileDataCrc32":118019308,
|
||||
"FileDataCrc32":787264196,
|
||||
"ProjectProps":{
|
||||
"CpuName":"65816",
|
||||
"IncludeUndocumentedInstr":false,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user