Virtual MSX diskdrive via joystick port

By RvS

Supporter (5)

RvS's picture

15-02-2019, 21:45

For a long time I have been playing with the idea of creating a virtual disk drive for my MSX (NMS8245).
The idea was to divert all disk calls to a small driver that routes all requests to an Arduino that is connected to the joystick port. The Arduino is connected (via USB) to my computer that hosts several disk images.
In theory, it should be possible to do this without any hardware modification to the MSX and it should be 'low cost', as all you would need is an Arduino (nano), a sub-d9 connector and a few wires.

I believe I have something working right now for my MSX. I can read/write at reasonable speed (~10kB/s) in Basic and partly in MSX-DOS.
I got it working by diverting the $4010 BDOS call (read/write sectors). This routine (in my diskrom) makes a call to RAM $F365 to read the primary slot register. I hijack this call and check if the call originates from $4010 by comparing stack.
If it is a $4010 call, it triggers the Arduino and this retrieves the data from the connected PC.
The current code is listed here:

Plenty of issues though:

  • The 'driver' occupies the 'PLAY' buffer, so using the PLAY command will kill it.
  • CALL FORMAT will fail as well, not entirely sure what goes wrong there.
  • Programs that use the second joystick port or the mouse might give issues as well.
  • The Arduino uses polling to check the MSX joystick pins, it might miss one, an interrupt version is in the making.
  • Currently, it is tuned to my diskrom. I would like to make a 'universal' driver. Help is welcome!

Login or register to post comments

By Vampier

Prophet (2272)

Vampier's picture

16-02-2019, 00:47

I've been thinking about something like this for transferring big files to openMSX. Interesting hardware and software combination for a real world MSX Big smile

By zPasi

Champion (292)

zPasi's picture

01-03-2019, 16:07

I had a similar idea some years ago, but then forgot about it. Without a real disk drive I would have to load the driver for that from a cassette. And with a disk drive, I wouldn't need that thing anymore Smile

But might adapt the idea for network access or something!

Why is that 74LS07-chip there? If the Arduino is 5V, should work without it as well?

By Manuel

Ascended (15117)

Manuel's picture

01-03-2019, 22:09

Reminds me of the nowind cartridge. Which is very cool.

By Wlcracks

Champion (283)

Wlcracks's picture

02-03-2019, 15:56

Some MSX computer have unbuffered joystick interfaces direct to engine or psg. Hot inserting or floating grounds can easily blow the input protection circuits and leave them hi-or low forever. If you like your joystick or other i/o always use a buffer or at least serial resistor networks.

By zPasi

Champion (292)

zPasi's picture

02-03-2019, 19:16

Wlcracks wrote:

Some MSX computer have unbuffered joystick interfaces direct to engine or psg. Hot inserting or floating grounds can easily blow the input protection circuits and leave them hi-or low forever.

I see.

But the i/o-pins of Arduino cannot output much currrent anyway. Doesn't the buffer chip make thing worse?

By RvS

Supporter (5)

RvS's picture

02-03-2019, 20:13

Hi, the 7407 is an ‘open collector’ buffer. I use it to protect my msx from configuration errors that I could make with the arduino. In theory you should be able to connect the arduino directly to the port but I would always use either resistors or a buffer to make sure you do not short circuit parts of the msx engine.

By RvS

Supporter (5)

RvS's picture

02-03-2019, 20:25

Disks are getting rare and proper drives as well. I want to add a SD card to the arduino so it can be used stand-alone.
Meanwhile I also added a tape-out (audio) part to the arduino so you can bload”cas:”,r the driver. Smile
For no-disk systems, I could work on some kind of loader.
The network part is interesting though.


Enlighted (5173)

NYYRIKKI's picture

02-03-2019, 23:08

I've also played a bit with similar ideas... I was making disk ROM for Sunrise IDE+RS232 cartridge that would have used the RS-232 for communication, but then Nowind was released before I got rid of loading errors and I thought that buying it solves my problem without need for debugging. It was anyway quite different project as I planned to flash the software to the cartridge it self and use RS-232 directly.

