From 1f820d0ae813694c40da9639aa7ec048b79fecbd Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Thu, 11 Jan 2024 19:31:04 +0100 Subject: [PATCH] Rewrite fgets in asm -104 bytes, -1% cycles --- libsrc/apple2/statvfs.s | 6 +- libsrc/common/fgets.c | 68 ---------------------- libsrc/common/fgets.s | 119 ++++++++++++++++++++++++++++++++++++++ libsrc/runtime/pushptr1.s | 14 +++++ 4 files changed, 135 insertions(+), 72 deletions(-) delete mode 100644 libsrc/common/fgets.c create mode 100644 libsrc/common/fgets.s create mode 100644 libsrc/runtime/pushptr1.s diff --git a/libsrc/apple2/statvfs.s b/libsrc/apple2/statvfs.s index 6274bb52b..8fcf46af8 100644 --- a/libsrc/apple2/statvfs.s +++ b/libsrc/apple2/statvfs.s @@ -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 diff --git a/libsrc/common/fgets.c b/libsrc/common/fgets.c deleted file mode 100644 index 21a991fd6..000000000 --- a/libsrc/common/fgets.c +++ /dev/null @@ -1,68 +0,0 @@ -/* -** Ullrich von Bassewitz, 11.08.1998 -** -** char* fgets (char* s, int size, FILE* f); -*/ - - - -#include -#include -#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; -} - - - diff --git a/libsrc/common/fgets.s b/libsrc/common/fgets.s new file mode 100644 index 000000000..465658191 --- /dev/null +++ b/libsrc/common/fgets.s @@ -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 #buf + lda #