From a232e9f691187fdb05c35c14d4152d17f4babaf5 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Tue, 8 Dec 2020 10:42:10 -0500 Subject: - Implemented support for the Orthogonal extension into both the assembler, and the emulator. I finally figured out how I could get support for the Ortho extension implemented into the old assembler. The only reason for doing this, is to buy me some while I start work on the new assembler, and to help me get an idea for how to do the same in the new assembler. --- assemble.c | 28 ++++++++++++++++--------- disasm.c | 10 +++++---- disasm.h | 11 ++++++++++ lexer.c | 67 ++++++++++++++++++++++++++++++------------------------------ opcode.h | 11 +++++----- sux.h | 14 ++++++------- test/ortho.s | 4 +--- 7 files changed, 83 insertions(+), 62 deletions(-) diff --git a/assemble.c b/assemble.c index 87d0464..91972eb 100644 --- a/assemble.c +++ b/assemble.c @@ -400,7 +400,7 @@ static uint8_t write_inst(uint8_t prefix, uint8_t ext_prefix, uint8_t opcode, op } if (isasm) { if (dbg) { - printf("$%04"PRIX64":\t", address); + printf("write_inst(): $%04"PRIX64":\t", address); for (int i = 0; i < inst_size; i++) { printf("%02X", ins.u8[i]); if (i < inst_size-1) { @@ -574,6 +574,11 @@ token *get_operands(token *t, operand *op, uint64_t address, uint8_t rs, uint8_t got_value = 0; } break; + case TOK_CC: + op[0].cc = t->byte; + i = 3; + break; + } if (!t) { break; @@ -630,7 +635,7 @@ uint64_t handle_opcode(token *t, bytecount *bc, uint8_t isasm, uint64_t address, get_operands(t, op, address, rs, dbg); if (dbg) { for (int i = 0; i < 2 && op[i].type != 0xFF; i++) { - printf("%i: op.type: %u, op.id: $%X, op.scale; $%X, op.rind[0]: $%X, op.rind[1]: $%X, op.value: $%"PRIX64"\n", i, op[i].type, op[i].id, op[i].scale, op[i].rind[0], op[i].rind[1], op[i].value); + printf("handle_opcode(): %i: op.type: %u, op.id: $%X, op.scale; $%X, op.rind[0]: $%X, op.rind[1]: $%X, op.value: $%"PRIX64"\n", i, op[i].type, op[i].id, op[i].scale, op[i].rind[0], op[i].rind[1], op[i].value); } } uint8_t is_eind = (op[0].type == 1 && op[0].id == MEM_RIND && op[0].rind[0] == REG_E); @@ -909,6 +914,9 @@ uint64_t handle_opcode(token *t, bytecount *bc, uint8_t isasm, uint64_t address, if (id == TOK_EXTOP) { opcode = ext_ortho_ops[get_ext_ortho(instr, dbg)]; } + if (op[0].cc != 0xFF && op[0].cc < 8) { + opcode |= (op[0].cc << 5); + } for (int i = 0; i < 2 && op[i].type != 0xFF; i++) { int i2 = 0; int j = 0; @@ -925,7 +933,7 @@ uint64_t handle_opcode(token *t, bytecount *bc, uint8_t isasm, uint64_t address, case MEM_ZMR: case MEM_IND: default: - if (of != 0xFF) { + if (op[i].id != MEM_IND && op[i].id != 0xFF) { max_val = 0; for (i2 = 8, j = 1; i2 <= 64; i2 += 8, j++) { max_val |= ((uint64_t)1 << (i2-1)); @@ -936,9 +944,9 @@ uint64_t handle_opcode(token *t, bytecount *bc, uint8_t isasm, uint64_t address, } } else { max_val = 0; - for (i2 = 0, j = 1; i2 <= 64; i2 += 8, j++) { + for (i2 = 8, j = 1; i2 <= 64; i2 += 8, j++) { max_val |= (0xFF << i2); - if (op[i].value <= max_val) { + if (op[0].value <= max_val) { opsize = j; break; } @@ -966,19 +974,19 @@ uint64_t handle_opcode(token *t, bytecount *bc, uint8_t isasm, uint64_t address, prefix |= amp[opsize-1]; } op_size[i] = opsize; - if (isasm /*&& dbg*/) { - printf("op_size[%i]: %i, opsize: %u\n", i, op_size[i], opsize); + if (isasm && dbg) { + printf("handle_opcode(): op_size[%i]: %i, opsize: %u\n", i, op_size[i], opsize); } break; } } } } - inst_size = write_inst(prefix, ext_prefix, opcode, op, address, op_size, isasm, /*dbg*/isasm); + inst_size = write_inst(prefix, ext_prefix, opcode, op, address, op_size, isasm, dbg); address += inst_size; bc->progsize += inst_size; - if (isasm /*&& dbg*/) { - printf("inst_size: $%X, bc->progsize: $%"PRIX64"\n", inst_size, bc->progsize); + if (isasm && dbg) { + printf("handle_opcode(): inst_size: $%X, bc->progsize: $%"PRIX64"\n", inst_size, bc->progsize); } } return address; diff --git a/disasm.c b/disasm.c index 010bc2f..e0f4fbc 100644 --- a/disasm.c +++ b/disasm.c @@ -159,6 +159,7 @@ static void disasm_ortho(struct sux *cpu, uint8_t opcode, uint8_t prefix, uint8_ memset(address, 0, sizeof(address)); memset(idx, 0, sizeof(idx)); memset(scale, 0, sizeof(scale)); + for (int i = 0; i < 2; i++) { int is_ind = 0; int is_rind = 0; @@ -251,7 +252,7 @@ static void disasm_ortho(struct sux *cpu, uint8_t opcode, uint8_t prefix, uint8_ case 4: sprintf(opr[i], "%s", reg[i]); break; } } - char *cc = ""; + const char *cc = ""; char *op2 = ""; int op_count; char *os = ""; /* Ortho Suffix. */ @@ -264,7 +265,8 @@ static void disasm_ortho(struct sux *cpu, uint8_t opcode, uint8_t prefix, uint8_ op_count = 1; } if (is_1cc(opcode)) { - switch (opcode) { + cc = set_cc[opcode >> 5]; + /*switch (opcode) { case ORTHO_1CC(SET, NG): cc = "NG"; break; case ORTHO_1CC(SET, PO): cc = "PO"; break; case ORTHO_1CC(SET, CS): cc = "CS"; break; @@ -273,8 +275,8 @@ static void disasm_ortho(struct sux *cpu, uint8_t opcode, uint8_t prefix, uint8_ case ORTHO_1CC(SET, NE): cc = "NE"; break; case ORTHO_1CC(SET, VS): cc = "VS"; break; case ORTHO_1CC(SET, VC): cc = "VC"; break; - } - op2 = cc; + }*/ + op2 = (char *)cc; } else if (is_2op(opcode)) { op2 = opr[1]; } diff --git a/disasm.h b/disasm.h index 3427592..2b65d12 100644 --- a/disasm.h +++ b/disasm.h @@ -336,6 +336,17 @@ static const char *ext_opname[0x100] = { [PCN_E ] = "PCN (E)" }; +static const char *set_cc[8] = { + "NG", + "PO", + "CS", + "CC", + "EQ", + "NE", + "VS", + "VC" +}; + #define ORTHO_1CC(mne, cc) \ [mne##_R##cc] = #mne " r, " #cc, [mne##_M##cc] = #mne " m, " #cc diff --git a/lexer.c b/lexer.c index 873fe6d..bb3701a 100644 --- a/lexer.c +++ b/lexer.c @@ -844,8 +844,7 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { } } if (!isop) { - uint8_t spaces = 0; - if (l->tok && l->tok->type == TOK_ORTHO && l->tok->byte == SET) { + if (l->tok && l->tok->id == TOK_ORTHO && l->tok->byte == SET) { for (k = 0; k < 8; k++) { int upper = toupper(lexeme[0]); if (upper == set_cc[k][0]) { @@ -856,40 +855,42 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { } } } - } - for (; isdelm(str[i+spaces], dbg) == 16; spaces++); - uint8_t ret = get_ptok(str[i+spaces], dbg); - if (ret == PTOK_COLON || ret == PTOK_EQU) { - islocal = (lex_type == TOK_LOCAL); - } - lex_type = TOK_SYM; - l->count++; - t = make_token(lex_type, islocal, space, tab, 0, "", NULL); - memcpy(sym, lexeme, j+1); - if (dbg) { - printf("lex(): spaces: %u\n", spaces); - } - if (is_struct) { - create_struct(cur_sym, l, t, lt, sym, dbg); - islocal = 0; - } else if ((str[i+spaces] != ':' && str[i+spaces] != '=')) { - uint8_t sym_struct = 0; - symbol *s; - /*tmp_sym = (s && s->isstruct) ? NULL : tmp_sym;*/ - if (tmp_sym) { - t->sym = find_member(lexeme, tmp_sym, dbg); - tmp_sym = NULL; - } else { - t->sym = get_sym(lexeme, address, t, islocal, dbg); + } else { + uint8_t spaces = 0; + for (; isdelm(str[i+spaces], dbg) == 16; spaces++); + uint8_t ret = get_ptok(str[i+spaces], dbg); + if (ret == PTOK_COLON || ret == PTOK_EQU) { + islocal = (lex_type == TOK_LOCAL); } - isfixup += (t && t->sym == NULL); - islocal = 0; + lex_type = TOK_SYM; + l->count++; + t = make_token(lex_type, islocal, space, tab, 0, "", NULL); + memcpy(sym, lexeme, j+1); if (dbg) { - printf("lex(): isfixup: %u\n", isfixup); + printf("lex(): spaces: %u\n", spaces); + } + if (is_struct) { + create_struct(cur_sym, l, t, lt, sym, dbg); + islocal = 0; + } else if ((str[i+spaces] != ':' && str[i+spaces] != '=')) { + uint8_t sym_struct = 0; + symbol *s; + /*tmp_sym = (s && s->isstruct) ? NULL : tmp_sym;*/ + if (tmp_sym) { + t->sym = find_member(lexeme, tmp_sym, dbg); + tmp_sym = NULL; + } else { + t->sym = get_sym(lexeme, address, t, islocal, dbg); + } + isfixup += (t && t->sym == NULL); + islocal = 0; + if (dbg) { + printf("lex(): isfixup: %u\n", isfixup); + } + } + if (!is_struct && t && t->sym && t->sym->isstruct) { + tmp_sym = t->sym; } - } - if (!is_struct && t && t->sym && t->sym->isstruct) { - tmp_sym = t->sym; } } break; diff --git a/opcode.h b/opcode.h index 1e5d820..5f952b3 100644 --- a/opcode.h +++ b/opcode.h @@ -13,11 +13,11 @@ #define EXT_OPNUM 49 #define ORTHO_OPNUM 16 -#define C (1 << 0) /* Carry flag. */ -#define Z (1 << 1) /* Zero flag. */ -#define I (1 << 2) /* Interrupt flag. */ -#define V (1 << 6) /* oVerflow flag. */ -#define N (1 << 7) /* Negative flag. */ +#define C (1 << 0) /* Carry flag. */ +#define Z (1 << 1) /* Zero flag. */ +#define I (1 << 2) /* Interrupt flag. */ +#define V (1 << 6) /* oVerflow flag. */ +#define N (1 << 7) /* Negative flag. */ /*extern uint8_t get_addrsize(uint8_t prefix, uint8_t addrmode);*/ extern char *showbits(uint64_t value, uint8_t bitnum, uint8_t dbg); @@ -74,6 +74,7 @@ struct op { uint8_t rind[2]; /* Register(s) used for register indirect. */ uint8_t scale; /* Scale used for SIB. */ int is_ind : 1; /* Flag used to determine if this operand is an indirect mode. */ + uint8_t cc; /* Condition code. 3 bits. */ uint64_t value; /* Value of operand (used only by memory operands). */ }; diff --git a/sux.h b/sux.h index d267755..c532c6e 100644 --- a/sux.h +++ b/sux.h @@ -34,8 +34,8 @@ static const uint64_t mem_size = 0x04000000; /* Size of address space. */ extern uint8_t step; extern uint8_t end; -#define setflag(flag, bit) ((flag)) ? (cpu->ps.u8[thread] |= bit) : (cpu->ps.u8[thread] &= ~bit) -#define getflag(bit) (cpu->ps.u8[thread] & bit) +#define setflag(flag, bit) ((flag)) ? (cpu->ps.u8[thread] |= (bit)) : (cpu->ps.u8[thread] &= ~(bit)) +#define getflag(bit) (cpu->ps.u8[thread] & (bit)) #define ORTHO_1CC(mne, cc) \ mne##_R##cc: case mne##_M##cc @@ -856,7 +856,7 @@ static /*inline*/ uint64_t mov(struct sux *cpu, uint64_t src, uint64_t size, uin } static /*inline*/ uint64_t set(struct sux *cpu, uint8_t flag, uint8_t thread) { - return flag; + return (flag != 0); } static /*inline*/ uint64_t inc_dec(struct sux *cpu, uint64_t value, uint8_t size, uint8_t inc, uint8_t thread) { @@ -1032,8 +1032,8 @@ static /*inline*/ void exec_ortho_inst(struct sux *cpu, uint8_t opcode, uint8_t push(cpu, address, 7, thread); } while (0); break; - case ORTHO_1OP(INC): dst = inc_dec(cpu, dst, size, 1, thread); break; - case ORTHO_1OP(DEC): dst = inc_dec(cpu, dst, size, 0, thread); break; + case ORTHO_1OP(INC): dst = inc_dec(cpu, dst, (op[0].type) ? size+1 : 8, 1, thread); break; + case ORTHO_1OP(DEC): dst = inc_dec(cpu, dst, (op[0].type) ? size+1 : 8, 0, thread); break; case ORTHO_1OP(PSH): push(cpu, dst, size, thread); break; case ORTHO_1OP(PUL): dst = pull(cpu, size, thread); break; case ORTHO_1OP(NOT): dst = ~dst; break; @@ -1391,7 +1391,7 @@ static /*inline*/ void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t p case ADC_IMM: /* ADC Immediate. */ case ADC_AB: /* ADC Absolute. */ case ADC_Z: /* ADC Zero Matrix. */ - cpu->a = adc(cpu, cpu->a, value, 8, getflag(C), thread); + cpu->a = adc(cpu, cpu->a, value, getflag(C), 8, thread); break; case PHP_IMP: push(cpu, cpu->ps.u8[thread], 0, thread); break; /* PusH Processor status to stack. */ case PHA_IMP: push(cpu, cpu->a , size, thread); break; /* PusH Accumulator to stack. */ @@ -1419,7 +1419,7 @@ static /*inline*/ void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t p case SBC_IMM: /* SBC Immediate. */ case SBC_AB: /* SBC Absolute. */ case SBC_Z: /* SBC Zero Matrix. */ - cpu->a = adc(cpu, cpu->a, ~value, 8, getflag(C), thread); + cpu->a = adc(cpu, cpu->a, ~value, getflag(C), 8, thread); break; case PLP_IMP: cpu->ps.u8[thread] = pull(cpu, 0, thread); break; /* PuLl Processor status from stack. */ case PLA_IMP: cpu->a = pull(cpu, size, thread); break; /* PuLl Accumulator from stack. */ diff --git a/test/ortho.s b/test/ortho.s index 4ca01f3..312c8eb 100644 --- a/test/ortho.s +++ b/test/ortho.s @@ -9,10 +9,7 @@ mem: reset: cps lds.d #$3FFFF -<<<<<<< HEAD mov a, #10 -======= ->>>>>>> 673efac... - Implemented support for the Orthogonal extension into and #0 tay xor b, b @@ -26,6 +23,7 @@ loop: inc.q count ; mov.q e, count mov (b+e), b + set a, eq mov a, (b+e) bra loop -- cgit v1.2.3-13-gbd6f