Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Significant Overhaul of the Interpreter's Timing Model #2235

Draft
wants to merge 368 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
368 commits
Select commit Hold shift + click to select a range
f692e73
the docs lied to me (again)
Jaklyy Aug 26, 2024
a9aad74
implement user mode load/stores
Jaklyy Aug 27, 2024
be290da
de-duplicate swp(b)
Jaklyy Aug 27, 2024
685c482
try not forgetting about stores lol
Jaklyy Aug 28, 2024
0003821
apparently i never tested this
Jaklyy Aug 29, 2024
f0bd2b9
Merge remote-tracking branch 'upstream/master' into interpreter-fixes
Jaklyy Aug 30, 2024
2d081a6
improve arm7 timings
Jaklyy Sep 1, 2024
7cfc4b5
ARM7: vram is 32 bit?
Jaklyy Sep 2, 2024
299713e
basic arm9 set up
Jaklyy Sep 5, 2024
ceb5a9f
draw (most of) the rest of the owl
Jaklyy Sep 6, 2024
41db7b9
fix main ram adding cycles twice if code and memory region are the same
Jaklyy Sep 7, 2024
bd1d1c5
fix thumb "no fetches"
Jaklyy Sep 8, 2024
53cc037
Merge branch 'pr/1955' into chemical-x
Jaklyy Sep 8, 2024
cacaf0e
make it work
Jaklyy Sep 8, 2024
c5ac682
improve data abort handling further
Jaklyy Sep 12, 2024
a0d7113
very minor optimization attempt
Jaklyy Sep 13, 2024
f2a02ab
Merge branch 'interpreter-fixes' into less-ambitious-timing-rework
Jaklyy Sep 13, 2024
3b9a9e4
multiply instructions can't write to r15
Jaklyy Sep 16, 2024
ac8c942
sat add/sub also fail to jump
Jaklyy Sep 16, 2024
e2f3dd1
clarify
Jaklyy Sep 16, 2024
e5654ec
r15 mrc mrs
Jaklyy Sep 16, 2024
89e8549
implement comparison instrs w/ rd == 15
Jaklyy Sep 17, 2024
6ebabde
implement changing thumb bit. and bkpt ig
Jaklyy Sep 18, 2024
45f87a1
prevent t bit changes without pipeline flush on arm7
Jaklyy Sep 20, 2024
c133814
some day i will remember to test before pushing
Jaklyy Sep 20, 2024
7afa805
slightly better code
Jaklyy Sep 20, 2024
157e9c5
reimplement changing t bit with arm7
Jaklyy Sep 20, 2024
8d451df
misaligned pc..........
Jaklyy Sep 21, 2024
7b0d71d
Revert T bit changing support for arm7
Jaklyy Sep 22, 2024
8af790b
ldm/str with empty rlist
Jaklyy Sep 23, 2024
3b73f21
str r15 is incremented by +2/+4 oop
Jaklyy Sep 23, 2024
7fb18b1
clean up code
Jaklyy Sep 24, 2024
e1d4fbe
i can't reproduce this anymore
Jaklyy Sep 24, 2024
3065141
probably not faster
Jaklyy Sep 24, 2024
a11208e
oops
Jaklyy Sep 25, 2024
19e0b18
Merge remote-tracking branch 'upstream/master' into interpreter-fixes
Jaklyy Sep 30, 2024
c62f0f1
Merge branch 'interpreter-fixes' into less-ambitious-timing-rework
Jaklyy Sep 30, 2024
286de74
Merge branch 'less-ambitious-timing-rework' into chemical-x
Jaklyy Sep 30, 2024
6e30cf3
functional write buffer prototype
Jaklyy Oct 8, 2024
9cf065e
idk
Jaklyy Oct 9, 2024
35c382a
jit
Jaklyy Oct 9, 2024
225bd50
Merge branch 'less-ambitious-timing-rework' into chemical-x
Jaklyy Oct 9, 2024
f2bc0fa
cache imp
Jaklyy Oct 9, 2024
746f6ed
should addr writes to the fifo take 1 cycle? probably?
Jaklyy Oct 9, 2024
0638c41
Merge branch 'less-ambitious-timing-rework' into chemical-x
Jaklyy Oct 9, 2024
60234a9
im dumb
Jaklyy Oct 9, 2024
2c3ef9f
writing to the write buffer seems to require bus cycle alignment
Jaklyy Oct 9, 2024
633572e
Merge branch 'less-ambitious-timing-rework' into chemical-x
Jaklyy Oct 10, 2024
e25dca0
writing to the write buffer has a 1 cycle delay before it can be done…
Jaklyy Oct 10, 2024
53b38c3
ok no it didn't lie to me
Jaklyy Oct 10, 2024
3870216
correction:
Jaklyy Oct 10, 2024
93dce82
implement cmp with "rd == 15" on arm9
Jaklyy Oct 10, 2024
787d0c9
mrc r15 updates flags
Jaklyy Oct 10, 2024
5c120f4
Merge branch 'interpreter-fixes' into less-ambitious-timing-rework
Jaklyy Oct 11, 2024
34bba25
tcm (and cache?) reads dont trigger write buffer drains
Jaklyy Oct 11, 2024
3d246dd
tcms just aren't bufferable
Jaklyy Oct 11, 2024
9f6cbd8
implement drain write buffer cache command
Jaklyy Oct 11, 2024
6b8671d
Merge branch 'less-ambitious-timing-rework' into chemical-x
Jaklyy Oct 11, 2024
a8722d8
tcms shouldn't be cacheable
Jaklyy Oct 11, 2024
e0e78a2
make empty r-list instructions a bit nicer
Jaklyy Oct 12, 2024
206fc94
Merge branch 'interpreter-fixes' into less-ambitious-timing-rework
Jaklyy Oct 12, 2024
1afefdc
use sse for set lookups
Jaklyy Oct 13, 2024
801f43d
reimplement codemem
Jaklyy Oct 13, 2024
f74c21d
Merge branch 'less-ambitious-timing-rework' into chemical-x
Jaklyy Oct 14, 2024
026719a
improve timing model
Jaklyy Oct 15, 2024
9f3ebea
Merge branch 'less-ambitious-timing-rework' into chemical-x
Jaklyy Oct 15, 2024
ca7d938
update for new write buffer implementation
Jaklyy Oct 15, 2024
263dd20
nvmnvmnvm
Jaklyy Oct 15, 2024
d8d2fcd
more optimizations
Jaklyy Oct 15, 2024
d476593
add notes
Jaklyy Oct 15, 2024
5f003eb
fix builds with jit disabled
Jaklyy Oct 16, 2024
05c153e
Merge branch 'interpreter-fixes' into less-ambitious-timing-rework
Jaklyy Oct 16, 2024
bb2727b
Merge branch 'less-ambitious-timing-rework' into chemical-x
Jaklyy Oct 16, 2024
460fd45
remove some old code
Jaklyy Oct 16, 2024
c00b188
im dumb
Jaklyy Oct 16, 2024
3fcdc45
Merge branch 'less-ambitious-timing-rework' into chemical-x
Jaklyy Oct 16, 2024
c605c93
still dumb
Jaklyy Oct 16, 2024
21763ce
reduce memtimings lut granularity
Jaklyy Oct 16, 2024
52ddaa7
fix resets
Jaklyy Oct 16, 2024
9f2b097
Merge branch 'less-ambitious-timing-rework' into chemical-x
Jaklyy Oct 16, 2024
d721264
move arm9 code fetches into the cycle add routine
Jaklyy Oct 16, 2024
26a6e88
aarch64 neon impl take one
Jaklyy Oct 17, 2024
ffb24e7
wrong bitshift
Jaklyy Oct 17, 2024
68e8ff4
this barely makes a difference in practice but it's less inefficient
Jaklyy Oct 17, 2024
e2a8101
re-add interlocks
Jaklyy Oct 18, 2024
cc031cd
Merge branch 'less-ambitious-timing-rework' into chemical-x
Jaklyy Oct 18, 2024
0e6d3fd
fix bad logical leaps
Jaklyy Oct 18, 2024
8ff0946
mrc causes interlocks
Jaklyy Oct 18, 2024
9ed4c66
add support for 1 reg ldm/stm a9 timings and fix a bug
Jaklyy Oct 18, 2024
e33d19c
fix a few misc things?
Jaklyy Oct 19, 2024
051b236
Merge branch 'less-ambitious-timing-rework' into chemical-x
Jaklyy Oct 19, 2024
d421630
hdfg
Jaklyy Oct 19, 2024
8fff17f
fix resets
Jaklyy Oct 19, 2024
e254ac3
fix ldrd/strd itcm timings
Jaklyy Oct 19, 2024
a32d597
Merge branch 'less-ambitious-timing-rework' into chemical-x
Jaklyy Oct 19, 2024
744f5c9
small fixes
Jaklyy Oct 19, 2024
af09e37
attempt at twl timings
Jaklyy Oct 21, 2024
e93381d
Merge branch 'less-ambitious-timing-rework' into chemical-x
Jaklyy Oct 21, 2024
54dd4e5
git hates me
Jaklyy Oct 21, 2024
d31f652
implement icache streaming
Jaklyy Oct 25, 2024
ebb63dc
implement dcache streaming
Jaklyy Oct 25, 2024
e783e77
fix an oopsie
Jaklyy Oct 25, 2024
e1f22bd
writing back dirty cache lines should be done in one burst if both ha…
Jaklyy Oct 26, 2024
ba904b4
redo cache streaming disable implementation
Jaklyy Oct 26, 2024
ca674b6
"fix" icache linefill disable timings
Jaklyy Oct 26, 2024
d88b46e
rework and fix bursts
Jaklyy Oct 27, 2024
ce55f29
loads to r15 force an interlock
Jaklyy Oct 28, 2024
c50d15d
code reads should trigger an edge case with dcache streaming
Jaklyy Oct 29, 2024
a421c55
fix 8 bit main ram write timing
Jaklyy Nov 2, 2024
ca1fb2b
write buffer mk3
Jaklyy Nov 3, 2024
dfd2512
fix some more tests
Jaklyy Nov 3, 2024
42d0359
Merge remote-tracking branch 'upstream/master' into chemical-x
Jaklyy Nov 3, 2024
8a857f1
why so many spaces
Jaklyy Nov 3, 2024
a662af9
improved...?
Jaklyy Nov 3, 2024
d929587
fix cache fill
Jaklyy Nov 3, 2024
d6d54fd
handle wb writes followed immediately by reads better
Jaklyy Nov 3, 2024
09cdec7
improve interlock timings
Jaklyy Nov 3, 2024
604b21c
this fixes stuff
Jaklyy Nov 4, 2024
24ed883
fix resetting under certain circumstances
Jaklyy Nov 4, 2024
3c7db9b
correct thumb multiply timings
Jaklyy Nov 6, 2024
3d49f5f
arm7 muls carry flag emulation.
Jaklyy Nov 6, 2024
3bd6274
Merge remote-tracking branch 'upstream/master' into interpreter-fixes
Jaklyy Nov 6, 2024
0d68cc0
Merge branch 'interpreter-fixes' into chemical-x
Jaklyy Nov 6, 2024
ef5de60
t blx long with bit 0 set should raise an exception
Jaklyy Nov 7, 2024
b3dec0b
Merge branch 'interpreter-fixes' into chemical-x
Jaklyy Nov 7, 2024
5091061
improve accuracy of prefetch abort handling slightly
Jaklyy Nov 8, 2024
60a819c
correct handling of T bit changes w/o pipeline flush on arm9
Jaklyy Nov 8, 2024
3fe73f7
Merge branch 'interpreter-fixes' into chemical-x
Jaklyy Nov 8, 2024
676f471
fix edge case with thumb prefetch aborts
Jaklyy Nov 8, 2024
9f8cf8d
ldm base writeback fails with r15
Jaklyy Nov 9, 2024
e4dd913
arm7 RORs unaligned ldr(s)h
Jaklyy Nov 9, 2024
bdc3151
T_LDR_SPREL does ROR + misc cleanup
Jaklyy Nov 9, 2024
ec241a8
im smrat :D
Jaklyy Nov 9, 2024
fce0555
slightly fix error in writeback handling
Jaklyy Nov 10, 2024
9d92b87
r15 writeback is very weird with ldr/str
Jaklyy Nov 10, 2024
514b437
Merge branch 'interpreter-fixes' into chemical-x
Jaklyy Nov 10, 2024
28d788f
fix build
Jaklyy Nov 12, 2024
4099823
more write buffer work
Jaklyy Nov 12, 2024
ac82cda
Merge remote-tracking branch 'upstream/master' into chemical-x
Jaklyy Nov 13, 2024
4db465e
some fixes to write buffer and icache prefetch
Jaklyy Nov 14, 2024
16efe8e
improvements to dma
Jaklyy Nov 17, 2024
172a79c
hacky stall for cache streaming+wb during dmas
Jaklyy Nov 17, 2024
0f20230
fix cache streaming
Jaklyy Dec 1, 2024
9f04905
fix mcr
Jaklyy Dec 1, 2024
5698cf1
lay ground work for main ram contention TAKE 2
Jaklyy Dec 5, 2024
ebc1168
implement queueing ldr RORs and sign extension
Jaklyy Dec 5, 2024
6f0a76d
Merge remote-tracking branch 'upstream/master' into chemical-x2
Jaklyy Dec 6, 2024
08435d2
implement arm7 code fetches
Jaklyy Dec 6, 2024
a049c43
finish arm7 contention
Jaklyy Dec 6, 2024
70dca68
improve accuracy of contention resolution
Jaklyy Dec 6, 2024
db7eb56
handle uncached/buffered accesses for arm9
Jaklyy Dec 7, 2024
698d78b
do dcache; tweak some contention handling logic
Jaklyy Dec 7, 2024
3d6ebc1
rework tracking of overlap
Jaklyy Dec 7, 2024
9a4dc94
reimplement interlocks
Jaklyy Dec 7, 2024
98f24d0
reimplement forced interlocks
Jaklyy Dec 7, 2024
d14c5ea
re-add itcm delay for ldm/stm
Jaklyy Dec 7, 2024
b40c6bc
implement write buffer
Jaklyy Dec 8, 2024
68b4d96
Queue ICache Prefetch
Jaklyy Dec 8, 2024
e69a2aa
write buffer shouldn't continue resolving main ram accesses if it pas…
Jaklyy Dec 8, 2024
8209fde
fix main ram timestamp
Jaklyy Dec 8, 2024
bda05a7
only recalc mpu lut if it changed
Jaklyy Dec 8, 2024
8e6755c
jakly pls
Jaklyy Dec 8, 2024
91752c1
fix emulator hanging under certain circumstances
Jaklyy Dec 8, 2024
0df4369
tweak scheduler for better performance
Jaklyy Dec 8, 2024
1a1934d
...removing the (s32) fixes sign extension? ig???
Jaklyy Dec 9, 2024
7a4234d
fix writeback when rn is also rd in ldr
Jaklyy Dec 9, 2024
f823a92
fix branches being able to break the queue system
Jaklyy Dec 9, 2024
aa2cdc3
optimize one of the main loops
Jaklyy Dec 9, 2024
33f6218
avoid checking T bit every instruction
Jaklyy Dec 9, 2024
fe9a9ee
actually those do literally nothing
Jaklyy Dec 9, 2024
cbdd6a0
cacheline align register array
Jaklyy Dec 9, 2024
918df04
cache line boundary align condition lut table
Jaklyy Dec 9, 2024
0111ee7
micro-optimization
Jaklyy Dec 9, 2024
52e1461
probably faster to directly access main ram?
Jaklyy Dec 9, 2024
8382769
fix a main loop freeze; exmemcnt bit 15 starts set
Jaklyy Dec 9, 2024
b048e0c
improve ExMemCnt handling and defaults
Jaklyy Dec 10, 2024
96c8f67
implement bit 10 of exmemcnt
Jaklyy Dec 10, 2024
feb1cd5
clarify some more write buffer details
Jaklyy Dec 10, 2024
d341260
dma rewrite 1
Jaklyy Dec 11, 2024
73be2f3
tweak dmas to be more accurate (actually less?)
Jaklyy Dec 13, 2024
642f085
probably unborks gxfifo stalls
Jaklyy Dec 13, 2024
456d07d
unbork gxfifo stalls
Jaklyy Dec 13, 2024
cce5070
probably not any faster
Jaklyy Dec 14, 2024
a445c0d
this makes a bit more sense
Jaklyy Dec 14, 2024
ac1d790
fix the system timestamp being run wayyyy too fast
Jaklyy Dec 14, 2024
610ac24
disable main ram contention for arm9 dma
Jaklyy Dec 14, 2024
5e94566
hopefully reduce desync potential a little?
Jaklyy Dec 14, 2024
4ea0e60
minor fix(?)
Jaklyy Dec 14, 2024
2051d41
implement MR cont. for arm7 dma; also a hack?
Jaklyy Dec 14, 2024
c902dcf
improve main ram dma timings
Jaklyy Dec 15, 2024
d912429
comment out some replaced stuff
Jaklyy Dec 15, 2024
2247f17
implement a main ram burst restart behavior
Jaklyy Dec 15, 2024
5b07765
misc tweaks to dma
Jaklyy Dec 15, 2024
db19912
tweak scheduling to be a little less gross
Jaklyy Dec 15, 2024
45be951
this should be smarter
Jaklyy Dec 15, 2024
443ecb3
improve(?) irq handling
Jaklyy Dec 16, 2024
93242e1
revert most scheduler changes
Jaklyy Dec 16, 2024
c96b49e
Revert "improve(?) irq handling"
Jaklyy Dec 16, 2024
c40efab
revert main ram dma
Jaklyy Dec 16, 2024
e77c201
slightly optimize main loop
Jaklyy Dec 16, 2024
29421f1
re-enable mainram dma
Jaklyy Dec 16, 2024
c90f10d
revert arm9 main ram dma again (again (again))
Jaklyy Dec 16, 2024
5c5f436
run arm 7 first?
Jaklyy Dec 16, 2024
67198a7
why did i remove that
Jaklyy Dec 16, 2024
7590c48
Revert "revert arm9 main ram dma again (again (again))"
Jaklyy Dec 16, 2024
6d0ab97
fix gamecard dma breaking w/ main ram contention
Jaklyy Dec 16, 2024
d383381
ONLY queue missed gamecard dmas
Jaklyy Dec 16, 2024
cacf891
Revert "run arm 7 first?"
Jaklyy Dec 16, 2024
e3c8746
fix a bug preventing main ram dmas from doing their first cycle properly
Jaklyy Dec 17, 2024
0a5499c
fix wrong "running" variable being updated during 16 bit main ram dmas
Jaklyy Dec 17, 2024
6ef7a33
small optimization to main ram dma
Jaklyy Dec 17, 2024
4a59829
clean up a few errors
Jaklyy Dec 18, 2024
4493634
improve dma accuracy slightly
Jaklyy Dec 19, 2024
0686523
card reads are "double buffered"
Jaklyy Dec 19, 2024
14c765d
Revert "improve dma accuracy slightly"
Jaklyy Dec 20, 2024
6897e4a
rework card read timings
Jaklyy Dec 20, 2024
dd857e8
fix an oversight
Jaklyy Dec 20, 2024
40527f8
remove leftover junk, fix an error with resets
Jaklyy Dec 20, 2024
e0ac68c
Reapply "improve dma accuracy slightly"
Jaklyy Dec 20, 2024
98d0a6b
fix gxfifo stalls being borked under certain circumstances
Jaklyy Dec 20, 2024
22f1b4d
theoretically improve dma responsiveness?
Jaklyy Dec 21, 2024
65e2f64
"immediate mode" dma start should be delayed 1 cycle
Jaklyy Dec 21, 2024
caa009c
better logic for gamecard reads
Jaklyy Dec 21, 2024
4940f94
improve accuracy and also performance
Jaklyy Dec 21, 2024
93dd0f4
fix an issue related to gx stalls
Jaklyy Dec 21, 2024
03dc0c4
fix another crash
Jaklyy Dec 22, 2024
9981a6b
fix a timestamp
Jaklyy Dec 23, 2024
85dc9f7
small improvements to arm9 dma timings
Jaklyy Dec 23, 2024
8d94384
minor fix?
Jaklyy Dec 24, 2024
01ba503
fix fixed src main ram dma timings being off by 1
Jaklyy Dec 24, 2024
2862408
tweaks to card read timings
Jaklyy Dec 24, 2024
3bd25ae
use timestamps for irq handling
Jaklyy Dec 26, 2024
21323bd
clunky fix to get the order of interlocks and irqs right
Jaklyy Dec 26, 2024
cec4c2c
fix handling of halts
Jaklyy Dec 26, 2024
c9e7eec
put out some fires
Jaklyy Dec 26, 2024
a919e7b
improve timer irqs
Jaklyy Dec 27, 2024
459c088
Merge remote-tracking branch 'upstream/master' into chemical-x2
Jaklyy Dec 27, 2024
4d4f374
minor optimization
Jaklyy Dec 27, 2024
c39db83
tentatively improve gxfifo irq timings?
Jaklyy Dec 27, 2024
a86a3f8
fix main ram dmas not stopping for major events
Jaklyy Dec 27, 2024
b9472d4
fix main ram dmas not halting for higher priority dmas
Jaklyy Dec 28, 2024
cc9a6f8
redo a bunch of gx handling for marginal accuracy benefits
Jaklyy Dec 29, 2024
d2737f6
minor error
Jaklyy Dec 29, 2024
4071099
Revert "redo a bunch of gx handling for marginal accuracy benefits"
Jaklyy Dec 29, 2024
9e60f45
implement savestate serialization
Jaklyy Dec 31, 2024
1bd9e87
move main ram contention junk
Jaklyy Jan 1, 2025
e7cba2e
attempt to make read/write timings more accurate?
Jaklyy Jan 1, 2025
aa2e827
small improvement to card read timings
Jaklyy Jan 1, 2025
fbc388f
more moving crud
Jaklyy Jan 2, 2025
8151f54
small oopsie
Jaklyy Jan 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,225 changes: 965 additions & 260 deletions src/ARM.cpp

