PAL-D Assembler Character String Processing

117 views
Skip to first unread message

David Meyer

unread,
Apr 7, 2021, 11:37:57 PMApr 7
to
I'm teaching myself assembler programming while exploring TSS/8 following the EDUsystem-50 Users Guide on BitSavers.org.

Working my way up to "Hello, World!", I've learned from an example in the Users Guide how to plug successive character codes into the accumulator and print them out with TLS/TSF.

For my next step, I've found the TEXT pseudo-op that packs a string into memory two characters per word, and the SAS instruction that outputs a string of characters from memory stored one per word.

Does PAL-D have facilities for doing any of the following:

- Convert TEXT-packed 2-char-per-word data into 1-char-per-word format for printing with SAS
- Unpack TEXT data for 1-char-at-a-time printing with TLS/TSF
- Load character string data into memory in the format expected by SAS

Thanks.

steve...@gmail.com

unread,
Apr 9, 2021, 10:38:13 AMApr 9
to
I'm not that familiar with PAL-D in particular so I can't answer your question directly. Having done PAL-III for years and having used the TEXT pseudo-op many times, PAL-III does not have a built-in utility for outputting (that I am aware of). On the other hand, converting from packed back to ASCII for print out is not at all difficult. I can share examples if you don't want to figure it out on your own.


Cheers,

-- steve

David Meyer

unread,
Apr 12, 2021, 6:37:37 AMApr 12
to
> converting from packed back to ASCII for print out is not at all difficult. I can share examples if you don't want to figure it out on your own.

Maybe not difficult for you, but I am starting out with near-zero knowledge of assembler. I have been trying to figure it out, but an example would be very helpful.

K. Krause

unread,
Apr 12, 2021, 11:00:02 AMApr 12
to
I'm not sure if we are speaking about the same thing. But the version of
PAL-D which I have documentation for is a very primitve extension of the
paper-tape PAL-III for use with the archaic disk-monitor, the forerunner
of PS/8 odr OS/8.
PDP-8s definitively have no instructions for working with strings
or to pack or unpack 6-bit ASCII or to print them out. Maybe your
ominous SAS-instruction is a JMS instruction to a special subroutine
provided by TSS/8 or EDU-50?
PAL-Assemblers allow to define or redefine OPCodes, which was used
for the floating-point packages: There were FMLT, FDIV, FADD or FSUB-
instructions which lastly were JMS-OPs into the respective routines.

Could you send a piece of your code, naturally a listing, not the
sourcecode here, so I can see, what PAL-D produces?


Klemens

Vincent Slyngstad

unread,
Apr 13, 2021, 3:17:20 AMApr 13
to
You might find some of the existing DECUS programs and the handbook
"Introduction to Programming" useful. A version of the character
packing and unpacking you mentioned is implemented in
decus-5-51/decus-8-51, for example:
https://so-much-stuff.com/pdp8/software/decus.php
http://svn.so-much-stuff.com/svn/trunk/pdp8/src/decus/5,8-51

Outputting packed text turns out to be something that almost any of the
non-trivial programs need to do -- storing unpacked text will burn
through a 4K memory field pretty quickly!

Vince

David Meyer

unread,
Apr 13, 2021, 9:00:18 AMApr 13
to
Thanks for the pointers.

I think I have figured out how to unpack and print characters packed with the TEXT pseudo-op:

/JOANNES I:I - IN PRINCIPIO ERAT VERBUM
/VERB4 - PRINT FROM PACKED STRING
0200 7200 CLA
0201 1377 TAD (-14) /PACKED STR. WORD COUNT * -1
0202 3223 DCA COUNT
0203 1376 TAD (PKSTR) /ADDR. OF PACKED STR.
0204 3224 DCA PTR
0205 7200 LOOP, CLA
0206 1624 TAD I PTR /CURR. PACKED STR. WORD
0207 4242 JMS GETCH1
0210 4271 JMS CVT6B
0211 4305 JMS PRCHR
0212 1624 TAD I PTR /RELOAD CURR. PACKED STR. WORD
0213 4245 JMS GETCH2
0214 4271 JMS CVT6B
0215 4305 JMS PRCHR
0216 2224 ISZ PTR /INCR. PACKED STR. WORD PTR.
0217 2223 ISZ COUNT /INCR. WORD COUNT - LOOP UNTIL 0
0220 5205 JMP LOOP
0221 4277 JMS PRCRLF
0222 7402 HLT
0223 0000 COUNT, 0 /PACKED STR. REMAINING WORD COUNT
0224 0000 PTR, 0 /CURR. PACKED STR. WORD PTR.
0225 1116 PKSTR, TEXT 'IN
0226 4020 P
0227 2211 RI
0230 1603 NC
0231 1120 IP
0232 1117 IO
0233 4005 E
0234 2201 RA
0235 2440 T
0236 2605 VE
0237 2202 RB
0240 2515 UM
0241 0000 '
/PACKED STR.
0242 0000 GETCH1, 0 /EXTRACT 1ST CHAR. FROM PACKED WORD
0243 4251 JMS SHFT6R
0244 5642 JMP I GETCH1
0245 0000 GETCH2, 0 /EXTRACT 2ND CHAR. FROM PACKED WORD
0246 4261 JMS ROT6L
0247 4251 JMS SHFT6R
0250 5645 JMP I GETCH2
0251 0000 SHFT6R, 0 /SHIFT AC VALUE 6 BITS TO RIGHT
0252 7110 RAR CLL;
0253 7110 RAR CLL;
0254 7110 RAR CLL;
0255 7110 RAR CLL;
0256 7110 RAR CLL;
0257 7110 RAR CLL
0260 5651 JMP I SHFT6R
0261 0000 ROT6L, 0 /ROTATE AC VALUE 6 BITS TO LEFT
0262 7004 RAL;
0263 7004 RAL;






