mirror of
https://github.com/jtauber/applepy.git
synced 2024-11-26 16:49:32 +00:00
implemented speaker; not a bad hack :-)
This commit is contained in:
parent
35c0e69991
commit
4dd414dea8
47
applepy.py
47
applepy.py
@ -3,6 +3,7 @@
|
|||||||
# originally written 2001, updated 2011
|
# originally written 2001, updated 2011
|
||||||
|
|
||||||
|
|
||||||
|
import numpy
|
||||||
import pygame
|
import pygame
|
||||||
import colorsys
|
import colorsys
|
||||||
|
|
||||||
@ -238,6 +239,30 @@ class Display:
|
|||||||
del pixels
|
del pixels
|
||||||
|
|
||||||
|
|
||||||
|
class Speaker:
|
||||||
|
|
||||||
|
CPU_CYCLES_PER_SAMPLE = 70
|
||||||
|
CHECK_INTERVAL = 1000
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pygame.mixer.pre_init(44100, -16, 1)
|
||||||
|
pygame.init()
|
||||||
|
self.reset()
|
||||||
|
|
||||||
|
def toggle(self, cycle):
|
||||||
|
if self.last_toggle is not None:
|
||||||
|
l = (cycle - self.last_toggle) / Speaker.CPU_CYCLES_PER_SAMPLE
|
||||||
|
self.buffer.extend([0, 0.8] if self.polarity else [0, -0.8])
|
||||||
|
self.buffer.extend(l * [0.5] if self.polarity else [-0.5])
|
||||||
|
self.polarity = not self.polarity
|
||||||
|
self.last_toggle = cycle
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
self.last_toggle = None
|
||||||
|
self.buffer = []
|
||||||
|
self.polarity = False
|
||||||
|
|
||||||
|
|
||||||
class ROM:
|
class ROM:
|
||||||
|
|
||||||
def __init__(self, start, size):
|
def __init__(self, start, size):
|
||||||
@ -267,9 +292,10 @@ class RAM(ROM):
|
|||||||
|
|
||||||
class SoftSwitches:
|
class SoftSwitches:
|
||||||
|
|
||||||
def __init__(self, display):
|
def __init__(self, display, speaker):
|
||||||
self.kbd = 0x00
|
self.kbd = 0x00
|
||||||
self.display = display
|
self.display = display
|
||||||
|
self.speaker = speaker
|
||||||
|
|
||||||
def read_byte(self, cycle, address):
|
def read_byte(self, cycle, address):
|
||||||
assert 0xC000 <= address <= 0xCFFF
|
assert 0xC000 <= address <= 0xCFFF
|
||||||
@ -278,7 +304,8 @@ class SoftSwitches:
|
|||||||
elif address == 0xC010:
|
elif address == 0xC010:
|
||||||
self.kbd = self.kbd & 0x7F
|
self.kbd = self.kbd & 0x7F
|
||||||
elif address == 0xC030:
|
elif address == 0xC030:
|
||||||
pass # toggle speaker
|
if self.speaker:
|
||||||
|
self.speaker.toggle(cycle)
|
||||||
elif address == 0xC050:
|
elif address == 0xC050:
|
||||||
self.display.txtclr()
|
self.display.txtclr()
|
||||||
elif address == 0xC051:
|
elif address == 0xC051:
|
||||||
@ -302,15 +329,16 @@ class SoftSwitches:
|
|||||||
|
|
||||||
class Memory:
|
class Memory:
|
||||||
|
|
||||||
def __init__(self, display=None):
|
def __init__(self, display=None, speaker=None):
|
||||||
self.display = display
|
self.display = display
|
||||||
|
self.speaker = speaker
|
||||||
self.rom = ROM(0xD000, 0x3000)
|
self.rom = ROM(0xD000, 0x3000)
|
||||||
|
|
||||||
# available from http://www.easy68k.com/paulrsm/6502/index.html
|
# available from http://www.easy68k.com/paulrsm/6502/index.html
|
||||||
self.rom.load_file(0xD000, "A2ROM.BIN")
|
self.rom.load_file(0xD000, "A2ROM.BIN")
|
||||||
|
|
||||||
self.ram = RAM(0x0000, 0xC000)
|
self.ram = RAM(0x0000, 0xC000)
|
||||||
self.softswitches = SoftSwitches(display)
|
self.softswitches = SoftSwitches(display, speaker)
|
||||||
|
|
||||||
def load(self, address, data):
|
def load(self, address, data):
|
||||||
if address < 0xC000:
|
if address < 0xC000:
|
||||||
@ -340,6 +368,13 @@ class Memory:
|
|||||||
self.display.update(address, value)
|
self.display.update(address, value)
|
||||||
if 0x2000 <= address < 0x5FFF and self.display:
|
if 0x2000 <= address < 0x5FFF and self.display:
|
||||||
self.display.update(address, value)
|
self.display.update(address, value)
|
||||||
|
|
||||||
|
def update(self, cycle):
|
||||||
|
if self.speaker.buffer and (cycle - self.speaker.last_toggle) > self.speaker.CHECK_INTERVAL:
|
||||||
|
sample_array = numpy.array(self.speaker.buffer)
|
||||||
|
sound = pygame.sndarray.make_sound(sample_array)
|
||||||
|
sound.play()
|
||||||
|
self.speaker.reset()
|
||||||
|
|
||||||
|
|
||||||
class Disassemble:
|
class Disassemble:
|
||||||
@ -774,6 +809,7 @@ class CPU:
|
|||||||
update_cycle += 1
|
update_cycle += 1
|
||||||
if update_cycle >= 1024:
|
if update_cycle >= 1024:
|
||||||
pygame.display.flip()
|
pygame.display.flip()
|
||||||
|
self.memory.update(self.cycles)
|
||||||
update_cycle = 0
|
update_cycle = 0
|
||||||
|
|
||||||
def test_run(self, start, end):
|
def test_run(self, start, end):
|
||||||
@ -1220,7 +1256,8 @@ class CPU:
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
display = Display()
|
display = Display()
|
||||||
mem = Memory(display)
|
speaker = Speaker()
|
||||||
|
mem = Memory(display, speaker)
|
||||||
|
|
||||||
cpu = CPU(mem)
|
cpu = CPU(mem)
|
||||||
cpu.run()
|
cpu.run()
|
||||||
|
Loading…
Reference in New Issue
Block a user