Extremely rough file reading working
This commit is contained in:
+116
-17
@@ -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<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 = {
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user