Handle European style DATE$
Closed this issue · 17 comments
8350 MID$(WF$,5) = RIGHT$(AD$,2): 'CREATE THE YEAR'S WORD FILE NAME FROM AD$
As mentioned in issue #15, European models may format DATE$ differently than the American MM/DD/YY, so any code that uses RIGHT$(DATE$,2) for the year would be wrong.
Here are the models which may have a different DATE$
- NEC 8201A/8300: uses YYMMDD. Year is
PEEK(63548)+10*PEEK(63549)
- European M102
- European Olivetti M10
Here's a chart we can fill in as we get more data
Model | DATE$ format |
ID in PEEK(1) |
Year (ones place) |
Year (tens place) |
---|---|---|---|---|
Kyocera K85 | 225 | 63796 | 63797 | |
Olivetti M10 Europe | 35 | 63796 | 63797 | |
Olivetti M10 North America | 125 | |||
NEC PC-8201 NEC PC-8201A |
YYMMDD | 148 | 63548 | 63549 |
NEC PC-8300 | YYMMDD | 148 | ||
Model 100 (US) | DDMMYY | 51 | 63789 | 63790 |
Model 102 (US) | DDMMYY | 167 | 63789 | 63790 |
Model 102 (UK) | 167 | 63789 | 63790 | |
Tandy 200 (US) | DDMMYY | 171 | 65333 | 65334 |
Side note about the ID in PEEK(1)
Looking at the Z88DK project's disassembly of the M100 ROM, it looks like the first three bytes are JP <BOOT>
where BOOT
is an address that just happens to be different for each machine type. PEEK(1) is the low byte of the little endian address. According to Z88DK's ROM comparison,
LABEL | M100 | KC85 | M10 |
---|---|---|---|
BOOT | $7D33 | $79E1 | $7A23 |
So, that's where I got the IDs for M100, KC85, and M10, (0x33, 0xE1, and 0x23, respectively).
Note that it is not specified which M100 ROM is used, so I am presuming this was the American version.
Side note about ID continued
The MAME project has ROMs for the KC85 and M100 whose first three bytes agree with the values from the Z88DK project. It additionally has ROMs for the T102, T200, PC8201, PC8201A, and PC8300. Again, it does not specify which version of the ROMs, American or European, for the Tandy computers, but I presume they are American.
LABEL | T102 | T200 | PC8201 | PC8201A | PC8300 |
---|---|---|---|---|---|
BOOT | $1BA7 | $98AB | $7C94 | $7C94 | $6AB8 |
These ROMs show the PEEK(1)
IDs for the T102, T200, PC8201/A, PC8300 to be 167, 171, 148, and 184, respectively. Since these values match what I've seen on my own American Tandy 200 and what @bgri reported for the NEC 8201A, I think they are likely accurate.
Note that even though the ROMs for the PC8201 and PC8201A are different, they both have the same BOOT address, so they cannot be distinguished by PEEK(1)
. If it is necessary to distinguish, one could use PEEK(3038)
. I believe the 8201 will return 249 and the 8201A will return 73. (Byte 3037 is a 0xCD, which is the opcode for CALL
, so 3038 is the low byte of the address).
Note about YEAR address. The Z88DK project's disassembly of the M100 ROM also specifies the address at which YEAR is stored for the M100, KC85, and M10.
LABEL | M100 | KC85 | M10 |
---|---|---|---|
YEAR | $F92D | $F934 | $F934 |
YEAR_2 | $F92E | $F935 | $F935 |
That means the US M100's Year (ones place and tens place) are stored in bytes 63789 and 63790, which checks out with the information from @bgri. So, the KC85 and M10 both have the same addresses for the Year: 63796 and 63797.
ROM Analysis for NEC
The ROMs for all three NEC computers contain the instruction
SHLD $F83C ; Store High Low Pair using Direct Address $F83C
Address $F83C is 63548 in decimal, where the 8201A stores the YEAR. There are no other references to that address in the 8201A ROM, so I'm fairly confident that is where the date code is being manipulated. Since the other two ROMs have the same instruction (albeit at a different location for the 8300), I think it is a safe bet that the YEAR address for all the NEC computers is the same.
ROM analysis for Tandy
Using a similar analysis of the Model 100, Tandy 102 (US), and Tandy 102 (UK) ROMs, all contain 22 2D F9
at the same location in memory:
SHLD $F92D ; Store High Low Pair using Direct Address $F92D
Which implies to me that the Tandy 102's YEAR address is the same as the Model 100's: 63789.
Unfortunately, the Tandy 200 does not contain the address $F92D in its ROM, so it must keep the YEAR elsewhere.
Hoo boy. I just found out Olivetti had a different ROM for a North American version of the M10. And a cursory glance at the binary makes it appear that the YEAR address is four bytes before the location in the European version (63792 instead of 63796). Many original ROMs can be found on the (most excellent) Tandy.wiki' site.
On the upside, while there is a UK ROM for the Tandy 102, I don't see European versions of the Model 100 or Tandy 200, so perhaps those didn't exist.
Still, this list is getting rather unwieldy and it may be best to find a different way of handling the year.
Found the Model T Cross Map which tells us what we already knew for the Model 100 and PC 8201.
M100 HEX |
M100 DEC |
PC8201 HEX |
PC8201 DEC |
T200 HEX |
T200 DEC |
Name1 | Name2 | Description |
---|---|---|---|---|---|---|---|---|
F92D | 63789 | F83C | 63548 | TIMYR1 | TIMBUF+10: Year (ones) | |||
F92E | 63790 | F83D | 63549 | TIMYR2 | TIMBUF+11: Year (tens) |
Wow! You've done a lot of work on this, well done!!
I've unpacked and powered up my 8201 (not /a) and 8300. Results on the hardware mostly align with what we see in the notes previously:
- 63548 = 1s place (both)
- 63549 = 10s place (both)
- peek(1) = 148 (both) !! Interesting, the chart above has 184 for the 8300. Yet my 'made in japan; exported and sold in Germany' version shows the same as the other NEC 8200 models -- 148.
And since I had the hardware out, I thought I'd grab shots of the ROM chips, just to see what's up...
NEC PC-8201
So that basically confirms the NEC side of things.
As for the m200 - there's a technical reference manual
Page D-11 gives a Date address of 1A9E
I'm guessing, that according to the chart, we're only looking at possibly 4 families to test (KC/Olivetti, NEC 8200-300, T100-102, and T200 (possibly NEC PC-8400(Starlet - like a t200))
The VirtualT emulator has most of these roms available so I'm thinking we can test virtually.. but as for real hardware... my collection isn't that big!! :D
- peek(1) = 148 (both) !! Interesting, the chart above has 184 for the 8300. Yet my 'made in japan; exported and sold in Germany' version shows the same as the other NEC 8200 models -- 148.
Definitely interesting! The ROM I got from the MAME project was only 32K, so perhaps it is bad or a different version. I double checked and it is not a typo; the value of the second byte for that ROM is 184.
I also checked the ROMs available on tandy.wiki and found that the PC-8300 ROM there matches your experience: 148.
$ curl -s http://tandy.wiki/images/e/ef/NEC_PC-8300.orig.bin | hd | awk 'NR==1 {print strtonum("0x"$3)}'
148
It's also 128K, so I suspect that that's the good copy. I've updated the table accordingly, but I wonder whether the 32K ROM the MAME project is/was using is actually legitimate for any PC-8300s.
Oh, and can you confirm that the DATE$
for the 8300 is the same as the 8201: YY/MM/DD?
As for the m200 - there's a technical reference manual
Page D-11 gives a Date address of 1A9E
trs80.com doesn't like to be linked to, which is too bad because it means they will show up lower on the Google page rank. Oh well, the same file can be found on archive.org: https://archive.org/details/Model_200_Technical_Reference_Manual_1986_Tandy
Unfortunately, it turns out appendix D is all ROM subroutines that can be called. So, that's not the location of the YEAR.
I did a simple FOR
loop to search for the year in memory on my Tandy 200 and discovered that it exists at 65333 and 65334. So, the Model T Crossmap Rosetta stone should look like this:
M100 HEX |
M100 DEC |
PC8201 HEX |
PC8201 DEC |
T200 HEX |
T200 DEC |
Name1 | Name2 | Description |
---|---|---|---|---|---|---|---|---|
F92D | 63789 | F83C | 63548 | FF35 | 65333 | TIMYR1 | TIMBUF+10: Year (ones) | |
F92E | 63790 | F83D | 63549 | FF36 | 65334 | TIMYR2 | TIMBUF+11: Year (tens) |
Interesting philosophy of trs80.com.
re: appendix D... sigh, I should have known that. Was getting tired last night...
re: FOR loop, of course! That's a great way to find it :)
re: DATE$, Yep, the 8300 date format matches (YY/MM/DD)
Interestingly, the BASIC displays 8201 Basic... yet the text on the chip indicates it's for an 8300 (previous photo)
So I thought I'd check the other unit's BASIC as well...
So the 8300 uses version 1.1
Thanks for confirming those similarities in the NEC family. I've merged their entries in the table.
EDIT: If you have the time, it may be good to double-check my assumptions on your actual 8201, 8201A, and 8300.
? PEEK(63548)+10*PEEK(63549)
Tangent: I wonder if they called it “NEC PC-8201 BASIC” on the 8300 in order to reassure people that their N82 programs would continue to run. Or, perhaps NEC did not want to enter into another licensing agreement with Microsoft at that point?
Also, just out of curiosity, was my prediction for how to distinguish the 8201 and 8201A correct (PEEK(3038)
)? And, since the 8300 has the same PEEK(1)
as the other NEC portables, how does one differentiate? Or are they so similar that it doesn't matter?
Also, just out of curiosity, was #16 (comment) for how to distinguish the 8201 and 8201A correct (PEEK(3038))? And, since the 8300 has the same PEEK(1) as the other NEC portables, how does one differentiate? Or are they so similar that it doesn't matter?
Sorry about the delay getting this -- been a busy time :)
And the results of ? PEEK(63548)+10*PEEK(63549)
Thanks for testing that. I guess the ROMs I was looking at were incorrect. Fortunately, there is no need to differentiate the 8201 and 8201A to get the DATE$, but something looks off about the PC-8300. Too bad they all return the same thing for PEEK(1).
The 8300 is an interesting little beast. It's got an 8201a emulator built into it.
So, one way to test for the 8300 is to look for the MS Basic version (1.0 for 8201/a, 1.1 for the 8300 (unless it's in emulator mode).
And to test for the 8201, I guess we could test for Japanese characters in the keymap? 8201a and 8300 don't have those unless the ROM has been edited.
I had hoped mapping PEEK(1)
to the YEAR address would be simpler and perhaps even more portable, but it seems like the best course may be to do something like:
10 ID=PEEK(1)
20 IF ID=148 YR=LEFT$(DATE$,2): ELSE YR=RIGHT$(DATE$,2)
That would use the European style on NEC portables and American style elsewhere. This would fail for the UK version of the Tandy 102, presuming it doesn't use the American style. And, of course, it doesn't handle the Olivetti M10, but then I never did find enough documentation to figure anything out about it.
The 8300 is an interesting little beast. It's got an 8201a emulator built into it.
Oh! I had been wondering why the 8300 had a huge 128K ROM. I had imagined it had some workaround to get past the 64K limit. Having four different ROM images makes more sense.
Oh! I had been wondering why the 8300 had a huge 128K ROM. I had imagined it had some workaround to get past the 64K limit. Having four different ROM images makes more sense.
Yeah, they sure did some interesting things with hardware and software back in the day :)
... and as you mention above, that does seem to be a good/simple way to handle the date until more info appears on those European/UK versions.