mirror of
https://github.com/mre/mos6502.git
synced 2024-06-16 05:29:31 +00:00
Merge efb1c3a3b8
into 65817524a2
This commit is contained in:
commit
885285e49e
33
examples/asm/euclid/euclid.ca65
Normal file
33
examples/asm/euclid/euclid.ca65
Normal file
|
@ -0,0 +1,33 @@
|
|||
; euclid.ca65
|
||||
; A program to find the greatest common divisor of two numbers
|
||||
|
||||
.ORG $1000
|
||||
|
||||
; .algo
|
||||
LDA $00 ; Load from F to A
|
||||
; .algo_
|
||||
SEC ; Set carry flag
|
||||
SBC $01 ; Subtract S from the number in A (from F)
|
||||
BEQ end ; Jump to .end if the difference is zero
|
||||
BMI swap ; Jump to .swap if the difference is negative
|
||||
STA $00 ; Load A to F
|
||||
JMP algo_ ; Jump to .algo_
|
||||
|
||||
; .end
|
||||
end:
|
||||
LDA $00 ; Load from F to A
|
||||
BRK ; Break (end program)
|
||||
|
||||
; .swap
|
||||
swap:
|
||||
LDX $00 ; Load F to X
|
||||
LDY $01 ; Load S to Y
|
||||
STX $01 ; Store X to S
|
||||
STY $00 ; Store Y to F
|
||||
JMP algo ; Jump to .algo
|
||||
|
||||
algo:
|
||||
JMP algo ; Infinite loop to prevent program from ending
|
||||
|
||||
algo_:
|
||||
JMP algo_ ; Infinite loop to prevent program from ending
|
BIN
examples/asm/functional_test/6502_functional_test.bin
Normal file
BIN
examples/asm/functional_test/6502_functional_test.bin
Normal file
Binary file not shown.
6125
examples/asm/functional_test/6502_functional_test.ca65
Normal file
6125
examples/asm/functional_test/6502_functional_test.ca65
Normal file
File diff suppressed because it is too large
Load Diff
3
examples/asm/functional_test/Makefile
Normal file
3
examples/asm/functional_test/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
build:
|
||||
ca65 -g 6502_functional_test.ca65
|
||||
ld65 -C ../linker.cfg -o 6502_functional_test.bin -Ln labels.dbg 6502_functional_test.o
|
37
examples/asm/functional_test/README.md
Normal file
37
examples/asm/functional_test/README.md
Normal file
|
@ -0,0 +1,37 @@
|
|||
# 6502 Functional Test
|
||||
|
||||
This is a test suite for 6502/65C02/65C816 processors. It contains a plethora of
|
||||
tests, which covers all documented opcodes.
|
||||
|
||||
Note that the binary was not built from the source code in the repository, but
|
||||
pre-built binaries were used instead. That is because the source code is not
|
||||
compatible with the assembler used by the [cc65](https://cc65.github.io/cc65/)
|
||||
toolchain.
|
||||
|
||||
## Building
|
||||
|
||||
```bash
|
||||
make build
|
||||
```
|
||||
|
||||
This will create a `6502_functional_test.bin` file in the `build` directory,
|
||||
which the emulator will load.
|
||||
|
||||
## Running
|
||||
|
||||
Then, from the root of the repository, run:
|
||||
|
||||
```bash
|
||||
cargo run --release --example functional
|
||||
```
|
||||
|
||||
## Credits
|
||||
|
||||
Taken from
|
||||
https://github.com/amb5l/6502_65C02_functional_tests
|
||||
which is a CA65-compatible port of
|
||||
https://github.com/Klaus2m5/6502_65C02_functional_tests
|
||||
|
||||
The original source code was written by Klaus Dormann, and is licensed under
|
||||
the GPL-3.0 license.
|
||||
```
|
369
examples/asm/functional_test/labels.dbg
Normal file
369
examples/asm/functional_test/labels.dbg
Normal file
|
@ -0,0 +1,369 @@
|
|||
al 000000 .__RAM_FILEOFFS__
|
||||
al 00017B .__RAM_LAST__
|
||||
al 000200 .__RAM_SIZE__
|
||||
al 000100 .__RAM_START__
|
||||
al 000000 .__ZP_FILEOFFS__
|
||||
al 00005C .__ZP_LAST__
|
||||
al 000100 .__ZP_SIZE__
|
||||
al 000000 .__ZP_START__
|
||||
al 0036A7 .break2
|
||||
al 003655 .res_trap
|
||||
al 00364F .nmi_trap
|
||||
al 0035D2 .ptr_ind_ret
|
||||
al 0035D9 .test_ind
|
||||
al 00346A .ckad1
|
||||
al 0032FF .dec_rti_ret
|
||||
al 003308 .bin_rti_ret
|
||||
al 0032A4 .tdad6
|
||||
al 0032B8 .tdad7
|
||||
al 00327B .tdad4
|
||||
al 003280 .tdad5
|
||||
al 00325F .tdad2
|
||||
al 003261 .tdad3
|
||||
al 00324F .tdad1
|
||||
al 003322 .chkdad
|
||||
al 00323D .tdad
|
||||
al 0031EC .tadd1
|
||||
al 003455 .chkadd
|
||||
al 0031DA .tadd
|
||||
al 003195 .tora15
|
||||
al 003179 .tora14
|
||||
al 00315B .tora13
|
||||
al 00313B .tora12
|
||||
al 00311C .tora11
|
||||
al 0030FF .tora10
|
||||
al 0030E2 .tora9
|
||||
al 0030C5 .tora8
|
||||
al 0030A9 .tora7
|
||||
al 00308D .tora6
|
||||
al 00306B .tora5
|
||||
al 003049 .tora4
|
||||
al 003029 .tora3
|
||||
al 003009 .tora2
|
||||
al 002FE7 .tora1
|
||||
al 002FC5 .tora
|
||||
al 002F9D .teor15
|
||||
al 002F81 .teor14
|
||||
al 002F63 .teor13
|
||||
al 002F43 .teor12
|
||||
al 002F24 .teor11
|
||||
al 002F07 .teor10
|
||||
al 002EEA .teor9
|
||||
al 002ECD .teor8
|
||||
al 002EB1 .teor7
|
||||
al 002E95 .teor6
|
||||
al 002E73 .teor5
|
||||
al 002E51 .teor4
|
||||
al 002E31 .teor3
|
||||
al 002E11 .teor2
|
||||
al 002DEF .teor1
|
||||
al 002DCD .teor
|
||||
al 002DA5 .tand15
|
||||
al 002D89 .tand14
|
||||
al 002D6B .tand13
|
||||
al 002D4B .tand12
|
||||
al 002D2C .tand11
|
||||
al 002D0F .tand10
|
||||
al 002CF2 .tand9
|
||||
al 002CD5 .tand8
|
||||
al 002CB9 .tand7
|
||||
al 002C9D .tand6
|
||||
al 002C7B .tand5
|
||||
al 002C59 .tand4
|
||||
al 002C39 .tand3
|
||||
al 002C19 .tand2
|
||||
al 002BF7 .tand1
|
||||
al 002BD5 .tand
|
||||
al 002BC7 .tdec17
|
||||
al 002B9E .tdec16
|
||||
al 002B97 .tinc17
|
||||
al 002B72 .tinc16
|
||||
al 002B6E .tdec7
|
||||
al 002B45 .tdec6
|
||||
al 002B3E .tinc7
|
||||
al 002B19 .tinc6
|
||||
al 002B09 .tdec15
|
||||
al 002AE4 .tdec14
|
||||
al 002ADD .tinc15
|
||||
al 002ABC .tinc14
|
||||
al 002AB8 .tdec5
|
||||
al 002A93 .tdec4
|
||||
al 002A8C .tinc5
|
||||
al 002A6B .tinc4
|
||||
al 002A5B .tdec13
|
||||
al 002A35 .tdec12
|
||||
al 002A2D .tinc13
|
||||
al 002A0B .tinc12
|
||||
al 002A04 .tdec3
|
||||
al 0029DE .tdec2
|
||||
al 0029D6 .tinc3
|
||||
al 0029B4 .tinc2
|
||||
al 0029A1 .tdec11
|
||||
al 00297E .tdec10
|
||||
al 002977 .tinc11
|
||||
al 002958 .tinc10
|
||||
al 002952 .tdec1
|
||||
al 00292F .tdec
|
||||
al 002928 .tinc1
|
||||
al 002909 .tinc
|
||||
al 0028D7 .trorc9
|
||||
al 0028B5 .trorc8
|
||||
al 002893 .tror9
|
||||
al 002871 .tror8
|
||||
al 00284F .trolc9
|
||||
al 00282D .trolc8
|
||||
al 00280B .trol9
|
||||
al 0027E9 .trol8
|
||||
al 0027C7 .tlsr9
|
||||
al 0027A5 .tlsr8
|
||||
al 002783 .tasl9
|
||||
al 002761 .tasl8
|
||||
al 002736 .trorc7
|
||||
al 002717 .trorc6
|
||||
al 0026F8 .tror7
|
||||
al 0026D9 .tror6
|
||||
al 0026BA .trolc7
|
||||
al 00269B .trolc6
|
||||
al 00267C .trol7
|
||||
al 00265D .trol6
|
||||
al 00263E .tlsr7
|
||||
al 00261F .tlsr6
|
||||
al 002600 .tasl7
|
||||
al 0025E1 .tasl6
|
||||
al 0025B3 .trorc5
|
||||
al 002591 .trorc4
|
||||
al 00256F .tror5
|
||||
al 00254D .tror4
|
||||
al 00252B .trolc5
|
||||
al 002509 .trolc4
|
||||
al 0024E7 .trol5
|
||||
al 0024C5 .trol4
|
||||
al 0024A3 .tlsr5
|
||||
al 002481 .tlsr4
|
||||
al 00245F .tasl5
|
||||
al 00243D .tasl4
|
||||
al 002412 .trorc3
|
||||
al 0023F3 .trorc2
|
||||
al 0023D4 .tror3
|
||||
al 0023B5 .tror2
|
||||
al 002396 .trolc3
|
||||
al 002377 .trolc2
|
||||
al 002358 .trol3
|
||||
al 002339 .trol2
|
||||
al 00231A .tlsr3
|
||||
al 0022FB .tlsr2
|
||||
al 0022DC .tasl3
|
||||
al 0022BD .tasl2
|
||||
al 002297 .trorc1
|
||||
al 00227D .trorc
|
||||
al 002263 .tror1
|
||||
al 002249 .tror
|
||||
al 00222F .trolc1
|
||||
al 002215 .trolc
|
||||
al 0021FB .trol1
|
||||
al 0021E1 .trol
|
||||
al 0021C7 .tlsr1
|
||||
al 0021AD .tlsr
|
||||
al 002193 .tasl1
|
||||
al 002179 .tasl
|
||||
al 00173E .tstay6
|
||||
al 00172F .tlday6
|
||||
al 00171C .tstay5
|
||||
al 00170E .tlday5
|
||||
al 0016FD .tstay4
|
||||
al 0016ED .tlday4
|
||||
al 0016D2 .tstax1
|
||||
al 0016C4 .tldax7
|
||||
al 0016B8 .tldax6
|
||||
al 001699 .tstay2
|
||||
al 001674 .tldax5
|
||||
al 00164F .tldax4
|
||||
al 00163A .tstay1
|
||||
al 001617 .tlday3
|
||||
al 0015F6 .tlday2
|
||||
al 0015E3 .tstay
|
||||
al 0015BF .tlday1
|
||||
al 00159D .tlday
|
||||
al 001574 .tstax
|
||||
al 001551 .tldax3
|
||||
al 001530 .tldax2
|
||||
al 00150E .tldax1
|
||||
al 0014EC .tldax
|
||||
al 000ED7 .tsty1
|
||||
al 000EC9 .tldy5
|
||||
al 000EBC .tldy4
|
||||
al 000E93 .tsty
|
||||
al 000E6E .tldy3
|
||||
al 000E4B .tldy2
|
||||
al 000E28 .tldy1
|
||||
al 000E05 .tldy
|
||||
al 000DDE .tstx1
|
||||
al 000DD0 .tldx5
|
||||
al 000DC3 .tldx4
|
||||
al 000D98 .tstx
|
||||
al 000D72 .tldx3
|
||||
al 000D4E .tldx2
|
||||
al 000D2B .tldx1
|
||||
al 000D08 .tldx
|
||||
al 0008CF .brk_ret1
|
||||
al 00365D .irq_trap
|
||||
al 0008A0 .brk_ret0
|
||||
al 00360F .test_jsr
|
||||
al 000828 .ind_ret
|
||||
al 0035D0 .ptr_tst_ind
|
||||
al 0007F6 .test_near
|
||||
al 0007D3 .far_ret
|
||||
al 0035A2 .test_far
|
||||
al 00063A .brvc8
|
||||
al 000637 .brvc7
|
||||
al 000633 .brvc6
|
||||
al 000630 .brvc5
|
||||
al 00062C .brvc4
|
||||
al 000629 .brvc3
|
||||
al 000625 .brvc2
|
||||
al 000622 .brvc1
|
||||
al 00061A .brpl8
|
||||
al 000617 .brpl7
|
||||
al 000613 .brpl6
|
||||
al 000610 .brpl5
|
||||
al 00060C .brpl4
|
||||
al 000609 .brpl3
|
||||
al 000605 .brpl2
|
||||
al 000602 .brpl1
|
||||
al 0005FA .brcc8
|
||||
al 0005F7 .brcc7
|
||||
al 0005F3 .brcc6
|
||||
al 0005F0 .brcc5
|
||||
al 0005EC .brcc4
|
||||
al 0005E9 .brcc3
|
||||
al 0005E5 .brcc2
|
||||
al 0005E2 .brcc1
|
||||
al 0005DA .brzc8
|
||||
al 0005D7 .brzc7
|
||||
al 0005D3 .brzc6
|
||||
al 0005D0 .brzc5
|
||||
al 0005CC .brzc4
|
||||
al 0005C9 .brzc3
|
||||
al 0005C5 .brzc2
|
||||
al 0005C2 .brzc1
|
||||
al 0005BA .brvs8
|
||||
al 0005B7 .brvs7
|
||||
al 0005B3 .brvs6
|
||||
al 0005B0 .brvs5
|
||||
al 0005AC .brvs4
|
||||
al 0005A9 .brvs3
|
||||
al 0005A5 .brvs2
|
||||
al 0005A2 .brvs1
|
||||
al 00059A .brmi8
|
||||
al 000597 .brmi7
|
||||
al 000593 .brmi6
|
||||
al 000590 .brmi5
|
||||
al 00058C .brmi4
|
||||
al 000589 .brmi3
|
||||
al 000585 .brmi2
|
||||
al 000582 .brmi1
|
||||
al 00057A .brcs8
|
||||
al 000577 .brcs7
|
||||
al 000573 .brcs6
|
||||
al 000570 .brcs5
|
||||
al 00056C .brcs4
|
||||
al 000569 .brcs3
|
||||
al 000565 .brcs2
|
||||
al 000562 .brcs1
|
||||
al 00055A .brzs8
|
||||
al 000557 .brzs7
|
||||
al 000553 .brzs6
|
||||
al 000550 .brzs5
|
||||
al 00054C .brzs4
|
||||
al 000549 .brzs3
|
||||
al 000545 .brzs2
|
||||
al 000542 .brzs1
|
||||
al 000534 .br14
|
||||
al 000523 .br13
|
||||
al 00051E .br12
|
||||
al 000519 .br11
|
||||
al 000531 .nbr14
|
||||
al 00052E .nbr13
|
||||
al 00052B .nbr12
|
||||
al 000528 .nbr11
|
||||
al 0004F8 .br4
|
||||
al 0004E7 .br3
|
||||
al 0004E2 .br2
|
||||
al 0004DD .br1
|
||||
al 0004F5 .nbr4
|
||||
al 0004F2 .nbr3
|
||||
al 0004EF .nbr2
|
||||
al 0004EC .nbr1
|
||||
al 000458 .test_bne
|
||||
al 00042A .psb_back
|
||||
al 000439 .psb_fwok
|
||||
al 00041B .psb_forw
|
||||
al 00040F .psb_bwok
|
||||
al 000434 .psb_test
|
||||
al 000400 .start
|
||||
al 00027B .data_bss_end
|
||||
al 000277 .absflo
|
||||
al 000273 .absrlo
|
||||
al 00026F .absEOa
|
||||
al 00026B .absANa
|
||||
al 000267 .absORa
|
||||
al 000256 .fINC
|
||||
al 000251 .rINC
|
||||
al 00024B .fRORc
|
||||
al 000245 .fROR
|
||||
al 000245 .fLSR
|
||||
al 00023F .fROLc
|
||||
al 000239 .fROL
|
||||
al 000239 .fASL
|
||||
al 000233 .rRORc
|
||||
al 00022D .rROR
|
||||
al 00022D .rLSR
|
||||
al 000227 .rROLc
|
||||
al 000221 .rROL
|
||||
al 000221 .rASL
|
||||
al 00021D .fLDx
|
||||
al 000215 .ex_sbci
|
||||
al 000212 .ex_adci
|
||||
al 00020F .ex_orai
|
||||
al 00020C .ex_eori
|
||||
al 000209 .ex_andi
|
||||
al 000209 .data_bss
|
||||
al 000201 .ram_chksm
|
||||
al 000200 .test_case
|
||||
al 00005C .zp_bss_end
|
||||
al 00005A .sbiy2
|
||||
al 000058 .adiy2
|
||||
al 000204 .sba2
|
||||
al 000056 .sbi2
|
||||
al 000203 .ada2
|
||||
al 000054 .adi2
|
||||
al 00025B .absOR
|
||||
al 00004C .indOR
|
||||
al 000263 .absEO
|
||||
al 000044 .indEO
|
||||
al 00025F .absAN
|
||||
al 00003C .indAN
|
||||
al 00003A .inwt
|
||||
al 000203 .abst
|
||||
al 000032 .indt
|
||||
al 000030 .inw1
|
||||
al 00021C .abs7f
|
||||
al 000218 .abs1
|
||||
al 000026 .ind1
|
||||
al 000022 .zpEO
|
||||
al 00001E .zpAN
|
||||
al 00001A .zpOR
|
||||
al 000019 .zp7f
|
||||
al 000015 .zp1
|
||||
al 000013 .zps
|
||||
al 000013 .zp_bss
|
||||
al 000012 .sb2
|
||||
al 000011 .adrf
|
||||
al 000010 .adrh
|
||||
al 00000F .adrl
|
||||
al 00000E .ad2
|
||||
al 00000D .ad1
|
||||
al 00000C .adfc
|
||||
al 00000C .zpt
|
||||
al 00000B .irq_x
|
||||
al 00000A .irq_a
|
68
examples/functional.rs
Normal file
68
examples/functional.rs
Normal file
|
@ -0,0 +1,68 @@
|
|||
use mos6502::cpu;
|
||||
use mos6502::memory::Bus;
|
||||
use mos6502::memory::Memory;
|
||||
use std::collections::HashMap;
|
||||
use std::fs::{read, File};
|
||||
use std::io::{BufRead, BufReader};
|
||||
|
||||
fn main() {
|
||||
// Load the binary file from disk
|
||||
let program = match read("examples/asm/functional_test/6502_functional_test.bin") {
|
||||
Ok(data) => data,
|
||||
Err(err) => {
|
||||
println!("Error reading functional test: {}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let mut cpu = cpu::CPU::new(Memory::new());
|
||||
|
||||
cpu.memory.set_bytes(0x00, &program);
|
||||
cpu.registers.program_counter = 0x400;
|
||||
|
||||
let labels =
|
||||
load_labels("examples/asm/functional_test/labels.dbg").expect("Could not load labels");
|
||||
|
||||
// run step-by-step
|
||||
let mut old_pc = cpu.registers.program_counter;
|
||||
while cpu.registers.program_counter != 0x3468 {
|
||||
// Use `fetch_next_and_decode` instead of
|
||||
// `single_step` to see the decoded instruction
|
||||
if let Some(decoded_instr) = cpu.fetch_next_and_decode() {
|
||||
let label = labels.get(&cpu.registers.program_counter);
|
||||
match label {
|
||||
Some(name) => println!("{}: {}", name, decoded_instr),
|
||||
None => println!("{}", decoded_instr),
|
||||
}
|
||||
cpu.execute_instruction(decoded_instr);
|
||||
}
|
||||
cpu.single_step();
|
||||
println!("{cpu:?}");
|
||||
|
||||
if cpu.registers.program_counter == old_pc {
|
||||
println!("Infinite loop detected!");
|
||||
break;
|
||||
}
|
||||
|
||||
old_pc = cpu.registers.program_counter;
|
||||
}
|
||||
}
|
||||
|
||||
fn load_labels(path: &str) -> std::io::Result<HashMap<u16, String>> {
|
||||
let mut labels = HashMap::new();
|
||||
let file = File::open(path)?;
|
||||
let reader = BufReader::new(file);
|
||||
|
||||
for line in reader.lines() {
|
||||
let line = line?;
|
||||
let parts: Vec<&str> = line.split(' ').collect();
|
||||
if parts.len() < 3 {
|
||||
continue;
|
||||
}
|
||||
let address = u16::from_str_radix(parts[1], 16).unwrap();
|
||||
let label = parts[2].to_owned();
|
||||
labels.insert(address, label);
|
||||
}
|
||||
|
||||
Ok(labels)
|
||||
}
|
13
src/cpu.rs
13
src/cpu.rs
|
@ -175,14 +175,15 @@ impl<M: Bus> CPU<M> {
|
|||
self.registers.program_counter =
|
||||
self.registers.program_counter.wrapping_add(num_bytes);
|
||||
|
||||
Some((instr, am_out))
|
||||
Some(DecodedInstr(instr, am_out))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn execute_instruction(&mut self, decoded_instr: DecodedInstr) {
|
||||
match decoded_instr {
|
||||
pub fn execute_instruction<T: Into<DecodedInstr>>(&mut self, decoded_instr: T) {
|
||||
let decoded_instr = decoded_instr.into();
|
||||
match (decoded_instr.0, decoded_instr.1) {
|
||||
(Instruction::ADC, OpInput::UseImmediate(val)) => {
|
||||
debug!("add with carry immediate: {}", val);
|
||||
self.add_with_carry(val as i8);
|
||||
|
@ -988,11 +989,7 @@ impl<M: Bus> CPU<M> {
|
|||
|
||||
impl<M: Bus> core::fmt::Debug for CPU<M> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"CPU Dump:\n\nAccumulator: {}",
|
||||
self.registers.accumulator
|
||||
)
|
||||
write!(f, "CPU {{ registers: {:?}", self.registers)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
// PC | program counter
|
||||
//
|
||||
|
||||
use core::fmt::{Display, Error, Formatter};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum Instruction {
|
||||
ADC, // ADd with Carry................ | NV ...ZC A = A + M + C
|
||||
|
@ -105,7 +107,7 @@ pub enum Instruction {
|
|||
TYA, // Transfer Y to Accumulator..... | N. ...Z. A = Y
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum OpInput {
|
||||
UseImplied,
|
||||
UseImmediate(u8),
|
||||
|
@ -113,6 +115,17 @@ pub enum OpInput {
|
|||
UseAddress(u16),
|
||||
}
|
||||
|
||||
impl Display for OpInput {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
|
||||
match self {
|
||||
OpInput::UseImplied => write!(f, ""),
|
||||
OpInput::UseImmediate(v) => write!(f, "#${:02X}", v),
|
||||
OpInput::UseRelative(v) => write!(f, "${:04X}", v),
|
||||
OpInput::UseAddress(v) => write!(f, "${:04X}", v),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum AddressingMode {
|
||||
Accumulator, // 1 LSR A work directly on accumulator
|
||||
|
@ -152,7 +165,46 @@ impl AddressingMode {
|
|||
}
|
||||
}
|
||||
|
||||
pub type DecodedInstr = (Instruction, OpInput);
|
||||
pub struct DecodedInstr(pub Instruction, pub OpInput);
|
||||
|
||||
impl Display for DecodedInstr {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
|
||||
// get addressing mode from instruction (if it exists)
|
||||
let am: Option<AddressingMode> = OPCODES.get(self.0 as usize).and_then(|x| x.map(|x| x.1));
|
||||
|
||||
match self.1 {
|
||||
OpInput::UseImplied => write!(f, "{:?}", self.0),
|
||||
OpInput::UseImmediate(imm) => write!(f, "{:?} #${:02X}", self.0, imm),
|
||||
OpInput::UseRelative(rel) => write!(f, "{:?} ${:04X}", self.0, rel),
|
||||
OpInput::UseAddress(addr) => match am {
|
||||
Some(AddressingMode::Accumulator) => write!(f, "{:?} A", self.0),
|
||||
Some(AddressingMode::Implied) => write!(f, "{:?}", self.0),
|
||||
Some(AddressingMode::Immediate) => write!(f, "{:?} #${:02X}", self.0, addr),
|
||||
Some(AddressingMode::ZeroPage) => write!(f, "{:?} :?${:02X}", self.0, addr),
|
||||
Some(AddressingMode::ZeroPageX) => write!(f, "{:?} :?${:02X},X", self.0, addr),
|
||||
Some(AddressingMode::ZeroPageY) => write!(f, "{:?} :?${:02X},Y", self.0, addr),
|
||||
Some(AddressingMode::Relative) => write!(f, "{:?} ${:04X}", self.0, addr),
|
||||
Some(AddressingMode::Absolute) => write!(f, "{:?} ${:04X}", self.0, addr),
|
||||
Some(AddressingMode::AbsoluteX) => write!(f, "{:?} ${:04X},X", self.0, addr),
|
||||
Some(AddressingMode::AbsoluteY) => write!(f, "{:?} ${:04X},Y", self.0, addr),
|
||||
Some(AddressingMode::Indirect) => write!(f, "{:?} (${:04X})", self.0, addr),
|
||||
Some(AddressingMode::IndexedIndirectX) => {
|
||||
write!(f, "{:?} (${:04X},X)", self.0, addr)
|
||||
}
|
||||
Some(AddressingMode::IndirectIndexedY) => {
|
||||
write!(f, "{:?} (${:04X}),Y", self.0, addr)
|
||||
}
|
||||
None => write!(f, "{:?} {}", self.0, self.1),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(Instruction, OpInput)> for DecodedInstr {
|
||||
fn from((instr, op): (Instruction, OpInput)) -> DecodedInstr {
|
||||
DecodedInstr(instr, op)
|
||||
}
|
||||
}
|
||||
|
||||
pub static OPCODES: [Option<(Instruction, AddressingMode)>; 256] = [
|
||||
/*0x00*/
|
||||
|
|
Loading…
Reference in New Issue
Block a user