Created
January 30, 2023 18:56
-
-
Save jarrodnorwell/aa2e852971881b4fbe15b9b285ee8a1f to your computer and use it in GitHub Desktop.
arm11 cpu stuff
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum Mode : uint32_t { | |
USER, | |
FIQ, | |
IRQ, | |
SUPERVISOR, | |
ABORT, | |
SYSTEM, | |
UNDEFINED | |
}; | |
enum Flag : uint32_t { | |
N, | |
Z, | |
C, | |
V, | |
Q, | |
J, | |
GE, | |
E, | |
A, | |
I, | |
F, | |
T, | |
M | |
}; | |
class ARM11 { | |
public: | |
ARM11(); | |
~ARM11() = default; | |
public: | |
bool pc_changed; | |
uint32_t registers[16]; | |
Mode mode; | |
Flag flag; | |
uint32_t r8_fiq, r9_fiq, r10_fiq, r11_fiq, r12_fiq, r13_fiq, r14_fiq; | |
uint32_t r13_svc, r14_svc; | |
uint32_t r13_abt, r14_abt; | |
uint32_t r13_irq, r14_irq; | |
uint32_t r13_und, r14_und; | |
uint32_t cpsr, sprs_fiq, sprs_svc, sprs_abt, sprs_irq, sprs_und; | |
public: | |
uint32_t get_sprs(); | |
void set_sprs(uint32_t value); | |
Mode get_mode(); | |
void set_mode(uint32_t value); | |
uint32_t get_ge(); | |
void set_ge(uint32_t value); | |
uint32_t get_register(uint32_t index); | |
void set_register(uint32_t index, uint32_t value); | |
}; | |
ARM11::ARM11() {} // TODO: this | |
uint32_t ARM11::get_sprs() { | |
switch (mode) { | |
case USER: | |
case SYSTEM: | |
printf("No sprs for user or system mode"); | |
return 0; | |
case FIQ: | |
return sprs_fiq; | |
case IRQ: | |
return sprs_irq; | |
case SUPERVISOR: | |
return sprs_svc; | |
case ABORT: | |
return sprs_abt; | |
case UNDEFINED: | |
return sprs_und; | |
} | |
} | |
void ARM11::set_sprs(uint32_t value) { | |
switch (mode) { | |
case USER: | |
case SYSTEM: | |
printf("No sprs for user or system mode"); | |
break; | |
case FIQ: | |
sprs_fiq = value; | |
break; | |
case IRQ: | |
sprs_irq = value; | |
break; | |
case SUPERVISOR: | |
sprs_svc = value; | |
break; | |
case ABORT: | |
sprs_abt = value; | |
break; | |
case UNDEFINED: | |
sprs_und = value; | |
break; | |
} | |
} | |
Mode ARM11::get_mode() { | |
return static_cast<Mode>(cpsr & 0x1F); | |
} | |
void ARM11::set_mode(uint32_t value) { | |
cpsr = (cpsr & 0x1F) | value; | |
} | |
uint32_t ARM11::get_ge() { | |
return (cpsr >> 16) & 0xF; | |
} | |
void ARM11::set_ge(uint32_t value) { | |
cpsr = (cpsr & 0xFFF0FFFF) | (value << 16); | |
} | |
uint32_t ARM11::get_register(uint32_t index) { | |
switch (mode) { | |
case USER: | |
case SYSTEM: | |
return registers[index]; | |
case FIQ: | |
if (index < 8 || index == 15) | |
return registers[index]; | |
else | |
switch (index) { | |
case 8: | |
return r8_fiq; | |
case 9: | |
return r9_fiq; | |
case 10: | |
return r10_fiq; | |
case 11: | |
return r11_fiq; | |
case 12: | |
return r12_fiq; | |
case 13: | |
return r13_fiq; | |
case 14: | |
return r14_fiq; | |
} | |
case IRQ: | |
if (index < 13 || index == 15) | |
return registers[index]; | |
else | |
switch (index) { | |
case 13: | |
return r13_irq; | |
case 14: | |
return r14_irq; | |
} | |
case SUPERVISOR: | |
if (index < 13 || index == 15) | |
return registers[index]; | |
else | |
switch (index) { | |
case 13: | |
return r13_svc; | |
case 14: | |
return r14_svc; | |
} | |
case ABORT: | |
if (index < 13 || index == 15) | |
return registers[index]; | |
else | |
switch (index) { | |
case 13: | |
return r13_abt; | |
case 14: | |
return r14_abt; | |
} | |
case UNDEFINED: | |
if (index < 13 || index == 15) | |
return registers[index]; | |
else | |
switch (index) { | |
case 13: | |
return r13_und; | |
case 14: | |
return r14_und; | |
} | |
} | |
} | |
void ARM11::set_register(uint32_t index, uint32_t value) { | |
switch (mode) { | |
case USER: | |
case SYSTEM: | |
registers[index] = value; | |
case FIQ: | |
if (index < 8 || index == 15) | |
registers[index] = value; | |
else | |
switch (index) { | |
case 8: | |
r8_fiq = value; | |
case 9: | |
r9_fiq = value; | |
case 10: | |
r10_fiq = value; | |
case 11: | |
r11_fiq = value; | |
case 12: | |
r12_fiq = value; | |
case 13: | |
r13_fiq = value; | |
case 14: | |
r14_fiq = value; | |
} | |
case IRQ: | |
if (index < 13 || index == 15) | |
registers[index] = value; | |
else | |
switch (index) { | |
case 13: | |
r13_irq = value; | |
case 14: | |
r14_irq = value; | |
} | |
case SUPERVISOR: | |
if (index < 13 || index == 15) | |
registers[index] = value; | |
else | |
switch (index) { | |
case 13: | |
r13_svc = value; | |
case 14: | |
r14_svc = value; | |
} | |
case ABORT: | |
if (index < 13 || index == 15) | |
registers[index] = value; | |
else | |
switch (index) { | |
case 13: | |
r13_abt = value; | |
case 14: | |
r14_abt = value; | |
} | |
case UNDEFINED: | |
if (index < 13 || index == 15) | |
registers[index] = value; | |
else | |
switch (index) { | |
case 13: | |
r13_und = value; | |
case 14: | |
r14_und = value; | |
} | |
} | |
pc_changed = true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment