83 lines
1.6 KiB
C
83 lines
1.6 KiB
C
#include "boot.h"
|
|
|
|
/*
|
|
* 6850 ACIA test wiring assumption:
|
|
* /CS2 is driven by not-A5, so the ACIA is selected when A5 = 1.
|
|
* RS is assumed to be wired to A0, giving:
|
|
* 0x20 = status/control
|
|
* 0x21 = data
|
|
*/
|
|
#define ACIA_CTRL_STATUS 0x20
|
|
#define ACIA_DATA 0x21
|
|
|
|
#define ACIA_STATUS_RDRF 0x01
|
|
#define ACIA_STATUS_TDRE 0x02
|
|
|
|
#define ACIA_CMD_MASTER_RESET 0x03
|
|
#define ACIA_CMD_8N1_DIV16 0x15
|
|
|
|
static void acia_init(void)
|
|
{
|
|
io_out(ACIA_CTRL_STATUS, ACIA_CMD_MASTER_RESET);
|
|
io_out(ACIA_CTRL_STATUS, ACIA_CMD_8N1_DIV16);
|
|
}
|
|
|
|
static uint8_t acia_status(void)
|
|
{
|
|
return io_in(ACIA_CTRL_STATUS);
|
|
}
|
|
|
|
static void acia_putc(uint8_t value)
|
|
{
|
|
while ((acia_status() & ACIA_STATUS_TDRE) == 0) {
|
|
}
|
|
io_out(ACIA_DATA, value);
|
|
}
|
|
|
|
static uint8_t acia_getc_nonblocking(uint8_t *value)
|
|
{
|
|
if ((acia_status() & ACIA_STATUS_RDRF) == 0) {
|
|
return 0;
|
|
}
|
|
|
|
*value = io_in(ACIA_DATA);
|
|
return 1;
|
|
}
|
|
|
|
static void acia_puts(const char *text)
|
|
{
|
|
while (*text) {
|
|
acia_putc((uint8_t)*text++);
|
|
}
|
|
}
|
|
|
|
void main(void)
|
|
{
|
|
uint8_t cnt = 0;
|
|
uint8_t ch = 0;
|
|
|
|
io_out(PIO_A_CTRL, 0x0F);
|
|
io_out(PIO_A_DATA, 0x00);
|
|
|
|
acia_init();
|
|
acia_puts("ACIA 6850 test ready\r\n");
|
|
|
|
for (;;) {
|
|
uint8_t status = acia_status();
|
|
|
|
if (acia_getc_nonblocking(&ch)) {
|
|
io_out(PIO_A_DATA, ch);
|
|
acia_putc(ch);
|
|
if (ch == '\r') {
|
|
acia_putc('\n');
|
|
}
|
|
delay_ms(50);
|
|
}
|
|
|
|
acia_putc((uint8_t)('0' + (cnt & 0x07)));
|
|
acia_puts("\r\n");
|
|
cnt++;
|
|
delay_ms(250);
|
|
}
|
|
}
|