From 76ad2cfc59c09711850fadf5f504dba2a73451bf Mon Sep 17 00:00:00 2001 From: Tamas Rudnai Date: Mon, 17 Feb 2020 22:22:14 -0800 Subject: [PATCH] - fps set to 15 - First effort for the track preloading - Disk accelerator back to 25 MHz --- A2Mac/ViewController.swift | 2 +- A2Mac/src/cpu/6502.h | 2 +- .../instructions/6502_instr_call_ret_jump.h | 2 +- A2Mac/src/dev/disk/disk.c | 7 +- A2Mac/src/dev/disk/disk.h | 6 +- A2Mac/src/dev/disk/woz.c | 107 +++++++++++++----- A2Mac/src/dev/disk/woz.h | 3 +- 7 files changed, 92 insertions(+), 37 deletions(-) diff --git a/A2Mac/ViewController.swift b/A2Mac/ViewController.swift index 65851bf..3f20f90 100644 --- a/A2Mac/ViewController.swift +++ b/A2Mac/ViewController.swift @@ -265,7 +265,7 @@ class ViewController: NSViewController { // return frameCnt += 1 - if ( frameCnt == 15 ) { + if ( frameCnt == fps / 2 ) { // flashingSpace = blockChar ViewController.charConvTbl = ViewController.charConvTblFlashOn } diff --git a/A2Mac/src/cpu/6502.h b/A2Mac/src/cpu/6502.h index 6537859..e4fbe2d 100644 --- a/A2Mac/src/cpu/6502.h +++ b/A2Mac/src/cpu/6502.h @@ -101,7 +101,7 @@ extern void hires_Update(void); extern double mips; extern double mhz; -#define fps 30 +#define fps 15 extern void tst6502(void); extern void m6502_ColdReset(void); diff --git a/A2Mac/src/cpu/instructions/6502_instr_call_ret_jump.h b/A2Mac/src/cpu/instructions/6502_instr_call_ret_jump.h index b903d54..23a0caf 100644 --- a/A2Mac/src/cpu/instructions/6502_instr_call_ret_jump.h +++ b/A2Mac/src/cpu/instructions/6502_instr_call_ret_jump.h @@ -68,7 +68,7 @@ INLINE void RTS() { // disk accelerator would only work for a certain amount of time // currently it is 200ms simulated times - if ( m6502.clktime - disk.clk_since_last_read > clk_diskAcceleratorTimeout ) { + if ( m6502.clktime - disk.clk_last_access > clk_diskAcceleratorTimeout ) { clk_6502_per_frm = clk_6502_per_frm_set; } } diff --git a/A2Mac/src/dev/disk/disk.c b/A2Mac/src/dev/disk/disk.c index 9e722bd..02d8f2b 100644 --- a/A2Mac/src/dev/disk/disk.c +++ b/A2Mac/src/dev/disk/disk.c @@ -17,7 +17,7 @@ disk_t disk = { 0, // clk_since_last_read }; -const unsigned long long clk_6502_per_frm_diskAccelerator = 100 * M / fps; // disk acceleration bumps up CPU clock to 100 MHz +const unsigned long long clk_6502_per_frm_diskAccelerator = 25 * M / fps; // disk acceleration bumps up CPU clock to 25 MHz const unsigned long long clk_diskAcceleratorTimeout = 200000ULL; @@ -60,7 +60,7 @@ void disk_phase() { // printf(", p:%d d:%d l:%d: ph:%u trk:%u)", position, direction, lastPosition, phase.count, woz_tmap.phase[phase.count]); - disk.clk_since_last_read = m6502.clktime; + disk.clk_last_access = m6502.clktime; clk_6502_per_frm = clk_6502_per_frm_diskAccelerator; } @@ -74,8 +74,9 @@ void disk_phase() { uint8_t disk_read() { dbgPrintf("io_DISK_READ (S%u)\n", 6); - disk.clk_since_last_read = m6502.clktime; + disk.clk_last_access = m6502.clktime; clk_6502_per_frm = clk_6502_per_frm_diskAccelerator; + return woz_read(); } diff --git a/A2Mac/src/dev/disk/disk.h b/A2Mac/src/dev/disk/disk.h index ff683f7..77202b3 100644 --- a/A2Mac/src/dev/disk/disk.h +++ b/A2Mac/src/dev/disk/disk.h @@ -18,17 +18,21 @@ #define minDiskPhaseNum 0 #define maxDiskPhaseNum (minDiskPhaseStates * maxDiskTrackNum) + typedef struct phase_s { uint8_t lastMagnet : 4; uint8_t magnet : 4; int count; } phase_t; + typedef struct disk_s { phase_t phase; - uint64_t clk_since_last_read; + uint64_t clk_last_access; + uint64_t clk_last_read; } disk_t; + extern disk_t disk; diff --git a/A2Mac/src/dev/disk/woz.c b/A2Mac/src/dev/disk/woz.c index 7f1bdf1..2babbfe 100644 --- a/A2Mac/src/dev/disk/woz.c +++ b/A2Mac/src/dev/disk/woz.c @@ -26,6 +26,54 @@ woz_header_t woz_header; woz_chunk_header_t woz_chunk_header; woz_tmap_t woz_tmap; woz_trks_t woz_trks; +int track_loaded = -1; + + + +#pragma pack(push, 1) + +typedef union trackEntry_u { + struct { + uint8_t data; + uint8_t shift; + }; + uint16_t shift16; +} trackEntry_t; + +#pragma pack(pop) + +trackEntry_t prepared_track[WOZ_TRACK_BYTE_COUNT]; + +typedef enum readState_e { + readNormal = 0, + readHold, +} readState_t; + +readState_t readState = readNormal; +uint8_t readLatch; + + +void woz_loadTrack( int track ) { + trackEntry_t reg = {0}; + + reg.shift = woz_trks[track].data[0]; + reg.data = woz_trks[track].data[1]; + prepared_track[0] = reg; + + for ( int offs = 1; offs < WOZ_TRACK_BYTE_COUNT; offs++ ) { + + for ( int i = 0; i < 8; i++ ) { + if (reg.shift & 0x80) { + reg.shift = 0; + } + + reg.shift16 <<= 1; + } + + reg.data = woz_trks[track].data[ (offs + 1) % WOZ_TRACK_BYTE_COUNT ]; + prepared_track[offs] = reg; + } +} uint8_t woz_read() { @@ -36,6 +84,11 @@ uint8_t woz_read() { dbgPrintf("TRCK TOO HIGH!\n"); return rand(); } + + if ( track != track_loaded ) { + woz_loadTrack(track); + track_loaded = track; + } #ifdef WOZ_REAL_SPIN @@ -166,39 +219,35 @@ uint8_t woz_read() { #elif defined( WOZ_REAL_SPIN2 ) - clkelpased = m6502.clktime - clklast; - clklast = m6502.clktime & ~3; +// clkelpased = m6502.clktime - disk.clk_last_read; +// disk.clk_last_read = m6502.clktime; - bitOffset = (clkelpased >> 2) & 7; - trackOffset += (clkelpased >> 5) % WOZ_TRACK_BYTE_COUNT; - WOZread.data = woz_trks[track].data[trackOffset]; + bitOffset = (m6502.clktime >> 2) & 7; + trackOffset = (m6502.clktime >> 5) % WOZ_TRACK_BYTE_COUNT; + trackEntry_t reg = prepared_track[trackOffset]; + + do { + switch (readState) { + case readNormal: + readLatch = reg.shift; + break; + + case readHold: + default: + readState = readNormal; + break; + } - // 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; -// } - trackOffset++; - trackOffset %= WOZ_TRACK_BYTE_COUNT; - -// printf("offs:%u\n", trackOffset); - WOZread.data = woz_trks[track].data[trackOffset]; + if (reg.shift & 0x80) { + reg.shift = 0; + readState = readHold; } - 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(); - + reg.shift16 <<= 1; + } while ( --bitOffset > 0 ); + + printf("READ: clk:%llu to:%u bo:%llu B:%02X\n", m6502.clktime, trackOffset, (m6502.clktime >> 2) & 7, readLatch); + return readLatch; #else // WOZ_REAL_SPIN diff --git a/A2Mac/src/dev/disk/woz.h b/A2Mac/src/dev/disk/woz.h index b95e29c..20ea9ab 100644 --- a/A2Mac/src/dev/disk/woz.h +++ b/A2Mac/src/dev/disk/woz.h @@ -76,6 +76,7 @@ typedef woz_track_t woz_trks_t[DISKII_MAXTRACKS]; #define __NO__WOZ_REAL_SPIN2 + #ifdef WOZ_REAL_SPIN typedef union { @@ -118,7 +119,7 @@ extern uint8_t WOZlatch; //extern woz_trks_t woz_trks; -extern uint8_t woz_read(); +extern uint8_t woz_read(void); extern void woz_loadFile( const char * filename );