Large diffs are not rendered by default.

965 changes: 866 additions & 99 deletions src/ARM.h

Large diffs are not rendered by default.

138 changes: 109 additions & 29 deletions src/ARMInterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ namespace melonDS::ARMInterpreter

void A_UNK(ARM* cpu)
{
if (cpu->CheckInterlock) return;
cpu->AddCycles_C();
Log(LogLevel::Warn, "undefined ARM%d instruction %08X @ %08X\n", cpu->Num?7:9, cpu->CurInstr, cpu->R[15]-8);
#ifdef GDBSTUB_ENABLED
cpu->GdbStub.Enter(cpu->GdbStub.IsConnected(), Gdb::TgtStatus::FaultInsn, cpu->R[15]-8);
Expand All @@ -49,11 +51,14 @@ void A_UNK(ARM* cpu)

cpu->R_UND[2] = oldcpsr;
cpu->R[14] = cpu->R[15] - 4;

cpu->JumpTo(cpu->ExceptionBase + 0x04);
}

void T_UNK(ARM* cpu)
{
if (cpu->CheckInterlock) return;
cpu->AddCycles_C();
Log(LogLevel::Warn, "undefined THUMB%d instruction %04X @ %08X\n", cpu->Num?7:9, cpu->CurInstr, cpu->R[15]-4);
#ifdef GDBSTUB_ENABLED
cpu->GdbStub.Enter(cpu->GdbStub.IsConnected(), Gdb::TgtStatus::FaultInsn, cpu->R[15]-4);
Expand All @@ -66,13 +71,27 @@ void T_UNK(ARM* cpu)

cpu->R_UND[2] = oldcpsr;
cpu->R[14] = cpu->R[15] - 2;

cpu->JumpTo(cpu->ExceptionBase + 0x04);
}

