MSX-AUDIO programming
This page was last modified 20:53, 28 January 2022 by Grauw. Based on work by Mars2000you and Aoineko and others.


Hardware support

The Panasonic FS-CA1 is the only device which implements the MSX-AUDIO standard, in addition to newer devices like the Tecnobytes AudioWave and GR8NET, so this information only applies to those.

The Philips NMS 1205 and Toshiba HX-MU900 are incomplete MSX-AUDIO standard implementations that do not provide the MSX-AUDIO BIOS and BASIC, nor the configurable I/O ports and mapper. On these sound modules, the Yamaha Y8950 MSX-AUDIO sound chip can only be accessed via direct I/O. Some people have modified these modules with an MSX-AUDIO BIOS.

For more information, see MSX-AUDIO.

MSX-AUDIO detection

Using BIOS

To find the MSX-AUDIO with MBIOS, you must read the bytes from 0080h to 0084h in the all slots. These bytes must contain the string "AUDIO".

Without BIOS

For sound cartridges without MBIOS (like the Philips NMS 1205 and Toshiba HX-MU900), you can detect the presence of the Y8950 chip by reading the value of the C0h I/O port. If you get 00h, 02h, 04h or 06h, then it’s likely that the Y8950 is present. The four values occur because bits 1 and 2 of the MSX-AUDIO status register are floating, they can read out as either 0 or 1. Mask these two bits out before comparing the value to zero: (in(0C0h) & 11111001b) == 0.

To confirm the presence of the Y8950, you should look for the presence of its ADPCM module, which differentiates the Y8950 from other OPL chips. You can achieve that by checking if starting ADPCM raises the PCM BUSY status flag.

Here the detection algorithm example used in VGMPlay:

MSXAudio_DATA_PORT: equ 0C1H

; f <- c: found
    in a,(MSXAudio_STATUS_PORT)
    and 11111001B
    ret nz
    ld de,10000000B << 8 | MSXAudio_ADPCM_CONTROL
    call MSXAudio_Detect_WriteRegister
    in a,(MSXAudio_STATUS_PORT)
    and 11111001B
    push af
    ld de,00000000B << 8 | MSXAudio_ADPCM_CONTROL
    call MSXAudio_Detect_WriteRegister
    pop af
    xor 00000001B
    ret nz
    ld a,e
    out (MSXAudio_ADDRESS_PORT),a
    ld b,8  ; wait 12 cycles
    djnz $
    ld a,d
    out (MSXAudio_DATA_PORT),a
    ld b,8  ; wait 12 cycles
    djnz $

For generic OPL chip detection, see: OPL programming

I/O ports

  • C0h = Register number for the master Y8950 (write only, 12 cycle of delay time)
  • C1h = Register data for the master Y8950 (write only for most registers, 84 cycle of delay time or 12 in data write mode column)
  • C2h = Register number for the slave Y8950 (write only, 12 cycle of delay time)
  • C3h = Register data for the slave Y8950 (write only for most registers, 84 cycle of delay time or 12 in data write mode column)

These I/O ports are configurable by writing one of the following values to address 3FFEh (bits 1-0).

	00 = Disable ports C0h~C3h. (Initial value)
	01 = Assign ports C0h~C1h to access the Y8950 registers.
	10 = Assign the ports C2h~C3h to access the Y8950 registers.
	11 = Assign ports C0h~C1h and C2h~C3h (For cartridge with two Y8950).

RAM/ROM mapper

MSX-AUDIO should include a 128kB ROM and 4kB work-RAM. The ROM is divised in 4 segments of 32kB. These are mapped in the same slot as described below.

The memory map is as that:

Page 0000h~2FFFh = MBIOS (fixed)
Page 3000h~3FFFh = 4kB RAM from the MSX-AUDIO cartridge (fixed)
Page 4000h~BFFFh = Selected segment (0 by default)

Following segments are selectable by a writting at 3FFFh (bits 1-0) in MSX-AUDIO slot. This switching address is mirrored at 7FFFh.

  • Segment 0 contains the MSX-AUDIO BASIC extension (4000h~6FFFh) and the 4kB RAM mirror (7000h~7FFFh)
  • Segment 1 is the Custom firmware (4000h~BFFFh)
  • Segment 2 is ADPCM data 1 (4000h~BFFFh)
  • Segment 3 is ADPCM data 2 (4000h~BFFFh)


MSX-Datapack translation: