68k/Z80 communication: Difference between revisions

From NeoGeo Development Wiki
Jump to navigation Jump to search
mNo edit summary
mNo edit summary
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
Inter-CPU communication is done through a byte-wide bi-directional register.
Communication between the {{Chipname|68k}} CPU and the {{Chipname|Z80}} CPU is done through 2 byte-wide registers.
 
There is no shared memory zone like in the Sega Genesis/Megadrive.


=68k to Z80 (request)=
=68k to Z80 (request)=


Writes to the {{Chipname|Z80}} are made through {{Reg|REG_SOUND}}.
Writes to the Z80 are done through {{Reg|REG_SOUND}}.
Any byte can be sent, its meaning is only determined by the way the Z80 code handles it (except for '''3 special cases''', as seen below).
Any byte can be sent, the meaning of it is only determined by the way the [[M1 ROM|Z80 code]] handles it (except for '''3 special cases''', as seen below).


When a byte is sent, the corresponding value is latched in {{Chipname|NEO-C1}} ({{Chipname|NEO-SUD}} in CD systems ?), and an NMI is triggered on the Z80 if enabled. The value can then be read on the Z80's port $00.
When a byte is sent, the corresponding value is latched in {{Chipname|NEO-C1}} ({{Chipname|NEO-SUD}} in CD systems ?), and an [[Z80 interrupts|NMI]] is triggered in the Z80 if enabled. The value can then be read on the Z80's side with [[Z80 port map|port $00]].


(What chip is used on first gen chipset ?)
(What chip is used on first gen chipset ?)


=Z80 to 68k (answer)=
=Z80 to 68k (reply)=


The Z80's port $0C is used to reply to the {{Chipname|68k}}. The value is also buffered in the same chips, but there are no interrupts generated.
The Z80's port $0C is used to reply to the 68k. The value is also buffered in the same chip, but no interrupt is generated.
The value can be read by using the same register, {{Reg|REG_SOUND}}.
The value can be read on the 68k's side by using the same register, {{Reg|REG_SOUND}}.


Many [[sound driver]]s acknowledge sound commands by echoing them back with bit 7 set to 1 when they are processed.
Many [[sound driver]]s acknowledge sound commands by echoing them back with bit 7 set to 1 when they are processed.


=Special commands=
=Special commands=
Commands $01 and $03 are always expected to be implemented in the Z80 code, as they are used by the [[System ROM]] for initialization purposes.
Commands $01, $02 and $03 are always expected to be implemented in the Z80 code, as they are used by the [[system ROM]] for initialization purposes.
During the MVS power up self-tests, if the Z80 doesn't reply to command $01 in time, the "[[Z80 ERROR]]" message is displayed and the system locks up.
During the MVS power up [[system_self-test|self-tests]], if the Z80 doesn't reply to command $01 in time, the "[[Z80 ERROR]]" message is displayed and the system locks up.


==Command $01==
==Command $01: Prepare switch==
It is sent by the system ROM when the [[slot]] is switched. As the {{Chipname|M1 ROM}} will be swapped, all sounds need to be stopped, NMI need to be activated, $01 needs to be sent back to the 68k and the Z80 code has to sit in a loop '''in RAM'''. After receiving the reply, the system ROM can then switch slots without crashing the Z80.
It is sent by the system ROM just before the [[slot]] is switched. As the {{Chipname|M1 ROM}} has to be swapped, all sounds need to be stopped, interrupts need to be enabled, $01 needs to be sent back to the 68k and the Z80 has to wait in a loop '''in RAM'''. After receiving the reply, the system ROM can then switch slots without crashing the Z80.


==Command $02==
==Command $02: Play eyecatcher music==
It is used by cartridge systems to play the [[eye catcher]] music. The pattern (melody) was certainly imposed by SNK, but developers often chose their own instruments parameters. [[Boot music]]. No reply is expected.
It is used in cartridge systems to play the [[eyecatcher]] music. See [[boot music]]. No reply is expected.


==Command $03==
==Command $03: Reset==
It is used to ask for a soft reset of the Z80, which needs to be done under 100ms. No reply is expected.
It is used to ask for a soft reset of the Z80, which needs to be done under 100ms as per SNK's recommendation. No reply is expected.


=Minimal command handlers=
=Minimal command handlers=
Line 34: Line 36:


