Giving octal a try

General discussions related to the Altair 8800 Clone

Giving octal a try

Postby mail@gabrielegan.com » May 28th, 2019, 2:58 pm

Last year I taught the undergraduate students on my course "Textual Studies Using Computers" to do 8080 assembly language programming, using the eight Altair Clones in my lab. Amazingly, since they are students of English Literature, they got the hang of it and were able to write programs for interesting textual projects. (One group wrote a program that counted the word-lengths and sentence-lengths in texts and used it to compare speeches by different US presidents, for example.)

On the kind advice of members of this forum, I taught my students to handle binary numbers primarily using hexadecimal representation. To counteract the Altair front panel's encouragement of octal notation I put coloured sleeves on the switches to group them in batches of four, for example. This all worked rather well, but I was thinking that for next academic year I might just experiment and see if the students do any better using octal notation for everything. There certainly were some students who just couldn't commit to memory the 4-bit patterns for A, B, C, D, E, and F, for example, and had to figure them out afresh every time. Maybe memorizing just eight 3-bit patterns will be possible for all the students.

Which leads me to my question: does anyone know of an assembler that will produce its PRN file using octal rather than hexadecimal notation for the memory addresses and machine code? Presumably, even if I find one of those we'll still have to use HEX format files to get our programs into the Altair Clone: there's no other way to upload our object code, right? (I should say, we don't run any operating system: the students use Altairs that have nothing at all in them when started up -- everything in memory is loaded into it by the students during the class.)

Regards

Gabriel Egan
mail@gabrielegan.com
 
Posts: 104
Joined: October 11th, 2014, 8:12 am

Re: Giving octal a try

Postby AltairClone » May 28th, 2019, 6:52 pm

The Altair DOS assembler produces octal listings.

Mike
AltairClone
Site Admin
 
Posts: 632
Joined: April 5th, 2013, 10:55 am

Re: Giving octal a try

Postby mail@gabrielegan.com » May 29th, 2019, 3:03 pm

Looking at the manual for the Altair DOS assembler, its listings appear to do something odd with addresses that are the operands of instructions. Whereas a hex listing will typically present such an address with the low byte first and the high byte second (because that is how the 8080 processor needs them), the Altair DOS assembler listing in octal puts the high byte first and then the low byte.

This means that the octal bytes cannot be entered into the Altair front panel in the order they are presented in the octal listing. The user has to remember to flip the high and low bytes of address-operands.

I checked and the Microsoft Macro-80 assembler running under CP/M does the same thing when you ask it to produce listings in octal: it lists addresses that are the operands of instructions in high-byte-then-low-byte order. Weirdly, if you ask the same Macro-80 assembler to produce its listing in hex rather than octal notation, it correctly lists first the low byte and then the high byte of each address-operand, putting them in the order the processor likes them.

That two assemblers from different manufacturers do this with octal listings makes me think it must be a feature not a bug. Does anybody know what the thinking is behind this? My fear is that it'll catch my students out and they'll fail to flip the high and low bytes of address-operands when entering them on the front panel.

Regards

Gabriel Egan
mail@gabrielegan.com
 
Posts: 104
Joined: October 11th, 2014, 8:12 am

Re: Giving octal a try

Postby AltairClone » May 29th, 2019, 7:41 pm

Interesting what you’ve found. I’ve never done any research looking for octal output, so you already know more than I do. In listings where I provide the octal bytes for front panel input (e.g., http://altairclone.com/downloads/front_ ... LLBITS.PRN), I run the executable binary through a program like BINHEX in a DOS command window.

Mike
AltairClone
Site Admin
 
Posts: 632
Joined: April 5th, 2013, 10:55 am

Re: Giving octal a try

Postby mail@gabrielegan.com » June 1st, 2019, 6:22 am

The mystery deepens . . .

It seems that this odd behaviour regarding the order of bytes in 2-byte operands is not confined to the octal listings. When asked to produce hex listings for the same short program, the assembler from Digital Research that comes with CP/M 2.2 (ASM.COM) correctly puts the bytes in the reverse order, as in

Code: Select all
  0013  013412            LXI B, 1234h
  0016  213412            LXI H, 1234h


while the M80.COM assembler from Microsoft does not reverse them:

Code: Select all
   0013'   01 1234        LXI B, 1234h
   0016'   21 1234        LXI H, 1234h


I would say that the M80.COM assembler is wrong and the Digital Research assembler is right.

Regards

Gabriel
mail@gabrielegan.com
 
Posts: 104
Joined: October 11th, 2014, 8:12 am

Re: Giving octal a try

Postby toml_12953 » June 1st, 2019, 9:33 pm

mail@gabrielegan.com wrote:The mystery deepens . . .

I would say that the M80.COM assembler is wrong and the Digital Research assembler is right.

Regards

Gabriel


It's not really a case of right or wrong. The M80 assembler is meant for people to read rather than to have
people be able to enter the bytes from the listing manually. I would rather use the DR listing, though.
toml_12953
 
Posts: 297
Joined: June 7th, 2013, 12:54 pm

Re: Giving octal a try

Postby TomXP411 » June 3rd, 2019, 12:02 pm

Yeah, as long as the actual object code is right, it's not a huge problem, but it is kind of annoying. (Actually, the more I think about it, the less I like this behavior. A listing should always show the raw bytes, with one byte per digit-grouping. Otherwise, you have no way to compare memory against the listing to confirm the accuracy of a program load.)

Having said that, there are situations where I may need to hand-enter code into a monitor, and the easy way to get to that point is to use the listing file. If the listing doesn't show the actual generated bytes, then that could be a real problem.

All of this reminds me that I need to get back to working on my Altair IDE.
Last edited by TomXP411 on June 4th, 2019, 12:06 pm, edited 1 time in total.
TomXP411
 
Posts: 42
Joined: March 8th, 2018, 4:13 pm

Re: Giving octal a try (and 'bastard' octal)

Postby mail@gabrielegan.com » June 4th, 2019, 7:42 am

On further reflection, there are considerable barriers to an assember's octal listing actually giving the correct byte values for 16-bit operands such as addresses. The main one is that if we try to list a 16-bit operand as apair of octal numbers in 2bit-3bit-3bit format the results can be very odd indeed.

If the operand is the address 0100H then the correct octal equivalent is 400Q. In hex we can just reverse the bytes to give them to the processor as 00H and 01H, but in octal we cannot reverse the digits since considered as a pair of independent octal bytes (rather than a 16-bit number) the required pair is 00Q and 001Q not 000Q and 004Q.

One solution would be to say that address 0100H is not equal to address 400Q but rather is equal to address 001,000Q. That is, we could treat each byte of a 16-bit address as a separate number in 2bit-3bit-3bit format. If an assembler listing used this format for the first column, the address column, of its output, then it would be possible for it to list 16-bit operands as pairs of octal bytes in reverse order, just as they need to be entered in memory. But so long as the assembler is using 'true' octal (in which 0100H = 400Q) instead of 'bastard' octal (in which 0100H = 001,000Q) it can't do the necessary inversion of the byte order.

I dimly remember this 'bastard' octal format being discussed in the 1970s but I can find no references to it now on the WorldWide Web. But I know I can't be imagining it as I've got a book called '8080 Machine Language Programming for Beginners' by Ron Santore (Portland OR: Dilithium Press, 1978) that uses it for its assembler listings. So, in Santore's listings the memory addresses go:

...
000,376
000,377
001,000
001,001
...

With memory addresses listed this way, it makes sense for an instruction to give its operand in the same 'bastard' octal, as in "LXI H, 001 000" and the assembler to reverse the bytes so the listing reads "041 000 001".

Santore undoubtedly had Altair 8800 users in mind as the readers of his book: his examples use SIO board addresses and conventions (negative logic, so "1" in the status byte means "not ready") and his sketch of a computer front panel looks like an Altair's.

Does anyone else remember 'bastard' octal? From a history-of-computing angle I'd like to pursue this line of enquiry, so if anybody has any pointers to discussions of 'bastard' octal I'd be grateful to hear about them.

Regards

Gabriel Egan
mail@gabrielegan.com
 
Posts: 104
Joined: October 11th, 2014, 8:12 am

Re: Giving octal a try (and 'bastard' octal)

Postby TomXP411 » June 4th, 2019, 12:00 pm

mail@gabrielegan.com wrote:On further reflection, there are considerable barriers to an assember's octal listing actually giving the correct byte values for 16-bit operands such as addresses. The main one is that if we try to list a 16-bit operand as apair of octal numbers in 2bit-3bit-3bit format the results can be very odd indeed.

If the operand is the address 0100H then the correct octal equivalent is 400Q. In hex we can just reverse the bytes to give them to the processor as 00H and 01H, but in octal we cannot reverse the digits since considered as a pair of independent octal bytes (rather than a 16-bit number) the required pair is 00Q and 001Q not 000Q and 004Q.


A listing should show the individual bytes, as they are emitted by the assembler. It doesn't matter whether a single byte is octal, decimal, hex, or binary. Printing per-byte will always give consistent results.

In thinking more about this, I'd question the reliability of an assembler that combines the two bytes of an address operand in the listing. That means the listing isn't simply printing the data as emitted, and as that's kind of the purpose of a lister (to see the emitted bytes next to the source code), it's not doing its job properly.
TomXP411
 
Posts: 42
Joined: March 8th, 2018, 4:13 pm

Re: Giving octal a try (and 'bastard' octal)

Postby KenF » April 28th, 2022, 12:41 pm

mail@gabrielegan.com wrote:
Does anyone else remember 'bastard' octal? From a history-of-computing angle I'd like to pursue this line of enquiry, so if anybody has any pointers to discussions of 'bastard' octal I'd be grateful to hear about them.

Regards

Gabriel Egan


Back in Jurassic times (i.e. 1975-76) that was called "Split Octal," and was very useful when referenced to the brand new 8080. But with it came problems. Some very good, if expensive, calculators were coming on line that could translate between binary, decimal, octal and hex - and far faster than using a table or calculating with a pencil. But for octal, there was a problem. Take the top of the memory address - 65535 in decimal, FFFFh in hex. Using the calculator to convert to octal will give you 177777. Unfortunately, this is useless for an 8 bit CPU, since the 8080 knows nothing about 16 bits. Only 8 at a time. But, in an assembler, such could be entered as 16 bit values like so - lxi h, 0ffffh or jmp 65525 or such. Works great, so why worry about octal?

Well, in the early days of the Altair, almost no hobbyist had an assembler, so we coded in binary. Usually there was a printed sheet of paper with addresses down the left side and eight or 16 blanks on each line to be filled in with binary code, after which the programmer would laboriously key the program in byte by byte. The address 0FFFFH in octal is a 16 bit value of 177777 octal, but even the 16 bit register pairs reference only by byte. Manually entering a 16 bit value, such as an address, has to be done one byte at a time. So the value would be "split" into bits lower than 256 and bits higher than 255. OFFFFH becomes 0FFH 0FFH. In split octal this becomes 377 377. Another... The value of decimal 1000 becomes 03E8 in hex and 1750 in unusable full octal. Splitting it into octal pairs gives a usable 003 350 that can be entered in the required 2 bytes. (Many were the early regrets that neither the Altair nor the Imsaii "split" their front panel switches and lights. The clones that we made almost always had split octal front panels.)

Also, the 8080 was "designed" in Octal. For a programmer of the 8080, the opcode 4Fh means nothing and has to be looked up. (Remember, no assembler) But in split octal it becomes 117. Ah! Clue lightbulb above head. The 1 digit shows that it is a 'mov' opcode. The second digit (target) is a 1 which is always a reference to the C register. The last digit, 7, is the A reg. Thus, this is a mov c,a instruction.

How about opcode 14h? Beats me. But convert to octal you get 024. Ah. the first 0 and last 4 gives that it is an increment (inr) instruction. But which register? Easy. 0=B,1=C,2=D,3=E,4=H,5=L,6=M,7=A The center 2 shows it to be an inr d instruction. If it was 044, then an inr h opcode.

Believe me, after many dozen sheets of manipulating nothing but 3 digit numbers, the programmer would begin to "read" binary code easily. To this day, when I see the trio of numbers, 303, I always think, 'jmp'.

I can still remember that red-letter event when a friend showed up with a cassette tape that had a working 8080 assembler. The modern computer age began that very day.
KenF
 
Posts: 30
Joined: April 25th, 2022, 11:13 am

Next

Return to General Discussions

Who is online

Users browsing this forum: No registered users and 20 guests

cron