Skip to content

Commit

Permalink
WIP: Dragon Text mode with D64
Browse files Browse the repository at this point in the history
  • Loading branch information
jedie committed Jul 27, 2014
1 parent 0caca33 commit 543275b
Show file tree
Hide file tree
Showing 18 changed files with 8,037 additions and 43 deletions.
8 changes: 6 additions & 2 deletions Dragon32_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@


class Dragon32Periphery2(Dragon32Periphery):
def update(self, cpu_cycles):
super(Dragon32Periphery2, self).update(cpu_cycles)
self._handle_events()

def mainloop(self, cpu):
log.critical("Pygame mainloop started.")
while cpu.running:
Expand Down Expand Up @@ -115,10 +119,10 @@ def run(self):

setup_logging(log,
# level=1 # hardcore debug ;)
# level=10 # DEBUG
level=10 # DEBUG
# level=20 # INFO
# level=30 # WARNING
level=40 # ERROR
# level=40 # ERROR
# level=50 # CRITICAL/FATAL
)
c = Dragon32()
Expand Down
135 changes: 135 additions & 0 deletions Dragon64_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#!/usr/bin/env python2
# encoding:utf-8

"""
Dragon 64 console
~~~~~~~~~~~~~~~~~
:created: 2014 by Jens Diemer - www.jensdiemer.de
:copyleft: 2014 by the DragonPy team, see AUTHORS for more details.
:license: GNU GPL v3 or above, see LICENSE for more details.
"""

import Queue
import sys
import threading
import time

from dragonpy.Dragon64.config import Dragon64Cfg
from dragonpy.Dragon32.periphery_dragon import Dragon32Periphery
from dragonpy.components.cpu6809 import CPU
from dragonpy.components.memory import Memory
from dragonpy.utils.logging_utils import log
from dragonpy.utils.logging_utils import setup_logging


CFG_DICT = {
"verbosity":None,
"display_cycle":False,

"trace":None,
# "trace":True,

"max_ops":None,
# "max_ops":5000,

"bus_socket_host":None,
"bus_socket_port":None,
"ram":None,
"rom":None,

"use_bus":False,
}


class Dragon32Periphery2(Dragon32Periphery):
def update(self, cpu_cycles):
super(Dragon32Periphery2, self).update(cpu_cycles)
if self.running:
self._handle_events()
else:
self.exit()

def mainloop(self, cpu):
log.critical("Pygame mainloop started.")
while cpu.running:
self._handle_events()

self.exit()
log.critical("Pygame mainloop stopped.")


class Dragon64(object):
def __init__(self):
self.cfg = Dragon64Cfg(CFG_DICT)

self.periphery = Dragon32Periphery2(self.cfg)
self.cfg.periphery = self.periphery

memory = Memory(self.cfg)
self.cpu = CPU(memory, self.cfg)
memory.cpu = self.cpu # FIXME

self.last_update = None
self.last_cycles = None
self.display_cycle_interval()

def display_cycle_interval(self):
if self.last_update is not None: # Skip the first time call.
cycles = self.cpu.cycles - self.last_cycles
duration = time.time() - self.last_update
log.critical(
"%i cycles/sec (%i cycles in last %isec)",
int(cycles / duration), cycles, duration
)

self.last_cycles = self.cpu.cycles
self.last_update = time.time()
if self.periphery.running and self.cpu.running:
t = threading.Timer(5.0, self.display_cycle_interval)
t.deamon = True
t.start()

def update_display_interval(self):
self.periphery.update(self.cpu.cycles)
if self.periphery.running and self.cpu.running:
t = threading.Timer(0.25, self.update_display_interval)
t.deamon = True
t.start()

def run(self):
self.update_display_interval()

cpu = self.cpu
cpu.reset()
max_ops = self.cfg.cfg_dict["max_ops"]
if max_ops:
log.critical("Running only %i ops!", max_ops)
for __ in xrange(max_ops):
cpu.get_and_call_next_op()
if not cpu.running:
break
log.critical("Quit CPU after given 'max_ops' %i ops.", max_ops)
cpu.quit()
else:
while cpu.running:
cpu.get_and_call_next_op()

self.periphery.exit()


if __name__ == '__main__':
print "Startup Dragon 64 machine..."
setup_logging(log,
# level=1 # hardcore debug ;)
# level=10 # DEBUG
# level=20 # INFO
# level=30 # WARNING
# level=40 # ERROR
# level=50 # CRITICAL/FATAL
level=60
)
c = Dragon64()
c.run()

print " --- END --- "
26 changes: 26 additions & 0 deletions Dragon64_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/bash

# https://github.com/jedie/PyDragon32/tree/master/misc#readme

