Subject: PAL-8 cross assembler

From: [email-masked] (Douglas W. Jones)
Date: Thu, 23 Sep 1993 16:17:37 GMT

I have added (probably incorrect) support for the RELOC operation in my
PAL-8 cross assembler written in C.  Anyone interested in checking it out
and telling me where I went wrong is welcome to a copy (by E-mail).

Here's a little example assembly listing from my assembler showing the
extent to which RELOC works:

   1                    *7000                   /WHERE THIS LOADS
   2                    RELOC   200             /WHERE THIS THINKS IT IS
   3 07000 0000 CODE,   .-.
   4 07001 1377         TAD     (.)             /A LITERAL, THE CURRENT LOC
   5 07002 7041         CMA IAC
   6 07003 1376         TAD     (CODE)          /A LITERAL
   7 07004 5600         JMP I   CODE		/A REF ON CURRENT PAGE
   8 07376 0200         PAGE                    /FORCE OUT THE LITERALS
     07377 0201
   9                    RELOC                   /TURN OFF RELOCATION
  10 07200 7200         .                       /PROVE THINGS ARE BACK TO NORMAL
  11                    $

Note that the literal reference to . on line 4 is interpreted as a ref
to 0201 and not 7001, and note that it defines the label CODE as 0200
instead of 7000.  Even so, it knows (on line 7) that CODE is a current
page address.

I haven't tested nested RELOC operations (I think they'll work), and I
don't know whether or not to relocate origin settings!  That is, should

			*7000
			RELOC	200

work the same as

			RELOC	200
			*7000

or not?  It can be done either way!
						Doug Jones
						[email-masked]

---

From: [email-masked] (Charles Lasner)
Date: 23 Sep 1993 20:36:47 GMT

In article <[email-masked]>,
>   2                    RELOC   200             /WHERE THIS THINKS IT IS
This should read:
    3 000200* 0000 CODE,   .-.			/WHERE THIS THINKS IT IS

In other words, you need support for more address bits, since the DEC version
of memory goes up to 128K, and the CESI version goes further.  BTW, P?S/8
PAL goes up to 256K.  You get these extensions either by specifying a larger
field than 7, or by using the BANK pseudo-op which allows specifying memory
to the nearest 32K.

And the address displayed is the one where the RELOC took it, but a "*" is
displayed to indicate that the assembler "knows" that relocation is in effect.

BTW, P?S/8 PAL and PAL-8 differ on a minor detail here:  RELOC is *not* the
only way to make the current location counter for the program and generated
binary differ.  For example you could use a sequence such as:

	*7000
	NOPUNCH
	*200
	ENPUNCH

This would mean that auto-generated origins such as literal dump origins
would be incorrect, so that's why you can't use literals with that scheme, but
it's otherwise totally viable, and historically used a lot, etc.

But in any case, it does mean the assembler gets "fooled" the same way that
RELOC can accomplish it.

P?S/8 PAL merely compares whether the program counter and binary address
counter differ.  It so, the "*" is appended.  PAL-8 isn't as "smart" and
only outputs the "*" when a RELOC-in-progress flag is set.  As a consequence
of this, use of RELOC with no argument becomes mandatory for cosmetic
purposes, even though cumulative use of RELOC could make the relocation
go away.  Concisely, RELOC . which doesn't actually relocate anything would
show an asterisk on every line until RELOC with no arg might occur.  Also,
there are versions of PAL8 with a RELOC-related bug: if RELOC with no arg
isn't given at the end of assembly, the relocation becomes pass-wise
additive!  Later versions initialize each assembly pass to prevent this!

>   8 07376 0200         PAGE                    /FORCE OUT THE LITERALS

This isn't like either PAL-8 or P?S/8 PAL.  PAL-8 would output the origin
by itself that is apparent, meaning 0400 in this page (all the code above
should be 0200-0204, not 7000-7004).  P?S/8 PAL goes one step further:  all
origins have a "*" in front of the four-digit origin.  Moreover, both
assemblers output the dumped literals *FIRST* then the "PAGE" or whatever
statement that triggered the dump.  P?S/8 PAL goes one step even further:
in front of the literal dump is an origin for it, complete with an asterisk
on it since all P?S/8 PAL origins start with a preceding asterisk.  So, what's
wrong here is that the address field has to be blank, and the data field
needs to have the origin's value, and optionally an asterisk in front of it
to do it P?S/8 PAL-style.  And all of the dumped literals need to come out
first, not following.  (Failure to do this will screw up thousands of pages
of existing source code pagination!)  Opting for P?S/8 PAL compatibility means
to initiate the literal dump with an origin setting on it's own line, complete
with its own asterisk, before the literal dump.  Then the literal dump happens,
then the source code line that triggered the whole dump.  Also note that
any origin or loc cntr-changing pseudo-op initiates this, such as PAGE,
SEGMNT, FIELD or BANK.  (PAGE is next page with no arg, or an explicit page
number 0-37.  (.AND. the supplied arg with 37), SEGMNT is the same except
using 1K-sized objects.  FIELD means an entire memory field difference, and
BANK means 32K different.  There needs to be an assembler option switch as to
whether FIELD and BANK do/do not generate an automatic *0200 afterwards (and
in the P?S/8 PAL version you can actually see the *0200 because of consistency
with the above, while PAL-8 gives no clues on the listing, so you have to
know how it was assembled to really be sure!)  In the case of FIELD and BANK
there is an automatic dump of a possible current page situation, *then* there 
is a possible dump of the page zero literals.  And of course, the pseudo-op
source line comes after the dumping has finished, etc.  (And in the P?S/8 PAL
version, each dump starts with the visibility of the origin setting of the
dump.  Note also, that in both assemblers, the dumped origins are always
influenced by the relocation value!) P?S/8 has an extension over PAL-8
regarding FIELD: If it is desirable to relocate code into a different
loading field, PAL-8 is incapable of doing this while also maintaining
the page-zero literal table.  Some people have just given up and either
resorted to "faking" literals or just not using them at all, or to using
only current page literals inefficiently.  P?S/8 PAL has a mechanism to avoid
this which is to add 4000 to the FIELD argument means to inhibit the page
zero literal dump aspect of what FIELD does.  Thus, you can change loading
fields, then restore the original field, then dump all page-zero literals
at that time:

	FIELD	0		/WHERE WE NORMALLY LOAD

	.			/SOME CODE

	PAGE			/GET TO A NEW PAGE

	FIELD	4001		/PRESERVE TABLE

	*7000			/LOAD IT THERE IN FIELD 1

	RELOC	200		/BUT IT'LL EXECUTE THERE IN FIELD 0

	.			/SOME CODE

	FIELD	4000		/GET BACK TO FIELD 0; TABLE STILL PRESERVED

The code continues normally, and eventually the page zero literal table
gets dumped normally.  Definitions apply to both the code actually loaded
into field 0, and also to the relocated code that actually loaded somewhere
in field 1.  Using techniques like this, overlays can be defined that fully
take advantage of the normal assembler literal usage, etc.  (Note: RELOC was
invented by Joseph R. Fischetti of the WCFMPG expressly to allow literals
to be used in relocated code.  I implemented it first in P?S/8 PAL and then
it was added to PAL-8 to mimic my implementation, albeit with the cosmetic
differences described above, etc.  The extension to FIELD was discussed as
a possible extension to MACREL, but was never implemented as a PAL-8 option.)

And of course the address is wrong here, because it should be 7377 internally
for the binary, but the assembler current location counter should be 0377
at that point due to the relocation.  Relocated code never shows the 
unrelocated addresses, just the desired (future execution) address.  And of
course each address, since it's subject to relocation, would have an asterisk
after it (in either assembler).

>   9                    RELOC                   /TURN OFF RELOCATION

Yes, this "officially" turns off relocation.  But in P?S/8 PAL, it is
sufficient just to have the relocation mathematically add to 0000.  When
a RELOC statement is given, a relocation value is created that is the
difference between where the current location counter was, and where it
now becomes.  This internal factor is added to all binary output origins at
all times, although the cosmetic assembler output uses the current location
counter so the output appears to be where the programmer intends.  Thus, 
merely using RELOC . in PAL-8 sets a flag that relocation is in effect, and
all cosmetic printouts that are affected get an asterisk until RELOC without
argument is given.  But in P?S/8 PAL, the relocation factor *is* the flag
as to whether to output the asterisk, and also, there are more places in
the output where origins are given, and thus it applies to all of them.  And
since P?S PAL would realize the relocation is null since the relocation value
became 0000, the asterisks would be supressed in that case.

Also notice that the definition of RELOC's relocation factor is cumulative
so that relocated code can in fact contain code to be further relocated!  This
actually happens in some programs!  Thus, the value of relocation is *added*
to the current relocation factor, not set to it.  (This is why code could
use multiple RELOC statements to get back to a state of non-relocation without
an express RELOC <no arg>, etc.)

>instead of 7000.  Even so, it knows (on line 7) that CODE is a current

Again, the key to the whole thing is that RELOC creates a factor looked at
only by the "back end" binary generation aspect of the assembler, and at
the source level appears to be an ordinary origin setting.

>or not?  It can be done either way!

Obviously, it does matter!  Your first form is clear what to do: the code
loads into 7000 in the current field, but it assembles as if in 0200 of
the current field.  The second example is indeterminate because it needs
to state where it was loading into *before* the statements given!  Assuming
that it was on say, 1000 at the time, then it would load the binary into
1000, but make it appear to be on 0200.  But then the *7000 comes along and
makes the assembler's origin advance by 6600 more than the apparent 0200, 
thus the actual loading address for the binary to follow would be 7600!

	*1000			/WHERE WE NOW ARE
	RELOC	200		/WHERE WE WANT IT TO APPEAR
	*7000			/WHERE WE WANT IT TO APPEAR

The concise interaction of all of these assembler directives, etc. is why
we have most of the important PDP-8 software.  Without it, creating the
software would have been lots harder!

>						[email-masked]

cjl

---

From: jones@pyrite (Douglas W. Jones,201H MLH,3193350740,3193382879)
Date: Fri, 24 Sep 1993 03:32:51 GMT

Thanks for the extensive comments!  As I've said before, my PAL compatable
cross assembler makes an attempt at a legible listing format, but the
emphasis of the project is on getting the right BIN and RIM output!
If the source code produces the right object code, I'm content to stop
there and leave cosmetic listing issues to others.  The purpose of the
thing is to aid in bootstrapping when all you've got is a bare machine
with device 03/04 support.

I haven't put any effort into supporting large model addressing, so it
supports fields 0 to 7, and no more.  That's enough to get quite far.

The clarification on the origin settings is useful!  The net result is that
*.+1 will work with RELOC in effect, but RELOC and * are not "commutative"
in the sense that their order matters.
					Doug Jones
					[email-masked]

---

From: [email-masked] (Charles Lasner)
Date: 24 Sep 1993 04:13:41 GMT

In article <[email-masked]>,

>supports fields 0 to 7, and no more.  That's enough to get quite far.

Please don't stop without it being language compatible down to the nitty
gritties.  And more importantly, we need a good cross-reference facility.
PAL8 is lame in this area, and also limited.  There are sources too big
to get a cref on!

cjl

---

From: [email-masked] (Charles Lasner)
Date: 24 Sep 1993 17:57:21 GMT

>and telling me where I went wrong is welcome to a copy (by E-mail).

What follows are OS/8 PAL8 and P?S/8 PAL listings of Doug's example:

/       ASSEMBLER TESTS                   PAL8-VB0  24-SEP-93 PAGE 1

              /       ASSEMBLER TESTS

        7000          *7000                   /WHERE THIS LOADS

        0200          RELOC   200             /WHERE THIS THINKS IT IS

000200* 0000  CODE,   .-.
000201* 1377          TAD     (.)             /A LITERAL, THE CURRENT LOC
000202* 7041          CMA IAC
000203* 1376          TAD     (CODE)          /A LITERAL
000204* 5600          JMP I   CODE            /A REF ON CURRENT PAGE

000376* 0200
000377* 0201
        0400          PAGE                    /FORCE OUT THEE LITERALS

        7200          RELOC                   /TURN OFF RELOCATION

007200  7200          .                       /PROVE THINGS ARE BACK TO NORMAL

                      $

/       ASSEMBLER TESTS                   PAL8-VB0  24-SEP-93 PAGE 2

CODE   0200      


ERRORS DETECTED: 0
LINKS GENERATED: 0

This shows where all the relocated origin stuff has had its effect, etc.  The
P?S/8 version follows:

/     ASSEMBLER TESTS         P?S PAL V08S    FRI  24-SEP-93  PAGE 1

              /       ASSEMBLER TESTS

       *7000          *7000                   /WHERE THIS LOADS

       *0200          RELOC   200             /WHERE THIS THINKS IT IS

000200* 0000  CODE,   .-.
000201* 1377          TAD     (.)             /A LITERAL, THE CURRENT LOC
000202* 7041          CMA IAC
000203* 1376          TAD     (CODE)          /A LITERAL
000204* 5600          JMP I   CODE            /A REF ON CURRENT PAGE

       *0376 
000376* 0200 
000377* 0201 
       *0400          PAGE                    /FORCE OUT THEE LITERALS

       *7200          RELOC                   /TURN OFF RELOCATION

007200  7200          .                       /PROVE THINGS ARE BACK TO NORMAL

                      $


/     ASSEMBLER TESTS         P?S PAL V08S    FRI  24-SEP-93  PAGE S-1
USER SYMBOL TABLE LISTING

CODE   0200 


/     ASSEMBLER TESTS         P?S PAL V08S    FRI  24-SEP-93  PAGE S-2
ASSEMBLY STATISTICS

NO ERRORS DETECTED 

NO LINKS GENERATED

5K MEMORY UTILIZED 

NO FILES CREATED

1 SYMBOL 

The P?S/8 origin outputs clearly show what's happening internally, and the
relocation asterisks make it clear what's relocated, etc.

Hope that helps a little

cjl