dptr = (uint16_t)udata.u_buf->bf_data;
block = udata.u_buf->bf_blk;
- kprintf("Issue command: drive %d block %d\n", minor, block);
+// kprintf("Issue command: drive %d block %d\n", minor, block);
cmd[0] = is_read ? FD_READ : FD_WRITE;
cmd[1] = block / 16; /* 2 sectors per block */
cmd[2] = ((block & 15) << 1); /* 0 - 1 base is corrected in asm */
while (ct < 2) {
for (tries = 0; tries < 4 ; tries++) {
- kprintf("Sector: %d Track %d\n", cmd[2]+1, cmd[1]);
+// kprintf("Sector: %d Track %d\n", cmd[2]+1, cmd[1]);
err = fd_operation(cmd, driveptr);
if (err == 0)
break;
/* 1: /dev/hd Hard disc block devices (hdx - not supported yet) */
{ no_open, no_close, no_rdwr, no_rdwr, no_ioctl },
/* 2: /dev/tty TTY devices */
- { tty_open, tty_close, tty_read, tty_write, tty_ioctl },
+ { tty_open, mtxtty_close,tty_read, tty_write, tty_ioctl },
/* 3: /dev/lpr Printer devices */
{ lpr_open, lpr_close, no_rdwr, lpr_write, no_ioctl },
/* 4: /dev/mem etc System devices (one offs) */
static uint8_t dart_setup[] = {
1, 0x19,
- 2, 0x00,
- 3, 0xC1, /* 8bit */
- 4, 0x04, /* 8N1 */
- 5, 0x72, /* Tx 8bit, enabled, rts on */
+ 2, 0x04, /* Vector */
+ 3, 0x00,
+ 4, 0x00,
+ 5, 0x00,
+};
+
+/* Baud rates for Z80 DART */
+static uint8_t dartbaud[] = {
+ 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x80, 0x40, 0x20,
+ 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00
+};
+
+static uint8_t dartbits[] = {
+ 0x00, 0x40, 0x80, 0xC0
};
void tty_setup(uint8_t minor)
irqflags_t flags;
int i;
char *p = dart_setup;
+ struct tty *t = &ttydata[minor];
+ uint8_t cf = t->termios.c_cflag;
+ uint8_t r;
+
+ if ((cf & CBAUD) < B150) {
+ cf &= ~CBAUD;
+ cf |= B150;
+ }
+ if ((cf & CBAUD) > B19200) {
+ cf &= ~CBAUD;
+ cf |= B19200;
+ }
+ r = dartbits[(cf & CSIZE) >> 4];
+ dart_setup[5] = 0x01 | r;
+ dart_setup[9] = 0x8A | r >> 1;
+ r = 0x04;
+ if (cf & PARENB) {
+ r |= 1;
+ if (!(cf & PARODD))
+ r|=2;
+ }
+ dart_setup[7] = r;
+ dart_setup[7] = r;
if (minor == 1) {
- ctc1 = 0x7F;
- ctc1 = 0x02; /* FIXME set by baud rate */
+ ctc1 = 0x45;
+ ctc1 = dartbaud[cf & CBAUD];
} else {
- ctc2 = 0x7F;
- ctc2 = 0x02;
+ ctc2 = 0x45;
+ ctc1 = dartbaud[cf & CBAUD];
}
flags = di();
for (i = 0; i < 10; i++) {
irqrestore(flags);
}
+int mtxtty_close(uint8_t minor)
+{
+ irqflags_t flags;
+ int err = tty_close(minor);
+
+ flags = di();
+ if (minor == 3) {
+ serialAc = 0x05;
+ serialAc = 0x00; /* Drop DTR/RTS */
+ }
+ if (minor == 4) {
+ serialBc = 0x05;
+ serialBc = 0x00; /* Drop DTR/RTS */
+ }
+ irqrestore(flags);
+ return err;
+}
static uint16_t keymap[8];
static uint16_t keyin[8];
keydecode();
}
-void serial_interrupt(void)
+void tty_interrupt(void)
{
uint8_t r;
tty_inproc(3, r);
r = serialAc;
}
+ if (!(r & 0x08))
+ tty_carrier_drop(3);
r = serialBc;
while (r & 0x01) {
r = serialBd;
tty_inproc(4, r);
r = serialBc;
}
+ serialAc = 0x07 << 3; /* Return from interrupt */
+ if (!(r & 0x08))
+ tty_carrier_drop(4);
}
- serialAc = 0x07 << 3; /* Return from interrupt */
}
/* This is used by the vt asm code, but needs to live in the kernel */
#define __DEVTTY_DOT_H__
extern void kbd_interrupt(void);
+extern void tty_interrupt(void);
+extern int mtxtty_close(uint8_t);
extern signed char vt_twidth[2];
extern signed char vt_tright[2];
uint16_t ramtop = PROGTOP;
uint16_t vdpport = 0x02 + 256 * 40; /* port and width */
+uint8_t membanks;
void pagemap_init(void)
{
int i;
- /* Ten banks (should check memory size) FIXME */
- for (i = 0x81; i < 0x8A; i++)
+ /* Up to ten banks */
+ for (i = 0x81; i <= membanks; i++)
pagemap_add(i);
}
/* On idle we spin checking for the terminals. Gives us more responsiveness
- for the polled ports */
+ for the polled ports. We don't need this on MTX, but we probably do for
+ MEMU */
+
void platform_idle(void)
{
- /* We don't want an idle poll and IRQ driven tty poll at the same moment */
irqflags_t irq = di();
-// tty_pollirq();
+ tty_interrupt();
irqrestore(irq);
}
void platform_interrupt(void)
{
- kbd_interrupt();
- timer_interrupt();
+ extern uint8_t irqvector;
+
+ if (irqvector == 1) {
+ tty_interrupt();
+ return;
+ }
+ kbd_interrupt();
+ timer_interrupt();
}
/* Nothing to do for the map of init */
.globl _sil_memcpy
.globl _kernel_flag
+ .globl _irqvector
; exported debugging tools
.globl _trap_monitor
; imported symbols
.globl _ramsize
.globl _procmem
+ .globl _membanks
.globl unix_syscall_entry
.globl null_handler
; COMMON MEMORY BANK (0xC000 upwards)
; -----------------------------------------------------------------------------
.area _COMMONMEM
+;
+; This is linked straight after the udata block so is 256 byte
+; aligned. Put the im2 table first
+;
+ .globl intvectors
+
+intvectors:
+ .dw ctc0_int ; VDP counting timer
+ .dw bogus_int ; Baud generator
+ .dw bogus_int ; Baud generator
+ .dw trace_int ; can be used for CPU tracing etc
+ .dw serial_int ; we don't use the vector mod functions
_trap_monitor:
di
out (0),a ; ROM mode, we are in common so survive
rst 0 ; kaboom
+_irqvector:
+ .db 0 ; used to identify the vector in question
+
+ctc0_int: push af
+ xor a
+ ld (_irqvector), a
+ pop af
+ jp interrupt_handler
+trace_int:
+bogus_int: reti
+serial_int:
+ push af
+ ld a, #1
+ ld (_irqvector), a
+ pop af
+ jp interrupt_handler
+
+; Kernel is in 0x80 so we just need to count the banks that differ
+size_ram:
+ ld hl, #0x1000 ; good as anywhere
+ ld bc, #0x8100 ; port 0 in c, b = 0x81
+size_next:
+ out (c), b
+ ld a, #0xA5
+ ld (hl), a
+ cp (hl)
+ jr nz, size_nonram
+ cpl
+ ld (hl), a
+ cp (hl)
+ jr nz, size_nonram
+ inc b
+ ld a, #0x8B
+ cp b
+ jr nz, size_next ; All banks done
+size_nonram:
+ ld a, #0x80
+ out (c), a ; Return to kernel
+ res 7,b ; Clear the flag so we just have banks
+ dec b ; Last valid bank
+ ld a, b
+ ld (_membanks), a
+ ld hl, #0
+ ld de, #48
+sizer: add hl, de
+ djnz sizer
+ ret
+
; -----------------------------------------------------------------------------
; KERNEL MEMORY BANK (below 0xC000, only accessible when the kernel is mapped)
; -----------------------------------------------------------------------------
ret
init_hardware:
+ call size_ram
; FIXME: do proper size checker
; set system RAM size (hardcoded for now)
- ld hl, #480
ld (_ramsize), hl
- ld hl, #(480-48) ; 64K for kernel
+ and a
+ sbc hl, de ; DE will hold 48 at this point
ld (_procmem), hl
; set up interrupt vectors for the kernel (also sets up common memory in page 0x000F which is unused)
; Program the video engine
call vdpinit
- ; FIXME: set up interrupt timer on the CTC
- ; 08 is channel 0, which is input for vdp
+ ; 08 is channel 0, which is input from VDP
; 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
xor a
out (0x08), a ; vector 0
- ld a, #0xA5
+ ld a, #0xC5
out (0x08), a ; CTC 0 as our IRQ source
- ld a, #0xFC
+ ld a, #0x01
out (0x08), a ; Timer constant
- im 1 ; set CPU interrupt mode
+ ld hl, #intvectors ; Work around SDCC crappiness
+ ld a, h
+ ld i, a
+ im 2 ; set CPU interrupt mode
call _vtinit ; init the console video