mirror of
https://github.com/fadden/6502bench.git
synced 2024-11-18 15:06:07 +00:00
Add custom flag updaters for ROL/ROR
There are some useful interactions between C/N and maybe Z. Added
a quick test to 1003-flags-and-branches.
Also, updated the 2008-address-changes tests. Change b37d3dba
extended the nearby-target range of out-of-file symbols by one, so
one line that didn't get an operand label now does.
This commit is contained in:
parent
0851746123
commit
fd6d8273a9
@ -518,6 +518,9 @@ namespace Asm65 {
|
||||
condBranchTakenFlags = curFlags;
|
||||
// Invoke the flag update delegate.
|
||||
newFlags = StatusFlagUpdater(curFlags, immVal, ref condBranchTakenFlags);
|
||||
|
||||
// TODO(maybe): there are some constraints we can impose: if Z=1 then
|
||||
// N=0, and if N=1 then Z=0. I'm not sure this is actually useful though.
|
||||
}
|
||||
|
||||
private static StatusFlags FlagUpdater_NoChange(StatusFlags flags, int immVal,
|
||||
@ -613,6 +616,40 @@ namespace Asm65 {
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
private static StatusFlags FlagUpdater_ROL(StatusFlags flags, int immVal,
|
||||
ref StatusFlags condBranchTakenFlags) {
|
||||
// this rotates the N flag into C, so set C=N
|
||||
// if carry is one, set Z=0; otherwise set Z/N=indeterminate
|
||||
// (if Z=1 we should set Z=C, but this seems rare and I don't entirely trust Z)
|
||||
if (flags.C == 1) {
|
||||
flags.C = flags.N;
|
||||
flags.Z = 0;
|
||||
flags.N = TriState16.INDETERMINATE;
|
||||
} else {
|
||||
flags.C = flags.N;
|
||||
flags.Z = flags.N = TriState16.INDETERMINATE;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
private static StatusFlags FlagUpdater_ROR(StatusFlags flags, int immVal,
|
||||
ref StatusFlags condBranchTakenFlags) {
|
||||
// if carry is set, set Z=0 and N=1;
|
||||
// if carry is clear, set N=0;
|
||||
// if carry is clear and Z=1, everything is zero and no flags change
|
||||
// (this seems unlikely, so I'm going to assume we've mis-read a flag and ignore this)
|
||||
// otherwise, Z/N/C=indeterminate
|
||||
if (flags.C == 1) {
|
||||
flags.Z = 0;
|
||||
flags.N = 1;
|
||||
flags.C = TriState16.INDETERMINATE;
|
||||
} else if (flags.C == 0) {
|
||||
flags.N = 0;
|
||||
flags.Z = flags.C = TriState16.INDETERMINATE;
|
||||
} else {
|
||||
flags.C = flags.Z = flags.N = TriState16.INDETERMINATE;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
private static StatusFlags FlagUpdater_PLP(StatusFlags flags, int immVal,
|
||||
ref StatusFlags condBranchTakenFlags) {
|
||||
// All flags are unknown. The caller may be able to match with a previous
|
||||
@ -1077,13 +1114,13 @@ namespace Asm65 {
|
||||
Mnemonic = OpName.ROL,
|
||||
Effect = FlowEffect.Cont,
|
||||
FlagsAffected = FlagsAffected_NZC,
|
||||
StatusFlagUpdater = FlagUpdater_NZC
|
||||
StatusFlagUpdater = FlagUpdater_ROL
|
||||
};
|
||||
private static OpDef OpROR = new OpDef() {
|
||||
Mnemonic = OpName.ROR,
|
||||
Effect = FlowEffect.Cont,
|
||||
FlagsAffected = FlagsAffected_NZC,
|
||||
StatusFlagUpdater = FlagUpdater_NZC
|
||||
StatusFlagUpdater = FlagUpdater_ROR
|
||||
};
|
||||
private static OpDef OpRTI = new OpDef() {
|
||||
Mnemonic = OpName.RTI,
|
||||
|
Binary file not shown.
@ -191,40 +191,63 @@ L10DD ora #$80
|
||||
dfb $00
|
||||
dfb $db
|
||||
|
||||
L10E3 clc
|
||||
L10E3 lda L10E3
|
||||
sec
|
||||
ror A
|
||||
bmi L10EC
|
||||
|
||||
dfb $00
|
||||
dfb $dc
|
||||
|
||||
L10EC clc
|
||||
ror A
|
||||
bpl L10F2
|
||||
|
||||
dfb $00
|
||||
dfb $dc
|
||||
|
||||
L10F2 lda #$00
|
||||
sec
|
||||
rol A
|
||||
bne L10FA
|
||||
|
||||
dfb $00
|
||||
dfb $dc
|
||||
|
||||
L10FA clc
|
||||
php
|
||||
sec
|
||||
plp
|
||||
bcc L10EB
|
||||
bcc L1102
|
||||
|
||||
dfb $00
|
||||
dfb $00
|
||||
|
||||
L10EB rep #$20
|
||||
L1102 rep #$20
|
||||
mx %01
|
||||
sep #$10
|
||||
jsr L1106
|
||||
jsr L111D
|
||||
rep #$30
|
||||
mx %00
|
||||
jsr L110C
|
||||
jsr L1123
|
||||
sep #$30
|
||||
mx %11
|
||||
jsr L110C
|
||||
jsr L1123
|
||||
rep #$20
|
||||
mx %01
|
||||
sep #$10
|
||||
jsr L1106
|
||||
jsr L111D
|
||||
sep #$30
|
||||
mx %11
|
||||
rts
|
||||
|
||||
mx %01
|
||||
L1106 lda #$1234
|
||||
L111D lda #$1234
|
||||
ldx #$ff
|
||||
rts
|
||||
|
||||
mx %11
|
||||
L110C lda #$ff
|
||||
L1123 lda #$ff
|
||||
ldx #$ee
|
||||
ldy #$dd
|
||||
rts
|
||||
|
@ -196,41 +196,64 @@ L10DD: ora #$80
|
||||
.byte $00
|
||||
.byte $db
|
||||
|
||||
L10E3: clc
|
||||
L10E3: lda L10E3
|
||||
sec
|
||||
ror A
|
||||
bmi L10EC
|
||||
|
||||
.byte $00
|
||||
.byte $dc
|
||||
|
||||
L10EC: clc
|
||||
ror A
|
||||
bpl L10F2
|
||||
|
||||
.byte $00
|
||||
.byte $dc
|
||||
|
||||
L10F2: lda #$00
|
||||
sec
|
||||
rol A
|
||||
bne L10FA
|
||||
|
||||
.byte $00
|
||||
.byte $dc
|
||||
|
||||
L10FA: clc
|
||||
php
|
||||
sec
|
||||
plp
|
||||
bcc L10EB
|
||||
bcc L1102
|
||||
|
||||
.byte $00
|
||||
.byte $00
|
||||
|
||||
L10EB: rep #$20
|
||||
L1102: rep #$20
|
||||
.a16
|
||||
sep #$10
|
||||
jsr L1106
|
||||
jsr L111D
|
||||
rep #$30
|
||||
.i16
|
||||
jsr L110C
|
||||
jsr L1123
|
||||
sep #$30
|
||||
.a8
|
||||
.i8
|
||||
jsr L110C
|
||||
jsr L1123
|
||||
rep #$20
|
||||
.a16
|
||||
sep #$10
|
||||
jsr L1106
|
||||
jsr L111D
|
||||
sep #$30
|
||||
.a8
|
||||
rts
|
||||
|
||||
.a16
|
||||
L1106: lda #$1234
|
||||
L111D: lda #$1234
|
||||
ldx #$ff
|
||||
rts
|
||||
|
||||
.a8
|
||||
L110C: lda #$ff
|
||||
L1123: lda #$ff
|
||||
ldx #$ee
|
||||
ldy #$dd
|
||||
rts
|
||||
|
@ -82,7 +82,7 @@ L3100 dfb $02
|
||||
fwd bit fwd
|
||||
lda ulabel
|
||||
lda ulabel+1
|
||||
lda $300e
|
||||
lda ulabel+2
|
||||
lda $300f
|
||||
lda L3100
|
||||
beq L3182
|
||||
|
@ -85,7 +85,7 @@ L3100: .byte $02
|
||||
fwd: bit fwd
|
||||
lda ulabel
|
||||
lda ulabel+1
|
||||
lda $300e
|
||||
lda ulabel+2
|
||||
lda $300f
|
||||
lda L3100
|
||||
beq L3182
|
||||
|
@ -176,6 +176,25 @@ ok_oraN0
|
||||
brk $db
|
||||
ok_oraN1
|
||||
|
||||
; check rol/ror
|
||||
:foo lda :foo ;scramble N/V
|
||||
sec
|
||||
ror A ;rotates the carry into the hi bit (N)
|
||||
bmi ok_ror1
|
||||
brk $dc
|
||||
ok_ror1
|
||||
clc
|
||||
ror A ;now try with carry clear
|
||||
bpl ok_ror2
|
||||
brk $dc
|
||||
ok_ror2
|
||||
lda #$00 ;set Z=1
|
||||
sec
|
||||
rol A ;set Z=0 (could also set C=0)
|
||||
bne ok_rol1
|
||||
brk $dc
|
||||
ok_rol1
|
||||
|
||||
; simple php/plp pair test
|
||||
clc
|
||||
php
|
||||
|
Loading…
Reference in New Issue
Block a user