NEO-ZMC: Difference between revisions

From NeoGeo Development Wiki
Jump to navigation Jump to search
No edit summary
m (a8 was written instead of a18)
(27 intermediate revisions by 3 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.


(Need Z80 IN instructions details: upper 8 bytes of address bus as data, lower 8 as port number)
=Pinout=
 
{{Pinout|NEO-ZMC|512}}
 
Pins 10, 11, 12 are certainly not connected since the addressing scheme doesn't allow mapping over 512KiB.


=Pinout=
* SDA0, SDA1, SDA8~15: Z80 address bus
[[File:Neo-zmc_pinout.png]]
* M1 A11~M1 A18: [[M1 ROM]] address lines
* SDRD0: Decoded write signal from {{Chipname|NEO-D0}} (latch on rising edge)
 
=Operation=
 
SDA8~15 is used for the bank number (data), SDA0 and SDA1 for selecting the bank zone.
 
{|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
|}


OpenOffice Draw file: [[File:neo-zmc.odg]]
==Details==
[[File:Neo-zmz_operation.png|thumb]]


=How It Work=
SDRD0 must be high before configuring banks.
[[File:Neo-zmz operation.png]]


Zmc acess the M1 in 32 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''';


Insert non-formatted text hereSDA10,SDA9,SDA8 is bank selector and SDA1,SDA0 is Rom size selector<br>
To configure a bank to be accessed (e.g. bank 1 in the $8000~$BFFF range):
*SDA1,SDA0 = 0,0 => 64k M1
* Set SDRD0 low (prepare for new bank configuration, outputs are tri-stated)
*SDA1,SDA0 = 0,1 => 128k M1
* Set SDA0~15 = '''$8103''' (select bank 1 and 16k range size) Why $8103 and not just $0103 ?
*SDA1,SDA0 = 1,0 => 256k M1
* Set SDRD0 high (latch bank, ready to convert inputs to proper output signals)
*SDA1,SDA0 = 1,1 => 512k M1
* Now, when the Z80 reads the '''$8000~BFFF''' range, NEO-ZMC will map this to the M1 ROM zone '''$04000~$07FFF''';


*SDRD0 is the WRITE (configure the range and size) / READ (acess that range), selector
==Logic definition==


Example:
Not tested.
#PUT SDRD0 in High logic level (5v);


#PUT SDA[15..0] = $8003 (configure '''bank 00''' + m1 512k);
<pre>
#SDMRD from High to Low (this set the bank and rom size);
reg [7:0] WINDOW_0;
#SDMRD from Low to High (this fixes the bank and ZMC configure the A[18..11];
reg [6:0] WINDOW_1;
#SDMRD still in High and SDA[15..0] = $8000~$BFFF will make ZMC access M1 from $00000~$03FFF;
reg [5:0] WINDOW_2;
#'''Bank 00 was read'''
reg [4:0] WINDOW_3;
#PUT SDA[15..0] = $8103 (configure '''bank 01''' + m1 512k);
#SDMRD from High to Low (this set the bank and rom size);
#SDMRD from Low to High (this fixes the bank and ZMC configure the A[18..11];
#SDMRD still in High and SDA[15..0] = $8000~$BFFF will make ZMC access M1 from $04000~$07FFF;
#'''Bank 01 was read'''
#PUT SDA[15..0] = $8203 (configure '''bank 02''' + m1 512k);
#SDMRD from High to Low (this set the bank and rom size);
#SDMRD from Low to High (this fixes the bank and ZMC configure the A[18..11];
#SDMRD still in High and SDA[15..0] = $8000~$BFFF will make ZMC access M1 from $08000~$0BFFF;
#'''Bank 02 was read'''
#PUT SDA[15..0] = $8303 (configure '''bank 03''' + m1 512k);
#SDMRD from High to Low (this set the bank and rom size);
#SDMRD from Low to High (this fixes the bank and ZMC configure the A[18..11];
#SDMRD still in High and SDA[15..0] = $8000~$BFFF will make ZMC access M1 from $0C000~$0FFFF;
#'''Bank 03 was read'''
#PUT SDA[15..0] = $8403 (configure '''bank 04''' + m1 512k);
#SDMRD from High to Low (this set the bank and rom size);
#SDMRD from Low to High (this fixes the bank and ZMC configure the A[18..11];
#SDMRD still in High and SDA[15..0] = $8000~$BFFF will make ZMC access M1 from $10000~$13FFF;
#'''Bank 04 was read'''
... and so on...


Here is the table for the banks
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]};


8003 => bank 00 (acess 00000‐03FFF );
always @(posedge nSDRD0)
8103 => bank 01 (acess 04000‐07FFF );
begin
8203 => bank 02 (acess 08000‐0BFFF );
  case (SDA[1:0])
8303 => bank 03 (acess 0C000‐0FFFF );
    0: WINDOW_0 <= SDA[15:8];
8403 => bank 04 (acess 10000‐13FFF );
    1: WINDOW_1 <= SDA[14:8];
8503 => bank 05 (acess 14000‐17FFF );
    2: WINDOW_2 <= SDA[13:8];
8603 => bank 06 (acess 18000‐1BFFF );
    3: WINDOW_3 <= SDA[12:8];
8703 => bank 07 (acess 1C000‐1FFFF );
  endcase
8803 => bank 08 (acess 20000‐23FFF );
end
8903 => bank 09 (acess 24000‐27FFF );
</pre>
8A03 => bank 10 (acess 28000‐2BFFF );
8B03 => bank 11 (acess 2C000‐2FFFF );
8C03 => bank 12 (acess 30000‐33FFF );
8D03 => bank 13 (acess 34000‐37FFF );
8E03 => bank 14 (acess 38000‐3BFFF );
8F03 => bank 15 (acess 3C000‐3FFFF );
9003 => bank 16 (acess 40000‐43FFF );
9103 => bank 17 (acess 40000‐47FFF );
9203 => bank 18 (acess 40000‐4BFFF );
9303 => bank 19 (acess 40000‐4FFFF );
9403 => bank 20 (acess 50000‐53FFF );
9503 => bank 21 (acess 54000‐57FFF );
9603 => bank 22 (acess 58000‐5BFFF );
9703 => bank 23 (acess 5C000‐5FFFF );
9803 => bank 24 (acess 60000‐63FFF );
9903 => bank 25 (acess 64000‐67FFF );
9A03 => bank 26 (acess 68000‐6BFFF );
9B03 => bank 27 (acess 6C000‐6FFFF );
9C03 => bank 28 (acess 70000‐73FFF );
9D03 => bank 29 (acess 74000‐77FFF );
9E03 => bank 30 (acess 78000‐7BFFF );
9F03 => bank 31 (acess 7C000‐7FFFF );


[[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