Later I also used Joystick port connected Arduino to transfer individual ROM-files to MSX memory... The idea was that you don't need any mass storage system, but you just need to write a little BASIC program to get started...


... after that it replaced the protocol with a bit faster one for actual ROM delivery. I was streaming the files from PC HDD but while talking with PC I just noticed that there are huge differences in RS implementations between different Arduino models. On some Arduinos my super simple protocol practically just failed miserably and became terribly slow... I guess it was related to how FIFO-buffers work over USB layer.

My last idea was that I connect SD-card directly to joystick port... but you would need to do voltage conversion anyway as those work with 3.3V logic... IIRC on eBay you can anyway buy SD-card holders that can do the conversion for you.

RvS wrote:
  • Currently, it is tuned to my diskrom. I would like to make a 'universal' driver. Help is welcome!

DiskROM is always a bit of a problem... Either you need to try to capture the traffic as you are now doing or then you need to implement your own ROM that requires space from bank 1... Practically this always means extra hardware of some sort as with disk you really need to reserve the existing RAM on page 1 for user.

I don't think any kind of universal driver is possible although you may manually come up with individual solutions for most of the disk ROMs. There are not many hooks you can use to catch the execution and the content of registers or stack is not guaranteed at all... You may even need to calculate some values back from custom formats etc. I must say it is kind of sad that there is no standard hook for disk I/O.

By RvS

Supporter (5)

RvS's picture

13-03-2019, 22:36

I have created a snipped of code that can check a hook if it is suitable. The 2 possible options are FFCF and F365.
If the registers HL,DE,B(C),A and carry can be found, it should work. With this it should be easy to check if the system works.

10 FOR I=&H9000 TO &H9081
20 READ A$: POKE I,VAL("&h"+A$)
40 H=&HF365:T$="    "
50 POKE &H9082,(H AND 255): POKE &H9083,((H AND &HFF00)/256) AND 255
60 DEFUSR=&H9000: A=USR(0)
70 CLS: S=&H9086: O=32: WIDTH 40
80 PRINT "Stack trace for disk call"
90 PRINT "Use an empty disk that is not protected"
100 PRINT "XX even for read, uneven for write."
140 FOR I=S TO S+O-1 STEP 2
150 R=PEEK(I)+PEEK(I+1)*256
160 W=PEEK(I+O)+PEEK(I+O+1)*256
170 R$=RIGHT$("0000"+HEX$(R),4)
180 W$=RIGHT$("0000"+HEX$(W),4)
190 READ A$:PRINT R$+T$+W$+T$+A$
200 NEXT I
210 DATA F3,3A,48,F3,32,7C,90,2A,82,90,22,4F,90,CD,51,90
220 DATA 21,86,90,22,84,90,B7,CD,6D,90,F3,CD,51,90,21,A6
230 DATA 90,22,84,90,37,CD,6D,90,FB,C9,F5,E5,D5,C5,21,00
240 DATA 00,39,ED,5B,84,90,01,20,00,ED,B0,21,C6,90,ED,5B
250 DATA 82,90,06,00,3A,80,90,4F,ED,B0,C1,D1,E1,F1,C3,00
260 DATA 00,2A,82,90,06,00,3A,80,90,4F,11,C6,90,ED,B0,11
270 DATA 2A,90,2A,82,90,3E,C3,77,23,73,23,72,C9,21,00,92
280 DATA 11,00,00,06,04,3A,81,90,4F,3E,00,F7,8F,10,40,C9
290 DATA 03,F9
300 DATA "BC:04F9","DE:0000","HL:9200","AF:00XX",-1,-2
310 DATA -3,-4,-5,-6,-7,-8,-9,-10,-11,-12

By RvS

Supporter (5)

RvS's picture

13-03-2019, 22:41

The program reads and writes the first 4 sectors of a disk.
Do not use this with your favorite/important disks because in case of an error, it could make the disk unreadable.
For single sided disks, change 'F9' in line 290 into 'F8'

My MSX profile