As I stated in a previous post, this blog was returning after a large pause. After showing a new device and a bit of history, nothing is more appropriate than summon an old and forgotten loose thread. And here we are.
Back in 2016, we take a look in Panasonic VW-KT300. We saw that it's a MSX2+ without a MSX-BIOS. The machine have a different BIOS, almost made from scratch. The disassembly of this BIOS confirmed to us that:
- The NEC gate-array is some kind of MSX-Engine;
- 64KB of RAM is a Memory Mapper;
- There are routines to initialize PPI and PSG;
- MSX's slots and pages structure is present;
- VW-KT300 is an MSX based hardware.
With this information, Alexandre Tabajara from Tabalabs boots the Video Titler using a MSX1 BIOS, The video with this experience even shows the MSX Basic prompt. Further try outs to boot it, now as a MSX2+, proved to be very frustrating and eventually, I give up and did go to the next archaeological excavation.
Now and then I take the disassembled SYSTEM0 code, understand and comment a few lines, and put it back in the drawer. This week I toke the code to read again and, suddenly, saw something very obvious: the machine, hardware wise, is a Panasonic MSX2+, what the MSX2+ from Panasonic has in slot 3.3?
The Panasonic Mapper.
Sometimes the information is just in front of our eyes. In the 2016's post I wrote, frustrated:
The layout of SLOT3.3, with all pages mapped to EDIT0, is a clue that there is a custom mapper that needs to be configured somehow.
"There is a custom mapper"... why not try the Panasonic one in a Panasonic machine?
For those unfamiliar with the Panasonic Mapper, it is used with few modifications in all MSX2+ and TurboR from Panasonic. It merges all MSX address spaces (RAM, ROMs, SRAM) in a big set with 512 segments of 8KB each. AFAIK this mapper is only present in the firmware slot: 3.3.
To select which segments are in each of the slot 3.3's pages, you need to write the desired segment number in a specific memory address for each page. To select which segments are in each of the slot 3.3's pages, you need to write the desired segment number in a specific memory address for each page, as you can see in the table below:
+-------------+-------SEGMENT-SELECTION-------+
| ADDRESS | 7FF8h | WRITE | READ |
+-------+-------------+---R/W---+-------------+-------+
| PAGE0 | 0000h~1FFFh | bit 0 | 6000h~63FFh | 7FF0h |
| | 2000h~3FFFh | bit 1 | 6400h~67FFh | 7FF1h |
+-------+-------------+---------+-------------+-------+
| PAGE1 | 4000h~5FFFh | bit 2 | 6800h~6BFFh | 7FF2h |
| | 6000h~7FFFh | bit 3 | 6C00h~6FFFh | 7FF3h |
+-------+-------------+---------+-------------+-------+
| PAGE2 | 8000h~9FFFh | bit 4 | 7000h~73FFh | 7FF4h |
| | A000h~BFFFh | bit 5 | 7800h~7BFFh | 7FF5h |
+-------+-------------+---------+-------------+-------+
| PAGE3 | C000h~DFFFh | bit 6 | 7400h~77FFh | 7FF6h |
| | E000h~FFFFh | bit 7 | 7C00h~7FEFh | 7FF7h |
+-------+-------------+---------+-------------+-------+
| (1) Segment number have 9 bits (1+8) |
| - most significant bit r/w from 7FF8h |
| - last 8 bits from memory specified |
| memory addresses for read and write |
| (2) 7FF9h is a control register: |
| 000bbb00 |
| ||+---> enable reading 7FF0h~7FF7h |
| |+----> enable reading 7FF9h |
| +-----> enable read/write 7FF8h |
+---------------------------------------------+
Having the VW-KT300's slot 3.3 using a Panasonic Mapper seems to be a good guess. Now we just need to check if our hypothesis is correct. And it's is easy to do, we only need to take a look at the SYSTEM0 disassembled code. Search for something like this:
di
ld a,0ffh
out (0a8h),a
ld a,00fh
ld (0ffffh),a
ld a,(0edf4h)
ld (06000h),a
inc a
ld (06400h),a
ret
The snippet above is part of the "shuffling around pages" code that puzzled me. If you want to check it yourself, it's from position 0641h in the VW_SYSTEM0.ROM file. The code does the following:
- Disables interruptions
- Activates pages 0 to 3 in primary slot 3
- Activates pages 0 and 1 in secondary slot 3.3
- Activates pages 2 and 3 in secondary slot 3.0
- Reads an arbitrary data from 0edf4h
- Writes the data in address 6000h
- Increases data by one
- Writes the increased data in address 6400h
- Returns
It's a safe assumption that the "arbitrary data" in 0edf4h is the segment number. Then, by the addresses 6000h and 6400h, two consecutive segments were wrote on Page 0. Nice. I still find the big picture code around this one very confusing, but it's clear that it's using the Panasonic Mapper to select the data to be visible in slot 3.3
We can also see the similarities between the labels inside the FS-VA1.ROM and the full A1WSX firmware. They are even in similar offsets!
+---------+----------+----------+
| OFFSET | FS-A1WSX | VW-KT300 |
+---------+----------+----------+
|00000010 |WSXSEG00P1|EDIT0 |
|00004010 |WSXSEG01P0|EDIT1 |
|00008010 |WSXSEG02P2|EDIT2 |
|0000c010 |WSXSEG03P0|SYSTEM1 |
|00010010 |WSXSEG04P1|VA1DATA |
|00014010 |WSXSEG05P2|DESIGN |
|00018010 | | |
|0001c010 | | |
|00020010 |WSXSEG06P1| |
|00024010 |WSXSEG07P2| |
|00028010 |WSXSEG08P1|DEMO |
|0002c010 |WSXSEG09P0| |
|00030010 |WSXSEG10P2|SYSTEM0 |
|00034010 |WSXSEG11P0|SAMPLE0 |
|00038010 |WSXSEG12P1|SAMPLE1 |
|... |... |----------+
|00170010 |WSXSEG30P1|
+---------+----------+
And what we can do with this information? Well, we still have lot of gaps in our knowledge about the Panasonic Video Titler VW-KT300, and some of them can only be filled if we can probe while the machine is running. Specially the convoluted page mapping code. Being the VW-KT300 very similar with the other Panasonic's MSX2+, and since these MSX2+ were emulated by OpenMSX, we can probably put the code from VW-KT300 to run in OpenMSX, too!
The first step is to create a machine definition in OpenMSX. A good idea is to use another MSX2+ from Panasonic as VW-KT300 base, we chose the FS-A1WSX. When a MSX turns on, it began to read the code from address 0000h in slot 0 (or 0.0), so the VW_SYSTEM0.ROM needs to be mapped there:
sha1: a321510f66f89413d18454c2cdcfd11dddd86536 |
We knew by the already disassembled initialization code, that the slot 3 is the only one which is expanded. So the VW_SYSTEM0.ROM is in slot 0, the other sub-slots were removed from the machine definition. Another change is the ROM size, we change to 0x4000, because VW_SYSTEM0.ROM is a 16KB ROM.
What else we know?
The slot 3.0 is the 64KB Memory Mapper, and the 3.3 is the Panasonic Mapper. The ROM file for the Panasonic Mapper needs to be a complete one. So we put the FS-VA1.ROM there:
sha1: f2def2d1f8be9c34e67e4e42675204a51aeae650 |
And let's start the machine!
Ok, that doesn't look right. |
Black screen. Using the MSX debug, the machine was trapped in a loop in the interruption handler, it goes to 0038h, which jumps to EE15h, and there we have an FFh which calls the interruption code in 0038h. Why this is happening??
The OpenMSX console helps a lot the debugging process. |
Our emulation try gives the first fruit: we find a difference between the usual MSX hardware and the PPI implemented in NEC gate-array. The SYSTEM0 didn't have the code to initialize the PPI ports. It starts just writing the slot configuration to I/O port A8h without first setting the PPI ports directions by writing in I/O port ABh.
Without writing the slot configuration in A8h, the pages 2 and 3 were kept in slot 0, which have nothing from 4000h to FFFFh. And "nothing" is a area full of FFh, that's why EE15h have FFh (rst 38h), goes back to 0038h and there returns to EE15h. We need to initialize the PPI ports configuration, then the A8h write will work as expected.
To be able to use the VW-KT300's code unmodified, I put an watchpoint at address 0001h which executes the proper PPI ports initialization when triggered. And then:
Japanese text says "Children's Day" |
Japanese text says "Sport's Day" |
Japanese text says "Presentation" or "Recital" |
Great! It's working! I guess those screens are some kind of examples of what can be done with this Video Titler. But the splash screen is missing. Also there's a lot of empty squares were should be characters.
We still need to debug and tune this machine definition, but that is for our next post!