void A_BKPT(ARM* cpu)
{
if (cpu->CheckInterlock) return;
if (cpu->Num == 1) return A_UNK(cpu); // checkme

Log(LogLevel::Warn, "BKPT: "); // combine with the prefetch abort warning message
((ARMv5*)cpu)->PrefetchAbort();
}



void A_MSR_IMM(ARM* cpu)
{
if (cpu->CheckInterlock) return;
if ((cpu->Num != 1) && (cpu->CurInstr & ((0x7<<16)|(1<<22)))) cpu->AddCycles_CI(2); // arm9 cpsr_sxc & spsr
else cpu->AddCycles_C();

u32* psr;
if (cpu->CurInstr & (1<<22))
{
Expand All @@ -90,7 +109,6 @@ void A_MSR_IMM(ARM* cpu)
case 0x1A:
case 0x1B: psr = &cpu->R_UND[2]; break;
default:
cpu->AddCycles_C();
return;
}
}
Expand All @@ -101,12 +119,9 @@ void A_MSR_IMM(ARM* cpu)

u32 mask = 0;
if (cpu->CurInstr & (1<<16)) mask |= 0x000000FF;
if (cpu->CurInstr & (1<<17)) mask |= 0x0000FF00;
if (cpu->CurInstr & (1<<18)) mask |= 0x00FF0000;
if (cpu->CurInstr & (1<<19)) mask |= 0xFF000000;