0264 7004 RAL;
0265 7004 RAL;
0266 7004 RAL;
0267 7004 RAL
0270 5661 JMP I ROT6L
0271 0000 CVT6B, 0 /CONVERT 6-BIT CHAR. CODE TO 8-BIT
0272 1375 TAD (7740) /8-COMPLEMENT OF 40 (SUBTRACT 40)
0273 7510 SPA
0274 1374 TAD (100)
0275 1373 TAD (240)
0276 5671 JMP I CVT6B
0277 0000 PRCRLF, 0 /PRINT CR-LF
0300 1372 TAD (215) /CR
0301 4305 JMS PRCHR
0302 1371 TAD (212) /LF
0303 4305 JMS PRCHR
0304 5677 JMP I PRCRLF
0305 0000 PRCHR, 0 /PRINT CHAR. CODE IN AC
0306 6046 TLS
0307 7200 CLA
0310 5705 JMP I PRCHR
0371 0212
0372 0215
0373 0240
0374 0100
0375 7740
0376 0225
0377 7764

David Meyer

unread,
Apr 13, 2021, 9:24:18 AMApr 13
to
I also figured out how to print an array of characters from memory with the SAS operator. Character literals make it a little easier to input strings in the source:

/JOANNES I:I - IN PRINCIPIO ERAT VERBUM
/VERB3 - PRINT FROM MEMORY WITH SAS
0200 7200 CLA
0201 1377 TAD (COUNT)
0202 6040 SAS
0203 5201 JMP .-2
0204 7402 HLT
0205 7746 COUNT, -32 /CHAR. COUNT * -1
0206 0206 PTR, . /ADDR. OF STR. - 1
0207 0311 STRING, "I;
0210 0316 "N;
0211 0240 " ;
0212 0320 "P;
0213 0322 "R;
0214 0311 "I;
0215 0316 "N;
0216 0303 "C;
0217 0311 "I;
0220 0320 "P;
0221 0311 "I;
0222 0317 "O
0223 0240 " ;
0224 0305 "E;
0225 0322 "R;
0226 0301 "A;
0227 0324 "T;
0230 0240 " ;
0231 0326 "V;
0232 0305 "E;
0233 0322 "R;
0234 0302 "B;
0235 0325 "U;
0236 0315 "M
0237 0215 215;
0240 0212 212
0377 0205

K. Krause

unread,
Apr 13, 2021, 10:40:02 AMApr 13
to
A funny construction. What in the listing is called SAS is
"illegal". It is the instruction TFL, "set Teleprinter Flag".
Which just does that what it is called: Set the Teleprinter Flag.
There are two possibilities: If the interrupt system is set up
accordingly, this will cause an interrupt, which eventually could
do the printout via TLS.
The other possibility is the User Flag. Since EDU-50 and TSS-8 is
a multiuser system, it runs probably with this flag set.
The UM flag enabled traps all instructions OSR, HLT, LAS and IOT
to which SAS odr TSF belongs, to prevent that a user gains full
control over the machine. So he cannot HLT it or have access to
memoryfields which are not allowed. These operations are privileged
to the operating system.

In this case SAS is like a systemtrap or system call, which is handled
by the runtime system of EDU-50 or TSS-8.
Parameters for this sys-call is the address of COUNT which has to be
loaded in AC. The second parameter is the word behind COUNT, the pointer
to the string itself.
Subroutines on PDP-8s and similar machines without stackpointer are
often programmed in a way that they have two or more exit points.
The first is the address directly behind the JMS or in this case the
SAS instruction, which jumps back to 0201, the other exit is the
next address, in this example the HLT at 204.
Note, that this SYS-call probably changes both, the COUNT and PTR as
well, so that this program probably will work only one time after
loading, if you don't reinialize them both.


Klemens

