aboutsummaryrefslogtreecommitdiffstats
path: root/data/mmuinit.pl
blob: f0a0a0a40410e4b3767faee018d9e4d9407fa6c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/usr/bin/perl
#
# Create MMU initialization file
#

# Each MMU entry is 16 bits; there are 4 address maps for each of
# 40-column mode and 80-column mode.  These are initialized with
# 1K/2K video RAM window at 29-31K (80 col only) and 31-32K.
# The defaults match the map uses from Mikrodatorn's 64K RAM
# expansion:
#
# 40-column mode:
#
# Map 0: default (32K RAM)
# Map 1: 0-31K is RAM
# Map 2: 0-63K RAM; 63-64K video
# Map 3: 0-64K RAM, no video
#
# 80-column mode:
#
# Map 4: default (32K RAM)
# Map 5: 0-29K, 30-31K is RAM
# Map 6: 0-62K RAM; 62-64K video
# Map 7: 0-64K RAM, no video
#
# The format of each entry is as follows:
# Bit  [15]    -> Make memory readonly
# Bits [14:12] -> device index:
#                 0 - SRAM
#                 1 - Flash ROM (RO)
#                 2 - Video RAM
#                 3 - Character generator RAM
#                 4 - Block graphics RAM
#                 5 - Reserved
#		  6 - Reserved
#                 7 - Hyperspace (reads back bits[7:0], RO)
#
# Bits [11:0] -> A[19:8]
#

$testram = 0;
$with_bgram = 1;

sub do_maps($$)
{
    my($testram, $is80) = @_;

    my $a = $is80 ? 4*256 : 0;
    my $i;
    my $lorom = $is80 ? 0x9080 : 0x9000;
    my $hirom = 0x9000;		# Do not switch on screen size change
    my $loram = $is80 ? 0x0140 : 0x0000;
    my $hiram = 0x0000;		# Do not switch on screen size change
    my $bgram = 0x4000;
    my $vram  = 0x2000;
    my $nothing = 0xffff;

    # Map 0 (standard)
    for ( $i = 0x00 ; $i < 0x40 ; $i++ ) { # BASIC
	printf("%03X : %04X;\n", $a++, $lorom+$i);
    }
    for ( $i = 0x40 ; $i < 0x48 ; $i++ ) { # Free for expansion
	printf("%03X : %04X;\n", $a++, $nothing);
    }
    for ( $i = 0x48 ; $i < 0x60 ; $i++ ) { # Free for expansion or bgram
	printf("%03X : %04X;\n", $a++,
	       $with_bgram ? $bgram+($i-0x48) : $nothing);
    }
    for ( $i = 0x60 ; $i < 0x74 ; $i++ ) { # DOS, IEC options
	printf("%03X : %04X;\n", $a++, $hirom+$i);
    }
    for ( $i = 0x74 ; $i < 0x78 ; $i++ ) { # Video RAM (for 80 col only)
	printf("%03X : %04X;\n", $a++,
	       $is80 ? $vram+($i-0x74) : $nothing);
    }
    for ( $i = 0x78 ; $i < 0x7B ; $i++ ) { # PR option
	printf("%03X : %04X;\n", $a++, $hirom+$i);
    }
    for ( $i = 0x7B ; $i < 0x7C ; $i++ ) { # RAM in the PR option area
	printf("%03X : %04X;\n", $a++, $hiram+$i);
    }
    for ( $i = 0x7C ; $i < 0x80 ; $i++ ) { # Video RAM
	printf("%03X : %04X;\n", $a++, $vram+4+($i-0x7C));
    }
    $a = do_ram($testram, $a, $i);

    # Map 1 (standard layout in RAM)
    for ( $i = 0x00 ; $i < 0x40 ; $i++ ) { # BASIC
	printf("%03X : %04X;\n", $a++, $loram+$i);
    }
    for ( $i = 0x40 ; $i < 0x48 ; $i++ ) { # Free for expansion
	printf("%03X : %04X;\n", $a++, $hiram+$i);
    }
    for ( $i = 0x48 ; $i < 0x60 ; $i++ ) { # Free for expansion or bgram
	printf("%03X : %04X;\n", $a++,
	       $with_bgram ? $bgram+($i-0x48) : $hiram+$i);
    }
    for ( $i = 0x60 ; $i < 0x74 ; $i++ ) { # DOS, IEC options
	printf("%03X : %04X;\n", $a++, $hiram+$i);
    }
    for ( $i = 0x74 ; $i < 0x78 ; $i++ ) { # Video RAM (for 80 col only)
	printf("%03X : %04X;\n", $a++,
	       $is80 ? $vram + ($i-0x74) : $hiram+$i);
    }
    for ( $i = 0x78 ; $i < 0x7B ; $i++ ) { # PR option
	printf("%03X : %04X;\n", $a++, $hiram+$i);
    }
    for ( $i = 0x7B ; $i < 0x7C ; $i++ ) { # RAM in the PR option area
	printf("%03X : %04X;\n", $a++, $hiram+$i);
    }
    for ( $i = 0x7C ; $i < 0x80 ; $i++ ) { # Video RAM
	printf("%03X : %04X;\n", $a++, $vram + 4 + ($i-0x7C));
    }
    $a = do_ram($testram, $a, $i);

    # Map 2 (CP/M with video enabled)
    for ( $i = 0x00 ; $i < ($is80 ? 0xF8 : 0xFC) ; $i++ ) { # RAM
	printf("%03X : %04X;\n", $a++, $hiram+$i);
    }
    for ( ; $i < 0x100 ; $i++ ) { # Video RAM
	printf("%03X : %04X;\n", $a++, $vram + ($i-0xF8));
    }

    # Map 3 (CP/M all memory)
    for ( $i = 0x00 ; $i < 0x100 ; $i++ ) { # All RAM
	printf("%03X : %04X;\n", $a++, $hiram+$i);
    }
}

sub do_ram($$$) {
    my($testram, $a, $i) = @_;

    my $hiram = 0x0000;		# Do not switch on screen size change

    if ( $testram ) {
	# Tiny amount of RAM (4K)
	for ( ; $i < 0xF0 ; $i++ ) {
	    printf("%03X : %04X;\n", $a++, $nothing);
	}
    }

    for ( ; $i < 0x100 ; $i++ ) {
	printf("%03X : %04X;\n", $a++, $hiram+$i);
    }

    return $a;
}

print "DEPTH = 2048;\n";
print "WIDTH = 16;\n";
print "ADDRESS_RADIX = HEX;\n";
print "DATA_RADIX    = HEX;\n";
print "CONTENT\n";
print "BEGIN\n";

do_maps($testram, 0);		# 40 col
do_maps($testram, 1);		# 80 col

print "END;\n";