summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lc3.c64
1 files changed, 39 insertions, 25 deletions
diff --git a/lc3.c b/lc3.c
index 6740b48..3dedc7d 100644
--- a/lc3.c
+++ b/lc3.c
@@ -131,33 +131,22 @@ uint16_t check_key()
FD_ZERO(&fds);
FD_SET(0, &fds);
tv.tv_sec = 0;
- tv.tv_sec = 0;
+ tv.tv_usec = 0;
const int r = select(1, &fds, NULL, NULL, &tv);
die(r, "check_key select()");
return 0 != r;
}
+void update_keyboard()
+{
+ uint8_t c;
+ ssize_t r = read(0, &c, 1);
+ die(r, "read_memory read()");
+ memory[MEMORY_KBDR] = (uint16_t) c;
+}
+
uint16_t read_memory(const uint16_t address)
{
- if (MEMORY_KBSR == address)
- {
- if (check_key())
- {
- memory[MEMORY_KBSR] |= 1u << 15;
- uint8_t c;
- ssize_t r = read(0, &c, 1);
- die(r, "read_memory read()");
- memory[MEMORY_KBDR] = (uint16_t) c;
- }
- else
- {
- memory[MEMORY_KBSR] &= ~(1u << 15);
- }
- }
- else if (MEMORY_DSR == address)
- {
- memory[MEMORY_DSR] = 1u << 15;
- }
return memory[address];
}
@@ -189,13 +178,31 @@ void fire(const uint16_t interrupt, const uint16_t priority)
void write_memory(const uint16_t address, const uint16_t value)
{
- if (MEMORY_DDR == address)
+ switch (address)
{
- uint8_t c = (uint8_t) value;
- ssize_t r = write(1, &c, 1);
- die(r, "write_memory write()");
+ case MEMORY_KBSR:
+ {
+ memory[MEMORY_KBSR] &= 0x8000;
+ memory[MEMORY_KBSR] |= value & 0x7fff;
+ break;
+ }
+ case MEMORY_KBDR:
+ case MEMORY_DSR:
+ {
+ break;
+ }
+ case MEMORY_DDR:
+ {
+ uint8_t c = (uint8_t) value;
+ ssize_t r = write(1, &c, 1);
+ die(r, "write_memory write()");
+ } // fallthrough
+ default:
+ {
+ memory[address] = value;
+ break;
+ }
}
- memory[address] = value;
}
void update_cond(const uint16_t reg)
@@ -494,6 +501,7 @@ int main(int argc, char ** argv)
signal(SIGINT, handle_signal);
atexit(restore_terminal);
prepare_terminal();
+ memory[MEMORY_DSR] = 0x8000;
registers[REGISTER_PC] = MEMORY_USER;
registers[REGISTER_PSR] |= FLAG_SUP;
registers[REGISTER_SSP] = MEMORY_USER;
@@ -503,7 +511,13 @@ int main(int argc, char ** argv)
step(instruction);
if (check_key())
{
+ update_keyboard();
fire(0x80, 4);
+ memory[MEMORY_KBSR] |= 0x8000;
+ }
+ else
+ {
+ memory[MEMORY_KBSR] &= 0x7fff;
}
}
}