-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)
--- /dev/null
+/*
+ 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);
+}
+
--- /dev/null
+#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
--- /dev/null
+;
+; 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)
#define CONFIG_IDE
+//#define CONFIG_BETADISK
/* Enable to make ^Z dump the inode table for debug */
#undef CONFIG_IDUMP
#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
#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 },
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