Last update: Nov. 28, 1997 (three more articles) Download MAP.COM (warning: this is for warning and study purpose only)
This page, based on opinions from coders in and outside Japan, gives a solution to "mapper conflict" problem, a headache to developers. This is more and more seen serious nowadays, since software done by non-Japanese developers seem to malfunction with RAM-enhanced Japanese MSXes but not in their homelands. Because of this, there is a strong movement to "banish" such non-Japanese software altogether.
Japanese MSXes are mostly turboRs - Panasonic A1-ST (256KB) and GT (512KB), which are owned by more than 70% of every Japanese MSX users. You can safely assume almost all of remaining developers own them.
Others are mostly 2+s, like Sony F1-XDJ and XV, Panasonic A1-WX and WSX with their clockup feature, and Sanyo WAVYs, which are uncommon in Japan. All of these 2+s and rest 2s, which are descendants of Sony HB-F1 and Panasonic FS-A1, have only 64KB RAM and occasionally had no mapper memory.
I have never seen 128KB RAM MSX2 except NMS8250 before. Sony F9000 and F7000 families are older than coming of MSX2 popularity in Japan, therefore you must recognize nobody (I know only one among 300 users) uses such 128KB or 256KB RAM MSX2s are here. In fact, they are regarded incompatible with later 2s. There is only one known NMS machine in Japan so forget about it.
WHEN YOU WANT TO SELL YOUR SOFTWARE FOR MSX2 WITH 128KB RAM OR BETTER, MAKE SURE TO LABEL IT AS "TURBOR ONLY" IN JAPAN. Otherwise, 2 or 2+ users would make errors of buying but being unable to play them, since Japanese users rarely modify their MSXes when compared to those not in Japan.
Acts of reading mapper registers were not completely held back through Japanese development scene - Microcabin did them in Fray turboR version and Illusion City. But do not imitate them!!
>Have you got any idea why NMSes do not cause "mapper RAM conflict"
>problems, which cause 1-megabyte GTs to hang up with certain European
>software? I heard because such software reads FC to FF in I/O port to
>detect mapper RAM locations, so cannot react to internally expanded
>memories.
MSX Engine in turbo R (S1990) only reports the lower 5 bits when mapper registers are read, the upper 3 bits are fixed at "1". 5 bits means 2^5=32 pages, 32*16K=512K. If more than 512K is present in turbo R, everything is all right when you only write to mapper registers. But when you read them, you only get the lower 5 bits of the actual page number.
Example:
Mapper port FE contains value 1 (&B00000001).
When read on NMS with 1024K mapper, &B11000001 is returned. The upper two bits are "1" because they are unused (1024K uses 6 bits in mapper register). If &B11000001 is written to mapper port FE, page 1 is selected because upper two bits are ignored as size is 1024K.
When read on turbo R with 1024K mapper, &B11100001 is returned. The upper three bits are "1" because MSX Engine only reports lower 5 bits. If &B11100001 is written to mapper port FE, page 33 is selected (33=&B100001).
This is the famous mapper conflict.
The solution to this is simple: do not read mapper ports. According to Alex Wulms, MSX standard disallows reading of mapper ports. Other people claim differently, but Alex has proven to be a reliable source many times before.
To make sure the value of a mapper register is known when it's needed, the value should be stored directly after a write to a mapper port. This is the same mechanism used for VDP ports, which are also read-only.
DOS2 does everything the way it should be done. Because of this, some programs don't work under DOS2, because they don't use DOS2 mapper routines to switch pages but write to mapper registers directly. In such a case DOS2 doesn't know that a new value is written and continues to use its own (now invalid) copy of the mapper register contents.
There is a program to make such ill-behaving programs work under DOS2: MAP.COM. It modifies DOS2 routines in such a way that they read the mapper registers. This may make some badly written programs work under DOS2 on some machines. But on a 1024K turbo R the result is no program which uses the mapper, either written good or bad, will run anymore!
The attitude of many Dutch programmers is: "MAP.COM works fine on all machines I've ever seen, so I use it in all my own programs". This is mistaking a remedy-for-some-machines for an actual solution of the problem. I really hate that kind of attitude...
On Nov. 6, 1997,Taro, the software developer for famous MEGA-SCSIs, pointed out as following in reply to above article.
*Isn't the term "page" used throughout, in fact, "segment"??
*About memory mappers on Japanese MSX2 or MSX2+ machines
Previous article states that, Japanese MSX2s and MSX2+s with RAM size of 64KB are not equipped with memory mappers. However, in fact, 2s of Panasonic FS-A1F and later, HB-F1XD or later (or was it XDJ the 2+ or later?) and WAVYs have 64KB memory mapper. If you read mapper registers in these machines, they only return a few (exact figures vary depending on machines) of lower bytes.
Therefore, software which illegally read mapper register I/O ports, do not run on these machines if you connect expansion mapper memory cartridges to them.
*About initial values in mapper registers
Caution:
This section is true only in case MSX-DOS1 (Disk BASIC v1.x) is running. In case of MSX-DOS2 (Disk BASIC v2.x), you should NEVER read nor write mapper register I/O ports; you should use specified mapper BIOS to switch memory mappers.
In MSX2 or later, after an MSX is resetted, it writes values 0,1,2,3 to FFh, FEh, FDh and FCh of I/O ports respectively, whether it is equipped with a memory mapper or not. Therefore, at the time of boot, any software can safely assume these as true values, without needs to reading mapper registers to check.
And at the same time, when a software quits its execution, it should adjust values of mapper registers back to these figures, so the software which runs after it can run safely with this same assumption.
However, this method cannot enable running of more than one software which are based on different running procedures SIMULTANEOUSLY on MSX-DOS1. (e.g. "resident" programs which run all times) Sadly, ASCII did not standardize any method to solve this. Those software should make some mutual deal about mapper segment numbers they use and how to exchange values in mapper register between themselves to run together.
In MSX-DOS2, methods to put (not write) or to get (not read) values of memory mapper registers, and a mean to allocate mapper segments without being interfered, are standardized as mapper BIOS, so if software are coded properly you can run more than one of them on MSX-DOS2 (this does not mean so-called multitask is possible, mind you).
;An example of a program which uses mappers under MSX-DOS1
;(MSX standard prohibits writes/reads to mapper registers in page 3)
Mapper_FE:
defb 1
Mapper_FD:
defb 2
Mapper_FC:
defb 3
Save_FE:
defb ?
Save_FD:
defb ?
Save_FC:
defb ?
;
Get_mapper_page2:
ld a,(Mapper_FE)
ret
Put_mapper_page2:
ld (Mapper_FE),a
out (0FEh),a
ret
...
Start_of_Program:
ld a,(Mapper_FE)
ld (Save_FE),a
ld a,(Mapper_FD)
ld (Save_FD),a
ld a,(Mapper_FC)
ld (Save_FC),a
...
End_of_program:
ld a,(Save_FE)
out (0FEh),a
ld a,(Save_FD)
out (0FDh),a
ld a,(Save_FC)
out (0FCh),a
ret
To one of the doubt which these facts suggest, Niga, known as hardware modification expert, replied as following.
>Weren't turboRs built without expecting memory expansions?
Yes, they should have expected to some degree. ST had 512K RAM in mind upon its production, as long as I see its substrate (however, 1 MB ST was not expected at its design stage, it looks), GT probably had 1MB in consideration. The proofs are existence of patterns for empty DRAM and jumper resistors in ST. In case of GT, existence of jumper lines which is estimated as to expect 1MB RAM. However, custom chips like S1990 and R800 were designed during ST time, so there is a possibility that their considerations are limited to 512KB of memory, which was expected with ST.
But, as you know, reading mapper registers is an act forbidden by mapper register, so you can hardly blame the designers when bugs occur by transgressing this rule. This is what software makers should keep themselves tight about.
This might not help you a lot, anyway, my opinions are something like these.
Taro's objection is correct, the part he pointed out to your notice that an A1F (MSX2). Unquestionably, internal memory of A1F is mapped. Mapper registers are not included within S1985 the MSX engine (I found correspondent pins unused) though, but seem to reside in one of other custom chips. Note A1mkII, the MSX2 of same era, was not mapped.
By the way, you told me Ninjinkuns do not work with internally expanded memories. Is this because it reads mapper registers, too?
Or might it work on 512KB WX...?
Also, Yoshimatsu TUQ who has enough experiences in reverse-engineering non-Japanese software, insists following knowledge is inevitable.
* Why you should not read mapper registers
Mapper registers exist independent for each slots which contain RAMs. Therefore, if there are more than 2 mapper RAMs and their sizes differ, they may try to return different values at same time. Then you will end up reading their values mixed up. (this is the "conflict")
You cannot learn their values independently.
This is why mapper registers are regulated not to be read.
Also, a mapper RAM which you cannot read its value is possible to exist.
You cannot run a software which runs mapper register values properly even if you try to increase RAMs of mapped machines (turboRs, all MSX2+s and a few of ancient MSX2s) using external cartridges like AddRAMs and Ukkarikuns. In this case, you have no other options than modifying MSXs themselves to run such software.
For instance, while I could not run a demo which requires 512KB RAM on an unmodified ST with an expansion cartridge, it ran on a F1-XD (an MSX2 without mapper RAM) with an 1MB RAM cartridge.
Without DOS2, using mapper RAM is like this: "I write to all segments I like and just hope there is no valuable information in them".
> My documentation states that if you are a good behaving child,
> you must (1) write to an address in the segment (2) read it
> (3) compare; if same, then you're given permission. It's
> natural they did what bad children did.
That's probably the algorithm to search for memory.
But it's not sufficient to prevent you from overwriting existing data in segments. It only makes sure that there is actually RAM at that address. Also most mappers have a wrap-around behavior. For example, NMS with 128K has 8 16K pages. When page 8 is used, result is page 0. When page 9 is used, result is page 1. Etc. This makes detection of mapper size not a straightforward task.
ポルトガル語版はこちら
最終更新日:平成9年11月28日
MAP.COMをダウンロードする(警告:これは解析以外の用途に使わないで下さい)
このページは、ある海外及び国内のプログラマーさんたちの意見に基づき、開発者の頭痛の種である「マッパー競合」問題に対しての解決策を提示します。日本外の開発者によって作られたソフトが、日本のRAM拡張済みMSXでは故障するという、製作された国では発生しない事態によって、これは近年大変重大な問題になりつつあります。これにより、そういったソフトをまとめて「国外追放」しようという強い動きすら発生しています。
日本のMSXの殆どは、パナソニックの A1-ST(256KB)及びGT(512KB)らのターボRです。全ての日本のユーザーの内75%が持っています。現在残っている開発者のほとんど全てがターボRを持っていると考えて差し支えないでしょう。
他のマシンの多くは、ソニー製 F1-XDJやXV、クロックアップを備えたパナソニックA1-WXやWSX、及び日本では比較的まれなサンヨーのWAVYといった2+です。これら全ての2+及び、それ以外の、ソニーHB-F1とパナソニックのFS-A1の末裔であるMSX2は、RAMを64KBしか積んでおらずしばしばマッパメモリは持っていません。
私は、
RAMが128KBのMSX2は、NMS8250以外には見たことがありません。ソニーのF9000やF7000系は、MSX2が日本で普及する以前のものなので、そういった128KBもしくは256KBのRAMを備えたMSX2は日本では誰も(私の知っている限り300人中1人しか)使っていないという事実を皆さんは認識する必要があります。実際、それらの機種は、後期のMSX2とは互換性がないとみなされています。NMS機は、日本では知られている限り一台しかありませんので考慮しないで下さい。
RAM128KB 以上のMSX2用のソフトを売る場合は、日本国内では必ず「ターボR専用」と銘打つ用に心がけてください。そうしない限り、MSX2もしくは2+のユーザーが間違って買ってしまったが遊べないという過ちを起こすことになります。日本のユーザーは、海外に比較するとはるかに自分のMSXを改造する事が少ないからです。
マッパーレジスターを読むという行為は日本の開発状況の中で常に抑制されていたわけではありません。マイクロキャビンは「フレイ」ターボ R専用版と「幻影都市」でやりました。それでも真似はしないようにして下さい。
> なぜ、「マッパーRAM競合」問題によって、1メガ拡張済みのGTが、一部のヨーロッパ製のソフトで暴走
> するにも関わらず、NMS機ではそういった問題が起きないのか見当が付きますか?聞いた話によるとそう
> いったソフトは、マッパーRAMの場所を検知するためにI/OポートのFCからFFを読むため、内部拡張し
>
たメモリーには対応出来ないそうなのですが。
ターボR中の
MSXエンジン(S1990)は、マッパレジスターが読まれた時、下位5ビットしか報告しません。上位3ビットは「1」で固定されたままなのです。5ビットということはすなわち2の5乗イコール32ページ。32かける16キロバイトすなわち512キロバイト。512キロバイト以上がターボR機中に存在している場合でも、マッパレジスターに書くだけなら何も問題はありません。しかしそれを読んでしまった場合、得られるのは実際のページ番号の内下位5ビットだけになってしまいます。
例:
マッパポート FEには、1という値(&B00000001)が格納されているとします。
1024 キロバイトマッパラムを積んだNMS機でこれを読むと、&B11000001 が返ってきます。上位2バイトは「1」です。なぜならそれらは使われていないからです(1024キロバイトの場合、マッパレジスター中の6ビットを使用します)。値&B11000001をマッパポートFEに書きこむと、ページ1が選択されます。なぜなら、上位2ビットは、サイズが1024キロバイトであることを考慮して、無視されるからです。
これが 1024キロバイトマッパラムを積んだターボRで読まれた場合は、&B11100001が返ってきます。上位3ビットは「1」です。なぜならMSXエンジンが下位5ビットしか報告しないからです。値&B11100001をマッパポートFEに書き込むと、ページ33が選択されてしまいます(33=&B100001)。
これが、有名なマッパ競合です。
これに対する解決策は単純です。マッパポートを読まなければいいのです。
アレックス・ウルムスさんによれば、MSX規格ではマッパポートを読むことは禁じられています。違う意見を述べている方も一部いるようですが、アレックスさんは過去何回も信用出来る情報源として証明付きです。
マッパレジスターの値を必要な際に分かるようにするためには、マッパポートに値を書き込んだ直後にその値を保存しておかなければなりません。これは、同じくリードオンリーである
VDPポートと同じ方法論によります。
DOS2
は、何もかも、やらなければならないとされている方法でしか行いません。このため、いくつかのプログラムはDOS2下で動作しません。なぜなら、そういったソフトは、ページを切り替える際にDOS2マッパルーチンを使用しないで直接マッパレジスターに書き込んでいるからです。こういう事をすると、DOS2は新たな値が書き込まれたことを知らずに自分で控えておいた、今となっては無効なマッパレジスターの内容を元にして続行してしまいます。
そういった不良動作をするプログラムを
DOS2下で動かすために、MAP.COM というプログラムが存在します。これは、DOS2ルーチンを、マッパレジスターを読むように改造するものです。これによって、一部の機種ではその手の杜撰に書かれたプログラムをDOS2下で動かせるように出来ることもあります。しかしながら、1024キロバイトのターボRでやるとその結果、マッパを使ったプログラムは良く出来ていようが杜撰だろうが、もう絶対に走らなくなってしまうのです。
オランダの多くのプログラマー達の傾向は、「俺の見てきたどの機種でも MAP.COMは問題なく動いてきたから、自分のプログラムでは全部使っちゃおうっと」というものです。一部の機種への対策を、問題の根本的な解決と取り違えているのです。私が大嫌いなのはこういった傾向なのですが...
上記の記事に対し、あの有名なMEGA-SCSI用ソフトの開発を行っておられるたろうさんより、以下の指摘がありました。
・一貫して使われている「マッパ」という用語は「セグメント」の事ではないでしょうか?
日本製MSX2、MSX2+のメモリマッパ搭載について
上の記事では日本製のRAM容量が64KBのMSX2・MSX2+にはメモリマッパが搭載されていないとありますが、厳密に言うとFS-A1F以降やHB-F1XD(XDJだったかも)以降やWAVYには、64KBのメモリマッパが搭載されて います。これらの機種のマッパレジスタI/Oを読み込んだ場合、機種によって少々異なりますが、どの機種も下位数ビットしか通知されません。
したがって、これらの機種に増設マッパメモリカートリッジを接続した場合、マッパレジスタI/Oを不正に読み込んでいるソフトウェアは動作しません。
・マッパレジスタの初期値について
注意 :
これは
MSX-DOS1(Disk BASIC v1.x)が動作している場合にのみ当てはまります。MSX-DOS2(Disk BASIC v2.x)の場合には、マッパレジスタのI/Oポートの読み書きを一切行ってはいけません。所定のマッパBIOSを用いてメモリマッパの切り替えをしなければなりません。
MSX2
以降では、メモリマッパの有無にかかわらず、リセット時にI/OポートのFFh,FEh,FDh,FChにそれぞれ0,1,2,3の値が書き込まれます。したがって、ソフトウェア側は起動時にマッパレジスタのI/Oポートを読むことなしにこれらの値を仮定して構いません。
また、次に動作するソフトウェアがこの仮定をしても大丈夫なように、動作を終了する時にはマッパレジスタを再びこの初期値に戻す必要があります。
ただし、この方法では別々に作られた複数のマッパを使用するソフトウェアをMSX-DOS1上で*同時に*動かすことができません。(例えば常駐するソフトウェア) 残念ながら、これを解決するためのアスキーによって規格化された方法はありません。各ソフトウェア同士で、自分が使用しているマッパセグメントの番号や現在設定されているマッパレジスタの値を交換する方法についてあらかじめ取り決めておくしかありません。
MSX-DOS2ではメモリマッパレジスタに値を設定(書き込むではない)したり値を取得(読み込むではない)する方法や、マッパセグメントの排他的な確保の方法がマッパBIOSとして規格化されているので、正しく組まれたソフトウェアなら複数を同時に動かすことが可能です。(マルチタスクが可能という意味ではありません)
;MSX-DOS1における正しいマッパ使用プログラムの例;(MSX規格では、ページ3のマッパレジスタの読み書きは禁止されている)
Mapper_FE:
defb 1
Mapper_FD:
defb 2
Mapper_FC:
defb 3
Save_FE:
defb ?
Save_FD:
defb ?
Save_FC:
defb ?
;
Get_mapper_page2:
ld a,(Mapper_FE)
ret
Put_mapper_page2:
ld (Mapper_FE),a
out (0FEh),a
ret
...
Start_of_Program:
ld a,(Mapper_FE)
ld (Save_FE),a
ld a,(Mapper_FD)
ld (Save_FD),a
ld a,(Mapper_FC)
ld (Save_FC),a
...
End_of_program:
ld a,(Save_FE)
out (0FEh),a
ld a,(Save_FD)
out (0FDh),a
ld a,(Save_FC)
out (0FCh),a
ret
これらの事実から生じる疑問に対し、ハードウェア改造の熟練者と知られる にがさんは次のように答えています。
>そもそもターボRって拡張する事 を予測した設計にはなっていないのでは
>ないでしょうか。
いえ、ある程度の拡張は想定されているはずです。少なくとも基板を見る限り、STでは512Kまで考えて作られていますし(しかし、STの1Mは設計段階では想定されていないようです)、GTは1Mも考えて作っているでしょう。根拠はSTの空きDRAMパターンと、ジャンパー抵抗などのパターンの存在。GTでは同様に1Mを想定したと思われるジャンパーの存在あたりです。ただ、カスタムチップのS1990やR800はSTの時代に設計された物なので、これらがSTで想定されているメモリー512Kまでしか考えていないということも有りうるかもしれません。
ただ、御存じのようにMSXではマッパーレジスタを読むことは禁止されている行為なので、これを犯した時に出るバグについては、設計側の責任とは言えないでしょう。ソフトを作る側が気を付けるべきことですね。
あんまりお役にたてませんでしたが、まぁ、私の考えとしてはこんなところです。
記事中にたろうさんが指摘された「A1F(MSX2)がマッパーを持っていない」と書かれていることに対する突っ込みは正しいです。A1Fは間違いなく内部のメモリーはマッパー仕様です。ただし、マッパーレジスタはMSX2エンジン「S1985」に内蔵されたものではなく(該当ピンが未使用だった)、他のカスタムチップにあるようです。ちなみに同時代のMSX2である「A1マーク2」はマッパー仕様ではありませんでした。
そういえば、 人参君は内部増設メモリーでは動かないんでしたよね。あれもやはりマッパーレジスタを読んでいるからなのですか?
WXの512Kだったら動くのかな・・・。
また、海外ソフトの解析の経験が豊富な
よしまつTUQさんは、以下の知識が必要であると述べています。
・マッパレジスタを読んではいけない理由
マッパレジスタは、RAMのあるスロットごとに独立しています。なので、2つ以上マッパRAMがあるときにそれぞれが違った容量を持っていると値を読んだときに違う値を同時に返そうとすることがあります。 すると、それらの値がごっちゃになって読み込まれます(これが「競合」です)。
それぞれの値を別々に知ることはできません。
だから、マッパレジスタは読めないように規定されているのです。
また、値を読めないマッパRAMも存在しえます。
マッパRAMを搭載したマシン(tR、MSX2+全部と、昔の一部のMSX2
)で外付けの「AddRAM」や「うっかりくん」で増設しても、マッパレジスタの
値を読んでいると正常に動作しません。 こういったソフトでは、本体改造する他に動かす手だてはありません。
たとえば、無改造のSTでは増設しても512KB必要なデモが動かなくて、F1−XD(マッパRAM非搭載のMSX2)に1MBのRAMをつけた場合は動きました。
マッパ
RAMの適切な使用は、MSX-DOS2の登場が余りにも遅すぎた以上、無理があったと主張するマールテン・フゥルネさんは、さらなる警告を加えます。
DOS2なしでは、マッパRAMを使うというのは、「俺は好きなセグメントに書きませてもらうぜ、その中に重要な情報は含まれていない事を期待しよう」というのと同じです。
>私の持っている記述には、良い子は(1)セグメントのとあるアドレスに
書き込む(2)それを読み出す(3)比較する。もし同じなら、許可します。
>と書かれています。悪い子のような事をしたのは当然でしょう。
それは、メモリーを調べ出すアルゴリズムでしょう。
しかしながら、セグメント中に存在するデータを上書きするのを防ぐにはそれでも十分ではありません。これで確認出来るのは、そのアドレスにRAMが実在するかどうかということだけです。また、多くのマッパは循環性を持っています。例えば、128KBのNMS機は、8つの16Kのページを持っています。ページ8が使われようとすると、結果はページ0となります。ページ9が使われようとすると結果はページ1となります。というわけで、マッパ容量の検知は単純明快な仕事ではなくなるわけです。