Floppy Controller

A project log for HP 4952A turned general purpose CP/M machine

Attempting to reverse engineer an HP 4952A into a general purpose z80 computer capable of running CP/M.

Trevor Johansen AaseTrevor Johansen Aase 02/18/2019 at 21:444 Comments

x86 ASM is not a pretty sight. x86 addressing sucks.

So I was banging my head on the wall with reverse engineering the main memory board when I figured "Hey, I have the full schematic of the floppy board, why not just use it as the main processor instead?!" The video hardware is accessible via the J1 backplane so it sure is possible. 

I dumped the 256kb rom and was immediately confused. I have never done x86 ASM and specifically chose z80 because the mnemonics make clear sense. The addressing is also linear and straight forward. The x86 machines of the past use a crazy offset system that you were forced to use. Here is a HaD writeup on how it works.

So this board boots to 0xFFFF0 but a 256kb rom is only 0x7FFF so essentially that means the reset instruction is at 0x7FF0. That instruction is EA 65 A4 00 F0 or Jump Far (0xA465 Left shift x4) + 0xF000 which is JMP 0xB3650. Once again we can only address 256kb so and that with 0x7FFF to get an effective JMP 0x3650. Now why is the world didn't they just do EA 00 00 50 36 or even EA 00 F8 50 36?!

EDIT: Upon reviewing the schematics I forgot how the memory was mapped and assumed ROM was at 0x00 like the z80. RAM is 0x0000:0x7FFF and ROM is 0xC0000:0xC7FFF and due to ignoring A15..A17 it repeats at 0xC8000, 0xD0000, 0xD8000, 0xE0000, 0xE8000, 0xF0000, 0xF8000. JMP 0xB3635 still makes no since but it's closer at least.

Well 0x3650 does drop us into a string of subroutines but they mean nothing to me as its all just ex ax xi over and over again. Cutter and IDA are not overly helpful as they can not extract that is code and what is data. 

Copy protection or data obfuscation by HP:

I find patches of code that are meaningless and are never called. in the 80c88 there are opcodes that don't exist x86 OpCodes You get a 00 60 00 which is absolutely nothing and does nothing. As its a ROM its not even a placeholder bit for a local variable. I swear that the guys at HP have a random number generator that fills a 256kb file and they or it with their code so all blank spaces are filled with complete garbage for obfuscation. 


Stuart Longland wrote 04/04/2019 at 11:32 point

Okay, so the instruction is EA 65 A4 00 F0… I tried looking up that instruction, I know it's a far jump, but exactly which order the code segment and offset are given, I couldn't find.  My only hunch is that being a little-endian system, maybe the whole 4 bytes is taken as a 32-bit value: 0xf000a465, and the most significant word is the code segment.

Hence I'm wondering what's at 0xf000:a465 (0xfa465)… given 0xf8000 is a repeat of the ROM, that to me says have a squiz at 0x2465.  I could be very wrong though. :-)

  Are you sure? yes | no

Ken Yap wrote 05/21/2019 at 06:02 point

That information isn't hard to find on the Internet. The format of the intersegment jump is: EA offset-l offset-h segment-l segment-h. So that instruction is JMP F000:A465, or FA465 in linear addressing, as the formula is segment * 16 + offset.

Chances are the ROM code was assembled with an origin at segment F000, and since the ROM is 32kB (256kb/8) and they didn't fully decode the address lines, copies appear at intervals of 32kB. However the A465 is strange since that's above 32kB. It would however be the same as 2465 with the addressing. OP, any chance you swapped it around transcribing, and it's actually 65A4?

  Are you sure? yes | no

David Given wrote 04/04/2019 at 11:00 point

I can recommend the Ghidra reverse engineering thingy --- open source, runs on Linux, understands lots of different architectures. I'm using it for the Z180 and Z80. It'll even decompile to C, mostly.

  Are you sure? yes | no

Ken Yap wrote 02/28/2019 at 12:40 point

Those patches of non-code may be constant data or strings.

  Are you sure? yes | no