Hi,
I've had a go at implementing SAM Messenger snapshot loading support for
libspectrum (I.e. FUSE).
It seems to work, but needs more testing. There was one snapshot that
I couldn't get working, but I've no idea why... perhaps a timing issue?
Anyway, I've included a disassembly of the messenger loader as well as
the diff against libspectrum.
Cheers,
--
Stuart Brady
; mesload.asm
08ed: di
ld (8938),sp ; 0938
in a,(fc) ; vmpr
ld (8937),a ; 0937
in a,(fa) ; lmpr
ld (8935),a ; 0935
ld a,04
out (fc),a ; vmpr
ld sp,bcea ; 3cea
pop iy ; restore iy
pop ix ; restore ix
pop de ; restore de'
pop bc ; restore bc'
pop hl ; restore hl'
pop af ; restore af'
exx
ex af,af'
pop de ; restore de
pop bc ; restore bc
pop hl ; restore hl
pop af ; restore i
ld i,a
cp 3f ; set interrupt mode...
jr z,ldstk
cp 00
jr z,ldstk
im 2
ldstk: ld sp,(bcfe) ; restore sp
ld a,a3 ; wpram | rom0 | bcd 3
out (fa),a ; lmpr
jp 0928 ; ???
ld a,05 ; bcd 5
0928: out (fb),a ; hmpr
pop af
ld r,a ; restore r
jp po,0933 ; check bit 2 of f, skip if zero
ei
0933: pop af ; restore af
ret ; restore pc
; note that sp has been incremented by 6 since it was loaded
diff -urN libspectrum.orig/internals.h libspectrum.messenger/internals.h
--- libspectrum.orig/internals.h 2006-01-21 04:49:19.000000000 +0000
+++ libspectrum.messenger/internals.h 2006-01-21 00:49:31.000000000 +0000
@@ -123,6 +123,9 @@
libspectrum_plusd_read( libspectrum_snap *snap,
const libspectrum_byte *buffer, size_t buffer_length );
libspectrum_error
+libspectrum_mes_read( libspectrum_snap *snap,
+ const libspectrum_byte *buffer, size_t buffer_length );
+libspectrum_error
internal_sna_read( libspectrum_snap *snap,
const libspectrum_byte *buffer, size_t buffer_length );
libspectrum_error
diff -urN libspectrum.orig/libspectrum.c libspectrum.messenger/libspectrum.c
--- libspectrum.orig/libspectrum.c 2006-01-21 04:49:34.000000000 +0000
+++ libspectrum.messenger/libspectrum.c 2006-01-21 00:45:27.000000000 +0000
@@ -450,6 +450,7 @@
{ LIBSPECTRUM_ID_RECORDING_RZX, "rzx", 3, "RZX!", 0,
4, 4 },
+ { LIBSPECTRUM_ID_SNAPSHOT_MES, "mes", 3, NULL, 0, 0, 0 },
{ LIBSPECTRUM_ID_SNAPSHOT_SNA, "sna", 3, NULL, 0, 0, 0 },
{ LIBSPECTRUM_ID_SNAPSHOT_SNP, "snp", 3, NULL, 0, 0, 0 },
{ LIBSPECTRUM_ID_SNAPSHOT_SP, "sp", 3, "\x53\x50\0", 0, 3, 1 },
@@ -559,6 +560,7 @@
*libspectrum_class = LIBSPECTRUM_CLASS_RECORDING; return 0;
case LIBSPECTRUM_ID_SNAPSHOT_PLUSD:
+ case LIBSPECTRUM_ID_SNAPSHOT_MES:
case LIBSPECTRUM_ID_SNAPSHOT_SNA:
case LIBSPECTRUM_ID_SNAPSHOT_SNP:
case LIBSPECTRUM_ID_SNAPSHOT_SP:
diff -urN libspectrum.orig/libspectrum.h.in
libspectrum.messenger/libspectrum.h.in
--- libspectrum.orig/libspectrum.h.in 2006-01-21 04:49:34.000000000 +0000
+++ libspectrum.messenger/libspectrum.h.in 2006-01-21 00:42:01.000000000
+0000
@@ -149,6 +149,7 @@
LIBSPECTRUM_ID_SNAPSHOT_SNP, /* .snp snapshot */
LIBSPECTRUM_ID_SNAPSHOT_ZXS, /* .zxs snapshot (zx32) */
LIBSPECTRUM_ID_SNAPSHOT_SZX, /* .szx snapshot (Spectaculator) */
+ LIBSPECTRUM_ID_SNAPSHOT_MES, /* .mes snapshot (Messenger) */
/* Below here, present only in 0.2.1 and later */
diff -urN libspectrum.orig/Makefile.am libspectrum.messenger/Makefile.am
--- libspectrum.orig/Makefile.am 2006-01-21 04:49:33.000000000 +0000
+++ libspectrum.messenger/Makefile.am 2006-01-20 23:53:21.000000000 +0000
@@ -32,6 +32,7 @@
dck.c \
ide.c \
libspectrum.c \
+ mes.c \
microdrive.c \
plusd.c \
rzx.c \
diff -urN libspectrum.orig/mes.c libspectrum.messenger/mes.c
--- libspectrum.orig/mes.c 1970-01-01 01:00:00.000000000 +0100
+++ libspectrum.messenger/mes.c 2006-01-21 04:16:37.000000000 +0000
@@ -0,0 +1,89 @@
+/* mes.c: Routines for handling SAM Coupe Messenger snapshots
+ Copyright (c) 2006 Stuart Brady
+ Copyright (c) 1998,2003 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Author contact information:
+
+ E-mail: [EMAIL PROTECTED]
+ Postal address: 15 Crescent Road, Wokingham, Berks, RG40 2DB, England
+
+*/
+
+#include <config.h>
+
+#include "internals.h"
+
+libspectrum_error
+libspectrum_mes_read( libspectrum_snap *snap, const libspectrum_byte *buffer,
+ size_t length )
+{
+ libspectrum_error error;
+ const libspectrum_byte *regs;
+ libspectrum_word sp;
+ libspectrum_byte i;
+
+ /* Length must be at least 64K (48K RAM with 16K ROM image) */
+ if( length < 0x10000 ) {
+ libspectrum_print_error(
+ LIBSPECTRUM_ERROR_CORRUPT,
+ "libspectrum_mes_read: not enough bytes for a .mes file"
+ );
+ return LIBSPECTRUM_ERROR_CORRUPT;
+ }
+
+ /* All Messenger snaps are of the 48K machine */
+ libspectrum_snap_set_machine( snap, LIBSPECTRUM_MACHINE_48 );
+
+ /* Get the RAM */
+ error = libspectrum_split_to_48k_pages( snap, buffer + 0x4000 );
+ if( error != LIBSPECTRUM_ERROR_NONE ) return error;
+
+ regs = buffer + 0x3cea; /* register offset */
+ libspectrum_snap_set_iy ( snap, regs[ 0] + regs[ 1] * 0x100 );
+ libspectrum_snap_set_ix ( snap, regs[ 2] + regs[ 3] * 0x100 );
+ libspectrum_snap_set_de_ ( snap, regs[ 4] + regs[ 5] * 0x100 );
+ libspectrum_snap_set_bc_ ( snap, regs[ 6] + regs[ 7] * 0x100 );
+ libspectrum_snap_set_hl_ ( snap, regs[ 8] + regs[ 9] * 0x100 );
+ libspectrum_snap_set_f_ ( snap, regs[10] );
+ libspectrum_snap_set_a_ ( snap, regs[11] );
+ libspectrum_snap_set_de ( snap, regs[12] + regs[13] * 0x100 );
+ libspectrum_snap_set_bc ( snap, regs[14] + regs[15] * 0x100 );
+ libspectrum_snap_set_hl ( snap, regs[16] + regs[17] * 0x100 );
+
+ /* Byte 18 not used */
+ i = regs[19];
+ if (i == 00 || i == 0x3f) {
+ libspectrum_snap_set_im ( snap, 0 );
+ } else {
+ libspectrum_snap_set_im ( snap, 2 );
+ }
+ libspectrum_snap_set_i ( snap, i );
+
+ sp = (regs[20] + regs[21] * 0x100) & 0xffff;
+ libspectrum_snap_set_sp ( snap, (sp + 6) & 0xffff );
+
+ libspectrum_snap_set_iff1 ( snap, buffer[sp + 0] & 0x02 ? 0 : 1 );
+ libspectrum_snap_set_iff2 ( snap, 0 );
+ libspectrum_snap_set_r ( snap, buffer[sp + 1] );
+ libspectrum_snap_set_f ( snap, buffer[sp + 2] );
+ libspectrum_snap_set_a ( snap, buffer[sp + 3] );
+ libspectrum_snap_set_pc ( snap, buffer[sp + 4] + buffer[sp + 5] * 0x100
);
+
+ return LIBSPECTRUM_ERROR_NONE;
+}
diff -urN libspectrum.orig/snapshot.c libspectrum.messenger/snapshot.c
--- libspectrum.orig/snapshot.c 2006-01-21 04:49:19.000000000 +0000
+++ libspectrum.messenger/snapshot.c 2006-01-21 00:46:20.000000000 +0000
@@ -224,6 +224,9 @@
case LIBSPECTRUM_ID_SNAPSHOT_PLUSD:
error = libspectrum_plusd_read( snap, buffer, length ); break;
+ case LIBSPECTRUM_ID_SNAPSHOT_MES:
+ error = libspectrum_mes_read( snap, buffer, length ); break;
+
case LIBSPECTRUM_ID_SNAPSHOT_SNA:
error = internal_sna_read( snap, buffer, length ); break;