Merge 23e7f44242
into 934bf1a495
This commit is contained in:
commit
b47390bdb7
28
applepy.py
28
applepy.py
|
@ -279,7 +279,7 @@ class Speaker:
|
|||
|
||||
def toggle(self, cycle):
|
||||
if self.last_toggle is not None:
|
||||
l = (cycle - self.last_toggle) / Speaker.CPU_CYCLES_PER_SAMPLE
|
||||
l = (cycle - self.last_toggle) // Speaker.CPU_CYCLES_PER_SAMPLE
|
||||
self.buffer.extend([0, 26000] if self.polarity else [0, -2600])
|
||||
self.buffer.extend((l - 2) * [16384] if self.polarity else [-16384])
|
||||
self.polarity = not self.polarity
|
||||
|
@ -391,7 +391,7 @@ class Apple2:
|
|||
|
||||
rs, _, _ = select.select([listener], [], [], 2)
|
||||
if not rs:
|
||||
print >>sys.stderr, "CPU module did not start"
|
||||
print("CPU module did not start", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
self.cpu, _ = listener.accept()
|
||||
|
||||
|
@ -404,7 +404,7 @@ class Apple2:
|
|||
break
|
||||
cycle, rw, addr, val = struct.unpack("<IBHB", op)
|
||||
if rw == 0:
|
||||
self.cpu.send(chr(self.softswitches.read_byte(cycle, addr)))
|
||||
self.cpu.send(struct.pack("B", self.softswitches.read_byte(cycle, addr)))
|
||||
elif rw == 1:
|
||||
self.display.update(addr, val)
|
||||
else:
|
||||
|
@ -415,7 +415,7 @@ class Apple2:
|
|||
quit = True
|
||||
|
||||
if event.type == pygame.KEYDOWN:
|
||||
key = ord(event.unicode) if event.unicode else 0
|
||||
key = ord(event.unicode.encode("ascii")) if event.unicode else 0
|
||||
if event.key == pygame.K_LEFT:
|
||||
key = 0x08
|
||||
if event.key == pygame.K_RIGHT:
|
||||
|
@ -435,16 +435,16 @@ class Apple2:
|
|||
|
||||
|
||||
def usage():
|
||||
print >>sys.stderr, "ApplePy - an Apple ][ emulator in Python"
|
||||
print >>sys.stderr, "James Tauber / http://jtauber.com/"
|
||||
print >>sys.stderr
|
||||
print >>sys.stderr, "Usage: applepy.py [options]"
|
||||
print >>sys.stderr
|
||||
print >>sys.stderr, " -c, --cassette Cassette wav file to load"
|
||||
print >>sys.stderr, " -R, --rom ROM file to use (default A2ROM.BIN)"
|
||||
print >>sys.stderr, " -r, --ram RAM file to load (default none)"
|
||||
print >>sys.stderr, " -p, --pc Initial PC value"
|
||||
print >>sys.stderr, " -q, --quiet Quiet mode, no sounds (default sounds)"
|
||||
print("ApplePy - an Apple ][ emulator in Python", file=sys.stderr)
|
||||
print("James Tauber / http://jtauber.com/", file=sys.stderr)
|
||||
print(file=sys.stderr)
|
||||
print("Usage: applepy.py [options]", file=sys.stderr)
|
||||
print(file=sys.stderr)
|
||||
print(" -c, --cassette Cassette wav file to load", file=sys.stderr)
|
||||
print(" -R, --rom ROM file to use (default A2ROM.BIN)", file=sys.stderr)
|
||||
print(" -r, --ram RAM file to load (default none)", file=sys.stderr)
|
||||
print(" -p, --pc Initial PC value", file=sys.stderr)
|
||||
print(" -q, --quiet Quiet mode, no sounds (default sounds)", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
|
|
@ -98,12 +98,12 @@ def run(win):
|
|||
|
||||
|
||||
def usage():
|
||||
print >>sys.stderr, "ApplePy - an Apple ][ emulator in Python"
|
||||
print >>sys.stderr, "James Tauber / http://jtauber.com/"
|
||||
print >>sys.stderr
|
||||
print >>sys.stderr, "Usage: applepy_curses.py [options]"
|
||||
print >>sys.stderr
|
||||
print >>sys.stderr, " -R, --rom ROM file to use (default A2ROM.BIN)"
|
||||
print("ApplePy - an Apple ][ emulator in Python", file=sys.stderr)
|
||||
print("James Tauber / http://jtauber.com/", file=sys.stderr)
|
||||
print(file=sys.stderr)
|
||||
print("Usage: applepy_curses.py [options]", file=sys.stderr)
|
||||
print(file=sys.stderr)
|
||||
print(" -R, --rom ROM file to use (default A2ROM.BIN)", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
|
32
control.py
32
control.py
|
@ -1,16 +1,16 @@
|
|||
import json
|
||||
import sys
|
||||
import urllib
|
||||
import urllib.request, urllib.parse, urllib.error
|
||||
|
||||
URL_PREFIX = "http://localhost:6502"
|
||||
|
||||
|
||||
def get(url):
|
||||
return json.loads(urllib.urlopen(URL_PREFIX + url).read())
|
||||
return json.loads(urllib.request.urlopen(URL_PREFIX + url).read())
|
||||
|
||||
|
||||
def post(url, data=None):
|
||||
return urllib.urlopen(URL_PREFIX + url, json.dumps(data) if data is not None else "")
|
||||
return urllib.request.urlopen(URL_PREFIX + url, json.dumps(data) if data is not None else "")
|
||||
|
||||
|
||||
def value(s):
|
||||
|
@ -45,7 +45,7 @@ def cmd_disassemble(a):
|
|||
addr = status["program_counter"]
|
||||
disasm = get("/disassemble/%d" % addr)
|
||||
for d in disasm:
|
||||
print format_disassemble(d)
|
||||
print(format_disassemble(d))
|
||||
|
||||
|
||||
def cmd_dump(a):
|
||||
|
@ -80,7 +80,7 @@ def cmd_dump(a):
|
|||
s += "."
|
||||
else:
|
||||
s += " "
|
||||
print s
|
||||
print(s)
|
||||
addr += 16
|
||||
|
||||
|
||||
|
@ -89,20 +89,20 @@ def cmd_help(a):
|
|||
if len(a) > 1:
|
||||
f = Commands.get(a[1])
|
||||
if f is not None:
|
||||
print f.__doc__
|
||||
print(f.__doc__)
|
||||
else:
|
||||
print "Unknown command:", a[1]
|
||||
print("Unknown command:", a[1])
|
||||
else:
|
||||
print "Commands:"
|
||||
print("Commands:")
|
||||
for c in sorted(Commands):
|
||||
print " ", c
|
||||
print(" ", c)
|
||||
|
||||
|
||||
def cmd_peek(a):
|
||||
"""Peek memory location"""
|
||||
addr = value(a[1])
|
||||
dump = get("/memory/%d" % addr)
|
||||
print "%04X: %02X" % (addr, dump[0])
|
||||
print("%04X: %02X" % (addr, dump[0]))
|
||||
|
||||
|
||||
def cmd_poke(a):
|
||||
|
@ -115,7 +115,7 @@ def cmd_poke(a):
|
|||
def cmd_status(a):
|
||||
"""CPU status"""
|
||||
status = get("/status")
|
||||
print "A=%02X X=%02X Y=%02X S=%02X PC=%04X F=%c%c0%c%c%c%c%c" % (
|
||||
print("A=%02X X=%02X Y=%02X S=%02X PC=%04X F=%c%c0%c%c%c%c%c" % (
|
||||
status["accumulator"],
|
||||
status["x_index"],
|
||||
status["y_index"],
|
||||
|
@ -128,9 +128,9 @@ def cmd_status(a):
|
|||
"I" if status["interrupt_disable_flag"] else "i",
|
||||
"Z" if status["zero_flag"] else "z",
|
||||
"C" if status["carry_flag"] else "c",
|
||||
)
|
||||
))
|
||||
disasm = get("/disassemble/%d" % status["program_counter"])
|
||||
print format_disassemble(disasm[0])
|
||||
print(format_disassemble(disasm[0]))
|
||||
|
||||
|
||||
def cmd_quit(a):
|
||||
|
@ -155,15 +155,15 @@ Commands = {
|
|||
|
||||
|
||||
def main():
|
||||
print "ApplePy control console"
|
||||
print("ApplePy control console")
|
||||
while True:
|
||||
s = raw_input("6502> ")
|
||||
s = input("6502> ")
|
||||
a = s.strip().split()
|
||||
f = Commands.get(a[0])
|
||||
if f is not None:
|
||||
f(a)
|
||||
else:
|
||||
print "Unknown command:", s
|
||||
print("Unknown command:", s)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
73
cpu6502.py
73
cpu6502.py
|
@ -3,7 +3,7 @@
|
|||
# originally written 2001, updated 2011
|
||||
|
||||
|
||||
import BaseHTTPServer
|
||||
import http.server
|
||||
import json
|
||||
import re
|
||||
import select
|
||||
|
@ -35,7 +35,7 @@ class ROM:
|
|||
def load_file(self, address, filename):
|
||||
with open(filename, "rb") as f:
|
||||
for offset, datum in enumerate(f.read()):
|
||||
self._mem[address - self.start + offset] = ord(datum)
|
||||
self._mem[address - self.start + offset] = datum
|
||||
|
||||
def read_byte(self, address):
|
||||
assert self.start <= address <= self.end
|
||||
|
@ -365,7 +365,7 @@ class Disassemble:
|
|||
return r, info[0]
|
||||
|
||||
|
||||
class ControlHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
class ControlHandler(http.server.BaseHTTPRequestHandler):
|
||||
|
||||
def __init__(self, request, client_address, server, cpu):
|
||||
self.cpu = cpu
|
||||
|
@ -385,13 +385,13 @@ class ControlHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
|||
r"/reset$": self.post_reset,
|
||||
}
|
||||
|
||||
BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, request, client_address, server)
|
||||
http.server.BaseHTTPRequestHandler.__init__(self, request, client_address, server)
|
||||
|
||||
def log_request(self, code, size=0):
|
||||
pass
|
||||
|
||||
def dispatch(self, urls):
|
||||
for r, f in urls.items():
|
||||
for r, f in list(urls.items()):
|
||||
m = re.match(r, self.path)
|
||||
if m is not None:
|
||||
f(m)
|
||||
|
@ -439,7 +439,7 @@ class ControlHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
|||
end = int(e)
|
||||
else:
|
||||
end = addr
|
||||
self.response(json.dumps(list(map(self.cpu.read_byte, range(addr, end + 1)))))
|
||||
self.response(json.dumps(list(map(self.cpu.read_byte, list(range(addr, end + 1))))))
|
||||
|
||||
def get_status(self, m):
|
||||
self.response(json.dumps(dict((x, getattr(self.cpu, x)) for x in (
|
||||
|
@ -505,10 +505,10 @@ class CPU:
|
|||
STACK_PAGE = 0x100
|
||||
RESET_VECTOR = 0xFFFC
|
||||
|
||||
def __init__(self, options, memory):
|
||||
def __init__(self, memory, pc=None):
|
||||
self.memory = memory
|
||||
|
||||
self.control_server = BaseHTTPServer.HTTPServer(("127.0.0.1", 6502), ControlHandlerFactory(self))
|
||||
self.control_server = memory.use_bus and http.server.HTTPServer(("127.0.0.1", 6502), ControlHandlerFactory(self))
|
||||
|
||||
self.accumulator = 0x00
|
||||
self.x_index = 0x00
|
||||
|
@ -528,8 +528,8 @@ class CPU:
|
|||
|
||||
self.setup_ops()
|
||||
self.reset()
|
||||
if options.pc is not None:
|
||||
self.program_counter = options.pc
|
||||
if pc is not None:
|
||||
self.program_counter = pc
|
||||
self.running = True
|
||||
self.quit = False
|
||||
|
||||
|
@ -704,13 +704,14 @@ class CPU:
|
|||
# a connection is accepted until the response
|
||||
# is sent. TODO: use an async HTTP server that
|
||||
# handles input data asynchronously.
|
||||
sockets = [self.control_server]
|
||||
rs, _, _ = select.select(sockets, [], [], timeout)
|
||||
for s in rs:
|
||||
if s is self.control_server:
|
||||
self.control_server._handle_request_noblock()
|
||||
else:
|
||||
pass
|
||||
if self.control_server:
|
||||
sockets = [self.control_server]
|
||||
rs, _, _ = select.select(sockets, [], [], timeout)
|
||||
for s in rs:
|
||||
if s is self.control_server:
|
||||
self.control_server._handle_request_noblock()
|
||||
else:
|
||||
pass
|
||||
|
||||
count = 1000
|
||||
while count > 0 and self.running:
|
||||
|
@ -718,9 +719,9 @@ class CPU:
|
|||
op = self.read_pc_byte()
|
||||
func = self.ops[op]
|
||||
if func is None:
|
||||
print "UNKNOWN OP"
|
||||
print hex(self.program_counter - 1)
|
||||
print hex(op)
|
||||
print("UNKNOWN OP")
|
||||
print(hex(self.program_counter - 1))
|
||||
print(hex(op))
|
||||
break
|
||||
else:
|
||||
self.ops[op]()
|
||||
|
@ -735,9 +736,9 @@ class CPU:
|
|||
op = self.read_pc_byte()
|
||||
func = self.ops[op]
|
||||
if func is None:
|
||||
print "UNKNOWN OP"
|
||||
print hex(self.program_counter - 1)
|
||||
print hex(op)
|
||||
print("UNKNOWN OP")
|
||||
print(hex(self.program_counter - 1))
|
||||
print(hex(op))
|
||||
break
|
||||
else:
|
||||
self.ops[op]()
|
||||
|
@ -1156,10 +1157,10 @@ class CPU:
|
|||
|
||||
def BRK(self):
|
||||
self.cycles += 5
|
||||
self.break_flag = 1 # set break_flag before status pushed
|
||||
self.push_word(self.program_counter + 1)
|
||||
self.push_byte(self.status_as_byte())
|
||||
self.program_counter = self.read_word(0xFFFE)
|
||||
self.break_flag = 1
|
||||
|
||||
def RTI(self):
|
||||
self.cycles += 4
|
||||
|
@ -1171,15 +1172,15 @@ class CPU:
|
|||
|
||||
|
||||
def usage():
|
||||
print >>sys.stderr, "ApplePy - an Apple ][ emulator in Python"
|
||||
print >>sys.stderr, "James Tauber / http://jtauber.com/"
|
||||
print >>sys.stderr
|
||||
print >>sys.stderr, "Usage: cpu6502.py [options]"
|
||||
print >>sys.stderr
|
||||
print >>sys.stderr, " -b, --bus Bus port number"
|
||||
print >>sys.stderr, " -p, --pc Initial PC value"
|
||||
print >>sys.stderr, " -R, --rom ROM file to use (default A2ROM.BIN)"
|
||||
print >>sys.stderr, " -r, --ram RAM file to load (default none)"
|
||||
print("ApplePy - an Apple ][ emulator in Python", file=sys.stderr)
|
||||
print("James Tauber / http://jtauber.com/", file=sys.stderr)
|
||||
print(file=sys.stderr)
|
||||
print("Usage: cpu6502.py [options]", file=sys.stderr)
|
||||
print(file=sys.stderr)
|
||||
print(" -b, --bus Bus port number", file=sys.stderr)
|
||||
print(" -p, --pc Initial PC value", file=sys.stderr)
|
||||
print(" -R, --rom ROM file to use (default A2ROM.BIN)", file=sys.stderr)
|
||||
print(" -r, --ram RAM file to load (default none)", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
@ -1219,11 +1220,11 @@ def get_options():
|
|||
if __name__ == "__main__":
|
||||
options = get_options()
|
||||
if options.bus is None:
|
||||
print "ApplePy cpu core"
|
||||
print "Run applepy.py instead"
|
||||
print("ApplePy cpu core")
|
||||
print("Run applepy.py instead")
|
||||
sys.exit(0)
|
||||
|
||||
mem = Memory(options)
|
||||
|
||||
cpu = CPU(options, mem)
|
||||
cpu = CPU(mem, options.pc)
|
||||
cpu.run(options.bus)
|
||||
|
|
Loading…
Reference in New Issue