build script! no more manually rebuilding cozette!
This commit is contained in:
		
							parent
							
								
									6e55faa2c0
								
							
						
					
					
						commit
						7d0b66f418
					
				
							
								
								
									
										15
									
								
								Cargo.toml
								
								
								
								
							
							
						
						
									
										15
									
								
								Cargo.toml
								
								
								
								
							| 
						 | 
				
			
			@ -2,27 +2,28 @@
 | 
			
		|||
name = "georgeemu"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
edition = "2021"
 | 
			
		||||
build = "build.rs"
 | 
			
		||||
 | 
			
		||||
[[bin]]
 | 
			
		||||
[[target.'cfg(not(target_arch = "wasm32"))'.bin]]
 | 
			
		||||
path = "src/bin/main.rs"
 | 
			
		||||
name = "georgeemu"
 | 
			
		||||
name = "george"
 | 
			
		||||
 | 
			
		||||
[target.'cfg(target_arch = "wasm32")'.lib]
 | 
			
		||||
crate-type = ["cdylib", "rlib"]
 | 
			
		||||
 | 
			
		||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
			
		||||
 | 
			
		||||
[build-dependencies]
 | 
			
		||||
bdf-parser = "0.1.0"
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
anyhow = "1.0.81"
 | 
			
		||||
minifb = { git = "https://github.com/augustkline/rust_minifb" }
 | 
			
		||||
minifb = { git = "https://github.com/emoon/rust_minifb" }
 | 
			
		||||
serde = { version = "1.0.197", features = ["serde_derive", "derive"] }
 | 
			
		||||
web-sys = "0.3.70"
 | 
			
		||||
 | 
			
		||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
 | 
			
		||||
console_error_panic_hook = "0.1.7"
 | 
			
		||||
minifb = { git = "https://github.com/augustkline/rust_minifb", features = [
 | 
			
		||||
  "web",
 | 
			
		||||
] }
 | 
			
		||||
web-sys = "0.3.70"
 | 
			
		||||
 | 
			
		||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
 | 
			
		||||
termion = "4.0.2"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,83 @@
 | 
			
		|||
