|
- #include <stdio.h>
- #include "acia.h"
-
- static void _check_irq(ACIA *acia)
- {
- // do we have RDRF?
- if ((acia->status & 0x01) && (acia->control & 0x80)) {
- acia->status |= 0x80;
- }
- // do we have TDRE?
- if ((acia->status & 0x02) && ((acia->control & 0xe0) == 0xe0)) {
- acia->status |= 0x80;
- }
- }
-
- void acia_init(ACIA *acia)
- {
- acia->status = 0x02; // TDRE
- acia->control = 0x00;
- acia->rx = 0;
- acia->tx = 0;
- acia->in_int = false;
- }
-
- bool acia_has_irq(ACIA *acia)
- {
- if (acia->in_int) {
- return false;
- }
- acia->in_int = acia->status & 0x80;
- return acia->in_int;
- }
-
- bool acia_cantransmit(ACIA *acia)
- {
- return !(acia->status & 0x01 // RDRF
- || acia->control & 0x40); // RTS
- }
-
- bool acia_hastx(ACIA *acia)
- {
- return !(acia->status & 0x02); // TRDE
- }
-
- uint8_t acia_read(ACIA *acia)
- {
- acia->status |= 0x02; // TRDE high
- _check_irq(acia);
- return acia->tx;
- }
-
- void acia_write(ACIA *acia, uint8_t val)
- {
- if (acia->control & 0x40) { // RTS high
- fprintf(stderr, "ACIA RTS high: can't send byte\n");
- return;
- }
- acia->status |= 0x01; // RDRF high
- acia->rx = val;
- _check_irq(acia);
- }
-
- uint8_t acia_ctl_rd(ACIA *acia)
- {
- return acia->status;
- }
-
- void acia_ctl_wr(ACIA *acia, uint8_t val)
- {
- acia->control = val;
- _check_irq(acia);
- }
-
- uint8_t acia_data_rd(ACIA *acia)
- {
- acia->status &= ~0x81; // RDRF and IRQ low
- acia->in_int = false;
- return acia->rx;
- }
-
- void acia_data_wr(ACIA *acia, uint8_t val)
- {
- acia->tx = val;
- acia->status &= ~0x82; // TRDE and IRQ low
- acia->in_int = false;
- _check_irq(acia);
- }
|