Skip to content

Commit

Permalink
Add colors
Browse files Browse the repository at this point in the history
  • Loading branch information
commonkestrel committed Jul 29, 2024
1 parent 40a9ddc commit 848d7d2
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 29 deletions.
15 changes: 11 additions & 4 deletions examples/box.asm
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@define TEXT_BUFFER 0xF800
@define TEXT_BUFFER 0xF000
@define SCREEN_WIDTH 80
@define SCREEN_HEIGHT 25
@define BOX_WIDTH (SCREEN_WIDTH - 2)
Expand All @@ -13,6 +13,8 @@
@define WALL 0xBA
@define DASH 0xCD

@define STYLE 0x0F

/// math = https://github.com/commonkestrel/fateful_math
@include <math/mul.asm>

Expand Down Expand Up @@ -137,14 +139,19 @@ draw_character:
push A, C; save X coordinate and character

push B, 0, SCREEN_WIDTH, 0
call [mul16] ; get Y offset
pop H, L ; get value
call [mul16] ; calculate Y offset
pop H, L ; get value of Y offset

pop C, A ; get character and X coordinate

add16 H, L, (TEXT_BUFFER >> 8), (TEXT_BUFFER & 0xFF) ; Shift address to text-buffer space
add16 H, L, 0, A ; add X to address
add16 H, L, H, L ; double address to account for modifier bytes
add16 H, L, (TEXT_BUFFER >> 8), (TEXT_BUFFER & 0xFF) ; Shift address to text-buffer space

st C

inc H, L
mv C, STYLE
st C

