]> git.sur5r.net Git - cc65/blob - libsrc/common/_fopen.s
Don't pass mode argument to open() from _fopen().
[cc65] / libsrc / common / _fopen.s
1 ;
2 ; Ullrich von Bassewitz, 22.11.2002
3 ;
4 ; FILE* __fastcall__ _fopen (const char* name, const char* mode, FILE* f);
5 ; /* Open the specified file and fill the descriptor values into f */
6 ;
7
8         .export         __fopen
9
10         .import         _open
11         .import         pushax, incsp4, return0
12         .importzp       sp, ptr1
13
14
15         .include        "errno.inc"
16         .include        "fcntl.inc"
17         .include        "_file.inc"
18
19
20 ; ------------------------------------------------------------------------
21 ; Code
22
23 .proc   __fopen
24
25         sta     file
26         stx     file+1          ; Save f
27
28 ; Get a pointer to the mode string
29
30         ldy     #1
31         lda     (sp),y
32         sta     ptr1+1
33         dey
34         lda     (sp),y
35         sta     ptr1
36
37 ; Look at the first character in mode
38
39         ldx     #$00            ; Mode will be in X
40         lda     (ptr1),y        ; Get first char from mode
41         cmp     #'w'
42         bne     @L1
43         ldx     #(O_WRONLY | O_CREAT | O_TRUNC)
44         bne     @L3
45 @L1:    cmp     #'r'
46         bne     @L2
47         ldx     #O_RDONLY
48         bne     @L3
49 @L2:    cmp     #'a'
50         bne     invmode
51         ldx     #(O_WRONLY | O_CREAT | O_APPEND)
52
53 ; Look at more chars from the mode string
54
55 @L3:    iny                     ; Next char
56         beq     invmode
57         lda     (ptr1),y
58         beq     modeok          ; End of mode string reached
59         cmp     #'+'
60         bne     @L4
61         txa
62         ora     #O_RDWR         ; Always do r/w in addition to anything else
63         tax
64         bne     @L3
65 @L4:    cmp     #'b'
66         beq     @L3             ; Binary mode is ignored
67
68 ; Invalid mode
69
70 invmode:
71         lda     #EINVAL
72         jsr     __seterrno      ; Set __errno, returns zero in A
73         tax                     ; a/x = 0
74         jmp     incsp4
75
76 ; Mode string successfully parsed. Store the binary mode onto the stack in
77 ; the same place where the mode string pointer was before. Then call open()
78
79 modeok: ldy     #$00
80         txa                     ; Mode -> A
81         sta     (sp),y
82         tya
83         iny
84         sta     (sp),y
85         ldy     #4              ; Size of arguments in bytes
86         jsr     _open           ; Will cleanup the stack
87
88 ; Check the result of the open() call
89
90         cpx     #$FF
91         bne     openok
92         cmp     #$FF
93         bne     openok
94         jmp     return0         ; Failure, errno/_oserror already set
95
96 ; Open call succeeded
97
98 openok: ldy     file
99         sty     ptr1
100         ldy     file+1
101         sty     ptr1+1
102         ldy     #_FILE::f_fd
103         sta     (ptr1),y        ; file->f_fd = fd;
104         ldy     #_FILE::f_flags
105         lda     #_FOPEN
106         sta     (ptr1),y        ; file->f_flags = _FOPEN;
107
108 ; Return the pointer to the file structure
109
110         lda     ptr1
111         ldx     ptr1+1
112         rts
113
114 .endproc
115
116 ; ------------------------------------------------------------------------
117 ; Data
118
119 .bss
120 file:   .res    2
121
122