if (!(cpu->CurInstr & (1<<22)))
mask &= 0xFFFFFFDF;
//if (cpu->CurInstr & (1<<17)) mask |= 0x0000FF00; // unused by arm 7 & 9
//if (cpu->CurInstr & (1<<18)) mask |= 0x00FF0000; // unused by arm 7 & 9
if (cpu->CurInstr & (1<<19)) mask |= ((cpu->Num==1) ? 0xF0000000 : 0xF8000000);

if ((cpu->CPSR & 0x1F) == 0x10) mask &= 0xFFFFFF00;

Expand All @@ -121,11 +136,29 @@ void A_MSR_IMM(ARM* cpu)
if (!(cpu->CurInstr & (1<<22)))
cpu->UpdateMode(oldpsr, cpu->CPSR);

cpu->AddCycles_C();
if (cpu->CPSR & 0x20) [[unlikely]]
{
if (cpu->Num == 0)
{
cpu->R[15] += 2; // pc should actually increment by 4 one more time after switching to thumb mode without a pipeline flush, this gets the same effect.
((ARMv5*)cpu)->StartExec = &ARMv5::StartExecTHUMB;
if (cpu->MRTrack.Type == MainRAMType::Null) ((ARMv5*)cpu)->FuncQueue[0] = ((ARMv5*)cpu)->StartExec;
}
else
{
Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: MSR REG T bit change on ARM7\n");
cpu->CPSR &= ~0x20; // keep it from crashing the emulator at least
}
}
}