<pre>
<pre>
;"MAKOTO V3" style handler
Command01_Handler:
Command01_Handler:
di ; Disable interrupts
        di ; Disable interrupts
         xor  a
         xor  a
         out  ($0C),a
         out  ($0C),a           ; Clear both buffers
         out  ($00),a
         out  ($00),a
         ; Init banks and stuff...
         ; Silence YM2610 here
         ld  sp,#fffc
         ld  sp,$FFFC          ; Reset SP
         ld  hl,stayinram
         ld  hl,stayinram
         push hl
         push hl
Line 47: Line 48:


stayinram:
stayinram:
         ld  hl,#fffd
         ld  hl,$FFFD
         ld  (hl),#c3         ; (FFFD)=C3, opcode for JP
         ld  (hl),$C3         ; (FFFD)=$C3, opcode for JP
         ld  (#fffe),hl         ; (FFFE)=FFFD (JP FFFD)
         ld  ($FFFE),hl         ; (FFFE)=$FFFD (makes "JP FFFD")
         ld  a,#01
        ei
         out  (#0c),a            ; Tell 68k that we're ready
         ld  a,$01
         jp  #fffd             ; Sit in RAM loop
         out  ($0C),a            ; Tell 68k that we're ready
         jp  $FFFD             ; Quickly jump to RAM loop
</pre>
</pre>


Line 58: Line 60:
Command03_Handler:
Command03_Handler:
di ; Disable interrupts
di ; Disable interrupts
ld  sp, $FFFF ; Clear call stack
ld  sp,$FFFF ; Clear call stack
ld  hl,0
ld  hl,0
push hl
push hl

Latest revision as of 05:27, 3 November 2016

Communication between the 68k CPU and the Z80 CPU is done through 2 byte-wide registers.

There is no shared memory zone like in the Sega Genesis/Megadrive.

68k to Z80 (request)

Writes to the Z80 are done through REG_SOUND. Any byte can be sent, the meaning of it is only determined by the way the Z80 code handles it (except for 3 special cases, as seen below).

When a byte is sent, the corresponding value is latched in NEO-C1 (NEO-SUD in CD systems ?), and an NMI is triggered in the Z80 if enabled. The value can then be read on the Z80's side with port $00.

(What chip is used on first gen chipset ?)

Z80 to 68k (reply)

The Z80's port $0C is used to reply to the 68k. The value is also buffered in the same chip, but no interrupt is generated. The value can be read on the 68k's side by using the same register, REG_SOUND.

Many sound drivers acknowledge sound commands by echoing them back with bit 7 set to 1 when they are processed.

Special commands

Commands $01, $02 and $03 are always expected to be implemented in the Z80 code, as they are used by the system ROM for initialization purposes. During the MVS power up self-tests, if the Z80 doesn't reply to command $01 in time, the "Z80 ERROR" message is displayed and the system locks up.

Command $01: Prepare switch

It is sent by the system ROM just before the slot is switched. As the M1 ROM has to be swapped, all sounds need to be stopped, interrupts need to be enabled, $01 needs to be sent back to the 68k and the Z80 has to wait in a loop in RAM. After receiving the reply, the system ROM can then switch slots without crashing the Z80.

Command $02: Play eyecatcher music

It is used in cartridge systems to play the eyecatcher music. See boot music. No reply is expected.

Command $03: Reset

It is used to ask for a soft reset of the Z80, which needs to be done under 100ms as per SNK's recommendation. No reply is expected.

Minimal command handlers

These are sufficient handlers for both init commands:

Command01_Handler:
        di			; Disable interrupts
        xor  a
        out  ($0C),a            ; Clear both buffers
        out  ($00),a
        ; Silence YM2610 here
        ld   sp,$FFFC           ; Reset SP
        ld   hl,stayinram
        push hl
        retn                    ; RETN to stayinram

stayinram:
        ld   hl,$FFFD
        ld   (hl),$C3	        ; (FFFD)=$C3, opcode for JP
        ld   ($FFFE),hl	        ; (FFFE)=$FFFD (makes "JP FFFD")
        ei
        ld   a,$01
        out  ($0C),a            ; Tell 68k that we're ready
        jp   $FFFD              ; Quickly jump to RAM loop
Command03_Handler:
	di			; Disable interrupts
	ld   sp,$FFFF		; Clear call stack
	ld   hl,0
	push hl
	retn			; RETN to 0