GoSXB: ROMfs, emulator sleep, miscellaneous stuff

This commit is contained in:
mgcaret 2020-05-01 23:09:05 -07:00
parent edef1c80b7
commit f13459e452
7 changed files with 278 additions and 3 deletions

2
.gitignore vendored
View File

@ -13,5 +13,7 @@ romfs
*.hex
of816-neon.bin
platforms/GoSXB/rom
platforms/GoSXB/romfs
platforms/GoSXB/romfs_files
cov.yml

View File

@ -1,6 +1,14 @@
#!/bin/bash
set -e -x
cd $(dirname $0)
if [ -r fcode/romfs.fs ]; then
toke fcode/romfs.fs
fi
if [ -d romfs_files ]; then
cd romfs_files
../mkromfs.rb ../romfs *
cd ..
fi
ca65 -I ../../inc GoSXB.s -l GoSXB.lst
../../build.sh GoSXB
ld65 -C GoSXB.l -S 0x8000 GoSXB.o ../../forth.o -m forth.map -o forth

View File

@ -0,0 +1,192 @@
\ GoSXB ROM Filesystem
\ Since the GoSXB has the ability to have unbanked ROM, this is much easier than a stock
\ WDC board
\ This ROMfs supports:
\ * up to 255 files
\ * name lengths up to 255 bytes,
\ * include/included for forth text
\ * load/loaded for FCode
\ * AUTOSTART file automatically executed
\ future: optionally have file access words such as open-file, read-file, and friends
start1 hex
." GoSXB ROMfs by M.G. ... "
s" vocabulary ROMfs also ROMfs definitions" eval
headerless
\ header structure
struct
4 field >magic
1 field >nentries
0 field >catalog
drop \ no need for struct size, catalog is variable
\ file entry structure
struct
4 field >offset \ relative to >magic, if 0: no more and rest of struct invalid
4 field >size
1 field >namelen
0 field >name
constant $entry-hdr-size
defer parse-word
s" parse-word" $find drop to parse-word
headers
\ romfs location
0 value $$romfs-addr
[ifdef] file-access-words
0 value $$romfs-tab
[endif]
\ temp vars for file I/O and such
0 value $curentry
: $romfs-first
$$romfs-addr >catalog to $curentry
;
: $romfs-next
$curentry dup >namelen c@ $entry-hdr-size + + to $curentry
;
: $romfs-entname ( -- addr len )
$curentry >name $curentry >namelen c@
;
: $romfs-nfiles ( -- count )
$$romfs-addr dup if
>nentries c@
then
;
\ scan a 65816 bank for ROMfs, every $1000 bytes
: $romfs-find-bank ( bank -- )
d# 16 << \ convert bank addr to upper byte
ffff 0 do dup i + \ address to probe (middle byte)
dup @ 5346474D = \ compare with magic
if to $$romfs-addr leave else drop then
1000 +loop
drop
;
\ scan banks $20-$2F for ROMfs
: $romfs-find ( -- )
30 20 do $$romfs-addr if leave else i $romfs-find-bank then loop
[ifdef] file-access-words
$$romfs-addr if
$romfs-nfiles 2* cells dup alloc-mem dup to $$romfs-tab swap erase
then
[endif]
;
[ifdef] file-access-words
\ return address or throw exception
: $romfs-addr ( -- addr )
$$romfs-addr ?dup 0= if d# -37 throw then
;
[endif]
external
: romfs-list ( -- )
$romfs-nfiles dup if
$romfs-first
0 do
$romfs-entname type cr
$romfs-next
loop
else
drop
then
;
: romfs-lookup ( addr len -- addr2 len2 | false )
$romfs-nfiles dup if
>r true -rot r>
$romfs-first
0 do
dup $curentry >namelen c@ = if
2dup $curentry >name swap comp
0= if
2drop drop false
$curentry >offset @ $$romfs-addr +
$curentry >size @
leave
then
then
$romfs-next
loop
rot if
\ either
\ 2drop
\ or
type ." not found!" cr
false
then
else
nip nip
then
;
external
\ See if file exists, if so, eval as text or load as FCode depending on first
\ byte
: ?romfs-run ( addr u -- ... )
romfs-lookup
dup if
over c@ 8 = if
\ is probably FCode
drop 1 1 byte-load
else
\ is hopefully text
eval
then
else
drop \ hope it wasn't zero bytes long...
then
;
: included ( c-addr u -- ... )
romfs-lookup dup if
eval
else
d# -69 throw
then
;
: include ( "< >name" -- ...)
parse-word included
;
: fc-loaded ( c-addr u -- ... )
romfs-lookup dup if
drop 1 byte-load
else
d# -69 throw
then
;
: fc-load ( "< >name" -- ... )
parse-word fc-loaded
;
headers
$romfs-find
s" previous definitions" eval
." loaded!" cr
$$romfs-addr ?dup if ." ROMfs at " u. cr then
s" AUTOEXEC" ?romfs-run
fcode-end

