[packages/fuse] - support for FDD3000, taken from fdd3000e - rel 6

witekfl witekfl at pld-linux.org
Tue Feb 18 13:38:27 CET 2014


commit 1d83233ef2f233ade2ac53355fd3af7a1b481898
Author: Witold Filipczyk <witekfl at poczta.onet.pl>
Date:   Tue Feb 18 13:33:33 2014 +0100

    - support for FDD3000, taken from fdd3000e
    - rel 6

 fuse-1.1.1.patch | 881 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 881 insertions(+)
---
diff --git a/fuse-1.1.1.patch b/fuse-1.1.1.patch
new file mode 100644
index 0000000..4c514c7
--- /dev/null
+++ b/fuse-1.1.1.patch
@@ -0,0 +1,881 @@
+diff -Naru fuse-1.1.1/fuse.c fuse-1.1.1.fdd3000/fuse.c
+--- fuse-1.1.1/fuse.c	2013-05-16 22:26:23.000000000 +0200
++++ fuse-1.1.1.fdd3000/fuse.c	2014-02-14 08:28:21.228997802 +0100
+@@ -274,6 +274,7 @@
+   rzx_init();
+   psg_init();
+   beta_init();
++  tim397_init();
+   opus_init();
+   plusd_init();
+   disciple_init();
+diff -Naru fuse-1.1.1/machines/machines_periph.c fuse-1.1.1.fdd3000/machines/machines_periph.c
+--- fuse-1.1.1/machines/machines_periph.c	2013-05-16 22:26:11.000000000 +0200
++++ fuse-1.1.1.fdd3000/machines/machines_periph.c	2014-02-14 08:30:34.228014927 +0100
+@@ -201,6 +201,7 @@
+   periph_set_present( PERIPH_TYPE_FULLER, PERIPH_PRESENT_OPTIONAL );
+   periph_set_present( PERIPH_TYPE_ZXPRINTER, PERIPH_PRESENT_OPTIONAL );
+   periph_set_present( PERIPH_TYPE_DISCIPLE, PERIPH_PRESENT_OPTIONAL );
++  periph_set_present( PERIPH_TYPE_TIM397, PERIPH_PRESENT_OPTIONAL );
+ }
+ 
+ /* The set of peripherals available on the 128K and similar machines */
+diff -Naru fuse-1.1.1/Makefile.in fuse-1.1.1.fdd3000/Makefile.in
+--- fuse-1.1.1/Makefile.in	2013-05-30 00:21:33.000000000 +0200
++++ fuse-1.1.1.fdd3000/Makefile.in	2014-02-14 08:33:02.997237928 +0100
+@@ -232,7 +232,7 @@
+ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+ LIBOBJS = @LIBOBJS@
+ LIBPNG_CONFIG = @LIBPNG_CONFIG@
+-LIBS = @LIBS@
++LIBS = @LIBS@ -lrt
+ LIBSPEC_CFLAGS = @LIBSPEC_CFLAGS@
+ LIBSPEC_HAVE_AUDIOFILE = @LIBSPEC_HAVE_AUDIOFILE@
+ LIBSPEC_HAVE_BZ2 = @LIBSPEC_HAVE_BZ2@
+diff -Naru fuse-1.1.1/memory.c fuse-1.1.1.fdd3000/memory.c
+--- fuse-1.1.1/memory.c	2013-05-16 22:26:23.000000000 +0200
++++ fuse-1.1.1.fdd3000/memory.c	2014-02-14 08:21:36.769616238 +0100
+@@ -37,6 +37,7 @@
+ #include "memory.h"
+ #include "module.h"
+ #include "peripherals/disk/opus.h"
++#include "peripherals/disk/ti_m397.h"
+ #include "peripherals/spectranet.h"
+ #include "peripherals/ula.h"
+ #include "settings.h"
+diff -Naru fuse-1.1.1/menu.c fuse-1.1.1.fdd3000/menu.c
+--- fuse-1.1.1/menu.c	2013-05-16 22:26:23.000000000 +0200
++++ fuse-1.1.1.fdd3000/menu.c	2014-02-14 08:21:36.769616238 +0100
+@@ -36,6 +36,7 @@
+ #include "peripherals/disk/beta.h"
+ #include "peripherals/disk/disciple.h"
+ #include "peripherals/disk/opus.h"
++#include "peripherals/disk/ti_m397.h"
+ #include "peripherals/disk/plusd.h"
+ #include "peripherals/ide/divide.h"
+ #include "peripherals/ide/simpleide.h"
+@@ -224,7 +225,8 @@
+   case 18: menu_select_roms_with_title( "+D",              42, 1 ); return;
+   case 19: menu_select_roms_with_title( "DISCiPLE",        43, 1 ); return;
+   case 20: menu_select_roms_with_title( "Opus Discovery",  44, 1 ); return;
+-  case 21: menu_select_roms_with_title( "SpeccyBoot",      45, 1 ); return;
++  case 21: menu_select_roms_with_title( "Timex M397",      45, 1 ); return;
++  case 22: menu_select_roms_with_title( "SpeccyBoot",      46, 1 ); return;
+ 
+   }
+ 
+diff -Naru fuse-1.1.1/menu_data.dat fuse-1.1.1.fdd3000/menu_data.dat
+--- fuse-1.1.1/menu_data.dat	2013-05-16 22:26:23.000000000 +0200
++++ fuse-1.1.1.fdd3000/menu_data.dat	2014-02-14 08:21:36.769616238 +0100
+@@ -101,7 +101,8 @@
+ Options/Select ROMs/+_D..., Item,, menu_options_selectroms_select,, 18
+ Options/Select ROMs/DISCiP_LE..., Item,, menu_options_selectroms_select,, 19
+ Options/Select ROMs/_Opus Discovery..., Item,, menu_options_selectroms_select,, 20
+-Options/Select ROMs/Specc_yBoot..., Item,, menu_options_selectroms_select,, 21
++Options/Select ROMs/_Timex M397..., Item,, menu_options_selectroms_select,, 21
++Options/Select ROMs/Specc_yBoot..., Item,, menu_options_selectroms_select,, 22
+ 
+ Options/_Filter..., Item,,, menu_filter_detail
+ 
+diff -Naru fuse-1.1.1/peripherals/disk/Makefile.am fuse-1.1.1.fdd3000/peripherals/disk/Makefile.am
+--- fuse-1.1.1/peripherals/disk/Makefile.am	2013-05-16 22:26:03.000000000 +0200
++++ fuse-1.1.1.fdd3000/peripherals/disk/Makefile.am	2014-02-14 08:21:36.769616238 +0100
+@@ -37,6 +37,7 @@
+ 		    opus.c \
+ 		    plusd.c \
+ 		    upd_fdc.c \
++		    ti_m397.c \
+ 		    wd_fdc.c
+ 
+ noinst_HEADERS = beta.h \
+@@ -47,4 +48,5 @@
+ 		 opus.h \
+ 		 plusd.h \
+ 		 upd_fdc.h \
++		 ti_m397.h \
+ 		 wd_fdc.h
+diff -Naru fuse-1.1.1/peripherals/disk/Makefile.in fuse-1.1.1.fdd3000/peripherals/disk/Makefile.in
+--- fuse-1.1.1/peripherals/disk/Makefile.in	2013-05-24 22:56:08.000000000 +0200
++++ fuse-1.1.1.fdd3000/peripherals/disk/Makefile.in	2014-02-14 08:32:46.900294664 +0100
+@@ -75,7 +75,7 @@
+ libdisk_a_LIBADD =
+ am_libdisk_a_OBJECTS = beta.$(OBJEXT) crc.$(OBJEXT) disciple.$(OBJEXT) \
+ 	disk.$(OBJEXT) fdd.$(OBJEXT) opus.$(OBJEXT) plusd.$(OBJEXT) \
+-	upd_fdc.$(OBJEXT) wd_fdc.$(OBJEXT)
++	upd_fdc.$(OBJEXT) ti_m397.$(OBJEXT) wd_fdc.$(OBJEXT)
+ libdisk_a_OBJECTS = $(am_libdisk_a_OBJECTS)
+ DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+ depcomp = $(SHELL) $(top_srcdir)/depcomp
+@@ -281,6 +281,7 @@
+ 		    opus.c \
+ 		    plusd.c \
+ 		    upd_fdc.c \
++		    ti_m397.c \
+ 		    wd_fdc.c
+ 
+ noinst_HEADERS = beta.h \
+@@ -291,6 +292,7 @@
+ 		 opus.h \
+ 		 plusd.h \
+ 		 upd_fdc.h \
++		 ti_m397.h \
+ 		 wd_fdc.h
+ 
+ all: all-am
+@@ -349,6 +351,7 @@
+ @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/opus.Po at am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/plusd.Po at am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/upd_fdc.Po at am__quote@
++ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ti_m397.Po at am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/wd_fdc.Po at am__quote@
+ 
+ .c.o:
+diff -Naru fuse-1.1.1/peripherals/disk/ti_m397.c fuse-1.1.1.fdd3000/peripherals/disk/ti_m397.c
+--- fuse-1.1.1/peripherals/disk/ti_m397.c	1970-01-01 01:00:00.000000000 +0100
++++ fuse-1.1.1.fdd3000/peripherals/disk/ti_m397.c	2014-02-14 08:53:54.159789884 +0100
+@@ -0,0 +1,562 @@
++/******************************************************************************
++ This file is a part od FDD3000 Emulator
++
++ Copyright (C) 2013 by Sławomir Szczyrba <sszczyrba at gmail.com>
++ Copyright (C) 2014 by Stefano Bodrato <stefano_bodrato hotmail dt com>
++
++ This program is free software: you can redistribute it and/or modify it under
++ the terms of the GNU Lesser General Public License as published by the Free
++ Software Foundation, either version 2 of the License, or (at your option) any
++ later version.
++    
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
++ details.
++
++ You should have received a copy of the GNU Lesser General Public License
++ along with this program. If not, see <http://www.gnu.org/licenses/lgpl.html>
++******************************************************************************/
++
++
++#include <config.h>
++
++#include <libspectrum.h>
++
++#include <string.h>
++
++#include "compat.h"
++#include "machine.h"
++#include "module.h"
++#include "ti_m397.h"
++#include "peripherals/printer.h"
++#include "settings.h"
++#include "ui/ui.h"
++#include "unittests/unittests.h"
++//#include "utils.h"
++#include "wd_fdc.h"
++#include "options.h"	/* needed for get combo options */
++#include "z80/z80.h"
++
++
++#include <errno.h>
++#include <fcntl.h>
++#include <signal.h>
++#include <stdio.h>
++#include <string.h>
++#include <sys/stat.h>        /* For mode constants */
++#include <sys/types.h>
++#include <unistd.h>
++
++
++#if defined (__MINGW32__) || defined (_WIN32) || defined (_WIN32_) || defined (__WIN32__)
++
++#include <windows.h>
++#include <tchar.h>
++
++#else
++
++#include <semaphore.h>
++#ifndef SEM_FAILED
++#define SEM_FAILED -1
++#endif
++#include <sys/mman.h>
++#include <sys/ipc.h>
++#include <sys/msg.h>
++#include <sys/socket.h>
++
++#endif
++
++
++
++/* IPC */
++
++typedef struct tFdd2TiLink {
++    uint8_t  fdd2ti;
++    uint8_t  ti2fdd;
++    uint8_t  fddAlive;
++    uint8_t  tiAlive;
++} fdd2TiLink;
++
++fdd2TiLink * fddlink;
++
++
++uint8_t data;
++int ipc, connected;
++char * path;
++
++
++
++#if defined (__MINGW32__) || defined (_WIN32) || defined (_WIN32_) || defined (__WIN32__)
++
++HANDLE fdd2tiF, fdd2tiE, ti2fddF, ti2fddE, fddAlive;
++HANDLE shm, shmf;
++DWORD dwRetVal = 0;
++
++TCHAR *shmId = _T("\\fdd.data");
++//TCHAR shmId[]=TEXT("Global\\fdd.data");
++TCHAR szTempFileName[MAX_PATH];  
++TCHAR lpTempPathBuffer[MAX_PATH];
++
++TCHAR fdd2tiE_Id[]=TEXT("Global\\fdd.fdd2ti.empty");
++TCHAR fdd2tiF_Id[]=TEXT("Global\\fdd.fdd2ti.full");
++TCHAR ti2fddE_Id[]=TEXT("Global\\fdd.ti2fdd.empty");
++TCHAR ti2fddF_Id[]=TEXT("Global\\fdd.ti2fdd.full");
++TCHAR fddAlive_Id[]=TEXT("Global\\fdd.alive");   
++/*
++TCHAR * fddAlive_Id = "fdd.alive";
++TCHAR * fdd2tiE_Id = "fdd.fdd2ti.empty";
++TCHAR * fdd2tiF_Id = "fdd.fdd2ti.full";
++TCHAR * ti2fddE_Id = "fdd.ti2fdd.empty";
++TCHAR * ti2fddF_Id = "fdd.ti2fdd.full";
++*/
++#else
++
++sem_t   *fdd2tiF,*fdd2tiE,*ti2fddF,*ti2fddE,*fddAlive;
++int   shm;
++const char * shmId = "fdd.data";
++
++const char * fddAlive_Id = "fdd.alive";
++const char * fdd2tiE_Id = "fdd.fdd2ti.empty";
++const char * fdd2tiF_Id = "fdd.fdd2ti.full";
++const char * ti2fddE_Id = "fdd.ti2fdd.empty";
++const char * ti2fddF_Id = "fdd.ti2fdd.full";
++
++#endif
++
++int8_t fddRead() {
++    uint8_t data=0;
++#if defined (__MINGW32__) || defined (_WIN32) || defined (_WIN32_) || defined (__WIN32__)
++	WaitForSingleObject(ti2fddF,INFINITE);
++    data=fddlink->fdd2ti;
++	ReleaseSemaphore(ti2fddE,1,NULL);
++#else
++    sem_wait(fdd2tiF);
++    data=fddlink->fdd2ti;
++    sem_post(fdd2tiE);
++#endif
++    return data;
++}
++
++void fddWrite(int8_t d) {
++#if defined (__MINGW32__) || defined (_WIN32) || defined (_WIN32_) || defined (__WIN32__)
++	WaitForSingleObject(ti2fddE,INFINITE);
++    fddlink->ti2fdd=d;
++	ReleaseSemaphore(ti2fddF,1,NULL);
++#else
++    sem_wait(ti2fddE);
++    fddlink->ti2fdd=d;
++    sem_post(ti2fddF);
++#endif
++}
++
++uint8_t fddIsAlive() {
++    uint8_t ok;
++#if defined (__MINGW32__) || defined (_WIN32) || defined (_WIN32_) || defined (__WIN32__)
++	WaitForSingleObject(fddAlive,INFINITE);
++    ok=fddlink->fddAlive&fddlink->tiAlive;
++	ReleaseSemaphore(fddAlive,1,NULL);
++#else
++    sem_wait(fddAlive);
++    ok=fddlink->fddAlive&fddlink->tiAlive;
++    sem_post(fddAlive);
++#endif
++    return ok;
++}
++
++void cleanUp() {
++    int i;
++    if(!ipc) { return; }
++    ipc=0;
++    connected=0;
++
++#if defined (__MINGW32__) || defined (_WIN32) || defined (_WIN32_) || defined (__WIN32__)
++
++	WaitForSingleObject(fddAlive,INFINITE);
++    fddlink->tiAlive=0;
++    i=fddlink->fddAlive;
++	ReleaseSemaphore(fddAlive,1,NULL);
++
++//    semResetAll();
++    CloseHandle(fddAlive);
++    CloseHandle(ti2fddF);
++    CloseHandle(ti2fddE);
++    CloseHandle(fdd2tiF);
++    CloseHandle(fdd2tiE);
++
++    UnmapViewOfFile(fddlink);
++    if(!i) {
++		CloseHandle(shm);
++		CloseHandle(shmf);
++    }
++
++#else
++
++    sem_wait(fddAlive);
++    fddlink->tiAlive=0;
++    i=fddlink->fddAlive;
++    sem_post(fddAlive);
++
++//    semResetAll();
++    sem_close(fddAlive);
++    sem_close(ti2fddF);
++    sem_close(ti2fddE);
++    sem_close(fdd2tiF);
++    sem_close(fdd2tiE);
++
++    munmap(fddlink,sizeof(fdd2TiLink));
++    if(!i) {
++        sem_unlink(fdd2tiE_Id);
++        sem_unlink(fdd2tiF_Id);
++        sem_unlink(ti2fddE_Id);
++        sem_unlink(ti2fddF_Id);
++        sem_unlink(fddAlive_Id);
++        shm_unlink(shmId);
++    }
++
++#endif
++
++}
++
++int openShm() {
++    int trunc;
++    if(!ipc) {
++#if defined (__MINGW32__) || defined (_WIN32) || defined (_WIN32_) || defined (__WIN32__)
++		//shmfile=ev.value("TMP",ev.value("TEMP","."))+"\\fdd.data";
++
++		 //  Gets the temp path env string (no guarantee it's a valid path).
++		dwRetVal = GetTempPath(MAX_PATH, lpTempPathBuffer); // buffer for path 
++		if (dwRetVal > MAX_PATH || (dwRetVal == 0))
++		{
++//			fprintf(stderr,"tim397_openShm: GetTempPath failed\n");
++			return (-1);
++		}
++		snprintf(szTempFileName,MAX_PATH,"%s%s",lpTempPathBuffer,shmId);		
++
++		shmf = CreateFile(szTempFileName, GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);		
++
++		if (shmf == INVALID_HANDLE_VALUE) 
++		{ 
++			//ui_error( UI_ERROR_ERROR, "tim397_openShm: CreateFile failed\n");
++			return (-1);
++		} 
++
++		shm = CreateFileMapping(
++					shmf,//INVALID_HANDLE_VALUE,    // use paging file
++					NULL,                    // default security
++					PAGE_READWRITE,          // read/write access
++					0,                       // maximum object size (high-order DWORD)
++					256,                     // maximum object size (low-order DWORD)
++					NULL);//TEXT("Global\\shmFdd"));                  // name of mapping object
++		if(shm==NULL){
++			//ui_error( UI_ERROR_ERROR, "tim397_openShm: CreateFileMapping failed\n");
++			CloseHandle(shmf);
++			return (-1);
++		}
++        //fddlink=(fdd2TiLink*)mmap(0,sizeof(fdd2TiLink),PROT_READ|PROT_WRITE,MAP_SHARED,shm,0);
++		fddlink = (fdd2TiLink*)MapViewOfFile(shm,   // handle to map object
++					FILE_MAP_ALL_ACCESS, // read/write permission
++					0,
++					0,
++					sizeof(fdd2TiLink));
++		if(fddlink==NULL){
++			//ui_error( UI_ERROR_ERROR, "tim397_openShm: MapViewOfFile (mmap) failed\n");
++			CloseHandle(shm);
++			CloseHandle(shmf);
++			return (-1);
++		}
++
++		fdd2tiE=OpenSemaphore(SEMAPHORE_MODIFY_STATE|SYNCHRONIZE, TRUE, fdd2tiE_Id);
++		fdd2tiF=OpenSemaphore(SEMAPHORE_MODIFY_STATE|SYNCHRONIZE, TRUE, fdd2tiF_Id);
++		ti2fddE=OpenSemaphore(SEMAPHORE_MODIFY_STATE|SYNCHRONIZE, TRUE, ti2fddE_Id);
++		ti2fddF=OpenSemaphore(SEMAPHORE_MODIFY_STATE|SYNCHRONIZE, TRUE, ti2fddF_Id);
++		fddAlive=OpenSemaphore(SEMAPHORE_MODIFY_STATE|SYNCHRONIZE, TRUE, fddAlive_Id);
++
++		if ((fdd2tiE==NULL) || (fdd2tiF==NULL) || 
++			(ti2fddE==NULL) || (ti2fddF==NULL) || (fddAlive==NULL)) {
++			//ui_error( UI_ERROR_ERROR, "tim397_openShm: semaphore creation failed\n");
++			return (-1);
++		}
++
++#else
++        shm = shm_open(shmId, O_RDWR, 0666);
++        if (-1==shm) { 
++			//ui_error( UI_ERROR_ERROR, "tim397_openShm: shm_open failed\n");
++			return (-1);
++		}
++        trunc=ftruncate(shm,sizeof(fdd2TiLink));
++        if (-1==trunc) { 
++			//ui_error( UI_ERROR_ERROR, "tim397_openShm: ftruncate failed\n");
++			return (-1);
++		}
++        fddlink=(fdd2TiLink*)mmap(0,sizeof(fdd2TiLink),PROT_READ|PROT_WRITE,MAP_SHARED,shm,0);
++        if(fddlink==MAP_FAILED) {
++			//ui_error( UI_ERROR_ERROR, "tim397_openShm: mmap failed\n");
++			return (-1);
++		}
++        close(shm);
++
++        fdd2tiE=sem_open(fdd2tiE_Id,O_RDWR,0666,1);
++        fdd2tiF=sem_open(fdd2tiF_Id,O_RDWR,0666,0);
++        ti2fddE=sem_open(ti2fddE_Id,O_RDWR,0666,1);
++        ti2fddF=sem_open(ti2fddF_Id,O_RDWR,0666,0);
++        fddAlive=sem_open(fddAlive_Id,O_RDWR,0666,1);
++		if ((fdd2tiE==SEM_FAILED) || (fdd2tiF==SEM_FAILED) || 
++			(ti2fddE==SEM_FAILED) || (ti2fddF==SEM_FAILED) || (fddAlive==SEM_FAILED)) {
++			//ui_error( UI_ERROR_ERROR, "tim397_openShm: semaphore creation failed\n");
++			return (-1);
++		}
++#endif
++		
++        ipc=1;
++    }
++    if(ipc&&(!connected)) {
++#if defined (__MINGW32__) || defined (_WIN32) || defined (_WIN32_) || defined (__WIN32__)
++		WaitForSingleObject(fddAlive,INFINITE);
++        if(fddlink->fddAlive){ fddlink->tiAlive=1; connected=1; }
++		ReleaseSemaphore(fddAlive,1,NULL);
++#else
++        sem_wait(fddAlive);
++        if(fddlink->fddAlive){ fddlink->tiAlive=1; connected=1; }
++        sem_post(fddAlive);
++#endif
++    }
++	return (0);
++}
++
++
++
++/*************************************************************************/
++
++libspectrum_byte tim397_io_read( libspectrum_word port, int *attached ) { 
++    libspectrum_byte b = 0;
++//ui_error( UI_ERROR_ERROR, "Reading from port: %u\n",port);
++    if(ipc&&connected) {
++//ui_error( UI_ERROR_ERROR, "Reading from port: %u\n",port);
++        if(fddIsAlive()) { b=fddRead(); } else  { connected=0; /*semResetAll();*/ return 0; }
++        *attached = 1;
++    }
++    return b;
++}
++
++void tim397_io_write( libspectrum_word port, libspectrum_byte b ) {
++//ui_error( UI_ERROR_ERROR, "Writing %u to port: %u\n",b,port);
++    if(ipc&&connected) { 
++//ui_error( UI_ERROR_ERROR, "Writing %u to port: %u\n",b,port);
++//		if ((port&&0xff) == 0xef)
++	if(fddIsAlive()) { fddWrite(b); } else  { connected=0; /*semResetAll();*/ }
++    }
++}
++
++/*************************************************************************/
++
++static void tim397_reset( int hard_reset );
++static void tim397_memory_map( void );
++static void tim397_enabled_snapshot( libspectrum_snap *snap );
++static void tim397_from_snapshot( libspectrum_snap *snap );
++static void tim397_to_snapshot( libspectrum_snap *snap );
++static void tim397_activate( void );
++
++
++/* Two 8Kb memory chunks accessible by the Z80 when /ROMCS is low */
++static memory_page tim397_memory_map_romcs_rom[ MEMORY_PAGES_IN_8K ];
++static memory_page tim397_memory_map_romcs_ram[ MEMORY_PAGES_IN_8K ];
++static int tim397_memory_source;
++
++int tim397_available = 0;
++int tim397_active = 0;
++
++static libspectrum_byte *tim397_ram;
++static int memory_allocated = 0;
++
++static module_info_t tim397_module_info = {
++  tim397_reset,
++  tim397_memory_map,
++  tim397_enabled_snapshot,
++  tim397_from_snapshot,
++  tim397_to_snapshot
++};
++
++void
++tim397_page( void )
++{
++	tim397_active = 1;
++	machine_current->ram.romcs = 1;
++	machine_current->memory_map();
++	//ui_error( UI_ERROR_ERROR, "tim397_page, PC: $%x\n",m397_pageflag);
++	ui_statusbar_update( UI_STATUSBAR_ITEM_DISK, UI_STATUSBAR_STATE_ACTIVE );
++}
++
++void
++tim397_unpage( void )
++{
++	tim397_active = 0;
++	machine_current->ram.romcs = 0;
++	machine_current->memory_map();
++	//ui_error( UI_ERROR_ERROR, "tim397_unpage, PC: $%x\n",z80.pc.w);
++	ui_statusbar_update( UI_STATUSBAR_ITEM_DISK, UI_STATUSBAR_STATE_INACTIVE );
++}
++
++static void
++tim397_memory_map( void )
++{
++  if( !tim397_active ) return;
++  memory_map_romcs_8k( 0x0000, tim397_memory_map_romcs_rom );
++  memory_map_romcs_8k( 0x2000, tim397_memory_map_romcs_ram );
++//  ui_error( UI_ERROR_ERROR, "tim397_memory_map, PC: $%x\n",z80.pc.w);
++}
++
++static const periph_port_t tim397_ports[] = {
++  { 0x00ff, 0x00ef, tim397_io_read, tim397_io_write },
++  { 0, 0, NULL, NULL }
++};
++
++static const periph_t tim397_periph = {
++  &settings_current.ti_m397,
++  tim397_ports,
++  1,
++  tim397_activate
++};
++
++int
++tim397_init( void )
++{
++  int i;
++  module_register( &tim397_module_info );
++
++  tim397_memory_source = memory_source_register( "TI_M397" );
++
++  for( i = 0; i < MEMORY_PAGES_IN_8K; i++ )
++    tim397_memory_map_romcs_rom[ i ].source = tim397_memory_source;
++  for( i = 0; i < MEMORY_PAGES_IN_8K; i++ )
++    tim397_memory_map_romcs_ram[ i ].source = tim397_memory_source;
++
++  periph_register( PERIPH_TYPE_TIM397, &tim397_periph );
++  ipc=0;
++
++  fprintf(stderr,"tim397_init\n");
++
++  return 0;
++}
++
++
++static void
++tim397_reset( int hard_reset )
++{
++
++  tim397_active = 0;
++  tim397_available = 0;
++  int i;
++
++  if( !periph_is_active( PERIPH_TYPE_TIM397 ) ) {
++    ui_statusbar_update( UI_STATUSBAR_ITEM_DISK,
++                         UI_STATUSBAR_STATE_NOT_AVAILABLE );
++    return;
++  }
++
++  if (openShm()!=0) {
++    settings_current.ti_m397 = 0;
++    periph_activate_type( PERIPH_TYPE_TIM397, 0 );
++//    ui_error( UI_ERROR_ERROR, "Link to FDD3000 emulator failed\n");
++    return;
++  }
++
++  if( machine_load_rom_bank( tim397_memory_map_romcs_rom, 0,
++                             settings_current.rom_tim397,
++                             settings_default.rom_tim397, 0x2000 ) ) {
++    settings_current.ti_m397 = 0;
++    periph_activate_type( PERIPH_TYPE_TIM397, 0 );
++    ui_statusbar_update( UI_STATUSBAR_ITEM_DISK,
++                         UI_STATUSBAR_STATE_NOT_AVAILABLE );
++    return;
++  }
++  
++  machine_current->ram.romcs = 0;
++  
++  for( i = 0; i < MEMORY_PAGES_IN_8K; i++ ) {
++	tim397_memory_map_romcs_ram[ i ].page = &tim397_ram[ i * MEMORY_PAGE_SIZE ];
++	tim397_memory_map_romcs_ram[ i ].writable = 1;
++  }
++
++  tim397_available = 1;
++  tim397_active = 0;
++
++  if( hard_reset ) {
++	memset( tim397_ram, 0, 0x2000 );
++  }
++ 
++  machine_current->memory_map();
++  ui_statusbar_update( UI_STATUSBAR_ITEM_DISK, UI_STATUSBAR_STATE_INACTIVE );
++  fprintf(stderr,"tim397_reset\n");
++}
++
++void
++tim397_end( void )
++{
++    tim397_available = 0;
++
++    if(ipc&&connected) {
++#if defined (__MINGW32__) || defined (_WIN32) || defined (_WIN32_) || defined (__WIN32__)
++	WaitForSingleObject(fddAlive,INFINITE);
++	fddlink->tiAlive=0;
++	ReleaseSemaphore(fddAlive,1,NULL);
++#else
++    sem_wait(fddAlive);
++	fddlink->tiAlive=0;
++    sem_post(fddAlive);
++#endif
++    }
++    ipc=0;
++    connected=0;
++    cleanUp();
++    fprintf(stderr,"tim397_end\n");
++}
++
++static void
++tim397_activate( void )
++{
++  if( !memory_allocated ) {
++    tim397_ram = memory_pool_allocate_persistent( 0x2000, 1 );
++    memory_allocated = 1;
++  }
++}
++
++int
++tim397_unittest( void )
++{
++  int r = 0;
++
++  tim397_page();
++
++  r += unittests_assert_16k_page( 0x0000, tim397_memory_source, 0 );
++  r += unittests_assert_16k_ram_page( 0x4000, 5 );
++  r += unittests_assert_16k_ram_page( 0x8000, 2 );
++  r += unittests_assert_16k_ram_page( 0xc000, 0 );
++
++  tim397_unpage();
++
++  r += unittests_paging_test_48( 2 );
++
++  return r;
++}
++
++
++static void
++tim397_enabled_snapshot( libspectrum_snap *snap )
++{
++  return;
++}
++
++static void
++tim397_from_snapshot( libspectrum_snap *snap )
++{
++  return;
++}
++
++static void
++tim397_to_snapshot( libspectrum_snap *snap GCC_UNUSED )
++{
++  //if( !periph_is_active( PERIPH_TYPE_TIM397 ) ) return;
++  return;
++}
++
+diff -Naru fuse-1.1.1/peripherals/disk/ti_m397.h fuse-1.1.1.fdd3000/peripherals/disk/ti_m397.h
+--- fuse-1.1.1/peripherals/disk/ti_m397.h	1970-01-01 01:00:00.000000000 +0100
++++ fuse-1.1.1.fdd3000/peripherals/disk/ti_m397.h	2014-02-14 08:31:43.972546695 +0100
+@@ -0,0 +1,28 @@
++/*
++    TIM397.h: Routines for handling the Timex TIM397 
++*/
++
++#ifndef FUSE_TIM397_H
++#define FUSE_TIM397_H
++
++#include <config.h>
++
++#include <libspectrum.h>
++
++#include "fdd.h"
++
++extern int tim397_available;  /* Is the tim397 available for use? */
++extern int tim397_active;     /* tim397 enabled? */
++
++int tim397_init( void );
++void tim397_end( void );
++
++void tim397_page( void );
++void tim397_unpage( void );
++
++libspectrum_byte tim397_io_read( libspectrum_word port, int *attached );
++void tim397_io_write( libspectrum_word port, libspectrum_byte b );
++
++int tim397_unittest( void );
++
++#endif                  /* #ifndef FUSE_tim397_H */
+diff -Naru fuse-1.1.1/periph.h fuse-1.1.1.fdd3000/periph.h
+--- fuse-1.1.1/periph.h	2013-05-24 22:42:22.000000000 +0200
++++ fuse-1.1.1.fdd3000/periph.h	2014-02-14 08:21:36.769616238 +0100
+@@ -65,6 +65,7 @@
+   PERIPH_TYPE_SPECCYBOOT,     /* SpeccyBoot interface */
+   PERIPH_TYPE_SPECDRUM,       /* SpecDrum interface */
+   PERIPH_TYPE_SPECTRANET,     /* Spectranet interface */
++  PERIPH_TYPE_TIM397,         /* FDD3000 disk interface */
+   PERIPH_TYPE_ULA,            /* Standard ULA */
+   PERIPH_TYPE_ULA_FULL_DECODE,/* Standard ULA responding only to 0xfe */
+   PERIPH_TYPE_UPD765,         /* +3 uPD765 FDC */
+diff -Naru fuse-1.1.1/settings.dat fuse-1.1.1.fdd3000/settings.dat
+--- fuse-1.1.1/settings.dat	2013-05-16 22:26:23.000000000 +0200
++++ fuse-1.1.1.fdd3000/settings.dat	2014-02-14 08:27:14.978179040 +0100
+@@ -64,6 +64,7 @@
+ interface2, boolean, 1
+ snapsasz80, null, 0
+ opus, boolean, 0
++ti_m397, boolean, 0
+ pal_tv2x, boolean, 0
+ movie_compr, string, NULL
+ movie_start, string, NULL
+@@ -235,6 +236,7 @@
+ rom_plusd, string, "plusd.rom",
+ rom_disciple, string, "disciple.rom",
+ rom_opus, string, "opus.rom",
++rom_tim397, string, "ti_m397.rom",
+ rom_speccyboot, string, "speccyboot-1.4.rom",
+ 
+ drive_plus3a_type, string, NULL
+diff -Naru fuse-1.1.1/settings.pl fuse-1.1.1.fdd3000/settings.pl
+--- fuse-1.1.1/settings.pl	2013-05-24 22:42:22.000000000 +0200
++++ fuse-1.1.1.fdd3000/settings.pl	2014-02-14 08:25:30.881179995 +0100
+@@ -762,7 +762,8 @@
+   case 42: return &( settings->rom_plusd );
+   case 43: return &( settings->rom_disciple );
+   case 44: return &( settings->rom_opus );
+-  case 45: return &( settings->rom_speccyboot );
++  case 45: return &( settings->rom_tim397 );
++  case 46: return &( settings->rom_speccyboot );
+   default: return NULL;
+   }
+ }
+diff -Naru fuse-1.1.1/ui/options.dat fuse-1.1.1.fdd3000/ui/options.dat
+--- fuse-1.1.1/ui/options.dat	2013-05-24 22:42:22.000000000 +0200
++++ fuse-1.1.1.fdd3000/ui/options.dat	2014-02-14 08:21:36.769616238 +0100
+@@ -64,6 +64,7 @@
+ Checkbox, (B)eta 128 interface, beta128, INPUT_KEY_b
+ Checkbox, Beta 128 (a)uto-boot in 48K machines, beta128_48boot, INPUT_KEY_a
+ Checkbox, (O)pus Discovery interface, opus, INPUT_KEY_o
++Checkbox, FDD(3)000 / M397 interface, ti_m397, INPUT_KEY_3
+ Postcheck, periph_postcheck
+ Posthook, periph_posthook
+ 
+diff -Naru fuse-1.1.1/ui/ui.h fuse-1.1.1.fdd3000/ui/ui.h
+--- fuse-1.1.1/ui/ui.h	2013-05-16 22:26:23.000000000 +0200
++++ fuse-1.1.1.fdd3000/ui/ui.h	2014-02-14 08:21:36.769616238 +0100
+@@ -39,6 +39,7 @@
+ #include "peripherals/disk/beta.h"
+ #include "peripherals/disk/disciple.h"
+ #include "peripherals/disk/opus.h"
++#include "peripherals/disk/ti_m397.h"
+ #include "peripherals/disk/plusd.h"
+ #include "ui/scaler/scaler.h"
+ 
+@@ -211,6 +212,7 @@
+   UI_MENU_ITEM_MEDIA_DISK_OPUS_2_EJECT,
+   UI_MENU_ITEM_MEDIA_DISK_OPUS_2_FLIP_SET,
+   UI_MENU_ITEM_MEDIA_DISK_OPUS_2_WP_SET,
++  UI_MENU_ITEM_MEDIA_DISK_TIM397,
+   UI_MENU_ITEM_MEDIA_IDE,
+   UI_MENU_ITEM_MEDIA_IDE_SIMPLE8BIT,
+   UI_MENU_ITEM_MEDIA_IDE_SIMPLE8BIT_MASTER_EJECT,
+diff -Naru fuse-1.1.1/ui.c fuse-1.1.1.fdd3000/ui.c
+--- fuse-1.1.1/ui.c	2013-05-16 22:26:23.000000000 +0200
++++ fuse-1.1.1.fdd3000/ui.c	2014-02-14 08:51:58.576646341 +0100
+@@ -548,6 +549,8 @@
+     "/Media/Disk/Opus/Drive 2/Write protect/Enable",
+     "/Media/Disk/Opus/Drive 2/Write protect/Disable", 1 },
+ 
++  { UI_MENU_ITEM_MEDIA_DISK_TIM397, "/Media/Disk/Timex M397" },
++
+   { UI_MENU_ITEM_MEDIA_IDE, "/Media/IDE" },
+ 
+   { UI_MENU_ITEM_MEDIA_IDE_SIMPLE8BIT, "/Media/IDE/Simple 8-bit" },
+diff -Naru fuse-1.1.1/z80/coretest.c fuse-1.1.1.fdd3000/z80/coretest.c
+--- fuse-1.1.1/z80/coretest.c	2013-05-16 22:26:16.000000000 +0200
++++ fuse-1.1.1.fdd3000/z80/coretest.c	2014-02-14 08:21:36.769616238 +0100
+@@ -459,6 +459,21 @@
+   abort();
+ }
+ 
++int tim397_available = 0;
++int tim397_active = 0;
++
++void
++tim397_page( void )
++{
++  abort();
++}
++
++void
++tim397_unpage( void )
++{
++  abort();
++}
++
+ int plusd_available = 0;
+ int plusd_active = 0;
+ 
+diff -Naru fuse-1.1.1/z80/z80_checks.h fuse-1.1.1.fdd3000/z80/z80_checks.h
+--- fuse-1.1.1/z80/z80_checks.h	2013-05-16 22:26:16.000000000 +0200
++++ fuse-1.1.1.fdd3000/z80/z80_checks.h	2014-02-14 08:23:42.063410052 +0100
+@@ -2,6 +2,7 @@
+ SETUP_CHECK( rzx, rzx_playback )
+ SETUP_CHECK( debugger, debugger_mode != DEBUGGER_MODE_INACTIVE )
+ SETUP_CHECK( beta, beta_available )
++SETUP_CHECK( tim397, tim397_available )
+ SETUP_CHECK( plusd, plusd_available )
+ SETUP_CHECK( disciple, disciple_available )
+ SETUP_CHECK( if1p, if1_available )
+diff -Naru fuse-1.1.1/z80/z80_ops.c fuse-1.1.1.fdd3000/z80/z80_ops.c
+--- fuse-1.1.1/z80/z80_ops.c	2013-05-16 22:26:16.000000000 +0200
++++ fuse-1.1.1.fdd3000/z80/z80_ops.c	2014-02-14 08:23:33.485342586 +0100
+@@ -36,6 +36,7 @@
+ #include "peripherals/disk/disciple.h"
+ #include "peripherals/disk/opus.h"
+ #include "peripherals/disk/plusd.h"
++#include "peripherals/disk/ti_m397.h"
+ #include "peripherals/ide/divide.h"
+ #include "peripherals/if1.h"
+ #include "peripherals/spectranet.h"
+@@ -176,6 +177,18 @@
+     }
+ 
+     END_CHECK
++
++    CHECK( tim397, tim397_available )
++
++    if( tim397_active ) {
++      if( PC == 0x0604 ) {
++        tim397_unpage();
++      }
++    } else if( PC == 0x0000 || PC == 0x0008 ) {
++      tim397_page();
++    }
++
++    END_CHECK
+ 
+     CHECK( plusd, plusd_available )
+ 
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/fuse.git/commitdiff/87c5873ce787da75018ac31176baad102ead0717



More information about the pld-cvs-commit mailing list