This commit is contained in:
4am 2018-08-23 16:02:48 -04:00
parent 9e024d24f8
commit d21e074f27
12 changed files with 650 additions and 16 deletions

View File

@ -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/

33
bin/do2po.py Executable file
View File

@ -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))

9
bin/extract.py Executable file
View File

@ -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/")

BIN
res/COVER Normal file

Binary file not shown.

BIN
res/COVER.A2FC Normal file

Binary file not shown.

BIN
res/PRODOS Normal file

Binary file not shown.

4
res/_FileInformation.txt Normal file
View File

@ -0,0 +1,4 @@
PRODOS=Type(FF),AuxType(0000),Access(C3)
LAUNCHER.SYSTEM=Type(FF),AuxType(2000),Access(C3)
COVER=Type(06),AuxType(4000),Access(C3)
COVER.A2FC=Type(06),AuxType(2000),Access(C3)

53
src/4cade.a Normal file
View File

@ -0,0 +1,53 @@
!cpu 6502
!to "build/LAUNCHER.SYSTEM",plain
*=$2000
MEMFLAG = $FF ; bit 7 = 0 if 64K, 1 if 128K
MACHID = $BF98 ; machine identification byte
lda MACHID
and #$30
cmp #$30 ; C=0 if 64K, C=1 if 128K
ror MEMFLAG ; set bit 7 from C
; jsr init ; initialize ProRWTS2
; lda $C08B
; lda $C08B
; lda #<cover
; sta namlo
; lda #>cover
; 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

10
src/constants.a Normal file
View File

@ -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

63
src/macros.a Normal file
View File

@ -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
}

455
src/prodos.mli.a Normal file
View File

@ -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

View File

@ -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