Add setjmp and longjmp

This commit is contained in:
drmortalwombat 2021-11-20 20:25:53 +01:00
parent f2dc0091a8
commit 4af2bc0bb2
13 changed files with 497 additions and 13 deletions

View File

@ -119,7 +119,7 @@ bool cwin_cursor_up(CharWin * win)
bool cwin_cursor_down(CharWin * win)
{
if (win->cy + 1 < win->cy)
if (win->cy + 1 < win->wy)
{
win->cy++;
return true;
@ -418,6 +418,8 @@ bool cwin_edit_char(CharWin * win, char ch)
case 147:
cwin_clear(win);
win->cx = 0;
win->cy = 0;
return false;
case 17:

203
include/c64/kernalio.c Normal file
View File

@ -0,0 +1,203 @@
#include "kernalio.h"
void krnio_setnam(const char * name)
{
__asm
{
lda name
ora name + 1
beq W1
ldy #$ff
L1: iny
lda (name), y
bne L1
tya
W1: ldx name
ldy name + 1
jsr $ffbd // setnam
}
}
bool krnio_open(char fnum, char device, char channel)
{
__asm
{
lda #0
sta accu
sta accu + 1
lda fnum
ldx device
ldy channel
jsr $ffba // setlfs
jsr $ffc0 // open
bcc W1
lda fnum
jsr $ffc3 // close
jmp E2
W1:
lda #1
sta accu
E2:
}
}
void krnio_close(char fnum)
{
__asm
{
lda fnum
jsr $ffc3 // close
}
}
krnioerr krnio_status(void)
{
__asm
{
jsr $ffb7 // readst
sta accu
lda #0
sta accu + 1
}
}
bool krnio_chkout(char fnum)
{
__asm
{
ldx fnum
jsr $ffc9 // chkout
lda #0
sta accu + 1
bcs W1
lda #1
W1: sta accu
}
}
bool krnio_chkin(char fnum)
{
__asm
{
ldx fnum
jsr $ffc6 // chkin
lda #0
sta accu + 1
bcs W1
lda #1
W1: sta accu
}
}
void krnio_clrchn(void)
{
__asm
{
jsr $ffcc // clrchn
}
}
bool krnio_chrout(char ch)
{
__asm
{
lda ch
jsr $ffd2 // chrout
sta accu
lda #0
sta accu + 1
}
}
int krnio_chrin(void)
{
__asm
{
jsr $ffcf // chrin
sta accu
jsr $ffb7
beq W1
lda #$ff
sta accu
W1:
sta accu + 1
}
}
int krnio_getch(char fnum)
{
int ch = -1;
if (krnio_chkin(fnum))
ch = krnio_chrin();
krnio_clrchn();
return ch;
}
int krnio_puts(char fnum, const char * data)
{
if (krnio_chkout(fnum))
{
int i = 0;
while (data[i])
krnio_chrout(data[i++]);
krnio_clrchn();
return i;
}
else
return -1;
}
int krnio_write(char fnum, const char * data, int num)
{
if (krnio_chkout(fnum))
{
for(int i=0; i<num; i++)
krnio_chrout(data[i]);
krnio_clrchn();
return num;
}
else
return -1;
}
int krnio_read(char fnum, char * data, int num)
{
if (krnio_chkin(fnum))
{
int i = 0;
int ch;
while (i < num && (ch = krnio_chrin()) >= 0)
data[i++] = (char)ch;
krnio_clrchn();
return i;
}
else
return -1;
}
int krnio_gets(char fnum, char * data, int num)
{
if (krnio_chkin(fnum))
{
int i = 0;
int ch;
while (i + 1 < num && (ch = krnio_chrin()) >= 0)
{
data[i++] = (char)ch;
if (ch == 13 || ch == 10)
break;
}
data[i] = 0;
krnio_clrchn();
return i;
}
else
return -1;
}

51
include/c64/kernalio.h Normal file
View File

@ -0,0 +1,51 @@
#ifndef C64_KERNALIO_H
#ifndef C64_KERNALIO_H
enum krnioerr
{
KRNIO_OK = 0,
KRNIO_DIR = 0x01,
KRNIO_TIMEOUT = 0x02,
KRNIO_SHORT = 0x04,
KRNIO_LONG = 0x08,
KRNIO_VERIFY = 0x10,
KRNIO_CHKSUM = 0x20,
KRNIO_EOF = 0x40,
KRNIO_NODEVICE = 0x80
};
void krnio_setnam(const char * name);
bool krnio_open(char fnum, char device, char channel);
void krnio_close(char fnum);
krnioerr krnio_status(void);
bool krnio_chkout(char fnum);
bool krnio_chkin(char fnum);
void krnio_clrchn(void);
bool krnio_chrout(char ch);
int krnio_chrin(void);
int krnio_getch(char fnum);
int krnio_write(char fnum, const char * data, int num);
int krnio_puts(char fnum, const char * data);
int krnio_read(char fnum, char * data, int num);
int krnio_gets(char fnum, char * data, int num);
#pragma compile("kernalio.c")
#endif

View File

@ -1885,6 +1885,22 @@ W1: jmp startup.yexec
#pragma bytecode(BC_BINOP_SHRI_I16, inp_binop_shr_s16.inp_binop_shri_s16)
#pragma bytecode(BC_BINOP_SHRR_I16, inp_binop_shr_s16.inp_binop_shrr_s16)
__asm inp_binop_adda_16
{
lda (ip), y
tax
clc
lda $00, x
adc accu
sta $00, x
lda $01, x
adc accu + 1
sta $01, x
jmp startup.yexec
}
#pragma bytecode(BC_BINOP_ADDA_16, inp_binop_adda_16)
__asm cmp16
{
inp_binop_cmpr_s16:

View File

@ -76,6 +76,8 @@ enum ByteCode
BC_BINOP_SHRR_U16,
BC_BINOP_SHRR_I16,
BC_BINOP_ADDA_16,
BC_BINOP_ADDI_16,
BC_BINOP_SUBI_16,
BC_BINOP_ANDI_16,

112
include/setjmp.c Normal file
View File

@ -0,0 +1,112 @@
#include "setjmp.h"
int setjmp(jmp_buf env)
{
__asm
{
ldy #0
lda __sp + 0
sta (env), y
iny
lda __sp + 1
sta (env), y
iny
lda __ip + 0
sta (env), y
iny
lda __ip + 1
sta (env), y
iny
lda __fp + 0
sta (env), y
iny
lda __fp + 1
sta (env), y
iny
ldx #0
loop:
lda __sregs, x
sta (env), y
iny
inx
cpx #32
bne loop
tsx
txa
sta (env), y
iny
lda $0100, x
sta (env), y
iny
lda $0101, x
sta (env), y
iny
}
return 0
}
#pragma native(setjmp)
void longjmp(jmp_buf env, int value)
{
__asm
{
ldy #0
lda (env), y
sta __sp + 0
iny
lda (env), y
sta __sp + 1
iny
lda (env), y
sta __ip + 0
iny
lda (env), y
sta __ip + 1
iny
lda (env), y
sta __fp + 0
iny
lda (env), y
sta __fp + 1
iny
ldx #0
loop:
lda (env), y
sta __sregs, x
iny
inx
cpx #32
bne loop
lda (env), y
tax
txs
iny
lda (env), y
sta $0100, x
iny
lda (env), y
sta $0101, x
iny
lda value
sta __accu
lda value + 1
sta __accu + 1
}
}
#pragma native(longjmp)

21
include/setjmp.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef SETJMP_H
#define SETJMP_H
struct _jmp_buf
{
void * sp, * ip, * fp;
char tmps[32];
char cpup, cpul, cpuh;
};
typedef struct _jmp_buf jmp_buf[1];
int setjmp(jmp_buf env);
void longjmp(jmp_buf env, int value);
#pragma compile("setjmp.c")
#endif

View File

@ -108,6 +108,8 @@ int strlen(const char * str)
return i;
}
#pragma native(strlen)
char * strcat(char * dst, const char * src)
{
char * d = dst;
@ -121,6 +123,17 @@ char * strcat(char * dst, const char * src)
return dst;
}
#pragma native(strcat)
char * cpycat(char * dst, const char * src)
{
do {} while (*dst++ = *src++);
return dst;
}
#pragma native(cpycat)
void * memset(void * dst, int value, int size)
{
__asm

View File

@ -9,6 +9,8 @@ int strlen(const char * str);
char * strcat(char * dst, const char * src);
char * cpycat(char * dst, const char * src);
void * memclr(void * dst, int size);
void * memset(void * dst, int value, int size);

View File

@ -549,6 +549,10 @@ bool ByteCodeInstruction::CheckAccuSize(uint32 & used)
used |= 0x0000ffff;
break;
case BC_BINOP_ADDA_16:
used |= 0x0000ffff;
break;
case BC_BINOP_ADDI_16:
if (mRegister == BC_REG_ACCU)
{
@ -730,6 +734,9 @@ bool ByteCodeInstruction::UsesRegister(uint32 reg) const
if (mCode >= BC_BINOP_ADD_L32 && mCode <= BC_BINOP_CMP_S32)
return true;
if (mCode == BC_BINOP_ADDA_16)
return true;
}
if (reg == BC_REG_ACCU)
@ -759,6 +766,8 @@ bool ByteCodeInstruction::UsesRegister(uint32 reg) const
return true;
if (mCode == BC_COPY || mCode == BC_STRCPY)
return true;
if (mCode == BC_BINOP_ADDA_16)
return true;
}
if (reg == BC_REG_ADDR)
@ -797,6 +806,8 @@ bool ByteCodeInstruction::ChangesRegister(uint32 reg) const
return true;
if (mCode == BC_CALL)
return true;
if (mCode == BC_BINOP_ADDA_16)
return true;
}
if (reg == BC_REG_ACCU)
@ -980,6 +991,7 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
case BC_BINOP_SHLR_16:
case BC_BINOP_SHRR_U16:
case BC_BINOP_SHRR_I16:
case BC_BINOP_ADDA_16:
block->PutCode(generator, mCode);
block->PutByte(mRegister);
break;
@ -4249,6 +4261,8 @@ bool ByteCodeBasicBlock::JoinTailCodeSequences(void)
{
ByteCodeBasicBlock* b = mEntryBlocks[i];
b->mIns.SetSize(b->mIns.Size() - 1);
if (mIns.Size() == 1)
mExitLive |= b->mExitLive;
b->mExitLive = LIVE_ACCU;
}
changed = true;
@ -4779,6 +4793,29 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase)
mIns[i + 0].mRegister = BC_REG_ACCU;
mIns[i + 1].mCode = BC_NOP;
mIns[i + 2].mCode = BC_NOP;
progress = true;
}
else if (
mIns[i + 0].mCode == BC_LOAD_REG_16 &&
mIns[i + 1].mCode == BC_BINOP_ADDR_16 &&
mIns[i + 2].mCode == BC_STORE_REG_16 && mIns[i + 0].mRegister == mIns[i + 2].mRegister && !(mIns[i + 2].mLive & LIVE_ACCU))
{
mIns[i + 0].mRegister = mIns[i + 1].mRegister;
mIns[i + 0].mRegisterFinal = mIns[i + 1].mRegisterFinal;
mIns[i + 1].mCode = BC_NOP;
mIns[i + 2].mCode = BC_BINOP_ADDA_16;
progress = true;
}
else if (
(mIns[i + 0].mCode == BC_LOAD_LOCAL_16 || mIns[i + 0].mCode == BC_LOAD_ABS_16 || mIns[i + 0].mCode == BC_LOAD_ADDR_16 ||
mIns[i + 0].mCode == BC_LOAD_LOCAL_U8 || mIns[i + 0].mCode == BC_LOAD_ABS_U8 || mIns[i + 0].mCode == BC_LOAD_ADDR_U8) &&
mIns[i + 1].mCode == BC_BINOP_ADDR_16 && mIns[i + 0].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal &&
mIns[i + 2].mCode == BC_STORE_REG_16 && !(mIns[i + 2].mLive & LIVE_ACCU))
{
mIns[i + 0].mRegister = mIns[i + 2].mRegister;
mIns[i + 1].mCode = BC_NOP;
mIns[i + 2].mCode = BC_BINOP_ADDA_16;
progress = true;
}
}
#endif
@ -5037,6 +5074,24 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase)
mIns[i + 1].mCode = BC_NOP;
progress = true;
}
#if 1
else if (
mIns[i + 0].mCode == BC_BINOP_ADDR_16 &&
mIns[i + 1].mCode == BC_STORE_REG_16 && mIns[i + 0].mRegister == mIns[i + 1].mRegister && !(mIns[i + 1].mLive & LIVE_ACCU))
{
mIns[i + 1].mCode = BC_BINOP_ADDA_16;
mIns[i + 0].mCode = BC_NOP;
progress = true;
}
else if (
mIns[i + 0].mCode == BC_BINOP_ADDA_16 &&
mIns[i + 1].mCode == BC_LOAD_REG_16 && mIns[i + 0].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
{
mIns[i + 1].mCode = BC_BINOP_ADDR_16;
mIns[i + 0].mCode = BC_NOP;
progress = true;
}
#endif
#if 1
else if (
i + 2 == mIns.Size() && mFalseJump &&
@ -5049,6 +5104,7 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase)
mBranch = TransposeBranchCondition(mBranch);
progress = true;
}
#endif
#if 0