On 13.04.21 15:24, David Meyer wrote:
> I also figured out how to print an array of characters from memory with the SAS operator. Character literals make it a little easier to input strings in the source:
>
> /JOANNES I:I - IN PRINCIPIO ERAT VERBUM
> /VERB3 - PRINT FROM MEMORY WITH SAS
> 0200 7200 CLA
> 0201 1377 TAD (COUNT)
> 0202 6040 SAS
> 0203 5201 JMP .-2
> 0204 7402 HLT
> 0205 7746 COUNT, -32 /CHAR. COUNT * -1
> 0206 0206 PTR, . /ADDR. OF STR. - 1
> 0207 0311 STRING, "I;
> 0210 0316 "N;
> 0211 0240 " ;
> 0212 0320 "P;
> 0213 0322 "R;
> 0214 0311 "I;
> 0215 0316 "N;
....


Vincent Slyngstad

unread,
Apr 13, 2021, 6:36:28 PMApr 13
to
On 4/13/2021 6:00 AM, David Meyer wrote:
> Thanks for the pointers.
>
> I think I have figured out how to unpack and print characters packed with the TEXT pseudo-op:

Your code looks like it works! I added
TSF
JMP .-1
to PRCHR in my copy so that will also run "bare metal" in SIMH, without
the whole TSS O/S for support.

Fiddled with your code a bit, for about a 10% code size reduction and
modest speed-up. (Part of the fun of the PDP-8 is seeing how small you
can make a given feature and still have it work.) There are still some
routines that could be in-lined, etc. to probably save a few more words.

Vince

David Meyer

unread,
Apr 13, 2021, 7:35:45 PMApr 13
to
On Wednesday, April 14, 2021 at 7:36:28 AM UTC+9, Vincent Slyngstad wrote:
> Your code looks like it works! I added
> TSF
> JMP .-1
> to PRCHR in my copy so that will also run "bare metal" in SIMH, without
> the whole TSS O/S for support.

Thank you.

The EDUsystem-50 Users Guide did note that the TSF; JMP .-1 sequence could only be omitted when running on the EDUsystem-50 version of Monitor.

> Fiddled with your code a bit, for about a 10% code size reduction and
> modest speed-up. (Part of the fun of the PDP-8 is seeing how small you
> can make a given feature and still have it work.) There are still some
> routines that could be in-lined, etc. to probably save a few more words.

It's a fascinating system.

steve...@gmail.com

unread,
Apr 23, 2021, 3:38:38 PMApr 23
to
Hi Vince,
Sorry for the delayed reply, I thought I had set up email notification when messages came to this board but it's not working. If you've already got the problem solved, great.

I tried to attach some sample code that solves the problem but apparently this group doesn't allow attachments. You can find the file "lf2cr.ls.txt" on DropBox at this URL:

https://www.dropbox.com/sh/p8n7kund4utqy4q/AAB4-6cLuPOyKk-M685w24dna?dl=0

This is a PAL-8 program I wrote to change *nix <LF> as end-of-line to OS/8 <CR><LF>. It uses the 6-bit packed ASCII "TEXT" directive. All of the TEXT strings to be printed start on page 8-2 of the listing. Subroutine "PRTLNX" on listing page 7 (memory address 01200) peels off the 6-bit packed ASCII bytes. Subroutine "MKCHAR" on the same listing page (memory address 01227) converts the 6-bit packed ASCII characters into their full 8-bit equivalent.

Even if you've already solved the 6-bit packed to 8-bit ASCII problem already, feel free to use this code as a non-trivial example of PAL-8 code. It is OS/8-specific, however. Disk file I/O is probably different in TSS/8. Some other PAL-8 code is also available at that same DropBox link.


Cheers,

-- steve

Vincent Slyngstad

unread,
Apr 23, 2021, 7:23:54 PMApr 23
to
On 4/23/2021 12:38 PM, steve...@gmail.com wrote:
> https://www.dropbox.com/sh/p8n7kund4utqy4q/AAB4-6cLuPOyKk-M685w24dna?dl=0
>
> This is a PAL-8 program I wrote to change *nix <LF> as end-of-line to OS/8 <CR><LF>. It uses the 6-bit packed ASCII "TEXT" directive. All of the TEXT strings to be printed start on page 8-2 of the listing. Subroutine "PRTLNX" on listing page 7 (memory address 01200) peels off the 6-bit packed ASCII bytes. Subroutine "MKCHAR" on the same listing page (memory address 01227) converts the 6-bit packed ASCII characters into their full 8-bit equivalent.
>
> Even if you've already solved the 6-bit packed to 8-bit ASCII problem already, feel free to use this code as a non-trivial example of PAL-8 code. It is OS/8-specific, however. Disk file I/O is probably different in TSS/8. Some other PAL-8 code is also available at that same DropBox link.

Nice, thanks! I think it was David who had the original question, though.

Vince

David Meyer

unread,
Apr 24, 2021, 7:10:12 AMApr 24
to
Thanks for posting that, steve. That's a really masterful example.
Reply all
Reply to author
Forward
0 new messages