use std::{
 | 
			
		||||
    env,
 | 
			
		||||
    fs::File,
 | 
			
		||||
    io::{stdin, stdout, IsTerminal, Read, Write},
 | 
			
		||||
    ops::Neg,
 | 
			
		||||
    os::unix::process::CommandExt,
 | 
			
		||||
    path::Path,
 | 
			
		||||
    process::{exit, Command},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// takes all charaters in bdf and returns a vec of each character row byte in order, normalized to
 | 
			
		||||
// width & height of the font (only works with 8 or fewer pixel wide fonts, should work for any height)
 | 
			
		||||
fn bdf_to_bitmap(mut bdf: File) -> [u8; 0x8000] {
 | 
			
		||||
    let mut bdf_font_bytes = Vec::new();
 | 
			
		||||
    bdf.read_to_end(&mut bdf_font_bytes).unwrap();
 | 
			
		||||
 | 
			
		||||
    let bdf_font = bdf_parser::BdfFont::parse(&bdf_font_bytes).unwrap();
 | 
			
		||||
    let mut bdf_vec = vec![];
 | 
			
		||||
    for glyph in bdf_font.glyphs.iter() {
 | 
			
		||||
        let glyph_offset_x = glyph.bounding_box.offset.x;
 | 
			
		||||
        let glyph_offset_y = glyph.bounding_box.offset.y;
 | 
			
		||||
        let glyph_height = glyph.bounding_box.size.y;
 | 
			
		||||
        let font_height = bdf_font.metadata.bounding_box.size.y;
 | 
			
		||||
        let font_offset_y = bdf_font.metadata.bounding_box.offset.y;
 | 
			
		||||
 | 
			
		||||
        let top_space = font_height + font_offset_y - glyph_height - glyph_offset_y;
 | 
			
		||||
        for _ in 0..top_space {
 | 
			
		||||
            bdf_vec.push(0x00);
 | 
			
		||||
        }
 | 
			
		||||
        for bitmap in glyph.bitmap.iter() {
 | 
			
		||||
            bdf_vec.push(bitmap >> glyph_offset_x);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let bottom_space = font_offset_y.neg() + glyph_offset_y;
 | 
			
		||||
        for _ in 0..bottom_space {
 | 
			
		||||
            bdf_vec.push(0x00);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    let height = bdf_font.metadata.bounding_box.size.y as usize;
 | 
			
		||||
    reorder_bitmap(&bdf_vec, height)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// takes an vec of ordered characters and translates them for use with the character rom
 | 
			
		||||
// TODO: make this work for any arbitrary char rom pin format using some kinda interface
 | 
			
		||||
fn reorder_bitmap(bitmap: &[u8], font_height: usize) -> [u8; 0x8000] {
 | 
			
		||||
    let mut rom = [0; 0x8000]; // create vec the size of character rom
 | 
			
		||||
 | 
			
		||||
    for row in 0..font_height {
 | 
			
		||||
        for ascii_address in 0..u8::MAX {
 | 
			
		||||
            // first 8 bits of address pick character
 | 
			
		||||
            // next 5 bits pick row
 | 
			
		||||
            // TODO: final 2 pick character set
 | 
			
		||||
            let byte = bitmap[ascii_address as usize * font_height + row];
 | 
			
		||||
            let rom_index: u16 = ((row as u16) << 8) + ascii_address as u16;
 | 
			
		||||
            rom[rom_index as usize] = byte;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    rom
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn rom_from_file<P>(path: P) -> [u8; 0x8000]
 | 
			
		||||
where
 | 
			
		||||
    P: AsRef<Path>,
 | 
			
		||||
{
 | 
			
		||||
    let file = File::open(path).unwrap();
 | 
			
		||||
    bdf_to_bitmap(file)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    let mut regen_font = Command::new("regen-font.sh");
 | 
			
		||||
    let mut cleanup = Command::new("cleanup.sh");
 | 
			
		||||
 | 
			
		||||
    regen_font.exec();
 | 
			
		||||
 | 
			
		||||
    let out_dir = env::var_os("OUT_DIR").unwrap();
 | 
			
		||||
    let dest_path = Path::new(&out_dir).join("cozette.rom");
 | 
			
		||||
 | 
			
		||||
    let cozette_rom_bytes = rom_from_file("build/cozette.bdf");
 | 
			
		||||
    let mut cozette_rom = File::create(dest_path).unwrap();
 | 
			
		||||
    cozette_rom.write_all(&cozette_rom_bytes).unwrap();
 | 
			
		||||
 | 
			
		||||
    cleanup.exec();
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
#! /bin/sh
 | 
			
		||||
 | 
			
		||||
rm *.bdf*
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
#   this is august's version of extended ascii for george <3
 | 
			
		||||
#   this is georgescii, august's version of extended ascii for george <3
 | 
			
		||||
#   we're limited to 255 characters
 | 
			
		||||
#   format: ascii byte, unicode hex, # unicode name
 | 
			
		||||
#
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
#! /bin/sh
 | 
			
		||||
 | 
			
		||||
fontforge -lang=ff -c 'Open($1); LoadEncodingFile($2, "george"); Reencode("george"); Generate($3)' Cozette.sfd georgeencoding.txt cozette.bdf
 | 
			
		||||
sed -i'' -e 's/FONTBOUNDINGBOX 11 13 0 -3/FONTBOUNDINGBOX 8 13 0 -3/' *.bdf
 | 
			
		||||
mv cozette-13.bdf cozette.bdf
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
    .org $00
 | 
			
		||||
 | 
			
		||||
    .byte $80
 | 
			
		||||
 | 
			
		||||
    .org $8000
 | 
			
		||||
 | 
			
		||||
reset: 
 | 
			
		||||
    bbr7 $00, reset
 | 
			
		||||
 | 
			
		||||
    .org $fffc
 | 
			
		||||
    .word reset
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -37,7 +37,8 @@ newline: ; sets cursor to start of next line
 | 
			
		|||
        rts
 | 
			
		||||
 | 
			
		||||
text:
 | 
			
		||||
    .asciiz "george loves u <3"
 | 
			
		||||
    .byte 1,2,3,2,4
 | 
			
		||||
    .asciiz "- george loves u <3"
 | 
			
		||||
 | 
			
		||||
random_y: 
 | 
			
		||||
    .byte 25,12,0,20,4,25,5,13
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -0,0 +1,189 @@
 | 
			
		|||
; .setcpu "65C02"
 | 
			
		||||
    .include "./macro.inc"
 | 
			
		||||
 | 
			
		||||
; okay so rn i wanna set up a very basic system init, and write a few subroutines to draw characters at x,y coordinates
 | 
			
		||||
n = $01 ; temporary storage for data stack operations
 | 
			
		||||
 | 
			
		||||
key_row = $200 ; used for character lookup when key pressed
 | 
			
		||||
key_col = $201
 | 
			
		||||
cursor = $202
 | 
			
		||||
 | 
			
		||||
char_buffer = $300 ; 256 byte character buffer
 | 
			
		||||
 | 
			
		||||
kb_row = $4400 ; keyboard hardware register
 | 
			
		||||
kb_row_cache = $203 ; cache 
 | 
			
		||||
 | 
			
		||||
    .org $8000
 | 
			
		||||
 | 
			
		||||
reset:
 | 
			
		||||
    sei
 | 
			
		||||
    ldx #0; initialize data stack pointer
 | 
			
		||||
 | 
			
		||||
initdisplay:
 | 
			
		||||
    lda #0
 | 
			
		||||
    ldy #0
 | 
			
		||||
 | 
			
		||||
cleardisplay:
 | 
			
		||||
    sta $6000,y
 | 
			
		||||
    sta $6100,y
 | 
			
		||||
    sta $6200,y
 | 
			
		||||
    sta $6300,y
 | 
			
		||||
    sta $6400,y
 | 
			
		||||
    sta $6500,y
 | 
			
		||||
    sta $6600,y
 | 
			
		||||
    sta $6700,y ; this goes slightly over but it's fine
 | 
			
		||||
    iny
 | 
			
		||||
    bne cleardisplay
 | 
			
		||||
    cli
 | 
			
		||||
 | 
			
		||||
print_test:
 | 
			
		||||
    lda #0
 | 
			
		||||
    sta key_row
 | 
			
		||||
    lda #5
 | 
			
		||||
    sta key_col
 | 
			
		||||
    push_coords #5, #5
 | 
			
		||||
 | 
			
		||||
main:
 | 
			
		||||
    ; jsr printtext
 | 
			
		||||
    ; key_zero:
 | 
			
		||||
    ;     stz keyboard_cache, x
 | 
			
		||||
    ;     dex
 | 
			
		||||
    ;     bpl key_zero
 | 
			
		||||
    ; fim: 
 | 
			
		||||
    ;     cli
 | 
			
		||||
    ;     bra fim
 | 
			
		||||
    jsr print
 | 
			
		||||
    ; jsr print
 | 
			
		||||
    stp
 | 
			
		||||
    jmp main
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
; keyboard: ; reads keyboard registers and stores the column and row of the first key found
 | 
			
		||||
;     ; TODO: make this routine store up to 8 indices (for 8 key rollover)
 | 
			
		||||
;     ldy #0 
 | 
			
		||||
;     .check_row: ; loop through each row
 | 
			
		||||
;         lda kb_row, y
 | 
			
		||||
;         beq .skip_row ; if row has no key pressed, skip checking which key
 | 
			
		||||
;         ; jmp key_down
 | 
			
		||||
;         sta kb_row_cache, y ; if key pressed, cache it
 | 
			
		||||
;         lda kb_row, y
 | 
			
		||||
;         cmp kb_row_cache, y ; has key changed?
 | 
			
		||||
;         beq key_down
 | 
			
		||||
;         .skip_row:
 | 
			
		||||
;             iny
 | 
			
		||||
;             cpy #5
 | 
			
		||||
;             bne .check_row
 | 
			
		||||
;     rts
 | 
			
		||||
 | 
			
		||||
;     key_down:               ; a is loaded with the row byte
 | 
			
		||||
;         phy
 | 
			
		||||
;         sty key_row         ; store character row
 | 
			
		||||
;         ldy #0
 | 
			
		||||
;         .find_col:          ; test each row bit, store column if key pressed
 | 
			
		||||
;             lsr             ; test bit 7
 | 
			
		||||
;             bcs store_col       ; if unset, don't go store character columnb
 | 
			
		||||
;             .skip:
 | 
			
		||||
;                 iny
 | 
			
		||||
;                 cpy #8
 | 
			
		||||
;                 bne .find_col   ; loop until we've checked each bit
 | 
			
		||||
;             rts
 | 
			
		||||
 | 
			
		||||
;     store_col:
 | 
			
		||||
;         sty key_col
 | 
			
		||||
;         jsr print
 | 
			
		||||
;         rts
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
print: ; x y -- prints the key indexed with key_col and key_row at position x, y
 | 
			
		||||
 | 
			
		||||
    keymap_index:
 | 
			
		||||
        push
 | 
			
		||||
        lda key_col
 | 
			
		||||
        stz 1, x
 | 
			
		||||
        sta 0, x
 | 
			
		||||
        push
 | 
			
		||||
        lda #8
 | 
			
		||||
        stz 1, x
 | 
			
		||||
        sta 0, x
 | 
			
		||||
        push
 | 
			
		||||
        lda key_row
 | 
			
		||||
        stz 1, x
 | 
			
		||||
        sta 0, x
 | 
			
		||||
        jsr mult
 | 
			
		||||
        jsr plus
 | 
			
		||||
        lda 0, x
 | 
			
		||||
        tay
 | 
			
		||||
    lda keymap, y
 | 
			
		||||
    push
 | 
			
		||||
    sta 0, x
 | 
			
		||||
    stz 1, x
 | 
			
		||||
    jsr draw_char
 | 
			
		||||
    rts
 | 
			
		||||
 | 
			
		||||
    keymap:
 | 
			
		||||
        .byte "?outrew?"
 | 
			
		||||
        .byte "?piygsq?"
 | 
			
		||||
        .byte "a??khvd?"
 | 
			
		||||
        .byte "42ljbfz?"
 | 
			
		||||
        .byte "31?mncx?"
 | 
			
		||||
        .byte "?????  m"
 | 
			
		||||
 | 
			
		||||
draw:
 | 
			
		||||
    ; push_coords #0, #0
 | 
			
		||||
    ; push_char #$00
 | 
			
		||||
    ; jsr draw_char
 | 
			
		||||
    rts
 | 
			
		||||
 | 
			
		||||
draw_char: ; draw a character c at (x, y) (n1: x n2: y n3: c -- )
 | 
			
		||||
    lda 0, x ; load a with character to draw
 | 
			
		||||
    pop ; and pop it off the stack
 | 
			
		||||
    jsr get_char_address ; calculate where to put the character in memory
 | 
			
		||||
    sta (0, x) ; store a at the address pointed to on the stack
 | 
			
		||||
    rts
 | 
			
		||||
 | 
			
		||||
get_char_address:   ; gets vram address for a character at (x, y),
 | 
			
		||||
                    ; (n1: x n2: y -- n: $6000 + x + (64 * y))
 | 
			
		||||
    ;jsr push_lit ; push 64 onto stack, low byte first
 | 
			
		||||
    ;.byte 64
 | 
			
		||||
    ;.byte 0
 | 
			
		||||
    pha
 | 
			
		||||
    lda #64
 | 
			
		||||
    push ; doing this instead until `push_lit` is fixed
 | 
			
		||||
    sta 0, x
 | 
			
		||||
    stz 1, x
 | 
			
		||||
    jsr mult ; multiply 64 with y (n2)
 | 
			
		||||
    jsr plus ; add result with x (n1)
 | 
			
		||||
 | 
			
		||||
    ;jsr push_lit ; push vram address onto the stack
 | 
			
		||||
    ;.byte $00
 | 
			
		||||
    ;.byte $60
 | 
			
		||||
    lda #$60
 | 
			
		||||
    push
 | 
			
		||||
    sta 1, x
 | 
			
		||||
    stz 0, x
 | 
			
		||||
    jsr plus ; add vram start address to result
 | 
			
		||||
 | 
			
		||||
    pla
 | 
			
		||||
    rts
 | 
			
		||||
 | 
			
		||||
fill: ; fills an area from (x1, y1) to (x2, y2) will character c, (n1: c n2: x1 n3: y1 n4: x2 n5: y2 -- )
 | 
			
		||||
    jsr get_char_address
 | 
			
		||||
 | 
			
		||||
isr: ; interrupt service routine
 | 
			
		||||
    pha
 | 
			
		||||
    phx
 | 
			
		||||
    phy
 | 
			
		||||
    ; jsr keyboard
 | 
			
		||||
    ply
 | 
			
		||||
    plx
 | 
			
		||||
    pla
 | 
			
		||||
    rti
 | 
			
		||||
 | 
			
		||||
    .include "math.inc"
 | 
			
		||||
 | 
			
		||||
    .org $fffc
 | 
			
		||||
    .word reset
 | 
			
		||||
    .word isr
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -0,0 +1,215 @@
 | 
			
		|||
; .setcpu "65C02"
 | 
			
		||||
    .include "./macro.inc"
 | 
			
		||||
 | 
			
		||||
    .org $8000
 | 
			
		||||
 | 
			
		||||
n = $01 ; temporary storage for data stack operations
 | 
			
		||||
 | 
			
		||||
temp = $20 ; scratchpad page
 | 
			
		||||
str_ptr = $30
 | 
			
		||||
 | 
			
		||||
cursor = $300
 | 
			
		||||
cursor_x = cursor
 | 
			
		||||
cursor_y = cursor + 1
 | 
			
		||||
 | 
			
		||||
char_buf = $302
 | 
			
		||||
char_buf_index = char_buf + 8
 | 
			
		||||
 | 
			
		||||
reset:
 | 
			
		||||
    sei
 | 
			
		||||
    ldx #0; initialize data stack pointer
 | 
			
		||||
 | 
			
		||||
init:
 | 
			
		||||
    lda #$31
 | 
			
		||||
    sta str_ptr
 | 
			
		||||
    lda #$80
 | 
			
		||||
    sta str_ptr + 1
 | 
			
		||||
 | 
			
		||||
    jsr clear
 | 
			
		||||
    lda #0
 | 
			
		||||
    sta cursor_x
 | 
			
		||||
    lda #0
 | 
			
		||||
    sta cursor_y
 | 
			
		||||
    cli
 | 
			
		||||
 | 
			
		||||
main:
 | 
			
		||||
    jsr print
 | 
			
		||||
    jmp main
 | 
			
		||||
 | 
			
		||||
newline: ; sets cursor to start of next line
 | 
			
		||||
    stz cursor_x
 | 
			
		||||
    lda cursor_y
 | 
			
		||||
    cmp #28
 | 
			
		||||
    bne .end
 | 
			
		||||
    stz cursor_y
 | 
			
		||||
    rts
 | 
			
		||||
    .end:
 | 
			
		||||
        inc cursor_y
 | 
			
		||||
        rts
 | 
			
		||||
 | 
			
		||||
text:
 | 
			
		||||
    .asciiz "hello <3"
 | 
			
		||||
 | 
			
		||||
; increments the cursor line by line, looping to (0, 0) after (63, 28)
 | 
			
		||||
 | 
			
		||||
inc_cursor:
 | 
			
		||||
    lda cursor_x
 | 
			
		||||
    cmp #63
 | 
			
		||||
    beq .newline
 | 
			
		||||
    inc cursor_x 
 | 
			
		||||
    rts
 | 
			
		||||
    .newline:
 | 
			
		||||
        lda cursor_y
 | 
			
		||||
        cmp #28
 | 
			
		||||
        beq .newscreen
 | 
			
		||||
        stz cursor_x
 | 
			
		||||
        inc cursor_y
 | 
			
		||||
        rts
 | 
			
		||||
    .newscreen:
 | 
			
		||||
        stz cursor_y
 | 
			
		||||
        stz cursor_x
 | 
			
		||||
        rts
 | 
			
		||||
 | 
			
		||||
; zeroes out the display, resets cursor to 0,0
 | 
			
		||||
 | 
			
		||||
clear: 
 | 
			
		||||
    lda #0
 | 
			
		||||
    ldy #0
 | 
			
		||||
 | 
			
		||||
   .loop:
 | 
			
		||||
        sta $6000,y
 | 
			
		||||
        sta $6100,y
 | 
			
		||||
        sta $6200,y
 | 
			
		||||
        sta $6300,y
 | 
			
		||||
        sta $6400,y
 | 
			
		||||
        sta $6500,y
 | 
			
		||||
        sta $6600,y
 | 
			
		||||
        sta $6700,y ; this goes slightly over but it's fine
 | 
			
		||||
        iny
 | 
			
		||||
        bne .loop
 | 
			
		||||
    stz cursor
 | 
			
		||||
    stz cursor + 1
 | 
			
		||||
    rts
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
; prints string from cursor position, stopping at end of string or at 256 chars, whichever comes first
 | 
			
		||||
; $6000 + (64*Y) + X
 | 
			
		||||
; THIS WILL WRITE OUT OF BOUNDS IF THE CURSOR IS OUT OF BOUNDS/STRING IS TOO LONG
 | 
			
		||||
 | 
			
		||||
; TODO: figure out a simple way of writing arbitrary length strings
 | 
			
		||||
; and 
 | 
			
		||||
 | 
			
		||||
print: 
 | 
			
		||||
   jsr cursor_addr
 | 
			
		||||
   ldy #0
 | 
			
		||||
   ; y_overflow = temp + 5
 | 
			
		||||
   .loop:
 | 
			
		||||
       lda (str_ptr), y
 | 
			
		||||
       beq .end
 | 
			
		||||
       sta (temp), y
 | 
			
		||||
       iny
 | 
			
		||||
       bra .loop
 | 
			
		||||
   .end:
 | 
			
		||||
   rts
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
; calculates real vram address from cursor (x, y)
 | 
			
		||||
 | 
			
		||||
cursor_addr:
 | 
			
		||||
    stz temp
 | 
			
		||||
    stz temp + 1
 | 
			
		||||
    lda cursor_y
 | 
			
		||||
    beq .add_x ; if y's zero just add x
 | 
			
		||||
    .y_mult:
 | 
			
		||||
        ; multiply by 64
 | 
			
		||||
        clc
 | 
			
		||||
        asl
 | 
			
		||||
        rol temp + 1 
 | 
			
		||||
        asl
 | 
			
		||||
        rol temp + 1 
 | 
			
		||||
        asl  
 | 
			
		||||
        rol temp + 1 
 | 
			
		||||
        asl  
 | 
			
		||||
        rol temp + 1 
 | 
			
		||||
        asl  
 | 
			
		||||
        rol temp + 1 
 | 
			
		||||
        asl  
 | 
			
		||||
        rol temp + 1 
 | 
			
		||||
        sta temp
 | 
			
		||||
    .add_x:
 | 
			
		||||
        clc
 | 
			
		||||
        lda cursor_x
 | 
			
		||||
        adc temp
 | 
			
		||||
        sta temp 
 | 
			
		||||
        lda #0
 | 
			
		||||
        adc temp + 1
 | 
			
		||||
        sta temp + 1
 | 
			
		||||
        clc
 | 
			
		||||
 | 
			
		||||
        lda #$60
 | 
			
		||||
        adc temp + 1
 | 
			
		||||
        sta temp + 1
 | 
			
		||||
    rts
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
; print_text:
 | 
			
		||||
;     lda text,y
 | 
			
		||||
;     beq .end
 | 
			
		||||
;     sta $6000, y
 | 
			
		||||
;     iny
 | 
			
		||||
;     bra print_text
 | 
			
		||||
;     .end:
 | 
			
		||||
;         ldy #0
 | 
			
		||||
;         rts
 | 
			
		||||
 | 
			
		||||
; draw_char: ; draw a character c at (x, y) (n1: x n2: y n3: c -- )
 | 
			
		||||
;     lda 0, x ; load a with character to draw
 | 
			
		||||
;     pop ; and pop it off the stack
 | 
			
		||||
;     jsr get_char_address ; calculate where to put the character in memory
 | 
			
		||||
;     sta (0, x) ; store a at the address pointed to on the stack
 | 
			
		||||
;     rts
 | 
			
		||||
 | 
			
		||||
; get_char_address:   ; gets vram address for a character at (x, y),
 | 
			
		||||
;                     ; (n1: x n2: y -- n: $6000 + x + (64 * y))
 | 
			
		||||
;     ;jsr push_lit ; push 64 onto stack, low byte first
 | 
			
		||||
;     ;.byte 64
 | 
			
		||||
;     ;.byte 0
 | 
			
		||||
;     pha
 | 
			
		||||
;     lda #64
 | 
			
		||||
;     push ; doing this instead until `push_lit` is fixed
 | 
			
		||||
;     sta 0, x
 | 
			
		||||
;     stz 1, x
 | 
			
		||||
;     jsr mult ; multiply 64 with y (n2)
 | 
			
		||||
;     jsr plus ; add result with x (n1)
 | 
			
		||||
 | 
			
		||||
;     ;jsr push_lit ; push vram address onto the stack
 | 
			
		||||
;     ;.byte $00
 | 
			
		||||
;     ;.byte $60
 | 
			
		||||
;     lda #$60
 | 
			
		||||
;     push
 | 
			
		||||
;     sta 1, x
 | 
			
		||||
;     stz 0, x
 | 
			
		||||
;     jsr plus ; add vram start address to result
 | 
			
		||||
 | 
			
		||||
;     pla
 | 
			
		||||
;     rts
 | 
			
		||||
 | 
			
		||||
; fill: ; fills an area from (x1, y1) to (x2, y2) will character c, (n1: c n2: x1 n3: y1 n4: x2 n5: y2 -- )
 | 
			
		||||
;     jsr get_char_address
 | 
			
		||||
 | 
			
		||||
isr: ; interrupt service routine
 | 
			
		||||
    pha
 | 
			
		||||
    phx
 | 
			
		||||
    phy
 | 
			
		||||
    ; jsr irq
 | 
			
		||||
    ply
 | 
			
		||||
    plx
 | 
			
		||||
    pla
 | 
			
		||||
    rti
 | 
			
		||||
 | 
			
		||||
    .include "math.inc"
 | 
			
		||||
 | 
			
		||||
    .org $fffc
 | 
			
		||||
    .word reset
 | 
			
		||||
    .word isr
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -0,0 +1,173 @@
 | 
			
		|||
; .setcpu "65C02"
 | 
			
		||||
    .include "./macro.inc"
 | 
			
		||||
 | 
			
		||||
; okay so rn i wanna set up a very basic system init, and write a few subroutines to draw characters at x,y coordinates
 | 
			
		||||
n = $01 ; temporary storage for data stack operations
 | 
			
		||||
 | 
			
		||||
key_row = $200 ; used for character lookup when key pressed
 | 
			
		||||
key_col = $201
 | 
			
		||||
cursor = $202
 | 
			
		||||
 | 
			
		||||
char_buffer = $300 ; 256 byte character buffer
 | 
			
		||||
 | 
			
		||||
kb_row = $4400 ; keyboard hardware register
 | 
			
		||||
kb_row_cache = $203 ; cache 
 | 
			
		||||
 | 
			
		||||
    .org $8000
 | 
			
		||||
 | 
			
		||||
reset:
 | 
			
		||||
    sei
 | 
			
		||||
    ldx #0; initialize data stack pointer
 | 
			
		||||
    jmp main
 | 
			
		||||
 | 
			
		||||
initdisplay:
 | 
			
		||||
    lda #20
 | 
			
		||||
    ldy #0
 | 
			
		||||
 | 
			
		||||
cleardisplay:
 | 
			
		||||
    sta $6000,y
 | 
			
		||||
    sta $6100,y
 | 
			
		||||
    sta $6200,y
 | 
			
		||||
    sta $6300,y
 | 
			
		||||
    sta $6400,y
 | 
			
		||||
    sta $6500,y
 | 
			
		||||
    sta $6600,y
 | 
			
		||||
    sta $6700,y ; this goes slightly over but it's fine
 | 
			
		||||
    iny
 | 
			
		||||
    bne cleardisplay
 | 
			
		||||
    cli
 | 
			
		||||
 | 
			
		||||
main:
 | 
			
		||||
    ; jsr keyboard
 | 
			
		||||
    ; key_zero:
 | 
			
		||||
    ;     stz keyboard_cache, x
 | 
			
		||||
    ;     dex
 | 
			
		||||
    ;     bpl key_zero
 | 
			
		||||
    ; fim: 
 | 
			
		||||
    ;     cli
 | 
			
		||||
    ;     bra fim
 | 
			
		||||
    ; jsr kitty_keys
 | 
			
		||||
    lda #9
 | 
			
		||||
    sta $6000
 | 
			
		||||
    jmp main
 | 
			
		||||
 | 
			
		||||
not_keyboard:
 | 
			
		||||
    ldy #0 
 | 
			
		||||
    .check_row: ; loop through each row
 | 
			
		||||
        lda kb_row, y
 | 
			
		||||
        beq .skip_row ; if row has no key pressed, skip checking which key
 | 
			
		||||
        sta kb_row_cache, y ; if key pressed, cache it
 | 
			
		||||
        lda kb_row, y
 | 
			
		||||
        cmp kb_row_cache, y ; has key changed?
 | 
			
		||||
        beq key_down
 | 
			
		||||
        .skip_row:
 | 
			
		||||
            iny
 | 
			
		||||
            cpy #5
 | 
			
		||||
            bne .check_row
 | 
			
		||||
    rts
 | 
			
		||||
 | 
			
		||||
key_down:               ; a is loaded with the row byte
 | 
			
		||||
    phy
 | 
			
		||||
    sty key_row         ; store character row
 | 
			
		||||
    ldy #0
 | 
			
		||||
    .find_col:          ; test each row bit, store column if key pressed
 | 
			
		||||
        lsr             ; test bit 7
 | 
			
		||||
        bcs store_col       ; if unset, don't go store character columnb
 | 
			
		||||
        .skip:
 | 
			
		||||
            iny
 | 
			
		||||
            cpy #8
 | 
			
		||||
            bne .find_col   ; loop until we've checked each bit
 | 
			
		||||
 | 
			
		||||
store_col:
 | 
			
		||||
    sty key_col
 | 
			
		||||
 | 
			
		||||
keymap_index:
 | 
			
		||||
    push
 | 
			
		||||
    lda key_col
 | 
			
		||||
    stz 1, x
 | 
			
		||||
    sta 0, x
 | 
			
		||||
    push
 | 
			
		||||
    lda #8
 | 
			
		||||
    stz 1, x
 | 
			
		||||
    sta 0, x
 | 
			
		||||
    push
 | 
			
		||||
    lda key_row
 | 
			
		||||
    stz 1, x
 | 
			
		||||
    sta 0, x
 | 
			
		||||
    jsr mult
 | 
			
		||||
    jsr plus
 | 
			
		||||
    lda 0, x
 | 
			
		||||
    tay
 | 
			
		||||
 | 
			
		||||
print: ; we've stored the character position, now let's 
 | 
			
		||||
    lda keymap, y
 | 
			
		||||
    ldy cursor
 | 
			
		||||
    sta $6000, y
 | 
			
		||||
    inc cursor
 | 
			
		||||
    ply
 | 
			
		||||
    rts
 | 
			
		||||
 | 
			
		||||
keymap:
 | 
			
		||||
    .byte "?outrew?"
 | 
			
		||||
    .byte "?piygsq?"
 | 
			
		||||
    .byte "a??khvd?"
 | 
			
		||||
    .byte "42ljbfz?"
 | 
			
		||||
    .byte "31?mncx?"
 | 
			
		||||
    .byte "?????  m"
 | 
			
		||||
 | 
			
		||||
; draw:
 | 
			
		||||
;     ; push_coords #0, #0
 | 
			
		||||
;     ; push_char #$00
 | 
			
		||||
;     ; jsr draw_char
 | 
			
		||||
;     rts
 | 
			
		||||
 | 
			
		||||
; draw_char: ; draw a character c at (x, y) (n1: x n2: y n3: c -- )
 | 
			
		||||
;     lda 0, x ; load a with character to draw
 | 
			
		||||
;     pop ; and pop it off the stack
 | 
			
		||||
;     jsr get_char_address ; calculate where to put the character in memory
 | 
			
		||||
;     sta (0, x) ; store a at the address pointed to on the stack
 | 
			
		||||
;     rts
 | 
			
		||||
 | 
			
		||||
; get_char_address:   ; gets vram address for a character at (x, y),
 | 
			
		||||
;                     ; (n1: x n2: y -- n: $6000 + x + (64 * y))
 | 
			
		||||
;     ;jsr push_lit ; push 64 onto stack, low byte first
 | 
			
		||||
;     ;.byte 64
 | 
			
		||||
;     ;.byte 0
 | 
			
		||||
;     pha
 | 
			
		||||
;     lda #64
 | 
			
		||||
;     push ; doing this instead until `push_lit` is fixed
 | 
			
		||||
;     sta 0, x
 | 
			
		||||
;     stz 1, x
 | 
			
		||||
;     jsr mult ; multiply 64 with y (n2)
 | 
			
		||||
;     jsr plus ; add result with x (n1)
 | 
			
		||||
 | 
			
		||||
;     ;jsr push_lit ; push vram address onto the stack
 | 
			
		||||
;     ;.byte $00
 | 
			
		||||
;     ;.byte $60
 | 
			
		||||
;     lda #$60
 | 
			
		||||
;     push
 | 
			
		||||
;     sta 1, x
 | 
			
		||||
;     stz 0, x
 | 
			
		||||
;     jsr plus ; add vram start address to result
 | 
			
		||||
 | 
			
		||||
;     pla
 | 
			
		||||
;     rts
 | 
			
		||||
 | 
			
		||||
; fill: ; fills an area from (x1, y1) to (x2, y2) will character c, (n1: c n2: x1 n3: y1 n4: x2 n5: y2 -- )
 | 
			
		||||
;     jsr get_char_address
 | 
			
		||||
 | 
			
		||||
isr: ; interrupt service routine
 | 
			
		||||
    pha
 | 
			
		||||
    phx
 | 
			
		||||
    phy
 | 
			
		||||
    ; jsr irq
 | 
			
		||||
    ply
 | 
			
		||||
    plx
 | 
			
		||||
    pla
 | 
			
		||||
    rti
 | 
			
		||||
 | 
			
		||||
    .include "math.inc"
 | 
			
		||||
 | 
			
		||||
    .org $fffc
 | 
			
		||||
    .word reset
 | 
			
		||||
    .word isr
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										4
									
								
								run.sh
								
								
								
								
							
							
						
						
									
										4
									
								
								run.sh
								
								
								
								
							| 
						 | 
				
			
			@ -7,6 +7,6 @@ fi
 | 
			
		|||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
vasm6502_oldstyle ./src/roms/$1.asm -dotdir -wdc02 -ldots -Fbin -o ./src/roms/$1.rom;
 | 
			
		||||
cargo run -- rom "./src/roms/$1.rom";
 | 
			
		||||
vasm6502_oldstyle roms/$1.asm -dotdir -wdc02 -ldots -Fbin -o roms/$1.rom;
 | 
			
		||||
cargo run -- rom "roms/$1.rom";
 | 
			
		||||
# hexdump -C ./cpu_dump.bin;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,9 +20,9 @@ impl MemHandle {
 | 
			
		|||
        memory.write(address, data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn dump(&self) {
 | 
			
		||||
    pub fn dump(&self) -> [u8; 0x10000] {
 | 
			
		||||
        let memory = self.0.lock().unwrap();
 | 
			
		||||
        let _ = memory.dump(PathBuf::from_str("./cpu_dump.bin").unwrap());
 | 
			
		||||
        memory.dump()
 | 
			
		||||
    }
 | 
			
		||||
    pub fn poke(&self, address: u16) {
 | 
			
		||||
        let memory = self.0.lock().unwrap();
 | 
			
		||||
| 
						 | 
				
			
			@ -47,7 +47,7 @@ pub struct Mem([u8; 0x10000]);
 | 
			
		|||
 | 
			
		||||
impl Default for Mem {
 | 
			
		||||
    fn default() -> Self {
 | 
			
		||||
        let bytes = include_bytes!("./roms/george.rom");
 | 
			
		||||
        let bytes = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/roms/george.rom"));
 | 
			
		||||
        let padding = [0; 0x8000];
 | 
			
		||||
        let mem: [u8; 0x10000] = {
 | 
			
		||||
            let mut rom: [u8; 0x10000] = [0; 0x10000];
 | 
			
		||||
| 
						 | 
				
			
			@ -65,10 +65,8 @@ impl Mem {
 | 
			
		|||
    pub fn new() -> Self {
 | 
			
		||||
        Self([0; 0x10000])
 | 
			
		||||
    }
 | 
			
		||||
    pub fn dump(&self, path: PathBuf) -> io::Result<()> {
 | 
			
		||||
        let mut outfile = File::create(path)?;
 | 
			
		||||
        outfile.write_all(&self.0)?;
 | 
			
		||||
        Ok(())
 | 
			
		||||
    pub fn dump(&self) -> [u8; 0x10000] {
 | 
			
		||||
        self.0
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn read(&self, address: u16) -> u8 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
#[cfg(not(target_arch = "wasm32"))]
 | 
			
		||||
use std::io::{self, Write};
 | 
			
		||||
use std::{env, fs::File, io::Read, path::Path};
 | 
			
		||||
 | 
			
		||||
#[cfg(not(target_arch = "wasm32"))]
 | 
			
		||||
use termion::{
 | 
			
		||||
| 
						 | 
				
			
			@ -43,8 +44,7 @@ const HEIGHT: usize = 380;
 | 
			
		|||
//     }
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
const CHAR_ROM: &[u8; 0x8000] = include_bytes!("./roms/cozette.rom");
 | 
			
		||||
 | 
			
		||||
const CHAR_ROM: &[u8; 0x8000] = include_bytes!(concat!(env!("OUT_DIR"), "/cozette.rom"));
 | 
			
		||||
#[cfg(not(target_arch = "wasm32"))]
 | 
			
		||||
const ASCII_LOOKUP: [&str; 256] = [
 | 
			
		||||
    " ", "░", "▒", "▓", "♡", "♥", "⭐", "✭", "", "✦", "✨", "♀", "♂", "⚢", "⚣", "⚥", "♩", "♪",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue