- Reads WOZ files! DOS compatibility only for now

- MHz can be changed from GUI
This commit is contained in:
Tamas Rudnai 2020-01-27 22:54:03 -08:00
parent fddb1d9642
commit ace3a8f68e
11 changed files with 428 additions and 106 deletions

View File

@ -652,9 +652,9 @@
);
OTHER_CFLAGS = (
"-DDISASSEMBLER",
"-DINTERRUPR_CHECK_PER_STEP",
"-DINTERRUPT_CHECK_PER_STEP",
);
OTHER_SWIFT_FLAGS = "-D_NO_HIRES -D_NO_HIRESDRAW -D_NO_HIRESLOW";
OTHER_SWIFT_FLAGS = "-D_NO_HIRES -DHIRESDRAW -D_NO_HIRESLOW";
PRODUCT_BUNDLE_IDENTIFIER = com.gamealloy.A2Mac;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
@ -683,9 +683,9 @@
);
OTHER_CFLAGS = (
"-DDISASSEMBLER",
"-DINTERRUPR_CHECK_PER_STEP",
"-DINTERRUPT_CHECK_PER_STEP",
);
OTHER_SWIFT_FLAGS = "-D_NO_HIRES -D_NO_HIRESDRAW -D_NO_HIRESLOW";
OTHER_SWIFT_FLAGS = "-D_NO_HIRES -DHIRESDRAW -D_NO_HIRESLOW";
PRODUCT_BUNDLE_IDENTIFIER = com.gamealloy.A2Mac;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "A2Mac/A2Mac-Bridging-Header.h";

View File

@ -9,6 +9,7 @@
#define CLK_WAIT
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
@ -27,6 +28,10 @@ woz_tmap_t woz_tmap;
woz_trks_t woz_trks;
uint16_t trackOffset = 0;
uint8_t bitOffset = 0;
FILE * outdev = NULL;
#ifdef DEBUG
#define INLINE
@ -47,8 +52,9 @@ const unsigned long long int iterations = G;
unsigned long long int inst_cnt = 0;
const unsigned int fps = 30;
const unsigned int MHz_6502 = 1.023 * M; // 2 * M; // 4 * M; // 8 * M; // 16 * M; // 128 * M; // 256 * M; // 512 * M;
const unsigned int clk_6502_per_frm = MHz_6502 / fps;
const unsigned long long default_MHz_6502 = 1.023 * M; // 2 * M; // 4 * M; // 8 * M; // 16 * M; // 128 * M; // 256 * M; // 512 * M;
unsigned long long MHz_6502 = default_MHz_6502;
unsigned long long clk_6502_per_frm = default_MHz_6502 / fps;
unsigned long long tick_per_sec = G;
unsigned long long tick_6502_per_sec = 0;
@ -151,9 +157,9 @@ void hires_Update () {
#include "6502_instructions.h"
/////
#ifdef SPEEDTEST
//#ifdef SPEEDTEST
unsigned long long int clktime = 0;
#endif
//#endif
INLINE int m6502_Step() {
@ -680,7 +686,7 @@ void m6502_Run() {
#endif
{
#ifdef INTERRUPR_CHECK_PER_STEP
#ifdef INTERRUPT_CHECK_PER_STEP
if ( m6502.IF ) {
switch (m6502.interrupt) {
case HLT:
@ -725,29 +731,29 @@ void m6502_Run() {
m6502.IF = 0;
}
#endif // INTERRUPR_CHECK_PER_STEP
#endif // INTERRUPT_CHECK_PER_STEP
// dbgPrintf("%llu %04X: ", clktime, m6502.PC);
#ifdef SPEEDTEST
//#ifdef SPEEDTEST
clktime +=
#endif
//#endif
clk = m6502_Step();
printDisassembly();
printDisassembly( outdev );
dbgPrintf2("A:%02X X:%02X Y:%02X SP:%02X %c%c%c%c%c%c%c%c\n\n",
m6502.A,
m6502.X,
m6502.Y,
m6502.SP,
m6502.N ? 'N' : 'n',
m6502.V ? 'V' : 'v',
m6502.res ? 'R' : 'r',
m6502.B ? 'B' : 'b',
m6502.D ? 'D' : 'd',
m6502.I ? 'I' : 'i',
m6502.Z ? 'Z' : 'z',
m6502.C ? 'C' : 'c'
);
// dbgPrintf2("A:%02X X:%02X Y:%02X SP:%02X %c%c%c%c%c%c%c%c\n\n",
// m6502.A,
// m6502.X,
// m6502.Y,
// m6502.SP,
// m6502.N ? 'N' : 'n',
// m6502.V ? 'V' : 'v',
// m6502.res ? 'R' : 'r',
// m6502.B ? 'B' : 'b',
// m6502.D ? 'D' : 'd',
// m6502.I ? 'I' : 'i',
// m6502.Z ? 'Z' : 'z',
// m6502.C ? 'C' : 'c'
// );
#ifdef CLK_WAIT
// ee += tick_6502_per_sec * clk;
@ -868,21 +874,15 @@ void m6502_ColdReset() {
tick_per_sec = e - epoch;
tick_6502_per_sec = tick_per_sec / MHz_6502;
memset( RAM, 0xFF, sizeof(Apple2_64K_RAM) );
memset( RAM, 0, sizeof(Apple2_64K_RAM) );
memset( RAM + 0xC000, 0, 0x1000 ); // I/O area should be 0
m6502.A = m6502.X = m6502.Y = 0xFF;
// reset vector
m6502.SP = 0xFF; //-3;
// N V - B D I Z C
// 0 0 1 1 0 1 0 0
m6502.SR = 0x34;
m6502.IF = 0;
outdev = fopen("/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/disassembly_new.log", "w+");
if (outdev == NULL) {
outdev = stdout;
}
// memory size
// *((uint16_t*)(&RAM[0x73])) = 0xC000;
#ifdef FUNCTIONTEST
FILE * f = fopen("/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/6502_functional_test.bin", "rb");
@ -900,13 +900,29 @@ void m6502_ColdReset() {
// Apple ][e ROM
read_rom("/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/Apple2Plus.rom", 0xD000);
// Disk ][ ROM in Slot 6
// read_rom("/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/DISK_II_C600.ROM", 0xC600);
read_rom("/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/DISK_II_C600.ROM", 0xC600);
// WOZ DISK
// read_woz("/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/DOS 3.3 System Master.woz");
// read_woz("/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/Hard Hat Mack - Disk 1, Side A.woz");
// read_woz("/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/Merlin-8 v2.48 (DOS 3.3).woz");
// read_woz("/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/DOS3.3.Launcher.2.2.woz");
read_woz("/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/Apple DOS 3.3 January 1983.woz");
m6502.A = m6502.X = m6502.Y = 0xFF;
// reset vector
m6502.SP = 0xFF; //-3;
// N V - B D I Z C
// 0 0 1 0 0 1 0 0
m6502.SR = 0x24;
m6502.IF = 0;
// memory size
//*((uint16_t*)(&RAM[0x73])) = 0xC000;
m6502.PC = memread16( RESET_VECTOR );
#endif

View File

@ -11,10 +11,14 @@
#import <stdint.h>
extern unsigned long long MHz_6502;
extern unsigned long long clk_6502_per_frm;
#ifdef DEBUG
//#define dbgPrintf(format, ...) printf (format, ## __VA_ARGS__)
#define dbgPrintf(format, ...)
#define dbgPrintf2(format, ...) printf (format, ## __VA_ARGS__)
#define dbgPrintf2(format, ...) if(outdev) fprintf(outdev, format, ## __VA_ARGS__)
#else
#define dbgPrintf(format, ...)
#define dbgPrintf2(format, ...)

View File

@ -12,9 +12,22 @@
#include "common.h"
#include "6502.h"
typedef union {
struct {
uint8_t latch;
uint8_t shift;
};
struct {
uint16_t lower15 : 15;
uint16_t valid : 1;
};
uint16_t shift16;
} WOZread_t;
uint8_t Apple2_64K_RAM[ 64 * KB ] = {0};
uint8_t * RAM = Apple2_64K_RAM;
WOZread_t WOZread = {0};
enum slot {
SLOT0 = 0x00,
@ -153,28 +166,106 @@ typedef union address16_u {
return 0;
static const minDiskPhaseNum = 0;
static const maxDiskPhaseNum = 80;
static int trackPhase = maxDiskPhaseNum;
static const int minDiskPhaseNum = 0;
static const int maxDiskPhaseNum = 79;
struct phase_t {
uint8_t current : 2;
uint8_t last : 2;
} phase = {0};
uint8_t lastMagnet : 4;
uint8_t magnet : 4;
int count;
} phase = { 0, 0, 0 };
static const int8_t phaseTransition[4][4] = {
{ 0, -1, 0, +1 },
{ +1, 0, -1, 0 },
{ 0, +1, 0, -1 },
{ -1, 0, +1, 0 },
//static const int8_t phaseTransition[4][4] = {
// { 0, -1, 0, +1 },
// { +1, 0, -1, 0 },
// { 0, +1, 0, -1 },
// { -1, 0, +1, 0 },
//};
//static const int phaseTransition[16][16] = {
//// 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
// { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 0000
// { 0, 0, -2, -1, 0, 0, 0, 0, +2, +1, 0, 0, 0, 0, 0, 0 }, // 0001
// { 0, +2, 0, +1, -2, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 0010
// { 0, +1, -1, 0, 0, 0, -2, 0, 0, +2, 0, 0, 0, 0, 0, 0 }, // 0011
// { 0, 0, +2, 0, 0, 0, +1, 0, -2, 0, 0, 0, -1, 0, 0, 0 }, // 0100
// { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 0101
// { 0, 0, +1, +2, -1, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0 }, // 0110
// { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 0111
// { 0, -2, 0, 0, +2, 0, 0, 0, 0, -1, 0, 0, +1, 0, 0, 0 }, // 1000
// { 0, -1, 0, -2, 0, 0, 0, 0, +1, 0, 0, 0, +2, 0, 0, 0 }, // 1001
// { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1010
// { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1011
// { 0, 0, 0, 0, +1, 0, +2, 0, -1, -2, 0, 0, 0, 0, 0, 0 }, // 1100
// { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1101
// { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1110
// { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1111
//};
// Magnet States --> Stepper Motor Position
//
// N
// 0001
// NW | NE
// 1001 | 0011
// |
// W 1000 ------- o ------- 0010 E
// |
// 1100 | 0110
// SW | SE
// 0100
// S
// motor position from the magnet state
// -1 means invalid, not supported
static const int magnet_to_Poistion[16] = {
// 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
-1, 0, 2, 1, 4, -1, 3, -1, 6, 7, -1, -1, 5, -1, -1, -1
};
static const int position_to_direction[8][8] = {
// N NE E SE S SW W NW
// 0 1 2 3 4 5 6 7
{ 0, 1, 2, 3, 0, -3, -2, -1 }, // 0 N
{ -1, 0, 1, 2, 3, 0, -3, -2 }, // 1 NE
{ -2, -1, 0, 1, 2, 3, 0, -3 }, // 2 E
{ -3, -2, -1, 0, 1, 2, 3, 0 }, // 3 SE
{ 0, -3, -2, -1, 0, 1, 2, 3 }, // 4 S
{ 3, 0, -3, -2, -1, 0, 1, 2 }, // 5 SW
{ 2, 3, 0, -3, -2, -1, 0, 1 }, // 6 W
{ 1, 2, 3, 0, -3, -2, -1, 0 }, // 7 NW
};
INLINE void diskII_phase() {
int position = magnet_to_Poistion[phase.magnet];
if ( position >= 0 ) {
int lastPosition = phase.count & 7;
int direction = position_to_direction[lastPosition][position];
phase.count += direction;
if ( phase.count < minDiskPhaseNum ) {
phase.count = minDiskPhaseNum;
}
else if ( phase.count > maxDiskPhaseNum ) {
phase.count = maxDiskPhaseNum;
}
printf(", p:%d d:%d l:%d: ph:%u trk:%u)", position, direction, lastPosition, phase.count, woz_tmap.phase[phase.count]);
}
printf("\n");
}
INLINE uint8_t ioRead( uint16_t addr ) {
dbgPrintf("mmio read:%04X\n", addr);
uint8_t currentMagnet = 0;
switch (addr) {
case io_KBD:
// if ( RAM[io_KBD] > 0x7F ) printf("io_KBD:%04X\n", addr);
@ -192,51 +283,80 @@ INLINE uint8_t ioRead( uint16_t addr ) {
case io_DISK_PHASE1_OFF + SLOT6:
case io_DISK_PHASE2_OFF + SLOT6:
case io_DISK_PHASE3_OFF + SLOT6:
dbgPrintf2("io_DISK_PHASE%u_OFF (S%u)\n", phase.current, 6);
phase.last = phase.current;
currentMagnet = (addr - io_DISK_PHASE0_OFF - SLOT6) / 2;
phase.magnet &= ~(1 << currentMagnet);
printf("io_DISK_PHASE%u_OFF (S%u, ps:%X) ", currentMagnet, 6, phase.magnet);
diskII_phase();
return 0;
case io_DISK_PHASE0_ON + SLOT6:
case io_DISK_PHASE1_ON + SLOT6:
case io_DISK_PHASE2_ON + SLOT6:
case io_DISK_PHASE3_ON + SLOT6: {
phase.current = (addr - io_DISK_PHASE0_ON - SLOT6) / 2;
trackPhase += phaseTransition[phase.current][phase.last];
if ( trackPhase < minDiskPhaseNum ) {
trackPhase = minDiskPhaseNum;
}
if ( trackPhase > maxDiskPhaseNum ) {
trackPhase = maxDiskPhaseNum;
}
dbgPrintf2("io_DISK_PHASE%u_ON (S%u, trk:%u)\n", phase.current, 6, trackPhase);
currentMagnet = (addr - io_DISK_PHASE0_ON - SLOT6) / 2;
phase.magnet |= 1 << currentMagnet;
printf("io_DISK_PHASE%u_ON (S%u, ps:%X) ", currentMagnet, 6, phase.magnet);
diskII_phase();
return 0;
}
case io_DISK_POWER_OFF + SLOT6:
dbgPrintf2("io_DISK_POWER_OFF (S%u)\n", 6);
return 0;
case io_DISK_POWER_ON + SLOT6:
dbgPrintf2("io_DISK_POWER_ON (S%u)\n", 6);
return 0;
case io_DISK_SELECT_1 + SLOT6:
dbgPrintf2("io_DISK_SELECT_1 (S%u)\n", 6);
return 0;
case io_DISK_SELECT_2 + SLOT6:
dbgPrintf2("io_DISK_SELECT_2 (S%u)\n", 6);
return 0;
case io_DISK_READ + SLOT6:
dbgPrintf("io_DISK_READ (S%u)\n", 6);
int track = woz_tmap.phase[trackPhase];
if (trackOffset >= WOZ_TRACK_BYTE_COUNT ) {
trackOffset = 0;
int track = woz_tmap.phase[phase.count];
if (outdev) fprintf(outdev, "track: %d (%d) ", track, phase.count);
if ( track >= 40 ) {
printf("TRCK TOO HIGH!\n");
return rand();
}
printf("offs:%u\n", trackOffset);
return woz_trks[track].data[trackOffset++];
// to avoid infinite loop and to search for bit 7 high
for ( int i = 0; i < WOZ_TRACK_BYTE_COUNT * 8; i++ ) {
if ( ++bitOffset >= 8 ) {
bitOffset = 0;
if ( ++trackOffset >= WOZ_TRACK_BYTE_COUNT ) {
trackOffset = 0;
}
// printf("offs:%u\n", trackOffset);
WOZread.latch = woz_trks[track].data[trackOffset];
}
WOZread.shift16 <<= 1;
if ( WOZread.valid ) {
uint8_t byte = WOZread.shift;
// printf("%02X ", byte);
WOZread.shift = 0;
if (outdev) fprintf(outdev, "byte: %02X\n", byte);
return byte;
}
}
if (outdev) fprintf(outdev, "TIME OUT!\n");
return rand();
case io_DISK_WRITE + SLOT6:
dbgPrintf2("io_DISK_WRITE (S%u)\n", 6);
return 0;
case io_DISK_CLEAR + SLOT6:
dbgPrintf2("io_DISK_CLEAR (S%u)\n", 6);
return 0;
case io_DISK_SHIFT + SLOT6:
dbgPrintf2("io_DISK_SHIFT (S%u)\n", 6);
return 0;
@ -392,6 +512,7 @@ INLINE uint8_t fetch() {
**/
INLINE uint16_t fetch16() {
uint16_t word = memread16( m6502.PC );
// disPrintf(disassembly.comment, "fetch16:%04X", word);
m6502.PC += 2;
disHexW( disassembly.pOpcode, word );
return word;
@ -424,6 +545,7 @@ INLINE uint16_t abs_addr() {
}
INLINE uint16_t ind_addr() {
disPrintf(disassembly.oper, "($%04X)", memread16(m6502.PC))
disPrintf(disassembly.comment, "ind_addr:%04X", memread16(memread16(m6502.PC)))
return memread16( fetch16() );
}
@ -433,7 +555,7 @@ INLINE uint16_t ind_addr() {
**/
INLINE uint16_t addr_abs_X() {
dbgPrintf("abs,X:%04X(%02X) ", *((uint16_t*)&RAM[m6502.PC]) + m6502.X, RAM[*((uint16_t*)&RAM[m6502.PC]) + m6502.X]);
disPrintf(disassembly.oper, "$%04X,X", memread16(m6502.PC))
disPrintf(disassembly.oper, "$%04X,X", memread16(m6502.PC));
return fetch16() + m6502.X;
}
INLINE uint8_t src_abs_X() {
@ -487,7 +609,8 @@ INLINE uint8_t * dest_zp() {
**/
INLINE uint16_t addr_zp_ind( uint8_t addr ) {
dbgPrintf("zpi:%02X:%04X(%02X) ", RAM[m6502.PC], *((uint16_t*)&RAM[m6502.PC]), RAM[*((uint16_t*)&RAM[m6502.PC])]);
disPrintf(disassembly.oper, "($%02X) {$%04X}", memread8(m6502.PC), memread16( memread8(m6502.PC) ) )
disPrintf(disassembly.oper, "($%02X)", memread8(m6502.PC) );
disPrintf(disassembly.comment, "ind_addr:%04X", memread16( memread8(m6502.PC) ) );
return memread16(addr);
}
@ -498,7 +621,8 @@ INLINE uint16_t addr_zp_ind( uint8_t addr ) {
**/
INLINE uint16_t addr_X_ind() {
dbgPrintf("zpXi:%02X:%04X(%02X) ", RAM[m6502.PC], *((uint16_t*)&RAM[m6502.PC]) + m6502.X, RAM[*((uint16_t*)&RAM[m6502.PC]) + m6502.X]);
disPrintf(disassembly.oper, "($%02X,X) {$%04X}", memread8(m6502.PC), memread16( memread8(m6502.PC) + m6502.X) )
disPrintf(disassembly.oper, "($%02X,X)", memread8(m6502.PC) )
disPrintf(disassembly.comment, "ind_addr:%04X", memread16( memread8(m6502.PC) + m6502.X) );
return memread16( fetch() + m6502.X );
}
INLINE uint8_t src_X_ind() {
@ -516,7 +640,8 @@ INLINE uint8_t * dest_X_ind() {
INLINE uint16_t addr_ind_Y() {
// uint8_t a = fetch();
// dbgPrintf("addr_ind_Y: %04X + %02X = %04X ", addr_zpg_ind( a ), m6502.Y, addr_zpg_ind( a ) + m6502.Y);
disPrintf(disassembly.oper, "($%02X),Y {$%04X}", memread8(m6502.PC), memread16( memread8(m6502.PC) ) + m6502.Y)
disPrintf(disassembly.oper, "($%02X),Y", memread8(m6502.PC) )
disPrintf(disassembly.comment, "ind_addr:%04X", memread16( memread8(m6502.PC) ) + m6502.Y );
return memread16( fetch() ) + m6502.Y;
}
INLINE uint8_t src_ind_Y() {

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14868" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14868"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
@ -641,8 +641,8 @@
<action selector="performMiniaturize:" target="Ady-hI-5gd" id="VwT-WD-YPe"/>
</connections>
</menuItem>
<menuItem title="Zoom" id="R4o-n2-Eq4">
<modifierMask key="keyEquivalentModifierMask"/>
<menuItem title="Zoom" keyEquivalent="z" id="R4o-n2-Eq4">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="performZoom:" target="Ady-hI-5gd" id="DIl-cC-cCs"/>
</connections>
@ -782,6 +782,102 @@
</connections>
</buttonCell>
</button>
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="LlM-EV-ruZ" customClass="HiRes" customModule="A2Mac" customModuleProvider="target">
<rect key="frame" x="16" y="8" width="568" height="384"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
</customView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Fb7-Jc-jmt">
<rect key="frame" x="598" y="186" width="74" height="17"/>
<constraints>
<constraint firstAttribute="height" constant="17" id="xCE-LE-hVy"/>
</constraints>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="left" title="CPU Speed" id="b3T-0k-ama">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<stackView distribution="fill" orientation="vertical" alignment="leading" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" fixedFrame="YES" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lVP-FP-u6x">
<rect key="frame" x="600" y="44" width="52" height="136"/>
<subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7Pw-e8-92m">
<rect key="frame" x="-1" y="119" width="55" height="18"/>
<buttonCell key="cell" type="radio" title="1.023" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="AgQ-Np-TYQ">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="speedSelected:" target="XfG-lQ-9wD" id="fJr-cu-aeu"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hU1-g7-CCX">
<rect key="frame" x="-1" y="95" width="30" height="18"/>
<buttonCell key="cell" type="radio" title="2" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="nfH-ww-Ofp">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="speedSelected:" target="XfG-lQ-9wD" id="5xI-Hq-xGm"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Hfg-DD-meM">
<rect key="frame" x="-1" y="71" width="31" height="18"/>
<buttonCell key="cell" type="radio" title="4" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="dqL-yg-qaX">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="speedSelected:" target="XfG-lQ-9wD" id="uCS-5C-ahW"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="OsQ-RW-v8K">
<rect key="frame" x="-1" y="47" width="37" height="18"/>
<buttonCell key="cell" type="radio" title="10" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="3Ve-WW-CIS">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="speedSelected:" target="XfG-lQ-9wD" id="QzE-hT-Qif"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vGb-dz-KHi">
<rect key="frame" x="-1" y="23" width="45" height="18"/>
<buttonCell key="cell" type="radio" title="100" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="BUX-kX-vwG">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="speedSelected:" target="XfG-lQ-9wD" id="fc9-ai-wSN"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="umb-DW-vGc">
<rect key="frame" x="-1" y="-1" width="47" height="18"/>
<buttonCell key="cell" type="radio" title="666" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="8VU-4B-7Pe">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="speedSelected:" target="XfG-lQ-9wD" id="Viq-Dy-2or"/>
</connections>
</button>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="FZk-VW-alq">
<rect key="frame" x="631" y="20" width="41" height="17"/>
<constraints>
@ -793,10 +889,6 @@
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="LlM-EV-ruZ" customClass="HiRes" customModule="A2Mac" customModuleProvider="target">
<rect key="frame" x="16" y="8" width="568" height="384"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
</customView>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="mfd-12-bcR" secondAttribute="trailing" constant="10" id="3NC-0i-OPC"/>
@ -840,5 +932,18 @@
</objects>
<point key="canvasLocation" x="723" y="320"/>
</scene>
<!--View Controller-->
<scene sceneID="Awv-7G-CRH">
<objects>
<viewController id="0CG-mQ-xR3" sceneMemberID="viewController">
<view key="view" id="MW2-U3-obl">
<rect key="frame" x="0.0" y="0.0" width="450" height="300"/>
<autoresizingMask key="autoresizingMask"/>
</view>
</viewController>
<customObject id="OhC-VN-jKp" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="241" y="1071"/>
</scene>
</scenes>
</document>

View File

@ -137,7 +137,7 @@ class HiRes: NSView {
scaleUnitSquare(to: NSSize(width: scaleSizeW, height: scaleSizeH))
// create smaller box views for draw optimization
// createHiRes()
//createHiRes()
#if METAL_YES
initMetal()

View File

@ -6,8 +6,20 @@
// Copyright © 2019 GameAlloy. All rights reserved.
//
import Cocoa
let K : Double = 1000.0
let M : Double = (K * K)
let G : Double = (M * K)
let T : Double = (G * K)
let KB : Double = 1024.0
let MB : Double = (KB * KB)
let GB : Double = (MB * KB)
let TB : Double = (GB * KB)
#if METAL_YES
import Metal
#endif
@ -285,7 +297,7 @@ class ViewController: NSViewController {
self.display.stringValue = txt
// self.display.stringValue = "testing\nit\nout"
if ( mhz < 10 ) {
if ( (mhz < 10) && (mhz != floor(mhz)) ) {
self.speedometer.stringValue = String(format: "%0.3lf MHz", mhz);
}
else {
@ -366,11 +378,23 @@ class ViewController: NSViewController {
// #endif
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
func setCPUClockSpeed( freq : Double ) {
mhz = freq
MHz_6502 = UInt64(mhz * M)
clk_6502_per_frm = MHz_6502 / UInt64(fps)
}
@IBAction func speedSelected(_ sender: NSButton) {
if ( sender.title == "Max" ) {
clk_6502_per_frm = UINT64_MAX
}
else if let freq = Double( sender.title ) {
setCPUClockSpeed(freq: freq)
}
}
}

View File

@ -11,6 +11,9 @@
#ifdef DISASSEMBLER
extern unsigned long long int clktime;
unsigned long long discnt = 0;
#define disHexB( to, b ) \
if ( m6502.dbgLevel.trace ) { \
snprintf((to), 4, "%02X ", (b)); \
@ -47,15 +50,43 @@
} \
}
INLINE void printDisassembly() {
if ( m6502.dbgLevel.trace ) {
printf("%s: %-14s%-6s%-14s%s\n",
disassembly.addr,
disassembly.opcode,
disassembly.inst,
disassembly.oper,
disassembly.comment
);
INLINE void printDisassembly( FILE * f ) {
if ( m6502.dbgLevel.trace && f ) {
// fprintf( f, "%s: %-14s%-6s%-14s%-16s A:%02X X:%02X Y:%02X S:%02X P:%02X (%c%c%c%c%c%c%c%c)\n",
// disassembly.addr,
// disassembly.opcode,
// disassembly.inst,
// disassembly.oper,
// disassembly.comment,
// m6502.A,
// m6502.X,
// m6502.Y,
// m6502.SP,
// m6502.SR,
// m6502.N ? 'N' : 'n',
// m6502.V ? 'V' : 'v',
// m6502.res ? 'R' : 'r',
// m6502.B ? 'B' : 'b',
// m6502.D ? 'D' : 'd',
// m6502.I ? 'I' : 'i',
// m6502.Z ? 'Z' : 'z',
// m6502.C ? 'C' : 'c'
// );
fprintf( f, "%llu\t%llu %s: %-11s%-4s%s\t0x%02X\t0x%02X\t0x%02X\t0x%02X\t0x%02X\t;\t%s\n", // Virtual ][ style
++discnt,
clktime,
disassembly.addr,
disassembly.opcode,
disassembly.inst,
disassembly.oper,
m6502.A,
m6502.X,
m6502.Y,
m6502.SR,
m6502.SP,
disassembly.comment
);
}
}

View File

@ -24,6 +24,7 @@
INLINE void JMP( uint16_t addr ) {
dbgPrintf("JMP %04X ", addr);
disPrintf(disassembly.inst, "JMP");
// disPrintf(disassembly.comment, "to:%04X", addr)
#ifdef DEBUG
if ( addr == m6502.PC - 3 ) {
dbgPrintf("Infinite Loop at %04X!\n", m6502.PC);

View File

@ -91,9 +91,8 @@ char * charConv =
**/
INLINE void STR( uint8_t * dst, uint8_t src ) {
dbgPrintf("STR [%04X], %02X ", (int)(dst - RAM), src );
*dst = src;
// uint16_t addr = dst - RAM;
uint16_t addr = dst - RAM;
// if ( ( addr >= 0x400 ) && ( addr < 0x800 ) ) {
// char c = charConv[src];
//// if ( c == '?' ) {
@ -103,11 +102,19 @@ INLINE void STR( uint8_t * dst, uint8_t src ) {
// if (( src > ' ' ) && ( c < 0x7F ))
// printf("*** PRINT: %04X: t:%02X '%c'\n", addr, src, isprint(c) ? c : ' ');
// }
// else if ( ( addr >= 0xC000 ) && ( addr < 0xD000 ) ) {
// else
if ( ( addr >= 0xC000 ) && ( addr < 0xD000 ) ) {
// printf("mmio write:[%04X] = %02X\n", addr, src);
// }
//
//
}
// Need to protect ROM!!!
else if ( ( addr >= 0xE000 ) && ( addr < 0xF000 ) ) {
// printf("mmio write:[%04X] = %02X\n", addr, src);
}
else {
*dst = src;
}
// else switch ( addr ) {
// case 0x36:
// case 0x37:

View File

@ -9,6 +9,12 @@
#ifndef woz_h
#define woz_h
#define DISKII_MAXTRACKS 80
#define DISKII_PHASES 4
#pragma pack(push)
#pragma pack(1)
typedef struct woz_header_s {
uint32_t magic;
@ -34,11 +40,12 @@ typedef struct woz_info_s {
// chunk data only
typedef struct woz_tmap_s {
uint8_t phase [80 * 4];
uint8_t phase [DISKII_MAXTRACKS * DISKII_PHASES];
} woz_tmap_t;
#define WOZ_TRACK_BYTE_COUNT 6646
// chunk data only
typedef struct woz_track_s {
uint8_t data [WOZ_TRACK_BYTE_COUNT];
uint16_t bytes_used;
@ -49,8 +56,10 @@ typedef struct woz_track_s {
uint16_t reserved;
} woz_track_t;
// chunk data only
typedef woz_track_t woz_trks_t[80];
// chunk data only
typedef woz_track_t woz_trks_t[DISKII_MAXTRACKS];
#pragma pack(pop)
#endif /* woz_h */