1; 2; Ullrich von Bassewitz, 16.11.2002 3; 4; int open (const char* name, int flags, ...); /* May take a mode argument */ 5 6 7 .export _open 8 .destructor closeallfiles, 5 9 10 .import addysp, popax 11 .import scratch, fnparse, fnaddmode, fncomplete, fnset 12 .import opencmdchannel, closecmdchannel, readdiskerror 13 .import fnunit, fnisfile 14 .import _close 15 .importzp sp, tmp2, tmp3 16 17 .include "errno.inc" 18 .include "fcntl.inc" 19 .include "filedes.inc" 20 .include "cbm.inc" 21 22 23;-------------------------------------------------------------------------- 24; closeallfiles: Close all open files. 25 26.proc closeallfiles 27 28 ldx #MAX_FDS-1 29loop: lda fdtab,x 30 beq next ; Skip unused entries 31 32; Close this file 33 34 txa 35 pha ; Save current value of X 36 ldx #0 37 jsr _close 38 pla 39 tax 40 41; Next file 42 43next: dex 44 bpl loop 45 46 rts 47 48.endproc 49 50;-------------------------------------------------------------------------- 51; _open 52 53.proc _open 54 55; Throw away any additional parameters passed through the ellipsis 56 57 dey ; Parm count < 4 shouldn't be needed to be... 58 dey ; ...checked (it generates a c compiler warning) 59 dey 60 dey 61 beq parmok ; Branch if parameter count ok 62 jsr addysp ; Fix stack, throw away unused parameters 63 64; Parameters ok. Pop the flags and save them into tmp3 65 66parmok: jsr popax ; Get flags 67 sta tmp3 68 69; Get the filename from stack and parse it. Bail out if is not ok 70 71 jsr popax ; Get name 72 jsr fnparse ; Parse it 73 tax 74 bne oserror ; Bail out if problem with name 75 76; Get a free file handle and remember it in tmp2 77 78 jsr freefd 79 lda #EMFILE ; Load error code 80 bcs seterrno ; Jump in case of errors 81 stx tmp2 82 83; Check the flags. We cannot have both, read and write flags set, and we cannot 84; open a file for writing without creating it. 85 86 lda tmp3 87 and #(O_RDWR | O_CREAT) 88 cmp #O_RDONLY ; Open for reading? 89 beq doread ; Yes: Branch 90 cmp #(O_WRONLY | O_CREAT) ; Open for writing? 91 beq dowrite 92 93; Invalid open mode 94 95 lda #EINVAL 96 97; Error entry. Sets _errno, clears _oserror, returns -1 98 99seterrno: 100 jmp __directerrno 101 102; Error entry: Close the file and exit. OS error code is in A on entry 103 104closeandexit: 105 pha 106 lda tmp2 107 clc 108 adc #LFN_OFFS 109 jsr CLOSE 110 ldx fnunit 111 jsr closecmdchannel 112 pla 113 114; Error entry: Set oserror and errno using error code in A and return -1 115 116oserror:jmp __mappederrno 117 118; Read bit is set. Add an 'r' to the name 119 120doread: lda #'r' 121 jsr fnaddmode ; Add the mode to the name 122 lda #LFN_READ 123 bne common ; Branch always 124 125; If O_TRUNC is set, scratch the file, but ignore any errors 126 127dowrite: 128 lda tmp3 129 and #O_TRUNC 130 beq notrunc 131 jsr scratch 132 133; Complete the the file name. Check for append mode here. 134 135notrunc: 136 lda tmp3 ; Get the mode again 137 and #O_APPEND ; Append mode? 138 bne append ; Branch if yes 139 140; Setup the name for create mode 141 142 lda #'w' 143 jsr fncomplete ; Add type and mode to the name 144 jmp appendcreate 145 146; Append bit is set. Add an 'a' to the name 147 148append: lda #'a' 149 jsr fnaddmode ; Add open mode to file name 150appendcreate: 151 lda #LFN_WRITE 152 153; Common read/write code. Flags in A, handle in tmp2 154 155common: sta tmp3 156 jsr fnset ; Set the file name 157 158 lda tmp2 159 clc 160 adc #LFN_OFFS 161 ldx fnunit 162 ldy fnisfile ; Is this a standard file on disk? 163 beq nofile ; Branch if not 164 tay ; Use the LFN also as SA for files 165nofile: ; ... else use SA=0 (read) 166 jsr SETLFS ; Set the file params 167 168 jsr OPEN 169 bcs oserror 170 171; Open the the drive command channel and read it 172 173 ldx fnunit 174 jsr opencmdchannel 175 bne closeandexit 176 ldx fnunit 177 jsr readdiskerror 178 bne closeandexit ; Branch on error 179 180; File is open. Mark it as open in the table 181 182 ldx tmp2 183 lda tmp3 184 sta fdtab,x 185 lda fnunit 186 sta unittab,x ; Remember 187 188; Done. Return the handle in a/x 189 190 txa ; Handle 191 ldx #0 192 stx __oserror ; Clear _oserror 193 rts 194 195.endproc 196 197