1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-29 13:31:59 +00:00
cc65/libsrc/apple2/open.s
Oliver Schmidt 419eb700b5 Renamed INITBSS to INIT and INIT to ONCE.
The way we want to use the INITBSS segment - and especially the fact that it won't have the type bss on all ROM based targets - means that the name INITBSS is misleading. After all INIT is the best name from my perspective as it serves several purposes and therefore needs a rather generic name.

Unfortunately this means that the current INIT segment needs to be renamed too. Looking for a short (ideally 4 letter) name I came up with ONCE as it contains all code (and data) accessed only once during initialization.
2016-03-06 21:27:19 +01:00

252 lines
6.1 KiB
ArmAsm

;
; Oliver Schmidt, 30.12.2004
;
; int open (const char* name, int flags, ...);
;
.export _open, closedirect, freebuffer
.export __filetype, __auxtype, __datetime
.constructor raisefilelevel
.destructor closeallfiles, 5
.import pushname, popname, __dos_type
.import iobuf_alloc, iobuf_free
.import addysp, incsp4, incaxy, pushax, popax
.include "zeropage.inc"
.include "errno.inc"
.include "fcntl.inc"
.include "mli.inc"
.include "filedes.inc"
.segment "ONCE"
raisefilelevel:
; Raise file level
lda __dos_type
beq :+
inc LEVEL
: rts
.code
_open:
; Throw away all parameters except name
; and flags occupying together 4 bytes
dey
dey
dey
dey
jsr addysp
; Start with first fdtab slot
ldy #$00
; Check for free fdtab slot
: lda fdtab + FD::REF_NUM,y
beq found
; Advance to next fdtab slot
.assert .sizeof(FD) = 4, error
iny
iny
iny
iny
; Check for end of fdtab
cpy #MAX_FDS * .sizeof(FD)
bcc :-
; Load errno code
lda #EMFILE
; Cleanup stack
errno: jsr incsp4 ; Preserves A
; Set __errno
jmp __directerrno
; Save fdtab slot
found: tya
pha
; Alloc I/O buffer
lda #<(fdtab + FD::BUFFER)
ldx #>(fdtab + FD::BUFFER)
jsr incaxy
jsr pushax
lda #$00
ldx #>$0100
jsr pushax ; Preserves A
ldx #>$0400
jsr iobuf_alloc
tay ; Save errno code
; Restore fdtab slot
pla
sta tmp2 ; Save fdtab slot
; Check for error
tya ; Restore errno code
bne errno
; Get and save flags
jsr popax
sta tmp3
; Get and push name
jsr popax
jsr pushname
bne oserr1
; Set pushed name
lda sp
ldx sp+1
sta mliparam + MLI::OPEN::PATHNAME
stx mliparam + MLI::OPEN::PATHNAME+1
; Check for create flag
lda tmp3 ; Restore flags
and #O_CREAT
beq open
; PATHNAME already set
.assert MLI::CREATE::PATHNAME = MLI::OPEN::PATHNAME, error
; Set all other parameters from template
ldx #(MLI::CREATE::CREATE_TIME+1) - (MLI::CREATE::PATHNAME+1) - 1
: lda CREATE,x
sta mliparam + MLI::CREATE::ACCESS,x
dex
bpl :-
; Create file
lda #CREATE_CALL
ldx #CREATE_COUNT
jsr callmli
bcc open
; Check for ordinary errors
cmp #$47 ; "Duplicate filename"
bne oserr2
; Check for exclusive flag
lda tmp3 ; Restore flags
and #O_EXCL
beq open
lda #$47 ; "Duplicate filename"
; Cleanup name
oserr2: jsr popname ; Preserves A
oserr1: ldy tmp2 ; Restore fdtab slot
; Cleanup I/O buffer
pha ; Save oserror code
jsr freebuffer
pla ; Restore oserror code
; Set __oserror
jmp __mappederrno
open: ldy tmp2 ; Restore fdtab slot
; Set allocated I/O buffer
ldx fdtab + FD::BUFFER+1,y
sta mliparam + MLI::OPEN::IO_BUFFER ; A = 0
stx mliparam + MLI::OPEN::IO_BUFFER+1
; Open file
lda #OPEN_CALL
ldx #OPEN_COUNT
jsr callmli
bcs oserr2
; Get and save fd
ldx mliparam + MLI::OPEN::REF_NUM
stx tmp1 ; Save fd
; Set flags and check for truncate flag
lda tmp3 ; Restore flags
sta fdtab + FD::FLAGS,y
and #O_TRUNC
beq done
; Set fd and zero size
stx mliparam + MLI::EOF::REF_NUM
ldx #$02
lda #$00
: sta mliparam + MLI::EOF::EOF,x
dex
bpl :-
; Set file size
lda #SET_EOF_CALL
ldx #EOF_COUNT
jsr callmli
bcc done
; Cleanup file
pha ; Save oserror code
lda tmp1 ; Restore fd
jsr closedirect
pla ; Restore oserror code
bne oserr2 ; Branch always
; Store fd
done: lda tmp1 ; Restore fd
sta fdtab + FD::REF_NUM,y
; Convert fdtab slot to handle
.assert .sizeof(FD) = 4, error
tya
lsr
lsr
; Cleanup name
jsr popname ; Preserves A
; Return success
ldx #$00
stx __oserror
rts
freebuffer:
; Free I/O buffer
lda #$00
ldx fdtab + FD::BUFFER+1,y
jmp iobuf_free
closedirect:
; Set fd
sta mliparam + MLI::CLOSE::REF_NUM
; Call close
lda #CLOSE_CALL
ldx #CLOSE_COUNT
jmp callmli
closeallfiles:
; All open files with current level (or higher)
lda #$00
jsr closedirect
; Restore original file level
lda __dos_type
beq :+
dec LEVEL
: rts
.data
CREATE: .byte %11000011 ; ACCESS: Standard full access
__filetype:
.byte $06 ; FILE_TYPE: Standard binary file
__auxtype:
.word $0000 ; AUX_TYPE: Load address N/A
.byte $01 ; STORAGE_TYPE: Standard seedling file
__datetime:
.word $0000 ; CREATE_DATE: Current date
.word $0000 ; CREATE_TIME: Current time