View File

@ -1,4 +1,8 @@
#!/bin/bash
EXEBIN=${GOSXB:-gosxb}
cd `dirname $0`
exec ${EXEBIN} -load 0x200000:forth -rom-bank 0x20 -rom-file rom
ROMFSOPTS=
if [ -r romfs ]; then
ROMFSOPTS="-load 0x220000:romfs -rom-bank 0x22"
fi
exec ${EXEBIN} -load 0x200000:forth -rom-bank 0x20 ${ROMFSOPTS} -rom-file rom

56
platforms/GoSXB/mkromfs.rb Executable file
View File

@ -0,0 +1,56 @@
#!/usr/bin/ruby
@out_bytes = []
@offset_map = {}
@nentries_offset = 4
def usage
abort("Usage: #{$0} <outfile> <infile> [<infile> ...]")
end
def new_romfs
@out_bytes = [0x4D, 0x47, 0x46, 0x53, 0x00]
end
def set_int32(offset, num)
@out_bytes[offset+0] = num & 0xFF
@out_bytes[offset+1] = num >> 8 & 0xFF
@out_bytes[offset+2] = num >> 16 & 0xFF
@out_bytes[offset+3] = num >> 24 & 0xFF
end
def add_int32(num)
@out_bytes += [num & 0xFF]
@out_bytes += [num >> 8 & 0xFF]
@out_bytes += [num >> 16 & 0xFF]
@out_bytes += [num >> 24 & 0xFF]
end
def add_file_header(name, size)
@offset_map[name] = @out_bytes.length
add_int32(0) # offset
add_int32(size)
@out_bytes += [name.length]
@out_bytes += name.bytes
@out_bytes[@nentries_offset] += 1
end
outfile = ARGV.shift || usage
usage if ARGV.empty?
abort("Too many files (>15)") if ARGV.count > 255
new_romfs
ARGV.each do |name|
add_file_header(name, File.size(name))
end
@offset_map.each_pair do |name, offset|
set_int32(offset, @out_bytes.length)
data = File.read(name)
@out_bytes += data.bytes
end
File.write(outfile, @out_bytes.map(&:chr).join)

View File

@ -185,7 +185,7 @@ wait: phx ; note 8-bit mode!
txa
sta f:VIA2+VIA::ORB ; strobe FT245RL WR low
lda VIA2+VIA::IRA ; get output byte back (we don't really need it)
xba
xba
lda #$00
sta f:VIA2+VIA::DDRA ; switch DDR A back to input
xba
@ -223,7 +223,8 @@ wait: phx ; note 8-bit mode!
.i8
lda #$00
sta f:VIA2+VIA::DDRA ; Ensure VIA2 DDR A is set up for input
: lda f:VIA2+VIA::IRB ; wait for FT245RL to have data & be ready
: wdm $10 ; cause emulator to sleep if no data ready
lda f:VIA2+VIA::IRB ; wait for FT245RL to have data & be ready
bit #%00000010 ; b1 = TUSB_RXFB
bne :-
lda f:VIA2+VIA::IRB
@ -261,11 +262,18 @@ wait: phx ; note 8-bit mode!
jmp _sf_success
.if include_fcode
list:
.dword romfs
.dword 0
.endif
.endproc
.if include_fcode
.proc romfs
PLATFORM_INCBIN "fcode/romfs.fc"
.endproc
.endif
; SXB really can't do this when ROM is banked out. Maybe restart Forth instead?
.proc _sf_reset_all
plx

View File

@ -4,3 +4,8 @@ dword dCPU_HZ,"$CPU_HZ"
FCONSTANT cpu_clk
eword
dword dROMFS,"$ROMFS"
ldy #.loword(romfs)
lda #.hiword(romfs)
PUSHNEXT
eword