File: fio_module.s

package info (click to toggle)
cc65 2.19-2
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 20,268 kB
  • sloc: ansic: 117,151; asm: 66,339; pascal: 4,248; makefile: 1,009; perl: 607
file content (189 lines) | stat: -rw-r--r-- 5,231 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
;
; Low level file I/O routines, ONLY for module loading OR sth similar
;
; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
; 25.12.2002
;
; only ONE opened file at a time, only O_RDONLY flag

; int open (const char* name, int flags, ...);  /* May take a mode argument */
; int __fastcall__ close (int fd);
; int __fastcall__ read (int fd, void* buf, unsigned count);

FILEDES         = 3             ; first free to use file descriptor

            .importzp ptr1, ptr2, ptr3, tmp1
            .import addysp, popax, popptr1
            .import __oserror
            .import _FindFile, _ReadByte
            .export _open, _close, _read

            .include "geossym.inc"
            .include "const.inc"
            .include "errno.inc"
            .include "fcntl.inc"

_open:
        cpy #4                  ; correct # of arguments (bytes)?
        beq @parmok             ; parameter count ok
        tya                     ; parm count < 4 shouldn't be needed to be...
        sec                     ; ...checked (it generates a c compiler warning)
        sbc #4
        tay
        jsr addysp              ; fix stack, throw away unused parameters

; Parameters ok. Pop the flags and save them into tmp3

@parmok:
        jsr popax               ; Get flags
        sta tmp1
        jsr popptr1             ; Get name
            
        lda filedesc            ; is there a file already open?
        bne @alreadyopen
            
        lda tmp1                ; check open mode
        and #(O_RDWR | O_CREAT)
        cmp #O_RDONLY           ; only O_RDONLY is valid
        bne @badmode
            
        lda ptr1
        ldx ptr1+1
        jsr _FindFile           ; try to find the file
        tax
        bne @oserror
            
        lda dirEntryBuf + OFF_DE_TR_SC ; tr&se for ReadByte (r1)
        sta f_track
        lda dirEntryBuf + OFF_DE_TR_SC + 1
        sta f_sector
        lda #<diskBlkBuf        ; buffer for ReadByte (r4)
        sta f_buffer
        lda #>diskBlkBuf
        sta f_buffer+1
        ldx #0                  ; offset for ReadByte (r5)
        stx f_offset
        stx f_offset+1
        lda #0                  ; clear errors
        sta __oserror
        jsr __seterrno
        lda #FILEDES            ; return fd
        sta filedesc
        rts
@badmode:
        lda #EINVAL             ; invalid parameters - invalid open mode
        .byte $2c               ; skip
@alreadyopen:
        lda #EMFILE             ; too many opened files (there can be only one)
        jmp __directerrno       ; set errno, clear oserror, return -1
@oserror:
        jmp __mappederrno       ; set platform error code, return -1

_close:
        lda #0
        sta __oserror
        jsr __seterrno          ; clear errors
        lda #0                  ; clear fd
        sta filedesc
        tax
        rts

_read:
    ; a/x - number of bytes
    ; popax - buffer ptr
    ; popax - fd, must be == to the above one
    ; return -1+__oserror or number of bytes read

        eor #$ff
        sta ptr1
        txa
        eor #$ff
        sta ptr1+1              ; -(# of bytes to read)-1
        jsr popax
        sta ptr2
        stx ptr2+1              ; buffer ptr
        jsr popax
        cmp #FILEDES            ; lo-byte == FILEDES
        bne @filenotopen
        txa                     ; hi-byte == 0
        beq @fileok             ; fd must be == FILEDES

@filenotopen:
        lda #EBADF
        jmp __directerrno       ; Sets _errno, clears _oserror, returns -1

@fileok:
        lda #0
        sta ptr3
        sta ptr3+1              ; put 0 into ptr3 (number of bytes read)
        sta __oserror           ; clear error flags
        jsr __seterrno

        lda f_track             ; restore stuff for ReadByte
        ldx f_sector
        sta r1L
        stx r1H
        lda f_buffer
        ldx f_buffer+1
        sta r4L
        stx r4H
        lda f_offset
        ldx f_offset+1
        sta r5L
        stx r5H

        clc
        bcc @L3                 ; branch always

@L0:    jsr _ReadByte
        ldy #0                  ; store the byte
        sta (ptr2),y
        inc ptr2                ; increment target address
        bne @L1
        inc ptr2+1

@L1:    inc ptr3                ; increment byte count
        bne @L2
        inc ptr3+1

@L2:    lda __oserror           ; was there error ?
        beq @L3
        cmp #BFR_OVERFLOW       ; EOF?
        beq @done               ; yes, we're done
        jmp __mappederrno       ; no, we're screwed

@L3:    inc ptr1                ; decrement the count
        bne @L0
        inc ptr1+1
        bne @L0

@done:
        lda r1L                 ; preserve data for ReadByte
        ldx r1H
        sta f_track
        stx f_sector
        lda r4L
        ldx r4H
        sta f_buffer
        stx f_buffer+1
        lda r5L
        ldx r5H
        sta f_offset
        stx f_offset+1

        lda ptr3                ; return byte count
        ldx ptr3+1
        rts

.bss

filedesc:
        .res 1                  ; file open flag - 0 (no file opened) or 1
f_track:
        .res 1                  ; values preserved for ReadByte
f_sector:
        .res 1
f_offset:
        .res 2
f_buffer:
        .res 2