mirror of
https://github.com/LemonBoy/grape.git
synced 2024-05-28 08:41:33 +00:00
65C02 opcodes. The cpu core passes nearly all the tests (fuck you decimal mode). Minor fixes here and there. Lo-res fixes and stuff.
This commit is contained in:
parent
8e45768c29
commit
d37d6f0bcf
|
@ -6,5 +6,14 @@ void cpu_reset ();
|
||||||
void cpu_nmi ();
|
void cpu_nmi ();
|
||||||
extern u32 cpu_regs[6];
|
extern u32 cpu_regs[6];
|
||||||
|
|
||||||
|
enum {
|
||||||
|
RF = 0,
|
||||||
|
RY,
|
||||||
|
RX,
|
||||||
|
RA,
|
||||||
|
RSP,
|
||||||
|
RPC,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
394
source/cpu.s
394
source/cpu.s
|
@ -1,6 +1,10 @@
|
||||||
.arm
|
.arm
|
||||||
.section .itcm,"ax",%progbits
|
.section .itcm,"ax",%progbits
|
||||||
|
|
||||||
|
#define UNDOC_OPS
|
||||||
|
//#define PRINT_TRACE
|
||||||
|
//#define CHECK_IDLE_JUMP
|
||||||
|
|
||||||
.global cpu_run
|
.global cpu_run
|
||||||
.global cpu_reset
|
.global cpu_reset
|
||||||
.global cpu_regs
|
.global cpu_regs
|
||||||
|
@ -27,16 +31,6 @@ cycles .req r5
|
||||||
orr r0, r1, lsl #8
|
orr r0, r1, lsl #8
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro rebase_sp r
|
|
||||||
ldr r0, =(mainram+0x100)
|
|
||||||
add \r, r0
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro unbase_sp r
|
|
||||||
ldr r0, =(mainram+0x100)
|
|
||||||
sub \r, reg_sp, r0
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro rebase_pc r
|
.macro rebase_pc r
|
||||||
ldr r1, =memmap_r
|
ldr r1, =memmap_r
|
||||||
mov r2, \r, lsr #12
|
mov r2, \r, lsr #12
|
||||||
|
@ -48,16 +42,22 @@ cycles .req r5
|
||||||
|
|
||||||
.macro unbase_pc r
|
.macro unbase_pc r
|
||||||
ldr r1, =last_page
|
ldr r1, =last_page
|
||||||
ldr r2, [r1]
|
ldr r1, [r1]
|
||||||
sub \r, reg_pc, r2
|
sub \r, reg_pc, r1
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro push b
|
.macro push r
|
||||||
strb \b, [reg_sp], #-1
|
ldr r3, =(mainram+0x100)
|
||||||
|
strb \r, [r3, reg_sp]
|
||||||
|
sub reg_sp, #1
|
||||||
|
and reg_sp, #255
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro pop
|
.macro pop r
|
||||||
ldrb r0, [reg_sp, #1]!
|
ldr r1, =(mainram+0x100)
|
||||||
|
add reg_sp, #1
|
||||||
|
and reg_sp, #255
|
||||||
|
ldrb \r, [r1, reg_sp]
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro adr_zp_z
|
.macro adr_zp_z
|
||||||
|
@ -77,51 +77,71 @@ cycles .req r5
|
||||||
.macro adr_abs r
|
.macro adr_abs r
|
||||||
fetchw
|
fetchw
|
||||||
mov r1, r0, lsr #8
|
mov r1, r0, lsr #8
|
||||||
cmp r1, #0xff
|
|
||||||
subeq cycles, #1
|
|
||||||
add r0, \r
|
add r0, \r
|
||||||
|
cmp r1, r0, lsr #8
|
||||||
|
// Page crossing adds a penality cycle
|
||||||
|
subne cycles, #1
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro adr_idx
|
.macro adr_idx
|
||||||
fetchw
|
fetchw
|
||||||
ldr r1, =memmap_r
|
and r4, r0, #0xff00
|
||||||
mov r2, r0, lsr #12
|
add r3, r0, #1
|
||||||
ldr r1, [r1, r2, lsl #2]
|
and r3, #255
|
||||||
add r1, r0
|
orr r4, r3
|
||||||
ldrb r0, [r1, #0]
|
ldr r2, =memmap_r
|
||||||
ldrb r1, [r1, #1]
|
|
||||||
|
lsr r1, r0, #12
|
||||||
|
ldr r3, [r2, r1, lsl #2]
|
||||||
|
ldrb r0, [r3, r0]
|
||||||
|
|
||||||
|
lsr r1, r4, #12
|
||||||
|
ldr r3, [r2, r1, lsl #2]
|
||||||
|
ldrb r1, [r3, r4]
|
||||||
|
|
||||||
orr r0, r1, lsl #8
|
orr r0, r1, lsl #8
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro adr_idx_x
|
.macro adr_idx_x
|
||||||
fetch
|
fetch
|
||||||
ldr r1, =memmap_r
|
|
||||||
add r0, reg_x
|
add r0, reg_x
|
||||||
ldr r1, [r1]
|
and r0, #255
|
||||||
add r1, r0
|
ldr r3, =memmap_r
|
||||||
ldrb r0, [r1, #0]
|
ldr r3, [r3]
|
||||||
ldrb r1, [r1, #1]
|
add r2, r0, #1
|
||||||
|
and r2, #255
|
||||||
|
ldrb r0, [r3, r0]
|
||||||
|
ldrb r1, [r3, r2]
|
||||||
orr r0, r1, lsl #8
|
orr r0, r1, lsl #8
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro adr_idx_y
|
.macro adr_idx_y
|
||||||
fetch
|
fetch
|
||||||
ldr r3, =memmap_r
|
ldr r3, =memmap_r
|
||||||
ldr r2, [r3]
|
ldr r3, [r3]
|
||||||
add r2, r2, r0
|
add r2, r0, #1
|
||||||
ldrb r0, [r2, #0]
|
and r2, #255
|
||||||
ldrb r1, [r2, #1]
|
ldrb r0, [r3, r0]
|
||||||
|
ldrb r1, [r3, r2]
|
||||||
orr r0, r1, lsl #8
|
orr r0, r1, lsl #8
|
||||||
add r1, r0, reg_y
|
add r0, reg_y
|
||||||
eor r2, r1, r0
|
// Page crossing adds a penality cycle
|
||||||
tst r2, #0x100
|
cmp r1, r0, lsr #8
|
||||||
subne cycles, #1
|
subne cycles, #1
|
||||||
mov r0, r1
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro adr_rel
|
.macro adr_rel
|
||||||
ldrsb r0, [reg_pc], #1
|
ldrsb r0, [reg_pc], #1
|
||||||
// Sign extend
|
#ifdef CHECK_IDLE_JUMP
|
||||||
|
cmp r0, #-2
|
||||||
|
bne 2f
|
||||||
|
// unbase_pc reg_pc
|
||||||
|
// ldr r0, =idle_loop_msg
|
||||||
|
// mov r1, reg_pc
|
||||||
|
// bl iprintf
|
||||||
|
b _xx
|
||||||
|
#endif
|
||||||
|
2: // Sign extend
|
||||||
add r2, reg_pc, r0
|
add r2, reg_pc, r0
|
||||||
eor r1, r2, reg_pc
|
eor r1, r2, reg_pc
|
||||||
tst r1, #0x100
|
tst r1, #0x100
|
||||||
|
@ -133,6 +153,7 @@ cycles .req r5
|
||||||
#define FLAG_ZERO 0x02<<24
|
#define FLAG_ZERO 0x02<<24
|
||||||
#define FLAG_INTR 0x04<<24
|
#define FLAG_INTR 0x04<<24
|
||||||
#define FLAG_DEC 0x08<<24
|
#define FLAG_DEC 0x08<<24
|
||||||
|
#define FLAG_BRK 0x20<<24
|
||||||
#define FLAG_OVER 0x40<<24
|
#define FLAG_OVER 0x40<<24
|
||||||
#define FLAG_NEG 0x80<<24
|
#define FLAG_NEG 0x80<<24
|
||||||
|
|
||||||
|
@ -147,6 +168,21 @@ cycles .req r5
|
||||||
orrvs reg_f, #FLAG_OVER
|
orrvs reg_f, #FLAG_OVER
|
||||||
orrmi reg_f, #FLAG_NEG
|
orrmi reg_f, #FLAG_NEG
|
||||||
mov reg_a, reg_a, lsr #24
|
mov reg_a, reg_a, lsr #24
|
||||||
|
// Decimal mode
|
||||||
|
tst reg_f, #FLAG_DEC
|
||||||
|
beq 1f
|
||||||
|
bic reg_f, #FLAG_CARRY
|
||||||
|
// Low nibble
|
||||||
|
and r2, reg_a, #0x0f
|
||||||
|
cmp r2, #0x09
|
||||||
|
addhi reg_a, #0x06
|
||||||
|
// High nibble
|
||||||
|
and r1, reg_a, #0xf0<<24
|
||||||
|
cmp r1, #0x90
|
||||||
|
addhi reg_a, #0x60
|
||||||
|
orrhi reg_f, #FLAG_CARRY
|
||||||
|
add cycles, #1
|
||||||
|
1: nop
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro op_sbc r
|
.macro op_sbc r
|
||||||
|
@ -159,6 +195,22 @@ cycles .req r5
|
||||||
orrmi reg_f, #FLAG_NEG
|
orrmi reg_f, #FLAG_NEG
|
||||||
movs reg_a, reg_a, lsr #24
|
movs reg_a, reg_a, lsr #24
|
||||||
orreq reg_f, #FLAG_ZERO
|
orreq reg_f, #FLAG_ZERO
|
||||||
|
// Decimal mode
|
||||||
|
tst reg_f, #FLAG_DEC
|
||||||
|
beq 1f
|
||||||
|
sub reg_a, #0x66
|
||||||
|
bic reg_f, #FLAG_CARRY
|
||||||
|
// Low nibble
|
||||||
|
and r2, reg_a, #0x0f
|
||||||
|
cmp r2, #0x09
|
||||||
|
addhi reg_a, #0x06
|
||||||
|
// High nibble
|
||||||
|
and r1, reg_a, #0xf0<<24
|
||||||
|
cmp r1, #0x90
|
||||||
|
addhi reg_a, #0x60
|
||||||
|
orrhi reg_f, #FLAG_CARRY
|
||||||
|
add cycles, #1
|
||||||
|
1: nop
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro op_and a1
|
.macro op_and a1
|
||||||
|
@ -216,11 +268,10 @@ cycles .req r5
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro op_lsr a1
|
.macro op_lsr a1
|
||||||
bic reg_f, #(FLAG_CARRY+FLAG_ZERO)
|
bic reg_f, #(FLAG_CARRY+FLAG_ZERO+FLAG_NEG)
|
||||||
movs \a1, \a1, lsr #1
|
movs \a1, \a1, lsr #1
|
||||||
orrcs reg_f, #FLAG_CARRY
|
orrcs reg_f, #FLAG_CARRY
|
||||||
orreq reg_f, #FLAG_ZERO
|
orreq reg_f, #FLAG_ZERO
|
||||||
//flag_neg \a1
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro op_ora a1
|
.macro op_ora a1
|
||||||
|
@ -264,9 +315,19 @@ cycles .req r5
|
||||||
orrne reg_f, #FLAG_NEG
|
orrne reg_f, #FLAG_NEG
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
.macro op_txb set, a1
|
||||||
|
tst \a1, reg_a
|
||||||
|
orreq reg_f, #FLAG_ZERO
|
||||||
|
bicne reg_f, #FLAG_ZERO
|
||||||
|
.if \set == 1
|
||||||
|
orr \a1, reg_a
|
||||||
|
.else
|
||||||
|
bic \a1, reg_a
|
||||||
|
.endif
|
||||||
|
.endm
|
||||||
|
|
||||||
// NOP
|
// NOP
|
||||||
_ea:
|
_ea:
|
||||||
_7a:
|
|
||||||
mov r0, #2
|
mov r0, #2
|
||||||
b instr_end
|
b instr_end
|
||||||
// ORA
|
// ORA
|
||||||
|
@ -451,7 +512,6 @@ _2c:
|
||||||
op_bit r0
|
op_bit r0
|
||||||
mov r0, #4
|
mov r0, #4
|
||||||
b instr_end
|
b instr_end
|
||||||
.ltorg
|
|
||||||
// BMI
|
// BMI
|
||||||
_30:
|
_30:
|
||||||
tst reg_f, #FLAG_NEG
|
tst reg_f, #FLAG_NEG
|
||||||
|
@ -481,8 +541,8 @@ _10:
|
||||||
b instr_end
|
b instr_end
|
||||||
// BRK
|
// BRK
|
||||||
_00:
|
_00:
|
||||||
add reg_pc, #1
|
|
||||||
unbase_pc r0
|
unbase_pc r0
|
||||||
|
add r0, #1
|
||||||
mov r1, r0, lsr #8
|
mov r1, r0, lsr #8
|
||||||
and r2, r0, #0xff
|
and r2, r0, #0xff
|
||||||
push r1
|
push r1
|
||||||
|
@ -490,7 +550,7 @@ _00:
|
||||||
mov r0, reg_f, lsr #24
|
mov r0, reg_f, lsr #24
|
||||||
orr r0, #0x30
|
orr r0, #0x30
|
||||||
push r0
|
push r0
|
||||||
orr reg_f, #FLAG_INTR
|
orr reg_f, #(FLAG_INTR|FLAG_BRK)
|
||||||
|
|
||||||
ldr r0, =memmap_r
|
ldr r0, =memmap_r
|
||||||
ldr r0, [r0, #0xf<<2]
|
ldr r0, [r0, #0xf<<2]
|
||||||
|
@ -505,21 +565,18 @@ _00:
|
||||||
b instr_end
|
b instr_end
|
||||||
// RTI
|
// RTI
|
||||||
_40:
|
_40:
|
||||||
pop
|
pop r0
|
||||||
bic reg_f, #0xff000000
|
mov reg_f, r0, lsl #24
|
||||||
orr reg_f, r0, lsl #24
|
pop reg_pc
|
||||||
pop
|
pop r0
|
||||||
mov reg_pc, r0
|
|
||||||
pop
|
|
||||||
orr reg_pc, r0, lsl #8
|
orr reg_pc, r0, lsl #8
|
||||||
|
rebase_pc reg_pc
|
||||||
mov r0, #6
|
mov r0, #6
|
||||||
b instr_end
|
b instr_end
|
||||||
.ltorg
|
|
||||||
// RTS
|
// RTS
|
||||||
_60:
|
_60:
|
||||||
pop
|
pop reg_pc
|
||||||
mov reg_pc, r0
|
pop r0
|
||||||
pop
|
|
||||||
orr reg_pc, r0, lsl #8
|
orr reg_pc, r0, lsl #8
|
||||||
add reg_pc, #1
|
add reg_pc, #1
|
||||||
rebase_pc reg_pc
|
rebase_pc reg_pc
|
||||||
|
@ -543,7 +600,6 @@ _20:
|
||||||
rebase_pc reg_pc
|
rebase_pc reg_pc
|
||||||
mov r0, #6
|
mov r0, #6
|
||||||
b instr_end
|
b instr_end
|
||||||
|
|
||||||
// STX
|
// STX
|
||||||
_86:
|
_86:
|
||||||
adr_zp_z
|
adr_zp_z
|
||||||
|
@ -584,7 +640,6 @@ _a4:
|
||||||
lsr reg_y, #24
|
lsr reg_y, #24
|
||||||
mov r0, #3
|
mov r0, #3
|
||||||
b instr_end
|
b instr_end
|
||||||
.ltorg
|
|
||||||
_b4:
|
_b4:
|
||||||
bic reg_f, #(FLAG_ZERO+FLAG_NEG)
|
bic reg_f, #(FLAG_ZERO+FLAG_NEG)
|
||||||
adr_zp reg_x
|
adr_zp reg_x
|
||||||
|
@ -782,13 +837,31 @@ _91:
|
||||||
// JMP
|
// JMP
|
||||||
_4c:
|
_4c:
|
||||||
adr_abs_z
|
adr_abs_z
|
||||||
mov reg_pc, r0
|
#ifdef CHECK_IDLE_JUMP
|
||||||
|
cmp reg_pc, r0
|
||||||
|
bne 2f
|
||||||
|
unbase_pc reg_pc
|
||||||
|
ldr r0, =idle_loop_msg
|
||||||
|
mov r1, reg_pc
|
||||||
|
bl iprintf
|
||||||
|
1: b 1b
|
||||||
|
#endif
|
||||||
|
2: mov reg_pc, r0
|
||||||
rebase_pc reg_pc
|
rebase_pc reg_pc
|
||||||
mov r0, #3
|
mov r0, #3
|
||||||
b instr_end
|
b instr_end
|
||||||
_6c:
|
_6c:
|
||||||
adr_idx
|
adr_idx
|
||||||
mov reg_pc, r0
|
#ifdef CHECK_IDLE_JUMP
|
||||||
|
cmp reg_pc, r0
|
||||||
|
bne 2f
|
||||||
|
unbase_pc reg_pc
|
||||||
|
ldr r0, =idle_loop_msg
|
||||||
|
mov r1, reg_pc
|
||||||
|
bl iprintf
|
||||||
|
1: b 1b
|
||||||
|
#endif
|
||||||
|
2: mov reg_pc, r0
|
||||||
rebase_pc reg_pc
|
rebase_pc reg_pc
|
||||||
mov r0, #5
|
mov r0, #5
|
||||||
b instr_end
|
b instr_end
|
||||||
|
@ -800,7 +873,7 @@ _48:
|
||||||
// PLA
|
// PLA
|
||||||
_68:
|
_68:
|
||||||
bic reg_f, #(FLAG_ZERO+FLAG_NEG)
|
bic reg_f, #(FLAG_ZERO+FLAG_NEG)
|
||||||
pop
|
pop r0
|
||||||
movs reg_a, r0, lsl #24
|
movs reg_a, r0, lsl #24
|
||||||
orreq reg_f, #FLAG_ZERO
|
orreq reg_f, #FLAG_ZERO
|
||||||
orrmi reg_f, #FLAG_NEG
|
orrmi reg_f, #FLAG_NEG
|
||||||
|
@ -1246,16 +1319,16 @@ _98:
|
||||||
// TXS
|
// TXS
|
||||||
_9a:
|
_9a:
|
||||||
mov reg_sp, reg_x
|
mov reg_sp, reg_x
|
||||||
rebase_sp reg_sp
|
|
||||||
mov r0, #2
|
mov r0, #2
|
||||||
b instr_end
|
b instr_end
|
||||||
// TSX
|
// TSX
|
||||||
_ba:
|
_ba:
|
||||||
bic reg_f, #(FLAG_ZERO+FLAG_NEG)
|
bic reg_f, #(FLAG_ZERO+FLAG_NEG)
|
||||||
unbase_sp reg_x
|
mov reg_x, reg_sp
|
||||||
|
movs reg_x, reg_x, lsl #24
|
||||||
orreq reg_f, #FLAG_ZERO
|
orreq reg_f, #FLAG_ZERO
|
||||||
movs r1, reg_x, lsl #24
|
|
||||||
orrmi reg_f, #FLAG_NEG
|
orrmi reg_f, #FLAG_NEG
|
||||||
|
mov reg_x, reg_x, lsr #24
|
||||||
mov r0, #2
|
mov r0, #2
|
||||||
b instr_end
|
b instr_end
|
||||||
// DEC
|
// DEC
|
||||||
|
@ -1303,13 +1376,13 @@ _18:
|
||||||
// PHP
|
// PHP
|
||||||
_08:
|
_08:
|
||||||
mov r0, reg_f, lsr #24
|
mov r0, reg_f, lsr #24
|
||||||
orr r0, #0x30 // MAGIC!
|
orr r0, #0x30 // BRK flag + reserved bit
|
||||||
push r0
|
push r0
|
||||||
mov r0, #3
|
mov r0, #3
|
||||||
b instr_end
|
b instr_end
|
||||||
// PLP
|
// PLP
|
||||||
_28:
|
_28:
|
||||||
pop
|
pop r0
|
||||||
mov reg_f, r0, lsl #24
|
mov reg_f, r0, lsl #24
|
||||||
mov r0, #4
|
mov r0, #4
|
||||||
b instr_end
|
b instr_end
|
||||||
|
@ -1410,6 +1483,11 @@ _b8:
|
||||||
bic reg_f, #FLAG_OVER
|
bic reg_f, #FLAG_OVER
|
||||||
mov r0, #2
|
mov r0, #2
|
||||||
b instr_end
|
b instr_end
|
||||||
|
#ifdef UNDOC_OPS
|
||||||
|
// NOP
|
||||||
|
_7a:
|
||||||
|
mov r0, #2
|
||||||
|
b instr_end
|
||||||
// LAX
|
// LAX
|
||||||
_b7:
|
_b7:
|
||||||
bic reg_f, #(FLAG_ZERO+FLAG_NEG)
|
bic reg_f, #(FLAG_ZERO+FLAG_NEG)
|
||||||
|
@ -1444,6 +1522,137 @@ _07:
|
||||||
op_ora r1
|
op_ora r1
|
||||||
mov r0, #5
|
mov r0, #5
|
||||||
b instr_end
|
b instr_end
|
||||||
|
_1a:
|
||||||
|
_3c:
|
||||||
|
_5a:
|
||||||
|
_89:
|
||||||
|
_93:
|
||||||
|
_c7:
|
||||||
|
_da:
|
||||||
|
_f7:
|
||||||
|
_fa:
|
||||||
|
_0c:
|
||||||
|
_3a:
|
||||||
|
_64:
|
||||||
|
_74:
|
||||||
|
_80:
|
||||||
|
_9c:
|
||||||
|
_9e:
|
||||||
|
b _xx
|
||||||
|
#else
|
||||||
|
// BIT
|
||||||
|
_89:
|
||||||
|
fetch
|
||||||
|
tst reg_a, r0
|
||||||
|
bicne reg_f, #FLAG_ZERO
|
||||||
|
orreq reg_f, #FLAG_ZERO
|
||||||
|
mov r0, #2
|
||||||
|
b instr_end
|
||||||
|
_3c:
|
||||||
|
adr_abs reg_x
|
||||||
|
bl readb
|
||||||
|
op_bit r0
|
||||||
|
mov r0, #4
|
||||||
|
b instr_end
|
||||||
|
// PHX
|
||||||
|
_da:
|
||||||
|
push reg_x
|
||||||
|
mov r0, #3
|
||||||
|
b instr_end
|
||||||
|
// PHY
|
||||||
|
_5a:
|
||||||
|
push reg_y
|
||||||
|
mov r0, #3
|
||||||
|
b instr_end
|
||||||
|
// PLX
|
||||||
|
_fa:
|
||||||
|
bic reg_f, #(FLAG_ZERO+FLAG_NEG)
|
||||||
|
pop reg_x
|
||||||
|
movs reg_x, reg_x, lsl #24
|
||||||
|
orreq reg_f, #FLAG_ZERO
|
||||||
|
orrmi reg_f, #FLAG_NEG
|
||||||
|
lsr reg_x, #24
|
||||||
|
mov r0, #4
|
||||||
|
b instr_end
|
||||||
|
// PLY
|
||||||
|
_7a:
|
||||||
|
bic reg_f, #(FLAG_ZERO+FLAG_NEG)
|
||||||
|
pop reg_y
|
||||||
|
movs reg_y, reg_y, lsl #24
|
||||||
|
orreq reg_f, #FLAG_ZERO
|
||||||
|
orrmi reg_f, #FLAG_NEG
|
||||||
|
lsr reg_y, #24
|
||||||
|
mov r0, #4
|
||||||
|
b instr_end
|
||||||
|
// TSB
|
||||||
|
_04:
|
||||||
|
adr_zp_z
|
||||||
|
ldr r1, =mainram
|
||||||
|
ldrb r2, [r1, r0]
|
||||||
|
op_txb 1, r2
|
||||||
|
strb r2, [r1, r0]
|
||||||
|
mov r0, #5
|
||||||
|
b instr_end
|
||||||
|
_0c:
|
||||||
|
adr_abs_z
|
||||||
|
mov r4, r0
|
||||||
|
bl readb
|
||||||
|
op_txb 1, r0
|
||||||
|
mov r1, r0
|
||||||
|
mov r0, r4
|
||||||
|
bl writeb
|
||||||
|
mov r0, #6
|
||||||
|
b instr_end
|
||||||
|
// INC
|
||||||
|
_1a:
|
||||||
|
op_inc reg_a
|
||||||
|
mov r0, #2
|
||||||
|
b instr_end
|
||||||
|
// DEC
|
||||||
|
_3a:
|
||||||
|
op_dec reg_a
|
||||||
|
mov r0, #2
|
||||||
|
b instr_end
|
||||||
|
// STZ
|
||||||
|
_64:
|
||||||
|
adr_zp_z
|
||||||
|
ldr r1, =mainram
|
||||||
|
mov r2, #0
|
||||||
|
strb r2, [r1, r0]
|
||||||
|
mov r0, #3
|
||||||
|
b instr_end
|
||||||
|
_74:
|
||||||
|
adr_zp reg_x
|
||||||
|
ldr r1, =mainram
|
||||||
|
mov r2, #0
|
||||||
|
strb r2, [r1, r0]
|
||||||
|
mov r0, #3
|
||||||
|
b instr_end
|
||||||
|
_9c:
|
||||||
|
adr_abs_z
|
||||||
|
mov r1, #0
|
||||||
|
bl writeb
|
||||||
|
mov r0, #4
|
||||||
|
b instr_end
|
||||||
|
_9e:
|
||||||
|
adr_abs reg_x
|
||||||
|
mov r1, #0
|
||||||
|
bl writeb
|
||||||
|
mov r0, #4
|
||||||
|
b instr_end
|
||||||
|
// BRA
|
||||||
|
_80:
|
||||||
|
adr_rel
|
||||||
|
mov r0, #3
|
||||||
|
b instr_end
|
||||||
|
_07:
|
||||||
|
_b7:
|
||||||
|
_fc:
|
||||||
|
_f7:
|
||||||
|
_c7:
|
||||||
|
_93:
|
||||||
|
b _xx
|
||||||
|
#endif
|
||||||
|
|
||||||
// http://emu-docs.org/CPU%2065xx/undocop.txt
|
// http://emu-docs.org/CPU%2065xx/undocop.txt
|
||||||
|
|
||||||
|
@ -1455,13 +1664,16 @@ _xx:
|
||||||
bic r2, #1
|
bic r2, #1
|
||||||
str r2, [r3]
|
str r2, [r3]
|
||||||
#endif
|
#endif
|
||||||
mov r1, r0
|
unbase_pc reg_pc
|
||||||
|
lsr reg_f, #24
|
||||||
|
stmfd sp!, {r0,reg_f,reg_sp,reg_pc}
|
||||||
ldr r0, =unhandled_msg
|
ldr r0, =unhandled_msg
|
||||||
mov r2, reg_a
|
mov r1, reg_a
|
||||||
mov r3, reg_x
|
mov r2, reg_x
|
||||||
stmfd sp!, {reg_y,reg_sp,reg_pc}
|
mov r3, reg_y
|
||||||
bl iprintf
|
bl iprintf
|
||||||
k: b k
|
hang:
|
||||||
|
b hang
|
||||||
|
|
||||||
// int cpu_run_1 (int cycles_to_do)
|
// int cpu_run_1 (int cycles_to_do)
|
||||||
cpu_run:
|
cpu_run:
|
||||||
|
@ -1473,39 +1685,38 @@ cpu_run:
|
||||||
mov cycles, r0
|
mov cycles, r0
|
||||||
loop:
|
loop:
|
||||||
fetch
|
fetch
|
||||||
#if 0
|
#ifdef PRINT_TRACE
|
||||||
unbase_pc reg_pc
|
unbase_pc reg_pc
|
||||||
mov r3, reg_pc, lsr #12
|
lsr reg_f, #24
|
||||||
cmp r3, #0xf
|
stmfd sp!, {r0,reg_f,reg_sp,reg_pc}
|
||||||
beq e
|
|
||||||
stmfd sp!, {reg_pc,r0}
|
|
||||||
ldr r0, =debug_msg
|
ldr r0, =debug_msg
|
||||||
mov r1, reg_a
|
mov r1, reg_a
|
||||||
mov r2, reg_x
|
mov r2, reg_x
|
||||||
mov r3, reg_y
|
mov r3, reg_y
|
||||||
bl iprintf
|
bl iprintf
|
||||||
ldmfd sp!, {reg_pc,r0}
|
ldmfd sp!, {r0,reg_f,reg_sp,reg_pc}
|
||||||
e: rebase_pc reg_pc
|
lsl reg_f, #24
|
||||||
|
1: rebase_pc reg_pc
|
||||||
#endif
|
#endif
|
||||||
ldr pc, [pc, r0, lsl #2]
|
ldr pc, [pc, r0, lsl #2]
|
||||||
nop
|
nop
|
||||||
op_tab:
|
op_tab:
|
||||||
.word _00,_01,_xx,_xx,_04,_05,_06,_07,_08,_09,_0a,_xx,_xx,_0d,_0e,_xx
|
.word _00,_01,_xx,_xx,_04,_05,_06,_07,_08,_09,_0a,_xx,_0c,_0d,_0e,_xx
|
||||||
.word _10,_11,_xx,_xx,_xx,_15,_16,_xx,_18,_19,_xx,_xx,_xx,_1d,_1e,_xx
|
.word _10,_11,_xx,_xx,_xx,_15,_16,_xx,_18,_19,_1a,_xx,_xx,_1d,_1e,_xx
|
||||||
.word _20,_21,_xx,_xx,_24,_25,_26,_xx,_28,_29,_2a,_xx,_2c,_2d,_2e,_xx
|
.word _20,_21,_xx,_xx,_24,_25,_26,_xx,_28,_29,_2a,_xx,_2c,_2d,_2e,_xx
|
||||||
.word _30,_31,_xx,_xx,_xx,_35,_36,_xx,_38,_39,_xx,_xx,_xx,_3d,_3e,_xx
|
.word _30,_31,_xx,_xx,_xx,_35,_36,_xx,_38,_39,_3a,_xx,_3c,_3d,_3e,_xx
|
||||||
.word _40,_41,_xx,_xx,_xx,_45,_46,_xx,_48,_49,_4a,_xx,_4c,_4d,_4e,_xx
|
.word _40,_41,_xx,_xx,_xx,_45,_46,_xx,_48,_49,_4a,_xx,_4c,_4d,_4e,_xx
|
||||||
.word _50,_51,_xx,_xx,_xx,_55,_56,_xx,_58,_59,_xx,_xx,_xx,_5d,_5e,_xx
|
.word _50,_51,_xx,_xx,_xx,_55,_56,_xx,_58,_59,_5a,_xx,_xx,_5d,_5e,_xx
|
||||||
.word _60,_61,_xx,_xx,_xx,_65,_66,_xx,_68,_69,_6a,_xx,_6c,_6d,_6e,_xx
|
.word _60,_61,_xx,_xx,_64,_65,_66,_xx,_68,_69,_6a,_xx,_6c,_6d,_6e,_xx
|
||||||
.word _70,_71,_xx,_xx,_xx,_75,_76,_xx,_78,_79,_7a,_xx,_xx,_7d,_7e,_xx
|
.word _70,_71,_xx,_xx,_74,_75,_76,_xx,_78,_79,_7a,_xx,_xx,_7d,_7e,_xx
|
||||||
.word _xx,_81,_xx,_xx,_84,_85,_86,_xx,_88,_xx,_8a,_xx,_8c,_8d,_8e,_xx
|
.word _80,_81,_xx,_xx,_84,_85,_86,_xx,_88,_89,_8a,_xx,_8c,_8d,_8e,_xx
|
||||||
.word _90,_91,_xx,_xx,_94,_95,_96,_xx,_98,_99,_9a,_xx,_xx,_9d,_xx,_xx
|
.word _90,_91,_xx,_93,_94,_95,_96,_xx,_98,_99,_9a,_xx,_9c,_9d,_9e,_xx
|
||||||
.word _a0,_a1,_a2,_xx,_a4,_a5,_a6,_xx,_a8,_a9,_aa,_xx,_ac,_ad,_ae,_xx
|
.word _a0,_a1,_a2,_xx,_a4,_a5,_a6,_xx,_a8,_a9,_aa,_xx,_ac,_ad,_ae,_xx
|
||||||
.word _b0,_b1,_xx,_xx,_b4,_b5,_b6,_b7,_b8,_b9,_ba,_xx,_bc,_bd,_be,_xx
|
.word _b0,_b1,_xx,_xx,_b4,_b5,_b6,_b7,_b8,_b9,_ba,_xx,_bc,_bd,_be,_xx
|
||||||
.word _c0,_c1,_xx,_xx,_c4,_c5,_c6,_xx,_c8,_c9,_ca,_xx,_cc,_cd,_ce,_xx
|
.word _c0,_c1,_xx,_xx,_c4,_c5,_c6,_c7,_c8,_c9,_ca,_xx,_cc,_cd,_ce,_xx
|
||||||
.word _d0,_d1,_xx,_xx,_xx,_d5,_d6,_xx,_d8,_d9,_xx,_xx,_xx,_dd,_de,_xx
|
.word _d0,_d1,_xx,_xx,_xx,_d5,_d6,_xx,_d8,_d9,_da,_xx,_xx,_dd,_de,_xx
|
||||||
.word _e0,_e1,_xx,_xx,_e4,_e5,_e6,_xx,_e8,_e9,_ea,_xx,_ec,_ed,_ee,_xx
|
.word _e0,_e1,_xx,_xx,_e4,_e5,_e6,_xx,_e8,_e9,_ea,_xx,_ec,_ed,_ee,_xx
|
||||||
.word _f0,_f1,_xx,_xx,_xx,_f5,_f6,_xx,_f8,_f9,_xx,_xx,_fc,_fd,_fe,_xx
|
.word _f0,_f1,_xx,_xx,_xx,_f5,_f6,_f7,_f8,_f9,_fa,_xx,_fc,_fd,_fe,_xx
|
||||||
instr_end:
|
instr_end:
|
||||||
subs cycles, r0
|
subs cycles, r0
|
||||||
bpl loop
|
bpl loop
|
||||||
|
@ -1530,7 +1741,6 @@ cpu_reset:
|
||||||
mov r5, r0 // r5 = pc
|
mov r5, r0 // r5 = pc
|
||||||
mov r4, #0xfd // r4 = sp
|
mov r4, #0xfd // r4 = sp
|
||||||
rebase_pc r5
|
rebase_pc r5
|
||||||
rebase_sp r4
|
|
||||||
mov r0, #0 // r0 = f
|
mov r0, #0 // r0 = f
|
||||||
mov r1, #0 // r1 = y
|
mov r1, #0 // r1 = y
|
||||||
mov r2, #0 // r2 = x
|
mov r2, #0 // r2 = x
|
||||||
|
@ -1544,8 +1754,12 @@ cpu_regs:
|
||||||
last_page:
|
last_page:
|
||||||
.word 0
|
.word 0
|
||||||
|
|
||||||
|
.section .rodata
|
||||||
unhandled_msg:
|
unhandled_msg:
|
||||||
.ascii "Unhandled op\n"
|
.ascii "- Unhandled op!\n"
|
||||||
debug_msg:
|
debug_msg:
|
||||||
.ascii "A%02x X%02x Y%02x P%04x OP %02x\n"
|
.ascii "A%02x X%02x Y%02x OP%02x F%02x SP%02x P%04x\n"
|
||||||
|
.byte 0
|
||||||
|
idle_loop_msg:
|
||||||
|
.ascii "Idle %04x\n"
|
||||||
.byte 0
|
.byte 0
|
||||||
|
|
19
source/emu.c
19
source/emu.c
|
@ -9,7 +9,6 @@ void irq_vblank ()
|
||||||
if (vblanks++ == 60) {
|
if (vblanks++ == 60) {
|
||||||
consoleClear();
|
consoleClear();
|
||||||
iprintf("FPS %i\n", frames_done);
|
iprintf("FPS %i\n", frames_done);
|
||||||
// iprintf("keybd_latch : %02x\n", keybd_latch);
|
|
||||||
frames_done = 0;
|
frames_done = 0;
|
||||||
vblanks = 0;
|
vblanks = 0;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +26,7 @@ int valid_rom_crc (const u16 crc)
|
||||||
const u16 known_crcs[] = {
|
const u16 known_crcs[] = {
|
||||||
0xAC8F, // 12288 BASIC.ROM
|
0xAC8F, // 12288 BASIC.ROM
|
||||||
0x3F44, // 12288 apple.rom
|
0x3F44, // 12288 apple.rom
|
||||||
|
0x9CB5, // 12288 A2ROM.BIN
|
||||||
};
|
};
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -42,14 +42,15 @@ void emu_init ()
|
||||||
u16 crc;
|
u16 crc;
|
||||||
int valid_crc;
|
int valid_crc;
|
||||||
|
|
||||||
keyboardShow();
|
keysSetRepeat(30, 10);
|
||||||
|
/*keyboardShow();*/
|
||||||
|
|
||||||
// Set some sane defaults
|
// Set some sane defaults
|
||||||
emu_vsync = 1;
|
emu_vsync = 0;
|
||||||
|
|
||||||
// Setup the video hardware
|
// Setup the video hardware
|
||||||
video_init();
|
video_init();
|
||||||
|
#if 1
|
||||||
// Load the appropriate bios
|
// Load the appropriate bios
|
||||||
if (load_bin("BASIC.ROM", 0xD000, 0x3000, &crc)) {
|
if (load_bin("BASIC.ROM", 0xD000, 0x3000, &crc)) {
|
||||||
valid_crc = valid_rom_crc(crc);
|
valid_crc = valid_rom_crc(crc);
|
||||||
|
@ -64,6 +65,16 @@ void emu_init ()
|
||||||
|
|
||||||
// Load the disk rom in place
|
// Load the disk rom in place
|
||||||
load_buf(disk_rom, 0xc600, 0x100);
|
load_buf(disk_rom, 0xc600, 0x100);
|
||||||
|
#else
|
||||||
|
if (load_bin("6502_functional_test.bin", 0x0, -1, NULL) > 0) {
|
||||||
|
const u16 reset_patch = 0x0400;
|
||||||
|
iprintf("Test rom loaded\n");
|
||||||
|
iprintf("PC : %04x\n", mainram[0xFFFD]<<8|mainram[0xFFFC]);
|
||||||
|
iprintf("Routing the reset vector to %04x\n", reset_patch);
|
||||||
|
mainram[0xFFFC] = reset_patch&0xFF;
|
||||||
|
mainram[0xFFFD] = (reset_patch>>8)&0xFF;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
basename = NULL;
|
basename = NULL;
|
||||||
|
|
||||||
|
|
|
@ -23,11 +23,13 @@ void update_input ()
|
||||||
int kbd_key;
|
int kbd_key;
|
||||||
|
|
||||||
scanKeys();
|
scanKeys();
|
||||||
keys = keysHeld()&0xfff;
|
keys = (keysDownRepeat()|keysDown())&0xfff;
|
||||||
|
|
||||||
// Send keyboard scancodes when a key is pressed
|
// Send keyboard scancodes when a key is pressed
|
||||||
if (emu_input == INPUT_KBD && keys) {
|
if (emu_input == INPUT_KBD && keys) {
|
||||||
keybd_latch = 0x80 ^ key_map[__builtin_ctz(keys)];
|
int bit_set = __builtin_ffs(keys);
|
||||||
|
if (bit_set)
|
||||||
|
keybd_latch = 0x80 ^ key_map[bit_set-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (emu_input == INPUT_JSTK) {
|
if (emu_input == INPUT_JSTK) {
|
||||||
|
|
|
@ -13,7 +13,7 @@ int main(int argc, char **argv)
|
||||||
keyboardDemoInit();
|
keyboardDemoInit();
|
||||||
|
|
||||||
fatInitDefault();
|
fatInitDefault();
|
||||||
/*nitroFSInit(NULL);*/
|
nitroFSInit(NULL);
|
||||||
|
|
||||||
soundEnable();
|
soundEnable();
|
||||||
|
|
||||||
|
@ -22,11 +22,12 @@ int main(int argc, char **argv)
|
||||||
emu_init();
|
emu_init();
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
|
/*load_disk("Airheart (1986)(Broderbund)[cr].dsk");*/
|
||||||
// Slow loading
|
// Slow loading
|
||||||
/*load_disk("PACMAN.DSK");*/
|
/*load_disk("PACMAN.DSK");*/
|
||||||
/*load_disk("Karateka (1984)(Broderbund).dsk");*/
|
/*load_disk("Karateka (1984)(Broderbund).dsk");*/
|
||||||
// Awesome!
|
// Awesome!
|
||||||
/*load_disk("lode.dsk");*/
|
load_disk("lode.dsk");
|
||||||
// AppleII+
|
// AppleII+
|
||||||
/*load_disk("Prince of Persia (1989)(Broderbund)(Disk 1 of 3)[cr].dsk");*/
|
/*load_disk("Prince of Persia (1989)(Broderbund)(Disk 1 of 3)[cr].dsk");*/
|
||||||
// Gfx heavy
|
// Gfx heavy
|
||||||
|
@ -36,13 +37,14 @@ int main(int argc, char **argv)
|
||||||
/*load_disk("Round About (1983)(Datamost).dsk");*/
|
/*load_disk("Round About (1983)(Datamost).dsk");*/
|
||||||
/*load_disk("Bug Attack (1981)(Cavalier Computer).dsk");*/
|
/*load_disk("Bug Attack (1981)(Cavalier Computer).dsk");*/
|
||||||
// Scroller
|
// Scroller
|
||||||
load_disk("TetrisII.DSK");
|
/*load_disk("TetrisII.DSK");*/
|
||||||
// Mixed mode
|
// Mixed mode
|
||||||
/*load_disk("tetris48k.nib");*/
|
/*load_disk("tetris48k.nib");*/
|
||||||
// Lowres
|
// Lowres
|
||||||
/*load_disk("Fracas (1980)(Quality Software).dsk");*/
|
/*load_disk("Fracas (1980)(Quality Software).dsk");*/
|
||||||
/*load_disk("Colorix.dsk");*/
|
/*load_disk("Colorix.dsk");*/
|
||||||
/*load_disk("LoRes Games.DSK");*/
|
/*load_disk("LoRes Games.DSK");*/
|
||||||
|
/*load_disk("LoRes Hijinks.DSK");*/
|
||||||
// SP Crash
|
// SP Crash
|
||||||
/*load_disk("Apple II Business Graphics 1.0 (1981).nib");*/
|
/*load_disk("Apple II Business Graphics 1.0 (1981).nib");*/
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -16,8 +16,8 @@ u8 readb (u16 addr);
|
||||||
void writeb (u16 addr, u8 val);
|
void writeb (u16 addr, u8 val);
|
||||||
void mem_reset (void);
|
void mem_reset (void);
|
||||||
|
|
||||||
int load_bin (char *file, u16 addr, u16 len, u16 *crc);
|
ssize_t load_bin (const char *file, const u32 addr, ssize_t len, u16 *crc);
|
||||||
int load_buf (const u8 *buf, u16 addr, u16 len);
|
ssize_t load_buf (const u8 *buf, const u32 addr, ssize_t len);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,36 +4,48 @@
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
|
||||||
int load_buf (const u8 *buf, u16 addr, u16 len)
|
ssize_t load_buf (const u8 *buf, const u32 addr, const ssize_t len)
|
||||||
{
|
{
|
||||||
if (addr + len > 0x10000) {
|
if (addr + len > 0x10000) {
|
||||||
iprintf("oob\n");
|
iprintf("oob\n");
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
memcpy(mainram + addr, buf, len);
|
memcpy(mainram + addr, buf, len);
|
||||||
|
|
||||||
return 1;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int load_bin (char *file, u16 addr, u16 len, u16 *crc)
|
ssize_t load_bin (const char *file, const u32 addr, const ssize_t len, u16 *crc)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
size_t read, bin_len;
|
||||||
|
|
||||||
if (addr + len > 0x10000) {
|
|
||||||
iprintf("oob\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
f = fopen(file, "rb");
|
f = fopen(file, "rb");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
iprintf("Can't open %s\n", file);
|
iprintf("Can't open %s\n", file);
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
fread(mainram + addr, 1, len, f);
|
|
||||||
|
if (len < 0) {
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
bin_len = ftell(f);
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
|
} else
|
||||||
|
bin_len = len;
|
||||||
|
|
||||||
|
if (addr + bin_len > 0x10000) {
|
||||||
|
bin_len = 0x4000;
|
||||||
|
iprintf("oob\n");
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
read = fread(mainram + addr, 1, bin_len, f);
|
||||||
|
fclose(f);
|
||||||
|
iprintf("Read %x to %x\n", read, addr);
|
||||||
|
|
||||||
if (crc)
|
if (crc)
|
||||||
*crc = swiCRC16(0xffff, mainram + addr, len);
|
*crc = swiCRC16(0xffff, mainram + addr, read);
|
||||||
|
|
||||||
return 1;
|
return read;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,17 +75,17 @@ void menu_print_page (const page_t *page, int *opts)
|
||||||
if (sel_entry->opts_no) {
|
if (sel_entry->opts_no) {
|
||||||
if (keys&KEY_LEFT && opts[cur] > 0) {
|
if (keys&KEY_LEFT && opts[cur] > 0) {
|
||||||
opts[cur]--;
|
opts[cur]--;
|
||||||
if (sel_entry->cb) sel_entry->cb(opts[cur]);
|
/*if (sel_entry->cb) sel_entry->cb(opts[cur]);*/
|
||||||
}
|
}
|
||||||
if (keys&KEY_RIGHT && opts[cur] < sel_entry->opts_no - 1) {
|
if (keys&KEY_RIGHT && opts[cur] < sel_entry->opts_no - 1) {
|
||||||
opts[cur]++;
|
opts[cur]++;
|
||||||
if (sel_entry->cb) sel_entry->cb(opts[cur]);
|
/*if (sel_entry->cb) sel_entry->cb(opts[cur]);*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keys&KEY_A) {
|
if (keys&KEY_A) {
|
||||||
if (sel_entry->cb)
|
if (sel_entry->cb)
|
||||||
sel_entry->cb(opts[cur]); // TODO : Handle errors
|
if (sel_entry->cb(opts[cur]))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,4 +97,10 @@ void menu_print_page (const page_t *page, int *opts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_msg (const char *msg)
|
||||||
|
{
|
||||||
|
iprintf("\n-- %s\n", msg);
|
||||||
|
swiDelay(10000000);
|
||||||
|
}
|
||||||
|
|
||||||
void pause_menu () { menu_print_page(&paused_pg, (int *)&paused_pg_opt); }
|
void pause_menu () { menu_print_page(&paused_pg, (int *)&paused_pg_opt); }
|
||||||
|
|
|
@ -11,7 +11,7 @@ typedef struct state_hdr_t {
|
||||||
|
|
||||||
#define STATE_MAGIC (0x47525033)
|
#define STATE_MAGIC (0x47525033)
|
||||||
|
|
||||||
char *build_path (int slot)
|
char *build_path (const int slot)
|
||||||
{
|
{
|
||||||
static char tmp[1024];
|
static char tmp[1024];
|
||||||
if (basename)
|
if (basename)
|
||||||
|
@ -21,14 +21,18 @@ char *build_path (int slot)
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
int state_save (int slot)
|
int state_save (const int slot)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
state_hdr_t h;
|
state_hdr_t h;
|
||||||
|
const char *path;
|
||||||
|
|
||||||
f = fopen(build_path(slot), "w+");
|
path = build_path(slot+1);
|
||||||
if (f)
|
f = fopen(path, "wb");
|
||||||
|
if (!f) {
|
||||||
|
print_msg("Save failed!");
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
h.magic = STATE_MAGIC;
|
h.magic = STATE_MAGIC;
|
||||||
h.ver = 1;
|
h.ver = 1;
|
||||||
|
@ -56,22 +60,27 @@ int state_save (int slot)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int state_load (int slot)
|
int state_load (const int slot)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
state_hdr_t h;
|
state_hdr_t h;
|
||||||
|
const char *path;
|
||||||
|
|
||||||
f = fopen(build_path(slot), "w+");
|
path = build_path(slot+1);
|
||||||
if (f)
|
f = fopen(path, "rb");
|
||||||
|
if (!f) {
|
||||||
|
print_msg("Load failed!");
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
h.magic = STATE_MAGIC;
|
|
||||||
h.ver = 1;
|
|
||||||
h.flags = 0;
|
|
||||||
h.resv = 0;
|
|
||||||
|
|
||||||
fread(&h, 1, sizeof(state_hdr_t), f);
|
fread(&h, 1, sizeof(state_hdr_t), f);
|
||||||
|
|
||||||
|
if (h.magic != STATE_MAGIC) {
|
||||||
|
fclose(f);
|
||||||
|
print_msg("Invalid save file!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
fread(&cpu_regs, 6, 4, f);
|
fread(&cpu_regs, 6, 4, f);
|
||||||
fread(&mainram, 1, sizeof(mainram), f);
|
fread(&mainram, 1, sizeof(mainram), f);
|
||||||
fread(&lcram, 1, sizeof(lcram), f);
|
fread(&lcram, 1, sizeof(lcram), f);
|
||||||
|
|
|
@ -112,11 +112,11 @@ u8 video_io_read (u16 addr)
|
||||||
switch (addr&0xf) {
|
switch (addr&0xf) {
|
||||||
case 0x0:
|
case 0x0:
|
||||||
text_mode = 0;
|
text_mode = 0;
|
||||||
mixed_mode = 0;
|
/*mixed_mode = 0;*/
|
||||||
break;
|
break;
|
||||||
case 0x1:
|
case 0x1:
|
||||||
text_mode = 1;
|
text_mode = 1;
|
||||||
mixed_mode = 0;
|
/*mixed_mode = 0;*/
|
||||||
break;
|
break;
|
||||||
case 0x2:
|
case 0x2:
|
||||||
mixed_mode = 0;
|
mixed_mode = 0;
|
||||||
|
@ -132,11 +132,9 @@ u8 video_io_read (u16 addr)
|
||||||
break;
|
break;
|
||||||
case 0x6:
|
case 0x6:
|
||||||
hires = 0;
|
hires = 0;
|
||||||
mixed_mode = 0;
|
|
||||||
break;
|
break;
|
||||||
case 0x7:
|
case 0x7:
|
||||||
hires = 1;
|
hires = 1;
|
||||||
mixed_mode = 0;
|
|
||||||
break;
|
break;
|
||||||
// Annunciators
|
// Annunciators
|
||||||
case 0x8:
|
case 0x8:
|
||||||
|
@ -176,12 +174,13 @@ void draw_lores_scr (u16 *map)
|
||||||
*map++ = col_a << 8 | col_a;
|
*map++ = col_a << 8 | col_a;
|
||||||
*map++ = col_a << 8 | col_a;
|
*map++ = col_a << 8 | col_a;
|
||||||
*map++ = col_a << 8 | col_a;
|
*map++ = col_a << 8 | col_a;
|
||||||
*map++ = col_b << 8 | col_a;
|
*map++ = col_a << 8 | col_a;
|
||||||
|
*map++ = col_b << 8 | col_b;
|
||||||
*map++ = col_b << 8 | col_b;
|
*map++ = col_b << 8 | col_b;
|
||||||
*map++ = col_b << 8 | col_b;
|
*map++ = col_b << 8 | col_b;
|
||||||
*map++ = col_b << 8 | col_b;
|
*map++ = col_b << 8 | col_b;
|
||||||
}
|
}
|
||||||
map += 232/2;
|
map += 192/2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,24 +319,25 @@ void video_draw ()
|
||||||
|
|
||||||
int video_set_scale (int mode)
|
int video_set_scale (int mode)
|
||||||
{
|
{
|
||||||
int scale_x;
|
int scaleg_x, scalet_x;
|
||||||
int scale_y;
|
int scale_y;
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
default:
|
default:
|
||||||
case 0:
|
case 0:
|
||||||
scale_x = floatToFixed(1., 8);
|
scaleg_x = scalet_x = floatToFixed(1., 8);
|
||||||
scale_y = floatToFixed(1., 8);
|
scale_y = floatToFixed(1., 8);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
// 280 / 256 = 1.09
|
// 280 / 256 = 1.09
|
||||||
scale_x = floatToFixed(1.09, 8);
|
scaleg_x = floatToFixed(1.09, 8);
|
||||||
|
scalet_x = floatToFixed(1.25, 8);
|
||||||
scale_y = floatToFixed(1., 8);
|
scale_y = floatToFixed(1., 8);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bgSetScale(gfx_bg, scale_x, scale_y);
|
bgSetScale(gfx_bg, scaleg_x, scale_y);
|
||||||
bgSetScale(text_bg, scale_x, scale_y);
|
bgSetScale(text_bg, scalet_x, scale_y);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user