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