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 program {EM}/lib.bin/em_led
mapflag -l* LNAME={EM}/{LIB}* mapflag -l* LNAME={EM}/{LIB}*
mapflag -i SEPID=-b1:0 mapflag -i SEPID=-b1:0
mapflag -fp FLOATS={EM}/{ILIB}fp
mapflag -ansi C_LIB={EM}/{LIB}ac mapflag -ansi C_LIB={EM}/{LIB}ac
args {ALIGN} {SEPID?} (.e:{HEAD}={EM}/{RT}em) \ args {ALIGN} {SEPID?} (.e:{HEAD}={EM}/{RT}em) \
({RTS}:.ocm.bas={EM}/{RT}cc) \ ({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_imm(int opc, int sz, expr_t exp);
void encode_addr(expr_t exp, int sz);
void branch(register int opc,expr_t exp); void branch(register int opc,expr_t exp);

View file

@ -8,43 +8,43 @@ operation
| OP_arithm SIZE '#' expr | OP_arithm SIZE '#' expr
{ encode_imm($1+0x9, $2, $4);} { encode_imm($1+0x9, $2, $4);}
| OP_arithm SIZE expr | OP_arithm SIZE expr
{ emit1($1+0x0D);} { emit1($1+0x0D); encode_addr($3, $2);}
| OP_arithm SIZE expr ',' REG_x | OP_arithm SIZE expr ',' REG_x
{ emit1($1+0x1D);} { emit1($1+0x1D); encode_addr($3, $2);}
| OP_arithm SIZE expr ',' REG_y | OP_arithm SIZE expr ',' REG_y
{ emit1($1+0x19);} { emit1($1+0x19); encode_addr($3, $2);}
| OP_arithm SIZE '(' expr ',' REG_x ')' | OP_arithm SIZE '(' expr ',' REG_x ')'
{ emit1($1+0x01);} { emit1($1+0x01); encode_addr($4, $2);}
| OP_arithm SIZE '(' expr ')' ',' REG_y | OP_arithm SIZE '(' expr ')' ',' REG_y
{ emit1($1+0x11);} { emit1($1+0x11); encode_addr($4, $2);}
| OP_jump expr | OP_jump expr
{ emit1($1);} { emit1($1); encode_addr($2, 0);}
| OP_jump '(' expr ')' | OP_jump '(' expr ')'
{ emit1($1+0x20);} { emit1($1+0x20); encode_addr($3, 0);}
| OP_jsr expr | OP_jsr expr
{ emit1($1);} { emit1($1); encode_addr($2, 0);}
| OP_rol REG_acc | OP_rol REG_acc
{ emit1($1+0x0A);} { emit1($1+0x0A);}
| OP_rol SIZE expr | OP_rol SIZE expr
{ emit1($1+0x0E);} { emit1($1+0x0E);encode_addr($3, $2);}
| OP_rol SIZE expr ',' REG_x | OP_rol SIZE expr ',' REG_x
{ emit1($1+0x1E);} { emit1($1+0x1E);encode_addr($3, $2);}
| OP_bit SIZE expr | OP_bit SIZE expr
{ emit1($1);} { emit1($1);encode_addr($3, $2);}
| OP_cpx SIZE '#' expr | OP_cpx SIZE '#' expr
{ emit1($1);} { encode_imm($1, $2, $4);}
| OP_cpx SIZE expr | OP_cpx SIZE expr
{ emit1($1+0x0C);} { emit1($1+0x0C);encode_addr($3, $2);}
| OP_inc SIZE expr | OP_inc SIZE expr
{ emit1($1+0x0E);} { emit1($1+0x0E);encode_addr($3, $2);}
| OP_inc SIZE expr ',' REG_x | OP_inc SIZE expr ',' REG_x
{ emit1($1+0x1E);} { emit1($1+0x1E);encode_addr($3, $2);}
| OP_stx SIZE expr | OP_stx SIZE expr
{ emit1($1);} { emit1($1);encode_addr($3, $2);}
| OP_ldx SIZE '#' expr | OP_ldx SIZE '#' expr
{ emit1($1);} { encode_imm($1, $2, $4);}
| OP_ldx SIZE expr | OP_ldx SIZE expr
{ emit1($1+0x0C);} { emit1($1+0x0C);encode_addr($3, $2);}
| OP_ldx SIZE expr ',' REG_x | 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(opc);
emit1(sz); emit1(sz);
switch(sz) switch(TARGET_SIZE(sz))
{ {
case 4:
case 0: case 0:
if (!FIT8(exp.val)) serror("bad operand size");
emit1(exp.val); emit1(exp.val);
break; break;
case 5:
case 1: case 1:
if (!FIT16(exp.val)) serror("bad operand size");
emit2(exp.val); emit2(exp.val);
break; break;
default: case 2:
emit4(exp.val); emit4(exp.val);
break; 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) void branch(register int opc, expr_t exp)
{ {
register int dist; uint32_t dist;
dist = exp.val - (DOTVAL + 2); dist = exp.val - (DOTVAL + 2);
if (pass == PASS_2 && dist > 0 && !(exp.typ & S_DOT)) if (pass == PASS_2 && dist > 0 && !(exp.typ & S_DOT))
dist -= DOTGAIN; dist -= DOTGAIN;
if (small(fitb(dist) && (exp.typ & ~S_DOT) == DOTTYP, 3)) { if (small(FIT16(dist) && (exp.typ & ~S_DOT) == DOTTYP, 3)) {
emit1(opc); emit1(dist); emit1(opc); emit2(dist & 0xFFFF);
} else { } else {
emit1(opc^0x20); emit1(0x03); /* Skip over ... */ emit1(opc^0x20); emit1(0x03); /* Skip over ... */
emit1(0x4C); /* ... far jump. */ emit1(0x4C); /* ... far jump. */

View file

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