Skip to content

Commit 30fd669

Browse files
committed
Fix register shift instructions
1 parent aee2131 commit 30fd669

File tree

2 files changed

+38
-20
lines changed

2 files changed

+38
-20
lines changed

src/instructions.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,14 @@ export function betweenRegisters(opcode: number, vm: VM) {
193193
vm.registers[0xf] = sub < 0 ? 0 : 1;
194194
break;
195195
case 0x6:
196-
//Shift value of register y right by one bit and assign it to register x
197-
//Store the least significant bit of register y in VF
198-
vm.registers[register1] = vm.registers[register2] >> 1;
199-
vm.registers[0xf] = vm.registers[register2] & 0x1;
196+
/**
197+
* This should shift value of register y right by one bit and assign it
198+
* to register x. However it seems like most implementations actually
199+
* just shift the register x right by one bit and store the least
200+
* significant bit prior to the sift in register VF.
201+
*/
202+
vm.registers[0xf] = vm.registers[register1] & 0x1;
203+
vm.registers[register1] = vm.registers[register1] >> 1;
200204
break;
201205
case 0x7: //Subtract register x from register y and assign to register x
202206
sub = vm.registers[register2] - vm.registers[register1];
@@ -205,10 +209,14 @@ export function betweenRegisters(opcode: number, vm: VM) {
205209
vm.registers[0xf] = sub < 0 ? 0 : 1;
206210
break;
207211
case 0xe:
208-
//Shift value of register y left by one bit and assign it to register x
209-
//Store the most significant bit of register y in VF
210-
vm.registers[register1] = (vm.registers[register2] << 1) & 0xff;
211-
vm.registers[0xf] = vm.registers[register2] >> 7;
212+
/**
213+
* This should shift value of register y left by one bit and assign it
214+
* to register x. However it seems like most implementations actually
215+
* just shift the register y left by one bit and store the most
216+
* significant bit prior to the shift in register VF.
217+
*/
218+
vm.registers[0xf] = vm.registers[register1] >> 7;
219+
vm.registers[register1] = (vm.registers[register1] << 1) & 0xff;
212220
break;
213221
default:
214222
throw new OpcodeError(

test/vm.ts

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -195,26 +195,36 @@ describe("Virtual machine", () => {
195195
expect(vm.registers[0xa]).to.equal(0xff);
196196
expect(vm.registers[0xf]).to.equal(0x0);
197197
});
198-
it("should shift register right by one bit and assign it to another register", () => {
199-
const vm = initializeVm([0x6bee, 0x8ab6, 0x6bff, 0x8ab6]);
200-
//Shift value register VB to the right by 1 bit and and store it in register
201-
//VA - set register VF to the least significant bit before the shift
198+
it("should shift register right by one bit", () => {
199+
const vm = initializeVm([
200+
0x6bee, //Store 0xEE in register VB (least significant bit is 0)
201+
0x8bb6, //Shift register VB right by one bit
202+
0x6bff, //Store 0xFF in register VB (least significant bit is 1)
203+
0x8bb6 //Shift register VB right by one bit
204+
]);
205+
//Register VB should be shifted right and register VF should be 0
202206
times(2, () => vm.next());
203-
expect(vm.registers[0xa]).to.equal(0x77);
207+
expect(vm.registers[0xb]).to.equal(0x77);
204208
expect(vm.registers[0xf]).to.equal(0x0);
209+
//Register VB should be shifted right and register VF should be 1
205210
times(2, () => vm.next());
206-
expect(vm.registers[0xa]).to.equal(0x7f);
211+
expect(vm.registers[0xb]).to.equal(0x7f);
207212
expect(vm.registers[0xf]).to.equal(0x1);
208213
});
209-
it("should shift register left by one bit and assign it to another register", () => {
210-
const vm = initializeVm([0x6bee, 0x8abe, 0x6b7f, 0x8abe]);
211-
//Shift value register VB to the left by 1 bit and and store it in register
212-
//VA - set register VF to the most significant bit before the shift
214+
it("should shift register left by one bit", () => {
215+
const vm = initializeVm([
216+
0x6bee, //Store 0xEE in register VB (most significant bit is 1)
217+
0x8bbe, //Shift register VB left by one bit
218+
0x6b7f, //Store 0x7F in register VB (most significant bit is 0)
219+
0x8bbe //Shift register VB left by one bit
220+
]);
221+
//Register VB should be shifted left and register VF should be 1
213222
times(2, () => vm.next());
214-
expect(vm.registers[0xa]).to.equal(0xdc);
223+
expect(vm.registers[0xb]).to.equal(0xdc);
215224
expect(vm.registers[0xf]).to.equal(0x1);
225+
//Register VB should be shifted left and register VF should be 0
216226
times(2, () => vm.next());
217-
expect(vm.registers[0xa]).to.equal(0xfe);
227+
expect(vm.registers[0xb]).to.equal(0xfe);
218228
expect(vm.registers[0xf]).to.equal(0x0);
219229
});
220230
});

0 commit comments

Comments
 (0)