home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 1
/
GoldFishApril1994_CD1.img
/
d1xx
/
d183
/
pcq
/
runtime
/
openers.asm
< prev
next >
Wrap
Assembly Source File
|
1989-02-25
|
4KB
|
149 lines
* Openers.asm (of PCQ Pascal runtime library)
* Copyright (c) 1989 Patrick Quaid
* This file takes care of opening and closing DOS files. In
* much the same way as the memory routines, these routines keep a
* list of the open files around. Open() puts the files on the list
* and Close() takes them off.
SECTION ONE
XREF _p%DOSBase
XREF _LVOOpen
XREF _p%new
XREF _p%dispose
XREF _p%wrapitup
XREF _LVORead
XREF _LVOClose
XDEF filekey
* algorithm for open:
*
* open the file
* set the link
* store the file handle
* if the record size is not 1, 2, or 4
* call _p%new to allocate a buffer
* store the address of the buffer
* if it's an input file
* read the first record
* set the eof field accordingly
XDEF _p%open
_p%open:
move.l d2,-(sp) ; save the access mode
move.l a0,-(sp) ; save address of file record
move.l d0,d1 ; get address of file name string
move.l _p%DOSBase,a6 ; d2 already has mode
jsr _LVOOpen(a6)
tst.l d0 ; opened ok?
bne.s 1$ ; if so, skip this
add.l #8,sp ; restore stack
rts ; and return
1$ move.l (sp)+,a0 ; get address back
move.l d0,(a0) ; save file handle in record
move.l filekey,14(a0) ; save link
move.l a0,filekey ; add to list
move.l 8(a0),d0 ; get size
cmp.l #1,d0 ; is it 1?
beq.s 2$ ; if so, skip this bit here.
cmp.l #2,d0 ; ditto if two or four
beq.s 2$
cmp.l #4,d0
beq.s 2$
move.l a0,-(sp) ; save address (again)
jsr _p%new ; get block of size in d0, left in d0
move.l (sp)+,a0 ; get address back again
move.l d0,4(a0) ; store the pointer to the new block
bne.s 2$ ; if it's ok, go on.
jmp _p%wrapitup ; no memory for file. Abort!
2$ move.b #0,12(a0) ; set eof = false
move.l (sp)+,d0 ; retrieve access mode
cmp.l #1005,d0 ; is it 1005?
bne.s 3$ ; if so, then it's an input file.
* at this point, a0 has the address of the file block, which
* is set up correctly except for the data direction. Thus we'll
* set that, then just call the arbitrary read routine on the file.
move.b #0,13(a0) ; set inout = input
jsr _p%readarbbuf ; read an arbitrary datum into buffer
; that routine sets the eof flag correctly
3$ move.l #-1,d0 ; regardless of how the read went, the
rts ; file IS open, so return true.
XDEF _p%readarbbuf
_p%readarbbuf
* read 'record length' bytes from 'filehandle' into the record's buffer
* a0 is the file record
* set the eof field accordingly
move.l a0,-(sp)
move.l (a0),d1 ; get file handle
move.l 8(a0),d3 ; get length
lea 4(a0),a1
move.l a1,d2 ; get address of buffer.
; this is correct for size = 1,2 or 3.
; figure most will be that size, right?
cmp.l #1,d3 ; is it, in fact, 1?
beq.s 1$ ; if so, then skip correction
cmp.l #2,d3 ; same with 2
beq.s 1$
cmp.l #4,d3 ; and 4
beq.s 1$
move.l 4(a0),d2 ; load ADDRESS of buffer (correct the assumption)
1$ move.l _p%DOSBase,a6
jsr _LVORead(a6)
move.l (sp)+,a0 ; retrieve address
cmp.l 8(a0),d0 ; did everything go ok?
beq.s 2$ ; yes, so just leave
move.b #-1,12(a0) ; eof = true
2$ rts
XDEF _p%close
_p%close:
move.l d0,a0 ; get address into a0
1$ cmp.l filekey,a0 ; is this first open file?
bne.s 2$ ; if not, go around
move.l 14(a0),filekey ; bypass record
bra 5$ ; and close file
2$ move.l filekey,a1
move.l 14(a1),a2 ; a1 is trailer, a2 is node
3$ cmp.l a2,a0 ; is this node the original?
beq.s 4$ ; if so, go
move.l a2,a1
move.l 14(a2),a2 ; set up for next
move.l a2,d0 ; is this zero?
bne 3$
rts ; wasn't in list! Abort!
4$ move.l 14(a2),a2 ; get next
move.l a2,14(a1) ; bypass this node
5$ move.l (a0),d1
move.l a0,-(sp)
move.l _p%DOSBase,a6
jsr _LVOClose(a6)
move.l (sp)+,a0
move.l 8(a0),d0
cmp.l #1,d0 ; if size = 1 then no buffer
beq.s 6$ ; so skip
cmp.l #2,d0 ; same for 2
beq.s 6$
cmp.l #4,d0 ; and 4
beq.s 6$
move.l 4(a0),d0 ; get address of block
jsr _p%dispose ; free the buffer
6$ rts
SECTION TWO
filekey dc.l 0
END