fuse-for-macosx-commits Mailing List for Fuse for macOS (Page 18)
Brought to you by:
fredm
You can subscribe to this list here.
| 2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(9) |
Dec
(31) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2007 |
Jan
(24) |
Feb
(11) |
Mar
(6) |
Apr
(48) |
May
(9) |
Jun
(38) |
Jul
(33) |
Aug
(15) |
Sep
|
Oct
(3) |
Nov
(6) |
Dec
(3) |
| 2008 |
Jan
|
Feb
(24) |
Mar
(11) |
Apr
(22) |
May
(7) |
Jun
|
Jul
|
Aug
|
Sep
(2) |
Oct
(3) |
Nov
(18) |
Dec
(23) |
| 2009 |
Jan
(16) |
Feb
(1) |
Mar
(1) |
Apr
|
May
|
Jun
(7) |
Jul
(4) |
Aug
(11) |
Sep
(9) |
Oct
|
Nov
(3) |
Dec
(2) |
| 2010 |
Jan
(1) |
Feb
|
Mar
(1) |
Apr
(2) |
May
(8) |
Jun
|
Jul
|
Aug
(2) |
Sep
(2) |
Oct
(9) |
Nov
|
Dec
(8) |
| 2011 |
Jan
|
Feb
|
Mar
|
Apr
(7) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(5) |
Nov
(2) |
Dec
|
| 2012 |
Jan
(4) |
Feb
(5) |
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
(10) |
Nov
(13) |
Dec
(11) |
| 2013 |
Jan
(4) |
Feb
(1) |
Mar
(8) |
Apr
(8) |
May
(16) |
Jun
(5) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(4) |
| 2014 |
Jan
|
Feb
(6) |
Mar
(2) |
Apr
(1) |
May
|
Jun
|
Jul
(1) |
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
(6) |
| 2015 |
Jan
|
Feb
|
Mar
(2) |
Apr
|
May
|
Jun
(5) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2016 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
(10) |
Jun
(9) |
Jul
(6) |
Aug
(5) |
Sep
(3) |
Oct
(6) |
Nov
(5) |
Dec
|
|
From: <fr...@us...> - 2007-07-01 02:41:09
|
Revision: 412
http://svn.sourceforge.net/fuse-for-macosx/?rev=412&view=rev
Author: fredm
Date: 2007-06-30 19:41:10 -0700 (Sat, 30 Jun 2007)
Log Message:
-----------
Load . into vendor/libdsk/current.
Modified Paths:
--------------
vendor/libdsk/current/ChangeLog
vendor/libdsk/current/configure
vendor/libdsk/current/configure.in
vendor/libdsk/current/doc/libdsk.lyx
vendor/libdsk/current/doc/libdsk.pdf
vendor/libdsk/current/doc/libdsk.txt
vendor/libdsk/current/include/libdsk.h
vendor/libdsk/current/lib/compsq.c
vendor/libdsk/current/lib/drvcpcem.c
vendor/libdsk/current/lib/drvcpcem.h
vendor/libdsk/current/lib/drvntwdm.c
vendor/libdsk/current/man/apriboot.1
vendor/libdsk/current/man/dskdump.1
vendor/libdsk/current/man/dskform.1
vendor/libdsk/current/man/dskid.1
vendor/libdsk/current/man/dskscan.1
vendor/libdsk/current/man/dsktrans.1
vendor/libdsk/current/man/dskutil.1
vendor/libdsk/current/man/md3serial.1
Modified: vendor/libdsk/current/ChangeLog
===================================================================
--- vendor/libdsk/current/ChangeLog 2007-07-01 02:20:49 UTC (rev 411)
+++ vendor/libdsk/current/ChangeLog 2007-07-01 02:41:10 UTC (rev 412)
@@ -1,3 +1,25 @@
+2006-11-18 John Elliott
+
+ * libdsk-1.1.11 released.
+
+2006-08-02 John Elliott
+
+ * cpcemu driver: Bug fix when a sector is not found and it has
+ to start searching again at the beginning of the track.
+
+2006-07-23 John Elliott
+
+ * libdsk-1.1.11 released.
+
+2006-07-02 Ramlaid <www.ramlaid.com>
+
+ * cpcemu driver: Modified so that the dsk_trkids() function more
+ accurately reflects the result from a real disk. Also exposed the
+ ST0-ST3 registers.
+ * SQ compression: Doesn't leak file handles if file not compressed.
+ * NTWDM driver: Uses the passed sector size in dsk_xread / dsk_xwrite
+ rather than the sector size in the geometry structure.
+
2006-04-18 John Elliott
* libdsk-1.1.10 released.
Modified: vendor/libdsk/current/configure
===================================================================
--- vendor/libdsk/current/configure 2007-07-01 02:20:49 UTC (rev 411)
+++ vendor/libdsk/current/configure 2007-07-01 02:41:10 UTC (rev 412)
@@ -814,8 +814,8 @@
NONENONEs,x,x, &&
program_prefix=${target_alias}-
-VERSION=1.1.10
-UPDATED='April 18, 2006'
+VERSION=1.1.12
+UPDATED='November 18, 2006'
am__api_version="1.4"
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
Modified: vendor/libdsk/current/configure.in
===================================================================
--- vendor/libdsk/current/configure.in 2007-07-01 02:20:49 UTC (rev 411)
+++ vendor/libdsk/current/configure.in 2007-07-01 02:41:10 UTC (rev 412)
@@ -2,8 +2,8 @@
AC_INIT(lib/dskopen.c)
AC_CONFIG_AUX_DIR(config)
AC_CANONICAL_SYSTEM
-VERSION=1.1.10
-UPDATED='April 18, 2006'
+VERSION=1.1.12
+UPDATED='November 18, 2006'
AM_INIT_AUTOMAKE(libdsk, $VERSION)
AM_CONFIG_HEADER(config.h)
Modified: vendor/libdsk/current/doc/libdsk.lyx
===================================================================
--- vendor/libdsk/current/doc/libdsk.lyx 2007-07-01 02:20:49 UTC (rev 411)
+++ vendor/libdsk/current/doc/libdsk.lyx 2007-07-01 02:41:10 UTC (rev 412)
@@ -26,7 +26,7 @@
\layout Title
-LibDsk v1.1.10
+LibDsk v1.1.12
\layout Author
John Elliott
@@ -136,6 +136,10 @@
For full details, see the file ChangeLog.
\layout Itemize
+Changes by Ramlaid <www.ramlaid.com> to the DSK and NTWDM drivers to improve
+ compatibility, and another fix to stop file handles leaking.
+\layout Itemize
+
Added a new driver:
\begin_inset Quotes eld
\end_inset
Modified: vendor/libdsk/current/doc/libdsk.pdf
===================================================================
(Binary files differ)
Modified: vendor/libdsk/current/doc/libdsk.txt
===================================================================
--- vendor/libdsk/current/doc/libdsk.txt 2007-07-01 02:20:49 UTC (rev 411)
+++ vendor/libdsk/current/doc/libdsk.txt 2007-07-01 02:41:10 UTC (rev 412)
@@ -1,4 +1,4 @@
-LibDsk v1.1.10
+LibDsk v1.1.12
John Elliott
@@ -198,6 +198,10 @@
For full details, see the file ChangeLog.
+ Changes by Ramlaid <www.ramlaid.com> to the DSK and
+ NTWDM drivers to improve compatibility, and another
+ fix to stop file handles leaking.
+
Added a new driver: "int25". This allows the DOS version
to run on Apricot PCs (which do not have an
IBM-compatible BIOS) and to access hard drive partitions.
Modified: vendor/libdsk/current/include/libdsk.h
===================================================================
--- vendor/libdsk/current/include/libdsk.h 2007-07-01 02:20:49 UTC (rev 411)
+++ vendor/libdsk/current/include/libdsk.h 2007-07-01 02:41:10 UTC (rev 412)
@@ -58,7 +58,7 @@
extern "C" {
#endif
-#define LIBDSK_VERSION "1.1.10"
+#define LIBDSK_VERSION "1.1.12"
/************************* TYPES ********************************/
Modified: vendor/libdsk/current/lib/compsq.c
===================================================================
--- vendor/libdsk/current/lib/compsq.c 2007-07-01 02:20:49 UTC (rev 411)
+++ vendor/libdsk/current/lib/compsq.c 2007-07-01 02:41:10 UTC (rev 412)
@@ -1,682 +1,686 @@
-/***************************************************************************
- * *
- * LIBDSK: General floppy and diskimage access library *
- * Copyright (C) 2002 John Elliott <jc...@se...> *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU Library General Public *
- * License as published by the Free Software Foundation; either *
- * version 2 of the License, or (at your option) any later version. *
- * *
- * This library 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 *
- * Library General Public License for more details. *
- * *
- * You should have received a copy of the GNU Library General Public *
- * License along with this library; if not, write to the Free *
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, *
- * MA 02111-1307, USA *
- * *
- ***************************************************************************/
-
-/* Squeeze (Huffman) compression/decompression. This is entirely new code,
- * created by John Elliott to avoid possible licensing problems with the
- * Richard Greenlaw/Theo Pozzy code used in earlier releases.
- *
- * In brief: Richard Greenlaw's original code had no licence with it at all.
- * However, a file dated 1983 on the CP/M CDROM suggests that he
- * intended it as not-for-profit rather than true PD.
- *
- * Theo Pozzy's UNIX port of SQ (1985) implies that the code he used
- * is truly PD. But his belief that SQ was public domain may not
- * be correct in the light of the 1983 letter above.
- *
- * My thanks to Russell Marks for pointing this out.
- *
- * Note that my code is less sophisticated than Richard Greenlaw's original.
- * It doesn't, for example, try to deal with pathologically unbalanced
- * encoding trees (where a source byte encodes to more than 16 bits).
- *
- */
-
-#include "compi.h"
-#include "compsq.h"
-
-
-/******************************* compsq.c **********************************/
-typedef dsk_err_t (*RLEFUNC)(SQ_COMPRESS_DATA *self, int ch);
-
-
-
-/************************ RLE COMPRESSION FUNCTIONS ************************/
-static void rle_reset(SQ_COMPRESS_DATA *self)
-{
- self->rle_char = -1;
- self->rle_run = 0;
-}
-
-
-
-
-static dsk_err_t rle_flush(SQ_COMPRESS_DATA *self, RLEFUNC writer)
-{
- dsk_err_t err = DSK_ERR_OK;
-/* We encode sequences of >3 bytes using RLE. However, the RLE trigger byte
- * itself (0x90) is encoded as 2 bytes, and we can't encode sequences of it; it
- * would encode to (eg) 20 90 90 xx, and then decompress as (20 90 90) xx
- * when it was compressed as 20 (90 90 xx).
- */
- if ( self->rle_run > 3 && self->rle_char != RLECODE)
- {
- err = (*writer)(self, self->rle_char);
- if (!err) err = (*writer)(self, RLECODE);
- if (!err) err = (*writer)(self, self->rle_run);
- }
- else while (self->rle_run)
- {
- if (!err) err = (*writer)(self, self->rle_char);
- if (self->rle_char == RLECODE && !err) err = (*writer)(self, 0x00);
- --self->rle_run;
- }
- self->rle_run = 0;
- return err;
-}
-
-
-
-/* Generate an RLE stream from a file */
-static dsk_err_t rle_stream(SQ_COMPRESS_DATA *self, RLEFUNC writer)
-{
- int c;
- dsk_err_t err;
-
- while ( (c = fgetc(self->fp_in)) != EOF )
- {
- self->ck_sum += (unsigned char)c;
-/* If this character is the same as the last, increase the count. */
- if (c == self->rle_char)
- {
- ++self->rle_run;
- if (self->rle_run == 0xFF) /* Max length of run */
- { /* flush & start again */
- err = rle_flush(self, writer);
- if (err) return err;
- self->rle_char = -1;
- self->rle_run = 0;
- }
- }
- else
- {
-/* If not, write out what we've got and start again. */
- err = rle_flush(self, writer);
- if (err) return err;
- self->rle_char = c;
- self->rle_run = 1;
- }
- }
- if (ferror(self->fp_in)) return DSK_ERR_SYSERR;
-/* Write out what we've got; then EOF. */
- err = rle_flush(self, writer);
- if (err) return err;
- self->rle_char = SQ_EOF;
- self->rle_run = 1;
- err = rle_flush(self, writer);
- if (err) return err;
- rewind(self->fp_in);
- return DSK_ERR_OK;
-}
-
-
-/*
-static dsk_err_t rle_print(SQ_COMPRESS_DATA *self, int ch)
-{
- if (ch == '\r' || ch == '\n' || (ch > 0x1F && ch < 0x7F))
- fputc(ch, self->fp_out);
- else fprintf(self->fp_out, "<%02x>", ch);
- return DSK_ERR_OK;
-} */
-/******************* RLE COMPRESSION FUNCTIONS: END ************************/
-
-static dsk_err_t huf_counter(SQ_COMPRESS_DATA *self, int ch)
-{
- if (ch >= 0 && ch <= SQ_EOF) ++self->huf_count[ch + MAXNODE];
- else return DSK_ERR_COMPRESS;
-
- return DSK_ERR_OK;
-}
-
-/* Find the index of the smallest nonzero character count in huf_count.
- */
-static int huf_smallest(SQ_COMPRESS_DATA *self, int skip)
-{
- unsigned long mv = ~0UL;
- int n, mi = -1;
-
- for (n = 0; n < MAXLEAF + MAXNODE; n++)
- {
- if (n == skip) continue;
- if (self->huf_count[n] < mv && self->huf_count[n] > 0)
- {
- mv = self->huf_count[n];
- mi = n;
- }
- }
- return mi;
-}
-
-
-/* Add a node. */
-static void huf_addnode(SQ_COMPRESS_DATA *self, int n1, int n2)
-{
- short e_n1, e_n2;
-
- //printf("%04X:%04X\r\n", n1, n2);
-
- if (n1 < MAXNODE) e_n1 = n1; else e_n1 = MAXNODE - 1 - n1;
- if (n2 < MAXNODE) e_n2 = n2; else e_n2 = MAXNODE - 1 - n2;
-
- /* If parent not set, parent is MAXNODE */
- self->huf_node[self->huf_curnode].parent = MAXNODE;
- self->huf_node[self->huf_curnode].left = e_n1;
- self->huf_node[self->huf_curnode].right = e_n2;
-
-/* If nodes hold leaves, record them. If they hold other nodes, set parents. */
- if (n1 >= MAXNODE) self->huf_leaves[n1 - MAXNODE] = self->huf_curnode;
- else self->huf_node[n1].parent = self->huf_curnode;
- if (n2 >= MAXNODE) self->huf_leaves[n2 - MAXNODE] = self->huf_curnode;
- else self->huf_node[n2].parent = self->huf_curnode;
-
-}
-
-
-
-/* Generate the Huffman dictionary for a file */
-static dsk_err_t analyze(SQ_COMPRESS_DATA *self)
-{
- int n, n1, n2;
- dsk_err_t err;
-
- /* Initialise counters */
- self->ck_sum = 0;
- for (n = 0; n < MAXNODE + MAXLEAF; n++) self->huf_count[n] = 0;
- rle_reset(self);
- err = rle_stream(self, huf_counter);
- if (err) return err;
-
- /* Start allocating nodes from the end. That way, the root node,
- * the last to be populated, will have the lowest number. */
- self->huf_curnode = MAXNODE - 1;
- self->huf_nodecount = 0;
- for (n = 0; n < MAXNODE + MAXLEAF; n++) if (self->huf_count[n])
- ++self->huf_nodecount;
-
- /* Special case if there's only one node (empty file) */
- if (self->huf_nodecount == 1)
- {
- n1 = huf_smallest(self, -1);
- huf_addnode(self, n1, n1);
- self->huf_nodecount = 0;
- --self->huf_curnode;
- }
-
- /* huf_nodecount = number of leaves */
- while (self->huf_nodecount > 1)
- {
- n1 = huf_smallest(self, -1);
- n2 = huf_smallest(self, n1);
- /* We have n1 and n2: Two nodes to be combined */
- huf_addnode(self, n1, n2);
-
- self->huf_count[self->huf_curnode] =
- self->huf_count[n1] + self->huf_count[n2];
- self->huf_count[n1] = 0;
- self->huf_count[n2] = 0;
- --self->huf_curnode;
- --self->huf_nodecount;
- }
- /* self->huf_curnode is now the node before the root node */
- return DSK_ERR_OK;
-}
-
-static dsk_err_t writec(SQ_COMPRESS_DATA *self, unsigned char c)
-{
- if (fputc(c, self->fp_out) == EOF) return DSK_ERR_SYSERR;
-
- return DSK_ERR_OK;
-}
-
-
-static dsk_err_t writes(SQ_COMPRESS_DATA *self, unsigned short s)
-{
- dsk_err_t e;
-
- e = writec(self, (unsigned char)(s & 0xFF)); if (e) return e;
- e = writec(self, (unsigned char)((s >> 8) & 0xFF)); if (e) return e;
- return DSK_ERR_OK;
-}
-
-static unsigned char st_masks[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
-
-static dsk_err_t flipbits(SQ_COMPRESS_DATA *self)
-{
- int n, bit;
-
- for (n = self->huf_nbits - 1; n >= 0; n--)
- {
- bit = (self->huf_bits[n / 8] & st_masks[n % 8]);
-
- if (bit) self->huf_out |= st_masks[self->huf_nout];
- ++self->huf_nout;
- if (self->huf_nout == 8)
- {
- if (fputc(self->huf_out, self->fp_out) == EOF)
- return DSK_ERR_SYSERR;
- self->huf_nout = 0;
- self->huf_out = 0;
- }
- }
- return DSK_ERR_OK;
-}
-
-
-/* Add a bit to the output bitstream */
-static void pushbit(SQ_COMPRESS_DATA *self, int bit)
-{
- int offs = self->huf_nbits / 8;
- unsigned char mask = st_masks[self->huf_nbits % 8];
-
- if (offs >= sizeof(self->huf_bits)) return;
-
- if (bit) self->huf_bits[offs] |= mask;
- else self->huf_bits[offs] &= ~mask;
- ++self->huf_nbits;
-}
-
-
-static dsk_err_t huf_encode(SQ_COMPRESS_DATA *self, int ch)
-{
- unsigned short nodepos;
- signed short child;
-
- if (ch < 0 || ch > SQ_EOF) return DSK_ERR_COMPRESS;
- /* Now find where this character ended up in the tree */
- nodepos = self->huf_leaves[ch];
- self->huf_nbits = 0;
-
- child = (-1 - ch);
-
- do
- {
- if (self->huf_node[nodepos].left == child) pushbit(self, 0);
- else if (self->huf_node[nodepos].right == child) pushbit(self, 1);
- else return DSK_ERR_COMPRESS;
-
- child = nodepos;
- nodepos = self->huf_node[nodepos].parent;
- }
- while (nodepos < MAXNODE);
- /* self->huf_bits holds the output bitstream (in reverse order).
- * Now write it out to disc */
- return flipbits(self);
-}
-
-
-
-static dsk_err_t compress(SQ_COMPRESS_DATA *self)
-{
- char *s = self->sq_truename;
- dsk_err_t e;
- unsigned short dictbase;
- unsigned short dictlen;
- unsigned short dn;
-
- e = writes(self, MAGIC); if (e) return e; /* Magic */
- e = writes(self, self->ck_sum);
- if (e) return e; /* Source file checksum */
- do /* Filename */
- {
- e = writec(self, *s); if (e) return e;
- } while ( *(s++) );
-
- dictbase = self->huf_curnode + 1;
- /* Dictionary length = MAXNODE - dictbase */
- dictlen = MAXNODE - dictbase;
- e = writes(self, dictlen); if (e) return e;
- for (dn = dictbase; dn < MAXNODE; dn++)
- {
- short l = self->huf_node[dn].left;
- short r = self->huf_node[dn].right;
-
- if (l >= 0) l -= dictbase;
- if (r >= 0) r -= dictbase;
-
- e = writes(self, l);
- e = writes(self, r);
- }
- /* Dictionary written. Start spitting bytes. */
- self->huf_nout = 0;
- self->huf_out = 0;
- rle_reset(self);
- e = rle_stream(self, huf_encode); if (e) return e;
-
- /* Write any pending bits */
- if (self->huf_nout)
- {
- if (fputc(self->huf_out, self->fp_out) == EOF)
- return DSK_ERR_SYSERR;
- }
- fseek(self->fp_out, 2, SEEK_SET);
-
- return DSK_ERR_OK;
-}
-
-/* DEBUG CODE ONLY
-static dsk_err_t putter(SQ_COMPRESS_DATA *self, int ch)
-{
- if (fputc(ch, self->fp_out) == EOF) return DSK_ERR_SYSERR;
- return DSK_ERR_OK;
-} */
-
-static dsk_err_t squeeze(SQ_COMPRESS_DATA *self)
-{
- dsk_err_t err;
-
- err = analyze(self);
- if (err) return err;
- err = compress(self);
-
- return DSK_ERR_OK;
-}
-
-
-static dsk_err_t readc(SQ_COMPRESS_DATA *self, unsigned char *c)
-{
- int i;
-
- i = fgetc(self->fp_in);
- if (i == EOF) return DSK_ERR_SYSERR;
- *c = i;
- return DSK_ERR_OK;
-}
-
-
-static dsk_err_t readu(SQ_COMPRESS_DATA *self, unsigned short *u)
-{
- unsigned char c1, c2;
- dsk_err_t err;
-
- err = readc(self, &c1); if (err) return err;
- err = readc(self, &c2); if (err) return err;
-
- *u = ((c2 << 8) | c1);
- return DSK_ERR_OK;
-}
-
-
-
-static dsk_err_t reads(SQ_COMPRESS_DATA *self, signed short *s)
-{
- unsigned char c1, c2;
- dsk_err_t err;
-
- err = readc(self, &c1); if (err) return err;
- err = readc(self, &c2); if (err) return err;
-
- *s = ((c2 << 8) | c1);
- return DSK_ERR_OK;
-}
-
-static dsk_err_t ckputc(SQ_COMPRESS_DATA *self, unsigned char b)
-{
- if (fputc(b, self->fp_out) == EOF) return DSK_ERR_SYSERR;
- self->ck_sum += b;
- return DSK_ERR_OK;
-}
-
-static dsk_err_t wrbyte(SQ_COMPRESS_DATA *self, unsigned char b)
-{
- int n;
- dsk_err_t e;
-
- if (self->rle_run == 1)
- {
- /* Last byte was 0x90. The one before that is self->rle_char */
- if (b == 0)
- {
- /* xx 90 00 becomes xx 90 */
- if (self->rle_char != -1)
- {
- e = ckputc(self, (unsigned char)(self->rle_char)); if (e) return e;
- }
- e = ckputc(self, RLECODE); if (e) return e;
- }
- else
- {
- if (self->rle_char == -1) return DSK_ERR_SYSERR;
- for (n = 0; n < b; n++)
- {
- e = ckputc(self, (unsigned char)(self->rle_char)); if (e) return e;
- }
- }
- self->rle_run = 0;
- self->rle_char = -1;
- return DSK_ERR_OK;
- }
-
- if (b == RLECODE)
- {
- /* Retain rle_char */
- self->rle_run = 1;
- return DSK_ERR_OK;
- }
- /* No special characters */
- if (self->rle_char != -1)
- {
- e = ckputc(self, (unsigned char)(self->rle_char)); if (e) return e;
- }
- self->rle_char = b;
-
- return DSK_ERR_OK;
-}
-
-
-
-static dsk_err_t unsqueeze(SQ_COMPRESS_DATA *self)
-{
- dsk_err_t err;
- unsigned short magic, checksum;
- unsigned char c;
- unsigned short dictlen;
- unsigned short nd;
- unsigned short node;
- signed short code;
-
- self->ck_sum = 0;
- err = readu(self, &magic);
- if (err) return err;
- if (magic != MAGIC) return DSK_ERR_COMPRESS;
- err = readu(self, &checksum);
- /* Filename (skip) */
- do
- {
- err = readc(self, &c);
- if (err) return err;
- } while (c);
- /* Dictionary length */
- err = readu(self, &dictlen);
- if (err) return err;
- if (dictlen > MAXNODE) return DSK_ERR_COMPRESS;
- /* Dictionary */
- for (nd = 0; nd < dictlen; nd++)
- {
- err = reads(self, &self->huf_node[nd].left);
- if (err) return err;
- err = reads(self, &self->huf_node[nd].right);
- if (err) return err;
- }
- /* Now start decoding data */
- self->huf_out = 0;
- self->huf_nout = 8;
- node = 0;
- rle_reset(self);
-/* if dictlen == 0, the file is empty */
- if (dictlen) while (1)
- {
- if (self->huf_nout == 8)
- {
- self->huf_nout = 0;
- err = readc(self, &self->huf_out);
- if (err) return err;
- }
- code = self->huf_out & st_masks[self->huf_nout];
- ++self->huf_nout;
- if (code) code = self->huf_node[node].right;
- else code = self->huf_node[node].left;
-
- if (code < 0)
- {
- if (-1 - code == SQ_EOF) break; /* Reached EOF */
- err = wrbyte(self, (unsigned char)(-1 - code));
- if (err) return err;
- node = 0;
- }
- else node = code;
- }
- if (self->rle_char != -1)
- {
- err = ckputc(self, (unsigned char)(self->rle_char)); if (err) return err;
-
- }
- if (checksum != self->ck_sum) return DSK_ERR_COMPRESS;
- return DSK_ERR_OK;
-}
-
-
-/* This struct contains function pointers to the driver's functions, and the
- * size of its DSK_DRIVER subclass */
-
-COMPRESS_CLASS cc_sq =
-{
- sizeof(SQ_COMPRESS_DATA),
- "sq",
- "Squeeze (Huffman coding)",
- sq_open, /* open */
- sq_creat, /* create new */
- sq_commit, /* commit */
- sq_abort /* abort */
-};
-
-
-
-dsk_err_t sq_open(COMPRESS_DATA *self)
-{
- SQ_COMPRESS_DATA *sq_self;
- dsk_err_t err;
- unsigned short magic;
-
-
- /* Sanity check: Is this meant for our driver? */
- if (self->cd_class != &cc_sq) return DSK_ERR_BADPTR;
- sq_self = (SQ_COMPRESS_DATA *)self;
- sq_self->sq_truename = NULL;
- sq_self->fp_in = NULL;
- sq_self->fp_out = NULL;
-
- /* Open the file to decompress */
- err = comp_fopen(self, &sq_self->fp_in);
- if (err) return DSK_ERR_NOTME;
-
- /* Check for SQ signature */
- err = readu(sq_self, &magic);
- if (err) return err;
-
- if (magic != MAGIC)
- {
- fclose(sq_self->fp_in);
- return DSK_ERR_NOTME;
- }
- /* OK. This is a Squeezed file. Decompress it. */
- rewind(sq_self->fp_in);
- err = comp_mktemp(self, &sq_self->fp_out);
-
- if (!err) err = unsqueeze(sq_self);
- fclose(sq_self->fp_in);
- if (sq_self->fp_out) fclose(sq_self->fp_out);
- if (err && sq_self->sq_truename) free(sq_self->sq_truename);
- return err;
-}
-
-
-dsk_err_t sq_commit(COMPRESS_DATA *self)
-{
- SQ_COMPRESS_DATA *sq_self;
- dsk_err_t err = DSK_ERR_OK;
-
- if (self->cd_class != &cc_sq) return DSK_ERR_BADPTR;
- sq_self = (SQ_COMPRESS_DATA *)self;
-
- sq_self->fp_in = NULL;
- sq_self->fp_out = NULL;
- if (self->cd_cfilename && self->cd_ufilename)
- {
- sq_self->fp_in = fopen(self->cd_ufilename, "rb");
- sq_self->fp_out = fopen(self->cd_cfilename, "wb");
- if (!sq_self->fp_in || !sq_self->fp_out) err = DSK_ERR_SYSERR;
- else err = squeeze(sq_self);
- }
- if (sq_self->fp_in) fclose(sq_self->fp_in);
- if (sq_self->fp_out) fclose(sq_self->fp_out);
- if (sq_self->sq_truename) free(sq_self->sq_truename);
- sq_self->sq_truename = NULL;
-
- return err;
-}
-
-
-/* abort: Free truename */
-dsk_err_t sq_abort(COMPRESS_DATA *self)
-{
- SQ_COMPRESS_DATA *sq_self;
- if (self->cd_class != &cc_sq) return DSK_ERR_BADPTR;
- sq_self = (SQ_COMPRESS_DATA *)self;
-
- if (sq_self->sq_truename) free(sq_self->sq_truename);
- sq_self->sq_truename = NULL;
- return DSK_ERR_OK;
-}
-
-/* Create: Set up truename */
-dsk_err_t sq_creat(COMPRESS_DATA *self)
-{
- char *ss;
- SQ_COMPRESS_DATA *sq_self;
- if (self->cd_class != &cc_sq) return DSK_ERR_BADPTR;
- sq_self = (SQ_COMPRESS_DATA *)self;
-
- if (sq_self->sq_truename) free(sq_self->sq_truename);
- sq_self->sq_truename = NULL;
-
-/* Try to guess the true name of the file from the compressed name. This
- * can only be done for certain well-known name manglings. */
- sq_self->sq_truename = malloc(1 + strlen(self->cd_cfilename));
- if (!sq_self->sq_truename) return DSK_ERR_NOMEM;
-
- /* UNIX SQ squeezes files by appending ".SQ" */
- strcpy(sq_self->sq_truename, self->cd_cfilename);
- ss = strstr(sq_self->sq_truename, ".SQ");
- if (ss) *ss = 0;
-
- /* Convert .DQK back to .DSK */
- ss = strstr(sq_self->sq_truename, ".DQK");
- if (ss) memcpy(ss, ".DSK", 4);
-
- /* Convert .DQK back to .DSK */
- ss = strstr(sq_self->sq_truename, ".dqk");
- if (ss) memcpy(ss, ".dsk", 4);
-
- return DSK_ERR_OK;
-}
-
-
-
+/***************************************************************************
+ * *
+ * LIBDSK: General floppy and diskimage access library *
+ * Copyright (C) 2002 John Elliott <jc...@se...> *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Library General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2 of the License, or (at your option) any later version. *
+ * *
+ * This library 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 *
+ * Library General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Library General Public *
+ * License along with this library; if not, write to the Free *
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, *
+ * MA 02111-1307, USA *
+ * *
+ ***************************************************************************/
+
+/* Squeeze (Huffman) compression/decompression. This is entirely new code,
+ * created by John Elliott to avoid possible licensing problems with the
+ * Richard Greenlaw/Theo Pozzy code used in earlier releases.
+ *
+ * In brief: Richard Greenlaw's original code had no licence with it at all.
+ * However, a file dated 1983 on the CP/M CDROM suggests that he
+ * intended it as not-for-profit rather than true PD.
+ *
+ * Theo Pozzy's UNIX port of SQ (1985) implies that the code he used
+ * is truly PD. But his belief that SQ was public domain may not
+ * be correct in the light of the 1983 letter above.
+ *
+ * My thanks to Russell Marks for pointing this out.
+ *
+ * Note that my code is less sophisticated than Richard Greenlaw's original.
+ * It doesn't, for example, try to deal with pathologically unbalanced
+ * encoding trees (where a source byte encodes to more than 16 bits).
+ *
+ */
+
+#include "compi.h"
+#include "compsq.h"
+
+
+/******************************* compsq.c **********************************/
+typedef dsk_err_t (*RLEFUNC)(SQ_COMPRESS_DATA *self, int ch);
+
+
+
+/************************ RLE COMPRESSION FUNCTIONS ************************/
+static void rle_reset(SQ_COMPRESS_DATA *self)
+{
+ self->rle_char = -1;
+ self->rle_run = 0;
+}
+
+
+
+
+static dsk_err_t rle_flush(SQ_COMPRESS_DATA *self, RLEFUNC writer)
+{
+ dsk_err_t err = DSK_ERR_OK;
+/* We encode sequences of >3 bytes using RLE. However, the RLE trigger byte
+ * itself (0x90) is encoded as 2 bytes, and we can't encode sequences of it; it
+ * would encode to (eg) 20 90 90 xx, and then decompress as (20 90 90) xx
+ * when it was compressed as 20 (90 90 xx).
+ */
+ if ( self->rle_run > 3 && self->rle_char != RLECODE)
+ {
+ err = (*writer)(self, self->rle_char);
+ if (!err) err = (*writer)(self, RLECODE);
+ if (!err) err = (*writer)(self, self->rle_run);
+ }
+ else while (self->rle_run)
+ {
+ if (!err) err = (*writer)(self, self->rle_char);
+ if (self->rle_char == RLECODE && !err) err = (*writer)(self, 0x00);
+ --self->rle_run;
+ }
+ self->rle_run = 0;
+ return err;
+}
+
+
+
+/* Generate an RLE stream from a file */
+static dsk_err_t rle_stream(SQ_COMPRESS_DATA *self, RLEFUNC writer)
+{
+ int c;
+ dsk_err_t err;
+
+ while ( (c = fgetc(self->fp_in)) != EOF )
+ {
+ self->ck_sum += (unsigned char)c;
+/* If this character is the same as the last, increase the count. */
+ if (c == self->rle_char)
+ {
+ ++self->rle_run;
+ if (self->rle_run == 0xFF) /* Max length of run */
+ { /* flush & start again */
+ err = rle_flush(self, writer);
+ if (err) return err;
+ self->rle_char = -1;
+ self->rle_run = 0;
+ }
+ }
+ else
+ {
+/* If not, write out what we've got and start again. */
+ err = rle_flush(self, writer);
+ if (err) return err;
+ self->rle_char = c;
+ self->rle_run = 1;
+ }
+ }
+ if (ferror(self->fp_in)) return DSK_ERR_SYSERR;
+/* Write out what we've got; then EOF. */
+ err = rle_flush(self, writer);
+ if (err) return err;
+ self->rle_char = SQ_EOF;
+ self->rle_run = 1;
+ err = rle_flush(self, writer);
+ if (err) return err;
+ rewind(self->fp_in);
+ return DSK_ERR_OK;
+}
+
+
+/*
+static dsk_err_t rle_print(SQ_COMPRESS_DATA *self, int ch)
+{
+ if (ch == '\r' || ch == '\n' || (ch > 0x1F && ch < 0x7F))
+ fputc(ch, self->fp_out);
+ else fprintf(self->fp_out, "<%02x>", ch);
+ return DSK_ERR_OK;
+} */
+/******************* RLE COMPRESSION FUNCTIONS: END ************************/
+
+static dsk_err_t huf_counter(SQ_COMPRESS_DATA *self, int ch)
+{
+ if (ch >= 0 && ch <= SQ_EOF) ++self->huf_count[ch + MAXNODE];
+ else return DSK_ERR_COMPRESS;
+
+ return DSK_ERR_OK;
+}
+
+/* Find the index of the smallest nonzero character count in huf_count.
+ */
+static int huf_smallest(SQ_COMPRESS_DATA *self, int skip)
+{
+ unsigned long mv = ~0UL;
+ int n, mi = -1;
+
+ for (n = 0; n < MAXLEAF + MAXNODE; n++)
+ {
+ if (n == skip) continue;
+ if (self->huf_count[n] < mv && self->huf_count[n] > 0)
+ {
+ mv = self->huf_count[n];
+ mi = n;
+ }
+ }
+ return mi;
+}
+
+
+/* Add a node. */
+static void huf_addnode(SQ_COMPRESS_DATA *self, int n1, int n2)
+{
+ short e_n1, e_n2;
+
+ //printf("%04X:%04X\r\n", n1, n2);
+
+ if (n1 < MAXNODE) e_n1 = n1; else e_n1 = MAXNODE - 1 - n1;
+ if (n2 < MAXNODE) e_n2 = n2; else e_n2 = MAXNODE - 1 - n2;
+
+ /* If parent not set, parent is MAXNODE */
+ self->huf_node[self->huf_curnode].parent = MAXNODE;
+ self->huf_node[self->huf_curnode].left = e_n1;
+ self->huf_node[self->huf_curnode].right = e_n2;
+
+/* If nodes hold leaves, record them. If they hold other nodes, set parents. */
+ if (n1 >= MAXNODE) self->huf_leaves[n1 - MAXNODE] = self->huf_curnode;
+ else self->huf_node[n1].parent = self->huf_curnode;
+ if (n2 >= MAXNODE) self->huf_leaves[n2 - MAXNODE] = self->huf_curnode;
+ else self->huf_node[n2].parent = self->huf_curnode;
+
+}
+
+
+
+/* Generate the Huffman dictionary for a file */
+static dsk_err_t analyze(SQ_COMPRESS_DATA *self)
+{
+ int n, n1, n2;
+ dsk_err_t err;
+
+ /* Initialise counters */
+ self->ck_sum = 0;
+ for (n = 0; n < MAXNODE + MAXLEAF; n++) self->huf_count[n] = 0;
+ rle_reset(self);
+ err = rle_stream(self, huf_counter);
+ if (err) return err;
+
+ /* Start allocating nodes from the end. That way, the root node,
+ * the last to be populated, will have the lowest number. */
+ self->huf_curnode = MAXNODE - 1;
+ self->huf_nodecount = 0;
+ for (n = 0; n < MAXNODE + MAXLEAF; n++) if (self->huf_count[n])
+ ++self->huf_nodecount;
+
+ /* Special case if there's only one node (empty file) */
+ if (self->huf_nodecount == 1)
+ {
+ n1 = huf_smallest(self, -1);
+ huf_addnode(self, n1, n1);
+ self->huf_nodecount = 0;
+ --self->huf_curnode;
+ }
+
+ /* huf_nodecount = number of leaves */
+ while (self->huf_nodecount > 1)
+ {
+ n1 = huf_smallest(self, -1);
+ n2 = huf_smallest(self, n1);
+ /* We have n1 and n2: Two nodes to be combined */
+ huf_addnode(self, n1, n2);
+
+ self->huf_count[self->huf_curnode] =
+ self->huf_count[n1] + self->huf_count[n2];
+ self->huf_count[n1] = 0;
+ self->huf_count[n2] = 0;
+ --self->huf_curnode;
+ --self->huf_nodecount;
+ }
+ /* self->huf_curnode is now the node before the root node */
+ return DSK_ERR_OK;
+}
+
+static dsk_err_t writec(SQ_COMPRESS_DATA *self, unsigned char c)
+{
+ if (fputc(c, self->fp_out) == EOF) return DSK_ERR_SYSERR;
+
+ return DSK_ERR_OK;
+}
+
+
+static dsk_err_t writes(SQ_COMPRESS_DATA *self, unsigned short s)
+{
+ dsk_err_t e;
+
+ e = writec(self, (unsigned char)(s & 0xFF)); if (e) return e;
+ e = writec(self, (unsigned char)((s >> 8) & 0xFF)); if (e) return e;
+ return DSK_ERR_OK;
+}
+
+static unsigned char st_masks[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
+
+static dsk_err_t flipbits(SQ_COMPRESS_DATA *self)
+{
+ int n, bit;
+
+ for (n = self->huf_nbits - 1; n >= 0; n--)
+ {
+ bit = (self->huf_bits[n / 8] & st_masks[n % 8]);
+
+ if (bit) self->huf_out |= st_masks[self->huf_nout];
+ ++self->huf_nout;
+ if (self->huf_nout == 8)
+ {
+ if (fputc(self->huf_out, self->fp_out) == EOF)
+ return DSK_ERR_SYSERR;
+ self->huf_nout = 0;
+ self->huf_out = 0;
+ }
+ }
+ return DSK_ERR_OK;
+}
+
+
+/* Add a bit to the output bitstream */
+static void pushbit(SQ_COMPRESS_DATA *self, int bit)
+{
+ int offs = self->huf_nbits / 8;
+ unsigned char mask = st_masks[self->huf_nbits % 8];
+
+ if (offs >= sizeof(self->huf_bits)) return;
+
+ if (bit) self->huf_bits[offs] |= mask;
+ else self->huf_bits[offs] &= ~mask;
+ ++self->huf_nbits;
+}
+
+
+static dsk_err_t huf_encode(SQ_COMPRESS_DATA *self, int ch)
+{
+ unsigned short nodepos;
+ signed short child;
+
+ if (ch < 0 || ch > SQ_EOF) return DSK_ERR_COMPRESS;
+ /* Now find where this character ended up in the tree */
+ nodepos = self->huf_leaves[ch];
+ self->huf_nbits = 0;
+
+ child = (-1 - ch);
+
+ do
+ {
+ if (self->huf_node[nodepos].left == child) pushbit(self, 0);
+ else if (self->huf_node[nodepos].right == child) pushbit(self, 1);
+ else return DSK_ERR_COMPRESS;
+
+ child = nodepos;
+ nodepos = self->huf_node[nodepos].parent;
+ }
+ while (nodepos < MAXNODE);
+ /* self->huf_bits holds the output bitstream (in reverse order).
+ * Now write it out to disc */
+ return flipbits(self);
+}
+
+
+
+static dsk_err_t compress(SQ_COMPRESS_DATA *self)
+{
+ char *s = self->sq_truename;
+ dsk_err_t e;
+ unsigned short dictbase;
+ unsigned short dictlen;
+ unsigned short dn;
+
+ e = writes(self, MAGIC); if (e) return e; /* Magic */
+ e = writes(self, self->ck_sum);
+ if (e) return e; /* Source file checksum */
+ do /* Filename */
+ {
+ e = writec(self, *s); if (e) return e;
+ } while ( *(s++) );
+
+ dictbase = self->huf_curnode + 1;
+ /* Dictionary length = MAXNODE - dictbase */
+ dictlen = MAXNODE - dictbase;
+ e = writes(self, dictlen); if (e) return e;
+ for (dn = dictbase; dn < MAXNODE; dn++)
+ {
+ short l = self->huf_node[dn].left;
+ short r = self->huf_node[dn].right;
+
+ if (l >= 0) l -= dictbase;
+ if (r >= 0) r -= dictbase;
+
+ e = writes(self, l);
+ e = writes(self, r);
+ }
+ /* Dictionary written. Start spitting bytes. */
+ self->huf_nout = 0;
+ self->huf_out = 0;
+ rle_reset(self);
+ e = rle_stream(self, huf_encode); if (e) return e;
+
+ /* Write any pending bits */
+ if (self->huf_nout)
+ {
+ if (fputc(self->huf_out, self->fp_out) == EOF)
+ return DSK_ERR_SYSERR;
+ }
+ fseek(self->fp_out, 2, SEEK_SET);
+
+ return DSK_ERR_OK;
+}
+
+/* DEBUG CODE ONLY
+static dsk_err_t putter(SQ_COMPRESS_DATA *self, int ch)
+{
+ if (fputc(ch, self->fp_out) == EOF) return DSK_ERR_SYSERR;
+ return DSK_ERR_OK;
+} */
+
+static dsk_err_t squeeze(SQ_COMPRESS_DATA *self)
+{
+ dsk_err_t err;
+
+ err = analyze(self);
+ if (err) return err;
+ err = compress(self);
+
+ return DSK_ERR_OK;
+}
+
+
+static dsk_err_t readc(SQ_COMPRESS_DATA *self, unsigned char *c)
+{
+ int i;
+
+ i = fgetc(self->fp_in);
+ if (i == EOF) return DSK_ERR_SYSERR;
+ *c = i;
+ return DSK_ERR_OK;
+}
+
+
+static dsk_err_t readu(SQ_COMPRESS_DATA *self, unsigned short *u)
+{
+ unsigned char c1, c2;
+ dsk_err_t err;
+
+ err = readc(self, &c1); if (err) return err;
+ err = readc(self, &c2); if (err) return err;
+
+ *u = ((c2 << 8) | c1);
+ return DSK_ERR_OK;
+}
+
+
+
+static dsk_err_t reads(SQ_COMPRESS_DATA *self, signed short *s)
+{
+ unsigned char c1, c2;
+ dsk_err_t err;
+
+ err = readc(self, &c1); if (err) return err;
+ err = readc(self, &c2); if (err) return err;
+
+ *s = ((c2 << 8) | c1);
+ return DSK_ERR_OK;
+}
+
+static dsk_err_t ckputc(SQ_COMPRESS_DATA *self, unsigned char b)
+{
+ if (fputc(b, self->fp_out) == EOF) return DSK_ERR_SYSERR;
+ self->ck_sum += b;
+ return DSK_ERR_OK;
+}
+
+static dsk_err_t wrbyte(SQ_COMPRESS_DATA *self, unsigned char b)
+{
+ int n;
+ dsk_err_t e;
+
+ if (self->rle_run == 1)
+ {
+ /* Last byte was 0x90. The one before that is self->rle_char */
+ if (b == 0)
+ {
+ /* xx 90 00 becomes xx 90 */
+ if (self->rle_char != -1)
+ {
+ e = ckputc(self, (unsigned char)(self->rle_char)); if (e) return e;
+ }
+ e = ckputc(self, RLECODE); if (e) return e;
+ }
+ else
+ {
+ if (self->rle_char == -1) return DSK_ERR_SYSERR;
+ for (n = 0; n < b; n++)
+ {
+ e = ckputc(self, (unsigned char)(self->rle_char)); if (e) return e;
+ }
+ }
+ self->rle_run = 0;
+ self->rle_char = -1;
+ return DSK_ERR_OK;
+ }
+
+ if (b == RLECODE)
+ {
+ /* Retain rle_char */
+ self->rle_run = 1;
+ return DSK_ERR_OK;
+ }
+ /* No special characters */
+ if (self->rle_char != -1)
+ {
+ e = ckputc(self, (unsigned char)(self->rle_char)); if (e) return e;
+ }
+ self->rle_char = b;
+
+ return DSK_ERR_OK;
+}
+
+
+
+static dsk_err_t unsqueeze(SQ_COMPRESS_DATA *self)
+{
+ dsk_err_t err;
+ unsigned short magic, checksum;
+ unsigned char c;
+ unsigned short dictlen;
+ unsigned short nd;
+ unsigned short node;
+ signed short code;
+
+ self->ck_sum = 0;
+ err = readu(self, &magic);
+ if (err) return err;
+ if (magic != MAGIC) return DSK_ERR_COMPRESS;
+ err = readu(self, &checksum);
+ /* Filename (skip) */
+ do
+ {
+ err = readc(self, &c);
+ if (err) return err;
+ } while (c);
+ /* Dictionary length */
+ err = readu(self, &dictlen);
+ if (err) return err;
+ if (dictlen > MAXNODE) return DSK_ERR_COMPRESS;
+ /* Dictionary */
+ for (nd = 0; nd < dictlen; nd++)
+ {
+ err = reads(self, &self->huf_node[nd].left);
+ if (err) return err;
+ err = reads(self, &self->huf_node[nd].right);
+ if (err) return err;
+ }
+ /* Now start decoding data */
+ self->huf_out = 0;
+ self->huf_nout = 8;
+ node = 0;
+ rle_reset(self);
+/* if dictlen == 0, the file is empty */
+ if (dictlen) while (1)
+ {
+ if (self->huf_nout == 8)
+ {
+ self->huf_nout = 0;
+ err = readc(self, &self->huf_out);
+ if (err) return err;
+ }
+ code = self->huf_out & st_masks[self->huf_nout];
+ ++self->huf_nout;
+ if (code) code = self->huf_node[node].right;
+ else code = self->huf_node[node].left;
+
+ if (code < 0)
+ {
+ if (-1 - code == SQ_EOF) break; /* Reached EOF */
+ err = wrbyte(self, (unsigned char)(-1 - code));
+ if (err) return err;
+ node = 0;
+ }
+ else node = code;
+ }
+ if (self->rle_char != -1)
+ {
+ err = ckputc(self, (unsigned char)(self->rle_char)); if (err) return err;
+
+ }
+ if (checksum != self->ck_sum) return DSK_ERR_COMPRESS;
+ return DSK_ERR_OK;
+}
+
+
+/* This struct contains function pointers to the driver's functions, and the
+ * size of its DSK_DRIVER subclass */
+
+COMPRESS_CLASS cc_sq =
+{
+ sizeof(SQ_COMPRESS_DATA),
+ "sq",
+ "Squeeze (Huffman coding)",
+ sq_open, /* open */
+ sq_creat, /* create new */
+ sq_commit, /* commit */
+ sq_abort /* abort */
+};
+
+
+
+dsk_err_t sq_open(COMPRESS_DATA *self)
+{
+ SQ_COMPRESS_DATA *sq_self;
+ dsk_err_t err;
+ unsigned short magic;
+
+
+ /* Sanity check: Is this meant for our driver? */
+ if (self->cd_class != &cc_sq) return DSK_ERR_BADPTR;
+ sq_self = (SQ_COMPRESS_DATA *)self;
+ sq_self->sq_truename = NULL;
+ sq_self->fp_in = NULL;
+ sq_self->fp_out = NULL;
+
+ /* Open the file to decompress */
+ err = comp_fopen(self, &sq_self->fp_in);
+ if (err) return DSK_ERR_NOTME;
+
+ /* Check for SQ signature */
+ err = readu(sq_self, &magic);
+ if (err) /* v1.1.11 Don't leak file handles */
+ {
+ fclose(sq_self->fp_in);
+ return err;
+ }
+
+ if (magic != MAGIC)
+ {
+ fclose(sq_self->fp_in);
+ return DSK_ERR_NOTME;
+ }
+ /* OK. This is a Squeezed file. Decompress it. */
+ rewind(sq_self->fp_in);
+ err = comp_mktemp(self, &sq_self->fp_out);
+
+ if (!err) err = unsqueeze(sq_self);
+ fclose(sq_self->fp_in);
+ if (sq_self->fp_out) fclose(sq_self->fp_out);
+ if (err && sq_self->sq_truename) free(sq_self->sq_truename);
+ return err;
+}
+
+
+dsk_err_t sq_commit(COMPRESS_DATA *self)
+{
+ SQ_COMPRESS_DATA *sq_self;
+ dsk_err_t err = DSK_ERR_OK;
+
+ if (self->cd_class != &cc_sq) return DSK_ERR_BADPTR;
+ sq_self = (SQ_COMPRESS_DATA *)self;
+
+ sq_self->fp_in = NULL;
+ sq_self->fp_out = NULL;
+ if (self->cd_cfilename && self->cd_ufilename)
+ {
+ sq_self->fp_in = fopen(self->cd_ufilename, "rb");
+ sq_self->fp_out = fopen(self->cd_cfilename, "wb");
+ if (!sq_self->fp_in || !sq_self->fp_out) err = DSK_ERR_SYSERR;
+ else err = squeeze(sq_self);
+ }
+ if (sq_self->fp_in) fclose(sq_self->fp_in);
+ if (sq_self->fp_out) fclose(sq_self->fp_out);
+ if (sq_self->sq_truename) free(sq_self->sq_truename);
+ sq_self->sq_truename = NULL;
+
+ return err;
+}
+
+
+/* abort: Free truename */
+dsk_err_t sq_abort(COMPRESS_DATA *self)
+{
+ SQ_COMPRESS_DATA *sq_self;
+ if (self->cd_class != &cc_sq) return DSK_ERR_BADPTR;
+ sq_self = (SQ_COMPRESS_DATA *)self;
+
+ if (sq_self->sq_truename) free(sq_self->sq_truename);
+ sq_self->sq_truename = NULL;
+ return DSK_ERR_OK;
+}
+
+/* Create: Set up truename */
+dsk_err_t sq_creat(COMPRESS_DATA *self)
+{
+ char *ss;
+ SQ_COMPRESS_DATA *sq_self;
+ if (self->cd_class != &cc_sq) return DSK_ERR_BADPTR;
+ sq_self = (SQ_COMPRESS_DATA *)self;
+
+ if (sq_self->sq_truename) free(sq_self->sq_truename);
+ sq_self->sq_truename = NULL;
+
+/* Try to guess the true name of the file from the compressed name. This
+ * can only be done for certain well-known name manglings. */
+ sq_self->sq_truename = malloc(1 + strlen(self->cd_cfilename));
+ if (!sq_self->sq_truename) return DSK_ERR_NOMEM;
+
+ /* UNIX SQ squeezes files by appending ".SQ" */
+ strcpy(sq_self->sq_truename, self->cd_cfilename);
+ ss = strstr(sq_self->sq_truename, ".SQ");
+ if (ss) *ss = 0;
+
+ /* Convert .DQK back to .DSK */
+ ss = strstr(sq_self->sq_truename, ".DQK");
+ if (ss) memcpy(ss, ".DSK", 4);
+
+ /* Convert .DQK back to .DSK */
+ ss = strstr(sq_self->sq_truename, ".dqk");
+ if (ss) memcpy(ss, ".dsk", 4);
+
+ return DSK_ERR_OK;
+}
+
+
+
Modified: vendor/libdsk/current/lib/drvcpcem.c
===================================================================
--- vendor/libdsk/current/lib/drvcpcem.c 2007-07-01 02:20:49 UTC (rev 411)
+++ vendor/libdsk/current/lib/drvcpcem.c 2007-07-01 02:41:10 UTC (rev 412)
@@ -1,935 +1,1126 @@
-/***************************************************************************
- * *
- * LIBDSK: General floppy and diskimage access library *
- * Copyright (C) 2001,2005 John Elliott <jc...@se...> *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU Library General Public *
- * License as published by the Free Software Foundation; either *
- * version 2 of the License, or (at your option) any later version. *
- * *
- * This library 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 *
- * Library General Public License for more details. *
- * *
- * You should have received a copy of the GNU Library General Public *
- * License along with this library; if not, write to the Free *
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, *
- * MA 02111-1307, USA *
- * *
- ***************************************************************************/
-
-/* Access functions for CPCEMU discs */
-
-#include "drvi.h"
-#include "drvcpcem.h"
-
-
-/* This struct contains function pointers to the driver's functions, and the
- * size of its DSK_DRIVER subclass */
-
-/* The CPCEMU drivers for normal and extended modes are in fact the same,
- * except for the "open" and "create" functions; these have been separated
- * simply so EDSKs can be created. */
-
-DRV_CLASS dc_cpcemu =
-{
- sizeof(CPCEMU_DSK_DRIVER),
- "dsk",
- "CPCEMU .DSK driver",
- cpcemu_open, /* open */
- cpcemu_creat, /* create new */
- cpcemu_close, /* close */
- cpcemu_read, /* read sector, working from physical address */
- cpcemu_write, /* write sector, working from physical address */
- cpcemu_format, /* format track, physical */
- NULL, /* get geometry */
- cpcemu_secid, /* logical sector ID */
- cpcemu_xseek, /* seek to track */
- cpcemu_status, /* get drive status */
- cpcemu_xread, /* read sector */
- cpcemu_xwrite, /* write sector */
-};
-
-DRV_CLASS dc_cpcext =
-{
- sizeof(CPCEMU_DSK_DRIVER),
- "edsk",
- "Extended .DSK driver",
- cpcext_open, /* open */
- cpcext_creat, /* create new */
- cpcemu_close, /* close */
- cpcemu_read, /* read sector, working from physical address */
- cpcemu_write, /* write sector, working from physical address */
- cpcemu_format, /* format track, physical */
- NULL, /* get geometry */
- cpcemu_secid, /* logical sector ID */
- cpcemu_xseek, /* seek to track */
- cpcemu_status, /* get drive status */
- cpcemu_xread, /* read sector */
- cpcemu_xwrite, /* write sector */
-};
-
-
-
-static dsk_err_t cpc_open(DSK_DRIVER *self, const char *filename, int ext);
-static dsk_err_t cpc_creat(DSK_DRIVER *self, const char *filename, int ext);
-
-
-dsk_err_t cpcemu_open(DSK_DRIVER *self, const char *filename)
-{
- return cpc_open(self, filename, 0);
-}
-
-dsk_err_t cpcext_open(DSK_DRIVER *self, const char *filename)
-{
- return cpc_open(self, filename, 1);
-}
-
-dsk_err_t cpcemu_creat(DSK_DRIVER *self, const char *filename)
-{
- return cpc_creat(self, filename, 0);
-}
-
-dsk_err_t cpcext_creat(DSK_DRIVER *self, const char *filename)
-{
- return cpc_creat(self, filename, 1);
-}
-
-
-#define DC_CHECK(self) if (self->dr_class != &dc_cpcemu && self->dr_class != &dc_cpcext) return DSK_ERR_BADPTR;
-
-
-/* Open DSK image, checking for the magic number */
-static dsk_err_t cpc_open(DSK_DRIVER *self, const char *filename, int extended)
-{
- CPCEMU_DSK_DRIVER *cpc_self;
- int n;
-
- /* Sanity check: Is this meant for our driver? */
- DC_CHECK(self)
- cpc_self = (CPCEMU_DSK_DRIVER *)self;
-
- cpc_self->cpc_fp = fopen(filename, "r+b");
- if (!cpc_self->cpc_fp)
- {
- cpc_self->cpc_readonly = 1;
- cpc_self->cpc_fp = fopen(filename, "rb");
- }
- if (!cpc_self->cpc_fp) return DSK_ERR_NOTME;
- /* Check for CPCEMU signature */
- if (fread(cpc_self->cpc_dskhead, 1, 256, cpc_self->cpc_fp) < 256)
- {
-/* 1.1.6 Don't leak file handles */
- fclose(cpc_self->cpc_fp);
- return DSK_ERR_NOTME;
- }
-
- if (extended)
- {
- if (memcmp("EXTENDED", cpc_self->cpc_dskhead, 8))
- {
-/* 1.1.6 Don't leak file handles */
- fclose(cpc_self->cpc_fp);
- return DSK_ERR_NOTME;
- }
- }
- else
- {
- if (memcmp("MV - CPC", cpc_self->cpc_dskhead, 8))
- {
-/* 1.1.6 Don't leak file handles */
- fclose(cpc_self->cpc_fp);
- return DSK_ERR_NOTME;
- }
- }
- /* OK, got signature. */
- cpc_self->cpc_trkhead[0] = 0;
- for (n = 0; n < 4; n++)
- {
- cpc_self->cpc_statusw[n] = -1;
- cpc_self->cpc_status[n] = 0;
- }
- return DSK_ERR_OK;
-}
-
-/* Create DSK image */
-static dsk_err_t cpc_creat(DSK_DRIVER *self, const char *filename, int extended)
-{
- CPCEMU_DSK_DRIVER *cpc_self;
- int n;
-
- /* Sanity check: Is this meant for our driver? */
- DC_CHECK(self)
- cpc_self = (CPCEMU_DSK_DRIVER *)self;
-
- cpc_self->cpc_fp = fopen(filename, "w+b");
- cpc_self->cpc_readonly = 0;
- if (!cpc_self->cpc_fp) return DSK_ERR_SYSERR;
- memset(cpc_self->cpc_dskhead, 0, 256);
-
- if (extended) strcpy((char *)cpc_self->cpc_dskhead,
- "EXTENDED CPC DSK File\r\nDisk-Info\r\n(LIBDSK)");
- else strcpy((char *)cpc_self->cpc_dskhead,
- "MV - CPCEMU Disk-File\r\nDisk-Info\r\n(LIBDSK)");
- if (fwrite(cpc_self->cpc_dskhead, 1 , 256, cpc_self->cpc_fp) < 256)
- return DSK_ERR_SYSERR;
- cpc_self->cpc_trkhead[0] = 0;
- for (n = 0; n < 4; n++)
- {
- cpc_self->cpc_statusw[n] = -1;
- cpc_self->cpc_status[n] = 0;
- }
- return DSK_ERR_OK;
-}
-
-
-dsk_err_t cpcemu_close(DSK_DRIVER *self)
-{
- CPCEMU_DSK_DRIVER *cpc_self;
-
- DC_CHECK(self)
- cpc_self = (CPCEMU_DSK_DRIVER *)self;
-
- if (cpc_self->cpc_fp)
- {
- if (fclose(cpc_self->cpc_fp) == EOF) return DSK_ERR_SYSERR;
- cpc_self->cpc_fp = NULL;
- }
- return DSK_ERR_OK;
-}
-
-
-
-
-
-
-/* Find the offset in a DSK for a particular cylinder/head.
- *
- * CPCEMU DSK files work in "tracks". For a single-sided disk, track number
- * is the same as cylinder number. For a double-sided disk, track number is
- * (2 * cylinder + head). This is independent of disc format.
- */
-static long lookup_track(CPCEMU_DSK_DRIVER *self, const DSK_GEOMETRY *geom,
- dsk_pcyl_t cylinder, dsk_phead_t head)
-{
- unsigned char *b;
- dsk_ltrack_t track;
- long trk_offset;
- unsigned int nt;
-
- if (!self->cpc_fp) return -1;
-
- /* [LIBDSK v0.6.0] Compare with our header, not the passed
- * geometry */
- /* Seek off the edge of the drive? Note that we allow one
- * extra cylinder & one extra head, so that we can move to
- * a blank track to format it. */
- if (cylinder > self->cpc_dskhead[0x30]) return -1;
- if (head > self->cpc_dskhead[0x31]) return -1;
-
- /* Convert cylinder & head to CPCEMU "track" */
-
- track = cylinder;
- if (self->cpc_dskhead[0x31] > 1) track *= 2;
- track += head;
-
- /* Look up the cylinder and head using the header. This behaves
- * differently in normal and extended DSK files */
-
- if (!memcmp(self->cpc_dskhead, "EXTENDED", 8))
- {
- trk_offset = 256; /* DSK header = 256 bytes */
- b = self->cpc_dskhead + 0x34;
- for (nt = 0; nt < track; nt++)
- {
- trk_offset += 256 * b[nt]; /* [v0.9.0] */
- }
- }
- else /* Normal; all tracks have the same length */
- {
- trk_offset = (self->cpc_dskhead[0x33] * 256);
- trk_offset += self->cpc_dskhead[0x32];
-
- trk_offset *= track; /* No. of tracks */
- trk_offset += 256; /* DSK header */
- }
- return trk_offset;
-}
-
-
-
-
-
-/* Seek to a cylinder. Checks if that particular cylinder exists.
- * We test for the existence of a cylinder by looking for Track <n>, Head 0.
- * Fortunately the DSK format does not allow for discs with different numbers
- * of tracks on each side (though this is obviously possible with a real disc)
- * so if head 0 exists then the whole cylinder does.
-
-
-static dsk_err_t seek_cylinder(CPCEMU_DSK_DRIVER *self, DSK_GEOMETRY *geom, int cylinder)
-{
- long nr;
- if (!self->cpc_fp) return DSK_ERR_NOTRDY;
-
- // Check if the DSK image goes out to the correct cylinder
- nr = lookup_track(self, geom, cylinder, 0);
-
- if (nr < 0) return DSK_ERR_SEEKFAIL;
- return DSK_ERR_OK;
-}
-*/
-
-/* Load the "Track-Info" header for the given cylinder and head */
-static dsk_err_t load_track_header(CPCEMU_DSK_DRIVER *self,
- const DSK_GEOMETRY *geom, int cylinder, int head)
-{
- long track;
- int sector_size;
- unsigned char rate, recording;
-
- track = lookup_track(self, geom, cylinder, head);
- if (track < 0) return DSK_ERR_SEEKFAIL; /* Bad track */
- fseek(self->cpc_fp, track, SEEK_SET);
- if (fread(self->cpc_trkhead, 1, 256, self->cpc_fp) < 256)
- return DSK_ERR_NOADDR; /* Missing address mark */
- if (memcmp(self->cpc_trkhead, "Track-Info", 10))
- {
- return DSK_ERR_NOADDR;
- }
- /* Check if the track density and recording mode match the density
- * and recording mode in the geometry. */
- sector_size = 128 << self->cpc_trkhead[0x14];
-
- rate = self->cpc_trkhead[0x12];
- recording = self->cpc_trkhead[0x13];
-
- /* Guess the data rate used. We assume Double Density, and then
- * look at the number of sectors in the track to see if the
- * format looks like a High Density one. */
- if (rate == 0)
- {
- if (sector_size == 1024 && self->cpc_trkhead[0x15] >= 7)
- {
- rate = 2; /* ADFS F */
- }
- else if (sector_size == 512 && self->cpc_trkhead[0x15] >= 15)
- {
- rate = 2; /* IBM PC 1.2M or 1.4M */
- }
- else rate = 1;
- }
- /* Similarly for recording mode. Note that I check for exactly
- * 10 sectors, because the MD3 copy protection scheme uses 9
- * 256-byte sectors and they're recorded using MFM. */
- if (recording == 0)
- {
- if (sector_size == 256 && self->cpc_trkhead[0x15] == 10)
- {
- recording = 1; /* BBC Micro DFS */
- }
- else recording = 2;
- }
- switch(rate)
- {
- /* 1: Single / Double Density */
- case 1: if (geom->dg_datarate != RATE_SD &&
- geom->dg_datarate != RATE_DD) return DSK_ERR_NOADDR;
- break;
- /* 2: High density */
- case 2: if (geom->dg_datarate != RATE_HD) return DSK_ERR_NOADDR;
- break;
- /* 3: Extra High Density */
- case 3: if (geom->dg_datarate != RATE_ED) return DSK_ERR_NOADDR;
- break;
- /* Unknown density */
- default:
- return DSK_ERR_NOADDR;
- }
- /* Check data rate */
- switch(recording)
- {
- case 1: if (!geom->dg_fm) return DSK_ERR_NOADDR;
- break;
- case 2: if (geom->dg_fm) return DSK_ERR_NOADDR;
- break;
- default: /* GCR??? */
- return DSK_ERR_NOADDR;
- }
- return DSK_ERR_OK;
-}
-
-
-/* Read a sector ID from a given track */
-dsk_err_t cpcemu_secid(DSK_DRIVER *self, const DSK_GEOMETRY *geom,
- dsk_pcyl_t cyl, dsk_phead_t head, DSK_FORMAT *result)
-{
- CPCEMU_DSK_DRIVER *cpc_self;
- dsk_err_t e;
- int offs;
-
- if (!self || !geom || !result)
- return DSK_ERR_BADPTR;
- DC_CHECK(self)
- cpc_self = (CPCEMU_DSK_DRIVER *)self;
-
- if (!cpc_self->cpc_fp) return DSK_ERR_NOTRDY;
-
- /* lookup_track() allows us to seek to a nonexistent track. */
- /* But we don't want this when reading; so ensure the track */
- /* does actually exist. */
- if (cyl >= cpc_self->cpc_dskhead[0x30]) return DSK_ERR_NOADDR;
- if (head >= cpc_self->cpc_dskhead[0x31]) return DSK_ERR_NOADDR;
-
-
- e = load_track_header(cpc_self, geom, cyl, head);
- if (e) return e;
-
- /* Offset of the chosen sector header */
- ++cpc_self->cpc_sector;
- offs = 0x18 + 8 * (cpc_self->cpc_sector % cpc_self->cpc_trkhead[0x15]);
-
- result->fmt_cylinder = cpc_self->cpc_trkhead[offs];
- result->fmt_head = cpc_self->cpc_trkhead[offs+1];
- result->fmt_sector = cpc_self->cpc_trkhead[offs+2];
- result->fmt_secsize = 128 << cpc_self->cpc_trkhead[offs+3];
- memset(cpc_self->cpc_status, 0, sizeof(cpc_self->cpc_status));
- return DSK_ERR_OK;
-}
-
-
-/* Find the offset of a sector in the current track
- * Enter with cpc_trkhead loaded and the file pointer
- * just after it (ie, you have just called load_track_header() )
- *
- * Returns secid = address of 8-byte sector info area in track header
- * seclen = actual length of sector data; may be a multiple of
- * the sector size for weak sectors
- */
-
-static long sector_offset(CPCEMU_DSK_DRIVER *self, dsk_psect_t sector,
- size_t *seclen, unsigned char **secid)
-{
- int maxsec = self->cpc_trkhead[0x15];
- long offset = 0;
- int n;
-
- /* Pointer to sector details */
- *secid = self->cpc_trkhead + 0x18;
-
- /* Length of sector */
- *seclen = (0x80 << self->cpc_trkhead[0x14]);
-
- /* Extended DSKs have individual sector sizes */
- if (!memcmp(self->cpc_dskhead, "EXTENDED", 8))
- {
- for (n = 0; n < maxsec; n++)
- {
- *seclen = (*secid)[6] + 256 * (*secid)[7]; /* [v0.9.0] */
- if ((*secid)[2] == sector) return offset;
- offset += (*seclen);
- (*secid) += 8;
- }
- }
- else /* Non-extended, all sector sizes are the same */
- {
- for (n = 0; n < maxsec; n++)
- {
- if ((*secid)[2] == sector) return offset;
- offset += (*seclen);
- (*secid) += 8;
- }
- }
- return -1; /* Sector not found */
-}
-
-
-static unsigned char *sector_head(CPCEMU_DSK_DRIVER *self, int sector)
-{
- int ms = self->cpc_trkhead[0x15];
- int sec;
-
- for (sec = 0; sec < ms; sec++)
- {
- if (self->cpc_trkhead[0x1A + 8 * sec] == sector)
- return self->cpc_trkhead + 0x18 + 8 * sec;
- }
- return NULL;
-}
-
-
-/* Seek within the DSK file to a given head & sector in the current cylinder.
- *
- * On entry, *request_len is the expected sector size.
- * If the sector is shorter than this, *request_len will be reduced.
- *
- * weak_copies will be set to 1 in normal use; 2 or more if multiple copies
- * of the sector have been saved.
- *
- * sseclen will be set to the actual size of a sector in the file, so that
- * a random copy can be extracted.
- */
-static dsk_err_t seekto_sector(CPCEMU_DSK_DRIVER *self,
- const DSK_GEOMETRY *geom, int cylinder, int head, int cyl_expected,
- int head_expected, int sector, size_t *request_len, int *weak_copies,
- size_t *sseclen)
-{
- int offs;
- size_t seclen; /* Length of sector data in file */
- dsk_err_t err;
- unsigned char *secid;
- long trkbase;
-
- *weak_copies = 1;
- err = load_track_header(self, geom, cylinder, head);
- if (err) return err;
- trkbase = ftell(self->cpc_fp);
- offs = (int)sector_offset(self, sector, &seclen, &secid);
-
- if (offs < 0) return DSK_ERR_NOADDR; /* Sector not found */
-
- if (cyl_expected != secid[0] || head_expected != secid[1])
- {
- /* We are not in the right place */
- return DSK_ERR_NOADDR;
- }
- *sseclen = 128 << (secid[3] & 7);
-/* Sector shorter than expected. Report a data error, and set
- * request_len to the actual size. */
- if ((*sseclen) < (*request_len))
- {
- err = DSK_ERR_DATAERR;
- *request_len = *sseclen;
- }
-/* Sector longer than expected. Report a data error but don't change
- * request_len */
- else if ((*sseclen) > (*request_len))
- {
- err = DSK_ERR_DATAERR;
- }
-/* If there is room for two or more copies, we have a weak-recording
- * situation. */
- if ((*sseclen) * 2 <= seclen)
- {
- *weak_copies = seclen / (*sseclen);
- }
-
- fseek(self->cpc_fp, trkbase + offs, SEEK_SET);
-
- return err;
-}
-
-
-/* Read a sector */
-dsk_err_t cpcemu_read(DSK_DRIVER *self, const DSK_GEOMETRY *geom,
- void *buf, dsk_pcyl_t cylinder,
- dsk_phead_t head, dsk_psect_t sector)
-{
- return cpcemu_xread(self, geom, buf, cylinder, head, cylinder,
- head, sector, geom->dg_secsize, 0);
-}
-
-dsk_err_t cpcemu_xread(DSK_DRIVER *self, const DSK_GEOMETRY *geom, void *buf,
- dsk_pcyl_t cylinder, dsk_phead_t head,
- dsk_pcyl_t cyl_expect, dsk_phead_t head_expect,
- dsk_psect_t sector, size_t sector_size, int *deleted)
-{
- CPCEMU_DSK_DRIVER *cpc_self;
- dsk_err_t err;
- int weak_copies;
- size_t sseclen;
- size_t len = sector_size; /* 1.1.2: Was geom->dg_secsize; but
- * that fails when individual sectors
- * are bigger than the size in geom. */
- int rdeleted = 0;
- int try_again = 0;
- unsigned char *sh;
-
- if (!buf || !geom || !self) return DSK_ERR_BADPTR;
- DC_CHECK(self)
- cpc_self = (CPCEMU_DSK_DRIVER *)self;
-
- if (deleted && *deleted) rdeleted = 0x40;
-
- do
- {
- err = seekto_sector(cpc_self, geom, cylinder,head,
- cyl_expect, head_expect, sector, &len,
- &weak_copies, &sseclen);
-/* Are we retrying because we are looking for deleted data and found
- * nondeleted or vice versa?
- *
- * If so, and we have run out of sectors in this track, AND we are on head 0,
- * AND the disc has 2 heads, AND we are in multitrack mode, then look on head 1
- * as well. Amazing.
- * */
- if (try_again == 1 && err == DSK_ERR_NOADDR)
- {
- err = DSK_ERR_NODATA;
- if ((!geom->dg_nomulti) && head == 0 &&
- cpc_self->cpc_dskhead[0x31] > 0)
- {
- head++;
- sector = geom->dg_secbase;
- continue;
- }
- }
- try_again = 0;
- if (err != DSK_ERR_DATAERR && err != DSK_ERR_OK)
- return err;
- /* We have the sector. But does it contain deleted data? */
- sh = sector_head(cpc_self, sector);
- if (!sh) return DSK_ERR_NODATA;
-
- if (deleted) *deleted = 0;
- if (rdeleted != (sh[5] & 0x40)) /* Mismatch! */
- {
- if (geom->dg_noskip)
- {
- if (deleted) *deleted = 1;
- }
- else
- {
-/* Try the next sector. */
- try_again = 1;
- ++sector;
- continue;
- }
- }
-/* This next line should never be true, because len starts as sector_size and
- * seekto_sector() only ever reduces it. */
- if (len > sector_size) len = sector_size;
-
-/* If there are multiple copies of the sector present, pick one at random */
- if (weak_copies > 1)
- {
- long offset = (rand() % weak_copies) * sseclen;
- fseek(cpc_self->cpc_fp, offset, SEEK_CUR);
- }
-
- if (fread(buf, 1, len, cpc_self->cpc_fp) < len)
- err = DSK_ERR_DATAERR;
-/* Sec...
[truncated message content] |
|
From: <fr...@us...> - 2007-07-01 02:20:49
|
Revision: 411
http://svn.sourceforge.net/fuse-for-macosx/?rev=411&view=rev
Author: fredm
Date: 2007-06-30 19:20:49 -0700 (Sat, 30 Jun 2007)
Log Message:
-----------
Add UTI entries for mgt disk images.
Modified Paths:
--------------
trunk/FuseImporter/Info.plist
trunk/fuse/fusepb/Info-Fuse.plist
Modified: trunk/FuseImporter/Info.plist
===================================================================
--- trunk/FuseImporter/Info.plist 2007-07-01 02:19:19 UTC (rev 410)
+++ trunk/FuseImporter/Info.plist 2007-07-01 02:20:49 UTC (rev 411)
@@ -21,6 +21,7 @@
<string>net.sourceforge.projects.fuse-emulator.csw</string>
<string>net.sourceforge.projects.fuse-emulator.hdf</string>
<string>net.sourceforge.projects.fuse-emulator.dsk</string>
+ <string>net.sourceforge.projects.fuse-emulator.mgt</string>
<string>net.sourceforge.projects.fuse-emulator.rzx</string>
<string>net.sourceforge.projects.fuse-emulator.scl</string>
<string>net.sourceforge.projects.fuse-emulator.scr</string>
@@ -170,6 +171,25 @@
<dict>
<key>UTTypeConformsTo</key>
<array>
+ <string>net.sourceforge.projects.fuse-emulator.MassStorage</string>
+ </array>
+ <key>UTTypeDescription</key>
+ <string>ZX Spectrum DISCiPLE/+D Disk Image</string>
+ <key>UTTypeIdentifier</key>
+ <string>net.sourceforge.projects.fuse-emulator.mgt</string>
+ <key>UTTypeReferenceURL</key>
+ <string>http://www.worldofspectrum.org/faq/reference/formats.htm</string>
+ <key>UTTypeTagSpecification</key>
+ <dict>
+ <key>public.filename-extension</key>
+ <array>
+ <string>mgt</string>
+ </array>
+ </dict>
+ </dict>
+ <dict>
+ <key>UTTypeConformsTo</key>
+ <array>
<string>public.audiovisual-content</string>
</array>
<key>UTTypeDescription</key>
Modified: trunk/fuse/fusepb/Info-Fuse.plist
===================================================================
--- trunk/fuse/fusepb/Info-Fuse.plist 2007-07-01 02:19:19 UTC (rev 410)
+++ trunk/fuse/fusepb/Info-Fuse.plist 2007-07-01 02:20:49 UTC (rev 411)
@@ -517,6 +517,25 @@
<dict>
<key>UTTypeConformsTo</key>
<array>
+ <string>net.sourceforge.projects.fuse-emulator.MassStorage</string>
+ </array>
+ <key>UTTypeDescription</key>
+ <string>ZX Spectrum DISCiPLE/+D Disk Image</string>
+ <key>UTTypeIdentifier</key>
+ <string>net.sourceforge.projects.fuse-emulator.mgt</string>
+ <key>UTTypeReferenceURL</key>
+ <string>http://www.worldofspectrum.org/faq/reference/formats.htm</string>
+ <key>UTTypeTagSpecification</key>
+ <dict>
+ <key>public.filename-extension</key>
+ <array>
+ <string>mgt</string>
+ </array>
+ </dict>
+ </dict>
+ <dict>
+ <key>UTTypeConformsTo</key>
+ <array>
<string>public.audiovisual-content</string>
</array>
<key>UTTypeDescription</key>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fr...@us...> - 2007-07-01 02:19:18
|
Revision: 410
http://svn.sourceforge.net/fuse-for-macosx/?rev=410&view=rev
Author: fredm
Date: 2007-06-30 19:19:19 -0700 (Sat, 30 Jun 2007)
Log Message:
-----------
List correct supported plusd file types and allow plusd disks to be ejected.
Modified Paths:
--------------
trunk/fuse/fusepb/controllers/FuseController.m
Modified: trunk/fuse/fusepb/controllers/FuseController.m
===================================================================
--- trunk/fuse/fusepb/controllers/FuseController.m 2007-07-01 02:17:49 UTC (rev 409)
+++ trunk/fuse/fusepb/controllers/FuseController.m 2007-07-01 02:19:19 UTC (rev 410)
@@ -183,8 +183,8 @@
@"SCL", nil];
[trdosFileTypes retain];
- plusdFileTypes = [NSMutableArray arrayWithObjects:@"mgt", @"MGT", @"img",
- @"IMG", nil];
+ plusdFileTypes = [NSMutableArray arrayWithObjects:@"dsk", @"DSK", @"mgt",
+ @"MGT", nil];
[plusdFileTypes retain];
allFileTypes = [NSMutableArray arrayWithArray:snapFileTypes];
@@ -1916,8 +1916,11 @@
[[DisplayOpenGLView instance] pause];
if( machine_current->machine == LIBSPECTRUM_MACHINE_PLUS3 ) {
[[DisplayOpenGLView instance] specplus3DiskEject:drive saveFirst:write];
+ } else if( machine_current->machine == LIBSPECTRUM_MACHINE_PENT ||
+ machine_current->machine == LIBSPECTRUM_MACHINE_SCORP ) {
+ [[DisplayOpenGLView instance] trdosDiskEject:drive saveFirst:write];
} else {
- [[DisplayOpenGLView instance] trdosDiskEject:drive saveFirst:write];
+ [[DisplayOpenGLView instance] plusdDiskEject:drive saveFirst:write];
}
[[DisplayOpenGLView instance] unpause];
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fr...@us...> - 2007-07-01 02:17:50
|
Revision: 409
http://svn.sourceforge.net/fuse-for-macosx/?rev=409&view=rev
Author: fredm
Date: 2007-06-30 19:17:49 -0700 (Sat, 30 Jun 2007)
Log Message:
-----------
Sometimes we raise an error in response to a message from the main thread,
and if we wait for the main thread which is blocked waiting for our response
we can end up in a deadlock situation.
Modified Paths:
--------------
trunk/fuse/ui/cocoa/cocoaerror.m
Modified: trunk/fuse/ui/cocoa/cocoaerror.m
===================================================================
--- trunk/fuse/ui/cocoa/cocoaerror.m 2007-07-01 02:16:18 UTC (rev 408)
+++ trunk/fuse/ui/cocoa/cocoaerror.m 2007-07-01 02:17:49 UTC (rev 409)
@@ -49,14 +49,14 @@
[[FuseController singleton]
performSelectorOnMainThread:@selector(showAlertPanel:)
withObject:alertString
- waitUntilDone:YES];
+ waitUntilDone:NO];
break;
case UI_ERROR_ERROR:
default:
[[FuseController singleton]
performSelectorOnMainThread:@selector(showCriticalAlertPanel:)
withObject:alertString
- waitUntilDone:YES];
+ waitUntilDone:NO];
break;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fr...@us...> - 2007-07-01 02:16:16
|
Revision: 408
http://svn.sourceforge.net/fuse-for-macosx/?rev=408&view=rev
Author: fredm
Date: 2007-06-30 19:16:18 -0700 (Sat, 30 Jun 2007)
Log Message:
-----------
Fix framework version numbers.
Modified Paths:
--------------
trunk/lib765/libdsk/config.h
trunk/lib765/libdsk/libdskpb/English.lproj/InfoPlist.strings
trunk/lib765/libdsk/libdskpb/Info-libdsk.plist
trunk/lib765/libdsk/libdskpb/libdsk.xcodeproj/project.pbxproj
Modified: trunk/lib765/libdsk/config.h
===================================================================
--- trunk/lib765/libdsk/config.h 2007-06-30 12:41:50 UTC (rev 407)
+++ trunk/lib765/libdsk/config.h 2007-07-01 02:16:18 UTC (rev 408)
@@ -113,5 +113,5 @@
#define PACKAGE "libdsk"
/* Version number of package */
-#define VERSION "1.1.3"
+#define VERSION "1.1.10"
Modified: trunk/lib765/libdsk/libdskpb/English.lproj/InfoPlist.strings
===================================================================
(Binary files differ)
Modified: trunk/lib765/libdsk/libdskpb/Info-libdsk.plist
===================================================================
--- trunk/lib765/libdsk/libdskpb/Info-libdsk.plist 2007-06-30 12:41:50 UTC (rev 407)
+++ trunk/lib765/libdsk/libdskpb/Info-libdsk.plist 2007-07-01 02:16:18 UTC (rev 408)
@@ -17,7 +17,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>1.1.3</string>
+ <string>1.1.10</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
Modified: trunk/lib765/libdsk/libdskpb/libdsk.xcodeproj/project.pbxproj
===================================================================
--- trunk/lib765/libdsk/libdskpb/libdsk.xcodeproj/project.pbxproj 2007-06-30 12:41:50 UTC (rev 407)
+++ trunk/lib765/libdsk/libdskpb/libdsk.xcodeproj/project.pbxproj 2007-07-01 02:16:18 UTC (rev 408)
@@ -66,36 +66,6 @@
B6A8C0DF083D81630060DD3A /* dskretry.c in Sources */ = {isa = PBXBuildFile; fileRef = B6A8C0DE083D81630060DD3A /* dskretry.c */; };
/* End PBXBuildFile section */
-/* Begin PBXBuildStyle section */
- 014CEA440018CDF011CA2923 /* Development */ = {
- isa = PBXBuildStyle;
- buildSettings = {
- COPY_PHASE_STRIP = NO;
- FRAMEWORK_VERSION = 1.1.3;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = YES;
- GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
- GCC_OPTIMIZATION_LEVEL = 0;
- MACOSX_DEPLOYMENT_TARGET = 10.3;
- OPTIMIZATION_CFLAGS = "-O0";
- ZERO_LINK = YES;
- };
- name = Development;
- };
- 014CEA450018CDF011CA2923 /* Deployment */ = {
- isa = PBXBuildStyle;
- buildSettings = {
- COPY_PHASE_STRIP = YES;
- GCC_ENABLE_CPP_EXCEPTIONS = NO;
- GCC_ENABLE_CPP_RTTI = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
- GCC_MODEL_CPU = G3;
- ZERO_LINK = NO;
- };
- name = Deployment;
- };
-/* End PBXBuildStyle section */
-
/* Begin PBXFileReference section */
089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
B674F59605BAD9CC008DE42C /* compbz2.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = compbz2.c; path = ../lib/compbz2.c; sourceTree = SOURCE_ROOT; };
@@ -333,30 +303,6 @@
);
buildRules = (
);
- buildSettings = {
- DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 1;
- FRAMEWORK_SEARCH_PATHS = ../../bzip2/libbz2pb/build/Deployment;
- FRAMEWORK_VERSION = 1.1.3;
- HEADER_SEARCH_PATHS = "";
- INFOPLIST_FILE = "Info-libdsk.plist";
- INSTALL_PATH = "@executable_path/../Frameworks";
- LIBRARY_SEARCH_PATHS = "";
- OTHER_LDFLAGS = (
- "-lz",
- "-seg1addr",
- 0x11000000,
- );
- PRODUCT_NAME = libdsk;
- SECTORDER_FLAGS = "";
- SKIP_INSTALL = YES;
- WARNING_CFLAGS = (
- "\U0001-Wmost",
- "-Wno-four-char-constants",
- "-Wno-unknown-pragmas",
- );
- WRAPPER_EXTENSION = framework;
- };
dependencies = (
);
name = libdsk;
@@ -371,12 +317,6 @@
0867D690FE84028FC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = B608B425090B5494004F72B2 /* Build configuration list for PBXProject "libdsk" */;
- buildSettings = {
- };
- buildStyles = (
- 014CEA440018CDF011CA2923 /* Development */,
- 014CEA450018CDF011CA2923 /* Deployment */,
- );
hasScannedForEncodings = 1;
mainGroup = 0867D691FE84028FC02AAC07 /* libdsk */;
productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fr...@us...> - 2007-06-30 12:41:48
|
Revision: 407
http://svn.sourceforge.net/fuse-for-macosx/?rev=407&view=rev
Author: fredm
Date: 2007-06-30 05:41:50 -0700 (Sat, 30 Jun 2007)
Log Message:
-----------
Must refresh display on resize or switch to/from fullscreen.
Modified Paths:
--------------
trunk/fuse/fusepb/views/DisplayOpenGLView.m
Modified: trunk/fuse/fusepb/views/DisplayOpenGLView.m
===================================================================
--- trunk/fuse/fusepb/views/DisplayOpenGLView.m 2007-06-29 13:16:48 UTC (rev 406)
+++ trunk/fuse/fusepb/views/DisplayOpenGLView.m 2007-06-30 12:41:50 UTC (rev 407)
@@ -144,6 +144,8 @@
if( !ui_mouse_grabbed ) ui_mouse_grabbed = ui_mouse_grab( 0 );
}
}
+
+ statusbar_updated = YES;
}
-(IBAction) zoom:(id)sender
@@ -533,7 +535,7 @@
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
- [self setNeedsDisplay:YES];
+ statusbar_updated = YES;
}
/* scrolled, moved or resized */
@@ -556,7 +558,7 @@
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
- [self setNeedsDisplay:YES];
+ statusbar_updated = YES;
}
-(void) destroyTexture
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fr...@us...> - 2007-06-29 13:16:48
|
Revision: 406
http://svn.sourceforge.net/fuse-for-macosx/?rev=406&view=rev
Author: fredm
Date: 2007-06-29 06:16:48 -0700 (Fri, 29 Jun 2007)
Log Message:
-----------
Correct link to +D documents.
Modified Paths:
--------------
trunk/fuse/fusepb/resources/Fuse Help/html/tocstart.html
Modified: trunk/fuse/fusepb/resources/Fuse Help/html/tocstart.html
===================================================================
--- trunk/fuse/fusepb/resources/Fuse Help/html/tocstart.html 2007-06-29 12:55:24 UTC (rev 405)
+++ trunk/fuse/fusepb/resources/Fuse Help/html/tocstart.html 2007-06-29 13:16:48 UTC (rev 406)
@@ -64,7 +64,7 @@
<p> <font face="Lucida Grande,Helvetica,Arial"> <a
href="divide.html">DivIDE</a></font></p>
<p> <font face="Lucida Grande,Helvetica,Arial"> <a
- href="divide.html">+D Emulation</a> </font> </p>
+ href="plusd.html">+D Emulation</a> </font> </p>
<font face="Lucida Grande,Helvetica,Arial"> </font>
<p> </p>
<p> <font face="Lucida Grande,Helvetica,Arial"> <a
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fr...@us...> - 2007-06-29 12:55:32
|
Revision: 405
http://svn.sourceforge.net/fuse-for-macosx/?rev=405&view=rev
Author: fredm
Date: 2007-06-29 05:55:24 -0700 (Fri, 29 Jun 2007)
Log Message:
-----------
Merge up to vendor revision 3018.
Revision Links:
--------------
http://svn.sourceforge.net/fuse-for-macosx/?rev=3018&view=rev
Modified Paths:
--------------
trunk/FuseImporter/libspectrum.h
trunk/fuse/Makefile.am
trunk/fuse/ay.c
trunk/fuse/ay.h
trunk/fuse/configure.in
trunk/fuse/dck.c
trunk/fuse/divide.c
trunk/fuse/divide.h
trunk/fuse/event.c
trunk/fuse/event.h
trunk/fuse/fuse.cpp
trunk/fuse/fusepb/Credits.html
trunk/fuse/fusepb/English.lproj/InfoPlist.strings
trunk/fuse/fusepb/Fuse.xcodeproj/project.pbxproj
trunk/fuse/fusepb/Info-Fuse.plist
trunk/fuse/fusepb/controllers/FuseController.h
trunk/fuse/fusepb/controllers/FuseController.m
trunk/fuse/fusepb/controllers/PreferencesController.m
trunk/fuse/fusepb/models/Emulator.h
trunk/fuse/fusepb/models/Emulator.m
trunk/fuse/fusepb/nibs/MainMenu.nib/classes.nib
trunk/fuse/fusepb/nibs/MainMenu.nib/info.nib
trunk/fuse/fusepb/nibs/MainMenu.nib/keyedobjects.nib
trunk/fuse/fusepb/nibs/Preferences.nib/info.nib
trunk/fuse/fusepb/nibs/Preferences.nib/keyedobjects.nib
trunk/fuse/fusepb/resources/Fuse Help/html/about.html
trunk/fuse/fusepb/resources/Fuse Help/html/compressed.html
trunk/fuse/fusepb/resources/Fuse Help/html/divide.html
trunk/fuse/fusepb/resources/Fuse Help/html/emulation.html
trunk/fuse/fusepb/resources/Fuse Help/html/filters.html
trunk/fuse/fusepb/resources/Fuse Help/html/mappings.html
trunk/fuse/fusepb/resources/Fuse Help/html/menus.html
trunk/fuse/fusepb/resources/Fuse Help/html/preferences.html
trunk/fuse/fusepb/resources/Fuse Help/html/printer.html
trunk/fuse/fusepb/resources/Fuse Help/html/spotlight.html
trunk/fuse/fusepb/resources/Fuse Help/html/tocstart.html
trunk/fuse/fusepb/views/DisplayOpenGLView.h
trunk/fuse/fusepb/views/DisplayOpenGLView.m
trunk/fuse/hacking/ChangeLog
trunk/fuse/if1.c
trunk/fuse/if1.h
trunk/fuse/if2.c
trunk/fuse/if2.h
trunk/fuse/joystick.c
trunk/fuse/joystick.h
trunk/fuse/keysyms.pl
trunk/fuse/machine.c
trunk/fuse/machine.h
trunk/fuse/machines/pentagon.c
trunk/fuse/machines/scorpion.c
trunk/fuse/machines/spec128.c
trunk/fuse/machines/spec16.c
trunk/fuse/machines/spec48.c
trunk/fuse/machines/spec_se.c
trunk/fuse/machines/specplus2.c
trunk/fuse/machines/specplus2a.c
trunk/fuse/machines/specplus3.c
trunk/fuse/machines/specplus3.h
trunk/fuse/machines/specplus3e.c
trunk/fuse/machines/tc2048.c
trunk/fuse/machines/tc2068.c
trunk/fuse/machines/ts2068.c
trunk/fuse/man/fuse.1
trunk/fuse/memory.c
trunk/fuse/memory.h
trunk/fuse/menu.c
trunk/fuse/menu_data.dat
trunk/fuse/periph.c
trunk/fuse/periph.h
trunk/fuse/printer.c
trunk/fuse/printer.h
trunk/fuse/roms/Makefile.am
trunk/fuse/rzx.c
trunk/fuse/rzx.h
trunk/fuse/scld.c
trunk/fuse/scld.h
trunk/fuse/settings.dat
trunk/fuse/simpleide.c
trunk/fuse/simpleide.h
trunk/fuse/slt.c
trunk/fuse/slt.h
trunk/fuse/snapshot.c
trunk/fuse/sound/alsasound.c
trunk/fuse/spectrum.c
trunk/fuse/spectrum.h
trunk/fuse/tape.c
trunk/fuse/trdos.c
trunk/fuse/trdos.h
trunk/fuse/ui/cocoa/cocoadisplay.h
trunk/fuse/ui/cocoa/cocoadisplay.m
trunk/fuse/ui/cocoa/cocoaerror.m
trunk/fuse/ui/cocoa/cocoajoystick.c
trunk/fuse/ui/cocoa/cocoascreenshot.h
trunk/fuse/ui/cocoa/cocoascreenshot.m
trunk/fuse/ui/cocoa/cocoastatusbar.m
trunk/fuse/ui/cocoa/cocoaui.h
trunk/fuse/ui/cocoa/cocoaui.m
trunk/fuse/ui/cocoa/keysyms.m
trunk/fuse/ui/gtk/gtkui.c
trunk/fuse/ui/options.dat
trunk/fuse/ui/svga/svgadisplay.c
trunk/fuse/ui/svga/svgakeyboard.c
trunk/fuse/ui/ui.h
trunk/fuse/ui/win32/win32ui.c
trunk/fuse/ui/xlib/xdisplay.c
trunk/fuse/ui/xlib/xui.c
trunk/fuse/ui.c
trunk/fuse/ula.c
trunk/fuse/ula.h
trunk/fuse/utils.c
trunk/fuse/widget/error.c
trunk/fuse/widget/memory.c
trunk/fuse/widget/menu.c
trunk/fuse/widget/options.pl
trunk/fuse/widget/pokefinder.c
trunk/fuse/widget/widget.c
trunk/fuse/widget/widget_internals.h
trunk/fuse/z80/coretest.c
trunk/fuse/z80/z80.c
trunk/fuse/z80/z80.h
trunk/fuse/z80/z80.pl
trunk/fuse/z80/z80_macros.h
trunk/fuse/z80/z80_ops.c
trunk/fuse/zxatasp.c
trunk/fuse/zxatasp.h
trunk/fuse/zxcf.c
trunk/fuse/zxcf.h
trunk/libspectrum/libspectrum/hacking/ChangeLog
trunk/libspectrum/libspectrum/libspectrum.c
trunk/libspectrum/libspectrum/libspectrum.h.in
trunk/libspectrum/libspectrum.h
Added Paths:
-----------
trunk/fuse/disk/
trunk/fuse/disk/Makefile.am
trunk/fuse/disk/plusd.c
trunk/fuse/disk/plusd.h
trunk/fuse/disk/wd1770.c
trunk/fuse/disk/wd1770.h
trunk/fuse/fusepb/resources/Fuse Help/html/plusd.html
trunk/fuse/module.c
trunk/fuse/module.h
trunk/fuse/roms/plusd.rom
Removed Paths:
-------------
trunk/fuse/disk/Makefile.am
trunk/fuse/disk/plusd.c
trunk/fuse/disk/plusd.h
trunk/fuse/disk/wd1770.c
trunk/fuse/disk/wd1770.h
Modified: trunk/FuseImporter/libspectrum.h
===================================================================
--- trunk/FuseImporter/libspectrum.h 2007-06-28 13:18:42 UTC (rev 404)
+++ trunk/FuseImporter/libspectrum.h 2007-06-29 12:55:24 UTC (rev 405)
@@ -1,7 +1,7 @@
/* libspectrum.h: the library for dealing with ZX Spectrum emulator files
Copyright (c) 2001-2007 Philip Kendall, Darren Salt, Fredrick Meunier
- $Id: libspectrum.h.in,v 1.141 2007/02/02 16:35:42 pak21 Exp $
+ $Id: libspectrum.h.in 3008 2007-06-17 18:54:58Z zubzero $
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -274,10 +274,10 @@
/* Below here, present only in x.x.x and later */
LIBSPECTRUM_ID_TAPE_WAV, /* .wav tape image */
+ LIBSPECTRUM_ID_COMPRESSED_XFD, /* xfdmaster (Amiga) compressed file */
+ LIBSPECTRUM_ID_DISK_IMG, /* .img +D disk image */
+ LIBSPECTRUM_ID_DISK_MGT, /* .mgt +D disk image */
- /* Amiga entry for improved compressed file support */
- LIBSPECTRUM_ID_COMPRESSED_XFD, /* xfdmaster compressed file */
-
LIBSPECTRUM_ID_SCREEN_SCR, /* .scr screen file */
} libspectrum_id_t;
@@ -307,6 +307,10 @@
LIBSPECTRUM_CLASS_MICRODRIVE, /* Microdrive cartridges */
+ /* Below here, present only in x.x.x and later */
+
+ LIBSPECTRUM_CLASS_DISK_PLUSD, /* +D disk image */
+
LIBSPECTRUM_CLASS_SCREENSHOT, /* Screenshot */
} libspectrum_class_t;
Modified: trunk/fuse/Makefile.am
===================================================================
--- trunk/fuse/Makefile.am 2007-06-28 13:18:42 UTC (rev 404)
+++ trunk/fuse/Makefile.am 2007-06-29 12:55:24 UTC (rev 405)
@@ -1,7 +1,7 @@
## Process this file with automake to produce Makefile.in
## Copyright (c) 1999-2004 Philip Kendall
-## $Id: Makefile.am 2920 2007-06-02 02:06:05Z fredm $
+## $Id: Makefile.am 3007 2007-06-17 18:50:48Z zubzero $
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
@@ -27,6 +27,7 @@
SUBDIRS = compat \
debugger \
+ @DISK@ \
hacking \
lib \
machines \
@@ -41,6 +42,7 @@
DIST_SUBDIRS = compat \
debugger \
+ disk \
hacking \
lib \
machines \
@@ -70,6 +72,7 @@
machine.c \
memory.c \
menu.c \
+ module.c \
periph.c \
printer.c \
profile.c \
@@ -98,6 +101,7 @@
fuse_LDADD = debugger/libdebugger.a \
@UI_LIBS@ \
+@DISK_LIBS@ \
machines/libmachines.a \
pokefinder/libpokefinder.a \
sound/libsound.a \
@@ -119,11 +123,12 @@
@WINDRES_OBJ@
fuse_DEPENDENCIES = @UI_LIBS@ \
+ @DISK_LIBS@ \
debugger/libdebugger.a \
machines/libmachines.a \
sound/libsound.a \
- z80/libz80.a \
- @WINDRES_OBJ@
+ z80/libz80.a \
+ @WINDRES_OBJ@
BUILT_SOURCES = settings.c settings.h
@@ -156,6 +161,7 @@
machine.h \
memory.h \
menu.h \
+ module.h \
periph.h \
psg.h \
rzx.h \
Modified: trunk/fuse/ay.c
===================================================================
--- trunk/fuse/ay.c 2007-06-28 13:18:42 UTC (rev 404)
+++ trunk/fuse/ay.c 2007-06-29 12:55:24 UTC (rev 405)
@@ -1,7 +1,7 @@
/* ay.c: AY-8-3912 routines
Copyright (c) 1999-2004 Philip Kendall
- $Id: ay.c 2889 2007-05-26 17:45:08Z zubzero $
+ $Id: ay.c 2993 2007-06-17 13:54:49Z pak21 $
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -27,6 +27,7 @@
#include "compat.h"
#include "machine.h"
+#include "module.h"
#include "printer.h"
#include "psg.h"
#include "sound.h"
@@ -40,6 +41,26 @@
};
+static void ay_from_snapshot( libspectrum_snap *snap );
+static void ay_to_snapshot( libspectrum_snap *snap );
+
+static module_info_t ay_module_info = {
+
+ NULL,
+ NULL,
+ ay_from_snapshot,
+ ay_to_snapshot,
+
+};
+
+int
+ay_init( void )
+{
+ module_register( &ay_module_info );
+
+ return 0;
+}
+
/* What happens when the AY register port (traditionally 0xfffd on the 128K
machines) is read from */
libspectrum_byte
@@ -97,12 +118,12 @@
if( current == 14 ) printer_serial_write( b );
}
-int
-ay_from_snapshot( libspectrum_snap *snap, int capabilities )
+static void
+ay_from_snapshot( libspectrum_snap *snap )
{
size_t i;
- if( capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_AY ) {
+ if( machine_current->capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_AY ) {
ay_registerport_write( 0xfffd,
libspectrum_snap_out_ay_registerport( snap ) );
@@ -114,11 +135,9 @@
}
}
-
- return 0;
}
-int
+static void
ay_to_snapshot( libspectrum_snap *snap )
{
size_t i;
@@ -130,6 +149,4 @@
for( i = 0; i < AY_REGISTERS; i++ )
libspectrum_snap_set_ay_registers( snap, i,
machine_current->ay.registers[i] );
-
- return 0;
}
Modified: trunk/fuse/ay.h
===================================================================
--- trunk/fuse/ay.h 2007-06-28 13:18:42 UTC (rev 404)
+++ trunk/fuse/ay.h 2007-06-29 12:55:24 UTC (rev 405)
@@ -1,7 +1,7 @@
/* ay.h: AY-8-3912 routines
Copyright (c) 1999-2004 Philip Kendall
- $Id: ay.h 2889 2007-05-26 17:45:08Z zubzero $
+ $Id: ay.h 2993 2007-06-17 13:54:49Z pak21 $
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -35,12 +35,11 @@
libspectrum_byte registers[ AY_REGISTERS ];
} ayinfo;
+int ay_init( void );
+
libspectrum_byte ay_registerport_read( libspectrum_word port, int *attached );
void ay_registerport_write( libspectrum_word port, libspectrum_byte b );
void ay_dataport_write( libspectrum_word port, libspectrum_byte b );
-int ay_from_snapshot( libspectrum_snap *snap, int capabilities );
-int ay_to_snapshot( libspectrum_snap *snap );
-
#endif /* #ifndef FUSE_AY_H */
Modified: trunk/fuse/configure.in
===================================================================
--- trunk/fuse/configure.in 2007-06-28 13:18:42 UTC (rev 404)
+++ trunk/fuse/configure.in 2007-06-29 12:55:24 UTC (rev 405)
@@ -1,5 +1,5 @@
dnl Process this file with autoconf to produce a configure script.
-dnl $Id: configure.in,v 1.155 2007/02/02 16:21:50 pak21 Exp $
+dnl $Id: configure.in 3007 2007-06-17 18:50:48Z zubzero $
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
@@ -358,6 +358,14 @@
lib/tape_se.szx
lib/tape_ts2068.szx])
+dnl LibDsk/lib765 prefix
+AC_ARG_WITH(disk-prefix,
+[ --with-disk-prefix=PFX where the LibDsk and/or lib765 libraries are installed (optional)],
+DSK_CFLAGS=-I$withval/include; DSKLIBS=-L$withval/lib,
+DSK_CFLAGS=""; DSK_LIBS="")
+ac_save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $DSK_CFLAGS"
+
dnl Do we want +3 disk support?
AC_MSG_CHECKING(whether +3 disk support requested)
AC_ARG_WITH(plus3-disk,
@@ -366,21 +374,27 @@
plus3disk=yes)
AC_MSG_RESULT($plus3disk)
if test "$plus3disk" = yes; then
- AC_ARG_WITH(plus3-disk-prefix,
- [ --with-plus3-disk-prefix=PFX where the +3 libraries are installed (optional)],
- DSK_CFLAGS=-I$withval/include; DSKLIBS=-L$withval/lib,
- DSK_CFLAGS=""; DSK_LIBS="")
- ac_save_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $DSK_CFLAGS"
AC_CHECK_HEADERS(765.h, DSKLIBS="$DSKLIBS -l765"; lib765=yes,
- AC_MSG_WARN(765.h not found - disk support disabled))
- if test "$lib765" = yes; then
- AC_CHECK_HEADERS(libdsk.h, DSKLIBS="$DSKLIBS -ldsk")
- fi
- CPPFLAGS="$ac_save_CPPFLAGS"
+ AC_MSG_WARN(765.h not found - +3 disk support disabled))
fi
+
+dnl Do we want LibDsk support?
+AC_ARG_WITH(libdsk,
+ [ --without-libdsk disable LibDsk support],
+ if test "$withval" = no; then libdsk=no; else libdsk=yes; fi,
+ libdsk=yes)
+AC_MSG_RESULT($libdsk)
+if test "$libdsk" = yes; then
+ AC_CHECK_HEADERS(libdsk.h, DSKLIBS="$DSKLIBS -ldsk";
+ DISK_LIBS="disk/libdisk.a"; DISK="disk",
+ AC_MSG_WARN(libdsk.h not found - LibDsk support disabled))
+fi
+
+CPPFLAGS="$ac_save_CPPFLAGS"
AC_SUBST(DSK_CFLAGS)
AC_SUBST(DSKLIBS)
+AC_SUBST(DISK_LIBS)
+AC_SUBST(DISK)
dnl Check if a version of libpng which supplies png_write_png is available
AC_CHECK_LIB( png, png_write_png,
@@ -568,6 +582,7 @@
AC_OUTPUT(Makefile \
compat/Makefile \
debugger/Makefile \
+disk/Makefile \
hacking/Makefile \
lib/Makefile \
machines/Makefile \
Modified: trunk/fuse/dck.c
===================================================================
--- trunk/fuse/dck.c 2007-06-28 13:18:42 UTC (rev 404)
+++ trunk/fuse/dck.c 2007-06-29 12:55:24 UTC (rev 405)
@@ -1,7 +1,7 @@
/* dck.c: dock snapshot (Warajevo .DCK) handling routines
Copyright (c) 2003-2004 Darren Salt, Fredrick Meunier, Philip Kendall
- $Id: dck.c 2889 2007-05-26 17:45:08Z zubzero $
+ $Id: dck.c 2995 2007-06-17 14:31:36Z pak21 $
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -61,7 +61,7 @@
error = settings_set_string( &settings_current.dck_file, filename );
if( error ) return error;
- machine_reset();
+ machine_reset( 0 );
return 0;
}
@@ -82,7 +82,7 @@
ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 0 );
- machine_reset();
+ machine_reset( 0 );
}
int
Copied: trunk/fuse/disk (from rev 404, vendor/fuse-emulator/current/fuse/disk)
Deleted: trunk/fuse/disk/Makefile.am
===================================================================
--- vendor/fuse-emulator/current/fuse/disk/Makefile.am 2007-06-28 13:18:42 UTC (rev 404)
+++ trunk/fuse/disk/Makefile.am 2007-06-29 12:55:24 UTC (rev 405)
@@ -1,34 +0,0 @@
-## Process this file with automake to produce Makefile.in
-## Copyright (c) 2007 Stuart Brady
-
-## $Id: Makefile.am 2889 2007-05-26 17:45:08Z zubzero $
-
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU 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 General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License along
-## with this program; if not, write to the Free Software Foundation, Inc.,
-## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-##
-## Author contact information:
-##
-## E-mail: phi...@sh...
-
-AUTOMAKE_OPTIONS = foreign
-
-noinst_LIBRARIES = libdisk.a
-
-INCLUDES = @LIBSPEC_CFLAGS@ @GTK_CFLAGS@ @GLIB_CFLAGS@
-
-libdisk_a_SOURCES = plusd.c \
- wd1770.c
-
-noinst_HEADERS = plusd.h \
- wd1770.h
Copied: trunk/fuse/disk/Makefile.am (from rev 404, vendor/fuse-emulator/current/fuse/disk/Makefile.am)
===================================================================
--- trunk/fuse/disk/Makefile.am (rev 0)
+++ trunk/fuse/disk/Makefile.am 2007-06-29 12:55:24 UTC (rev 405)
@@ -0,0 +1,34 @@
+## Process this file with automake to produce Makefile.in
+## Copyright (c) 2007 Stuart Brady
+
+## $Id: Makefile.am 2889 2007-05-26 17:45:08Z zubzero $
+
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU 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 General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with this program; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+##
+## Author contact information:
+##
+## E-mail: phi...@sh...
+
+AUTOMAKE_OPTIONS = foreign
+
+noinst_LIBRARIES = libdisk.a
+
+INCLUDES = @LIBSPEC_CFLAGS@ @GTK_CFLAGS@ @GLIB_CFLAGS@
+
+libdisk_a_SOURCES = plusd.c \
+ wd1770.c
+
+noinst_HEADERS = plusd.h \
+ wd1770.h
Deleted: trunk/fuse/disk/plusd.c
===================================================================
--- vendor/fuse-emulator/current/fuse/disk/plusd.c 2007-06-28 13:18:42 UTC (rev 404)
+++ trunk/fuse/disk/plusd.c 2007-06-29 12:55:24 UTC (rev 405)
@@ -1,571 +0,0 @@
-/* plusd.c: Routines for handling the +D interface
- Copyright (c) 1999-2007 Stuart Brady, Fredrick Meunier, Philip Kendall,
- Dmitry Sanarin, Darren Salt
-
- $Id$
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
- Author contact information:
-
- Philip: phi...@sh...
-
- Stuart: sd...@nt...
-
-*/
-
-#include <config.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#ifdef HAVE_STRINGS_H
-#include <strings.h> /* Needed for strncasecmp() on QNX6 */
-#endif /* #ifdef HAVE_STRINGS_H */
-#include <limits.h>
-#include <sys/stat.h>
-
-#include <libdsk.h>
-
-#include <libspectrum.h>
-
-#include "compat.h"
-#include "event.h"
-#include "machine.h"
-#include "module.h"
-#include "plusd.h"
-#include "printer.h"
-#include "settings.h"
-#include "ui/ui.h"
-#include "utils.h"
-#include "wd1770.h"
-#include "z80/z80.h"
-
-int plusd_available = 0;
-int plusd_active = 0;
-int plusd_index_pulse = 0;
-
-wd1770_fdc plusd_fdc;
-wd1770_drive plusd_drives[ PLUSD_NUM_DRIVES ];
-
-static const char *plusd_template = "fuse.plusd.XXXXXX";
-
-static void plusd_reset( int hard_reset );
-static void plusd_memory_map( void );
-static void plusd_from_snapshot( libspectrum_snap *snap );
-static void plusd_to_snapshot( libspectrum_snap *snap );
-
-static module_info_t plusd_module_info = {
-
- plusd_reset,
- plusd_memory_map,
- plusd_from_snapshot,
- plusd_to_snapshot,
-
-};
-
-void
-plusd_page( void )
-{
- plusd_active = 1;
- machine_current->ram.romcs = 1;
- machine_current->memory_map();
-}
-
-void
-plusd_unpage( void )
-{
- plusd_active = 0;
- machine_current->ram.romcs = 0;
- machine_current->memory_map();
-}
-
-static void
-plusd_memory_map( void )
-{
- if( !plusd_active ) return;
-
- memory_map_read[ 0 ] = memory_map_write[ 0 ] = memory_map_romcs[ 0 ];
- memory_map_read[ 1 ] = memory_map_write[ 1 ] = memory_map_ram[ 16 * 2 ];
-}
-
-void
-plusd_set_cmdint( wd1770_fdc *f )
-{
- z80_interrupt();
-}
-
-const periph_t plusd_peripherals[] = {
- /* ---- ---- 1110 0011 */
- { 0x00ff, 0x00e3, plusd_sr_read, plusd_cr_write },
- /* ---- ---- 1110 1011 */
- { 0x00ff, 0x00eb, plusd_tr_read, plusd_tr_write },
- /* ---- ---- 1111 0011 */
- { 0x00ff, 0x00f3, plusd_sec_read, plusd_sec_write },
- /* ---- ---- 1111 1011 */
- { 0x00ff, 0x00fb, plusd_dr_read, plusd_dr_write },
-
- /* ---- ---- 1110 1111 */
- { 0x00ff, 0x00ef, NULL, plusd_cn_write },
- /* ---- ---- 1110 0111 */
- { 0x00ff, 0x00e7, plusd_mem_read, plusd_mem_write },
- /* 0000 0000 1111 0111 */
- { 0x00ff, 0x00f7, plusd_printer_read, printer_parallel_write },
-};
-
-const size_t plusd_peripherals_count =
- sizeof( plusd_peripherals ) / sizeof( periph_t );
-
-int
-plusd_init( void )
-{
- int i;
- wd1770_drive *d;
-
- plusd_fdc.current_drive = &plusd_drives[ 0 ];
-
- for( i = 0; i < PLUSD_NUM_DRIVES; i++ ) {
- d = &plusd_drives[ i ];
-
- d->disk = NULL;
- d->filename[0] = '\0';
- }
-
- plusd_fdc.set_cmdint = &plusd_set_cmdint;
- plusd_fdc.reset_cmdint = NULL;
- plusd_fdc.set_datarq = NULL;
- plusd_fdc.reset_datarq = NULL;
- plusd_fdc.iface = NULL;
-
- plusd_fdc.rates[ 0 ] = 6;
- plusd_fdc.rates[ 1 ] = 12;
- plusd_fdc.rates[ 2 ] = 2;
- plusd_fdc.rates[ 3 ] = 3;
-
- module_register( &plusd_module_info );
-
- return 0;
-}
-
-static void
-plusd_reset( int hard_reset )
-{
- int i;
- wd1770_drive *d;
- wd1770_fdc *f = &plusd_fdc;
-
- plusd_available = 0;
-
- if( !periph_plusd_active )
- return;
-
- machine_load_rom_bank( memory_map_romcs, 0, 0,
- settings_default.rom_plusd,
- settings_current.rom_plusd, 0x2000 );
-
- memory_map_romcs[0].source = MEMORY_SOURCE_PERIPHERAL;
-
- machine_current->ram.romcs = 0;
-
- memory_map_romcs[ 0 ].writable = 0;
- memory_map_romcs[ 1 ].writable = 0;
- memory_map_ram[ 16 * 2 ].writable = 1;
-
- plusd_available = 1;
- plusd_active = 0;
- plusd_index_pulse = 0;
-
- if( hard_reset ) {
- for( i = 0; i < 8192; i++ ) {
- memory_map_ram[ 16 * 2 ].page[ i ] = 0;
- }
- }
-
- f->spin_cycles = 0;
- f->direction = 0;
-
- f->state = wd1770_state_none;
- f->status_type = wd1770_status_type1;
-
- f->status_register = 0;
- f->track_register = 0;
- f->sector_register = 0;
- f->data_register = 0;
-
- for( i = 0; i < PLUSD_NUM_DRIVES; i++ ) {
- d = &plusd_drives[ i ];
-
- d->index_pulse = 0;
- d->index_interrupt = 0;
- d->track = 0;
- d->side = 0;
- }
-
- f->status_register |= WD1770_SR_LOST; /* track 0 */
-
- /* We can eject disks only if they are currently present */
- ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_PLUSD_1_EJECT,
- !!plusd_drives[ PLUSD_DRIVE_1 ].disk );
- ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_PLUSD_2_EJECT,
- !!plusd_drives[ PLUSD_DRIVE_2 ].disk );
-
- plusd_fdc.current_drive = &plusd_drives[ 0 ];
- machine_current->memory_map();
- plusd_event_index( 0 );
-
- ui_statusbar_update( UI_STATUSBAR_ITEM_DISK, UI_STATUSBAR_STATE_INACTIVE );
-}
-
-void
-plusd_end( void )
-{
- plusd_available = 0;
-}
-
-libspectrum_byte
-plusd_sr_read( libspectrum_word port GCC_UNUSED, int *attached )
-{
- *attached = 1;
- return wd1770_sr_read( &plusd_fdc );
-}
-
-void
-plusd_cr_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b )
-{
- wd1770_cr_write( &plusd_fdc, b );
-}
-
-libspectrum_byte
-plusd_tr_read( libspectrum_word port GCC_UNUSED, int *attached )
-{
- *attached = 1;
- return wd1770_tr_read( &plusd_fdc );
-}
-
-void
-plusd_tr_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b )
-{
- wd1770_tr_write( &plusd_fdc, b );
-}
-
-libspectrum_byte
-plusd_sec_read( libspectrum_word port GCC_UNUSED, int *attached )
-{
- *attached = 1;
- return wd1770_sec_read( &plusd_fdc );
-}
-
-void
-plusd_sec_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b )
-{
- wd1770_sec_write( &plusd_fdc, b );
-}
-
-libspectrum_byte
-plusd_dr_read( libspectrum_word port GCC_UNUSED, int *attached )
-{
- *attached = 1;
- return wd1770_dr_read( &plusd_fdc );
-}
-
-void
-plusd_dr_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b )
-{
- wd1770_dr_write( &plusd_fdc, b );
-}
-
-void
-plusd_cn_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b )
-{
- int drive, side;
- int i;
-
- drive = ( b & 0x03 ) == 2 ? 1 : 0;
- side = ( b & 0x80 ) ? 1 : 0;
-
- /* TODO: set current_drive to NULL when bits 0 and 1 of b are '00' or '11' */
- plusd_fdc.current_drive = &plusd_drives[ drive ];
-
- for( i = 0; i < PLUSD_NUM_DRIVES; i++ ) {
- plusd_drives[ i ].side = side;
- }
-
- printer_parallel_strobe_write( b & 0x40 );
-}
-
-libspectrum_byte
-plusd_mem_read( libspectrum_word port GCC_UNUSED, int *attached )
-{
- plusd_page();
- return 0;
-}
-
-void
-plusd_mem_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b )
-{
- plusd_unpage();
-}
-
-libspectrum_byte
-plusd_printer_read( libspectrum_word port GCC_UNUSED, int *attached )
-{
- *attached = 1;
-
- /* bit 7 = busy. other bits high? */
-
- if(!settings_current.printer)
- return(0xff); /* no printer attached */
-
- return(0x7f); /* never busy */
-}
-
-int
-plusd_disk_insert_default_autoload( plusd_drive_number which,
- const char *filename )
-{
- return plusd_disk_insert( which, filename, settings_current.auto_load );
-}
-
-int
-plusd_disk_insert( plusd_drive_number which, const char *filename,
- int autoload )
-{
- int fd, error;
- char tempfilename[ PATH_MAX ];
- int israw = 0;
- dsk_format_t fmt;
- wd1770_drive *d;
- int l;
-
- if( which >= PLUSD_NUM_DRIVES ) {
- ui_error( UI_ERROR_ERROR, "plusd_disk_insert: unknown drive %d",
- which );
- fuse_abort();
- }
-
- d = &plusd_drives[ which ];
-
- /* Eject any disk already in the drive */
- if( d->disk ) {
- /* Abort the insert if we want to keep the current disk */
- if( plusd_disk_eject( which, 0 ) ) return 0;
- }
-
- /* Make a temporary copy of the disk file */
- error = utils_make_temp_file( &fd, tempfilename, filename, plusd_template );
- if( error ) return error;
- strcpy( d->filename, tempfilename );
-
- /* Determine the disk image format */
- l = strlen( filename );
- if( l >= 5 ) {
- if( !strcmp( filename + ( l - 4 ), ".dsk" ) ||
- !strcmp( filename + ( l - 4 ), ".mgt" ) ) {
- israw = 1;
- fmt = FMT_800K;
- } else if( !strcmp( filename + ( l - 4 ), ".img" ) ) {
- israw = 1;
- fmt = FMT_MGT800;
- }
- }
-
- /* And now insert the disk */
- if( israw ) {
-
- /* If the "logical" driver is not available, try the "raw" driver (unless
- * we're using FMT_MGT800, for which the raw driver will not work */
- if( dsk_open( &d->disk, tempfilename, "logical", NULL ) != DSK_ERR_OK &&
- ( fmt == FMT_MGT800 ||
- dsk_open( &d->disk, tempfilename, "raw", NULL ) != DSK_ERR_OK ) ) {
- ui_error( UI_ERROR_ERROR, "Failed to open disk image" );
- return 1;
- }
-
- if( dg_stdformat( &d->geom, fmt, NULL, NULL ) != DSK_ERR_OK ) {
- ui_error( UI_ERROR_ERROR, "Failed to set geometry for disk" );
- dsk_close( &d->disk );
- return 1;
- }
-
- } else {
-
- if( dsk_open( &d->disk, tempfilename, NULL, NULL ) != DSK_ERR_OK ) {
- ui_error( UI_ERROR_ERROR, "Failed to open disk image" );
- return 1;
- }
-
- if( dsk_getgeom( d->disk, &d->geom ) != DSK_ERR_OK ) {
- ui_error( UI_ERROR_ERROR, "Failed to determine geometry for disk" );
- dsk_close( &d->disk );
- return 1;
- }
-
- }
-
- /* Set the 'eject' item active */
- switch( which ) {
- case PLUSD_DRIVE_1:
- ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_PLUSD_1_EJECT, 1 );
- break;
- case PLUSD_DRIVE_2:
- ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_PLUSD_2_EJECT, 1 );
- break;
- }
-
- if( autoload ) {
- /* XXX */
- }
-
- return 0;
-}
-
-int
-plusd_disk_eject( plusd_drive_number which, int write )
-{
- wd1770_drive *d;
-
- if( which >= PLUSD_NUM_DRIVES )
- return 1;
-
- d = &plusd_drives[ which ];
-
- if( !d->disk )
- return 0;
-
- if( write ) {
-
- if( ui_plusd_disk_write( which ) ) return 1;
-
- } else {
-
- if( dsk_dirty( plusd_drives[which].disk ) ) {
-
- ui_confirm_save_t confirm = ui_confirm_save(
- "Disk has been modified.\nDo you want to save it?"
- );
-
- switch( confirm ) {
-
- case UI_CONFIRM_SAVE_SAVE:
- if( ui_plusd_disk_write( which ) ) return 1;
- break;
-
- case UI_CONFIRM_SAVE_DONTSAVE: break;
- case UI_CONFIRM_SAVE_CANCEL: return 1;
-
- }
- }
- }
-
- dsk_close( &d->disk );
- unlink( d->filename );
-
- /* Set the 'eject' item inactive */
- switch( which ) {
- case PLUSD_DRIVE_1:
- ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_PLUSD_1_EJECT, 0 );
- break;
- case PLUSD_DRIVE_2:
- ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_PLUSD_2_EJECT, 0 );
- break;
- }
- return 0;
-}
-
-int
-plusd_disk_write( plusd_drive_number which, const char *filename )
-{
- wd1770_drive *d = &plusd_drives[ which ];
- utils_file file;
- FILE *f;
- int error;
- size_t bytes_written;
-
- dsk_close( &d->disk );
-
- f = fopen( filename, "wb" );
- if( !f ) {
- ui_error( UI_ERROR_ERROR, "couldn't open '%s' for writing: %s", filename,
- strerror( errno ) );
- }
-
- error = utils_read_file( d->filename, &file );
- if( error ) { fclose( f ); return error; }
-
- bytes_written = fwrite( file.buffer, 1, file.length, f );
- if( bytes_written != file.length ) {
- ui_error( UI_ERROR_ERROR, "could write only %lu of %lu bytes to '%s'",
- (unsigned long)bytes_written, (unsigned long)file.length,
- filename );
- utils_close_file( &file ); fclose( f );
- }
-
- error = utils_close_file( &file ); if( error ) { fclose( f ); return error; }
-
- if( fclose( f ) ) {
- ui_error( UI_ERROR_ERROR, "error closing '%s': %s", filename,
- strerror( errno ) );
- return 1;
- }
-
- return 0;
-}
-
-int
-plusd_event_cmd_done( libspectrum_dword last_tstates )
-{
- plusd_fdc.status_register &= ~WD1770_SR_BUSY;
- return 0;
-}
-
-int
-plusd_event_index( libspectrum_dword last_tstates )
-{
- int error;
- int next_tstates;
- int i;
-
- plusd_index_pulse = !plusd_index_pulse;
- for( i = 0; i < PLUSD_NUM_DRIVES; i++ ) {
- wd1770_drive *d = &plusd_drives[ i ];
-
- d->index_pulse = plusd_index_pulse;
- if( !plusd_index_pulse && d->index_interrupt ) {
- wd1770_set_cmdint( &plusd_fdc );
- d->index_interrupt = 0;
- }
- }
- next_tstates = ( plusd_index_pulse ? 10 : 190 ) *
- machine_current->timings.processor_speed / 1000;
- error = event_add( last_tstates + next_tstates, EVENT_TYPE_PLUSD_INDEX );
- if( error )
- return error;
- return 0;
-}
-
-static void
-plusd_from_snapshot( libspectrum_snap *snap )
-{
- /* XXX */
-}
-
-static void
-plusd_to_snapshot( libspectrum_snap *snap )
-{
- /* XXX */
-}
Copied: trunk/fuse/disk/plusd.c (from rev 404, vendor/fuse-emulator/current/fuse/disk/plusd.c)
===================================================================
--- trunk/fuse/disk/plusd.c (rev 0)
+++ trunk/fuse/disk/plusd.c 2007-06-29 12:55:24 UTC (rev 405)
@@ -0,0 +1,571 @@
+/* plusd.c: Routines for handling the +D interface
+ Copyright (c) 1999-2007 Stuart Brady, Fredrick Meunier, Philip Kendall,
+ Dmitry Sanarin, Darren Salt
+
+ $Id$
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Author contact information:
+
+ Philip: phi...@sh...
+
+ Stuart: sd...@nt...
+
+*/
+
+#include <config.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h> /* Needed for strncasecmp() on QNX6 */
+#endif /* #ifdef HAVE_STRINGS_H */
+#include <limits.h>
+#include <sys/stat.h>
+
+#include <libdsk.h>
+
+#include <libspectrum.h>
+
+#include "compat.h"
+#include "event.h"
+#include "machine.h"
+#include "module.h"
+#include "plusd.h"
+#include "printer.h"
+#include "settings.h"
+#include "ui/ui.h"
+#include "utils.h"
+#include "wd1770.h"
+#include "z80/z80.h"
+
+int plusd_available = 0;
+int plusd_active = 0;
+int plusd_index_pulse = 0;
+
+wd1770_fdc plusd_fdc;
+wd1770_drive plusd_drives[ PLUSD_NUM_DRIVES ];
+
+static const char *plusd_template = "fuse.plusd.XXXXXX";
+
+static void plusd_reset( int hard_reset );
+static void plusd_memory_map( void );
+static void plusd_from_snapshot( libspectrum_snap *snap );
+static void plusd_to_snapshot( libspectrum_snap *snap );
+
+static module_info_t plusd_module_info = {
+
+ plusd_reset,
+ plusd_memory_map,
+ plusd_from_snapshot,
+ plusd_to_snapshot,
+
+};
+
+void
+plusd_page( void )
+{
+ plusd_active = 1;
+ machine_current->ram.romcs = 1;
+ machine_current->memory_map();
+}
+
+void
+plusd_unpage( void )
+{
+ plusd_active = 0;
+ machine_current->ram.romcs = 0;
+ machine_current->memory_map();
+}
+
+static void
+plusd_memory_map( void )
+{
+ if( !plusd_active ) return;
+
+ memory_map_read[ 0 ] = memory_map_write[ 0 ] = memory_map_romcs[ 0 ];
+ memory_map_read[ 1 ] = memory_map_write[ 1 ] = memory_map_ram[ 16 * 2 ];
+}
+
+void
+plusd_set_cmdint( wd1770_fdc *f )
+{
+ z80_interrupt();
+}
+
+const periph_t plusd_peripherals[] = {
+ /* ---- ---- 1110 0011 */
+ { 0x00ff, 0x00e3, plusd_sr_read, plusd_cr_write },
+ /* ---- ---- 1110 1011 */
+ { 0x00ff, 0x00eb, plusd_tr_read, plusd_tr_write },
+ /* ---- ---- 1111 0011 */
+ { 0x00ff, 0x00f3, plusd_sec_read, plusd_sec_write },
+ /* ---- ---- 1111 1011 */
+ { 0x00ff, 0x00fb, plusd_dr_read, plusd_dr_write },
+
+ /* ---- ---- 1110 1111 */
+ { 0x00ff, 0x00ef, NULL, plusd_cn_write },
+ /* ---- ---- 1110 0111 */
+ { 0x00ff, 0x00e7, plusd_mem_read, plusd_mem_write },
+ /* 0000 0000 1111 0111 */
+ { 0x00ff, 0x00f7, plusd_printer_read, printer_parallel_write },
+};
+
+const size_t plusd_peripherals_count =
+ sizeof( plusd_peripherals ) / sizeof( periph_t );
+
+int
+plusd_init( void )
+{
+ int i;
+ wd1770_drive *d;
+
+ plusd_fdc.current_drive = &plusd_drives[ 0 ];
+
+ for( i = 0; i < PLUSD_NUM_DRIVES; i++ ) {
+ d = &plusd_drives[ i ];
+
+ d->disk = NULL;
+ d->filename[0] = '\0';
+ }
+
+ plusd_fdc.set_cmdint = &plusd_set_cmdint;
+ plusd_fdc.reset_cmdint = NULL;
+ plusd_fdc.set_datarq = NULL;
+ plusd_fdc.reset_datarq = NULL;
+ plusd_fdc.iface = NULL;
+
+ plusd_fdc.rates[ 0 ] = 6;
+ plusd_fdc.rates[ 1 ] = 12;
+ plusd_fdc.rates[ 2 ] = 2;
+ plusd_fdc.rates[ 3 ] = 3;
+
+ module_register( &plusd_module_info );
+
+ return 0;
+}
+
+static void
+plusd_reset( int hard_reset )
+{
+ int i;
+ wd1770_drive *d;
+ wd1770_fdc *f = &plusd_fdc;
+
+ plusd_available = 0;
+
+ if( !periph_plusd_active )
+ return;
+
+ machine_load_rom_bank( memory_map_romcs, 0, 0,
+ settings_default.rom_plusd,
+ settings_current.rom_plusd, 0x2000 );
+
+ memory_map_romcs[0].source = MEMORY_SOURCE_PERIPHERAL;
+
+ machine_current->ram.romcs = 0;
+
+ memory_map_romcs[ 0 ].writable = 0;
+ memory_map_romcs[ 1 ].writable = 0;
+ memory_map_ram[ 16 * 2 ].writable = 1;
+
+ plusd_available = 1;
+ plusd_active = 0;
+ plusd_index_pulse = 0;
+
+ if( hard_reset ) {
+ for( i = 0; i < 8192; i++ ) {
+ memory_map_ram[ 16 * 2 ].page[ i ] = 0;
+ }
+ }
+
+ f->spin_cycles = 0;
+ f->direction = 0;
+
+ f->state = wd1770_state_none;
+ f->status_type = wd1770_status_type1;
+
+ f->status_register = 0;
+ f->track_register = 0;
+ f->sector_register = 0;
+ f->data_register = 0;
+
+ for( i = 0; i < PLUSD_NUM_DRIVES; i++ ) {
+ d = &plusd_drives[ i ];
+
+ d->index_pulse = 0;
+ d->index_interrupt = 0;
+ d->track = 0;
+ d->side = 0;
+ }
+
+ f->status_register |= WD1770_SR_LOST; /* track 0 */
+
+ /* We can eject disks only if they are currently present */
+ ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_PLUSD_1_EJECT,
+ !!plusd_drives[ PLUSD_DRIVE_1 ].disk );
+ ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_PLUSD_2_EJECT,
+ !!plusd_drives[ PLUSD_DRIVE_2 ].disk );
+
+ plusd_fdc.current_drive = &plusd_drives[ 0 ];
+ machine_current->memory_map();
+ plusd_event_index( 0 );
+
+ ui_statusbar_update( UI_STATUSBAR_ITEM_DISK, UI_STATUSBAR_STATE_INACTIVE );
+}
+
+void
+plusd_end( void )
+{
+ plusd_available = 0;
+}
+
+libspectrum_byte
+plusd_sr_read( libspectrum_word port GCC_UNUSED, int *attached )
+{
+ *attached = 1;
+ return wd1770_sr_read( &plusd_fdc );
+}
+
+void
+plusd_cr_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b )
+{
+ wd1770_cr_write( &plusd_fdc, b );
+}
+
+libspectrum_byte
+plusd_tr_read( libspectrum_word port GCC_UNUSED, int *attached )
+{
+ *attached = 1;
+ return wd1770_tr_read( &plusd_fdc );
+}
+
+void
+plusd_tr_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b )
+{
+ wd1770_tr_write( &plusd_fdc, b );
+}
+
+libspectrum_byte
+plusd_sec_read( libspectrum_word port GCC_UNUSED, int *attached )
+{
+ *attached = 1;
+ return wd1770_sec_read( &plusd_fdc );
+}
+
+void
+plusd_sec_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b )
+{
+ wd1770_sec_write( &plusd_fdc, b );
+}
+
+libspectrum_byte
+plusd_dr_read( libspectrum_word port GCC_UNUSED, int *attached )
+{
+ *attached = 1;
+ return wd1770_dr_read( &plusd_fdc );
+}
+
+void
+plusd_dr_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b )
+{
+ wd1770_dr_write( &plusd_fdc, b );
+}
+
+void
+plusd_cn_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b )
+{
+ int drive, side;
+ int i;
+
+ drive = ( b & 0x03 ) == 2 ? 1 : 0;
+ side = ( b & 0x80 ) ? 1 : 0;
+
+ /* TODO: set current_drive to NULL when bits 0 and 1 of b are '00' or '11' */
+ plusd_fdc.current_drive = &plusd_drives[ drive ];
+
+ for( i = 0; i < PLUSD_NUM_DRIVES; i++ ) {
+ plusd_drives[ i ].side = side;
+ }
+
+ printer_parallel_strobe_write( b & 0x40 );
+}
+
+libspectrum_byte
+plusd_mem_read( libspectrum_word port GCC_UNUSED, int *attached )
+{
+ plusd_page();
+ return 0;
+}
+
+void
+plusd_mem_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b )
+{
+ plusd_unpage();
+}
+
+libspectrum_byte
+plusd_printer_read( libspectrum_word port GCC_UNUSED, int *attached )
+{
+ *attached = 1;
+
+ /* bit 7 = busy. other bits high? */
+
+ if(!settings_current.printer)
+ return(0xff); /* no printer attached */
+
+ return(0x7f); /* never busy */
+}
+
+int
+plusd_disk_insert_default_autoload( plusd_drive_number which,
+ const char *filename )
+{
+ return plusd_disk_insert( which, filename, settings_current.auto_load );
+}
+
+int
+plusd_disk_insert( plusd_drive_number which, const char *filename,
+ int autoload )
+{
+ int fd, error;
+ char tempfilename[ PATH_MAX ];
+ int israw = 0;
+ dsk_format_t fmt;
+ wd1770_drive *d;
+ int l;
+
+ if( which >= PLUSD_NUM_DRIVES ) {
+ ui_error( UI_ERROR_ERROR, "plusd_disk_insert: unknown drive %d",
+ which );
+ fuse_abort();
+ }
+
+ d = &plusd_drives[ which ];
+
+ /* Eject any disk already in the drive */
+ if( d->disk ) {
+ /* Abort the insert if we want to keep the current disk */
+ if( plusd_disk_eject( which, 0 ) ) return 0;
+ }
+
+ /* Make a temporary copy of the disk file */
+ error = utils_make_temp_file( &fd, tempfilename, filename, plusd_template );
+ if( error ) return error;
+ strcpy( d->filename, tempfilename );
+
+ /* Determine the disk image format */
+ l = strlen( filename );
+ if( l >= 5 ) {
+ if( !strcmp( filename + ( l - 4 ), ".dsk" ) ||
+ !strcmp( filename + ( l - 4 ), ".mgt" ) ) {
+ israw = 1;
+ fmt = FMT_800K;
+ } else if( !strcmp( filename + ( l - 4 ), ".img" ) ) {
+ israw = 1;
+ fmt = FMT_MGT800;
+ }
+ }
+
+ /* And now insert the disk */
+ if( israw ) {
+
+ /* If the "logical" driver is not available, try the "raw" driver (unless
+ * we're using FMT_MGT800, for which the raw driver will not work */
+ if( dsk_open( &d->disk, tempfilename, "logical", NULL ) != DSK_ERR_OK &&
+ ( fmt == FMT_MGT800 ||
+ dsk_open( &d->disk, tempfilename, "raw", NULL ) != DSK_ERR_OK ) ) {
+ ui_error( UI_ERROR_ERROR, "Failed to open disk image" );
+ return 1;
+ }
+
+ if( dg_stdformat( &d->geom, fmt, NULL, NULL ) != DSK_ERR_OK ) {
+ ui_error( UI_ERROR_ERROR, "Failed to set geometry for disk" );
+ dsk_close( &d->disk );
+ return 1;
+ }
+
+ } else {
+
+ if( dsk_open( &d->disk, tempfilename, NULL, NULL ) != DSK_ERR_OK ) {
+ ui_error( UI_ERROR_ERROR, "Failed to open disk image" );
+ return 1;
+ }
+
+ if( dsk_getgeom( d->disk, &d->geom ) != DSK_ERR_OK ) {
+ ui_error( UI_ERROR_ERROR, "Failed to determine geometry for disk" );
+ dsk_close( &d->disk );
+ return 1;
+ }
+
+ }
+
+ /* Set the 'eject' item active */
+ switch( which ) {
+ case PLUSD_DRIVE_1:
+ ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_PLUSD_1_EJECT, 1 );
+ break;
+ case PLUSD_DRIVE_2:
+ ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_PLUSD_2_EJECT, 1 );
+ break;
+ }
+
+ if( autoload ) {
+ /* XXX */
+ }
+
+ return 0;
+}
+
+int
+plusd_disk_eject( plusd_drive_number which, int write )
+{
+ wd1770_drive *d;
+
+ if( which >= PLUSD_NUM_DRIVES )
+ return 1;
+
+ d = &plusd_drives[ which ];
+
+ if( !d->disk )
+ return 0;
+
+ if( write ) {
+
+ if( ui_plusd_disk_write( which ) ) return 1;
+
+ } else {
+
+ if( dsk_dirty( plusd_drives[which].disk ) ) {
+
+ ui_confirm_save_t confirm = ui_confirm_save(
+ "Disk has been modified.\nDo you want to save it?"
+ );
+
+ switch( confirm ) {
+
+ case UI_CONFIRM_SAVE_SAVE:
+ if( ui_plusd_disk_write( which ) ) return 1;
+ break;
+
+ case UI_CONFIRM_SAVE_DONTSAVE: break;
+ case UI_CONFIRM_SAVE_CANCEL: return 1;
+
+ }
+ }
+ }
+
+ dsk_close( &d->disk );
+ unlink( d->filename );
+
+ /* Set the 'eject' item inactive */
+ switch( which ) {
+ case PLUSD_DRIVE_1:
+ ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_PLUSD_1_EJECT, 0 );
+ break;
+ case PLUSD_DRIVE_2:
+ ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_PLUSD_2_EJECT, 0 );
+ break;
+ }
+ return 0;
+}
+
+int
+plusd_disk_write( plusd_drive_number which, const char *filename )
+{
+ wd1770_drive *d = &plusd_drives[ which ];
+ utils_file file;
+ FILE *f;
+ int error;
+ size_t bytes_written;
+
+ dsk_close( &d->disk );
+
+ f = fopen( filename, "wb" );
+ if( !f ) {
+ ui_error( UI_ERROR_ERROR, "couldn't open '%s' for writing: %s", filename,
+ strerror( errno ) );
+ }
+
+ error = utils_read_file( d->filename, &file );
+ if( error ) { fclose( f ); return error; }
+
+ bytes_written = fwrite( file.buffer, 1, file.length, f );
+ if( bytes_written != file.length ) {
+ ui_error( UI_ERROR_ERROR, "could write only %lu of %lu bytes to '%s'",
+ (unsigned long)bytes_written, (unsigned long)file.length,
+ filename );
+ utils_close_file( &file ); fclose( f );
+ }
+
+ error = utils_close_file( &file ); if( error ) { fclose( f ); return error; }
+
+ if( fclose( f ) ) {
+ ui_error( UI_ERROR_ERROR, "error closing '%s': %s", filename,
+ strerror( errno ) );
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+plusd_event_cmd_done( libspectrum_dword last_tstates )
+{
+ plusd_fdc.status_register &= ~WD1770_SR_BUSY;
+ return 0;
+}
+
+int
+plusd_event_index( libspectrum_dword last_tstates )
+{
+ int error;
+ int next_tstates;
+ int i;
+
+ plusd_index_pulse = !plusd_index_pulse;
+ for( i = 0; i < PLUSD_NUM_DRIVES; i++ ) {
+ wd1770_drive *d = &plusd_drives[ i ];
+
+ d->index_pulse = plusd_index_pulse;
+ if( !plusd_index_pulse && d->index_interrupt ) {
+ wd1770_set_cmdint( &plusd_fdc );
+ d->index_interrupt = 0;
+ }
+ }
+ next_tstates = ( plusd_index_pulse ? 10 : 190 ) *
+ machine_current->timings.processor_speed / 1000;
+ error = event_add( last_tstates + next_tstates, EVENT_TYPE_PLUSD_INDEX );
+ if( error )
+ return error;
+ return 0;
+}
+
+static void
+plusd_from_snapshot( libspectrum_snap *snap )
+{
+ /* XXX */
+}
+
+static void
+plusd_to_snapshot( libspectrum_snap *snap )
+{
+ /* XXX */
+}
Deleted: trunk/fuse/disk/plusd.h
===================================================================
--- vendor/fuse-emulator/current/fuse/disk/plusd.h 2007-06-28 13:18:42 UTC (rev 404)
+++ trunk/fuse/disk/plusd.h 2007-06-29 12:55:24 UTC (rev 405)
@@ -1,94 +0,0 @@
-/* plusd.h: Routines for handling the +D interface
- Copyright (c) 2005-2007 Stuart Brady
-
- $Id$
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
- Author contact information:
-
- Philip: phi...@sh...
-
- Stuart: sd...@nt...
-
-*/
-
-#ifndef FUSE_PLUSD_H
-#define FUSE_PLUSD_H
-
-#include <config.h>
-
-typedef enum plusd_drive_number {
- PLUSD_DRIVE_1 = 0,
- PLUSD_DRIVE_2,
-} plusd_drive_number;
-
-#ifdef HAVE_LIBDSK_H
-
-#include <libspectrum.h>
-
-#include "wd1770.h"
-#include "periph.h"
-
-extern int plusd_available; /* Is the +D available for use? */
-extern int plusd_active; /* +D enabled? */
-extern int plusd_index_pulse;
-
-extern const periph_t plusd_peripherals[];
-extern const size_t plusd_peripherals_count;
-
-int plusd_init( void );
-void plusd_end( void );
-
-void plusd_page( void );
-void plusd_unpage( void );
-
-libspectrum_byte plusd_sr_read( libspectrum_word port, int *attached );
-void plusd_cr_write( libspectrum_word port, libspectrum_byte b );
-
-libspectrum_byte plusd_tr_read( libspectrum_word port, int *attached );
-void plusd_tr_write( libspectrum_word port, libspectrum_byte b );
-
-libspectrum_byte plusd_sec_read( libspectrum_word port, int *attached );
-void plusd_sec_write( libspectrum_word port, libspectrum_byte b );
-
-libspectrum_byte plusd_dr_read( libspectrum_word port, int *attached );
-void plusd_dr_write( libspectrum_word port, libspectrum_byte b );
-
-libspectrum_byte plusd_joy_read( libspectrum_word port, int *attached );
-void plusd_cn_write( libspectrum_word port, libspectrum_byte b );
-
-libspectrum_byte plusd_mem_read( libspectrum_word port, int *attached );
-void plusd_mem_write( libspectrum_word port, libspectrum_byte b );
-
-libspectrum_byte plusd_printer_read( libspectrum_word port, int *attached );
-
-extern wd1770_fdc plusd_fdc;
-
-#define PLUSD_NUM_DRIVES 2
-extern wd1770_drive plusd_drives[ PLUSD_NUM_DRIVES ];
-
-int plusd_disk_insert( plusd_drive_number which, const char *filename,
- int autoload );
-int plusd_disk_insert_default_autoload( plusd_drive_number which,
- const char *filename );
-int plusd_disk_eject( plusd_drive_number which, int write );
-int plusd_disk_write( plusd_drive_number which, const char *filename );
-int plusd_event_cmd_done( libspectrum_dword last_tstates );
-int plusd_event_index( libspectrum_dword last_tstates );
-
-#endif /* #ifndef HAVE_LIBDSK_H */
-
-#endif /* #ifndef FUSE_PLUSD_H */
Copied: trunk/fuse/disk/plusd.h (from rev 404, vendor/fuse-emulator/current/fuse/disk/plusd.h)
===================================================================
--- trunk/fuse/disk/plusd.h (rev 0)
+++ trunk/fuse/disk/plusd.h 2007-06-29 12:55:24 UTC (rev 405)
@@ -0,0 +1,94 @@
+/* plusd.h: Routines for handling the +D interface
+ Copyright (c) 2005-2007 Stuart Brady
+
+ $Id$
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Author contact information:
+
+ Philip: phi...@sh...
+
+ Stuart: sd...@nt...
+
+*/
+
+#ifndef FUSE_PLUSD_H
+#define FUSE_PLUSD_H
+
+#include <config.h>
+
+typedef enum plusd_drive_number {
+ PLUSD_DRIVE_1 = 0,
+ PLUSD_DRIVE_2,
+} plusd_drive_number;
+
+#ifdef HAVE_LIBDSK_H
+
+#include <libspectrum.h>
+
+#include "wd1770.h"
+#include "periph.h"
+
+extern int plusd_available; /* Is the +D available for use? */
+extern int plusd_active; /* +D enabled? */
+extern int plusd_index_pulse;
+
+extern const periph_t plusd_peripherals[];
+extern const size_t plusd_peripherals_count;
+
+int plusd_init( void );
+void plusd_end( void );
+
+void plusd_page( void );
+void plusd_unpage( void );
+
+libspectrum_byte plusd_sr_read( libspectrum_word port, int *attached );
+void plusd_cr_write( libspectrum_word port, libspectrum_byte b );
+
+libspectrum_byte plusd_tr_read( libspectrum_word port, int *attached );
+void plusd_tr_write( libspectrum_word port, libspectrum_byte b );
+
+libspectrum_byte plusd_sec_read( libspectrum_word port, int *attached );
+void plusd_sec_write( libspectrum_word port, libspectrum_byte b );
+
+libspectrum_byte plusd_dr_read( libspectrum_word port, int *attached );
+void plusd_dr_write( libspectrum_word port, libspectrum_byte b );
+
+libspectrum_byte plusd_joy_read( libspectrum_word port, int *attached );
+void plusd_cn_write( libspectrum_word port, libspectrum_byte b );
+
+libspectrum_byte plusd_mem_read( libspectrum_word port, int *attached );
+void plusd_mem_write( libspectrum_word port, libspectrum_byte b );
+
+libspectrum_byte plusd_printer_read( libspectrum_word port, int *attached );
+
+extern wd1770_fdc plusd_fdc;
+
+#define PLUSD_NUM_DRIVES 2
+extern wd1770_drive plusd_drives[ PLUSD_NUM_DRIVES ];
+
+int plusd_disk_insert( plusd_drive_number which, const char *filename,
+ int autoload );
+int plusd_disk_insert_default_autoload( plusd_drive_number which,
+ const char *filename );
+int plusd_disk_eject( plusd_drive_number which, int write );
+int plusd_disk_write( plusd_drive_number which, const char *filename );
+int plusd_event_cmd_done( libspectrum_dword last_tstates );
+int plusd_event_index( libspectrum_dword last_tstates );
+
+#endif /* #ifndef HAVE_LIBDSK_H */
+
+#endif /* #ifndef FUSE_PLUSD_H */
Deleted: trunk/fuse/disk/wd1770.c
===================================================================
--- vendor/fuse-emulator/current/fuse/disk/wd1770.c 2007-06-28 13:18:42 UTC (rev 404)
+++ trunk/fuse/disk/wd1770.c 2007-06-29 12:55:24 UTC (rev 405)
@@ -1,389 +0,0 @@
-/* wd1770.c: Routines for handling the WD1770 floppy disk controller
- Copyright (c) 2002-2007 Stuart Brady, Fredrick Meunier, Philip Kendall,
- Dmitry Sanarin
-
- $Id$
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
- Author contact information:
-
- Philip: phi...@sh...
-
- Stuart: sd...@nt...
-
-*/
-
-#include <config.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#ifdef HAVE_STRINGS_H
-#include <strings.h> /* Needed for strncasecmp() on QNX6 */
-#endif /* #ifdef HAVE_STRINGS_H */
-#include <limits.h>
-#include <sys/stat.h>
-
-#include <libdsk.h>
-
-#include <libspectrum.h>
-
-#include "compat.h"
-#include "event.h"
-#include "machine.h"
-#include "ui/ui.h"
-#include "wd1770.h"
-#include "z80/z80.h"
-
-char secbuf[1024];
-
-void
-statusbar_update( int busy )
-{
- ui_statusbar_update( UI_STATUSBAR_ITEM_DISK,
- busy ? UI_STATUSBAR_STATE_ACTIVE :
- UI_STATUSBAR_STATE_INACTIVE );
-}
-
-void
-wd1770_set_cmdint( wd1770_fdc *f )
-{
- if( f->set_cmdint )
- f->set_cmdint( f );
-}
-
-void
-wd1770_reset_cmdint( wd1770_fdc *f )
-{
- if( f->reset_cmdint )
- f->reset_cmdint( f );
-}
-
-void
-wd1770_set_datarq( wd1770_fdc *f )
-{
- f->status_register |= WD1770_SR_IDX_DRQ;
- if( f->set_datarq )
- f->set_datarq( f );
-}
-
-void
-wd1770_reset_datarq( wd1770_fdc *f )
-{
- f->status_register &= ~WD1770_SR_IDX_DRQ;
- if( f->reset_datarq )
- f->reset_datarq( f );
-}
-
-static void
-wd1770_seek( wd1770_fdc *f, int track, int update, int verify )
-{
- wd1770_drive *d = f->current_drive;
-
- if( track < d->track ) {
- f->direction = -1;
- if( f->track_register == 0 )
- f->track_register = 255;
- else if( update ) {
- int trk = f->track_register;
-
- trk += track - d->track + 256;
- trk %= 256;
- f->track_register = trk;
- }
- } else if( track > d->track ) {
- f->direction = 1;
- if( f->track_register == 255 )
- f->track_register = 0;
- else if( update ) {
- int trk = f->track_register;
-
- trk += track - d->track;
- trk %= 256;
- f->track_register = trk;
- }
- }
-
- if( verify ) {
- if( track < 0 )
- f->status_register |= WD1770_SR_RNF;
- else if( track >= d->geom.dg_cylinders )
- f->status_register |= WD1770_SR_RNF;
- else
- f->status_register &= ~WD1770_SR_RNF;
- } else
- f->status_register &= ~WD1770_SR_RNF;
-
- if( track < 0 )
- track = 0;
- if( track > 255 )
- track = 255;
- d->track = track;
-
- if( d->track == 0 )
- f->status_register |= WD1770_SR_LOST;
- else
- f->status_register &= ~WD1770_SR_LOST;
-}
-
-libspectrum_byte
-wd1770_sr_read( wd1770_fdc *f )
-{
- wd1770_drive *d = f->current_drive;
-
- f->status_register &= ~( WD1770_SR_MOTORON | WD1770_SR_SPINUP |
- WD1770_SR_WRPROT | WD1770_SR_CRCERR );
- if( f->status_type == wd1770_status_type1 ) {
- f->status_register &= ~WD1770_SR_IDX_DRQ;
- if( !d->disk || d->index_pulse )
- f->status_register |= WD1770_SR_IDX_DRQ;
- }
- return f->status_register;
-}
-
-
-void
-wd1770_cr_write( wd1770_fdc *f, libspectrum_byte b )
-{
- wd1770_drive *d = f->current_drive;
-
- /* command register: */
- if( ( b & 0xf0 ) == 0xd0 ) { /* Type IV - Force Interrupt */
- statusbar_update(0);
- f->status_register &= ~WD1770_SR_BUSY;
- f->status_register &= ~WD1770_SR_WRPROT;
- f->status_register &= ~WD1770_SR_CRCERR;
- f->status_register &= ~WD1770_SR_IDX_DRQ;
- f->state = wd1770_state_none;
- f->status_type = wd1770_status_type1;
- if( d->track == 0 )
- f->status_register |= WD1770_SR_LOST;
- else
- f->status_register &= ~WD1770_SR_LOST;
- wd1770_reset_datarq( f );
- if( b & 0x08 )
- wd1770_set_cmdint( f );
- if( b & 0x04 )
- d->index_interrupt = 1;
- return;
- }
-
- if( f->status_register & WD1770_SR_BUSY )
- return;
-
- /*
- f->status_register |= WD1770_SR_BUSY;
- event_add( tstates +
- 10 * machine_current->timings.processor_speed / 1000,
- EVENT_TYPE_PLUSD_CMD_DONE );
- */
-
- if( !( b & 0x08 ) ) {
- f->spin_cycles = 5;
- f->status_register |= WD1770_SR_MOTORON;
- f->status_register |= WD1770_SR_SPINUP;
- }
-
- if( !( b & 0x80 ) ) { /* Type I */
- int update = b & 0x10 ? 1 : 0;
- int verify = b & 0x04 ? 1 : 0;
-/* int rate = b & 0x03 ? 1 : 0; */
-
- switch( ( b >> 5 ) & 0x03 ) {
- case 0x00:
- if( ( b & 0x4 ) ) { /* Restore */
- f->track_register = d->track;
- wd1770_seek( f, 0, update, verify );
- } else { /* Seek */
- wd1770_seek( f, f->data_register, 0, verify );
- }
- f->direction = 1;
- break;
- case 0x01: /* Step */
- wd1770_seek( f, d->track + f->direction, update, verify );
- break;
- case 0x02: /* Step In */
- wd1770_seek( f, d->track + 1, update, verify );
- break;
- case 0x03: /* Step Out */
- wd1770_seek( f, d->track - 1, update, verify );
- break;
- }
- f->status_type = wd1770_status_type1;
- wd1770_set_cmdint( f );
- wd1770_reset_datarq( f );
- } else if( !( b & 0x40 ) ) { /* Type II */
- int multisector = b & 0x10 ? 1 : 0;
-/* int delay = b & 0x04 ? 1 : 0; */
-
- if( !( b & 0x20 ) ) { /* Read Sector */
- f->state = wd1770_state_read;
- } else { /* Write Sector */
-/* int dammark = b & 0x01; */
-
- f->state = wd1770_state_write;
- }
- if( f->sector_register < d->geom.dg_secbase ||
- f->sector_register >= d->geom.dg_secbase + d->geom.dg_sectors ||
- d->track >= d->geom.dg_cylinders ||
- d->track < 0 ) {
- f->status_register |= WD1770_SR_RNF;
- wd1770_set_cmdint( f );
- wd1770_reset_datarq( f );
- } else {
- wd1770_set_datarq( f );
- statusbar_update(1);
- f->status_register |= WD1770_SR_BUSY;
- f->status_register &= ~( WD1770_SR_WRPROT | WD1770_SR_RNF |
- WD1770_SR_CRCERR | WD1770_SR_LOST );
- f->status_type = wd1770_status_type2;
- f->data_track = d->track;
- f->data_sector = f->sector_register;
- f->data_side = d->side;
- f->data_offset = 0;
- f->data_multisector = multisector;
- }
- } else if( ( b & 0xf0 ) != 0xd0 ) { /* Type III */
-/* int delay = b & 0x04; */
-
- switch( b & 0xf0 ) {
- case 0x00: /* Read Track */
- fprintf( stderr, "read track not yet implemented\n" );
- break;
- case 0x01: /* Write Track */
- fprintf( stderr, "write track not yet implemented\n" );
- break;
- case 0x02: /* Read Address */
- fprintf( stderr, "read address not yet implemented\n" );
- break;
- }
- f->status_type = wd1770_status_type2;
- }
-}
-
-libspectrum_byte
-wd1770_tr_read( wd1770_fdc *f )
-{
- return f->track_reg...
[truncated message content] |
|
From: <fr...@us...> - 2007-06-28 13:18:50
|
Revision: 404
http://svn.sourceforge.net/fuse-for-macosx/?rev=404&view=rev
Author: fredm
Date: 2007-06-28 06:18:42 -0700 (Thu, 28 Jun 2007)
Log Message:
-----------
Tag vendor/fuse-emulator/current as vendor/fuse-emulator/fuse-r3018.
Added Paths:
-----------
vendor/fuse-emulator/fuse-r3018/
Copied: vendor/fuse-emulator/fuse-r3018 (from rev 403, vendor/fuse-emulator/current)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fr...@us...> - 2007-06-28 13:18:20
|
Revision: 403
http://svn.sourceforge.net/fuse-for-macosx/?rev=403&view=rev
Author: fredm
Date: 2007-06-28 06:18:21 -0700 (Thu, 28 Jun 2007)
Log Message:
-----------
Load . into vendor/fuse-emulator/current.
Modified Paths:
--------------
vendor/fuse-emulator/current/fuse/Makefile.am
vendor/fuse-emulator/current/fuse/ay.c
vendor/fuse-emulator/current/fuse/ay.h
vendor/fuse-emulator/current/fuse/configure.in
vendor/fuse-emulator/current/fuse/dck.c
vendor/fuse-emulator/current/fuse/divide.c
vendor/fuse-emulator/current/fuse/divide.h
vendor/fuse-emulator/current/fuse/event.c
vendor/fuse-emulator/current/fuse/event.h
vendor/fuse-emulator/current/fuse/fuse.c
vendor/fuse-emulator/current/fuse/hacking/ChangeLog
vendor/fuse-emulator/current/fuse/if1.c
vendor/fuse-emulator/current/fuse/if1.h
vendor/fuse-emulator/current/fuse/if2.c
vendor/fuse-emulator/current/fuse/if2.h
vendor/fuse-emulator/current/fuse/joystick.c
vendor/fuse-emulator/current/fuse/joystick.h
vendor/fuse-emulator/current/fuse/keysyms.pl
vendor/fuse-emulator/current/fuse/machine.c
vendor/fuse-emulator/current/fuse/machine.h
vendor/fuse-emulator/current/fuse/machines/pentagon.c
vendor/fuse-emulator/current/fuse/machines/scorpion.c
vendor/fuse-emulator/current/fuse/machines/spec128.c
vendor/fuse-emulator/current/fuse/machines/spec16.c
vendor/fuse-emulator/current/fuse/machines/spec48.c
vendor/fuse-emulator/current/fuse/machines/spec_se.c
vendor/fuse-emulator/current/fuse/machines/specplus2.c
vendor/fuse-emulator/current/fuse/machines/specplus2a.c
vendor/fuse-emulator/current/fuse/machines/specplus3.c
vendor/fuse-emulator/current/fuse/machines/specplus3.h
vendor/fuse-emulator/current/fuse/machines/specplus3e.c
vendor/fuse-emulator/current/fuse/machines/tc2048.c
vendor/fuse-emulator/current/fuse/machines/tc2068.c
vendor/fuse-emulator/current/fuse/machines/ts2068.c
vendor/fuse-emulator/current/fuse/man/fuse.1
vendor/fuse-emulator/current/fuse/memory.c
vendor/fuse-emulator/current/fuse/memory.h
vendor/fuse-emulator/current/fuse/menu.c
vendor/fuse-emulator/current/fuse/menu_data.dat
vendor/fuse-emulator/current/fuse/periph.c
vendor/fuse-emulator/current/fuse/periph.h
vendor/fuse-emulator/current/fuse/printer.c
vendor/fuse-emulator/current/fuse/printer.h
vendor/fuse-emulator/current/fuse/roms/Makefile.am
vendor/fuse-emulator/current/fuse/rzx.c
vendor/fuse-emulator/current/fuse/rzx.h
vendor/fuse-emulator/current/fuse/scld.c
vendor/fuse-emulator/current/fuse/scld.h
vendor/fuse-emulator/current/fuse/settings.dat
vendor/fuse-emulator/current/fuse/simpleide.c
vendor/fuse-emulator/current/fuse/simpleide.h
vendor/fuse-emulator/current/fuse/slt.c
vendor/fuse-emulator/current/fuse/slt.h
vendor/fuse-emulator/current/fuse/snapshot.c
vendor/fuse-emulator/current/fuse/sound/alsasound.c
vendor/fuse-emulator/current/fuse/sound/coreaudiosound.c
vendor/fuse-emulator/current/fuse/spectrum.c
vendor/fuse-emulator/current/fuse/spectrum.h
vendor/fuse-emulator/current/fuse/tape.c
vendor/fuse-emulator/current/fuse/trdos.c
vendor/fuse-emulator/current/fuse/trdos.h
vendor/fuse-emulator/current/fuse/ui/gtk/gtkui.c
vendor/fuse-emulator/current/fuse/ui/options.dat
vendor/fuse-emulator/current/fuse/ui/svga/svgadisplay.c
vendor/fuse-emulator/current/fuse/ui/svga/svgakeyboard.c
vendor/fuse-emulator/current/fuse/ui/ui.h
vendor/fuse-emulator/current/fuse/ui/win32/win32ui.c
vendor/fuse-emulator/current/fuse/ui/xlib/xdisplay.c
vendor/fuse-emulator/current/fuse/ui/xlib/xui.c
vendor/fuse-emulator/current/fuse/ui.c
vendor/fuse-emulator/current/fuse/ula.c
vendor/fuse-emulator/current/fuse/ula.h
vendor/fuse-emulator/current/fuse/utils.c
vendor/fuse-emulator/current/fuse/widget/error.c
vendor/fuse-emulator/current/fuse/widget/memory.c
vendor/fuse-emulator/current/fuse/widget/menu.c
vendor/fuse-emulator/current/fuse/widget/options.pl
vendor/fuse-emulator/current/fuse/widget/pokefinder.c
vendor/fuse-emulator/current/fuse/widget/widget.c
vendor/fuse-emulator/current/fuse/widget/widget_internals.h
vendor/fuse-emulator/current/fuse/z80/coretest.c
vendor/fuse-emulator/current/fuse/z80/z80.c
vendor/fuse-emulator/current/fuse/z80/z80.h
vendor/fuse-emulator/current/fuse/z80/z80.pl
vendor/fuse-emulator/current/fuse/z80/z80_macros.h
vendor/fuse-emulator/current/fuse/z80/z80_ops.c
vendor/fuse-emulator/current/fuse/zxatasp.c
vendor/fuse-emulator/current/fuse/zxatasp.h
vendor/fuse-emulator/current/fuse/zxcf.c
vendor/fuse-emulator/current/fuse/zxcf.h
vendor/fuse-emulator/current/fuse-utils/hacking/ChangeLog
vendor/fuse-emulator/current/fuse-utils/man/fuse-utils.1
vendor/fuse-emulator/current/fusetest/Makefile
vendor/fuse-emulator/current/fusetest/fusetest.asm
vendor/fuse-emulator/current/fusetest/sync.asm
vendor/fuse-emulator/current/fusetest/tests.asm
vendor/fuse-emulator/current/libspectrum/hacking/ChangeLog
vendor/fuse-emulator/current/libspectrum/libspectrum.c
vendor/fuse-emulator/current/libspectrum/libspectrum.h.in
Added Paths:
-----------
vendor/fuse-emulator/current/fuse/disk/
vendor/fuse-emulator/current/fuse/disk/Makefile.am
vendor/fuse-emulator/current/fuse/disk/plusd.c
vendor/fuse-emulator/current/fuse/disk/plusd.h
vendor/fuse-emulator/current/fuse/disk/wd1770.c
vendor/fuse-emulator/current/fuse/disk/wd1770.h
vendor/fuse-emulator/current/fuse/module.c
vendor/fuse-emulator/current/fuse/module.h
vendor/fuse-emulator/current/fuse/roms/plusd.rom
vendor/fuse-emulator/current/fusetest/delay.asm
Modified: vendor/fuse-emulator/current/fuse/Makefile.am
===================================================================
--- vendor/fuse-emulator/current/fuse/Makefile.am 2007-06-27 12:52:44 UTC (rev 402)
+++ vendor/fuse-emulator/current/fuse/Makefile.am 2007-06-28 13:18:21 UTC (rev 403)
@@ -1,7 +1,7 @@
## Process this file with automake to produce Makefile.in
## Copyright (c) 1999-2004 Philip Kendall
-## $Id: Makefile.am 2920 2007-06-02 02:06:05Z fredm $
+## $Id: Makefile.am 3007 2007-06-17 18:50:48Z zubzero $
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
@@ -27,6 +27,7 @@
SUBDIRS = compat \
debugger \
+ @DISK@ \
hacking \
lib \
machines \
@@ -41,6 +42,7 @@
DIST_SUBDIRS = compat \
debugger \
+ disk \
hacking \
lib \
machines \
@@ -70,6 +72,7 @@
machine.c \
memory.c \
menu.c \
+ module.c \
periph.c \
printer.c \
profile.c \
@@ -98,6 +101,7 @@
fuse_LDADD = debugger/libdebugger.a \
@UI_LIBS@ \
+@DISK_LIBS@ \
machines/libmachines.a \
pokefinder/libpokefinder.a \
sound/libsound.a \
@@ -119,11 +123,12 @@
@WINDRES_OBJ@
fuse_DEPENDENCIES = @UI_LIBS@ \
+ @DISK_LIBS@ \
debugger/libdebugger.a \
machines/libmachines.a \
sound/libsound.a \
- z80/libz80.a \
- @WINDRES_OBJ@
+ z80/libz80.a \
+ @WINDRES_OBJ@
BUILT_SOURCES = settings.c settings.h
@@ -156,6 +161,7 @@
machine.h \
memory.h \
menu.h \
+ module.h \
periph.h \
psg.h \
rzx.h \
Modified: vendor/fuse-emulator/current/fuse/ay.c
===================================================================
--- vendor/fuse-emulator/current/fuse/ay.c 2007-06-27 12:52:44 UTC (rev 402)
+++ vendor/fuse-emulator/current/fuse/ay.c 2007-06-28 13:18:21 UTC (rev 403)
@@ -1,7 +1,7 @@
/* ay.c: AY-8-3912 routines
Copyright (c) 1999-2004 Philip Kendall
- $Id: ay.c 2889 2007-05-26 17:45:08Z zubzero $
+ $Id: ay.c 2993 2007-06-17 13:54:49Z pak21 $
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -27,6 +27,7 @@
#include "compat.h"
#include "machine.h"
+#include "module.h"
#include "printer.h"
#include "psg.h"
#include "sound.h"
@@ -40,6 +41,26 @@
};
+static void ay_from_snapshot( libspectrum_snap *snap );
+static void ay_to_snapshot( libspectrum_snap *snap );
+
+static module_info_t ay_module_info = {
+
+ NULL,
+ NULL,
+ ay_from_snapshot,
+ ay_to_snapshot,
+
+};
+
+int
+ay_init( void )
+{
+ module_register( &ay_module_info );
+
+ return 0;
+}
+
/* What happens when the AY register port (traditionally 0xfffd on the 128K
machines) is read from */
libspectrum_byte
@@ -97,12 +118,12 @@
if( current == 14 ) printer_serial_write( b );
}
-int
-ay_from_snapshot( libspectrum_snap *snap, int capabilities )
+static void
+ay_from_snapshot( libspectrum_snap *snap )
{
size_t i;
- if( capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_AY ) {
+ if( machine_current->capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_AY ) {
ay_registerport_write( 0xfffd,
libspectrum_snap_out_ay_registerport( snap ) );
@@ -114,11 +135,9 @@
}
}
-
- return 0;
}
-int
+static void
ay_to_snapshot( libspectrum_snap *snap )
{
size_t i;
@@ -130,6 +149,4 @@
for( i = 0; i < AY_REGISTERS; i++ )
libspectrum_snap_set_ay_registers( snap, i,
machine_current->ay.registers[i] );
-
- return 0;
}
Modified: vendor/fuse-emulator/current/fuse/ay.h
===================================================================
--- vendor/fuse-emulator/current/fuse/ay.h 2007-06-27 12:52:44 UTC (rev 402)
+++ vendor/fuse-emulator/current/fuse/ay.h 2007-06-28 13:18:21 UTC (rev 403)
@@ -1,7 +1,7 @@
/* ay.h: AY-8-3912 routines
Copyright (c) 1999-2004 Philip Kendall
- $Id: ay.h 2889 2007-05-26 17:45:08Z zubzero $
+ $Id: ay.h 2993 2007-06-17 13:54:49Z pak21 $
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -35,12 +35,11 @@
libspectrum_byte registers[ AY_REGISTERS ];
} ayinfo;
+int ay_init( void );
+
libspectrum_byte ay_registerport_read( libspectrum_word port, int *attached );
void ay_registerport_write( libspectrum_word port, libspectrum_byte b );
void ay_dataport_write( libspectrum_word port, libspectrum_byte b );
-int ay_from_snapshot( libspectrum_snap *snap, int capabilities );
-int ay_to_snapshot( libspectrum_snap *snap );
-
#endif /* #ifndef FUSE_AY_H */
Modified: vendor/fuse-emulator/current/fuse/configure.in
===================================================================
--- vendor/fuse-emulator/current/fuse/configure.in 2007-06-27 12:52:44 UTC (rev 402)
+++ vendor/fuse-emulator/current/fuse/configure.in 2007-06-28 13:18:21 UTC (rev 403)
@@ -1,5 +1,5 @@
dnl Process this file with autoconf to produce a configure script.
-dnl $Id: configure.in 2928 2007-06-03 13:39:12Z zubzero $
+dnl $Id: configure.in 3007 2007-06-17 18:50:48Z zubzero $
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
@@ -357,6 +357,14 @@
lib/tape_se.szx
lib/tape_ts2068.szx])
+dnl LibDsk/lib765 prefix
+AC_ARG_WITH(disk-prefix,
+[ --with-disk-prefix=PFX where the LibDsk and/or lib765 libraries are installed (optional)],
+DSK_CFLAGS=-I$withval/include; DSKLIBS=-L$withval/lib,
+DSK_CFLAGS=""; DSK_LIBS="")
+ac_save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $DSK_CFLAGS"
+
dnl Do we want +3 disk support?
AC_MSG_CHECKING(whether +3 disk support requested)
AC_ARG_WITH(plus3-disk,
@@ -365,21 +373,27 @@
plus3disk=yes)
AC_MSG_RESULT($plus3disk)
if test "$plus3disk" = yes; then
- AC_ARG_WITH(plus3-disk-prefix,
- [ --with-plus3-disk-prefix=PFX where the +3 libraries are installed (optional)],
- DSK_CFLAGS=-I$withval/include; DSKLIBS=-L$withval/lib,
- DSK_CFLAGS=""; DSK_LIBS="")
- ac_save_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $DSK_CFLAGS"
AC_CHECK_HEADERS(765.h, DSKLIBS="$DSKLIBS -l765"; lib765=yes,
- AC_MSG_WARN(765.h not found - disk support disabled))
- if test "$lib765" = yes; then
- AC_CHECK_HEADERS(libdsk.h, DSKLIBS="$DSKLIBS -ldsk")
- fi
- CPPFLAGS="$ac_save_CPPFLAGS"
+ AC_MSG_WARN(765.h not found - +3 disk support disabled))
fi
+
+dnl Do we want LibDsk support?
+AC_ARG_WITH(libdsk,
+ [ --without-libdsk disable LibDsk support],
+ if test "$withval" = no; then libdsk=no; else libdsk=yes; fi,
+ libdsk=yes)
+AC_MSG_RESULT($libdsk)
+if test "$libdsk" = yes; then
+ AC_CHECK_HEADERS(libdsk.h, DSKLIBS="$DSKLIBS -ldsk";
+ DISK_LIBS="disk/libdisk.a"; DISK="disk",
+ AC_MSG_WARN(libdsk.h not found - LibDsk support disabled))
+fi
+
+CPPFLAGS="$ac_save_CPPFLAGS"
AC_SUBST(DSK_CFLAGS)
AC_SUBST(DSKLIBS)
+AC_SUBST(DISK_LIBS)
+AC_SUBST(DISK)
dnl Check if a version of libpng which supplies png_write_png is available
AC_CHECK_LIB( png, png_write_png,
@@ -567,6 +581,7 @@
AC_OUTPUT(Makefile \
compat/Makefile \
debugger/Makefile \
+disk/Makefile \
hacking/Makefile \
lib/Makefile \
machines/Makefile \
Modified: vendor/fuse-emulator/current/fuse/dck.c
===================================================================
--- vendor/fuse-emulator/current/fuse/dck.c 2007-06-27 12:52:44 UTC (rev 402)
+++ vendor/fuse-emulator/current/fuse/dck.c 2007-06-28 13:18:21 UTC (rev 403)
@@ -1,7 +1,7 @@
/* dck.c: dock snapshot (Warajevo .DCK) handling routines
Copyright (c) 2003-2004 Darren Salt, Fredrick Meunier, Philip Kendall
- $Id: dck.c 2889 2007-05-26 17:45:08Z zubzero $
+ $Id: dck.c 2995 2007-06-17 14:31:36Z pak21 $
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -61,7 +61,7 @@
error = settings_set_string( &settings_current.dck_file, filename );
if( error ) return error;
- machine_reset();
+ machine_reset( 0 );
return 0;
}
@@ -82,7 +82,7 @@
ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 0 );
- machine_reset();
+ machine_reset( 0 );
}
int
Added: vendor/fuse-emulator/current/fuse/disk/Makefile.am
===================================================================
--- vendor/fuse-emulator/current/fuse/disk/Makefile.am (rev 0)
+++ vendor/fuse-emulator/current/fuse/disk/Makefile.am 2007-06-28 13:18:21 UTC (rev 403)
@@ -0,0 +1,34 @@
+## Process this file with automake to produce Makefile.in
+## Copyright (c) 2007 Stuart Brady
+
+## $Id: Makefile.am 2889 2007-05-26 17:45:08Z zubzero $
+
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU 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 General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with this program; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+##
+## Author contact information:
+##
+## E-mail: phi...@sh...
+
+AUTOMAKE_OPTIONS = foreign
+
+noinst_LIBRARIES = libdisk.a
+
+INCLUDES = @LIBSPEC_CFLAGS@ @GTK_CFLAGS@ @GLIB_CFLAGS@
+
+libdisk_a_SOURCES = plusd.c \
+ wd1770.c
+
+noinst_HEADERS = plusd.h \
+ wd1770.h
Added: vendor/fuse-emulator/current/fuse/disk/plusd.c
===================================================================
--- vendor/fuse-emulator/current/fuse/disk/plusd.c (rev 0)
+++ vendor/fuse-emulator/current/fuse/disk/plusd.c 2007-06-28 13:18:21 UTC (rev 403)
@@ -0,0 +1,571 @@
+/* plusd.c: Routines for handling the +D interface
+ Copyright (c) 1999-2007 Stuart Brady, Fredrick Meunier, Philip Kendall,
+ Dmitry Sanarin, Darren Salt
+
+ $Id$
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Author contact information:
+
+ Philip: phi...@sh...
+
+ Stuart: sd...@nt...
+
+*/
+
+#include <config.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h> /* Needed for strncasecmp() on QNX6 */
+#endif /* #ifdef HAVE_STRINGS_H */
+#include <limits.h>
+#include <sys/stat.h>
+
+#include <libdsk.h>
+
+#include <libspectrum.h>
+
+#include "compat.h"
+#include "event.h"
+#include "machine.h"
+#include "module.h"
+#include "plusd.h"
+#include "printer.h"
+#include "settings.h"
+#include "ui/ui.h"
+#include "utils.h"
+#include "wd1770.h"
+#include "z80/z80.h"
+
+int plusd_available = 0;
+int plusd_active = 0;
+int plusd_index_pulse = 0;
+
+wd1770_fdc plusd_fdc;
+wd1770_drive plusd_drives[ PLUSD_NUM_DRIVES ];
+
+static const char *plusd_template = "fuse.plusd.XXXXXX";
+
+static void plusd_reset( int hard_reset );
+static void plusd_memory_map( void );
+static void plusd_from_snapshot( libspectrum_snap *snap );
+static void plusd_to_snapshot( libspectrum_snap *snap );
+
+static module_info_t plusd_module_info = {
+
+ plusd_reset,
+ plusd_memory_map,
+ plusd_from_snapshot,
+ plusd_to_snapshot,
+
+};
+
+void
+plusd_page( void )
+{
+ plusd_active = 1;
+ machine_current->ram.romcs = 1;
+ machine_current->memory_map();
+}
+
+void
+plusd_unpage( void )
+{
+ plusd_active = 0;
+ machine_current->ram.romcs = 0;
+ machine_current->memory_map();
+}
+
+static void
+plusd_memory_map( void )
+{
+ if( !plusd_active ) return;
+
+ memory_map_read[ 0 ] = memory_map_write[ 0 ] = memory_map_romcs[ 0 ];
+ memory_map_read[ 1 ] = memory_map_write[ 1 ] = memory_map_ram[ 16 * 2 ];
+}
+
+void
+plusd_set_cmdint( wd1770_fdc *f )
+{
+ z80_interrupt();
+}
+
+const periph_t plusd_peripherals[] = {
+ /* ---- ---- 1110 0011 */
+ { 0x00ff, 0x00e3, plusd_sr_read, plusd_cr_write },
+ /* ---- ---- 1110 1011 */
+ { 0x00ff, 0x00eb, plusd_tr_read, plusd_tr_write },
+ /* ---- ---- 1111 0011 */
+ { 0x00ff, 0x00f3, plusd_sec_read, plusd_sec_write },
+ /* ---- ---- 1111 1011 */
+ { 0x00ff, 0x00fb, plusd_dr_read, plusd_dr_write },
+
+ /* ---- ---- 1110 1111 */
+ { 0x00ff, 0x00ef, NULL, plusd_cn_write },
+ /* ---- ---- 1110 0111 */
+ { 0x00ff, 0x00e7, plusd_mem_read, plusd_mem_write },
+ /* 0000 0000 1111 0111 */
+ { 0x00ff, 0x00f7, plusd_printer_read, printer_parallel_write },
+};
+
+const size_t plusd_peripherals_count =
+ sizeof( plusd_peripherals ) / sizeof( periph_t );
+
+int
+plusd_init( void )
+{
+ int i;
+ wd1770_drive *d;
+
+ plusd_fdc.current_drive = &plusd_drives[ 0 ];
+
+ for( i = 0; i < PLUSD_NUM_DRIVES; i++ ) {
+ d = &plusd_drives[ i ];
+
+ d->disk = NULL;
+ d->filename[0] = '\0';
+ }
+
+ plusd_fdc.set_cmdint = &plusd_set_cmdint;
+ plusd_fdc.reset_cmdint = NULL;
+ plusd_fdc.set_datarq = NULL;
+ plusd_fdc.reset_datarq = NULL;
+ plusd_fdc.iface = NULL;
+
+ plusd_fdc.rates[ 0 ] = 6;
+ plusd_fdc.rates[ 1 ] = 12;
+ plusd_fdc.rates[ 2 ] = 2;
+ plusd_fdc.rates[ 3 ] = 3;
+
+ module_register( &plusd_module_info );
+
+ return 0;
+}
+
+static void
+plusd_reset( int hard_reset )
+{
+ int i;
+ wd1770_drive *d;
+ wd1770_fdc *f = &plusd_fdc;
+
+ plusd_available = 0;
+
+ if( !periph_plusd_active )
+ return;
+
+ machine_load_rom_bank( memory_map_romcs, 0, 0,
+ settings_default.rom_plusd,
+ settings_current.rom_plusd, 0x2000 );
+
+ memory_map_romcs[0].source = MEMORY_SOURCE_PERIPHERAL;
+
+ machine_current->ram.romcs = 0;
+
+ memory_map_romcs[ 0 ].writable = 0;
+ memory_map_romcs[ 1 ].writable = 0;
+ memory_map_ram[ 16 * 2 ].writable = 1;
+
+ plusd_available = 1;
+ plusd_active = 0;
+ plusd_index_pulse = 0;
+
+ if( hard_reset ) {
+ for( i = 0; i < 8192; i++ ) {
+ memory_map_ram[ 16 * 2 ].page[ i ] = 0;
+ }
+ }
+
+ f->spin_cycles = 0;
+ f->direction = 0;
+
+ f->state = wd1770_state_none;
+ f->status_type = wd1770_status_type1;
+
+ f->status_register = 0;
+ f->track_register = 0;
+ f->sector_register = 0;
+ f->data_register = 0;
+
+ for( i = 0; i < PLUSD_NUM_DRIVES; i++ ) {
+ d = &plusd_drives[ i ];
+
+ d->index_pulse = 0;
+ d->index_interrupt = 0;
+ d->track = 0;
+ d->side = 0;
+ }
+
+ f->status_register |= WD1770_SR_LOST; /* track 0 */
+
+ /* We can eject disks only if they are currently present */
+ ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_PLUSD_1_EJECT,
+ !!plusd_drives[ PLUSD_DRIVE_1 ].disk );
+ ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_PLUSD_2_EJECT,
+ !!plusd_drives[ PLUSD_DRIVE_2 ].disk );
+
+ plusd_fdc.current_drive = &plusd_drives[ 0 ];
+ machine_current->memory_map();
+ plusd_event_index( 0 );
+
+ ui_statusbar_update( UI_STATUSBAR_ITEM_DISK, UI_STATUSBAR_STATE_INACTIVE );
+}
+
+void
+plusd_end( void )
+{
+ plusd_available = 0;
+}
+
+libspectrum_byte
+plusd_sr_read( libspectrum_word port GCC_UNUSED, int *attached )
+{
+ *attached = 1;
+ return wd1770_sr_read( &plusd_fdc );
+}
+
+void
+plusd_cr_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b )
+{
+ wd1770_cr_write( &plusd_fdc, b );
+}
+
+libspectrum_byte
+plusd_tr_read( libspectrum_word port GCC_UNUSED, int *attached )
+{
+ *attached = 1;
+ return wd1770_tr_read( &plusd_fdc );
+}
+
+void
+plusd_tr_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b )
+{
+ wd1770_tr_write( &plusd_fdc, b );
+}
+
+libspectrum_byte
+plusd_sec_read( libspectrum_word port GCC_UNUSED, int *attached )
+{
+ *attached = 1;
+ return wd1770_sec_read( &plusd_fdc );
+}
+
+void
+plusd_sec_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b )
+{
+ wd1770_sec_write( &plusd_fdc, b );
+}
+
+libspectrum_byte
+plusd_dr_read( libspectrum_word port GCC_UNUSED, int *attached )
+{
+ *attached = 1;
+ return wd1770_dr_read( &plusd_fdc );
+}
+
+void
+plusd_dr_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b )
+{
+ wd1770_dr_write( &plusd_fdc, b );
+}
+
+void
+plusd_cn_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b )
+{
+ int drive, side;
+ int i;
+
+ drive = ( b & 0x03 ) == 2 ? 1 : 0;
+ side = ( b & 0x80 ) ? 1 : 0;
+
+ /* TODO: set current_drive to NULL when bits 0 and 1 of b are '00' or '11' */
+ plusd_fdc.current_drive = &plusd_drives[ drive ];
+
+ for( i = 0; i < PLUSD_NUM_DRIVES; i++ ) {
+ plusd_drives[ i ].side = side;
+ }
+
+ printer_parallel_strobe_write( b & 0x40 );
+}
+
+libspectrum_byte
+plusd_mem_read( libspectrum_word port GCC_UNUSED, int *attached )
+{
+ plusd_page();
+ return 0;
+}
+
+void
+plusd_mem_write( libspectrum_word port GCC_UNUSED, libspectrum_byte b )
+{
+ plusd_unpage();
+}
+
+libspectrum_byte
+plusd_printer_read( libspectrum_word port GCC_UNUSED, int *attached )
+{
+ *attached = 1;
+
+ /* bit 7 = busy. other bits high? */
+
+ if(!settings_current.printer)
+ return(0xff); /* no printer attached */
+
+ return(0x7f); /* never busy */
+}
+
+int
+plusd_disk_insert_default_autoload( plusd_drive_number which,
+ const char *filename )
+{
+ return plusd_disk_insert( which, filename, settings_current.auto_load );
+}
+
+int
+plusd_disk_insert( plusd_drive_number which, const char *filename,
+ int autoload )
+{
+ int fd, error;
+ char tempfilename[ PATH_MAX ];
+ int israw = 0;
+ dsk_format_t fmt;
+ wd1770_drive *d;
+ int l;
+
+ if( which >= PLUSD_NUM_DRIVES ) {
+ ui_error( UI_ERROR_ERROR, "plusd_disk_insert: unknown drive %d",
+ which );
+ fuse_abort();
+ }
+
+ d = &plusd_drives[ which ];
+
+ /* Eject any disk already in the drive */
+ if( d->disk ) {
+ /* Abort the insert if we want to keep the current disk */
+ if( plusd_disk_eject( which, 0 ) ) return 0;
+ }
+
+ /* Make a temporary copy of the disk file */
+ error = utils_make_temp_file( &fd, tempfilename, filename, plusd_template );
+ if( error ) return error;
+ strcpy( d->filename, tempfilename );
+
+ /* Determine the disk image format */
+ l = strlen( filename );
+ if( l >= 5 ) {
+ if( !strcmp( filename + ( l - 4 ), ".dsk" ) ||
+ !strcmp( filename + ( l - 4 ), ".mgt" ) ) {
+ israw = 1;
+ fmt = FMT_800K;
+ } else if( !strcmp( filename + ( l - 4 ), ".img" ) ) {
+ israw = 1;
+ fmt = FMT_MGT800;
+ }
+ }
+
+ /* And now insert the disk */
+ if( israw ) {
+
+ /* If the "logical" driver is not available, try the "raw" driver (unless
+ * we're using FMT_MGT800, for which the raw driver will not work */
+ if( dsk_open( &d->disk, tempfilename, "logical", NULL ) != DSK_ERR_OK &&
+ ( fmt == FMT_MGT800 ||
+ dsk_open( &d->disk, tempfilename, "raw", NULL ) != DSK_ERR_OK ) ) {
+ ui_error( UI_ERROR_ERROR, "Failed to open disk image" );
+ return 1;
+ }
+
+ if( dg_stdformat( &d->geom, fmt, NULL, NULL ) != DSK_ERR_OK ) {
+ ui_error( UI_ERROR_ERROR, "Failed to set geometry for disk" );
+ dsk_close( &d->disk );
+ return 1;
+ }
+
+ } else {
+
+ if( dsk_open( &d->disk, tempfilename, NULL, NULL ) != DSK_ERR_OK ) {
+ ui_error( UI_ERROR_ERROR, "Failed to open disk image" );
+ return 1;
+ }
+
+ if( dsk_getgeom( d->disk, &d->geom ) != DSK_ERR_OK ) {
+ ui_error( UI_ERROR_ERROR, "Failed to determine geometry for disk" );
+ dsk_close( &d->disk );
+ return 1;
+ }
+
+ }
+
+ /* Set the 'eject' item active */
+ switch( which ) {
+ case PLUSD_DRIVE_1:
+ ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_PLUSD_1_EJECT, 1 );
+ break;
+ case PLUSD_DRIVE_2:
+ ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_PLUSD_2_EJECT, 1 );
+ break;
+ }
+
+ if( autoload ) {
+ /* XXX */
+ }
+
+ return 0;
+}
+
+int
+plusd_disk_eject( plusd_drive_number which, int write )
+{
+ wd1770_drive *d;
+
+ if( which >= PLUSD_NUM_DRIVES )
+ return 1;
+
+ d = &plusd_drives[ which ];
+
+ if( !d->disk )
+ return 0;
+
+ if( write ) {
+
+ if( ui_plusd_disk_write( which ) ) return 1;
+
+ } else {
+
+ if( dsk_dirty( plusd_drives[which].disk ) ) {
+
+ ui_confirm_save_t confirm = ui_confirm_save(
+ "Disk has been modified.\nDo you want to save it?"
+ );
+
+ switch( confirm ) {
+
+ case UI_CONFIRM_SAVE_SAVE:
+ if( ui_plusd_disk_write( which ) ) return 1;
+ break;
+
+ case UI_CONFIRM_SAVE_DONTSAVE: break;
+ case UI_CONFIRM_SAVE_CANCEL: return 1;
+
+ }
+ }
+ }
+
+ dsk_close( &d->disk );
+ unlink( d->filename );
+
+ /* Set the 'eject' item inactive */
+ switch( which ) {
+ case PLUSD_DRIVE_1:
+ ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_PLUSD_1_EJECT, 0 );
+ break;
+ case PLUSD_DRIVE_2:
+ ui_menu_activate( UI_MENU_ITEM_MEDIA_DISK_PLUSD_2_EJECT, 0 );
+ break;
+ }
+ return 0;
+}
+
+int
+plusd_disk_write( plusd_drive_number which, const char *filename )
+{
+ wd1770_drive *d = &plusd_drives[ which ];
+ utils_file file;
+ FILE *f;
+ int error;
+ size_t bytes_written;
+
+ dsk_close( &d->disk );
+
+ f = fopen( filename, "wb" );
+ if( !f ) {
+ ui_error( UI_ERROR_ERROR, "couldn't open '%s' for writing: %s", filename,
+ strerror( errno ) );
+ }
+
+ error = utils_read_file( d->filename, &file );
+ if( error ) { fclose( f ); return error; }
+
+ bytes_written = fwrite( file.buffer, 1, file.length, f );
+ if( bytes_written != file.length ) {
+ ui_error( UI_ERROR_ERROR, "could write only %lu of %lu bytes to '%s'",
+ (unsigned long)bytes_written, (unsigned long)file.length,
+ filename );
+ utils_close_file( &file ); fclose( f );
+ }
+
+ error = utils_close_file( &file ); if( error ) { fclose( f ); return error; }
+
+ if( fclose( f ) ) {
+ ui_error( UI_ERROR_ERROR, "error closing '%s': %s", filename,
+ strerror( errno ) );
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+plusd_event_cmd_done( libspectrum_dword last_tstates )
+{
+ plusd_fdc.status_register &= ~WD1770_SR_BUSY;
+ return 0;
+}
+
+int
+plusd_event_index( libspectrum_dword last_tstates )
+{
+ int error;
+ int next_tstates;
+ int i;
+
+ plusd_index_pulse = !plusd_index_pulse;
+ for( i = 0; i < PLUSD_NUM_DRIVES; i++ ) {
+ wd1770_drive *d = &plusd_drives[ i ];
+
+ d->index_pulse = plusd_index_pulse;
+ if( !plusd_index_pulse && d->index_interrupt ) {
+ wd1770_set_cmdint( &plusd_fdc );
+ d->index_interrupt = 0;
+ }
+ }
+ next_tstates = ( plusd_index_pulse ? 10 : 190 ) *
+ machine_current->timings.processor_speed / 1000;
+ error = event_add( last_tstates + next_tstates, EVENT_TYPE_PLUSD_INDEX );
+ if( error )
+ return error;
+ return 0;
+}
+
+static void
+plusd_from_snapshot( libspectrum_snap *snap )
+{
+ /* XXX */
+}
+
+static void
+plusd_to_snapshot( libspectrum_snap *snap )
+{
+ /* XXX */
+}
Added: vendor/fuse-emulator/current/fuse/disk/plusd.h
===================================================================
--- vendor/fuse-emulator/current/fuse/disk/plusd.h (rev 0)
+++ vendor/fuse-emulator/current/fuse/disk/plusd.h 2007-06-28 13:18:21 UTC (rev 403)
@@ -0,0 +1,94 @@
+/* plusd.h: Routines for handling the +D interface
+ Copyright (c) 2005-2007 Stuart Brady
+
+ $Id$
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Author contact information:
+
+ Philip: phi...@sh...
+
+ Stuart: sd...@nt...
+
+*/
+
+#ifndef FUSE_PLUSD_H
+#define FUSE_PLUSD_H
+
+#include <config.h>
+
+typedef enum plusd_drive_number {
+ PLUSD_DRIVE_1 = 0,
+ PLUSD_DRIVE_2,
+} plusd_drive_number;
+
+#ifdef HAVE_LIBDSK_H
+
+#include <libspectrum.h>
+
+#include "wd1770.h"
+#include "periph.h"
+
+extern int plusd_available; /* Is the +D available for use? */
+extern int plusd_active; /* +D enabled? */
+extern int plusd_index_pulse;
+
+extern const periph_t plusd_peripherals[];
+extern const size_t plusd_peripherals_count;
+
+int plusd_init( void );
+void plusd_end( void );
+
+void plusd_page( void );
+void plusd_unpage( void );
+
+libspectrum_byte plusd_sr_read( libspectrum_word port, int *attached );
+void plusd_cr_write( libspectrum_word port, libspectrum_byte b );
+
+libspectrum_byte plusd_tr_read( libspectrum_word port, int *attached );
+void plusd_tr_write( libspectrum_word port, libspectrum_byte b );
+
+libspectrum_byte plusd_sec_read( libspectrum_word port, int *attached );
+void plusd_sec_write( libspectrum_word port, libspectrum_byte b );
+
+libspectrum_byte plusd_dr_read( libspectrum_word port, int *attached );
+void plusd_dr_write( libspectrum_word port, libspectrum_byte b );
+
+libspectrum_byte plusd_joy_read( libspectrum_word port, int *attached );
+void plusd_cn_write( libspectrum_word port, libspectrum_byte b );
+
+libspectrum_byte plusd_mem_read( libspectrum_word port, int *attached );
+void plusd_mem_write( libspectrum_word port, libspectrum_byte b );
+
+libspectrum_byte plusd_printer_read( libspectrum_word port, int *attached );
+
+extern wd1770_fdc plusd_fdc;
+
+#define PLUSD_NUM_DRIVES 2
+extern wd1770_drive plusd_drives[ PLUSD_NUM_DRIVES ];
+
+int plusd_disk_insert( plusd_drive_number which, const char *filename,
+ int autoload );
+int plusd_disk_insert_default_autoload( plusd_drive_number which,
+ const char *filename );
+int plusd_disk_eject( plusd_drive_number which, int write );
+int plusd_disk_write( plusd_drive_number which, const char *filename );
+int plusd_event_cmd_done( libspectrum_dword last_tstates );
+int plusd_event_index( libspectrum_dword last_tstates );
+
+#endif /* #ifndef HAVE_LIBDSK_H */
+
+#endif /* #ifndef FUSE_PLUSD_H */
Added: vendor/fuse-emulator/current/fuse/disk/wd1770.c
===================================================================
--- vendor/fuse-emulator/current/fuse/disk/wd1770.c (rev 0)
+++ vendor/fuse-emulator/current/fuse/disk/wd1770.c 2007-06-28 13:18:21 UTC (rev 403)
@@ -0,0 +1,389 @@
+/* wd1770.c: Routines for handling the WD1770 floppy disk controller
+ Copyright (c) 2002-2007 Stuart Brady, Fredrick Meunier, Philip Kendall,
+ Dmitry Sanarin
+
+ $Id$
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Author contact information:
+
+ Philip: phi...@sh...
+
+ Stuart: sd...@nt...
+
+*/
+
+#include <config.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h> /* Needed for strncasecmp() on QNX6 */
+#endif /* #ifdef HAVE_STRINGS_H */
+#include <limits.h>
+#include <sys/stat.h>
+
+#include <libdsk.h>
+
+#include <libspectrum.h>
+
+#include "compat.h"
+#include "event.h"
+#include "machine.h"
+#include "ui/ui.h"
+#include "wd1770.h"
+#include "z80/z80.h"
+
+char secbuf[1024];
+
+void
+statusbar_update( int busy )
+{
+ ui_statusbar_update( UI_STATUSBAR_ITEM_DISK,
+ busy ? UI_STATUSBAR_STATE_ACTIVE :
+ UI_STATUSBAR_STATE_INACTIVE );
+}
+
+void
+wd1770_set_cmdint( wd1770_fdc *f )
+{
+ if( f->set_cmdint )
+ f->set_cmdint( f );
+}
+
+void
+wd1770_reset_cmdint( wd1770_fdc *f )
+{
+ if( f->reset_cmdint )
+ f->reset_cmdint( f );
+}
+
+void
+wd1770_set_datarq( wd1770_fdc *f )
+{
+ f->status_register |= WD1770_SR_IDX_DRQ;
+ if( f->set_datarq )
+ f->set_datarq( f );
+}
+
+void
+wd1770_reset_datarq( wd1770_fdc *f )
+{
+ f->status_register &= ~WD1770_SR_IDX_DRQ;
+ if( f->reset_datarq )
+ f->reset_datarq( f );
+}
+
+static void
+wd1770_seek( wd1770_fdc *f, int track, int update, int verify )
+{
+ wd1770_drive *d = f->current_drive;
+
+ if( track < d->track ) {
+ f->direction = -1;
+ if( f->track_register == 0 )
+ f->track_register = 255;
+ else if( update ) {
+ int trk = f->track_register;
+
+ trk += track - d->track + 256;
+ trk %= 256;
+ f->track_register = trk;
+ }
+ } else if( track > d->track ) {
+ f->direction = 1;
+ if( f->track_register == 255 )
+ f->track_register = 0;
+ else if( update ) {
+ int trk = f->track_register;
+
+ trk += track - d->track;
+ trk %= 256;
+ f->track_register = trk;
+ }
+ }
+
+ if( verify ) {
+ if( track < 0 )
+ f->status_register |= WD1770_SR_RNF;
+ else if( track >= d->geom.dg_cylinders )
+ f->status_register |= WD1770_SR_RNF;
+ else
+ f->status_register &= ~WD1770_SR_RNF;
+ } else
+ f->status_register &= ~WD1770_SR_RNF;
+
+ if( track < 0 )
+ track = 0;
+ if( track > 255 )
+ track = 255;
+ d->track = track;
+
+ if( d->track == 0 )
+ f->status_register |= WD1770_SR_LOST;
+ else
+ f->status_register &= ~WD1770_SR_LOST;
+}
+
+libspectrum_byte
+wd1770_sr_read( wd1770_fdc *f )
+{
+ wd1770_drive *d = f->current_drive;
+
+ f->status_register &= ~( WD1770_SR_MOTORON | WD1770_SR_SPINUP |
+ WD1770_SR_WRPROT | WD1770_SR_CRCERR );
+ if( f->status_type == wd1770_status_type1 ) {
+ f->status_register &= ~WD1770_SR_IDX_DRQ;
+ if( !d->disk || d->index_pulse )
+ f->status_register |= WD1770_SR_IDX_DRQ;
+ }
+ return f->status_register;
+}
+
+
+void
+wd1770_cr_write( wd1770_fdc *f, libspectrum_byte b )
+{
+ wd1770_drive *d = f->current_drive;
+
+ /* command register: */
+ if( ( b & 0xf0 ) == 0xd0 ) { /* Type IV - Force Interrupt */
+ statusbar_update(0);
+ f->status_register &= ~WD1770_SR_BUSY;
+ f->status_register &= ~WD1770_SR_WRPROT;
+ f->status_register &= ~WD1770_SR_CRCERR;
+ f->status_register &= ~WD1770_SR_IDX_DRQ;
+ f->state = wd1770_state_none;
+ f->status_type = wd1770_status_type1;
+ if( d->track == 0 )
+ f->status_register |= WD1770_SR_LOST;
+ else
+ f->status_register &= ~WD1770_SR_LOST;
+ wd1770_reset_datarq( f );
+ if( b & 0x08 )
+ wd1770_set_cmdint( f );
+ if( b & 0x04 )
+ d->index_interrupt = 1;
+ return;
+ }
+
+ if( f->status_register & WD1770_SR_BUSY )
+ return;
+
+ /*
+ f->status_register |= WD1770_SR_BUSY;
+ event_add( tstates +
+ 10 * machine_current->timings.processor_speed / 1000,
+ EVENT_TYPE_PLUSD_CMD_DONE );
+ */
+
+ if( !( b & 0x08 ) ) {
+ f->spin_cycles = 5;
+ f->status_register |= WD1770_SR_MOTORON;
+ f->status_register |= WD1770_SR_SPINUP;
+ }
+
+ if( !( b & 0x80 ) ) { /* Type I */
+ int update = b & 0x10 ? 1 : 0;
+ int verify = b & 0x04 ? 1 : 0;
+/* int rate = b & 0x03 ? 1 : 0; */
+
+ switch( ( b >> 5 ) & 0x03 ) {
+ case 0x00:
+ if( ( b & 0x4 ) ) { /* Restore */
+ f->track_register = d->track;
+ wd1770_seek( f, 0, update, verify );
+ } else { /* Seek */
+ wd1770_seek( f, f->data_register, 0, verify );
+ }
+ f->direction = 1;
+ break;
+ case 0x01: /* Step */
+ wd1770_seek( f, d->track + f->direction, update, verify );
+ break;
+ case 0x02: /* Step In */
+ wd1770_seek( f, d->track + 1, update, verify );
+ break;
+ case 0x03: /* Step Out */
+ wd1770_seek( f, d->track - 1, update, verify );
+ break;
+ }
+ f->status_type = wd1770_status_type1;
+ wd1770_set_cmdint( f );
+ wd1770_reset_datarq( f );
+ } else if( !( b & 0x40 ) ) { /* Type II */
+ int multisector = b & 0x10 ? 1 : 0;
+/* int delay = b & 0x04 ? 1 : 0; */
+
+ if( !( b & 0x20 ) ) { /* Read Sector */
+ f->state = wd1770_state_read;
+ } else { /* Write Sector */
+/* int dammark = b & 0x01; */
+
+ f->state = wd1770_state_write;
+ }
+ if( f->sector_register < d->geom.dg_secbase ||
+ f->sector_register >= d->geom.dg_secbase + d->geom.dg_sectors ||
+ d->track >= d->geom.dg_cylinders ||
+ d->track < 0 ) {
+ f->status_register |= WD1770_SR_RNF;
+ wd1770_set_cmdint( f );
+ wd1770_reset_datarq( f );
+ } else {
+ wd1770_set_datarq( f );
+ statusbar_update(1);
+ f->status_register |= WD1770_SR_BUSY;
+ f->status_register &= ~( WD1770_SR_WRPROT | WD1770_SR_RNF |
+ WD1770_SR_CRCERR | WD1770_SR_LOST );
+ f->status_type = wd1770_status_type2;
+ f->data_track = d->track;
+ f->data_sector = f->sector_register;
+ f->data_side = d->side;
+ f->data_offset = 0;
+ f->data_multisector = multisector;
+ }
+ } else if( ( b & 0xf0 ) != 0xd0 ) { /* Type III */
+/* int delay = b & 0x04; */
+
+ switch( b & 0xf0 ) {
+ case 0x00: /* Read Track */
+ fprintf( stderr, "read track not yet implemented\n" );
+ break;
+ case 0x01: /* Write Track */
+ fprintf( stderr, "write track not yet implemented\n" );
+ break;
+ case 0x02: /* Read Address */
+ fprintf( stderr, "read address not yet implemented\n" );
+ break;
+ }
+ f->status_type = wd1770_status_type2;
+ }
+}
+
+libspectrum_byte
+wd1770_tr_read( wd1770_fdc *f )
+{
+ return f->track_register;
+}
+
+void
+wd1770_tr_write( wd1770_fdc *f, libspectrum_byte b )
+{
+ f->track_register = b;
+}
+
+libspectrum_byte
+wd1770_sec_read( wd1770_fdc *f )
+{
+ return f->sector_register;
+}
+
+void
+wd1770_sec_write( wd1770_fdc *f, libspectrum_byte b )
+{
+ f->sector_register = b;
+}
+
+libspectrum_byte
+wd1770_dr_read( wd1770_fdc *f )
+{
+ wd1770_drive *d = f->current_drive;
+
+ if( f->state == wd1770_state_read ) {
+ if( !d->disk ||
+ f->data_sector >= d->geom.dg_secbase + d->geom.dg_sectors ||
+ f->data_track >= d->geom.dg_cylinders ||
+ f->data_side >= d->geom.dg_heads ) {
+ f->status_register |= WD1770_SR_RNF;
+ fprintf( stderr, "read from non-existent sector\n" );
+ return f->data_register;
+ }
+
+ if( f->data_offset == 0 &&
+ ( d->geom.dg_secsize > sizeof( secbuf ) ||
+ dsk_pread( d->disk, &d->geom, secbuf, f->data_track,
+ f->data_side, f->data_sector ) != DSK_ERR_OK ) ) {
+ f->status_register |= WD1770_SR_RNF;
+ statusbar_update(0);
+ f->status_register &= ~WD1770_SR_BUSY;
+ f->status_type = wd1770_status_type2;
+ f->state = wd1770_state_none;
+ wd1770_set_cmdint( f );
+ wd1770_reset_datarq( f );
+ } else if( f->data_offset < d->geom.dg_secsize ) {
+ f->data_register = secbuf[ f->data_offset++ ];
+ if( f->data_offset == d->geom.dg_secsize ) {
+ if( f->data_multisector &&
+ f->data_sector < d->geom.dg_secbase + d->geom.dg_sectors ) {
+ f->data_sector++;
+ f->data_offset = 0;
+ }
+ if( !f->data_multisector ||
+ f->data_sector >= d->geom.dg_secbase + d->geom.dg_sectors ) {
+ statusbar_update(0);
+ f->status_register &= ~WD1770_SR_BUSY;
+ f->status_type = wd1770_status_type2;
+ f->state = wd1770_state_none;
+ wd1770_set_cmdint( f );
+ wd1770_reset_datarq( f );
+ }
+ }
+ }
+ }
+ return f->data_register;
+}
+
+void
+wd1770_dr_write( wd1770_fdc *f, libspectrum_byte b )
+{
+ wd1770_drive *d = f->current_drive;
+
+ f->data_register = b;
+ if( f->state == wd1770_state_write ) {
+ if( !d->disk || f->data_sector >= d->geom.dg_secbase + d->geom.dg_sectors ||
+ f->data_track >= d->geom.dg_cylinders ||
+ f->data_side >= d->geom.dg_heads ) {
+ f->status_register |= WD1770_SR_RNF;
+ fprintf( stderr, "write to non-existent sector\n" );
+ return;
+ }
+
+ if( f->data_offset < sizeof( secbuf ) )
+ secbuf[ f->data_offset++ ] = b;
+ if( f->data_offset == d->geom.dg_secsize ) {
+ dsk_pwrite( d->disk, &d->geom, secbuf, f->data_track,
+ f->data_side, f->data_sector );
+ if( f->data_multisector &&
+ f->data_sector < d->geom.dg_secbase + d->geom.dg_sectors ) {
+ f->data_sector++;
+ f->data_offset = 0;
+ }
+ if( !f->data_multisector ||
+ f->data_sector >= d->geom.dg_secbase + d->geom.dg_sectors ) {
+ statusbar_update(0);
+ f->status_register &= ~WD1770_SR_BUSY;
+ f->status_type = wd1770_status_type2;
+ f->state = wd1770_state_none;
+ wd1770_set_cmdint( f );
+ wd1770_reset_datarq( f );
+ }
+ }
+ }
+}
Added: vendor/fuse-emulator/current/fuse/disk/wd1770.h
===================================================================
--- vendor/fuse-emulator/current/fuse/disk/wd1770.h (rev 0)
+++ vendor/fuse-emulator/current/fuse/disk/wd1770.h 2007-06-28 13:18:21 UTC (rev 403)
@@ -0,0 +1,119 @@
+/* wd1770.h: Routines for handling the WD1770 floppy disk controller
+ Copyright (c) 2003-2007 Stuart Brady, Fredrick Meunier, Philip Kendall
+
+ $Id$
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Author contact information:
+
+ Philip: phi...@sh...
+
+ Stuart: sd...@nt...
+
+*/
+
+#ifndef FUSE_WD1770_H
+#define FUSE_WD1770_H
+
+#include <libdsk.h>
+
+#include <libspectrum.h>
+
+#include "fuse.h"
+
+static const int WD1770_SR_MOTORON = 1<<7; /* Motor on */
+static const int WD1770_SR_WRPROT = 1<<6; /* Write-protect */
+static const int WD1770_SR_SPINUP = 1<<5; /* Record type / Spin-up complete */
+static const int WD1770_SR_RNF = 1<<4; /* Record Not Found */
+static const int WD1770_SR_CRCERR = 1<<3; /* CRC error */
+static const int WD1770_SR_LOST = 1<<2; /* Lost data */
+static const int WD1770_SR_IDX_DRQ = 1<<1; /* Index pulse / Data request */
+static const int WD1770_SR_BUSY = 1<<0; /* Busy (command under execution) */
+
+extern int wd1770_index_pulse;
+extern int wd1770_index_interrupt;
+
+typedef struct wd1770_drive {
+ DSK_PDRIVER disk;
+ DSK_GEOMETRY geom;
+ char filename[ PATH_MAX ];
+
+ int index_pulse;
+ int index_interrupt;
+
+ int track;
+ int side;
+} wd1770_drive;
+
+typedef struct wd1770_fdc {
+ wd1770_drive *current_drive;
+
+ int rates[ 4 ];
+ int spin_cycles;
+ int direction; /* 0 = spindlewards, 1 = rimwards */
+
+ enum wd1770_state {
+ wd1770_state_none = 0,
+ wd1770_state_seek,
+ wd1770_state_read,
+ wd1770_state_write,
+ wd1770_state_readtrack,
+ wd1770_state_writetrack,
+ wd1770_state_readid,
+ } state;
+
+ enum wd1770_status_type {
+ wd1770_status_type1,
+ wd1770_status_type2,
+ } status_type;
+
+ /* state during transfer */
+ int data_track;
+ int data_sector;
+ int data_side;
+ int data_multisector;
+ int data_offset;
+
+ libspectrum_byte status_register; /* status register */
+ libspectrum_byte track_register; /* track register */
+ libspectrum_byte sector_register; /* sector register */
+ libspectrum_byte data_register; /* data register */
+
+ void ( *set_cmdint ) ( struct wd1770_fdc *f );
+ void ( *reset_cmdint ) ( struct wd1770_fdc *f );
+ void ( *set_datarq ) ( struct wd1770_fdc *f );
+ void ( *reset_datarq ) ( struct wd1770_fdc *f );
+ void *iface;
+} wd1770_fdc;
+
+libspectrum_byte wd1770_sr_read( wd1770_fdc *f );
+void wd1770_cr_write( wd1770_fdc *f, libspectrum_byte b );
+
+libspectrum_byte wd1770_tr_read( wd1770_fdc *f );
+void wd1770_tr_write( wd1770_fdc *f, libspectrum_byte b );
+
+libspectrum_byte wd1770_sec_read( wd1770_fdc *f );
+void wd1770_sec_write( wd1770_fdc *f, libspectrum_byte b );
+
+libspectrum_byte wd1770_dr_read( wd1770_fdc *f );
+void wd1770_dr_write( wd1770_fdc *f, libspectrum_byte b );
+
+void wd1770_set_cmdint( wd1770_fdc *f );
+void wd1770_reset_cmdint( wd1770_fdc *f );
+void wd1770_set_datarq( wd1770_fdc *f );
+void wd1770_reset_datarq( wd1770_fdc *f );
+
+#endif /* #ifndef FUSE_WD1770_H */
Modified: vendor/fuse-emulator/current/fuse/divide.c
===================================================================
--- vendor/fuse-emulator/current/fuse/divide.c 2007-06-27 12:52:44 UTC (rev 402)
+++ vendor/fuse-emulator/current/fuse/divide.c 2007-06-28 13:18:21 UTC (rev 403)
@@ -1,7 +1,7 @@
/* divide.c: DivIDE interface routines
Copyright (c) 2005 Matthew Westcott
- $Id: divide.c 2889 2007-05-26 17:45:08Z zubzero $
+ $Id: divide.c 2995 2007-06-17 14:31:36Z pak21 $
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -29,6 +29,7 @@
#include "ide.h"
#include "machine.h"
+#include "module.h"
#include "periph.h"
#include "settings.h"
#include "ui/ui.h"
@@ -74,6 +75,16 @@
static libspectrum_byte divide_ram[ DIVIDE_PAGES ][ DIVIDE_PAGE_LENGTH ];
static libspectrum_byte divide_eprom[ DIVIDE_PAGE_LENGTH ];
+static void divide_reset( int hard_reset );
+static void divide_memory_map( void );
+
+static module_info_t divide_module_info = {
+
+ divide_reset,
+ divide_memory_map,
+
+};
+
/* Housekeeping functions */
int
@@ -103,6 +114,8 @@
ui_menu_activate( UI_MENU_ITEM_MEDIA_IDE_DIVIDE_SLAVE_EJECT, 1 );
}
+ module_register( ÷_module_info );
+
return error;
}
@@ -117,14 +130,19 @@
return error;
}
-void
-divide_reset( void )
+/* DivIDE does not page in immediately on a reset condition (we do that by
+ trapping PC instead); however, it needs to perform housekeeping tasks upon
+ reset */
+static void
+divide_reset( int hard_reset )
{
if( !settings_current.divide_enabled ) return;
- /* FIXME: MAPRAM bit of control register should be preserved on reset,
- but cleared on hard restart */
- divide_control = 0;
+ if( hard_reset ) {
+ divide_control = 0;
+ } else {
+ divide_control &= DIVIDE_CONTROL_MAPRAM;
+ }
divide_automap = 0;
divide_refresh_page_state();
@@ -301,9 +319,13 @@
void
divide_memory_map( void )
{
+ int upper_ram_page;
+
+ if( !divide_active ) return;
+
/* low bits of divide_control register give page number to use in upper
bank; only lowest two bits on original 32K model */
- int upper_ram_page = divide_control & (DIVIDE_PAGES - 1);
+ upper_ram_page = divide_control & (DIVIDE_PAGES - 1);
if( divide_control & DIVIDE_CONTROL_CONMEM ) {
memory_map_romcs[0].page = divide_eprom;
Modified: vendor/fuse-emulator/current/fuse/divide.h
===================================================================
--- vendor/fuse-emulator/current/fuse/divide.h 2007-06-27 12:52:44 UTC (rev 402)
+++ vendor/fuse-emulator/current/fuse/divide.h 2007-06-28 13:18:21 UTC (rev 403)
@@ -1,7 +1,7 @@
/* divide.h: DivIDE interface routines
Copyright (c) 2005 Matthew Westcott
- $Id: divide.h 2889 2007-05-26 17:45:08Z zubzero $
+ $Id: divide.h 2993 2007-06-17 13:54:49Z pak21 $
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -47,10 +47,8 @@
int divide_init( void );
int divide_end( void );
-void divide_reset( void );
int divide_insert( const char *filename, libspectrum_ide_unit unit );
int divide_commit( libspectrum_ide_unit unit );
int divide_eject( libspectrum_ide_unit unit );
-void divide_memory_map( void );
#endif /* #ifndef FUSE_DIVIDE_H */
Modified: vendor/fuse-emulator/current/fuse/event.c
===================================================================
--- vendor/fuse-emulator/current/fuse/event.c 2007-06-27 12:52:44 UTC (rev 402)
+++ vendor/fuse-emulator/current/fuse/event.c 2007-06-28 13:18:21 UTC (rev 403)
@@ -1,7 +1,7 @@
/* event.c: Routines needed for dealing with the event list
Copyright (c) 2000-2004 Philip Kendall
- $Id: event.c 2918 2007-06-01 12:51:20Z fredm $
+ $Id: event.c 3007 2007-06-17 18:50:48Z zubzero $
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -173,8 +173,20 @@
trdos_event_cmd_done( ptr->tstates );
break;
- case EVENT_TYPE_TRDOS_INDEX: trdos_event_index( ptr->tstates ); break;
+ case EVENT_TYPE_TRDOS_INDEX:
+ trdos_event_index( ptr->tstates );
+ break;
+#ifdef HAVE_LIBDSK_H
+ case EVENT_TYPE_PLUSD_CMD_DONE:
+ plusd_event_cmd_done( ptr->tstates );
+ break;
+
+ case EVENT_TYPE_PLUSD_INDEX:
+ plusd_event_index( ptr->tstates );
+ break;
+#endif /* #ifdef HAVE_LIBDSK_H */
+
case EVENT_TYPE_BREAKPOINT:
debugger_check( DEBUGGER_BREAKPOINT_TYPE_TIME, 0 );
break;
@@ -183,9 +195,10 @@
tape_event_record_sample( ptr->tstates );
break;
- default:
- ui_error( UI_ERROR_ERROR, "unknown event type %d", ptr->type );
+ case EVENT_TYPE_RZX_SENTINEL:
+ rzx_sentinel();
break;
+
}
if( event_free ) {
free( ptr );
@@ -297,11 +310,14 @@
case EVENT_TYPE_INTERRUPT: return "Retriggered interrupt";
case EVENT_TYPE_NMI: return "Non-maskable interrupt";
case EVENT_TYPE_NULL: return "[Deleted event]";
- case EVENT_TYPE_TRDOS_CMD_DONE: return "End of TR-DOS command";
- case EVENT_TYPE_TRDOS_INDEX: return "TR-DOS index";
+ case EVENT_TYPE_TRDOS_CMD_DONE: return "End of BetaDisk command";
+ case EVENT_TYPE_TRDOS_INDEX: return "BetaDisk index";
+ case EVENT_TYPE_PLUSD_CMD_DONE: return "End of +D command";
+ case EVENT_TYPE_PLUSD_INDEX: return "+D index";
case EVENT_TYPE_BREAKPOINT: return "Breakpoint";
case EVENT_TYPE_TIMER: return "Timer";
case EVENT_TYPE_TAPE_RECORD: return "Tape sample record";
+ case EVENT_TYPE_RZX_SENTINEL: return "RZX sentinel";
}
Modified: vendor/fuse-emulator/current/fuse/event.h
===================================================================
--- vendor/fuse-emulator/current/fuse/event.h 2007-06-27 12:52:44 UTC (rev 402)
+++ vendor/fuse-emulator/current/fuse/event.h 2007-06-28 13:18:21 UTC (rev 403)
@@ -1,7 +1,7 @@
/* event.h: Routines needed for dealing with the event list
Copyright (c) 2000-2004 Philip Kendall
- $Id: event.h 2918 2007-06-01 12:51:20Z fredm $
+ $Id: event.h 3007 2007-06-17 18:50:48Z zubzero $
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -47,10 +47,13 @@
EVENT_TYPE_INTERRUPT,
EVENT_TYPE_NMI,
EVENT_TYPE_NULL,
+ EVENT_TYPE_RZX_SENTINEL,
EVENT_TYPE_TRDOS_CMD_DONE,
EVENT_TYPE_TRDOS_INDEX,
EVENT_TYPE_TIMER,
EVENT_TYPE_TAPE_RECORD,
+ EVENT_TYPE_PLUSD_CMD_DONE,
+ EVENT_TYPE_PLUSD_INDEX,
} event_type;
Modified: vendor/fuse-emulator/current/fuse/fuse.c
===================================================================
--- vendor/fuse-emulator/current/fuse/fuse.c 2007-06-27 12:52:44 UTC (rev 402)
+++ vendor/fuse-emulator/current/fuse/fuse.c 2007-06-28 13:18:21 UTC (rev 403)
@@ -1,7 +1,7 @@
/* fuse.c: The Free Unix Spectrum Emulator
Copyright (c) 1999-2007 Philip Kendall
- $Id: fuse.c 2889 2007-05-26 17:45:08Z zubzero $
+ $Id: fuse.c 3007 2007-06-17 18:50:48Z zubzero $
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -45,6 +45,7 @@
#include <SDL.h> /* Needed on MacOS X and Windows */
#endif /* #ifdef UI_SDL */
+#include "ay.h"
#include "dck.h"
#include "debugger/debugger.h"
#include "display.h"
@@ -52,6 +53,7 @@
#include "event.h"
#include "fuse.h"
#include "if1.h"
+#include "if2.h"
#include "joystick.h"
#include "keyboard.h"
#include "machine.h"
@@ -60,8 +62,10 @@
#include "printer.h"
#include "psg.h"
#include "rzx.h"
+#include "scld.h"
#include "settings.h"
#include "simpleide.h"
+#include "slt.h"
#include "snapshot.h"
#include "sound.h"
#include "sound/lowlevel.h"
@@ -71,6 +75,7 @@
#include "trdos.h"
#include "ui/ui.h"
#include "ui/scaler/scaler.h"
+#include "ula.h"
#include "utils.h"
#include "zxatasp.h"
#include "zxcf.h"
@@ -103,6 +108,7 @@
typedef struct start_files_t {
const char *disk_plus3;
+ const char *disk_plusd;
const char *disk_trdos;
const char *dock;
const char *if2;
@@ -241,11 +247,19 @@
if( rzx_init() ) return 1;
if( psg_init() ) return 1;
if( trdos_init() ) return 1;
+#ifdef HAVE_LIBDSK_H
+ if( plusd_init() ) return 1;
+#endif /* #ifdef HAVE_LIBDSK_H */
if( simpleide_init() ) return 1;
if( zxatasp_init() ) return 1;
if( zxcf_init() ) return 1;
if( if1_init() ) return 1;
+ if( if2_init() ) return 1;
if( divide_init() ) return 1;
+ if( scld_init() ) return 1;
+ if( ula_init() ) return 1;
+ if( ay_init() ) return 1;
+ if( slt_init() ) return 1;
error = pokefinder_clear(); if( error ) return error;
@@ -468,6 +482,7 @@
setup_start_files( start_files_t *start_files )
{
start_files->disk_plus3 = settings_current.plus3disk_file;
+ start_files->disk_plusd = settings_current.plusddisk_file;
start_files->disk_trdos = settings_current.trdosdisk_file;
start_files->dock = settings_current.dck_file;
start_files->if2 = settings_current.if2_file;
@@ -549,6 +564,9 @@
case LIBSPECTRUM_CLASS_DISK_PLUS3:
start_files->disk_plus3 = filename; break;
+ case LIBSPECTRUM_CLASS_DISK_PLUSD:
+ start_files->disk_plusd = filename; break;
+
case LIBSPECTRUM_CLASS_DISK_TRDOS:
start_files->disk_trdos = filename; break;
@@ -643,6 +661,11 @@
if( error ) return error;
}
+ if( start_files->disk_plusd ) {
+ error = utils_open_file( start_files->disk_plusd, autoload, NULL );
+ if( error ) return error;
+ }
+
if( start_files->disk_trdos ) {
error = utils_open_file( start_files->disk_trdos, autoload, NULL );
if( error ) return error;
@@ -682,14 +705,14 @@
if( start_files->simpleide_master ) {
error = simpleide_insert( start_files->simpleide_master,
LIBSPECTRUM_IDE_MASTER );
- simpleide_reset();
+ simpleide_reset( 0 );
if( error ) return error;
}
if( start_files->simpleide_slave ) {
error = simpleide_insert( start_files->simpleide_slave,
LIBSPECTRUM_IDE_SLAVE );
- simpleide_reset();
+ simpleide_reset( 0 );
if( error ) return error;
}
@@ -752,6 +775,9 @@
zxcf_end();
if1_end();
divide_end();
+#ifdef HAVE_LIBDSK_H
+ plusd_end();
+#endif /* #ifdef HAVE_LIBDSK_H */
machine_end();
Modified: vendor/fuse-emulator/current/fuse/hacking/ChangeLog
===================================================================
--- vendor/fuse-emulator/current/fuse/hacking/ChangeLog 2007-06-27 12:52:44 UTC (rev 402)
+++ vendor/fuse-emulator/current/fuse/hacking/ChangeLog 2007-06-28 13:18:21 UTC (rev 403)
@@ -1769,3 +1769,108 @@
20070608 man/fuse.1: fix dashes (Stuart).
20070608 sound/alsasound.c: update FSF address (Stuart).
20070609 profile.c: fix printf() warning.
+20070609 BRANCH: plusd_20070609
+20070609 Makefile.am,configure.in,disk/{Makefile.am,plusd.{c,h},wd1770.{c,h}},
+ event.{c,h},fuse.c,machine.c,machines/{spec128.c,spec48.c},memory.c,
+ menu.c,menu_data.dat,periph.{c,h},roms/{Makefile.am,plusd.rom},
+ settings.dat,snapshot.c,tape.c,ui.c,ui/{gtk/gtkui.c,options.dat,ui.h},
+ widget/menu.c,z80/{coretest.c,z80.c,z80_ops.c}: +D emulation
+ (part of patch #1546570) (plusd_20070609) (Stuart).
+20070610 event.[ch],spectrum.c,rzx.[ch],ula.h: add RZX "sentinel" event to
+ prevent running off the end of the contention array on very long
+ frames (see bug #1057471).
+20070610 widget/{memory.c,pokefinder.c,widget_internals.h}: fix up warnings.
+20070610 widget/error.c: don't try and output widgets if we don't have a
+ display yet (fixes bug #1718115).
+20070610 man/fuse.1: remove outdated widget-specific sections (Stuart).
+20070610 keysyms.pl,ui/svga/{svgakeyboard.c,svgadisplay.c}: fix bitrot
+ (fixes bug #1727516) (Gergely Szasz).
+20070610 ui/svga: ignore *.a files.
+20070610 man/fuse.1: add +D documentation (plusd_20070609) (Stuart).
+20070610 man/fuse.1: spelling fixes (Stuart).
+20070611 machines/specplus2.c: enable +D support (plusd_20070609) (Stuart).
+20070611 machines/specplus3.c: save disk images if their 'dirty' state cannot
+ be determined (Stuart).
+20070611 sound/alsasound.c: stop sound_lowlevel...
[truncated message content] |
|
From: <fr...@us...> - 2007-06-27 12:52:47
|
Revision: 402
http://svn.sourceforge.net/fuse-for-macosx/?rev=402&view=rev
Author: fredm
Date: 2007-06-27 05:52:44 -0700 (Wed, 27 Jun 2007)
Log Message:
-----------
Add deployment postprocessing to libspectrum.
Modified Paths:
--------------
trunk/libspectrum/libspectrum.xcodeproj/project.pbxproj
Modified: trunk/libspectrum/libspectrum.xcodeproj/project.pbxproj
===================================================================
--- trunk/libspectrum/libspectrum.xcodeproj/project.pbxproj 2007-06-26 14:05:14 UTC (rev 401)
+++ trunk/libspectrum/libspectrum.xcodeproj/project.pbxproj 2007-06-27 12:52:44 UTC (rev 402)
@@ -369,6 +369,7 @@
ppc,
);
DEBUG_INFORMATION_FORMAT = dwarf;
+ DEPLOYMENT_POSTPROCESSING = YES;
MACOSX_DEPLOYMENT_TARGET_i386 = 10.4;
MACOSX_DEPLOYMENT_TARGET_ppc = 10.3;
SDKROOT_i386 = /Developer/SDKs/MacOSX10.4u.sdk;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fr...@us...> - 2007-06-26 14:05:14
|
Revision: 401
http://svn.sourceforge.net/fuse-for-macosx/?rev=401&view=rev
Author: fredm
Date: 2007-06-26 07:05:14 -0700 (Tue, 26 Jun 2007)
Log Message:
-----------
Fix for problem with closing debugger window.
Modified Paths:
--------------
trunk/fuse/fusepb/controllers/DebuggerController.m
trunk/fuse/fusepb/models/Emulator.h
trunk/fuse/fusepb/models/Emulator.m
trunk/fuse/fusepb/views/DisplayOpenGLView.h
trunk/fuse/fusepb/views/DisplayOpenGLView.m
Modified: trunk/fuse/fusepb/controllers/DebuggerController.m
===================================================================
--- trunk/fuse/fusepb/controllers/DebuggerController.m 2007-06-26 12:07:47 UTC (rev 400)
+++ trunk/fuse/fusepb/controllers/DebuggerController.m 2007-06-26 14:05:14 UTC (rev 401)
@@ -26,6 +26,7 @@
#import "DebuggerController.h"
#import "DisplayOpenGLView.h"
+#import "Emulator.h"
#include <config.h>
@@ -577,7 +578,7 @@
int
ui_debugger_activate( void )
{
- [[DebuggerController singleton] debugger_activate:nil];
+ [[Emulator instance] debuggerActivate];
return 0;
}
Modified: trunk/fuse/fusepb/models/Emulator.h
===================================================================
--- trunk/fuse/fusepb/models/Emulator.h 2007-06-26 12:07:47 UTC (rev 400)
+++ trunk/fuse/fusepb/models/Emulator.h 2007-06-26 14:05:14 UTC (rev 401)
@@ -169,4 +169,6 @@
-(int) trdosDiskWrite:(trdos_drive_number)which;
-(ui_confirm_joystick_t) confirmJoystick:(libspectrum_joystick)type inputs:(int)theInputs;
+-(void) debuggerActivate;
+
@end
Modified: trunk/fuse/fusepb/models/Emulator.m
===================================================================
--- trunk/fuse/fusepb/models/Emulator.m 2007-06-26 12:07:47 UTC (rev 400)
+++ trunk/fuse/fusepb/models/Emulator.m 2007-06-26 14:05:14 UTC (rev 401)
@@ -724,4 +724,9 @@
return [proxy_view confirmJoystick:type inputs:theInputs];
}
+-(void) debuggerActivate
+{
+ [proxy_view debuggerActivate];
+}
+
@end
Modified: trunk/fuse/fusepb/views/DisplayOpenGLView.h
===================================================================
--- trunk/fuse/fusepb/views/DisplayOpenGLView.h 2007-06-26 12:07:47 UTC (rev 400)
+++ trunk/fuse/fusepb/views/DisplayOpenGLView.h 2007-06-26 14:05:14 UTC (rev 401)
@@ -196,6 +196,8 @@
-(int) trdosDiskWrite:(trdos_drive_number)which;
-(ui_confirm_joystick_t) confirmJoystick:(libspectrum_joystick)type inputs:(int)theInputs;
+-(void) debuggerActivate;
+
-(void) mouseMoved:(NSEvent *)theEvent;
-(void) mouseDown:(NSEvent *)theEvent;
-(void) mouseUp:(NSEvent *)theEvent;
Modified: trunk/fuse/fusepb/views/DisplayOpenGLView.m
===================================================================
--- trunk/fuse/fusepb/views/DisplayOpenGLView.m 2007-06-26 12:07:47 UTC (rev 400)
+++ trunk/fuse/fusepb/views/DisplayOpenGLView.m 2007-06-26 14:05:14 UTC (rev 401)
@@ -25,6 +25,7 @@
#import "DisplayOpenGLView.h"
#import "Emulator.h"
#import "FuseController.h"
+#import "DebuggerController.h"
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
@@ -989,6 +990,11 @@
return [[FuseController singleton] confirmJoystick:type inputs:theInputs];
}
+-(void) debuggerActivate
+{
+ [[DebuggerController singleton] debugger_activate:nil];
+}
+
-(void) mouseMoved:(NSEvent *)theEvent
{
[proxy_emulator mouseMoved:theEvent];
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fr...@us...> - 2007-06-26 12:07:48
|
Revision: 400
http://svn.sourceforge.net/fuse-for-macosx/?rev=400&view=rev
Author: fredm
Date: 2007-06-26 05:07:47 -0700 (Tue, 26 Jun 2007)
Log Message:
-----------
Don't bother updating the screen if nothing has changed.
Modified Paths:
--------------
trunk/fuse/fusepb/views/DisplayOpenGLView.h
trunk/fuse/fusepb/views/DisplayOpenGLView.m
trunk/fuse/ui/cocoa/cocoadisplay.h
trunk/fuse/ui/cocoa/cocoadisplay.m
trunk/fuse/ui/cocoa/cocoastatusbar.m
Modified: trunk/fuse/fusepb/views/DisplayOpenGLView.h
===================================================================
--- trunk/fuse/fusepb/views/DisplayOpenGLView.h 2007-06-24 21:52:32 UTC (rev 399)
+++ trunk/fuse/fusepb/views/DisplayOpenGLView.h 2007-06-26 12:07:47 UTC (rev 400)
@@ -66,6 +66,7 @@
ui_statusbar_state disk_state;
ui_statusbar_state mdr_state;
ui_statusbar_state tape_state;
+ BOOL statusbar_updated;
NSWindow *fullscreenWindow;
NSWindow *windowedWindow;
Modified: trunk/fuse/fusepb/views/DisplayOpenGLView.m
===================================================================
--- trunk/fuse/fusepb/views/DisplayOpenGLView.m 2007-06-24 21:52:32 UTC (rev 399)
+++ trunk/fuse/fusepb/views/DisplayOpenGLView.m 2007-06-26 12:07:47 UTC (rev 400)
@@ -255,6 +255,8 @@
currentScreenTex = 0;
+ statusbar_updated = NO;
+
return self;
}
@@ -430,7 +432,8 @@
PIG_dirtytable *workdirty = NULL;
[buffered_screen_lock lock];
- if( NO == screenTexInitialised ) {
+ if( NO == screenTexInitialised ||
+ ( 0 == buffered_screen.dirty->count && NO == statusbar_updated ) ) {
[buffered_screen_lock unlock];
return;
}
@@ -488,6 +491,8 @@
/* Swap buffer to screen */
[[self openGLContext] flushBuffer];
+ statusbar_updated = NO;
+
[buffered_screen_lock unlock];
}
@@ -941,18 +946,21 @@
-(void) setDiskState:(NSNumber*)state
{
disk_state = [state unsignedCharValue];
+ statusbar_updated = YES;
[[FuseController singleton] setDiskState:state];
}
-(void) setTapeState:(NSNumber*)state
{
tape_state = [state unsignedCharValue];
+ statusbar_updated = YES;
[[FuseController singleton] setTapeState:state];
}
-(void) setMdrState:(NSNumber*)state
{
mdr_state = [state unsignedCharValue];
+ statusbar_updated = YES;
[[FuseController singleton] setMdrState:state];
}
Modified: trunk/fuse/ui/cocoa/cocoadisplay.h
===================================================================
--- trunk/fuse/ui/cocoa/cocoadisplay.h 2007-06-24 21:52:32 UTC (rev 399)
+++ trunk/fuse/ui/cocoa/cocoadisplay.h 2007-06-26 12:07:47 UTC (rev 400)
@@ -50,8 +50,6 @@
extern NSLock *buffered_screen_lock;
extern Cocoa_Texture buffered_screen;
-void cocoadisplay_display_updated( void );
-
void copy_area( Cocoa_Texture *dest_screen, Cocoa_Texture *src_screen, PIG_rect *r );
#endif /* #ifndef FUSE_COCOADISPLAY_H */
Modified: trunk/fuse/ui/cocoa/cocoadisplay.m
===================================================================
--- trunk/fuse/ui/cocoa/cocoadisplay.m 2007-06-24 21:52:32 UTC (rev 399)
+++ trunk/fuse/ui/cocoa/cocoadisplay.m 2007-06-26 12:07:47 UTC (rev 400)
@@ -498,9 +498,3 @@
return 0;
}
-
-void
-cocoadisplay_display_updated( void )
-{
- display_updated = 1;
-}
Modified: trunk/fuse/ui/cocoa/cocoastatusbar.m
===================================================================
--- trunk/fuse/ui/cocoa/cocoastatusbar.m 2007-06-24 21:52:32 UTC (rev 399)
+++ trunk/fuse/ui/cocoa/cocoastatusbar.m 2007-06-26 12:07:47 UTC (rev 400)
@@ -42,7 +42,6 @@
withObject:[NSNumber numberWithUnsignedChar:state]
waitUntilDone:NO
];
- if ( settings_current.statusbar ) cocoadisplay_display_updated();
return 0;
case UI_STATUSBAR_ITEM_PAUSED:
@@ -55,7 +54,6 @@
withObject:[NSNumber numberWithUnsignedChar:state]
waitUntilDone:NO
];
- if ( settings_current.statusbar ) cocoadisplay_display_updated();
return 0;
case UI_STATUSBAR_ITEM_MICRODRIVE:
@@ -64,7 +62,6 @@
withObject:[NSNumber numberWithUnsignedChar:state]
waitUntilDone:NO
];
- if ( settings_current.statusbar ) cocoadisplay_display_updated();
return 0;
case UI_STATUSBAR_ITEM_MOUSE:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fr...@us...> - 2007-06-24 21:52:30
|
Revision: 399
http://svn.sourceforge.net/fuse-for-macosx/?rev=399&view=rev
Author: fredm
Date: 2007-06-24 14:52:32 -0700 (Sun, 24 Jun 2007)
Log Message:
-----------
Use a CoreVideo display link rather than setting needs display from the
emulator thread.
Modified Paths:
--------------
trunk/fuse/TODO
trunk/fuse/fusepb/Fuse.xcodeproj/project.pbxproj
trunk/fuse/fusepb/views/DisplayOpenGLView.h
trunk/fuse/fusepb/views/DisplayOpenGLView.m
trunk/fuse/ui/cocoa/cocoadisplay.m
Modified: trunk/fuse/TODO
===================================================================
--- trunk/fuse/TODO 2007-06-24 01:06:12 UTC (rev 398)
+++ trunk/fuse/TODO 2007-06-24 21:52:32 UTC (rev 399)
@@ -30,12 +30,12 @@
DisplayOpenGLView and flip between them on frame end), should also have a
mutex taken while DisplayOpenGLView changes and cocoadisplay flips to
prevent thread sync problems
-* Add .WAV loader using audiofile
+X Add .WAV loader using audiofile
+X Figure out why minimise icon image is partially blanked when minimise starts
* Quit keyhandling when command key is pressed
* Use sheets rather than modal dialogs (for Save As)
* Put in latest hq[23]x filters (HQ2x_555 from ScummVM should do the trick)
* Make border display optional
-* Figure out why minimise icon image is partially blanked when minimise starts
* Allow Cmd-w to close as many windows as possible
* Make activity icons transparent
* Seperate out sound buffer interleaving code to allow for the use of hardware etc.
Modified: trunk/fuse/fusepb/Fuse.xcodeproj/project.pbxproj
===================================================================
--- trunk/fuse/fusepb/Fuse.xcodeproj/project.pbxproj 2007-06-24 01:06:12 UTC (rev 398)
+++ trunk/fuse/fusepb/Fuse.xcodeproj/project.pbxproj 2007-06-24 21:52:32 UTC (rev 399)
@@ -241,6 +241,7 @@
B61F46A109121DF100C8096C /* gcrypt.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6BA1A8B04E4F3290017354F /* gcrypt.framework */; };
B61F46A209121DF100C8096C /* libbz2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6202BD105BD43D800A1EA8F /* libbz2.framework */; };
B61F46A409121DF100C8096C /* FuseImporter.mdimporter in CopyFiles */ = {isa = PBXBuildFile; fileRef = B64FEA96084F8EC300879389 /* FuseImporter.mdimporter */; };
+ B6251C3E0C2EB24500BD5543 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6251C3D0C2EB24500BD5543 /* QuartzCore.framework */; };
B639B7680A6BAFCF00927E24 /* csw.icns in Resources */ = {isa = PBXBuildFile; fileRef = B639B7670A6BAFCF00927E24 /* csw.icns */; };
B639B7D10A6BB45600927E24 /* raw.icns in Resources */ = {isa = PBXBuildFile; fileRef = B639B7D00A6BB45600927E24 /* raw.icns */; };
B6403FD80A7E4B1A00E00B11 /* loader.c in Sources */ = {isa = PBXBuildFile; fileRef = B6403FD60A7E4B1A00E00B11 /* loader.c */; };
@@ -378,6 +379,7 @@
B6202BD105BD43D800A1EA8F /* libbz2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = libbz2.framework; path = ../../bzip2/build/Deployment/libbz2.framework; sourceTree = SOURCE_ROOT; };
B621A11E062E92FB00F63DBC /* if2.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = if2.c; path = ../if2.c; sourceTree = SOURCE_ROOT; };
B621A11F062E92FB00F63DBC /* if2.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = if2.h; path = ../if2.h; sourceTree = SOURCE_ROOT; };
+ B6251C3D0C2EB24500BD5543 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = /System/Library/Frameworks/QuartzCore.framework; sourceTree = "<absolute>"; };
B62E1BC303E298B200A80002 /* Debugger.nib */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = Debugger.nib; path = nibs/Debugger.nib; sourceTree = SOURCE_ROOT; };
B62F3BB4059F5B5900A7009A /* PokeFinder.nib */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = PokeFinder.nib; path = nibs/PokeFinder.nib; sourceTree = "<group>"; };
B62F3BCE059F5BF300A7009A /* PokeFinderController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PokeFinderController.h; path = controllers/PokeFinderController.h; sourceTree = "<group>"; };
@@ -666,6 +668,7 @@
B6A6F0F30B3D602F000B88E9 /* AudioUnit.framework in Frameworks */,
B6A6F1060B3D60D0000B88E9 /* OpenGL.framework in Frameworks */,
B653532B0B902CB20083F942 /* IOKit.framework in Frameworks */,
+ B6251C3E0C2EB24500BD5543 /* QuartzCore.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -693,17 +696,18 @@
1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
isa = PBXGroup;
children = (
+ F541C0750396490901C2A5B9 /* 765.framework */,
B6FA759C0C1D7507007F5A10 /* audiofile.framework */,
B6A6F0F20B3D602F000B88E9 /* AudioUnit.framework */,
B64E2A160A6534A3006863D9 /* Carbon.framework */,
+ 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
B6A6F0ED0B3D5F9E000B88E9 /* CoreAudio.framework */,
+ B6BA1A8B04E4F3290017354F /* gcrypt.framework */,
B653532A0B902CB20083F942 /* IOKit.framework */,
B6202BD105BD43D800A1EA8F /* libbz2.framework */,
- 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
F520C8BC038D022E01A804BA /* OpenGL.framework */,
+ B6251C3D0C2EB24500BD5543 /* QuartzCore.framework */,
F541C04303963A9F01C2A5B9 /* spectrum.framework */,
- F541C0750396490901C2A5B9 /* 765.framework */,
- B6BA1A8B04E4F3290017354F /* gcrypt.framework */,
);
name = "Linked Frameworks";
sourceTree = "<group>";
@@ -1548,8 +1552,8 @@
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
+ i386,
ppc,
- i386,
);
COPY_PHASE_STRIP = NO;
FRAMEWORK_SEARCH_PATHS = (
Modified: trunk/fuse/fusepb/views/DisplayOpenGLView.h
===================================================================
--- trunk/fuse/fusepb/views/DisplayOpenGLView.h 2007-06-24 01:06:12 UTC (rev 398)
+++ trunk/fuse/fusepb/views/DisplayOpenGLView.h 2007-06-24 21:52:32 UTC (rev 399)
@@ -23,6 +23,7 @@
*/
#import <Cocoa/Cocoa.h>
+#import <QuartzCore/QuartzCore.h>
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
@@ -74,6 +75,9 @@
Emulator *real_emulator;
Emulator *proxy_emulator;
NSConnection *kitConnection;
+
+ CVDisplayLinkRef displayLink;
+ CGDirectDisplayID mainViewDisplayID;
}
+(DisplayOpenGLView *) instance;
@@ -213,4 +217,7 @@
-(void) windowWillMiniaturize:(NSNotification *)aNotification;
-(void) windowDidMiniaturize:(NSNotification *)notification;
+-(CVReturn) displayFrame:(const CVTimeStamp *)timeStamp;
+-(void) windowChangedScreen:(NSNotification*)inNotification;
+
@end
Modified: trunk/fuse/fusepb/views/DisplayOpenGLView.m
===================================================================
--- trunk/fuse/fusepb/views/DisplayOpenGLView.m 2007-06-24 01:06:12 UTC (rev 398)
+++ trunk/fuse/fusepb/views/DisplayOpenGLView.m 2007-06-24 21:52:32 UTC (rev 399)
@@ -89,6 +89,19 @@
return bitmap;
}
+CVReturn MyDisplayLinkCallback (
+ CVDisplayLinkRef displayLink,
+ const CVTimeStamp *inNow,
+ const CVTimeStamp *inOutputTime,
+ CVOptionFlags flagsIn,
+ CVOptionFlags *flagsOut,
+ void *displayLinkContext)
+{
+ CVReturn error =
+ [(DisplayOpenGLView*) displayLinkContext displayFrame:inOutputTime];
+ return error;
+}
+
@implementation DisplayOpenGLView
static DisplayOpenGLView *instance = nil;
@@ -249,6 +262,29 @@
{
/* keep the window in the standard aspect ratio if the user resizes */
[[self window] setContentAspectRatio:NSMakeSize(4.0,3.0)];
+
+ CVReturn error = kCVReturnSuccess;
+ CGDirectDisplayID displayID = CGMainDisplayID();
+
+ mainViewDisplayID = displayID;
+
+ error = CVDisplayLinkCreateWithCGDisplay( displayID, &displayLink );
+ if( error ) {
+ NSLog( @"DisplayLink created with error:%d", error );
+ displayLink = NULL;
+ return;
+ }
+ error = CVDisplayLinkSetOutputCallback( displayLink,
+ MyDisplayLinkCallback, self );
+ if( error ) {
+ NSLog( @"Callback created with error:%d", error );
+ return;
+ }
+
+ error = CVDisplayLinkStart( displayLink );
+ if( error ) {
+ NSLog( @"error starting displayLink:%d", error );
+ }
}
- (void)windowWillClose:(NSNotification *)notification
@@ -393,8 +429,11 @@
int i;
PIG_dirtytable *workdirty = NULL;
- if( NO == screenTexInitialised ) return;
[buffered_screen_lock lock];
+ if( NO == screenTexInitialised ) {
+ [buffered_screen_lock unlock];
+ return;
+ }
if( screenTex[currentScreenTex].dirty )
pig_dirty_copy( &workdirty, screenTex[currentScreenTex].dirty );
@@ -1113,4 +1152,23 @@
[[self window] setOpaque:YES];
}
+-(CVReturn) displayFrame:(const CVTimeStamp *)timeStamp
+{
+ [self drawRect:NSZeroRect];
+
+ return kCVReturnSuccess;
+}
+
+-(void) windowChangedScreen:(NSNotification*)inNotification
+{
+ NSWindow *window = [self window];
+ CGDirectDisplayID displayID = (CGDirectDisplayID)[[[[window screen]
+ deviceDescription] objectForKey:@"NSScreenNumber"] intValue];
+ if((displayID != NULL) && (mainViewDisplayID != displayID))
+ {
+ CVDisplayLinkSetCurrentCGDisplay(displayLink, displayID);
+ mainViewDisplayID = displayID;
+ }
+}
+
@end
Modified: trunk/fuse/ui/cocoa/cocoadisplay.m
===================================================================
--- trunk/fuse/ui/cocoa/cocoadisplay.m 2007-06-24 01:06:12 UTC (rev 398)
+++ trunk/fuse/ui/cocoa/cocoadisplay.m 2007-06-24 21:52:32 UTC (rev 399)
@@ -437,13 +437,6 @@
pig_dirty_merge( buffered_screen.dirty, screen->dirty );
- /* We usually can't call AppKit stuff from other threads, but we seem to be
- able to call setNeedsDisplay as long as we are not in drawRect: in the
- main thread - prefer this to sending a message to the main thread as we
- can send loads of messages when we are fastloading and can clog up the
- pipes, the buffered_screen_lock should protect us from drawRect: */
- [[DisplayOpenGLView instance] setNeedsDisplay:YES];
-
/* release lock for buffered screen */
[buffered_screen_lock unlock];
@@ -490,10 +483,13 @@
int
uidisplay_end( void )
{
+ [buffered_screen_lock lock];
+
if( screen && screen->pixels ) {
[[DisplayOpenGLView instance] destroyTexture];
}
+ [buffered_screen_lock unlock];
[buffered_screen_lock release];
free_screen( &unscaled_screen );
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fr...@us...> - 2007-06-24 01:06:11
|
Revision: 398
http://svn.sourceforge.net/fuse-for-macosx/?rev=398&view=rev
Author: fredm
Date: 2007-06-23 18:06:12 -0700 (Sat, 23 Jun 2007)
Log Message:
-----------
Update microdrive status icon.
Modified Paths:
--------------
trunk/fuse/fusepb/views/DisplayOpenGLView.m
Modified: trunk/fuse/fusepb/views/DisplayOpenGLView.m
===================================================================
--- trunk/fuse/fusepb/views/DisplayOpenGLView.m 2007-06-24 00:56:44 UTC (rev 397)
+++ trunk/fuse/fusepb/views/DisplayOpenGLView.m 2007-06-24 01:06:12 UTC (rev 398)
@@ -914,7 +914,7 @@
-(void) setMdrState:(NSNumber*)state
{
mdr_state = [state unsignedCharValue];
- //[[FuseController singleton] setMdrState:state];
+ [[FuseController singleton] setMdrState:state];
}
-(ui_confirm_save_t) confirmSave:(NSString*)theMessage
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fr...@us...> - 2007-06-24 00:56:59
|
Revision: 397
http://svn.sourceforge.net/fuse-for-macosx/?rev=397&view=rev
Author: fredm
Date: 2007-06-23 17:56:44 -0700 (Sat, 23 Jun 2007)
Log Message:
-----------
Update disk status icon.
Modified Paths:
--------------
trunk/fuse/fusepb/views/DisplayOpenGLView.m
Modified: trunk/fuse/fusepb/views/DisplayOpenGLView.m
===================================================================
--- trunk/fuse/fusepb/views/DisplayOpenGLView.m 2007-06-24 00:55:27 UTC (rev 396)
+++ trunk/fuse/fusepb/views/DisplayOpenGLView.m 2007-06-24 00:56:44 UTC (rev 397)
@@ -902,7 +902,7 @@
-(void) setDiskState:(NSNumber*)state
{
disk_state = [state unsignedCharValue];
- //[[FuseController singleton] setDiskState:state];
+ [[FuseController singleton] setDiskState:state];
}
-(void) setTapeState:(NSNumber*)state
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fr...@us...> - 2007-06-24 00:55:35
|
Revision: 396
http://svn.sourceforge.net/fuse-for-macosx/?rev=396&view=rev
Author: fredm
Date: 2007-06-23 17:55:27 -0700 (Sat, 23 Jun 2007)
Log Message:
-----------
Improve window "miniaturizeation" to eliminate white glitch during genie effect.
Modified Paths:
--------------
trunk/fuse/fusepb/views/DisplayOpenGLView.h
trunk/fuse/fusepb/views/DisplayOpenGLView.m
Modified: trunk/fuse/fusepb/views/DisplayOpenGLView.h
===================================================================
--- trunk/fuse/fusepb/views/DisplayOpenGLView.h 2007-06-23 16:11:43 UTC (rev 395)
+++ trunk/fuse/fusepb/views/DisplayOpenGLView.h 2007-06-24 00:55:27 UTC (rev 396)
@@ -207,4 +207,10 @@
-(BOOL) becomeFirstResponder;
-(BOOL) resignFirstResponder;
+-(BOOL) isFlipped;
+
+-(void) copyGLtoQuartz;
+-(void) windowWillMiniaturize:(NSNotification *)aNotification;
+-(void) windowDidMiniaturize:(NSNotification *)notification;
+
@end
Modified: trunk/fuse/fusepb/views/DisplayOpenGLView.m
===================================================================
--- trunk/fuse/fusepb/views/DisplayOpenGLView.m 2007-06-23 16:11:43 UTC (rev 395)
+++ trunk/fuse/fusepb/views/DisplayOpenGLView.m 2007-06-24 00:55:27 UTC (rev 396)
@@ -83,6 +83,12 @@
return pixels;
}
+const void *
+get_byte_pointer(void *bitmap)
+{
+ return bitmap;
+}
+
@implementation DisplayOpenGLView
static DisplayOpenGLView *instance = nil;
@@ -1011,49 +1017,100 @@
return YES;
}
-- (BOOL)isFlipped
+-(BOOL) isFlipped
{
return YES;
}
--(void) copyGLToBackingStore
+/* Minimise code from example code posted by user arekkusu
+ * (http://www.idevgames.com) at http://www.idevgames.com in thread
+ * "Properly minimizing an OpenGL view"
+ */
+-(void) copyGLtoQuartz
{
- [[self openGLContext] makeCurrentContext];
+ NSSize size = [self frame].size;
+ GLfloat zero = 0.0f;
+ long rowbytes = size.width * 4;
+ rowbytes = (rowbytes + 3)& ~3; // ctx rowbytes is always multiple of 4, per glGrab
+ unsigned char* bitmap = malloc(rowbytes * size.height);
+
+ [[NSOpenGLContext currentContext] makeCurrentContext];
+ glFinish(); // finish any pending OpenGL commands
+ glPushAttrib(GL_ALL_ATTRIB_BITS); // reset all properties that affect glReadPixels, in case app was using them
+ glDisable(GL_COLOR_TABLE);
+ glDisable(GL_CONVOLUTION_1D);
+ glDisable(GL_CONVOLUTION_2D);
+ glDisable(GL_HISTOGRAM);
+ glDisable(GL_MINMAX);
+ glDisable(GL_POST_COLOR_MATRIX_COLOR_TABLE);
+ glDisable(GL_POST_CONVOLUTION_COLOR_TABLE);
+ glDisable(GL_SEPARABLE_2D);
+
+ glPixelMapfv(GL_PIXEL_MAP_R_TO_R, 1, &zero);
+ glPixelMapfv(GL_PIXEL_MAP_G_TO_G, 1, &zero);
+ glPixelMapfv(GL_PIXEL_MAP_B_TO_B, 1, &zero);
+ glPixelMapfv(GL_PIXEL_MAP_A_TO_A, 1, &zero);
+
+ glPixelStorei(GL_PACK_SWAP_BYTES, 0);
+ glPixelStorei(GL_PACK_LSB_FIRST, 0);
+ glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
+ glPixelStorei(GL_PACK_ALIGNMENT, 4); // force 4-byte alignment from RGBA framebuffer
+ glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_PACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_PACK_SKIP_IMAGES, 0);
+
+ glPixelTransferi(GL_MAP_COLOR, 0);
+ glPixelTransferf(GL_RED_SCALE, 1.0f);
+ glPixelTransferf(GL_RED_BIAS, 0.0f);
+ glPixelTransferf(GL_GREEN_SCALE, 1.0f);
+ glPixelTransferf(GL_GREEN_BIAS, 0.0f);
+ glPixelTransferf(GL_BLUE_SCALE, 1.0f);
+ glPixelTransferf(GL_BLUE_BIAS, 0.0f);
+ glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
+ glPixelTransferf(GL_ALPHA_BIAS, 0.0f);
+ glPixelTransferf(GL_POST_COLOR_MATRIX_RED_SCALE, 1.0f);
+ glPixelTransferf(GL_POST_COLOR_MATRIX_RED_BIAS, 0.0f);
+ glPixelTransferf(GL_POST_COLOR_MATRIX_GREEN_SCALE, 1.0f);
+ glPixelTransferf(GL_POST_COLOR_MATRIX_GREEN_BIAS, 0.0f);
+ glPixelTransferf(GL_POST_COLOR_MATRIX_BLUE_SCALE, 1.0f);
+ glPixelTransferf(GL_POST_COLOR_MATRIX_BLUE_BIAS, 0.0f);
+ glPixelTransferf(GL_POST_COLOR_MATRIX_ALPHA_SCALE, 1.0f);
+ glPixelTransferf(GL_POST_COLOR_MATRIX_ALPHA_BIAS, 0.0f);
+ glReadPixels(0, 0, size.width, size.height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, bitmap);
+ glPopAttrib();
- NSSize size = [self bounds].size;
+ [self lockFocus];
+ // create a CGImageRef from the memory block
+ CGDataProviderDirectAccessCallbacks gProviderCallbacks = { get_byte_pointer, NULL, NULL, NULL };
+ CGDataProviderRef provider = CGDataProviderCreateDirectAccess(bitmap, rowbytes * size.height, &gProviderCallbacks);
+ CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
+ CGImageRef cgImage = CGImageCreate(size.width, size.height, 8, 32, rowbytes, cs,
+ kCGImageAlphaNoneSkipFirst, provider, NULL, NO, kCGRenderingIntentDefault);
- void *buffer = malloc(size.width * size.height * 4);
+ // composite the CGImage into the view
+ CGContextRef gc = [[NSGraphicsContext currentContext] graphicsPort];
+ CGContextDrawImage(gc, CGRectMake(0, 0, size.width, size.height), cgImage);
- glReadPixels( 0,
- 0,
- size.width,
- size.height,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- buffer );
+ // clean up
+ CGImageRelease(cgImage);
+ CGDataProviderRelease(provider);
+ CGColorSpaceRelease(cs);
+ free(bitmap);
- [self lockFocus];
-
- NSDrawBitmap( [self bounds],
- size.width,
- size.height,
- 8,
- 4,
- 32,
- size.width * 4,
- NO,
- NO,
- NSDeviceRGBColorSpace,
- (unsigned char const **)&buffer );
-
[self unlockFocus];
-
- free(buffer);
+ [[self window] flushWindow];
}
-(void) windowWillMiniaturize:(NSNotification *)aNotification
{
- [self copyGLToBackingStore];
+ [self copyGLtoQuartz];
+ [[self window] setOpaque:NO]; // required to make the Quartz underlay and the window shadow appear correctly
}
+-(void) windowDidMiniaturize:(NSNotification *)notification
+{
+ [[self window] setOpaque:YES];
+}
+
@end
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fr...@us...> - 2007-06-23 16:11:42
|
Revision: 395
http://svn.sourceforge.net/fuse-for-macosx/?rev=395&view=rev
Author: fredm
Date: 2007-06-23 09:11:43 -0700 (Sat, 23 Jun 2007)
Log Message:
-----------
Attempt to limit the memory bus requirements of the program by tracking dirty
rects through the render pipeline and just updating the dirty info in the
texture. Should help older PPC machines in particular.
Modified Paths:
--------------
trunk/fuse/fusepb/Fuse.xcodeproj/project.pbxproj
trunk/fuse/fusepb/views/DisplayOpenGLView.h
trunk/fuse/fusepb/views/DisplayOpenGLView.m
trunk/fuse/ui/cocoa/cocoadisplay.h
trunk/fuse/ui/cocoa/cocoadisplay.m
Added Paths:
-----------
trunk/fuse/ui/cocoa/dirty.c
trunk/fuse/ui/cocoa/dirty.h
trunk/fuse/ui/cocoa/dirtyrects.txt
Modified: trunk/fuse/fusepb/Fuse.xcodeproj/project.pbxproj
===================================================================
--- trunk/fuse/fusepb/Fuse.xcodeproj/project.pbxproj 2007-06-23 15:20:36 UTC (rev 394)
+++ trunk/fuse/fusepb/Fuse.xcodeproj/project.pbxproj 2007-06-23 16:11:43 UTC (rev 395)
@@ -280,6 +280,8 @@
B6B076B20B59FE9A00D4F95C /* Emulator.h in Headers */ = {isa = PBXBuildFile; fileRef = B6B076B00B59FE9A00D4F95C /* Emulator.h */; };
B6B076B30B59FE9A00D4F95C /* Emulator.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B076B10B59FE9A00D4F95C /* Emulator.m */; };
B6B99F8A0B5F798700EE408F /* cocoadisplay.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B99F890B5F798700EE408F /* cocoadisplay.m */; };
+ B6CA27A70C2CDBC500F06FB3 /* dirty.c in Sources */ = {isa = PBXBuildFile; fileRef = B6CA27A50C2CDBC500F06FB3 /* dirty.c */; };
+ B6CA27A80C2CDBC500F06FB3 /* dirty.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CA27A60C2CDBC500F06FB3 /* dirty.h */; };
B6CE7F410B2830A300EB65B3 /* cocoadisplay.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CE7F3B0B2830A300EB65B3 /* cocoadisplay.h */; };
B6CE7F420B2830A300EB65B3 /* cocoajoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = B6CE7F3C0B2830A300EB65B3 /* cocoajoystick.c */; };
B6CE7F440B2830A300EB65B3 /* cocoaui.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CE7F3E0B2830A300EB65B3 /* cocoaui.h */; };
@@ -514,6 +516,8 @@
B6C86978065611B3003000A6 /* intern.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = intern.h; path = scaler/intern.h; sourceTree = SOURCE_ROOT; };
B6C8B723076D2B1A0007B7B5 /* if1.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = if1.c; path = ../if1.c; sourceTree = SOURCE_ROOT; };
B6C8B724076D2B1A0007B7B5 /* if1.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = if1.h; path = ../if1.h; sourceTree = SOURCE_ROOT; };
+ B6CA27A50C2CDBC500F06FB3 /* dirty.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = dirty.c; sourceTree = "<group>"; };
+ B6CA27A60C2CDBC500F06FB3 /* dirty.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = dirty.h; sourceTree = "<group>"; };
B6CA304C049CEC410037E9F2 /* psg.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = psg.c; path = ../psg.c; sourceTree = SOURCE_ROOT; };
B6CA304D049CEC410037E9F2 /* psg.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = psg.h; path = ../psg.h; sourceTree = SOURCE_ROOT; };
B6CC82FF0800E408006EFFB9 /* CAMachines.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CAMachines.h; path = content_arrays/CAMachines.h; sourceTree = SOURCE_ROOT; };
@@ -959,6 +963,8 @@
B67DC2180B63835100FA31B6 /* cocoastatusbar.m */,
B6CE7F3E0B2830A300EB65B3 /* cocoaui.h */,
B6A6F0D90B3D141B000B88E9 /* cocoaui.m */,
+ B6CA27A50C2CDBC500F06FB3 /* dirty.c */,
+ B6CA27A60C2CDBC500F06FB3 /* dirty.h */,
B6E0252B0B38AFE500E23A0F /* keysyms.m */,
);
path = cocoa;
@@ -1278,6 +1284,7 @@
B6B076B20B59FE9A00D4F95C /* Emulator.h in Headers */,
B65352DB0B8CF6780083F942 /* SDL_joystick.h in Headers */,
B65352F30B8CF6CC0083F942 /* SDL_sysjoystick.h in Headers */,
+ B6CA27A80C2CDBC500F06FB3 /* dirty.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1519,6 +1526,7 @@
B67DC2190B63835100FA31B6 /* cocoastatusbar.m in Sources */,
B65352F20B8CF6CC0083F942 /* SDL_sysjoystick.c in Sources */,
B65353150B8FF3D20083F942 /* SDL_joystick.c in Sources */,
+ B6CA27A70C2CDBC500F06FB3 /* dirty.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Modified: trunk/fuse/fusepb/views/DisplayOpenGLView.h
===================================================================
--- trunk/fuse/fusepb/views/DisplayOpenGLView.h 2007-06-23 15:20:36 UTC (rev 394)
+++ trunk/fuse/fusepb/views/DisplayOpenGLView.h 2007-06-23 16:11:43 UTC (rev 395)
@@ -42,8 +42,8 @@
@interface DisplayOpenGLView : NSOpenGLView
{
- /* Need texture size and dimensions and two backing textures */
- Cocoa_Texture screenTex[MAX_SCREEN_BUFFERS]; /* Screen texture */
+ /* Two backing textures */
+ Cocoa_Texture screenTex[MAX_SCREEN_BUFFERS];
GLuint screenTexId[MAX_SCREEN_BUFFERS];
int currentScreenTex;
Modified: trunk/fuse/fusepb/views/DisplayOpenGLView.m
===================================================================
--- trunk/fuse/fusepb/views/DisplayOpenGLView.m 2007-06-23 15:20:36 UTC (rev 394)
+++ trunk/fuse/fusepb/views/DisplayOpenGLView.m 2007-06-23 16:11:43 UTC (rev 395)
@@ -33,6 +33,7 @@
#include "fuse.h"
#include "fusepb/main.h"
#include "settings.h"
+#include "ui/cocoa/dirty.h"
unsigned char *
NSBitmapImageRepToRGBAPixelArray(NSBitmapImageRep * bitmap, int red)
@@ -383,19 +384,33 @@
-(void) drawRect:(NSRect)aRect
{
+ int i;
+ PIG_dirtytable *workdirty = NULL;
+
if( NO == screenTexInitialised ) return;
+ [buffered_screen_lock lock];
+ if( screenTex[currentScreenTex].dirty )
+ pig_dirty_copy( &workdirty, screenTex[currentScreenTex].dirty );
+
currentScreenTex = !currentScreenTex;
- /* Need to draw texture to screen here */
- /* FIXME: lock screen - direct lock probably faster [emulation lockScreen]; */
- [buffered_screen_lock lock];
- /* should draw directly from emulation screen instead of screenTex, switch between
- buffers there */
- memcpy( screenTex[currentScreenTex].pixels, buffered_screen.pixels, screenTex[currentScreenTex].pitch * screenTex[currentScreenTex].full_height );
- /* FIXME: unlock screen - direct lock probably faster [emulation unlockScreen]; */
- [buffered_screen_lock unlock];
+ pig_dirty_copy( &screenTex[currentScreenTex].dirty, buffered_screen.dirty );
+ if( workdirty )
+ pig_dirty_merge(workdirty, screenTex[currentScreenTex].dirty);
+ else
+ pig_dirty_copy(&workdirty, screenTex[currentScreenTex].dirty);
+
+ /* Draw texture to screen */
+ for(i = 0; i < workdirty->count; ++i)
+ copy_area( &screenTex[currentScreenTex], &buffered_screen,
+ workdirty->rects + i );
+
+ buffered_screen.dirty->count = 0;
+
+ pig_dirty_close( workdirty );
+
[[self openGLContext] makeCurrentContext];
glClear( GL_COLOR_BUFFER_BIT );
@@ -427,6 +442,8 @@
/* Swap buffer to screen */
[[self openGLContext] flushBuffer];
+
+ [buffered_screen_lock unlock];
}
/* want to keep image in the original aspect ratio in the face of window resizing */
@@ -496,12 +513,15 @@
GLuint i;
if( screenTexInitialised == NO) return;
- /* FIXME: May want to have a double buffered texture later */
+
glDeleteTextures( MAX_SCREEN_BUFFERS, screenTexId );
for(i = 0; i < MAX_SCREEN_BUFFERS; i++)
{
free( screenTex[i].pixels );
screenTex[i].pixels = NULL;
+ if(screenTex[i].dirty)
+ pig_dirty_close( screenTex[i].dirty );
+ screenTex[i].dirty = NULL;
}
screenTexInitialised = NO;
}
@@ -513,7 +533,6 @@
[[self openGLContext] makeCurrentContext];
[[self openGLContext] update];
- /* FIXME: May want to have a double buffered texture later */
glGenTextures( MAX_SCREEN_BUFFERS, screenTexId );
for(i = 0; i < MAX_SCREEN_BUFFERS; i++)
Modified: trunk/fuse/ui/cocoa/cocoadisplay.h
===================================================================
--- trunk/fuse/ui/cocoa/cocoadisplay.h 2007-06-23 15:20:36 UTC (rev 394)
+++ trunk/fuse/ui/cocoa/cocoadisplay.h 2007-06-23 16:11:43 UTC (rev 395)
@@ -30,9 +30,11 @@
#import <Foundation/NSLock.h>
#include "ui/ui.h"
+#include "dirty.h"
typedef struct Cocoa_Texture {
void *pixels;
+ PIG_dirtytable *dirty;
int full_height;
int full_width;
int image_height;
@@ -50,4 +52,6 @@
void cocoadisplay_display_updated( void );
+void copy_area( Cocoa_Texture *dest_screen, Cocoa_Texture *src_screen, PIG_rect *r );
+
#endif /* #ifndef FUSE_COCOADISPLAY_H */
Modified: trunk/fuse/ui/cocoa/cocoadisplay.m
===================================================================
--- trunk/fuse/ui/cocoa/cocoadisplay.m 2007-06-23 15:20:36 UTC (rev 394)
+++ trunk/fuse/ui/cocoa/cocoadisplay.m 2007-06-23 16:11:43 UTC (rev 395)
@@ -36,6 +36,7 @@
#import "DisplayOpenGLView.h"
#include "cocoadisplay.h"
+#include "dirty.h"
#include "display.h"
#include "fuse.h"
#include "machine.h"
@@ -92,6 +93,10 @@
static int display_updated = 0;
+/* This is a rule of thumb for the maximum number of rects that can be updated
+ each frame. */
+#define MAX_UPDATE_RECT 300
+
static void
init_scalers( void )
{
@@ -138,12 +143,20 @@
screen->full_height = screen->image_height+3;
screen->image_yoffset = 1;
- screen->pixels = calloc( screen->full_width*screen->full_height, sizeof(uint16_t) );
+ screen->pixels = calloc( screen->full_width*screen->full_height,
+ sizeof(uint16_t) );
if( !screen->pixels ) {
fprintf( stderr, "%s: couldn't allocate screen.pixels\n", fuse_progname );
return 1;
}
+ screen->dirty = pig_dirty_open( MAX_UPDATE_RECT );
+ if( !screen->dirty ) {
+ free( screen->pixels );
+ fprintf( stderr, "%s: couldn't allocate screen.dirty\n", fuse_progname );
+ return 1;
+ }
+
screen->pitch = screen->full_width * sizeof(uint16_t);
return 0;
@@ -154,8 +167,12 @@
{
if( screen->pixels ) {
free( screen->pixels );
- screen->pixels=NULL;
+ screen->pixels = NULL;
}
+ if( screen->dirty ) {
+ pig_dirty_close( screen->dirty );
+ screen->dirty = NULL;
+ }
}
static int
@@ -182,6 +199,9 @@
screen->image_width, 1.0f );
if( error ) return error;
+ /* Destroy any existing OpenGL textures (and their dirty lists) */
+ [[DisplayOpenGLView instance] destroyTexture];
+
/* Create OpenGL textures for the image in DisplayOpenGLView */
[[DisplayOpenGLView instance] createTexture:&buffered_screen];
@@ -388,44 +408,82 @@
}
void
+copy_area( Cocoa_Texture *dest_screen, Cocoa_Texture *src_screen, PIG_rect *r )
+{
+ int y;
+
+ for( y = r->y; y <= r->y + r->h; y++ ) {
+ int src_offset = (y + src_screen->image_yoffset) * src_screen->pitch +
+ sizeof(uint16_t) * ( r->x + src_screen->image_xoffset);
+ int dest_offset = (y + dest_screen->image_yoffset) * dest_screen->pitch +
+ sizeof(uint16_t) * ( r->x + dest_screen->image_xoffset);
+ memcpy( dest_screen->pixels + dest_offset, src_screen->pixels + src_offset,
+ r->w * sizeof(uint16_t) );
+ }
+}
+
+void
uidisplay_frame_end( void )
{
- if( display_updated )
+ int i;
+
+ if( display_updated ) {
/* obtain lock for buffered screen */
[buffered_screen_lock lock];
+
/* copy screen data to buffered screen */
- memcpy( buffered_screen.pixels, screen->pixels, screen->pitch * screen->full_height );
+ for(i = 0; i < screen->dirty->count; ++i)
+ copy_area( &buffered_screen, screen, screen->dirty->rects + i );
+
+ pig_dirty_merge( buffered_screen.dirty, screen->dirty );
+
+ /* We usually can't call AppKit stuff from other threads, but we seem to be
+ able to call setNeedsDisplay as long as we are not in drawRect: in the
+ main thread - prefer this to sending a message to the main thread as we
+ can send loads of messages when we are fastloading and can clog up the
+ pipes, the buffered_screen_lock should protect us from drawRect: */
+ [[DisplayOpenGLView instance] setNeedsDisplay:YES];
+
/* release lock for buffered screen */
[buffered_screen_lock unlock];
- [[DisplayOpenGLView instance]
- performSelectorOnMainThread:@selector(setNeedsDisplayYes)
- withObject:nil
- waitUntilDone:NO
- ];
- display_updated = 0;
+
+ display_updated = 0;
+ unscaled_screen.dirty->count = 0;
+ if( current_scaler != SCALER_NORMAL ) scaled_screen.dirty->count = 0;
+ }
}
void
uidisplay_area( int x, int y, int width, int height )
{
- int scaled_x, scaled_y;
+ PIG_rect r = { x, y, width, height };
- display_updated=1;
+ display_updated = 1;
- if( current_scaler == SCALER_NORMAL ) return;
+ if( current_scaler == SCALER_NORMAL ) {
+ pig_dirty_add( unscaled_screen.dirty, &r );
+ return;
+ }
/* Extend the dirty region by 1 pixel for scalers that "smear" the screen,
e.g. 2xSAI */
if( scaler_flags & SCALER_FLAGS_EXPAND )
scaler_expander( &x, &y, &width, &height, image_width, image_height );
- scaled_x = display_current_size * x;
- scaled_y = display_current_size * y;
+ r.x = display_current_size * x;
+ r.y = display_current_size * y;
+ r.w = display_current_size * width;
+ r.h = display_current_size * height;
+ pig_dirty_add( scaled_screen.dirty, &r );
/* Create scaled image */
- scaler_proc16( unscaled_screen.pixels + ( y + 1 ) * unscaled_screen.pitch + sizeof(uint16_t) * ( x + 1 ),
+ scaler_proc16( unscaled_screen.pixels + ( y + unscaled_screen.image_yoffset ) *
+ unscaled_screen.pitch + sizeof(uint16_t) *
+ ( x + unscaled_screen.image_xoffset ),
unscaled_screen.pitch,
- scaled_screen.pixels + scaled_y * scaled_screen.pitch + sizeof(uint16_t) * scaled_x,
+ scaled_screen.pixels + ( r.y + scaled_screen.image_yoffset ) *
+ scaled_screen.pitch + sizeof(uint16_t) *
+ ( r.x + scaled_screen.image_xoffset ),
scaled_screen.pitch, width, height );
}
@@ -448,5 +506,5 @@
void
cocoadisplay_display_updated( void )
{
- display_updated=1;
+ display_updated = 1;
}
Added: trunk/fuse/ui/cocoa/dirty.c
===================================================================
--- trunk/fuse/ui/cocoa/dirty.c (rev 0)
+++ trunk/fuse/ui/cocoa/dirty.c 2007-06-23 16:11:43 UTC (rev 395)
@@ -0,0 +1,188 @@
+/*
+------------------------------------------------------------
+ Fixed Rate Pig - a fixed logic frame rate demo
+------------------------------------------------------------
+ * Copyright (C) 2004 David Olofson <da...@ol...>
+ *
+ * This software is released under the terms of the GPL.
+ *
+ * Contact author for permission if you want to use this
+ * software, or work derived from it, under other terms.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "dirty.h"
+
+/* Approximate worth of one dirtyrect in pixels. */
+#define PIG_WORST_MERGE 300
+
+/*
+ * If the merged result gets at most this many percent
+ * bigger than the larger of the two input rects,
+ * accept it as Perfect.
+ */
+#define PIG_INSTANT_MERGE 10
+
+
+PIG_dirtytable *pig_dirty_open(int size)
+{
+ PIG_dirtytable *pdt = (PIG_dirtytable *)malloc(sizeof(PIG_dirtytable));
+ if(!pdt)
+ return NULL;
+
+ pdt->size = size;
+ pdt->rects = (PIG_rect *)calloc(size, sizeof(PIG_rect));
+ if(!pdt->rects)
+ {
+ free(pdt);
+ return NULL;
+ }
+
+ pdt->count = 0;
+ pdt->best = 0;
+ return pdt;
+}
+
+
+void pig_dirty_close(PIG_dirtytable *pdt)
+{
+ free(pdt->rects);
+ free(pdt);
+}
+
+
+void pig_mergerect(PIG_rect *from, PIG_rect *to)
+{
+ int x1 = from->x;
+ int y1 = from->y;
+ int x2 = from->x + from->w;
+ int y2 = from->y + from->h;
+ if(to->x < x1)
+ x1 = to->x;
+ if(to->y < y1)
+ y1 = to->y;
+ if(to->x + to->w > x2)
+ x2 = to->x + to->w;
+ if(to->y + to->h > y2)
+ y2 = to->y + to->h;
+ to->x = x1;
+ to->y = y1;
+ to->w = x2 - x1;
+ to->h = y2 - y1;
+}
+
+
+void pig_intersectrect(PIG_rect *from, PIG_rect *to)
+{
+ int Amin, Amax, Bmin, Bmax;
+ Amin = to->x;
+ Amax = Amin + to->w;
+ Bmin = from->x;
+ Bmax = Bmin + from->w;
+ if(Bmin > Amin)
+ Amin = Bmin;
+ to->x = Amin;
+ if(Bmax < Amax)
+ Amax = Bmax;
+ to->w = Amax - Amin > 0 ? Amax - Amin : 0;
+
+ Amin = to->y;
+ Amax = Amin + to->h;
+ Bmin = from->y;
+ Bmax = Bmin + from->h;
+ if(Bmin > Amin)
+ Amin = Bmin;
+ to->y = Amin;
+ if(Bmax < Amax)
+ Amax = Bmax;
+ to->h = Amax - Amin > 0 ? Amax - Amin : 0;
+}
+
+
+void pig_dirty_add(PIG_dirtytable *pdt, PIG_rect *dr)
+{
+ int i, j, best_i, best_loss;
+ /*
+ * Look for merger candidates.
+ *
+ * We start right before the best match we
+ * had the last time around. This can give
+ * us large numbers of direct or quick hits
+ * when dealing with old/new rects for moving
+ * objects and the like.
+ */
+ best_i = -1;
+ best_loss = 100000000;
+ if(pdt->count)
+ i = (pdt->best + pdt->count - 1) % pdt->count;
+ for(j = 0; j < pdt->count; ++j)
+ {
+ int a1, a2, am, ratio, loss;
+ PIG_rect testr;
+
+ a1 = dr->w * dr->h;
+
+ testr = pdt->rects[i];
+ a2 = testr.w * testr.h;
+
+ pig_mergerect(dr, &testr);
+ am = testr.w * testr.h;
+
+ /* Perfect or Instant Pick? */
+ ratio = 100 * am / (a1 > a2 ? a1 : a2);
+ if(ratio < PIG_INSTANT_MERGE)
+ {
+ /* Ok, this is good enough! Stop searching. */
+ pig_mergerect(dr, &pdt->rects[i]);
+ pdt->best = i;
+ return;
+ }
+
+ loss = am - a1 - a2;
+ if(loss < best_loss)
+ {
+ best_i = i;
+ best_loss = loss;
+ pdt->best = i;
+ }
+
+ ++i;
+ i %= pdt->count;
+ }
+ /* ...and if the best result is good enough, merge! */
+ if((best_i >= 0) && (best_loss < PIG_WORST_MERGE))
+ {
+ pig_mergerect(dr, &pdt->rects[best_i]);
+ return;
+ }
+
+ /* Try to add to table... */
+ if(pdt->count < pdt->size)
+ {
+ pdt->rects[pdt->count++] = *dr;
+ return;
+ }
+
+ /* Emergency: Table full! Grab best candidate... */
+ pig_mergerect(dr, &pdt->rects[best_i]);
+}
+
+
+void pig_dirty_copy(PIG_dirtytable **pdt, PIG_dirtytable *from)
+{
+ if(*pdt) pig_dirty_close(*pdt);
+ *pdt = pig_dirty_open(from->size);
+ if(*pdt) {
+ memcpy((*pdt)->rects, from->rects, from->count * sizeof(PIG_rect));
+ (*pdt)->count = from->count;
+ }
+}
+
+
+void pig_dirty_merge(PIG_dirtytable *pdt, PIG_dirtytable *from)
+{
+ int i;
+ for(i = 0; i < from->count; ++i)
+ pig_dirty_add(pdt, from->rects + i);
+}
Added: trunk/fuse/ui/cocoa/dirty.h
===================================================================
--- trunk/fuse/ui/cocoa/dirty.h (rev 0)
+++ trunk/fuse/ui/cocoa/dirty.h 2007-06-23 16:11:43 UTC (rev 395)
@@ -0,0 +1,52 @@
+/*
+------------------------------------------------------------
+ Fixed Rate Pig - a fixed logic frame rate demo
+------------------------------------------------------------
+ * Copyright (C) 2004 David Olofson <da...@ol...>
+ *
+ * This software is released under the terms of the GPL.
+ *
+ * Contact author for permission if you want to use this
+ * software, or work derived from it, under other terms.
+ */
+
+#ifndef PIG_DIRTY_H
+#define PIG_DIRTY_H
+
+typedef struct PIG_rect
+{
+ int x;
+ int y;
+ int w;
+ int h;
+} PIG_rect;
+
+/* A table of dirtyrects for one display page */
+typedef struct PIG_dirtytable
+{
+ int size; /* Table size */
+ PIG_rect *rects; /* Table of rects */
+ int count; /* # of rects currently used */
+ int best; /* Merge testing starts here! */
+} PIG_dirtytable;
+
+
+PIG_dirtytable *pig_dirty_open(int size);
+void pig_dirty_close(PIG_dirtytable *pdt);
+
+/* Add rectangle 'dr' to table 'pdt' */
+void pig_dirty_add(PIG_dirtytable *pdt, PIG_rect *dr);
+
+/* Copy table 'from' into 'pdt' */
+void pig_dirty_copy(PIG_dirtytable **pdt, PIG_dirtytable *from);
+
+/* Merge table 'from' into 'pdt' */
+void pig_dirty_merge(PIG_dirtytable *pdt, PIG_dirtytable *from);
+
+/* Extend 'to' to a new rect that includes both 'from' and 'to' */
+void pig_mergerect(PIG_rect *from, PIG_rect *to);
+
+/* Clip 'to' into a rect that is the intersection of 'from' and 'to' */
+void pig_intersectrect(PIG_rect *from, PIG_rect *to);
+
+#endif /* PIG_DIRTY_H */
Added: trunk/fuse/ui/cocoa/dirtyrects.txt
===================================================================
--- trunk/fuse/ui/cocoa/dirtyrects.txt (rev 0)
+++ trunk/fuse/ui/cocoa/dirtyrects.txt 2007-06-23 16:11:43 UTC (rev 395)
@@ -0,0 +1,83 @@
+
+ Smart Dirty Rectangle Management
+ --------------------------------
+
+pig_dirty() contains an algorithm that tries to find
+the the best dirtyrect candidates for merging. While
+searching, it looks out for perfect or sufficiently
+good candidates.
+
+(Perfect candidate:)
+ The merged rectangle is of the same size
+ as the largest of the two input rectangles:
+
+ Amerged <= MAX(A1, A2)
+
+ We don't actually test for this, but rather for...
+
+Instant Pick candidate:
+ Not Perfect, but good enough to be treated
+ as such, considering the cost of going on
+ searching for a better candidate:
+ Amerged 100 / MAX(A1, A2) - 100 <= PIG_INSTANT_MERGE
+
+ (That is, the area of the merged rect must be
+ no more than PIG_INSTANT_MERGE % bigger than
+ the area of the larger of the two input rects.)
+
+ Note that this is also about how likely it is
+ that thereis* a better candidate. Assuming
+ that PIG_INSTANT_MERGE is set to a sensible
+ value, it is not very likely at all. There
+ would have to be another dirtyrect nearby, and
+ the chance of that being a better match is
+ rather low, since that would most likely have
+ caused it to be merged with the tested dirtyrect
+ long before our new rect came in.
+
+(Good candidate:)
+ The area of the merged rectangle is smaller
+ than the total area of the two input rectangles:
+
+ (Amerged - A1 - A2) < 0
+
+ We don't actually test for this, but rather for...
+
+Acceptable candidate:
+ The area of the merged rectangle is larger
+ than the total of the two input rectangles, but
+ since there is some per-rectangle overhead,
+ merging is still a win:
+
+ (Amerged - A1 - A2) <= PIG_WORST_MERGE
+
+ The default setting assumes that the cost of a
+ rectangle is in the range of 300 pixels. One
+ should probably benchmark a few different systems
+ to see if that's reasonable.
+
+Unacceptable candidate:
+ The area of the merged rectangle is larger than
+ the total of the input rectangles to the degree
+ that merging is a definite loss:
+
+ (Amerged - A1 - A2) > PIG_WORST_MERGE
+
+The algorithm instantly returns Perfect candidates as
+solutions. If there are only Good and Acceptable
+candidates, the best one (lowest number of wasted
+pixels) is the solution.
+
+If there are only Unacceptable candidates, there is no
+sensible merger solution, so pig_dirty() will try to add
+a new dirtyrect.
+
+If that fails (table full), the best candidate is used,
+even though it would have been Unacceptable under normal
+circumstances.
+
+
+TODO: Thereare* more alternatives than just "merge" or
+TODO: "don't merge"! For example, it might pay off to
+TODO: detect overlapping and clip dirtyrects to avoid
+TODO: it, when merging is not a viable option.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fr...@us...> - 2007-06-23 15:20:35
|
Revision: 394
http://svn.sourceforge.net/fuse-for-macosx/?rev=394&view=rev
Author: fredm
Date: 2007-06-23 08:20:36 -0700 (Sat, 23 Jun 2007)
Log Message:
-----------
Make HiFi Beeper the default on OS X.
Modified Paths:
--------------
trunk/fuse/settings.dat
Modified: trunk/fuse/settings.dat
===================================================================
--- trunk/fuse/settings.dat 2007-06-20 04:17:59 UTC (rev 393)
+++ trunk/fuse/settings.dat 2007-06-23 15:20:36 UTC (rev 394)
@@ -65,7 +65,7 @@
stereo_beeper, boolean, 0,, beeper-stereo
sound_force_8bit, boolean, 0
sound_freq, numeric, 32000, 'f'
-sound_hifi, boolean, 0
+sound_hifi, boolean, 1
volume, numeric, 0
joy_prompt, boolean, 1,, joyprompt
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fr...@us...> - 2007-06-20 04:17:57
|
Revision: 393
http://svn.sourceforge.net/fuse-for-macosx/?rev=393&view=rev
Author: fredm
Date: 2007-06-19 21:17:59 -0700 (Tue, 19 Jun 2007)
Log Message:
-----------
Add support for tape fastloading to the emulation loop.
Modified Paths:
--------------
trunk/fuse/fusepb/models/Emulator.m
Modified: trunk/fuse/fusepb/models/Emulator.m
===================================================================
--- trunk/fuse/fusepb/models/Emulator.m 2007-06-20 03:56:24 UTC (rev 392)
+++ trunk/fuse/fusepb/models/Emulator.m 2007-06-20 04:17:59 UTC (rev 393)
@@ -159,6 +159,17 @@
(0.8 * sound_framesiz / (float)settings_current.sound_freq ) )
too_long = 1;
}
+ /* If we're fastloading, keep running frames until we have used up 95% of
+ the timer interval */
+ } else if( settings_current.fastload && tape_is_playing() ) {
+ int done = 0;
+ CFTimeInterval startTime = CFAbsoluteTimeGetCurrent();
+ while( !done ) {
+ event_do_frame();
+ CFTimeInterval endTime = CFAbsoluteTimeGetCurrent();
+ if( (endTime - startTime) > (0.95 * timerInterval) )
+ done = 1;
+ }
} else {
float speed = ( settings_current.emulation_speed < 1 ?
100.0 :
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fr...@us...> - 2007-06-20 03:56:22
|
Revision: 392
http://svn.sourceforge.net/fuse-for-macosx/?rev=392&view=rev
Author: fredm
Date: 2007-06-19 20:56:24 -0700 (Tue, 19 Jun 2007)
Log Message:
-----------
Fix texture colours on bigendian machines.
Modified Paths:
--------------
trunk/fuse/fusepb/views/DisplayOpenGLView.m
Modified: trunk/fuse/fusepb/views/DisplayOpenGLView.m
===================================================================
--- trunk/fuse/fusepb/views/DisplayOpenGLView.m 2007-06-20 02:25:45 UTC (rev 391)
+++ trunk/fuse/fusepb/views/DisplayOpenGLView.m 2007-06-20 03:56:24 UTC (rev 392)
@@ -65,9 +65,16 @@
int i;
for( i = 0; i < targetWidth * targetHeight; i++ ) {
+#ifdef WORDS_BIGENDIAN
+ pixels[i*4+3] = red ? pixels[i*4+0] : 0; // r on ppc
+ pixels[i*4+2] = red ? 0 : pixels[i*4+1]; // g on ppc
+ pixels[i*4+0] = 0;
+ pixels[i*4+1] = 0;
+#else /* #ifdef WORDS_BIGENDIAN */
pixels[i*4+0] = red ? pixels[i*4+0] : 0; // r on i386
pixels[i*4+1] = red ? 0 : pixels[i*4+1]; // g on i386
pixels[i*4+2] = 0;
+#endif /* #ifdef WORDS_BIGENDIAN */
}
[bitmap2 release];
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fr...@us...> - 2007-06-20 02:25:53
|
Revision: 391
http://svn.sourceforge.net/fuse-for-macosx/?rev=391&view=rev
Author: fredm
Date: 2007-06-19 19:25:45 -0700 (Tue, 19 Jun 2007)
Log Message:
-----------
AppKit can only be called from the main thread, so pass any calls in the
emulator back to FuseController.
Modified Paths:
--------------
trunk/fuse/fusepb/controllers/FuseController.h
trunk/fuse/fusepb/controllers/FuseController.m
trunk/fuse/fusepb/models/Emulator.h
trunk/fuse/fusepb/models/Emulator.m
trunk/fuse/fusepb/views/DisplayOpenGLView.h
trunk/fuse/fusepb/views/DisplayOpenGLView.m
trunk/fuse/ui/cocoa/cocoaui.m
Modified: trunk/fuse/fusepb/controllers/FuseController.h
===================================================================
--- trunk/fuse/fusepb/controllers/FuseController.h 2007-06-19 02:56:57 UTC (rev 390)
+++ trunk/fuse/fusepb/controllers/FuseController.h 2007-06-20 02:25:45 UTC (rev 391)
@@ -196,6 +196,12 @@
- (void)showAlertPanel:(NSString*)message;
- (void)showCriticalAlertPanel:(NSString*)message;
+-(ui_confirm_save_t) confirmSave:(NSString*)theMessage;
+-(int) tapeWrite;
+-(int) plus3DiskWrite:(specplus3_drive_number)which;
+-(int) trdosDiskWrite:(trdos_drive_number)which;
+-(ui_confirm_joystick_t) confirmJoystick:(libspectrum_joystick)type inputs:(int)theInputs;
+
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication;
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename;
Modified: trunk/fuse/fusepb/controllers/FuseController.m
===================================================================
--- trunk/fuse/fusepb/controllers/FuseController.m 2007-06-19 02:56:57 UTC (rev 390)
+++ trunk/fuse/fusepb/controllers/FuseController.m 2007-06-20 02:25:45 UTC (rev 391)
@@ -117,6 +117,12 @@
static NSSavePanel *sPanel = nil;
+const char* connection_names[] = {
+ "the keyboard",
+ "joystick 1",
+ "joystick 2",
+};
+
@implementation FuseController
static FuseController *singleton = nil;
@@ -749,7 +755,7 @@
- (IBAction)tape_write:(id)sender
{
- ui_tape_write();
+ [self tapeWrite];
}
- (IBAction)tape_record:(id)sender
@@ -1466,6 +1472,199 @@
NSRunCriticalAlertPanel(@"Fuse - Error", message, nil, nil, nil);
}
+-(ui_confirm_save_t) confirmSave:(NSString*)theMessage
+{
+ int result;
+
+ ui_confirm_save_t confirm;
+
+ if( !settings_current.confirm_actions ) return UI_CONFIRM_SAVE_DONTSAVE;
+
+ [[DisplayOpenGLView instance] pause];
+
+ if( ui_mouse_grabbed ) ui_mouse_grabbed = ui_mouse_release( 1 );
+
+ confirm = UI_CONFIRM_SAVE_CANCEL;
+
+ result = NSRunAlertPanel(@"Confirm", theMessage, @"Save",
+ @"Don't Save", @"Cancel");
+
+ switch( result ) {
+ case NSAlertDefaultReturn:
+ confirm = UI_CONFIRM_SAVE_SAVE;
+ break;
+ case NSAlertAlternateReturn:
+ confirm = UI_CONFIRM_SAVE_DONTSAVE;
+ break;
+ case NSAlertOtherReturn:
+ default:
+ confirm = UI_CONFIRM_SAVE_CANCEL;
+ }
+
+ [[DisplayOpenGLView instance] unpause];
+
+ return confirm;
+}
+
+-(int) tapeWrite
+{
+ char *filename = NULL;
+
+ [[DisplayOpenGLView instance] pause];
+
+ filename = cocoaui_savepanel_get_filename( @"Write Tape As", [NSArray arrayWithObjects:@"tzx", @"tap", @"csw", nil] );
+
+ if( !filename ) { [[DisplayOpenGLView instance] unpause]; return 1; }
+
+ /* We will be calling this from the main thread while the emulator is
+ paused */
+ tape_write( filename );
+
+ [self addRecentSnapshotWithString:[NSString stringWithUTF8String:filename]];
+
+ free( filename );
+
+ [[DisplayOpenGLView instance] unpause];
+
+ return 0;
+}
+
+-(int) plus3DiskWrite:(specplus3_drive_number)which
+{
+ char drive, *filename = NULL;
+
+ drive = which == SPECPLUS3_DRIVE_A ? 'A' : 'B';
+
+ if( !specplus3_disk_present( which ) ) {
+ ui_error( UI_ERROR_INFO, "No disk present in drive %c:", drive );
+ return 0;
+ }
+
+ [[DisplayOpenGLView instance] pause];
+
+ NSString *title = [NSString stringWithFormat:@"Write +3 Disk %c: As", drive];
+ filename = cocoaui_savepanel_get_filename( title, [NSArray arrayWithObjects:@"dsk", nil] );
+
+ if( !filename ) { [[DisplayOpenGLView instance] unpause]; return 1; }
+
+ /* We will be calling this from the Emulator thread */
+ specplus3_disk_write( which, filename );
+
+ [self addRecentSnapshotWithString:[NSString stringWithUTF8String:filename]];
+
+ free( filename );
+
+ [[DisplayOpenGLView instance] unpause];
+
+ return 0;
+}
+
+-(int) trdosDiskWrite:(trdos_drive_number)which
+{
+ char drive, *filename = NULL;
+
+ switch( which ) {
+ case TRDOS_DRIVE_A: drive = 'A'; break;
+ case TRDOS_DRIVE_B: drive = 'B'; break;
+ case TRDOS_DRIVE_C: drive = 'C'; break;
+ case TRDOS_DRIVE_D: drive = 'D'; break;
+ default: drive = '?'; break;
+ }
+
+ [[DisplayOpenGLView instance] pause];
+
+ NSString *title = [NSString stringWithFormat:@"Write TR-DOS Disk %c: As", drive];
+ filename = cocoaui_savepanel_get_filename( title, [NSArray arrayWithObjects:@"trd", nil] );
+
+ if( !filename ) { [[DisplayOpenGLView instance] unpause]; return 1; }
+
+ /* We will be calling this from the main thread with emulator paused */
+ trdos_disk_write( which, filename );
+
+ [self addRecentSnapshotWithString:[NSString stringWithUTF8String:filename]];
+
+ free( filename );
+
+ [[DisplayOpenGLView instance] unpause];
+
+ return 0;
+}
+
+-(ui_confirm_joystick_t) confirmJoystick:(libspectrum_joystick)type inputs:(int)theInputs
+{
+ char* joystick_name;
+ char input_names[256] = "";
+ NSString *alertString;
+ NSAlert *alert;
+
+ if( !settings_current.joy_prompt ) return UI_CONFIRM_JOYSTICK_NONE;
+
+ alert = [[NSAlert alloc] init];
+ [alert addButtonWithTitle:@"None"];
+ [alert addButtonWithTitle:@"Joystick 2"];
+ [alert addButtonWithTitle:@"Joystick 1"];
+ [alert addButtonWithTitle:@"Keyboard"];
+
+ [alert setMessageText:@"Configure joystick"];
+ joystick_name = strdup( libspectrum_joystick_name( type ) );
+ joystick_name[0] = tolower( joystick_name[0] );
+ if( theInputs ) {
+ int num_inputs = 0;
+ int i = 0;
+ const char* conn_names[3];
+
+ for( i = 0; theInputs>>i; i++ ) {
+ if( ( theInputs>> i ) & 0x01 ) {
+ conn_names[num_inputs++] = connection_names[i];
+ }
+ }
+
+ if( num_inputs >= 1 ) {
+ sprintf(input_names, " connected to %s", conn_names[0]);
+ }
+ if( num_inputs >= 3 ) {
+ sprintf(input_names, "%s, %s", input_names, conn_names[2]);
+ }
+ if( num_inputs >= 2 ) {
+ sprintf(input_names, "%s and %s", input_names, conn_names[1]);
+ }
+ }
+ alertString = [NSString stringWithFormat:@"The snapshot you are loading is configured for a %s joystick%s. Fuse is not currently configured for a %s joystick, would you like to connect the joystick to:", joystick_name, input_names, joystick_name ];
+ free( joystick_name );
+
+ [alert setInformativeText:alertString];
+ [alert setAlertStyle:NSWarningAlertStyle];
+
+ ui_confirm_joystick_t confirm;
+
+ if( ui_mouse_grabbed ) ui_mouse_grabbed = ui_mouse_release( 1 );
+
+ [[DisplayOpenGLView instance] pause];
+
+ confirm = UI_CONFIRM_JOYSTICK_NONE;
+
+ switch( [alert runModal] ) {
+ case NSAlertFirstButtonReturn:
+ confirm = UI_CONFIRM_JOYSTICK_NONE;
+ break;
+ case NSAlertSecondButtonReturn:
+ confirm = UI_CONFIRM_JOYSTICK_JOYSTICK_2;
+ break;
+ case NSAlertThirdButtonReturn:
+ confirm = UI_CONFIRM_JOYSTICK_JOYSTICK_1;
+ break;
+ case NSAlertThirdButtonReturn+1:
+ confirm = UI_CONFIRM_JOYSTICK_KEYBOARD;
+ break;
+ }
+
+ [alert release];
+
+ [[DisplayOpenGLView instance] unpause];
+
+ return confirm;
+}
+
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
{
return YES;
@@ -1865,222 +2064,6 @@
return 0;
}
-int
-ui_tape_write( void )
-{
- char *filename = NULL;
-
- [[DisplayOpenGLView instance] pause];
-
- filename = cocoaui_savepanel_get_filename( @"Write Tape As", [NSArray arrayWithObjects:@"tzx", @"tap", @"csw", nil] );
-
- if( !filename ) { [[DisplayOpenGLView instance] unpause]; return 1; }
-
- /* We will be calling this from the Emulator thread */
- tape_write( filename );
-
- [[FuseController singleton]
- performSelectorOnMainThread:@selector(addRecentSnapshotWithString:)
- withObject:[NSString stringWithUTF8String:filename]
- waitUntilDone:NO
- ];
-
- free( filename );
-
- [[DisplayOpenGLView instance] unpause];
-
- return 0;
-}
-
-int
-ui_plus3_disk_write( specplus3_drive_number which )
-{
- char drive, *filename = NULL;
-
- drive = which == SPECPLUS3_DRIVE_A ? 'A' : 'B';
-
- if( !specplus3_disk_present( which ) ) {
- ui_error( UI_ERROR_INFO, "No disk present in drive %c:", drive );
- return 0;
- }
-
- [[DisplayOpenGLView instance] pause];
-
- NSString *title = [NSString stringWithFormat:@"Write +3 Disk %c: As", drive];
- filename = cocoaui_savepanel_get_filename( title, [NSArray arrayWithObjects:@"dsk", nil] );
-
- if( !filename ) { [[DisplayOpenGLView instance] unpause]; return 1; }
-
- /* We will be calling this from the Emulator thread */
- specplus3_disk_write( which, filename );
-
- [[FuseController singleton]
- performSelectorOnMainThread:@selector(addRecentSnapshotWithString:)
- withObject:[NSString stringWithUTF8String:filename]
- waitUntilDone:NO
- ];
-
- free( filename );
-
- [[DisplayOpenGLView instance] unpause];
-
- return 0;
-}
-
-int
-ui_trdos_disk_write( trdos_drive_number which )
-{
- char drive, *filename = NULL;
-
- switch( which ) {
- case TRDOS_DRIVE_A: drive = 'A'; break;
- case TRDOS_DRIVE_B: drive = 'B'; break;
- case TRDOS_DRIVE_C: drive = 'C'; break;
- case TRDOS_DRIVE_D: drive = 'D'; break;
- default: drive = '?'; break;
- }
-
- [[DisplayOpenGLView instance] pause];
-
- NSString *title = [NSString stringWithFormat:@"Write TR-DOS Disk %c: As", drive];
- filename = cocoaui_savepanel_get_filename( title, [NSArray arrayWithObjects:@"trd", nil] );
-
- if( !filename ) { [[DisplayOpenGLView instance] unpause]; return 1; }
-
- /* We will be calling this from the Emulator thread */
- trdos_disk_write( which, filename );
-
- [[FuseController singleton]
- performSelectorOnMainThread:@selector(addRecentSnapshotWithString:)
- withObject:[NSString stringWithUTF8String:filename]
- waitUntilDone:NO
- ];
-
- free( filename );
-
- [[DisplayOpenGLView instance] unpause];
-
- return 0;
-}
-
-ui_confirm_save_t
-ui_confirm_save( const char *message )
-{
- NSString *alertString = [NSString stringWithUTF8String:message];
- int result;
-
- ui_confirm_save_t confirm;
-
- if( !settings_current.confirm_actions ) return UI_CONFIRM_SAVE_DONTSAVE;
-
- if( ui_mouse_grabbed ) ui_mouse_grabbed = ui_mouse_release( 1 );
-
- [[DisplayOpenGLView instance] pause];
-
- confirm = UI_CONFIRM_SAVE_CANCEL;
-
- result = NSRunAlertPanel(@"Confirm", alertString, @"Save",
- @"Don't Save", @"Cancel");
-
- switch( result ) {
- case NSAlertDefaultReturn:
- confirm = UI_CONFIRM_SAVE_SAVE;
- break;
- case NSAlertAlternateReturn:
- confirm = UI_CONFIRM_SAVE_DONTSAVE;
- break;
- case NSAlertOtherReturn:
- default:
- confirm = UI_CONFIRM_SAVE_CANCEL;
- }
-
- [[DisplayOpenGLView instance] unpause];
-
- return confirm;
-}
-
-const char* connection_names[] = {
- "the keyboard",
- "joystick 1",
- "joystick 2",
-};
-
-ui_confirm_joystick_t
-ui_confirm_joystick( libspectrum_joystick libspectrum_type, int inputs )
-{
- char* joystick_name;
- char input_names[256] = "";
- NSString *alertString;
- NSAlert *alert;
-
- if( !settings_current.joy_prompt ) return UI_CONFIRM_JOYSTICK_NONE;
-
- alert = [[NSAlert alloc] init];
- [alert addButtonWithTitle:@"None"];
- [alert addButtonWithTitle:@"Joystick 2"];
- [alert addButtonWithTitle:@"Joystick 1"];
- [alert addButtonWithTitle:@"Keyboard"];
-
- [alert setMessageText:@"Configure joystick"];
- joystick_name = strdup( libspectrum_joystick_name( libspectrum_type ) );
- joystick_name[0] = tolower( joystick_name[0] );
- if( inputs ) {
- int num_inputs = 0;
- int i = 0;
- const char* conn_names[3];
-
- for( i = 0; inputs>>i; i++ ) {
- if( ( inputs >> i ) & 0x01 ) {
- conn_names[num_inputs++] = connection_names[i];
- }
- }
-
- if( num_inputs >= 1 ) {
- sprintf(input_names, " connected to %s", conn_names[0]);
- }
- if( num_inputs >= 3 ) {
- sprintf(input_names, "%s, %s", input_names, conn_names[2]);
- }
- if( num_inputs >= 2 ) {
- sprintf(input_names, "%s and %s", input_names, conn_names[1]);
- }
- }
- alertString = [NSString stringWithFormat:@"The snapshot you are loading is configured for a %s joystick%s. Fuse is not currently configured for a %s joystick, would you like to connect the joystick to:", joystick_name, input_names, joystick_name ];
- free( joystick_name );
-
- [alert setInformativeText:alertString];
- [alert setAlertStyle:NSWarningAlertStyle];
-
- ui_confirm_joystick_t confirm;
-
- if( ui_mouse_grabbed ) ui_mouse_grabbed = ui_mouse_release( 1 );
-
- [[DisplayOpenGLView instance] pause];
-
- confirm = UI_CONFIRM_JOYSTICK_NONE;
-
- switch( [alert runModal] ) {
- case NSAlertFirstButtonReturn:
- confirm = UI_CONFIRM_JOYSTICK_NONE;
- break;
- case NSAlertSecondButtonReturn:
- confirm = UI_CONFIRM_JOYSTICK_JOYSTICK_2;
- break;
- case NSAlertThirdButtonReturn:
- confirm = UI_CONFIRM_JOYSTICK_JOYSTICK_1;
- break;
- case NSAlertThirdButtonReturn+1:
- confirm = UI_CONFIRM_JOYSTICK_KEYBOARD;
- break;
- }
-
- [alert release];
-
- [[DisplayOpenGLView instance] unpause];
-
- return confirm;
-}
-
static int
cocoaui_confirm( const char *message )
{
Modified: trunk/fuse/fusepb/models/Emulator.h
===================================================================
--- trunk/fuse/fusepb/models/Emulator.h 2007-06-19 02:56:57 UTC (rev 390)
+++ trunk/fuse/fusepb/models/Emulator.h 2007-06-20 02:25:45 UTC (rev 391)
@@ -29,7 +29,10 @@
#include "input.h"
#include "machines/specplus3.h"
#include "trdos.h"
+#include "ui/ui.h"
+@class DisplayOpenGLView;
+
@interface Emulator : NSObject
{
BOOL isEmulating;
@@ -46,6 +49,8 @@
int cocoakeyboard_caps_shift_pressed;
int cocoakeyboard_symbol_shift_pressed;
input_key unicode_keysym;
+
+ DisplayOpenGLView *proxy_view;
}
+(Emulator *) instance;
@@ -158,4 +163,10 @@
-(void) keyDown:(NSEvent *)theEvent;
-(void) keyUp:(NSEvent *)theEvent;
+-(ui_confirm_save_t) confirmSave:(NSString*)theMessage;
+-(int) tapeWrite;
+-(int) plus3DiskWrite:(specplus3_drive_number)which;
+-(int) trdosDiskWrite:(trdos_drive_number)which;
+-(ui_confirm_joystick_t) confirmJoystick:(libspectrum_joystick)type inputs:(int)theInputs;
+
@end
Modified: trunk/fuse/fusepb/models/Emulator.m
===================================================================
--- trunk/fuse/fusepb/models/Emulator.m 2007-06-19 02:56:57 UTC (rev 390)
+++ trunk/fuse/fusepb/models/Emulator.m 2007-06-20 02:25:45 UTC (rev 391)
@@ -76,7 +76,8 @@
connectionWithReceivePort:[portArray objectAtIndex:0]
sendPort:[portArray objectAtIndex:1]];
[serverConnection setRootObject:self];
- [(id)[serverConnection rootProxy] setServer:self];
+ proxy_view = (id)[serverConnection rootProxy];
+ [proxy_view setServer:self];
if( fuse_init( ac, av ) ) {
fprintf( stderr, "%s: error initialising -- giving up!\n", fuse_progname );
@@ -687,4 +688,29 @@
[self keyChange:theEvent type:INPUT_EVENT_KEYRELEASE];
}
+-(ui_confirm_save_t) confirmSave:(NSString*)theMessage
+{
+ return [proxy_view confirmSave:theMessage];
+}
+
+-(int) tapeWrite
+{
+ return [proxy_view tapeWrite];
+}
+
+-(int) plus3DiskWrite:(specplus3_drive_number)which
+{
+ return [proxy_view plus3DiskWrite:which];
+}
+
+-(int) trdosDiskWrite:(trdos_drive_number)which
+{
+ return [proxy_view trdosDiskWrite:which];
+}
+
+-(ui_confirm_joystick_t) confirmJoystick:(libspectrum_joystick)type inputs:(int)theInputs
+{
+ return [proxy_view confirmJoystick:type inputs:theInputs];
+}
+
@end
Modified: trunk/fuse/fusepb/views/DisplayOpenGLView.h
===================================================================
--- trunk/fuse/fusepb/views/DisplayOpenGLView.h 2007-06-19 02:56:57 UTC (rev 390)
+++ trunk/fuse/fusepb/views/DisplayOpenGLView.h 2007-06-20 02:25:45 UTC (rev 391)
@@ -185,6 +185,12 @@
-(void) setTapeState:(NSNumber*)state;
-(void) setMdrState:(NSNumber*)state;
+-(ui_confirm_save_t) confirmSave:(NSString*)theMessage;
+-(int) tapeWrite;
+-(int) plus3DiskWrite:(specplus3_drive_number)which;
+-(int) trdosDiskWrite:(trdos_drive_number)which;
+-(ui_confirm_joystick_t) confirmJoystick:(libspectrum_joystick)type inputs:(int)theInputs;
+
-(void) mouseMoved:(NSEvent *)theEvent;
-(void) mouseDown:(NSEvent *)theEvent;
-(void) mouseUp:(NSEvent *)theEvent;
Modified: trunk/fuse/fusepb/views/DisplayOpenGLView.m
===================================================================
--- trunk/fuse/fusepb/views/DisplayOpenGLView.m 2007-06-19 02:56:57 UTC (rev 390)
+++ trunk/fuse/fusepb/views/DisplayOpenGLView.m 2007-06-20 02:25:45 UTC (rev 391)
@@ -573,9 +573,7 @@
-(void) openFile:(const char *)filename
{
- /* openFile can end up calling a dialog for joystick selection, this must
- run on the main thread */
- [real_emulator openFile:filename];
+ [proxy_emulator openFile:filename];
}
-(void) tapeOpen:(const char *)filename
@@ -887,6 +885,31 @@
//[[FuseController singleton] setMdrState:state];
}
+-(ui_confirm_save_t) confirmSave:(NSString*)theMessage
+{
+ return [[FuseController singleton] confirmSave:theMessage];
+}
+
+-(int) tapeWrite
+{
+ return [[FuseController singleton] tapeWrite];
+}
+
+-(int) plus3DiskWrite:(specplus3_drive_number)which
+{
+ return [[FuseController singleton] plus3DiskWrite:which];
+}
+
+-(int) trdosDiskWrite:(trdos_drive_number)which
+{
+ return [[FuseController singleton] trdosDiskWrite:which];
+}
+
+-(ui_confirm_joystick_t) confirmJoystick:(libspectrum_joystick)type inputs:(int)theInputs
+{
+ return [[FuseController singleton] confirmJoystick:type inputs:theInputs];
+}
+
-(void) mouseMoved:(NSEvent *)theEvent
{
[proxy_emulator mouseMoved:theEvent];
Modified: trunk/fuse/ui/cocoa/cocoaui.m
===================================================================
--- trunk/fuse/ui/cocoa/cocoaui.m 2007-06-19 02:56:57 UTC (rev 390)
+++ trunk/fuse/ui/cocoa/cocoaui.m 2007-06-20 02:25:45 UTC (rev 391)
@@ -29,6 +29,7 @@
#include <stdio.h>
#import "FuseController.h"
+#import "Emulator.h"
#include "display.h"
#include "fuse.h"
@@ -106,3 +107,34 @@
return 0;
}
+
+ui_confirm_save_t
+ui_confirm_save( const char *message )
+{
+ return [[Emulator instance]
+ confirmSave:[NSString stringWithUTF8String:message]];
+}
+
+int
+ui_tape_write( void )
+{
+ return [[Emulator instance] tapeWrite];
+}
+
+int
+ui_plus3_disk_write( specplus3_drive_number which )
+{
+ return [[Emulator instance] plus3DiskWrite:which];
+}
+
+int
+ui_trdos_disk_write( trdos_drive_number which )
+{
+ return [[Emulator instance] trdosDiskWrite:which];
+}
+
+ui_confirm_joystick_t
+ui_confirm_joystick( libspectrum_joystick libspectrum_type, int inputs )
+{
+ return [[Emulator instance] confirmJoystick:libspectrum_type inputs:inputs];
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fr...@us...> - 2007-06-19 02:56:55
|
Revision: 390
http://svn.sourceforge.net/fuse-for-macosx/?rev=390&view=rev
Author: fredm
Date: 2007-06-18 19:56:57 -0700 (Mon, 18 Jun 2007)
Log Message:
-----------
Add direct tape recording menus.
Modified Paths:
--------------
trunk/fuse/fusepb/controllers/FuseController.h
trunk/fuse/fusepb/controllers/FuseController.m
trunk/fuse/fusepb/models/Emulator.h
trunk/fuse/fusepb/models/Emulator.m
trunk/fuse/fusepb/nibs/MainMenu.nib/classes.nib
trunk/fuse/fusepb/nibs/MainMenu.nib/info.nib
trunk/fuse/fusepb/nibs/MainMenu.nib/keyedobjects.nib
trunk/fuse/fusepb/views/DisplayOpenGLView.h
trunk/fuse/fusepb/views/DisplayOpenGLView.m
Modified: trunk/fuse/fusepb/controllers/FuseController.h
===================================================================
--- trunk/fuse/fusepb/controllers/FuseController.h 2007-06-18 12:03:30 UTC (rev 389)
+++ trunk/fuse/fusepb/controllers/FuseController.h 2007-06-19 02:56:57 UTC (rev 390)
@@ -52,6 +52,7 @@
IBOutlet NSMenuItem *zxatasp;
IBOutlet NSMenuItem *zxcf;
IBOutlet NSMenuItem *tapePlay;
+ IBOutlet NSMenuItem *tapeRecord;
IBOutlet NSMenu *recentSnaps;
IBOutlet NSWindow *window;
@@ -114,6 +115,7 @@
- (IBAction)tape_play:(id)sender;
- (IBAction)tape_rewind:(id)sender;
- (IBAction)tape_write:(id)sender;
+- (IBAction)tape_record:(id)sender;
- (IBAction)showRollbackPane:(id)sender;
- (IBAction)showTapeBrowserPane:(id)sender;
Modified: trunk/fuse/fusepb/controllers/FuseController.m
===================================================================
--- trunk/fuse/fusepb/controllers/FuseController.m 2007-06-18 12:03:30 UTC (rev 389)
+++ trunk/fuse/fusepb/controllers/FuseController.m 2007-06-19 02:56:57 UTC (rev 390)
@@ -101,6 +101,7 @@
static int if1M8WpSet = 0;
static int profileStart = 1;
static int profileStop = 0;
+static int playTape = 1;
static NSMutableArray *allFileTypes = nil;
static NSMutableArray *dckFileTypes = nil;
@@ -751,6 +752,11 @@
ui_tape_write();
}
+- (IBAction)tape_record:(id)sender
+{
+ [[DisplayOpenGLView instance] tapeToggleRecord];
+}
+
- (IBAction)cocoa_break:(id)sender
{
[[DisplayOpenGLView instance] cocoaBreak];
@@ -1138,10 +1144,17 @@
- (void)ui_menu_activate_machine_profiler:(NSNumber*)active
{
- profileStart = ![active boolValue];
- profileStop = [active boolValue];
+ profileStart = ![active boolValue];
+ profileStop = [active boolValue];
}
+- (void)ui_menu_activate_tape_record:(NSNumber*)active
+{
+ playTape = ![active boolValue];
+ [tapeRecord setTitle:[active boolValue] == NO ? @"Record" :
+ @"Stop Recording"];
+}
+
- (BOOL)validateMenuItem:(id <NSMenuItem>)menuItem
{
switch( [menuItem tag] ) {
@@ -1228,6 +1241,13 @@
case 71:
return profileStop == 0 ? NO : YES;
break;
+ case 72:
+ case 73:
+ case 74:
+ case 75:
+ case 76:
+ return playTape == 0 ? NO : YES;
+ break;
default:
return YES;
}
@@ -1825,6 +1845,10 @@
method = @selector(ui_menu_activate_media_ide_divide_slave_eject:);
break;
+ case UI_MENU_ITEM_TAPE_RECORDING:
+ method = @selector(ui_menu_activate_tape_record:);
+ break;
+
default:
ui_error( UI_ERROR_ERROR, "Attempt to activate unknown menu item %d",
item );
Modified: trunk/fuse/fusepb/models/Emulator.h
===================================================================
--- trunk/fuse/fusepb/models/Emulator.h 2007-06-18 12:03:30 UTC (rev 389)
+++ trunk/fuse/fusepb/models/Emulator.h 2007-06-19 02:56:57 UTC (rev 390)
@@ -69,6 +69,7 @@
-(void) tapeOpen:(const char *)filename;
-(void) tapeWrite:(const char *)filename;
-(void) tapeTogglePlay;
+-(void) tapeToggleRecord;
-(void) tapeRewind;
-(void) tapeClear;
-(int) tapeClose;
Modified: trunk/fuse/fusepb/models/Emulator.m
===================================================================
--- trunk/fuse/fusepb/models/Emulator.m 2007-06-18 12:03:30 UTC (rev 389)
+++ trunk/fuse/fusepb/models/Emulator.m 2007-06-19 02:56:57 UTC (rev 390)
@@ -201,6 +201,12 @@
tape_toggle_play( 0 );
}
+-(void) tapeToggleRecord
+{
+ if( tape_recording ) tape_record_stop();
+ else tape_record_start();
+}
+
-(void) tapeRewind
{
tape_select_block( 0 );
Modified: trunk/fuse/fusepb/nibs/MainMenu.nib/classes.nib
===================================================================
--- trunk/fuse/fusepb/nibs/MainMenu.nib/classes.nib 2007-06-18 12:03:30 UTC (rev 389)
+++ trunk/fuse/fusepb/nibs/MainMenu.nib/classes.nib 2007-06-19 02:56:57 UTC (rev 390)
@@ -62,6 +62,7 @@
"tape_clear" = id;
"tape_open" = id;
"tape_play" = id;
+ "tape_record" = id;
"tape_rewind" = id;
"tape_write" = id;
};
@@ -82,6 +83,7 @@
savePanelAccessoryView = id;
simple8Bit = NSMenuItem;
tapePlay = NSMenuItem;
+ tapeRecord = NSMenuItem;
window = NSWindow;
zxatasp = NSMenuItem;
zxcf = NSMenuItem;
Modified: trunk/fuse/fusepb/nibs/MainMenu.nib/info.nib
===================================================================
--- trunk/fuse/fusepb/nibs/MainMenu.nib/info.nib 2007-06-18 12:03:30 UTC (rev 389)
+++ trunk/fuse/fusepb/nibs/MainMenu.nib/info.nib 2007-06-19 02:56:57 UTC (rev 390)
@@ -3,11 +3,11 @@
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
- <string>998 637 356 240 0 0 1440 878 </string>
+ <string>615 505 356 240 0 0 1024 746 </string>
<key>IBEditorPositions</key>
<dict>
<key>29</key>
- <string>201 691 344 44 0 0 1440 878 </string>
+ <string>121 582 392 44 0 0 1024 746 </string>
</dict>
<key>IBFramework Version</key>
<string>446.1</string>
@@ -17,6 +17,6 @@
<integer>29</integer>
</array>
<key>IBSystem Version</key>
- <string>8L2127</string>
+ <string>8P135</string>
</dict>
</plist>
Modified: trunk/fuse/fusepb/nibs/MainMenu.nib/keyedobjects.nib
===================================================================
(Binary files differ)
Modified: trunk/fuse/fusepb/views/DisplayOpenGLView.h
===================================================================
--- trunk/fuse/fusepb/views/DisplayOpenGLView.h 2007-06-18 12:03:30 UTC (rev 389)
+++ trunk/fuse/fusepb/views/DisplayOpenGLView.h 2007-06-19 02:56:57 UTC (rev 390)
@@ -108,6 +108,7 @@
-(void) tapeOpen:(const char *)filename;
-(void) tapeWrite:(const char *)filename;
-(void) tapeTogglePlay;
+-(void) tapeToggleRecord;
-(void) tapeRewind;
-(void) tapeClear;
-(int) tapeClose;
Modified: trunk/fuse/fusepb/views/DisplayOpenGLView.m
===================================================================
--- trunk/fuse/fusepb/views/DisplayOpenGLView.m 2007-06-18 12:03:30 UTC (rev 389)
+++ trunk/fuse/fusepb/views/DisplayOpenGLView.m 2007-06-19 02:56:57 UTC (rev 390)
@@ -593,6 +593,11 @@
[proxy_emulator tapeTogglePlay];
}
+-(void) tapeToggleRecord
+{
+ [proxy_emulator tapeToggleRecord];
+}
+
-(void) tapeRewind
{
[proxy_emulator tapeRewind];
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fr...@us...> - 2007-06-18 12:03:28
|
Revision: 389
http://svn.sourceforge.net/fuse-for-macosx/?rev=389&view=rev
Author: fredm
Date: 2007-06-18 05:03:30 -0700 (Mon, 18 Jun 2007)
Log Message:
-----------
Make sure error alert panels are invoked from the main thread.
Modified Paths:
--------------
trunk/fuse/fusepb/controllers/FuseController.h
trunk/fuse/fusepb/controllers/FuseController.m
trunk/fuse/ui/cocoa/cocoaerror.m
Modified: trunk/fuse/fusepb/controllers/FuseController.h
===================================================================
--- trunk/fuse/fusepb/controllers/FuseController.h 2007-06-17 14:04:21 UTC (rev 388)
+++ trunk/fuse/fusepb/controllers/FuseController.h 2007-06-18 12:03:30 UTC (rev 389)
@@ -191,6 +191,9 @@
- (void)setTapeState:(NSNumber*)state;
- (void)setMdrState:(NSNumber*)state;
+- (void)showAlertPanel:(NSString*)message;
+- (void)showCriticalAlertPanel:(NSString*)message;
+
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication;
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename;
Modified: trunk/fuse/fusepb/controllers/FuseController.m
===================================================================
--- trunk/fuse/fusepb/controllers/FuseController.m 2007-06-17 14:04:21 UTC (rev 388)
+++ trunk/fuse/fusepb/controllers/FuseController.m 2007-06-18 12:03:30 UTC (rev 389)
@@ -1436,6 +1436,16 @@
{
}
+- (void)showAlertPanel:(NSString*)message
+{
+ NSRunAlertPanel(@"Fuse - Info", message, nil, nil, nil);
+}
+
+- (void)showCriticalAlertPanel:(NSString*)message
+{
+ NSRunCriticalAlertPanel(@"Fuse - Error", message, nil, nil, nil);
+}
+
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
{
return YES;
Modified: trunk/fuse/ui/cocoa/cocoaerror.m
===================================================================
--- trunk/fuse/ui/cocoa/cocoaerror.m 2007-06-17 14:04:21 UTC (rev 388)
+++ trunk/fuse/ui/cocoa/cocoaerror.m 2007-06-18 12:03:30 UTC (rev 389)
@@ -34,6 +34,8 @@
#include <stdio.h>
#include <unistd.h>
+#import "FuseController.h"
+
#include "fuse.h"
#include "ui/ui.h"
#include "settings.h"
@@ -41,30 +43,21 @@
int
aqua_verror( ui_error_level severity, const char *message )
{
- NSString *title;
-
- /* Set the appropriate title */
- switch( severity ) {
- case UI_ERROR_INFO:
- title = @"Fuse - Info";
- break;
- case UI_ERROR_ERROR:
- title = @"Fuse - Error";
- break;
- default:
- title = @"Fuse - (Unknown error)";
- break;
- }
-
NSString *alertString = [NSString stringWithUTF8String:message];
switch( severity ) {
case UI_ERROR_INFO:
- NSRunAlertPanel(title, alertString, nil, nil, nil);
+ [[FuseController singleton]
+ performSelectorOnMainThread:@selector(showAlertPanel:)
+ withObject:alertString
+ waitUntilDone:YES];
break;
case UI_ERROR_ERROR:
default:
- NSRunCriticalAlertPanel(title, alertString, nil, nil, nil);
+ [[FuseController singleton]
+ performSelectorOnMainThread:@selector(showCriticalAlertPanel:)
+ withObject:alertString
+ waitUntilDone:YES];
break;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fr...@us...> - 2007-06-17 14:04:57
|
Revision: 388
http://svn.sourceforge.net/fuse-for-macosx/?rev=388&view=rev
Author: fredm
Date: 2007-06-17 07:04:21 -0700 (Sun, 17 Jun 2007)
Log Message:
-----------
Correct initialisation of coreaudio stereo output.
Modified Paths:
--------------
trunk/fuse/sound/coreaudiosound.c
Modified: trunk/fuse/sound/coreaudiosound.c
===================================================================
--- trunk/fuse/sound/coreaudiosound.c 2007-06-17 13:35:22 UTC (rev 387)
+++ trunk/fuse/sound/coreaudiosound.c 2007-06-17 14:04:21 UTC (rev 388)
@@ -108,9 +108,9 @@
| kLinearPCMFormatFlagIsBigEndian
#endif /* #ifdef WORDS_BIGENDIAN */
| kLinearPCMFormatFlagIsPacked;
- deviceFormat.mBytesPerPacket = 2;
+ deviceFormat.mBytesPerPacket = *stereoptr ? 4 : 2;
deviceFormat.mFramesPerPacket = 1;
- deviceFormat.mBytesPerFrame = 2;
+ deviceFormat.mBytesPerFrame = *stereoptr ? 4 : 2;
deviceFormat.mBitsPerChannel = 16;
deviceFormat.mChannelsPerFrame = *stereoptr ? 2 : 1;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|