Well, it's still a mystery as indicated as remarks in the blueMSX source :
SFG05 Midi: The MIDI Out is probably buffered. If UART is unbuffered, all
// data will not be transmitted correctly. Question is how big
// the buffer is.
// The command bits are not clear at all. Only known bit is the
// reset bit.
// NOTES: Cmd bit 3: seems to be enable/disable something (checked before RX
// Cmd bit 4: is set when IM2 is used, cleared when IM1 is used
That's what I almost thought.
I've "googled" the last hour to find something about the SFG and the BIOS inside.
Many posts, up to 12 years ago, many questions, but no definitive explanations.
No listing, no dissasembled code.
The SFG BIOS Manual only described how to use the Calls but not very clear.
It seems the only way is to disassemble one of the Yamaha software that uses the SFG.
Partly the code that does I/O. But I guess it's more mystery for me after that.
Midi works very well on this machine, I used it almost two years every Day in the 80's.
And I dont remember of missing notes.....
Anyway, Thanks for responses
After hours of disassembling the MIBIOS I found something interesting:
Yamaha uses a byte somewhere in the ROM variables (F9A5h - this is somewhere in the middle of the music queue of Voice A) to save the state of the last write command to the 3FF6h.
(These area is previously saved from overwriting and cannot destroyed from "normal" BIOS - the "PLAY" ROM variable is overwritten with a RET command))
and sometimes the content of these byte is taken and processed and rewritten to 3FF6h like this:
LD HL,0F9A5H LD A,(HL) OR 02H LD (HL),A LD (3FF6H),A
LD A,(0F9A5H) RES 3,A ; Bit 3 IRQon is set to zero LD (0F9A5H),A LD A,(0F9A5H) ; mystery LD (3FF6H),A
LD A,(0F9A5H) PUSH AF AND 67H ; mask Bit 7,4,3 LD (0F9A5H),A LD (3FF6H),A EI NOP DI
unfortunally these variables in the music queue aren´t nowhere described and I´m going deeper and deeper and what I previously said: the mystery grows up! Yamaha uses a lot of variables in these space. They all setup in an endless subroutine.
The next I want to do is to follow the R- and M-calls in the MBIOS to get some information how to handle the 3FF6 Register.
I have disassembled the whole code from 0000h to 3FFFh and working on a clear listing in my assembler. If I´m ready with that, in one or two years, I´m back with my work
Is someone out there who have deeper informations?
EDIT:
this is interesting, it waits for something:
LD A,(0F9A5H) PUSH AF AND 67H ; mask Bit 7,4,3 LD (0F9A5H),A LD (3FF6H),A L0655: EI NOP ; gives interrupt a chance DI LD A,(0F9A2H) LD C,A LD A,(0F9A3H) CP C JR NZ,L0655 POP AF AND 0FDH LD (0F9A5H),A L0654: LD B,5AH L0656: DJNZ L0656 LD A,05H LD (3FF6H),A IM 1 POP BC POP AF RET
I don't Know of it is useable for you but sfg05 bios calls can be found at the website
http://gomsx.net/hansotten/ ??
After years, I´ll come back with this work.
Have much more expieriences with VDP and someone more....
I have simply modified the Code from Yamaha Goteborg MAP.GEN and got a simple MIDI THRU machine, without any screen Action.
It works fine on my real CX5M.
This is the main Loop:
THRLOOP: CALL INMD LD HL,DATABUF LD (HL),D LD A,D CP #E0 ;PITCH WHEEL CH 1? JR Z,THREND ;RETURN TO BASIC CALL OPMD JR THRLOOP THREND: CALL BACK RET
I can go out of this Loop with pitch on channel one.
All is fine.
But my question is, how can I Interrupt this Loop with keycommands?
I´m always inside the SFG05 wit DI.
Is this the way? (excerpt from above)
L0655: EI NOP ; gives interrupt a chance DI
I´ve tried it in my other code where I have a Loop they wait for MIDI Input:
it´s almost the same from Yamaha Goteborg Code
INMD: XOR D EI ; Interrupt to get KEY is pressed? is that enough? Do I have to put a NOP after this? CALL CHECKBUFF ; I´ve copied the BIOS code for this into RAM because of other SLOT JP NZ, KEYPR ; if key is pressed then go to OUT Routine DI LD A,(MIDSTATR) ;get status from Statusregister LD (MIDSTAT),A BIT 5,A JR NZ,FE ;if bit 5 of status is set then Framing Error BIT 1,A ; JR Z,INMD ;if bit 1 of status is zero, not ready yet,again
EI ; Interrupt to get KEY is pressed? is that enough? Do I have to put a NOP after this?
CHECKBUFF: LD HL,(0F3FAh) ; GETPTN Keyboardbuffer LD A,(0F3F8h) ; PUTPNT SUB L ; check if same SET Z if empty RET
EDIT:
that doesn´t work, I got no Keyaction, the program hangs...
INMD: XOR D EI NOP DI CALL CHECKBUFF JP NZ, KEYPR ; if key is pressed then go to OUT Routine
After reading SFG BIOS, Rodnay Zaks Z80 Book and some other stuff, I realize, the better way is to dive into interrupt programming.
I guess, to organize my program with interrupt handling, is a good choice to get control over BIOS Standard I/O (like Screen and Keyboard handling) and otherwise the opportunities of realtime MIDI Support.
Am I right?
Doesn’t MBIOS do the IM2 mode interrupt handling for you? I remember reading that in the application manual…
Indead! But first I have to understand interrupt handling at all.
I failed the the First time with starting MBIOs 11 with a little hook as described.
It's frustrating! but now it's Football time
A question to NYYRIKKI or someone who has expieriences with the SFG05:
I found a lot of informations about the SFG05, some code (see the post above)
but no detailed informations about the exactly handling of the two MIDI registers
Sorry... I newer dived in to MIDI stuff as I didn't have MIDI keyboard or cables.
Doesn’t MBIOS do the IM2 mode interrupt handling for you? I remember reading that in the application manual…
Really? This is first time I remember hearing that IM2 mode is used on MSX. In IM2 mode the interrupt jump address is formed by reading 16bit value from address pointed by register I (hi byte) and value in databus (lo byte).
If you can't decipher the correct databus values from the MBIOS, then maybe you can adapt this source for your needs:
; DATABUS Ver 2.1 for MSX (Made By: NYYRIKKI) ; ; This program reads a value from databus when ; Z80 leaves databus control to peripherals. ; ; Usage from MSX-BASIC: ; ; BLOAD "DATABUS.BIN",R:PRINT USR(0) ; ;----------------------------------------------------------------------------------------- USR: EQU #F7F8 USR0: EQU #F39A DEFB #FE DEFW BEGIN DEFW END DEFW START ORG #B000 BEGIN: START: LD HL,CODE LD (USR0),HL RET CODE: DI LD HL,#BF00 LD BC,0 NEXT: LD A,C ADD A,B CP #10 JP NC,NOMORE LD (HL),A INC HL CP #F JP Z,SKIP LD (HL),B INC HL SKIP: INC C LD A,C CP #10 JP NZ,NEXT NOMORE: LD C,0 INC B LD A,B CP #10 JP NZ,NEXT LD (HL),#C0 LD HL,#BF00 LD DE,#BE00 LD BC,0 FIXL: LD A,(HL) LD C,A OR #C0 LD (HL),A INC HL LD A,(HL) RLCA RLCA RLCA RLCA OR C LD E,A EX DE,HL LD A,E DEC A LD (HL),A EX DE,HL DJNZ FIXL LD HL,#C0C0 LD DE,#C0C1 LD B,#10 MAKEPROG: PUSH BC LD BC,#F PUSH HL PUSH DE LD (HL),4 ;INC B LDIR LD (HL),#CD ;CALL INC HL LD DE,CALCUT LD (HL),E INC HL LD (HL),D POP DE POP HL POP BC INC H INC D DJNZ MAKEPROG LD A,#BF LD I,A IM 2 EI NOP HALT ; Any interrupt will be accepted. LD L,A LD H,#BE LD A,(HL) LD (USR),A XOR A LD (USR+1),A RET CALCUT: POP AF AND #F RLCA RLCA RLCA RLCA OR B XOR #F IM 1 EI RETI END:
Really? This is first time I remember hearing that IM2 mode is used on MSX.
River Raid by Activision uses IM2.