Previous Thread
Next Thread
Print Thread
Page 41 of 80 1 2 39 40 41 42 43 79 80
Joined: Feb 2014
Posts: 1,102
Likes: 173
G
Very Senior Member
Offline
Very Senior Member
G
Joined: Feb 2014
Posts: 1,102
Likes: 173
More silly fun:

You midi guys would know all of this stuff, but I just discovered the virtual midi piano keyboard (vmpk) and it's pretty cool if you don't have a real midi keyboard handy.

./mame64 apple2p -sl2 midi -verbose -flop1 ../../Passport\ designs\ -\ Master\ tracks\ v1.8.dsk -snapsize 560x384 -debug -midiout "VMPK Input" -midiin "VMPK Output" -log

I also installed fluidsynth for linux so I can get some midi sounds too.

Now I get a bunch more items when I listmidi:

Code
./mame64 apple2e -listmidi

MIDI input ports:
Midi Through Port-0 (default)
Portable Grand MIDI 1 
VMPK Output 

MIDI output ports:
Midi Through Port-0 (default)
Portable Grand MIDI 1 
Synth input port (20027:0) 
VMPK Input 
qjackctl 

./mame64 apple2p -sl2 midi -verbose -flop1 ../../Passport\ designs\ -\ Master\ tracks\ v1.8.dsk -snapsize 560x384 -debug -midiin "Virtual Keyboard" -log -midiout "Synth input port (20027:0)"

On ubuntu, just "sudo apt install vmpk fluidsynth" and get a soundfont2 from the net (I got the General User one)

[Linked Image from i.imgur.com]


Joined: May 2006
Posts: 148
Likes: 4
F
Senior Member
Offline
Senior Member
F
Joined: May 2006
Posts: 148
Likes: 4
[Linked Image from firehawke.sanctuarycrew.com]
This is a glaring omission that has now been corrected. I'll PR this addition tonight.

Joined: Feb 2014
Posts: 1,102
Likes: 173
G
Very Senior Member
Offline
Very Senior Member
G
Joined: Feb 2014
Posts: 1,102
Likes: 173
Hi Arbee,

I was looking at how mame hooks up to the midi with portmidi src/osd/modules/midi/portmidi.cpp and it seems that it doesn't pass the 1 byte messages through like F8 (timing clock).


Code

int osd_midi_device_pm::read(uint8_t *pOut)

...

                                case 0xf:   // system common
                                        switch (status & 0xf)
                                        {
                                                case 0: // System Exclusive
                                                {
                                                        *pOut++ = status;   // this should be OK: the shortest legal sysex is F0 tt dd F7, I believe
                                                        *pOut++ = (rx_evBuf[msg].message>>8) & 0xff;
                                                        *pOut++ = (rx_evBuf[msg].message>>16) & 0xff;
                                                        uint8_t last = *pOut++ = (rx_evBuf[msg].message>>24) & 0xff;
                                                        bytesOut += 4;
                                                        rx_sysex = (last != MIDI_EOX);
                                                        break;
                                                }

                                                case 7: // End of System Exclusive
                                                        *pOut++ = status;
                                                        bytesOut += 1;
                                                        rx_sysex = false;
                                                        break;

                                                case 2: // song pos
                                                case 3: // song select
                                                        *pOut++ = status;
                                                        *pOut++ = Pm_MessageData1(rx_evBuf[msg].message);
                                                        *pOut++ = Pm_MessageData2(rx_evBuf[msg].message);
                                                        bytesOut += 3;
                                                        break;

                                                default:    // all other defined Fx messages are 1 byte

                                                        *pOut++ = status;             // shouldn't we pass the 1 byte messages along?
                                                        bytesOut += 1;
                                                        break;
                                        }




Also if I read it correctly, 0xF3 (song select) should only supply 2 bytes (status + 1 data byte).


http://www.personal.kent.edu/~sbirch/Music_Production/MP-II/MIDI/midi_protocol.htm
http://www.personal.kent.edu/~sbirch/Music_Production/MP-II/MIDI/midi_system_common_messages.htm
http://www.personal.kent.edu/~sbirch/Music_Production/MP-II/MIDI/midi_system_real.htm

