2020-12-30 13:36:19 +11:00
|
|
|
#include <stdio.h>
|
2020-01-01 14:03:48 +11:00
|
|
|
#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;
|
|
|
|
}
|
|
|
|
|
Make KEY non-blocking
... and rename it to KEY?. Then, add KEY from KEY? for its blocking
version.
I need this for an upcoming Remote Shell feature. If a Collapse OS
system remotely controls another shell, it needs to be able to poll
both the remote system and the local keyboard at the same time. A
blocking KEY is incompatible with this.
In some places, the polling mechanism doesn't make sense, so this
new KEY? always returns a character. In some places, I just haven't
implemented the mechanism yet, so I kept the old blocking code and
added a "always 1" flag as a temporary shim.
I have probably broken something, but in emulators, Collapse OS runs
fine. It's an important reminder of what will be lost with the new
"dogfooding" approach (see recent mailing list message): without
emulators, it's much harder to to sweeping changes like this without
breaking stuff.
It's fine, I don't expect many more of these core changes to the
system. It's nearly feature-complete.
2021-01-02 00:05:29 +11:00
|
|
|
bool acia_cantransmit(ACIA *acia)
|
2020-01-01 14:03:48 +11:00
|
|
|
{
|
Make KEY non-blocking
... and rename it to KEY?. Then, add KEY from KEY? for its blocking
version.
I need this for an upcoming Remote Shell feature. If a Collapse OS
system remotely controls another shell, it needs to be able to poll
both the remote system and the local keyboard at the same time. A
blocking KEY is incompatible with this.
In some places, the polling mechanism doesn't make sense, so this
new KEY? always returns a character. In some places, I just haven't
implemented the mechanism yet, so I kept the old blocking code and
added a "always 1" flag as a temporary shim.
I have probably broken something, but in emulators, Collapse OS runs
fine. It's an important reminder of what will be lost with the new
"dogfooding" approach (see recent mailing list message): without
emulators, it's much harder to to sweeping changes like this without
breaking stuff.
It's fine, I don't expect many more of these core changes to the
system. It's nearly feature-complete.
2021-01-02 00:05:29 +11:00
|
|
|
return !(acia->status & 0x01 // RDRF
|
|
|
|
|| acia->control & 0x40); // RTS
|
2020-01-01 14:03:48 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2020-12-30 13:36:19 +11:00
|
|
|
if (acia->control & 0x40) { // RTS high
|
|
|
|
fprintf(stderr, "ACIA RTS high: can't send byte\n");
|
|
|
|
return;
|
|
|
|
}
|
2020-01-01 14:03:48 +11:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|