Pretty working 65oo2 assembler.

This commit is contained in:
d0p1 🏳️‍⚧️ 2024-02-23 16:09:37 +01:00
parent 7550b7dbc6
commit c4bbe52d24
5 changed files with 71 additions and 29 deletions

View file

@ -35,7 +35,6 @@ name led
program {EM}/lib.bin/em_led
mapflag -l* LNAME={EM}/{LIB}*
mapflag -i SEPID=-b1:0
mapflag -fp FLOATS={EM}/{ILIB}fp
mapflag -ansi C_LIB={EM}/{LIB}ac
args {ALIGN} {SEPID?} (.e:{HEAD}={EM}/{RT}em) \
({RTS}:.ocm.bas={EM}/{RT}cc) \

View file

@ -1,2 +1,19 @@
#define TARGET_SIZE_B 0x0
#define TARGET_SIZE_W 0x1
#define TARGET_SIZE_L 0x2
#define TARGET_SIZE_zext 1 << 2
#define ADDR_SIZE_B (0x0 << 3)
#define ADDR_SIZE_W (0x1 << 3)
#define ADDR_SIZE_L (0x2 << 3)
#define TARGET_SIZE(x) (x & 0x3)
#define TARGET_ZEXT(x) (x & 0x4)
#define ADDR_SIZE(x) (x >> 3)
#define FIT8(x) (((x) & ~((int)0xFF)) == 0)
#define FIT16(x) (((x) & ~((int)0xFFFF)) == 0)
void encode_imm(int opc, int sz, expr_t exp);
void encode_addr(expr_t exp, int sz);
void branch(register int opc,expr_t exp);

View file

@ -8,43 +8,43 @@ operation
| OP_arithm SIZE '#' expr
{ encode_imm($1+0x9, $2, $4);}
| OP_arithm SIZE expr
{ emit1($1+0x0D);}
{ emit1($1+0x0D); encode_addr($3, $2);}
| OP_arithm SIZE expr ',' REG_x
{ emit1($1+0x1D);}
{ emit1($1+0x1D); encode_addr($3, $2);}
| OP_arithm SIZE expr ',' REG_y
{ emit1($1+0x19);}
{ emit1($1+0x19); encode_addr($3, $2);}
| OP_arithm SIZE '(' expr ',' REG_x ')'
{ emit1($1+0x01);}
{ emit1($1+0x01); encode_addr($4, $2);}
| OP_arithm SIZE '(' expr ')' ',' REG_y
{ emit1($1+0x11);}
{ emit1($1+0x11); encode_addr($4, $2);}
| OP_jump expr
{ emit1($1);}
{ emit1($1); encode_addr($2, 0);}
| OP_jump '(' expr ')'
{ emit1($1+0x20);}
{ emit1($1+0x20); encode_addr($3, 0);}
| OP_jsr expr
{ emit1($1);}
{ emit1($1); encode_addr($2, 0);}
| OP_rol REG_acc
{ emit1($1+0x0A);}
| OP_rol SIZE expr
{ emit1($1+0x0E);}
{ emit1($1+0x0E);encode_addr($3, $2);}
| OP_rol SIZE expr ',' REG_x
{ emit1($1+0x1E);}
{ emit1($1+0x1E);encode_addr($3, $2);}
| OP_bit SIZE expr
{ emit1($1);}
{ emit1($1);encode_addr($3, $2);}
| OP_cpx SIZE '#' expr
{ emit1($1);}
{ encode_imm($1, $2, $4);}
| OP_cpx SIZE expr
{ emit1($1+0x0C);}
{ emit1($1+0x0C);encode_addr($3, $2);}
| OP_inc SIZE expr
{ emit1($1+0x0E);}
{ emit1($1+0x0E);encode_addr($3, $2);}
| OP_inc SIZE expr ',' REG_x
{ emit1($1+0x1E);}
{ emit1($1+0x1E);encode_addr($3, $2);}
| OP_stx SIZE expr
{ emit1($1);}
{ emit1($1);encode_addr($3, $2);}
| OP_ldx SIZE '#' expr
{ emit1($1);}
{ encode_imm($1, $2, $4);}
| OP_ldx SIZE expr
{ emit1($1+0x0C);}
{ emit1($1+0x0C);encode_addr($3, $2);}
| OP_ldx SIZE expr ',' REG_x
{ emit1($1+0x1C);}
{ emit1($1+0x1C);encode_addr($3, $2);}
;

View file

@ -4,33 +4,60 @@ encode_imm(int opc, int sz, expr_t exp)
{
emit1(opc);
emit1(sz);
switch(sz)
switch(TARGET_SIZE(sz))
{
case 4:
case 0:
if (!FIT8(exp.val)) serror("bad operand size");
emit1(exp.val);
break;
case 5:
case 1:
if (!FIT16(exp.val)) serror("bad operand size");
emit2(exp.val);
break;
default:
case 2:
emit4(exp.val);
break;
default:
break;
}
}
void
encode_addr(expr_t exp, int sz)
{
uint32_t dist;
dist = exp.val;
if (FIT8(dist))
{
emit1(ADDR_SIZE_B | sz);
emit1(dist & 0xFF);
}
else if (FIT16(dist))
{
emit1(ADDR_SIZE_W | sz);
emit2(dist & 0xFFFF);
}
else
{
emit1(ADDR_SIZE_L | sz);
emit4(dist);
}
}
void branch(register int opc, expr_t exp)
{
register int dist;
uint32_t dist;
dist = exp.val - (DOTVAL + 2);
if (pass == PASS_2 && dist > 0 && !(exp.typ & S_DOT))
dist -= DOTGAIN;
if (small(fitb(dist) && (exp.typ & ~S_DOT) == DOTTYP, 3)) {
emit1(opc); emit1(dist);
if (small(FIT16(dist) && (exp.typ & ~S_DOT) == DOTTYP, 3)) {
emit1(opc); emit2(dist & 0xFFFF);
} else {
emit1(opc^0x20); emit1(0x03); /* Skip over ... */
emit1(0x4C); /* ... far jump. */

View file

@ -50,7 +50,6 @@ name led
program {EM}/lib/ack/em_led
mapflag -l* LNAME={PLATFORMDIR}/lib*
mapflag -i SEPID=-b1:0
mapflag -fp FLOATS={EM}/{ILIB}fp
args {ALIGN} {SEPID?} \
({RTS}:.b=-u _i_main) \
(.e:{HEAD}={PLATFORMDIR}/boot.o) \