commit - 5b16a7cee00e49a1bfa70d0f63622686776b9f1f
commit + fd060ab5f0d52b3b95453ee6d3ab14e7135891f6
blob - 966431d7270ad444dff4709625e9d61ac3c004d8
blob + 4cd01a83f40f2978d90d7269132e5443657caaea
--- hackem.c
+++ hackem.c
/* I/O update routines */
void w_dummy(struct device *, uint16_t *, uint16_t);
-void r_itape(struct device *, uint16_t *, uint16_t);
void w_itape(struct device *, uint16_t *, uint16_t);
+void t_itape(struct device *, uint16_t *);
void r_otape(struct device *, uint16_t *, uint16_t);
void w_otape(struct device *, uint16_t *, uint16_t);
-void t_tape(struct device *, uint16_t *);
+void t_otape(struct device *, uint16_t *);
/* device structures */
struct device dev_dummy = {NULL, w_dummy}; /* writes are no-ops */
-struct tape dev_itape = {{r_itape, w_itape, t_tape}, stdin};
-struct tape dev_otape = {{r_otape, w_otape, t_tape}, stdout};
-struct tape dev_printer = {{r_otape, w_otape, t_tape}, stderr};
+struct tape dev_itape = {{NULL, w_itape, t_itape}, stdin};
+struct tape dev_otape = {{r_otape, w_otape, t_otape}, stdout};
+struct tape dev_printer = {{r_otape, w_otape, t_otape}, stderr};
/* instruction and data memories */
uint16_t ram[32 * 1024]; /* includes I/O space */
* indicates that the value at offset 0 is valid. All other bits are undefined.
*
* Procedure to acquire one byte of input:
- * 1. Read offset 1 until it is negative.
- * 2. Read offset 0; if it is negative, indicate the end of input.
- * 3. Otherwise, the value read from offset 0 is the input byte.
- * 4. Write 1 to offset 1.
+ * 1. Write 1 to offset 1.
+ * 2. Read offset 1 until it is negative.
+ * 3. Read offset 0; if it is negative, indicate the end of input.
+ * 4. Otherwise, the value read from offset 0 is the input byte.
*/
void
-r_itape(struct device *dev, uint16_t *mem, uint16_t offset)
+w_itape(struct device *dev, uint16_t *mem, uint16_t offset)
{
struct tape *tp = (struct tape *)dev;
- int c;
-
+
if (offset & 1) { /* offset 1 */
- // XXX read status word
- } else { /* offset 0 */
- #if 0 // XXX busy time
- if (t < tp->busy) /* device busy */
+ if (tp->busy)
return;
- #endif
- if ((c = fgetc(tp->stream)) != EOF)
- mem[offset] = (uint16_t) c;
- else
- mem[offset] = -1;
- }
-}
+ /* store "garbage" at offset 0 and "invalid" at offset 1 */
+ mem[0] = 0;
+ mem[1] = 0;
-void
-w_itape(struct device *dev, uint16_t *mem, uint16_t offset)
-{
- // XXX input tape advance/seek
+ /* mark drive busy for 150 ms */
+ tp->busy = cpufreq * 150 / 1000;
+ assert(tp->busy >= 0);
+ } else { /* offset 0 */
+ /* no effect */
+ }
}
void
-t_tape(struct device *dev, uint16_t *mem)
+t_itape(struct device *dev, uint16_t *mem)
{
struct tape *tp = (struct tape *)dev;
+ int c;
- if (tp->busy > 0)
- tp->busy--;
+ if (tp->busy == 0) /* idle */
+ return;
+
+ if (--tp->busy == 0) {
+ /* fetch and store the next character */
+ if ((c = fgetc(tp->stream)) != EOF)
+ mem[0] = c;
+ else
+ mem[0] = 0x8000;
+
+ /* set control word to "ready" */
+ mem[1] = 0x8000;
+ }
}
assert(tp->busy >= 0);
}
}
+
+void
+t_otape(struct device *dev, uint16_t *mem)
+{
+ struct tape *tp = (struct tape *)dev;
+
+ if (tp->busy > 0)
+ tp->busy--;
+}