• Please review our updated Terms and Rules here

Epson HX-20 - FORTH ROM

Looking though my notes, I see that the instructions for initialising the RAM expansion card give two different sets, depending in if you've got BASIC v1.0 or v1.1. I assume that I've got v1.0 as those instructions were the ones that worked. Maybe the FORTH ROM workks OK for 1.0 as well. maybe there's a problem if you've got 1.1?

The instructions for 1.0 change byte FEFD to 68 to set the Option ROM ON, and change FE99 to 40 to set the Option ROM OFF. The changes for 1.1 are FFFB to 18 or FFFE to E0 respectively. I don't know if I knew which set was right for me, just that the 1.0 instructions worked, and the 1.1 did not.

I cannot remember, but I'm sure that I got the FORTH ROM well before I got the RAM expansion, so I DID need to use the instructions to activate the FORTH (which uses address FFF5). I cannot remember if I still needed to do that once I had the RAM board, maybe the board setting activated the ROM anyway.

If you get the FORTH menu item showing, then the HX has accessed the ROM OK. The Trap message means that you're trying to use an invalid instruction, usually something is 00 which is invalid. My manual tries to explain what the Trap means, but it's a little vague for me. Operation manual page 9-1 - just calls it 'programme overrun'. I too tried to follow the Programme Counter and tried to work out where it had gone to, and it was somewhere into the ROM code in my case (I think).

I'll need to make sure all the BASIC progs I've got loaded are saved properly (as .WAV files), I think most are stored as .WAV anyway. Then try to activate my HX with the extra RAM and the option ROM, and see what that does. Rather, DOES NOW. I'm sure that it WAS all working, I've got piles of notes, prints, etc where I was playing with the FORTH. I had some FORTH code loaded that disassembled the dictionary. I had some definitions loaded that allowed the FORTH to access the TF-20 floppy drive as raw sectors (8 sectors per 'Screen) and this worked until my HX and the TF stopped communicating!!

It should be possible to write a (say) BASIC prog that can access the FORTH ROM as a normal dictionary. VLIST should be easy? Something like the disassembly would be more complicated, as the prog would need to do more actual FORTH. This could at least check the integrity of the .BIN file.

Geoff
 
I have started to disassemble the FORTH ROM and came across an inconsistency I am trying to resolve with the utility subroutines within the $Exxx and $Fxxx ROMs.

I am just wondering (thinking aloud) as to whether the utility subroutines changed at some point - thus invalidating the FORTH ROM? If the FORTH ROM is calling a subroutine at address $FF4F expecting it to execute function 'A' and it executes function 'B' instead...

Let me ponder that thought for a bit...

It is just possible that different 'language' variants still have the same underlying subroutine tables - but that doesn't mean there is an older ROM that the FORTH may have been designed to use.

Dave
I've been poking at the ROM as well. I found a good list of routines in this PDF, starting at PDF page 19: http://www.vintagecomputer.net/fjkraan/comp/hx20/doc/tmS_13-14.pdf

It looks like there's a jump table at the top of ROM, and address $FF4F is the "Display one character on virtual screen" routine.

The header at the TOP of ROM specifies $600C as the entry point, which is just a NOP followed by a jmp to "START".

Code:
START:
    ldaa    #$0C
    jsr    $FF4F    (DSPSCH)
    ldx    #$70E0
    ldab    #$05
    jsr    $D715
    ldaa    #$16
    jsr    $FF4F    (DSPSCH)
    stx    X0098
    jsr    KEYIN
    rora
    bcs    DOWARM
    jmp    COLDJMP
DOWARM:
    jmp    WENT

$70E0 contains the string "\x00\x01Warm?". I have no idea what the routine at $D715 is. Some sort of string printing routine? X is loaded with the string's starting address-2, and B is loaded with the string's length. I don't know what the leading $00 and $01 are for...

Once it hits KEYIN ($FF9A) the machine should pause and wait for a character from the keyboard. Something seems to be going wrong before this point.

I reverse-engineered the ROM a bit further, and this seems to be a pretty vanilla version of FIG-FORTH, with some minor changes to take advantage of the 6301's enhanced instruction set. You can match up a lot of the words 1-to-1 with this listing http://www.forth.org/fig-forth/fig-forth_6800.pdf
 
Following the above, the question 'Warm?' should be answered Y or N. Warm assumes that the state of RAM is OK for FORTH, i.e. FORTH has been used before, and BASIC has not been run since. Can't remember, but I think that anything other than Y goes to Cold start, which resets the system RAM ready for FORTH. So the code listed above may be reacting to Y (or) anything else?

The definition at D715 may well be the FORTH word to print a string. It may do this by merely placing the data into the screen buffer/memory, and then calling the ROM routine at FF4F which displays the data in the buffer on the virtual screen.

Geoff
 
Regarding doing a ROM dump for my ROMs?

When I did the dump for the FORTH ROM, my TF-20 drive was working (rather, the TF was communicating with the HX). So it was a trivial prog involved to use BASIC and read the addresses 6000-7FFF and write the 8k data bytes to a file on the floppy. But now, I don't have the TF working (well, it makes the right clicks, but no link to the HX). In theory, I might be able to do the same thing sending the data to a .WAV file, but the Disk Basic supported RANDOM Files (byte data) while the normal BASIC isn't so helpful. I'll need to experiment.

Geoff
 
Following the above, the question 'Warm?' should be answered Y or N. Warm assumes that the state of RAM is OK for FORTH, i.e. FORTH has been used before, and BASIC has not been run since. Can't remember, but I think that anything other than Y goes to Cold start, which resets the system RAM ready for FORTH. So the code listed above may be reacting to Y (or) anything else?

The definition at D715 may well be the FORTH word to print a string. It may do this by merely placing the data into the screen buffer/memory, and then calling the ROM routine at FF4F which displays the data in the buffer on the virtual screen.

Geoff
If you type an "n", the ASCII code for that is $6e. "y" is ASCII code $79. The "rora" opcode rotates the least-significant bit into C. For "n", C is set to 0. For "y" it gets set to 1. If the carry bit is set (by typing a "y"), a warm start is performed by branching to DOWARM. The WARM start does not load the initial Forth variables that COLD does.

$D715 lives in the part of the system ROM containing routines for the monitor, according to the memory map. All of the FORTH routines live somewhere between $6000 and $7FFF.
 
Well thank you guys, all of this is very helpful. So it is good to know that the ROM is indeed supposed to work from 0x6000 on. I am having some issue with my Expansion Unit that provides up to 16 KBs of RAM and 2 EPROMs (either 2764 or 27128 it seems), and I don't seem to be able to see the ROMs there with the monitor.

So I unplugged the external expander (as I did before), and only have the stock HX-20 with the internal option ROM = FORTH in 11E, so this is 0x6000 to 0x7FFF, and I am able to see the "right bytes" from the FORTH.BIN image there, so it is definitely not "memory mapping / paging" related. I can also execute a G 600C (the Startaddress) and get the same Trap!

So next I'll wait for the 1.0 OS / BASIC, that should hopefully fix that issue then, right? Unless the Forth really needs 16 or 8 KB RAM expansion, but that shouldn't be the case, as Geoff already explained.

Btw, my expansion module is the one described here; I tried different configurations as explained. But the Forth needs to be in 11E or 13B in the Expander, if I understand
https://fjkraan.home.xs4all.nl/comp/hx20/memoryMap.html
correctly. With the 2nd config (13B) with DIP switches OFF ON ON OFF A A for that config, I can't read the proper bytes from 0x6000 on with the monitor via D. Which makes me suspicious (maybe the Expander doesn't like my EPROMS somehow).

