2020-02-17 04:38:38 +00:00
|
|
|
//
|
|
|
|
// disk.c
|
2020-07-13 17:23:33 +00:00
|
|
|
// Steve ][
|
2020-02-17 04:38:38 +00:00
|
|
|
//
|
|
|
|
// Created by Tamas Rudnai on 2/15/20.
|
2020-07-13 17:16:37 +00:00
|
|
|
// Copyright © 2019, 2020 Tamas Rudnai. All rights reserved.
|
2020-07-13 17:10:33 +00:00
|
|
|
//
|
|
|
|
// This file is part of Steve ][ -- The Apple ][ Emulator.
|
|
|
|
//
|
|
|
|
// Steve ][ is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// Steve ][ is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with Steve ][. If not, see <https://www.gnu.org/licenses/>.
|
2020-02-17 04:38:38 +00:00
|
|
|
//
|
|
|
|
|
2020-06-19 22:16:27 +00:00
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
2020-02-17 04:38:38 +00:00
|
|
|
#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
|
2020-06-19 22:16:27 +00:00
|
|
|
0, // clk_last_access
|
2020-02-17 07:09:29 +00:00
|
|
|
0, // clk_since_last_read
|
2020-06-19 22:16:27 +00:00
|
|
|
0, // drive number
|
2020-02-17 04:38:38 +00:00
|
|
|
};
|
|
|
|
|
2020-06-09 04:12:40 +00:00
|
|
|
const int diskAccelerator_frames = 2;
|
2020-05-09 21:40:42 +00:00
|
|
|
int diskAccelerator_count = 0;
|
2020-06-14 03:13:20 +00:00
|
|
|
int diskAccelerator_speed = 25; // if less than actual CPU speed means no acceleration
|
2020-06-12 14:15:06 +00:00
|
|
|
int diskAccelerator_enabled = 0;
|
2020-06-12 06:16:26 +00:00
|
|
|
int disk_sfx_enabled = 1;
|
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-06-11 21:50:07 +00:00
|
|
|
const uint8_t phy2log_dos33[16] = {
|
|
|
|
0, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 15
|
|
|
|
};
|
|
|
|
const uint8_t log2phy_dos33[16] = {
|
|
|
|
0, 13, 11, 9, 7, 5, 3, 1, 14, 12, 10, 8, 6, 4, 2, 15
|
|
|
|
};
|
|
|
|
|
|
|
|
const uint8_t phy2log_pascal[16] = {
|
|
|
|
0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15
|
|
|
|
};
|
|
|
|
const uint8_t log2phy_pascal[16] = {
|
|
|
|
0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15
|
|
|
|
};
|
|
|
|
|
|
|
|
const uint8_t phy2log_cpm[16] = {
|
|
|
|
0, 11, 6, 1, 12, 7, 2, 13, 8, 3, 14, 9, 4, 15, 10, 5
|
|
|
|
};
|
|
|
|
const uint8_t log2phy_cpm[16] = {
|
|
|
|
0, 3, 6, 9, 12, 15, 2, 5, 8, 11, 14, 1, 4, 7, 10, 13
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-05-03 04:26:24 +00:00
|
|
|
void disk_accelerator_speedup() {
|
2020-06-14 03:13:20 +00:00
|
|
|
if ( ( diskAccelerator_enabled ) && ( FRAME(diskAccelerator_speed) >= clk_6502_per_frm ) ) {
|
2020-06-09 03:52:10 +00:00
|
|
|
clk_6502_per_frm =
|
2020-06-14 03:13:20 +00:00
|
|
|
clk_6502_per_frm_max = FRAME(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;
|
2020-06-12 01:29:26 +00:00
|
|
|
spkr_play_disk_ioerr();
|
2020-02-17 04:38:38 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
if( disk.phase.count > maxDiskPhaseNum ) {
|
|
|
|
disk.phase.count = maxDiskPhaseNum;
|
2020-06-12 01:29:26 +00:00
|
|
|
spkr_play_disk_ioerr();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
spkr_play_disk_arm();
|
2020-02-17 04:38:38 +00:00
|
|
|
}
|
|
|
|
|
2020-06-09 04:12:40 +00:00
|
|
|
// TODO: Add track positioning sfx
|
|
|
|
// spkr_toggle();
|
2020-06-09 03:52:10 +00:00
|
|
|
|
|
|
|
// 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-12 01:29:26 +00:00
|
|
|
|
|
|
|
|
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-06-12 01:29:26 +00:00
|
|
|
void disk_motor_on() {
|
|
|
|
spkr_play_disk_motor();
|
|
|
|
spkr_stop_disk_motor( -1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
void disk_motor_off() {
|
|
|
|
spkr_stop_disk_motor( 3 * fps ); // 3 second delay
|
|
|
|
}
|
2020-06-07 04:09:00 +00:00
|
|
|
|
2020-02-17 04:38:38 +00:00
|
|
|
uint8_t disk_read() {
|
|
|
|
dbgPrintf("io_DISK_READ (S%u)\n", 6);
|
2020-06-19 22:16:27 +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-06-11 21:50:07 +00:00
|
|
|
// Debug disk read
|
|
|
|
// spkr_toggle();
|
|
|
|
|
2020-06-19 22:16:27 +00:00
|
|
|
if ( disk.drive ) {
|
|
|
|
return rand();
|
|
|
|
}
|
|
|
|
|
2020-02-17 04:38:38 +00:00
|
|
|
return woz_read();
|
|
|
|
}
|
|
|
|
|