Joined: Mar 2001
Posts: 17,217
Likes: 234
R
Very Senior Member
Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 17,217
Likes: 234
Thanks! You missed a detail or two but it's fixed in GitHub top-of-tree now smile

Joined: Feb 2014
Posts: 1,102
Likes: 173
G
Very Senior Member
Offline
Very Senior Member
G
Joined: Feb 2014
Posts: 1,102
Likes: 173
Originally Posted by R. Belmont
Thanks! You missed a detail or two but it's fixed in GitHub top-of-tree now smile


Thanks, RB! I always miss those details 8-)

Joined: Feb 2014
Posts: 1,102
Likes: 173
G
Very Senior Member
Offline
Very Senior Member
G
Joined: Feb 2014
Posts: 1,102
Likes: 173
I think I've finally figured out why MasterTracks 1.8 was freezing after typing some midi keys, it's actually very subtle.

After setting up a new ubuntu system on a new laptop, I thought I'd download a fresh mame for experiments/mangling.

I totally forgot all about the typo in a2midi.cpp after a month or two of being busy with other stuff. (Yeah, I suppose I should read my own posts 8-)

(I mistakenly thought that this typo didn't make a difference)

https://github.com/mamedev/mame/blob/master/src/devices/bus/a2bus/a2midi.cpp

Code
WRITE_LINE_MEMBER( a2bus_midi_device::acia_irq_w )
{
	m_acia_irq = state ? true : false;

	if (m_acia_irq || m_ptm_irq)
	{
		raise_slot_irq();
	}
	else
	{
		lower_slot_irq();
	}
}

WRITE_LINE_MEMBER( a2bus_midi_device::ptm_irq_w )
{
	m_acia_irq = state ? true : false;                // should be m_ptm_irq

	if (m_acia_irq || m_ptm_irq)
	{
		raise_slot_irq();
	}
	else
	{
		lower_slot_irq();
	}
}


So how does the bug manifest itself?

You've got the 6840ptm and the 6850 acia both modifying the variable m_acia_irq.

The 6502 interrupt routine at $2572 (vector stored at $3FE/3FF) will first check the midi to see if there's data, if not the routine will check the timer and reset it by reading c0a1 and c0a4 which will clear the timer interrupt.

The problem comes in when you have midi data that comes in generating an IRQ while there's a timer IRQ as well. The 6840 routine update_interrupts() will only modify its IRQ variable on transitions from 0 to 1 or 1 to 0, so once it calls a2bus_midi_device::ptm_irq_w (true) and setting m_acia_irq to true it won't call it again.

But our interrupt routine processes the midi byte first, clearing the midi interrupt by reading $c0a9 and it calls a2bus_midi_device::acia_irq_w(false) which will set m_acia_irq to false.

This ends up dropping all interrupts for the timer so it will never update the clock.

It will keep processing the midi acia interrupts, but no timer processing will happen after this occurs.

I ended up disassembling a bunch of master tracks to figure out how it worked. I think I understand quite a bit more about the 6840 and the 6850 now. (the 6840 data sheet is really difficult to figure out)




Joined: Feb 2014
Posts: 1,102
Likes: 173
G
Very Senior Member
Offline
Very Senior Member
G
Joined: Feb 2014
Posts: 1,102
Likes: 173
Some more dumb fun seeing if I can read midi data from the 6850 ACIA with lua. (with a midi card in slot 2 -sl2 midi)

If I keep polling 0xc0a8 every 1/31250*10 seconds (1 second divided by the midi clock times 10 bits) I should be able to see all of the data bytes since one byte will arrive at this interval.

It's useful to me to see just exactly how the device behaves.

We'll just read 18 bytes and then exit the coroutine.

Code

mem=manager:machine().devices[":maincpu"].spaces["program"]
mem:write_u8(0xc0a8,19)  -- acia master reset CR0=1, CR1=1
mem:write_u8(0xc0a8,17)  -- set divider to 16 CR0=1, CR1=0
co1 = function() for i=1,18 do 
  status=mem:read_u8(0xc0a8)
  while (status&1)==0 do 
     emu.wait(1/31250*10) 
     status=mem:read_u8(0xc0a8) 
  end 
  data=mem:read_u8(0xc0a9) 
  if (status&0x20)~=0 then print ("OVERRUN ") end 
  print(string.format("status=%x  data=%x",status,data)) 
  emu.wait(1/31250*10) 
end end
myco1=coroutine.create(co1) ok,errormsg=coroutine.resume(myco1)


and you get something like this as output:

Code
[MAME]> myco1=coroutine.create(co1) ok,errormsg=coroutine.resume(myco1)
status=3  data=45
OVERRUN 
status=23  data=45
[MAME]> status=3  data=90
status=3  data=49
status=3  data=44
status=3  data=90
status=3  data=49
status=3  data=0

Joined: Mar 2001
Posts: 17,217
Likes: 234
R
Very Senior Member
Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 17,217
Likes: 234
Neat. I've started working on creating a "picture" image device so we can emulate the ComputerEyes for real now that the gameio is a slot. (I already added the Sirius Joyport so you can get more precise control of a lot of classic A2 games that support it).

Joined: Feb 2014
Posts: 1,102
Likes: 173
G
Very Senior Member
Offline
Very Senior Member
G
Joined: Feb 2014
Posts: 1,102
Likes: 173
Hi Arbee,

that sounds awesome! I gotta try the Joyport now. 8-)