Hence, I am using stock HX-20 now, with FORTH = 11E, as it should be. Screenshots of the monitor and G 600C in that config. You can see that it correctly reads the first bytes from the FORTH.BIN ROM, so this config is definitely good:

20220324_194604.jpg20220324_194609.jpg
 
Last edited:
My RAM card uses a similar process to activate the 8K Option ROM. i.e. you can have EITHER the 16k RAM active, OR 8k RAM with the Option ROM active. May be that if I use THAT process to enable the Option ROM then I don't need to use the monitor process I mentioned above. Can't remember. What do you need to do to activate your RAM card, and do you have an option re all the 16k or just 8k RAM AND the ROM.
Regarding this, in my case, it should be clear by now that there is no such software configurability, and all of this is done by jumpers and DIP switches, as explained in the
(note the " All this is set in hardware, so no software switching." at the end)
 
I concur with the disassembly.

I have come across two (2) memory maps for the HX-20. The differences appear to manifest themselves as to the contents of ROMs C/D and E/F.

All the routines that can be accessed by a nice 'jump table' should be supported across different revisions of the ROMs. However, the subroutine call to $D715 is not within the 'nice' subroutine jump table - and may (therefore) constrain FORTH to execute with a specific ROM set.

In one case, ROMs C/D are classed as 'UTILITY' and E/F as MONITOR; whereas in the other case ROMs C/D are classed as BASIC/MENU/MONITOR and E/F as I/O.

I have seen a similar thing with the Commodore PET where some of the low-level (I/O routines) are accessed via a subroutine table - but some software companies use subroutines within the BASIC ROM - and hence these programs are 'locked' to a specific version of BASIC. Of course, the software supplier is quite happy to sell users an 'upgrade' version when Commodore produced a new set of BASIC ROMs!

I see here https://frigolit.net/resources/hx-20/firmware there appears to be two (2) distinct 'sets' of ROM firmware:

