diff --git a/libsrc/common/fgetc.c b/libsrc/common/fgetc.c
deleted file mode 100644
index b4ba18d73..000000000
--- a/libsrc/common/fgetc.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-** fgetc.c
-**
-** (C) Copyright 1998, 2002 Ullrich von Bassewitz (uz@cc65.org)
-**
-*/
-
-
-
-#include <stdio.h>
-#include <unistd.h>
-#include "_file.h"
-
-
-
-/*****************************************************************************/
-/*                                   Code                                    */
-/*****************************************************************************/
-
-
-
-int __fastcall__ fgetc (register FILE* f)
-{
-    unsigned char c;
-
-    /* Check if the file is open or if there is an error condition */
-    if ((f->f_flags & _FOPEN) == 0 || (f->f_flags & (_FERROR | _FEOF)) != 0) {
-        return EOF;
-    }
-
-    /* If we have a pushed back character, return it */
-    if (f->f_flags & _FPUSHBACK) {
-        f->f_flags &= ~_FPUSHBACK;
-        return f->f_pushback;
-    }
-
-    /* Read one byte */
-    switch (read (f->f_fd, &c, 1)) {
-
-        case -1:
-            /* Error */
-            f->f_flags |= _FERROR;
-            return EOF;
-
-        case 0:
-            /* EOF */
-            f->f_flags |= _FEOF;
-            return EOF;
-
-        default:
-            /* Char read */
-            return c;
-
-    }
-}
-
-
-
diff --git a/libsrc/common/fgetc.s b/libsrc/common/fgetc.s
new file mode 100644
index 000000000..777696b7a
--- /dev/null
+++ b/libsrc/common/fgetc.s
@@ -0,0 +1,92 @@
+;
+; Colin Leroy-Mira, 2024
+;
+; int __fastcall__ fgetc (register FILE* f)
+;
+
+        .export         _fgetc
+        .import         _read, pusha0, pushax, popptr1, incsp2, returnFFFF
+        .importzp       ptr1
+
+        .include        "stdio.inc"
+        .include        "_file.inc"
+
+_fgetc:
+        sta     ptr1
+        stx     ptr1+1
+        jsr     pushax          ; Backup our ptr
+
+        ldy     #_FILE::f_flags
+        lda     (ptr1),y
+        tax
+        and     #_FOPEN         ; Check for file open
+        beq     ret_eof
+        txa
+        and     #(_FERROR|_FEOF); Check for error/eof
+        bne     ret_eof
+
+        txa
+        and     #_FPUSHBACK     ; Check for pushed back char
+        beq     do_read
+
+        txa
+        and     #<(~_FPUSHBACK) ; Reset flag
+        sta     (ptr1),y
+
+        .assert _FILE::f_pushback = _FILE::f_flags+1, error
+        iny
+        jsr     incsp2          ; Drop our ptr copy
+        lda     (ptr1),y        ; Return pushed back char
+        ldx     #$00
+        rts
+
+do_read:
+        ; Push _read parameters
+        ldy     #_FILE::f_fd
+        lda     (ptr1),y
+        jsr     pusha0
+
+        lda     #<c
+        ldx     #>c
+        jsr     pushax
+
+        lda     #$01
+        ldx     #$00
+
+        ; Read
+        jsr     _read
+
+        ; Check for errors
+        cmp     #$00
+        beq     set_feof
+
+        cmp     #<(-1)
+        beq     set_ferror
+
+        jsr     incsp2
+        ; Return char
+        ldx     #$00
+        lda     c
+        rts
+
+ret_eof:
+        jsr     incsp2
+        jmp     returnFFFF
+
+set_ferror:
+        lda     #_FERROR
+        bne     set_err
+set_feof:
+        lda     #_FEOF
+set_err:
+        pha
+        jsr     popptr1
+        pla
+        ldy     #_FILE::f_flags
+        ora     (ptr1),y
+        sta     (ptr1),y
+        jmp     returnFFFF
+
+        .bss
+
+c:      .res 1
diff --git a/test/ref/test_fgets.c b/test/ref/test_fgets.c
index 70d30a066..72ea308dd 100644
--- a/test/ref/test_fgets.c
+++ b/test/ref/test_fgets.c
@@ -45,6 +45,11 @@ int main(int argc,char **argv)
       return 1;
     }
 
+    /* Test ungetc while we're at it */
+    buf[0] = fgetc(in);
+    ungetc(buf[0], in);
+
+
     while (fgets(buf, sizeof(buf), in) != NULL)
     {
         printf("%s",buf);