forked from dhansel/Altair8800
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmem.cpp
144 lines (117 loc) · 3.22 KB
/
mem.cpp
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
// -----------------------------------------------------------------------------
// Altair 8800 Simulator
// Copyright (C) 2017 David Hansel
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
// -----------------------------------------------------------------------------
#include "Altair8800.h"
#include "mem.h"
#include "host.h"
byte Mem[MEMSIZE];
byte MEM_READ_STEP(uint16_t a)
{
if( altair_isreset() )
{
byte v = MREAD(a);
host_set_status_leds_READMEM();
altair_set_outputs(a, v);
altair_wait_step();
v = host_read_data_leds(); // CPU reads whatever is on the data bus at this point
host_clr_status_led_MEMR();
return v;
}
else
return 0x00;
}
void MEM_WRITE_STEP(uint16_t a, byte v)
{
if( altair_isreset() )
{
MWRITE(a, v);
host_set_status_leds_WRITEMEM();
#if SHOW_BUS_OUTPUT>0
altair_set_outputs(a, v);
#else
altair_set_outputs(a, 0xff);
#endif
altair_wait_step();
host_clr_status_led_WO();
}
}
#if USE_PROTECT>0
word protected_flag = 0;
byte protected_flags[32];
void mem_protect(uint16_t a)
{
protected_flags[((a)>>8)/8] |= (1<<(((a)>>8)&0x07));
protected_flag = 1;
}
void mem_unprotect(uint16_t a)
{
byte i;
protected_flags[((a)>>8)/8] &= ~(1<<(((a)>>8)&0x07));
for(i=0; i<32 && protected_flags[i]==0; i++);
protected_flag = i<32;
}
#endif
word mem_ram_limit = 0xFFFF;
static word mem_ram_limit_user = 0xFFFF;
static word mem_ram_limit_sys = 0xFFFF;
void mem_set_ram_limit_sys(uint16_t a)
{
if( a < MEMSIZE )
mem_ram_limit_sys = a;
else
mem_ram_limit_sys = MEMSIZE-1;
mem_ram_limit = min(mem_ram_limit_user, mem_ram_limit_sys);
}
void mem_set_ram_limit_usr(uint16_t a)
{
if( a < mem_ram_limit_user )
{
// areas without RAM read 0xFF
for(uint16_t i=a; i<MEMSIZE-1 && i<mem_ram_limit_sys-1; i++)
Mem[i+1] = 0xFF;
}
else if( a > mem_ram_limit_user )
{
// initialize newly "installed" RAM with 0
for(uint16_t i=mem_ram_limit_user+1; i<MEMSIZE-1 && i<a && i<mem_ram_limit_sys; i++)
Mem[i+1] = 0x00;
}
if( a < MEMSIZE )
mem_ram_limit_user = a;
else
mem_ram_limit_user = MEMSIZE-1;
mem_ram_limit = min(mem_ram_limit_user, mem_ram_limit_sys);
}
uint16_t mem_get_ram_limit_usr()
{
return mem_ram_limit_user;
}
void mem_clr_ram_limit()
{
mem_ram_limit = mem_ram_limit_user;
}
void mem_setup()
{
#if USE_PROTECT>0
for(int i=0; i<32; i++) protected_flags[i]=0x00;
protected_flag = 0;
#endif
mem_ram_limit_user = MEMSIZE-1;
mem_ram_limit_sys = 0xFFFF;
mem_clr_ram_limit();
}