From c4bbe52d24fc32eb1c6dd0b6b0b103482ce0ab78 Mon Sep 17 00:00:00 2001 From: d0p1 Date: Fri, 23 Feb 2024 16:09:37 +0100 Subject: [PATCH] Pretty working 65oo2 assembler. --- lib/m65oo2/descr | 1 - mach/m65oo2/as/mach1.c | 17 +++++++++++++++++ mach/m65oo2/as/mach4.c | 38 ++++++++++++++++++------------------- mach/m65oo2/as/mach5.c | 43 ++++++++++++++++++++++++++++++++++-------- plat/pc65oo2/descr | 1 - 5 files changed, 71 insertions(+), 29 deletions(-) diff --git a/lib/m65oo2/descr b/lib/m65oo2/descr index 722fc4390..d250701dc 100644 --- a/lib/m65oo2/descr +++ b/lib/m65oo2/descr @@ -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) \ diff --git a/mach/m65oo2/as/mach1.c b/mach/m65oo2/as/mach1.c index 570acce1c..4da760f29 100644 --- a/mach/m65oo2/as/mach1.c +++ b/mach/m65oo2/as/mach1.c @@ -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); diff --git a/mach/m65oo2/as/mach4.c b/mach/m65oo2/as/mach4.c index d65e16d06..31ea98735 100644 --- a/mach/m65oo2/as/mach4.c +++ b/mach/m65oo2/as/mach4.c @@ -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);} ; \ No newline at end of file diff --git a/mach/m65oo2/as/mach5.c b/mach/m65oo2/as/mach5.c index 7549e2041..13a11a06a 100644 --- a/mach/m65oo2/as/mach5.c +++ b/mach/m65oo2/as/mach5.c @@ -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. */ diff --git a/plat/pc65oo2/descr b/plat/pc65oo2/descr index 5bbe0b68b..0d7f7000b 100644 --- a/plat/pc65oo2/descr +++ b/plat/pc65oo2/descr @@ -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) \