From 5f6bc2fc86482337315d05cce52416ecf6ab678a Mon Sep 17 00:00:00 2001 From: JJ Bliss Date: Mon, 27 Apr 2026 21:21:01 -0400 Subject: [PATCH] Extremely rough file reading working --- uxn/uxn.ha | 133 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 116 insertions(+), 17 deletions(-) diff --git a/uxn/uxn.ha b/uxn/uxn.ha index 2d4f21d..3ea4630 100644 --- a/uxn/uxn.ha +++ b/uxn/uxn.ha @@ -2,6 +2,8 @@ use fmt; use os; use fs; use io; +use bufio; +use bytes; use time; use time::date; use strings; @@ -27,6 +29,7 @@ export type uxn = struct { screen_update: bool, screen: uxn_screen, palette: [4] u16, + files: [2] uxnFile, }; export def MAXWIDTH = 4096; @@ -35,6 +38,21 @@ export def SCREENRATE = 60; //Screen consists of two layers of 2-bit pixels export type uxn_screen = ([MAXWIDTH][MAXHEIGHT]u8, [MAXWIDTH][MAXHEIGHT]u8); +export type uxnFile = struct { + file: io::handle, + filepath: str, + state: filestate, + +}; +export type filestate = enum { + IDLE, + FILE_READ, + FILE_WRITE, + DIR_READ, + DIR_WRITE +}; + + def NUMBANKS = 0x10; def BANKSIZE = 0x10000; def BANKS_CAP = NUMBANKS * BANKSIZE; @@ -65,6 +83,11 @@ fn initialize_uxn_mem() *uxn = { screen_update = true, screen = ([[0...]...],[[0...]...]), palette = [0...], + files = [uxnFile { + file = io::empty, + filepath = "", + state = filestate::IDLE, + }...], })!; }; @@ -157,21 +180,34 @@ fn emu_deo(port: u8, value: u8, state: *uxn) void = { case 0x19 => fmt::error(value)!; case 0x21 => - let high = state.dev[0x20]; - let low = value; + const high = state.dev[0x20]; + const low = value; state.screen_vector = short_from_bytes(high,low); case 0x2e => draw_pixel(value,state); case 0x2f => draw_sprite(value,state); case 0x81 => - let high = state.dev[0x80]; - let low = value; + const high = state.dev[0x80]; + const low = value; state.controller_vector = short_from_bytes(high,low); case 0x91 => - let high = state.dev[0x90]; - let low = value; + const high = state.dev[0x90]; + const low = value; state.mouse_vector = short_from_bytes(high,low); + case 0xa9 => // File/name [0] + set_file_name(0,state); + case 0xad => // File/read [0] + read_file_to_addr(0,state); + case 0xaf => //File/write [0] + write_file_from_addr(0,state); + case 0xb9 => // File/name [1] + set_file_name(1,state); + case 0xbd => // File/read [1] + read_file_to_addr(1,state); + case 0xbf => //File/write [1] + write_file_from_addr(1,state); + case => if( port == 0x22 || port == 0x23 || @@ -188,31 +224,94 @@ fn emu_deo(port: u8, value: u8, state: *uxn) void = { }; }; +fn read_file_to_addr(fi: u8, state: *uxn) void = { + const length = if(fi == 0) { yield short_from_bytes(state.dev[0xaa],state.dev[0xab]); } + else { yield short_from_bytes(state.dev[0xba],state.dev[0xbb]); }; + const destaddr = if(fi == 0) { yield short_from_bytes(state.dev[0xac],state.dev[0xad]); } + else { yield short_from_bytes(state.dev[0xbd],state.dev[0xbd]); }; + fmt::printfln("Reading {} bytes to 0x{:x}", length, destaddr)!; + let bytesread = 0; + for(let i: u16 =0; i + bytesread += 1; + fmt::printfln("Reading byte {}: from file",b)!; + state.ram[destaddr+i] = b; + case let eof: io::EOF => + break; + case let err: io::error => + fmt::fatalf("Error reading: {}", io::strerror(err)); + }; + }; + + if(fi == 0){ + state.dev[0xa2] = (bytesread >> 8): u8; + state.dev[0xa3] = (bytesread): u8; + }else if(fi ==1){ + state.dev[0xb2] = (bytesread >> 8): u8; + state.dev[0xb3] = (bytesread): u8; + }; + return; +}; +fn write_file_from_addr(fi: u8,state: *uxn) void = { + return; +}; +fn set_file_name(fi: u8, state: *uxn) void = { + const nameaddr = if(fi == 0) { yield short_from_bytes(state.dev[0xa8],state.dev[0xa9]); } + else { yield short_from_bytes(state.dev[0xb8],state.dev[0xb9]); }; + const nameslice: []u8 = bytes::cut(state.ram[nameaddr..],0x00).0; + const name: str = match(strings::fromutf8(nameslice)){ + case let s: str => + yield s; + case => + fmt::fatal("Bad String encoding in filename"); + }; + + io::close(state.files[fi].file)!; + fmt::printfln("Opening file: {}",name)!; + state.files[fi].file = match (os::open(name,fs::flag::RDONLY)) { + case let file: io::file => + yield file; + case let err: fs::error => + fmt::printfln("Error opening {}: {}", name, fs::strerror(err))!; + if(fi == 0){ + state.dev[0xa2] = 0; + state.dev[0xa3] = 0; + }else if(fi ==1){ + state.dev[0xb2] = 0; + state.dev[0xb3] = 0; + }; + yield io::empty; + }; + return; +}; + + fn deo_expansion(addr: u16, state: *uxn) void = { const op = state.ram[addr]; - const length = short_from_bytes(state.ram[addr+1],state.dev[addr+2]); + const length = short_from_bytes(state.ram[addr+1],state.ram[addr+2]); switch(op) { case 0x00 => //fill - const bank = short_from_bytes(state.ram[addr+3],state.dev[addr+4]); - const addr = short_from_bytes(state.ram[addr+5],state.dev[addr+6]); + const bank = short_from_bytes(state.ram[addr+3],state.ram[addr+4]); + const addr = short_from_bytes(state.ram[addr+5],state.ram[addr+6]); const value = state.ram[addr+7]; if(bank < numbanks) for(let i: u16 =0; i < length; i+=1){ state.ram[bank * banksize + addr + i] = value; }; case 0x01 => //cpyl - const srcbank = short_from_bytes(state.ram[addr+3],state.dev[addr+4]); - const srcaddr = short_from_bytes(state.ram[addr+5],state.dev[addr+6]); - const dstbank = short_from_bytes(state.ram[addr+7],state.dev[addr+8]); - const dstaddr = short_from_bytes(state.ram[addr+9],state.dev[addr+10]); + const srcbank = short_from_bytes(state.ram[addr+3],state.ram[addr+4]); + const srcaddr = short_from_bytes(state.ram[addr+5],state.ram[addr+6]); + const dstbank = short_from_bytes(state.ram[addr+7],state.ram[addr+8]); + const dstaddr = short_from_bytes(state.ram[addr+9],state.ram[addr+10]); if(srcbank < numbanks && dstbank < numbanks) for(let i: u16 =0; i < length; i+=1){ const readval = state.ram[srcbank * banksize + srcaddr + i]; state.ram[dstbank * banksize + dstaddr + i] = readval; }; case 0x02 => //cpr TODO are these actually different?? Either way need to not use for loop - const srcbank = short_from_bytes(state.ram[addr+3],state.dev[addr+4]); - const srcaddr = short_from_bytes(state.ram[addr+5],state.dev[addr+6]); - const dstbank = short_from_bytes(state.ram[addr+7],state.dev[addr+8]); - const dstaddr = short_from_bytes(state.ram[addr+9],state.dev[addr+10]); + const srcbank = short_from_bytes(state.ram[addr+3],state.ram[addr+4]); + const srcaddr = short_from_bytes(state.ram[addr+5],state.ram[addr+6]); + const dstbank = short_from_bytes(state.ram[addr+7],state.ram[addr+8]); + const dstaddr = short_from_bytes(state.ram[addr+9],state.ram[addr+10]); if(srcbank < numbanks && dstbank < numbanks) for(let i: u16 =0; i < length; i+=1){ const readval = state.ram[srcbank * banksize + srcaddr + i]; state.ram[dstbank * banksize + dstaddr + i] = readval;