Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more 8086 Instructions #13

Open
roerohan opened this issue Sep 23, 2020 · 4 comments
Open

Add more 8086 Instructions #13

roerohan opened this issue Sep 23, 2020 · 4 comments
Assignees
Labels
enhancement New feature or request good first issue Good for newcomers hacktoberfest Hacktoberfest 2020 help wanted Extra attention is needed

Comments

@roerohan
Copy link
Owner

Add more Instructions

Currently, 8086.js can only execute the instructions in the switch-case below. However, support needs to be added for the remaining instructions to make it more usable.

Also, some instructions are not implemented properly, which maybe be because of one of the following reasons.

  • They do not set the right flags
  • They do not check the operand sizes before executing the operation.

These need to be fixed to make it behave more like an Intel 8086.

Currently implemented instructions

The following is a list of instructions that have been implemented. They have been written in src/emulator/cpu/core.js, and they use the Addressing class from addressing.js in the same folder.

Note: Relative addressing has not been implemented yet.

switch (mnemonic.value) {
case 'MOV':
if (op1.size < op2.size) {
throw SyntaxError(`Can't move larger ${op2.size} bit value to ${op1.size} bit location`);
}
setAddr(op1, getAddr(op2));
break;
case 'JS':
if (regs.flags.getFlag(flags.sign) === 1) {
ip = getAddr(op1) - 1;
}
break;
case 'JNS': {
if (regs.flags.getFlag(flags.sign) === 0) {
ip = getAddr(op1) - 1;
}
break;
}
case 'JO': {
if (regs.flags.getFlag(flags.overflow) === 1) {
ip = getAddr(op1) - 1;
}
break;
}
case 'JNO': {
if (regs.flags.getFlag(flags.overflow) === 0) {
ip = getAddr(op1) - 1;
}
break;
}
case 'JP':
case 'JPE':
{
if (regs.flags.getFlag(flags.parity) === 1) {
ip = getAddr(op1) - 1;
}
break;
}
case 'JNP':
{
if (regs.flags.getFlag(flags.parity) === 0) {
ip = getAddr(op1) - 1;
}
break;
}
case 'ADD':
if (!op2) {
let s = op1.size === 8 ? regs.AX.get('l') : regs.AX.get();
s += getAddr(op1);
regs.AX.set(s);
} else {
let s = getAddr(op1);
s += getAddr(op2);
setAddr(op1, s);
}
break;
case 'DIV':
if (op1.size === 8) {
const al = regs.AX.get('l') / getAddr(op1);
const ah = regs.AX.get('l') % getAddr(op1);
regs.AX.set(al, 'l');
regs.AX.set(ah, 'h');
} else {
const ax = regs.AX.get() / getAddr(op1);
const dx = regs.AX.get() % getAddr(op1);
regs.AX.set(ax);
regs.DX.set(dx);
}
break;
case 'MUL':
if (op1.size === 8) {
const prod = regs.AX.get('l') * getAddr(op1);
regs.AX.set(prod);
} else {
const prod = regs.AX.get() * getAddr(op1);
regs.AX.set(prod);
// Store higher bits in DX
}
break;
case 'AND':
setAddr(op1, getAddr(op1) & getAddr(op2));
break;
case 'OR':
setAddr(op1, getAddr(op1) | getAddr(op2));
break;
case 'SUB': {
const s1 = getAddr(op1);
const s2 = getAddr(op2);
const ans = s1 - s2;
setAddr(op1, ans);
break;
}
case 'CMP': {
const s1 = getAddr(op1);
const s2 = getAddr(op2);
if (s1 === s2) {
regs.flags.setFlag(flags.zero);
regs.flags.unsetFlag(flags.carry);
} else if (s1 > s2) {
regs.flags.unsetFlag(flags.zero);
regs.flags.unsetFlag(flags.carry);
} else {
regs.flags.setFlag(flags.carry);
regs.flags.unsetFlag(flags.zero);
}
break;
}
case 'NOT': {
setAddr(op1, ~getAddr(op1));
break;
}
case 'JMP': {
ip = getAddr(op1) - 1;
break;
}
case 'JE':
case 'JZ':
{
if (regs.flags.getFlag(flags.zero) === 1) {
ip = getAddr(op1) - 1;
}
break;
}
case 'JNE':
case 'JNZ':
{
if (regs.flags.getFlag(flags.zero) === 0) {
ip = getAddr(op1) - 1;
}
break;
}
default:
break;
}

@roerohan roerohan added good first issue Good for newcomers hacktoberfest Hacktoberfest 2020 enhancement New feature or request help wanted Extra attention is needed labels Sep 23, 2020
@roerohan roerohan pinned this issue Sep 23, 2020
@gieitlaldywithamy
Copy link

i'll take this if you want looks like a decent first issue :)

@roerohan
Copy link
Owner Author

roerohan commented Sep 24, 2020

That would be wonderful @gieitlaldywithamy 😄 🎉
I'll assign this issue to you, you can add support for any number of instructions you want and make a PR.
However, I plan to keep this issue open until we can support all Intel 8086 instructions!

Please check out CONTRIBUTING.md for guidelines about commit messages and code style

@gieitlaldywithamy
Copy link

thanks for the git tips but could you provide some more specifications? what instructions do you want implemented and which don't work? is this the list you would like implemented
https://en.wikipedia.org/wiki/X86_instruction_listings

@thebongy
Copy link
Collaborator

thebongy commented Sep 25, 2020

@gieitlaldywithamy We usually use
https://www.gabrielececchetti.it/Teaching/CalcolatoriElettronici/Docs/i8086_instruction_set.pdf as a reference.

The pdf sometimes doesn't describe how flag registers are set for some commands. For those cases, I recommend searching up the instruction on google, and trying to research more about a specific instruction, so we can accurately mimic how it would work on an 8086.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers hacktoberfest Hacktoberfest 2020 help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants