From ecd5e69d171013aadcfc48c07c525104fef1a3a1 Mon Sep 17 00:00:00 2001 From: Will Sowerbutts Date: Fri, 24 Apr 2015 20:47:01 +0100 Subject: [PATCH] zeta-v2: Add support for PPIDE storage --- Kernel/platform-zeta-v2/Makefile | 8 +- Kernel/platform-zeta-v2/config.h | 43 ++++++++++- Kernel/platform-zeta-v2/devices.c | 20 ++++- Kernel/platform-zeta-v2/discard.c | 11 +++ Kernel/platform-zeta-v2/fuzix.lnk | 3 + Kernel/platform-zeta-v2/ppide.c | 123 ++++++++++++++++++++++++++++++ 6 files changed, 198 insertions(+), 10 deletions(-) create mode 100644 Kernel/platform-zeta-v2/ppide.c diff --git a/Kernel/platform-zeta-v2/Makefile b/Kernel/platform-zeta-v2/Makefile index 718b662f..1a168a28 100644 --- a/Kernel/platform-zeta-v2/Makefile +++ b/Kernel/platform-zeta-v2/Makefile @@ -1,10 +1,10 @@ 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) @@ -47,4 +47,4 @@ image: 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 diff --git a/Kernel/platform-zeta-v2/config.h b/Kernel/platform-zeta-v2/config.h index 4253422a..22e808cf 100644 --- a/Kernel/platform-zeta-v2/config.h +++ b/Kernel/platform-zeta-v2/config.h @@ -35,7 +35,7 @@ /* 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 */ @@ -48,12 +48,51 @@ #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 */ diff --git a/Kernel/platform-zeta-v2/devices.c b/Kernel/platform-zeta-v2/devices.c index 1e4af908..63bbb7d1 100644 --- a/Kernel/platform-zeta-v2/devices.c +++ b/Kernel/platform-zeta-v2/devices.c @@ -12,14 +12,26 @@ 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}, }; diff --git a/Kernel/platform-zeta-v2/discard.c b/Kernel/platform-zeta-v2/discard.c index 1a14456b..4081d80b 100644 --- a/Kernel/platform-zeta-v2/discard.c +++ b/Kernel/platform-zeta-v2/discard.c @@ -5,6 +5,12 @@ #include #include "config.h" +#ifdef CONFIG_PPIDE +#include + +void ppide_init(void); +#endif + void pagemap_init(void) { int i; @@ -26,8 +32,13 @@ void map_init(void) { } + void device_init(void) { ds1302_init(); uart0_init(); +#ifdef CONFIG_PPIDE + ppide_init(); + devide_init(); +#endif } diff --git a/Kernel/platform-zeta-v2/fuzix.lnk b/Kernel/platform-zeta-v2/fuzix.lnk index a6fdec83..885f22f4 100644 --- a/Kernel/platform-zeta-v2/fuzix.lnk +++ b/Kernel/platform-zeta-v2/fuzix.lnk @@ -38,6 +38,9 @@ usermem_std-z80.rel 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 diff --git a/Kernel/platform-zeta-v2/ppide.c b/Kernel/platform-zeta-v2/ppide.c new file mode 100644 index 00000000..2e5d053b --- /dev/null +++ b/Kernel/platform-zeta-v2/ppide.c @@ -0,0 +1,123 @@ +/* 2015-04-24 WRS: devide glue functions for PPIDE */ + +#include +#include +#include +#include +#include +#include +#include + +__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; +} -- 2.34.1