1

I am trying to learn assembler on the various retro machines I own, or am about to buy.

Today I tried converting this 8080 routine (which worked, repeatedly):

| START: | MVI A,0  | 8000 | 3e |
|        |          | 8001 | 00 |
| LOOP:  | INR A    | 8002 | 3c |
|        | CPI 10   | 8003 | fe |
|        |          | 8004 | 0a |
|        | JZ HALT  | 8005 | ca |
|        |          | 8006 | 0b |
|        |          | 8007 | 80 |
|        | JMP LOOP | 8008 | c3 |
|        |          | 8009 | 02 |
|        |          | 800a | 80 |
| HALT:  | HLT      | 800b | 76 |

to run on my Epson HX-20, which has two Hitachi 6301 chips, using the datasheet available at vintagecomputer.net. It was a lot of guesswork on my part with the mnemonics, but I came up with this:

| START: | LDA A 0  | 1000 | 86  |
|        |          | 1001 | 00  |
| LOOP:  | INC A    | 1002 | 4c  |
|        | CMP A 10 | 1003 | b1  |
|        |          | 1004 | 0a  |
|        | BEO      | 1005 | 27  | #Branch if = zero
|        |          | 1006 | 0b  |
|        |          | 1007 | 10  |
|        | JMP LOOP | 1008 | 6e  |
|        |          | 1009 | 02  |
|        |          | 100a | 10  |
| HALT:  | SWI      | 100b | 3f  | #Software interrupt

To my surprise, this worked first time, and I could see the A accumulator* now held 0a. To my greater surprise, it hasn't worked since, when I have changed the value of 1004. I tried turning the machine on and off, but due to the way the HX-20 works, this does not clear RAM.

Why did this routine only work once? My guess is that branch is not quite the same as jump, and it is waiting to come back, or maybe I need to reset the zero flag?

In any case, I can set the value of the A accumulator manually using LDA A, or the HX-20 Monitor x command, so it would not appear to be a malfunctioning RAM issue.

I'm now wondering if I'm going mad, and it didn't work the first time after all...

* The HX-20 also has a B accumulator.

6

There are several issues:

  • BEQ is a two byte instruction, using a relative offset, not a 3 byte with an absolute address.

  • The $6E JMP you used is an indexed one, with two bytes length, not three. It's parameter is a relative offset added to the X register.

So for the BEQ you want to use

For the JMP, $7E would be the right encoding when using absolute, or rather use a BRA ($20) to keep the programm short and relocable.

The final programm would look more like this:

1000 86 00    LDAA #00
1002 4C       INCA
1003 B1 0A    CMPA #10
1005 27 02    BEQ  L1009
1007 20 F9    BRA  L1002
1009 3F       SWI

(Well, a real programm one would change the BEQ for a BNE and scrap the BRA, but that's a different story)


If I may add, your assumption seams to be that a port can be done by just exchangeing opcodes, but that's as frivoulous as translating from English to German by swaping words according to some dictionary.

  • 1
    Yeah, since asking the question I've been reading more about the chip and realising how wrong I was to try to translate mnemonic-for-mnemonic. I'd got about halfway towards your answer, but was stuck on exactly how to calculate relative addressing, which your example clearly illustrated. So I accept it was a bad question, and am grateful for the time you took to nevertheless write a good answer! :-) – harlandski Mar 15 '18 at 18:30
  • Thanks, glad I could help. Relative addressing is, at least on 6800ish CPUs, rather straight forewart. Just take the address of the next instruction and subtract it from you target. – Raffzahn Mar 15 '18 at 18:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.