Add COPY command. Fixes #2

This commit is contained in:
Joshua Bell 2021-04-12 20:43:49 -07:00
parent f5fc93e608
commit ef8857752f
5 changed files with 254 additions and 14 deletions

View File

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

View File

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

201
copy.cmd.s Normal file
View File

@ -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
page_num2 := *+1 ; address needing updating
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
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
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
lda #>DATABUF
sta RWDATA+1
lda #<DATALEN
sta RWCOUNT
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
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"

View File

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

View File

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