mirror of
https://github.com/cc65/cc65.git
synced 2024-11-05 08:05:51 +00:00
Rewrite fgets in asm
-104 bytes, -1% cycles
This commit is contained in:
parent
57e65a6bf6
commit
1f820d0ae8
@ -6,7 +6,7 @@
|
||||
|
||||
.export _statvfs
|
||||
.import _dio_query_sectsize
|
||||
.import mli_file_info, pushax, popax, popptr1
|
||||
.import mli_file_info, pushax, popax, popptr1, pushptr1
|
||||
.include "zeropage.inc"
|
||||
.include "apple2.inc"
|
||||
.include "errno.inc"
|
||||
@ -45,9 +45,7 @@ _statvfs:
|
||||
sty vol_sep ; Register '/' index
|
||||
lda #$00
|
||||
sta (ptr1),y ; Cut pathname at first slash
|
||||
: lda ptr1
|
||||
ldx ptr1+1
|
||||
jsr pushax
|
||||
: jsr pushptr1
|
||||
|
||||
jsr mli_file_info
|
||||
|
||||
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
** Ullrich von Bassewitz, 11.08.1998
|
||||
**
|
||||
** char* fgets (char* s, int size, FILE* f);
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "_file.h"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
char* __fastcall__ fgets (char* s, unsigned size, register FILE* f)
|
||||
{
|
||||
register char* p = s;
|
||||
unsigned i;
|
||||
int c;
|
||||
|
||||
if (size == 0) {
|
||||
/* Invalid size */
|
||||
return (char*) _seterrno (EINVAL);
|
||||
}
|
||||
|
||||
/* Read input */
|
||||
i = 0;
|
||||
while (--size) {
|
||||
|
||||
/* Get next character */
|
||||
if ((c = fgetc (f)) == EOF) {
|
||||
/* Error or EOF */
|
||||
if ((f->f_flags & _FERROR) != 0 || i == 0) {
|
||||
/* ERROR or EOF on first char */
|
||||
*p = '\0';
|
||||
return 0;
|
||||
} else {
|
||||
/* EOF with data already read */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* One char more */
|
||||
*p = c;
|
||||
++p;
|
||||
++i;
|
||||
|
||||
/* Stop at end of line */
|
||||
if ((char)c == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Terminate the string */
|
||||
*p = '\0';
|
||||
|
||||
/* Done */
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
119
libsrc/common/fgets.s
Normal file
119
libsrc/common/fgets.s
Normal file
@ -0,0 +1,119 @@
|
||||
;
|
||||
; Colin Leroy-Mira, 2024
|
||||
;
|
||||
; char* __fastcall__ fgets (char* s, unsigned size, register FILE* f)
|
||||
;
|
||||
|
||||
.export _fgets
|
||||
.import _fgetc, popptr1, pushptr1, popax, pushax, return0, ___errno
|
||||
.importzp ptr1, ptr4
|
||||
|
||||
.include "errno.inc"
|
||||
.include "stdio.inc"
|
||||
.include "_file.inc"
|
||||
|
||||
.macpack cpu
|
||||
|
||||
terminate_ptr:
|
||||
lda #$00
|
||||
tax
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
sta (ptr4)
|
||||
.else
|
||||
tay
|
||||
sta (ptr4),y
|
||||
.endif
|
||||
rts
|
||||
|
||||
_fgets:
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
|
||||
jsr popax
|
||||
sta size
|
||||
stx size+1
|
||||
|
||||
jsr popax
|
||||
sta ptr4
|
||||
stx ptr4+1
|
||||
sta buf
|
||||
stx buf+1
|
||||
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
stz didread
|
||||
.else
|
||||
lda #$00 ; We have read nothing yet
|
||||
sta didread
|
||||
.endif
|
||||
|
||||
; Check size
|
||||
lda size
|
||||
ora size+1
|
||||
bne read_loop
|
||||
lda #EINVAL
|
||||
sta ___errno
|
||||
jmp return0
|
||||
|
||||
read_loop:
|
||||
lda size ; Dec size
|
||||
bne :+
|
||||
dec size+1
|
||||
: dec size
|
||||
|
||||
bne :+ ; Check bound
|
||||
ldx size+1
|
||||
beq done
|
||||
|
||||
: jsr pushptr1 ; Push ptr1 for backup and load it to AX for fgetc
|
||||
jsr _fgetc ; Read a char
|
||||
|
||||
pha
|
||||
jsr popptr1 ; Get ptr1 back
|
||||
pla
|
||||
|
||||
cpx #<EOF
|
||||
beq got_eof
|
||||
|
||||
ldy #$01
|
||||
sty didread ; We read at least one char
|
||||
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
sta (ptr4)
|
||||
.else
|
||||
dey
|
||||
sta (ptr4),y
|
||||
.endif
|
||||
|
||||
inc ptr4
|
||||
bne :+
|
||||
inc ptr4+1
|
||||
|
||||
: cmp #$0A ; Stop at \n
|
||||
beq done
|
||||
|
||||
clc
|
||||
bcc read_loop
|
||||
|
||||
got_eof:
|
||||
lda didread
|
||||
beq stopped_at_first_char
|
||||
ldy #_FILE::f_flags
|
||||
lda (ptr1),y
|
||||
and #_FERROR
|
||||
bne stopped_at_first_char
|
||||
|
||||
done:
|
||||
jsr terminate_ptr
|
||||
ldx #>buf
|
||||
lda #<buf
|
||||
rts
|
||||
|
||||
stopped_at_first_char:
|
||||
jmp terminate_ptr
|
||||
|
||||
.bss
|
||||
|
||||
c: .res 1
|
||||
buf: .res 2
|
||||
size: .res 2
|
||||
didread:.res 1
|
14
libsrc/runtime/pushptr1.s
Normal file
14
libsrc/runtime/pushptr1.s
Normal file
@ -0,0 +1,14 @@
|
||||
;
|
||||
; Colin Leroy-Mira, 2024
|
||||
;
|
||||
; CC65 runtime: Push ptr1 to stack.
|
||||
; A/X destroyed (set to ptr1)
|
||||
|
||||
.export pushptr1
|
||||
.import pushax
|
||||
.importzp ptr1
|
||||
|
||||
pushptr1:
|
||||
lda ptr1
|
||||
ldx ptr1+1
|
||||
jmp pushax
|
Loading…
Reference in New Issue
Block a user