1
0
ain48/src/ain48.c

192 lines
6.5 KiB
C

#include <ain48.h>
#include <string.h>
u12 *ain48_write_instruction(u12 *code, struct instruction *i) {
u4 u4tmp;
u8 u8tmp;
switch (i->format) {
case AMAL:
*code++ = i->AMAL.ac | (i->AMAL.s ? 1 << 4 : 0) |
(i->AMAL.i1 ? 1 << 5 : 0) | (i->AMAL.i2 ? 1 << 6 : 0);
*code = ((u12)i->AMAL.rf) << 8;
if (!i->AMAL.i1)
*code |= ((u12)i->AMAL.data.r1) << 4;
if (!i->AMAL.i2)
*code |= ((u12)i->AMAL.data.r2);
if (i->AMAL.i1 && i->AMAL.i2) {
if (i->AMAL.s)
memcpy(&u8tmp, &i->AMAL.data.simm, sizeof(u8));
else
u8tmp = i->AMAL.data.imm;
*code |= u8tmp;
} else if (i->AMAL.i1) {
if (i->AMAL.s)
memcpy(&u4tmp, &i->AMAL.data.simm1, sizeof(u4));
else
u4tmp = i->AMAL.data.imm1;
*code |= u4tmp;
} else if (i->AMAL.i2) {
if (i->AMAL.s)
memcpy(&u4tmp, &i->AMAL.data.simm2, sizeof(u4));
else
u4tmp = i->AMAL.data.imm2;
*code |= ((u12)u4tmp) << 4;
}
return ++code;
case IML:
*code++ = 00400 | i->IML.r;
*code++ = i->IML.imm & 07777;
*code++ = (i->IML.imm >> 12) & 07777;
*code++ = (i->IML.imm >> 24) & 07777;
*code++ = (i->IML.imm >> 36) & 07777;
return code;
case IPL:
*code++ = 00500 | (i->IPL.s ? (1 << 4) : 0) | i->IPL.r;
if (i->IPL.s) {
memcpy(code++, &i->IPL.simm, sizeof(u12));
} else {
*code++ = i->IPL.imm;
}
return code;
case AMLS:
*code++ = 01000 | (i->AMLS.s ? 1 << 8 : 0) | (((u12)i->AMLS.rd) << 4) |
i->AMLS.rl;
memcpy(code++, &i->AMLS.imm, sizeof(u12));
return code;
case ASSS:
*code++ = 07770 | i->ASSS_ac;
return code;
case ASLI:
*code++ = 04000 | (i->ASLI.R ? 1 << 0 : 0) | (i->ASLI.U ? 1 << 1 : 0) |
(i->ASLI.N ? 1 << 2 : 0) | (i->ASLI.E ? 1 << 3 : 0) |
(i->ASLI.I ? 1 << 4 : 0);
*code++ = i->ASLI.imm & 07777;
*code++ = (i->ASLI.imm >> 12) & 07777;
*code++ = (i->ASLI.imm >> 24) & 07777;
*code++ = (i->ASLI.imm >> 36) & 07777;
return code;
case ASLR:
*code++ = 05000 | (i->ASLR.R ? 1 << 0 : 0) | (i->ASLR.U ? 1 << 1 : 0) |
(i->ASLR.N ? 1 << 2 : 0) | (i->ASLR.E ? 1 << 3 : 0) |
(i->ASLR.I ? 1 << 4 : 0) | (((u12)i->ASLR.rl) << 5);
return code;
case ASRD:
*code++ = 05000 | (i->ASRD.R ? 1 << 0 : 0) | (i->ASRD.U ? 1 << 1 : 0) |
(i->ASRD.N ? 1 << 2 : 0) | (i->ASRD.E ? 1 << 3 : 0) |
(i->ASLR.I ? 1 << 4 : 0) | (((u12)i->ASRD.rl) << 5);
memcpy(code++, &i->ASRD.imm, sizeof(u12));
return code;
default:
return nullptr;
}
}
u12 *ain48_read_instr(u12 *code, struct instruction *i) {
u12 byte = *code++;
if ((byte & 07600) == 0) { // AMAL
i->format = AMAL;
i->AMAL.i1 = (byte & 00040) > 0;
i->AMAL.i2 = (byte & 00100) > 0;
i->AMAL.s = (byte & 00020) > 0;
i->AMAL.ac = (enum amal_ac) (byte & 00017);
byte = *code++;
i->AMAL.rf = (byte >> 8) & 017;
if (!i->AMAL.i1)
i->AMAL.data.r1 = (byte >> 4) & 017;
if (!i->AMAL.i2)
i->AMAL.data.r2 = byte & 017;
if (i->AMAL.i1 && i->AMAL.i2) {
if (i->AMAL.s) {
u8 tmp = byte & 0377;
memcpy(&i->AMAL.data.simm, &tmp, sizeof(i8));
} else
i->AMAL.data.imm = byte & 0337;
} else if (i->AMAL.i1) {
if (i->AMAL.s) {
u4 tmp = byte & 017;
memcpy(&i->AMAL.data.simm1, &tmp, sizeof(i4));
}
else
i->AMAL.data.imm1 = byte & 017;
} else if (i->AMAL.i2) {
if (i->AMAL.s) {
u4 tmp = (byte >> 4) & 017;
memcpy(&i->AMAL.data.simm2, &tmp, sizeof(i4));
}
else
i->AMAL.data.imm2 = (byte >> 4) & 017;
}
return code;
} else if ((byte & 07600) == 00400) { // IML
i->format = IML;
i->IML.r = byte & 017;
byte = *code++;
i->IML.imm = (u48)byte;
byte = *code++;
i->IML.imm |= ((u48)byte << 12);
byte = *code++;
i->IML.imm |= ((u48)byte << 24);
byte = *code++;
i->IML.imm |= ((u48)byte << 36);
return code;
} else if ((byte & 07600) == 00600) { // IPL
i->format = IPL;
i->IPL.r = byte & 017;
i->IPL.s = (byte & 00020) > 0;
byte = *code++;
if (i->IPL.s) {
memcpy(&i->IPL.simm, &byte, sizeof(i12));
} else {
i->IPL.imm = byte;
}
return code;
} else if ((byte & 07000) == 01000) { // AMLS
i->format = AMLS;
i->AMLS.s = (byte & 00400) > 0;
i->AMLS.rd = (byte >> 4) & 017;
i->AMLS.rl = byte & 017;
memcpy(&i->AMLS.imm, code++, sizeof(i12));
return code;
} else if ((byte & 07770) == 07770) { // ASSS
i->format = ASSS;
i->ASSS_ac = byte & 00007;
return code;
} else if ((byte & 07000) == 04000) { // ASLI
i->format = ASLI;
i->ASLI.R = (byte & 0b1) > 0;
i->ASLI.U = (byte & 0b10) > 0;
i->ASLI.N = (byte & 0b100) > 0;
i->ASLI.E = (byte & 0b1000) > 0;
i->ASLI.I = (byte & 0b10000) > 0;
byte = *code++;
i->ASLI.imm = (u48)byte;
byte = *code++;
i->ASLI.imm |= ((u48)byte << 12);
byte = *code++;
i->ASLI.imm |= ((u48)byte << 24);
byte = *code++;
i->ASLI.imm |= ((u48)byte << 36);
return code;
} else if ((byte & 07000) == 05000) { // ASLR
i->format = ASLR;
i->ASLR.R = (byte & 0b1) > 0;
i->ASLR.U = (byte & 0b10) > 0;
i->ASLR.N = (byte & 0b100) > 0;
i->ASLR.E = (byte & 0b1000) > 0;
i->ASLR.I = (byte & 0b10000) > 0;
i->ASLR.rl = (byte >> 5) & 017;
return code;
} else if ((byte & 07000) == 06000) { // ASRD
i->format = ASRD;
i->ASRD.R = (byte & 0b1) > 0;
i->ASRD.U = (byte & 0b10) > 0;
i->ASRD.N = (byte & 0b100) > 0;
i->ASRD.E = (byte & 0b1000) > 0;
i->ASRD.I = (byte & 0b10000) > 0;
i->ASRD.rl = (byte >> 5) & 017;
memcpy(&i->ASRD.imm, code++, sizeof(i12));
return code;
} else return nullptr; // ILLEGAL INSTRUCTION
}