From 4963eeca9d4e0b891c57b28fc09e6b2fee222346 Mon Sep 17 00:00:00 2001 From: Greg Hewgill Date: Tue, 16 Aug 2011 15:49:48 +1200 Subject: [PATCH 1/3] initial cassette input --- applepy.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/applepy.py b/applepy.py index 479de65..592cc64 100644 --- a/applepy.py +++ b/applepy.py @@ -9,6 +9,7 @@ import struct import subprocess import sys import time +import wave class Display: @@ -288,12 +289,24 @@ class Speaker: self.play() +class Cassette: + + def __init__(self, fn): + wav = wave.open(fn, "r") + self.raw = wav.readframes(wav.getnframes()) + + def read_byte(self, cycle): + sys.stdout.write(str(cycle * 22000 / 1000000) + "\r") + return ord(self.raw[cycle * 22000 / 1000000]) + + class SoftSwitches: - def __init__(self, display, speaker): + def __init__(self, display, speaker, cassette): self.kbd = 0x00 self.display = display self.speaker = speaker + self.cassette = cassette def read_byte(self, cycle, address): assert 0xC000 <= address <= 0xCFFF @@ -320,6 +333,8 @@ class SoftSwitches: self.display.lores() elif address == 0xC057: self.display.hires() + elif address == 0xC060: + return self.cassette.read_byte(cycle) else: pass # print "%04X" % address return 0x00 @@ -327,10 +342,10 @@ class SoftSwitches: class Apple2: - def __init__(self, options, display, speaker): + def __init__(self, options, display, speaker, cassette): self.display = display self.speaker = speaker - self.softswitches = SoftSwitches(display, speaker) + self.softswitches = SoftSwitches(display, speaker, cassette) args = [ sys.executable, @@ -429,6 +444,7 @@ if __name__ == "__main__": options = get_options() display = Display() speaker = None if options.quiet else Speaker() + cassette = Cassette("k7_apple_600202300_littlebrickout.wav") - apple = Apple2(options, display, speaker) + apple = Apple2(options, display, speaker, cassette) apple.run() From 6951db69adf9f42297a1cb3739610f62d92ae294 Mon Sep 17 00:00:00 2001 From: Greg Hewgill Date: Tue, 16 Aug 2011 16:41:15 +1200 Subject: [PATCH 2/3] finish cassette support --- applepy.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/applepy.py b/applepy.py index 592cc64..4fbfa37 100644 --- a/applepy.py +++ b/applepy.py @@ -296,8 +296,8 @@ class Cassette: self.raw = wav.readframes(wav.getnframes()) def read_byte(self, cycle): - sys.stdout.write(str(cycle * 22000 / 1000000) + "\r") - return ord(self.raw[cycle * 22000 / 1000000]) + offset = cycle * 22000 / 1000000 + return ord(self.raw[offset]) if offset < len(self.raw) else 0x80 class SoftSwitches: @@ -334,7 +334,8 @@ class SoftSwitches: elif address == 0xC057: self.display.hires() elif address == 0xC060: - return self.cassette.read_byte(cycle) + if self.cassette: + return self.cassette.read_byte(cycle) else: pass # print "%04X" % address return 0x00 @@ -406,6 +407,7 @@ def usage(): 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, " -q, --quiet Quiet mode, no sounds (default sounds)" @@ -415,6 +417,7 @@ def usage(): def get_options(): class Options: def __init__(self): + self.cassette = None self.rom = "A2ROM.BIN" self.ram = None self.quiet = False @@ -423,7 +426,10 @@ def get_options(): a = 1 while a < len(sys.argv): if sys.argv[a].startswith("-"): - if sys.argv[a] in ("-R", "--rom"): + if sys.argv[a] in ("-c", "--cassette"): + a += 1 + options.cassette = sys.argv[a] + elif sys.argv[a] in ("-R", "--rom"): a += 1 options.rom = sys.argv[a] elif sys.argv[a] in ("-r", "--ram"): @@ -444,7 +450,7 @@ if __name__ == "__main__": options = get_options() display = Display() speaker = None if options.quiet else Speaker() - cassette = Cassette("k7_apple_600202300_littlebrickout.wav") + cassette = Cassette(options.cassette) if options.cassette else None apple = Apple2(options, display, speaker, cassette) apple.run() From b8c7949d8e1a27f521bbb898468e2fa0b6036ca8 Mon Sep 17 00:00:00 2001 From: Greg Hewgill Date: Tue, 16 Aug 2011 18:22:41 +1200 Subject: [PATCH 3/3] attempt to skip to data part of tape --- applepy.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/applepy.py b/applepy.py index 4fbfa37..5052474 100644 --- a/applepy.py +++ b/applepy.py @@ -294,9 +294,18 @@ class Cassette: def __init__(self, fn): wav = wave.open(fn, "r") self.raw = wav.readframes(wav.getnframes()) + self.start_cycle = 0 + self.start_offset = 0 + + for i, b in enumerate(self.raw): + if ord(b) > 0xA0: + self.start_offset = i + break def read_byte(self, cycle): - offset = cycle * 22000 / 1000000 + if self.start_cycle == 0: + self.start_cycle = cycle + offset = self.start_offset + (cycle - self.start_cycle) * 22000 / 1000000 return ord(self.raw[offset]) if offset < len(self.raw) else 0x80