View File

@ -77,6 +77,8 @@ enum ByteCode
BC_BINOP_SHRR_U16,
BC_BINOP_SHRR_I16,
BC_BINOP_ADDA_16,
BC_BINOP_ADDI_16,
BC_BINOP_SUBI_16,
BC_BINOP_ANDI_16,

View File

@ -246,6 +246,10 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int star
fprintf(file, "ADD\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_ADDA_16:
fprintf(file, "ADD\t%s, ACCU", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;
break;
case BC_BINOP_SUBR_16:
fprintf(file, "SUB\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc));
i += 1;

View File

@ -43,7 +43,7 @@ Declaration* Parser::ParseStructDeclaration(uint32 flags, DecType dt)
Declaration* pdec = mScope->Insert(structName, dec);
if (pdec)
{
if (pdec->mType == dt && (pdec->mFlags & DTF_DEFINED))
if (pdec->mType == dt && !(pdec->mFlags & DTF_DEFINED))
{
dec = pdec;
}
@ -68,22 +68,22 @@ Declaration* Parser::ParseStructDeclaration(uint32 flags, DecType dt)
for (;;)
{
Declaration* mdec = ParseDeclaration(false);
int offset = dec->mSize;
if (dt == DT_TYPE_UNION)
offset = 0;
while (mdec)
{
if (!(mdec->mBase->mFlags & DTF_DEFINED))
mErrors->Error(mdec->mLocation, EERR_UNDEFINED_OBJECT, "Undefined type used in struct member declaration");
mdec->mType = DT_ELEMENT;
if (dt == DT_TYPE_UNION)
{
mdec->mOffset = 0;
if (mdec->mBase->mSize > dec->mSize)
dec->mSize = mdec->mBase->mSize;
}
else
{
mdec->mOffset = dec->mSize;
dec->mSize += mdec->mBase->mSize;
}
mdec->mOffset = offset;
offset += mdec->mBase->mSize;
if (offset > dec->mSize)
dec->mSize = offset;
dec->mScope->Insert(mdec->mIdent, mdec);
if (mlast)
mlast->mNext = mdec;