Subversion Repositories ngs

Rev

Rev 3 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 lvd 1
// part of NeoGS project (c) 2007-2008 NedoPC
2
//
3
// memmap is memory mapper for NGS. Physical memory divided in 16kb pages.
4
// At (a15=0,a14=0) there is always zero page of MEM, at (a15=0,a14=1) there is
5
// always third page of RAM, at (a15=1,a14=0) there is page of MEM determined by
6
// mode_pg0 input bus, at (a15=1,a14=1) - page of MEM determined by mode_pg1 input.
7
// When mode_norom=0, MEM is ROM, otherwise MEM is RAM.
8
// When mode_ramro=1, zero and first pages of RAM are read-only.
9
// Memory addressed by mema14..mema18 (total 512kb) and then by either
10
// romcs_n (only 512kb of ROM) or ram0cs_n..ram3cs_n (2Mb of RAM).
11
// Memory decoding is static - it depends on only a14,a15 and mode_pg0,1 inputs.
12
// memoe_n and memwe_n generated from only mreq_n, rd_n and wr_n with the
13
// exception of read-only page of RAM (no memwe_n). ROM is always read/write (flash).
14
 
15
module memmap(
16
 
17
        a15,a14, // Z80 address signals
18
 
19
        mreq_n, // Z80 bus control signals
20
        rd_n,   //
21
        wr_n,   //
22
 
23
        mema14,mema15, // memory addresses
24
        mema16,mema17, //
25
        mema18,        // (512kB max)
26
 
27
        ram0cs_n, // four RAM /CS'es
28
        ram1cs_n, //
29
        ram2cs_n, //
30
        ram3cs_n, // (total 512kb * 4 = 2Mb)
31
 
32
        romcs_n, // ROM (flash) /CS
33
 
34
        memoe_n, // memory /OE and /WE
35
        memwe_n, //
36
 
37
        mode_ramro, // 1 - zero page (32k) of ram is R/O
38
        mode_norom, // 0 - ROM instead of RAM at everything except $4000-$7FFF
39
        mode_pg0,   // page at $8000-$BFFF
40
        mode_pg1    // page at $C000-$FFFF (128x16kb = 2Mb max)
41
);
42
 
43
// inputs and outputs
44
 
45
        input a15,a14;
46
 
47
        input mreq_n,rd_n,wr_n;
48
 
49
        output reg mema14,mema15,mema16,mema17,mema18;
50
 
51
        output reg ram0cs_n,ram1cs_n,ram2cs_n,ram3cs_n;
52
 
53
        output reg romcs_n;
54
 
55
        output reg memoe_n,memwe_n;
56
 
57
        input mode_ramro,mode_norom;
58
        input [6:0] mode_pg0,mode_pg1;
59
 
60
 
61
// internal vars and regs
62
 
63
        reg [6:0] high_addr;
64
 
65
 
66
 
67
// addresses mapping
68
 
69
        always @*
70
        begin
71
        case( {a15,a14} )
72
                        2'b00: // $0000-$3FFF
73
                                high_addr <= 7'b0000000;
74
                        2'b01: // $4000-$7FFF
75
                                high_addr <= 7'b0000011;
76
                        2'b10: // $8000-$BFFF
77
                                high_addr <= mode_pg0;
78
                        2'b11: // $C000-$FFFF
79
                                high_addr <= mode_pg1;
80
        endcase
81
        end
82
 
83
 
84
// memory addresses
85
 
86
        always @*
87
        begin
88
                { mema18,mema17,mema16,mema15,mema14 } <= high_addr[4:0];
89
        end
90
 
91
 
92
// memory chip selects
93
 
94
        always @*
95
        begin
96
                if( (mode_norom==1'b0) && ( {a15,a14}!=2'b01 ) ) // ROM selected
97
                begin
98
                        romcs_n <= 1'b0;
99
 
100
                        ram0cs_n <= 1'b1;
101
                        ram1cs_n <= 1'b1;
102
                        ram2cs_n <= 1'b1;
103
                        ram3cs_n <= 1'b1;
104
                end
105
                else // RAM
106
                begin
107
                        romcs_n <= 1'b1;
108
 
109
                        ram0cs_n <= ( high_addr[6:5]==2'b00 ) ? 1'b0 : 1'b1;
110
                        ram1cs_n <= ( high_addr[6:5]==2'b01 ) ? 1'b0 : 1'b1;
111
                        ram2cs_n <= ( high_addr[6:5]==2'b10 ) ? 1'b0 : 1'b1;
112
                        ram3cs_n <= ( high_addr[6:5]==2'b11 ) ? 1'b0 : 1'b1;
113
                end
114
        end
115
 
116
 
117
// memory /OE and /WE
118
 
119
        always @*
120
        begin
121
                memoe_n <= mreq_n | rd_n;
122
 
123
                if( (high_addr[6:1] == 6'd0) && (mode_ramro==1'b1) && (mode_norom==1'b1) ) // R/O
124
                        memwe_n <= 1'b1;
125
                else // no R/O
126
                        memwe_n <= mreq_n | wr_n;
127
        end
128
 
129
endmodule
130