Continuing from last week, this week I mostly focused more on prepping for our evoke liveshow! Specifically, I implemented
midiLastNote, which yields the last note value that came from a note on message through a specific port (so we can do eg.
part = midiLastNote("Akai MPD26") - 36) and worked on "unrigging" cameras/sync etc from various scenes from our demos and making them just play on their own. This turns out to be quite boring work, but just blasting through it appears to be going pretty well and I'm starting to get pretty stoked about the show!
Other than that I didn't do that much on personal projects, except a couple clever MSX things. For example, I solved the mem mapping problem enough with a very simple solution.
You see, many MSX2 demos actually ship as disk images, where the disk contains both the demo itself, and MSX-DOS (usually MSX-DOS2 specifically). What's nice about this is that the MSX machine will automatically boot into MSX-DOS from the disk if the disk is inserted before the machine powers on, and then it will go ahead and run
AUTOEXEC.BAT if present which starts the demo. This is very convenient because MSX-DOS requires the full 64k address space to be visible to run, so having the demo as an MSX-DOS executable ensures a consistent environment memory-wise without having to mess with mappers and/or mem searches.
However, this solution isn't perfect. MSX-DOS has some licensing problems in that nobody seems to agree whether or not it's ok to distribute it in the first place. MSX-DOS2 doesn't have this licensing restriction, but requires 128kb RAM to run (which I now believe is why many MSX2 demos require 128kb RAM in the first place!), so in my case, that doesn't work (my machine only has 64kb RAM, something that's common of Japanese MSX2 machines). Additionally, running MSX-DOS further contrains which parts of the MSX address space is available at runtime in order to properly support the OS (although granted this can be trashed if we don't want to cleanly return to the OS and the actual routines from MSX-DOS aren't used, but yeah).
Since MSX-DOS doesn't really add much value the way I see it beyond mem mapping (the actual disk I/O is implemented at a lower-level in the on-system disk ROM's anyways and are always available), I dug a bit deeper to see if there's any way we can take advantage of its mem mapping without having to bundle it with the demo. MSX-DOS is really just two files -
MSXDOS.SYS, the main OS, and
COMMAND.COM, the interactive command-line processor. If these files are present on a typical MSX-formatted floppy disk, the default bootsector on the disk will automatically load and run
MSXDOS.SYS on startup, thus initiating the OS bootstrapping process. But are there more details here that can help us understand the process here? Is the address space mapped to RAM before or after this?
MSX-DOS is invoked by the following procedure: 1. Resetting MSX causes all the slots to be examined first, and when two bytes, 41H and 42H, are written in the top of the examined slot, the slot is interpreted as connected to a certain ROM. When connected with ROM, the INIT (initialize) routine whose address is set to the header portion of ROM is carried out. In the case of the INIT routine of the disk interface ROM, the work area for the drive connected to the interface is allocated first. 2. When all slots have been examined, FEDAH (H.STKE) is then referred to. Unless the contents of this address is C9H (unless a certain routine is set to the hook of H.STKE during INIT routine), the environment for DISK-BASIC is prepared and execution jumps to H.STKE. 3. When the contents of H.STKE is C9H in the examination above, the cartridge with TEXT entry is searched in each slot and, if found, the environment for DISK-BASIC is prepared, and then the BASIC program at the cartridge is carried out. 4. Then, the contents of the boot sector (logical sector #0) is transferred to C000H to C0FFH. At this time, when "DRIVE NOT READY" or "READ ERROR" occurs, or when the top of the transferred sector is neither EBH nor E9H, DISK-BASIC is invoked. 5. The routine at C01EH is called with CY flag reset. Normally, since code "RET NC" is written to this address, nothing is carried and the execution returns. Any boot program written here in assembly language is invoked automatically. 6. RAM capacity is examined (contents of RAM will not be destroyed). Less than 64K bytes causes DISK-BASIC to be invoked. 7. The environment for MSX-DOS is prepared and C01EH is called with a CY flag set. MSXDOS.SYS is loaded from 100H, and the execution jumps to 100H. After this, MSX-DOS transfers itself to a high order address. If MSXDOS.SYS does not exist, DISK-BASIC is invoked. 8. MSXDOS.SYS loads COMMAND.COM from 100H and jumps to its start address. COMMAND.COM also transfers itself to a high order address and then begins to execute. If COMMAND.COM does not exist, the message "INSERT A DISKETTE" appears and the execution waits for the correct diskette to be inserted in the drive. 9. At the first boot for MSX-DOS, when a file named "AUTOEXEC.BAT" exists, it is carried out as a batch file. When MSX-DOS is not invoked and DISK-BASIC starts, if a BASIC program named "AUTOEXEC.BAS" exists, it will be carried out.
Aha! Now, ignoring most of these steps, we have some critical information here: According to steps 6 and 7, the environment for MSX-DOS is prepared before
MSXDOS.SYS is loaded. This means before the system even touches MSX-DOS, we have 64k of RAM visible on the machine (note that I'm assuming we have an MSX2 with more than 64k of RAM, but this is required by the MSX2 standard).
Additionally, we can assume that
MSXDOS.SYS is loaded by file name, since we don't have to do any special disk preparation to put MS-DOS on a disk - we just put
COMMAND.COM on the disk, and it's supposed to work! Additionally,
MSXDOS.SYS will be loaded to a specific address in memory, and then assume full control of the system. Are you seeing where I'm going with this? :)
So, my solution is very simple. We drop MSX-DOS altogether and call our demo file
MSXDOS.SYS! This way, it will be loaded by the default bootsector into an environment with 64k RAM visible, and a system and disk BIOS initialized by the system. This works quite well so far; I haven't done extensive testing with which mem we can/can't use, whether or not the disk routines can load into mem under the disk ROM area, etc, so it will need some more investigation - but I like this solution, as it gets around the mem locating/visibility issues we had to solve, as well as avoiding licensing problems with other solutions.
Note that we could have also made our own custom bootsector that would load another filename, but keeping the default one makes it easier to build the disk, and if somehow the demo ended up being distributed as just the demo files, it would make it trivial for a user to make their own disk by just putting the files onto a normally-formatted MSX-DOS disk.
After implementing that solution I proceeded to play with the available disk ROM commands (after some tips from the guys at #msxdev, a quite helpful bunch!) and even got the system to load a message from disk and display it on the screen. However, it looks like we'll be quite limited in terms of actually doing any useful disk loading during the demo, but I'll have to play more with that too :) .
Until next time!
Last Edited on Wed Aug 16 2017 05:49:30 GMT-0400 (EDT)