This commit is contained in:
Joshua Bell 2018-12-31 20:18:35 -08:00
parent d28b73fefb
commit 0310508579
1 changed files with 156 additions and 140 deletions

296
chtype.s
View File

@ -1,207 +1,223 @@
;;; ============================================================
;;; ;;;
;;; CHTYPE - File type changing command for ProDOS-8
;;;
;;; Install:
;;; -CHTYPE (from BASIC.SYSTEM prompt)
;;; Usage:
;;; CHTYPE filename,Ttype[,Aaux][,S#][,D#]
;;;
;;; * filename can be relative or absolute path
;;; * type can be BIN, SYS, TXT (etc) or $nn
;;; * optional A$1234 sets aux type info
;;;
;;; Build with: ca65 - https://cc65.github.io/doc/ca65.html
;;;
;;; ============================================================
.org $2000 .org $2000
INBUF := $200 ;GETLN input buffer. ;;; ============================================================
INBUF := $200 ; GETLN input buffer
;;; ============================================================ ;;; ============================================================
;;; ROM routines ;;; ProDOS MLI / Global Page
WAIT := $FCA8 ;Monitor wait routine. SET_FILE_INFO = $C3
BELL := $FF3A ;Monitor bell routine GET_FILE_INFO = $C4
CROUT := $FD8E DATE := $BF90
PRBYTE := $FDDA
COUT := $FDED
;;; ============================================================ ;;; ============================================================
;;; BASIC.SYSTEM global page ;;; BASIC.SYSTEM Global Page
EXTRNCMD := $BE06 ; External cmd JMP vector. EXTRNCMD := $BE06 ; External command jmp vector
ERROUT := $BE09 ; Error routine vector. ERROUT := $BE09 ; Error routine jmp vector
ERRCODE := $BE0F ; Error code XTRNADDR := $BE50 ; Ext cmd implementation addr
XTRNADDR := $BE50 ; Ext cmd implementation addr.
XLEN := $BE52 ;Length of command string-1. XLEN := $BE52 ; Length of command string minus 1
XCNUM := $BE53 ;CI cmd no. (ext cmd = 0). XCNUM := $BE53 ; Command number (ext cmd = 0).
PBITS := $BE54 ; Command parameter bits. PBITS := $BE54 ; Command parameter bits
FBITS := $BE56 ; Found parameter bits. FBITS := $BE56 ; Found parameter bits
VADDR := $BE58 ; Address parameter .enum PBitsFlags
VSLOT := $BE61 ; Slot parameter ;; PBITS
VTYPE := $BE6A ; Type parameter PFIX = $80 ; Prefix needs fetching
VPATH1 := $BE6C ; Pathname buffer SLOT = $40 ; No parameters to be processed
RRUN = $20 ; Command only valid during program
FNOPT = $10 ; Filename is optional
CRFLG = $08 ; CREATE allowed
T = $04 ; File type
FN2 = $02 ; Filename '2' for RENAME
FN1 = $01 ; Filename expected
GOSYSTEM := $BE70 ; Use instead of MLI ;; PBITS+1
AD = $08 ; Address
B = $40 ; Byte
E = $20 ; End address
L = $10 ; Length
LINE = $08 ; '@' line number
SD = $04 ; Slot and drive numbers
F = $02 ; Field
R = $01 ; Record
SSGINFO := $BEB4 ; Get/Set Info Parameter block (set size to set=7 or get=$A) ;; Setting SD in PBITS+1 enables desired automatic behavior: if
FIFNAME := $BEB5 ; Should be implcitly linked already ;; a relative path is given, an appropriate prefix is computed,
FIFILID := $BEB8 ;; using S# and D# options if supplied. Without this, absolute
FIAUXID := $BEB9 ;; paths must be used if no prefix is set.
.endenum
VADDR := $BE58 ; Address parameter
VSLOT := $BE61 ; Slot parameter
VTYPE := $BE6A ; Type parameter
VPATH1 := $BE6C ; Pathname buffer
GOSYSTEM := $BE70 ; Use instead of MLI
SSGINFO := $BEB4 ; Get/Set Info Parameter block
FIFILID := $BEB8 ; (set size to set=7 or get=$A)
FIAUXID := $BEB9
FIMDATE := $BEBE
;;; ============================================================ ;;; ============================================================
;;; TODO: Relocate into ProDOS-allocated buffer ;;; TODO: Relocate into ProDOS-allocated buffer
;;; ;;; ============================================================
;;; Remember to save the previous command address.
;;; ;; Save previous external command address
lda EXTRNCMD+1 lda EXTRNCMD+1
sta nxtcmd sta next_command
lda EXTRNCMD+2 lda EXTRNCMD+2
sta nxtcmd+1 sta next_command+1
;;;
lda #<handler ;Install the address of our ;; Install in external command address
sta EXTRNCMD+1 ; command handler in the lda #<handler
lda #>handler ; external command JMP sta EXTRNCMD+1
sta EXTRNCMD+2 ; vector. lda #>handler
sta EXTRNCMD+2
rts rts
;;;
;;; ============================================================
;;; Command Handler
;;; ============================================================
handler: handler:
ldx #0 ;Check for our command. ;; Check for this command, character by character.
nxtchr: lda INBUF,x ;Get first character. ldx #0
nxtchr: lda INBUF,x
and #$7F ;Convert to ASCII and #$7F ; Convert to ASCII
cmp #'a' ; Convert to upper-case
cmp #'a' ;Convert to upper-case
bcc :+ bcc :+
cmp #'z'+1 cmp #'z'+1
bcs :+ bcs :+
and #$DF and #$DF
: cmp cmd,x ;Does it match? : cmp cmd,x
bne notours ;NO, SO CONTINUE WITH NEXT CMD. bne not_ours
inx ;Next character inx
cpx #cmdlen ;All characters yet? cpx #cmdlen
bne nxtchr ;No, read next one. bne nxtchr
;;;
lda #cmdlen-1 ;Our cmd! Put cmd length-1
sta XLEN ; in CI global XLEN.
lda #<execute ;Point XTRNADDR to our
sta XTRNADDR ; command execution
lda #>execute ; routine
sta XTRNADDR+1
lda #0 ;Mark the cmd number as
sta XCNUM ; zero (external).
;;;
;; Must set at least one bit in PBITS low byte.
lda #%10000000 ; bit 7 = Address ;; A match - indicate end of command string for BI's parser.
sta PBITS+1 lda #cmdlen-1
;;; sta XLEN
lda #%00000101 ; bit 8 = filename req'd, bit 10 = Type
;; Point BI's parser at the command execution routine.
lda #<execute
sta XTRNADDR
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 sta PBITS
clc ;Everything is OK.
rts ;Return to BASIC.SYSTEM lda #PBitsFlags::AD | PBitsFlags::SD ; Address, Slot & Drive handling
sta PBITS+1
clc ; Success (so far)
rts ; Return to BASIC.SYSTEM
;;; ============================================================ ;;; ============================================================
notours: not_ours:
sec ;SET CARRY AND LET sec ; Signal failure...
jmp (nxtcmd) ; NEXT EXT CMD GO FOR IT. next_command := *+1
jmp $ffff ; Execute next command in chain
;;; ============================================================ ;;; ============================================================
execute: execute:
;; Filename? ;; Verify required arguments
lda FBITS lda FBITS
and #%00000001 ; Filename? and #PBitsFlags::FN1 ; Filename?
bne :+ bne :+
lda #$10 ; SYNTAX ERROR lda #$10 ; SYNTAX ERROR
sec sec
rts rts
: :
;; Type? ;;; --------------------------------------------------
lda FBITS lda FBITS
and #%00000100 ; Type? and #PBitsFlags::T ; Type?
bne :+ bne :+
lda #$B ; INVALID PARAMETER lda #$B ; INVALID PARAMETER
sec sec
rts rts1: rts
: :
;; Show Filename ;;; --------------------------------------------------
lda #'P'|$80
jsr COUT
lda #'='|$80
jsr COUT
ptr := $06 ;; Get the existing file info
lda VPATH1
sta ptr
lda VPATH1+1
sta ptr+1
ldy #0
lda (ptr),y
tax
iny
: lda (ptr),y
ora #$80
jsr COUT
iny
dex
bne :-
jsr CROUT
;; Show Type
lda #'T'|$80
jsr COUT
lda #'='|$80
jsr COUT
lda #'$'|$80
jsr COUT
lda VTYPE
jsr PRBYTE
jsr CROUT
;; Addr?
lda FBITS+1
and #%10000000 ; Addr?
beq :+
lda #'A'|$80
jsr COUT
lda #'='|$80
jsr COUT
lda #'$'|$80
jsr COUT
lda VADDR+1 ; hi
jsr PRBYTE
lda VADDR ; lo
jsr PRBYTE
jsr CROUT
:
;; Get/Set File Info
;; GET_FILE_INFO
lda #$A lda #$A
sta SSGINFO sta SSGINFO
lda #$C4 ; GET_FILE_INFO lda #GET_FILE_INFO
jsr GOSYSTEM jsr GOSYSTEM
bcs rts1 bcs rts1
;; SET_FILE_INFO ;;; --------------------------------------------------
;; Set new file info
lda #$7 lda #$7
sta SSGINFO sta SSGINFO
;; Apply new file type
lda VTYPE lda VTYPE
sta FIFILID sta FIFILID
;; TODO: optional Aux Type
lda #$C3 ; SET_FILE_INFO
jsr GOSYSTEM
bcs rts1
clc ;All done successfully. ;; Apply optional Address argument as new aux type
rts1: rts ;Back to BASIC.SYSTEM. lda FBITS+1
and #%10000000
beq :+
lda VADDR
sta FIAUXID
lda VADDR+1
sta FIAUXID+1
:
;; Apply current date/time
ldx #3
: lda DATE,x
sta FIMDATE,x
dex
bpl :-
lda #SET_FILE_INFO
jmp GOSYSTEM
;;; ============================================================ ;;; ============================================================
;;; Data ;;; Data
cmd: .byte "CHTYPE" ;Our command cmd: .byte "CHTYPE" ; Command string
cmdlen = *-cmd ;Our command length cmdlen = *-cmd
nxtcmd: .word 0 ; STORE THE NEXT COMMAND'S
; ADDRESS HERE.