Subversion Repositories Spectranet

[/] [trunk/] [modules/] [basext/] [tapetrap.asm] - Blame information for rev 442

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 222 winston
;The MIT License
2
;
3
;Copyright (c) 2009 Dylan Smith
4
;
5
;Permission is hereby granted, free of charge, to any person obtaining a copy
6
;of this software and associated documentation files (the "Software"), to deal
7
;in the Software without restriction, including without limitation the rights
8
;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
;copies of the Software, and to permit persons to whom the Software is
10
;furnished to do so, subject to the following conditions:
11
;
12
;The above copyright notice and this permission notice shall be included in
13
;all copies or substantial portions of the Software.
14
;
15
;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
;THE SOFTWARE.
22 399 winston
.include        "defs.inc"
23
.include        "spectranet.inc"
24
.include        "fcntl.inc"
25
.include        "sysvars.inc"
26 442 winston
.include        "errno.inc"
27 399 winston
.text
28 222 winston
; Initialize and handle tape traps.
29
 
30
;---------------------------------------------------------------------------
31
; F_settrap: Sets up tape traps for the named file.
32
; This must be called immediately after ZX_STK_FETCH to get the string.
33 399 winston
.globl F_settrap
34
F_settrap:
35 222 winston
        ld hl, INTERPWKSPC
36
        call F_basstrcpy        ; get the string from the interpreter
37
 
38
        ld a, (v_trapfd)        ; File already open?
39
        and a                   ; if so this will be nonzero
40
        call nz, F_releasetrap  ; and the old file should be closed.
41
 
42
        ld hl, INTERPWKSPC      ; try to open the file
43
        ld d, 0x00              ; no flags
44
        ld e, O_RDONLY          ; read only
45
        call OPEN
46
        ret c                   ; exit now on error
47
        ld (v_trapfd), a        ; save the file descriptor
48
 
49
        ld de, v_trap_blklen    ; read the TAP block length to "prime the
50
        ld bc, 2                ; system" as it were.
51
        call READ
52
        jp c, J_cleanup_traperr ; clean up if an error occurs (EOF is
53
                                ; considered an error at this point too)
54
 
55
        ld hl, TAPETRAPBLOCK    ; Program the CPLD NMI trap
56
        call SETTRAP
57
        ret
58
 
59 399 winston
TAPETRAPBLOCK:
60 222 winston
        defb    0xFF            ; this page
61
        defw    F_loadbytes     ; function to call
62 223 winston
        defw    0x0564          ; address at time of NMI
63
        defw    0x0562          ; address to trap with NMI
64 222 winston
 
65 399 winston
DEFAULTTRAPBLOCK:
66 239 winston
        defb    0xFF            ; this page
67
        defw    F_bootfile      ; function to call
68
        defw    0x0564          ; address at time of NMI
69
        defw    0x0562          ; address to trap with NMI
70
 
71 222 winston
;---------------------------------------------------------------------------
72
; F_releasetrap: Closes the file associated with the tape trap and disables
73
; the trap itself.
74 399 winston
.globl F_releasetrap
75
F_releasetrap:
76 222 winston
        push ix
77
        ld a, 1
78
        out (254), a
79
        ld a, (v_trapfd)
80
        call VCLOSE             ; close the file
81
        call DISABLETRAP        ; disable the tape trap address
82
        xor a
83
        ld (v_trapfd), a        ; clear the fd variable
84
        pop ix
85
        ret
86
 
87
;---------------------------------------------------------------------------
88
; F_loadbytes: Does the job of LD-BYTES in the main Spectrum ROM, but loading
89
; from a filesystem instead of tape.
90
; Parameters:           IX - address to load with data
91
;                       DE - how many bytes to load
92
;                       A - 0x00 for a header, 0xFF for data
93
;                       Carry flag is set for loading, reset for verify
94
; On return, the carry flag is the *opposite* to normal Spectranet code -
95
; the routines that call loadbytes expect carry to be set if there's NOT
96
; an error.
97 399 winston
.globl F_loadbytes
98
F_loadbytes:
99 222 winston
        push ix                 ; store address
100 399 winston
.globl F_loadbytes_nopush
101
F_loadbytes_nopush:             ; (if IX has already been pushed)
102 222 winston
        ld ix, 4                ; point IX at the stacked registers
103
        add ix, sp
104
 
105 242 winston
        ld hl, (NMISTACK)       ; get the old stack pointer
106
        ld (hl), 0x3F           ; and set the return address to
107
        inc hl
108
        ld (hl), 0x05           ; 0x053F SA/LD-RET in the Spectrum ROM
109
 
110 222 winston
        ld a, (v_trapfd)        ; this could be better optimized...
111
        ld bc, 1
112
        ld de, INTERPWKSPC
113
        push ix
114
        call READ               ; get the "flag" byte.
115
        pop ix
116 399 winston
        jr c, .cleanuperror14
117 222 winston
 
118
        ld a, (INTERPWKSPC)     ; compare the flag byte read with the flag
119 223 winston
        cp (ix+1)               ; passed in A to LD-BYTES
