Skip to content

Commit 295d5ac

Browse files
Add remaining LC-3 instructions, refactor slightly (#3)
1 parent 6b9a6b1 commit 295d5ac

4 files changed

Lines changed: 109 additions & 50 deletions

File tree

include/instructions.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ void execute_lea(uint16_t instr);
2222
void execute_st(uint16_t instr);
2323
void execute_sti(uint16_t instr);
2424
void execute_str(uint16_t instr);
25-
void execute_math(uint16_t instr);
2625
void execute_trap(uint16_t instr);
2726
void execute_bad_opcode(uint16_t instr);
2827

include/utils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include <stdint.h>
99
#include <signal.h>
1010

11-
void handle_interrupt();
11+
void handle_interrupt(int signal);
1212
void disable_input_buffering();
1313
void restore_input_buffering();
1414
void update_flags(uint16_t r);

src/instructions.c

Lines changed: 105 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ enum
140140
};
141141
*/
142142

143-
void execute_add(uint16_t instr) {
143+
void execute_add(uint16_t instr)
144+
{
144145
uint16_t r0 = GET_DR(instr);
145146
uint16_t r1 = GET_SR1(instr);
146147
uint16_t imm_flag = GET_IMM_FLAG5(instr);
@@ -155,7 +156,8 @@ void execute_add(uint16_t instr) {
155156
update_flags(r0);
156157
}
157158

158-
void execute_and(uint16_t instr) {
159+
void execute_and(uint16_t instr)
160+
{
159161
uint16_t r0 = GET_DR(instr);
160162
uint16_t r1 = GET_SR1(instr);
161163
uint16_t imm_flag = GET_IMM_FLAG5(instr);
@@ -170,13 +172,97 @@ void execute_and(uint16_t instr) {
170172
update_flags(r0);
171173
}
172174

173-
void execute_not(uint16_t instr) {
175+
void execute_not(uint16_t instr)
176+
{
174177
uint16_t r0 = GET_DR(instr);
175178
uint16_t r1 = GET_SR1(instr);
176179
reg[r0] = ~reg[r1];
177180
update_flags(r0);
178181
}
179182

183+
void execute_br(uint16_t instr)
184+
{
185+
uint16_t pc_offset = sext(GET_PC_OFFSET9(instr), 9);
186+
uint16_t cond_flag = (instr >> 9) & 0x7;
187+
if (cond_flag & reg[R_COND]) {
188+
reg[R_PC] += pc_offset;
189+
}
190+
}
191+
192+
void execute_jmp(uint16_t instr)
193+
{
194+
uint16_t r1 = GET_BASE_R(instr);
195+
reg[R_PC] = reg[r1];
196+
}
197+
198+
void execute_jsr(uint16_t instr)
199+
{
200+
uint16_t long_flag = (instr >> 11) & 1;
201+
reg[R_R7] = reg[R_PC];
202+
if (long_flag) {
203+
uint16_t pc_offset = sext(GET_PC_OFFSET11(instr), 11);
204+
reg[R_PC] += pc_offset;
205+
} else {
206+
uint16_t r1 = GET_BASE_R(instr);
207+
reg[R_PC] = reg[r1];
208+
}
209+
}
210+
211+
void execute_ld(uint16_t instr)
212+
{
213+
uint16_t r0 = GET_DR(instr);
214+
uint16_t pc_offset = sext(GET_PC_OFFSET9(instr), 9);
215+
reg[r0] = mem_read(reg[R_PC] + pc_offset);
216+
update_flags(r0);
217+
}
218+
219+
void execute_ldr(uint16_t instr)
220+
{
221+
uint16_t r0 = GET_DR(instr);
222+
uint16_t r1 = GET_BASE_R(instr);
223+
uint16_t offset6 = sext(GET_OFFSET6(instr), 6);
224+
reg[r0] = mem_read(reg[r1] + offset6);
225+
update_flags(r0);
226+
}
227+
228+
void execute_ldi(uint16_t instr)
229+
{
230+
uint16_t r0 = GET_DR(instr);
231+
uint16_t pc_offset = sext(GET_PC_OFFSET9(instr), 9);
232+
reg[r0] = mem_read(mem_read(reg[R_PC] + pc_offset));
233+
update_flags(r0);
234+
}
235+
236+
void execute_lea(uint16_t instr)
237+
{
238+
uint16_t r0 = GET_DR(instr);
239+
uint16_t pc_offset = sext(GET_PC_OFFSET9(instr), 9);
240+
reg[r0] = reg[R_PC] + pc_offset;
241+
update_flags(r0);
242+
}
243+
244+
void execute_st(uint16_t instr)
245+
{
246+
uint16_t r0 = GET_DR(instr);
247+
uint16_t pc_offset = sext(GET_PC_OFFSET9(instr), 9);
248+
mem_write(reg[R_PC] + pc_offset, reg[r0]);
249+
}
250+
251+
void execute_sti(uint16_t instr)
252+
{
253+
uint16_t r0 = GET_DR(instr);
254+
uint16_t pc_offset = sext(GET_PC_OFFSET9(instr), 9);
255+
mem_write(mem_read(reg[R_PC] + pc_offset), reg[r0]);
256+
}
257+
258+
void execute_str(uint16_t instr)
259+
{
260+
uint16_t r0 = GET_DR(instr);
261+
uint16_t r1 = GET_BASE_R(instr);
262+
uint16_t offset6 = sext(GET_OFFSET6(instr), 6);
263+
mem_write(reg[r1] + offset6, reg[r0]);
264+
}
265+
180266
static void trap_dispatch(uint8_t trapvect8) {
181267
switch (trapvect8) {
182268
case TRAP_GETC: trap_getc(); break;
@@ -193,6 +279,7 @@ static void trap_dispatch(uint8_t trapvect8) {
193279

194280
void execute_trap(uint16_t instr) {
195281
uint8_t trapvect8 = instr & 0xFF;
282+
reg[R_R7] = reg[R_PC];
196283
trap_dispatch(trapvect8);
197284
}
198285

@@ -205,52 +292,24 @@ void execute_bad_opcode(uint16_t instr) {
205292

206293

207294

208-
209-
210-
211-
212295
void execute_instruction(uint16_t instruction) {
213296
uint16_t op = GET_OP(instruction);
214297
switch (op) {
215-
case OP_ADD: execute_add(instruction); break;
216-
case OP_AND: execute_and(instruction); break;
217-
case OP_NOT: execute_not(instruction); break;
218-
case OP_TRAP: execute_trap(instruction); break;
219-
/*
220-
case OP_BR:
221-
execute_br((uint16_t)instruction);
222-
break;
223-
case OP_JMP:
224-
execute_jmp((uint16_t)instruction);
225-
break;
226-
case OP_JSR:
227-
execute_jsr((uint16_t)instruction);
228-
break;
229-
case OP_LD:
230-
execute_ld((uint16_t)instruction);
231-
break;
232-
case OP_LDI:
233-
execute_ldi((uint16_t)instruction);
234-
break;
235-
case OP_LDR:
236-
execute_ldr((uint16_t)instruction);
237-
break;
238-
case OP_LEA:
239-
execute_lea((uint16_t)instruction);
240-
break;
241-
case OP_ST:
242-
execute_st((uint16_t)instruction);
243-
break;
244-
case OP_STI:
245-
execute_sti((uint16_t)instruction);
246-
break;
247-
case OP_STR:
248-
execute_str((uint16_t)instruction);
249-
break;
250-
*/
251-
default:
252-
execute_bad_opcode((uint16_t)instruction);
253-
break;
298+
case OP_ADD: execute_add(instruction); break;
299+
case OP_AND: execute_and(instruction); break;
300+
case OP_NOT: execute_not(instruction); break;
301+
case OP_TRAP: execute_trap(instruction); break;
302+
case OP_BR: execute_br(instruction); break;
303+
case OP_JMP: execute_jmp(instruction); break;
304+
case OP_JSR: execute_jsr(instruction); break;
305+
case OP_LD: execute_ld(instruction); break;
306+
case OP_LDI: execute_ldi(instruction); break;
307+
case OP_LDR: execute_ldr(instruction); break;
308+
case OP_LEA: execute_lea(instruction); break;
309+
case OP_ST: execute_st(instruction); break;
310+
case OP_STI: execute_sti(instruction); break;
311+
case OP_STR: execute_str(instruction); break;
312+
default: execute_bad_opcode(instruction); break;
254313
}
255314
}
256315

src/utils.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@ uint16_t check_key()
4848

4949

5050

51-
void handle_interrupt()
51+
void handle_interrupt(int signal)
5252
{
53+
(void)signal;
5354
restore_input_buffering();
5455
printf("\n");
5556
exit(-2);
@@ -82,7 +83,7 @@ void read_image_file(FILE* file)
8283
}
8384
origin = swap16(origin);
8485

85-
uint16_t max_read = UINT16_MAX - origin;
86+
uint16_t max_read = MEMORY_MAX - origin;
8687
uint16_t* p = memory + origin;
8788
size_t read = fread(p, sizeof(uint16_t), max_read, file);
8889

0 commit comments

Comments
 (0)