home *** CD-ROM | disk | FTP | other *** search
-
- * 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
-
-