summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2020-12-08 10:42:10 -0500
committermrb0nk500 <b0nk@b0nk.xyz>2020-12-09 11:43:33 -0500
commita232e9f691187fdb05c35c14d4152d17f4babaf5 (patch)
tree9fdf364ce91506ed4490cd95ced6355459d7e8b5
parent50875a80729eaf3be2b1473e385eca1102fce4e6 (diff)
- 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.
-rw-r--r--assemble.c28
-rw-r--r--disasm.c10
-rw-r--r--disasm.h11
-rw-r--r--lexer.c67
-rw-r--r--opcode.h11
-rw-r--r--sux.h14
-rw-r--r--test/ortho.s4
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