(
set -x
python2 Dragon64_test.py | python ../PyDragon32/misc/filter_xroar_trace.py --display --start-stop=B3D9-ffff | tee Dragon64_test_trace.txt
#~ python2 Dragon64_test.py | python ../PyDragon32/misc/filter_xroar_trace.py --unique | tee Dragon64_test_trace.txt
#~ python2 Dragon64_test.py > Dragon64_test_trace.txt
#~ python2 Dragon64_test.py | tee Dragon64_test_trace.txt
)
echo
read -n1 -p "Start bash? [y,n]" doit
echo
case $doit in
y|Y)
bash -i
exit 0
;;
n|N)
echo "bye bye"
;;
*)
echo "input, don't know, bye."
;;
esac
13 changes: 13 additions & 0 deletions dragonpy/Dragon32/MC6821_PIA.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ def get_write_func_map(self):
0xff02: self.write_PIA0_B_data, # PIA 0 B side Data reg. PB7
0xff03: self.write_PIA0_B_control, # PIA 0 B side Control reg. CB1

0xff06: self.write_serial_interface, # Only Dragon 64

0xff20: self.write_PIA1_A_data, # PIA 1 A side Data reg. PA7
0xff21: self.write_PIA1_A_control, # PIA 1 A side Control reg. CA1
0xff22: self.write_PIA1_B_data, # PIA 1 B side Data reg. PB7
Expand All @@ -65,6 +67,8 @@ def get_read_func_map(self):
0xff02: self.read_PIA0_B_data, # PIA 0 B side Data reg. PB7
0xff03: self.read_PIA0_B_control, # PIA 0 B side Control reg. CB1

0xff04: self.read_serial_interface, # Only Dragon 64

0xff20: self.read_PIA1_A_data, # PIA 1 A side Data reg. PA7
0xff21: self.read_PIA1_A_control, # PIA 1 A side Control reg. CA1
0xff22: self.read_PIA1_B_data, # PIA 1 B side Data reg. PB7
Expand Down Expand Up @@ -154,4 +158,13 @@ def write_PIA1_B_control(self, cpu_cycles, op_address, address, value):
""" write to 0xff23 -> PIA 1 B side Control reg. CB1 """
log.error("TODO: write $%02x to 0xff23 -> PIA 1 B side Control reg. CB1", value)

#--------------------------------------------------------------------------

def read_serial_interface(self, cpu_cycles, op_address, address):
log.error("TODO: read from $%04x (D64 serial interface", address)
return 0x00

def write_serial_interface(self, cpu_cycles, op_address, address, value):
log.error("TODO: write $%02x to $%04x (D64 serial interface", value, address)


101 changes: 84 additions & 17 deletions dragonpy/Dragon32/MC6883_SAM.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
$ffc0-ffc5 SAM VDG Mode registers V0-V2
$ffc0/ffc1 SAM VDG Reg V0
$ffc2/ffc3 SAM VDG Reg V1
$ffc3/ffc5 SAM VDG Reg V2
$ffc4/ffc5 SAM VDG Reg V2
$ffc6-ffd3 SAM Display offset in 512 byte pages F0-F6
$ffc6/ffc7 SAM Display Offset bit F0
$ffc8/ffc9 SAM Display Offset bit F1
Expand Down Expand Up @@ -59,27 +59,94 @@ def __init__(self, cfg):

def get_write_func_map(self):
write_func_map = {
# TODO
0xffc0: self.write_VDG_mode_register_v0,
0xffc2: self.write_VDG_mode_register_v1,
0xffc4: self.write_VDG_mode_register_v2,
0xffc6: self.write_display_offset_F0,
0xffc8: self.write_display_offset_F1,
0xffc9: self.write_D64_dynamic_memory, # Dragon 64 only
0xffca: self.write_display_offset_F2,
0xffcc: self.write_display_offset_F3,
0xffce: self.write_display_offset_F4,
0xffd0: self.write_display_offset_F5,
0xffd2: self.write_display_offset_F6,
0xffd4: self.write_page_bit,
0xffd6: self.write_MPU_rate_bit0,
0xffd8: self.write_MPU_rate_bit1,
0xffda: self.write_size_select_bit0,
0xffdc: self.write_size_select_bit1,
0xffde: self.write_map_type,
0xffdd: self.write_map0,
}
return write_func_map

def get_read_func_map(self):
read_func_map = {
# TODO
0xffc2: self.read_VDG_mode_register_v1,
}
return read_func_map

def __call__(self, address):
msg = "TODO: SAM call at $%x" % address
log.error(msg)
value = 0x7e
log.debug(" SAM call at $%x returned $%x \t| %s" % (
address, value, self.cfg.mem_info.get_shortest(address)
))
return value
# raise NotImplementedError

