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