120 239 winston
 
121 399 winston
        jr nz, .skip4           ; if they aren't the same skip the block
122 222 winston
 
123
        ld c, (ix+6)            ; get the requested length into
124
        ld b, (ix+7)            ; BC
125
        pop de                  ; and the address into DE
126
        ld h, b                 ; remaining length in HL
127
        ld l, c
128 399 winston
.readloop4:
129 222 winston
        ld a, (v_trapfd)
130
        push hl
131
        push ix
132
        call READ
133
        pop ix
134
        pop hl
135 399 winston
        jr c, .cleanuperror24
136 222 winston
        sbc hl, bc              ; decrement length remaining
137
        ld b, h                 ; update requested bytes
138
        ld c, l
139 399 winston
        jr nz, .readloop4       ; continue until 0 bytes remain
140 222 winston
 
141
        ld a, (v_trapfd)
142
        ld bc, 3                ; now read the "check sum" + next block length
143
        ld de, INTERPWKSPC
144
        push ix
145
        call READ
146
        pop ix
147 399 winston
        jr c, .checkeof4                ; EOF?
148 222 winston
        ld hl, (INTERPWKSPC+1)  ; Get the length of the next block and copy
149
        ld (v_trap_blklen), hl  ; to the length storage.
150 399 winston
.success4:
151 222 winston
        ld (ix+2), 1            ; set carry flag in return stack
152
        jp PAGETRAPRETURN
153
 
154 399 winston
.checkeof4:
155 222 winston
        cp EOF                  ; End of file - not an error condition
156 399 winston
        jr nz, .cleanuperror24
157 222 winston
        call F_releasetrap      ; Close the file and release the trap
158
        ld (ix+2), 1            ; Signal success to ROM
159
        jp PAGETRAPRETURN
160
 
161 399 winston
.cleanuperror14:
162 222 winston
        pop hl                  ; restore the stack (originally ix)
163 399 winston
.cleanuperror24:
164 222 winston
        call F_releasetrap      ; Release the trap and close files
165
        ld (ix+2), 0            ; reset the carry flag to signal error
166
        jp PAGETRAPRETURN
167
 
168 399 winston
.skip4:                         ; TODO: when seek() is working...
169 222 winston
        call F_releasetrap
170
        pop de                  ; restore stack
171
        pop ix
172
        ld a, 2
173
        out (254), a            ; for debugging
174
        ld (ix+2), 0            ; ensure C is cleared
175
        jp PAGETRAPRETURN
176
 
177 399 winston
J_trapreturn:
178 222 winston
 
179
;---------------------------------------------------------------------------
180 399 winston
J_cleanup_traperr:
181 222 winston
        push af
182
        ld a, (v_trapfd)
183
        call VCLOSE
184
        pop af
185 239 winston
        ret
186
 
187
;--------------------------------------------------------------------------
188
; F_initbootfile: Sets up LOAD ""
189 399 winston
.globl F_initbootfile
190
F_initbootfile:
191 239 winston
        ld hl, DEFAULTTRAPBLOCK ; Program the CPLD NMI trap
192
        call SETTRAP
193
        ret
194
 
195
;--------------------------------------------------------------------------
196
; F_bootfile
197
; Handles the case of an unsolicited LOAD "". It will try to load the file
198
; "boot" in the current working directory. If the file doesn't exist, it
199
; releases the trap and returns control to the tape loader.
200 399 winston
.globl F_bootfile
201
F_bootfile:
202 239 winston
        push ix
203
        ld hl, DEFAULTFILE      ; first copy the filename into memory
204
        ld de, INTERPWKSPC      ; that's accessable by the FS module
205
        ld bc, DEFAULTFILELEN
206
        ldir
207
 
208
        ld hl, INTERPWKSPC      ; try to open the file
209
        ld d, 0x00              ; no flags
210
        ld e, O_RDONLY          ; read only
211
        call OPEN
212 399 winston
        jr c, .usetape6         ; On error, simply pass control back to the
213 239 winston
                                ; ROM tape loader.
214
        ld (v_trapfd), a        ; save the file descriptor
215
 
216
        ld de, v_trap_blklen    ; read the TAP block length to "prime the
217
        ld bc, 2                ; system" as it were.
218
        call READ
219 399 winston
        jr c, .cleanupusetape6  ; any errors, then clean up and use tape. (EOF
220 239 winston
                                ; considered an error at this point too)
221
 
222
        ld hl, TAPETRAPBLOCK    ; Reprogram the NMI trap.
223
        call SETTRAP
224
        jp F_loadbytes_nopush   ; and go to loadbytes to do the work.
225
 
226 399 winston
.cleanupusetape6:
227 239 winston
        ld a, (v_trapfd)
228
        call VCLOSE             ; close the file
229 399 winston
.usetape6:
230 239 winston
        pop ix
231
        jp PAGETRAPRETURN
232
 
233 399 winston
DEFAULTFILE:
234
        defb    "boot.zx6",0
235
DEFAULTFILELEN: equ $-DEFAULTFILE
236 239 winston