#include #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); }