From d21e074f278029a9d2a4e37b4cc1f848d642a59d Mon Sep 17 00:00:00 2001 From: 4am Date: Thu, 23 Aug 2018 16:02:48 -0400 Subject: [PATCH] . --- Makefile | 31 ++- bin/do2po.py | 33 +++ bin/extract.py | 9 + res/COVER | Bin 0 -> 8192 bytes res/COVER.A2FC | Bin 0 -> 16384 bytes res/PRODOS | Bin 0 -> 17128 bytes res/_FileInformation.txt | 4 + src/4cade.a | 53 ++++ src/constants.a | 10 + src/macros.a | 63 +++++ src/prodos.mli.a | 455 +++++++++++++++++++++++++++++++++ src/{PRORWTS2.S => prorwts2.a} | 8 +- 12 files changed, 650 insertions(+), 16 deletions(-) create mode 100755 bin/do2po.py create mode 100755 bin/extract.py create mode 100644 res/COVER create mode 100644 res/COVER.A2FC create mode 100644 res/PRODOS create mode 100644 res/_FileInformation.txt create mode 100644 src/4cade.a create mode 100644 src/constants.a create mode 100644 src/macros.a create mode 100644 src/prodos.mli.a rename src/{PRORWTS2.S => prorwts2.a} (99%) diff --git a/Makefile b/Makefile index dfa5dc00b..ede737de6 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ # DISK=4cade.2mg +VOLUME=A.4AM.PACK # third-party tools required to build # https://sourceforge.net/projects/acme-crossass/ @@ -19,26 +20,34 @@ ACME=acme CADIUS=cadius asm: md - $(ACME) -r build/prorwts2.lst src/PRORWTS2.S + $(ACME) -r build/4cade.lst src/4cade.a dsk: md asm - cadius CREATEVOLUME build/"$(DISK)" "A.4AM.PACK" 32MB -# cp res/_FileInformation.txt build/ -# bin/fixFileInformation.sh build/_FileInformation.txt -# $(CADIUS) ADDFILE build/"$(DISK)" "/A.4AM.PACK/" "res/CREDITS.TXT" -# $(CADIUS) CREATEFOLDER build/"$(DISK)" "/A.4AM.PACK/LIB/" -# $(CADIUS) ADDFILE build/"$(DISK)" "/A.4AM.PACK/LIB/" "build/ONBEYONDZ1" + $(CADIUS) CREATEVOLUME build/"$(DISK)" "${VOLUME}" 32766KB >/dev/null + cp res/_FileInformation.txt build/ + $(CADIUS) ADDFILE build/"$(DISK)" "/${VOLUME}/" "res/PRODOS" >/dev/null + $(CADIUS) ADDFILE build/"$(DISK)" "/${VOLUME}/" "build/LAUNCHER.SYSTEM" >/dev/null + $(CADIUS) ADDFILE build/"$(DISK)" "/${VOLUME}/" "res/COVER" >/dev/null + $(CADIUS) ADDFILE build/"$(DISK)" "/${VOLUME}/" "res/COVER.A2FC" >/dev/null + $(CADIUS) CREATEFOLDER build/"$(DISK)" "/${VOLUME}/X/" >/dev/null + bin/do2po.py res/dsk/ build/po/ + rsync -a res/dsk/*.po build/po/ + bin/extract.py build/po/ | sh + rm -f build/X/**/.DS_Store + rm -f build/X/**/PRODOS + $(CADIUS) ADDFOLDER build/"$(DISK)" "/${VOLUME}/X" "build/X" artwork: dsk - $(CADIUS) ADDFOLDER build/"$(DISK)" "/A.4AM.PACK/ARTWORK" "res/artwork" -# $(CADIUS) ADDFILE build/"$(DISK)" "/A.4AM.PACK/ARTWORK/" "res/DHRSLIDE.SYSTEM" -# $(CADIUS) ADDFOLDER build/"$(DISK)" "/A.4AM.PACK/ARTWORKGS" "res/artworkgs" +# $(CADIUS) ADDFOLDER build/"$(DISK)" "/${VOLUME}/ARTWORK" "res/artwork" +# $(CADIUS) ADDFILE build/"$(DISK)" "/${VOLUME}/ARTWORK/" "res/DHRSLIDE.SYSTEM" +# $(CADIUS) ADDFOLDER build/"$(DISK)" "/${VOLUME}/ARTWORKGS" "res/artworkgs" mount: dsk osascript bin/V2Make.scpt "`pwd`" bin/4cade.vii build/"$(DISK)" md: - mkdir -p build + mkdir -p build/po + mkdir -p build/X clean: rm -rf build/ diff --git a/bin/do2po.py b/bin/do2po.py new file mode 100755 index 000000000..12244be60 --- /dev/null +++ b/bin/do2po.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 + +import sys +import glob +import os.path + +kMap = {0x00: 0x00, + 0x07: 0x08, + 0x0E: 0x01, + 0x06: 0x09, + 0x0D: 0x02, + 0x05: 0x0A, + 0x0C: 0x03, + 0x04: 0x0B, + 0x0B: 0x04, + 0x03: 0x0C, + 0x0A: 0x05, + 0x02: 0x0D, + 0x09: 0x06, + 0x01: 0x0E, + 0x08: 0x07, + 0x0F: 0x0F} + +indir, outdir = sys.argv[1:3] + +for infile in glob.glob(os.path.join(indir, "*.dsk")): + outfile = os.path.join(outdir, os.path.splitext(os.path.basename(infile))[0] + ".po") + with open(infile, 'rb') as f, open(outfile, 'wb') as g: + for track in range(0, 0x23): + sectors = [bytes(256)] * 0x10 + for dos_sector in range(0, 0x10): + sectors[kMap[dos_sector]] = f.read(256) + g.write(b"".join(sectors)) diff --git a/bin/extract.py b/bin/extract.py new file mode 100755 index 000000000..6d98061a7 --- /dev/null +++ b/bin/extract.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python3 + +import sys +import glob +import os.path + +indir = sys.argv[1] +for infile in glob.glob(os.path.join(indir, "*.po")): + print("cadius EXTRACTVOLUME \"" + infile + "\" build/X/ || cadius EXTRACTVOLUME \"" + infile + "\" build/X/") diff --git a/res/COVER b/res/COVER new file mode 100644 index 0000000000000000000000000000000000000000..c416e5de572a20449b2061c448b0b59488747d9a GIT binary patch literal 8192 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 Be*XXf literal 0 HcmV?d00001 diff --git a/res/COVER.A2FC b/res/COVER.A2FC new file mode 100644 index 0000000000000000000000000000000000000000..43a475b69dbce2f454ae2ee7f607f83b23048229 GIT binary patch literal 16384 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 BlbQek literal 0 HcmV?d00001 diff --git a/res/PRODOS b/res/PRODOS new file mode 100644 index 0000000000000000000000000000000000000000..a701ba0fe5f8ec83998d9ea99e88cb974b75a8fd GIT binary patch literal 17128 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 z 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 +; sta namhi +; lda #0 +; sta sizelo +; lda #$20 +; sta sizehi +; jsr hddopendir +; bit $C055 +; bit $C052 +; bit $C057 +; bit $C050 +- lda #0 + beq - + +cover !byte cover_e-cover_b +cover_b !text "COVER" +cover_e + +;LoadDHGR +; sta $C000 +; ldx #$20 ; copy $2000 bytes to auxmem +; stx @copya+2 +; stx @copyb+2 +; ldy #0 +;@writeToAuxLoop +; sta $C005 +;@copya lda $FF00, y +;@copyb sta $FF00, y +; iny +; bne @copya +; sta $C004 +; inc @copya+2 +; inc @copyb+2 +; dex +; bne @writeToAuxLoop diff --git a/src/constants.a b/src/constants.a new file mode 100644 index 000000000..80191f6ad --- /dev/null +++ b/src/constants.a @@ -0,0 +1,10 @@ +;license:MIT +;(c) 2018 by 4am +; + +; zero page +PARAM = $00 ; used by PARAMS_ON_STACK macro, so basically everywhere +PTR = $02 +SRC = $04 +DEST = $06 +SAVE = $08 diff --git a/src/macros.a b/src/macros.a new file mode 100644 index 000000000..1209b136e --- /dev/null +++ b/src/macros.a @@ -0,0 +1,63 @@ +;license:MIT +;(c) 2018 by 4am +; +; common assembler macros +; + +; for functions that take parameters on the stack +; set (PARAM) to point to the parameters and +; move the stack pointer to the first byte after the parameters +; clobbers A,X +!macro PARAMS_ON_STACK .bytes { + pla + sta PARAM + plx + stx PARAM+1 + lda #.bytes + clc + adc PARAM + bcc + + inx ++ phx + pha +} + +; for functions that take parameters on the stack +; load a 16-bit value from the parameters on the stack into A (low) and Y (high) +; (assumes PARAMS_ON_STACK was used first) +!macro LDPARAM .offset { + ldy #.offset+1 + lda (PARAM),y + pha + dey + lda (PARAM),y + ply +} + +; load the address of .ptr into A (low) and Y (high) +!macro LDADDR .ptr { + lda #<.ptr + ldy #>.ptr +} + +; load a 16-bit value into A (low) and Y (high) +!macro LDAY .ptr { + lda .ptr + ldy .ptr+1 +} + +; store a 16-bit value from A (low) and Y (high) +!macro STAY .ptr { + sta .ptr + sty .ptr+1 +} + +; use BIT to swallow the following 1-byte opcode +!macro HIDE_NEXT_BYTE { + !byte $24 +} + +; use BIT to swallow the following 2-byte opcode +!macro HIDE_NEXT_2_BYTES { + !byte $2C +} diff --git a/src/prodos.mli.a b/src/prodos.mli.a new file mode 100644 index 000000000..fb9cb3e1e --- /dev/null +++ b/src/prodos.mli.a @@ -0,0 +1,455 @@ +;license:MIT +;(c) 2017-8 by 4am +; +; ProDOS - file and other MLI routines +; +; Public functions +; - LoadFile +; - LoadDHRFile +; - LoadSHRFile +; - SaveFile +; - SetPrefix +; - GetFileInfo +; + +; MLI command codes +CMD_QUIT = $65 ; quit to ProDOS +CMD_CREATE = $C0 ; create new file +CMD_DESTROY = $C1 ; delete a file +CMD_SETFILEINFO= $C3 ; set file info +CMD_GETFILEINFO= $C4 ; get file (or volume) info +CMD_SETPREFIX = $C6 ; change default pathname prefix +CMD_OPEN = $C8 ; open a file +CMD_READ = $CA ; read an open file +CMD_WRITE = $CB ; write to an open file +CMD_CLOSE = $CC ; close an open file + +; MLI parameter counts +PC_QUIT = $04 +PC_CREATE = $07 +PC_DESTROY = $01 +PC_SETFILEINFO = $07 +PC_GETFILEINFO = $0A +PC_SETPREFIX = $01 +PC_OPEN = $03 +PC_READ = $04 +PC_WRITE = $04 +PC_CLOSE = $01 + +; ROM addresses +PRODOSMLI = $BF00 ; [callable] MLI entry point +MACHID = $BF98 ; machine identification byte + +kAccessBits = $C3 ; full access (used in SaveFile) + +;------------------------------- +; LoadFile +; load a file into memory all at once, using ProDOS MLI calls +; +; in: stack contains 6 bytes of parameters: +; +1 address of pathname +; +3 address of data buffer (to receive file contents) +; +5 address of ProDOS file buffer +; out: if C set, load failed and A contains error code +; from open or read +; if C clear, load succeeded and ($02) contains +; data loaded from file +; all other flags clobbered +; all registers clobbered +; stack set to next instruction after parameters +;------------------------------- +LoadFile + +PARAMS_ON_STACK 6 + + +LDPARAM 1 + +STAY mliparam+1 ; pathname + +LDPARAM 5 + +STAY mliparam+3 ; ProDOS file buffer + + jsr _openfile + bcs @exit ; C set on error + + pha ; push file reference number + +LDPARAM 3 + +STAY mliparam+2 ; data buffer + lda #$FF + sta mliparam+4 ; max data length (unlimited, YOLO) + sta mliparam+5 + pla ; pull file reference number + jsr _readfile + php ; save flags from readfile + pha + jsr _closefile ; always close whether read worked or not + pla + plp ; restore flags from readfile + ; (so caller gets codes from read attempt, + ; not close) +@exit rts + +;------------------------------- +; LoadDHRFile +; load uncompressed DHR file into memory from .A2FC file +; 1. load first half ($2000 bytes) +; 2. copy to auxmem +; 3. load second half ($2000 bytes) +; +; always loads into graphics page 1 ($2000/main and $2000/aux) +; +; in: stack contains 4 bytes of parameters: +; +1 address of pathname +; +3 address of ProDOS file buffer +; out: if C set, load failed +; if C clear, load succeeded +; all other flags clobbered +; all registers clobbered +; stack set to next instruction after parameters +;------------------------------- +LoadDHRFile + +PARAMS_ON_STACK 4 + + ldy #$04 +- lda (PARAM),y + sta mliparam,y + dey + bne - + + jsr _openfile + bcs @exit ; C set on error + sta @saverefnum ; store file refnum + + ldy #$20 + stz mliparam+2 ; read into $2000 in main mem + sty mliparam+3 + stz mliparam+4 ; read length = $2000 bytes (first half of file) + sty mliparam+5 + + jsr _readfile + bcs @close + + sta $C000 + ldx #$20 ; copy $2000 bytes to auxmem + stx @copya+2 + stx @copyb+2 + ldy #0 +@writeToAuxLoop + sta $C005 +@copya lda $FF00, y +@copyb sta $FF00, y + iny + bne @copya + sta $C004 + inc @copya+2 + inc @copyb+2 + dex + bne @writeToAuxLoop + + lda @saverefnum + jsr _readfile ; read another $2000 bytes into $2000 (stays in main mem) + +@close php ; save flags from readfile +@saverefnum=*+1 + lda #$FD ; file refnum (SMC) + jsr _closefile + plp ; restore flags from readfile +@exit rts + +;------------------------------- +; LoadSHRFile +; load uncompressed SHR file into memory from .PIC file +; 1. load first quarter ($2000 bytes) +; 2. copy to graphics memory +; 3. load second quarter ($2000 bytes) +; 4. copy to graphics memory +; 5. load third quarter ($2000 bytes) +; 6. copy to graphics memory +; 7. load fourth quarter ($2000 bytes) +; 8. copy to graphics memory +; +; in: stack contains 4 bytes of parameters: +; +1 address of pathname +; +3 address of ProDOS file buffer +; out: if C set, load failed +; if C clear, load succeeded +; all other flags clobbered +; all registers clobbered +; stack set to next instruction after parameters +;------------------------------- +LoadSHRFile + +PARAMS_ON_STACK 4 + + ldy #$04 +- lda (PARAM),y + sta mliparam,y + dey + bne - + + jsr _openfile + bcs @exit ; C set on error + sta @saverefnum ; store file refnum + + ldy #$20 + stz mliparam+2 ; read into $2000 in main mem + sty mliparam+3 + stz mliparam+4 ; read length = $2000 bytes (one quarter of file) + sty mliparam+5 + sty @shrdest+2 + + ldx #4 ; four quarters +- lda @saverefnum ; file refnum + jsr _readfile + bcs @close + phx + +!cpu 65816 + xce + rep #$30 +!rl +!al + lda #$1FFF + tax + inx +@shrdest ldy #$FD00 ; SMC + phb + mvn 0,$E1 + plb + sty @shrdest+1 +!as +!rs + sec + xce +!cpu 65C02 + + plx + dex + bne - + +@close php ; save flags from readfile +@saverefnum=*+1 + lda #$FD ; file refnum (SMC) + jsr _closefile + plp ; restore flags from readfile +@exit rts + +;------------------------------- +; SaveFile +; save a file to disk all at once, using ProDOS MLI calls +; +; in: stack contains 11 ($0B) bytes of parameters: +; +1 address of pathname +; +3 [byte] file type +; +4 [word] aux file type +; +6 address of data buffer +; +8 [word] length of data buffer +; +A address of ProDOS file buffer +; out: if C set, save failed +; if C clear, save succeeded +; all other flags clobbered +; all registers clobbered +; stack set to next instruction after parameters +;------------------------------- +SaveFile + +PARAMS_ON_STACK $0B + +LDPARAM 1 + +STAY mliparam+1 ; pathname + lda #CMD_DESTROY ; MLI destroy command + ldy #PC_DESTROY ; number of parameters for 'destroy' command + jsr mli ; don't care if this fails + + ldy #$03 + lda (PARAM),y ; file type + sta mliparam+4 + +LDPARAM 4 + +STAY mliparam+5 ; aux file type + lda #kAccessBits + sta mliparam+3 ; access bits (full access) + ldy #1 + sty mliparam+7 ; storage type (file) + dey + sty mliparam+8 ; creation date (current) + sty mliparam+9 + sty mliparam+10 ; creation time (current) + sty mliparam+11 + lda #CMD_CREATE ; MLI create command + ldy #PC_CREATE ; number of parameters for 'create' command + jsr mli + bcs @exit + + +LDPARAM 10 + +STAY mliparam+3 ; PrODOS file buffer + jsr _openfile + bcs @exit + + sta mliparam+1 ; store file reference number + +LDPARAM 6 + +STAY mliparam+2 ; data buffer + +LDPARAM 8 + +STAY mliparam+4 ; data length + lda #CMD_WRITE ; MLI write command + ldy #PC_WRITE ; number of parameters for 'write' command + jsr mli + php ; save flags from write command + jsr _closefile ; always close whether write worked or not + plp ; restore flags from write + ; (so caller gets codes from write attempt, + ; not close) +@exit rts + +;------------------------------- +; SetAuxFileType +; set auxiliary file information only +; access bits and file-type are hard-coded +; intended for updating save-games only +; +; in: stack contains 4 bytes of parameters: +; +1 address of pathname +; +3 auxiliary type to set +; out: if C set, MLI call failed and A contains error code +; from set +; if C clear, MLI call succeeded +; all other flags clobbered +; all registers clobbered +; stack set to next instruction after parameters +;------------------------------- +SetAuxFileType + +PARAMS_ON_STACK 4 + +LDPARAM 1 + +STAY mliparam+1 ; pathname + +LDPARAM 3 + +STAY mliparam+5 ; aux type + lda #%11000011 + sta mliparam+3 ; access bits + lda #4 + sta mliparam+4 ; file type + lda #0 + sta extra+0 ; date + sta extra+1 ; date + sta extra+2 ; time + sta extra+3 ; time + lda #CMD_SETFILEINFO ; MLI command + ldy #PC_SETFILEINFO ; number of parameters for 'setfileinfo' command + bra mli + +;------------------------------- +; SetPrefix +; set current directory +; +; in: stack contains 2 bytes of parameters: +; +1 address of pathname +; out: if C set, call failed and A contains error code +; if C clear, call succeeded +; all other flags clobbered +; all registers clobbered +; stack set to next instruction after parameters +;------------------------------- +SetPrefix + +PARAMS_ON_STACK 2 + +LDPARAM 1 + +STAY mliparam+1 ; pathname + lda #CMD_SETPREFIX + ldy #PC_SETPREFIX + bra mli + +;------------------------------- +; GetFileInfo +; just what it says on the tin +; +; in: stack contains 2 bytes of parameters: +; +1 address of pathname +; out: if C set, MLI call failed and A contains error code +; from open or read +; if C clear, MLI call succeeded and mliparam contains +; all the info +; all other flags clobbered +; all registers clobbered +; stack set to next instruction after parameters +;------------------------------- +GetFileInfo + +PARAMS_ON_STACK 2 + +LDPARAM 1 + +STAY mliparam+1 ; pathname + lda #CMD_GETFILEINFO ; MLI command + ldy #PC_GETFILEINFO ; number of parameters for 'getfileinfo' command + bra mli + +;------------------------------- +; open file via ProDOS MLI +; +; in: caller has filled @mliparam with address of +; pathname, address of data buffer, and maximum +; data length +; out: if C set, open failed and A contains error code +; if C clear, open succeeded and A contains +; file reference number +;------------------------------- +_openfile + lda #CMD_OPEN ; MLI command + ldy #PC_OPEN ; number of parameters for 'open' command + jsr mli + bcs @exit + lda refnum ; caller should save file reference number + ; as this memory location may be + ; overwritten by later MLI calls +@exit rts + +;------------------------------- +; read an open file via ProDOS MLI +; +; in: A = file reference number +; caller has filled @mliparam with address of +; data buffer and maximum data length +; out: if C set, read failed and A contains error code +; if C clear, read succeeded and A contains the same +; file reference number that was passed in +;------------------------------- +_readfile + sta mliparam+1 ; store file reference number + lda #CMD_READ ; MLI read command + ldy #PC_READ ; number of parameters for 'read' command + jsr mli + bcs @exit + lda mliparam+1 ; if no error, return file reference number +@exit rts + +;------------------------------- +; close an open file +; in: A = file reference number +; out: if error, C set and A contains error code +; if success, C clear +;------------------------------- +_closefile + sta mliparam+1 ; store file reference number + lda #CMD_CLOSE ; MLI close command + ldy #PC_CLOSE ; number of parameters for 'close' command + bra mli + +QuitToProDOS + lda #CMD_QUIT + ldy #PC_QUIT + ; execution falls through here +;------------------------------- +; low-level MLI wrapper +; in: A = MLI command code +; Y = number of MLI parameters +; caller has filled @mliparam +; with all relevant parameters +; out: returns immediately after +; calling MLI, so whatever +; state the MLI routine sets, +; the caller will see it +; verbatim +;------------------------------- +mli sta mlicmd ; store command code + sty mliparam ; number of parameters + jsr PRODOSMLI ; call ProDOS +mlicmd !byte 00 ; command number + !word mliparam ; address of parameter table + rts +mliparam !byte $FE,$FE,$FE,$FE +filetype !byte $FE ; file type (set by MLI get_file_info) +auxtype ; auxiliary file type (2 bytes, set by MLI get_file_info) +refnum !byte $FE ; file refnum (set by MLI open) +mlilen !byte $FE,$FE ; file length (set by MLI read) +blocks !byte $FE,$FE ; blocks used (set by getvolumeinfo/getfileinfo) + ; member is also used by createfile +extra !byte $FE,$FE,$FE,$FE,$FE,$FE,$FE,$FE + ; used by get_file_info diff --git a/src/PRORWTS2.S b/src/prorwts2.a similarity index 99% rename from src/PRORWTS2.S rename to src/prorwts2.a index 9627655c1..d6c298fe2 100644 --- a/src/PRORWTS2.S +++ b/src/prorwts2.a @@ -9,8 +9,6 @@ ver_02 = 1 } else { ;ver_02 = 0 !cpu 65c02 } ;ver_02 -!to "build/prorwts2",plain -*=$800 ;place no code before init label below. @@ -43,8 +41,8 @@ ver_02 = 1 allow_sparse = 0 ;enable support for reading sparse files bounds_check = 0 ;set to 1 to prevent access beyond the end of the file ;but limits file size to 64k-2 bytes. - no_interrupts= 0 ;set to 1 to disable interrupts across calls - detect_err = 0 ;set to 1 to to detect errors in no_interrupt mode + no_interrupts= 1 ;set to 1 to disable interrupts across calls + detect_err = 1 ;set to 1 to to detect errors in no_interrupt mode swap_zp = 0 ;set to 1 to include code to preserve zpage ;used only by rwts_mode rwts_mode = 0 ;set to 1 to enable emulation of DOS RWTS when running from hard disk @@ -582,7 +580,7 @@ filename !byte filename_e-filename_b filename_b !text "diskimage.dsk" filename_e } else { ;rwts_mode = 0 - rts + rts } ;rwts_mode c7_parms !byte 1