#undef DEBUG /* UNdefine to delete debug code sequences */
__sfr __at 0x0C serialAd;
-__sfr __at 0x0D serialAc;
-__sfr __at 0x0E serialBd;
+__sfr __at 0x0D serialBd;
+__sfr __at 0x0E serialAc;
__sfr __at 0x0F serialBc;
+__sfr __at 0x09 ctc1;
+__sfr __at 0x0A ctc2;
+
+signed char vt_twidth[2] = { 80, 40 };
+signed char vt_tright[2] = { 79, 39 };
+uint8_t curtty; /* output side */
+uint8_t inputtty; /* input side */
+static struct vt_switch ttysave[2];
+
char tbuf1[TTYSIZ];
char tbuf2[TTYSIZ];
+char tbuf3[TTYSIZ];
+char tbuf4[TTYSIZ];
struct s_queue ttyinq[NUM_DEV_TTY + 1] = { /* ttyinq[0] is never used */
{NULL, NULL, NULL, 0, 0, 0},
{tbuf1, tbuf1, tbuf1, TTYSIZ, 0, TTYSIZ / 2},
- {tbuf2, tbuf2, tbuf2, TTYSIZ, 0, TTYSIZ / 2}
+ {tbuf2, tbuf2, tbuf2, TTYSIZ, 0, TTYSIZ / 2},
+ {tbuf3, tbuf3, tbuf3, TTYSIZ, 0, TTYSIZ / 2},
+ {tbuf4, tbuf4, tbuf4, TTYSIZ, 0, TTYSIZ / 2}
};
/* tty1 is the screen tty2 is the debug port */
{
/* Debug port for bringup */
if (c == '\n')
- tty_putc(2, '\r');
- tty_putc(2, c);
+ tty_putc(1, '\r');
+ tty_putc(1, c);
}
-/* Both console and debug port are always ready */
bool tty_writeready(uint8_t minor)
{
- minor;
- return 1;
+ uint8_t reg = 0xFF;
+ if (minor == 3)
+ reg = serialAc;
+ if (minor == 4)
+ reg = serialBc;
+ return reg & 4;
}
void tty_putc(uint8_t minor, unsigned char c)
{
minor;
- if (minor == 1) {
+ if (minor < 3) {
+ if (curtty != minor - 1) {
+ vt_save(&ttysave[curtty]);
+ curtty = minor - 1;
+ vt_load(&ttysave[curtty]);
+ }
vtoutput(&c, 1);
return;
}
- serialAd = c;
+ if (minor == 3)
+ serialAd = c;
+ else
+ serialBd = c;
}
int tty_carrier(uint8_t minor)
{
- minor;
- return 1;
+ uint8_t reg = 0xFF;
+ if (minor == 3)
+ reg = serialAc;
+ if (minor == 4)
+ reg = serialBc;
+ return (reg & 8) ? 1 : 0;
}
+static uint8_t dart_setup[] = {
+ 1, 0x19,
+ 2, 0x00,
+ 3, 0xC1, /* 8bit */
+ 4, 0x04, /* 8N1 */
+ 5, 0x72, /* Tx 8bit, enabled, rts on */
+};
+
void tty_setup(uint8_t minor)
{
- minor;
+ irqflags_t flags;
+ int i;
+ char *p = dart_setup;
+
+ if (minor == 1) {
+ ctc1 = 0x7F;
+ ctc1 = 0x02; /* FIXME set by baud rate */
+ } else {
+ ctc2 = 0x7F;
+ ctc2 = 0x02;
+ }
+ flags = di();
+ for (i = 0; i < 10; i++) {
+ if (minor == 3)
+ serialAc = *p++;
+ else
+ serialBc = *p++;
+ }
+ irqrestore(flags);
}
+
static uint16_t keymap[8];
static uint16_t keyin[8];
static uint8_t keybyte, keybit;
}
static uint8_t keyboard[8][10] = {
- {'1', '3', '5', '7', '9' , '-', '\\', 0/*page */, 3/*brk*/, 0/*f1*/},
+ {'1', '3', '5', '7', '9' , '-', '\\', 0/*page */, 3/*brk*/, 0xF1/*f1*/},
{ 27, '2', '4', '6', '8', '0', '^', 0/*eol*/, 8, 0/*f5*/},
- { 0/*ctrl*/, 'w', 'r', 'y', 'i', 'p', '[', 0/*up*/, 9, 0/*f2*/ },
+ { 0/*ctrl*/, 'w', 'r', 'y', 'i', 'p', '[', 0/*up*/, 9, 0xF2/*f2*/ },
{'q', 'e', 't' , 'u', 'o', '@', 10, 8/*left*/, 127, 0 /* f6 */ },
{ 0/*capsl*/, 's', 'f', 'h', 'k', ';', ']', 0/*right*/, 0, 0/*f7*/ },
{ 'a', 'd', 'g', 'j', 'l', ':', 13, 12/*home*/, 0, 0 /*f3 */ },
{
uint8_t c;
+ if ((keybyte == 0xF1 || keybyte == 0xF2)
+ && inputtty != keybyte - 0xF1) {
+ inputtty = keybyte - 0xF1;
+ vt_save(&ttysave[inputtty]);
+ vt_load(&ttysave[inputtty]);
+ return;
+ }
if (keybyte == 4 && keybit == 0) {
capslock = 1 - capslock;
return;
}
if (capslock && c >= 'a' && c <= 'z')
c -= 'a' - 'A';
- tty_inproc(1, c);
+ tty_inproc(inputtty + 1, c);
}
void kbd_interrupt(void)
keydecode();
}
+void serial_interrupt(void)
+{
+ uint8_t r;
+
+ r = serialAc;
+ if (r & 0x02) {
+ while (r & 0x01) {
+ r = serialAd;
+ tty_inproc(3, r);
+ r = serialAc;
+ }
+ r = serialBc;
+ while (r & 0x01) {
+ r = serialBd;
+ tty_inproc(4, r);
+ r = serialBc;
+ }
+ }
+ serialAc = 0x07 << 3; /* Return from interrupt */
+}
+
/* This is used by the vt asm code, but needs to live in the kernel */
uint16_t cursorpos;
; -----------------------------------------------------------------------------
; KERNEL MEMORY BANK (below 0xC000, only accessible when the kernel is mapped)
; -----------------------------------------------------------------------------
+
+ .area _CONST
+crtcmap:
+ .db 0x77, 0x50, 0x5c, 0x09, 0x1e, 0x03, 0x18, 0x1b
+ .db 0x00, 0x09, 0x60, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00
+
.area _CODE
init_early:
+;
+; Bring up the 80 column card early so it can be used for debug
+;
+ ld hl, #crtcmap
+ xor a
+ ld bc, #0x1139 ; 17 commands to port 0x38/39
+init6845:
+ dec c
+ out (c), a
+ inc c
+ inc a
+ outi
+ jr nz, init6845
ret
init_hardware:
; 09 is channel 1, output for DART ser 0 } fed 4MHz/13
; 0A is channel 2, output for DATA ser 1 }
; 0B is channel 3, counting CSTTE edges (cpu clocks) at 4MHz
- ; 0C-0F are A data, B data, A ctrl, B ctrl
+
+ xor a
+ out (0x08), a ; vector 0
+ ld a, #0x97
+ out (0x08), a ; CTC 0 as our IRQ source
+ ld a, #0x05
+ out (0x08), a ; Timer constant (gives us 10Hz)
+ ; should be 0x06 for NTSC boxes
+ ; FIXME - how to tell ?
im 1 ; set CPU interrupt mode
push af
ld a, #0x80 ; ROM off bank 0
; the map port is write only, so keep a local stash
- ld (map_save), a
+ ld (map_copy), a
out (0), a
pop af
ret