ASRCS = crt0.s tricks.s commonmem.s zeta-v2.s monitor.s
ASRCS += ds1302-n8vem.s devrd_hw.s
-CSRCS = devices.c main.c devtty.c devrd.c
+CSRCS = devices.c main.c devtty.c devrd.c ppide.c
DISCARD_CSRCS = discard.c devtty_discard.c
-DISCARD_DSRCS = ../dev/ds1302_discard.c
+DISCARD_DSRCS = ../dev/ds1302_discard.c ../dev/devide_discard.c
DSRCS = ../dev/devfd.c ../dev/devsd.c ../dev/mbr.c ../dev/blkdev.c
-DSRCS += ../dev/ds1302.c
+DSRCS += ../dev/ds1302.c ../dev/devide.c
DASRCS = ../dev/devfd_hw.s
AOBJS = $(ASRCS:.s=.rel)
sdasz80 -o bootrom.s
sdldz80 -m -i bootrom.rel
makebin -s 256 bootrom.ihx > bootrom.bin
- cat bootrom.bin ../fuzix.bin > ../fuzix.rom
+ cat bootrom.bin ../fuzix.bin > fuzix.rom
/* We need a tidier way to do this from the loader */
#define CMDLINE NULL /* Location of root dev name */
-#define BOOTDEVICENAMES "fd,rd"
+#define BOOTDEVICENAMES "hd#,fd,,rd"
//#define SWAPDEV (256 + 1) /* Device for swapping */
#define NBUFS 10 /* Number of block buffers */
#define CONFIG_RTC_INTERVAL 30 /* deciseconds between reading RTC seconds counter */
/* Floppy support */
-#define CONFIG_FLOPPY /* # define CONFIG_FLOPPY to enable floppy */
+#define CONFIG_FLOPPY /* #define CONFIG_FLOPPY to enable floppy */
+
+/* PPIDE support */
+#define CONFIG_PPIDE /* #define CONFIG_PPIDE to enable IDE on 8255A */
+#ifdef CONFIG_PPIDE
+#define PPIDE_BASE 0x60 /* Base address of 8255A */
+#define IDE_REG_INDIRECT /* IDE registers are not directly connected to the CPU bus */
+
+/* IDE control signal to 8255 port C mapping */
+#define PPIDE_A0_LINE 0x01 // Direct from 8255 to IDE interface
+#define PPIDE_A1_LINE 0x02 // Direct from 8255 to IDE interface
+#define PPIDE_A2_LINE 0x04 // Direct from 8255 to IDE interface
+#define PPIDE_CS0_LINE 0x08 // Inverter between 8255 and IDE interface
+#define PPIDE_CS1_LINE 0x10 // Inverter between 8255 and IDE interface
+#define PPIDE_WR_LINE 0x20 // Inverter between 8255 and IDE interface
+#define PPIDE_WR_BIT 5 // (1 << PPIDE_WR_BIT) = PPIDE_WR_LINE
+#define PPIDE_RD_LINE 0x40 // Inverter between 8255 and IDE interface
+#define PPIDE_RD_BIT 6 // (1 << PPIDE_RD_BIT) = PPIDE_RD_LINE
+#define PPIDE_RST_LINE 0x80 // Inverter between 8255 and IDE interface
+
+/* 8255 configuration */
+#define PPIDE_PPI_BUS_READ 0x92
+#define PPIDE_PPI_BUS_WRITE 0x80
+
+/* IDE register addresses */
+#define ide_reg_data (PPIDE_CS0_LINE)
+#define ide_reg_error (PPIDE_CS0_LINE | PPIDE_A0_LINE)
+#define ide_reg_features (PPIDE_CS0_LINE | PPIDE_A0_LINE)
+#define ide_reg_sec_count (PPIDE_CS0_LINE | PPIDE_A1_LINE)
+#define ide_reg_lba_0 (PPIDE_CS0_LINE | PPIDE_A1_LINE | PPIDE_A0_LINE)
+#define ide_reg_lba_1 (PPIDE_CS0_LINE | PPIDE_A2_LINE)
+#define ide_reg_lba_2 (PPIDE_CS0_LINE | PPIDE_A2_LINE | PPIDE_A0_LINE)
+#define ide_reg_lba_3 (PPIDE_CS0_LINE | PPIDE_A2_LINE | PPIDE_A1_LINE)
+#define ide_reg_devhead (PPIDE_CS0_LINE | PPIDE_A2_LINE | PPIDE_A1_LINE)
+#define ide_reg_command (PPIDE_CS0_LINE | PPIDE_A2_LINE | PPIDE_A1_LINE | PPIDE_A0_LINE)
+#define ide_reg_status (PPIDE_CS0_LINE | PPIDE_A2_LINE | PPIDE_A1_LINE | PPIDE_A0_LINE)
+#define ide_reg_altstatus (PPIDE_CS1_LINE | PPIDE_A2_LINE | PPIDE_A1_LINE)
+#define ide_reg_control (PPIDE_CS1_LINE | PPIDE_A2_LINE | PPIDE_A1_LINE | PPIDE_A0_LINE)
+#endif /* CONFIG_PPIDE */
/* Optional ParPortProp board connected to PPI */
//#define CONFIG_PPP /* #define CONFIG_PPP to enable as tty3 */
/* Device parameters */
+#define CONFIG_RAMDISK /* enable memory-backed disk driver */
#define NUM_DEV_RD 1
#define DEV_RD_PAGES 16 /* size of the RAM disk in pages */
#define DEV_RD_START 48 /* first page used by the RAM disk */
struct devsw dev_tab[] = /* The device driver switch table */
{
/* open close read write ioctl */
- /* 0: /dev/fd - Floppy disk block devices */
+ /* 0: /dev/hd - block device interface */
+#ifdef CONFIG_PPIDE
+ { blkdev_open, no_close, blkdev_read, blkdev_write, blkdev_ioctl},
+#else
+ { no_open, no_close, no_rdwr, no_rdwr, no_ioctl},
+#endif
+ /* 1: /dev/fd - Floppy disk block devices */
+#ifdef CONFIG_FLOPPY
{ fd_open, fd_close, fd_read, fd_write, no_ioctl},
- /* 1: /dev/hd - RAM disk interface */
- { rd_open, no_close, rd_read, rd_write, no_ioctl},
+#else
+ { no_open, no_close, no_rdwr, no_rdwr, no_ioctl},
+#endif
/* 2: /dev/tty -- serial ports */
{ tty_open, tty_close, tty_read, tty_write, tty_ioctl},
- /* 3: unused slot */
+ /* 3: RAM disk */
+#ifdef CONFIG_RAMDISK
+ { rd_open, no_close, rd_read, rd_write, no_ioctl},
+#else
{ no_open, no_close, no_rdwr, no_rdwr, no_ioctl},
+#endif
/* 4: /dev/mem etc System devices (one offs) */
{ no_open, no_close, sys_read, sys_write, sys_ioctl},
};
#include <ds1302.h>
#include "config.h"
+#ifdef CONFIG_PPIDE
+#include <devide.h>
+
+void ppide_init(void);
+#endif
+
void pagemap_init(void)
{
int i;
{
}
+
void device_init(void)
{
ds1302_init();
uart0_init();
+#ifdef CONFIG_PPIDE
+ ppide_init();
+ devide_init();
+#endif
}
platform-zeta-v2/discard.rel
platform-zeta-v2/devtty.rel
platform-zeta-v2/devtty_discard.rel
+platform-zeta-v2/ppide.rel
+platform-zeta-v2/devide.rel
+platform-zeta-v2/devide_discard.rel
platform-zeta-v2/mbr.rel
platform-zeta-v2/blkdev.rel
platform-zeta-v2/ds1302.rel
--- /dev/null
+/* 2015-04-24 WRS: devide glue functions for PPIDE */
+
+#include <kernel.h>
+#include <kdata.h>
+#include <printf.h>
+#include <stdbool.h>
+#include <timer.h>
+#include <devide.h>
+#include <blkdev.h>
+
+__sfr __at (PPIDE_BASE + 0x00) ppi_port_a; /* IDE bus LSB */
+__sfr __at (PPIDE_BASE + 0x01) ppi_port_b; /* IDE bus MSB */
+__sfr __at (PPIDE_BASE + 0x02) ppi_port_c; /* IDE bus control signals */
+__sfr __at (PPIDE_BASE + 0x03) ppi_control; /* 8255 command register */
+
+void ppide_init(void)
+{
+ ppi_control = PPIDE_PPI_BUS_READ;
+ ppi_port_c = ide_reg_status;
+}
+
+uint8_t devide_readb(uint8_t regaddr)
+{
+ uint8_t r;
+
+ /* note: ppi_control should contain PPIDE_PPI_BUS_READ already */
+ ppi_port_c = regaddr;
+ ppi_control = 1 | (PPIDE_RD_BIT << 1); /* begin /RD pulse */
+ r = ppi_port_a;
+ ppi_control = 0 | (PPIDE_RD_BIT << 1); /* end /RD pulse */
+ return r;
+}
+
+void devide_writeb(uint8_t regaddr, uint8_t value)
+{
+ ppi_control = PPIDE_PPI_BUS_WRITE;
+ ppi_port_c = regaddr;
+ ppi_port_a = value;
+ ppi_port_b = 0;
+ ppi_control = 1 | (PPIDE_WR_BIT << 1); /* begin /WR pulse */
+ ppi_control = 0 | (PPIDE_WR_BIT << 1); /* end /WR pulse */
+ ppi_control = PPIDE_PPI_BUS_READ;
+}
+
+/****************************************************************************/
+/* The innermost part of the transfer routines has to live in common memory */
+/* since it must be able to bank switch to the user memory bank. */
+/****************************************************************************/
+COMMON_MEMORY
+
+void devide_read_data(void) __naked
+{
+ __asm
+ ld a, #ide_reg_data
+ ld c, #PPIDE_BASE+2 ; select control lines
+ out (c), a ; select IDE data register
+ ld hl, (_blk_op+BLKPARAM_ADDR_OFFSET) ; blkparam.addr
+ ld d, #ide_reg_data ; register address
+ ld e, #ide_reg_data | PPIDE_RD_LINE ; register address with /RD asserted
+ ld b, #0 ; setup count
+ ld a, (_blk_op+BLKPARAM_IS_USER_OFFSET) ; blkparam.is_user
+ or a ; test is_user
+ push af ; save flags
+ ld a, #PPIDE_BASE+0 ; I will be needing this later
+ jr z, goread ; just start the transfer if kernel memory
+ call map_process_always ; else map user memory first
+goread: ; now we do the transfer
+ out (c), e ; assert /RD
+ ld c, a ; PPIDE_BASE
+ ini ; read byte from LSB
+ inc c ; up to MSB
+ ini ; read byte from MSB
+ inc c ; control lines
+ out (c), d ; de-assert /RD
+ inc b ; (delay) counteract second ini instruction
+ jr nz, goread ; (delay) next word
+ ; read completed
+ pop af ; recover is_user test result
+ ret z ; done if kernel memory transfer
+ jp map_kernel ; else map kernel then return
+ __endasm;
+}
+
+void devide_write_data(void) __naked
+{
+ __asm
+ ld c, #PPIDE_BASE+2 ; select control lines
+ ld a, #ide_reg_data
+ out (c), a ; select data register
+ ld a, #PPIDE_PPI_BUS_WRITE
+ inc c ; up to 8255A command register
+ out (c), a ; 8255A ports A, B to output mode
+ dec c ; back down to the control lines
+ ld hl, (_blk_op+BLKPARAM_ADDR_OFFSET) ; blkparam.addr
+ ld d, #ide_reg_data ; register address
+ ld e, #ide_reg_data | PPIDE_WR_LINE ; register address with /WR asserted
+ ld b, #0 ; setup count
+ ld a, (_blk_op+BLKPARAM_IS_USER_OFFSET) ; blkparam.is_user
+ or a ; test is_user
+ push af ; save flags
+ ld a, #PPIDE_BASE+0 ; I will be needing this later
+ jr z, gowrite ; just start the transfer if kernel memory
+ call map_process_always ; else map user memory first
+gowrite: ; now we do the transfer
+ out (c), d ; de-assert /WR
+ ld c, a ; PPIDE_BASE
+ outi ; write byte to LSB
+ inc c ; up to MSB
+ outi ; write byte to MSB
+ inc c ; up to control lines
+ out (c), e ; assert /WR
+ inc b ; (delay) offset to counteract second outi instruction
+ jr nz, gowrite ; (delay) next word
+ ; write completed
+ out (c), d ; de-assert /WR
+ ld a, #PPIDE_PPI_BUS_READ
+ inc c ; up to 8255A command register
+ out (c), a ; 8255A ports A, B to read mode
+ pop af ; recover is_user test result
+ ret z ; done if kernel memory transfer
+ jp map_kernel ; else map kernel then return
+ __endasm;
+}