void A_MSR_REG(ARM* cpu)
{
if (cpu->CheckInterlock) return ((ARMv5*)cpu)->HandleInterlocksExecute<false>(cpu->CurInstr & 0xF);

if ((cpu->Num != 1) && (cpu->CurInstr & ((0x7<<16)|(1<<22)))) cpu->AddCycles_CI(2); // arm9 cpsr_sxc & spsr
else cpu->AddCycles_C();

u32* psr;
if (cpu->CurInstr & (1<<22))
{
Expand All @@ -143,7 +176,6 @@ void A_MSR_REG(ARM* cpu)
case 0x1A:
case 0x1B: psr = &cpu->R_UND[2]; break;
default:
cpu->AddCycles_C();
return;
}
}
Expand All @@ -154,12 +186,9 @@ void A_MSR_REG(ARM* cpu)

u32 mask = 0;
if (cpu->CurInstr & (1<<16)) mask |= 0x000000FF;
if (cpu->CurInstr & (1<<17)) mask |= 0x0000FF00;
if (cpu->CurInstr & (1<<18)) mask |= 0x00FF0000;
if (cpu->CurInstr & (1<<19)) mask |= 0xFF000000;

if (!(cpu->CurInstr & (1<<22)))
mask &= 0xFFFFFFDF;
//if (cpu->CurInstr & (1<<17)) mask |= 0x0000FF00; // unused by arm 7 & 9
//if (cpu->CurInstr & (1<<18)) mask |= 0x00FF0000; // unused by arm 7 & 9
if (cpu->CurInstr & (1<<19)) mask |= ((cpu->Num==1) ? 0xF0000000 : 0xF8000000);

