From ef8857752f6fc3b359ccfc621750b6a7bc155bb2 Mon Sep 17 00:00:00 2001 From: Joshua Bell Date: Mon, 12 Apr 2021 20:43:49 -0700 Subject: [PATCH] Add COPY command. Fixes #2 --- Makefile | 1 + README.md | 24 ++++--- copy.cmd.s | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++++ package.sh | 2 +- prodos.inc | 40 ++++++++++- 5 files changed, 254 insertions(+), 14 deletions(-) create mode 100644 copy.cmd.s diff --git a/Makefile b/Makefile index 6871394..8f01ec1 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ OUTDIR := out TARGETS := $(OUTDIR)/path.BIN \ $(OUTDIR)/chtype.CMD $(OUTDIR)/chtime.CMD \ + $(OUTDIR)/copy.CMD \ $(OUTDIR)/bell.CMD $(OUTDIR)/hello.CMD $(OUTDIR)/echo.CMD $(OUTDIR)/online.CMD XATTR := $(shell command -v xattr 2> /dev/null) diff --git a/README.md b/README.md index ed2aa10..d8a0bbd 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ cmdname - load and execute named CMD, if in PATH Once set, binary files of type `CMD` in the specified directories can be invoked by name. * CMD file is loaded at $4000 and invoked; should return (`rts`) on completion. +* $4000-$5FFF is assumed reserved for the CMD file and any buffers it needs. * The command line will be present at $200 (`GETLN` input buffer). * Supports multi-segment, colon-separated paths, e.g. `/hd/cmds:/hd2/more.cmds` * Commands can use the BI parser for arguments. See `chtype.cmd.s` for an example. @@ -46,13 +47,16 @@ Notes: * Commands with BASIC keywords as _prefixes_ are allowed as long as the command continues with an alphabetic character. For example, `ONLINE` is allowed despite conflicting with the valid BASIC statement `ONLINE GOTO10` which is short for `ON LINE GOTO 10`. Sample commands included: -* `BELL` - beeps the speaker -* `HELLO` - shows a short message -* `ONLINE` - lists online volumes (volume name, slot and drive) -* `ECHO` - echoes back anything following the command -* `CHTYPE` - change the type/auxtype of a file. e.g. `chtype file,T$F1,A$1234` - * `T` (type) and `A` (auxtype) are optional. If neither is specified, current types are shown. - * `S` and `D` arguments can be used to specify slot and drive. -* `CHTIME` - change the modification date/time of a file. e.g. `chtime file,A$1234,B$5678` - * `A` (date) and `B` (time) are optional. If neither is specified, current values are shown. - * `S` and `D` arguments can be used to specify slot and drive. +* Useful utilities: + * `ONLINE` - lists online volumes (volume name, slot and drive) + * `COPY` - copy a single file, e.g. `copy /path/to/file,dstfile` + * `CHTYPE` - change the type/auxtype of a file. e.g. `chtype file,T$F1,A$1234` + * `T` (type) and `A` (auxtype) are optional. If neither is specified, current types are shown. + * `S` and `D` arguments can be used to specify slot and drive. + * `CHTIME` - change the modification date/time of a file. e.g. `chtime file,A$1234,B$5678` + * `A` (date) and `B` (time) are optional. If neither is specified, current values are shown. + * `S` and `D` arguments can be used to specify slot and drive. +* Other examples: + * `BELL` - beeps the speaker + * `HELLO` - shows a short message + * `ECHO` - echoes back anything following the command diff --git a/copy.cmd.s b/copy.cmd.s new file mode 100644 index 0000000..b1b3ae5 --- /dev/null +++ b/copy.cmd.s @@ -0,0 +1,201 @@ +;;; ============================================================ +;;; +;;; COPY - Copy changing command for ProDOS-8 +;;; +;;; Usage: COPY pathname1,pathname2 +;;; +;;; Inspiration from COPY.ALL by Sandy Mossberg, Nibble 6/1987 +;;; +;;; ============================================================ + + .include "apple2.inc" + .include "more_apple2.inc" + .include "prodos.inc" + +;;; ============================================================ + + .org $4000 + + ;; NOTE: Assumes XLEN is set by PATH + + ;; Point BI's parser at the command execution routine. + lda #execute + sta XTRNADDR+1 + + ;; Mark command as external (zero). + lda #0 + sta XCNUM + + ;; Set accepted parameter flags (Name, Type, Address) + + lda #PBitsFlags::FN1 | PBitsFlags::FN2 ; Filenames + sta PBITS + lda #0 + sta PBITS+1 + + clc ; Success (so far) + rts ; Return to BASIC.SYSTEM + +;;; ============================================================ + + FN1INFO := $2EE + FN1BUF := $4200 + FN2BUF := $4600 + DATABUF := $4A00 + DATALEN = $6000 - DATABUF + +execute: + ;; Get FN1 info + lda #$A + sta SSGINFO + lda #GET_FILE_INFO + jsr GOSYSTEM + bcs rts1 + + ;; Reject directory file + lda FIFILID + cmp #$F ; DIR + bne :+ + lda #$D ; FILE TYPE MISMATCH + sec +rts1: rts +: + + ;; Save FN1 info + ldx #$11 +: lda SSGINFO,x + sta FN1INFO,x + dex + bpl :- + + ;; Open FN1 + lda #FN1BUF + sta OSYSBUF+1 + lda #OPEN + jsr GOSYSTEM + bcs rts1 + lda OREFNUM + sta FN1REF + + ;; Copy FN2 to FN1 + ptr1 := $06 + ptr2 := $08 + lda VPATH1 + sta ptr1 + lda VPATH1+1 + sta ptr1+1 + lda VPATH2 + sta ptr2 + lda VPATH2+1 + sta ptr2+1 + ldy #0 + lda (ptr2),y + tay +: lda (ptr2),y + sta (ptr1),y + dey + bpl :- + + ;; Get FN1 info + lda #GET_FILE_INFO + jsr GOSYSTEM + bcs :+ + + lda #$13 ; DUPLICATE FILE NAME +err: pha + jsr close + pla + sec + rts + +: cmp #6 ; BI Errors 6 and 7 cover + beq :+ ; vol dir, pathname, or filename + cmp #7 ; not found. + bne err ; Otherwise - fail. +: + + ;; Create FN2 + lda #$C3 ; Free access + sta CRACESS + ldx #3 +: lda FN1INFO+4,x ; storage type, file type, + sta CRFKIND-3,x ; aux type, create date/time + lda FN1INFO+$E,x + sta CRFKIND+1,x + dex + bpl :- + lda #CREATE + jsr GOSYSTEM + bcs err + + ;; Open FN2 + lda #FN2BUF + sta OSYSBUF+1 + lda #OPEN + jsr GOSYSTEM + bcs err + lda OREFNUM + sta FN2REF + + ;; Read +read: lda FN1REF + sta RWREFNUM + lda #DATABUF + sta RWDATA+1 + lda #DATALEN + sta RWCOUNT+1 + lda #READ + jsr GOSYSTEM + bcc :+ + cmp #5 ; END OF DATA + beq finish +: + + ;; Write + lda FN2REF + sta RWREFNUM + lda #DATABUF + sta RWDATA+1 + lda RWTRANS + sta RWCOUNT + lda RWTRANS+1 + sta RWCOUNT+1 + lda #WRITE + jsr GOSYSTEM + bcc read + jmp err + + +finish: jsr close + clc + rts + +.proc close + lda FN1REF + sta CFREFNUM + lda #CLOSE + jsr GOSYSTEM + lda FN2REF + sta CFREFNUM + lda #CLOSE + jsr GOSYSTEM + rts +.endproc + +FN1REF: .byte 0 +FN2REF: .byte 0 + + .assert * <= FN1BUF, error, "Too long" diff --git a/package.sh b/package.sh index 625d7ac..6dc315f 100755 --- a/package.sh +++ b/package.sh @@ -18,7 +18,7 @@ add_file () { } add_file "out/path.BIN" "path#062000" -for file in bell echo hello online chtype chtime; do +for file in bell echo hello online chtype chtime copy; do add_file "out/${file}.CMD" "${file}#F04000" done diff --git a/prodos.inc b/prodos.inc index 8c553a0..862d576 100644 --- a/prodos.inc +++ b/prodos.inc @@ -4,11 +4,13 @@ MLI := $BF00 DATE := $BF90 +CREATE = $C0 SET_FILE_INFO = $C3 GET_FILE_INFO = $C4 ON_LINE = $C5 OPEN = $C8 READ = $CA +WRITE = $CB CLOSE = $CC .macro MLI_CALL cmd, params @@ -61,28 +63,60 @@ VADDR := $BE58 ; Address parameter VBYTE := $BE5A ; Byte parameter VSLOT := $BE61 ; Slot parameter VTYPE := $BE6A ; Type parameter -VPATH1 := $BE6C ; Pathname buffer +VPATH1 := $BE6C ; Pathname 1 buffer +VPATH2 := $BE6E ; Pathname 2 buffer (RENAME) GOSYSTEM := $BE70 ; Use instead of MLI + XRETURN := $BE9E ; Handy RTS +SCREATE := $BEA0 ; CREATE Parameter block +CRACESS := $BEA3 ; $C1 if directory create +CRFILID := $BEA4 +CRAUXID := $BEA5 +CRFKIND := $BEA7 +SSGPREFX := $BEAC +SDSTROY := $BEAC +SRECNAME := $BEAF + SSGINFO := $BEB4 ; GET_FILE_INFO Parameter block -FIFILID := $BEB8 ; (set size $A) -FIAUXID := $BEB9 +FIACESS := $BEB7 ; Access used by lock/unlock +FIFILID := $BEB8 ; FILE ID is type specifier +FIAUXID := $BEB9 ; Aux_id is used for load addr and record length +FIFKIND := $BEBB ; Identifies trees vs. directories +FIBLOKS := $BEBC ; Used by CAT commands for root FIMDATE := $BEBE +SONLINE := $BEC6 +SSETMKR := $BEC6 +SGETMRK := $BEC6 +SSETEOF := $BEC6 +SGETEOF := $BEC6 +SSETBUF := $BEC6 +SGETBUF := $BEC6 +SBUFREF := $BEC7 +SREFNUM := $BEC7 +SUNITNUM := $BEC7 +SDATPTR := $BEC8 +SMARK := $BEC8 +SEOF := $BEC8 +SBUFADR := $BEC8 SOPEN := $BECB ; OPEN OSYSBUF := $BECE OREFNUM := $BED0 SREAD := $BED5 ; READ +SWRITE := $BED5 ; WRITE RWREFNUM := $BED6 RWDATA := $BED7 RWCOUNT := $BED9 +RWTRANS := $BEDB SCLOSE := $BEDD ; CLOSE +SFLUSH := $BEDD ; FLUSH CFREFNUM := $BEDE +CCCSPARE := $BEDF GETBUFR := $BEF5 FREEBUFR := $BEF8