forked from deadsy/py_z80
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtec1.py
More file actions
228 lines (190 loc) · 6.63 KB
/
Copy pathtec1.py
File metadata and controls
228 lines (190 loc) · 6.63 KB
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
#-----------------------------------------------------------------------------
"""
Talking Electronics Computer Emulator
"""
#-----------------------------------------------------------------------------
import memory
import z80da
import z80
import monitor
import util
import pygame
from pygame.locals import *
#-----------------------------------------------------------------------------
_screen_x = 400
_screen_y = 50
_border = (0, 0, 0)
#-----------------------------------------------------------------------------
class memmap:
"""memory devices and address map"""
def __init__(self, romfile = './roms/tec1a.rom'):
self.rom = memory.rom(11)
self.rom.load_file(0, romfile)
self.ram = memory.ram(11)
self.empty = memory.null()
def select(self, adr):
"""return the memory object selected by this address"""
# select with 2k granularity
memmap = (
self.rom, # 0x0000 - 0x07ff
self.ram, # 0x0800 - 0x0fff
self.empty, # 0x1000
self.empty, # 0x1800
self.empty, # 0x2000
self.empty, # 0x2800
self.empty, # 0x3000
self.empty, # 0x3800
self.empty, # 0x4000
self.empty, # 0x4800
self.empty, # 0x5000
self.empty, # 0x5800
self.empty, # 0x6000
self.empty, # 0x6800
self.empty, # 0x7000
self.empty, # 0x7800
self.empty, # 0x8000
self.empty, # 0x8800
self.empty, # 0x9000
self.empty, # 0x9800
self.empty, # 0xa000
self.empty, # 0xa800
self.empty, # 0xb000
self.empty, # 0xb800
self.empty, # 0xc000
self.empty, # 0xc800
self.empty, # 0xd000
self.empty, # 0xd800
self.empty, # 0xe000
self.empty, # 0xe800
self.empty, # 0xf000
self.empty, # 0xf800
)
return memmap[adr >> 11]
def __getitem__(self, adr):
adr &= 0xffff
return self.select(adr)[adr]
def __setitem__(self, adr, val):
adr &= 0xffff
self.select(adr)[adr] = val
#-----------------------------------------------------------------------------
class display:
"""6 x 7 segment led displays"""
def __init__(self):
pass
def select(self, val):
print '%d' % val
def segments(self, val):
pass
def refresh(self, screen):
"""refresh the whole display"""
bg = pygame.Surface(screen.get_size())
bg = bg.convert()
bg.fill(_border)
screen.blit(bg, (0, 0))
pygame.display.flip()
def update(self, screen):
"""update the video display"""
pygame.display.flip()
#-----------------------------------------------------------------------------
class keyboard:
"""keyboard emulation"""
def __init__(self):
pass
def get(self):
"""process keyboard events"""
for event in pygame.event.get():
if event.type == KEYDOWN:
return True
elif event.type == KEYUP:
pass
return False
def rd(self, adr):
"""return the current port value"""
return 0
#-----------------------------------------------------------------------------
class io:
"""io handler"""
def __init__(self, display, keyboard):
self.display = display
self.keyboard = keyboard
def rd(self, adr):
print 'rd %04x' % adr
return 0xff
def wr(self, adr, val):
adr &= 0xff
if adr == 0x01:
self.display.select(val)
elif adr == 0x02:
self.display.segments(val)
else:
print 'wr %04x %02x' % (adr, val)
#-----------------------------------------------------------------------------
class tec1:
def __init__(self, app):
self.app = app
self.display = display()
self.keyboard = keyboard()
self.mem = memmap()
self.io = io(self.display, self.keyboard)
self.cpu = z80.cpu(self.mem, self.io)
self.mon = monitor.monitor(self.cpu)
self.menu_root = (
('..', 'return to main menu', util.cr, self.parent_menu, None),
('da', 'disassemble memory', monitor._help_disassemble, self.mon.cli_disassemble, None),
('exit', 'exit the application', util.cr, self.exit, None),
('help', 'display general help', util.cr, app.general_help, None),
('memory', 'memory functions', None, None, self.mon.menu_memory),
('regs', 'display cpu registers', util.cr, self.mon.cli_registers, None),
('run', 'run the emulation', util.cr, self.cli_run, None),
('step', 'single step the emulation', util.cr, self.cli_step, None),
)
# setup the video window
pygame.init()
self.screen = pygame.display.set_mode((_screen_x, _screen_y))
pygame.display.set_caption('Talking Electronics Computer TEC 1')
self.display.refresh(self.screen)
app.cli.set_poll(pygame.event.pump)
app.cli.set_root(self.menu_root)
self.app.cli.set_prompt('\ntec1> ')
def cli_run(self, app, args):
"""run the emulation"""
app.put('\n\npress any key to halt\n')
irq = False
x = 0
while True:
if app.io.anykey():
return
try:
pc = self.cpu._get_pc()
if irq:
self.cpu.interrupt(x)
irq = False
x += 1
else:
self.cpu.execute()
except z80.Error, e:
self.cpu._set_pc(pc)
app.put('exception: %s\n' % e)
return
print x
self.display.update(self.screen)
irq = self.keyboard.get()
def current_instruction(self):
"""return a string for the current instruction"""
pc = self.cpu._get_pc()
(operation, operands, n) = self.cpu.da(pc)
return '%04x %-5s %s' % (pc, operation, operands)
def cli_step(self, app, args):
"""single step the cpu"""
done = 'done: %s' % self.current_instruction()
self.cpu.execute()
next = 'next: %s' % self.current_instruction()
app.put('\n\n%s\n' % '\n'.join((done, next)))
def exit(self, app, args):
"""exit the application"""
app.exit(app, [])
def parent_menu(self, app, args):
"""return to parent menu"""
app.put('\n')
app.main_menu()
#-----------------------------------------------------------------------------