diff --git a/Components/1770/1770.cpp b/Components/1770/1770.cpp index 17d839962..1ba3a97ea 100644 --- a/Components/1770/1770.cpp +++ b/Components/1770/1770.cpp @@ -7,7 +7,9 @@ // #include "1770.hpp" + #include "../../Storage/Disk/Encodings/MFM/Constants.hpp" +#include "../../Outputs/Log.hpp" using namespace WD; @@ -25,10 +27,10 @@ void WD1770::set_register(int address, uint8_t value) { if((value&0xf0) == 0xd0) { if(value == 0xd0) { // Force interrupt **immediately**. - printf("Force interrupt immediately\n"); + LOG("Force interrupt immediately"); posit_event(static_cast(Event1770::ForceInterrupt)); } else { - printf("!!!TODO: force interrupt!!!\n"); + ERROR("!!!TODO: force interrupt!!!"); update_status([] (Status &status) { status.type = Status::One; }); @@ -193,7 +195,7 @@ void WD1770::posit_event(int new_event_type) { // Wait for a new command, branch to the appropriate handler. case 0: wait_for_command: - printf("Idle...\n"); + LOG("Idle..."); set_data_mode(DataMode::Scanning); index_hole_count_ = 0; @@ -209,7 +211,7 @@ void WD1770::posit_event(int new_event_type) { status.interrupt_request = false; }); - printf("Starting %02x\n", command_); + LOG("Starting " << std::hex << command_ << std::endl); if(!(command_ & 0x80)) goto begin_type_1; if(!(command_ & 0x40)) goto begin_type_2; @@ -327,7 +329,7 @@ void WD1770::posit_event(int new_event_type) { } if(header_[0] == track_) { - printf("Reached track %d\n", track_); + LOG("Reached track " << std::dec << track_); update_status([] (Status &status) { status.crc_error = false; }); @@ -396,20 +398,20 @@ void WD1770::posit_event(int new_event_type) { READ_ID(); if(index_hole_count_ == 5) { - printf("Failed to find sector %d\n", sector_); + LOG("Failed to find sector " << std::dec << sector_); update_status([] (Status &status) { status.record_not_found = true; }); goto wait_for_command; } if(distance_into_section_ == 7) { - printf("Considering %d/%d\n", header_[0], header_[2]); + LOG("Considering " << std::dec << header_[0] << "/" << header_[2]); set_data_mode(DataMode::Scanning); if( header_[0] == track_ && header_[2] == sector_ && (has_motor_on_line() || !(command_&0x02) || ((command_&0x08) >> 3) == header_[1])) { - printf("Found %d/%d\n", header_[0], header_[2]); + LOG("Found " << std::dec << header_[0] << "/" << header_[2]); if(get_crc_generator().get_value()) { - printf("CRC error; back to searching\n"); + LOG("CRC error; back to searching"); update_status([] (Status &status) { status.crc_error = true; }); @@ -465,7 +467,7 @@ void WD1770::posit_event(int new_event_type) { distance_into_section_++; if(distance_into_section_ == 2) { if(get_crc_generator().get_value()) { - printf("CRC error; terminating\n"); + LOG("CRC error; terminating"); update_status([this] (Status &status) { status.crc_error = true; }); @@ -476,7 +478,7 @@ void WD1770::posit_event(int new_event_type) { sector_++; goto test_type2_write_protection; } - printf("Finished reading sector %d\n", sector_); + LOG("Finished reading sector " << std::dec << sector_); goto wait_for_command; } goto type2_check_crc; @@ -558,7 +560,7 @@ void WD1770::posit_event(int new_event_type) { sector_++; goto test_type2_write_protection; } - printf("Wrote sector %d\n", sector_); + LOG("Wrote sector " << std::dec << sector_); goto wait_for_command; diff --git a/Components/8272/i8272.cpp b/Components/8272/i8272.cpp index 8cbc434c8..d45109ac5 100644 --- a/Components/8272/i8272.cpp +++ b/Components/8272/i8272.cpp @@ -7,9 +7,8 @@ // #include "i8272.hpp" -//#include "../../Storage/Disk/Encodings/MFM/Encoder.hpp" -#include +#include "../../Outputs/Log.hpp" using namespace Intel::i8272; @@ -115,7 +114,7 @@ void i8272::run_for(Cycles cycles) { while(steps--) { // Perform a step. int direction = (drives_[c].target_head_position < drives_[c].head_position) ? -1 : 1; - printf("Target %d versus believed %d\n", drives_[c].target_head_position, drives_[c].head_position); + LOG("Target " << std::dec << drives_[c].target_head_position << " versus believed " << drives_[c].head_position); select_drive(c); get_drive().step(Storage::Disk::HeadPosition(direction)); if(drives_[c].target_head_position >= 0) drives_[c].head_position += direction; @@ -386,17 +385,17 @@ void i8272::posit_event(int event_type) { // the index hole limit is breached or a sector is found with a cylinder, head, sector and size equal to the // values in the internal registers. index_hole_limit_ = 2; -// printf("Seeking %02x %02x %02x %02x\n", cylinder_, head_, sector_, size_); +// LOG("Seeking " << std::dec << cylinder_ << " " << head_ " " << sector_ << " " << size_); find_next_sector: FIND_HEADER(); if(!index_hole_limit_) { // Two index holes have passed wihout finding the header sought. -// printf("Not found\n"); +// LOG("Not found"); SetNoData(); goto abort; } index_hole_count_ = 0; -// printf("Header\n"); +// LOG("Header"); READ_HEADER(); if(index_hole_count_) { // This implies an index hole was sighted within the header. Error out. @@ -407,11 +406,11 @@ void i8272::posit_event(int event_type) { // This implies a CRC error in the header; mark as such but continue. SetDataError(); } -// printf("Considering %02x %02x %02x %02x [%04x]\n", header_[0], header_[1], header_[2], header_[3], get_crc_generator().get_value()); +// LOG("Considering << std::hex << header_[0] << " " << header_[1] << " " << header_[2] << " " << header_[3] << " [" << get_crc_generator().get_value() << "]"); if(header_[0] != cylinder_ || header_[1] != head_ || header_[2] != sector_ || header_[3] != size_) goto find_next_sector; // Branch to whatever is supposed to happen next -// printf("Proceeding\n"); +// LOG("Proceeding"); switch(command_[0] & 0x1f) { case CommandReadData: case CommandReadDeletedData: @@ -425,7 +424,7 @@ void i8272::posit_event(int event_type) { // Performs the read data or read deleted data command. read_data: - printf("Read [deleted] data [%02x %02x %02x %02x ... %02x %02x]\n", command_[2], command_[3], command_[4], command_[5], command_[6], command_[8]); + LOG("Read [deleted] data [" << std::hex << command_[2] << " " << command_[3] << " " << command_[4] << " " << command_[5] << " ... " << command_[6] << " " << command_[8] << "]"); read_next_data: goto read_write_find_header; @@ -509,7 +508,7 @@ void i8272::posit_event(int event_type) { goto post_st012chrn; write_data: - printf("Write [deleted] data [%02x %02x %02x %02x ... %02x %02x]\n", command_[2], command_[3], command_[4], command_[5], command_[6], command_[8]); + LOG("Write [deleted] data [" << std::hex << command_[2] << " " << command_[3] << " " << command_[4] << " " << command_[5] << " ... " << command_[6] << " " << command_[8] << "]"); if(get_drive().get_is_read_only()) { SetNotWriteable(); @@ -544,7 +543,7 @@ void i8272::posit_event(int event_type) { goto write_loop; } - printf("Wrote %d bytes\n", distance_into_section_); + LOG("Wrote " << std::dec << distance_into_section_ << " bytes"); write_crc(); expects_input_ = false; WAIT_FOR_EVENT(Event::DataWritten); @@ -560,7 +559,7 @@ void i8272::posit_event(int event_type) { // Performs the read ID command. read_id: // Establishes the drive and head being addressed, and whether in double density mode. - printf("Read ID [%02x %02x]\n", command_[0], command_[1]); + LOG("Read ID [" << std::hex << command_[0] << " " << command_[1] << "]"); // Sets a maximum index hole limit of 2 then waits either until it finds a header mark or sees too many index holes. // If a header mark is found, reads in the following bytes that produce a header. Otherwise branches to data not found. @@ -582,7 +581,7 @@ void i8272::posit_event(int event_type) { // Performs read track. read_track: - printf("Read track [%02x %02x %02x %02x]\n", command_[2], command_[3], command_[4], command_[5]); + LOG("Read track [" << std::hex << command_[2] << " " << command_[3] << " " << command_[4] << " " << command_[5] << "]"); // Wait for the index hole. WAIT_FOR_EVENT(Event::IndexHole); @@ -623,7 +622,7 @@ void i8272::posit_event(int event_type) { // Performs format [/write] track. format_track: - printf("Format track\n"); + LOG("Format track"); if(get_drive().get_is_read_only()) { SetNotWriteable(); goto abort; @@ -667,7 +666,7 @@ void i8272::posit_event(int event_type) { break; } - printf("W: %02x %02x %02x %02x, %04x\n", header_[0], header_[1], header_[2], header_[3], get_crc_generator().get_value()); + LOG("W: " << std::hex << header_[0] << " " << header_[1] << " " << header_[2] << " " << header_[3] << ", " << get_crc_generator().get_value()); write_crc(); // Write the sector body. @@ -699,15 +698,15 @@ void i8272::posit_event(int event_type) { goto post_st012chrn; scan_low: - printf("Scan low unimplemented!!\n"); + ERROR("Scan low unimplemented!!"); goto wait_for_command; scan_low_or_equal: - printf("Scan low or equal unimplemented!!\n"); + ERROR("Scan low or equal unimplemented!!"); goto wait_for_command; scan_high_or_equal: - printf("Scan high or equal unimplemented!!\n"); + ERROR("Scan high or equal unimplemented!!"); goto wait_for_command; // Performs both recalibrate and seek commands. These commands occur asynchronously, so the actual work @@ -738,11 +737,11 @@ void i8272::posit_event(int event_type) { // up in run_for understands to mean 'keep going until track 0 is active'). if(command_.size() > 2) { drives_[drive].target_head_position = command_[2]; - printf("Seek to %02x\n", command_[2]); + LOG("Seek to " << std::hex << command_[2]); } else { drives_[drive].target_head_position = -1; drives_[drive].head_position = 0; - printf("Recalibrate\n"); + LOG("Recalibrate"); } // Check whether any steps are even needed; if not then mark as completed already. @@ -755,7 +754,7 @@ void i8272::posit_event(int event_type) { // Performs sense interrupt status. sense_interrupt_status: - printf("Sense interrupt status\n"); + LOG("Sense interrupt status"); { // Find the first drive that is in the CompletedSeeking state. int found_drive = -1; @@ -783,7 +782,7 @@ void i8272::posit_event(int event_type) { // Performs specify. specify: // Just store the values, and terminate the command. - printf("Specify\n"); + LOG("Specify"); step_rate_time_ = 16 - (command_[1] >> 4); // i.e. 1 to 16ms head_unload_time_ = (command_[1] & 0x0f) << 4; // i.e. 16 to 240ms head_load_time_ = command_[2] & ~1; // i.e. 2 to 254 ms in increments of 2ms @@ -794,7 +793,7 @@ void i8272::posit_event(int event_type) { goto wait_for_command; sense_drive_status: - printf("Sense drive status\n"); + LOG("Sense drive status"); { int drive = command_[1] & 3; select_drive(drive); @@ -833,11 +832,11 @@ void i8272::posit_event(int event_type) { // Posts whatever is in result_stack_ as a result phase. Be aware that it is a stack, so the // last thing in it will be returned first. post_result: - printf("Result to %02x, main %02x: ", command_[0] & 0x1f, main_status_); + LOGNBR("Result to " << std::hex << (command_[0] & 0x1f) << ", main " << main_status_); for(std::size_t c = 0; c < result_stack_.size(); c++) { - printf("%02x ", result_stack_[result_stack_.size() - 1 - c]); + LOGNBR(result_stack_[result_stack_.size() - 1 - c]); } - printf("\n"); + LOGNBR(std::endl); // Set ready to send data to the processor, no longer in non-DMA execution phase. is_executing_ = false; diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 2b21d153e..06bbc3832 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -1381,6 +1381,7 @@ 4BD4A8CF1E077FD20020D856 /* PCMTrackTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PCMTrackTests.mm; sourceTree = ""; }; 4BD5F1931D13528900631CD1 /* CSBestEffortUpdater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSBestEffortUpdater.h; path = Updater/CSBestEffortUpdater.h; sourceTree = ""; }; 4BD5F1941D13528900631CD1 /* CSBestEffortUpdater.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = CSBestEffortUpdater.mm; path = Updater/CSBestEffortUpdater.mm; sourceTree = ""; }; + 4BD601A920D89F2A00CBCE57 /* Log.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = Log.hpp; path = ../../Outputs/Log.hpp; sourceTree = ""; }; 4BD61663206B2AC700236112 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/QuickLoadOptions.xib"; sourceTree = SOURCE_ROOT; }; 4BD67DC9209BE4D600AB2146 /* StaticAnalyser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = StaticAnalyser.hpp; sourceTree = ""; }; 4BD67DCA209BE4D600AB2146 /* StaticAnalyser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StaticAnalyser.cpp; sourceTree = ""; }; @@ -1774,6 +1775,7 @@ children = ( 4B0CCC411C62D0B3001CAC5F /* CRT */, 4BD060A41FE49D3C006E14BE /* Speaker */, + 4BD601A920D89F2A00CBCE57 /* Log.hpp */, ); name = Outputs; sourceTree = ""; diff --git a/Outputs/Log.hpp b/Outputs/Log.hpp new file mode 100644 index 000000000..36f7e2fe9 --- /dev/null +++ b/Outputs/Log.hpp @@ -0,0 +1,31 @@ +// +// Log.hpp +// Clock Signal +// +// Created by Thomas Harte on 18/06/2018. +// Copyright © 2018 Thomas Harte. All rights reserved. +// + +#ifndef Log_h +#define Log_h + +#ifdef NDEBUG + +#define LOG(x) +#define LOGNBR(x) +#define ERROR(x) +#define ERRORNBR(x) + +#else + +#include + +#define LOG(x) std::cout << x << std::endl +#define LOGNBR(x) std::cout << x +#define ERROR(x) std::cerr << x << std::endl +#define ERRORNBR(x) std::cerr << x + +#endif + + +#endif /* Log_h */