diff --git a/.travis.yml b/.travis.yml index 5650818..30a4a9d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ sudo: enabled -os: osx +os: linux language: c install: diff --git a/Makefile b/Makefile index 4470e6f..adc8eb5 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ LDFLAGS = --config apple2-asm.cfg OUTDIR = out TARGETS = $(OUTDIR)/path.BIN \ + $(OUTDIR)/chtype.CMD $(OUTDIR)/chtime.CMD \ $(OUTDIR)/bell.CMD $(OUTDIR)/hello.CMD $(OUTDIR)/echo.CMD $(OUTDIR)/online.CMD .PHONY: clean all package diff --git a/README.md b/README.md index 6be3dd4..ed2aa10 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ Once set, binary files of type `CMD` in the specified directories can be invoked * CMD file is loaded at $4000 and invoked; should return (`rts`) on completion. * 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. Example: ``` @@ -48,3 +49,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. diff --git a/bell.cmd.s b/bell.cmd.s index 44c2e0a..0756218 100644 --- a/bell.cmd.s +++ b/bell.cmd.s @@ -1,9 +1,10 @@ .include "apple2.inc" - -BELL := $FF3A + .include "more_apple2.inc" .org $4000 jsr BELL + + clc rts diff --git a/chtime.cmd.s b/chtime.cmd.s new file mode 100644 index 0000000..cb96514 --- /dev/null +++ b/chtime.cmd.s @@ -0,0 +1,142 @@ +;;; ============================================================ +;;; +;;; CHTIME - File modification time changing command for ProDOS-8 +;;; +;;; Usage: CHTIME filename[,Adate][,Btime][,S#][,D#] +;;; +;;; * filename can be relative or absolute path +;;; * specify A$nnnn to set file date +;;; * specify B$nnnn to set file time +;;; * with neither A nor B option, prints current values +;;; +;;; ============================================================ + + .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 + + lda #PBitsFlags::FN1 ; Filename + sta PBITS + + ;; Address, Byte, Slot & Drive handling + lda #PBitsFlags::AD | PBitsFlags::B | PBitsFlags::SD + sta PBITS+1 + + clc ; Success (so far) + rts ; Return to BASIC.SYSTEM + +;;; ============================================================ + +not_ours: + sec ; Signal failure... + next_command := *+1 + jmp $ffff ; Execute next command in chain + +;;; ============================================================ + +execute: + ;; Verify required arguments + + lda FBITS + and #PBitsFlags::FN1 ; Filename? + bne :+ + lda #$10 ; SYNTAX ERROR + sec +rts1: rts +: + +;;; -------------------------------------------------- + + ;; Get the existing file info + lda #$A + sta SSGINFO + lda #GET_FILE_INFO + jsr GOSYSTEM + bcs rts1 + +;;; -------------------------------------------------- + + ;; Apply options + ldy #0 ; count number of options + + ;; Apply optional Address argument as new date + lda FBITS+1 + and #PBitsFlags::AD ; Address set? + beq :+ + iny + lda VADDR + sta FIMDATE + lda VADDR+1 + sta FIMDATE+1 +: + + ;; Apply optional Byte argument as new time + lda FBITS+1 + and #PBitsFlags::B ; Type set? + beq :+ + iny + lda VBYTE + sta FIMDATE+2 + lda VBYTE+1 + sta FIMDATE+3 +: + + ;; If no options were used, show current details instead. + cpy #0 + beq show + + ;; Set new file info + lda #$7 + sta SSGINFO + + lda #SET_FILE_INFO + jmp GOSYSTEM + +;;; -------------------------------------------------- + +show: + lda #'A'|$80 + jsr COUT + lda #'='|$80 + jsr COUT + lda #'$'|$80 + jsr COUT + lda FIMDATE+1 + jsr PRBYTE + lda FIMDATE + jsr PRBYTE + jsr CROUT + + lda #'B'|$80 + jsr COUT + lda #'='|$80 + jsr COUT + lda #'$'|$80 + jsr COUT + lda FIMDATE+3 + jsr PRBYTE + lda FIMDATE+2 + jsr PRBYTE + jsr CROUT + + clc + rts diff --git a/chtype.cmd.s b/chtype.cmd.s new file mode 100644 index 0000000..46829ed --- /dev/null +++ b/chtype.cmd.s @@ -0,0 +1,138 @@ +;;; ============================================================ +;;; +;;; CHTYPE - File type changing command for ProDOS-8 +;;; +;;; Usage: CHTYPE filename[,Ttype][,Aaux][,S#][,D#] +;;; +;;; * filename can be relative or absolute path +;;; * specify T$nn to set file type +;;; * specify A$nnnn to set aux type info +;;; * type can be BIN, SYS, TXT (etc) or $nn +;;; * with neither T nor A option, prints current values +;;; +;;; ============================================================ + + .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::T | PBitsFlags::FN1 ; Filename and Type + sta PBITS + + lda #PBitsFlags::AD | PBitsFlags::SD ; Address, Slot & Drive handling + sta PBITS+1 + + clc ; Success (so far) + rts ; Return to BASIC.SYSTEM + +;;; ============================================================ + +execute: + ;; Verify required arguments + + lda FBITS + and #PBitsFlags::FN1 ; Filename? + bne :+ + lda #$10 ; SYNTAX ERROR + sec +rts1: rts +: + +;;; -------------------------------------------------- + + ;; Get the existing file info + lda #$A + sta SSGINFO + lda #GET_FILE_INFO + jsr GOSYSTEM + bcs rts1 + +;;; -------------------------------------------------- + + ;; Apply options + ldy #0 ; count number of options + + ;; Apply optional Type argument as new file type + lda FBITS + and #PBitsFlags::T ; Type set? + beq :+ + iny + lda VTYPE + sta FIFILID +: + + ;; Apply optional Address argument as new aux type + lda FBITS+1 + and #PBitsFlags::AD ; Address set? + beq :+ + iny + lda VADDR + sta FIAUXID + lda VADDR+1 + sta FIAUXID+1 +: + + ;; If no options were used, show current details instead. + cpy #0 + beq show + + ;; Apply current date/time + ldx #3 +: lda DATE,x + sta FIMDATE,x + dex + bpl :- + + ;; Set new file info + lda #$7 + sta SSGINFO + + lda #SET_FILE_INFO + jmp GOSYSTEM + +;;; -------------------------------------------------- + +show: + lda #'T'|$80 + jsr COUT + lda #'='|$80 + jsr COUT + lda #'$'|$80 + jsr COUT + lda FIFILID + jsr PRBYTE + jsr CROUT + + lda #'A'|$80 + jsr COUT + lda #'='|$80 + jsr COUT + lda #'$'|$80 + jsr COUT + lda FIAUXID+1 + jsr PRBYTE + lda FIAUXID + jsr PRBYTE + jsr CROUT + + clc + rts diff --git a/echo.cmd.s b/echo.cmd.s index 9bddb55..037bc7b 100644 --- a/echo.cmd.s +++ b/echo.cmd.s @@ -1,9 +1,6 @@ .include "apple2.inc" - -CROUT := $FD8E -COUT := $FDED -INBUF := $200 + .include "more_apple2.inc" .org $4000 @@ -39,7 +36,8 @@ INBUF := $200 inx jmp :- -exit: rts +exit: clc + rts .proc skip_spaces lda INBUF,x diff --git a/hello.cmd.s b/hello.cmd.s index 18206a1..55d43df 100644 --- a/hello.cmd.s +++ b/hello.cmd.s @@ -1,8 +1,6 @@ .include "apple2.inc" - -CROUT := $FD8E -COUT := $FDED + .include "more_apple2.inc" .org $4000 @@ -16,6 +14,8 @@ COUT := $FDED jmp :- done: jsr CROUT + + clc rts str: .byte "Hello, world!", 0 \ No newline at end of file diff --git a/more_apple2.inc b/more_apple2.inc new file mode 100644 index 0000000..87d6eaa --- /dev/null +++ b/more_apple2.inc @@ -0,0 +1,23 @@ +;;; ============================================================ +;;; Memory locations + +INBUF := $200 + +;;; ============================================================ +;;; Monitor ROM routines + +CROUT := $FD8E +PRBYTE := $FDDA +COUT := $FDED + +MOVE := $FE2C ; call with Y=0 +MOVE_SRC := $3C +MOVE_END := $3E +MOVE_DST := $42 + +BELL := $FF3A + +;;; ============================================================ +;;; Applesoft ROM locations + +TOKEN_NAME_TABLE := $D0D0 diff --git a/online.cmd.s b/online.cmd.s index 350593b..ca2a1d9 100644 --- a/online.cmd.s +++ b/online.cmd.s @@ -1,10 +1,8 @@ .include "apple2.inc" + .include "more_apple2.inc" .include "prodos.inc" -CROUT := $FD8E ; Issue a carriage return. -COUT := $FDED ; Output a character. - .org $4000 ;;; ============================================================ @@ -83,7 +81,8 @@ next: dec count sta ptr+1 jmp loop -exit: rts +exit: clc + rts ;;; ============================================================ diff --git a/path.s b/path.s index 21a057e..e5b1bac 100644 --- a/path.s +++ b/path.s @@ -9,6 +9,7 @@ .org $2000 .include "apple2.inc" + .include "more_apple2.inc" .include "prodos.inc" ;;; ============================================================ @@ -16,21 +17,6 @@ cmd_load_addr := $4000 max_cmd_size = $2000 -;;; ============================================================ -;;; Monitor ROM routines/locations - -INBUF := $200 ; GETLN input buffer - -CROUT := $FD8E -COUT := $FDED - -MOVE := $FE2C ; call with Y=0 -MOVE_SRC := $3C -MOVE_END := $3E -MOVE_DST := $42 - -TOKEN_NAME_TABLE := $D0D0 - CASE_MASK = $DF ;;; ============================================================ @@ -342,6 +328,10 @@ notok: dey ldy #0 sta (ptr),y + ;; Indicate end of command string for BI's parser (if command uses it) + dex + stx XLEN + ;; Check to see if path exists. lda #$A ; param length sta SSGINFO @@ -363,7 +353,7 @@ notok: dey lda #>XRETURN sta XTRNADDR+1 - ;; MLI/BI trashes part of INBUF, so stash it in upper half. + ;; MLI/BI trashes part of INBUF (clock driver?), so stash it in upper half. ldx #$7F : lda INBUF,x sta INBUF+$80,x @@ -411,7 +401,6 @@ notok: dey ;; Invoke command jsr cmd_load_addr - clc ; success rts ; Return to BASIC.SYSTEM fail_load: diff --git a/prodos.inc b/prodos.inc index 8825445..8c553a0 100644 --- a/prodos.inc +++ b/prodos.inc @@ -2,7 +2,9 @@ ;;; ProDOS MLI / Global Page MLI := $BF00 +DATE := $BF90 +SET_FILE_INFO = $C3 GET_FILE_INFO = $C4 ON_LINE = $C5 OPEN = $C8 @@ -55,6 +57,10 @@ FBITS := $BE56 ; Found parameter bits ;; paths must be used if no prefix is set. .endenum +VADDR := $BE58 ; Address parameter +VBYTE := $BE5A ; Byte parameter +VSLOT := $BE61 ; Slot parameter +VTYPE := $BE6A ; Type parameter VPATH1 := $BE6C ; Pathname buffer GOSYSTEM := $BE70 ; Use instead of MLI @@ -63,6 +69,8 @@ XRETURN := $BE9E ; Handy RTS SSGINFO := $BEB4 ; GET_FILE_INFO Parameter block FIFILID := $BEB8 ; (set size $A) +FIAUXID := $BEB9 +FIMDATE := $BEBE SOPEN := $BECB ; OPEN OSYSBUF := $BECE