if ((cpu->CPSR & 0x1F) == 0x10) mask &= 0xFFFFFF00;

Expand All @@ -174,11 +203,25 @@ void A_MSR_REG(ARM* cpu)
if (!(cpu->CurInstr & (1<<22)))
cpu->UpdateMode(oldpsr, cpu->CPSR);

cpu->AddCycles_C();
if (cpu->CPSR & 0x20) [[unlikely]]
{
if (cpu->Num == 0)
{
cpu->R[15] += 2; // pc should actually increment by 4 one more time after switching to thumb mode without a pipeline flush, this gets the same effect.
((ARMv5*)cpu)->StartExec = &ARMv5::StartExecTHUMB;
if (cpu->MRTrack.Type == MainRAMType::Null) ((ARMv5*)cpu)->FuncQueue[0] = ((ARMv5*)cpu)->StartExec;
}
else
{
Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: MSR REG T bit change on ARM7\n");
cpu->CPSR &= ~0x20; // keep it from crashing the emulator at least
}
}
}

void A_MRS(ARM* cpu)
{
if (cpu->CheckInterlock) return;
u32 psr;
if (cpu->CurInstr & (1<<22))
{
Expand All @@ -201,8 +244,19 @@ void A_MRS(ARM* cpu)
else
psr = cpu->CPSR;

cpu->R[(cpu->CurInstr>>12) & 0xF] = psr;
cpu->AddCycles_C();
if (cpu->Num != 1) // arm9
{
cpu->AddCycles_CI(2); // 1 X
((ARMv5*)cpu)->AddCycles_MW(2); // 2 M
}
else cpu->AddCycles_C(); // arm7

if (((cpu->CurInstr>>12) & 0xF) == 15)
{
if (cpu->Num == 1) // doesn't seem to jump on the arm9? checkme
cpu->JumpTo(psr & ~0x1); // checkme: this shouldn't be able to switch to thumb?
}
else cpu->R[(cpu->CurInstr>>12) & 0xF] = psr;
}


Expand All @@ -211,80 +265,106 @@ void A_MCR(ARM* cpu)
if ((cpu->CPSR & 0x1F) == 0x10)
return A_UNK(cpu);

if (cpu->CheckInterlock) return ((ARMv5*)cpu)->HandleInterlocksExecute<false>((cpu->CurInstr>>12)&0xF);

u32 cp = (cpu->CurInstr >> 8) & 0xF;
//u32 op = (cpu->CurInstr >> 21) & 0x7;
u32 op = (cpu->CurInstr >> 21) & 0x7;
u32 cn = (cpu->CurInstr >> 16) & 0xF;
u32 cm = cpu->CurInstr & 0xF;
u32 cpinfo = (cpu->CurInstr >> 5) & 0x7;
u32 val = cpu->R[(cpu->CurInstr>>12)&0xF];
if (((cpu->CurInstr>>12) & 0xF) == 15) val += 4;

if (cpu->Num==0 && cp==15)
{
((ARMv5*)cpu)->CP15Write((cn<<8)|(cm<<4)|cpinfo, cpu->R[(cpu->CurInstr>>12)&0xF]);
((ARMv5*)cpu)->CP15Write((cn<<8)|(cm<<4)|cpinfo|(op<<12), val);
}
else if (cpu->Num==1 && cp==14)
{
Log(LogLevel::Debug, "MCR p14,%d,%d,%d on ARM7\n", cn, cm, cpinfo);
}
else
{
Log(LogLevel::Warn, "bad MCR opcode p%d,%d,%d,%d on ARM%d\n", cp, cn, cm, cpinfo, cpu->Num?7:9);
Log(LogLevel::Warn, "bad MCR opcode p%d, %d, reg, c%d, c%d, %d on ARM%d\n", cp, op, cn, cm, cpinfo, cpu->Num?7:9);
return A_UNK(cpu); // TODO: check what kind of exception it really is
}

cpu->AddCycles_CI(1 + 1); // TODO: checkme

if (cpu->Num==0) cpu->AddCycles_CI(5); // checkme
else /* ARM7 */ cpu->AddCycles_CI(1 + 1); // TODO: checkme
}

