Updated readme
This commit is contained in:
parent
5c7c9d065f
commit
8b8430bf13
47
README.md
47
README.md
|
@ -15,8 +15,8 @@ For more detail, check out this post about how I started the project:
|
||||||
[Making a 68000 Emulator in Rust](https://jabberwocky.ca/posts/2021-11-making_an_emulator.html)
|
[Making a 68000 Emulator in Rust](https://jabberwocky.ca/posts/2021-11-making_an_emulator.html)
|
||||||
|
|
||||||
|
|
||||||
Running
|
Computie
|
||||||
-------
|
--------
|
||||||
|
|
||||||
For Computie, it can do everything the 68k-SMT board can do, including run the
|
For Computie, it can do everything the 68k-SMT board can do, including run the
|
||||||
monitor program and load the Computie OS kernel and boot it from the
|
monitor program and load the Computie OS kernel and boot it from the
|
||||||
|
@ -32,6 +32,9 @@ host, and set up host routing. The exact commands in
|
||||||
`src/machines/computie.rs` might need to be adjusted to work on different
|
`src/machines/computie.rs` might need to be adjusted to work on different
|
||||||
hosts.
|
hosts.
|
||||||
|
|
||||||
|
TRS-80
|
||||||
|
------
|
||||||
|
|
||||||
For the TRS-80, it can run Level I or Level II Basic, but it doesn't yet
|
For the TRS-80, it can run Level I or Level II Basic, but it doesn't yet
|
||||||
support a cassette tape drive or floppy drive. I haven't tested it that
|
support a cassette tape drive or floppy drive. I haven't tested it that
|
||||||
thoroughly either, so any help with it would be welcome. I mostly made it to
|
thoroughly either, so any help with it would be welcome. I mostly made it to
|
||||||
|
@ -40,16 +43,50 @@ Genesis emulator. The frontend uses the
|
||||||
[`minifb`](https://github.com/emoon/rust_minifb) rust crate to open a window
|
[`minifb`](https://github.com/emoon/rust_minifb) rust crate to open a window
|
||||||
and render the characters to screen, as well as accept input from the keyboard.
|
and render the characters to screen, as well as accept input from the keyboard.
|
||||||
```
|
```
|
||||||
cargo run -p moa-minifb --release --bin moa-trs-80 --
|
cargo run -p moa-minifb --release --bin moa-trs-80
|
||||||
```
|
```
|
||||||
By default it will start Level I Basic. To use the other rom, add the option
|
By default it will start Level I Basic. To use the other rom, add the option
|
||||||
`--rom binaries/trs80/level2.rom`
|
`--rom binaries/trs80/level2.rom`
|
||||||
|
|
||||||
The Genesis emulator is a work in progress but can be run with:
|
![alt text](images/trs-80-level-ii-basic.png)
|
||||||
|
|
||||||
|
Sega Genesis/MegaDrive
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
It can be run with:
|
||||||
```
|
```
|
||||||
cargo run -p moa-minifb --release --bin moa-genesis
|
cargo run -p moa-minifb --release --bin moa-genesis -- <ROM FILE>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The Genesis emulator is a work in progress. It can play a few games but some
|
||||||
|
games won't run because the bank switching for the Z80 coprocessor is not
|
||||||
|
working yet, and some games will hang waiting for the Z80 to respond. For the
|
||||||
|
video processor, the window layer is not drawn and the layer priority is not
|
||||||
|
handled. The horizontal scroll also doesn't work on a line-by-line basis so it
|
||||||
|
tends to be quite jerky as you move, with the sprites and cells misaligned
|
||||||
|
until you've moved one complete cell over (8x8 pixels).
|
||||||
|
|
||||||
|
On the Sonic 2 title screen, the colours for Tails are wonky, probably because
|
||||||
|
there's some trickery going on to get more than 16 colours per line, but the
|
||||||
|
emulator currently renders the whole frame at once instead of line by line, so
|
||||||
|
changes that should be made while the screen is updating don't show up
|
||||||
|
![alt text](images/sega-genesis-sonic2-title.png)
|
||||||
|
|
||||||
|
In the first one, it's mostly working but the bottom of the clouds should be a
|
||||||
|
different colour. Highlight/Shadow colours are not yet supported
|
||||||
|
![alt text](sega-genesis-sonic2-start.png)
|
||||||
|
|
||||||
|
I'm not yet sure why the clouds in the background are cut off suddenly
|
||||||
|
![alt text](sega-genesis-sonic2-bridge.png)
|
||||||
|
|
||||||
|
There are some graphics glitches in Earthworm Jim, but it's almost playable if it
|
||||||
|
wasn't for the 'jump' button, which only makes him jump a few pixels
|
||||||
|
![alt text](sega-genesis-earthworm-jim.png)
|
||||||
|
|
||||||
|
|
||||||
|
General Options
|
||||||
|
---------------
|
||||||
|
|
||||||
By default, the minifb frontend will scale the window by 2. This can be
|
By default, the minifb frontend will scale the window by 2. This can be
|
||||||
changed with the `--scale [1,2,4]` option.
|
changed with the `--scale [1,2,4]` option.
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,20 @@
|
||||||
|
|
||||||
|
|
||||||
use moa_minifb;
|
use moa_minifb;
|
||||||
use moa::machines::genesis::build_genesis;
|
use moa::machines::genesis::{build_genesis, SegaGenesisOptions};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let matches = moa_minifb::new("Sega Genesis/Mega Drive Emulator")
|
let matches = moa_minifb::new("Sega Genesis/Mega Drive Emulator")
|
||||||
|
.arg("<ROM> 'ROM file to load (must be flat binary)'")
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
|
let mut options = SegaGenesisOptions::new();
|
||||||
|
if let Some(filename) = matches.value_of("ROM") {
|
||||||
|
options.rom = filename.to_string();
|
||||||
|
}
|
||||||
|
|
||||||
moa_minifb::run(matches, |frontend| {
|
moa_minifb::run(matches, |frontend| {
|
||||||
build_genesis(frontend)
|
build_genesis(frontend, options)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.8 KiB |
|
@ -14,15 +14,29 @@ use crate::peripherals::genesis;
|
||||||
use crate::host::traits::{Host};
|
use crate::host::traits::{Host};
|
||||||
|
|
||||||
|
|
||||||
pub fn build_genesis<H: Host>(host: &mut H) -> Result<System, Error> {
|
pub struct SegaGenesisOptions {
|
||||||
|
pub rom: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SegaGenesisOptions {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
rom: "".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build_genesis<H: Host>(host: &mut H, options: SegaGenesisOptions) -> Result<System, Error> {
|
||||||
let mut system = System::new();
|
let mut system = System::new();
|
||||||
|
|
||||||
|
let mut rom = MemoryBlock::load(&options.rom).unwrap();
|
||||||
//let mut rom = MemoryBlock::load("binaries/genesis/GenTestV3.0.bin").unwrap();
|
//let mut rom = MemoryBlock::load("binaries/genesis/GenTestV3.0.bin").unwrap();
|
||||||
//let mut rom = MemoryBlock::load("binaries/genesis/HDRV_Genesis_Test_v1_4.bin").unwrap();
|
//let mut rom = MemoryBlock::load("binaries/genesis/HDRV_Genesis_Test_v1_4.bin").unwrap();
|
||||||
//let mut rom = MemoryBlock::load("binaries/genesis/ComradeOj's tiny demo.bin").unwrap();
|
//let mut rom = MemoryBlock::load("binaries/genesis/ComradeOj's tiny demo.bin").unwrap();
|
||||||
|
//let mut rom = MemoryBlock::load("binaries/genesis/Digital Rain demo.bin").unwrap();
|
||||||
//let mut rom = MemoryBlock::load("binaries/genesis/Sonic The Hedgehog (W) (REV 00) [!].bin").unwrap();
|
//let mut rom = MemoryBlock::load("binaries/genesis/Sonic The Hedgehog (W) (REV 00) [!].bin").unwrap();
|
||||||
//let mut rom = MemoryBlock::load("binaries/genesis/Sonic The Hedgehog (W) (REV 01) [!].bin").unwrap();
|
//let mut rom = MemoryBlock::load("binaries/genesis/Sonic The Hedgehog (W) (REV 01) [!].bin").unwrap();
|
||||||
let mut rom = MemoryBlock::load("binaries/genesis/Sonic the Hedgehog 2 (JUE) [!].bin").unwrap();
|
//let mut rom = MemoryBlock::load("binaries/genesis/Sonic the Hedgehog 2 (JUE) [!].bin").unwrap();
|
||||||
//let mut rom = MemoryBlock::load("binaries/genesis/Sonic the Hedgehog 3 (U) [!].bin").unwrap();
|
//let mut rom = MemoryBlock::load("binaries/genesis/Sonic the Hedgehog 3 (U) [!].bin").unwrap();
|
||||||
//let mut rom = MemoryBlock::load("binaries/genesis/Earthworm Jim (U) [h1].bin").unwrap();
|
//let mut rom = MemoryBlock::load("binaries/genesis/Earthworm Jim (U) [h1].bin").unwrap();
|
||||||
//let mut rom = MemoryBlock::load("binaries/genesis/Home Alone (beta).bin").unwrap();
|
//let mut rom = MemoryBlock::load("binaries/genesis/Home Alone (beta).bin").unwrap();
|
||||||
|
@ -50,7 +64,7 @@ pub fn build_genesis<H: Host>(host: &mut H) -> Result<System, Error> {
|
||||||
let bus_request = coproc.bus_request.clone();
|
let bus_request = coproc.bus_request.clone();
|
||||||
|
|
||||||
system.add_addressable_device(0x00a00000, coproc_mem)?;
|
system.add_addressable_device(0x00a00000, coproc_mem)?;
|
||||||
//system.add_device("coproc", wrap_transmutable(coproc))?;
|
system.add_device("coproc", wrap_transmutable(coproc))?;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,27 +79,7 @@ pub fn build_genesis<H: Host>(host: &mut H) -> Result<System, Error> {
|
||||||
system.add_peripheral("vdp", 0x00c00000, wrap_transmutable(vdp)).unwrap();
|
system.add_peripheral("vdp", 0x00c00000, wrap_transmutable(vdp)).unwrap();
|
||||||
|
|
||||||
|
|
||||||
// TODO this is temporarily a 68010 because GenTest tests the CPU type by relying on the illegal instruction
|
let mut cpu = M68k::new(M68kType::MC68000, 7_670_454, BusPort::new(0, 24, 16, system.bus.clone()));
|
||||||
// exception which is bypassed to Error and I don't want to un-bypass yet while testing
|
|
||||||
let mut cpu = M68k::new(M68kType::MC68010, 7_670_454, BusPort::new(0, 24, 16, system.bus.clone()));
|
|
||||||
|
|
||||||
//cpu.enable_tracing();
|
|
||||||
//cpu.add_breakpoint(0x206);
|
|
||||||
//cpu.add_breakpoint(0x1dd0); // Sonic: some kind of palette fading function
|
|
||||||
//cpu.add_breakpoint(0x16ee);
|
|
||||||
//cpu.decoder.dump_disassembly(&mut system, 0x206, 0x2000);
|
|
||||||
|
|
||||||
//cpu.add_breakpoint(0x16a0e);
|
|
||||||
//cpu.add_breakpoint(0x16812);
|
|
||||||
//cpu.add_breakpoint(0x166ec);
|
|
||||||
//cpu.add_breakpoint(0x13e18);
|
|
||||||
//cpu.add_breakpoint(0x16570);
|
|
||||||
//cpu.add_breakpoint(0x1714);
|
|
||||||
|
|
||||||
//cpu.add_breakpoint(0x43c2);
|
|
||||||
|
|
||||||
//cpu.add_breakpoint(0x21a);
|
|
||||||
|
|
||||||
system.add_interruptable_device("cpu", wrap_transmutable(cpu)).unwrap();
|
system.add_interruptable_device("cpu", wrap_transmutable(cpu)).unwrap();
|
||||||
|
|
||||||
Ok(system)
|
Ok(system)
|
||||||
|
|
|
@ -418,9 +418,8 @@ impl Ym7101State {
|
||||||
|
|
||||||
for cell_y in 0..cells_v {
|
for cell_y in 0..cells_v {
|
||||||
for cell_x in 0..cells_h {
|
for cell_x in 0..cells_h {
|
||||||
let pattern_addr = self.get_pattern_addr(cell_table, cell_x as usize, cell_y as usize);
|
let pattern_w = read_beu16(&self.vram[self.get_pattern_addr(cell_table, cell_x as usize, cell_y as usize)..]);
|
||||||
let pattern = read_beu16(&self.vram[pattern_addr..]);
|
self.draw_pattern(frame, pattern_w, (cell_x << 3) as u32, (cell_y << 3) as u32);
|
||||||
self.draw_pattern(frame, pattern, (cell_x << 3) as u32, (cell_y << 3) as u32);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue