mirror of
https://github.com/livingcomputermuseum/DumpDectape.git
synced 2026-02-27 01:10:46 +00:00
Updated PC code to handle 12, 16, or 18 bit data from the PDP-8; added 12-bit dump program for PDP-8. (18-bit program is used for both 18 and 16-bit tapes).
This commit is contained in:
@@ -6,8 +6,8 @@
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{88B646C3-54D8-4D63-BB8A-B391C996FE47}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>DumpDT18</RootNamespace>
|
||||
<AssemblyName>DumpDT18</AssemblyName>
|
||||
<RootNamespace>DumpDectape</RootNamespace>
|
||||
<AssemblyName>DumpDectape</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
@@ -47,6 +47,8 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<None Include="dumpdt12.bin" />
|
||||
<None Include="dumpdt12.pal" />
|
||||
<None Include="dumpdt18-550.bin">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
@@ -57,6 +59,7 @@
|
||||
<None Include="dumpdt18.pal" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="dumpdt12.lst" />
|
||||
<Content Include="dumpdt18-550.lst" />
|
||||
<Content Include="dumpdt18.lst" />
|
||||
</ItemGroup>
|
||||
@@ -2,15 +2,14 @@
|
||||
using System.IO;
|
||||
using System.IO.Ports;
|
||||
|
||||
/*
|
||||
* This program receives an 18-bit Dectape image from the serial port from the
|
||||
PDP8 TD8E dump program. It is loosely based on David Gesswein's dumptd8e
|
||||
program.
|
||||
//
|
||||
// This program receives an Dectape image in 12, 16, or 18b format from the serial port, from the
|
||||
// appropriate PDP8 TD8E dump program. It is loosely based on David Gesswein's dumptd8e
|
||||
// program.
|
||||
|
||||
This program should be running before the PDP8 end is started.
|
||||
// This program should be running before the PDP8 end is started.
|
||||
|
||||
*/
|
||||
namespace DumpDT18
|
||||
namespace DumpDectape
|
||||
{
|
||||
class Program
|
||||
{
|
||||
@@ -24,42 +23,61 @@ namespace DumpDT18
|
||||
static void Main(string[] args)
|
||||
{
|
||||
|
||||
if (args.Length < 3)
|
||||
if (!ReadConfiguration(args))
|
||||
{
|
||||
Console.WriteLine("usage: DumpDT18 <port> <baud> <filename>");
|
||||
// Just exit, configuration is invalid.
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Open the serial port. Or try, anyway.
|
||||
//
|
||||
SerialPort port = new SerialPort(args[0], int.Parse(args[1]));
|
||||
port.StopBits = StopBits.One;
|
||||
port.Handshake = Handshake.None;
|
||||
port.Parity = Parity.None;
|
||||
SerialPort port = new SerialPort(_configuration.PortName, _configuration.BaudRate, _configuration.Parity, 8, _configuration.StopBits);
|
||||
port.Handshake = Handshake.None;
|
||||
port.Open();
|
||||
|
||||
string tapeFileName = args[2];
|
||||
string tapeFileName = _configuration.FileName;
|
||||
string diagFileName = Path.Combine(Path.GetDirectoryName(tapeFileName), Path.GetFileNameWithoutExtension(tapeFileName) + ".log");
|
||||
|
||||
// Open the output file
|
||||
using (FileStream tapeOutput = new FileStream(tapeFileName, FileMode.Create, FileAccess.Write),
|
||||
diagOutput = new FileStream(diagFileName, FileMode.Create, FileAccess.Write))
|
||||
{
|
||||
IBlockProcessor blockProcessor = null;
|
||||
int tapeBits = 0;
|
||||
|
||||
switch (_configuration.TapeType)
|
||||
{
|
||||
case TapeType.Twelve:
|
||||
blockProcessor = new BlockProcessor12(tapeOutput);
|
||||
tapeBits = 12;
|
||||
break;
|
||||
|
||||
case TapeType.Sixteen:
|
||||
blockProcessor = new BlockProcessor16(tapeOutput);
|
||||
tapeBits = 16;
|
||||
break;
|
||||
|
||||
case TapeType.Eighteen:
|
||||
blockProcessor = new BlockProcessor18(tapeOutput);
|
||||
tapeBits = 18;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidOperationException("Unexpected tape type.");
|
||||
}
|
||||
|
||||
StreamWriter diagText = new StreamWriter(diagOutput);
|
||||
diagText.AutoFlush = true;
|
||||
diagText.WriteLine("Summary log for 18-bit DECTape image {0} captured on {1}:", tapeFileName, DateTime.Now);
|
||||
diagText.WriteLine("Summary log for {0}-bit DECTape image {1} captured on {2}:", tapeBits, tapeFileName, DateTime.Now);
|
||||
|
||||
Console.WriteLine("Initialized, waiting for tape data.");
|
||||
|
||||
ReadState readState = ReadState.BlockFlag;
|
||||
int wordCount18 = 0;
|
||||
int blockNumber = 0;
|
||||
int byteIndex36 = 0;
|
||||
int byteIndex12 = 0;
|
||||
int checksumByteIndex = 0;
|
||||
ushort temp = 0;
|
||||
int chksum12 = 0;
|
||||
ulong thirtySix = 0;
|
||||
int badBlocks = 0;
|
||||
|
||||
while (true)
|
||||
@@ -77,13 +95,12 @@ namespace DumpDT18
|
||||
{
|
||||
case 0xff:
|
||||
case 0xfd:
|
||||
wordCount18 = 0;
|
||||
byteIndex36 = 0;
|
||||
blockProcessor.StartBlock();
|
||||
readState = ReadState.BlockData;
|
||||
|
||||
if (b == 0xfd)
|
||||
{
|
||||
Console.WriteLine("\nBlock {0} bad\n", blockNumber);
|
||||
Console.Write(" {0} bad ", blockNumber);
|
||||
diagText.WriteLine("Block {0} bad.", blockNumber);
|
||||
badBlocks++;
|
||||
}
|
||||
@@ -91,7 +108,7 @@ namespace DumpDT18
|
||||
|
||||
case 0xfe:
|
||||
readState = ReadState.Checksum;
|
||||
byteIndex12 = 0;
|
||||
checksumByteIndex = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -103,10 +120,10 @@ namespace DumpDT18
|
||||
|
||||
case ReadState.Checksum:
|
||||
// read first byte of checksum
|
||||
if (byteIndex12 == 0)
|
||||
if (checksumByteIndex == 0)
|
||||
{
|
||||
temp = (ushort)b;
|
||||
byteIndex12 = 1;
|
||||
checksumByteIndex = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -115,102 +132,25 @@ namespace DumpDT18
|
||||
chksum12 = (temp + chksum12) & 0xfff;
|
||||
if (chksum12 != 0)
|
||||
{
|
||||
Console.WriteLine("Read completed. Warning: Checksum error: {0}.", ToOctal(chksum12));
|
||||
diagText.WriteLine("Checksum error: {0}", ToOctal(chksum12));
|
||||
return;
|
||||
Console.WriteLine("Warning: Checksum error during read: {0}.", ToOctal(chksum12));
|
||||
diagText.WriteLine("Warning: Checksum error during read: {0}.", ToOctal(chksum12));
|
||||
}
|
||||
Console.WriteLine("Read completed successfully. {0} blocks read, {1} bad blocks.", blockNumber, badBlocks);
|
||||
diagText.WriteLine("Read successful. {0} blocks read, {1} bad blocks.", blockNumber, badBlocks);
|
||||
Console.WriteLine("Read completed {0}. {1} blocks read, {2} bad blocks.", chksum12 == 0 ? "successfully" : "with checksum errors", blockNumber, badBlocks);
|
||||
diagText.WriteLine("Read completed {0}. {1} blocks read, {2} bad blocks.", chksum12 == 0 ? "successfully" : "with checksum errors", blockNumber, badBlocks);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case ReadState.BlockData:
|
||||
//
|
||||
// Process the current byte.
|
||||
//
|
||||
blockProcessor.ProcessByte(b);
|
||||
|
||||
//
|
||||
// There are 384 12-bit words per block and each 12-bit word is
|
||||
// transferred as 1.5 bytes. The 384 12-bit words in a block
|
||||
// correspond to 256 18-bit words (1.5 12-bit words per 18-bit word)
|
||||
// which we want to write out to an 18-bit SIMH dectape image. This
|
||||
// is further complicated by the fact that due to the way the
|
||||
// bits actually get written to the tape, reading 18-bit words
|
||||
// as 1.5 12-bit words ends up transposing 6-bit segments inside
|
||||
// a 36-bit segment:
|
||||
// If the original 6-bit half-word ordering is:
|
||||
// 5 4 3 2 1 0
|
||||
// When read back into sequential 12-bit words, these half-words get
|
||||
// rearranged:
|
||||
// 2 5 4 1 0 3
|
||||
// Deal with the 12-bit checksum.
|
||||
//
|
||||
// To keep things somewhat easy to understand here (so as to preserve
|
||||
// my own sanity) at the expense of slightly longer code,
|
||||
// the state machine below parses 9 bytes (72 bits) at a time
|
||||
// which corresponds to 2 36-bit words (4 18-bit words) and re-arranges the 6-bit
|
||||
// half-words after each 36-bit word is read in. These re-arranged words are then
|
||||
// pushed out to disk in standard SIMH 18b format.
|
||||
//
|
||||
// We do this while ALSO summing the 12-bit checksum used at the end of the transfer.
|
||||
//
|
||||
switch (byteIndex36++)
|
||||
{
|
||||
case 0:
|
||||
thirtySix = b;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
thirtySix |= (ulong)(b << 8);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
thirtySix |= (ulong)(b << 16);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
thirtySix |= (ulong)(b << 24);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
thirtySix |= (ulong)((b & 0xf) << 32);
|
||||
|
||||
// First 36-bit word finished.
|
||||
WriteThirtySix(tapeOutput, MangleBits(thirtySix));
|
||||
wordCount18 += 2;
|
||||
|
||||
// Start next 36-bit word
|
||||
thirtySix = (ulong)((b & 0xf0) >> 4);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
thirtySix |= (ulong)(b << 4);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
thirtySix |= (ulong)(b << 12);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
thirtySix |= (ulong)(b << 20);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
thirtySix |= (ulong)(b << 28);
|
||||
|
||||
// Second 36-bit word finished.
|
||||
WriteThirtySix(tapeOutput, MangleBits(thirtySix));
|
||||
wordCount18 += 2;
|
||||
|
||||
byteIndex36 = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidOperationException("Unexpected state when building 36-bit word.");
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Deal with the 12-bit checksum
|
||||
//
|
||||
switch (byteIndex12++)
|
||||
switch (checksumByteIndex++)
|
||||
{
|
||||
case 0:
|
||||
temp = (ushort)b;
|
||||
@@ -225,7 +165,7 @@ namespace DumpDT18
|
||||
case 2:
|
||||
temp = (ushort)((temp | (b << 4)) & 0xfff);
|
||||
chksum12 = chksum12 + temp;
|
||||
byteIndex12 = 0;
|
||||
checksumByteIndex = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -235,11 +175,11 @@ namespace DumpDT18
|
||||
//
|
||||
// Start next block when at end.
|
||||
//
|
||||
if (wordCount18 == 256)
|
||||
if (blockProcessor.BlockDone)
|
||||
{
|
||||
readState = ReadState.BlockFlag;
|
||||
blockNumber++;
|
||||
byteIndex36 = 0;
|
||||
checksumByteIndex = 0;
|
||||
if ((blockNumber % 5) == 0)
|
||||
{
|
||||
Console.Write("{0}", blockNumber);
|
||||
@@ -254,14 +194,14 @@ namespace DumpDT18
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ulong MangleBits(ulong mangled)
|
||||
public static ulong MangleBits(ulong mangled)
|
||||
{
|
||||
ulong unmangled;
|
||||
|
||||
//
|
||||
// Reading 18-bit DECTapes on a 12-bit PDP-8 presents an interesting
|
||||
// Reading 18-bit or 16-bit DECTapes on a 12-bit PDP-8 presents an interesting
|
||||
// ordering of 6-bit half-words.
|
||||
// Effectively, each 36-bit sequence reorders 6-bit sequences as:
|
||||
// original: 5 4 3 2 1 0
|
||||
@@ -277,6 +217,284 @@ namespace DumpDT18
|
||||
((mangled & 0xfc0000000) >> 6);
|
||||
|
||||
return unmangled;
|
||||
}
|
||||
|
||||
public static string ToOctal(int i)
|
||||
{
|
||||
return Convert.ToString(i, 8);
|
||||
}
|
||||
|
||||
private static void PrintUsage()
|
||||
{
|
||||
Console.WriteLine("DumpDectape captures SIMH-compatible Dectape images from a PDP-8 system running the appropriate dump program.");
|
||||
Console.WriteLine("usage: DumpDectape -port <port> [-baud <baud>] [-stop <stop>] [-parity <parity>] -type <type> -file <filename>");
|
||||
Console.WriteLine(" <port> specifies the serial port to use (e.g. 'com1')");
|
||||
Console.WriteLine(" <baud> specifies the baud rate to use (e.g. '9600')");
|
||||
Console.WriteLine(" <stop> specifies the number of stop bits (e.g. '1')");
|
||||
Console.WriteLine(" <parity> specifies the parity (e.g. 'Even')");
|
||||
Console.WriteLine(" If unspecified, DumpDectape defaults to 9600 baud, 1 stop bit, no parity.");
|
||||
Console.WriteLine(" <type> specifies the type of Dectape being dumped: 18b, 16b, or 12b.");
|
||||
Console.WriteLine(" <filename> specifies the name of the SIMH image file to create.");
|
||||
}
|
||||
|
||||
private static bool ReadConfiguration(string[] args)
|
||||
{
|
||||
_configuration = new Configuration();
|
||||
|
||||
int index = 0;
|
||||
while(index < args.Length)
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (args[index++])
|
||||
{
|
||||
case "-port":
|
||||
_configuration.PortName = args[index++];
|
||||
break;
|
||||
|
||||
case "-baud":
|
||||
_configuration.BaudRate = int.Parse(args[index++]);
|
||||
break;
|
||||
|
||||
case "-stop":
|
||||
switch(args[index++])
|
||||
{
|
||||
case "1":
|
||||
_configuration.StopBits = StopBits.One;
|
||||
break;
|
||||
|
||||
case "2":
|
||||
_configuration.StopBits = StopBits.Two;
|
||||
break;
|
||||
|
||||
case "1.5":
|
||||
_configuration.StopBits = StopBits.OnePointFive;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidOperationException("Invalid Stop Bits specification.");
|
||||
}
|
||||
break;
|
||||
|
||||
case "-parity":
|
||||
_configuration.Parity = (Parity)Enum.Parse(typeof(Parity), args[index++]);
|
||||
break;
|
||||
|
||||
case "-type":
|
||||
switch(args[index++])
|
||||
{
|
||||
case "12b":
|
||||
_configuration.TapeType = TapeType.Twelve;
|
||||
break;
|
||||
|
||||
case "16b":
|
||||
_configuration.TapeType = TapeType.Sixteen;
|
||||
break;
|
||||
|
||||
case "18b":
|
||||
_configuration.TapeType = TapeType.Eighteen;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidOperationException("Invalid Tape Type specification.");
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case "-file":
|
||||
_configuration.FileName = args[index++];
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidOperationException("Invalid option.");
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// TODO: be more helpful about where the user screwed up.
|
||||
PrintUsage();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Ensure required options have been set, if not, print usage instructions.
|
||||
if (_configuration.TapeType == TapeType.Unspecified ||
|
||||
string.IsNullOrWhiteSpace(_configuration.PortName) ||
|
||||
string.IsNullOrWhiteSpace(_configuration.FileName))
|
||||
{
|
||||
PrintUsage();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private enum TapeType
|
||||
{
|
||||
Unspecified = 0,
|
||||
Twelve,
|
||||
Sixteen,
|
||||
Eighteen,
|
||||
}
|
||||
|
||||
private class Configuration
|
||||
{
|
||||
public Configuration()
|
||||
{
|
||||
// Set things to defaults.
|
||||
FileName = null;
|
||||
PortName = null;
|
||||
BaudRate = 9600;
|
||||
Parity = Parity.None;
|
||||
StopBits = StopBits.One;
|
||||
TapeType = TapeType.Unspecified;
|
||||
}
|
||||
|
||||
public string FileName;
|
||||
public string PortName;
|
||||
public int BaudRate;
|
||||
public Parity Parity;
|
||||
public StopBits StopBits;
|
||||
public TapeType TapeType;
|
||||
}
|
||||
|
||||
private static Configuration _configuration;
|
||||
}
|
||||
|
||||
public interface IBlockProcessor
|
||||
{
|
||||
void StartBlock();
|
||||
|
||||
void ProcessByte(ulong b);
|
||||
|
||||
bool BlockDone { get; }
|
||||
}
|
||||
|
||||
public class BlockProcessor18 : IBlockProcessor
|
||||
{
|
||||
public BlockProcessor18(Stream outputStream)
|
||||
{
|
||||
_outStream = outputStream;
|
||||
_byteIndex36 = 0;
|
||||
_thirtySix = 0;
|
||||
_wordCount18 = 0;
|
||||
_blockDone = true;
|
||||
}
|
||||
|
||||
public bool BlockDone
|
||||
{
|
||||
get { return _blockDone; }
|
||||
}
|
||||
|
||||
public void StartBlock()
|
||||
{
|
||||
_blockDone = false;
|
||||
_byteIndex36 = 0;
|
||||
_wordCount18 = 0;
|
||||
_thirtySix = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Appends a new byte onto the output data.
|
||||
/// </summary>
|
||||
/// <param name="b"></param>
|
||||
/// <returns>true if the end of the block has been reached, false otherwise</returns>
|
||||
public void ProcessByte(ulong b)
|
||||
{
|
||||
if (_blockDone)
|
||||
{
|
||||
throw new InvalidOperationException("Invalid state: ProcessByte called before StartBlock.");
|
||||
}
|
||||
|
||||
//
|
||||
// For 18-bit tapes:
|
||||
// There are 384 12-bit words per block and each 12-bit word is
|
||||
// transferred as 1.5 bytes. The 384 12-bit words in a block
|
||||
// correspond to 256 18-bit words (1.5 12-bit words per 18-bit word)
|
||||
// which we want to write out to an 18-bit SIMH dectape image. This
|
||||
// is further complicated by the fact that due to the way the
|
||||
// bits actually get written to the tape, reading 18-bit words
|
||||
// as 1.5 12-bit words ends up transposing 6-bit segments inside
|
||||
// a 36-bit segment:
|
||||
// If the original 6-bit half-word ordering is:
|
||||
// 5 4 3 2 1 0
|
||||
// When read back into sequential 12-bit words, these half-words get
|
||||
// rearranged:
|
||||
// 2 5 4 1 0 3
|
||||
//
|
||||
// To keep things somewhat easy to understand here (so as to preserve
|
||||
// my own sanity) at the expense of slightly longer code,
|
||||
// the state machine below parses 9 bytes (72 bits) at a time
|
||||
// which corresponds to 2 36-bit words (4 18-bit words) and re-arranges the 6-bit
|
||||
// half-words after each 36-bit word is read in. These re-arranged words are then
|
||||
// pushed out to disk in standard SIMH 18b format.
|
||||
//
|
||||
switch (_byteIndex36++)
|
||||
{
|
||||
case 0:
|
||||
_thirtySix = b;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
_thirtySix |= (ulong)(b << 8);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
_thirtySix |= (ulong)(b << 16);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
_thirtySix |= (ulong)(b << 24);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
_thirtySix |= (ulong)((b & 0xf) << 32);
|
||||
|
||||
// First 36-bit word finished.
|
||||
WriteThirtySix(_outStream, Program.MangleBits(_thirtySix));
|
||||
_wordCount18 += 2;
|
||||
|
||||
// Start next 36-bit word
|
||||
_thirtySix = (ulong)((b & 0xf0) >> 4);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
_thirtySix |= (ulong)(b << 4);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
_thirtySix |= (ulong)(b << 12);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
_thirtySix |= (ulong)(b << 20);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
_thirtySix |= (ulong)(b << 28);
|
||||
|
||||
// Second 36-bit word finished.
|
||||
WriteThirtySix(_outStream, Program.MangleBits(_thirtySix));
|
||||
_wordCount18 += 2;
|
||||
|
||||
_byteIndex36 = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidOperationException("Unexpected state when building 36-bit word.");
|
||||
|
||||
}
|
||||
|
||||
if (_wordCount18 == 256)
|
||||
{
|
||||
// Finished with the current block, reset our word count
|
||||
// and let the caller know we're done.
|
||||
|
||||
_blockDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteThirtySix(Stream outStream, ulong thirtySix)
|
||||
@@ -287,7 +505,7 @@ namespace DumpDT18
|
||||
|
||||
private static void WriteEighteen(Stream outStream, uint eighteen)
|
||||
{
|
||||
outStream.WriteByte((byte) (eighteen & 0x000000ff));
|
||||
outStream.WriteByte((byte)(eighteen & 0x000000ff));
|
||||
outStream.WriteByte((byte)((eighteen & 0x0000ff00) >> 8));
|
||||
outStream.WriteByte((byte)((eighteen & 0x00ff0000) >> 16));
|
||||
outStream.WriteByte((byte)((eighteen & 0xff000000) >> 24));
|
||||
@@ -295,9 +513,293 @@ namespace DumpDT18
|
||||
outStream.Flush();
|
||||
}
|
||||
|
||||
public static string ToOctal(int i)
|
||||
/// <summary>
|
||||
/// The current byte index into the two 36-bit words we're building
|
||||
/// </summary>
|
||||
private int _byteIndex36;
|
||||
|
||||
/// <summary>
|
||||
/// The current 36-bit word we've built
|
||||
/// </summary>
|
||||
private ulong _thirtySix;
|
||||
|
||||
/// <summary>
|
||||
/// The number of 18-bit words we've read.
|
||||
/// </summary>
|
||||
private int _wordCount18;
|
||||
|
||||
/// <summary>
|
||||
/// Whether we've completed a block (and StartBlock must be called before processing more data)
|
||||
/// </summary>
|
||||
private bool _blockDone;
|
||||
|
||||
/// <summary>
|
||||
/// The stream we'll flush the data to.
|
||||
/// </summary>
|
||||
private Stream _outStream;
|
||||
}
|
||||
|
||||
public class BlockProcessor16 : IBlockProcessor
|
||||
{
|
||||
public BlockProcessor16(Stream outputStream)
|
||||
{
|
||||
return Convert.ToString(i, 8);
|
||||
_outStream = outputStream;
|
||||
_byteIndex36 = 0;
|
||||
_thirtySix = 0;
|
||||
_wordCount16 = 0;
|
||||
_blockDone = true;
|
||||
}
|
||||
|
||||
public bool BlockDone
|
||||
{
|
||||
get { return _blockDone; }
|
||||
}
|
||||
|
||||
public void StartBlock()
|
||||
{
|
||||
_blockDone = false;
|
||||
_byteIndex36 = 0;
|
||||
_wordCount16 = 0;
|
||||
_thirtySix = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Appends a new byte onto the output data.
|
||||
/// </summary>
|
||||
/// <param name="b"></param>
|
||||
/// <returns>true if the end of the block has been reached, false otherwise</returns>
|
||||
public void ProcessByte(ulong b)
|
||||
{
|
||||
if (_blockDone)
|
||||
{
|
||||
throw new InvalidOperationException("Invalid state: ProcessByte called before StartBlock.");
|
||||
}
|
||||
|
||||
//
|
||||
// For 16-bit tapes:
|
||||
// See the comments in BlockProcessor18.ProcessByte for the nitty-gritty.
|
||||
// 16-bit tapes are handled nearly identically, since the format on tape is identical.
|
||||
// The difference is that 16-bit dectapes do not use the upper 2 bits of each
|
||||
// 18-bit word on tape. After the typical 18-bit processing and re-arrangement, we write out the data
|
||||
// in the standard 16-bit SIMH format.
|
||||
// Some of this code could technically be factored out.
|
||||
//
|
||||
switch (_byteIndex36++)
|
||||
{
|
||||
case 0:
|
||||
_thirtySix = b;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
_thirtySix |= (ulong)(b << 8);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
_thirtySix |= (ulong)(b << 16);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
_thirtySix |= (ulong)(b << 24);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
_thirtySix |= (ulong)((b & 0xf) << 32);
|
||||
|
||||
// First 36-bit word finished.
|
||||
WriteThirtySix(_outStream, Program.MangleBits(_thirtySix));
|
||||
_wordCount16 += 2;
|
||||
|
||||
// Start next 36-bit word
|
||||
_thirtySix = (ulong)((b & 0xf0) >> 4);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
_thirtySix |= (ulong)(b << 4);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
_thirtySix |= (ulong)(b << 12);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
_thirtySix |= (ulong)(b << 20);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
_thirtySix |= (ulong)(b << 28);
|
||||
|
||||
// Second 36-bit word finished.
|
||||
WriteThirtySix(_outStream, Program.MangleBits(_thirtySix));
|
||||
_wordCount16 += 2;
|
||||
|
||||
_byteIndex36 = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidOperationException("Unexpected state when building 36-bit word.");
|
||||
|
||||
}
|
||||
|
||||
if (_wordCount16 == 256)
|
||||
{
|
||||
// Finished with the current block, reset our word count
|
||||
// and let the caller know we're done.
|
||||
|
||||
_blockDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteThirtySix(Stream outStream, ulong thirtySix)
|
||||
{
|
||||
WriteSixteen(outStream, (uint)(thirtySix & 0xffff));
|
||||
|
||||
// TODO: verify this is correct.
|
||||
WriteSixteen(outStream, (uint)((thirtySix & 0x3fffc0000) >> 18));
|
||||
}
|
||||
|
||||
private static void WriteSixteen(Stream outStream, uint sixteen)
|
||||
{
|
||||
outStream.WriteByte((byte) (sixteen & 0x00ff));
|
||||
outStream.WriteByte((byte)((sixteen & 0xff00) >> 8));
|
||||
outStream.Flush();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The current byte index into the two 36-bit words we're building
|
||||
/// </summary>
|
||||
private int _byteIndex36;
|
||||
|
||||
/// <summary>
|
||||
/// The current 36-bit word we've built
|
||||
/// </summary>
|
||||
private ulong _thirtySix;
|
||||
|
||||
/// <summary>
|
||||
/// The number of 18-bit words we've read.
|
||||
/// </summary>
|
||||
private int _wordCount16;
|
||||
|
||||
/// <summary>
|
||||
/// Whether we've completed a block (and StartBlock must be called before processing more data)
|
||||
/// </summary>
|
||||
private bool _blockDone;
|
||||
|
||||
/// <summary>
|
||||
/// The stream we'll flush the data to.
|
||||
/// </summary>
|
||||
private Stream _outStream;
|
||||
}
|
||||
|
||||
public class BlockProcessor12 : IBlockProcessor
|
||||
{
|
||||
public BlockProcessor12(Stream outputStream)
|
||||
{
|
||||
_outStream = outputStream;
|
||||
_byteIndex12 = 0;
|
||||
_twelve = 0;
|
||||
_wordCount12 = 0;
|
||||
_blockDone = true;
|
||||
}
|
||||
|
||||
public bool BlockDone
|
||||
{
|
||||
get { return _blockDone; }
|
||||
}
|
||||
|
||||
public void StartBlock()
|
||||
{
|
||||
_blockDone = false;
|
||||
_byteIndex12 = 0;
|
||||
_twelve = 0;
|
||||
_wordCount12 = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Appends a new byte onto the output data.
|
||||
/// </summary>
|
||||
/// <param name="b"></param>
|
||||
/// <returns>true if the end of the block has been reached, false otherwise</returns>
|
||||
public void ProcessByte(ulong b)
|
||||
{
|
||||
if (_blockDone)
|
||||
{
|
||||
throw new InvalidOperationException("Invalid state: ProcessByte called before StartBlock.");
|
||||
}
|
||||
|
||||
//
|
||||
// For 12-bit tapes:
|
||||
// There are 129 12-bit words per block and each 12-bit word is
|
||||
// transferred as 1.5 bytes. The reassembled 12-bit words are then
|
||||
// pushed out to disk in standard SIMH 12b format.
|
||||
//
|
||||
switch (_byteIndex12++)
|
||||
{
|
||||
case 0:
|
||||
_twelve = b;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
_twelve |= (ulong)(b << 8);
|
||||
|
||||
// First 12-bit word finished.
|
||||
WriteTwelve(_outStream, _twelve);
|
||||
_wordCount12++;
|
||||
|
||||
// Start next 12-bit word.
|
||||
_twelve = (ulong)(b >> 4);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// Second 12-bit word finished.
|
||||
_twelve |= (ulong)((b << 4));
|
||||
WriteTwelve(_outStream, _twelve);
|
||||
_wordCount12++;
|
||||
|
||||
// Start over.
|
||||
_byteIndex12 = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidOperationException("Unexpected state when building 12-bit word.");
|
||||
}
|
||||
|
||||
if (_wordCount12 == 129)
|
||||
{
|
||||
// Finished with the current block.
|
||||
_blockDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteTwelve(Stream outStream, ulong twelve)
|
||||
{
|
||||
outStream.WriteByte((byte) (twelve & 0x0ff));
|
||||
outStream.WriteByte((byte)((twelve & 0xf00) >> 8));
|
||||
outStream.Flush();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The current byte index into the two 36-bit words we're building
|
||||
/// </summary>
|
||||
private int _byteIndex12;
|
||||
|
||||
/// <summary>
|
||||
/// The current 36-bit word we've built
|
||||
/// </summary>
|
||||
private ulong _twelve;
|
||||
|
||||
/// <summary>
|
||||
/// The number of 18-bit words we've read.
|
||||
/// </summary>
|
||||
private int _wordCount12;
|
||||
|
||||
/// <summary>
|
||||
/// Whether we've completed a block (and StartBlock must be called before processing more data)
|
||||
/// </summary>
|
||||
private bool _blockDone;
|
||||
|
||||
/// <summary>
|
||||
/// The stream we'll flush the data to.
|
||||
/// </summary>
|
||||
private Stream _outStream;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,12 +5,12 @@ using System.Runtime.InteropServices;
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("DumpPDP7")]
|
||||
[assembly: AssemblyTitle("DumpDectape")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("DumpPDP7")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017")]
|
||||
[assembly: AssemblyProduct("DumpDectape")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017 LCM+L")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
|
||||
BIN
DumpDT18/dumpdt12.bin
Normal file
BIN
DumpDT18/dumpdt12.bin
Normal file
Binary file not shown.
796
DumpDT18/dumpdt12.lst
Normal file
796
DumpDT18/dumpdt12.lst
Normal file
@@ -0,0 +1,796 @@
|
||||
|
||||
|
||||
|
||||
/ TD8E 12-bit DECtape DUMP Program. Based on DUMPREST code fro Page 1
|
||||
|
||||
|
||||
1 / TD8E 12-bit DECtape DUMP Program. Based on DUMPREST code from D. Gesswein
|
||||
2 / (see ftp://ftp.pdp8online.com/software/dumprest).
|
||||
3 / Modified to handle arbitrary-length tapes by J. Dersch
|
||||
4 /
|
||||
5 / This program will send a DECtape image out the console port.
|
||||
6 / The format of the data sent is 0xff (0377) or 0xfd if read error
|
||||
7 / followed by 129 12-bit words of data for each block.
|
||||
8 / After the last block a 0xfe (0376) is sent
|
||||
9 / with a two byte checksum, low 8 bits first then upper 4.
|
||||
10 / The words in a block are sent as three bytes for each 2 words.
|
||||
11 / 1 = low 8 bits first word
|
||||
12 / 2 = upper 4 bits first and lower 4 bits second
|
||||
13 / 3 = upper 8 bits second word
|
||||
14 /
|
||||
15 / The program (PC) receiving the data should be started before this program.
|
||||
16 /
|
||||
17 / To run, start at 0200.
|
||||
18 / SR 11 should be drive, only 0 and 1 supported without reassembling
|
||||
19 / SR 6-8 should be maximum memory field in computer, needs 8k minimum
|
||||
20 /
|
||||
21 / The receiving program should be running first.
|
||||
22 / At normal exit hitting cont will restart the program.
|
||||
23 /
|
||||
24 / Should halt at label finish (140) with number of recoverable errors in AC
|
||||
25 / The current block being read will be displayed in the AC
|
||||
26 / while running.
|
||||
27 /
|
||||
28 / The PC program will print out the bad location if an error occurs.
|
||||
29 /
|
||||
30 / We will retry each read up to four times on error.
|
||||
31 /
|
||||
32 / This transfers the standard 129 word by 1474 blocks used by 12-bit DEC hardware,
|
||||
33 / using standard checksums (as used by the PDP-9 and later machines).
|
||||
34 / It will read as many blocks are present up to the forward end-zone, so it will
|
||||
35 / handle tapes that vary from the standard block length.
|
||||
36 /
|
||||
37 0030 INAD=030 / Address of serial input, 30 for console
|
||||
38 6030 KCF2=6000 INAD
|
||||
39 6031 KSF2=6001 INAD
|
||||
40 6032 KCC2=6002 INAD
|
||||
41 6034 KRS2=6004 INAD
|
||||
42 6035 KIE2=6005 INAD
|
||||
43 6036 KRB2=6006 INAD
|
||||
44
|
||||
45 0040 OUTAD=040 / Address of serial output, 40 for console
|
||||
46 6040 TFL2=6000 OUTAD
|
||||
47 6041 TSF2=6001 OUTAD
|
||||
48 6042 TCF2=6002 OUTAD
|
||||
49 6044 TPC2=6004 OUTAD
|
||||
50 6045 TSK2=6005 OUTAD
|
||||
|
||||
|
||||
|
||||
/ TD8E 12-bit DECtape DUMP Program. Based on DUMPREST code fro Page 2
|
||||
|
||||
|
||||
51 6046 TLS2=6006 OUTAD
|
||||
52
|
||||
53
|
||||
54 /CODE BASED ON:
|
||||
55 /2 TD8E INITIALIZER PROGRAM, V7A
|
||||
56 /
|
||||
57 /COPYRIGHT (C) 1975, 1977
|
||||
58 /DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
|
||||
59 /
|
||||
60 /
|
||||
61 /
|
||||
62 /THIS SOFTWARE IS FURNISHED UNDER A LICENSE FOR USE ONLY ON A
|
||||
63 /SINGLE COMPUTER SYSTEM AND MAY BE COPIED ONLY WITH THE INCLU-
|
||||
64 /SION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE, OR ANT OTHER
|
||||
65 /COPIES THEREOF, MAY NOT BR PROVIDED OR OTHERWISE MADE AVAILABLE
|
||||
66 /TO ANY OTHER PERSON EXCEPT FOR USE ON SUCH SYSTEM AND TO ONE WHO
|
||||
67 /AGREES TO THESE LICENSE TERMS. TITLE TO AND OWNERSHIP OF THE
|
||||
68 /SOFTWARE SHALL AT ALL TIMES REMAIN IN DEC.
|
||||
69 /
|
||||
70 /
|
||||
71 /THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT
|
||||
72 /NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL
|
||||
73 /EQUIPMRNT COROPATION.
|
||||
74 /
|
||||
75 /DEC ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
|
||||
76 /SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DEC.
|
||||
77 /
|
||||
78 /
|
||||
79 /
|
||||
80 /
|
||||
81 /
|
||||
82 /
|
||||
83
|
||||
84 /DECEMBER 21, 1973 GB/RL/EF/SR
|
||||
85
|
||||
86 /ABSTRACT--
|
||||
87 / THE ROUTINE DESCRIBED AND LISTED HERE IS A GENERAL
|
||||
88 /DATA HANDLER FOR THE TD8E DECTAPE SYSTEM. THE ROUTINE
|
||||
89 /CONTAINS SEARCH, READ, AND WRITE FUNCTIONS IN A FORMAT
|
||||
90 /WHICH IS COMPATIBLE WITH OS/8 DEVICE HANDLER CALLING
|
||||
91 /SEQUENCES.
|
||||
92
|
||||
93 /FIXES SINCE FIELD-TEST RELEASE:
|
||||
94
|
||||
95 /1. FIXED BUG RE CLA ON RETRY AFTER ERROR
|
||||
96 /2. ALLOWED FINAL BOOTSTRAP TO BE INTO A WRITE-LOCKED DEVICE
|
||||
97
|
||||
98 /OS/8 V3D CHANGES:
|
||||
99
|
||||
100 /3. FIXED BUG RE TD8E BUILD (V6B PATCH)
|
||||
|
||||
|
||||
|
||||
/ TD8E 12-bit DECtape DUMP Program. Based on DUMPREST code fro Page 3
|
||||
|
||||
|
||||
101
|
||||
102 /THIS ROUTINE CAN BE RE-EDITED AND ASSEMBLED TO PRODUCE
|
||||
103 /VARIATIONS ON THE BASIC TD8E SYSTEM. ASSEMBLY PARAMETERS
|
||||
104 /CONTROL:
|
||||
105 /A) WHAT DRIVES (UNITS 0-7) WILL BE USED
|
||||
106 /B) THE ORIGIN OF THE TWO PAGE ROUTINE
|
||||
107 /C) WHAT MEMORY FIELD THE ROUTINE WILL RUN IN
|
||||
108 /D) THE SIZE OF THE DECTAPE BLOCK TO BE READ/WRITTEN
|
||||
109
|
||||
110 /FOLLOWING ARE THE PARAMETERS SET UP FOR THE STANDARD
|
||||
111 /DEC VERSION OF THIS ROUTINE:
|
||||
112
|
||||
113 0010 DRIVE=10 /UNITS 0 AND 1 SELECTED
|
||||
114 0600 ORIGIN=600 /ENTER AT ORIGIN, ORIGIN+4
|
||||
115 0000 AFIELD=0 /INITIAL FIELD SETTING
|
||||
116 0000 MFIELD=00 /AFIELD*10=MFIELD
|
||||
117 0201 WDSBLK=201 /129 12-BIT WORDS PER BLOCK
|
||||
118
|
||||
119 /THE USE OF THE PARAMETERS IS AS FOLLOWS:
|
||||
120
|
||||
121 / DRIVE: DRIVE DETERMINES WHICH UNITS WILL BE SELECTED
|
||||
122 / DRIVE=10 IMPLIES UNITS 0 &1
|
||||
123 / DRIVE=20 IMPLIES UNITS 2&3
|
||||
124 / DRIVE=30 IMPLIES UNITS 4&5
|
||||
125 / DRIVE=40 IMPLIES UNITS 6&7
|
||||
126
|
||||
127 /ORIGIN: ALTERING ORIGIN CAUSES ASSEMBLY IN A DIFFERENT
|
||||
128 / MEMORY LOCATION. WHEN CHANGING ORIGIN KEEP IN MIND
|
||||
129 /THAT THIS IS A TWO PAGE ROUTINE.
|
||||
130
|
||||
131 /AFIELD: AFIELD DETERMINES THE INITIAL FIELD SETTING FOR THE
|
||||
132 / LOADER. PERMISSIBLE VALUES FOR AFIELD ARE 0 TO 7.
|
||||
133
|
||||
134 /MFIELD: MFIELD IS USED IN A CIF CDF MFIELD INSTRUCTION.
|
||||
135 / THE VALUE INSERTED FOR MFIELD SHOULD BE 10(8) TIMES
|
||||
136 / THE VALUE FOR AFIELD. THE PERMISSIBLE VALUES ARE 00-70.
|
||||
137
|
||||
138 /WDSBLK: WDSBLK GOVERNS HOW MANY WORDS THE ROUTINE THINKS ARE
|
||||
139 / IN A DECTAPE BLOCK. THE STANDARD VALUE IS 201(8) OR
|
||||
140 / 128 DECIMAL. NOTE THAT THE FUNCTION WORD BIT 10 CAN
|
||||
141 / 129 DECIMAL ??? (DJG)
|
||||
142 / BE USED TO SUBTRACT ONE FROM WDSBLK. THE VALUE USED
|
||||
143 / FOR WDSBLK SHOULD BE THE NUMBER OF WORDS THE TAPE WAS
|
||||
144 / FORMATTED TO CONTAIN.
|
||||
145
|
||||
146 /IF WE WANT A HANDLER FOR UNITS 2&3 TO RESIDE IN
|
||||
147 /FIELD 2 AT LOCATION 3000 AND READ/WRITE 256(10) WORDS
|
||||
148 /PER BLOCK, THE PARAMETERS WOULD BE:
|
||||
149 / DRIVE=20
|
||||
150 / ORIGIN=3000
|
||||
|
||||
|
||||
|
||||
/ TD8E 12-bit DECtape DUMP Program. Based on DUMPREST code fro Page 4
|
||||
|
||||
|
||||
151 / AFIELD=2
|
||||
152 / MFIELD=20
|
||||
153 / WDSBLK=400
|
||||
154 /THE CALL TO THE SUBROUTINE FOLLOWS BASICALLY THE
|
||||
155 /CALLING SEQUENCE FOR OS/8 DEVICE HANDLERS.
|
||||
156 /THE CALLING SEQUENCE IS:
|
||||
157
|
||||
158 / CDF CURRENT
|
||||
159 / CIF MFIELD /MFIELD=FIELD ASSEMBLED IN
|
||||
160 / JMS ENTRY /ENTRY=ORIGIN (EVEN NUMBERED DRIVE
|
||||
161 /AND ORIGIN+4 FOR ODD NUMBERED DRIVE.
|
||||
162 / ARG1
|
||||
163 / ARG1B (DJG)
|
||||
164 / ARG2
|
||||
165 / ARG3
|
||||
166 / ERROR RETURN
|
||||
167 / NORMAL RETURN
|
||||
168
|
||||
169 /THE ARGUMENTS ARE:
|
||||
170
|
||||
171 /ARG1: FUNCTION WORD BIT0: 0=READ, 1=WRITE
|
||||
172 / BITS 1-5: UNUSED, WAS # BLOCKS IN OPERATION (DJG)
|
||||
173 / BITS 6-8: FIELD OF BUFFER AREA
|
||||
174 / BIT 9: UNUSED
|
||||
175 / BIT 10: # OF WORDS/BLOCK.
|
||||
176 / 0= WDSBLK, 1=WDSBLK-1
|
||||
177 / BIT 11: 1=START FORWARD, 0=REVERSE
|
||||
178 /ARG1A: # OF BLOCKS IN OPERATIONA (DJG)
|
||||
179 /ARG2: BUFFER ADDRESS FOR OPERATION
|
||||
180 /ARG3: STARTING BLOCK FOR OPERATION
|
||||
181
|
||||
182 /ERRORS: THE HANDLER DETECTS TWO TYPES OF ERRORS:
|
||||
183 /A) FATAL ERRORS- PARITY ERROR, TIMING ERROR,
|
||||
184 / TOO GREAT A BLOCK NUMBER
|
||||
185 / FATAL ERRORS TAKE ERROR RETURN WITH THE
|
||||
186 / AC=4000.
|
||||
187 /B) NON-FATAL- SELECT ERROR.
|
||||
188 / IF NO PROPER UNIT IS SELECTED, THE ERROR
|
||||
189 / RETURN IS TAKEN WITH CLEAR AC.
|
||||
190 /FATAL ERRORS TRY THREE TIMES BEFORE TAKING ERROR RETURN.
|
||||
191 /THE NORMAL RETURN IS TAKEN AFTER ALL INDICATED
|
||||
192 /BLOCKS HAVE BEEN TRANSFERRED. THE AC IS CLEAR.
|
||||
193
|
||||
194 /THE TD8E IOT'S ARE:
|
||||
195 6771 SDSS=7001-DRIVE /SKIP ON SINGLE LINE FLAG
|
||||
196 6772 SDST=7002-DRIVE /SKIP ON TIMING ERROR
|
||||
197 6773 SDSQ=7003-DRIVE /SKIP ON QUAD LINE FLAG
|
||||
198 6774 SDLC=7004-DRIVE /LOAD COMMAND REGISTER
|
||||
199 6775 SDLD=7005-DRIVE /LOAD DATA REGISTER
|
||||
200 6776 SDRC=7006-DRIVE /READ COMMAND REGISTER
|
||||
|
||||
|
||||
|
||||
/ TD8E 12-bit DECtape DUMP Program. Based on DUMPREST code fro Page 5
|
||||
|
||||
|
||||
201 6777 SDRD=7007-DRIVE /READ DATA REGISTER
|
||||
202
|
||||
203 /THE IOT'S IN GENERAL ARE 677X,676X,675X,AND 674X.
|
||||
204 /THE OTHERS CONTROL UNITS 2-7.
|
||||
205
|
||||
206 / THIS HANDLER USES DECTAPE BLOCKS NOT OS/8 BLOCKS !
|
||||
207
|
||||
208 0600 *ORIGIN
|
||||
209
|
||||
210 / MODIFIED SO BIT 0 ON ENTRY IS UNIT 1
|
||||
211 00600 0000 DTA0, 0
|
||||
212 00601 3047 DCA UNIT /SAVE UNIT POSITION
|
||||
213 00602 6214 RDF
|
||||
214 00603 1360 TAD C6203 /GET DATA FIELD AND SETUP RETURN
|
||||
215 00604 3356 DCA LEAVE
|
||||
216 00605 1600 TAD I DTA0 /GET FUNCTION WORD
|
||||
217 00606 6775 SDLD /PUT FUNCTION INTO DATA REGISTER
|
||||
218 00607 7200 CLA
|
||||
219 00610 1022 TAD MWORDS
|
||||
220 00611 3023 DCA WCOUNT /STORE MASTER WORD COUNT
|
||||
221 00612 2200 ISZ DTA0 /TO BLOCK COUNT (DJG)
|
||||
222 00613 1600 TAD I DTA0 / (DJG)
|
||||
223 00614 7041 CIA / (DJG)
|
||||
224 00615 3051 DCA PGCT / (DJG)
|
||||
225 00616 2200 ISZ DTA0 /TO BUFFER
|
||||
226 00617 1600 TAD I DTA0
|
||||
227 00620 3044 DCA XBUFF /SAVE ADDRESS (DJG)
|
||||
228 00621 2200 ISZ DTA0 /TO BLOCK NUMBER
|
||||
229 00622 1600 TAD I DTA0
|
||||
230 00623 3046 DCA BLOCK
|
||||
231 00624 2200 ISZ DTA0 /POINT TO ERROR EXIT
|
||||
232 00625 6203 CIF CDF MFIELD /TO ROUTINES DATA FIELD
|
||||
233 00626 6777 SDRD
|
||||
234 00627 0376 AND C70 /GET FIELD FOR XFER
|
||||
235 00630 1361 TAD C6201 /FORM CDF N
|
||||
236 00631 3251 DCA XFIELD /IF=0 AND DF=N AT XFER.
|
||||
237 00632 1047 TAD UNIT /TEST FOR SELECT ERROR
|
||||
238 00633 6774 SDLC
|
||||
239 00634 7200 CLA / Moved here because my drive 1 is slow selecting
|
||||
240 00635 1020 TAD RETRY
|
||||
241 00636 3050 DCA TRYCNT /3 ERROR TRIES
|
||||
242 00637 6776 SDRC
|
||||
243 00640 0364 AND C100
|
||||
244 00641 7640 SZA CLA
|
||||
245 00642 5351 JMP FATAL-1
|
||||
246 00643 6777 SDRD /PUT FUNCT INTO XFUNCT IN SECOND PG.
|
||||
247 00644 3763 DCA I CXFUN
|
||||
248 00645 1023 TAD WCOUNT
|
||||
249 00646 3452 DCA I CXWCT
|
||||
250 00647 6777 SDRD /GET MOTION BIT TO LINK
|
||||
|
||||
|
||||
|
||||
/ TD8E 12-bit DECtape DUMP Program. Based on DUMPREST code fro Page 6
|
||||
|
||||
|
||||
251 00650 7110 CLL RAR
|
||||
252 00651 7402 XFIELD, HLT /INTO NEXT PAGE
|
||||
253 00652 5263 JMP GO /AND START THE MOTION.
|
||||
254 00653 6772 RWCOM, SDST /ANY CHECKSUM ERRORS?
|
||||
255 00654 7640 SZA CLA /OR CHECKSUM ERRORS?
|
||||
256 00655 5341 JMP TRY3 /PLEASE NOTE THAT THE LINK IS ALWAYS
|
||||
257 /SET AT RWCOM. GETCHK SETS IT.
|
||||
258 00656 2051 ISZ PGCT / (DJG)
|
||||
259 00657 7410 SKP / (DJG)
|
||||
260 00660 5350 JMP EXIT /ALL DONE. GET OUT
|
||||
261 00661 2046 ISZ BLOCK /NEXT BLOCK TO XFER
|
||||
262 00662 7120 CLL CML /FORCES MOTION FORWARD
|
||||
263 00663 7232 GO, CLA CML RTR /LINK BECOMES MOTION BIT
|
||||
264 00664 1365 TAD C1000
|
||||
265 00665 1047 TAD UNIT /PUT IN 'GO' AND UNIT #
|
||||
266 00666 6774 SDLC /LOOK FOR BLOCK NO.
|
||||
267 00667 7200 CLA
|
||||
268 00670 1044 TAD XBUFF
|
||||
269 00671 3043 DCA OLDBUF
|
||||
270 00672 6214 RDF
|
||||
271 00673 1361 TAD C6201
|
||||
272 00674 3342 DCA OLDFLD
|
||||
273 00675 4762 JMS I CRDQUD /WAIT AT LEAST 6 LINES TO LOOK
|
||||
274 00676 4762 JMS I CRDQUD
|
||||
275 00677 7600 CM200, 7600 /COULD HAVE SAVED A LOC. HERE
|
||||
276 00700 6771 SRCH, SDSS
|
||||
277 00701 5300 JMP .-1 /WAIT FOR SINGLE LINE FLAG
|
||||
278 00702 6776 SDRC
|
||||
279 00703 7106 CLL RTL /DIRECTION TO LINK. INFO BITS
|
||||
280 /ARE SHIFTED.
|
||||
281 00704 0045 AND C374 /ISOLATE MARK TRACK BITS
|
||||
282 00705 1323 TAD M110 /IS IT END ZONE?
|
||||
283 00706 7450 SNA /THE LINK STAYS SAME THRU THIS
|
||||
284 00707 5331 JMP ENDZ
|
||||
285 00710 1053 TAD M20 /CHECK FOR BLOCK MARK
|
||||
286 00711 7640 SZA CLA
|
||||
287 00712 5300 JMP SRCH
|
||||
288 00713 6777 SDRD /GET THE BLOCK NUMBER
|
||||
289 00714 7430 SZL /IF WE ARE IN REVERSE, LOOK FOR 3
|
||||
290 /BLOCKS BEFORE TARGET BLOCK. THIS
|
||||
291 /ALLOWS TURNAROUND AND UP TO SPEED.
|
||||
292 00715 1377 TAD C3 /REVERSE
|
||||
293 00716 7040 CMA
|
||||
294 00717 1046 TAD BLOCK
|
||||
295 00720 7040 CMA /IS IT RIGHT BLOCK?
|
||||
296 00721 7450 SNA
|
||||
297 00722 5372 JMP FOUND /YES..HOORAY!
|
||||
298 00723 7670 M110, SZL SNA CLA /NO, BUT ARE WE HEADED FOR IT?
|
||||
299 /ABOVE SNA IS SUPERFLUOUS.
|
||||
300 00724 5300 JMP SRCH /YES
|
||||
|
||||
|
||||
|
||||
/ TD8E 12-bit DECtape DUMP Program. Based on DUMPREST code fro Page 7
|
||||
|
||||
|
||||
301 00725 6776 SDRC /NO, TURN US AROUND.
|
||||
302 00726 7106 CLL RTL /DIRECTION TO LINK
|
||||
303 00727 7200 CLA /THIS CODE USED TO BE SHARED WITH ENDZ,
|
||||
304 00730 5263 JMP GO /BUT NOW ENDZ HANDLES END OF TAPE CASES ONLY.
|
||||
305 00731 6776 ENDZ, SDRC /WE ARE IN THE END ZONE
|
||||
306 00732 7106 CLL RTL /DIRECTION TO LINK
|
||||
307 00733 7630 SZL CLA /ARE WE IN REVERSE?
|
||||
308 00734 5263 JMP GO /YES..TURN US AROUND
|
||||
309 00735 1046 TAD BLOCK /IF WE ARE ON BLOCK ZERO, IT IS POSSIBLE FOR US TO BE AT THE
|
||||
310 /REVERSE ENDZONE GOING FORWARD, EITHER DUE TO A RETRY OR BECAUSE
|
||||
311 /THE TAPE WAS STARTED IN A POSITION BEFORE THE END ZONE.
|
||||
312 /THESE CASES SHOULD NOT BE TREATED AS END-OF-TAPE.
|
||||
313 00736 7640 SZA CLA
|
||||
314 00737 5353 JMP ENDEX /END OF TAPE. STOP THE UNIT AND TAKE THE END EXIT.
|
||||
315 00740 5263 JMP GO
|
||||
316
|
||||
317 00741 7200 TRY3, CLA
|
||||
318 00742 7000 OLDFLD, NOP
|
||||
319 00743 1043 TAD OLDBUF
|
||||
320 00744 3044 DCA XBUFF
|
||||
321 00745 2050 ISZ TRYCNT
|
||||
322 00746 5263 JMP GO /TRY 3 TIMES
|
||||
323 00747 5352 JMP FATAL /LINK OFF MEANS AC=4000 ON RETURN
|
||||
324 00750 2200 EXIT, ISZ DTA0 /TAKE THE NORMAL RETURN
|
||||
325 00751 7120 CLL CML /AC=0 ON NORMAL RETURN
|
||||
326 00752 2200 FATAL, ISZ DTA0 /TAKE THE ERROR RETURN
|
||||
327 00753 1047 ENDEX, TAD UNIT
|
||||
328 00754 6774 SDLC /STOP THE UNIT
|
||||
329 00755 7230 CLA CML RAR
|
||||
330 00756 7402 LEAVE, HLT
|
||||
331 00757 5600 JMP I DTA0
|
||||
332
|
||||
333
|
||||
334 00760 6203 C6203, 6203
|
||||
335 00761 6201 C6201, 6201
|
||||
336 00762 1060 CRDQUD, RDQUAD
|
||||
337 00763 1120 CXFUN, XFUNCT
|
||||
338 00764 0100 C100, 100
|
||||
339 00765 1000 C1000, 1000
|
||||
340
|
||||
341
|
||||
342 / NOTE THAT THE ABOVE CODE SEGMENT COMES VERY CLOSE TO TOUCHING
|
||||
343 / THIS ONE, AND THIS ONE MUST RESIDE AT THE END OF THIS PAGE.
|
||||
344 / BE CAREFUL ADDING NEW CODE TO THE ABOVE PAGE.
|
||||
345 0772 *ORIGIN+172
|
||||
346 00772 7630 FOUND, SZL CLA /RIGHT BLOCK. HOW ABOUT DIRECTION?
|
||||
347 00773 5263 JMP GO /WRONG..TURN AROUND
|
||||
348 00774 1047 TAD UNIT /PUT UNIT INTO LINK
|
||||
349 00775 7104 CLL RAL /AC IS NOW 0
|
||||
350 00776 0070 C70, 70 /********DON'T MOVE THIS!!!!******
|
||||
|
||||
|
||||
|
||||
/ TD8E 12-bit DECtape DUMP Program. Based on DUMPREST code fro Page 8
|
||||
|
||||
|
||||
351 00777 0003 C3, 3
|
||||
352 /INTO NEXT PAGE
|
||||
353 1000 *ORIGIN+200
|
||||
354 01000 6202 CIF MFIELD
|
||||
355 01001 7010 RAR /NOW GET UNIT #
|
||||
356 01002 3265 DCA XUNIT
|
||||
357 01003 6776 SDRC
|
||||
358 01004 6774 SDLC
|
||||
359 01005 6771 REVGRD, SDSS
|
||||
360 01006 5205 JMP .-1 /LOOK FOR REVERSE GUARD
|
||||
361 01007 6776 SDRC
|
||||
362 01010 0222 AND K77
|
||||
363 01011 1321 TAD CM32 /IS IT REVERSE GUARD?
|
||||
364 01012 7640 SZA CLA
|
||||
365 01013 5205 JMP REVGRD /NO.KEEP LOOKING
|
||||
366 01014 1325 TAD XWCT
|
||||
367 01015 3324 DCA WORDS /WORD COUNTER
|
||||
368 01016 1320 TAD XFUNCT /GET FUNCTION READ OR WRITE
|
||||
369 01017 7700 K7700, SMA CLA
|
||||
370 01020 5223 JMP READ /NEG. IS WRITE
|
||||
371 01021 7402 WRITE, HLT /WRITE CODE REMOVED
|
||||
372 01022 0077 K77, 77 /ABOVE MAY SKIP (NOT ANYMORE DJG)
|
||||
373 01023 4260 READ, JMS RDQUAD
|
||||
374 01024 4260 JMS RDQUAD
|
||||
375 01025 4260 JMS RDQUAD /SKIP CONTROL WORDS
|
||||
376 01026 0222 AND K77
|
||||
377 01027 1217 TAD K7700 /TACK 7700 ONTO CHECKSUM.
|
||||
378 01030 3323 DCA CHKSUM /CHECKSUM ONLY LOW 6 BITS ANYWAY
|
||||
379 01031 4260 RDLP, JMS RDQUAD
|
||||
380 01032 4265 JMS EQUFUN /COMPUT CHECKSUM AS WE GO
|
||||
381 01033 3444 DCA I XBUFF /IT GETS CONDENSED LATER
|
||||
382 01034 2044 ISZ XBUFF /AT END OF FIELD?
|
||||
383 01035 5242 JMP STFLD2+1 /NOT AT END OF FIELD (DJG)
|
||||
384 01036 6214 RDF
|
||||
385 01037 1377 TAD (6211
|
||||
386 01040 3241 DCA STFLD2
|
||||
387 01041 7000 STFLD2, NOP
|
||||
388 01042 2324 ISZ WORDS /DONE THIS OP?
|
||||
389 01043 5231 JMP RDLP /NO SUCH LUCK
|
||||
390 01044 1320 TAD XFUNCT /IF OP WAS FOR WDSBLK-1, READ AND
|
||||
391 01045 7112 CLL RTR /CHECKSUM THE LAST TAPE WORD
|
||||
392 01046 7620 SNL CLA
|
||||
393 01047 5252 JMP RDLP2
|
||||
394 01050 4260 JMS RDQUAD /NOT NEEDED FOR WDSBLK/BLOCK
|
||||
395 01051 4265 JMS EQUFUN /CHECKSUM IT
|
||||
396 01052 4260 RDLP2, JMS RDQUAD /READ CHECKSUM
|
||||
397 01053 0217 AND K7700
|
||||
398 01054 4265 JMS EQUFUN
|
||||
399 01055 4302 JMS GETCHK /GET SIX BIT CHECKSUM
|
||||
400 01056 5717 JMP I CRWCOM
|
||||
|
||||
|
||||
|
||||
/ TD8E 12-bit DECtape DUMP Program. Based on DUMPREST code fro Page 9
|
||||
|
||||
|
||||
401 01057 0300 C300, 300 /PROTECTION (NOT ANYMORE DJG)
|
||||
402
|
||||
403 01060 0000 RDQUAD, 0 /READ A 12 BIT WORD
|
||||
404 01061 6773 SDSQ
|
||||
405 01062 5261 JMP .-1
|
||||
406 01063 6777 SDRD /READ DATA
|
||||
407 01064 5660 JMP I RDQUAD
|
||||
408
|
||||
409 XUNIT,
|
||||
410 01065 0000 EQUFUN, 0 /COMPUTE EQUIVALENCE CHECKSUM
|
||||
411 01066 7040 CMA
|
||||
412 01067 3326 DCA EQUTMP /ACTUALLY CHECKSUMS ON DECTAPE ARE
|
||||
413 01070 1326 TAD EQUTMP /EQUIVALENCE OF ALL WORDS IN A RECORD
|
||||
414 01071 0323 AND CHKSUM /SIX BITS AT A TIME. BUT SINCE EQUIVALENCE
|
||||
415 01072 7041 CIA /IS ASSOCIATIVE, WE CAN DO IT 12
|
||||
416 01073 7104 CLL RAL /BITS AT A TIME AND CONDENSE LATER.
|
||||
417 01074 1326 TAD EQUTMP /THIS ROUTINE USES THESE IDENTITIES:
|
||||
418 01075 1323 TAD CHKSUM /A+B=(A.XOR.B)+2*(A.AND.B)
|
||||
419 01076 3323 DCA CHKSUM /A.EQU.B=.NOT.(A.XOR.B)=A.XOR.(.NOT.B)
|
||||
420 01077 1326 TAD EQUTMP /A.EQU.B=(A+(.NOT.B))-2*(A.AND.(.NOT.B))
|
||||
421 01100 7040 CMA
|
||||
422 01101 5665 JMP I EQUFUN
|
||||
423
|
||||
424 01102 0000 GETCHK, 0 /FORM 6 BIT CHECKSUM
|
||||
425 01103 7200 CLA
|
||||
426 01104 1323 TAD CHKSUM
|
||||
427 01105 7040 CMA
|
||||
428 01106 7106 CLL RTL
|
||||
429 01107 7006 RTL
|
||||
430 01110 7006 RTL
|
||||
431 01111 4265 JMS EQUFUN
|
||||
432 01112 7320 CLA CLL CML /FORCES LINK ON AT RWCOM
|
||||
433 01113 1323 TAD CHKSUM
|
||||
434 01114 0217 AND K7700
|
||||
435 01115 5702 JMP I GETCHK
|
||||
436
|
||||
437 01116 0752 CFATAL, FATAL
|
||||
438 01117 0653 CRWCOM, RWCOM
|
||||
439 01120 0000 XFUNCT, 0
|
||||
440 01121 7746 CM32, -32
|
||||
441 01122 1400 C1400, 1400
|
||||
442 01123 0000 CHKSUM, 0
|
||||
443 01124 0000 WORDS, 0
|
||||
444 01125 0000 XWCT, 0
|
||||
445 01126 0000 EQUTMP, 0
|
||||
446
|
||||
01177 6211
|
||||
447 0020 *20
|
||||
448 00020 7774 RETRY, 7774 / RETRY UP TO 4 TIME
|
||||
449 00021 3777 NUMBLK, 3777 / MAX NUMBER OF BLOCKS TO ATTEMPT READING. BY DEFAULT THIS PROGRAM WILL READ UNTIL
|
||||
|
||||
|
||||
|
||||
/ TD8E 12-bit DECtape DUMP Program. Based on DUMPREST code fro Page 10
|
||||
|
||||
|
||||
450 / IT HITS THE END OF THE TAPE (FORWARD ENDZONE). IF YOU NEED TO LIMIT THE NUMBER OF BLOCKS
|
||||
451 / READ, MODIFY THIS VALUE.
|
||||
452 00022 7577 MWORDS, -WDSBLK / WORDS PER BLOCK
|
||||
453 00023 0000 WCOUNT, 0
|
||||
454 00024 0036 BLKFLD, 36 / 30 129 WORD BLOCKS OF 12-BIT WORDS
|
||||
455 / WRAPPING PAST END OF LAST FIELD DOESN'T WORK
|
||||
456 00025 0000 FIELDS, 0
|
||||
457 00026 0000 RDSIZE, 0 / NUMBER BLOCKS PER READ
|
||||
458 00027 0000 CBLOCK, 0 / CURRENT BLOCK TO XFER
|
||||
459 00030 0000 CLKSUM, 0
|
||||
460 00031 0000 DRVSEL, 0
|
||||
461 00032 0377 READST, 377
|
||||
462 00033 0000 LOC, 0
|
||||
463 00034 0000 LEN, 0
|
||||
464 00035 0000 BCNT, 0 / BLOCKS TO SEND TO PC
|
||||
465 00036 0000 TEMP, 0
|
||||
466 00037 0017 C17, 17
|
||||
467 00040 0360 C360, 360
|
||||
468 00041 0000 CHKSM, 0
|
||||
469 00042 0000 ERRCN2, 0
|
||||
470 00043 0000 OLDBUF, 0 / BELOW ARE USED BY DTA0 ROUTINE
|
||||
471 00044 0000 XBUFF, 0
|
||||
472 00045 0374 C374, 374
|
||||
473 00046 0000 BLOCK, 0
|
||||
474 00047 0000 UNIT, 0
|
||||
475 00050 7775 TRYCNT, -3
|
||||
476 00051 0000 PGCT, 0
|
||||
477 00052 1125 CXWCT, XWCT
|
||||
478 00053 7760 M20, -20
|
||||
479
|
||||
480 0140 *140
|
||||
481 00140 7402 FINISH, HLT / Normal good halt
|
||||
482 00141 5777@ JMP START
|
||||
483
|
||||
484 0200 *200
|
||||
485 00200 6201 START, CDF 0
|
||||
486 00201 6007 CAF
|
||||
487 00202 7704 CLA CLL OSR / Get drive
|
||||
488 00203 0377 AND (1
|
||||
489 00204 7012 RTR
|
||||
490 00205 3031 DCA DRVSEL
|
||||
491 00206 7704 CLA CLL OSR / Get max field
|
||||
492 00207 7012 RTR
|
||||
493 00210 7010 RAR
|
||||
494 00211 0376 AND (7
|
||||
495 00212 7450 SNA
|
||||
496 00213 7402 HLT / Must have at least 1 field for buffer
|
||||
497 00214 7041 CIA
|
||||
498 00215 3025 DCA FIELDS
|
||||
499 00216 3042 DCA ERRCN2
|
||||
|
||||
|
||||
|
||||
/ TD8E 12-bit DECtape DUMP Program. Based on DUMPREST code fro Page 11
|
||||
|
||||
|
||||
500 00217 1024 RDSZLP, TAD BLKFLD / Multiply by number of fields available
|
||||
501 00220 2025 ISZ FIELDS
|
||||
502 00221 5217 JMP RDSZLP
|
||||
503 00222 3026 DCA RDSIZE / NUMBER BLOCK PER READ
|
||||
504 00223 3027 DCA CBLOCK
|
||||
505 00224 3041 DCA CHKSM
|
||||
506
|
||||
507 00225 7200 DUMPLP, CLA
|
||||
508 00226 1026 TAD RDSIZE
|
||||
509 00227 1027 TAD CBLOCK
|
||||
510 00230 7041 CIA
|
||||
511 00231 1021 TAD NUMBLK / MORE BLOCKS LEFT THAN READSIZE?
|
||||
512 00232 7500 SMA / NO, READ NUMBER LEFT
|
||||
513 00233 7200 CLA / YES, ONLY READ RDSIZE
|
||||
514 00234 1026 TAD RDSIZE
|
||||
515 00235 7450 SNA / ANY MORE BLOCKS?
|
||||
516 00236 5270 JMP DONE / NO, DO FINISH STUFF
|
||||
517 00237 3245 DCA ARGSZ
|
||||
518 00240 1027 TAD CBLOCK
|
||||
519 00241 3247 DCA ARGBK
|
||||
520 00242 1031 TAD DRVSEL
|
||||
521 00243 4775@ JMS DTA0
|
||||
522 00244 0010 0010 / READ STARTING IN FIELD 1
|
||||
523 00245 0000 ARGSZ, 0
|
||||
524 00246 0000 0
|
||||
525 00247 0000 ARGBK, 0
|
||||
526 00250 5774@ JMP ENDRET / TAKEN WHEN END OF TAPE IS HIT
|
||||
527 00251 5323 JMP ERRRET / TAKEN WHEN AN ERROR IS ENCOUNTERED
|
||||
528 00252 1373 TAD (377 / All blocks good
|
||||
529 00253 3032 DCA READST
|
||||
530 / Send data, each block starts with FF
|
||||
531 00254 7300 CLA CLL / then 2 12 bit words in 3 bytes
|
||||
532 00255 3033 DCA LOC / ERRRET DUPLICATES SOME OF THIS
|
||||
533 00256 1245 TAD ARGSZ
|
||||
534 00257 7041 CIA
|
||||
535 00260 3035 DCA BCNT / Setup loop counter with number blocks read
|
||||
536 00261 6211 CDF 10
|
||||
537 00262 4772@ OUTBL1, JMS OUTBLK / Send a block
|
||||
538 00263 2027 ISZ CBLOCK
|
||||
539 00264 2035 ISZ BCNT / Send all read?
|
||||
540 00265 5262 JMP OUTBL1 / No
|
||||
541 00266 6201 CDF 0
|
||||
542 00267 5225 JMP DUMPLP / Go read next batch
|
||||
543
|
||||
544
|
||||
545 00270 7200 DONE, CLA / Send FE and -checksum of all words
|
||||
546 00271 1371 TAD (376
|
||||
547 00272 4770@ JMS PUN
|
||||
548 00273 7300 CLA CLL
|
||||
549 00274 1041 TAD CHKSM / Send checksum in two bytes, low bits first
|
||||
|
||||
|
||||
|
||||
/ TD8E 12-bit DECtape DUMP Program. Based on DUMPREST code fro Page 12
|
||||
|
||||
|
||||
550 00275 7041 CIA
|
||||
551 00276 4770@ JMS PUN
|
||||
552 00277 7300 CLA CLL
|
||||
553 00300 1041 TAD CHKSM
|
||||
554 00301 7041 CIA
|
||||
555 00302 7012 RTR
|
||||
556 00303 7012 RTR
|
||||
557 00304 7012 RTR
|
||||
558 00305 7012 RTR
|
||||
559 00306 0037 AND C17
|
||||
560 00307 4770@ JMS PUN
|
||||
561 00310 7200 CLA
|
||||
562 00311 1031 TAD DRVSEL
|
||||
563 00312 4775@ JMS DTA0 / REWIND TAPE
|
||||
564 00313 0010 0010
|
||||
565 00314 0001 1
|
||||
566 00315 0000 0
|
||||
567 00316 0000 0
|
||||
568 00317 7000 NOP
|
||||
569 00320 7000 NOP
|
||||
570 00321 1042 TAD ERRCN2 / Leave AC with # of errors
|
||||
571 00322 5140 JMP FINISH
|
||||
572
|
||||
573 /SEND GOOD BLOCKS READ WITH GOOD BLOCK FLAG
|
||||
574 /THEN BAD WITH BAD BLOCK FLAG.
|
||||
575 ERRRET,
|
||||
576 / HLT / ****** If we want to stop on error
|
||||
577 00323 6211 CDF 10
|
||||
578 00324 7300 CLA CLL
|
||||
579 00325 3033 DCA LOC
|
||||
580 00326 1027 TAD CBLOCK
|
||||
581 00327 7041 CIA
|
||||
582 00330 1046 TAD BLOCK /Get - number good blocks read
|
||||
583 00331 7041 CIA /Last was bad
|
||||
584 00332 7450 SNA
|
||||
585 00333 5343 JMP FSTBAD /First block is bad, no good to send
|
||||
586 00334 3035 DCA BCNT
|
||||
587 00335 1373 TAD (377
|
||||
588 00336 3032 DCA READST
|
||||
589 00337 4772@ OUTBL2, JMS OUTBLK /Send good blocks
|
||||
590 00340 2027 ISZ CBLOCK
|
||||
591 00341 2035 ISZ BCNT
|
||||
592 00342 5337 JMP OUTBL2
|
||||
593 00343 1367 FSTBAD, TAD (375 /NOW SEND BAD BLOCK
|
||||
594 00344 3032 DCA READST
|
||||
595 00345 4772@ JMS OUTBLK
|
||||
596 00346 2027 ISZ CBLOCK
|
||||
597 00347 2042 ISZ ERRCN2
|
||||
598 00350 6201 CDF 0
|
||||
599 00351 5225 JMP DUMPLP /And read from here on
|
||||
|
||||
|
||||
|
||||
/ TD8E 12-bit DECtape DUMP Program. Based on DUMPREST code fro Page 13
|
||||
|
||||
|
||||
600
|
||||
00367 0375
|
||||
00370 0511
|
||||
00371 0376
|
||||
00372 0422
|
||||
00373 0377
|
||||
00374 0400
|
||||
00375 0600
|
||||
00376 0007
|
||||
00377 0001
|
||||
601 PAGE
|
||||
602 ENDRET, /SEND LAST SET OF BLOCKS READ BEFORE END OF TAPE AND FINISH.
|
||||
603 00400 6211 CDF 10
|
||||
604 00401 7300 CLA CLL
|
||||
605 00402 3033 DCA LOC
|
||||
606 00403 1027 TAD CBLOCK
|
||||
607 00404 7041 CIA
|
||||
608 00405 1046 TAD BLOCK / GET NUMBER OF BLOCKS READ IN LAST BATCH
|
||||
609 00406 7040 CMA / +1 to -BCNT SO WE SEND ALL BLOCKS
|
||||
610 00407 7450 SNA
|
||||
611 00410 5777@ JMP DONE / READ ZERO BLOCKS IN LAST BATCH, WE ARE DONE
|
||||
612 00411 3035 DCA BCNT
|
||||
613 00412 1376 TAD (377
|
||||
614 00413 3032 DCA READST
|
||||
615 00414 4222 OUTBL3, JMS OUTBLK / SEND ALL BLOCKS
|
||||
616 00415 2027 ISZ CBLOCK
|
||||
617 00416 2035 ISZ BCNT
|
||||
618 00417 5214 JMP OUTBL3
|
||||
619 00420 6201 CDF 0
|
||||
620 00421 5777@ JMP DONE / NO MORE BLOCKS, DONE.
|
||||
621
|
||||
622 00422 0000 OUTBLK, 0 /Send a block of data out serial port
|
||||
623 00423 7200 CLA
|
||||
624 00424 1023 TAD WCOUNT
|
||||
625 00425 3034 DCA LEN
|
||||
626 00426 1032 TAD READST /Send good/bad flag
|
||||
627 00427 4311 JMS PUN
|
||||
628 00430 7300 OUT, CLA CLL
|
||||
629 00431 1433 TAD I LOC
|
||||
630 00432 1041 TAD CHKSM / Keep checksum of all words sent
|
||||
631 00433 3041 DCA CHKSM
|
||||
632 00434 1433 TAD I LOC / Send 2 words as 3 bytes
|
||||
633 00435 4311 JMS PUN
|
||||
634 00436 7300 CLA CLL
|
||||
635 00437 1433 TAD I LOC
|
||||
636 00440 7012 RTR / Shift top 4 bits to low 4
|
||||
637 00441 7012 RTR
|
||||
638 00442 7012 RTR
|
||||
639 00443 7012 RTR
|
||||
640 00444 0037 AND C17
|
||||
|
||||
|
||||
|
||||
/ TD8E 12-bit DECtape DUMP Program. Based on DUMPREST code fro Page 14
|
||||
|
||||
|
||||
641 00445 3036 DCA TEMP
|
||||
642 00446 2033 ISZ LOC
|
||||
643 00447 5254 JMP STFLD3+1 /NOT AT END OF FIELD (DJG)
|
||||
644 00450 6214 RDF /At end, inc to next field
|
||||
645 00451 1375 TAD (6211 /BUILD CDF
|
||||
646 00452 3253 DCA STFLD3
|
||||
647 00453 7000 STFLD3, NOP
|
||||
648 00454 2034 ISZ LEN /END OF BUFFER?
|
||||
649 00455 7410 SKP /NO
|
||||
650 00456 5306 JMP ENDBK /YES
|
||||
651 00457 1433 TAD I LOC
|
||||
652 00460 1041 TAD CHKSM
|
||||
653 00461 3041 DCA CHKSM
|
||||
654 00462 1433 TAD I LOC
|
||||
655 00463 7006 RTL
|
||||
656 00464 7006 RTL
|
||||
657 00465 0040 AND C360
|
||||
658 00466 1036 TAD TEMP
|
||||
659 00467 4311 JMS PUN
|
||||
660 00470 7300 CLA CLL
|
||||
661 00471 1433 TAD I LOC
|
||||
662 00472 7012 RTR
|
||||
663 00473 7012 RTR
|
||||
664 00474 4311 JMS PUN
|
||||
665 00475 2033 ISZ LOC
|
||||
666 00476 5303 JMP STFLD4+1 /NOT AT END OF FIELD (DJG)
|
||||
667 00477 6214 RDF
|
||||
668 00500 1375 TAD (6211 /BUILD CDF
|
||||
669 00501 3302 DCA STFLD4
|
||||
670 00502 7000 STFLD4, NOP
|
||||
671 00503 2034 ISZ LEN
|
||||
672 00504 5230 JMP OUT
|
||||
673 00505 5622 JMP I OUTBLK
|
||||
674 00506 1036 ENDBK, TAD TEMP /SEND LAST PART OF WORD
|
||||
675 00507 4311 JMS PUN
|
||||
676 00510 5622 JMP I OUTBLK
|
||||
677
|
||||
678 00511 0000 PUN, 0 / Send byte out serial port
|
||||
679 / PLS / Punch for testing with emulator
|
||||
680 00512 6046 TLS2 / Send out console
|
||||
681 00513 7300 CLA CLL
|
||||
682 00514 1027 TAD CBLOCK
|
||||
683 / PSF
|
||||
684 00515 6041 TSF2 /Wait until character sent
|
||||
685 00516 5315 JMP .-1
|
||||
686 00517 7200 CLA
|
||||
687 00520 5711 JMP I PUN
|
||||
688
|
||||
00575 6211
|
||||
00576 0377
|
||||
|
||||
|
||||
|
||||
/ TD8E 12-bit DECtape DUMP Program. Based on DUMPREST code fro Page 15
|
||||
|
||||
|
||||
00577 0270
|
||||
00177 0200
|
||||
689 $
|
||||
|
||||
No detected errors
|
||||
12 links generated
|
||||
689
DumpDT18/dumpdt12.pal
Normal file
689
DumpDT18/dumpdt12.pal
Normal file
@@ -0,0 +1,689 @@
|
||||
/ TD8E 12-bit DECtape DUMP Program. Based on DUMPREST code from D. Gesswein
|
||||
/ (see ftp://ftp.pdp8online.com/software/dumprest).
|
||||
/ Modified to handle arbitrary-length tapes by J. Dersch
|
||||
/
|
||||
/ This program will send a DECtape image out the console port.
|
||||
/ The format of the data sent is 0xff (0377) or 0xfd if read error
|
||||
/ followed by 129 12-bit words of data for each block.
|
||||
/ After the last block a 0xfe (0376) is sent
|
||||
/ with a two byte checksum, low 8 bits first then upper 4.
|
||||
/ The words in a block are sent as three bytes for each 2 words.
|
||||
/ 1 = low 8 bits first word
|
||||
/ 2 = upper 4 bits first and lower 4 bits second
|
||||
/ 3 = upper 8 bits second word
|
||||
/
|
||||
/ The program (PC) receiving the data should be started before this program.
|
||||
/
|
||||
/ To run, start at 0200.
|
||||
/ SR 11 should be drive, only 0 and 1 supported without reassembling
|
||||
/ SR 6-8 should be maximum memory field in computer, needs 8k minimum
|
||||
/
|
||||
/ The receiving program should be running first.
|
||||
/ At normal exit hitting cont will restart the program.
|
||||
/
|
||||
/ Should halt at label finish (140) with number of recoverable errors in AC
|
||||
/ The current block being read will be displayed in the AC
|
||||
/ while running.
|
||||
/
|
||||
/ The PC program will print out the bad location if an error occurs.
|
||||
/
|
||||
/ We will retry each read up to four times on error.
|
||||
/
|
||||
/ This transfers the standard 129 word by 1474 blocks used by 12-bit DEC hardware,
|
||||
/ using standard checksums (as used by the PDP-9 and later machines).
|
||||
/ It will read as many blocks are present up to the forward end-zone, so it will
|
||||
/ handle tapes that vary from the standard block length.
|
||||
/
|
||||
INAD=030 / Address of serial input, 30 for console
|
||||
KCF2=6000 INAD
|
||||
KSF2=6001 INAD
|
||||
KCC2=6002 INAD
|
||||
KRS2=6004 INAD
|
||||
KIE2=6005 INAD
|
||||
KRB2=6006 INAD
|
||||
|
||||
OUTAD=040 / Address of serial output, 40 for console
|
||||
TFL2=6000 OUTAD
|
||||
TSF2=6001 OUTAD
|
||||
TCF2=6002 OUTAD
|
||||
TPC2=6004 OUTAD
|
||||
TSK2=6005 OUTAD
|
||||
TLS2=6006 OUTAD
|
||||
|
||||
|
||||
/CODE BASED ON:
|
||||
/2 TD8E INITIALIZER PROGRAM, V7A
|
||||
/
|
||||
/COPYRIGHT (C) 1975, 1977
|
||||
/DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
|
||||
/
|
||||
/
|
||||
/
|
||||
/THIS SOFTWARE IS FURNISHED UNDER A LICENSE FOR USE ONLY ON A
|
||||
/SINGLE COMPUTER SYSTEM AND MAY BE COPIED ONLY WITH THE INCLU-
|
||||
/SION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE, OR ANT OTHER
|
||||
/COPIES THEREOF, MAY NOT BR PROVIDED OR OTHERWISE MADE AVAILABLE
|
||||
/TO ANY OTHER PERSON EXCEPT FOR USE ON SUCH SYSTEM AND TO ONE WHO
|
||||
/AGREES TO THESE LICENSE TERMS. TITLE TO AND OWNERSHIP OF THE
|
||||
/SOFTWARE SHALL AT ALL TIMES REMAIN IN DEC.
|
||||
/
|
||||
/
|
||||
/THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT
|
||||
/NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL
|
||||
/EQUIPMRNT COROPATION.
|
||||
/
|
||||
/DEC ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
|
||||
/SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DEC.
|
||||
/
|
||||
/
|
||||
/
|
||||
/
|
||||
/
|
||||
/
|
||||
|
||||
/DECEMBER 21, 1973 GB/RL/EF/SR
|
||||
|
||||
/ABSTRACT--
|
||||
/ THE ROUTINE DESCRIBED AND LISTED HERE IS A GENERAL
|
||||
/DATA HANDLER FOR THE TD8E DECTAPE SYSTEM. THE ROUTINE
|
||||
/CONTAINS SEARCH, READ, AND WRITE FUNCTIONS IN A FORMAT
|
||||
/WHICH IS COMPATIBLE WITH OS/8 DEVICE HANDLER CALLING
|
||||
/SEQUENCES.
|
||||
|
||||
/FIXES SINCE FIELD-TEST RELEASE:
|
||||
|
||||
/1. FIXED BUG RE CLA ON RETRY AFTER ERROR
|
||||
/2. ALLOWED FINAL BOOTSTRAP TO BE INTO A WRITE-LOCKED DEVICE
|
||||
|
||||
/OS/8 V3D CHANGES:
|
||||
|
||||
/3. FIXED BUG RE TD8E BUILD (V6B PATCH)
|
||||
|
||||
/THIS ROUTINE CAN BE RE-EDITED AND ASSEMBLED TO PRODUCE
|
||||
/VARIATIONS ON THE BASIC TD8E SYSTEM. ASSEMBLY PARAMETERS
|
||||
/CONTROL:
|
||||
/A) WHAT DRIVES (UNITS 0-7) WILL BE USED
|
||||
/B) THE ORIGIN OF THE TWO PAGE ROUTINE
|
||||
/C) WHAT MEMORY FIELD THE ROUTINE WILL RUN IN
|
||||
/D) THE SIZE OF THE DECTAPE BLOCK TO BE READ/WRITTEN
|
||||
|
||||
/FOLLOWING ARE THE PARAMETERS SET UP FOR THE STANDARD
|
||||
/DEC VERSION OF THIS ROUTINE:
|
||||
|
||||
DRIVE=10 /UNITS 0 AND 1 SELECTED
|
||||
ORIGIN=600 /ENTER AT ORIGIN, ORIGIN+4
|
||||
AFIELD=0 /INITIAL FIELD SETTING
|
||||
MFIELD=00 /AFIELD*10=MFIELD
|
||||
WDSBLK=201 /129 12-BIT WORDS PER BLOCK
|
||||
|
||||
/THE USE OF THE PARAMETERS IS AS FOLLOWS:
|
||||
|
||||
/ DRIVE: DRIVE DETERMINES WHICH UNITS WILL BE SELECTED
|
||||
/ DRIVE=10 IMPLIES UNITS 0 &1
|
||||
/ DRIVE=20 IMPLIES UNITS 2&3
|
||||
/ DRIVE=30 IMPLIES UNITS 4&5
|
||||
/ DRIVE=40 IMPLIES UNITS 6&7
|
||||
|
||||
/ORIGIN: ALTERING ORIGIN CAUSES ASSEMBLY IN A DIFFERENT
|
||||
/ MEMORY LOCATION. WHEN CHANGING ORIGIN KEEP IN MIND
|
||||
/THAT THIS IS A TWO PAGE ROUTINE.
|
||||
|
||||
/AFIELD: AFIELD DETERMINES THE INITIAL FIELD SETTING FOR THE
|
||||
/ LOADER. PERMISSIBLE VALUES FOR AFIELD ARE 0 TO 7.
|
||||
|
||||
/MFIELD: MFIELD IS USED IN A CIF CDF MFIELD INSTRUCTION.
|
||||
/ THE VALUE INSERTED FOR MFIELD SHOULD BE 10(8) TIMES
|
||||
/ THE VALUE FOR AFIELD. THE PERMISSIBLE VALUES ARE 00-70.
|
||||
|
||||
/WDSBLK: WDSBLK GOVERNS HOW MANY WORDS THE ROUTINE THINKS ARE
|
||||
/ IN A DECTAPE BLOCK. THE STANDARD VALUE IS 201(8) OR
|
||||
/ 128 DECIMAL. NOTE THAT THE FUNCTION WORD BIT 10 CAN
|
||||
/ 129 DECIMAL ??? (DJG)
|
||||
/ BE USED TO SUBTRACT ONE FROM WDSBLK. THE VALUE USED
|
||||
/ FOR WDSBLK SHOULD BE THE NUMBER OF WORDS THE TAPE WAS
|
||||
/ FORMATTED TO CONTAIN.
|
||||
|
||||
/IF WE WANT A HANDLER FOR UNITS 2&3 TO RESIDE IN
|
||||
/FIELD 2 AT LOCATION 3000 AND READ/WRITE 256(10) WORDS
|
||||
/PER BLOCK, THE PARAMETERS WOULD BE:
|
||||
/ DRIVE=20
|
||||
/ ORIGIN=3000
|
||||
/ AFIELD=2
|
||||
/ MFIELD=20
|
||||
/ WDSBLK=400
|
||||
/THE CALL TO THE SUBROUTINE FOLLOWS BASICALLY THE
|
||||
/CALLING SEQUENCE FOR OS/8 DEVICE HANDLERS.
|
||||
/THE CALLING SEQUENCE IS:
|
||||
|
||||
/ CDF CURRENT
|
||||
/ CIF MFIELD /MFIELD=FIELD ASSEMBLED IN
|
||||
/ JMS ENTRY /ENTRY=ORIGIN (EVEN NUMBERED DRIVE
|
||||
/AND ORIGIN+4 FOR ODD NUMBERED DRIVE.
|
||||
/ ARG1
|
||||
/ ARG1B (DJG)
|
||||
/ ARG2
|
||||
/ ARG3
|
||||
/ ERROR RETURN
|
||||
/ NORMAL RETURN
|
||||
|
||||
/THE ARGUMENTS ARE:
|
||||
|
||||
/ARG1: FUNCTION WORD BIT0: 0=READ, 1=WRITE
|
||||
/ BITS 1-5: UNUSED, WAS # BLOCKS IN OPERATION (DJG)
|
||||
/ BITS 6-8: FIELD OF BUFFER AREA
|
||||
/ BIT 9: UNUSED
|
||||
/ BIT 10: # OF WORDS/BLOCK.
|
||||
/ 0= WDSBLK, 1=WDSBLK-1
|
||||
/ BIT 11: 1=START FORWARD, 0=REVERSE
|
||||
/ARG1A: # OF BLOCKS IN OPERATIONA (DJG)
|
||||
/ARG2: BUFFER ADDRESS FOR OPERATION
|
||||
/ARG3: STARTING BLOCK FOR OPERATION
|
||||
|
||||
/ERRORS: THE HANDLER DETECTS TWO TYPES OF ERRORS:
|
||||
/A) FATAL ERRORS- PARITY ERROR, TIMING ERROR,
|
||||
/ TOO GREAT A BLOCK NUMBER
|
||||
/ FATAL ERRORS TAKE ERROR RETURN WITH THE
|
||||
/ AC=4000.
|
||||
/B) NON-FATAL- SELECT ERROR.
|
||||
/ IF NO PROPER UNIT IS SELECTED, THE ERROR
|
||||
/ RETURN IS TAKEN WITH CLEAR AC.
|
||||
/FATAL ERRORS TRY THREE TIMES BEFORE TAKING ERROR RETURN.
|
||||
/THE NORMAL RETURN IS TAKEN AFTER ALL INDICATED
|
||||
/BLOCKS HAVE BEEN TRANSFERRED. THE AC IS CLEAR.
|
||||
|
||||
/THE TD8E IOT'S ARE:
|
||||
SDSS=7001-DRIVE /SKIP ON SINGLE LINE FLAG
|
||||
SDST=7002-DRIVE /SKIP ON TIMING ERROR
|
||||
SDSQ=7003-DRIVE /SKIP ON QUAD LINE FLAG
|
||||
SDLC=7004-DRIVE /LOAD COMMAND REGISTER
|
||||
SDLD=7005-DRIVE /LOAD DATA REGISTER
|
||||
SDRC=7006-DRIVE /READ COMMAND REGISTER
|
||||
SDRD=7007-DRIVE /READ DATA REGISTER
|
||||
|
||||
/THE IOT'S IN GENERAL ARE 677X,676X,675X,AND 674X.
|
||||
/THE OTHERS CONTROL UNITS 2-7.
|
||||
|
||||
/ THIS HANDLER USES DECTAPE BLOCKS NOT OS/8 BLOCKS !
|
||||
|
||||
*ORIGIN
|
||||
|
||||
/ MODIFIED SO BIT 0 ON ENTRY IS UNIT 1
|
||||
DTA0, 0
|
||||
DCA UNIT /SAVE UNIT POSITION
|
||||
RDF
|
||||
TAD C6203 /GET DATA FIELD AND SETUP RETURN
|
||||
DCA LEAVE
|
||||
TAD I DTA0 /GET FUNCTION WORD
|
||||
SDLD /PUT FUNCTION INTO DATA REGISTER
|
||||
CLA
|
||||
TAD MWORDS
|
||||
DCA WCOUNT /STORE MASTER WORD COUNT
|
||||
ISZ DTA0 /TO BLOCK COUNT (DJG)
|
||||
TAD I DTA0 / (DJG)
|
||||
CIA / (DJG)
|
||||
DCA PGCT / (DJG)
|
||||
ISZ DTA0 /TO BUFFER
|
||||
TAD I DTA0
|
||||
DCA XBUFF /SAVE ADDRESS (DJG)
|
||||
ISZ DTA0 /TO BLOCK NUMBER
|
||||
TAD I DTA0
|
||||
DCA BLOCK
|
||||
ISZ DTA0 /POINT TO ERROR EXIT
|
||||
CIF CDF MFIELD /TO ROUTINES DATA FIELD
|
||||
SDRD
|
||||
AND C70 /GET FIELD FOR XFER
|
||||
TAD C6201 /FORM CDF N
|
||||
DCA XFIELD /IF=0 AND DF=N AT XFER.
|
||||
TAD UNIT /TEST FOR SELECT ERROR
|
||||
SDLC
|
||||
CLA / Moved here because my drive 1 is slow selecting
|
||||
TAD RETRY
|
||||
DCA TRYCNT /3 ERROR TRIES
|
||||
SDRC
|
||||
AND C100
|
||||
SZA CLA
|
||||
JMP FATAL-1
|
||||
SDRD /PUT FUNCT INTO XFUNCT IN SECOND PG.
|
||||
DCA I CXFUN
|
||||
TAD WCOUNT
|
||||
DCA I CXWCT
|
||||
SDRD /GET MOTION BIT TO LINK
|
||||
CLL RAR
|
||||
XFIELD, HLT /INTO NEXT PAGE
|
||||
JMP GO /AND START THE MOTION.
|
||||
RWCOM, SDST /ANY CHECKSUM ERRORS?
|
||||
SZA CLA /OR CHECKSUM ERRORS?
|
||||
JMP TRY3 /PLEASE NOTE THAT THE LINK IS ALWAYS
|
||||
/SET AT RWCOM. GETCHK SETS IT.
|
||||
ISZ PGCT / (DJG)
|
||||
SKP / (DJG)
|
||||
JMP EXIT /ALL DONE. GET OUT
|
||||
ISZ BLOCK /NEXT BLOCK TO XFER
|
||||
CLL CML /FORCES MOTION FORWARD
|
||||
GO, CLA CML RTR /LINK BECOMES MOTION BIT
|
||||
TAD C1000
|
||||
TAD UNIT /PUT IN 'GO' AND UNIT #
|
||||
SDLC /LOOK FOR BLOCK NO.
|
||||
CLA
|
||||
TAD XBUFF
|
||||
DCA OLDBUF
|
||||
RDF
|
||||
TAD C6201
|
||||
DCA OLDFLD
|
||||
JMS I CRDQUD /WAIT AT LEAST 6 LINES TO LOOK
|
||||
JMS I CRDQUD
|
||||
CM200, 7600 /COULD HAVE SAVED A LOC. HERE
|
||||
SRCH, SDSS
|
||||
JMP .-1 /WAIT FOR SINGLE LINE FLAG
|
||||
SDRC
|
||||
CLL RTL /DIRECTION TO LINK. INFO BITS
|
||||
/ARE SHIFTED.
|
||||
AND C374 /ISOLATE MARK TRACK BITS
|
||||
TAD M110 /IS IT END ZONE?
|
||||
SNA /THE LINK STAYS SAME THRU THIS
|
||||
JMP ENDZ
|
||||
TAD M20 /CHECK FOR BLOCK MARK
|
||||
SZA CLA
|
||||
JMP SRCH
|
||||
SDRD /GET THE BLOCK NUMBER
|
||||
SZL /IF WE ARE IN REVERSE, LOOK FOR 3
|
||||
/BLOCKS BEFORE TARGET BLOCK. THIS
|
||||
/ALLOWS TURNAROUND AND UP TO SPEED.
|
||||
TAD C3 /REVERSE
|
||||
CMA
|
||||
TAD BLOCK
|
||||
CMA /IS IT RIGHT BLOCK?
|
||||
SNA
|
||||
JMP FOUND /YES..HOORAY!
|
||||
M110, SZL SNA CLA /NO, BUT ARE WE HEADED FOR IT?
|
||||
/ABOVE SNA IS SUPERFLUOUS.
|
||||
JMP SRCH /YES
|
||||
SDRC /NO, TURN US AROUND.
|
||||
CLL RTL /DIRECTION TO LINK
|
||||
CLA /THIS CODE USED TO BE SHARED WITH ENDZ,
|
||||
JMP GO /BUT NOW ENDZ HANDLES END OF TAPE CASES ONLY.
|
||||
ENDZ, SDRC /WE ARE IN THE END ZONE
|
||||
CLL RTL /DIRECTION TO LINK
|
||||
SZL CLA /ARE WE IN REVERSE?
|
||||
JMP GO /YES..TURN US AROUND
|
||||
TAD BLOCK /IF WE ARE ON BLOCK ZERO, IT IS POSSIBLE FOR US TO BE AT THE
|
||||
/REVERSE ENDZONE GOING FORWARD, EITHER DUE TO A RETRY OR BECAUSE
|
||||
/THE TAPE WAS STARTED IN A POSITION BEFORE THE END ZONE.
|
||||
/THESE CASES SHOULD NOT BE TREATED AS END-OF-TAPE.
|
||||
SZA CLA
|
||||
JMP ENDEX /END OF TAPE. STOP THE UNIT AND TAKE THE END EXIT.
|
||||
JMP GO
|
||||
|
||||
TRY3, CLA
|
||||
OLDFLD, NOP
|
||||
TAD OLDBUF
|
||||
DCA XBUFF
|
||||
ISZ TRYCNT
|
||||
JMP GO /TRY 3 TIMES
|
||||
JMP FATAL /LINK OFF MEANS AC=4000 ON RETURN
|
||||
EXIT, ISZ DTA0 /TAKE THE NORMAL RETURN
|
||||
CLL CML /AC=0 ON NORMAL RETURN
|
||||
FATAL, ISZ DTA0 /TAKE THE ERROR RETURN
|
||||
ENDEX, TAD UNIT
|
||||
SDLC /STOP THE UNIT
|
||||
CLA CML RAR
|
||||
LEAVE, HLT
|
||||
JMP I DTA0
|
||||
|
||||
|
||||
C6203, 6203
|
||||
C6201, 6201
|
||||
CRDQUD, RDQUAD
|
||||
CXFUN, XFUNCT
|
||||
C100, 100
|
||||
C1000, 1000
|
||||
|
||||
|
||||
/ NOTE THAT THE ABOVE CODE SEGMENT COMES VERY CLOSE TO TOUCHING
|
||||
/ THIS ONE, AND THIS ONE MUST RESIDE AT THE END OF THIS PAGE.
|
||||
/ BE CAREFUL ADDING NEW CODE TO THE ABOVE PAGE.
|
||||
*ORIGIN+172
|
||||
FOUND, SZL CLA /RIGHT BLOCK. HOW ABOUT DIRECTION?
|
||||
JMP GO /WRONG..TURN AROUND
|
||||
TAD UNIT /PUT UNIT INTO LINK
|
||||
CLL RAL /AC IS NOW 0
|
||||
C70, 70 /********DON'T MOVE THIS!!!!******
|
||||
C3, 3
|
||||
/INTO NEXT PAGE
|
||||
*ORIGIN+200
|
||||
CIF MFIELD
|
||||
RAR /NOW GET UNIT #
|
||||
DCA XUNIT
|
||||
SDRC
|
||||
SDLC
|
||||
REVGRD, SDSS
|
||||
JMP .-1 /LOOK FOR REVERSE GUARD
|
||||
SDRC
|
||||
AND K77
|
||||
TAD CM32 /IS IT REVERSE GUARD?
|
||||
SZA CLA
|
||||
JMP REVGRD /NO.KEEP LOOKING
|
||||
TAD XWCT
|
||||
DCA WORDS /WORD COUNTER
|
||||
TAD XFUNCT /GET FUNCTION READ OR WRITE
|
||||
K7700, SMA CLA
|
||||
JMP READ /NEG. IS WRITE
|
||||
WRITE, HLT /WRITE CODE REMOVED
|
||||
K77, 77 /ABOVE MAY SKIP (NOT ANYMORE DJG)
|
||||
READ, JMS RDQUAD
|
||||
JMS RDQUAD
|
||||
JMS RDQUAD /SKIP CONTROL WORDS
|
||||
AND K77
|
||||
TAD K7700 /TACK 7700 ONTO CHECKSUM.
|
||||
DCA CHKSUM /CHECKSUM ONLY LOW 6 BITS ANYWAY
|
||||
RDLP, JMS RDQUAD
|
||||
JMS EQUFUN /COMPUT CHECKSUM AS WE GO
|
||||
DCA I XBUFF /IT GETS CONDENSED LATER
|
||||
ISZ XBUFF /AT END OF FIELD?
|
||||
JMP STFLD2+1 /NOT AT END OF FIELD (DJG)
|
||||
RDF
|
||||
TAD (6211
|
||||
DCA STFLD2
|
||||
STFLD2, NOP
|
||||
ISZ WORDS /DONE THIS OP?
|
||||
JMP RDLP /NO SUCH LUCK
|
||||
TAD XFUNCT /IF OP WAS FOR WDSBLK-1, READ AND
|
||||
CLL RTR /CHECKSUM THE LAST TAPE WORD
|
||||
SNL CLA
|
||||
JMP RDLP2
|
||||
JMS RDQUAD /NOT NEEDED FOR WDSBLK/BLOCK
|
||||
JMS EQUFUN /CHECKSUM IT
|
||||
RDLP2, JMS RDQUAD /READ CHECKSUM
|
||||
AND K7700
|
||||
JMS EQUFUN
|
||||
JMS GETCHK /GET SIX BIT CHECKSUM
|
||||
JMP I CRWCOM
|
||||
C300, 300 /PROTECTION (NOT ANYMORE DJG)
|
||||
|
||||
RDQUAD, 0 /READ A 12 BIT WORD
|
||||
SDSQ
|
||||
JMP .-1
|
||||
SDRD /READ DATA
|
||||
JMP I RDQUAD
|
||||
|
||||
XUNIT,
|
||||
EQUFUN, 0 /COMPUTE EQUIVALENCE CHECKSUM
|
||||
CMA
|
||||
DCA EQUTMP /ACTUALLY CHECKSUMS ON DECTAPE ARE
|
||||
TAD EQUTMP /EQUIVALENCE OF ALL WORDS IN A RECORD
|
||||
AND CHKSUM /SIX BITS AT A TIME. BUT SINCE EQUIVALENCE
|
||||
CIA /IS ASSOCIATIVE, WE CAN DO IT 12
|
||||
CLL RAL /BITS AT A TIME AND CONDENSE LATER.
|
||||
TAD EQUTMP /THIS ROUTINE USES THESE IDENTITIES:
|
||||
TAD CHKSUM /A+B=(A.XOR.B)+2*(A.AND.B)
|
||||
DCA CHKSUM /A.EQU.B=.NOT.(A.XOR.B)=A.XOR.(.NOT.B)
|
||||
TAD EQUTMP /A.EQU.B=(A+(.NOT.B))-2*(A.AND.(.NOT.B))
|
||||
CMA
|
||||
JMP I EQUFUN
|
||||
|
||||
GETCHK, 0 /FORM 6 BIT CHECKSUM
|
||||
CLA
|
||||
TAD CHKSUM
|
||||
CMA
|
||||
CLL RTL
|
||||
RTL
|
||||
RTL
|
||||
JMS EQUFUN
|
||||
CLA CLL CML /FORCES LINK ON AT RWCOM
|
||||
TAD CHKSUM
|
||||
AND K7700
|
||||
JMP I GETCHK
|
||||
|
||||
CFATAL, FATAL
|
||||
CRWCOM, RWCOM
|
||||
XFUNCT, 0
|
||||
CM32, -32
|
||||
C1400, 1400
|
||||
CHKSUM, 0
|
||||
WORDS, 0
|
||||
XWCT, 0
|
||||
EQUTMP, 0
|
||||
|
||||
*20
|
||||
RETRY, 7774 / RETRY UP TO 4 TIME
|
||||
NUMBLK, 3777 / MAX NUMBER OF BLOCKS TO ATTEMPT READING. BY DEFAULT THIS PROGRAM WILL READ UNTIL
|
||||
/ IT HITS THE END OF THE TAPE (FORWARD ENDZONE). IF YOU NEED TO LIMIT THE NUMBER OF BLOCKS
|
||||
/ READ, MODIFY THIS VALUE.
|
||||
MWORDS, -WDSBLK / WORDS PER BLOCK
|
||||
WCOUNT, 0
|
||||
BLKFLD, 36 / 30 129 WORD BLOCKS OF 12-BIT WORDS
|
||||
/ WRAPPING PAST END OF LAST FIELD DOESN'T WORK
|
||||
FIELDS, 0
|
||||
RDSIZE, 0 / NUMBER BLOCKS PER READ
|
||||
CBLOCK, 0 / CURRENT BLOCK TO XFER
|
||||
CLKSUM, 0
|
||||
DRVSEL, 0
|
||||
READST, 377
|
||||
LOC, 0
|
||||
LEN, 0
|
||||
BCNT, 0 / BLOCKS TO SEND TO PC
|
||||
TEMP, 0
|
||||
C17, 17
|
||||
C360, 360
|
||||
CHKSM, 0
|
||||
ERRCN2, 0
|
||||
OLDBUF, 0 / BELOW ARE USED BY DTA0 ROUTINE
|
||||
XBUFF, 0
|
||||
C374, 374
|
||||
BLOCK, 0
|
||||
UNIT, 0
|
||||
TRYCNT, -3
|
||||
PGCT, 0
|
||||
CXWCT, XWCT
|
||||
M20, -20
|
||||
|
||||
*140
|
||||
FINISH, HLT / Normal good halt
|
||||
JMP START
|
||||
|
||||
*200
|
||||
START, CDF 0
|
||||
CAF
|
||||
CLA CLL OSR / Get drive
|
||||
AND (1
|
||||
RTR
|
||||
DCA DRVSEL
|
||||
CLA CLL OSR / Get max field
|
||||
RTR
|
||||
RAR
|
||||
AND (7
|
||||
SNA
|
||||
HLT / Must have at least 1 field for buffer
|
||||
CIA
|
||||
DCA FIELDS
|
||||
DCA ERRCN2
|
||||
RDSZLP, TAD BLKFLD / Multiply by number of fields available
|
||||
ISZ FIELDS
|
||||
JMP RDSZLP
|
||||
DCA RDSIZE / NUMBER BLOCK PER READ
|
||||
DCA CBLOCK
|
||||
DCA CHKSM
|
||||
|
||||
DUMPLP, CLA
|
||||
TAD RDSIZE
|
||||
TAD CBLOCK
|
||||
CIA
|
||||
TAD NUMBLK / MORE BLOCKS LEFT THAN READSIZE?
|
||||
SMA / NO, READ NUMBER LEFT
|
||||
CLA / YES, ONLY READ RDSIZE
|
||||
TAD RDSIZE
|
||||
SNA / ANY MORE BLOCKS?
|
||||
JMP DONE / NO, DO FINISH STUFF
|
||||
DCA ARGSZ
|
||||
TAD CBLOCK
|
||||
DCA ARGBK
|
||||
TAD DRVSEL
|
||||
JMS DTA0
|
||||
0010 / READ STARTING IN FIELD 1
|
||||
ARGSZ, 0
|
||||
0
|
||||
ARGBK, 0
|
||||
JMP ENDRET / TAKEN WHEN END OF TAPE IS HIT
|
||||
JMP ERRRET / TAKEN WHEN AN ERROR IS ENCOUNTERED
|
||||
TAD (377 / All blocks good
|
||||
DCA READST
|
||||
/ Send data, each block starts with FF
|
||||
CLA CLL / then 2 12 bit words in 3 bytes
|
||||
DCA LOC / ERRRET DUPLICATES SOME OF THIS
|
||||
TAD ARGSZ
|
||||
CIA
|
||||
DCA BCNT / Setup loop counter with number blocks read
|
||||
CDF 10
|
||||
OUTBL1, JMS OUTBLK / Send a block
|
||||
ISZ CBLOCK
|
||||
ISZ BCNT / Send all read?
|
||||
JMP OUTBL1 / No
|
||||
CDF 0
|
||||
JMP DUMPLP / Go read next batch
|
||||
|
||||
|
||||
DONE, CLA / Send FE and -checksum of all words
|
||||
TAD (376
|
||||
JMS PUN
|
||||
CLA CLL
|
||||
TAD CHKSM / Send checksum in two bytes, low bits first
|
||||
CIA
|
||||
JMS PUN
|
||||
CLA CLL
|
||||
TAD CHKSM
|
||||
CIA
|
||||
RTR
|
||||
RTR
|
||||
RTR
|
||||
RTR
|
||||
AND C17
|
||||
JMS PUN
|
||||
CLA
|
||||
TAD DRVSEL
|
||||
JMS DTA0 / REWIND TAPE
|
||||
0010
|
||||
1
|
||||
0
|
||||
0
|
||||
NOP
|
||||
NOP
|
||||
TAD ERRCN2 / Leave AC with # of errors
|
||||
JMP FINISH
|
||||
|
||||
/SEND GOOD BLOCKS READ WITH GOOD BLOCK FLAG
|
||||
/THEN BAD WITH BAD BLOCK FLAG.
|
||||
ERRRET,
|
||||
/ HLT / ****** If we want to stop on error
|
||||
CDF 10
|
||||
CLA CLL
|
||||
DCA LOC
|
||||
TAD CBLOCK
|
||||
CIA
|
||||
TAD BLOCK /Get - number good blocks read
|
||||
CIA /Last was bad
|
||||
SNA
|
||||
JMP FSTBAD /First block is bad, no good to send
|
||||
DCA BCNT
|
||||
TAD (377
|
||||
DCA READST
|
||||
OUTBL2, JMS OUTBLK /Send good blocks
|
||||
ISZ CBLOCK
|
||||
ISZ BCNT
|
||||
JMP OUTBL2
|
||||
FSTBAD, TAD (375 /NOW SEND BAD BLOCK
|
||||
DCA READST
|
||||
JMS OUTBLK
|
||||
ISZ CBLOCK
|
||||
ISZ ERRCN2
|
||||
CDF 0
|
||||
JMP DUMPLP /And read from here on
|
||||
|
||||
PAGE
|
||||
ENDRET, /SEND LAST SET OF BLOCKS READ BEFORE END OF TAPE AND FINISH.
|
||||
CDF 10
|
||||
CLA CLL
|
||||
DCA LOC
|
||||
TAD CBLOCK
|
||||
CIA
|
||||
TAD BLOCK / GET NUMBER OF BLOCKS READ IN LAST BATCH
|
||||
CMA / +1 to -BCNT SO WE SEND ALL BLOCKS
|
||||
SNA
|
||||
JMP DONE / READ ZERO BLOCKS IN LAST BATCH, WE ARE DONE
|
||||
DCA BCNT
|
||||
TAD (377
|
||||
DCA READST
|
||||
OUTBL3, JMS OUTBLK / SEND ALL BLOCKS
|
||||
ISZ CBLOCK
|
||||
ISZ BCNT
|
||||
JMP OUTBL3
|
||||
CDF 0
|
||||
JMP DONE / NO MORE BLOCKS, DONE.
|
||||
|
||||
OUTBLK, 0 /Send a block of data out serial port
|
||||
CLA
|
||||
TAD WCOUNT
|
||||
DCA LEN
|
||||
TAD READST /Send good/bad flag
|
||||
JMS PUN
|
||||
OUT, CLA CLL
|
||||
TAD I LOC
|
||||
TAD CHKSM / Keep checksum of all words sent
|
||||
DCA CHKSM
|
||||
TAD I LOC / Send 2 words as 3 bytes
|
||||
JMS PUN
|
||||
CLA CLL
|
||||
TAD I LOC
|
||||
RTR / Shift top 4 bits to low 4
|
||||
RTR
|
||||
RTR
|
||||
RTR
|
||||
AND C17
|
||||
DCA TEMP
|
||||
ISZ LOC
|
||||
JMP STFLD3+1 /NOT AT END OF FIELD (DJG)
|
||||
RDF /At end, inc to next field
|
||||
TAD (6211 /BUILD CDF
|
||||
DCA STFLD3
|
||||
STFLD3, NOP
|
||||
ISZ LEN /END OF BUFFER?
|
||||
SKP /NO
|
||||
JMP ENDBK /YES
|
||||
TAD I LOC
|
||||
TAD CHKSM
|
||||
DCA CHKSM
|
||||
TAD I LOC
|
||||
RTL
|
||||
RTL
|
||||
AND C360
|
||||
TAD TEMP
|
||||
JMS PUN
|
||||
CLA CLL
|
||||
TAD I LOC
|
||||
RTR
|
||||
RTR
|
||||
JMS PUN
|
||||
ISZ LOC
|
||||
JMP STFLD4+1 /NOT AT END OF FIELD (DJG)
|
||||
RDF
|
||||
TAD (6211 /BUILD CDF
|
||||
DCA STFLD4
|
||||
STFLD4, NOP
|
||||
ISZ LEN
|
||||
JMP OUT
|
||||
JMP I OUTBLK
|
||||
ENDBK, TAD TEMP /SEND LAST PART OF WORD
|
||||
JMS PUN
|
||||
JMP I OUTBLK
|
||||
|
||||
PUN, 0 / Send byte out serial port
|
||||
/ PLS / Punch for testing with emulator
|
||||
TLS2 / Send out console
|
||||
CLA CLL
|
||||
TAD CBLOCK
|
||||
/ PSF
|
||||
TSF2 /Wait until character sent
|
||||
JMP .-1
|
||||
CLA
|
||||
JMP I PUN
|
||||
|
||||
$
|
||||
@@ -1,6 +1,6 @@
|
||||
/ TD8E 18-bit DECtape DUMP Program. Based on DUMPREST code from D. Gesswein
|
||||
/ (see ftp://ftp.pdp8online.com/software/dumprest).
|
||||
/ Modified for 18-bit PDP-7 550 DECtape imaging by J. Dersch
|
||||
/ Modified for 18-bit PDP-7 550 DECtape imaging and arbitrary-lengths by J. Dersch
|
||||
/
|
||||
/ This program will send a DECtape image out the console port.
|
||||
/ The format of the data sent is 0xff (0377) or 0xfd if read error
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/ TD8E 18-bit DECtape DUMP Program. Based on DUMPREST code from D. Gesswein
|
||||
/ (see ftp://ftp.pdp8online.com/software/dumprest).
|
||||
/ Modified for 18-bit DECtape w/standard checksum imaging by J. Dersch
|
||||
/ Modified for 18-bit DECtape w/standard checksum imaging and arbitrary-lengths
|
||||
/ by J. Dersch
|
||||
/
|
||||
/ This program will send a DECtape image out the console port.
|
||||
/ The format of the data sent is 0xff (0377) or 0xfd if read error
|
||||
|
||||
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26403.7
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DumpDT18", "DumpDT18\DumpDT18.csproj", "{88B646C3-54D8-4D63-BB8A-B391C996FE47}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DumpDectape", "DumpDT18\DumpDectape.csproj", "{88B646C3-54D8-4D63-BB8A-B391C996FE47}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Reference in New Issue
Block a user