@@ 3,19 3,40 @@
#include <stdint.h>
#include <string.h>
+/**
+ * @brief The KIA queue depth.
+ *
+ * All hardware instances of the KIA implement a 16-byte queue.
+ */
#define KIA_QUEUE_DEPTH 16
+/**
+ * @brief Answers with the slot index after the one provided.
+ */
+int
+next_slot(int slot) {
+ return (slot + 1) % KIA_QUEUE_DEPTH;
+}
+
typedef struct {
int read_ptr;
int write_ptr;
uint8_t queue;
} KIA_t;
+/**
+ * @brief Resets the KIA_t instance to its empty-queue condition.
+ */
void
kia_reset(KIA_t *pk) {
memset((void *)pk, 0, sizeof(KIA_t));
}
+/**
+ * @brief Answers with a new KIA instance.
+ *
+ * Answers NULL if there is no memory available.
+ */
KIA_t *
kia_new(void) {
KIA_t *pk = (KIA_t *)malloc(sizeof(KIA_t));
@@ 23,22 44,44 @@ kia_new(void) {
return pk;
}
+/**
+ * @brief Answers with the queue's read/write pointers.
+ *
+ * Used for unit testing only.
+ */
void
-kia_test_get_pointers(KIA_t *pk, int *p_read_pointer, int *p_write_pointer) {
+kia_test_get_pointers(
+ KIA_t *pk, int *p_read_pointer, int *p_write_pointer
+) {
*p_read_pointer = pk->read_ptr;
*p_write_pointer = pk->write_ptr;
}
+/**
+ * @brief Pops the input queue.
+ */
void
kia_pop(void) {
}
+/**
+ * @brief Pushes the `byte` onto the tail of the input queue.
+ *
+ * If there isn't enough room, the byte will be dropped.
+ */
void
kia_push(KIA_t *pk, uint8_t byte) {
++pk->write_ptr;
pk->queue = byte;
}
+/**
+ * @brief Answers with the byte at the head of the queue. Does NOT
+ * pop the queue.
+ *
+ * Typically called by the emulator in response to the virtual CPU
+ * reading from a memory-mapped I/O location.
+ */
uint8_t
kia_peek(KIA_t *pk) {
return pk->queue;
@@ 89,7 132,9 @@ test_push_byte() {
kia_test_get_pointers(pk, &new_read, &new_write);
if(new_read != old_read) goto read_ptr_fail;
- if(new_write != ((old_write + 1) % KIA_QUEUE_DEPTH)) goto write_ptr_fail;
+ if(new_write != next_slot(old_write)) {
+ goto write_ptr_fail;
+ }
if(kia_peek(pk) != expected_byte) goto push_data_fail;