Extremely rough file reading working

This commit is contained in:
JJ Bliss
2026-04-27 21:21:01 -04:00
parent a6d9603b51
commit 5f6bc2fc86
+116 -17
View File
@@ -2,6 +2,8 @@ use fmt;
use os; use os;
use fs; use fs;
use io; use io;
use bufio;
use bytes;
use time; use time;
use time::date; use time::date;
use strings; use strings;
@@ -27,6 +29,7 @@ export type uxn = struct {
screen_update: bool, screen_update: bool,
screen: uxn_screen, screen: uxn_screen,
palette: [4] u16, palette: [4] u16,
files: [2] uxnFile,
}; };
export def MAXWIDTH = 4096; export def MAXWIDTH = 4096;
@@ -35,6 +38,21 @@ export def SCREENRATE = 60;
//Screen consists of two layers of 2-bit pixels //Screen consists of two layers of 2-bit pixels
export type uxn_screen = ([MAXWIDTH][MAXHEIGHT]u8, [MAXWIDTH][MAXHEIGHT]u8); 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 NUMBANKS = 0x10;
def BANKSIZE = 0x10000; def BANKSIZE = 0x10000;
def BANKS_CAP = NUMBANKS * BANKSIZE; def BANKS_CAP = NUMBANKS * BANKSIZE;
@@ -65,6 +83,11 @@ fn initialize_uxn_mem() *uxn = {
screen_update = true, screen_update = true,
screen = ([[0...]...],[[0...]...]), screen = ([[0...]...],[[0...]...]),
palette = [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 => case 0x19 =>
fmt::error(value)!; fmt::error(value)!;
case 0x21 => case 0x21 =>
let high = state.dev[0x20]; const high = state.dev[0x20];
let low = value; const low = value;
state.screen_vector = short_from_bytes(high,low); state.screen_vector = short_from_bytes(high,low);
case 0x2e => case 0x2e =>
draw_pixel(value,state); draw_pixel(value,state);
case 0x2f => case 0x2f =>
draw_sprite(value,state); draw_sprite(value,state);
case 0x81 => case 0x81 =>
let high = state.dev[0x80]; const high = state.dev[0x80];
let low = value; const low = value;
state.controller_vector = short_from_bytes(high,low); state.controller_vector = short_from_bytes(high,low);
case 0x91 => case 0x91 =>
let high = state.dev[0x90]; const high = state.dev[0x90];
let low = value; const low = value;
state.mouse_vector = short_from_bytes(high,low); 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 => case =>
if( port == 0x22 || if( port == 0x22 ||
port == 0x23 || 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<length; i+=1){
match (bufio::read_byte(state.files[fi].file)){
case let b: u8 =>
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 = { fn deo_expansion(addr: u16, state: *uxn) void = {
const op = state.ram[addr]; 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) { switch(op) {
case 0x00 => //fill case 0x00 => //fill
const bank = short_from_bytes(state.ram[addr+3],state.dev[addr+4]); const bank = short_from_bytes(state.ram[addr+3],state.ram[addr+4]);
const addr = short_from_bytes(state.ram[addr+5],state.dev[addr+6]); const addr = short_from_bytes(state.ram[addr+5],state.ram[addr+6]);
const value = state.ram[addr+7]; const value = state.ram[addr+7];
if(bank < numbanks) for(let i: u16 =0; i < length; i+=1){ if(bank < numbanks) for(let i: u16 =0; i < length; i+=1){
state.ram[bank * banksize + addr + i] = value; state.ram[bank * banksize + addr + i] = value;
}; };
case 0x01 => //cpyl case 0x01 => //cpyl
const srcbank = short_from_bytes(state.ram[addr+3],state.dev[addr+4]); const srcbank = short_from_bytes(state.ram[addr+3],state.ram[addr+4]);
const srcaddr = short_from_bytes(state.ram[addr+5],state.dev[addr+6]); const srcaddr = short_from_bytes(state.ram[addr+5],state.ram[addr+6]);
const dstbank = short_from_bytes(state.ram[addr+7],state.dev[addr+8]); const dstbank = short_from_bytes(state.ram[addr+7],state.ram[addr+8]);
const dstaddr = short_from_bytes(state.ram[addr+9],state.dev[addr+10]); 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){ if(srcbank < numbanks && dstbank < numbanks) for(let i: u16 =0; i < length; i+=1){
const readval = state.ram[srcbank * banksize + srcaddr + i]; const readval = state.ram[srcbank * banksize + srcaddr + i];
state.ram[dstbank * banksize + dstaddr + i] = readval; state.ram[dstbank * banksize + dstaddr + i] = readval;
}; };
case 0x02 => //cpr TODO are these actually different?? Either way need to not use for loop 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 srcbank = short_from_bytes(state.ram[addr+3],state.ram[addr+4]);
const srcaddr = short_from_bytes(state.ram[addr+5],state.dev[addr+6]); const srcaddr = short_from_bytes(state.ram[addr+5],state.ram[addr+6]);
const dstbank = short_from_bytes(state.ram[addr+7],state.dev[addr+8]); const dstbank = short_from_bytes(state.ram[addr+7],state.ram[addr+8]);
const dstaddr = short_from_bytes(state.ram[addr+9],state.dev[addr+10]); 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){ if(srcbank < numbanks && dstbank < numbanks) for(let i: u16 =0; i < length; i+=1){
const readval = state.ram[srcbank * banksize + srcaddr + i]; const readval = state.ram[srcbank * banksize + srcaddr + i];
state.ram[dstbank * banksize + dstaddr + i] = readval; state.ram[dstbank * banksize + dstaddr + i] = readval;