diff --git a/bin/buildfileinfo.js b/bin/buildfileinfo.js new file mode 100644 index 000000000..7abd73a57 --- /dev/null +++ b/bin/buildfileinfo.js @@ -0,0 +1,7 @@ +a = new ActiveXObject("scripting.filesystemobject") +fileinfo = "" +for (b = new Enumerator(a.GetFolder(WScript.Arguments(0)).files); !b.atEnd(); b.moveNext()) +{ + fileinfo += "\r\n" + b.item().Name.toUpperCase() + "=Type(06),AuxType(4000),Access(C3)" +} +a.createtextfile(WScript.Arguments(0)+"\\_FileInformation.txt", 1).write(fileinfo.substring(2)) diff --git a/bin/buildproboot.js b/bin/buildproboot.js new file mode 100644 index 000000000..8a1f1e6f3 --- /dev/null +++ b/bin/buildproboot.js @@ -0,0 +1,7 @@ +a = new ActiveXObject("scripting.filesystemobject") +b = a.opentextfile(WScript.Arguments(0)) +c = b.read(0x40) +b.skip(0x200) +d = b.read(0x1fff600) +b.close() +b=a.createtextfile(WScript.Arguments(0), 1).write(c+a.opentextfile("res\\proboothd").read(512)+d) diff --git a/bin/do2po.js b/bin/do2po.js new file mode 100644 index 000000000..846523ce5 --- /dev/null +++ b/bin/do2po.js @@ -0,0 +1,39 @@ +kMap = [0x00, + 0x0E, + 0x0D, + 0x0C, + 0x0B, + 0x0A, + 0x09, + 0x08, + 0x07, + 0x06, + 0x05, + 0x04, + 0x03, + 0x02, + 0x01, + 0x0F + ] + +a = new ActiveXObject("scripting.filesystemobject") +for (b = new Enumerator(a.GetFolder(WScript.Arguments(0)).files); !b.atEnd(); b.moveNext()) +{ + if (a.GetExtensionName(b.item()).toLowerCase() == "dsk") + { + fi = a.opentextfile(b.item()) + fo = a.createtextfile(WScript.Arguments(1)+"\\"+a.GetBaseName(b.item())+".po", 1) + for (track = 0; track < 0x23; ++track) + { + sectors = new Array(0x10) + for (dos_sector = 0; dos_sector < 0x10; ++dos_sector) + { + sectors[kMap[dos_sector]] = fi.read(256) + } + for (dos_sector = 0; dos_sector < 0x10; ++dos_sector) + { + fo.write(sectors[dos_sector]) + } + } + } +} diff --git a/res/demo/WAVY.NAVY b/res/demo/WAVY.NAVY index b96a3a6f7..78c2ebb33 100644 Binary files a/res/demo/WAVY.NAVY and b/res/demo/WAVY.NAVY differ diff --git a/res/demo/WAVY.NAVY.1 b/res/demo/WAVY.NAVY.1 new file mode 100644 index 000000000..b96a3a6f7 Binary files /dev/null and b/res/demo/WAVY.NAVY.1 differ diff --git a/res/demo/WAVY.NAVY.LOADER b/res/demo/WAVY.NAVY.LOADER deleted file mode 100644 index 78c2ebb33..000000000 Binary files a/res/demo/WAVY.NAVY.LOADER and /dev/null differ diff --git a/res/demo/_FileInformation.txt b/res/demo/_FileInformation.txt index 480803375..507e5f778 100644 --- a/res/demo/_FileInformation.txt +++ b/res/demo/_FileInformation.txt @@ -1,2 +1,2 @@ WAVY.NAVY=Type(06),AuxType(0800),Access(C3) -#WAVY.NAVY.1=Type(06),AuxType(0000),Access(C3) +WAVY.NAVY.1=Type(06),AuxType(0000),Access(C3) diff --git a/res/proboothd b/res/proboothd new file mode 100644 index 000000000..105727915 Binary files /dev/null and b/res/proboothd differ diff --git a/res/proboothd.s b/res/proboothd.s new file mode 100644 index 000000000..c4f02f003 --- /dev/null +++ b/res/proboothd.s @@ -0,0 +1,135 @@ +;license:BSD-3-Clause +;minimal open/read binary file in ProDOS filesystem +;copyright (c) Peter Ferrie 2016-2018 +!cpu 6502 +!to "proboothd",plain +*=$800 + + ;zpage usage, arbitrary selection except for the "ProDOS constant" ones + command = $42 ;ProDOS constant + unit = $43 ;ProDOS constant + adrlo = $44 ;ProDOS constant + adrhi = $45 ;ProDOS constant + bloklo = $46 ;ProDOS constant + blokhi = $47 ;ProDOS constant + + A2L = $3e + A2H = $3f + sizehi = $53 + + ;constants + scrn2p2 = $f87b + dirbuf = $1e00 ;for size-optimisation + + !byte 1 + tay +- txa + jsr scrn2p2 + ora #$c0 + sta $be30, y + sta slot+2 + sta entry+2 +slot lda $cfff + sta entry+1 + + lda fakeMLI_e-$100, y + sta $be00+fakeMLI_e-fakeMLI, y + iny + bne - + stx $bf30 + sty $200 + +opendir ;read volume directory key block + ldx #2 + + ;include volume directory header in count + +firstent lda #>dirbuf + sta adrhi + sta A2H + jsr seekread + lda #4 + sta A2L +nextent ldy #0 + + ;match name lengths before attempting to match names + + lda (A2L), y + and #$0f + tax + inx +- cmp filename, y + beq foundname + + ;move to next directory in this block + + clc + lda A2L + adc #$27 + sta A2L + bcc + + + ;there can be only one page crossed, so we can increment instead of adc + + inc A2H ++ cmp #$ff ;4+($27*$0d) + bne nextent + + ;read next directory block when we reach the end of this block + + ldx dirbuf+2 + ldy dirbuf+3 + bcs firstent + +foundname iny + lda (A2L), y + dex + bne - + stx $ff + + ;cache KEY_POINTER + + ldy #$11 + lda (A2L), y + tax + iny + lda (A2L), y + tay + +readfile jsr seekread + inc adrhi + inc adrhi + + ;fetch data block and read it + +blockind ldy $ff + inc $ff + ldx dirbuf, y + lda dirbuf+256, y + tay + bne readfile + txa + bne readfile + +readdone jmp $2000 + +seekread stx bloklo + sty blokhi +entry jmp $d1d1 + +fakeMLI pla + tax + inx + inx + inx + txa + pha + rts +fakeMLI_e + +filename !byte filename_e - filename_b +filename_b !text "LAUNCHER.SYSTEM" ;your start-up file, file is max 40kb +filename_e + +*=$9f8 +!byte $D3,$C1,$CE,$A0,$C9,$CE,$C3,$AE diff --git a/src/4cade.a b/src/4cade.a index 57677c443..935e5d912 100644 --- a/src/4cade.a +++ b/src/4cade.a @@ -149,6 +149,11 @@ AttractMode sta $100,x dex bpl - + ldx #(end_promote-promote-1) +- lda promote,x ; copy tiny ProDOS to main memory + sta $bf00,x + dex + bpl - jmp $100 ; jump to pre-launch code @prelaunch ; this runs from main memory +READ_ROM_NO_WRITE @@ -249,6 +254,35 @@ WaitOnScreenshot @burn3 jsr Exit Exit rts +promote +!pseudopc $bf00 { + lda $c08b + clc + bcc @do_enter +;$bf06 + rts ;clock interface, must be RTS on real ProDOS if program uses $20x +@do_enter + lda $c08b + jmp ProDOS_enter + !text "q4!" +;$bf10 + !word $c1d1, $c2d1, $c3d1, $c4d1, $c5d1, $c6d1, $c7d1 +ProDOS_exit + lda $c081 + pla ;saved inside ProDOS_enter + tay + pla + tax + lda #0 + rts +ProDOS_fatal ;only for debugging, will be removed + lda $c081 + jsr $fe89 + jsr $fe93 + jmp $ff3a +} +end_promote + Reboot ldx #(@end-@start-1) - lda @start,x @@ -272,6 +306,7 @@ Home ; this will be run from main memory +READ_ROM_NO_WRITE sta $C00C ; get out of DHGR mode + sta $C05F ; get out of DHGR mode jsr $FB2F ; TEXT jsr $FC58 ; HOME +READ_RAM1_WRITE_RAM1 diff --git a/src/glue.prorwts2.a b/src/glue.prorwts2.a index 504bd13c3..e3e216f42 100644 --- a/src/glue.prorwts2.a +++ b/src/glue.prorwts2.a @@ -10,6 +10,8 @@ gRootDirectory !word $FDFD +gPrefix + !word $FDFD ;------------------------------------------------------------------------------ ; LoadFile @@ -27,6 +29,7 @@ LoadFile +PARAMS_ON_STACK 2 +LDPARAM 1 +STAY namlo ; set filename + +STAY gPrefix ; remember path jsr traverse ; go to subdirectory, set up filename for read @@ -179,3 +182,209 @@ traverse sta (namlo), y @go rts + +;------------------------------------------------------------------------------ +; ProDOS_enter +; intercept certain ProDOS requests +; wrap them to ProRWTS2 file requests +; +; in: return address+1 is command and pointer to parameter block +; out: all flags clobbered +; A=0, X and Y preserved +; stack set to next instruction after parameters +; +; to do: preserve non-$4x zpage locations for titles that open files after start +; enable seek +; enable < 512 bytes reads +;------------------------------------------------------------------------------ +packet = $40 ;word +buffer = $42 ;word +ProDOS_enter + pla + sta @fetchaddr+1 + pla + sta @fetchaddr+2 + jsr @fetchbyte + sta @request+1 + jsr @fetchbyte + sta packet + jsr @fetchbyte + sta packet+1 + lda @fetchaddr+2 + pha + lda @fetchaddr+1 + pha + txa + pha + tya + pha +@request + lda #$d1 + cmp #$c7 + beq @do_prefix + cmp #$c8 + beq @do_open + cmp #$ca + beq @do_read + cmp #$cb + beq @do_write + cmp #$cc + beq @do_close +;; cmp #$ce +;; beq @do_seek + ;;any others?? + jmp ProDOS_fatal +@do_prefix + jsr @imp_prefix + jmp ProDOS_exit +@do_open + jsr @imp_open + jmp ProDOS_exit +@do_read + jsr @imp_read + jmp ProDOS_exit +@do_write + jsr @imp_write + jmp ProDOS_exit +@do_close + jsr @imp_close + jmp ProDOS_exit +;;@do_seek +;; jsr @imp_seek +;; jmp ProDOS_exit + + +PREV_BLOCK_LO = $0 ;ProDOS constant +PREV_BLOCK_HI = $1 ;ProDOS constant +@imp_prefix + ldx #buffer + jsr @setbuffer1 + lda gPrefix + sta packet + lda gPrefix+1 + sta packet+1 + ldy #0 + lda (packet), y + tax + inx + !byte $2c +@copy_prefix + lda (packet), y + iny + iny + iny + cmp #$2e + bcs @skip_slash1 + lda #'/' +@skip_slash1 + sta (buffer), y + bcs @skip_slash2 + tya + ldy #0 + sta (buffer), y + tay +@skip_slash2 + dey + dey + dex + bne @copy_prefix + ldy #1 + lda #'/' + sta (buffer), y + iny + lda #'X' + sta (buffer), y + rts + +@imp_open + ldx #namlo + jsr @setbuffer1 + iny + inc @handles+1 +@handles + ldx #0 + iny + lda (packet), y + sta @handle-1, x + iny + txa + sta (packet), y + rts + +@imp_read + lda #cmdread + !byte $2c +@imp_write + lda #cmdwrite + sta reqcmd + jsr @set_rdwrbuff + jmp hddopendir + +@imp_close + dec @handles+1 + bne @close_ret + lda #$b1 + sta overridepatch1 + sta overridepatch2 + lda #bloklo + sta overridepatch1+1 + sta overridepatch2+1 + lda #>hdddirbuf + +@patch_buffer + sta bufferpatch2+2 + sta bufferpatch3+2 + sta bufferpatch4+2 + sta bufferpatch6+1 + sta bufferpatch7+2 + sta bufferpatch9+2 + sta bufferpatch10+1 + tax + inx + stx bufferpatch5+2 + stx bufferpatch8+2 + dex + dex + stx bufferpatch1+1 +@close_ret + rts + +@fetchbyte + inc @fetchaddr+1 + bne @fetchaddr + lda @fetchaddr+2 +@fetchaddr + lda $d1d1 + rts + +@set_rdwrbuff + ldy #1 + lda (packet), y + tax + lda @handle-1,x + jsr @patch_buffer + lda #$a9 + sta overridepatch1 + sta overridepatch2 + iny + lda (packet), y + sta overridepatch1+1 + iny + lda (packet), y + sta overridepatch2+1 + ldx #sizelo + iny + !byte $2c +@setbuffer1 + ldy #1 + +@setbuffer + lda (packet), y + sta $0,x + iny + lda (packet), y + sta $1,x + rts + +@handle + !byte 0, 0 ;only up to two handles at a time diff --git a/src/prorwts2.a b/src/prorwts2.a index f29bb4c6c..5ed62a33e 100644 --- a/src/prorwts2.a +++ b/src/prorwts2.a @@ -1925,6 +1925,7 @@ unrhddblockhi = unrelochdd + (* - reloc) hddreaddir ;note that calling this location directly limits subdirectories to 14 entries! lda #NAME_LENGTH + ENTRY_SIZE hddfirstent sta bloklo +bufferpatch1 lda #>(hdddirbuf - 1) sta blokhi @@ -1999,7 +2000,9 @@ hddnextent ldy #0 ;read next directory block when we reach the end of this block +bufferpatch2 ldx hdddirbuf + NEXT_BLOCK_LO +bufferpatch3 lda hdddirbuf + NEXT_BLOCK_HI jsr hddreaddirsec lda #NAME_LENGTH @@ -2088,11 +2091,13 @@ hddfoundname iny !if override_adr = 0 { ldy #AUX_TYPE +overridepatch1 lda (bloklo), y !if (allow_subdir + allow_saplings + allow_trees + (aligned_read xor 1)) > 0 { sta ldrlo sta ldrlo2 iny +overridepatch2 lda (bloklo), y sta ldrhi sta ldrhi2 @@ -2110,12 +2115,14 @@ hddfoundname iny lda (bloklo), y tax !if (allow_subdir + allow_saplings + allow_trees) > 0 { +bufferpatch4 sta hdddirbuf !if (allow_trees + (fast_trees xor 1)) > 1 { sta treeblklo } ;allow_trees = 1 and fast_trees = 0 iny lda (bloklo), y +bufferpatch5 sta hdddirbuf + 256 !if (allow_trees + (fast_trees xor 1)) > 1 { sta treeblkhi @@ -2187,6 +2194,7 @@ hddrdwrfilei bcc + ldy #2 sty sizehi +bufferpatch6 ldx #>hdddirbuf lda #0 !if aligned_read = 0 { @@ -2478,7 +2486,9 @@ skiptree sty lastblk } ;rwts_mode +bufferpatch7 ldx hdddirbuf, y +bufferpatch8 lda hdddirbuf + 256, y !if detect_treof = 1 { bne noteof2 @@ -2492,6 +2502,7 @@ noteof2 } ;detect_treof !if allow_sparse = 1 { pha +bufferpatch9 ora hdddirbuf, y tay pla @@ -2663,6 +2674,7 @@ hddreaddirsel hddreaddirsec !if allow_trees = 0 { +bufferpatch10 hddreaddirsect ldy #>hdddirbuf } else { ;allow_trees = 1 ldy #>hdddirbuf diff --git a/winmake.bat b/winmake.bat new file mode 100644 index 000000000..e0dac4a10 --- /dev/null +++ b/winmake.bat @@ -0,0 +1,78 @@ +@echo off +rem +rem 4cade Makefile for Windows +rem assembles source code, optionally builds a disk image +rem +rem a qkumba monstrosity from 2018-10-29 +rem + +set DISK=4cade.2mg +set VOLUME=A.4AM.PACK + +rem third-party tools required to build (must be in path) +rem https://sourceforge.net/projects/acme-crossass/ +set ACME=acme +rem https://www.brutaldeluxe.fr/products/crossdevtools/cadius/ +rem https://github.com/mach-kernel/cadius +set CADIUS=cadius + +if "%1" equ "asm" ( +:asm +2>nul md build +2>nul md build\po +2>nul md build\X +2>nul md build\HGR +2>nul md build\DHGR +2>nul md build\SS +2>nul md build\DEMO +2>nul md build\FX + +%ACME% -r build\4cade.lst src\4cade.a +%ACME% src\fx\fx.hgr.diagonal.a +%ACME% src\fx\fx.hgr.iris.a +%ACME% src\fx\fx.hgr.interlock.ud.a +%ACME% src\fx\fx.hgr.interlock.lr.a +%ACME% src\fx\fx.hgr.spiral.a +%ACME% src\fx\fx.hgr.fizzle.a +%ACME% src\fx\fx.hgr.bar.dissolve.a +goto :EOF +) + +if "%1" equ "clean" ( +:clean +echo y|1>nul 2>nul rd build /s +goto :EOF +) + +if "%1" equ "dsk" ( +:dsk +call :asm +2>nul del build\log +%CADIUS% CREATEVOLUME "build\%DISK%" "%VOLUME%" 32766KB >>build\log +1>nul copy /y res\_FileInformation.txt build\ >>build\log +cscript /nologo bin/buildproboot.js "build\%DISK%" +%CADIUS% ADDFILE "build\%DISK%" "/%VOLUME%/" "res\PRODOS" >>build\log +%CADIUS% ADDFILE "build\%DISK%" "/%VOLUME%/" "build\LAUNCHER.SYSTEM" >>build\log +%CADIUS% CREATEFOLDER "build\%DISK%" "/%VOLUME%/X/" >>build\log +%CADIUS% ADDFILE "build\%DISK%" "/%VOLUME%/" "res\GAMES.CONF" >>build\log +%CADIUS% ADDFILE "build\%DISK%" "/%VOLUME%/" "res\ATTRACT.CONF" >>build\log +%CADIUS% ADDFILE "build\%DISK%" "/%VOLUME%/" "res\FX.CONF" >>build\log +%CADIUS% ADDFILE "build\%DISK%" "/%VOLUME%/" "res\COVER" >>build\log +%CADIUS% ADDFILE "build\%DISK%" "/%VOLUME%/" "res\COVER.A2FC" >>build\log +1>nul copy /y res\hgr\* build\HGR >>build\log +cscript /nologo bin/buildfileinfo.js build\HGR >>build\log +%CADIUS% ADDFOLDER "build\%DISK%" "/%VOLUME%/HGR" "build/HGR" >>build/log +1>nul copy /y res\dhgr\* build\DHGR >>build\log +cscript /nologo bin/buildfileinfo.js build\DHGR >>build\log +%CADIUS% ADDFOLDER "build\%DISK%" "/%VOLUME%/DHGR" "build/DHGR" >>build\log +1>nul copy /y res\ss\* build\SS >>build\log +%CADIUS% ADDFOLDER "build\%DISK%" "/%VOLUME%/SS" "build/SS" >>build\log +1>nul copy /y res\demo\* build\DEMO >>build\log +%CADIUS% ADDFOLDER "build\%DISK%" "/%VOLUME%/DEMO" "build/DEMO" >>build\log +1>nul copy /y res\fx\* build\FX >>build\log +%CADIUS% ADDFOLDER "build\%DISK%" "/%VOLUME%/FX" "build/FX" >>build\log +cscript /nologo bin/do2po.js res\dsk\ build\po\ +goto :EOF +) + +echo usage: %0 clean / asm / dsk