From: Alexander Tsidaev Date: Sun, 7 Aug 2016 09:28:59 +0000 (+0500) Subject: zx128: Betadisk-128 driver X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=56079391b490ef6ee1a7e0760ffb8b8bcb498a01;p=FUZIX.git zx128: Betadisk-128 driver --- diff --git a/Kernel/platform-zx128/Makefile b/Kernel/platform-zx128/Makefile index ea317290..d28c9660 100644 --- a/Kernel/platform-zx128/Makefile +++ b/Kernel/platform-zx128/Makefile @@ -1,7 +1,7 @@ -CSRCS = devtty.c devices.c main.c devmdv.c devfd.c bank128.c +CSRCS = devtty.c devices.c main.c devmdv.c devfd.c bank128.c betadisk.c DSRCS = ../dev/devide.c ../dev/mbr.c ../dev/blkdev.c DDSRCS = ../dev/devide_discard.c -ASRCS = crt0.s zx128.s zxvideo.s microdrive.s disciple.s +ASRCS = crt0.s zx128.s zxvideo.s microdrive.s disciple.s betadisk_internal.s ASRCS += tricks.s commonmem.s COBJS = $(CSRCS:.c=.rel) diff --git a/Kernel/platform-zx128/betadisk.c b/Kernel/platform-zx128/betadisk.c new file mode 100644 index 00000000..4dcf7e4f --- /dev/null +++ b/Kernel/platform-zx128/betadisk.c @@ -0,0 +1,58 @@ +/* + ZX Spectrum floppy drive driver for Betadisk-128 interface. + + Betadisk is based on wd1793 chip, but all its ports are hidden + and only become available when an opcode fetch is performed in the ROM + area 0x3D00..0x3DFF. This forces us to use TR-DOS ROM procedures + instead of direct wd1793 access. + + Idea and initial version by b2m @ http://zx-pk.ru +*/ + +#include +#include + +#include "betadisk.h" + +int betadisk_open(uint8_t minor, uint16_t flag) +{ + flag; + if(minor != 0) { + udata.u_error = ENODEV; + return -1; + } + return 0; +} + +static int betadisk_transfer(bool is_read, uint8_t rawflag) +{ + blkno_t block; + + if (rawflag != 0) + return 0; + + block = udata.u_buf->bf_blk<<1; + + /* Read only for now */ + if (!is_read) + return 1; + + betadisk_seek_internal(block>>4); + block &= 15; + betadisk_read_internal(block, udata.u_buf->bf_data); + betadisk_read_internal(block+1, udata.u_buf->bf_data+256); + return 1; +} + +int betadisk_read(uint8_t minor, uint8_t rawflag, uint8_t flag) +{ + flag;minor; + return betadisk_transfer(true, rawflag); +} + +int betadisk_write(uint8_t minor, uint8_t rawflag, uint8_t flag) +{ + flag;minor; + return betadisk_transfer(false, rawflag); +} + diff --git a/Kernel/platform-zx128/betadisk.h b/Kernel/platform-zx128/betadisk.h new file mode 100644 index 00000000..7a666fa6 --- /dev/null +++ b/Kernel/platform-zx128/betadisk.h @@ -0,0 +1,12 @@ +#ifndef __BETADISK_H__ +#define __BETADISK_H__ + +int betadisk_open(uint8_t minor, uint16_t flag); +int betadisk_read(uint8_t minor, uint8_t rawflag, uint8_t flag); +int betadisk_write(uint8_t minor, uint8_t rawflag, uint8_t flag); + +/* Hacks in assembler */ +void betadisk_seek_internal(uint16_t track); +void betadisk_read_internal(uint16_t sector, uint8_t* buf); + +#endif diff --git a/Kernel/platform-zx128/betadisk_internal.s b/Kernel/platform-zx128/betadisk_internal.s new file mode 100644 index 00000000..cb29a9a4 --- /dev/null +++ b/Kernel/platform-zx128/betadisk_internal.s @@ -0,0 +1,49 @@ +; +; TR-DOS 5.03 calls +; Procedure addresses for another TR-DOS version may be different! + +; If we are not sure what ROM page is active now (Basic-48 or Basic-48), +; then we need to set port 0x7FFD bit D4=1 manually because these hacks work +; correctly only when Basic-48 is mapped. + + .module betadisk_internal + + ; exported symbols + .globl _betadisk_seek_internal + .globl _betadisk_read_internal + + .area _CODE + +; _betadisk_seek_internal positions head to the requested track +; void betadisk_seek_internal(uint16_t track); + +_betadisk_seek_internal: + ld hl, #4 ; skipping return address and mapper word + add hl, sp ; now hl points directly at the "track" argument + ld a, (hl) ; it is uint16_t, but actually only lower byte matters (80 tracks max) + or a ; calculating needed side of the disk + rra + ld c,a + ld a,#0x3C ; top side + jr nc,01$ + ld a,#0x2C ; bottom side +01$: + ld hl,#0x2F4D ; address of SEARCH TR-DOS procedure + push hl + jp 0x3D2F ; classical way to perform jp (sp) inside TR-DOS ROM + +; betadisk_read_internal reads desired sector from the current track +; void betadisk_read_internal(uint16_t sector, uint8_t* buf); + +_betadisk_read_internal: + pop ix ; return address + pop bc ; mapper spacer + pop de ; sector number (only E matters) + pop hl ; buf address + push hl + push de + push bc + push ix + ld bc,#0x2F1B ; address of READ SECTOR procedure of TR-DOS ROM + push bc + jp 0x3D2F ; jp (SP) diff --git a/Kernel/platform-zx128/config.h b/Kernel/platform-zx128/config.h index 4928dbb3..5e65c1f2 100644 --- a/Kernel/platform-zx128/config.h +++ b/Kernel/platform-zx128/config.h @@ -1,4 +1,5 @@ #define CONFIG_IDE +//#define CONFIG_BETADISK /* Enable to make ^Z dump the inode table for debug */ #undef CONFIG_IDUMP @@ -66,3 +67,8 @@ #define swap_map(x) ((uint8_t *)(x|0xC000)) #define platform_discard() + +/* Betadisk functions do not work with modern procedures */ +#ifdef CONFIG_BETADISK +#define CONFIG_LEGACY_EXEC +#endif diff --git a/Kernel/platform-zx128/devices.c b/Kernel/platform-zx128/devices.c index 72a43e21..b8abe9ba 100644 --- a/Kernel/platform-zx128/devices.c +++ b/Kernel/platform-zx128/devices.c @@ -6,13 +6,19 @@ #include #include #include +#include #include #include struct devsw dev_tab[] = /* The device driver switch table */ { +#ifdef CONFIG_BETADISK + /* 0: /dev/fd Floppy disc block devices: betadisk */ + { betadisk_open, no_close, betadisk_read, betadisk_write, no_ioctl }, +#else /* 0: /dev/fd Floppy disc block devices: disciple */ { fd_open, no_close, fd_read, fd_write, no_ioctl }, +#endif #ifdef CONFIG_IDE /* 1: /dev/hd Hard disc block devices */ { blkdev_open, no_close, blkdev_read, blkdev_write, blkdev_ioctl }, diff --git a/Kernel/platform-zx128/fuzix.lnk b/Kernel/platform-zx128/fuzix.lnk index 2fc2f137..3770488d 100644 --- a/Kernel/platform-zx128/fuzix.lnk +++ b/Kernel/platform-zx128/fuzix.lnk @@ -25,6 +25,8 @@ platform-zx128/devmdv.rel platform-zx128/microdrive.rel platform-zx128/devfd.rel platform-zx128/disciple.rel +platform-zx128/betadisk.rel +platform-zx128/betadisk_internal.rel devio.rel filesys.rel process.rel