void A_MRC(ARM* cpu)
{
if ((cpu->CPSR & 0x1F) == 0x10)
return A_UNK(cpu);

if (cpu->CheckInterlock) return ((ARMv5*)cpu)->HandleInterlocksExecute<false>((cpu->CurInstr>>12)&0xF);

u32 cp = (cpu->CurInstr >> 8) & 0xF;
//u32 op = (cpu->CurInstr >> 21) & 0x7;
u32 op = (cpu->CurInstr >> 21) & 0x7;
u32 cn = (cpu->CurInstr >> 16) & 0xF;
u32 cm = cpu->CurInstr & 0xF;
u32 cpinfo = (cpu->CurInstr >> 5) & 0x7;
u32 rd = (cpu->CurInstr>>12) & 0xF;

if (cpu->Num==0 && cp==15)
{
cpu->R[(cpu->CurInstr>>12)&0xF] = ((ARMv5*)cpu)->CP15Read((cn<<8)|(cm<<4)|cpinfo);
if (rd != 15) cpu->R[rd] = ((ARMv5*)cpu)->CP15Read((cn<<8)|(cm<<4)|cpinfo|(op<<12));
else
{
// r15 updates the top 4 bits of the cpsr, done to "allow for conditional branching based on coprocessor status"
u32 flags = ((ARMv5*)cpu)->CP15Read((cn<<8)|(cm<<4)|cpinfo|(op<<12)) & 0xF0000000;
cpu->CPSR = (cpu->CPSR & ~0xF0000000) | flags;
}
}
else if (cpu->Num==1 && cp==14)
{
Log(LogLevel::Debug, "MRC p14,%d,%d,%d on ARM7\n", cn, cm, cpinfo);
}
else
{
Log(LogLevel::Warn, "bad MRC opcode p%d,%d,%d,%d on ARM%d\n", cp, cn, cm, cpinfo, cpu->Num?7:9);
Log(LogLevel::Warn, "bad MRC opcode p%d, %d, reg, c%d, c%d, %d on ARM%d\n", cp, op, cn, cm, cpinfo, cpu->Num?7:9);
return A_UNK(cpu); // TODO: check what kind of exception it really is
}

cpu->AddCycles_CI(2 + 1); // TODO: checkme
if (cpu->Num != 1)
{
cpu->AddCycles_CI(2); // 1 Execute cycle
((ARMv5*)cpu)->AddCycles_MW(2); // 2 Memory cycles
((ARMv5*)cpu)->SetupInterlock((cpu->CurInstr >> 12) & 0xF);
}
else cpu->AddCycles_CI(2 + 1); // TODO: checkme
}



