2020-02-17 04:38:38 +00:00
|
|
|
//
|
|
|
|
// disk.c
|
|
|
|
// A2Mac
|
|
|
|
//
|
|
|
|
// Created by Tamas Rudnai on 2/15/20.
|
|
|
|
// Copyright © 2020 GameAlloy. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#include "disk.h"
|
2020-05-28 02:12:28 +00:00
|
|
|
#include "6502.h"
|
|
|
|
#include "common.h"
|
2020-02-17 04:38:38 +00:00
|
|
|
#include "woz.h"
|
2020-06-09 03:52:10 +00:00
|
|
|
#include "speaker.h"
|
2020-02-17 04:38:38 +00:00
|
|
|
|
|
|
|
|
|
|
|
disk_t disk = {
|
2020-02-17 07:09:29 +00:00
|
|
|
{ 0, 0, 0 }, // phase
|
|
|
|
0, // clk_since_last_read
|
2020-02-17 04:38:38 +00:00
|
|
|
};
|
|
|
|
|
2020-06-09 03:52:10 +00:00
|
|
|
const int diskAccelerator_frames = 1;
|
2020-05-09 21:40:42 +00:00
|
|
|
int diskAccelerator_count = 0;
|
2020-05-28 02:12:28 +00:00
|
|
|
int diskAccelerator_speed = 25 * M / fps; // if less than actual CPU speed means no acceleration
|
2020-02-17 04:38:38 +00:00
|
|
|
|
|
|
|
|
|
|
|
// motor position from the magnet state
|
|
|
|
// -1 means invalid, not supported
|
|
|
|
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
|
|
|
|
};
|
|
|
|
|
|
|
|
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
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2020-05-03 04:26:24 +00:00
|
|
|
void disk_accelerator_speedup() {
|
2020-05-03 05:04:22 +00:00
|
|
|
if ( diskAccelerator_speed >= clk_6502_per_frm ) {
|
2020-06-09 03:52:10 +00:00
|
|
|
clk_6502_per_frm =
|
|
|
|
clk_6502_per_frm_max = diskAccelerator_speed; // clk_6502_per_frm_diskAccelerator;
|
2020-05-03 04:26:24 +00:00
|
|
|
diskAccelerator_count = diskAccelerator_frames;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-17 04:38:38 +00:00
|
|
|
void disk_phase() {
|
|
|
|
|
|
|
|
int position = magnet_to_Poistion[disk.phase.magnet];
|
|
|
|
if ( position >= 0 ) {
|
|
|
|
int lastPosition = disk.phase.count & 7;
|
|
|
|
int direction = position_to_direction[lastPosition][position];
|
|
|
|
|
|
|
|
disk.phase.count += direction;
|
|
|
|
if( disk.phase.count < minDiskPhaseNum ) {
|
|
|
|
disk.phase.count = minDiskPhaseNum;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if( disk.phase.count > maxDiskPhaseNum ) {
|
|
|
|
disk.phase.count = maxDiskPhaseNum;
|
|
|
|
}
|
|
|
|
|
2020-06-09 03:52:10 +00:00
|
|
|
spkr_toggle();
|
|
|
|
|
|
|
|
// printf("Head Position: p:%d d:%d l:%d: ph:%u)\n", position, direction, lastPosition, disk.phase.count);
|
2020-02-17 04:38:38 +00:00
|
|
|
|
2020-02-18 06:22:14 +00:00
|
|
|
disk.clk_last_access = m6502.clktime;
|
2020-05-03 04:26:24 +00:00
|
|
|
disk_accelerator_speedup();
|
2020-02-17 04:38:38 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
// invalid magnet config
|
|
|
|
}
|
|
|
|
|
2020-06-09 03:52:10 +00:00
|
|
|
// printf("\n");
|
2020-02-17 04:38:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-06-07 04:09:00 +00:00
|
|
|
void disk_phase_on( uint8_t currentMagnet ) {
|
|
|
|
disk.phase.magnet |= 1 << currentMagnet;
|
|
|
|
disk_phase();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void disk_phase_off( uint8_t currentMagnet ) {
|
|
|
|
disk.phase.magnet &= ~(1 << currentMagnet);
|
|
|
|
disk_phase();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-02-17 04:38:38 +00:00
|
|
|
uint8_t disk_read() {
|
|
|
|
dbgPrintf("io_DISK_READ (S%u)\n", 6);
|
2020-02-18 06:22:14 +00:00
|
|
|
disk.clk_last_access = m6502.clktime;
|
2020-05-03 04:26:24 +00:00
|
|
|
disk_accelerator_speedup();
|
|
|
|
|
2020-02-17 04:38:38 +00:00
|
|
|
return woz_read();
|
|
|
|
}
|
|
|
|
|