zx128: Betadisk-128 driver
authorAlexander Tsidaev <a.tsidaev@gmail.com>
Sun, 7 Aug 2016 09:28:59 +0000 (14:28 +0500)
committerAlexander Tsidaev <a.tsidaev@gmail.com>
Sun, 7 Aug 2016 10:52:11 +0000 (15:52 +0500)
Kernel/platform-zx128/Makefile
Kernel/platform-zx128/betadisk.c [new file with mode: 0644]
Kernel/platform-zx128/betadisk.h [new file with mode: 0644]
Kernel/platform-zx128/betadisk_internal.s [new file with mode: 0644]
Kernel/platform-zx128/config.h
Kernel/platform-zx128/devices.c
Kernel/platform-zx128/fuzix.lnk

index ea31729..d28c966 100644 (file)
@@ -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 (file)
index 0000000..4dcf7e4
--- /dev/null
@@ -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 <kernel.h>
+#include <kdata.h>
+
+#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 (file)
index 0000000..7a666fa
--- /dev/null
@@ -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 (file)
index 0000000..cb29a9a
--- /dev/null
@@ -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)
index 4928dbb..5e65c1f 100644 (file)
@@ -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
index 72a43e2..b8abe9b 100644 (file)
@@ -6,13 +6,19 @@
 #include <vt.h>
 #include <devmdv.h>
 #include <devfd.h>
+#include <betadisk.h>
 #include <devide.h>
 #include <blkdev.h>
 
 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 },
index 2fc2f13..3770488 100644 (file)
@@ -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