void A_SVC(ARM* cpu)
void A_SVC(ARM* cpu) // A_SWI
{
if (cpu->CheckInterlock) return;
cpu->AddCycles_C();
u32 oldcpsr = cpu->CPSR;
cpu->CPSR &= ~0xBF;
cpu->CPSR |= 0x93;
cpu->UpdateMode(oldcpsr, cpu->CPSR);

cpu->R_SVC[2] = oldcpsr;
cpu->R[14] = cpu->R[15] - 4;

cpu->JumpTo(cpu->ExceptionBase + 0x08);
}

void T_SVC(ARM* cpu)
void T_SVC(ARM* cpu) // T_SWI
{
if (cpu->CheckInterlock) return;
cpu->AddCycles_C();
u32 oldcpsr = cpu->CPSR;
cpu->CPSR &= ~0xBF;
cpu->CPSR |= 0x93;
cpu->UpdateMode(oldcpsr, cpu->CPSR);

cpu->R_SVC[2] = oldcpsr;
cpu->R[14] = cpu->R[15] - 2;

cpu->JumpTo(cpu->ExceptionBase + 0x08);
}

Expand Down
1 change: 1 addition & 0 deletions src/ARMInterpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ void A_MRS(ARM* cpu);
void A_MCR(ARM* cpu);
void A_MRC(ARM* cpu);
void A_SVC(ARM* cpu);
void A_BKPT(ARM* cpu);

void T_SVC(ARM* cpu);

Expand Down
Loading
Loading