(03-08-2015 08:35 AM)brouhaha Wrote: [ -> ]I'm not convinced that you have an accurate model of how the instruction works.
My understanding based both on hardware experimentation and on study of the firmware of various models is that the clear data regs instruction (octal 1260) always clears all of the data registers in the selected 16-register group (i.e., all registers whose address ignoring the low four bits is equal to the selected address. It works that way whether the chip is PMOS, NMOS, or CMOS. It definitely does not clear all the registers when there are multiple 16-register chips; it only clears the selected one. Two details I'm not entirely certain of:
- Does the 1260 instruction clear a complete 16 registers-group when they are implemented in two 8-register chips?
- Does the 1260 instruction clear all 32-registers of a 32-register group? I'm fairly certain that it does not.
In the 29C, the firmware at address 6331 explicitly does a clear with address 0x10 selected, if it has detected that the cold-start constant (BCD 34934284) is not present in the status register (0x2e). I believe this clears only the registers from 0x10 through 0x1f. If the instruction was incorrectly implemented and cleared all RAM, or cleared the entire CMOS RAM chip (0x10 through 0x2f), it would wipe out the cold-start constant that it has just written (at address 6324) into the status register, which is why it would clear that RAM at every power-up.
On the other hand, if the instruction was implemented to not EVER clear the CMOS RAM chip, it would cause problems on a true cold start, leaving garbage behind. (Possibly not causing any actual problem in your simulation code if you zero all registers on a true cold start.)
When I started the ACT project, I didn't want to dig much into the ACT instructions. The nonpareil emulator was already so perfect for HP25 and HP-21, and as I know now also for HP-22 and HP-27. So I didn't study the HP firmware and the emulator very much. But curiosity led me to the idea that there could be some secrets lifted and when I decided to buy a defective HP-29C I did it with the intention to repair it and make this calculator repairable for others. Soon I understood that the very best way to find out how some unknown instructions behave could only be solved by a ROM emulator and a sophisticated sequence of instructions, that reveal, what the original ACT does in response to these instructions. Till today I never came so far to make a ROM emulator. It is still ahead although the hardware is already there and it is not too difficult to implement. But as lazy as I am, I reduced my work to the aim, just to make the HP-29C firmware running by making assumptions, guessing and the try and error method.
I admit and agree totally, that my implementation, which made the HP-29C firmware finally running, is not necessarily an accurate model of the real ACT. As an example, imagine that the emulator doesn't do anything with the instruction xxxx and the HP-29C doesn't use the instruction xxxx in its whole 4k ROM code, then it will emulate perfectly well, but is not an accurate model of the real ACT. If another firmware uses the xxxx instruction, the emulator will fail.
The Clear Registers instruction 1260 is used only once in the HP29C 4k ROM code at address 6331. In my ACT all RAM registers will be loaded from Flash memory prior to act_reset() and I don't want to have them cleared, so my easy solution for the HP-29C was to ignore this single instruction. Well it works well, but I cannot be very proud. I would liked to have the time to build a ROM emulator and writing software for it and find out the exact behaviour of the Clear Register instruction in any contexts. I plan to do that in the future.
I made the observation, that 1260 with ramaddr set to 0x10 cleared register 0-31, but not registers 32-47, which contained the 98 program steps.
Your implementation does exactly what you describe in words, it clears 16 registers and works for HP-25. Since the HP-25 only has 16 registers ram_addr never will be >=0x10.
Code:
static void op_clear_data_regs ()
{
int base;
int i, j;
base = act_reg->ram_addr & ~ 017;
for (i = base; i <= base + 15; i++)
for (j = 0; j < WSIZE; j++)
act_reg->ram [i] [j] = 0;
}
The HP29C uses clear register at ram_addr 0x10, but I observe the lower ram 0x00-0x0F is also cleared at the same time, the upper RAM is not cleared. Keep in mind that the 1260 instruction is not performed by the ACT, it only issues the opcode on the bus, it is decoded and performed by the RAM chips itself. Therefore I assumed, that the RAM chips (which always contain a 16 register RAM group but I'm not sure), could be designed different, some of them perform the clear instructions, others don't. And the CMOS type don't. This would raise the question why ram_addr is loaded with 0x10 before. So I may be wrong. But it could explain, why you needed to implemented base = act_reg->ram_addr & ~ 017 statement.
My assumption and it is only an assumption: The clear instruction is independent from ram_addr and clears those RAMs, that are listening to this command.
I really need to build a ROM emulator to get from assumptions to knowledge. It would be the best scope for real instruction analyzing.
But at least making assumptions and prove whether they can withstand the experiments is the real scientific method. I have repaired two HP-29C now, and they really like the emulator model as it is at the moment.
But I know there is still lot of work to do for the HP-97 etc.
Bernhard