ret
Expand Down
Binary file added misc/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 8 additions & 7 deletions src/emulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ impl State {
fn init(program: Box<[u8]>) -> Self {
State {
pc: 0,
sp: 0xF7FF,
sp: 0xEFFF,
ctrl: Control::default(),
sreg: SReg::empty(),
timer: 0,
Expand Down Expand Up @@ -665,8 +665,8 @@ impl State {
)
} else if cw.contains(ControlWord::LA) {
match self.addr {
0x0000..=0xF7FF => self.mem[self.addr as usize],
0xF800..=0xFFCF => self.text_buffer.get(self.addr - 0xF800),
0x0000..=0xEFFF => self.mem[self.addr as usize],
0xF000..=0xFFCF => self.text_buffer.get(self.addr - 0xF000),
0xFFD0..=0xFFFC => match self.peripherals.get(&((self.addr - 0xFFC0) as u8)) {
Some(periph) => unsafe {
if let Ok(stateful_read) =
Expand Down Expand Up @@ -708,11 +708,11 @@ impl State {

if cw.contains(ControlWord::SA) {
match self.addr {
0x0000..=0xF7FF => {
0x0000..=0xEFFF => {
self.mem[self.addr as usize] = bus;
}
0xF800..=0xFFCF => {
self.text_buffer.set(self.addr - 0xF800, bus);
0xF000..=0xFFCF => {
self.text_buffer.set(self.addr - 0xF000, bus);
}
0xFFD0..=0xFFFC => match self.peripherals.get(&((self.addr - 0xFFC0) as u8)) {
Some(periph) => unsafe {
Expand Down Expand Up @@ -845,9 +845,10 @@ impl State {
self.ctrl.clock = 0;
self.mem.fill(0);
self.sreg = SReg::from_bits_retain(0);
self.sp = 0xF7FF;
self.sp = 0xEFFF;
self.alu.clear();
self.bank.clear();
self.text_buffer.reset();

for periph in self.peripherals.values() {
unsafe {
Expand Down
94 changes: 76 additions & 18 deletions src/emulator/display.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,84 @@
use std::{
cell::UnsafeCell,
marker::PhantomData,
pin::Pin,
sync::atomic::{AtomicU16, AtomicU8, Ordering},
};
use std::pin::Pin;
use std::str::FromStr;

use async_std::task::JoinHandle;
use minifb::{Scale, ScaleMode, WindowOptions};
use minifb::{Icon, Scale, ScaleMode, WindowOptions};

const FONT: &[u8; 1 << 12] = include_bytes!("../vga-font.rom");
const WIDTH: usize = 640;
const HEIGHT: usize = 400;

const COLORS: [u32; 16] = [
0x000000,
0x0000aa,
0x00aa00,
0x00aaaa,
0xaa0000,
0xaa00aa,
0xaa5500,
0xaaaaaa,
0x555555,
0x5555ff,
0x55ff55,
0x55ffff,
0xff5555,
0xff55ff,
0xffff55,
0xffffff,
];

#[derive(Debug)]
pub struct TextBuffer {
data: Pin<Box<[u8; 1 << 12]>>,
chars: Pin<Box<[u8; 1 << 11]>>,
modifiers: Pin<Box<[u8; 1 << 11]>>,
handle: JoinHandle<()>,
}

struct BufferPtr(*const [u8; 1 << 12]);
struct BufferPtr{
chars: *const [u8; 1 << 11],
modifiers: *const [u8; 1 << 11],
}

unsafe impl Send for BufferPtr {}

impl TextBuffer {
pub fn spawn() -> TextBuffer {
let data = Box::pin([0; 1 << 12]);
let chars = Box::pin([0; 1 << 11]);
let modifiers = Box::pin([0; 1 << 11]);

let handle = async_std::task::spawn(run_handle(BufferPtr(&*data)));
let handle = async_std::task::spawn(run_handle(BufferPtr{
chars: &*chars,
modifiers: &*modifiers,
}));

TextBuffer { data, handle }
TextBuffer { chars, modifiers, handle }
}

pub fn get(&self, addr: u16) -> u8 {
self.data[addr as usize]
if addr % 2 == 0 {
let sub_index = (addr >> 1) as usize;
self.chars[sub_index]
} else {
let sub_index = (addr >> 1) as usize;
self.modifiers[sub_index]
}
}

pub fn set(&mut self, addr: u16, data: u8) {
self.data[addr as usize] = data;
println!("setting {addr} to {data}");

if addr % 2 == 0 {
let sub_index = (addr >> 1) as usize;
self.chars[sub_index] = data;
} else {
let sub_index = (addr >> 1) as usize;
self.modifiers[sub_index] = data;
}
}

pub fn reset(&mut self) {
self.chars.fill(0);
self.modifiers.fill(0);
}
}

Expand All @@ -47,6 +90,12 @@ async fn run_handle(buffer: BufferPtr) {

let mut window =
minifb::Window::new("f8ful", WIDTH, HEIGHT, opts).expect("should be able to create window");
// match the VGA standard
window.set_target_fps(75);
if let Some(icon) = get_icon() {
window.set_icon(icon);
}

let mut fb = [0x00000000; WIDTH * HEIGHT];

while window.is_open() {
Expand All @@ -58,15 +107,19 @@ async fn run_handle(buffer: BufferPtr) {
let char_x = x / 8;
let char_y = y / 16;
let char_idx = char_x + char_y * WIDTH / 8;
let character = 0x10;
let character = unsafe { (*buffer.0)[char_idx] };
let (character, modifier) = unsafe {(
(*buffer.chars)[char_idx],
(*buffer.modifiers)[char_idx]
)};

let font_addr = ((character as usize) << 4) + font_y;
let lit = FONT[font_addr] & (1 << (7 - font_x)) > 0;

// This part isn't part of the actual CPU,
// the real value will be transmitted via wire instead of stored.
fb[x + y * WIDTH] = if lit { 0x00FFFFFF } else { 0x00000000 };
// the real value will be transmitted via VGA instead of stored.
let fg = COLORS[(modifier & 0xf) as usize];
let bg = COLORS[(modifier >> 4) as usize];
fb[x + y * WIDTH] = if lit { fg } else { bg };
}
}

Expand All @@ -76,3 +129,8 @@ async fn run_handle(buffer: BufferPtr) {
}

}

fn get_icon() -> Option<Icon> {
// TODO: actually add icon
None
}

0 comments on commit 848d7d2

Please sign in to comment.