Joined: Feb 2014
Posts: 1,102
Likes: 173
G
Very Senior Member
Offline
Very Senior Member
G
Joined: Feb 2014
Posts: 1,102
Likes: 173
Hi Arbee,

I thought I'd give the sirius joyport a spin with my favorite game ever Stellar 7 and it was only letting me go left and right, but not up and down.

Diving into joyport.cpp it looks like we just need to swap an_0 with an_1 and vice versa, super simple fix.

an_0 selecting the player
and an_1 choosing which direction we're reading

Code
git diff
diff --git a/src/devices/bus/a2gameio/joyport.cpp b/src/devices/bus/a2gameio/joyport.cpp
index cfc8ef1246..9ed0579644 100644
--- a/src/devices/bus/a2gameio/joyport.cpp
+++ b/src/devices/bus/a2gameio/joyport.cpp
@@ -76,23 +76,23 @@ void apple2_joyport_device::device_start()
 
 READ_LINE_MEMBER(apple2_joyport_device::sw0_r)
 {
-       u8 port_read = m_an1 ? m_player2->read() : m_player1->read();
+       u8 port_read = m_an0 ? m_player2->read() : m_player1->read();
 
        return BIT(port_read, 4);
 }
 
 READ_LINE_MEMBER(apple2_joyport_device::sw1_r)
 {
-       u8 port_read = m_an1 ? m_player2->read() : m_player1->read();
+       u8 port_read = m_an0 ? m_player2->read() : m_player1->read();
 
-       return m_an0 ? BIT(port_read, 0) : BIT(port_read, 3);
+       return m_an1 ? BIT(port_read, 0) : BIT(port_read, 3);
 }
 
 READ_LINE_MEMBER(apple2_joyport_device::sw2_r)
 {
-       u8 port_read = m_an1 ? m_player2->read() : m_player1->read();
+       u8 port_read = m_an0 ? m_player2->read() : m_player1->read();
 
-       return m_an0 ? BIT(port_read, 2) : BIT(port_read, 1);
+       return m_an1 ? BIT(port_read, 2) : BIT(port_read, 1);
 }
 
 WRITE_LINE_MEMBER(apple2_joyport_device::an0_w)
(END)


Page 41 of 80 1 2 39 40 41 42 43 79 80

Link Copied to Clipboard
Who's Online Now
4 members (Olivier Galibert, Dodg, 2 invisible), 354 guests, and 5 robots.
Key: Admin, Global Mod, Mod
ShoutChat
Comment Guidelines: Do post respectful and insightful comments. Don't flame, hate, spam.
Forum Statistics
Forums9
Topics9,320
Posts121,944
Members5,074
Most Online1,283
Dec 21st, 2022
Our Sponsor
These forums are sponsored by Superior Solitaire, an ad-free card game collection for macOS and iOS. Download it today!

Superior Solitaire
Forum hosted by www.retrogamesformac.com