From f13459e452cc94c30caf172ebad0b32aa2dc414f Mon Sep 17 00:00:00 2001 From: mgcaret Date: Fri, 1 May 2020 23:09:05 -0700 Subject: [PATCH] GoSXB: ROMfs, emulator sleep, miscellaneous stuff --- .gitignore | 2 + platforms/GoSXB/build.sh | 8 ++ platforms/GoSXB/fcode/romfs.fs | 192 +++++++++++++++++++++++++++++++ platforms/GoSXB/gosxb-of816.sh | 6 +- platforms/GoSXB/mkromfs.rb | 56 +++++++++ platforms/GoSXB/platform-lib.s | 12 +- platforms/GoSXB/platform-words.s | 5 + 7 files changed, 278 insertions(+), 3 deletions(-) create mode 100644 platforms/GoSXB/fcode/romfs.fs create mode 100755 platforms/GoSXB/mkromfs.rb diff --git a/.gitignore b/.gitignore index 7eac325..37ddec4 100644 --- a/.gitignore +++ b/.gitignore @@ -13,5 +13,7 @@ romfs *.hex of816-neon.bin platforms/GoSXB/rom +platforms/GoSXB/romfs +platforms/GoSXB/romfs_files cov.yml diff --git a/platforms/GoSXB/build.sh b/platforms/GoSXB/build.sh index 288ad2e..3859f60 100755 --- a/platforms/GoSXB/build.sh +++ b/platforms/GoSXB/build.sh @@ -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 diff --git a/platforms/GoSXB/fcode/romfs.fs b/platforms/GoSXB/fcode/romfs.fs new file mode 100644 index 0000000..f9dc24d --- /dev/null +++ b/platforms/GoSXB/fcode/romfs.fs @@ -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 diff --git a/platforms/GoSXB/gosxb-of816.sh b/platforms/GoSXB/gosxb-of816.sh index 644d5f5..da31b89 100755 --- a/platforms/GoSXB/gosxb-of816.sh +++ b/platforms/GoSXB/gosxb-of816.sh @@ -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 diff --git a/platforms/GoSXB/mkromfs.rb b/platforms/GoSXB/mkromfs.rb new file mode 100755 index 0000000..557e8ac --- /dev/null +++ b/platforms/GoSXB/mkromfs.rb @@ -0,0 +1,56 @@ +#!/usr/bin/ruby + +@out_bytes = [] +@offset_map = {} +@nentries_offset = 4 + +def usage + abort("Usage: #{$0} [ ...]") +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) diff --git a/platforms/GoSXB/platform-lib.s b/platforms/GoSXB/platform-lib.s index edd2e0d..47c271d 100644 --- a/platforms/GoSXB/platform-lib.s +++ b/platforms/GoSXB/platform-lib.s @@ -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 diff --git a/platforms/GoSXB/platform-words.s b/platforms/GoSXB/platform-words.s index 14d789f..c60a9fa 100644 --- a/platforms/GoSXB/platform-words.s +++ b/platforms/GoSXB/platform-words.s @@ -4,3 +4,8 @@ dword dCPU_HZ,"$CPU_HZ" FCONSTANT cpu_clk eword +dword dROMFS,"$ROMFS" + ldy #.loword(romfs) + lda #.hiword(romfs) + PUSHNEXT +eword