Subject: Re: Continuing saga of the emulated RX01

From: Charles Lasner <[email-masked]>
Date: Thu, 3 Nov 1994 18:31:10 -0500 (EST)

On Wed, 2 Nov 1994, Douglas W. Jones wrote:

> 
> Well, the fix to make my emulator correctly handle the 100 function
> code wasn't enough to get me something really nice, but it's clear
> that quite a bit is working:
> 
> The RX01 bootstrap pulls in a general purpose RX01 read/write routine
> into 7600 through 7777; I'll call it RXIO.  This begins at 7607, and is
> prefixed by a tiny bit of bootstrap code:
> 
> * 7600
> 	JMS	RXIO
> 	5000		/ argument 1 (write 8 blocks field 0)
> 	0000		/ argument 2 (buffer)
> 	0033		/ argument 3 (block)
> 	CLA HLT		/ error return
> 	CDI 0010	/ normal return, setup for JMP
> 	JMP	MORE	/ go to next part of boot

This is the standard OS/8 core-save opening.  You circumvent it by 
starting at 07605.  If you start at 07600, 8 *PAGES* of memory are saved 
in field 0 starting from address 0000.  The data is written to logical 
record 0033.

Please avoid the use of the nebulous term "block" since it means 
different things to different people!  A DECtape block is (almost!) half 
of an OS/8 record.  Two such blocks are an OS/8 record, etc.  (Note: the 
almost is because DECtape blocks are actually 129 words, and most code 
goes out of its way to ignore the 129th word, thus a logical DECtape 
block is 128 words while a physical DECtape block is 129 words.  In any 
case, a logical OS/8 record is two logical DECtape blocks!)

> 
> The first sector that the boot pulled in from disk included this bit
> of code that landed in field 1:
> 
> 	FIELD 1
> * 7667
> 	CIF 0000	/ setup for JMS
> 	JMS	RXIO
> 	1000		/ argument 1 (read 8 blocks field 0)
> 	0000		/ argument 2 (buffer)
> 	0007		/ argument 3 (block)
> 	CLA SMA SZA OSR HLT / error return (a kitchen sink constant?)
> 	CDI 0000	/ setup for jump!
> 	JMP I	.+1	/ go to loaded code?
> 	0400		/ points to start of loaded code?

All of this code is a skeleton to be filled in as necessary when an 
executable program is started.  This allows the last swap-in over the 
previously in-control code that did any other loading just before this 
last load.  Generally, this will be a field-zero load of the contents of 
some of the swap records (oops!, I almost said swap blocks :-).)

> 
> My best effort at hand disassembly and decyphering of the RXIO routine
> indicates that the parameters are as follows:
> 
> 	argument 1:  d sssss fff ???
> 		d = direction of transfer (0=read, 1=write)
> 		s = number of consecutive OS/8 disk blocks to transfer
> 		f = field containing the buffer
> 		? = unknown use, if any

Almost.  The sssss are the number of pages involved in the transfer and 
can be odd, even 1 page long!  00000 means to transfer 0040 pages.  Note 
that if you write an odd page count, you are forever giving up the second 
half of the last record's former contents.  However, you are guaranteed 
that *something* can later be read there!  (without error!)

For example, if you are using the RK8E, write one page will zero the 
second half of the record.  Read one page reads and DMA's the first page, 
but makes you wait while the second half is checked for CRC, etc.  But 
the contents of memory is undisturbed past the first half.  Later, the 
just-half-written record can be completely or half-wise read in without 
error.  If read in, the second half will now contain all zeroes.

In the case of the RX01 handler, the second half will actually be 
unaffected!  This is because the logical record is 4 physical sectors.  
Thus, the handler only works on pairs of sectors, not quads.  If the page 
count is odd, the transfer ends on a pair leaving another pair unscathed, 
etc.  But this behaviour is a quirk, not a guarantee!  Additionally, 
there are other RX handlers where this is (rightfully so!) not true, etc.

The ??? bits are almost ignored.  The lowest bit is set in a small 
handful of places throughout OS/8.  All such cases have only one purpose: 
to "help" DECtape (and LINCtape!) based systems to start a tape search in 
the forward direction instead of the normal reverse search.  Note that in 
all DEC-written handlers, this is quite lame, as it fails to find actual 
cases where dynamically it could be determined that the search direction 
*should* have been forward initially!  (But cannot be determined 
statically as in these few implemented cases, etc.)

I have written an actual DECtape handler for TC01/08 that does the 
guesswork itself and ignores the bit.

In any case, there are no other functions for these bits in 
*FILE-STRUCTURED DEVICE* handlers.  There are several non-file-structured 
handlers that actually use these bits for device extensions.  All known 
ones are for devices akin to magtapes handled as non-file devices.  The 
functions are called by the MCPIP program, etc.

> 
> 	argument 2:
> 		starting address of buffer in indicated field
> 
> 	argument 3:
> 		OS/8 disk block number of first block to transfer

Call it logical record, but otherwise fine :-).

> 
> Furthermore, this nice little routine is only good for reading or writing
> unit zero and has no provisions for working with another unit.

It's a system handler.  You are slightly incorrect.  In the RX case, the 
boot dynamics can determine that the boot drive is drive 1.  In that 
case, it becomes a drive one only routine and cannot work with unit 0, 
etc.  In any case, yes, it's a one-drive handler.

P?S/8 handlers include a logical unit extension that supports (using the 
same relative bits as unused above!) drives 0-7.  The boot drive could be 
any one of those 8 drives and is determined at boot time on the devices 
that support boot to logical drives other than 0, etc.

But OS/8 needs one handler per drive!  However, some handlers use a trick 
of a "co-resident" handler where there are multiple entry points, each 
handling a different drive.

The longest handler ever written was done by myself and Ricky Schreiber.  
This handler supports 16 entry points!  8 of the entry points are for 
DTA0: through DTA7: on a TC01/08.  Additionally, the same piece of code 
supports DECtape being used as a non-file-structured device on multiple 
reels of tape that get auto-unloaded when full.  You mount an additional 
tape if the handler requires it, etc.  Thus, a system can have both 
file-structured and non-file structured use of TC01/08 at the same time, 
etc.  The file-structured entry points support auto-search-direction 
guessing and ignore the lame attempts by OS/8 proper to "suggest" a 
direction hardly ever (except in a handful of places).  Thus, the handler 
performs a whole lot better than the standard DEC one, which handles the 
drives 0-7 file-structured only and only searches forward when told to in 
function[11], etc.  (Note: non-file structured handles always search 
backwards because you are obliged to read/write the next sequential block 
next time, etc.)  (Or sequential record if you want to talk OS/8 records, 
but this was a physical description, not a logical one! :-))

> 
> So, OS/8 experts out there, is this a reasonable thing to have gotten
> from a bootable OS/8 diskette?  Unfortunately, whatever the darned thing
> reads into memory isn't very interesting -- it goes off the deep end, but
> it takes a long time to do so.  It's hard to imagine that my emulator is
> at fault at this point in time.  Too much sensible stuff seems to be
> accomplished before it goes belly up.  Unfortunately, it does go belly
> up.

So far, this is a proper system.

> 
> So, I'm still in the market for a known good bootable RX01 diskette image.
> CJL!  You did promise me some of those in exchange for the PDP-8/A I
> mailed you some years ago.

Sounds like you still have stuff to fix!  Getting yet another system 
probably won't help, etc.

> 				Doug Jones
> 				[email-masked]

cjl