From 4c72225c6e44b1a9470d553713e4ca58f0414c23 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 26 Oct 2012 14:49:25 +0000 Subject: [PATCH] added basic support for the loop flags in tzx [David Haywood] --- hash/spectrum_cass.xml | 33 +++++++++++------- src/lib/formats/tzx_cas.c | 71 ++++++++++++++++++++++++++++++++++----- 2 files changed, 82 insertions(+), 22 deletions(-) diff --git a/hash/spectrum_cass.xml b/hash/spectrum_cass.xml index 934e4c862ac..03398a23069 100644 --- a/hash/spectrum_cass.xml +++ b/hash/spectrum_cass.xml @@ -19,7 +19,7 @@ The MESS emulation at the time of writing isn't very good, the following emulators are used to determine how things should work Fuse (Free Unix Spectrum Emulator) - Free, High Compatibility can run some of the trickier images, Windows port available - http://fuse-emulator.sourceforge.net/ - Spectaculator - Commercial, a bit more user friendly than above, similar compatibility - http://www.spectaculator.com/ + Spectaculator - Commercial, a bit more user friendly than above, similar compatibility - http://www.spectaculator.com/ Note, even with those emulators you'll have to turn off some of the speed cheats on loading to get good compatibilty for example, in Fuse Use Tape Traps @@ -30,9 +30,14 @@ MESS doesn't have any accelerated loading so some games which require the tricks to be disabled in other emulators work in MESS without trickery, eg Xanthius http://newton.sunderland.ac.uk/~specfreak/Schemes/schemes.html is a rather outdated guide mentioning some of the custom loaders, and showing disassemblies of them. + + legacy emulators including Real Spectrum ( http://zxm.speccy.cz/realspec/ ) appear to struggle with some of the more complex tape protections + + + ToDo: Find an emulator which works with the 'Gremlin 2' protected tapes 'M.A.S.K' and 'Basil The Great Mouse Detective' all TZX images I've found fail in the + above emulators, although RealSpectrum does load some copies of MASK but fails loading the 2nd part of the game. - legacy emulators including Real Spectrum ( http://zxm.speccy.cz/realspec/ ) appear to struggle with some of the more complex tape protections --> @@ -344,8 +349,8 @@ - - + + Batman (set 2) 1986 Ocean @@ -356,8 +361,9 @@ - - + + + Batman (set 3) 1986 Ocean @@ -368,7 +374,7 @@ - + Batman (set 4) 1986 @@ -381,6 +387,7 @@ + Batman (set 5) 1986 @@ -392,8 +399,8 @@ - - + + Batman (set 6) 1986 Ocean @@ -404,8 +411,8 @@ - - + + Batman (set 7) 1986 Ocean @@ -416,8 +423,8 @@ - - + + Batman (set 8) 1986 Ocean diff --git a/src/lib/formats/tzx_cas.c b/src/lib/formats/tzx_cas.c index 1ad91f771c2..4cdc9d4587d 100644 --- a/src/lib/formats/tzx_cas.c +++ b/src/lib/formats/tzx_cas.c @@ -80,7 +80,7 @@ static void tzx_cas_get_blocks( const UINT8 *casdata, int caslen ) { int pos = sizeof(TZX_HEADER) + 2; int max_block_count = INITIAL_MAX_BLOCK_COUNT; - + int loopcount = 0, loopoffset = 0; blocks = (UINT8**)malloc(max_block_count * sizeof(UINT8*)); memset(blocks,0,max_block_count); block_count = 0; @@ -134,15 +134,31 @@ static void tzx_cas_get_blocks( const UINT8 *casdata, int caslen ) datasize = casdata[pos] + (casdata[pos + 1] << 8) + (casdata[pos + 2] << 16); pos += 3 + datasize; break; - case 0x20: case 0x23: case 0x24: + case 0x20: case 0x23: pos += 2; break; + + case 0x24: + loopcount = casdata[pos] + (casdata[pos + 1] << 8); + pos +=2; + loopoffset = pos; + break; + case 0x21: case 0x30: datasize = casdata[pos]; pos += 1 + datasize; break; - case 0x22: case 0x25: case 0x27: + case 0x22: case 0x27: break; + + case 0x25: + if (loopcount>0) + { + pos = loopoffset; + loopcount--; + } + break; + case 0x26: datasize = casdata[pos] + (casdata[pos + 1] << 8); pos += 2 + 2 * datasize; @@ -313,6 +329,8 @@ static int tzx_cas_do_work( INT16 **buffer ) wave_data = WAVE_LOW; + int loopcount = 0, loopoffset = 0; + while (current_block < block_count) { int pause_time; @@ -322,8 +340,9 @@ static int tzx_cas_do_work( INT16 **buffer ) UINT8 *cur_block = blocks[current_block]; UINT8 block_type = cur_block[0]; + /* Uncomment this to include into error.log a list of the types each block */ -// LOG_FORMATS("tzx_cas_fill_wave: block %d, block_type %02x\n", current_block, block_type); + LOG_FORMATS("tzx_cas_fill_wave: block %d, block_type %02x\n", current_block, block_type); switch (block_type) { @@ -460,14 +479,29 @@ static int tzx_cas_do_work( INT16 **buffer ) LOG_FORMATS("Please use a .tzx handling utility to split the merged tape files.\n"); current_block++; break; - case 0x15: /* Direct Recording */ - case 0x18: /* CSW Recording */ - case 0x19: /* Generalized Data Block */ + case 0x24: /* Loop Start */ + loopcount = cur_block[1] + (cur_block[2] << 8); + current_block++; + loopoffset = current_block; + + LOG_FORMATS("loop start %d %d\n", loopcount, current_block); + break; + case 0x25: /* Loop End */ + if (loopcount>0) + { + current_block = loopoffset; + loopcount--; + LOG_FORMATS("do loop\n"); + } + else + { + current_block++; + } + break; + case 0x21: /* Group Start */ case 0x22: /* Group End */ case 0x23: /* Jump To Block */ - case 0x24: /* Loop Start */ - case 0x25: /* Loop End */ case 0x26: /* Call Sequence */ case 0x27: /* Return From Sequence */ case 0x28: /* Select Block */ @@ -477,6 +511,25 @@ static int tzx_cas_do_work( INT16 **buffer ) LOG_FORMATS("Unsupported block type (%02x) encountered.\n", block_type); current_block++; break; + + case 0x15: /* Direct Recording */ + // having this missing is fatal + printf("Unsupported block type (0x15 - Direct Recording) encountered.\n"); + current_block++; + break; + + case 0x18: /* CSW Recording */ + // having this missing is fatal + printf("Unsupported block type (0x15 - CSW Recording) encountered.\n"); + current_block++; + break; + + case 0x19: /* Generalized Data Block */ + // having this missing is fatal + printf("Unsupported block type (0x19 - Generalized Data Block) encountered.\n"); + current_block++; + break; + } } return size;