def write_byte(self, address, value):
log.error(" *** TODO: SAM write byte $%02x to $%x \t| %s" % (
value, address, self.cfg.mem_info.get_shortest(address)
))
# def read_VDG_mode_register_v0(self, cpu_cycles, op_address, address):
# log.error("TODO: read VDG mode register V0 $%04x", address)
# return 0x00

def read_VDG_mode_register_v1(self, cpu_cycles, op_address, address):
log.error("TODO: read VDG mode register V1 $%04x", address)
return 0x00

#--------------------------------------------------------------------------

def write_VDG_mode_register_v0(self, cpu_cycles, op_address, address, value):
log.error("TODO: write VDG mode register V0 $%02x to $%04x", value, address)

def write_VDG_mode_register_v1(self, cpu_cycles, op_address, address, value):
log.error("TODO: write VDG mode register V1 $%02x to $%04x", value, address)

def write_VDG_mode_register_v2(self, cpu_cycles, op_address, address, value):
log.error("TODO: write VDG mode register V2 $%02x to $%04x", value, address)

def write_display_offset_F0(self, cpu_cycles, op_address, address, value):
log.error("TODO: write display_offset_F0 $%02x to $%04x", value, address)

def write_display_offset_F1(self, cpu_cycles, op_address, address, value):
log.error("TODO: write display_offset_F1 $%02x to $%04x", value, address)

def write_display_offset_F2(self, cpu_cycles, op_address, address, value):
log.error("TODO: write display_offset_F2 $%02x to $%04x", value, address)

def write_display_offset_F3(self, cpu_cycles, op_address, address, value):
log.error("TODO: write display_offset_F3 $%02x to $%04x", value, address)

def write_display_offset_F4(self, cpu_cycles, op_address, address, value):
log.error("TODO: write display_offset_F4 $%02x to $%04x", value, address)

def write_display_offset_F5(self, cpu_cycles, op_address, address, value):
log.error("TODO: write display_offset_F5 $%02x to $%04x", value, address)

def write_display_offset_F6(self, cpu_cycles, op_address, address, value):
log.error("TODO: write display_offset_F6 $%02x to $%04x", value, address)

def write_page_bit(self, cpu_cycles, op_address, address, value):
log.error("TODO: write page_bit $%02x to $%04x", value, address)

def write_MPU_rate_bit0(self, cpu_cycles, op_address, address, value):
log.error("TODO: write MPU_rate_bit0 $%02x to $%04x", value, address)

def write_MPU_rate_bit1(self, cpu_cycles, op_address, address, value):
log.error("TODO: write MPU_rate_bit1 $%02x to $%04x", value, address)

def write_size_select_bit0(self, cpu_cycles, op_address, address, value):
log.error("TODO: write size_select_bit0 $%02x to $%04x", value, address)

def write_size_select_bit1(self, cpu_cycles, op_address, address, value):
log.error("TODO: write size_select_bit1 $%02x to $%04x", value, address)

def write_map_type(self, cpu_cycles, op_address, address, value):
log.error("TODO: write map_type $%02x to $%04x", value, address)

def write_map0(self, cpu_cycles, op_address, address, value):
log.error("TODO: write map0 $%02x to $%04x", value, address)

def write_D64_dynamic_memory(self, cpu_cycles, op_address, address, value):
log.error("TODO: write D64_dynamic_memory $%02x to $%04x", value, address)

5 changes: 3 additions & 2 deletions dragonpy/Dragon32/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,13 @@ class Dragon32Cfg(BaseConfig):

BUS_ADDR_AREAS = (
# TODO: Add all devices!
(0x0400, 0x05ff, "Alphanumeric Display"),
(0xc000, 0xfeff, "DOS ROM / cartridge expansion port"),
(0xff00, 0xff04, "PIA 0 (Peripheral Interface Adaptor MC6821)"),
(0xff04, 0xff07, "D64 ACIA serial port"),
(0xff20, 0xff23, "PIA 1 (Peripheral Interface Adaptor MC6821)"),
(0xffc0, 0xffdf, "SAM (Synchronous Address Multiplexer MC6883)"),
(0xc000, 0xfeff, "DOS ROM / cartridge expansion port"),
(0xfff0, 0xffff, "Interrupt vectors"),
(0xfff0, 0xfffe, "Interrupt vectors"),
)

DEFAULT_ROM = os.path.join(
Expand Down
5 changes: 1 addition & 4 deletions dragonpy/Dragon32/mem_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,9 @@
:license: GNU GPL v3 or above, see LICENSE for more details.
"""

import logging

from dragonpy.core.memory_info import BaseMemoryInfo
from dragonpy.utils.humanize import nice_hex

log = logging.getLogger("DragonPy.dragon32.mem_info")
from dragonpy.utils.logging_utils import log


class DragonMemInfo(BaseMemoryInfo):
Expand Down
Loading

0 comments on commit 543275b

Please sign in to comment.