1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-09-30 23:55:09 +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:
Andy McFadden 2018-10-09 12:27:47 -07:00
parent 0851746123
commit fd6d8273a9
7 changed files with 124 additions and 22 deletions

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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