SPECSAISIE 1.2 (C) BROADSOFT 2003
==============

A Java program [Java is a trademark of Sun Microsystems, Inc.]

Written by Andrew Broad
http://www.geocities.com/andrewbroad/


Introduction
------------

SPECSAISIE is a Java program for performing surgery on/between SNA files and TAP files, and various other functions related to these Spectrum-emulation file-formats. There are even some special Manic Miner and Jet Set Willy functions on top of that, and plans to extend the functionality in the future.

An SNA (snapshot) file is an encoding of the complete state of a Spectrum at the moment it was created. SPECSAISIE allows you to manipulate SNA files. There are other snapshot file-formats such as Z80, which are not supported by SPECSAISIE but can be converted to SNA files by the C program SPConv [http://www.worldofspectrum.org/utilities.html] or via an emulator.

A TAP file is an encoding of the files on a Spectrum tape. Because a TAP file is fundamentally different in nature to an SNA file, there is no straightforward conversion between them, but SPECSAISIE lets you load a TAP file onto an existing SNA file (loading a tape into memory), and save a TAP file from an SNA file (the current implementation only works for CODE files, not BASIC files and array files).

SPECSAISIE currently supports the following functions:


General Spectrum functions:

* PrintHeaders: Print the header of each Spectrum file on a tape.

* Split: Split a TAP file into separate TAP files for each Spectrum file on
  the tape (the resulting TAP files can be recombined using simple file-
  concatenation).

* TAPtoSNA: Convert a TAP file to an SNA file by loading the Spectrum files on
  the tape into memory.

* SNAtoTAP: Convert an SNA file to a TAP file by saving Spectrum files onto
  tape from memory.

* TAPtoBinary: Convert a (singleton) TAP file to a raw binary by stripping off
  its header. For example, to create an SCR screenshot from a SCREEN$ file.

* SNAtoBinary: Save a raw binary from a range of addresses in an SNA file.

* BinaryToTAP: Convert a raw binary file to a TAP file.

* BinaryToSNA: Patch a raw binary file onto an SNA file.

* FixChecksum: Fix any checksum-errors in a TAP file. So you could edit a
  TAP file in a text-editor, for example, and then run it through this to
  correct the checksums.

* Peek: Print the byte-value(s) stored in an address or a range of addresses.

* Poke: Write a byte-value into a specified address.

* Compare: Compare two SNA files byte-by-byte, reporting addresses for which
  the two memories have different values, and what the value is for the second
  memory.

* Saisie: Generate a BASIC program for typing data from emulator files into a
  real Spectrum. The program includes a DATA line for each eight bytes, and a
  checksum for each line.

* CSaisie: Combines Compare and Saisie to generate a listing of changes from
  one file to another, calling Saisie for clusters of many differences.

* Count: Generate hash totals for an SNA file for quick checking, i.e. add up 
  all the byte values between specified intervals. 

* ASCII: Print an address-range from an SNA file as ASCII text.


Manic Miner/Jet Set Willy functions:

* RoomsMM: Given an SNA file of a Manic Miner game, print the 20 room-titles.

* RoomsJSW: Given an SNA file of a Jet Set Willy game, print the 64 room-
  titles.

* RoomMM: Given an SNA file of a Manic Miner game, generate an ASCII preview
  of a given room.

* RoomJSW: Given an SNA file of a Jet Set Willy game, generate an ASCII
  preview of a given room.

* BGB_JSW: Detect occurrences of the block-graphics bug in a JSW game
  (an experimental implementation).


Instructions
------------

To use SPECSAISIE, you need a Java compiler and a Java interpreter (freely downloadable from http://java.sun.com/j2se/1.4.1/download.html). I developed and use SPECSAISIE using Java 1.2 on a Sun workstation running UNIX. The code should be portable to different platforms - and even earlier versions of Java - without modification, although I can't guarantee this.

SPECSAISIE has various classes with "main" functions - one for each external function listed above. Before each such class can be used, its source code (.java file) has to be compiled - e.g. "javac PrintHeaders.java" to compile PrintHeaders (resulting in PrintHeaders.class). The Java compiler should compile any other source files it uses on demand. But if you get errors about classes defined in other .java files not being found - or anyway if you want to compile all the source files at once - try "javac *.java".

Each "main" class, once compiled, is used via the Java interpreter (java). Instructions on how to use each such class follow (in alphabetical order of class name).

The SPECSAISIE source code is 'Javadoccable' - you can have it generate HTML documentation for each class by using "javadoc PrintHeaders.java" &c.

+-------+
| ASCII |
+-------+

Prints an address-range from an SNA file as ASCII text.

Usage: java ASCII <file.SNA> (<start_address> (<stop_address>))

e.g. "java ASCII JETSET.SNA 33908 34131":
  JET-SET WILLY by Matthew Smith   1984 SOFTWARE PROJECTS Ltd . . . . .Guide Willy to collect all the items around the house before Midnight so Maria will let you get to your bed. . . . . . .+++++ Press ENTER to Start +++++

+---------+
| BGB_JSW |
+---------+

Detects occurrences of the Block-Graphics Bug in a JSW game (as an SNA file), where a block graphic in a room is corrupted if its colour attribute occurs as a byte of pixel-data in any of the preceding block graphics. At the time of releasing SPECSAISIE 1.0, implementation is experimental and incomplete, including much diagnostic output for testing/debugging purposes. The next version will allow the user to tell it to ignore certain colour attributes (such as 0 and 255, which tend to be used for unused block graphics), and it will be adapted to MM (BGB_MM).

Usage: java BGB_JSW <file.SNA>

e.g. "java BGB_JSW JETSET.SNA" would detect occurrences of the BGB in JETSET.SNA.

+-------------+
| BinaryToSNA |
+-------------+

Patches a raw binary file onto an SNA file. For example, one could patch an SCR file (which is a raw 6912-byte binary file) onto an SNA file.

Usage: java BinaryToSNA <load.SNA> <binary_file> <save_as.SNA> <start_address>

e.g. "java BinaryToSNA WEPRETTY.SNA KRISNIK.SCR WEPRETTY.SNA 16384"

A blank SNA file, taken just after resetting the emulated Spectrum, is included in this archive (NEW.SNA).

+-------------+
| BinaryToTAP |
+-------------+

Converts a raw binary file to a TAP file. For example, I wrote We Pretty on my real Spectrum, but drew the loading-screen on my emulator, saving it as an SCR file (KRISNIK.SCR), which is a raw 6912-byte binary file.

Usage: java BinaryToTAP <binary_file> <save_as.TAP> <Spectrum filename> <start_address> (<length>)

e.g. "java BinaryToTAP KRISNIK.SCR WEPRETTY.TAP Krisnikova 16384"

If no length is specified (as in the above example), the length of the binary file is used. If the length specified is longer than the binary file, the length of the binary file is used.

+---------+
| Compare |
+---------+

Compares two SNA files byte-by-byte, printing the addresses which hold different values and the value for the /second/ SNA file.

Usage: java Compare <file1.SNA> <file2.SNA> (<start_address> (<stop_address>))

e.g. Comparing the Bug-Byte and Software Projects versions of Manic Miner:

     "java Compare MM-BB.SNA MM-SP.SNA 32768 65535"

     "java Compare MM-BB.SNA MM-SP.SNA 32768" (default is 65535)

     "java Compare MM-BB.SNA MM-SP.SNA" (default is 16357 65535 -
     i.e. the whole 49179 bytes of the SNA file)

+-------+
| Count |
+-------+

Computes hash totals (i.e. adding up all the byte values between two addresses) for an SNA file, of specified granularity. I use this to check that I have typed something into my real Spectrum correctly, especially if I did so using Compare (which I use when the differences from a file I've already got on the real Spectrum are sparse) rather than Saisie (when the differences are dense).

Usage: java Count <file.SNA> (<start_address> (<step_size> (<stop_address>)))

e.g. "java Count JETSET.SNA 32768 1024 65535"
This computes hash totals for 32768-33791, 33792-34815, ..., 64512-65535, which is my standard check for a MM/JSW game.

     "java Count JETSET.SNA 32768 1024" (default is 65535)
     "java Count JETSET.SNA 32768" (default is 1024 65535)
     "java Count JETSET.SNA" (default is 32768 1024 65535)

If (stop_address + 1 - start_address) is not divisible by step_size (as it should be), it will count past the stop-address for the last block (including values after the stop-address in the count), but will fail for the last block if this causes it to run off the end of memory (65535).

The program I use to do the counting on my real Spectrum (to check against a printout from SPECSAISIE) is:

Specific program			General program template
----------------			------------------------

10 FOR a=32768 TO 65535 STEP 1024	FOR a=<start_address> TO 
20  LET c=0				       <stop_address> STEP <step_size>
30  FOR i=0 TO 1023                       FOR i=0 TO stepsize-1
40   LET c=c+PEEK(a+i)
50  NEXT i
60  PRINT a;": ";
70 NEXT a


+---------+
| CSaisie | (new as of SPECSAISIE 1.2)
+---------+

Combines Compare and Saisie to generate a type-in for a new Spectrum file that covers all the changes from an old file to the new file with minimal typing effort.

The idea is to compare the old file with the new file byte-for-byte, and replace clusters of differences with Saisie output wherever the differences are dense enough for typing a block of contiguous bytes to be less effort than POKEing the individual changes.

Usage: java CSaisie <old_file.SNA> <new_file.SNA> <start_address>
(<length> (<stop_address> (<distance> (<density>))))

e.g. "java CSaisie MM-BB.SNA MM-SP.SNA 32768 1024 65535 64 17"

This compares MM-BB.SNA with MM-SP.SNA from 32768 to 65535 in blocks of 1024 bytes, clustering the differences such that the addresses of differences in separate clusters are at least 64 bytes apart in memory (<distance> - the default is 64). If there are at least 17 differences in a given cluster (<density> - the default is 17), then the Compare-output for that cluster is replaced with Saisie-output to cover all the differences in that cluster.

+-------------+
| FixChecksum |
+-------------+

Fixes the checksums on a TAP file if they are incorrect, i.e. it supposes that the contents of the TAP file are correct and alters the checksums if necessary to make it valid. For example, you could edit a TAP file using a text-editor, and then use FixChecksum to correct the checksums.

Usage: java FixChecksum <file.TAP> 

e.g. "java FixChecksum JS_DIZZY.TAP"

+------+
| Peek |
+------+

Prints the byte-value stored at a specified address, or the byte-values stored in a range of addresses.

Usage: java Peek <file.SNA> <start_address> (<stop_address>)

e.g. "java Peek JETSET.SNA 35899":
35899: 53

e.g. "java Peek JETSET.SNA 35591 35593":
35591: 33
35592: 0
35593: 154

+------+
| Poke |
+------+

Writes a byte-value into a specified address.

Usage: java Poke <file.SNA> <address> <byte>

e.g. "java Poke JETSET.SNA 35899 0"

+--------------+
| PrintHeaders |
+--------------+

Prints basic information about each Spectrum file on a TAP file:
- Name: the filename of a Spectrum file
- Type: the type (BASIC, code, number-array or character-array)
- Line (for BASIC files): the line-number to GO TO when it's loaded
- VarA (for BASIC files): offset of the variable-area relative to the start of
  the program (in bytes). Same as Leng if no variables are saved.
- Star (for CODE files): the start-address
- Leng: the length of the file (in bytes)
- Stop (for CODE files): the stop-address (new as of version 1.1;
       derived from the start-address and the length: Stop = Star + Leng-1)

Usage: java PrintHeaders <file.TAP>

e.g. "java PrintHeaders JETSET.TAP"

Name: "JETSET    "
Type: BASIC
Line: 0
VarA: 1005
Leng: 1005

Name: "JETSET 1  "
Type: CODE
Star: 32768 (Stop: 65535)
Leng: 32768

+---------+
| RoomJSW |
+---------+

Prints an ASCII-text-preview of a given room in a Jet Set Willy game (given as an SNA file).

Usage: java RoomJSW <file.SNA> <room_number>
where {0 <= room_number <= 63}

e.g. "java RoomJSW WEPRETTY.SNA 33"

+--------+
| RoomMM |
+--------+

Prints an ASCII-text-preview of a given room in a Manic Miner game (given as an SNA file).

Usage: java RoomMM <file.SNA> <room_number>
where {0 <= room_number <= 19}

e.g. "java RoomsMM MA_JOLIE.SNA 0"

+----------+
| RoomsJSW |
+----------+

Prints the 64 room-titles in a Jet Set Willy game (as an SNA file).

Usage: java RoomsJSW <file.SNA>

e.g. "java RoomsJSW WEPRETTY.SNA"

+---------+
| RoomsMM |
+---------+

Prints the 20 room-titles in a Manic Miner game (as an SNA file).

Usage: java RoomsMM <file.SNA>

e.g. "java RoomsMM MA_JOLIE.SNA"

+--------+
| Saisie |
+--------+

Generates a BASIC program for typing in a specified block of code. I use this all the time for typing MM/JSW games from the Internet into my real Spectrum! :-) The program consists of DATA lines of eight bytes each, plus a checksum (a weighted modulo value between 256 and 999, which takes into account the addresses and values of the eight data-bytes).

SPECSAISIE 1.1 only generates the DATA lines, not the rest of the BASIC program (saved on my real Spectrum) that reads and pokes the data, checking the checksums and reporting lines with errors. A future version may, on request from the user, generate the rest of the BASIC program - which, for now, is in the text-file SPECSAISIE.BAS, to which the following indented section pertains:
>>>
Line 60 of the program in SPECSAISIE.BAS has to be edited manually to specify the start-address, length, and CLEAR-address (CLEAR tells the Spectrum the highest address it may automatically overwrite, so CLEAR start-1 is typically used to reserve addresses start to 65535).

If you edit the CLEAR-address and get "RAMTOP no good" when you run the program, you will need to relocate the code to higher in memory where it will fit, and modify the program accordingly. Say you wanted to type in a 1024-byte block of code starting at 32768. You could relocate it to start at 49152 by modifying the program as follows:
  60 CLEAR 32767+16384: LET start=32768: LET length=1024
 140   READ byte: IF byte<256 THEN POKE addr+16384,byte
 230 SAVE f$ CODE start+16384,length
 250 VERIFY f$ CODE start+16384,length

Obviously, you would have to relocate the code back to 32768 when you loaded it back in, by typing LOAD "" CODE 32768 rather than just LOAD "" CODE!
<<<

Usage: java Saisie <file.SNA> <start_address> (<length> (<stop_address>))

e.g. "java Saisie MM-BB.SNA 45056 32" (the first row of "Central Cavern" in MM):
1000 DATA 22,0,0,0,0,0,0,0,454
1010 DATA 0,0,0,5,0,0,0,0,460
1020 DATA 5,0,0,0,0,0,0,0,453
1030 DATA 0,0,0,0,0,0,0,22,632

"java Saisie MM-BB.SNA 45056 > 45056.TXT"
This redirects the output to a file called 45056.TXT (for those of you who are unfamiliar with UNIX, the "> 45056.TXT" bit is not part of the call to java Saisie, which is just "java Saisie MM-BB.SNA 45056" - the default length is 1024 bytes).

As of version 1.1, Saisie takes the following command-line flags:
-r: automatically annotate the first line of the output with the filename,
    start-address and length
-f: write the output to files rather than standard output,
    each file named after the start-address of the block

The fourth argument (stop-address) is new as of version 1.1, and is for generating more than one block of output at once.

e.g. "java Saisie MM-BB.SNA 45056 1024 65535 -rf"
This generates 20 type-in files (with filenames 45056, 46080, ..., 64512),
with a REM statement planted in the first line of each file, to say that it's
from MM-BB.SNA, the start-address of that output file, and the length (1024).

Trivia: SPECSAISIE started as a simple Lisp program for my Mac (PowerLisp being the only language on my Mac which enabled reading files byte-by-byte) for generating listings for typing in machine code. It ran like molasses under PowerLisp (it literally took about half an hour to generate a listing for a 1K block!), so eventually I decided to convert it to a Java program to run on my Sun at university, and add lots of other nice features. The name SPECSAISIE comes from these Amstrad magazines called AM!MAG and MICRO!MAG that I found in France in 1989 and 1990, which were full of type-in machine-code games for the Amstrad CPC (and endless hours of fun I had typing them in, too! :-) ). The program for typing in the machine code, with checksums, was called AMSAISIE.

+-------------+
| SNAtoBinary |
+-------------+

Save a raw binary file from an SNA file, given a range of addresses. An example use would be to create an SCR file from an SNA file (you could then convert the SCR file to a GIF image file using scr2gif, for example).

Usage: java SNAtoBinary <sna> <binary filename> <start_address> <length>

e.g. "java SNAtoBinary GL.SNA GL.SCR 16384 6912"

+----------+
| SNAtoTAP |
+----------+

Converts an SNA file to a TAP file. More precisely, it saves a Spectrum file from the memory encoded in the SNA file to form a singleton TAP file. It can save either a BASIC file (you specify the auto-start line-number) or a CODE file (you specify the start-address and length).

Usage: java SNAtoTAP <sna> <tap> <Spectrum filename> <start> <length>
where         <sna>: SNA file
              <tap>: TAP file to save
<Spectrum filename>: name of CODE file
            <start>: start-address
           <length>: length (in bytes)

   OR: java SNAtoTAP <sna> <tap> <Spectrum filename> (<line>)
where         <sna>: SNA file
              <tap>: TAP file to save
<Spectrum filename>: name of BASIC file
             <line>: auto-start line-number

e.g. "java SNAtoTAP JETSET.SNA JETSET_1.TAP "JSWProgram" 10"

     "java SNAtoTAP JETSET.SNA JETSET_1.TAP "JSWProgram"" (no auto-start)

     "java SNAtoTAP JETSET.SNA JETSET_2.TAP "JSWBytes" 32768 32768"

+-------+
| Split |
+-------+

Splits a TAP file into singleton TAP files (i.e. a separate TAP file for each Spectrum file on the TAP file), calling them <name>_1.TAP, <name>_2.TAP, <name>_3.TAP, &c. You will find Split to be an invaluable intermediate function when working with SPECSAISIE (e.g. to rearrange TAP files, or to dig out a CODE file to convert to SNA).

Usage: java Split <file.TAP>

e.g. "java Split JETSET.TAP"

This would create two TAP files, JETSET_1.TAP (the BASIC loader) and JETSET_2.TAP (the CODE file).

The TAP file-format respects simple file-concatenation, so the inverse of the above operation would be "cat JETSET_1.TAP JETSET_2.TAP > JETSET.TAP".

+-------------+
| TAPtoBinary |
+-------------+

Strips off the headers of a singleton TAP file, saving it as a raw binary file (if given a TAP file with more than one Spectrum file on it, it ignores all Spectrum files after the first - you'll probably have to use Split first). An example use would be to create an SCR file from a TAP file with a SCREEN$ on it (you could then convert the SCR file to a GIF image file using scr2gif, for example).

Usage: java TAPtoBinary <file.TAP> <binary_file_name>

e.g. Say KRISNIK.TAP was a TAP file containing just a SCREEN$ file. Then "java TAPtoBinary KRISNIK.TAP KRISNIK.SCR" would create a raw binary file of 6912 bytes (the standard length of a SCREEN$) called KRISNIK.SCR.

+----------+
| TAPtoSNA |
+----------+

Converts a TAP file to an SNA file. More precisely, it loads each Spectrum file on the TAP file onto an existing SNA file, and then saves the resulting SNA file.

TAPtoSNA is useful for converting TAP files to SNA in order to be able to use the other nice functions of SPECSAISIE which operate on SNA files (e.g. RoomsMM, RoomsJSW, Compare, Saisie, Count, &c.), but I wouldn't recommend it for converting a TAP file that you want to release in SNA format - use an emulator for that. I make no warranties that the resulting SNA file will work on a Spectrum emulator - it may crash if, for example, RAMTOP is not set correctly, and that's your problem.

If you /are/ going to use TAPtoSNA to load CODE files onto an existing SNA file, with the intention of using the resulting SNA file on an emulator, bear in mind that anything like CLEAR 32767, that you normally have to do before loading a machine-code file, has to be done before saving the initial SNA file. Only use TAPtoSNA to generate SNA files for use with an emulator if you know what you're doing - otherwise, you're better off using an emulator to save an SNA file from the TAP file.

A blank SNA file, taken just after resetting the emulated Spectrum, is included in this archive (NEW.SNA).

Usage: java TAPtoSNA <sna0> <tap> <sna1> (<addr>)
 where <sna0>: SNA file representing initial state;
        <tap>: TAP file to load;
       <sna1>: SNA file representing state after loading TAP file;
       <addr>: Optional address to relocate CODE files to.

e.g. "java TAPtoSNA NEW.SNA JETSET.TAP JETSET.SNA"

An example of where you would want to relocate a CODE file in memory is if you wanted to apply RoomsJSW to a JSW128 game. RoomsJSW assumes that the rooms are stored in 49152-65535, whereas a JSW128 TAP file contains four 16K room files, some of which are saved 32768-49151. Such a file would have to be relocated to a start-address of 49152 for RoomsJSW to work. Suppose you had one of these room files as a singleton TAP file ROOMS1.TAP. Then "java TAPtoSNA NEW.SNA ROOMS1.TAP ROOMS1.SNA 49152" would create ROOMS1.SNA with the rooms starting at 49152, suitable for "java RoomsJSW ROOMS1.SNA".

Be aware that if you specify a relocation-address for a multi-file TAP file,
it will relocate every CODE file on the tape to that address!


Internet
--------

I currently have a website at http://www.geocities.com/andrewbroad/. Some relevant pages within this website are:

* http://www.geocities.com/andrewbroad/cs/java/
My Java pages.

* http://www.geocities.com/andrewbroad/spectrum/
Top-level index of my Spectrum pages.

* http://www.geocities.com/andrewbroad/spectrum/download/
My download page. Currently contains my Manic Miner Screen Editor, and my MM/JSW games. Also has previews of forthcoming software (mostly MM/JSW games), including projected release-dates (which may change over time according to my progress).

* http://www.geocities.com/andrewbroad/spectrum/willy/
My Manic Miner/Jet Set Willy pages.

I recommend the comp.sys.sinclair USENET newsgroup as a place for discussing Spectrum-related topics. It's worth at least browsing through the headers each day (says he who has long since lost touch with USENET :-o ). I announce my releases on comp.sys.sinclair (though it's better to check my web pages periodically for news). The newsgroup is archived at http://groups.google.com/ for those who don't have access to a news-server - in fact, it's worth surfing there even if you do, as not all news-servers receive all newsgroup postings! http://www.mailandnews.com/ (a free Web-based email service) also provides access to newsgroups over the Web.


Copyright Notice
----------------

SPECSAISIE is, of course, my copyright, but I don't mind you putting it on your own website or redistributing it otherwise, provided that no money is charged, and that you acknowledge that it is the copyright of Broadsoft (2003). This document must be included with all copies of the program. Modifications are discouraged but not forbidden, and you should state specifically what you have modified.

I give my permission to translate SPECSAISIE to other languages, or to run on other platforms, or otherwise reuse parts of the design or code, provided that you give me credit where credit is due. And please let me know - it's not that I'd be likely to object, I'd just be very interested to know what follows from releasing SPECSAISIE!


Version History
---------------

1st September 2000: Release of SPECSAISIE version 1.0 on the Internet.

14th September 2002: SPECSAISIE 1.1 released:
+ RoomMM;
+ RoomJSW;
+ SNAtoTAP (early brick version - CODE files only);
+ added stop-address to Saisie to generate multiple blocks at once,
  with command-line flags:
  -f (write output to files instead of standard output);
  -r (insert REM statement in first line of output with filename,
      start-address and length);
+ added derived attribute Stop to PrintHeaders.

7th January 2003 (Iroda Tulyaganova's 21st birthday!): SPECSAISIE 1.2 released:
+ CSaisie;
+ TAPtoSNA (now works for BASIC files);
+ SNAtoTAP (can now save BASIC files);
+ SNAtoBinary;
+ BinaryToSNA;
+ BinaryToTAP (now creates a TAP file from scratch);
+ ASCII;
+ Peek;
+ Poke.

7th July 2003: SPECSAISIE 1.2 uploaded to my new website. This README.TXT has been updated accordingly; the other files are completely unchanged.

If you release your own version of SPECSAISIE, please do not increment the version number I've given it, but start a separate branch. For example, if your name is Matthew Smith then you might call it version 1.2M or something - do not call it version 2.0, 1.3 or 1.2.1, because that's what I would call my next version (depending on whether the changes are major or minor). My versions shall be considered the definitive ones, and I make no promises to incorporate other people's changes.

Later versions of SPECSAISIE would feature additional functionality, such as (listed in the order I plan to implement them):

* Writing a BASIC program from an SNA file to a text-file (expanding the
  ASCII codes for BASIC keywords, and dropping the CHR$ 14 binary-forms of
  numerical constants). The text-file thus generated should be a valid input
  to BAS2TAP [http://www.worldofspectrum.org/utilities.html#other].
  Usage: java SNAtoBAS <file.SNA> (<start_line> (<end_line>))

* Generating line-by-line checksums for BASIC programs, in order to check that
  a BASIC program has been transferred to emulator-format correctly.
  Usage: java BASICchecksums <file.SNA> (<start_line> (<end_line>))

* Compare should have a command-line flag for bidirectional comparison, i.e.
  at the option of the user, it could show the value at each address in both
  the old code and the new.

* Saisie should (at the option of the user) automatically generate the program
  in SPECSAISIE.BAS, modifying line 60 as appropriate, and relocating the code
  if you would get "RAMTOP no good".

* BGB_JSW should allow the user to tell it to ignore certain colour attributes
  (such as 0 and 255, which tend to be used for unused block graphics), and it
  should be adapted to MM (BGB_MM). At the option of the user, the algorithm
  could automatically detect and filter out unused block graphics.

* RoomMM and RoomJSW could be extended to show more information from the
  room-format. In particular, RoomJSW should show the conveyor and the ramp
  (at the option of the user), and could even support moving from room to room
  (next room, previous room, left, right, up, down). Both functions could also
  show the items and/or guardians in a room (at the option of the user), and
  additional functions could show the graphics.

* RoomsMM and RoomsJSW could be extended to provide the additional
  functionality that Arsen Torbarina's JSW Monitor (for MS-DOS) provides,
  namely to show the connections of each room rather than just the title.
  For games which use John Elliott's teleporter extension, it should also
  indicate when a room has a teleporter, and the target room.
  Detection of invisible items, autocollect items and multiple items 
  would be implemented as separate functions.

* Functions other than file-conversion functions should take TAP files as
  input as well as SNA files, to unburden the user from having to run
  TAP files through Split and then TAPtoSNA.
