NEO-ZMC: Difference between revisions

From NeoGeo Development Wiki
Jump to navigation Jump to search
mNo edit summary
m (a8 was written instead of a18)
(7 intermediate revisions by 2 users not shown)
Line 1: Line 1:
[[File:crt_zmc.jpg|right|thumb|NEO-ZMC chip on a MVS [[cartridges|cartridge]]. Picture courtesy of [[http://www.mvs-scans.com MVS-Scans]].]]
{{ChipInfo
|picture=crt_zmc.jpg
|pkg=SOIC24
|manu=fujitsu
|date=1995 ?
|gates=
|used_on=[[cartridges]]
}}


Z80 memory controller. Has a hardwired 32KiB bank and switchable 16/8/4/2KiB banks arranged as a register file. To save pins the high address lines (A15-A8) are used for data input. The chip's write strobe is (port) address decoded inside the console.
{{Chipname|Z80}} '''M'''emory '''C'''ontroller. Provides a hardwired 32KiB bank and [[Z80 bankswitching|switchable 16, 8, 4, and 2KiB banks]] arranged as a register file. To save pins, the Z80's upper address lines (A15~A18) are used for data input. The chip's write strobe is [[Z80 port map|port]] address decoded inside the system.


=Pinout=
=Pinout=
[[File:Neo-zmc_pinout.png]]


OpenOffice Draw file: [[File:neo-zmc.odg]]
{{Pinout|NEO-ZMC|512}}


*SDA0,SDA1,SDA8~15: [[Z80]] address bus
Pins 10, 11, 12 are certainly not connected since the addressing scheme doesn't allow mapping over 512KiB.
*SDRD0: /Write signal from [[NEO-D0]]
 
* SDA0, SDA1, SDA8~15: Z80 address bus
* M1 A11~M1 A18: [[M1 ROM]] address lines
* SDRD0: Decoded write signal from {{Chipname|NEO-D0}} (latch on rising edge)


=Operation=
=Operation=


SDA10,SDA9,SDA8 are bank selector and SDA1,SDA0 range size selector or rom size selector.
SDA8~15 is used for the bank number (data), SDA0 and SDA1 for selecting the bank zone.
 
SDA1,SDA0 = 0,0 (Z80 port 8) select bank ranges for the Z80 $F000~$F7FF range (2Kbytes) (64k M1)
 
SDA1,SDA0 = 0,1 (Z80 port 9) select bank ranges for the Z80 $E000~$EFFF range (4Kbytes) (128k M1)  
 
SDA1,SDA0 = 1,0 (Z80 port A) select bank ranges for the Z80 $C000~$DFFF range (8Kbytes) (256k M1)
 
SDA1,SDA0 = 1,1 (Z80 port B) select bank ranges for the Z80 $8000~$BFFF range (16Kbytes) (512k M1)
 
SDRD0 is the /write signal: the bank configuration is latched and the address output lines are changed on the rising edge.


{|class="wikitable"
!SDA1
!SDA0
!Z80 port
!Bank zone
!Address range
!Size
!Latch size
|-
|0||0||$08||0||$F000~$F7FF||2KiB||8 bits
|-
|0||1||$09||1||$E000~$EFFF||4KiB||7 bits
|-
|1||0||$0A||2||$C000~$DFFF||8KiB||6 bits
|-
|1||1||$0B||3||$8000~$BFFF||16KiB||5 bits
|}


'''Details:'''
==Details==
[[File:Neo-zmz_operation.png|thumb]]


SDRD0 must be high before configuring banks.
SDRD0 must be high before configuring banks.


To configure a bank to be accessed (e.g. bank 0 in the $8000~$BFFF range):
To configure a bank to be accessed (e.g. bank 0 in the $8000~$BFFF range):
*Set SDRD0 low (prepare for new bank configuration, outputs are tri-stated)
* Set SDRD0 low (prepare for new bank configuration, outputs are tri-stated)
*Set SDA0~15 = '''$8003''' (select bank 0 and 16k range size) Why $8003 and not just $0003 ?
* Set SDA0~15 = '''$8003''' (select bank 0 and 16k range size) Why $8003 and not just $0003 ?
*Set SDRD0 high (latch bank, ready to convert inputs to proper output signals)
* Set SDRD0 high (latch bank, ready to convert inputs to proper output signals)
*Now, when the Z80 accesses the '''$8000~BFFF''' range, NEO-ZMC will convert this the M1 ROM zone '''$00000~$03FFF''';
* Now, when the Z80 reads the '''$8000~BFFF''' range, NEO-ZMC will map this to the M1 ROM zone '''$00000~$03FFF''';


To configure a bank to be accessed (e.g. bank 1 in the $8000~$BFFF range):
To configure a bank to be accessed (e.g. bank 1 in the $8000~$BFFF range):
*Set SDRD0 low (prepare for new bank configuration, outputs are tri-stated)
* Set SDRD0 low (prepare for new bank configuration, outputs are tri-stated)
*Set SDA0~15 = '''$8103''' (select bank 1 and 16k range size) Why $8103 and not just $0103 ?
* Set SDA0~15 = '''$8103''' (select bank 1 and 16k range size) Why $8103 and not just $0103 ?
*Set SDRD0 high (latch bank, ready to convert inputs to proper output signals)
* Set SDRD0 high (latch bank, ready to convert inputs to proper output signals)
*Now, when the Z80 accesses the '''$8000~BFFF''' range, NEO-ZMC will convert this the M1 ROM zone '''$04000~$07FFF''';
* Now, when the Z80 reads the '''$8000~BFFF''' range, NEO-ZMC will map this to the M1 ROM zone '''$04000~$07FFF''';
 
==Logic definition==


To configure a bank to be accessed (e.g. bank 3 in the $C000~$DFFF range):
Not tested.
*Set SDRD0 low (prepare for new bank configuration, outputs are tri-stated)
*Set SDA0~15 = '''$8302''' (select bank 3 and 8k range size) Why $8302 and not just $0302 ?
*Set SDRD0 high (latch bank, ready to convert inputs to proper output signals)
*Now, when the Z80 accesses the '''$C000~DFFF''' range, NEO-ZMC will convert this the M1 ROM zone '''$06000~$07FFF''';


[[File:Neo-zmz operation.png|right|x400px]]
<pre>
{|class="wikitable"
reg [7:0] WINDOW_0;
!Z80 address bus
reg [6:0] WINDOW_1;
(SDA0~15)
reg [5:0] WINDOW_2;
!BANK
reg [4:0] WINDOW_3;
0-31
 
!Window...
assign MA = (!SDA[15]) ? {4'b0000, SDA[14:11]} :    // Pass-through
!...mapped to
(SDA[15:12] == 4'b1111) ? WINDOW_0 :
(M1 A0~18)
(SDA[15:12] == 4'b1110) ? {WINDOW_1, SDA[11]} :
|-
(SDA[15:13] == 3'b110) ? {WINDOW_2, SDA[12:11]} :
|$8003
{WINDOW_3, SDA[13:11]};
|bank 00
|$8000~$BFFF
|$00000~$03FFF
|-
|$8103
|bank 01
|$8000~$BFFF
|$04000~$07FFF
|-
|$8203
|bank 02
|$8000~$BFFF
|$08000~$0BFFF
|-
|$8303
|bank 03
|$8000~$BFFF
|$0C000~$0FFFF
|-
|$8403
|bank 04
|$8000~$BFFF
|$10000~$13FFF
|-
|$8503
|bank 05
|$8000~$BFFF
|$14000~$17FFF
|-
|$8603
|bank 06
|$8000~$BFFF
|$18000~$1BFFF
|-
|$8703
|bank 07
|$8000~$BFFF
|$1C000~$1FFFF
|-
|$8803
|bank 08
|$8000~$BFFF
|$20000~$23FFF
|-
|$8903
|bank 09
|$8000~$BFFF
|$24000~$27FFF
|-
|$8A03
|bank 10
|$8000~$BFFF
|$28000~$2BFFF
|-
|$8B03
|bank 11
|$8000~$BFFF
|$2C000~$2FFFF
|-
|$8C03
|bank 12
|$8000~$BFFF
|$30000~$33FFF
|-
|$8D03
|bank 13
|$8000~$BFFF
|$34000~$37FFF
|-
|$8E03
|bank 14
|$8000~$BFFF
|$38000~$3BFFF
|-
|$8F03
|bank 15
|$8000~$BFFF
|$3C000~$3FFFF
|-
|$9003
|bank 16
|$8000~$BFFF
|$40000~$43FFF
|-
|$9103
|bank 17
|$8000~$BFFF
|$40000~$47FFF
|-
|$9203
|bank 18
|$8000~$BFFF
|$40000~$4BFFF
|-
|$9303
|bank 19
|$8000~$BFFF
|$40000~$4FFFF
|-
|$9403
|bank 20
|$8000~$BFFF
|$50000~$53FFF
|-
|$9503
|bank 21
|$8000~$BFFF
|$54000~$57FFF
|-
|$9603
|bank 22
|$8000~$BFFF
|$58000~$5BFFF
|-
|$9703
|bank 23
|$8000~$BFFF
|$5C000~$5FFFF
|-
|$9803
|bank 24
|$8000~$BFFF
|$60000~$63FFF
|-
|$9903
|bank 25
|$8000~$BFFF
|$64000~$67FFF
|-
|$9A03
|bank 26
|$8000~$BFFF
|$68000~$6BFFF
|-
|$9B03
|bank 27
|$8000~$BFFF
|$6C000~$6FFFF
|-
|$9C03
|bank 28
|$8000~$BFFF
|$70000~$73FFF
|-
|$9D03
|bank 29
|$8000~$BFFF
|$74000~$77FFF
|-
|$9E03
|bank 30
|$8000~$BFFF
|$78000~$7BFFF
|-
|$9F03
|bank 31
|$8000~$BFFF
|$7C000~$7FFFF
|}


Others range sets may differ from the range access here.(e.g. $8000, $8001 or $8002)
always @(posedge nSDRD0)
begin
  case (SDA[1:0])
    0: WINDOW_0 <= SDA[15:8];
    1: WINDOW_1 <= SDA[14:8];
    2: WINDOW_2 <= SDA[13:8];
    3: WINDOW_3 <= SDA[12:8];
  endcase
end
</pre>


[[Category:Audio system]]
[[Category:Chips]]
[[Category:Chips]]

Revision as of 09:08, 14 January 2019

Package SOIC24
Manufacturer
First use 1995 ?
Used on cartridges

Z80 Memory Controller. Provides a hardwired 32KiB bank and switchable 16, 8, 4, and 2KiB banks arranged as a register file. To save pins, the Z80's upper address lines (A15~A18) are used for data input. The chip's write strobe is port address decoded inside the system.

Pinout


Edit this pinout

Pins 10, 11, 12 are certainly not connected since the addressing scheme doesn't allow mapping over 512KiB.

  • SDA0, SDA1, SDA8~15: Z80 address bus
  • M1 A11~M1 A18: M1 ROM address lines
  • SDRD0: Decoded write signal from NEO-D0 (latch on rising edge)

Operation

SDA8~15 is used for the bank number (data), SDA0 and SDA1 for selecting the bank zone.

SDA1 SDA0 Z80 port Bank zone Address range Size Latch size
0 0 $08 0 $F000~$F7FF 2KiB 8 bits
0 1 $09 1 $E000~$EFFF 4KiB 7 bits
1 0 $0A 2 $C000~$DFFF 8KiB 6 bits
1 1 $0B 3 $8000~$BFFF 16KiB 5 bits

Details

SDRD0 must be high before configuring banks.

To configure a bank to be accessed (e.g. bank 0 in the $8000~$BFFF range):

  • Set SDRD0 low (prepare for new bank configuration, outputs are tri-stated)
  • Set SDA0~15 = $8003 (select bank 0 and 16k range size) Why $8003 and not just $0003 ?
  • Set SDRD0 high (latch bank, ready to convert inputs to proper output signals)
  • Now, when the Z80 reads the $8000~BFFF range, NEO-ZMC will map this to the M1 ROM zone $00000~$03FFF;

To configure a bank to be accessed (e.g. bank 1 in the $8000~$BFFF range):

  • Set SDRD0 low (prepare for new bank configuration, outputs are tri-stated)
  • Set SDA0~15 = $8103 (select bank 1 and 16k range size) Why $8103 and not just $0103 ?
  • Set SDRD0 high (latch bank, ready to convert inputs to proper output signals)
  • Now, when the Z80 reads the $8000~BFFF range, NEO-ZMC will map this to the M1 ROM zone $04000~$07FFF;

Logic definition

Not tested.

reg [7:0] WINDOW_0;
reg [6:0] WINDOW_1;
reg [5:0] WINDOW_2;
reg [4:0] WINDOW_3;

assign MA = (!SDA[15]) ? {4'b0000, SDA[14:11]} :     // Pass-through
		(SDA[15:12] == 4'b1111) ? WINDOW_0 :
		(SDA[15:12] == 4'b1110) ? {WINDOW_1, SDA[11]} :
		(SDA[15:13] == 3'b110) ? {WINDOW_2, SDA[12:11]} :
		{WINDOW_3, SDA[13:11]};

always @(posedge nSDRD0)
begin
  case (SDA[1:0])
    0: WINDOW_0 <= SDA[15:8];
    1: WINDOW_1 <= SDA[14:8];
    2: WINDOW_2 <= SDA[13:8];
    3: WINDOW_3 <= SDA[12:8];
  endcase
end