mirror of
https://github.com/cc65/cc65.git
synced 2024-12-27 00:29:31 +00:00
a BIT of 65C02 optimisations
Use BIT immediate instead of AND when reloading A is required afterwards. Add an fread unit test as the optimisation touches fread. Sprinkle a few zero page indexed while we're at it.
This commit is contained in:
parent
2a03e5d8c9
commit
1fab179cb4
@ -13,6 +13,7 @@
|
||||
.import _strlower, _strlen
|
||||
|
||||
.macpack generic
|
||||
.macpack cpu
|
||||
|
||||
; ----------------------------------------------------------------------------
|
||||
; We will store variables into the register bank in the zeropage. Define
|
||||
@ -37,7 +38,11 @@ FCount = ptr2
|
||||
|
||||
GetFormatChar:
|
||||
ldy #0
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
lda (Format)
|
||||
.else
|
||||
lda (Format),y
|
||||
.endif
|
||||
IncFormatPtr:
|
||||
inc Format
|
||||
bne @L1
|
||||
@ -110,7 +115,11 @@ GetIntArg:
|
||||
lda (ArgList),y
|
||||
tax
|
||||
dey
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
lda (ArgList)
|
||||
.else
|
||||
lda (ArgList),y
|
||||
.endif
|
||||
rts
|
||||
|
||||
; ----------------------------------------------------------------------------
|
||||
@ -135,9 +144,9 @@ ReadInt:
|
||||
pha ; Save digit value
|
||||
lda ptr1
|
||||
ldx ptr1+1
|
||||
asl ptr1
|
||||
asl a
|
||||
rol ptr1+1 ; * 2
|
||||
asl ptr1
|
||||
asl a
|
||||
rol ptr1+1 ; * 4, assume carry clear
|
||||
adc ptr1
|
||||
sta ptr1
|
||||
@ -265,10 +274,16 @@ Save: lda regbank,y
|
||||
; Initialize the output counter in the output descriptor to zero
|
||||
|
||||
lda #0
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
sta (OutData)
|
||||
ldy #$01
|
||||
sta (OutData),y
|
||||
.else
|
||||
tay
|
||||
sta (OutData),y
|
||||
iny
|
||||
sta (OutData),y
|
||||
.endif
|
||||
|
||||
; Get the output function from the output descriptor and remember it
|
||||
|
||||
@ -338,7 +353,11 @@ MainLoop:
|
||||
sta (sp),y
|
||||
dey
|
||||
lda FCount
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
sta (sp)
|
||||
.else
|
||||
sta (sp),y
|
||||
.endif
|
||||
jsr CallOutFunc ; Call the output function
|
||||
|
||||
; We're back from out(), or we didn't call it. Check for end of string.
|
||||
@ -551,10 +570,16 @@ CheckCount:
|
||||
jsr GetIntArg
|
||||
sta ptr1
|
||||
stx ptr1+1 ; Get user supplied pointer
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
lda (OutData) ; Low byte of OutData->ccount
|
||||
sta (ptr1)
|
||||
ldy #1
|
||||
.else
|
||||
ldy #0
|
||||
lda (OutData),y ; Low byte of OutData->ccount
|
||||
sta (ptr1),y
|
||||
iny
|
||||
.endif
|
||||
lda (OutData),y ; High byte of OutData->ccount
|
||||
sta (ptr1),y
|
||||
jmp MainLoop ; Done
|
||||
|
@ -12,6 +12,8 @@
|
||||
.include "stdio.inc"
|
||||
.include "_file.inc"
|
||||
|
||||
.macpack cpu
|
||||
|
||||
_fgetc:
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
@ -20,11 +22,16 @@ _fgetc:
|
||||
jsr checkferror
|
||||
bne ret_eof
|
||||
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
bit #_FPUSHBACK ; Check for pushed back char
|
||||
beq do_read
|
||||
.else
|
||||
tax
|
||||
and #_FPUSHBACK ; Check for pushed back char
|
||||
beq do_read
|
||||
|
||||
txa
|
||||
.endif
|
||||
|
||||
and #<(~_FPUSHBACK) ; Reset flag
|
||||
sta (ptr1),y
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
.include "_file.inc"
|
||||
|
||||
.macpack generic
|
||||
.macpack cpu
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Code
|
||||
@ -47,13 +48,21 @@
|
||||
|
||||
ldy #_FILE::f_flags
|
||||
lda (file),y
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
bit #_FOPEN ; Is the file open?
|
||||
.else
|
||||
and #_FOPEN ; Is the file open?
|
||||
.endif
|
||||
beq @L1 ; Branch if no
|
||||
|
||||
; Check if the stream is in an error state
|
||||
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
bit #_FERROR
|
||||
.else
|
||||
lda (file),y ; get file->f_flags again
|
||||
and #_FERROR
|
||||
.endif
|
||||
beq @L2
|
||||
|
||||
; File not open or in error state
|
||||
@ -65,11 +74,19 @@
|
||||
|
||||
; Remember if we have a pushed back character and reset the flag.
|
||||
|
||||
@L2: tax ; X = 0
|
||||
@L2: .if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
ldx #$00
|
||||
bit #_FPUSHBACK
|
||||
.else
|
||||
tax ; X = 0
|
||||
lda (file),y
|
||||
and #_FPUSHBACK
|
||||
.endif
|
||||
beq @L3
|
||||
|
||||
.if (.not .cpu .bitand ::CPU_ISET_65SC02)
|
||||
lda (file),y
|
||||
.endif
|
||||
and #<~_FPUSHBACK
|
||||
sta (file),y ; file->f_flags &= ~_FPUSHBACK;
|
||||
inx ; X = 1
|
||||
@ -118,12 +135,20 @@
|
||||
; Copy the buffer pointer into ptr1, and increment the pointer value passed
|
||||
; to read() by one, so read() starts to store data at buf+1.
|
||||
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
lda (sp)
|
||||
sta ptr1
|
||||
add #1
|
||||
sta (sp)
|
||||
ldy #1
|
||||
.else
|
||||
ldy #0
|
||||
lda (sp),y
|
||||
sta ptr1
|
||||
add #1
|
||||
sta (sp),y
|
||||
iny
|
||||
.endif
|
||||
lda (sp),y
|
||||
sta ptr1+1
|
||||
adc #0
|
||||
@ -134,8 +159,12 @@
|
||||
|
||||
ldy #_FILE::f_pushback
|
||||
lda (file),y
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
sta (ptr1) ; *buf = file->f_pushback;
|
||||
.else
|
||||
ldy #0
|
||||
sta (ptr1),y ; *buf = file->f_pushback;
|
||||
.endif
|
||||
|
||||
; Restore the low byte of count and decrement count by one. This may result
|
||||
; in count being zero, so check for that.
|
||||
@ -210,4 +239,3 @@
|
||||
.bss
|
||||
save: .res 2
|
||||
pb: .res 1
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
.export _fwrite
|
||||
|
||||
.import _write
|
||||
.import pushax, incsp6, addysp, ldaxysp, pushwysp, return0
|
||||
.import pushax, pusha0, incsp6, addysp, ldaxysp, pushwysp, return0
|
||||
.import tosumulax, tosudivax
|
||||
|
||||
.importzp ptr1
|
||||
@ -16,6 +16,7 @@
|
||||
.include "errno.inc"
|
||||
.include "_file.inc"
|
||||
|
||||
.macpack cpu
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Code
|
||||
@ -33,7 +34,11 @@
|
||||
|
||||
ldy #_FILE::f_flags
|
||||
lda (ptr1),y
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
bit #_FOPEN
|
||||
.else
|
||||
and #_FOPEN ; Is the file open?
|
||||
.endif
|
||||
bne @L2 ; Branch if yes
|
||||
|
||||
; File not open
|
||||
@ -45,7 +50,9 @@
|
||||
|
||||
; Check if the stream is in an error state
|
||||
|
||||
@L2: lda (ptr1),y ; get file->f_flags again
|
||||
@L2: .if (.not .cpu .bitand ::CPU_ISET_65SC02)
|
||||
lda (ptr1),y ; get file->f_flags again
|
||||
.endif
|
||||
and #_FERROR
|
||||
bne @L1
|
||||
|
||||
@ -53,8 +60,7 @@
|
||||
|
||||
ldy #_FILE::f_fd
|
||||
lda (ptr1),y
|
||||
ldx #$00
|
||||
jsr pushax ; file->f_fd
|
||||
jsr pusha0 ; file->f_fd
|
||||
|
||||
ldy #9
|
||||
jsr pushwysp ; buf
|
||||
@ -123,4 +129,3 @@
|
||||
|
||||
.bss
|
||||
file: .res 2
|
||||
|
||||
|
70
test/ref/test_fread.c
Normal file
70
test/ref/test_fread.c
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
!!DESCRIPTION!! fgets test
|
||||
!!LICENCE!! Public domain
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
FILE *in, *out;
|
||||
char buf[32];
|
||||
|
||||
#define INFILE "cf.in"
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
static char outfile_path[FILENAME_MAX+1];
|
||||
static int r;
|
||||
|
||||
sprintf(outfile_path, "%s.test.out", argv[0]);
|
||||
|
||||
out = fopen(outfile_path, "wb");
|
||||
if (out == NULL) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (fread(buf, 1, sizeof(buf), out) != NULL) {
|
||||
printf("Error, could fread with write-only file\n");
|
||||
return 1;
|
||||
}
|
||||
if (!ferror(out)) {
|
||||
printf("Error: file pointer should be in error state\n");
|
||||
}
|
||||
fclose(out);
|
||||
unlink(outfile_path);
|
||||
|
||||
in = fopen(INFILE, "rb");
|
||||
if (in == NULL) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Test that ungetc doesn't break fread */
|
||||
buf[0] = fgetc(in);
|
||||
ungetc(buf[0], in);
|
||||
|
||||
r = fread(buf, 1, sizeof(buf), out);
|
||||
|
||||
if (r == 0) {
|
||||
printf("Error: could not start reading.\n");
|
||||
}
|
||||
fwrite(buf, 1, r, stdout);
|
||||
|
||||
/* Finish reading file. */
|
||||
while ((r = fread(buf, 1, sizeof(buf), out)) != 0)
|
||||
{
|
||||
fwrite(buf, 1, r, stdout);
|
||||
}
|
||||
|
||||
if (!feof(in))
|
||||
{
|
||||
printf("We should have EOF!\n");
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user