mirror of
https://github.com/cc65/cc65.git
synced 2024-12-27 15:29:46 +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
|
.import _strlower, _strlen
|
||||||
|
|
||||||
.macpack generic
|
.macpack generic
|
||||||
|
.macpack cpu
|
||||||
|
|
||||||
; ----------------------------------------------------------------------------
|
; ----------------------------------------------------------------------------
|
||||||
; We will store variables into the register bank in the zeropage. Define
|
; We will store variables into the register bank in the zeropage. Define
|
||||||
@ -37,7 +38,11 @@ FCount = ptr2
|
|||||||
|
|
||||||
GetFormatChar:
|
GetFormatChar:
|
||||||
ldy #0
|
ldy #0
|
||||||
|
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||||
|
lda (Format)
|
||||||
|
.else
|
||||||
lda (Format),y
|
lda (Format),y
|
||||||
|
.endif
|
||||||
IncFormatPtr:
|
IncFormatPtr:
|
||||||
inc Format
|
inc Format
|
||||||
bne @L1
|
bne @L1
|
||||||
@ -110,7 +115,11 @@ GetIntArg:
|
|||||||
lda (ArgList),y
|
lda (ArgList),y
|
||||||
tax
|
tax
|
||||||
dey
|
dey
|
||||||
|
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||||
|
lda (ArgList)
|
||||||
|
.else
|
||||||
lda (ArgList),y
|
lda (ArgList),y
|
||||||
|
.endif
|
||||||
rts
|
rts
|
||||||
|
|
||||||
; ----------------------------------------------------------------------------
|
; ----------------------------------------------------------------------------
|
||||||
@ -135,9 +144,9 @@ ReadInt:
|
|||||||
pha ; Save digit value
|
pha ; Save digit value
|
||||||
lda ptr1
|
lda ptr1
|
||||||
ldx ptr1+1
|
ldx ptr1+1
|
||||||
asl ptr1
|
asl a
|
||||||
rol ptr1+1 ; * 2
|
rol ptr1+1 ; * 2
|
||||||
asl ptr1
|
asl a
|
||||||
rol ptr1+1 ; * 4, assume carry clear
|
rol ptr1+1 ; * 4, assume carry clear
|
||||||
adc ptr1
|
adc ptr1
|
||||||
sta ptr1
|
sta ptr1
|
||||||
@ -265,10 +274,16 @@ Save: lda regbank,y
|
|||||||
; Initialize the output counter in the output descriptor to zero
|
; Initialize the output counter in the output descriptor to zero
|
||||||
|
|
||||||
lda #0
|
lda #0
|
||||||
|
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||||
|
sta (OutData)
|
||||||
|
ldy #$01
|
||||||
|
sta (OutData),y
|
||||||
|
.else
|
||||||
tay
|
tay
|
||||||
sta (OutData),y
|
sta (OutData),y
|
||||||
iny
|
iny
|
||||||
sta (OutData),y
|
sta (OutData),y
|
||||||
|
.endif
|
||||||
|
|
||||||
; Get the output function from the output descriptor and remember it
|
; Get the output function from the output descriptor and remember it
|
||||||
|
|
||||||
@ -338,7 +353,11 @@ MainLoop:
|
|||||||
sta (sp),y
|
sta (sp),y
|
||||||
dey
|
dey
|
||||||
lda FCount
|
lda FCount
|
||||||
|
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||||
|
sta (sp)
|
||||||
|
.else
|
||||||
sta (sp),y
|
sta (sp),y
|
||||||
|
.endif
|
||||||
jsr CallOutFunc ; Call the output function
|
jsr CallOutFunc ; Call the output function
|
||||||
|
|
||||||
; We're back from out(), or we didn't call it. Check for end of string.
|
; We're back from out(), or we didn't call it. Check for end of string.
|
||||||
@ -551,10 +570,16 @@ CheckCount:
|
|||||||
jsr GetIntArg
|
jsr GetIntArg
|
||||||
sta ptr1
|
sta ptr1
|
||||||
stx ptr1+1 ; Get user supplied pointer
|
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
|
ldy #0
|
||||||
lda (OutData),y ; Low byte of OutData->ccount
|
lda (OutData),y ; Low byte of OutData->ccount
|
||||||
sta (ptr1),y
|
sta (ptr1),y
|
||||||
iny
|
iny
|
||||||
|
.endif
|
||||||
lda (OutData),y ; High byte of OutData->ccount
|
lda (OutData),y ; High byte of OutData->ccount
|
||||||
sta (ptr1),y
|
sta (ptr1),y
|
||||||
jmp MainLoop ; Done
|
jmp MainLoop ; Done
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
.include "stdio.inc"
|
.include "stdio.inc"
|
||||||
.include "_file.inc"
|
.include "_file.inc"
|
||||||
|
|
||||||
|
.macpack cpu
|
||||||
|
|
||||||
_fgetc:
|
_fgetc:
|
||||||
sta ptr1
|
sta ptr1
|
||||||
stx ptr1+1
|
stx ptr1+1
|
||||||
@ -20,11 +22,16 @@ _fgetc:
|
|||||||
jsr checkferror
|
jsr checkferror
|
||||||
bne ret_eof
|
bne ret_eof
|
||||||
|
|
||||||
|
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||||
|
bit #_FPUSHBACK ; Check for pushed back char
|
||||||
|
beq do_read
|
||||||
|
.else
|
||||||
tax
|
tax
|
||||||
and #_FPUSHBACK ; Check for pushed back char
|
and #_FPUSHBACK ; Check for pushed back char
|
||||||
beq do_read
|
beq do_read
|
||||||
|
|
||||||
txa
|
txa
|
||||||
|
.endif
|
||||||
|
|
||||||
and #<(~_FPUSHBACK) ; Reset flag
|
and #<(~_FPUSHBACK) ; Reset flag
|
||||||
sta (ptr1),y
|
sta (ptr1),y
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
.include "_file.inc"
|
.include "_file.inc"
|
||||||
|
|
||||||
.macpack generic
|
.macpack generic
|
||||||
|
.macpack cpu
|
||||||
|
|
||||||
; ------------------------------------------------------------------------
|
; ------------------------------------------------------------------------
|
||||||
; Code
|
; Code
|
||||||
@ -47,13 +48,21 @@
|
|||||||
|
|
||||||
ldy #_FILE::f_flags
|
ldy #_FILE::f_flags
|
||||||
lda (file),y
|
lda (file),y
|
||||||
|
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||||
|
bit #_FOPEN ; Is the file open?
|
||||||
|
.else
|
||||||
and #_FOPEN ; Is the file open?
|
and #_FOPEN ; Is the file open?
|
||||||
|
.endif
|
||||||
beq @L1 ; Branch if no
|
beq @L1 ; Branch if no
|
||||||
|
|
||||||
; Check if the stream is in an error state
|
; 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
|
lda (file),y ; get file->f_flags again
|
||||||
and #_FERROR
|
and #_FERROR
|
||||||
|
.endif
|
||||||
beq @L2
|
beq @L2
|
||||||
|
|
||||||
; File not open or in error state
|
; File not open or in error state
|
||||||
@ -65,11 +74,19 @@
|
|||||||
|
|
||||||
; Remember if we have a pushed back character and reset the flag.
|
; 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
|
lda (file),y
|
||||||
and #_FPUSHBACK
|
and #_FPUSHBACK
|
||||||
|
.endif
|
||||||
beq @L3
|
beq @L3
|
||||||
|
|
||||||
|
.if (.not .cpu .bitand ::CPU_ISET_65SC02)
|
||||||
lda (file),y
|
lda (file),y
|
||||||
|
.endif
|
||||||
and #<~_FPUSHBACK
|
and #<~_FPUSHBACK
|
||||||
sta (file),y ; file->f_flags &= ~_FPUSHBACK;
|
sta (file),y ; file->f_flags &= ~_FPUSHBACK;
|
||||||
inx ; X = 1
|
inx ; X = 1
|
||||||
@ -118,12 +135,20 @@
|
|||||||
; Copy the buffer pointer into ptr1, and increment the pointer value passed
|
; 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.
|
; 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
|
ldy #0
|
||||||
lda (sp),y
|
lda (sp),y
|
||||||
sta ptr1
|
sta ptr1
|
||||||
add #1
|
add #1
|
||||||
sta (sp),y
|
sta (sp),y
|
||||||
iny
|
iny
|
||||||
|
.endif
|
||||||
lda (sp),y
|
lda (sp),y
|
||||||
sta ptr1+1
|
sta ptr1+1
|
||||||
adc #0
|
adc #0
|
||||||
@ -134,8 +159,12 @@
|
|||||||
|
|
||||||
ldy #_FILE::f_pushback
|
ldy #_FILE::f_pushback
|
||||||
lda (file),y
|
lda (file),y
|
||||||
|
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||||
|
sta (ptr1) ; *buf = file->f_pushback;
|
||||||
|
.else
|
||||||
ldy #0
|
ldy #0
|
||||||
sta (ptr1),y ; *buf = file->f_pushback;
|
sta (ptr1),y ; *buf = file->f_pushback;
|
||||||
|
.endif
|
||||||
|
|
||||||
; Restore the low byte of count and decrement count by one. This may result
|
; Restore the low byte of count and decrement count by one. This may result
|
||||||
; in count being zero, so check for that.
|
; in count being zero, so check for that.
|
||||||
@ -210,4 +239,3 @@
|
|||||||
.bss
|
.bss
|
||||||
save: .res 2
|
save: .res 2
|
||||||
pb: .res 1
|
pb: .res 1
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
.export _fwrite
|
.export _fwrite
|
||||||
|
|
||||||
.import _write
|
.import _write
|
||||||
.import pushax, incsp6, addysp, ldaxysp, pushwysp, return0
|
.import pushax, pusha0, incsp6, addysp, ldaxysp, pushwysp, return0
|
||||||
.import tosumulax, tosudivax
|
.import tosumulax, tosudivax
|
||||||
|
|
||||||
.importzp ptr1
|
.importzp ptr1
|
||||||
@ -16,6 +16,7 @@
|
|||||||
.include "errno.inc"
|
.include "errno.inc"
|
||||||
.include "_file.inc"
|
.include "_file.inc"
|
||||||
|
|
||||||
|
.macpack cpu
|
||||||
|
|
||||||
; ------------------------------------------------------------------------
|
; ------------------------------------------------------------------------
|
||||||
; Code
|
; Code
|
||||||
@ -33,7 +34,11 @@
|
|||||||
|
|
||||||
ldy #_FILE::f_flags
|
ldy #_FILE::f_flags
|
||||||
lda (ptr1),y
|
lda (ptr1),y
|
||||||
|
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||||
|
bit #_FOPEN
|
||||||
|
.else
|
||||||
and #_FOPEN ; Is the file open?
|
and #_FOPEN ; Is the file open?
|
||||||
|
.endif
|
||||||
bne @L2 ; Branch if yes
|
bne @L2 ; Branch if yes
|
||||||
|
|
||||||
; File not open
|
; File not open
|
||||||
@ -45,7 +50,9 @@
|
|||||||
|
|
||||||
; Check if the stream is in an error state
|
; 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
|
and #_FERROR
|
||||||
bne @L1
|
bne @L1
|
||||||
|
|
||||||
@ -53,8 +60,7 @@
|
|||||||
|
|
||||||
ldy #_FILE::f_fd
|
ldy #_FILE::f_fd
|
||||||
lda (ptr1),y
|
lda (ptr1),y
|
||||||
ldx #$00
|
jsr pusha0 ; file->f_fd
|
||||||
jsr pushax ; file->f_fd
|
|
||||||
|
|
||||||
ldy #9
|
ldy #9
|
||||||
jsr pushwysp ; buf
|
jsr pushwysp ; buf
|
||||||
@ -123,4 +129,3 @@
|
|||||||
|
|
||||||
.bss
|
.bss
|
||||||
file: .res 2
|
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