The first two (2) (according to their MD5 code) differ only in rom0 ($Exxx and $Fxxx) whereas the last set of ROMs appear to be completely different.

The ROM set that has been posted in this thread appears to be BASIC V1.1. It would be interesting to get a copy of the different set and see if it is BASIC 1.0... And whether these work with your FORTH ROM.

Dave
 
There's a document (PDF) published by Martin Hepperle regarding the HX that makes reference to the two ROM versions. He's specifically referring to the location of character set data, but points out that there is an 8 byte difference between 1.0 and 1.1 which means that all offsets determined for 1 version will be 8 bytes out for the other. The problem here may relate to this.

I don't know when 1.1 started being used. I got my HX late 1983 when the machine had just become available, and I'm sure (as noted above) that my machine is 1.0. The HCCS package was released fairly early, it says (c) 1983. I got it fairly early, prob early '84. It's entirely possible that it might call directly ROM routines, I assume that the one referred to relates to something to do with the screen/virtual screen. Maybe this routine is not in the JumpBlock, or maybe there is a problem doing it via the JB so it was called directly.

If we can work out what the problem is, then it can be fixed. I assume that the .BIN file could be patched to change this call before the file is burned to the chip. Also, if the code for 1.0 can be found, that could be used instead of 1.1, but that MIGHT cause other problems?

I'm now trying to clear out my HX, so I can re-init, re-activate the FORTH ROM, and ensure that it still works. I expect it does, it was not TOO long ago that it was working.

If need be, I could save the code for the ROMs I have.

I cannot remember how I did the FORTH ROM. I could have done it as I said before, used a little BAS prog and written to a Random file on the floppy drive - OR - maybe I used SAVEM and them manipulated the resultant file to remove all the extra data and leave the 8k, now I think back I think there were different versions of the .BIN file that were larger than 8k? If I'm going to write to a .WAV, the latter would be safer. I assume that for loading to a chip then you do need the pure raw data, rather than the format used in a SAVEM file?

Geoff
 
I patched the ROM and replaced the offending part of code with something that just prints "W". Now FORTH boots up! I guess we just need to figure what what string printing routine we need to call, or clear out enough space in the ROM to put our own in there.PXL_20220325_135140306.jpg
 
Well done, although I wonder if some of the other FORTH words make use of other routines?

It’s a good place to start though!

If we can get a copy of versions 1.0 and 1.1 it shouldn’t be that difficult to map the calls from one version to another as you say.

Dave
 
It looks like there are some words that use other "invalid" routines. If I try to use a word that isn't in the dictionary ("FOO", for example), I get the expected "FOO ?" but then a trap is triggered at program counter address $0000.
 
Here's the ROM image with the patch. I realize that I forgot to attach it.
 

Attachments

  • HX-20 FORTH Patched 03252022_1022.zip
    49.7 KB · Views: 11
Hello,

Right, progress.

I've just completed the reset of my HX, and I've reactivated the FORTH, and it's working fine. I've done a VLIST, and it lists all the words. Done a couple of little direct things, and all seems OK. So my version is working fine with 1.0

It does appear that the system does not like 1.1, for the reason discussed. There could well be other places where the noted call is made. I can see what's at that address in my system, and let you know. You could look on your system, and see if the same code is close by (8 bytes away?) and maybe change the addr to point to the correct addr for 1.1?

I'll check that, and get back.

Geoff
 
Hi all, wow, huge progress! That's great, I'll try the patched ROM... but I understand that it is not fully patched yet.
So we really need to find the 1.0 ROMs... this person said he would be uploading them soon
 
Last edited:
The code at D715 is as follows:

7e, ff, 49, df, 67, de, 67, 3c, 86, 20, bd, d6, c9, d6, 67 etc

This seems to be:

jmp ff49
stx 67
ldx 67
psh X
lda 20
jsr d6c9
lda 67
etc

but if that's so, then whatever is after the absolute JMP may be irrelevant at this point?

Geoff
 
The code at D715 is as follows:

7e, ff, 49, df, 67, de, 67, 3c, 86, 20, bd, d6, c9, d6, 67 etc
32 84 0F 81 0A
2B 02 8B 07 8B
30 7E D6 9D 5F

So, whatever the difference between 1.0 and 1.1, it's definitely not a simple 8byte offset in address...
 
Last edited:
Oh, I've found the files I did back in 2015.

Looks like I did use the built-in SAVEM process, this gave me a file 10,368 for 6000-7fff.

I then used a little BAS prog to read that file as 20 byte records with a 4 byte header and 16 byte data, writing the 16 byte data back to a new file. This created the 8,192 byte file you've got.

Could do the same for the other ROMs. 8000-9FFF, A000-BFFF, C000-DFFF, E000-FFFF? Assuming writing the original file as a .WAV will work, then the hxtape process to convert the .WAV to text? I've done this with smaller files before, OK.

Geoff
 
Back
Top