Add setjmp and longjmp
This commit is contained in:
parent
f2dc0091a8
commit
4af2bc0bb2
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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:
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue