; Assembler include file that makes the constants and structures in _file.h
; available for asm code.
-; Struct _FILE offsets and size
-_FILE_f_fd = $00
-_FILE_f_flags = $01
-_FILE_size = $02
+; Struct _FILE
+.struct _FILE
+ f_fd .byte
+ f_flags .byte
+.endstruct
; Flags field
_FCLOSED = $00
; Assembler include file that makes the constants and structures in _heap.h
; available for asm code.
-HEAP_ADMIN_SPACE = 2
-HEAP_MIN_BLOCKSIZE = 6 ; Minimum size of an allocated block
+; Struct freeblock
+; NOTE: For performance reasons, the asm code often uses increment/decrement
+; operators to access other offsets, so just changing offsets here will
+; probably not work.
+.struct freeblock
+ size .word
+ next .word
+ prev .word
+.endstruct
-; Struct freeblock offsets and size. NOTE: For performance reasons, the asm
-; code often uses increment/decrement operators to access other offsets, so
-; just changing offsets here will probably not work.
-freeblock_size = 0
-freeblock_next = 2
-freeblock_prev = 4
+HEAP_ADMIN_SPACE = 2
+HEAP_MIN_BLOCKSIZE = .sizeof (freeblock) ; Minimum size of an allocated block
; Variables
.global __heaporg
lda #0
jsr getfd
- sta __filetab + (0 * _FILE_size) ; setup stdin
+ sta __filetab + (0 * .sizeof(_FILE)); setup stdin
lda #0
jsr getfd
- sta __filetab + (1 * _FILE_size) ; setup stdout
+ sta __filetab + (1 * .sizeof(_FILE)); setup stdout
lda #0
jsr getfd
- sta __filetab + (2 * _FILE_size) ; setup stderr
+ sta __filetab + (2 * .sizeof(_FILE)); setup stderr
; Push arguments and call main
ldy #0
lda #_FOPEN
-Loop: and __filetab + _FILE_f_flags,y ; load flags
+Loop: and __filetab + _FILE::f_flags,y ; load flags
beq Found ; jump if closed
-.repeat ::_FILE_size
+.repeat .sizeof(_FILE)
iny
.endrepeat
- cpy #(FOPEN_MAX * _FILE_size) ; Done?
+ cpy #(FOPEN_MAX * .sizeof(_FILE)) ; Done?
bne Loop
; File table is full
;
.export __filetab
-
+
.include "stdio.inc"
.include "fcntl.inc"
.include "_file.inc"
; Standard file descriptors
_stdin:
- .word __filetab + (STDIN_FILENO * _FILE_size)
+ .word __filetab + (STDIN_FILENO * .sizeof(_FILE))
_stdout:
- .word __filetab + (STDOUT_FILENO * _FILE_size)
+ .word __filetab + (STDOUT_FILENO * .sizeof(_FILE))
_stderr:
- .word __filetab + (STDERR_FILENO * _FILE_size)
+ .word __filetab + (STDERR_FILENO * .sizeof(_FILE))
-;
+;
; Ullrich von Bassewitz, 22.11.2002
;
; FILE* __fastcall__ _fopen (const char* name, const char* mode, FILE* f);
sty ptr1
ldy file+1
sty ptr1+1
- ldy #_FILE_f_fd
+ ldy #_FILE::f_fd
sta (ptr1),y ; file->f_fd = fd;
- ldy #_FILE_f_flags
+ ldy #_FILE::f_flags
lda #_FOPEN
sta (ptr1),y ; file->f_flags = _FOPEN;
; The block is large enough. Set the size field in the block.
-@L1: ldy #freeblock_size
+@L1: ldy #freeblock::size
sta (ptr2),y
iny
txa
; size_t __fastcall__ _heapmaxavail (void);
;
;
-
+
.importzp ptr1, ptr2
.export __heapmaxavail
; if (Size < F->size) {
- ldy #freeblock_size
+ ldy #freeblock::size
lda ptr2
sub (ptr1),y
iny
; Size = F->size;
- ldy #freeblock_size
+ ldy #freeblock::size
lda (ptr1),y
sta ptr2
iny
__heapmemavail:
-; size_t Size = 0;
+; size_t Size = 0;
lda #0
sta ptr2
; Size += F->size;
- ldy #freeblock_size
+ ldy #freeblock::size
lda (ptr1),y
add ptr2
sta ptr2
.export _fclose
.import _close
- .importzp ptr1
+ .importzp ptr1
.include "errno.inc"
.include "_file.inc"
; Check if the file is really open
- ldy #_FILE_f_flags
+ ldy #_FILE::f_flags
lda (ptr1),y
and #_FOPEN
bne @L1
@L1: lda #_FCLOSED
sta (ptr1),y
- ldy #_FILE_f_fd
+ ldy #_FILE::f_fd
lda (ptr1),y
ldx #0
jmp _close ; Will set errno and return an error flag
getf: sta ptr1
stx ptr1+1
- ldy #_FILE_f_flags
+ ldy #_FILE::f_flags
lda (ptr1),y ; get f->f_flags
and #_FOPEN ; file open?
beq @L1 ; jump if no
; Check if the file is open
- ldy #_FILE_f_flags
+ ldy #_FILE::f_flags
lda (ptr1),y
and #_FOPEN ; Is the file open?
bne @L2 ; Branch if yes
; Build the stackframe for read()
- ldy #_FILE_f_fd
+ ldy #_FILE::f_fd
lda (ptr1),y
ldx #$00
jsr pushax ; file->f_fd
sta ptr1
lda file+1
sta ptr1+1
- ldy #_FILE_f_flags
+ ldy #_FILE::f_flags
lda (ptr1),y
ora tmp1
sta (ptr1),y
sta ptr2
bcs @L1
dec ptr2+1
-@L1: ldy #freeblock_size+1
+@L1: ldy #freeblock::size+1
lda (ptr2),y ; High byte of size
sta ptr1+1 ; Save it
dey
lda __heaplast+1
sta ptr1+1 ; Pointer to last block now in ptr1
- ldy #freeblock_size
+ ldy #freeblock::size
lda (ptr1),y ; Low byte of block size
add ptr1
tax
; Correct the next pointer of the now last block
- ldy #freeblock_prev+1 ; Offset of ->prev field
+ ldy #freeblock::prev+1 ; Offset of ->prev field
lda (ptr1),y
sta ptr2+1 ; Remember f->prev in ptr2
sta __heaplast+1
; The free list is empty, so this is the first and only block. A contains
; zero if we come here.
- ldy #freeblock_next-1
+ ldy #freeblock::next-1
@L2: iny ; f->next = f->prev = 0;
sta (ptr2),y
- cpy #freeblock_prev+1 ; Done?
+ cpy #freeblock::prev+1 ; Done?
bne @L2
lda ptr2
lda #0
sta ptr4
sta ptr4+1 ; left = 0;
- ldy #freeblock_next+1
+ ldy #freeblock::next+1
ldx ptr3
@Loop: lda ptr3+1 ; High byte of right
; Merge with the right block. Do f->size += right->size;
- ldy #freeblock_size
+ ldy #freeblock::size
lda ptr1
add (ptr3),y
sta (ptr2),y
; No right merge, just set the link.
NoRightMerge:
- ldy #freeblock_next ; f->next = right;
+ ldy #freeblock::next ; f->next = right;
lda ptr3
sta (ptr2),y
iny ; Points to next+1
; We don't have a left block, so f is actually the new freelist start
- ldy #freeblock_prev
+ ldy #freeblock::prev
sta (ptr2),y ; f->prev = 0;
iny
sta (ptr2),y
; Check if the left block is adjacent to the following one
CheckLeftMerge2:
- ldy #freeblock_size ; Calculate left + left->size
+ ldy #freeblock::size ; Calculate left + left->size
lda (ptr4),y ; Low byte of left->size
add ptr4
tax
-
+
; Check if the file is open
- ldy #_FILE_f_flags
+ ldy #_FILE::f_flags
lda (ptr1),y
and #_FOPEN ; Is the file open?
bne @L2 ; Branch if yes
; Build the stackframe for write()
- ldy #_FILE_f_fd
+ ldy #_FILE::f_fd
lda (ptr1),y
ldx #$00
jsr pushax ; file->f_fd
sta ptr1
lda file+1
sta ptr1+1
- ldy #_FILE_f_flags
+ ldy #_FILE::f_flags
lda (ptr1),y
ora #_FERROR
sta (ptr1),y
jmp @L4
-@L3: ldy #freeblock_size
+@L3: ldy #freeblock::size
lda (ptr2),y
sub ptr1
tax ; Remember low byte for later
- iny ; Y points to freeblock_size+1
+ iny ; Y points to freeblock::size+1
lda (ptr2),y
sbc ptr1+1
bcs BlockFound ; Beware: Contents of a/x/y are known!
; Next block in list
- iny ; Points to freeblock_next
+ iny ; Points to freeblock::next
lda (ptr2),y
tax
- iny ; Points to freeblock_next+1
+ iny ; Points to freeblock::next+1
lda (ptr2),y
stx ptr2
sta ptr2+1
; does already contain the correct size word, all we have to do is to
; remove it from the free list.
- ldy #freeblock_prev+1 ; Load f->prev
+ ldy #freeblock::prev+1 ; Load f->prev
lda (ptr2),y
sta ptr3+1
dey
lda (ptr2),y
sta ptr3
- dey ; Points to freeblock_next+1
+ dey ; Points to freeblock::next+1
ora ptr3+1
beq @L1 ; Jump if f->prev zero
; Fill the size into the admin space of the block and return the user pointer
FillSizeAndRet:
- ldy #freeblock_size ; *p = size;
+ ldy #freeblock::size ; *p = size;
lda ptr1 ; Low byte of block size
sta (ptr2),y
- iny ; Points to freeblock_size+1
+ iny ; Points to freeblock::size+1
lda ptr1+1
sta (ptr2),y