mirror of
https://github.com/cc65/cc65.git
synced 2024-08-20 09:29:12 +00:00
159 lines
3.4 KiB
ArmAsm
159 lines
3.4 KiB
ArmAsm
|
;
|
||
|
; Ullrich von Bassewitz, 16.11.2002
|
||
|
;
|
||
|
; File name handling for CBM file I/O
|
||
|
;
|
||
|
|
||
|
.export fnparse, fnset, fncomplete
|
||
|
.export fnunit, fnlen, fncmd, fnbuf
|
||
|
|
||
|
.import __curunit, __filetype
|
||
|
.importzp ptr1
|
||
|
|
||
|
.include "ctype.inc"
|
||
|
.include "cbm.inc"
|
||
|
|
||
|
|
||
|
;--------------------------------------------------------------------------
|
||
|
; fnparse: Parse a filename passed in in a/x. Will set the following
|
||
|
; variables:
|
||
|
;
|
||
|
; fnlen -> length of filename
|
||
|
; fnbuf -> filename including drive spec
|
||
|
; fnunit -> unit from spec or default unit
|
||
|
|
||
|
|
||
|
.proc fnparse
|
||
|
|
||
|
sta ptr1
|
||
|
stx ptr1+1 ; Save pointer to name
|
||
|
|
||
|
; For now we're always using the default unit
|
||
|
|
||
|
lda __curunit
|
||
|
sta fnunit
|
||
|
|
||
|
; Check the name for a drive spec
|
||
|
|
||
|
ldy #0
|
||
|
lda (ptr1),y
|
||
|
sta fnbuf+0
|
||
|
cmp #'0'
|
||
|
beq digit
|
||
|
cmp #'1'
|
||
|
bne nodrive
|
||
|
|
||
|
digit: iny
|
||
|
lda (ptr1),y
|
||
|
cmp #':'
|
||
|
bne nodrive
|
||
|
|
||
|
; We found a drive spec, copy it to the buffer
|
||
|
|
||
|
sta fnbuf+1
|
||
|
iny ; Skip colon
|
||
|
bne drivedone ; Branch always
|
||
|
|
||
|
; We did not find a drive spec, always use drive zero
|
||
|
|
||
|
nodrive:
|
||
|
lda #'0'
|
||
|
sta fnbuf+0
|
||
|
lda #':'
|
||
|
sta fnbuf+1
|
||
|
ldy #$00 ; Reposition to start of name
|
||
|
|
||
|
; Drive spec done. Copy the name into the file name buffer. Check that all
|
||
|
; file name characters are valid and that the maximum length is not exceeded.
|
||
|
|
||
|
drivedone:
|
||
|
lda #2 ; Length of drive spec
|
||
|
sta fnlen
|
||
|
|
||
|
nameloop:
|
||
|
lda (ptr1),y ; Get next char from filename
|
||
|
beq namedone ; Jump if end of name reached
|
||
|
|
||
|
; Check for valid chars in the file name
|
||
|
|
||
|
tax
|
||
|
lda __ctype,x
|
||
|
and #CT_ALNUM ; Letters and digits are allowed
|
||
|
beq invalidname
|
||
|
|
||
|
; Check the maximum length, store the character
|
||
|
|
||
|
ldx fnlen
|
||
|
cpx #14 ; Maximum length reached?
|
||
|
bcs invalidname
|
||
|
lda (ptr1),y ; Reload char
|
||
|
sta fnbuf,x ; Store into buffer
|
||
|
inc fnlen ; Count characters
|
||
|
iny ; Next char from name
|
||
|
bne nameloop ; Branch always
|
||
|
|
||
|
; Invalid file name
|
||
|
|
||
|
invalidname:
|
||
|
lda #33 ; Invalid file name
|
||
|
|
||
|
; Done, we've successfully parsed the name.
|
||
|
|
||
|
namedone:
|
||
|
rts
|
||
|
|
||
|
.endproc
|
||
|
|
||
|
|
||
|
;--------------------------------------------------------------------------
|
||
|
; fnset: Tell the kernal about the file name
|
||
|
|
||
|
.proc fnset
|
||
|
|
||
|
lda fnlen
|
||
|
ldx #<fnbuf
|
||
|
ldy #>fnbuf
|
||
|
jmp SETNAM
|
||
|
|
||
|
.endproc
|
||
|
|
||
|
;--------------------------------------------------------------------------
|
||
|
; fncomplete: Complete a filename by adding ",t,m" where t is the file type
|
||
|
; and m is the access mode passed in in the A register
|
||
|
|
||
|
.proc fncomplete
|
||
|
|
||
|
pha ; Save mode
|
||
|
ldx fnlen
|
||
|
lda #','
|
||
|
sta fnbuf,x
|
||
|
inx
|
||
|
lda __filetype
|
||
|
sta fnbuf,x
|
||
|
inx
|
||
|
lda #','
|
||
|
sta fnbuf,x
|
||
|
inx
|
||
|
pla
|
||
|
sta fnbuf,x
|
||
|
inx
|
||
|
stx fnlen
|
||
|
rts
|
||
|
|
||
|
.endproc
|
||
|
|
||
|
;--------------------------------------------------------------------------
|
||
|
; Data
|
||
|
|
||
|
.bss
|
||
|
|
||
|
fnunit: .res 1
|
||
|
fnlen: .res 1
|
||
|
|
||
|
.data
|
||
|
fncmd: .byte 's' ; Use as scratch command
|
||
|
fnbuf: .res 20
|
||
|
|
||
|
|
||
|
|