Checkpoint WIP

- use exotic opcodes in player
- optimize encoder
This commit is contained in:
kris 2020-08-24 21:27:24 +01:00
parent 5fb995c435
commit 7a4a36af6b
4 changed files with 621 additions and 88 deletions

View File

@ -52,10 +52,10 @@ def lookahead(step_size: int, initial_position: float, data: numpy.ndarray,
target_val = data[offset:offset + voltages.shape[1]]
scaled_voltages = voltages / step_size
position_scale = (1 - 1 / step_size)
for i in range(0, voltages.shape[1]):
positions[:, i + 1] = (
scaled_voltages[:, i] + positions[:, i] * (1 - 1 / step_size))
scaled_voltages[:, i] + positions[:, i] * position_scale)
err = positions[:, 1:] - target_val
total_error = numpy.sum(numpy.power(err, 2), axis=1)
@ -76,11 +76,16 @@ def evolve(opcode: opcodes.Opcode, starting_position, starting_voltage,
position = starting_position
total_err = 0.0
v = starting_voltage
last_v = v
num_flips = 0
for i, v in enumerate(voltages):
if v != last_v:
num_flips += 1
last_v = v
position += (v - position) / step_size
err = position - data[starting_idx + i]
total_err += err ** 2
return position, v, total_err, starting_idx + opcode_length
return position, v, total_err, starting_idx + opcode_length, num_flips
def audio_bytestream(data: numpy.ndarray, step: int, lookahead_steps: int):
@ -99,34 +104,33 @@ def audio_bytestream(data: numpy.ndarray, step: int, lookahead_steps: int):
i = 0
last_updated = 0
opcode_counts = collections.defaultdict(int)
while i < dlen:
num_flips = 0
while i < int(dlen/10):
if (i - last_updated) > int((dlen / 1000)):
eta.print_status()
last_updated = i
candidate_opcodes = opcodes.opcode_lookahead(
candidate_opcodes, voltages = opcodes.candidate_opcodes(
frame_offset, lookahead_steps)
pruned_opcodes, voltages = opcodes.prune_opcodes(
candidate_opcodes, lookahead_steps)
opcode_idx = lookahead(step, position, data, i, voltage * voltages)
opcode = pruned_opcodes[opcode_idx].opcodes[0]
opcode = candidate_opcodes[opcode_idx].opcodes[0]
opcode_counts[opcode] += 1
yield opcode
# TODO: round position and memoize, and use in lookahead too
position, voltage, new_error, i = evolve(
position, voltage, new_error, i, new_flips = evolve(
opcode, position, voltage, step, data, i)
total_err += new_error
num_flips += new_flips
frame_offset = (frame_offset + 1) % 2048
for _ in range(frame_offset % 2048, 2047):
yield opcodes.Opcode.NOTICK_6
yield opcodes.Opcode.TICK_00
yield opcodes.Opcode.EXIT
eta.done()
print("Total error %f" % total_err)
print("%d speaker actuations" % num_flips)
print("Opcodes used:")
for v, k in sorted(list(opcode_counts.items()), key=lambda kv: kv[1],

View File

@ -5,19 +5,86 @@ from typing import Dict, List, Tuple, Iterable
# TODO: support 6502 cycle counts as well
#
# class Opcode(enum.Enum):
# """Audio player opcodes representing atomic units of audio playback work."""
# TICK_17 = 0x00
# TICK_15 = 0x01
# TICK_13 = 0x02
# TICK_14 = 0x0a
# TICK_12 = 0x0b
# TICK_10 = 0x0c
# NOTICK_6 = 0x0f
#
# EXIT = 0x12
# SLOWPATH = 0x22
#
# # XXX not yet diminishing returns, add more?
# # TODO: incremental quality from each of these
# TICK_TICK_TICK_TICK_TICK = 0x77
# TICK_TICK_TICK_TICK = 0x7a
# TICK_TICK_TICK = 0x7d
# TICK_TICK = 0x80
# INC_INC_INC_INC_INC = 0x89
# INC_INC_INC_INC = 0x8c
# INC_INC_INC = 0x8f
# INC_INC = 0x92
# INC = 0x95
# STAX_STAX_STAX_STAX_STAX = 0x9b
# STAX_STAX_STAX_STAX = 0x9e
# STAX_STAX_STAX = 0xa1
# STAX_STAX = 0xa4
# STAX = 0xa7
# INCX_INCX_INCX_INCX_INCX = 0xad
# INCX_INCX_INCX_INCX = 0xb0
# INCX_INCX_INCX = 0xb3
# INCX_INCX = 0xb6
# INCX = 0xb9
class Opcode(enum.Enum):
"""Audio player opcodes representing atomic units of audio playback work."""
TICK_17 = 0x00
TICK_15 = 0x01
TICK_13 = 0x02
TICK_14 = 0x0a
TICK_12 = 0x0b
TICK_10 = 0x0c
NOTICK_6 = 0x0f
EXIT = 0x12
SLOWPATH = 0x22
TICK_01 = 0x01
TICK_02 = 0x02
TICK_03 = 0x03
TICK_04 = 0x04
TICK_05 = 0x05
TICK_08 = 0x08
TICK_09 = 0x09
TICK_0a = 0x0a
TICK_0b = 0x0b
TICK_0c = 0x0c
TICK_0e = 0x0e
TICK_12 = 0x12
TICK_13 = 0x13
TICK_14 = 0x14
TICK_17 = 0x17
TICK_1b = 0x1b
TICK_1c = 0x1c
TICK_1d = 0x1d
TICK_20 = 0x20
TICK_24 = 0x24
TICK_25 = 0x25
TICK_27 = 0x27
TICK_2e = 0x2e
TICK_2f = 0x2f
TICK_32 = 0x32
TICK_36 = 0x36
TICK_37 = 0x37
TICK_3a = 0x3a
TICK_3e = 0x3e
TICK_40 = 0x40
TICK_47 = 0x47
TICK_49 = 0x49
TICK_50 = 0x50
TICK_53 = 0x53
TICK_5a = 0x5a
TICK_5d = 0x5d
TICK_65 = 0x65
TICK_70 = 0x70
TICK_79 = 0x79
TICK_82 = 0x82
TICK_8b = 0x8b
TICK_94 = 0x94
EXIT = 0xfe
SLOWPATH = 0xff
def make_tick_voltages(length) -> numpy.ndarray:
@ -35,31 +102,195 @@ def make_notick_voltages(length) -> numpy.ndarray:
def make_slowpath_voltages() -> numpy.ndarray:
"""Voltage sequence for slowpath TCP processing."""
length = 8 * 14 + 10 # TODO: 6502
length = 14 * 10 + 10 # TODO: 6502
c = numpy.full(length, 1.0, dtype=numpy.float32)
voltage_high = True
for i in range(8):
for i in range(15):
voltage_high = not voltage_high
for j in range(3 + 14 * i, min(length, 3 + 14 * (i + 1))):
for j in range(3 + 10 * i, min(length, 3 + 10 * (i + 1))):
c[j] = 1.0 if voltage_high else -1.0
return c
# exp3
class Opcode(enum.Enum):
TICK_00 = 0x00
TICK_01 = 0x01
TICK_02 = 0x02
TICK_03 = 0x03
TICK_04 = 0x04
TICK_05 = 0x05
TICK_08 = 0x08
TICK_09 = 0x09
TICK_0a = 0x0a
TICK_0b = 0x0b
TICK_11 = 0x11
TICK_12 = 0x12
TICK_13 = 0x13
TICK_1a = 0x1a
TICK_1b = 0x1b
TICK_23 = 0x23
TICK_2c = 0x2c
TICK_2d = 0x2d
TICK_2e = 0x2e
TICK_34 = 0x34
TICK_35 = 0x35
TICK_36 = 0x36
TICK_3c = 0x3c
TICK_3d = 0x3d
TICK_46 = 0x46
TICK_47 = 0x47
TICK_4e = 0x4e
TICK_4f = 0x4f
TICK_56 = 0x56
TICK_60 = 0x60
TICK_6a = 0x6a
TICK_72 = 0x72
TICK_7a = 0x7a
TICK_7b = 0x7b
TICK_81 = 0x81
TICK_8a = 0x8a
TICK_93 = 0x93
TICK_9c = 0x9c
TICK_a5 = 0xa5
TICK_ae = 0xae
EXIT = 0xb5
SLOWPATH = 0xb8
# Sequence of applied voltage inversions that result from executing each player
# opcode, at each processor cycle. We assume the starting applied voltage is
# 1.0.
VOLTAGE_SCHEDULE = {
Opcode.TICK_17: make_tick_voltages(17),
Opcode.TICK_15: make_tick_voltages(15),
Opcode.TICK_13: make_tick_voltages(13),
Opcode.TICK_14: make_tick_voltages(14),
Opcode.TICK_12: make_tick_voltages(12),
Opcode.TICK_10: make_tick_voltages(10),
Opcode.NOTICK_6: make_notick_voltages(6),
Opcode.TICK_00: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
Opcode.TICK_01: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
Opcode.TICK_02: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
Opcode.TICK_03: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
Opcode.TICK_04: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
Opcode.TICK_05: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
Opcode.TICK_08: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
Opcode.TICK_09: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
Opcode.TICK_0a: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
Opcode.TICK_0b: numpy.array((1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
Opcode.TICK_11: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
Opcode.TICK_12: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
Opcode.TICK_13: numpy.array((1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
Opcode.TICK_1a: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
Opcode.TICK_1b: numpy.array((1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
Opcode.TICK_23: numpy.array((1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
Opcode.TICK_2c: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
Opcode.TICK_2d: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
Opcode.TICK_2e: numpy.array((1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
Opcode.TICK_34: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
Opcode.TICK_35: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
Opcode.TICK_36: numpy.array((1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
Opcode.TICK_3c: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
Opcode.TICK_3d: numpy.array((1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
Opcode.TICK_46: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
Opcode.TICK_47: numpy.array((1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
Opcode.TICK_4e: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
Opcode.TICK_4f: numpy.array((1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
Opcode.TICK_56: numpy.array((1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
Opcode.TICK_60: numpy.array((1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
Opcode.TICK_6a: numpy.array((1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
Opcode.TICK_72: numpy.array((1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
Opcode.TICK_7a: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
Opcode.TICK_7b: numpy.array((1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
Opcode.TICK_81: numpy.array((1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
Opcode.TICK_8a: numpy.array((1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
Opcode.TICK_93: numpy.array((1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
Opcode.TICK_9c: numpy.array((1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
Opcode.TICK_a5: numpy.array((1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
Opcode.TICK_ae: numpy.array((1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
Opcode.SLOWPATH: make_slowpath_voltages(),
}
} # type: Dict[Opcode, numpy.ndarray]
#
# class Opcode(enum.Enum):
# TICK_00 = 0x00
# TICK_01 = 0x01
# TICK_02 = 0x02
# TICK_03 = 0x03
# TICK_04 = 0x04
# TICK_05 = 0x05
# TICK_08 = 0x08
# TICK_09 = 0x09
# TICK_0a = 0x0a
# TICK_0b = 0x0b
# TICK_0c = 0x0c
# TICK_11 = 0x11
# TICK_12 = 0x12
# TICK_13 = 0x13
# TICK_14 = 0x14
# TICK_1a = 0x1a
# TICK_1b = 0x1b
# TICK_1c = 0x1c
# TICK_23 = 0x23
# TICK_24 = 0x24
# TICK_25 = 0x25
# TICK_2d = 0x2d
# TICK_2e = 0x2e
# TICK_2f = 0x2f
# TICK_37 = 0x37
# TICK_38 = 0x38
# TICK_40 = 0x40
# TICK_41 = 0x41
# TICK_4a = 0x4a
# TICK_4b = 0x4b
# TICK_54 = 0x54
# TICK_5d = 0x5d
# TICK_67 = 0x67
# TICK_71 = 0x71
# TICK_72 = 0x72
# TICK_7b = 0x7b
# TICK_85 = 0x85
# TICK_8f = 0x8f
# TICK_9a = 0x9a
# TICK_a5 = 0xa5
# TICK_b0 = 0xb0
# EXIT = 0xba
# SLOWPATH = 0xbd
#
# VOLTAGE_SCHEDULE = {
# Opcode.TICK_00: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
# Opcode.TICK_01: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
# Opcode.TICK_02: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
# Opcode.TICK_03: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
# Opcode.TICK_04: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
# Opcode.TICK_05: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
# Opcode.TICK_08: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
# Opcode.TICK_09: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
# Opcode.TICK_0a: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
# Opcode.TICK_0b: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
# Opcode.TICK_0c: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
# Opcode.TICK_11: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.TICK_12: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.TICK_13: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.TICK_14: numpy.array((1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.TICK_1a: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.TICK_1b: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.TICK_1c: numpy.array((1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.TICK_23: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.TICK_24: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.TICK_25: numpy.array((1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.TICK_2d: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.TICK_2e: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.TICK_2f: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.TICK_37: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.TICK_38: numpy.array((1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.TICK_40: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.TICK_41: numpy.array((1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.TICK_4a: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.TICK_4b: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.TICK_54: numpy.array((1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.TICK_5d: numpy.array((1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.TICK_67: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.TICK_71: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
# Opcode.TICK_72: numpy.array((1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
# Opcode.TICK_7b: numpy.array((1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
# Opcode.TICK_85: numpy.array((1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
# Opcode.TICK_8f: numpy.array((1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
# Opcode.TICK_9a: numpy.array((1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
# Opcode.TICK_a5: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0), dtype=numpy.float32),
# Opcode.TICK_b0: numpy.array((1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0), dtype=numpy.float32),
# Opcode.SLOWPATH: make_slowpath_voltages(),
# }
def cycle_length(op: Opcode) -> int:
"""Returns the 65C02 cycle length of a player opcode."""
@ -163,14 +394,14 @@ def cycle_lookahead(
@functools.lru_cache(None)
def prune_opcodes(
opcodes: Tuple[_Opcodes], lookahead_cycles: int
def candidate_opcodes(frame_offset:int, lookahead_cycles: int
) -> Tuple[List[_Opcodes], numpy.ndarray]:
"""Deduplicate a tuple of opcode sequences that are equivalent.
For each opcode sequence whose effect is the same when truncated to
lookahead_cycles, retains the first such opcode sequence.
"""
opcodes = opcode_lookahead(frame_offset, lookahead_cycles)
seen_cycles = set()
pruned_opcodes = []
pruned_cycles = []
@ -182,4 +413,4 @@ def prune_opcodes(
pruned_opcodes.append(ops)
pruned_cycles.append(cycles.cycles)
return pruned_opcodes, numpy.array(pruned_cycles, dtype=numpy.float32)
return pruned_opcodes, numpy.array(pruned_cycles, dtype=numpy.float32)

Binary file not shown.

View File

@ -108,9 +108,9 @@ zpdummy = $ff
; RESET AND CONFIGURE W5100
bootstrap:
; install reset handler
LDA #<exit
LDA #<real_exit
STA RESET_VECTOR
LDA #>exit
LDA #>real_exit
STA RESET_VECTOR+1
EOR #$A5
STA RESET_VECTOR+2 ; checksum to ensure warm-start reset
@ -273,6 +273,21 @@ setup:
STA WADRH
JMP checkrecv
real_exit:
INC RESET_VECTOR+2 ; Invalidate power-up byte
JSR PRODOS ; Call the MLI ($BF00)
.BYTE $65 ; CALL TYPE = QUIT
.ADDR exit_parmtable ; Pointer to parameter table
exit_parmtable:
.BYTE 4 ; Number of parameters is 4
.BYTE 0 ; 0 is the only quit type
.WORD 0000 ; Pointer reserved for future use
.BYTE 0 ; Byte reserved for future use
.WORD 0000 ; Pointer reserved for future use
; real_slowpath:
; The actual player code, which will be copied to $3xx for execution
;
; opcode cycle counts are for 65c02, for 6502 they are 1 less because JMP (indirect) is 5 cycles instead of 6.
@ -306,36 +321,308 @@ begin_copy_page1:
; 23 = NOTICK_6 + TICK_17
; 25 = NOTICK_6 + NOTICK_6 + TICK_13
; 27 = ...
tick_00: ;
NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_01:
NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_02:
NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_03:
NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_04:
NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_05:
JMP (WDATA) ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; $300
tick_odd: ; (NOTICK_6), (TICK_10), TICK_13, TICK_15, TICK_17
NOP ; 2
NOP ; 2
STA zpdummy ; 3
STA $C030 ; 4
JMP (WDATA) ; 6
tick_08:
NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
tick_09:
NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
tick_0a: ;
NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
tick_0b: ;
STA $C030 ; voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; $30a
tick_even: ; NOTICK_6, TICK_10, TICK_12, TICK_14
NOP ; 2
NOP ; 2
STA $C030 ; 4
JMP (WDATA) ; 6
tick_11:
NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
tick_12:
NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
tick_13: ;
STA $C030 ; voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; $312
tick_1a:
NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
tick_1b: ;
STA $C030 ; voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_23: ;
STA $C030 ; voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_2c:
NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
tick_2d:
NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
tick_2e:
INC $C030 ; voltages (1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_34:
NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_35:
NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_36:
STA $C030,X ; voltages (1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_3c: ;
NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_3d: ;
STA $C030 ; voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
STA $C030 ; [DUP 1] voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_46:
NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
tick_47:
INC $C030 ; voltages (1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_4e:
NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_4f:
STA $C030,X ; voltages (1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_56: ;
STA $C030 ; voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
NOP ; [DUP 1] voltages (1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
STA $C030 ; [DUP 1] voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_60:
STA $C030 ; voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
STA $C030 ; [DUP 2] voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_6a:
INC $C030 ; voltages (1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_72:
STA $C030,X ; voltages (1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_7a:
NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_7b: ; 1133687
INC $C030,X ; voltages (1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_81: ; 929768
STA $C030 ; voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
INC $C030 ; [DUP 5] voltages (1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_8a:
STA $C030 ; voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
STA $C030,X ; [DUP 6] voltages (1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_93:
INC $C030 ; voltages (1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
STA $C030 ; [DUP 1] voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_9c:
STA $C030,X ; voltages (1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
STA $C030 ; [DUP 1] voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_a5:
STA $C030,X ; voltages (1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
STA $C030,X ; [DUP 6] voltages (1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
tick_ae:
INC $C030,X ; voltages (1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; 181 bytes
;tick_00:
; NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_01:
; NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_02:
; NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_03:
; NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_04:
; NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_05:
; JMP (WDATA) ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_08:
; NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_09:
; NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_0a:
; NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_0b:
; NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_0c:
; STA zpdummy ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_11:
; NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
;tick_12:
; NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
;tick_13:
; NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
;tick_14:
; STA $C030 ; voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_1a:
; NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
;tick_1b:
; NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
;tick_1c:
; STA $C030 ; voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_23:
; NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
;tick_24:
; NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
;tick_25:
; STA $C030 ; voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; STA zpdummy ; [DUP 1] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_2d:
; NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
;tick_2e:
; NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
;tick_2f:
; STA zpdummy ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; STA $C030 ; [DUP 6] voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_37:
; NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
;tick_38:
; STA $C030 ; voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_40:
; NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
;tick_41:
; STA $C030 ; voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; NOP ; [DUP 1] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; STA zpdummy ; [DUP 1] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_4a:
; NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
;tick_4b:
; STA zpdummy ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; STA $C030 ; [DUP 7] voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_54:
; STA $C030 ; voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_5d:
; STA $C030 ; voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; NOP ; [DUP 1] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; NOP ; [DUP 1] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; STA zpdummy ; [DUP 1] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_67:
; STA zpdummy ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; STA $C030 ; [DUP 11] voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_71:
; NOP ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_72:
; STA $C030 ; voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; STA $C030 ; [DUP 6] voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_7b:
; STA $C030 ; voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; NOP ; [DUP 6] voltages (1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; STA $C030 ; [DUP 6] voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_85:
; STA $C030 ; voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; STA $C030 ; [DUP 7] voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; NOP ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_8f:
; STA $C030 ; voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; STA $C030 ; [DUP 8] voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; STA zpdummy ; [DUP 1] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_9a:
; STA $C030 ; voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; STA zpdummy ; [DUP 9] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; STA $C030 ; [DUP 6] voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_a5:
; STA zpdummy ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; STA $C030 ; [DUP 32] voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; STA $C030 ; [DUP 6] voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
;tick_b0:
; STA zpdummy ; voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; STA $C030 ; [DUP 8] voltages (1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0)
; STA zpdummy ; [DUP 1] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; JMP (WDATA) ; [DUP 0] voltages (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
; 186 bytes
; $3c4
; Quit to ProDOS
exit:
INC RESET_VECTOR+2 ; Invalidate power-up byte
JSR PRODOS ; Call the MLI ($BF00)
.BYTE $65 ; CALL TYPE = QUIT
.ADDR exit_parmtable ; Pointer to parameter table
exit_parmtable:
.BYTE 4 ; Number of parameters is 4
.BYTE 0 ; 0 is the only quit type
.WORD 0000 ; Pointer reserved for future use
.BYTE 0 ; Byte reserved for future use
.WORD 0000 ; Pointer reserved for future use
JMP real_exit
; Manage W5100 socket buffer and ACK TCP stream.
;
@ -354,59 +641,70 @@ exit_parmtable:
; If we do stall waiting for data then there is no need to worry about maintaining an even cadence, because audio
; will already be disrupted (since the encoder won't have predicted it, so will be tracking wrong). The speaker will
; resynchronize within a few hundred microseconds though.
slowpath: ;$322
slowpath: ;$3c7
STA TICK ; 4
JMP _slowpath ; 3 rest of slowpath doesn't fit in page 3
end_copy_page1:
_slowpath:
STA zpdummy ; 3
; Save the W5100 address pointer so we can come back here later
; We know the low-order byte is 0 because Socket RX memory is page-aligned and so is 2K frame.
; IMPORTANT - from now on until we restore this below, we can't trash the Y register!
STA TICK ; 4 [10]
LDY WADRH ; 4
; Read Received Read pointer
LDA #>S0RXRD ; 2
STA TICK ; 4 [10]
STA WADRH ; 4
STA TICK ; 4 [14]
LDX #<S0RXRD ; 2
STA TICK ; 4 [10]
STX WADRL ; 4
NOP ; 2
STA TICK ; 4 [10]
LDA WDATA ; 4 Read high byte
STA TICK ; 4 [14]
; No need to read low byte since it's guaranteed to be 0 since we're at the end of a 2K frame.
; Update new Received Read pointer
; We have received an additional 2KB
CLC ; 2
STA TICK ; 4 [10]
ADC #$08 ; 2
STX WADRL ; 4 Reset address pointer, X still has #<S0RXRD
NOP ; 2
STA TICK ; 4 [14]
STA WDATA ; 4 Store new high byte
STA TICK ; 4 [10]
; No need to store low byte since it's unchanged at 0
STA WDATA ; 4 Store new high byte
; Send the Receive command
LDA #<S0CR ; 2
STA TICK ; 4 [10]
STA WADRL ; 4
STA TICK ; 4 [14]
LDA #SCRECV ; 2
STA TICK ; 4 [10]
STA WDATA ; 4
checkrecv:
LDA #<S0RXRSR ; 2 Socket 0 Received Size register
STA TICK ; 4 [10]
LDX #$07 ; 2
STA TICK ; 4 [14]
NOP ; 2
NOP ; 2
STA TICK ; 4 [10]
; we might loop an unknown number of times here waiting for data but the default should be to fall
; straight through
@0:
STA WADRL ; 4
CPX WDATA ; 4 High byte of received size
NOP ; 2
STA TICK ; 4 [14]
STA TICK ; 4 [10]
CPX WDATA ; 4 High byte of received size
BCS @0 ; 2 in common case when there is already sufficient data waiting.
STA TICK ; 4 [10]
; point W5100 back into the RX buffer where we left off
; There is data to read - we don't care exactly how much because it's at least 2K
@ -417,10 +715,10 @@ checkrecv:
; Since we're using an 8K socket, that means we don't have to do any work to manage the read pointer!
STY WADRH ; 4
LDX #$00 ; 2
NOP ; 2
STA TICK ; 4 [14]
STA TICK ; 4 [10]
STX WADRL ; 4
NOP ; 2
STA TICK ; 4 [10]
JMP (WDATA) ; 6 [10/14]
end_copy_page1:
.endproc