Let’s start with his voice! (Part 4 – Understanding how HERO used to speak)

So HERO-1 came with a book that as a child was a bit of a bible to me.  In the back of the book, there were a couple of sayings that were hardcoded into his ROM. It also contained basic instructions on how to get him to say those phrases.

To quote from his book:

ENTERING SPEECH PROGRAMS
The command “72” tells the Robot to speak.  The next entry after the 72 tells where the phonemes (represented in hexadecimal numbers) are found in memory.  The phonemes are entered, beginning at the prescribed address and proceeding until the speech is complete.  The entry “FF” is identified as not being a phoneme; instead it “turns off” the speak command.  Entries after the FF will be interpreted as normal action commands for the Robot.  A typical “speak only” program for the Robot would be:

RESET Enter the executive mode
A          Enter the repeat mode
A          Use the automatic memory address increment
0100    Memory address for program beginning
72        Speak program
0105    Memory address of phonemes
20FE    Wait here after completing speech
##        Phoneme codes, entered in order
##
03        Pause (necessary at the end)
FF       Speech mode is done.

It’s only now after learning about the SC-01-A speech chip that I understand that the phonemes are all 6 bits, and so FF is used as a flag as there can’t possibly be a meaning to the speech chip for this.  In fact, anything after 3F can’t be used, so 40 through FF could be used as flags if needed.

Now, as I review the segment of code above, I realize for the first time exactly what it’s doing – well almost.

RESET – reset the state of HERO
A – (Enter repeat mode) Don’t yet know what this means
A – each byte entered auto increments the memory address so we can quickly enter sequential instructions
0100 – set base starting address

From this point, the entry of the remainder of the program populates memory as follows:

0x0100:0x72         –Denote speech program
0x0101:0x01         –first byte of phoneme address
0x0102:0x05         –second byte of phoneme address
0x0103:0x20         –Wait here? byte 1
0x0104:0xFE         — Wait here? byte 2
0x0105:0xXX        — First phoneme byte.
0xYYYY:0x03       — pause phoneme (still sent to speech chip)
0xYYYY+1:0xFF  — denote speech mode is done

With an understanding of the memory addresses the bytes lie at, it can clearly be seen that since the program is started at address 0x0100, and set as a speech program (0x72) and the next 4 bytes define “start of program” (2 bytes) and “what to do at the end of the program” (2 bytes), that the following address where the first phoneme would be entered is 0x0105 thus explaining where the 0x0105 address comes from.

Further, it can be surmised that the command 0x72:

  1. takes an address for the speech program
  2. pushes the “current instruction pointer(IP) + 1” address to the stack
  3. jumps to the address specified and executes the speech program until it finds a 0xFF which is used as a flag since it cannot be a phoneme as per the 6 bits the speech chip uses
  4. jumps to the address that is then popped off the stack

This then brings further scrutiny to the 0x02FE.  What exactly does this do?  A little searching on-line brought me to a fascinating research paper from 1984 (John Fulcher. “Down-line loading on hero robot” Department of Computing Science Working Paper Series (1984). Available at http://works.bepress.com/jfulcher/24)

Of particular interest was this section on page 15:

P.2 Voice Dictionary – it might be helpful to add two notes here, viz.
(i) 20FE is not an address which this speak program jumps to/waits at
after completing its speech, but rather 20FE is a 6800-assembly
instruction (branch relative – to itself, viz an infinite loop).
In order to link speech routines to other program routines, have
to replace this by 7E (AD DR) – viz Jump extended to the next
routine.
(ii) The Hex codes shown for the phonemes (& words) in this
dictionary are at the lowest of the four pitches possible; to
change individual phonemes to higher pitches, simply add 40, 80
or C0 to the basic hex code indicated.

WOW!  this is fascinating on 2 notes:

  1. Clearly, John Fulcher encountered the same misgivings about the 0x20FE back in 1984, as he made a special point to explain that it’s not an address (as I had previously thought as well). 0x20 is a BRA, or unconditional branch statement, and 0xFE or decimal -2, which steps back 2 memory addresses.  As for why -2, and not -1 as I’d have thought, I’ve found an old document from Nov 76 The Motorola M6800 Programming Reference.  In the section on relative addressing, it states:
    The relationship between the relative address and the absolute address of the destination of a branch instruction is expressed by:
    D = (PC + 2) + A
    where:
    PC = address of the first byte of the branch instruction
    D = address of the destination of the branch instruction
    A = the 8-bit, two’s complement, binary number, stored in the second byte of the branch instruction.

    This means if we want D = PC after execution, that A needs to be -2.
    (D = (PC + 2) + -2) = (D = PC).   -2 = 0xFE and so 0x20FE = an infinite loop Q.E.D.

  2. The second point on page 15, stating that the hex codes are for the lowest of four possible pitches was also fascinating.  I had never seen a reference to this before, and while I have experimented with P105 pins 1 and 2 (labeled pitch) from the Arduino, I never realized that HERO had a way to control the pitch via code.  In fact, earlier in this very blog post, I had stated:

    In fact, anything after 3F can’t be used, so 40 through FF could essentially have all been used as flags if there had been need – but I digress.

    While it’s true they are not used as phonemes, I hadn’t considered they could be used as pitch.  It’s actually a very elegant concept since bit 7 and 8 allow for 4 pitch combinations when used in conjunction.  That leaves the question then of why is 0xFF a flag?  The answer to that is 0x3F is a STOP/”no sound” phoneme.  This then would leave 0x3F, 0x7F, 0xBF, and 0xFF to all mean STOP, with different pitches.  As the very concept of no sound with a different pitch makes no sense, it then leaves us with 4 potential flags.  0x3F could then be assumed to mean solely communicate with the speech chip as it is only a phoneme and uses 6 bits. This leaves us 3 flags.  Of those, it’s possible that 0x7F, 0xBF, and 0xFF could all be used as flags and so it is likely that only 0xFF is actually used as a flag.  To put that another way, if you want to “STOP” the speech chip, send 0x3F.  If you want to stop the program, send 0xFF.  I will definitely need to keep the pitch bits alive as I progress on the speech programming.

Some of the things I’ve learned while researching this make me consider creating or hooking into a Motorola 6800 emulator in the future so that old programs could possibly be entered and work the same way on HERO.  That’s a lot to get my head around at the moment, so I’m not planning on that at this time.

One other consideration has come out of my research for this post.  There were a couple of pre-programmed speeches that came hardcoded in HERO’s ROM.  Perhaps his most famous went like this:

I have a a brain.  Just like you do.  But my brain is a computer.  My owner programs my computer for me and I always do as I’m programmed.

This, as well as 29 other sayings, were all memorable parts of my childhood, and thus of HERO’s core essence.  I realized as I was working through this post that I should definitely be able to navigate to the spot in HERO’s RAM that stored the classic speeches and get the actual bytes that made them up.  From there, I could hard code those speeches into the Arduino that will control the speech chip and by hijacking 0x7F to mean run the speech that follows, and passing a byte after it that denotes the speech (0x00 – 0x1D) – I could have him say his old phrases in precisely the same way he once did.    I get teary-eyed just thinking of it! 😉

Leave a Reply

Your email address will not be published. Required fields are marked *