Skip to content
Permalink
Browse files

raster beam register value

  • Loading branch information...
irmen committed Jul 12, 2018
1 parent f607170 commit 4e876e5c63ff2eb4f953c5457ce7dfc061c4970d
Showing with 20 additions and 8 deletions.
  1. +1 −2 pyc64/cputools.py
  2. +2 −2 pyc64/emulator.py
  3. +17 −4 pyc64/memory.py
@@ -49,8 +49,7 @@ def run(self, pc=None, microsleep=None, loop_detect_delay=0.5):
break
self.step()
instructions += 1
if microsleep and instructions % 4000 == 0:
# print("microsleep", instructions)
if microsleep and instructions % 5000 == 0:
microsleep()
if self.pc == end_address:
# when this address is reached, we consider it the end of the program
@@ -621,7 +621,7 @@ def reset_machine(self):
self.switch_interpreter("basic")
if self.screen.using_roms:
print("using actual ROM reset routine (sys 64738)")
do_sys(self.screen, 64738, use_rom_routines=True)
do_sys(self.screen, 64738, self.interpret_thread._microsleep, use_rom_routines=True)
self.interpreter.write_prompt("\n\n\n\n\n")


@@ -700,7 +700,7 @@ def run(self):

def _microsleep(self):
# artificial microscopic delay to yield the thread and allow screen to refresh
self.window.hertztick.wait(1)
self.window.hertztick.wait(.02)
self.window.hertztick.clear()

def stop(self):
@@ -10,7 +10,7 @@
License: MIT open-source.
"""

import os
import math
import time
import struct
import codecs
@@ -273,11 +273,9 @@ def __init__(self, columns=40, rows=25, sprites=8, rom_directory=""):
# apply some ROM patches to make the reset routine work on the simulator:
self.memory._patch(0xe388, 0x4c) # JMP to same address near the end of the reset routine
self.memory._patch(0xe389, 0x88) # ...to avoid entering actual basic program loop. RTS won't work because the stack is clobbered I think.
self.memory._patch(0xe38a, 0xe3) # ...(this jmp loop is recognised by the cpu emulator as an 'end of the program')
self.memory._patch(0xe38a, 0xe3) # ...(this jmp loop is recognised by tahe cpu emulator as an 'end of the program')
# self.memory._patch(0xfce5, 0xea) # NOP to not clobber stack pointer register in reset routine
self.memory._patch(0xfcf6, 0x90) # skip a large part of the memory init routine that is very slow and may cause issues
self.memory._patch(0xff61, 0xea) # NOP to skip a loop in the reset routine
self.memory._patch(0xff62, 0xea) # NOP to skip a loop in the reset routine
self.hz = 60 # NTSC
self.columns = columns
self.rows = rows
@@ -324,6 +322,19 @@ def write_jiffieclock(address, oldval, newval):
def write_controlregister(address, oldval, newval):
pass

def read_controlregister(address, value):
# the high bit of the control register is bit#9 of the raster beam position (0-319)
frac, _ = math.modf(time.time() * self.hz)
if 320 * frac > 255:
return value | 0x80
return value & 0x7f

def read_raster(address, value):
# the raster beam position which goes from 0-319 every 1/hz second
# this register contains the low 8 bits of this value
frac, _ = math.modf(time.time() * self.hz)
return int(320 * frac) % 255

self.memory.intercept_read(160, read_jiffieclock)
self.memory.intercept_read(161, read_jiffieclock)
self.memory.intercept_read(162, read_jiffieclock)
@@ -334,6 +345,8 @@ def write_controlregister(address, oldval, newval):
self.memory.intercept_write(53281, write_screencolor)
self.memory.intercept_write(53270, write_controlregister)
self.memory.intercept_write(53265, write_controlregister)
self.memory.intercept_read(53265, read_controlregister)
self.memory.intercept_read(53266, read_raster)

def reset(self, hard=False):
self._full_repaint = True

0 comments on commit 4e876e5

Please sign in to comment.
You can’t perform that action at this time.