2025-08-23 20:42:59 -05:00

58 lines
1.5 KiB
C

#include <stdint.h>
/*
This example does not configure the SCIF, and presumes it is already
configured for UART transmission.
This is *not* the default SCIF state as initialized by the Dreamcast boot
rom. However, the serial loader does not attempt to un-initialize the SCIF
prior to jumping to system memory.
*/
// SH4 on-chip peripheral module control
volatile uint8_t * SCFTDR2 = (volatile uint8_t *)(0xffe80000 + 0x0c);
volatile uint16_t * SCFSR2 = (volatile uint16_t *)(0xffe80000 + 0x10);
volatile uint16_t * SCFCR2 = (volatile uint16_t *)(0xffe80000 + 0x18);
#define SCFSR2__TDFE (1 << 5)
#define SCFSR2__TEND (1 << 6)
#define SCFCR2__TTRG(n) (((n) & 0b11) << 4)
static inline void character(const char c)
{
// wait for transmit fifo to become partially empty
while ((*SCFSR2 & SCFSR2__TDFE) == 0);
// unset TDFE bit
*SCFSR2 &= ~SCFSR2__TDFE;
*SCFTDR2 = c;
}
static inline void string(const char * s)
{
while (*s != 0) {
character(*s++);
}
}
void main()
{
// set the transmit trigger to `1 byte`--this changes the behavior of TDFE
*SCFCR2 = SCFCR2__TTRG(0b11);
string("hello\n");
// hack: "flush" the `hello` characters before the serial loader resets the
// serial interface
//
// Other methods to detect "transmit fifo is empty" appear to be
// non-functional (including polling SCFDR2 or SCFSR2)
//
// It would also be appropriate to use an SH7091 timer here, to delay a
// certain number of milliseconds, though that would require defining more
// registers.
string(" ");
}