From c72ca3547be96fcc26a4dc245c95cb83979b33d5 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Thu, 13 Jan 2022 10:37:44 +0100 Subject: [PATCH] Fix longjump and kernalio end of file handling --- include/c64/asm6502.h | 2 +- include/c64/kernalio.c | 46 +++++++++++++++++++++++++++++++++ include/c64/kernalio.h | 4 +++ include/setjmp.c | 8 +++--- oscar64/NativeCodeGenerator.cpp | 25 +++++++++++++----- oscar64/Parser.cpp | 19 +++++++++++--- 6 files changed, 89 insertions(+), 15 deletions(-) diff --git a/include/c64/asm6502.h b/include/c64/asm6502.h index e743b74..419fd2b 100644 --- a/include/c64/asm6502.h +++ b/include/c64/asm6502.h @@ -80,7 +80,7 @@ enum AsmIns ASM_BIT = 0x20, // Jump - ASM_JMP = 0x4c, + ASM_JMP = 0x40, ASM_JSR = 0x2c }; diff --git a/include/c64/kernalio.c b/include/c64/kernalio.c index 3860e81..2296c38 100644 --- a/include/c64/kernalio.c +++ b/include/c64/kernalio.c @@ -1,5 +1,6 @@ #include "kernalio.h" +krnioerr krnio_pstatus[16]; void krnio_setnam(const char * name) { @@ -24,6 +25,8 @@ void krnio_setnam(const char * name) bool krnio_open(char fnum, char device, char channel) { + krnio_pstatus[fnum] = KRNIO_OK; + __asm { lda #0 @@ -75,6 +78,37 @@ krnioerr krnio_status(void) #pragma native(krnio_status) + +bool krnio_load(char fnum, char device, char channel) +{ + __asm + { + lda #0 + sta accu + sta accu + 1 + + lda fnum + ldx device + ldy channel + jsr $ffba // setlfs + + lda #0 + ldx #0 + ldy #0 + jsr $FFD5 // open + bcc W1 + + lda #0 + jmp E2 + W1: + lda #1 + sta accu + E2: + } +} + +#pragma native(krnio_load) + bool krnio_chkout(char fnum) { __asm @@ -146,11 +180,15 @@ int krnio_chrin(void) int krnio_getch(char fnum) { + if (krnio_pstatus[fnum] == KRNIO_EOF) + return -1; + int ch = -1; if (krnio_chkin(fnum)) { ch = krnio_chrin(); krnioerr err = krnio_status(); + krnio_pstatus[fnum] = err; if (err) { if (err == KRNIO_EOF) @@ -209,6 +247,9 @@ int krnio_write(char fnum, const char * data, int num) int krnio_read(char fnum, char * data, int num) { + if (krnio_pstatus[fnum] == KRNIO_EOF) + return 0; + if (krnio_chkin(fnum)) { int i = 0; @@ -217,6 +258,7 @@ int krnio_read(char fnum, char * data, int num) { ch = krnio_chrin(); krnioerr err = krnio_status(); + krnio_pstatus[fnum] = err; if (err && err != KRNIO_EOF) break; data[i++] = (char)ch; @@ -234,6 +276,9 @@ int krnio_read(char fnum, char * data, int num) int krnio_gets(char fnum, char * data, int num) { + if (krnio_pstatus[fnum] == KRNIO_EOF) + return 0; + if (krnio_chkin(fnum)) { int i = 0; @@ -242,6 +287,7 @@ int krnio_gets(char fnum, char * data, int num) { ch = krnio_chrin(); krnioerr err = krnio_status(); + krnio_pstatus[fnum] = err; if (err && err != KRNIO_EOF) break; data[i++] = (char)ch; diff --git a/include/c64/kernalio.h b/include/c64/kernalio.h index c755216..93780a9 100644 --- a/include/c64/kernalio.h +++ b/include/c64/kernalio.h @@ -16,6 +16,8 @@ enum krnioerr KRNIO_NODEVICE = 0x80 }; +extern krnioerr krnio_pstatus[16]; + // Set filename for next krnio_open operation, make sure // that the string is still valid when calling krnio_open @@ -33,6 +35,8 @@ void krnio_close(char fnum); krnioerr krnio_status(void); +bool krnio_load(char fnum, char device, char channel); + // select the given file for stream output bool krnio_chkout(char fnum); diff --git a/include/setjmp.c b/include/setjmp.c index 45cce53..04401fb 100644 --- a/include/setjmp.c +++ b/include/setjmp.c @@ -40,11 +40,11 @@ int setjmp(jmp_buf env) sta (env), y iny - lda $0100, x + lda $0101, x sta (env), y iny - lda $0101, x + lda $0102, x sta (env), y iny } @@ -95,11 +95,11 @@ void longjmp(jmp_buf env, int value) iny lda (env), y - sta $0100, x + sta $0101, x iny lda (env), y - sta $0101, x + sta $0102, x iny lda value diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 6fe781d..706d641 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -7825,13 +7825,26 @@ void NativeCodeBasicBlock::CallFunction(InterCodeProcedure* proc, NativeCodeProc { if (ins->mSrc[0].mTemp < 0) { - NativeCodeInstruction lins(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSrc[0].mIntConst, ins->mSrc[0].mLinkerObject, NCIF_LOWER); - NativeCodeInstruction hins(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSrc[0].mIntConst, ins->mSrc[0].mLinkerObject, NCIF_UPPER); + if (ins->mSrc[0].mLinkerObject) + { + NativeCodeInstruction lins(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSrc[0].mIntConst, ins->mSrc[0].mLinkerObject, NCIF_LOWER); + NativeCodeInstruction hins(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSrc[0].mIntConst, ins->mSrc[0].mLinkerObject, NCIF_UPPER); - mIns.Push(lins); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU)); - mIns.Push(hins); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1)); + mIns.Push(lins); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU)); + mIns.Push(hins); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1)); + } + else + { + NativeCodeInstruction lins(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff); + NativeCodeInstruction hins(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff); + + mIns.Push(lins); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU)); + mIns.Push(hins); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1)); + } } else { diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 19c4d00..37bf283 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -271,6 +271,8 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint32 flags) mScanner->NextToken(); if (mScanner->mToken == TK_IDENT) { + int minValue = 0, maxValue = 0; + for (;;) { Declaration* cdec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); @@ -293,16 +295,25 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint32 flags) mErrors->Error(mScanner->mLocation, EERR_CONSTANT_TYPE, "Integer constant expected"); } cdec->mInteger = nitem++; - if (dec->mInteger < 0) - dec->mFlags |= DTF_SIGNED; - if (cdec->mInteger < -128 || cdec->mInteger > 127) - dec->mSize = 2; + if (dec->mInteger < minValue) + minValue = dec->mInteger; + else if (dec->mInteger > maxValue) + maxValue = dec->mInteger; if (mScanner->mToken == TK_COMMA) mScanner->NextToken(); else break; } + + if (minValue < 0) + { + dec->mFlags |= DTF_SIGNED; + if (minValue < -128 || maxValue > 127) + dec->mSize = 2; + } + else if (maxValue > 255) + dec->mSize = 2; } if (mScanner->mToken == TK_CLOSE_BRACE)