├── Firmware ├── .vscode │ ├── .cortex-debug.peripherals.state.json │ ├── .cortex-debug.registers.state.json │ ├── c_cpp_properties.json │ ├── extensions.json │ ├── launch.json │ └── settings.json ├── CMakeLists.txt ├── EventMachine.c ├── EventMachine.h ├── MicroDriveControl.c ├── MicroDriveControl.h ├── MicroPicoDrive.c ├── PIO_machines.pio ├── SharedBuffers.c ├── SharedBuffers.h ├── SharedEvents.h ├── UserInterface.c ├── UserInterface.h ├── pff │ ├── 00readme.txt │ ├── diskio.c │ ├── diskio.h │ ├── pff.c │ ├── pff.h │ └── pffconf.h ├── pico_sdk_import.cmake └── ssd1306 │ ├── font.h │ ├── ssd1306.c │ └── ssd1306.h ├── Hardware ├── BOM.txt ├── MicroPicoDrive │ ├── EdgeCon.pretty │ │ └── Edge_connector_02x08.kicad_mod │ ├── MicroPicoDrive-backups │ │ ├── MicroPicoDrive-2023-05-29_203418.zip │ │ ├── MicroPicoDrive-2023-05-30_125441.zip │ │ ├── MicroPicoDrive-2023-05-30_130802.zip │ │ ├── MicroPicoDrive-2023-07-29_010023.zip │ │ ├── MicroPicoDrive-2023-07-29_150801.zip │ │ ├── MicroPicoDrive-2023-07-30_122208.zip │ │ ├── MicroPicoDrive-2023-07-31_143826.zip │ │ ├── MicroPicoDrive-2023-07-31_222641.zip │ │ ├── MicroPicoDrive-2023-08-03_011139.zip │ │ ├── MicroPicoDrive-2023-08-03_012055.zip │ │ ├── MicroPicoDrive-2023-08-05_002551.zip │ │ ├── MicroPicoDrive-2023-08-11_081052.zip │ │ ├── MicroPicoDrive-2023-08-12_144109.zip │ │ ├── MicroPicoDrive-2023-09-19_195752.zip │ │ ├── MicroPicoDrive-2023-09-20_210319.zip │ │ ├── MicroPicoDrive-2023-09-22_121144.zip │ │ ├── MicroPicoDrive-2023-09-22_130835.zip │ │ ├── MicroPicoDrive-2023-09-23_051410.zip │ │ ├── MicroPicoDrive-2023-09-27_094133.zip │ │ ├── MicroPicoDrive-2023-10-02_184407.zip │ │ ├── MicroPicoDrive-2023-10-08_101315.zip │ │ ├── MicroPicoDrive-2023-10-08_143311.zip │ │ ├── MicroPicoDrive-2023-10-08_152605.zip │ │ ├── MicroPicoDrive-2023-10-08_154223.zip │ │ ├── MicroPicoDrive-2023-10-08_183524.zip │ │ └── MicroPicoDrive-2023-11-01_024118.zip │ ├── MicroPicoDrive.kicad_pcb │ ├── MicroPicoDrive.kicad_pcb_ │ ├── MicroPicoDrive.kicad_prl │ ├── MicroPicoDrive.kicad_pro │ ├── MicroPicoDrive.kicad_sch │ ├── RPi_Pico.kicad_sym │ ├── RPi_Pico.lib │ ├── RPi_Pico.pretty │ │ ├── CUI_SJ-3523-audio-jack.kicad_mod │ │ ├── DSUB-15-L77HDE15SD1CH4F.kicad_mod │ │ ├── Icon_ │ │ ├── MBR120_SOD-123.kicad_mod │ │ ├── RPi_Pico_SMD_TH.kicad_mod │ │ └── USB_Micro-B_Amphenol_10103594-0001LF_Horizontal_modified.kicad_mod │ ├── SN74LVC1T45DBVR.lib │ ├── SN74LVC1T45DBVR.pretty │ │ └── SOT95P280X145-6N.kicad_mod │ ├── TXU0304QPWRQ1.lib │ ├── TXU0304QPWRQ1.pretty │ │ └── TXU0304QPWRQ1.kicad_mod │ ├── fp-info-cache │ ├── fp-lib-table │ └── sym-lib-table └── MicroPicoDriveCartridge │ ├── CartridgeComponents.bak │ ├── CartridgeComponents.kicad_sym │ ├── CartridgeComponents.pretty │ ├── Edge.kicad_mod │ ├── SDCard.kicad_mod │ └── Screen.kicad_mod │ └── MicroPicoDriveCartridge │ ├── MicroPicoDriveCartridge-backups │ ├── MicroPicoDriveCartridge-2023-05-23_142327.zip │ ├── MicroPicoDriveCartridge-2023-05-23_150242.zip │ ├── MicroPicoDriveCartridge-2023-05-23_171754.zip │ ├── MicroPicoDriveCartridge-2023-05-24_175259.zip │ ├── MicroPicoDriveCartridge-2023-05-30_125634.zip │ ├── MicroPicoDriveCartridge-2023-05-30_130710.zip │ ├── MicroPicoDriveCartridge-2023-07-29_001629.zip │ ├── MicroPicoDriveCartridge-2023-07-29_010023.zip │ ├── MicroPicoDriveCartridge-2023-07-30_123117.zip │ ├── MicroPicoDriveCartridge-2023-07-30_163305.zip │ ├── MicroPicoDriveCartridge-2023-07-31_111700.zip │ ├── MicroPicoDriveCartridge-2023-07-31_143906.zip │ ├── MicroPicoDriveCartridge-2023-07-31_222643.zip │ ├── MicroPicoDriveCartridge-2023-09-20_052350.zip │ ├── MicroPicoDriveCartridge-2023-09-20_205039.zip │ ├── MicroPicoDriveCartridge-2023-09-22_121901.zip │ ├── MicroPicoDriveCartridge-2023-09-22_180210.zip │ ├── MicroPicoDriveCartridge-2023-10-02_193844.zip │ ├── MicroPicoDriveCartridge-2023-10-02_194415.zip │ ├── MicroPicoDriveCartridge-2023-10-02_195242.zip │ ├── MicroPicoDriveCartridge-2023-10-02_212053.zip │ ├── MicroPicoDriveCartridge-2023-10-08_100613.zip │ ├── MicroPicoDriveCartridge-2023-10-09_011235.zip │ ├── MicroPicoDriveCartridge-2023-10-13_211810.zip │ ├── MicroPicoDriveCartridge-2023-11-03_022304.zip │ └── MicroPicoDriveCartridge-2023-11-03_214532.zip │ ├── MicroPicoDriveCartridge.kicad_pcb │ ├── MicroPicoDriveCartridge.kicad_prl │ ├── MicroPicoDriveCartridge.kicad_pro │ ├── MicroPicoDriveCartridge.kicad_sch │ ├── fp-info-cache │ ├── fp-lib-table │ └── sym-lib-table ├── LICENSE ├── README.md └── Software ├── .gitignore ├── MDTools ├── MDTools.csproj └── Program.cs ├── MDToolsUI ├── BatchConverter.cs ├── DeviceNameSelector.cs ├── DirectoryExplorer.cs ├── InputBox.cs ├── MDToolsUI.csproj ├── MDToolsUI.csproj.user ├── MediaInfo.cs ├── Program.cs ├── Properties │ └── PublishProfiles │ │ ├── FolderProfile.pubxml │ │ ├── FolderProfile.pubxml.user │ │ ├── FolderProfile1.pubxml │ │ └── FolderProfile1.pubxml.user └── Utils.cs ├── MicroDriveTools.sln ├── MicroDriveTools ├── Classes │ ├── MicroDriveCartridge.cs │ ├── MicroDriveDirectory.cs │ ├── MicroDriveFile.cs │ ├── MicroDriveSectorMap.cs │ ├── ZIPFile.cs │ └── ZIPImporter.cs ├── ConvertTools.cs ├── MicroDriveTools.csproj └── Structs │ └── MicroDriveStructs.cs └── TestTools ├── ABACUS.MDV ├── Program.cs ├── SAVE1.MDV ├── TestTools.csproj ├── caca.mdv ├── carttest.mdv ├── carttest2.mdv ├── e.txt ├── fmt.mdv ├── mcosmic_m.zip ├── mmetropolism.zip ├── pacman_patched.mdv ├── pepe.mdv └── starplod.zip /Firmware/.vscode/.cortex-debug.peripherals.state.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /Firmware/.vscode/.cortex-debug.registers.state.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /Firmware/.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Linux", 5 | "includePath": [ 6 | "${workspaceFolder}/**", 7 | "${env:PICO_SDK_PATH}/**" 8 | ], 9 | "defines": [], 10 | "compilerPath": "C:\\Program Files (x86)\\GNU Arm Embedded Toolchain\\10 2021.10\\bin\\arm-none-eabi-gcc.EXE", 11 | "cStandard": "gnu17", 12 | "cppStandard": "gnu++14", 13 | "intelliSenseMode": "linux-gcc-arm", 14 | "configurationProvider" : "ms-vscode.cmake-tools" 15 | } 16 | ], 17 | "version": 4 18 | } 19 | -------------------------------------------------------------------------------- /Firmware/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "marus25.cortex-debug", 4 | "ms-vscode.cmake-tools", 5 | "ms-vscode.cpptools" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /Firmware/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Cortex Debug", 9 | "cwd": "${workspaceRoot}", 10 | "executable": "${command:cmake.launchTargetPath}", 11 | "request": "launch", 12 | "type": "cortex-debug", 13 | "servertype": "openocd", 14 | "gdbPath": "arm-none-eabi-gdb", 15 | "device": "RP2040", 16 | "configFiles": [ 17 | "interface/picoprobe.cfg", 18 | "target/rp2040.cfg" 19 | ], 20 | "svdFile": "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd", 21 | "runToEntryPoint": "main", 22 | // Give restart the same functionality as runToEntryPoint - main 23 | "postRestartCommands": [ 24 | "break main", 25 | "continue" 26 | ], 27 | "showDevDebugOutput": "raw" 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /Firmware/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cmake.configureOnOpen": false, 3 | "cmake.statusbar.advanced": { 4 | "debug" : { 5 | "visibility": "hidden" 6 | }, "launch" : { 7 | "visibility": "hidden" 8 | }, 9 | "build" : { 10 | "visibility": "default" 11 | }, 12 | "buildTarget" : { 13 | "visibility": "hidden" 14 | }, 15 | }, 16 | } 17 | -------------------------------------------------------------------------------- /Firmware/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Generated Cmake Pico project file 2 | 3 | cmake_minimum_required(VERSION 3.13) 4 | 5 | set(CMAKE_C_STANDARD 11) 6 | set(CMAKE_CXX_STANDARD 17) 7 | 8 | # Initialise pico_sdk from installed location 9 | # (note this can come from environment, CMake cache etc) 10 | set(PICO_SDK_PATH "F:/PicoSDK/Pico/pico-sdk") 11 | 12 | set(PICO_BOARD pico CACHE STRING "Board type") 13 | 14 | # Pull in Raspberry Pi Pico SDK (must be before project) 15 | include(pico_sdk_import.cmake) 16 | 17 | if (PICO_SDK_VERSION_STRING VERSION_LESS "1.4.0") 18 | message(FATAL_ERROR "Raspberry Pi Pico SDK version 1.4.0 (or later) required. Your version is ${PICO_SDK_VERSION_STRING}") 19 | endif() 20 | 21 | project(MicroPicoDrive C CXX ASM) 22 | 23 | # Initialise the Raspberry Pi Pico SDK 24 | pico_sdk_init() 25 | 26 | # Add executable. Default name is the project name, version 0.1 27 | 28 | # add_executable(MicroPicoDrive MicroPicoDrive.c ) 29 | FILE(GLOB CSources *.c) 30 | ADD_EXECUTABLE(MicroPicoDrive ${CSources} ssd1306/ssd1306.c pff/diskio.c pff/pff.c) 31 | 32 | # Create C header file with the name .pio.h 33 | pico_generate_pio_header(${PROJECT_NAME} 34 | ${CMAKE_CURRENT_LIST_DIR}/PIO_machines.pio 35 | ) 36 | 37 | pico_set_program_name(MicroPicoDrive "MicroPicoDrive") 38 | pico_set_program_version(MicroPicoDrive "0.1") 39 | 40 | pico_enable_stdio_uart(MicroPicoDrive 0) 41 | pico_enable_stdio_usb(MicroPicoDrive 0) 42 | 43 | # Add the standard library to the build 44 | target_link_libraries(MicroPicoDrive 45 | pico_stdlib 46 | pico_multicore) 47 | 48 | # Add the standard include files to the build 49 | target_include_directories(MicroPicoDrive PRIVATE 50 | ${CMAKE_CURRENT_LIST_DIR} 51 | ${CMAKE_CURRENT_LIST_DIR}/.. # for our common lwipopts or any other standard includes, if required 52 | ) 53 | 54 | # Add any user requested libraries 55 | target_link_libraries(MicroPicoDrive 56 | hardware_spi 57 | hardware_pio 58 | hardware_dma 59 | hardware_timer 60 | hardware_i2c) 61 | 62 | pico_add_extra_outputs(MicroPicoDrive) 63 | 64 | -------------------------------------------------------------------------------- /Firmware/EventMachine.c: -------------------------------------------------------------------------------- 1 | #include "EventMachine.h" 2 | 3 | //Initialize the event machine 4 | void event_machine_init(evtmachine_t* machine, event_handler handler, uint8_t event_size, uint8_t queue_depth) 5 | { 6 | queue_init(&machine->queue, event_size, queue_depth); 7 | machine->handler = handler; 8 | } 9 | 10 | //Adds an event to the machine 11 | void event_push(evtmachine_t* machine, void* event) 12 | { 13 | queue_add_blocking(&machine->queue, event); 14 | } 15 | 16 | //Processes the pending events 17 | void event_process_queue(evtmachine_t* machine, void* event_buffer, uint8_t max_events) 18 | { 19 | uint8_t evt_count = 0; 20 | while(!queue_is_empty(&machine->queue) && evt_count++ < max_events) 21 | { 22 | queue_remove_blocking(&machine->queue, event_buffer); 23 | machine->handler(event_buffer); 24 | } 25 | } 26 | 27 | //Clears the stored events in the machine 28 | void event_clear(evtmachine_t* machine) 29 | { 30 | machine->queue.wptr = 0; 31 | machine->queue.rptr = 0; 32 | } 33 | 34 | //Free an event machine 35 | void event_free(evtmachine_t* machine) 36 | { 37 | queue_free(&machine->queue); 38 | machine->handler = NULL; 39 | } -------------------------------------------------------------------------------- /Firmware/EventMachine.h: -------------------------------------------------------------------------------- 1 | #ifndef __EVENTMACHINE__ 2 | #define __EVENTMACHINE__ 3 | 4 | #include "pico/stdlib.h" 5 | #include "pico/util/queue.h" 6 | 7 | //Event handler function declaration 8 | typedef void(*event_handler)(void*); 9 | 10 | //Event machine struct 11 | typedef struct evtmachine 12 | { 13 | //Queue to store events 14 | queue_t queue; 15 | //Function to process the events 16 | event_handler handler; 17 | 18 | } evtmachine_t; 19 | 20 | void event_machine_init(evtmachine_t* machine, event_handler handler, uint8_t args_size, uint8_t queue_depth); 21 | void event_push(evtmachine_t* machine, void* event); 22 | void event_process_queue(evtmachine_t* machine, void* event_buffer, uint8_t max_events); 23 | void event_clear(evtmachine_t* machine); 24 | void event_free(evtmachine_t* machine); 25 | 26 | #endif -------------------------------------------------------------------------------- /Firmware/MicroDriveControl.h: -------------------------------------------------------------------------------- 1 | #ifndef __MICRODRIVECONTROL__ 2 | #define __MICRODRIVECONTROL__ 3 | 4 | #include "hardware/pio.h" 5 | 6 | #define MD_SER_DATA_IN 0 7 | #define MD_SER_CLK 1 8 | #define MD_SER_DATA_OUT 2 9 | #define MD_READ_HEAD_1 3 10 | #define MD_READ_HEAD_2 5 11 | #define MD_WRITE_HEAD_1 4 12 | #define MD_WRITE_HEAD_2 6 13 | #define MD_RW 7 14 | #define MD_ERASE 8 15 | #define MD_HEAD_DIR 22 16 | 17 | #define QL_HEADER_SIZE 71 18 | #define QL_SECTOR_SIZE 2455 19 | #define QL_PREAMBLE_SIZE 48 20 | 21 | #define SHIFTER_ALARM 0 22 | #define WRITE_GAP_ALARM 1 23 | 24 | //2780 25 | #define QL_WRITE_GAP_US 3600 26 | #define SHIFTER_SELECT_US 10000 27 | 28 | //Enumeration with the meaning of the status lines 29 | typedef enum __attribute__((packed)) 30 | { 31 | MDL_WRITE = 0, //ULA wants to write to the MD 32 | MDL_WRITE_GAP = 1, //Write gap 33 | MDL_INVALID = 2, 34 | MDL_READ = 3 //ULA wants to read from the MD 35 | 36 | } mdlinestatus_t; 37 | 38 | //Status of the md itself 39 | typedef enum __attribute__((packed)) 40 | { 41 | MDS_DESELECTED, 42 | MDS_SELECTED 43 | 44 | } mdstatus_t; 45 | 46 | //Selected substatus 47 | typedef enum __attribute__((packed)) 48 | { 49 | MDA_IDLE, 50 | MDA_READ_HEADER_GAP, 51 | MDA_READ_HEADER, 52 | MDA_READ_SECTOR_GAP, 53 | MDA_READ_SECTOR, 54 | MDA_WRITE_HEADER_GAP, 55 | MDA_WRITE_HEADER, 56 | MDA_WRITE_SECTOR_GAP, 57 | MDA_WRITE_SECTOR 58 | 59 | } mdactivestatus_t; 60 | 61 | //Internal events for the md control 62 | typedef enum __attribute__((packed)) 63 | { 64 | MDE_SHIFT_CHANGED, //Shifter status has changed (0 or 1) 65 | MDE_SELECT_TIMEOUT_EXPIRED, //Shifter selection time has expired, MD has been selected or deselected 66 | MDE_MD_STATUS_CHANGED, //Status lines have changed 67 | MDE_DMA_READ_IRQ, //A read IRQ has been raised 68 | MDE_DMA_WRITE_IRQ, //A write IRQ has been changed 69 | MDE_CHECK_WRITE_FINISH, //Check if the TX buffers are empty and the transfer has finished 70 | MDE_WRITE_GAP_FINISHED //A write gap has finished 71 | 72 | } mdevents_t; 73 | 74 | typedef struct mdcontrolevent 75 | { 76 | 77 | mdevents_t event; 78 | uint16_t args; 79 | 80 | } mdcontrolevent_t; 81 | 82 | void select_md(); 83 | void deselect_md(); 84 | void check_ui_notifications(mdactivestatus_t previousState, bool fromGap); 85 | bool common_gap_code(uint8_t** selectedTrack1Buffer, uint8_t** selectedTrack2Buffer, bool forRead); 86 | void begin_write_gap(); 87 | void end_write_gap(); 88 | void begin_read_gap(); 89 | void end_read_gap(); 90 | void shifter_alarm(uint alarm_num); 91 | void write_gap_alarm(uint alarm_num); 92 | static inline void abort_shifter_alarm(); 93 | static inline void abort_write_gap_alarm(); 94 | static inline void begin_shifter_alarm(); 95 | static inline void begin_write_gap_alarm(); 96 | static inline void start_PIO_shifter(); 97 | static inline void deselect_PIO_status(); 98 | static inline void select_PIO_status(); 99 | static inline void begin_PIO_read_gap(); 100 | static inline void end_PIO_read_gap(); 101 | static inline void sleep_PIO_write(); 102 | static inline void begin_PIO_write_gap(); 103 | static inline void end_PIO_write_gap(); 104 | void process_md_event(void* event); 105 | void process_ui_event(void* event); 106 | void track1_write_irq(); 107 | void track2_write_irq(); 108 | void status_irq(); 109 | void shifter_irq(); 110 | void init_DMAs(); 111 | void enable_read_DMAs(uint8_t* buffer_track_1, uint8_t* buffer_track_2, bool isHeader); 112 | void enable_write_DMAs(uint8_t* buffer_track_1, uint8_t* buffer_track_2, bool isHeader); 113 | void disable_DMAs(bool readDMAs); 114 | void reset_transfer_machine(PIO pio, uint sm, uint initial_pc); 115 | void reset_transfer_machines(); 116 | void init_PIO_machines(); 117 | void init_alarms(); 118 | void RunMDControl(); 119 | 120 | #endif -------------------------------------------------------------------------------- /Firmware/MicroPicoDrive.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pico/stdlib.h" 3 | #include "pico/multicore.h" 4 | #include "MicroDriveControl.h" 5 | #include "UserInterface.h" 6 | 7 | int main() 8 | { 9 | //We don't give a fuck, overclock to 200Mhz because we can :P 10 | set_sys_clock_khz(200000, true); 11 | 12 | //Start the MD control in core1 13 | multicore_launch_core1(RunUserInterface); 14 | 15 | //Run the user interface in core0 16 | RunMDControl(); 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /Firmware/PIO_machines.pio: -------------------------------------------------------------------------------- 1 | ;differential manchester rx, machine reads a bit each 20 clocks, so the machine runs 20 times faster than the source 2 | ;as the QL runs at a 100Khz speed the PIO must run at 2Mhz 3 | ;the original design reads a bit each 16 clocks, we use 20 as we do manual pushes and we want the wait for the initial clock 4 | ;to have some extra cycles so it can resynchronize in case the ULA skews a bit the write frequency. 5 | ;the QL ULA sends a preamble to calibrate the clock because the media was a tape and it would stretch with the time and change the 6 | ;frequency of the data, we don't have that problem as we are reading from the ULA and it has a precise clock of 100Khz 7 | ;just synchronizing with the clock change is enough to read data in a precise way. 8 | ;the preamble causes a bit of trouble because we need to find and discard it before reading actual data, as the PIO 9 | ;is very limited we opt to read the bits as-is and send them to the CPU cores, they will take care to transform them 10 | ;into the real data. 11 | ;the original design sets the scratch registers and autopush from the machine configuration and uses a wrap, we don't use it 12 | ;for readability and we have enough instructions left so I prefer to consolidate as much code as I can in the PIO itself 13 | 14 | .program microdrive_read 15 | 16 | start: 17 | 18 | set x, 1 ; prepare scratch registers 19 | set y, 0 ; we will use X and Y to send the bit value to the input shift register 20 | 21 | 22 | public rx_gap: 23 | 24 | wait 0 irq 7 ; in the read gap we do nothing except to wait for an IRQ 25 | set pindirs 0 ; set the pin as input 26 | 27 | initial_high: ; we come from a low state (from a gap o from a bit finished in low state) 28 | 29 | wait 1 pin 0 [14] ; wait for the rising edge, we skip three fourths of the bit cycle to sample at the middle of the second half of the bit cycle 30 | jmp pin high_0 ; if the input pin is one then there has been no value change, the bit is a zero, else we fall through and this was a one 31 | 32 | high_1: 33 | 34 | in x, 1 ; send the one bit to the isr 35 | push ; send it to the fifo 36 | jmp initial_high ; we are in a low state, the next bit must start with a high change 37 | 38 | high_0: 39 | 40 | in y, 1 ; send the zero bit to the isr 41 | push ; send the isr to the fifo 42 | ; here we do nothing, the code falls through to the initial low as we are in a high state 43 | 44 | initial_low: 45 | 46 | wait 0 pin 0 [14] ; we wait for the low edge, we skip three fourths of the bit cycle to sample at the middle of the second half of the bit cycle 47 | jmp pin low_1 ; if the input pin is a one then we have read a value change, it is a one 48 | 49 | low_0: 50 | 51 | in y, 1 ; send the zero to the isr 52 | push ; send the isr to the fifo 53 | jmp initial_high ; we are in a low state, next bit must start with a high change 54 | 55 | low_1: 56 | 57 | in x, 1 ; send the one to the isr 58 | push ; send the isr to the fifo 59 | jmp initial_low ; we are in a high state, the next bit must start with a low change 60 | 61 | 62 | ;---------------------------------------------------------------------------- 63 | 64 | ;differential manchester tx, machine transmits a bit each 16 clocks, so the machine runs 16 times faster than the source. 65 | ;as the QL runs at a 100Khz speed the PIO must run at 1.6Mhz 66 | ;each pull from the FIFO is a bit, this is done this way for the RX side of the machine 67 | ;as the ULA writes a preamble with lots of trash, it's barely impossible to process it with the PIO 68 | 69 | .program microdrive_write 70 | .side_set 1 opt 71 | 72 | public tx_sleep: 73 | 74 | set pindirs 0 side 0 ; on sleep the tx machine sets the pin as input to not to disturb the rx one 75 | jmp tx_sleep ; stay here forever until the CPU changes the PC to the tx gap 76 | 77 | public tx_gap: 78 | 79 | set pindirs 1 side 1 ; on the tx gap we set line as output with low state 80 | wait 0 irq 7 ; wait for an external IRQ to exit from the gap 81 | 82 | initial_high: ; we start with a high clock (or continue from a low state) 83 | 84 | out x, 1 side 1 ; get a bit from the FIFO, set pin to high, move the bit to X 85 | jmp !x high_0 [6] ; jump to a high starting zero if X = 0, delay always for six instructions (8 cycles in total) 86 | 87 | high_1: 88 | nop side 0 ; this is a one and we come from a high state, so set it to low. 89 | jmp initial_high [6] ; Next bit will start in high and we delay for 8 cycles 90 | 91 | high_0: 92 | nop 93 | nop [6] ; We don't do anything here but delay for 8 cycles as the program will fall through to initial_low 94 | 95 | initial_low: 96 | 97 | out x, 1 side 0 ; pull from the fifo and set pin to zero, move bit to X 98 | jmp !x low_0 [6] ; jump to a low starting zero if X = 0, delay always for six instructions (8 cycles in total) 99 | 100 | low_1: 101 | nop side 1 ; this is a one and we come from a low state, so set it to high 102 | jmp initial_low [6] ; Next bit will start in low and we delay for 8 cycles 103 | 104 | low_0: 105 | nop 106 | jmp initial_high [6] ; As this is a zero we do nothing and start the next cycle at high level 107 | 108 | ;---------------------------------------------------------------------------- 109 | 110 | ; microdrive shift/select machine 111 | ; the state machine runs 32 times faster than the MD ser_data clock. 112 | ; as the SER_DATA clock runs at 21.5Khz then SM should run at 688Khz. 113 | ; timming is not crytical for this application as we synchronize with the clock on each edge. 114 | 115 | .program microdrive_shift_select 116 | 117 | startup: 118 | 119 | set pindirs, 4 ; pin0 = data_in (in), pin1 = clock (in), pin2 = data_out (out) 120 | wait 1 irq 6 ; we wait for an IRQ before starting 121 | 122 | wait_rising: 123 | 124 | wait 1 pin 1 [7] ; wait for rising edge of clock and half a cycle 125 | in pins 1 ; read data pin to ISR 126 | mov y, isr ; store the value in Y for later comparison 127 | mov osr, y ; copy Y to OSR (prepare data to be sent to the out pin) 128 | wait 0 pin 1 ; wait for falling edge of clock 129 | out pins, 1 ; move the readed bit to the out pin 130 | 131 | jmp x!=y state_changed ; check if the new state is not the same 132 | mov isr, null ; clear the ISR 133 | jmp wait_rising ; wait for the next rising edge 134 | 135 | state_changed: 136 | 137 | mov x, y ; copy to X the new state for later comparison 138 | push ; send it to the FIFO 139 | irq 0 ; notify the software 140 | jmp wait_rising ; wait for the next rising edge 141 | 142 | ;---------------------------------------------------------------------------- 143 | 144 | ; microdrive status machine 145 | ; the state machine runs at maximum speed 146 | ; possible MD states: 11b, read (erase off, read on) 147 | ; 01b, write gap (erase on, read on) 148 | ; 00b, write (erase on, write on) 149 | ; 150 | ; if by any chance a 10b is read the software must ignore it (it should not happen, the MD will never leave write on with erase off) 151 | 152 | .program microdrive_status 153 | 154 | start: 155 | set pindirs 0 ; all inputs, pin0 = R/!W, pin1 = !ERASE 156 | 157 | public device_deselected: 158 | 159 | set x, 2 ; Init X with 10b (erase off, write on, an impossible state) 160 | mov isr, null ; ensure ISR is clear 161 | wait 1 irq 6 ; wait for IRQ 6 162 | 163 | device_selected: 164 | 165 | in pins, 2 ; read pins to the ISR 166 | mov y, isr ; copy to Y 167 | jmp x!=y status_changed ; check if state has changed 168 | mov isr, null ; clear ISR if not (else the push will take care of clearing it) 169 | jmp device_selected ; loop until a change is found 170 | 171 | status_changed: 172 | 173 | mov x, y ; copy new state to X 174 | push ; push the state to the FIFO (we have it in the ISR) 175 | irq 0 ; trigger IRQ to notify to the software the change 176 | jmp device_selected ; loop -------------------------------------------------------------------------------- /Firmware/SharedBuffers.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "EventMachine.h" 3 | #include "SharedBuffers.h" 4 | /* 5 | 6 | Buffers for the microdrive PIO machines 7 | We have two sets so we can go ahead before the user interface core 8 | processes the received data or writes new sectors to it 9 | 10 | */ 11 | 12 | //First set of buffers 13 | //Header of a sector, two tracks 14 | uint8_t header_1_track_1[HEADER_BUFFER_SIZE]; 15 | uint8_t header_1_track_2[HEADER_BUFFER_SIZE]; 16 | 17 | //Content of a sector, two tracks 18 | uint8_t sector_1_track_1[SECTOR_BUFFER_SIZE]; 19 | uint8_t sector_1_track_2[SECTOR_BUFFER_SIZE]; 20 | uint8_t bufferset_1_sector_number = 0; 21 | 22 | //Second set of buffers 23 | //Header of a sector, two tracks 24 | uint8_t header_2_track_1[HEADER_BUFFER_SIZE]; 25 | uint8_t header_2_track_2[HEADER_BUFFER_SIZE]; 26 | 27 | //Content of a sector, two tracks 28 | uint8_t sector_2_track_1[SECTOR_BUFFER_SIZE]; 29 | uint8_t sector_2_track_2[SECTOR_BUFFER_SIZE]; 30 | uint8_t bufferset_2_sector_number = 0; 31 | 32 | //Cartridge image buffer 33 | uint8_t cartridge_image[CART_SIZE]; 34 | 35 | /* 36 | Event machines 37 | */ 38 | 39 | //Machine processed by the ui control, receives events from the md 40 | evtmachine_t mdToUiEventQueue; 41 | //Machine processed by the md control, receives events from the ui 42 | evtmachine_t uiToMdEventQueue; -------------------------------------------------------------------------------- /Firmware/SharedBuffers.h: -------------------------------------------------------------------------------- 1 | #ifndef __SHAREDBUFFERS__ 2 | #define __SHAREDBUFFERS__ 3 | 4 | #include "pico/stdlib.h" 5 | #include "EventMachine.h" 6 | 7 | #define CART_SIZE 160140 8 | 9 | #define HEADER_BUFFER_SIZE 128 10 | #define SECTOR_BUFFER_SIZE 2980 11 | 12 | #define HEADER_TRACK_DATA_SIZE 8 13 | #define SECTOR_TRACK_DATA_SIZE 306 14 | 15 | #define PREAMBLE_ZERO_BITS (5 * 8) 16 | #define PREAMBLE_ONE_BITS 8 17 | 18 | #define PREAMBLE_ZERO_BYTES 10 19 | #define PREAMBLE_ONE_BYTES 2 20 | 21 | extern uint8_t cartridge_image[CART_SIZE]; 22 | 23 | extern uint8_t header_1_track_1[HEADER_BUFFER_SIZE]; 24 | extern uint8_t header_1_track_2[HEADER_BUFFER_SIZE]; 25 | 26 | extern uint8_t sector_1_track_1[SECTOR_BUFFER_SIZE]; 27 | extern uint8_t sector_1_track_2[SECTOR_BUFFER_SIZE]; 28 | 29 | extern uint8_t bufferset_1_sector_number; 30 | 31 | extern uint8_t header_2_track_1[HEADER_BUFFER_SIZE]; 32 | extern uint8_t header_2_track_2[HEADER_BUFFER_SIZE]; 33 | 34 | extern uint8_t sector_2_track_1[SECTOR_BUFFER_SIZE]; 35 | extern uint8_t sector_2_track_2[SECTOR_BUFFER_SIZE]; 36 | 37 | extern uint8_t bufferset_2_sector_number; 38 | 39 | extern evtmachine_t mdToUiEventQueue; 40 | extern evtmachine_t uiToMdEventQueue; 41 | 42 | #endif -------------------------------------------------------------------------------- /Firmware/SharedEvents.h: -------------------------------------------------------------------------------- 1 | #ifndef __SHAREDEVENTS__ 2 | #define __SHAREDEVENTS__ 3 | 4 | typedef enum __attribute__((packed)) 5 | { 6 | MTU_MD_DESELECTED, 7 | MTU_MD_SELECTED, 8 | MTU_MD_READING, //ULA is reading from the MD 9 | MTU_MD_WRITTING, //ULA is writting to the MD 10 | MTU_BUFFERSET_READ, //A buffer set (header + sector) has been read by the ULA 11 | MTU_BUFFERSET_WRITTEN, //A buffer set (header + sector) has been written by the ULA 12 | 13 | } mdtouievent_t; 14 | 15 | typedef enum __attribute__((packed)) 16 | { 17 | UTM_CARTRIDGE_INSERTED, 18 | UTM_CARTRIDGE_REMOVED 19 | 20 | } uitomdevent_t; 21 | 22 | typedef struct mtuevent 23 | { 24 | mdtouievent_t event; 25 | uint8_t arg; 26 | 27 | } mtuevent_t; 28 | 29 | typedef struct utmevent 30 | { 31 | uitomdevent_t event; 32 | 33 | } utmevent_t; 34 | 35 | #endif -------------------------------------------------------------------------------- /Firmware/UserInterface.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __USERINTERFACE__ 3 | #define __USERINTERFACE__ 4 | 5 | #define PIN_LED_ON 25 6 | 7 | #define PIN_LED_SELECT 9 8 | #define PIN_LED_READ 11 9 | #define PIN_LED_WRITE 10 10 | 11 | #define PIN_BTN_BACK 12 12 | #define PIN_BTN_NEXT 13 13 | #define PIN_BTN_SELECT 14 14 | 15 | #define PIN_UI_DETECT 15 16 | 17 | #define I2C_PORT i2c0 18 | #define I2C_SDA 20 19 | #define I2C_SCL 21 20 | 21 | #define CART_MDV_SIZE 174930 22 | #define CART_MPD_SIZE 160140 23 | 24 | #define MDV_PREAMBLE_SIZE 12 25 | #define MDV_HEADER_SIZE 16 26 | #define MDV_DATA_SIZE 646 27 | #define MDV_PAD_SIZE 34 28 | #define MDV_SECTOR_SIZE 686 29 | 30 | #define MPD_HEADER_SIZE 16 31 | #define MPD_DATA_SIZE 612 32 | 33 | #define CARTRIDGE_HEADER_SIZE 16 34 | #define CARTRIDGE_DATA_SIZE 612 35 | #define CARTRIDGE_SECTOR_SIZE 628 36 | #define CARTRIDGE_SECTOR_COUNT 255 37 | 38 | #define PATH_BUFFER_SIZE 300 39 | 40 | typedef enum 41 | { 42 | IDLE, 43 | DELAY, 44 | INIT_SCREEN, 45 | WELCOME, 46 | SHOW_WAITING_SD_CARD, 47 | WAITING_SD_CARD, 48 | OPEN_FOLDER, 49 | READ_FOLDER_ENTRY, 50 | SELECT_FILE, 51 | FILE_SELECTED, 52 | FILE_LOAD, 53 | CARTRIDGE_READY 54 | 55 | } USER_INTERFACE_STATE; 56 | 57 | typedef enum 58 | { 59 | NONE, 60 | MDV, 61 | MPD 62 | } CARTRIDGE_FORMAT; 63 | 64 | typedef struct __attribute__((__packed__)) SECTOR_HEADER 65 | { 66 | uint8_t HeaderData[14]; 67 | uint16_t Checksum; 68 | 69 | } SECTOR_HEADER_t; 70 | 71 | typedef struct __attribute__((__packed__)) SECTOR_RECORD 72 | { 73 | uint8_t HeaderData[2]; 74 | uint16_t HeaderChecksum; 75 | uint8_t FilePreamble[8]; 76 | uint8_t Data[512]; 77 | uint16_t DataChecksum; 78 | uint8_t ExtraBytes[84]; 79 | uint16_t ExtraBytesChecksum; 80 | 81 | } SECTOR_RECORD_t; 82 | 83 | typedef struct __attribute__((__packed__)) SECTOR 84 | { 85 | SECTOR_HEADER_t Header; 86 | SECTOR_RECORD_t Record; 87 | 88 | } SECTOR_t; 89 | 90 | void RunUserInterface(); 91 | 92 | #endif -------------------------------------------------------------------------------- /Firmware/pff/00readme.txt: -------------------------------------------------------------------------------- 1 | Petit FatFs Module Source Files R0.03a (C)ChaN, 2019 2 | 3 | 4 | FILES 5 | 6 | pff.h Common include file for Petit FatFs and application module. 7 | pff.c Petit FatFs module. 8 | diskio.h Common include file for Petit FatFs and disk I/O module. 9 | diskio.c Skeleton of low level disk I/O module. 10 | 11 | Low level disk I/O module is not included in this archive because the Petit 12 | FatFs module is only a generic file system layer and not depend on any 13 | specific storage device. You have to provide a low level disk I/O module that 14 | written to control your storage device. 15 | 16 | 17 | 18 | AGREEMENTS 19 | 20 | Petit FatFs module is an open source software to implement FAT file system to 21 | small embedded systems. This is a free software and is opened for education, 22 | research and commercial developments under license policy of following trems. 23 | 24 | Copyright (C) 2019, ChaN, all right reserved. 25 | 26 | * The Petit FatFs module is a free software and there is NO WARRANTY. 27 | * No restriction on use. You can use, modify and redistribute it for 28 | personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY. 29 | * Redistributions of source code must retain the above copyright notice. 30 | 31 | 32 | 33 | REVISION HISTORY 34 | 35 | Jun 15, 2009 R0.01a First release (Branched from FatFs R0.07b) 36 | 37 | Dec 14, 2009 R0.02 Added multiple code page support. 38 | Added write funciton. 39 | Changed stream read mode interface. 40 | 41 | Dec 07,'2010 R0.02a Added some configuration options. 42 | Fixed fails to open objects with DBCS character. 43 | 44 | Jun 10, 2014 R0.03 Separated out configuration options to pffconf.h. 45 | Added _USE_LCC option. 46 | Added _FS_FAT16 option. 47 | 48 | Jan 30, 2019 R0.03a Supported stdint.h for C99 and later. 49 | Removed _WORD_ACCESS option. 50 | Changed prefix of configuration options, _ to PF_. 51 | Added some code pages. 52 | Removed some code pages actually not valid. 53 | 54 | -------------------------------------------------------------------------------- /Firmware/pff/diskio.c: -------------------------------------------------------------------------------- 1 | /*-----------------------------------------------------------------------*/ 2 | /* Low level disk I/O module skeleton for Petit FatFs (C)ChaN, 2014 */ 3 | /*-----------------------------------------------------------------------*/ 4 | 5 | #include "diskio.h" 6 | #include "pico/stdlib.h" 7 | #include "hardware/spi.h" 8 | /*-------------------------------------------------------------------------- 9 | SPI and Pin selection 10 | ---------------------------------------------------------------------------*/ 11 | 12 | #define SELECT() gpio_put(PF_SPI_CS, 0) 13 | #define DESELECT() gpio_put(PF_SPI_CS, 1) 14 | #define SELECTING (gpio_is_dir_out(PF_SPI_CS) && !gpio_get(PF_SPI_CS)) 15 | #define FCLK_SLOW() spi_set_baudrate(spi, CLK_SLOW) 16 | #define FCLK_FAST() spi_set_baudrate(spi, CLK_FAST) 17 | 18 | spi_inst_t *spi = PF_SPI; 19 | 20 | static 21 | BYTE CardType; /* Card type flags */ 22 | 23 | static inline uint32_t _millis(void) 24 | { 25 | return to_ms_since_boot(get_absolute_time()); 26 | } 27 | 28 | /*-----------------------------------------------------------------------*/ 29 | /* SPI controls (Platform dependent) */ 30 | /*-----------------------------------------------------------------------*/ 31 | 32 | /* Initialize MMC interface */ 33 | void init_spi(void) 34 | { 35 | /* GPIO pin configuration */ 36 | /* pull up of MISO is MUST (10Kohm external pull up is recommended) */ 37 | /* Set drive strength and slew rate if needed to meet wire condition */ 38 | gpio_init(PF_SPI_SCK); 39 | gpio_disable_pulls(PF_SPI_SCK); 40 | //gpio_pull_up(PIN_SPI_SCK); 41 | //gpio_set_drive_strength(PIN_SPI_SCK, PADS_BANK0_GPIO0_DRIVE_VALUE_4MA); // 2mA, 4mA (default), 8mA, 12mA 42 | //gpio_set_slew_rate(PIN_SPI_SCK, 0); // 0: SLOW (default), 1: FAST 43 | gpio_set_function(PF_SPI_SCK, GPIO_FUNC_SPI); 44 | 45 | gpio_init(PF_SPI_MISO); 46 | #ifdef PF_MISO_PULLUP 47 | gpio_pull_up(PF_SPI_MISO); 48 | #else 49 | gpio_disable_pulls(PF_SPI_MISO); 50 | #endif 51 | gpio_set_function(PF_SPI_MISO, GPIO_FUNC_SPI); 52 | 53 | gpio_init(PF_SPI_MOSI); 54 | gpio_disable_pulls(PF_SPI_MOSI); 55 | //gpio_pull_up(PIN_SPI_MOSI); 56 | //gpio_set_drive_strength(PIN_SPI_MOSI, PADS_BANK0_GPIO0_DRIVE_VALUE_4MA); // 2mA, 4mA (default), 8mA, 12mA 57 | //gpio_set_slew_rate(PIN_SPI_MOSI, 0); // 0: SLOW (default), 1: FAST 58 | gpio_set_function(PF_SPI_MOSI, GPIO_FUNC_SPI); 59 | 60 | gpio_init(PF_SPI_CS); 61 | gpio_disable_pulls(PF_SPI_CS); 62 | //gpio_pull_up(PIN_SPI_CS); 63 | //gpio_set_drive_strength(PIN_SPI_CS, PADS_BANK0_GPIO0_DRIVE_VALUE_4MA); // 2mA, 4mA (default), 8mA, 12mA 64 | //gpio_set_slew_rate(PIN_SPI_CS, 0); // 0: SLOW (default), 1: FAST 65 | gpio_set_dir(PF_SPI_CS, GPIO_OUT); 66 | 67 | /* chip _select invalid*/ 68 | DESELECT(); 69 | 70 | spi_init(spi, CLK_SLOW); 71 | 72 | /* SPI parameter config */ 73 | spi_set_format(spi, 74 | 8, /* data_bits */ 75 | SPI_CPOL_0, /* cpol */ 76 | SPI_CPHA_0, /* cpha */ 77 | SPI_MSB_FIRST /* order */ 78 | ); 79 | } 80 | 81 | /* Exchange a byte */ 82 | static inline BYTE spi_exchange ( 83 | BYTE dat /* Data to send */ 84 | ) 85 | { 86 | spi_write_read_blocking(spi, &dat, &dat, 1); 87 | return dat; 88 | } 89 | 90 | //Send a byte 91 | static inline void xmit_spi(BYTE d) 92 | { 93 | spi_exchange(d); 94 | } 95 | 96 | //Receive a byte 97 | static inline BYTE rcv_spi(void) 98 | { 99 | return spi_exchange(0xFF); 100 | } 101 | 102 | /*-----------------------------------------------------------------------*/ 103 | /* Send a command packet to MMC */ 104 | /*-----------------------------------------------------------------------*/ 105 | static BYTE send_cmd(BYTE cmd, /* 1st byte (Start + Index) */ 106 | DWORD arg /* Argument (32 bits) */ 107 | ) 108 | { 109 | BYTE n, res; 110 | 111 | if (cmd & 0x80) { /* ACMD is the command sequence of CMD55-CMD */ 112 | cmd &= 0x7F; 113 | res = send_cmd(CMD55, 0); 114 | if (res > 1) 115 | return res; 116 | } 117 | 118 | /* Select the card */ 119 | DESELECT(); 120 | rcv_spi(); 121 | SELECT(); 122 | rcv_spi(); 123 | 124 | /* Send a command packet */ 125 | xmit_spi(cmd); /* Start + Command index */ 126 | xmit_spi((BYTE)(arg >> 24)); /* Argument[31..24] */ 127 | xmit_spi((BYTE)(arg >> 16)); /* Argument[23..16] */ 128 | xmit_spi((BYTE)(arg >> 8)); /* Argument[15..8] */ 129 | xmit_spi((BYTE)arg); /* Argument[7..0] */ 130 | n = 0x01; /* Dummy CRC + Stop */ 131 | if (cmd == CMD0) 132 | n = 0x95; /* Valid CRC for CMD0(0) */ 133 | if (cmd == CMD8) 134 | n = 0x87; /* Valid CRC for CMD8(0x1AA) */ 135 | xmit_spi(n); 136 | 137 | /* Receive a command response */ 138 | n = 10; /* Wait for a valid response in timeout of 10 attempts */ 139 | do { 140 | res = rcv_spi(); 141 | } while ((res & 0x80) && --n); 142 | 143 | return res; /* Return with the response value */ 144 | } 145 | 146 | 147 | /*-----------------------------------------------------------------------*/ 148 | /* Initialize Disk Drive */ 149 | /*-----------------------------------------------------------------------*/ 150 | 151 | DSTATUS disk_initialize (void) 152 | { 153 | BYTE n, cmd, ty, ocr[4]; 154 | UINT tmr; 155 | 156 | #if PF_USE_WRITE 157 | if (CardType && SELECTING) 158 | disk_writep(0, 0); /* Finalize write process if it is in progress */ 159 | #endif 160 | 161 | init_spi(); /* Initialize ports to control MMC */ 162 | DESELECT(); 163 | FCLK_SLOW(); 164 | for (n = 10; n; n--) 165 | rcv_spi(); /* 80 dummy clocks with CS=H */ 166 | 167 | ty = 0; 168 | if (send_cmd(CMD0, 0) == 1) 169 | { /* GO_IDLE_STATE */ 170 | if (send_cmd(CMD8, 0x1AA) == 1) 171 | { /* SDv2 */ 172 | for (n = 0; n < 4; n++) 173 | ocr[n] = rcv_spi(); /* Get trailing return value of R7 resp */ 174 | 175 | if (ocr[2] == 0x01 && ocr[3] == 0xAA) 176 | { /* The card can work at vdd range of 2.7-3.6V */ 177 | for (tmr = 10000; tmr && send_cmd(ACMD41, 1UL << 30); tmr--) 178 | sleep_us(100); /* Wait for leaving idle state (ACMD41 with HCS bit) */ 179 | 180 | if (tmr && send_cmd(CMD58, 0) == 0) 181 | { /* Check CCS bit in the OCR */ 182 | for (n = 0; n < 4; n++) 183 | ocr[n] = rcv_spi(); 184 | 185 | ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 (HC or SC) */ 186 | } 187 | } 188 | } else { /* SDv1 or MMCv3 */ 189 | if (send_cmd(ACMD41, 0) <= 1) 190 | { 191 | ty = CT_SD1; 192 | cmd = ACMD41; /* SDv1 */ 193 | } else 194 | { 195 | ty = CT_MMC; 196 | cmd = CMD1; /* MMCv3 */ 197 | } 198 | 199 | for (tmr = 10000; tmr && send_cmd(cmd, 0); tmr--) 200 | sleep_us(100); /* Wait for leaving idle state */ 201 | 202 | if (!tmr || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */ 203 | ty = 0; 204 | } 205 | } 206 | 207 | CardType = ty; 208 | DESELECT(); 209 | rcv_spi(); 210 | 211 | if (ty) 212 | { /* OK */ 213 | FCLK_FAST(); /* Set fast clock */ 214 | return 0; 215 | } 216 | else 217 | { 218 | return STA_NOINIT; 219 | } 220 | } 221 | 222 | 223 | 224 | /*-----------------------------------------------------------------------*/ 225 | /* Read Partial Sector */ 226 | /*-----------------------------------------------------------------------*/ 227 | 228 | DRESULT disk_readp(BYTE *buff, /* Pointer to the read buffer (NULL:Forward to the stream) */ 229 | DWORD sector, /* Sector number (LBA) */ 230 | UINT offset, /* Byte offset to read from (0..511) */ 231 | UINT count /* Number of bytes to read (ofs + cnt mus be <= 512) */ 232 | ) 233 | { 234 | DRESULT res; 235 | BYTE rc; 236 | UINT bc; 237 | 238 | if (!(CardType & CT_BLOCK)) 239 | sector *= 512; /* Convert to byte address if needed */ 240 | 241 | res = RES_ERROR; 242 | if (send_cmd(CMD17, sector) == 0) { /* READ_SINGLE_BLOCK */ 243 | 244 | // bc = 40000; /* Time counter */ 245 | do { /* Wait for response */ 246 | rc = rcv_spi(); 247 | } while (rc == 0xFF); 248 | 249 | if (rc == 0xFE) { /* A data packet arrived */ 250 | 251 | bc = 512 + 2 - offset - count; /* Number of trailing bytes to skip */ 252 | 253 | /* Skip leading bytes */ 254 | while (offset--) 255 | rcv_spi(); 256 | 257 | /* Receive a part of the sector */ 258 | if (buff) { /* Store data to the memory */ 259 | do { 260 | *buff++ = rcv_spi(); 261 | } while (--count); 262 | } else { /* Forward data to the outgoing stream */ 263 | do { 264 | // FORWARD(rcv_spi()); 265 | } while (--count); 266 | } 267 | 268 | /* Skip trailing bytes and CRC */ 269 | do 270 | rcv_spi(); 271 | while (--bc); 272 | 273 | res = RES_OK; 274 | } 275 | } 276 | 277 | DESELECT(); 278 | rcv_spi(); 279 | 280 | return res; 281 | } 282 | 283 | 284 | 285 | #if PF_USE_WRITE 286 | DRESULT disk_writep(const BYTE *buff, /* Pointer to the bytes to be written (NULL:Initiate/Finalize sector write) */ 287 | DWORD sc /* Number of bytes to send, Sector number (LBA) or zero */ 288 | ) 289 | { 290 | DRESULT res; 291 | UINT bc; 292 | static UINT wc; /* Sector write counter */ 293 | 294 | res = RES_ERROR; 295 | 296 | if (buff) { /* Send data bytes */ 297 | bc = sc; 298 | while (bc && wc) { /* Send data bytes to the card */ 299 | xmit_spi(*buff++); 300 | wc--; 301 | bc--; 302 | } 303 | res = RES_OK; 304 | } else { 305 | if (sc) { /* Initiate sector write process */ 306 | if (!(CardType & CT_BLOCK)) 307 | sc *= 512; /* Convert to byte address if needed */ 308 | if (send_cmd(CMD24, sc) == 0) { /* WRITE_SINGLE_BLOCK */ 309 | xmit_spi(0xFF); 310 | xmit_spi(0xFE); /* Data block header */ 311 | wc = 512; /* Set byte counter */ 312 | res = RES_OK; 313 | } 314 | } else { /* Finalize sector write process */ 315 | bc = wc + 2; 316 | while (bc--) { 317 | xmit_spi(0); /* Fill left bytes and CRC with zeros */ 318 | } 319 | do { 320 | res = rcv_spi(); 321 | } while (res == 0xFF); 322 | if ((res & 0x1F) == 0x05) { /* Receive data resp and wait for end of write process in timeout of 500ms */ 323 | for (bc = 5000; rcv_spi() != 0xFF && bc; bc--) /* Wait for ready */ 324 | sleep_us(100); 325 | if (bc) 326 | res = RES_OK; 327 | } 328 | DESELECT(); 329 | rcv_spi(); 330 | } 331 | } 332 | 333 | return res; 334 | } 335 | #endif 336 | -------------------------------------------------------------------------------- /Firmware/pff/diskio.h: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------- 2 | / PFF - Low level disk interface modlue include file (C)ChaN, 2014 3 | /-----------------------------------------------------------------------*/ 4 | 5 | #ifndef _DISKIO_DEFINED 6 | #define _DISKIO_DEFINED 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | #include "pff.h" 13 | 14 | 15 | /* Status of Disk Functions */ 16 | typedef BYTE DSTATUS; 17 | 18 | 19 | /* Results of Disk Functions */ 20 | typedef enum { 21 | RES_OK = 0, /* 0: Function succeeded */ 22 | RES_ERROR, /* 1: Disk error */ 23 | RES_NOTRDY, /* 2: Not ready */ 24 | RES_PARERR /* 3: Invalid parameter */ 25 | } DRESULT; 26 | 27 | 28 | /*---------------------------------------*/ 29 | /* Prototypes for disk control functions */ 30 | 31 | DSTATUS disk_initialize (void); 32 | DRESULT disk_readp (BYTE* buff, DWORD sector, UINT offser, UINT count); 33 | DRESULT disk_writep (const BYTE* buff, DWORD sc); 34 | 35 | #define STA_NOINIT 0x01 /* Drive not initialized */ 36 | #define STA_NODISK 0x02 /* No medium in the drive */ 37 | 38 | 39 | /*------------------------*/ 40 | /* Implementation defines */ 41 | 42 | #ifdef PF_USE_SPI0 43 | #define PF_SPI spi0 44 | #elif PF_USE_SPI1 45 | #define PF_SPI spi1 46 | #else 47 | #error "SPI port not defined" 48 | #endif 49 | 50 | /* Definitions for MMC/SDC command */ 51 | #define CMD0 (0x40 + 0) /* GO_IDLE_STATE */ 52 | #define CMD1 (0x40 + 1) /* SEND_OP_COND (MMC) */ 53 | #define ACMD41 (0xC0 + 41) /* SEND_OP_COND (SDC) */ 54 | #define CMD8 (0x40 + 8) /* SEND_IF_COND */ 55 | #define CMD16 (0x40 + 16) /* SET_BLOCKLEN */ 56 | #define CMD17 (0x40 + 17) /* READ_SINGLE_BLOCK */ 57 | #define CMD24 (0x40 + 24) /* WRITE_BLOCK */ 58 | #define CMD55 (0x40 + 55) /* APP_CMD */ 59 | #define CMD58 (0x40 + 58) /* READ_OCR */ 60 | 61 | /* Card type flags (CardType) */ 62 | #define CT_MMC 0x01 /* MMC ver 3 */ 63 | #define CT_SD1 0x02 /* SD ver 1 */ 64 | #define CT_SD2 0x04 /* SD ver 2 */ 65 | #define CT_BLOCK 0x08 /* Block addressing */ 66 | 67 | 68 | #define CLK_SLOW 100000 69 | 70 | #ifdef __cplusplus 71 | } 72 | #endif 73 | 74 | #endif /* _DISKIO_DEFINED */ 75 | -------------------------------------------------------------------------------- /Firmware/pff/pff.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------/ 2 | / Petit FatFs - FAT file system module include file R0.03a 3 | /----------------------------------------------------------------------------/ 4 | / Petit FatFs module is an open source software to implement FAT file system to 5 | / small embedded systems. This is a free software and is opened for education, 6 | / research and commercial developments under license policy of following trems. 7 | / 8 | / Copyright (C) 2019, ChaN, all right reserved. 9 | / 10 | / * The Petit FatFs module is a free software and there is NO WARRANTY. 11 | / * No restriction on use. You can use, modify and redistribute it for 12 | / personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY. 13 | / * Redistributions of source code must retain the above copyright notice. 14 | / 15 | /----------------------------------------------------------------------------*/ 16 | 17 | #ifndef PF_DEFINED 18 | #define PF_DEFINED 8088 /* Revision ID */ 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | #include "pffconf.h" 25 | 26 | #if PF_DEFINED != PFCONF_DEF 27 | #error Wrong configuration file (pffconf.h). 28 | #endif 29 | 30 | 31 | /* Integer types used for FatFs API */ 32 | 33 | #if defined(_WIN32) /* Main development platform */ 34 | #include 35 | #elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */ 36 | #include 37 | typedef unsigned int UINT; /* int must be 16-bit or 32-bit */ 38 | typedef unsigned char BYTE; /* char must be 8-bit */ 39 | typedef uint16_t WORD; /* 16-bit unsigned integer */ 40 | typedef uint16_t WCHAR; /* 16-bit unsigned integer */ 41 | typedef uint32_t DWORD; /* 32-bit unsigned integer */ 42 | #else /* Earlier than C99 */ 43 | typedef unsigned int UINT; /* int must be 16-bit or 32-bit */ 44 | typedef unsigned char BYTE; /* char must be 8-bit */ 45 | typedef unsigned short WORD; /* 16-bit unsigned integer */ 46 | typedef unsigned short WCHAR; /* 16-bit unsigned integer */ 47 | typedef unsigned long DWORD; /* 32-bit unsigned integer */ 48 | #endif 49 | #define PF_INTDEF 1 50 | 51 | 52 | #if PF_FS_FAT32 53 | #define CLUST DWORD 54 | #else 55 | #define CLUST WORD 56 | #endif 57 | 58 | 59 | /* File system object structure */ 60 | 61 | typedef struct { 62 | BYTE fs_type; /* FAT sub type */ 63 | BYTE flag; /* File status flags */ 64 | BYTE csize; /* Number of sectors per cluster */ 65 | BYTE pad1; 66 | WORD n_rootdir; /* Number of root directory entries (0 on FAT32) */ 67 | CLUST n_fatent; /* Number of FAT entries (= number of clusters + 2) */ 68 | DWORD fatbase; /* FAT start sector */ 69 | DWORD dirbase; /* Root directory start sector (Cluster# on FAT32) */ 70 | DWORD database; /* Data start sector */ 71 | DWORD fptr; /* File R/W pointer */ 72 | DWORD fsize; /* File size */ 73 | CLUST org_clust; /* File start cluster */ 74 | CLUST curr_clust; /* File current cluster */ 75 | DWORD dsect; /* File current data sector */ 76 | } FATFS; 77 | 78 | 79 | 80 | /* Directory object structure */ 81 | 82 | typedef struct { 83 | WORD index; /* Current read/write index number */ 84 | BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */ 85 | CLUST sclust; /* Table start cluster (0:Static table) */ 86 | CLUST clust; /* Current cluster */ 87 | DWORD sect; /* Current sector */ 88 | } DIR; 89 | 90 | 91 | 92 | /* File status structure */ 93 | 94 | typedef struct { 95 | DWORD fsize; /* File size */ 96 | WORD fdate; /* Last modified date */ 97 | WORD ftime; /* Last modified time */ 98 | BYTE fattrib; /* Attribute */ 99 | char fname[13]; /* File name */ 100 | } FILINFO; 101 | 102 | 103 | 104 | /* File function return code (FRESULT) */ 105 | 106 | typedef enum { 107 | FR_OK = 0, /* 0 */ 108 | FR_DISK_ERR, /* 1 */ 109 | FR_NOT_READY, /* 2 */ 110 | FR_NO_FILE, /* 3 */ 111 | FR_NOT_OPENED, /* 4 */ 112 | FR_NOT_ENABLED, /* 5 */ 113 | FR_NO_FILESYSTEM /* 6 */ 114 | } FRESULT; 115 | 116 | 117 | 118 | /*--------------------------------------------------------------*/ 119 | /* Petit FatFs module application interface */ 120 | 121 | FRESULT pf_mount (FATFS* fs); /* Mount/Unmount a logical drive */ 122 | FRESULT pf_open (const char* path); /* Open a file */ 123 | FRESULT pf_read (void* buff, UINT btr, UINT* br); /* Read data from the open file */ 124 | FRESULT pf_write (const void* buff, UINT btw, UINT* bw); /* Write data to the open file */ 125 | FRESULT pf_lseek (DWORD ofs); /* Move file pointer of the open file */ 126 | FRESULT pf_opendir (DIR* dj, const char* path); /* Open a directory */ 127 | FRESULT pf_readdir (DIR* dj, FILINFO* fno); /* Read a directory item from the open directory */ 128 | 129 | 130 | 131 | /*--------------------------------------------------------------*/ 132 | /* Flags and offset address */ 133 | 134 | 135 | /* File status flag (FATFS.flag) */ 136 | #define FA_OPENED 0x01 137 | #define FA_WPRT 0x02 138 | #define FA__WIP 0x40 139 | 140 | 141 | /* FAT sub type (FATFS.fs_type) */ 142 | #define FS_FAT12 1 143 | #define FS_FAT16 2 144 | #define FS_FAT32 3 145 | 146 | 147 | /* File attribute bits for directory entry */ 148 | 149 | #define AM_RDO 0x01 /* Read only */ 150 | #define AM_HID 0x02 /* Hidden */ 151 | #define AM_SYS 0x04 /* System */ 152 | #define AM_VOL 0x08 /* Volume label */ 153 | #define AM_LFN 0x0F /* LFN entry */ 154 | #define AM_DIR 0x10 /* Directory */ 155 | #define AM_ARC 0x20 /* Archive */ 156 | #define AM_MASK 0x3F /* Mask of defined bits */ 157 | 158 | 159 | #ifdef __cplusplus 160 | } 161 | #endif 162 | 163 | #endif /* _PFATFS */ 164 | -------------------------------------------------------------------------------- /Firmware/pff/pffconf.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------/ 2 | / Petit FatFs - Configuration file 3 | /---------------------------------------------------------------------------*/ 4 | 5 | #ifndef PFCONF_DEF 6 | #define PFCONF_DEF 8088 /* Revision ID */ 7 | 8 | /*---------------------------------------------------------------------------/ 9 | / Function Configurations (0:Disable, 1:Enable) 10 | /---------------------------------------------------------------------------*/ 11 | 12 | #define PF_USE_READ 1 /* pf_read() function */ 13 | #define PF_USE_DIR 1 /* pf_opendir() and pf_readdir() function */ 14 | #define PF_USE_LSEEK 1 /* pf_lseek() function */ 15 | #define PF_USE_WRITE 1 /* pf_write() function */ 16 | 17 | #define PF_FS_FAT12 0 /* FAT12 */ 18 | #define PF_FS_FAT16 0 /* FAT16 */ 19 | #define PF_FS_FAT32 1 /* FAT32 */ 20 | 21 | 22 | /*---------------------------------------------------------------------------/ 23 | / Locale and Namespace Configurations 24 | /---------------------------------------------------------------------------*/ 25 | 26 | #define PF_USE_LCC 1 /* Allow lower case ASCII and non-ASCII chars */ 27 | 28 | #define PF_CODE_PAGE 850 29 | /* The PF_CODE_PAGE specifies the code page to be used on the target system. 30 | / SBCS code pages with PF_USE_LCC == 1 requiers a 128 byte of case conversion 31 | / table. It might occupy RAM on some platforms, e.g. avr-gcc. 32 | / When PF_USE_LCC == 0, PF_CODE_PAGE has no effect. 33 | / 34 | / 437 - U.S. 35 | / 720 - Arabic 36 | / 737 - Greek 37 | / 771 - KBL 38 | / 775 - Baltic 39 | / 850 - Latin 1 40 | / 852 - Latin 2 41 | / 855 - Cyrillic 42 | / 857 - Turkish 43 | / 860 - Portuguese 44 | / 861 - Icelandic 45 | / 862 - Hebrew 46 | / 863 - Canadian French 47 | / 864 - Arabic 48 | / 865 - Nordic 49 | / 866 - Russian 50 | / 869 - Greek 2 51 | / 932 - Japanese (DBCS) 52 | / 936 - Simplified Chinese (DBCS) 53 | / 949 - Korean (DBCS) 54 | / 950 - Traditional Chinese (DBCS) 55 | */ 56 | 57 | /*---------------------------------------------------------------------------/ 58 | / Pico implementation settings 59 | /---------------------------------------------------------------------------*/ 60 | 61 | //Can be SPI0 or SPI1 62 | #define PF_USE_SPI0 63 | //PIN definitions, change per your needs 64 | #define PF_SPI_MISO 16 65 | #define PF_SPI_CS 17 66 | #define PF_SPI_SCK 18 67 | #define PF_SPI_MOSI 19 68 | //Fast clock selection, this depends on the target card 69 | #define CLK_FAST 20000000 70 | //Select if we need a weak pull up in MISO or the card adapter already contains one 71 | #define PF_MISO_PULLUP 72 | 73 | #endif /* PF_CONF */ 74 | -------------------------------------------------------------------------------- /Firmware/pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | # GIT_SUBMODULES_RECURSE was added in 3.17 33 | if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") 34 | FetchContent_Declare( 35 | pico_sdk 36 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 37 | GIT_TAG master 38 | GIT_SUBMODULES_RECURSE FALSE 39 | ) 40 | else () 41 | FetchContent_Declare( 42 | pico_sdk 43 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 44 | GIT_TAG master 45 | ) 46 | endif () 47 | 48 | if (NOT pico_sdk) 49 | message("Downloading Raspberry Pi Pico SDK") 50 | FetchContent_Populate(pico_sdk) 51 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 52 | endif () 53 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 54 | else () 55 | message(FATAL_ERROR 56 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 57 | ) 58 | endif () 59 | endif () 60 | 61 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 62 | if (NOT EXISTS ${PICO_SDK_PATH}) 63 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 64 | endif () 65 | 66 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 67 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 68 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 69 | endif () 70 | 71 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 72 | 73 | include(${PICO_SDK_INIT_CMAKE_FILE}) 74 | -------------------------------------------------------------------------------- /Firmware/ssd1306/font.h: -------------------------------------------------------------------------------- 1 | #ifndef _inc_font 2 | #define _inc_font 3 | 4 | /* 5 | * Format 6 | * , , , 7 | * , , 8 | * 9 | */ 10 | const uint8_t font_8x5[] = 11 | { 12 | 8, 5, 1, 32, 126, 13 | 0x00, 0x00, 0x00, 0x00, 0x00, 14 | 0x00, 0x00, 0x5F, 0x00, 0x00, 15 | 0x00, 0x07, 0x00, 0x07, 0x00, 16 | 0x14, 0x7F, 0x14, 0x7F, 0x14, 17 | 0x24, 0x2A, 0x7F, 0x2A, 0x12, 18 | 0x23, 0x13, 0x08, 0x64, 0x62, 19 | 0x36, 0x49, 0x56, 0x20, 0x50, 20 | 0x00, 0x08, 0x07, 0x03, 0x00, 21 | 0x00, 0x1C, 0x22, 0x41, 0x00, 22 | 0x00, 0x41, 0x22, 0x1C, 0x00, 23 | 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 24 | 0x08, 0x08, 0x3E, 0x08, 0x08, 25 | 0x00, 0x80, 0x70, 0x30, 0x00, 26 | 0x08, 0x08, 0x08, 0x08, 0x08, 27 | 0x00, 0x00, 0x60, 0x60, 0x00, 28 | 0x20, 0x10, 0x08, 0x04, 0x02, 29 | 0x3E, 0x51, 0x49, 0x45, 0x3E, 30 | 0x00, 0x42, 0x7F, 0x40, 0x00, 31 | 0x72, 0x49, 0x49, 0x49, 0x46, 32 | 0x21, 0x41, 0x49, 0x4D, 0x33, 33 | 0x18, 0x14, 0x12, 0x7F, 0x10, 34 | 0x27, 0x45, 0x45, 0x45, 0x39, 35 | 0x3C, 0x4A, 0x49, 0x49, 0x31, 36 | 0x41, 0x21, 0x11, 0x09, 0x07, 37 | 0x36, 0x49, 0x49, 0x49, 0x36, 38 | 0x46, 0x49, 0x49, 0x29, 0x1E, 39 | 0x00, 0x00, 0x14, 0x00, 0x00, 40 | 0x00, 0x40, 0x34, 0x00, 0x00, 41 | 0x00, 0x08, 0x14, 0x22, 0x41, 42 | 0x14, 0x14, 0x14, 0x14, 0x14, 43 | 0x00, 0x41, 0x22, 0x14, 0x08, 44 | 0x02, 0x01, 0x59, 0x09, 0x06, 45 | 0x3E, 0x41, 0x5D, 0x59, 0x4E, 46 | 0x7C, 0x12, 0x11, 0x12, 0x7C, 47 | 0x7F, 0x49, 0x49, 0x49, 0x36, 48 | 0x3E, 0x41, 0x41, 0x41, 0x22, 49 | 0x7F, 0x41, 0x41, 0x41, 0x3E, 50 | 0x7F, 0x49, 0x49, 0x49, 0x41, 51 | 0x7F, 0x09, 0x09, 0x09, 0x01, 52 | 0x3E, 0x41, 0x41, 0x51, 0x73, 53 | 0x7F, 0x08, 0x08, 0x08, 0x7F, 54 | 0x00, 0x41, 0x7F, 0x41, 0x00, 55 | 0x20, 0x40, 0x41, 0x3F, 0x01, 56 | 0x7F, 0x08, 0x14, 0x22, 0x41, 57 | 0x7F, 0x40, 0x40, 0x40, 0x40, 58 | 0x7F, 0x02, 0x1C, 0x02, 0x7F, 59 | 0x7F, 0x04, 0x08, 0x10, 0x7F, 60 | 0x3E, 0x41, 0x41, 0x41, 0x3E, 61 | 0x7F, 0x09, 0x09, 0x09, 0x06, 62 | 0x3E, 0x41, 0x51, 0x21, 0x5E, 63 | 0x7F, 0x09, 0x19, 0x29, 0x46, 64 | 0x26, 0x49, 0x49, 0x49, 0x32, 65 | 0x03, 0x01, 0x7F, 0x01, 0x03, 66 | 0x3F, 0x40, 0x40, 0x40, 0x3F, 67 | 0x1F, 0x20, 0x40, 0x20, 0x1F, 68 | 0x3F, 0x40, 0x38, 0x40, 0x3F, 69 | 0x63, 0x14, 0x08, 0x14, 0x63, 70 | 0x03, 0x04, 0x78, 0x04, 0x03, 71 | 0x61, 0x59, 0x49, 0x4D, 0x43, 72 | 0x00, 0x7F, 0x41, 0x41, 0x41, 73 | 0x02, 0x04, 0x08, 0x10, 0x20, 74 | 0x00, 0x41, 0x41, 0x41, 0x7F, 75 | 0x04, 0x02, 0x01, 0x02, 0x04, 76 | 0x40, 0x40, 0x40, 0x40, 0x40, 77 | 0x00, 0x03, 0x07, 0x08, 0x00, 78 | 0x20, 0x54, 0x54, 0x78, 0x40, 79 | 0x7F, 0x28, 0x44, 0x44, 0x38, 80 | 0x38, 0x44, 0x44, 0x44, 0x28, 81 | 0x38, 0x44, 0x44, 0x28, 0x7F, 82 | 0x38, 0x54, 0x54, 0x54, 0x18, 83 | 0x00, 0x08, 0x7E, 0x09, 0x02, 84 | 0x18, 0xA4, 0xA4, 0x9C, 0x78, 85 | 0x7F, 0x08, 0x04, 0x04, 0x78, 86 | 0x00, 0x44, 0x7D, 0x40, 0x00, 87 | 0x20, 0x40, 0x40, 0x3D, 0x00, 88 | 0x7F, 0x10, 0x28, 0x44, 0x00, 89 | 0x00, 0x41, 0x7F, 0x40, 0x00, 90 | 0x7C, 0x04, 0x78, 0x04, 0x78, 91 | 0x7C, 0x08, 0x04, 0x04, 0x78, 92 | 0x38, 0x44, 0x44, 0x44, 0x38, 93 | 0xFC, 0x18, 0x24, 0x24, 0x18, 94 | 0x18, 0x24, 0x24, 0x18, 0xFC, 95 | 0x7C, 0x08, 0x04, 0x04, 0x08, 96 | 0x48, 0x54, 0x54, 0x54, 0x24, 97 | 0x04, 0x04, 0x3F, 0x44, 0x24, 98 | 0x3C, 0x40, 0x40, 0x20, 0x7C, 99 | 0x1C, 0x20, 0x40, 0x20, 0x1C, 100 | 0x3C, 0x40, 0x30, 0x40, 0x3C, 101 | 0x44, 0x28, 0x10, 0x28, 0x44, 102 | 0x4C, 0x90, 0x90, 0x90, 0x7C, 103 | 0x44, 0x64, 0x54, 0x4C, 0x44, 104 | 0x00, 0x08, 0x36, 0x41, 0x00, 105 | 0x00, 0x00, 0x77, 0x00, 0x00, 106 | 0x00, 0x41, 0x36, 0x08, 0x00, 107 | 0x02, 0x01, 0x02, 0x04, 0x02, 108 | }; 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /Firmware/ssd1306/ssd1306.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 David Schramm 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | /* 26 | 27 | MIT License 28 | 29 | Copyright (c) 2023 Agustín Giménez Bernad 30 | 31 | Permission is hereby granted, free of charge, to any person obtaining a copy 32 | of this software and associated documentation files (the "Software"), to deal 33 | in the Software without restriction, including without limitation the rights 34 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 35 | copies of the Software, and to permit persons to whom the Software is 36 | furnished to do so, subject to the following conditions: 37 | 38 | The above copyright notice and this permission notice shall be included in all 39 | copies or substantial portions of the Software. 40 | 41 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 42 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 43 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 44 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 45 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 46 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 47 | SOFTWARE. 48 | 49 | */ 50 | 51 | /** 52 | * @file ssd1306.h 53 | * 54 | * simple driver for ssd1306 displays 55 | */ 56 | 57 | #ifndef _inc_ssd1306 58 | #define _inc_ssd1306 59 | #include 60 | #include 61 | 62 | /** 63 | * @brief defines commands used in ssd1306 64 | */ 65 | typedef enum { 66 | SET_CONTRAST = 0x81, 67 | SET_ENTIRE_ON = 0xA4, 68 | SET_NORM_INV = 0xA6, 69 | SET_DISP = 0xAE, 70 | SET_MEM_ADDR = 0x20, 71 | SET_COL_ADDR = 0x21, 72 | SET_PAGE_ADDR = 0x22, 73 | SET_DISP_START_LINE = 0x40, 74 | SET_SEG_REMAP = 0xA0, 75 | SET_MUX_RATIO = 0xA8, 76 | SET_COM_OUT_DIR = 0xC0, 77 | SET_DISP_OFFSET = 0xD3, 78 | SET_COM_PIN_CFG = 0xDA, 79 | SET_DISP_CLK_DIV = 0xD5, 80 | SET_PRECHARGE = 0xD9, 81 | SET_VCOM_DESEL = 0xDB, 82 | SET_CHARGE_PUMP = 0x8D 83 | } ssd1306_command_t; 84 | 85 | /** 86 | * @brief holds the configuration 87 | */ 88 | typedef struct { 89 | uint8_t width; /**< width of display */ 90 | uint8_t height; /**< height of display */ 91 | uint8_t pages; /**< stores pages of display (calculated on initialization*/ 92 | uint8_t address; /**< i2c address of display*/ 93 | i2c_inst_t *i2c_i; /**< i2c connection instance */ 94 | bool external_vcc; /**< whether display uses external vcc */ 95 | uint8_t *buffer; /**< display buffer */ 96 | size_t bufsize; /**< buffer size */ 97 | } ssd1306_t; 98 | 99 | /** 100 | * @brief initialize display 101 | * 102 | * @param[in] p : pointer to instance of ssd1306_t 103 | * @param[in] width : width of display 104 | * @param[in] height : heigth of display 105 | * @param[in] address : i2c address of display 106 | * @param[in] i2c_instance : instance of i2c connection 107 | * 108 | * @return bool. 109 | * @retval true for Success 110 | * @retval false if initialization failed 111 | */ 112 | bool ssd1306_init(ssd1306_t *p, uint16_t width, uint16_t height, uint8_t address, i2c_inst_t *i2c_instance); 113 | 114 | /** 115 | * @brief deinitialize display 116 | * 117 | * @param[in] p : instance of display 118 | * 119 | */ 120 | void ssd1306_deinit(ssd1306_t *p); 121 | 122 | /** 123 | * @brief turn off display 124 | * 125 | * @param[in] p : instance of display 126 | * 127 | */ 128 | void ssd1306_poweroff(ssd1306_t *p); 129 | 130 | /** 131 | @brief turn on display 132 | 133 | @param[in] p : instance of display 134 | 135 | */ 136 | void ssd1306_poweron(ssd1306_t *p); 137 | 138 | /** 139 | @brief set contrast of display 140 | 141 | @param[in] p : instance of display 142 | @param[in] val : contrast 143 | 144 | */ 145 | void ssd1306_contrast(ssd1306_t *p, uint8_t val); 146 | 147 | /** 148 | @brief set invert display 149 | 150 | @param[in] p : instance of display 151 | @param[in] inv : inv==0: disable inverting, inv!=0: invert 152 | 153 | */ 154 | void ssd1306_invert(ssd1306_t *p, uint8_t inv); 155 | 156 | /** 157 | @brief display buffer, should be called on change 158 | 159 | @param[in] p : instance of display 160 | 161 | */ 162 | void ssd1306_show(ssd1306_t *p); 163 | 164 | /** 165 | @brief clear display buffer 166 | 167 | @param[in] p : instance of display 168 | 169 | */ 170 | void ssd1306_clear(ssd1306_t *p); 171 | 172 | /** 173 | @brief draw pixel on buffer 174 | 175 | @param[in] p : instance of display 176 | @param[in] x : x position 177 | @param[in] y : y position 178 | */ 179 | void ssd1306_draw_pixel(ssd1306_t *p, uint32_t x, uint32_t y); 180 | 181 | /** 182 | @brief draw pixel on buffer 183 | 184 | @param[in] p : instance of display 185 | @param[in] x1 : x position of starting point 186 | @param[in] y1 : y position of starting point 187 | @param[in] x2 : x position of end point 188 | @param[in] y2 : y position of end point 189 | */ 190 | void ssd1306_draw_line(ssd1306_t *p, int32_t x1, int32_t y1, int32_t x2, int32_t y2); 191 | 192 | /** 193 | @brief draw filled square at given position with given size 194 | 195 | @param[in] p : instance of display 196 | @param[in] x : x position of starting point 197 | @param[in] y : y position of starting point 198 | @param[in] width : width of square 199 | @param[in] height : height of square 200 | */ 201 | void ssd1306_draw_square(ssd1306_t *p, uint32_t x, uint32_t y, uint32_t width, uint32_t height); 202 | 203 | /** 204 | @brief draw empty square at given position with given size 205 | 206 | @param[in] p : instance of display 207 | @param[in] x : x position of starting point 208 | @param[in] y : y position of starting point 209 | @param[in] width : width of square 210 | @param[in] height : height of square 211 | */ 212 | void ssd13606_draw_empty_square(ssd1306_t *p, uint32_t x, uint32_t y, uint32_t width, uint32_t height); 213 | 214 | /** 215 | @brief draw monochrome bitmap with offset 216 | 217 | @param[in] p : instance of display 218 | @param[in] data : image data (whole file) 219 | @param[in] size : size of image data in bytes 220 | @param[in] x_offset : offset of horizontal coordinate 221 | @param[in] y_offset : offset of vertical coordinate 222 | */ 223 | void ssd1306_bmp_show_image_with_offset(ssd1306_t *p, const uint8_t *data, const long size, uint32_t x_offset, uint32_t y_offset); 224 | 225 | /** 226 | @brief draw monochrome bitmap 227 | 228 | @param[in] p : instance of display 229 | @param[in] data : image data (whole file) 230 | @param[in] size : size of image data in bytes 231 | */ 232 | void ssd1306_bmp_show_image(ssd1306_t *p, const uint8_t *data, const long size); 233 | 234 | /** 235 | @brief draw char with given font 236 | 237 | @param[in] p : instance of display 238 | @param[in] x : x starting position of char 239 | @param[in] y : y starting position of char 240 | @param[in] scale : scale font to n times of original size (default should be 1) 241 | @param[in] font : pointer to font 242 | @param[in] c : character to draw 243 | */ 244 | void ssd1306_draw_char_with_font(ssd1306_t *p, uint32_t x, uint32_t y, uint32_t scale, const uint8_t *font, char c); 245 | 246 | /** 247 | @brief draw char with builtin font 248 | 249 | @param[in] p : instance of display 250 | @param[in] x : x starting position of char 251 | @param[in] y : y starting position of char 252 | @param[in] scale : scale font to n times of original size (default should be 1) 253 | @param[in] c : character to draw 254 | */ 255 | void ssd1306_draw_char(ssd1306_t *p, uint32_t x, uint32_t y, uint32_t scale, char c); 256 | 257 | /** 258 | @brief draw string with given font 259 | 260 | @param[in] p : instance of display 261 | @param[in] x : x starting position of text 262 | @param[in] y : y starting position of text 263 | @param[in] scale : scale font to n times of original size (default should be 1) 264 | @param[in] font : pointer to font 265 | @param[in] s : text to draw 266 | */ 267 | void ssd1306_draw_string_with_font(ssd1306_t *p, uint32_t x, uint32_t y, uint32_t scale, const uint8_t *font, const char *s ); 268 | 269 | /** 270 | @brief draw string with builtin font 271 | 272 | @param[in] p : instance of display 273 | @param[in] x : x starting position of text 274 | @param[in] y : y starting position of text 275 | @param[in] scale : scale font to n times of original size (default should be 1) 276 | @param[in] s : text to draw 277 | */ 278 | void ssd1306_draw_string(ssd1306_t *p, uint32_t x, uint32_t y, uint32_t scale, const char *s); 279 | 280 | #endif 281 | -------------------------------------------------------------------------------- /Hardware/BOM.txt: -------------------------------------------------------------------------------- 1 | --Main unit-- 2 | 3 | C1 to C6: 100nf, 0603 4 | R1: 4k7, 0603 5 | IC1, IC2: SN74LVC1T45DBVR 6 | IC3: TXU0304PWR 7 | U1: 7805 TO220 or DC/DC buck module 8 | U2: Raspberry pico 9 | J1: Card edge connector, 2x8p, 2.54mm, curved pin. 10 | J2: Male IDC, 2x7p, 2.54mm (check assembly instructions for more details) 11 | 12 | 13 | --Cartridge-- 14 | 15 | R1 to R3: 1k, 0603 16 | SW1 to SW3: SMD microswitch push button 17 | SCR1: 0'49" SD1306 module 18 | D1 to D3: 3mm LED (red, green and blue) 19 | SD1: SD card socket module 20 | 21 | --Buy links-- 22 | 23 | SN74LVC1T45: https://es.aliexpress.com/item/1005004345377244.html 24 | TXU0304PWR: https://es.aliexpress.com/item/1005004929752779.html 25 | DC/DC buck converter: https://es.aliexpress.com/item/1005005343434991.html 26 | Card edge connector: https://es.aliexpress.com/item/1005001884522039.html 27 | IDC connector: https://es.aliexpress.com/item/1005001835803614.html 28 | Screen module: https://es.aliexpress.com/item/1005003874700775.html 29 | SD card module: https://es.aliexpress.com/item/32791255542.html -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/EdgeCon.pretty/Edge_connector_02x08.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "Edge_connector_02x08" (version 20211014) (generator pcbnew) 2 | (layer "F.Cu") 3 | (tedit 0) 4 | (attr through_hole) 5 | (fp_text reference "EC**" (at 0.25 0 unlocked) (layer "F.SilkS") 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | (tstamp d09fca4c-55e2-452c-818b-2a461bf643cc) 8 | ) 9 | (fp_text value "Edge_connector_02x08" (at -0.09 5.95 unlocked) (layer "F.Fab") 10 | (effects (font (size 1 1) (thickness 0.15))) 11 | (tstamp e5803e45-bd73-45c0-b324-74c3d0cd5ee0) 12 | ) 13 | (fp_text user "${REFERENCE}" (at 0.16 -0.05 180) (layer "F.Fab") 14 | (effects (font (size 1 1) (thickness 0.15))) 15 | (tstamp 12e3318b-d723-448e-80f4-0a2add1fb722) 16 | ) 17 | (fp_line (start 10.22 -0.15) (end 13.5 -0.15) (layer "F.SilkS") (width 0.12) (tstamp 021ed89a-ca5a-454a-8f0d-f9d80781599b)) 18 | (fp_line (start 10.22 -0.15) (end 10.22 -6.47) (layer "F.SilkS") (width 0.12) (tstamp 2ea2fe11-f110-4c15-9711-2061b7ff7476)) 19 | (fp_line (start 10 -6.47) (end 10.22 -6.47) (layer "F.SilkS") (width 0.12) (tstamp 3c79e170-ac0b-4e96-8929-fdb40c607bec)) 20 | (fp_line (start -13.4 9) (end 13.5 9) (layer "F.SilkS") (width 0.12) (tstamp 3cbb184a-f234-407b-9174-d026edde4a38)) 21 | (fp_line (start -10.22 -0.15) (end -10.22 -6.47) (layer "F.SilkS") (width 0.12) (tstamp 43daede3-09f4-4370-a4cd-1742a0f3e737)) 22 | (fp_line (start -10.22 -11.55) (end -10.22 -12.66) (layer "F.SilkS") (width 0.12) (tstamp 507ddcf1-9cbb-4b45-975b-709e12df4ebb)) 23 | (fp_line (start 13.5 9) (end 13.5 -0.15) (layer "F.SilkS") (width 0.12) (tstamp 6e72ccaa-c091-4330-a23e-92e3f7e9d19d)) 24 | (fp_line (start -13.4 9) (end -13.4 -0.15) (layer "F.SilkS") (width 0.12) (tstamp 6f5f0c33-b595-427a-8f2d-635a21b1d521)) 25 | (fp_line (start -10.22 -6.47) (end -10 -6.47) (layer "F.SilkS") (width 0.12) (tstamp abfde176-9928-4197-ac35-08e17e97277e)) 26 | (fp_line (start -13.4 -0.15) (end -10.22 -0.15) (layer "F.SilkS") (width 0.12) (tstamp fa046664-257d-4913-8c8f-978c16ab4985)) 27 | (fp_line (start -10.22 -12.66) (end -8.89 -12.66) (layer "F.SilkS") (width 0.12) (tstamp fed962e6-4c11-41ad-933f-6a0484a22c92)) 28 | (fp_line (start 13.66 9.2) (end 13.66 -13.35) (layer "F.CrtYd") (width 0.05) (tstamp 0023162f-a07e-408b-b318-1e8e9f305001)) 29 | (fp_line (start -13.59 -13.35) (end -13.59 9.2) (layer "F.CrtYd") (width 0.05) (tstamp 02565f97-cd17-42be-94e0-c07f1614224c)) 30 | (fp_line (start 13.66 -13.35) (end -13.59 -13.35) (layer "F.CrtYd") (width 0.05) (tstamp 69a7514c-f517-4b46-bf93-1effc96b0e95)) 31 | (fp_line (start -13.59 9.2) (end 13.66 9.2) (layer "F.CrtYd") (width 0.05) (tstamp d94f6a76-1cd8-44c8-b9e0-1b2743a67b84)) 32 | (fp_line (start -6.05 -11.55) (end -6.65 -11.55) (layer "F.Fab") (width 0.1) (tstamp 43d1b320-be08-4c34-893b-273664b3ea68)) 33 | (fp_line (start -8.59 -11.55) (end -9.19 -11.55) (layer "F.Fab") (width 0.1) (tstamp 55366e14-cec9-493d-901d-448b04d2f286)) 34 | (fp_line (start 1.57 -11.55) (end 0.97 -11.55) (layer "F.Fab") (width 0.1) (tstamp 772b2560-c224-4933-9225-40be66422908)) 35 | (fp_line (start -3.51 -11.55) (end -4.11 -11.55) (layer "F.Fab") (width 0.1) (tstamp 89b31927-f663-4a3a-a530-c0fd8571c8d7)) 36 | (fp_line (start 9.19 -11.55) (end 8.59 -11.55) (layer "F.Fab") (width 0.1) (tstamp a7928873-604e-41b4-8f3c-a9332a26491c)) 37 | (fp_line (start 4.11 -11.55) (end 3.51 -11.55) (layer "F.Fab") (width 0.1) (tstamp c457d6bc-d372-4e5a-9060-512765531115)) 38 | (fp_line (start -0.97 -11.55) (end -1.57 -11.55) (layer "F.Fab") (width 0.1) (tstamp e23187f9-dcd6-499f-90d3-0eec00b87622)) 39 | (fp_line (start 6.65 -11.55) (end 6.05 -11.55) (layer "F.Fab") (width 0.1) (tstamp fe9e9f21-2e7d-4a1f-9cf8-dbb5f94d13c1)) 40 | (pad "1" thru_hole rect (at -8.89 -11.55 90) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp e33b88e6-21b7-46e6-ba61-2812267872a7)) 41 | (pad "2" thru_hole oval (at -8.89 -6.47 90) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 3525d7fb-9fbb-407a-b98f-dbe710a5769f)) 42 | (pad "3" thru_hole oval (at -6.35 -11.55 90) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp cdd161f0-22d1-4053-9a0b-ffab3a54d82f)) 43 | (pad "4" thru_hole oval (at -6.35 -6.47 90) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 5569ffb9-3194-4ed5-a115-e717546fbbd5)) 44 | (pad "5" thru_hole oval (at -3.81 -11.55 90) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 9462ae22-4e7f-462a-824e-86cf308ddca1)) 45 | (pad "6" thru_hole oval (at -3.81 -6.47 90) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 791865d8-d8e2-4bb4-a45d-5c1ab6b1ca50)) 46 | (pad "7" thru_hole oval (at -1.27 -11.55 90) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 877182c1-f7de-4075-b871-3852bba4d685)) 47 | (pad "8" thru_hole oval (at -1.27 -6.47 90) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 0c23fd3c-8e92-44f9-9905-f0d6b673c1e2)) 48 | (pad "9" thru_hole oval (at 1.27 -11.55 90) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 8fc2e36b-243b-47e2-890e-f3a8d0cb9deb)) 49 | (pad "10" thru_hole oval (at 1.27 -6.47 90) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp efca2809-2036-46b8-8545-a5bdd08b5301)) 50 | (pad "11" thru_hole oval (at 3.81 -11.55 90) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 098660ff-f93c-4ccb-8579-57628aa895a7)) 51 | (pad "12" thru_hole oval (at 3.81 -6.47 90) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp f25c7d87-b8db-41e0-abfc-bec8048ef2cc)) 52 | (pad "13" thru_hole oval (at 6.35 -11.55 90) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp fffd8529-ec61-4c2e-ae6d-c3e663947951)) 53 | (pad "14" thru_hole oval (at 6.35 -6.47 90) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 66096f4f-c798-4425-8537-e7adeb21bec3)) 54 | (pad "15" thru_hole oval (at 8.89 -11.55 90) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 452c8d75-aa5e-4c5d-b7f7-07aa48bbf245)) 55 | (pad "16" thru_hole oval (at 8.89 -6.47 90) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 966cd2ae-4255-4a92-af40-093e3a84f37c)) 56 | ) 57 | -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-05-29_203418.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-05-29_203418.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-05-30_125441.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-05-30_125441.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-05-30_130802.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-05-30_130802.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-07-29_010023.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-07-29_010023.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-07-29_150801.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-07-29_150801.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-07-30_122208.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-07-30_122208.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-07-31_143826.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-07-31_143826.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-07-31_222641.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-07-31_222641.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-08-03_011139.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-08-03_011139.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-08-03_012055.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-08-03_012055.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-08-05_002551.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-08-05_002551.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-08-11_081052.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-08-11_081052.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-08-12_144109.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-08-12_144109.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-09-19_195752.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-09-19_195752.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-09-20_210319.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-09-20_210319.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-09-22_121144.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-09-22_121144.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-09-22_130835.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-09-22_130835.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-09-23_051410.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-09-23_051410.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-09-27_094133.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-09-27_094133.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-10-02_184407.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-10-02_184407.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-10-08_101315.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-10-08_101315.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-10-08_143311.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-10-08_143311.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-10-08_152605.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-10-08_152605.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-10-08_154223.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-10-08_154223.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-10-08_183524.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-10-08_183524.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-11-01_024118.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/MicroPicoDrive-backups/MicroPicoDrive-2023-11-01_024118.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/MicroPicoDrive.kicad_prl: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "active_layer": 33, 4 | "active_layer_preset": "", 5 | "auto_track_width": true, 6 | "hidden_netclasses": [], 7 | "hidden_nets": [], 8 | "high_contrast_mode": 0, 9 | "net_color_mode": 1, 10 | "opacity": { 11 | "images": 0.6, 12 | "pads": 1.0, 13 | "tracks": 1.0, 14 | "vias": 1.0, 15 | "zones": 0.6 16 | }, 17 | "ratsnest_display_mode": 0, 18 | "selection_filter": { 19 | "dimensions": true, 20 | "footprints": true, 21 | "graphics": true, 22 | "keepouts": true, 23 | "lockedItems": true, 24 | "otherItems": true, 25 | "pads": true, 26 | "text": true, 27 | "tracks": true, 28 | "vias": true, 29 | "zones": true 30 | }, 31 | "visible_items": [ 32 | 0, 33 | 1, 34 | 2, 35 | 3, 36 | 4, 37 | 5, 38 | 8, 39 | 9, 40 | 10, 41 | 11, 42 | 12, 43 | 13, 44 | 14, 45 | 15, 46 | 16, 47 | 17, 48 | 18, 49 | 19, 50 | 20, 51 | 21, 52 | 22, 53 | 23, 54 | 24, 55 | 25, 56 | 26, 57 | 27, 58 | 28, 59 | 29, 60 | 30, 61 | 32, 62 | 33, 63 | 34, 64 | 35, 65 | 36 66 | ], 67 | "visible_layers": "ffc3302_ffffffff", 68 | "zone_display_mode": 0 69 | }, 70 | "meta": { 71 | "filename": "MicroPicoDrive.kicad_prl", 72 | "version": 3 73 | }, 74 | "project": { 75 | "files": [] 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/RPi_Pico.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.4 2 | #encoding utf-8 3 | # 4 | # AudioJack-CUI-SJ-3523-SMT 5 | # 6 | DEF AudioJack-CUI-SJ-3523-SMT J 0 20 Y Y 1 F N 7 | F0 "J" 0 350 50 H V C CNN 8 | F1 "AudioJack-CUI-SJ-3523-SMT" 0 250 50 H V C CNN 9 | F2 "RPi_Pico:CUI_SJ-3523-audio-jack" 100 -250 50 H I C CNN 10 | F3 "" 0 0 50 H I C CNN 11 | $FPLIST 12 | Jack* 13 | $ENDFPLIST 14 | DRAW 15 | S -200 -200 -250 -100 0 1 10 F 16 | S 100 150 -200 -200 0 1 10 f 17 | P 4 0 1 10 0 -100 25 -125 50 -100 100 -100 N 18 | P 5 0 1 10 -75 -100 -50 -125 -25 -100 -25 0 100 0 N 19 | P 5 0 1 10 100 100 -100 100 -100 -100 -125 -125 -150 -100 N 20 | X S 1 200 100 100 L 50 50 1 1 P 21 | X T 2 200 -100 100 L 50 50 1 1 P 22 | X R 3 200 0 100 L 50 50 1 1 P 23 | ENDDRAW 24 | ENDDEF 25 | # 26 | # NC7WZ16P6X 27 | # 28 | DEF NC7WZ16P6X U 0 40 Y Y 1 F N 29 | F0 "U" -200 250 50 H V C CNN 30 | F1 "NC7WZ16P6X" 0 -250 50 H V C CNN 31 | F2 "Package_TO_SOT_SMD:SOT-363_SC-70-6" 0 -350 50 H I C CNN 32 | F3 "" 0 0 50 H I C CNN 33 | DRAW 34 | S -250 200 250 -200 0 1 0 f 35 | P 2 0 1 0 50 -100 100 -100 N 36 | P 2 0 1 0 50 100 100 100 N 37 | P 6 0 1 0 -100 -100 -50 -100 -50 -50 50 -100 -50 -150 -50 -100 N 38 | P 7 0 1 0 -100 100 -50 100 -50 150 50 100 -50 50 -50 100 -100 100 N 39 | X A1 1 -350 100 100 R 50 50 1 1 I 40 | X GND 2 -350 0 100 R 50 50 1 1 W 41 | X A2 3 -350 -100 100 R 50 50 1 1 I 42 | X Y2 4 350 -100 100 L 50 50 1 1 O 43 | X VCC 5 350 0 100 L 50 50 1 1 W 44 | X Y1 6 350 100 100 L 50 50 1 1 O 45 | ENDDRAW 46 | ENDDEF 47 | # 48 | # Pico 49 | # 50 | DEF Pico U 0 40 Y Y 1 F N 51 | F0 "U" -550 1100 50 H V C CNN 52 | F1 "Pico" 0 750 50 H V C CNN 53 | F2 "RPi_Pico:RPi_Pico_SMD_TH" 0 0 50 V I C CNN 54 | F3 "" 0 0 50 H I C CNN 55 | DRAW 56 | T 0 0 850 50 0 0 0 "Raspberry Pi" Normal 0 C C 57 | S -600 1050 600 -1050 0 1 0 f 58 | X GPIO0 1 -700 950 100 R 50 50 1 1 B 59 | X GPIO7 10 -700 50 100 R 50 50 1 1 B 60 | X GPIO8 11 -700 -50 100 R 50 50 1 1 B 61 | X GPIO9 12 -700 -150 100 R 50 50 1 1 B 62 | X GND 13 -700 -250 100 R 50 50 1 1 W 63 | X GPIO10 14 -700 -350 100 R 50 50 1 1 B 64 | X GPIO11 15 -700 -450 100 R 50 50 1 1 B 65 | X GPIO12 16 -700 -550 100 R 50 50 1 1 B 66 | X GPIO13 17 -700 -650 100 R 50 50 1 1 B 67 | X GND 18 -700 -750 100 R 50 50 1 1 W 68 | X GPIO14 19 -700 -850 100 R 50 50 1 1 B 69 | X GPIO1 2 -700 850 100 R 50 50 1 1 B 70 | X GPIO15 20 -700 -950 100 R 50 50 1 1 B 71 | X GPIO16 21 700 -950 100 L 50 50 1 1 B 72 | X GPIO17 22 700 -850 100 L 50 50 1 1 B 73 | X GND 23 700 -750 100 L 50 50 1 1 W 74 | X GPIO18 24 700 -650 100 L 50 50 1 1 B 75 | X GPIO19 25 700 -550 100 L 50 50 1 1 B 76 | X GPIO20 26 700 -450 100 L 50 50 1 1 B 77 | X GPIO21 27 700 -350 100 L 50 50 1 1 B 78 | X GND 28 700 -250 100 L 50 50 1 1 W 79 | X GPIO22 29 700 -150 100 L 50 50 1 1 B 80 | X GND 3 -700 750 100 R 50 50 1 1 W 81 | X RUN 30 700 -50 100 L 50 50 1 1 I 82 | X GPIO26_ADC0 31 700 50 100 L 50 50 1 1 B 83 | X GPIO27_ADC1 32 700 150 100 L 50 50 1 1 B 84 | X AGND 33 700 250 100 L 50 50 1 1 W 85 | X GPIO28_ADC2 34 700 350 100 L 50 50 1 1 B 86 | X ADC_VREF 35 700 450 100 L 50 50 1 1 U 87 | X 3V3 36 700 550 100 L 50 50 1 1 U 88 | X 3V3_EN 37 700 650 100 L 50 50 1 1 I 89 | X GND 38 700 750 100 L 50 50 1 1 B 90 | X VSYS 39 700 850 100 L 50 50 1 1 U 91 | X GPIO2 4 -700 650 100 R 50 50 1 1 B 92 | X VBUS 40 700 950 100 L 50 50 1 1 U 93 | X SWCLK 41 -100 -1150 100 U 50 50 1 1 I 94 | X GND 42 0 -1150 100 U 50 50 1 1 W 95 | X SWDIO 43 100 -1150 100 U 50 50 1 1 B 96 | X GPIO3 5 -700 550 100 R 50 50 1 1 B 97 | X GPIO4 6 -700 450 100 R 50 50 1 1 B 98 | X GPIO5 7 -700 350 100 R 50 50 1 1 B 99 | X GND 8 -700 250 100 R 50 50 1 1 W 100 | X GPIO6 9 -700 150 100 R 50 50 1 1 B 101 | ENDDRAW 102 | ENDDEF 103 | 104 | # 105 | #End Library 106 | -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/RPi_Pico.pretty/CUI_SJ-3523-audio-jack.kicad_mod: -------------------------------------------------------------------------------- 1 | (module CUI_SJ-3523-audio-jack (layer F.Cu) (tedit 5F03199E) 2 | (descr "3.5 mm, Stereo, Right Angle, Surface Mount (SMT), Audio Jack Connector (https://www.cui.com/product/resource/sj-352x-smt-series.pdf)") 3 | (tags "3.5mm audio cui horizontal jack stereo") 4 | (attr smd) 5 | (fp_text reference J2 (at 0.1 9.7 -270) (layer F.SilkS) 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | ) 8 | (fp_text value AudioJack3 (at 0 10.35 -180) (layer F.Fab) 9 | (effects (font (size 1 1) (thickness 0.15))) 10 | ) 11 | (fp_line (start -3.1 -2.3) (end -5.1 -2.3) (layer F.SilkS) (width 0.12)) 12 | (fp_line (start -3.1 -4.9) (end -5.1 -4.9) (layer F.SilkS) (width 0.12)) 13 | (fp_line (start -3.1 4.2) (end -3.1 -2.3) (layer F.SilkS) (width 0.12)) 14 | (fp_line (start -3.1 8.6) (end -3.1 7.4) (layer F.SilkS) (width 0.12)) 15 | (fp_line (start 3.1 8.6) (end -3.1 8.6) (layer F.SilkS) (width 0.12)) 16 | (fp_line (start 3.1 -0.3) (end 3.1 8.6) (layer F.SilkS) (width 0.12)) 17 | (fp_line (start 3.1 -6.1) (end 3.1 -2.9) (layer F.SilkS) (width 0.12)) 18 | (fp_line (start 2.6 -6.1) (end 3.1 -6.1) (layer F.SilkS) (width 0.12)) 19 | (fp_line (start -3.1 -4.9) (end -3.1 -6.1) (layer F.SilkS) (width 0.12)) 20 | (fp_text user %R (at 0 0 -180) (layer F.Fab) 21 | (effects (font (size 1 1) (thickness 0.15))) 22 | ) 23 | (fp_line (start -5.6 -6.1) (end 5.6 -6.1) (layer F.CrtYd) (width 0.05)) 24 | (fp_line (start -5.6 9) (end -5.6 -6.1) (layer F.CrtYd) (width 0.05)) 25 | (fp_line (start 5.6 9) (end -5.6 9) (layer F.CrtYd) (width 0.05)) 26 | (fp_line (start 5.6 -6.1) (end 5.6 9) (layer F.CrtYd) (width 0.05)) 27 | (fp_line (start 2.5 -6) (end 3 -6) (layer F.Fab) (width 0.1)) 28 | (fp_line (start 2.5 -8.5) (end 2.5 -6) (layer F.Fab) (width 0.1)) 29 | (fp_line (start -2.5 -8.5) (end 2.5 -8.5) (layer F.Fab) (width 0.1)) 30 | (fp_line (start -2.5 -6) (end -2.5 -8.5) (layer F.Fab) (width 0.1)) 31 | (fp_line (start -3 -6) (end -2.5 -6) (layer F.Fab) (width 0.1)) 32 | (fp_line (start -3 8.5) (end -3 -6) (layer F.Fab) (width 0.1)) 33 | (fp_line (start 3 8.5) (end -3 8.5) (layer F.Fab) (width 0.1)) 34 | (fp_line (start 3 -6) (end 3 8.5) (layer F.Fab) (width 0.1)) 35 | (pad "" np_thru_hole circle (at 0 4.5) (size 1.7 1.7) (drill 1.7) (layers *.Cu *.Mask)) 36 | (pad "" np_thru_hole circle (at 0 -2.5) (size 1.7 1.7) (drill 1.7) (layers *.Cu *.Mask)) 37 | (pad 2 smd rect (at -3.7 5.8) (size 2.8 2.8) (layers F.Cu F.Paste F.Mask)) 38 | (pad 1 smd rect (at -3.7 -3.6) (size 2.8 2.2) (layers F.Cu F.Paste F.Mask)) 39 | (pad 3 smd rect (at 3.7 -1.6) (size 2.8 2.2) (layers F.Cu F.Paste F.Mask)) 40 | (model CUI_DEVICES_SJ-3523-SMT-TR.step 41 | (offset (xyz 0 6 0)) 42 | (scale (xyz 1 1 1)) 43 | (rotate (xyz -90 0 90)) 44 | ) 45 | ) 46 | -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/RPi_Pico.pretty/DSUB-15-L77HDE15SD1CH4F.kicad_mod: -------------------------------------------------------------------------------- 1 | (module DSUB-15-L77HDE15SD1CH4F (layer F.Cu) (tedit 5EFF80D9) 2 | (descr "15-pin D-Sub connector, horizontal/angled (90 deg), THT-mount, female, pitch 2.29x1.98mm, pin-PCB-offset 3.0300000000000002mm, distance of mounting holes 25mm, distance of mounting holes to PCB edge 4.9399999999999995mm, see https://disti-assets.s3.amazonaws.com/tonar/files/datasheets/16730.pdf") 3 | (tags "15-pin D-Sub connector horizontal angled 90deg THT female pitch 2.29x1.98mm pin-PCB-offset 3.0300000000000002mm mounting-holes-distance 25mm mounting-hole-offset 25mm") 4 | (fp_text reference REF** (at 10.2 17.43 180) (layer F.SilkS) 5 | (effects (font (size 1 1) (thickness 0.15))) 6 | ) 7 | (fp_text value DSUB-15-L77HDE15SD1CH4F (at -0.01 -7.45 180) (layer F.Fab) 8 | (effects (font (size 1 1) (thickness 0.15))) 9 | ) 10 | (fp_arc (start 12.5 11.43) (end 14.1 11.43) (angle 180) (layer F.Fab) (width 0.1)) 11 | (fp_arc (start -12.5 11.43) (end -10.9 11.43) (angle 180) (layer F.Fab) (width 0.1)) 12 | (fp_line (start 15.415 16.1) (end 15.415 0.45) (layer F.Fab) (width 0.1)) 13 | (fp_line (start 15.415 0.45) (end -15.435 0.45) (layer F.Fab) (width 0.1)) 14 | (fp_line (start -15.435 0.45) (end -15.435 16.1) (layer F.Fab) (width 0.1)) 15 | (fp_line (start -15.435 16.1) (end 15.415 16.1) (layer F.Fab) (width 0.1)) 16 | (fp_line (start 15.415 0.45) (end 15.415 0.05) (layer F.Fab) (width 0.1)) 17 | (fp_line (start 15.415 0.05) (end -15.435 0.05) (layer F.Fab) (width 0.1)) 18 | (fp_line (start -15.435 0.05) (end -15.435 0.45) (layer F.Fab) (width 0.1)) 19 | (fp_line (start -15.435 0.45) (end 15.415 0.45) (layer F.Fab) (width 0.1)) 20 | (fp_line (start 8.14 0.05) (end 8.14 -5.95) (layer F.Fab) (width 0.1)) 21 | (fp_line (start 8.14 -5.95) (end -8.16 -5.95) (layer F.Fab) (width 0.1)) 22 | (fp_line (start -8.16 -5.95) (end -8.16 0.05) (layer F.Fab) (width 0.1)) 23 | (fp_line (start -8.16 0.05) (end 8.14 0.05) (layer F.Fab) (width 0.1)) 24 | (fp_line (start 14.99 0.05) (end 14.99 -4.95) (layer F.Fab) (width 0.1)) 25 | (fp_line (start 14.99 -4.95) (end 9.99 -4.95) (layer F.Fab) (width 0.1)) 26 | (fp_line (start 9.99 -4.95) (end 9.99 0.05) (layer F.Fab) (width 0.1)) 27 | (fp_line (start 9.99 0.05) (end 14.99 0.05) (layer F.Fab) (width 0.1)) 28 | (fp_line (start -10.01 0.05) (end -10.01 -4.95) (layer F.Fab) (width 0.1)) 29 | (fp_line (start -10.01 -4.95) (end -15.01 -4.95) (layer F.Fab) (width 0.1)) 30 | (fp_line (start -15.01 -4.95) (end -15.01 0.05) (layer F.Fab) (width 0.1)) 31 | (fp_line (start -15.01 0.05) (end -10.01 0.05) (layer F.Fab) (width 0.1)) 32 | (fp_line (start 14.09 0.45) (end 14.09 11.43) (layer F.Fab) (width 0.1)) 33 | (fp_line (start 10.89 0.45) (end 10.89 11.43) (layer F.Fab) (width 0.1)) 34 | (fp_line (start -10.91 0.45) (end -10.91 11.43) (layer F.Fab) (width 0.1)) 35 | (fp_line (start -14.11 0.45) (end -14.11 11.43) (layer F.Fab) (width 0.1)) 36 | (fp_line (start -4.115 16.974338) (end -4.615 16.974338) (layer F.SilkS) (width 0.12)) 37 | (fp_line (start -4.615 16.974338) (end -4.365 16.541325) (layer F.SilkS) (width 0.12)) 38 | (fp_line (start -4.365 16.541325) (end -4.115 16.974338) (layer F.SilkS) (width 0.12)) 39 | (fp_line (start 16 16.63) (end 16 0) (layer F.CrtYd) (width 0.05)) 40 | (fp_line (start 16 0) (end -16 0) (layer F.CrtYd) (width 0.05)) 41 | (fp_line (start -16 0) (end -16 16.63) (layer F.CrtYd) (width 0.05)) 42 | (fp_line (start -16 16.63) (end 16 16.63) (layer F.CrtYd) (width 0.05)) 43 | (fp_text user %R (at -0.01 -2.95 180) (layer F.Fab) 44 | (effects (font (size 1 1) (thickness 0.15))) 45 | ) 46 | (fp_line (start 27.48 0) (end -27.48 0) (layer Dwgs.User) (width 0.12)) 47 | (fp_line (start 15.5 0.03) (end 15.5 16.23) (layer F.SilkS) (width 0.12)) 48 | (fp_line (start 15.5 16.23) (end -15.5 16.23) (layer F.SilkS) (width 0.12)) 49 | (fp_line (start -15.5 16.23) (end -15.5 0.03) (layer F.SilkS) (width 0.12)) 50 | (pad 0 thru_hole circle (at 12.495 11.43 180) (size 4 4) (drill 3.2) (layers *.Cu *.Mask)) 51 | (pad 0 thru_hole circle (at -12.495 11.43 180) (size 4 4) (drill 3.2) (layers *.Cu *.Mask)) 52 | (pad 8 thru_hole circle (at -0.895 11.43 180) (size 1.7 1.7) (drill 1.1) (layers *.Cu *.Mask)) 53 | (pad 7 thru_hole circle (at -3.185 11.43 180) (size 1.7 1.7) (drill 1.1) (layers *.Cu *.Mask)) 54 | (pad 6 thru_hole circle (at -5.475 11.43 180) (size 1.7 1.7) (drill 1.1) (layers *.Cu *.Mask)) 55 | (pad 9 thru_hole circle (at 1.395 11.43 180) (size 1.7 1.7) (drill 1.1) (layers *.Cu *.Mask)) 56 | (pad 10 thru_hole circle (at 3.685 11.43 180) (size 1.7 1.7) (drill 1.1) (layers *.Cu *.Mask)) 57 | (pad 14 thru_hole circle (at 2.54 8.89 180) (size 1.7 1.7) (drill 1.1) (layers *.Cu *.Mask)) 58 | (pad 15 thru_hole circle (at 4.83 8.89 180) (size 1.7 1.7) (drill 1.1) (layers *.Cu *.Mask)) 59 | (pad 12 thru_hole circle (at -2.04 8.89 180) (size 1.7 1.7) (drill 1.1) (layers *.Cu *.Mask)) 60 | (pad 13 thru_hole circle (at 0.25 8.89 180) (size 1.7 1.7) (drill 1.1) (layers *.Cu *.Mask)) 61 | (pad 11 thru_hole circle (at -4.33 8.89 180) (size 1.7 1.7) (drill 1.1) (layers *.Cu *.Mask)) 62 | (pad 5 thru_hole circle (at 4.83 13.97 180) (size 1.7 1.7) (drill 1.1) (layers *.Cu *.Mask)) 63 | (pad 4 thru_hole circle (at 2.54 13.97 180) (size 1.7 1.7) (drill 1.1) (layers *.Cu *.Mask)) 64 | (pad 3 thru_hole circle (at 0.25 13.97 180) (size 1.7 1.7) (drill 1.1) (layers *.Cu *.Mask)) 65 | (pad 2 thru_hole circle (at -2.04 13.97 180) (size 1.7 1.7) (drill 1.1) (layers *.Cu *.Mask)) 66 | (pad 1 thru_hole rect (at -4.33 13.97 180) (size 1.7 1.7) (drill 1.1) (layers *.Cu *.Mask)) 67 | (model ${KISYS3DMOD}/Connector_Dsub.3dshapes/DSUB-15-HD_Female_Horizontal_P2.29x1.98mm_EdgePinOffset3.03mm_Housed_MountingHolesOffset4.94mm.wrl 68 | (at (xyz 0 0 0)) 69 | (scale (xyz 1 1 1)) 70 | (rotate (xyz 0 0 0)) 71 | ) 72 | ) 73 | -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/RPi_Pico.pretty/Icon_: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDrive/RPi_Pico.pretty/Icon_ -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/RPi_Pico.pretty/MBR120_SOD-123.kicad_mod: -------------------------------------------------------------------------------- 1 | (module MBR120_SOD-123 (layer F.Cu) (tedit 5F02E60A) 2 | (descr SOD-123) 3 | (tags SOD-123) 4 | (attr smd) 5 | (fp_text reference REF** (at 0 -2) (layer F.SilkS) 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | ) 8 | (fp_text value MBR120_SOD-123 (at 0 2.1) (layer F.Fab) 9 | (effects (font (size 1 1) (thickness 0.15))) 10 | ) 11 | (fp_text user %R (at 0 -2) (layer F.Fab) 12 | (effects (font (size 1 1) (thickness 0.15))) 13 | ) 14 | (fp_line (start -2.3 -1) (end -2.3 1) (layer F.SilkS) (width 0.12)) 15 | (fp_line (start 0.25 0) (end 0.75 0) (layer F.Fab) (width 0.1)) 16 | (fp_line (start 0.25 0.4) (end -0.35 0) (layer F.Fab) (width 0.1)) 17 | (fp_line (start 0.25 -0.4) (end 0.25 0.4) (layer F.Fab) (width 0.1)) 18 | (fp_line (start -0.35 0) (end 0.25 -0.4) (layer F.Fab) (width 0.1)) 19 | (fp_line (start -0.35 0) (end -0.35 0.55) (layer F.Fab) (width 0.1)) 20 | (fp_line (start -0.35 0) (end -0.35 -0.55) (layer F.Fab) (width 0.1)) 21 | (fp_line (start -0.75 0) (end -0.35 0) (layer F.Fab) (width 0.1)) 22 | (fp_line (start -1.4 0.9) (end -1.4 -0.9) (layer F.Fab) (width 0.1)) 23 | (fp_line (start 1.4 0.9) (end -1.4 0.9) (layer F.Fab) (width 0.1)) 24 | (fp_line (start 1.4 -0.9) (end 1.4 0.9) (layer F.Fab) (width 0.1)) 25 | (fp_line (start -1.4 -0.9) (end 1.4 -0.9) (layer F.Fab) (width 0.1)) 26 | (fp_line (start -2.35 -1.15) (end 2.35 -1.15) (layer F.CrtYd) (width 0.05)) 27 | (fp_line (start 2.35 -1.15) (end 2.35 1.15) (layer F.CrtYd) (width 0.05)) 28 | (fp_line (start 2.35 1.15) (end -2.35 1.15) (layer F.CrtYd) (width 0.05)) 29 | (fp_line (start -2.35 -1.15) (end -2.35 1.15) (layer F.CrtYd) (width 0.05)) 30 | (fp_line (start -2.3 1) (end 1.65 1) (layer F.SilkS) (width 0.12)) 31 | (fp_line (start -2.3 -1) (end 1.65 -1) (layer F.SilkS) (width 0.12)) 32 | (pad 1 smd rect (at -1.475 0) (size 1.25 1.22) (layers F.Cu F.Paste F.Mask)) 33 | (pad 2 smd rect (at 1.475 0) (size 1.25 1.22) (layers F.Cu F.Paste F.Mask)) 34 | (model ${KISYS3DMOD}/Diode_SMD.3dshapes/D_SOD-123.wrl 35 | (at (xyz 0 0 0)) 36 | (scale (xyz 1 1 1)) 37 | (rotate (xyz 0 0 0)) 38 | ) 39 | ) 40 | -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/RPi_Pico.pretty/USB_Micro-B_Amphenol_10103594-0001LF_Horizontal_modified.kicad_mod: -------------------------------------------------------------------------------- 1 | (module USB_Micro-B_Amphenol_10103594-0001LF_Horizontal_modified (layer F.Cu) (tedit 5F0317C2) 2 | (descr "Micro USB Type B 10103594-0001LF, http://cdn.amphenol-icc.com/media/wysiwyg/files/drawing/10103594.pdf") 3 | (tags "USB USB_B USB_micro USB_OTG") 4 | (attr smd) 5 | (fp_text reference J5 (at -5.365 -2.58 -180) (layer F.SilkS) 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | ) 8 | (fp_text value USB_B_Micro (at -0.025 3.32 -180) (layer F.Fab) 9 | (effects (font (size 1 1) (thickness 0.15))) 10 | ) 11 | (fp_line (start 4.14 1.7) (end -4.13 1.7) (layer F.CrtYd) (width 0.05)) 12 | (fp_line (start 4.14 1.7) (end 4.14 -3.995) (layer F.CrtYd) (width 0.05)) 13 | (fp_line (start -4.13 -3.995) (end -4.13 1.7) (layer F.CrtYd) (width 0.05)) 14 | (fp_line (start -4.13 -3.995) (end 4.14 -3.995) (layer F.CrtYd) (width 0.05)) 15 | (fp_line (start -4.02 1.7) (end 4.02 1.7) (layer Dwgs.User) (width 0.1)) 16 | (fp_line (start -3.775 2.22) (end -3.775 -1.98) (layer F.Fab) (width 0.12)) 17 | (fp_line (start -2.975 -2.73) (end 3.725 -2.73) (layer F.Fab) (width 0.12)) 18 | (fp_line (start 3.725 -2.73) (end 3.725 2.22) (layer F.Fab) (width 0.12)) 19 | (fp_line (start 3.725 2.22) (end -3.775 2.22) (layer F.Fab) (width 0.12)) 20 | (fp_line (start -3.775 -1.98) (end -2.975 -2.73) (layer F.Fab) (width 0.12)) 21 | (fp_line (start -1.325 -3.98) (end -1.725 -4.43) (layer F.SilkS) (width 0.12)) 22 | (fp_line (start -1.725 -4.43) (end -0.925 -4.43) (layer F.SilkS) (width 0.12)) 23 | (fp_line (start -0.925 -4.43) (end -1.325 -3.98) (layer F.SilkS) (width 0.12)) 24 | (fp_line (start 3.825 1.62) (end 3.825 -1.18) (layer F.SilkS) (width 0.12)) 25 | (fp_line (start 3.825 -1.18) (end 4.125 -1.18) (layer F.SilkS) (width 0.12)) 26 | (fp_line (start 4.125 -1.18) (end 4.125 -2.73) (layer F.SilkS) (width 0.12)) 27 | (fp_line (start -3.875 1.62) (end -3.875 -1.18) (layer F.SilkS) (width 0.12)) 28 | (fp_line (start -4.175 -1.18) (end -3.875 -1.18) (layer F.SilkS) (width 0.12)) 29 | (fp_line (start -4.175 -1.18) (end -4.175 -2.73) (layer F.SilkS) (width 0.12)) 30 | (fp_text user %R (at -0.025 -1.13 -180) (layer F.Fab) 31 | (effects (font (size 1 1) (thickness 0.15))) 32 | ) 33 | (fp_text user "PCB edge" (at -0.025 1.12 -180) (layer Dwgs.User) 34 | (effects (font (size 0.5 0.5) (thickness 0.075))) 35 | ) 36 | (pad 6 smd rect (at 0.9625 0.25 90) (size 2.5 1.425) (layers F.Cu F.Paste F.Mask)) 37 | (pad 6 smd rect (at -0.9625 0.25 90) (size 2.5 1.425) (layers F.Cu F.Paste F.Mask)) 38 | (pad 6 thru_hole oval (at 2.725 0 90) (size 1.8 1.3) (drill oval 1.2 0.7) (layers *.Cu *.Mask)) 39 | (pad 6 thru_hole oval (at -2.725 0 90) (size 1.8 1.3) (drill oval 1.2 0.7) (layers *.Cu *.Mask)) 40 | (pad 6 thru_hole oval (at -2.425 -3.03 90) (size 1.45 1.05) (drill oval 1.05 0.65) (layers *.Cu *.Mask)) 41 | (pad 5 smd rect (at 1.3 -2.825 90) (size 1.75 0.4) (layers F.Cu F.Paste F.Mask)) 42 | (pad 4 smd rect (at 0.65 -2.825 90) (size 1.75 0.4) (layers F.Cu F.Paste F.Mask)) 43 | (pad 3 smd rect (at 0 -2.825 90) (size 1.75 0.4) (layers F.Cu F.Paste F.Mask)) 44 | (pad 2 smd rect (at -0.65 -2.825 90) (size 1.75 0.4) (layers F.Cu F.Paste F.Mask)) 45 | (pad 1 smd rect (at -1.3 -2.825 90) (size 1.75 0.4) (layers F.Cu F.Paste F.Mask)) 46 | (pad 6 smd rect (at 2.9 -3.03) (size 2 1.46) (layers F.Cu F.Paste F.Mask)) 47 | (pad 6 smd rect (at -2.9 -3.03) (size 2 1.46) (layers F.Cu F.Paste F.Mask)) 48 | (pad 6 smd rect (at -2.9875 -1.7) (size 1.825 0.7) (layers F.Cu F.Paste F.Mask)) 49 | (pad 6 smd roundrect (at -2.725 -0.425) (size 1.3 3.25) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.296)) 50 | (pad 6 smd roundrect (at 2.725 -0.425) (size 1.3 3.25) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.296)) 51 | (pad 6 smd rect (at 2.9875 -1.7) (size 1.825 0.7) (layers F.Cu F.Paste F.Mask)) 52 | (pad 6 thru_hole oval (at 2.425 -3.03 90) (size 1.45 1.05) (drill oval 1.05 0.65) (layers *.Cu *.Mask)) 53 | (model 10103594.stp 54 | (offset (xyz 0 0.2 2.2)) 55 | (scale (xyz 1 1 1)) 56 | (rotate (xyz 90 0 180)) 57 | ) 58 | ) 59 | -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/SN74LVC1T45DBVR.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | #SamacSys ECAD Model SN74LVC1T45DBVR 4 | #/250028/175246/2.49/6/3/Integrated Circuit 5 | DEF SN74LVC1T45DBVR IC 0 30 Y Y 1 F N 6 | F0 "IC" 950 300 50 H V L CNN 7 | F1 "SN74LVC1T45DBVR" 950 200 50 H V L CNN 8 | F2 "SOT95P280X145-6N" 950 100 50 H I L CNN 9 | F3 "https://componentsearchengine.com/Datasheets/2/SN74LVC1T45DBVR.pdf" 950 0 50 H I L CNN 10 | F4 "1-Bit Bus Transceiver, Translation SOT23 Texas Instruments SN74LVC1T45DBVR, Voltage Level Translator, Bus Transceiver, 3-State, 1.65 5.5 V, 6-Pin SOT-23" 950 -100 50 H I L CNN "Description" 11 | F5 "1.45" 950 -200 50 H I L CNN "Height" 12 | F6 "595-SN74LVC1T45DBVR" 950 -300 50 H I L CNN "Mouser Part Number" 13 | F7 "https://www.mouser.co.uk/ProductDetail/Texas-Instruments/SN74LVC1T45DBVR?qs=pajgIaoyDUhg6sKXdsM%2Fvg%3D%3D" 950 -400 50 H I L CNN "Mouser Price/Stock" 14 | F8 "Texas Instruments" 950 -500 50 H I L CNN "Manufacturer_Name" 15 | F9 "SN74LVC1T45DBVR" 950 -600 50 H I L CNN "Manufacturer_Part_Number" 16 | DRAW 17 | X VCCA 1 0 0 200 R 50 50 0 0 P 18 | X GND 2 0 -100 200 R 50 50 0 0 P 19 | X A 3 0 -200 200 R 50 50 0 0 P 20 | X VCCB 6 1100 0 200 L 50 50 0 0 P 21 | X DIR 5 1100 -100 200 L 50 50 0 0 P 22 | X B 4 1100 -200 200 L 50 50 0 0 P 23 | P 5 0 1 6 200 100 900 100 900 -300 200 -300 200 100 N 24 | ENDDRAW 25 | ENDDEF 26 | # 27 | #End Library 28 | -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/SN74LVC1T45DBVR.pretty/SOT95P280X145-6N.kicad_mod: -------------------------------------------------------------------------------- 1 | (module "SOT95P280X145-6N" (layer F.Cu) 2 | (descr "DBV (R-PDSO-G6)") 3 | (tags "Integrated Circuit") 4 | (attr smd) 5 | (fp_text reference IC** (at 0 0) (layer F.SilkS) 6 | (effects (font (size 1.27 1.27) (thickness 0.254))) 7 | ) 8 | (fp_text user %R (at 0 0) (layer F.Fab) 9 | (effects (font (size 1.27 1.27) (thickness 0.254))) 10 | ) 11 | (fp_text value "SOT95P280X145-6N" (at 0 0) (layer F.SilkS) hide 12 | (effects (font (size 1.27 1.27) (thickness 0.254))) 13 | ) 14 | (fp_line (start -2.1 -1.775) (end 2.1 -1.775) (layer F.CrtYd) (width 0.05)) 15 | (fp_line (start 2.1 -1.775) (end 2.1 1.775) (layer F.CrtYd) (width 0.05)) 16 | (fp_line (start 2.1 1.775) (end -2.1 1.775) (layer F.CrtYd) (width 0.05)) 17 | (fp_line (start -2.1 1.775) (end -2.1 -1.775) (layer F.CrtYd) (width 0.05)) 18 | (fp_line (start -0.8 -1.45) (end 0.8 -1.45) (layer F.Fab) (width 0.1)) 19 | (fp_line (start 0.8 -1.45) (end 0.8 1.45) (layer F.Fab) (width 0.1)) 20 | (fp_line (start 0.8 1.45) (end -0.8 1.45) (layer F.Fab) (width 0.1)) 21 | (fp_line (start -0.8 1.45) (end -0.8 -1.45) (layer F.Fab) (width 0.1)) 22 | (fp_line (start -0.8 -0.5) (end 0.15 -1.45) (layer F.Fab) (width 0.1)) 23 | (fp_line (start -0.3 -1.45) (end 0.3 -1.45) (layer F.SilkS) (width 0.2)) 24 | (fp_line (start 0.3 -1.45) (end 0.3 1.45) (layer F.SilkS) (width 0.2)) 25 | (fp_line (start 0.3 1.45) (end -0.3 1.45) (layer F.SilkS) (width 0.2)) 26 | (fp_line (start -0.3 1.45) (end -0.3 -1.45) (layer F.SilkS) (width 0.2)) 27 | (fp_line (start -1.85 -1.6) (end -0.65 -1.6) (layer F.SilkS) (width 0.2)) 28 | (pad 1 smd rect (at -1.25 -0.95 90) (size 0.6 1.2) (layers F.Cu F.Paste F.Mask)) 29 | (pad 2 smd rect (at -1.25 0 90) (size 0.6 1.2) (layers F.Cu F.Paste F.Mask)) 30 | (pad 3 smd rect (at -1.25 0.95 90) (size 0.6 1.2) (layers F.Cu F.Paste F.Mask)) 31 | (pad 4 smd rect (at 1.25 0.95 90) (size 0.6 1.2) (layers F.Cu F.Paste F.Mask)) 32 | (pad 5 smd rect (at 1.25 0 90) (size 0.6 1.2) (layers F.Cu F.Paste F.Mask)) 33 | (pad 6 smd rect (at 1.25 -0.95 90) (size 0.6 1.2) (layers F.Cu F.Paste F.Mask)) 34 | (model SN74LVC1T45DBVR.stp 35 | (at (xyz 0 0 0)) 36 | (scale (xyz 1 1 1)) 37 | (rotate (xyz 0 0 0)) 38 | ) 39 | ) 40 | -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/TXU0304QPWRQ1.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | #SamacSys ECAD Model TXU0304QPWRQ1 4 | #/14636844/175246/2.49/14/3/Integrated Circuit 5 | DEF TXU0304QPWRQ1 IC 0 30 Y Y 1 F N 6 | F0 "IC" 950 300 50 H V L CNN 7 | F1 "TXU0304QPWRQ1" 950 200 50 H V L CNN 8 | F2 "SOP65P640X120-14N" 950 100 50 H I L CNN 9 | F3 "https://www.ti.com/lit/ds/symlink/txu0304-q1.pdf" 950 0 50 H I L CNN 10 | F4 "TXU0304QPWRQ1" 950 -100 50 H I L CNN "Description" 11 | F5 "1.2" 950 -200 50 H I L CNN "Height" 12 | F6 "595-TXU0304QPWRQ1" 950 -300 50 H I L CNN "Mouser Part Number" 13 | F7 "https://www.mouser.co.uk/ProductDetail/Texas-Instruments/TXU0304QPWRQ1?qs=QNEnbhJQKvZXfjMNvwmKIA%3D%3D" 950 -400 50 H I L CNN "Mouser Price/Stock" 14 | F8 "Texas Instruments" 950 -500 50 H I L CNN "Manufacturer_Name" 15 | F9 "TXU0304QPWRQ1" 950 -600 50 H I L CNN "Manufacturer_Part_Number" 16 | DRAW 17 | X VCCA 1 0 0 200 R 50 50 0 0 P 18 | X A1 2 0 -100 200 R 50 50 0 0 P 19 | X A2 3 0 -200 200 R 50 50 0 0 P 20 | X A3 4 0 -300 200 R 50 50 0 0 P 21 | X A4Y 5 0 -400 200 R 50 50 0 0 P 22 | X NC_1 6 0 -500 200 R 50 50 0 0 P 23 | X GND 7 0 -600 200 R 50 50 0 0 P 24 | X VCCB 14 1100 0 200 L 50 50 0 0 P 25 | X B1Y 13 1100 -100 200 L 50 50 0 0 P 26 | X B2Y 12 1100 -200 200 L 50 50 0 0 P 27 | X B3Y 11 1100 -300 200 L 50 50 0 0 P 28 | X B4 10 1100 -400 200 L 50 50 0 0 P 29 | X NC_2 9 1100 -500 200 L 50 50 0 0 P 30 | X OE 8 1100 -600 200 L 50 50 0 0 P 31 | P 5 0 1 6 200 100 900 100 900 -700 200 -700 200 100 N 32 | ENDDRAW 33 | ENDDEF 34 | # 35 | #End Library 36 | -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/TXU0304QPWRQ1.pretty/TXU0304QPWRQ1.kicad_mod: -------------------------------------------------------------------------------- 1 | (module "SOP65P640X120-14N" (layer F.Cu) 2 | (descr "PW (R-PDSO-G14)") 3 | (tags "Integrated Circuit") 4 | (attr smd) 5 | (fp_text reference IC** (at 0 0) (layer F.SilkS) 6 | (effects (font (size 1.27 1.27) (thickness 0.254))) 7 | ) 8 | (fp_text user %R (at 0 0) (layer F.Fab) 9 | (effects (font (size 1.27 1.27) (thickness 0.254))) 10 | ) 11 | (fp_text value "SOP65P640X120-14N" (at 0 0) (layer F.SilkS) hide 12 | (effects (font (size 1.27 1.27) (thickness 0.254))) 13 | ) 14 | (fp_line (start -3.925 -2.8) (end 3.925 -2.8) (layer F.CrtYd) (width 0.05)) 15 | (fp_line (start 3.925 -2.8) (end 3.925 2.8) (layer F.CrtYd) (width 0.05)) 16 | (fp_line (start 3.925 2.8) (end -3.925 2.8) (layer F.CrtYd) (width 0.05)) 17 | (fp_line (start -3.925 2.8) (end -3.925 -2.8) (layer F.CrtYd) (width 0.05)) 18 | (fp_line (start -2.2 -2.5) (end 2.2 -2.5) (layer F.Fab) (width 0.1)) 19 | (fp_line (start 2.2 -2.5) (end 2.2 2.5) (layer F.Fab) (width 0.1)) 20 | (fp_line (start 2.2 2.5) (end -2.2 2.5) (layer F.Fab) (width 0.1)) 21 | (fp_line (start -2.2 2.5) (end -2.2 -2.5) (layer F.Fab) (width 0.1)) 22 | (fp_line (start -2.2 -1.85) (end -1.55 -2.5) (layer F.Fab) (width 0.1)) 23 | (fp_line (start -1.85 -2.5) (end 1.85 -2.5) (layer F.SilkS) (width 0.2)) 24 | (fp_line (start 1.85 -2.5) (end 1.85 2.5) (layer F.SilkS) (width 0.2)) 25 | (fp_line (start 1.85 2.5) (end -1.85 2.5) (layer F.SilkS) (width 0.2)) 26 | (fp_line (start -1.85 2.5) (end -1.85 -2.5) (layer F.SilkS) (width 0.2)) 27 | (fp_line (start -3.675 -2.525) (end -2.2 -2.525) (layer F.SilkS) (width 0.2)) 28 | (pad 1 smd rect (at -2.938 -1.95 90) (size 0.45 1.475) (layers F.Cu F.Paste F.Mask)) 29 | (pad 2 smd rect (at -2.938 -1.3 90) (size 0.45 1.475) (layers F.Cu F.Paste F.Mask)) 30 | (pad 3 smd rect (at -2.938 -0.65 90) (size 0.45 1.475) (layers F.Cu F.Paste F.Mask)) 31 | (pad 4 smd rect (at -2.938 0 90) (size 0.45 1.475) (layers F.Cu F.Paste F.Mask)) 32 | (pad 5 smd rect (at -2.938 0.65 90) (size 0.45 1.475) (layers F.Cu F.Paste F.Mask)) 33 | (pad 6 smd rect (at -2.938 1.3 90) (size 0.45 1.475) (layers F.Cu F.Paste F.Mask)) 34 | (pad 7 smd rect (at -2.938 1.95 90) (size 0.45 1.475) (layers F.Cu F.Paste F.Mask)) 35 | (pad 8 smd rect (at 2.938 1.95 90) (size 0.45 1.475) (layers F.Cu F.Paste F.Mask)) 36 | (pad 9 smd rect (at 2.938 1.3 90) (size 0.45 1.475) (layers F.Cu F.Paste F.Mask)) 37 | (pad 10 smd rect (at 2.938 0.65 90) (size 0.45 1.475) (layers F.Cu F.Paste F.Mask)) 38 | (pad 11 smd rect (at 2.938 0 90) (size 0.45 1.475) (layers F.Cu F.Paste F.Mask)) 39 | (pad 12 smd rect (at 2.938 -0.65 90) (size 0.45 1.475) (layers F.Cu F.Paste F.Mask)) 40 | (pad 13 smd rect (at 2.938 -1.3 90) (size 0.45 1.475) (layers F.Cu F.Paste F.Mask)) 41 | (pad 14 smd rect (at 2.938 -1.95 90) (size 0.45 1.475) (layers F.Cu F.Paste F.Mask)) 42 | (model TXU0304QPWRQ1.stp 43 | (at (xyz 0 0 0)) 44 | (scale (xyz 1 1 1)) 45 | (rotate (xyz 0 0 0)) 46 | ) 47 | ) 48 | -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name "RPi_Pico")(type "KiCad")(uri "${KIPRJMOD}/RPi_Pico.pretty")(options "")(descr "")) 3 | (lib (name "TXU0304QPWRQ1")(type "KiCad")(uri "${KIPRJMOD}/TXU0304QPWRQ1.pretty")(options "")(descr "")) 4 | (lib (name "SN74LVC1T45DBVR")(type "KiCad")(uri "${KIPRJMOD}/SN74LVC1T45DBVR.pretty")(options "")(descr "")) 5 | (lib (name "EdgeCon")(type "KiCad")(uri "${KIPRJMOD}/EdgeCon.pretty")(options "")(descr "")) 6 | ) 7 | -------------------------------------------------------------------------------- /Hardware/MicroPicoDrive/sym-lib-table: -------------------------------------------------------------------------------- 1 | (sym_lib_table 2 | (lib (name "RPi_Pico")(type "KiCad")(uri "${KIPRJMOD}/RPi_Pico.kicad_sym")(options "")(descr "")) 3 | (lib (name "TXU0304QPWRQ1")(type "Legacy")(uri "${KIPRJMOD}/TXU0304QPWRQ1.lib")(options "")(descr "")) 4 | (lib (name "SN74LVC1T45DBVR")(type "Legacy")(uri "${KIPRJMOD}/SN74LVC1T45DBVR.lib")(options "")(descr "")) 5 | ) 6 | -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/CartridgeComponents.bak: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20211014) (generator kicad_symbol_editor) 2 | (symbol "Screen" (in_bom yes) (on_board yes) 3 | (property "Reference" "SCR" (id 0) (at 0 6.35 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "Screen" (id 1) (at 0 8.89 0) 7 | (effects (font (size 1.27 1.27))) 8 | ) 9 | (property "Footprint" "" (id 2) (at 0 6.35 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "" (id 3) (at 0 6.35 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (symbol "Screen_0_1" 16 | (rectangle (start -6.35 2.54) (end 6.35 -2.54) 17 | (stroke (width 0) (type default) (color 0 0 0 0)) 18 | (fill (type none)) 19 | ) 20 | ) 21 | (symbol "Screen_1_1" 22 | (pin passive line (at -8.89 1.27 0) (length 2.54) 23 | (name "GND" (effects (font (size 1.27 1.27)))) 24 | (number "1" (effects (font (size 1.27 1.27)))) 25 | ) 26 | (pin passive line (at -8.89 -1.27 0) (length 2.54) 27 | (name "VCC" (effects (font (size 1.27 1.27)))) 28 | (number "2" (effects (font (size 1.27 1.27)))) 29 | ) 30 | (pin input line (at 8.89 1.27 180) (length 2.54) 31 | (name "SCL" (effects (font (size 1.27 1.27)))) 32 | (number "3" (effects (font (size 1.27 1.27)))) 33 | ) 34 | (pin bidirectional line (at 8.89 -1.27 180) (length 2.54) 35 | (name "SDA" (effects (font (size 1.27 1.27)))) 36 | (number "4" (effects (font (size 1.27 1.27)))) 37 | ) 38 | ) 39 | ) 40 | ) 41 | -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/CartridgeComponents.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20211014) (generator kicad_symbol_editor) 2 | (symbol "SDCard" (in_bom yes) (on_board yes) 3 | (property "Reference" "SD" (id 0) (at 0 8.89 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "SDCard" (id 1) (at 0 -8.89 0) 7 | (effects (font (size 1.27 1.27))) 8 | ) 9 | (property "Footprint" "" (id 2) (at -5.08 15.24 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "" (id 3) (at -5.08 15.24 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (symbol "SDCard_0_1" 16 | (rectangle (start -11.43 7.62) (end 11.43 -7.62) 17 | (stroke (width 0) (type default) (color 0 0 0 0)) 18 | (fill (type none)) 19 | ) 20 | ) 21 | (symbol "SDCard_1_1" 22 | (pin passive line (at 13.97 -5.08 180) (length 2.54) 23 | (name "DETECT" (effects (font (size 1.27 1.27)))) 24 | (number "1" (effects (font (size 1.27 1.27)))) 25 | ) 26 | (pin bidirectional line (at 13.97 2.54 180) (length 2.54) 27 | (name "D1" (effects (font (size 1.27 1.27)))) 28 | (number "2" (effects (font (size 1.27 1.27)))) 29 | ) 30 | (pin bidirectional line (at 13.97 5.08 180) (length 2.54) 31 | (name "D0/MISO" (effects (font (size 1.27 1.27)))) 32 | (number "3" (effects (font (size 1.27 1.27)))) 33 | ) 34 | (pin passive line (at -13.97 2.54 0) (length 2.54) 35 | (name "GND" (effects (font (size 1.27 1.27)))) 36 | (number "4" (effects (font (size 1.27 1.27)))) 37 | ) 38 | (pin input line (at -13.97 -5.08 0) (length 2.54) 39 | (name "CLK" (effects (font (size 1.27 1.27)))) 40 | (number "5" (effects (font (size 1.27 1.27)))) 41 | ) 42 | (pin passive line (at -13.97 5.08 0) (length 2.54) 43 | (name "VCC" (effects (font (size 1.27 1.27)))) 44 | (number "6" (effects (font (size 1.27 1.27)))) 45 | ) 46 | (pin input line (at -13.97 -2.54 0) (length 2.54) 47 | (name "CMD/MOSI" (effects (font (size 1.27 1.27)))) 48 | (number "7" (effects (font (size 1.27 1.27)))) 49 | ) 50 | (pin bidirectional line (at 13.97 -2.54 180) (length 2.54) 51 | (name "D3/CS" (effects (font (size 1.27 1.27)))) 52 | (number "8" (effects (font (size 1.27 1.27)))) 53 | ) 54 | (pin bidirectional line (at 13.97 0 180) (length 2.54) 55 | (name "D2" (effects (font (size 1.27 1.27)))) 56 | (number "9" (effects (font (size 1.27 1.27)))) 57 | ) 58 | ) 59 | ) 60 | (symbol "Screen" (in_bom yes) (on_board yes) 61 | (property "Reference" "SCR" (id 0) (at 0 6.35 0) 62 | (effects (font (size 1.27 1.27))) 63 | ) 64 | (property "Value" "Screen" (id 1) (at 0 8.89 0) 65 | (effects (font (size 1.27 1.27))) 66 | ) 67 | (property "Footprint" "" (id 2) (at 0 6.35 0) 68 | (effects (font (size 1.27 1.27)) hide) 69 | ) 70 | (property "Datasheet" "" (id 3) (at 0 6.35 0) 71 | (effects (font (size 1.27 1.27)) hide) 72 | ) 73 | (symbol "Screen_0_1" 74 | (rectangle (start -6.35 2.54) (end 6.35 -2.54) 75 | (stroke (width 0) (type default) (color 0 0 0 0)) 76 | (fill (type none)) 77 | ) 78 | ) 79 | (symbol "Screen_1_1" 80 | (pin passive line (at -8.89 1.27 0) (length 2.54) 81 | (name "GND" (effects (font (size 1.27 1.27)))) 82 | (number "1" (effects (font (size 1.27 1.27)))) 83 | ) 84 | (pin passive line (at -8.89 -1.27 0) (length 2.54) 85 | (name "VCC" (effects (font (size 1.27 1.27)))) 86 | (number "2" (effects (font (size 1.27 1.27)))) 87 | ) 88 | (pin input line (at 8.89 1.27 180) (length 2.54) 89 | (name "SCL" (effects (font (size 1.27 1.27)))) 90 | (number "3" (effects (font (size 1.27 1.27)))) 91 | ) 92 | (pin bidirectional line (at 8.89 -1.27 180) (length 2.54) 93 | (name "SDA" (effects (font (size 1.27 1.27)))) 94 | (number "4" (effects (font (size 1.27 1.27)))) 95 | ) 96 | ) 97 | ) 98 | ) 99 | -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/CartridgeComponents.pretty/Edge.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "Edge" (version 20211014) (generator pcbnew) 2 | (layer "F.Cu") 3 | (tedit 0) 4 | (attr smd) 5 | (fp_text reference "REF**" (at -10.5664 -8.9944 unlocked) (layer "F.SilkS") 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | (tstamp e000728f-e3c5-4fc4-86af-db9ceb3a6542) 8 | ) 9 | (fp_text value "Edge" (at -10.5664 -7.4944 unlocked) (layer "F.Fab") 10 | (effects (font (size 1 1) (thickness 0.15))) 11 | (tstamp 18d3014d-7089-41b5-ab03-53cc0a265580) 12 | ) 13 | (fp_text user "${REFERENCE}" (at -10.5664 -5.9944 unlocked) (layer "F.Fab") 14 | (effects (font (size 1 1) (thickness 0.15))) 15 | (tstamp 662bafcb-dcfb-4471-a8a9-f5c777fdf249) 16 | ) 17 | (fp_line (start 11.5 5.4) (end 13.4 5.4) (layer "Edge.Cuts") (width 0.12) (tstamp 08fae221-7b6f-4c57-be73-6210c6206091)) 18 | (fp_line (start -15.4 -3.4) (end -13.4 -2.4) (layer "Edge.Cuts") (width 0.12) (tstamp 20ac7a70-5cb9-4418-b061-8e4ee8d36b79)) 19 | (fp_line (start -13.4 5.4) (end -13.4 -2.4) (layer "Edge.Cuts") (width 0.12) (tstamp 22591446-6d82-47ac-b525-9e9deb496c8c)) 20 | (fp_line (start -10.5 -4.4) (end 10.5 -4.4) (layer "Edge.Cuts") (width 0.12) (tstamp 3c5840eb-164e-426c-ab78-faa89624b9dc)) 21 | (fp_line (start -11.5 -3.4) (end -11.5 5.4) (layer "Edge.Cuts") (width 0.12) (tstamp 3db00451-fbc3-4980-9f8f-a31cdc894554)) 22 | (fp_line (start 10.5 -4.4) (end 11.5 -3.4) (layer "Edge.Cuts") (width 0.12) (tstamp 84282cc7-416d-48c2-ae9f-c0149b35065e)) 23 | (fp_line (start 13.4 -2.4) (end 15.4 -3.4) (layer "Edge.Cuts") (width 0.12) (tstamp 8f0e1ea6-d278-4117-9e02-aaadcc59362e)) 24 | (fp_line (start -11.5 5.4) (end -13.4 5.4) (layer "Edge.Cuts") (width 0.12) (tstamp a0af1aa5-82ff-4825-8836-86496e7db65f)) 25 | (fp_line (start 11.5 -3.4) (end 11.5 5.4) (layer "Edge.Cuts") (width 0.12) (tstamp af66589f-0dae-4737-851f-f8cddd35005b)) 26 | (fp_line (start -10.5 -4.4) (end -11.5 -3.4) (layer "Edge.Cuts") (width 0.12) (tstamp b71ea2fc-03b3-4a1a-950e-5a040f1be797)) 27 | (fp_line (start 13.4 5.4) (end 13.4 -2.4) (layer "Edge.Cuts") (width 0.12) (tstamp d9c1c6f8-c198-49f9-bff0-eab2393a0053)) 28 | (fp_line (start -15.4 5.4) (end -15.4 -3.4) (layer "Edge.Cuts") (width 0.12) (tstamp dbc9643b-8b89-4ff3-80f6-063535be3753)) 29 | (fp_line (start 15.4 5.4) (end 15.4 -3.4) (layer "Edge.Cuts") (width 0.12) (tstamp ddb83956-0781-4967-adf3-cb27a82b32ef)) 30 | (pad "1" smd roundrect (at -8.89 0) (size 2 8) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp f8621ac5-1e7e-4e87-8c69-5fd403df9470)) 31 | (pad "2" smd roundrect (at -8.89 0) (size 2 8) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) (tstamp e002a979-85bc-451a-a77b-29ce2a8f19f9)) 32 | (pad "3" smd roundrect (at -6.35 0) (size 2 8) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 64d1d0fe-4fd6-4a55-8314-56a651e1ccab)) 33 | (pad "4" smd roundrect (at -6.35 0) (size 2 8) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) (tstamp af7ed34f-31b5-4744-97e9-29e5f4d85343)) 34 | (pad "5" smd roundrect (at -3.81 0) (size 2 8) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 0a8dfc5c-35dc-4e44-a2bf-5968ebf90cca)) 35 | (pad "6" smd roundrect (at -3.81 0) (size 2 8) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) (tstamp 37f8ba3f-cca4-4b16-b699-07a704844fc9)) 36 | (pad "7" smd roundrect (at -1.27 0) (size 2 8) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 97e5f992-979e-4291-bd9a-a77c3fd4b1b5)) 37 | (pad "8" smd roundrect (at -1.27 0) (size 2 8) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) (tstamp 6df433d7-73cd-4877-8d2e-047853b9077c)) 38 | (pad "9" smd roundrect (at 1.27 0) (size 2 8) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 21573090-1953-4b11-9042-108ae79fe9c5)) 39 | (pad "10" smd roundrect (at 1.27 0) (size 2 8) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) (tstamp 4648968b-aa58-4f57-8f45-54b088364670)) 40 | (pad "11" smd roundrect (at 3.81 0) (size 2 8) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 2cd3975a-2259-4fa9-8133-e1586b9b9618)) 41 | (pad "12" smd roundrect (at 3.81 0) (size 2 8) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) (tstamp 6239967a-77bd-4ec9-89cd-e04efd8dbe26)) 42 | (pad "13" smd roundrect (at 6.35 0) (size 2 8) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp f6dcb5b4-0971-448a-b9ab-6db37a750704)) 43 | (pad "14" smd roundrect (at 6.35 0) (size 2 8) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) (tstamp de2abbd8-9b48-47ba-b77e-4c65ca048af6)) 44 | (pad "15" smd roundrect (at 8.89 0) (size 2 8) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 42f10020-b50a-4739-a546-6b63e441c980)) 45 | (pad "16" smd roundrect (at 8.89 0) (size 2 8) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) (tstamp 3dfbccca-f469-4a6f-a8bd-5f55435b5cfa)) 46 | ) 47 | -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/CartridgeComponents.pretty/SDCard.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "SDCard" (version 20211014) (generator pcbnew) 2 | (layer "F.Cu") 3 | (tedit 0) 4 | (attr through_hole) 5 | (fp_text reference "REF**" (at -7.5184 -10.771 unlocked) (layer "F.SilkS") 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | (tstamp 3eb6166e-d2a4-4778-a9e3-fd9ea19f972e) 8 | ) 9 | (fp_text value "SDCard" (at -7.5184 -9.271 unlocked) (layer "F.Fab") 10 | (effects (font (size 1 1) (thickness 0.15))) 11 | (tstamp c36f7147-bc6f-4cbe-8b56-617ae1aaead3) 12 | ) 13 | (fp_text user "${REFERENCE}" (at -7.5184 -7.771 unlocked) (layer "F.Fab") 14 | (effects (font (size 1 1) (thickness 0.15))) 15 | (tstamp a6e79250-4ea1-4a1f-b168-c1d347acb43a) 16 | ) 17 | (fp_line (start 7 19.5) (end 7 17.5) (layer "F.SilkS") (width 0.12) (tstamp 6c7215dc-2dbc-4951-bfca-623bac82e99f)) 18 | (fp_line (start -7 19.5) (end -7 17.5) (layer "F.SilkS") (width 0.12) (tstamp 89fa7fcb-3c2b-4c1b-b3ed-e2a1cf745f7d)) 19 | (fp_line (start 7 19.5) (end -7 19.5) (layer "F.SilkS") (width 0.12) (tstamp 9396dbf5-aa3c-4ba1-a9ae-1945fbb2026c)) 20 | (fp_line (start -10 17.5) (end 10 17.5) (layer "F.SilkS") (width 0.12) (tstamp a4eb21c6-285b-40a9-9401-daa21a94bf6e)) 21 | (fp_line (start -10 -2.5) (end -10 17.5) (layer "F.SilkS") (width 0.12) (tstamp ec464e2c-70c1-4b51-8600-7384ed6e411a)) 22 | (fp_line (start 10 -2.5) (end 10 17.5) (layer "F.SilkS") (width 0.12) (tstamp f5707a39-7e4e-416d-b856-204502394794)) 23 | (fp_line (start -10 -2.5) (end 10 -2.5) (layer "F.SilkS") (width 0.12) (tstamp f7925461-00b9-45fa-8499-f4088f9215ce)) 24 | (pad "1" thru_hole circle (at -8 0) (size 1.35 1.35) (drill 0.8) (layers *.Cu *.Mask) (tstamp 06cccf2c-d0d0-41ad-bc61-a0c3e7cbae93)) 25 | (pad "2" thru_hole circle (at -6 0) (size 1.35 1.35) (drill 0.8) (layers *.Cu *.Mask) (tstamp f23aaf25-de61-4f0e-9770-0b4e07746fe6)) 26 | (pad "3" thru_hole circle (at -4 0) (size 1.35 1.35) (drill 0.8) (layers *.Cu *.Mask) (tstamp c15af059-8b9d-458f-a49d-de88857a3451)) 27 | (pad "4" thru_hole circle (at -2 0) (size 1.35 1.35) (drill 0.8) (layers *.Cu *.Mask) (tstamp ccc51975-f79d-42b1-9218-b1bb4e005f58)) 28 | (pad "5" thru_hole circle (at 0 0) (size 1.35 1.35) (drill 0.8) (layers *.Cu *.Mask) (tstamp 6ac440ba-4881-4f79-8968-a3e9f9fd1b3e)) 29 | (pad "6" thru_hole circle (at 2 0) (size 1.35 1.35) (drill 0.8) (layers *.Cu *.Mask) (tstamp 284b4b05-f802-48af-884a-d2ca721ae34d)) 30 | (pad "7" thru_hole circle (at 4 0) (size 1.35 1.35) (drill 0.8) (layers *.Cu *.Mask) (tstamp 328427ae-624d-4ad5-9eae-c7dba1277b8f)) 31 | (pad "8" thru_hole circle (at 6 0) (size 1.35 1.35) (drill 0.8) (layers *.Cu *.Mask) (tstamp 9eb5fc74-7ee2-4483-b24f-769829d8a6c2)) 32 | (pad "9" thru_hole circle (at 8 0) (size 1.35 1.35) (drill 0.8) (layers *.Cu *.Mask) (tstamp 4ee7e00d-7ebf-4975-bd69-7b422f82b3e0)) 33 | ) 34 | -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/CartridgeComponents.pretty/Screen.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "Screen" (version 20211014) (generator pcbnew) 2 | (layer "F.Cu") 3 | (tedit 0) 4 | (attr through_hole) 5 | (fp_text reference "SCR**" (at 0.0254 -2.5908 unlocked) (layer "F.SilkS") 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | (tstamp 1241b7f2-e266-4f5c-8a97-9f0f9d0eef37) 8 | ) 9 | (fp_text value "Screen" (at 0 5.1816 unlocked) (layer "F.Fab") 10 | (effects (font (size 1 1) (thickness 0.15))) 11 | (tstamp 7d0dab95-9e7a-486e-a1d7-fc48860fd57d) 12 | ) 13 | (fp_text user "${REFERENCE}" (at 0 3.6322 unlocked) (layer "F.Fab") 14 | (effects (font (size 1 1) (thickness 0.15))) 15 | (tstamp 6241e6d3-a754-45b6-9f7c-e43019b93226) 16 | ) 17 | (fp_line (start -2.54 1.33) (end 5.14 1.33) (layer "F.SilkS") (width 0.12) (tstamp 1dfbf353-5b24-4c0f-8322-8fcd514ae75e)) 18 | (fp_line (start -2.54 1.33) (end -2.54 -1.33) (layer "F.SilkS") (width 0.12) (tstamp 2e0a9f64-1b78-4597-8d50-d12d2268a95a)) 19 | (fp_line (start -5.14 1.33) (end -5.14 0) (layer "F.SilkS") (width 0.12) (tstamp 582622a2-fad4-4737-9a80-be9fffbba8ab)) 20 | (fp_line (start 5.14 1.33) (end 5.14 -1.33) (layer "F.SilkS") (width 0.12) (tstamp 9aaeec6e-84fe-4644-b0bc-5de24626ff48)) 21 | (fp_line (start -3.81 1.33) (end -5.14 1.33) (layer "F.SilkS") (width 0.12) (tstamp d3e133b7-2c84-4206-a2b1-e693cb57fe56)) 22 | (fp_line (start -2.54 -1.33) (end 5.14 -1.33) (layer "F.SilkS") (width 0.12) (tstamp f988d6ea-11c5-4837-b1d1-5c292ded50c6)) 23 | (fp_rect (start -7.5 -1.4) (end 7.5 14.6) (layer "Dwgs.User") (width 0.12) (fill none) (tstamp 701e1517-e8cf-46f4-b538-98e721c97380)) 24 | (fp_rect (start -7.7 -1.6) (end 7.7 14.8) (layer "F.CrtYd") (width 0.05) (fill none) (tstamp ef4533db-6ea4-4b68-b436-8e9575be570d)) 25 | (fp_line (start 5.08 -1.27) (end 5.08 1.27) (layer "F.Fab") (width 0.1) (tstamp 59fc765e-1357-4c94-9529-5635418c7d73)) 26 | (fp_line (start 5.08 1.27) (end -4.445 1.27) (layer "F.Fab") (width 0.1) (tstamp 89a8e170-a222-41c0-b545-c9f4c5604011)) 27 | (fp_line (start -5.08 -1.27) (end 5.08 -1.27) (layer "F.Fab") (width 0.1) (tstamp 9529c01f-e1cd-40be-b7f0-83780a544249)) 28 | (fp_line (start -5.08 0.635) (end -5.08 -1.27) (layer "F.Fab") (width 0.1) (tstamp 96db52e2-6336-4f5e-846e-528c594d0509)) 29 | (fp_line (start -4.445 1.27) (end -5.08 0.635) (layer "F.Fab") (width 0.1) (tstamp d68e5ddb-039c-483f-88a3-1b0b7964b482)) 30 | (pad "1" thru_hole rect (at -3.81 0 90) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp be4b72db-0e02-4d9b-844a-aff689b4e648)) 31 | (pad "2" thru_hole oval (at -1.27 0 90) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 5889287d-b845-4684-b23e-663811b25d27)) 32 | (pad "3" thru_hole oval (at 1.27 0 90) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 38cfe839-c630-43d3-a9ec-6a89ba9e318a)) 33 | (pad "4" thru_hole oval (at 3.81 0 90) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 269f19c3-6824-45a8-be29-fa58d70cbb42)) 34 | ) 35 | -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-05-23_142327.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-05-23_142327.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-05-23_150242.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-05-23_150242.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-05-23_171754.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-05-23_171754.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-05-24_175259.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-05-24_175259.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-05-30_125634.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-05-30_125634.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-05-30_130710.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-05-30_130710.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-07-29_001629.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-07-29_001629.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-07-29_010023.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-07-29_010023.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-07-30_123117.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-07-30_123117.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-07-30_163305.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-07-30_163305.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-07-31_111700.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-07-31_111700.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-07-31_143906.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-07-31_143906.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-07-31_222643.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-07-31_222643.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-09-20_052350.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-09-20_052350.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-09-20_205039.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-09-20_205039.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-09-22_121901.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-09-22_121901.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-09-22_180210.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-09-22_180210.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-10-02_193844.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-10-02_193844.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-10-02_194415.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-10-02_194415.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-10-02_195242.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-10-02_195242.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-10-02_212053.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-10-02_212053.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-10-08_100613.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-10-08_100613.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-10-09_011235.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-10-09_011235.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-10-13_211810.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-10-13_211810.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-11-03_022304.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-11-03_022304.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-11-03_214532.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge-backups/MicroPicoDriveCartridge-2023-11-03_214532.zip -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/MicroPicoDriveCartridge.kicad_prl: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "active_layer": 44, 4 | "active_layer_preset": "", 5 | "auto_track_width": true, 6 | "hidden_nets": [], 7 | "high_contrast_mode": 0, 8 | "net_color_mode": 1, 9 | "opacity": { 10 | "pads": 1.0, 11 | "tracks": 1.0, 12 | "vias": 1.0, 13 | "zones": 0.6 14 | }, 15 | "ratsnest_display_mode": 0, 16 | "selection_filter": { 17 | "dimensions": true, 18 | "footprints": true, 19 | "graphics": true, 20 | "keepouts": true, 21 | "lockedItems": true, 22 | "otherItems": true, 23 | "pads": true, 24 | "text": true, 25 | "tracks": true, 26 | "vias": true, 27 | "zones": true 28 | }, 29 | "visible_items": [ 30 | 0, 31 | 1, 32 | 2, 33 | 3, 34 | 4, 35 | 5, 36 | 8, 37 | 9, 38 | 10, 39 | 11, 40 | 12, 41 | 13, 42 | 14, 43 | 15, 44 | 16, 45 | 17, 46 | 18, 47 | 19, 48 | 20, 49 | 21, 50 | 22, 51 | 23, 52 | 24, 53 | 25, 54 | 26, 55 | 27, 56 | 28, 57 | 29, 58 | 30, 59 | 32, 60 | 33, 61 | 34, 62 | 35, 63 | 36 64 | ], 65 | "visible_layers": "fffffff_80000001", 66 | "zone_display_mode": 0 67 | }, 68 | "meta": { 69 | "filename": "MicroPicoDriveCartridge.kicad_prl", 70 | "version": 3 71 | }, 72 | "project": { 73 | "files": [] 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name "CartridgeComponents")(type "KiCad")(uri "F:/KiCad/Proyectos/MicroPicoDrive/MicroPicoDriveCartridge/CartridgeComponents.pretty")(options "")(descr "")) 3 | ) 4 | -------------------------------------------------------------------------------- /Hardware/MicroPicoDriveCartridge/MicroPicoDriveCartridge/sym-lib-table: -------------------------------------------------------------------------------- 1 | (sym_lib_table 2 | (lib (name "CartridgeComponents")(type "KiCad")(uri "F:/KiCad/Proyectos/MicroPicoDrive/MicroPicoDriveCartridge/CartridgeComponents.kicad_sym")(options "")(descr "")) 3 | ) 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Agustín Gimenez Bernad 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MicroPicoDrive - An internal replacement of the Sinclair QL Microdrive. 2 | 3 | ## UPDATE 22/03/2023 4 | 5 | The device has been tested and patched to work with Minerva. Yup! 6 | Also, the PCB has been modified, it should now be correctly placed but I'm waiting to receive a new batch of PCB's, until then I can't ensure 100% that it is totally fixed. 7 | 8 | The Wiki has been set in place with documentation on how to assemble and use the device. 9 | 10 | The BOM has been added to the Hardware folder and contains links to the more uncommon components. 11 | 12 | Have fun! 13 | 14 | # Initial commit 15 | 16 | WARNING! This is a work in progress, I need to test it with Minerva ROM and do some adjustments to the PCB, be ware! 17 | 18 | So, I got a Sinclair QL some months ago, I wanted one for many many years, I'm a Sinclair fan and I always have been in the Spectrum world and the QL always has been something that I wanted to get. 19 | The unit I got was a broken one, it was stored since the 80's in a repair shop, when I got it the machine was non-working, without microdrives, with a faulty membrane and without a single screw, so the first that I did was to repair it. 20 | 21 | And once I got it fully working I wanted to load something, but without microdrives it was a bit difficult... xD 22 | 23 | I checked which solutions were available but I didn't liked none so I decided to create my own replacement, armed with my [logic analizer](https://github.com/gusmanb/logicanalyzer) and patience I learnt the internals of the microdrive protocol and created an internal replacement that uses "cartridges" and can be installed in the internal space of the QL. 24 | 25 | And this is what I got: 26 | 27 | ![IMG_20230919_020735](https://github.com/gusmanb/micropicodrive/assets/4086913/33d1c477-5055-4630-a182-1f720620ed9e) 28 | ![IMG_20230919_020740](https://github.com/gusmanb/micropicodrive/assets/4086913/d03f2089-6421-410a-b68f-075cdda09699) 29 | 30 | The device is based in an RP2040 (I love the PIO units, those damn things are a wonder!) and some level shifters... and that's it. Well, that's it for the internal unit, there is also a screen, some buttons and an SD card holder for the cartridge! 31 | 32 | ![IMG_20230919_021006](https://github.com/gusmanb/micropicodrive/assets/4086913/a702383c-78bb-46b4-889f-02ecd6c4707d) 33 | ![IMG_20230919_021144](https://github.com/gusmanb/micropicodrive/assets/4086913/b51687d6-f8bf-4490-ace4-03ce6e5b20b0) 34 | 35 | The thing is completelly working with the stock rom, it can load programs without problems, can format cartridges, store images, etc, all without problems. 36 | 37 | ![IMG_20230919_021200](https://github.com/gusmanb/micropicodrive/assets/4086913/f3bd98f9-7f8e-4986-9b22-3d015cdf9be5) 38 | ![IMG_20230919_021312](https://github.com/gusmanb/micropicodrive/assets/4086913/9525a51d-6cf1-495c-8d3a-bfe2cf339633) 39 | 40 | Also, I found that a lot of the software is stored as Zip files, the device right now supports MDV, IMG and my own custom format, so I checked the available utilities to manipulate MDV images and... it was a boomer to find that there is no updated one, only mdvtools that is ancient and after compiling manually it I found that most of the converted images were flawed. 41 | 42 | So, again, I decided to create mi own solution, and this is what I finally got: 43 | 44 | ![imagen](https://github.com/gusmanb/micropicodrive/assets/4086913/4f412604-17ac-4195-a32c-49bdbf13fb4a) 45 | ![imagen](https://github.com/gusmanb/micropicodrive/assets/4086913/f6bb86fa-ec53-434f-914e-1e64be1dfd91) 46 | 47 | It can create MDV images from the ground, import MDV and ZIP files (and yes, it supports the QL zip format, it preserves the executable and data space attributes), manipulate the existing files, extract them, etc, so with this finally I got a full toolset for the QL! 48 | 49 | Now I'm waiting for the components to build a 512Kb RAM expansion and from there I don't know where I will continue, may be a floppy drive emulator? IDE interface? Not sure, but the first is to add those 512Kb and a Minerva ROM to test the microdrive. 50 | 51 | In any case, this is a work in progress, beware that I need to do some adjustments to the PCB and finish some tools for the software. 52 | 53 | If you want more info don't esitate to contact me. 54 | 55 | Have fun! 56 | -------------------------------------------------------------------------------- /Software/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Oo]ut/ 33 | [Ll]og/ 34 | [Ll]ogs/ 35 | 36 | # Visual Studio 2015/2017 cache/options directory 37 | .vs/ 38 | # Uncomment if you have tasks that create the project's static files in wwwroot 39 | #wwwroot/ 40 | 41 | # Visual Studio 2017 auto generated files 42 | Generated\ Files/ 43 | 44 | # MSTest test Results 45 | [Tt]est[Rr]esult*/ 46 | [Bb]uild[Ll]og.* 47 | 48 | # NUnit 49 | *.VisualState.xml 50 | TestResult.xml 51 | nunit-*.xml 52 | 53 | # Build Results of an ATL Project 54 | [Dd]ebugPS/ 55 | [Rr]eleasePS/ 56 | dlldata.c 57 | 58 | # Benchmark Results 59 | BenchmarkDotNet.Artifacts/ 60 | 61 | # .NET Core 62 | project.lock.json 63 | project.fragment.lock.json 64 | artifacts/ 65 | 66 | # ASP.NET Scaffolding 67 | ScaffoldingReadMe.txt 68 | 69 | # StyleCop 70 | StyleCopReport.xml 71 | 72 | # Files built by Visual Studio 73 | *_i.c 74 | *_p.c 75 | *_h.h 76 | *.ilk 77 | *.meta 78 | *.obj 79 | *.iobj 80 | *.pch 81 | *.pdb 82 | *.ipdb 83 | *.pgc 84 | *.pgd 85 | *.rsp 86 | *.sbr 87 | *.tlb 88 | *.tli 89 | *.tlh 90 | *.tmp 91 | *.tmp_proj 92 | *_wpftmp.csproj 93 | *.log 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio LightSwitch build output 298 | **/*.HTMLClient/GeneratedArtifacts 299 | **/*.DesktopClient/GeneratedArtifacts 300 | **/*.DesktopClient/ModelManifest.xml 301 | **/*.Server/GeneratedArtifacts 302 | **/*.Server/ModelManifest.xml 303 | _Pvt_Extensions 304 | 305 | # Paket dependency manager 306 | .paket/paket.exe 307 | paket-files/ 308 | 309 | # FAKE - F# Make 310 | .fake/ 311 | 312 | # CodeRush personal settings 313 | .cr/personal 314 | 315 | # Python Tools for Visual Studio (PTVS) 316 | __pycache__/ 317 | *.pyc 318 | 319 | # Cake - Uncomment if you are using it 320 | # tools/** 321 | # !tools/packages.config 322 | 323 | # Tabs Studio 324 | *.tss 325 | 326 | # Telerik's JustMock configuration file 327 | *.jmconfig 328 | 329 | # BizTalk build output 330 | *.btp.cs 331 | *.btm.cs 332 | *.odx.cs 333 | *.xsd.cs 334 | 335 | # OpenCover UI analysis results 336 | OpenCover/ 337 | 338 | # Azure Stream Analytics local run output 339 | ASALocalRun/ 340 | 341 | # MSBuild Binary and Structured Log 342 | *.binlog 343 | 344 | # NVidia Nsight GPU debugger configuration file 345 | *.nvuser 346 | 347 | # MFractors (Xamarin productivity tool) working folder 348 | .mfractor/ 349 | 350 | # Local History for Visual Studio 351 | .localhistory/ 352 | 353 | # BeatPulse healthcheck temp database 354 | healthchecksdb 355 | 356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 357 | MigrationBackup/ 358 | 359 | # Ionide (cross platform F# VS Code tools) working folder 360 | .ionide/ 361 | 362 | # Fody - auto-generated XML schema 363 | FodyWeavers.xsd 364 | 365 | #Releases folder 366 | Releases/ 367 | 368 | #Firmware build files 369 | Firmware/LogicAnalyzer/build/ 370 | -------------------------------------------------------------------------------- /Software/MDTools/MDTools.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Software/MDTools/Program.cs: -------------------------------------------------------------------------------- 1 | using MicroDriveTools.Classes; 2 | 3 | MicroDriveDirectory? currentDirectory = null; 4 | 5 | Console.WriteLine("Welcome to MicroDrive Tools V1.0"); 6 | 7 | while (MainMenu()) ; 8 | 9 | Console.WriteLine("Bye!"); 10 | 11 | bool MainMenu() 12 | { 13 | Console.WriteLine(); 14 | Console.WriteLine("Choose an option:"); 15 | Console.WriteLine(); 16 | Console.WriteLine("1. Create new directory"); 17 | Console.WriteLine("2. Import cartridge"); 18 | Console.WriteLine("3. Import zip file"); 19 | Console.WriteLine("4. Import regular file"); 20 | Console.WriteLine("5. View current directory"); 21 | Console.WriteLine("6. Remove file from directory"); 22 | Console.WriteLine("7. Export cartridge"); 23 | Console.WriteLine("8. Exit"); 24 | Console.WriteLine(); 25 | 26 | Console.Write("Option: "); 27 | switch(Console.ReadLine()) 28 | { 29 | case "1": 30 | CreateNewDirectory(); 31 | return true; 32 | case "2": 33 | ImportCartridge(); 34 | return true; 35 | case "3": 36 | ImportZIPFile(); 37 | return true; 38 | case "4": 39 | ImportRegularFile(); 40 | return true; 41 | case "5": 42 | ViewDirectory(); 43 | return true; 44 | case "6": 45 | RemoveFile(); 46 | return true; 47 | case "7": 48 | ExportCartridge(); 49 | return true; 50 | case "8": 51 | return false; 52 | default: 53 | Console.WriteLine("Invalid option"); 54 | return true; 55 | } 56 | } 57 | void ExportCartridge() 58 | { 59 | try 60 | { 61 | if (currentDirectory == null) 62 | { 63 | Console.WriteLine("There is no directory loaded. Do you want to create a new one? (Y/N)"); 64 | if (Console.ReadLine()?.ToUpper() != "Y") 65 | return; 66 | 67 | CreateNewDirectory(); 68 | } 69 | 70 | Console.WriteLine("Enter cartridge file name:"); 71 | string fileName = Console.ReadLine(); 72 | 73 | Console.WriteLine("Enter medium name:"); 74 | string mediumName = Console.ReadLine(); 75 | 76 | MicroDriveCartridge cartridge = new MicroDriveCartridge(currentDirectory, mediumName); 77 | cartridge.SaveMDV(fileName); 78 | 79 | Console.WriteLine("Cartridge saved."); 80 | } 81 | catch(Exception ex) 82 | { 83 | Console.WriteLine($"Error exporting cartridge: {ex.Message}"); 84 | } 85 | 86 | } 87 | void RemoveFile() 88 | { 89 | try 90 | { 91 | if (currentDirectory == null) 92 | { 93 | Console.WriteLine("There is no directory loaded. Do you want to create a new one? (Y/N)"); 94 | if (Console.ReadLine()?.ToUpper() != "Y") 95 | return; 96 | 97 | CreateNewDirectory(); 98 | } 99 | 100 | Console.WriteLine("Enter file name:"); 101 | 102 | string fileName = Console.ReadLine(); 103 | 104 | if (!currentDirectory.RemoveFile(fileName)) 105 | Console.WriteLine("File not found."); 106 | else 107 | Console.WriteLine("File removed from directory."); 108 | } 109 | catch(Exception ex) 110 | { 111 | Console.WriteLine($"Error removing file: {ex.Message}"); 112 | } 113 | } 114 | void ViewDirectory() 115 | { 116 | try 117 | { 118 | if (currentDirectory == null) 119 | { 120 | Console.WriteLine("There is no directory loaded. Do you want to create a new one? (Y/N)"); 121 | if (Console.ReadLine()?.ToUpper() != "Y") 122 | return; 123 | 124 | CreateNewDirectory(); 125 | } 126 | 127 | Console.WriteLine("Directory contents:"); 128 | 129 | Console.WriteLine(); 130 | 131 | foreach (var file in currentDirectory.Files) 132 | { 133 | Console.WriteLine($"{file.Header.FileName} ({file.Header.FileLength} bytes, {(file.Header.FileType == 1 ? "Executable" : "Regular file")})"); 134 | } 135 | 136 | Console.WriteLine(); 137 | 138 | Console.WriteLine("Listing complete."); 139 | } 140 | catch(Exception ex) 141 | { 142 | Console.WriteLine($"Error viewing directory: {ex.Message}"); 143 | } 144 | } 145 | void ImportRegularFile() 146 | { 147 | try 148 | { 149 | if (currentDirectory == null) 150 | { 151 | Console.WriteLine("There is no directory loaded. Do you want to create a new one? (Y/N)"); 152 | if (Console.ReadLine()?.ToUpper() != "Y") 153 | return; 154 | 155 | CreateNewDirectory(); 156 | } 157 | 158 | Console.WriteLine("Enter file name:"); 159 | string fileName = Console.ReadLine(); 160 | 161 | if (!File.Exists(fileName)) 162 | { 163 | Console.WriteLine("File not found."); 164 | return; 165 | } 166 | 167 | string storeName = Path.GetFileName(fileName).Replace(".", "_"); 168 | 169 | Console.WriteLine($"Enter file name for storage (default: {storeName}):"); 170 | 171 | string? storeName2 = Console.ReadLine(); 172 | 173 | if (!string.IsNullOrEmpty(storeName2)) 174 | storeName = storeName2; 175 | 176 | byte[] data = File.ReadAllBytes(fileName); 177 | Console.WriteLine("Is this file executable? (Y/N)"); 178 | 179 | if (Console.ReadLine()?.ToUpper() == "Y") 180 | { 181 | Console.WriteLine("Enter data space:"); 182 | uint dataSpace = uint.Parse(Console.ReadLine() ?? "0"); 183 | 184 | currentDirectory.AddFile(new MicroDriveFile(storeName, data, true, dataSpace)); 185 | } 186 | else 187 | currentDirectory.AddFile(new MicroDriveFile(storeName, data)); 188 | 189 | Console.WriteLine("File added to directory."); 190 | } 191 | catch(Exception ex) 192 | { 193 | Console.WriteLine($"Error importing file: {ex.Message}"); 194 | } 195 | } 196 | void ImportZIPFile() 197 | { 198 | try 199 | { 200 | Console.WriteLine("Enter zip file name:"); 201 | string fileName = Console.ReadLine(); 202 | 203 | if (!File.Exists(fileName)) 204 | { 205 | Console.WriteLine("File not found."); 206 | return; 207 | } 208 | 209 | MicroDriveDirectory directory = ZIPImporter.ImportZIPFile(fileName); 210 | if (currentDirectory == null) 211 | { 212 | currentDirectory = directory; 213 | Console.WriteLine("Directory loaded from zip file."); 214 | } 215 | else 216 | { 217 | foreach (var file in directory.Files) 218 | currentDirectory.AddFile(file); 219 | 220 | Console.WriteLine("Zip file merged with directory."); 221 | } 222 | } 223 | catch(Exception ex) 224 | { 225 | Console.WriteLine($"Error importing zip file: {ex.Message}"); 226 | } 227 | } 228 | void ImportCartridge() 229 | { 230 | try 231 | { 232 | Console.WriteLine("Enter cartridge file name:"); 233 | string fileName = Console.ReadLine(); 234 | 235 | if (!File.Exists(fileName)) 236 | { 237 | Console.WriteLine("File not found."); 238 | return; 239 | } 240 | 241 | MicroDriveCartridge cartridge = MicroDriveCartridge.LoadMDV(fileName); 242 | if (currentDirectory == null) 243 | { 244 | currentDirectory = cartridge.Directory; 245 | Console.WriteLine("Directory imported from cartridge."); 246 | } 247 | else 248 | { 249 | foreach (var file in cartridge.Directory.Files) 250 | currentDirectory.AddFile(file); 251 | 252 | Console.WriteLine("Cartridge directory merged with current directory."); 253 | } 254 | } 255 | catch(Exception ex) 256 | { 257 | Console.WriteLine($"Error importing cartridge: {ex.Message}"); 258 | } 259 | } 260 | void CreateNewDirectory() 261 | { 262 | try 263 | { 264 | if (currentDirectory != null) 265 | { 266 | Console.WriteLine("There is already a directory loaded. Do you want to discard it? (Y/N)"); 267 | if (Console.ReadLine()?.ToUpper() != "Y") 268 | return; 269 | } 270 | 271 | currentDirectory = new MicroDriveDirectory(); 272 | 273 | Console.WriteLine("Directory created."); 274 | } 275 | catch(Exception ex) 276 | { 277 | Console.WriteLine($"Error creating directory: {ex.Message}"); 278 | } 279 | } -------------------------------------------------------------------------------- /Software/MDToolsUI/BatchConverter.cs: -------------------------------------------------------------------------------- 1 | using MicroDriveTools.Classes; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Terminal.Gui; 8 | 9 | namespace MDToolsUI 10 | { 11 | public class BatchConverter : Dialog 12 | { 13 | CheckBox ckFix; 14 | string[]? selectedNames; 15 | Button? btnConvert; 16 | Button? btnCancel; 17 | 18 | public BatchConverter() 19 | { 20 | Title = "Batch converter"; 21 | Width = 30; 22 | Height = 10; 23 | ckFix = new CheckBox("Fix drives") { Checked = true, X = Pos.Center(), Y = 1 }; 24 | 25 | Add(ckFix); 26 | 27 | Button btnSelectFiles = new Button("Select files") { X = Pos.Center(), Y = 3 }; 28 | btnSelectFiles.X = Pos.Center(); 29 | 30 | btnSelectFiles.Clicked += () => 31 | { 32 | var dlg = new OpenDialog("Select files", "Select files to convert", new List() { ".zip", ".mdv", ".*" }, OpenDialog.OpenMode.File) { AllowsMultipleSelection = true } ; 33 | 34 | Application.Run(dlg); 35 | 36 | if (!dlg.Canceled && dlg.FilePaths != null && dlg.FilePaths.Count > 0) 37 | selectedNames = dlg.FilePaths.ToArray(); 38 | else 39 | selectedNames = null; 40 | 41 | if(btnConvert != null) 42 | btnConvert.Enabled = selectedNames != null && selectedNames.Length > 0; 43 | }; 44 | 45 | Add(btnSelectFiles); 46 | } 47 | 48 | public override void OnLoaded() 49 | { 50 | base.OnLoaded(); 51 | btnConvert = new Button("Convert"); 52 | btnConvert.Clicked += () => 53 | { 54 | if (selectedNames == null || selectedNames.Length == 0) 55 | return; 56 | 57 | var dlg = new OpenDialog("Destination", "Select destination folder", null, OpenDialog.OpenMode.Directory); 58 | 59 | Application.Run(dlg); 60 | 61 | if (dlg.Canceled || dlg.FilePath == null) 62 | return; 63 | 64 | var dest = dlg.FilePath.ToString(); 65 | 66 | string[]? fixNames = null; 67 | 68 | if (ckFix.Checked) 69 | { 70 | var nameSelector = new DeviceNameSelector(); 71 | Application.Run(nameSelector); 72 | 73 | if (nameSelector.SelectedNames != null && nameSelector.SelectedNames.Length > 0) 74 | fixNames = nameSelector.SelectedNames; 75 | else 76 | return; 77 | } 78 | 79 | foreach(var file in selectedNames) 80 | { 81 | try 82 | { 83 | ushort? mediumId = null; 84 | string mediumName = null; 85 | 86 | MicroDriveDirectory? dir = null; 87 | 88 | if (file.EndsWith(".zip")) 89 | { 90 | dir = ZIPImporter.ImportZIPFile(file); 91 | mediumName = System.IO.Path.GetFileNameWithoutExtension(file).Replace(".", "_"); 92 | } 93 | else if (file.EndsWith(".mdv")) 94 | { 95 | var mdv = MicroDriveCartridge.LoadMDV(file); 96 | dir = mdv.Directory; 97 | mediumId = mdv.Sectors[0].Header.MediumId; 98 | mediumName = mdv.Sectors[0].Header.MediumName; 99 | } 100 | else 101 | { 102 | MessageBox.ErrorQuery("Error", $"Unsupported file type: {System.IO.Path.GetExtension(file)}.", "Ok"); 103 | return; 104 | } 105 | 106 | if (mediumName.Length > 10) 107 | mediumName = mediumName.Substring(0, 10); 108 | 109 | if (fixNames != null) 110 | { 111 | foreach (var bFile in dir.Files) 112 | { 113 | byte[] data = bFile.Data; 114 | Utils.ReplaceDriveNames(data, fixNames); 115 | bFile.UpdateData(data); 116 | 117 | } 118 | } 119 | 120 | MicroDriveCartridge cartridge = new MicroDriveCartridge(dir, mediumName, MicroDriveCartridge.MicroDriveSectorStrategy.Spaced, mediumId); 121 | 122 | var newFile = System.IO.Path.Combine(dest, System.IO.Path.GetFileNameWithoutExtension(file) + ".mdv"); 123 | 124 | cartridge.SaveMDV(newFile); 125 | } 126 | catch(Exception ex) { MessageBox.ErrorQuery("Error", $"Error converting file \"{Path.GetFileName(file)}\": {ex.Message}.", "Ok"); return; } 127 | } 128 | 129 | MessageBox.Query("Done", "Conversion completed.", "Ok"); 130 | 131 | Application.RequestStop(); 132 | }; 133 | btnConvert.Enabled = false; 134 | 135 | btnCancel = new Button("Cancel"); 136 | btnCancel.Clicked += () => 137 | { 138 | Application.RequestStop(); 139 | }; 140 | 141 | AddButton(btnConvert); 142 | AddButton(btnCancel); 143 | 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /Software/MDToolsUI/DeviceNameSelector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Terminal.Gui; 7 | 8 | namespace MDToolsUI 9 | { 10 | public class DeviceNameSelector : Dialog 11 | { 12 | CheckBox ckFlp; 13 | CheckBox ckFdk; 14 | CheckBox ckDsk; 15 | CheckBox ckDrv; 16 | public string[]? SelectedNames { get; set; } 17 | public DeviceNameSelector() 18 | { 19 | Title = "Select device names"; 20 | 21 | Width = 25; 22 | Height = 9; 23 | 24 | ckFlp = new CheckBox(9, 1, "flp") { Checked = true }; 25 | ckFdk = new CheckBox(9, 2, "fdk") { Checked = true }; 26 | ckDsk = new CheckBox(9, 3, "dsk") { Checked = true }; 27 | ckDrv = new CheckBox(9, 4, "drv") { Checked = true }; 28 | 29 | Add(ckFlp); 30 | Add(ckFdk); 31 | Add(ckDsk); 32 | Add(ckDrv); 33 | } 34 | 35 | public override void OnLoaded() 36 | { 37 | base.OnLoaded(); 38 | 39 | Button ok = new Button("Ok"); 40 | ok.Clicked += () => 41 | { 42 | 43 | if(!ckFlp.Checked && !ckFdk.Checked && !ckDsk.Checked && !ckDrv.Checked) 44 | { 45 | MessageBox.ErrorQuery(Title, "At least one device name must be selected.", "Ok"); 46 | return; 47 | } 48 | 49 | List selectedNames = new List(); 50 | if (ckFlp.Checked) selectedNames.Add("flp"); 51 | if (ckFdk.Checked) selectedNames.Add("fdk"); 52 | if (ckDsk.Checked) selectedNames.Add("dsk"); 53 | if (ckDrv.Checked) selectedNames.Add("drv"); 54 | SelectedNames = selectedNames.ToArray(); 55 | 56 | Application.RequestStop(); 57 | }; 58 | 59 | AddButton(ok); 60 | 61 | Button cancel = new Button("Cancel"); 62 | cancel.Clicked += () => 63 | { 64 | SelectedNames = null; 65 | Application.RequestStop(); 66 | }; 67 | 68 | AddButton(cancel); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Software/MDToolsUI/InputBox.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Terminal.Gui; 7 | 8 | namespace MDToolsUI 9 | { 10 | public class InputBox : Dialog 11 | { 12 | TextField input; 13 | public string? Input { get; set; } 14 | public InputBox(string Title, string Prompt, string Default = "") 15 | { 16 | 17 | this.Title = Title; 18 | Width = Dim.Percent(50); 19 | Height = 8; 20 | Label prompt = new Label(1, 1, Prompt); 21 | 22 | Add(prompt); 23 | 24 | input = new TextField(Default); 25 | input.X = Pos.Center(); 26 | input.Y = 3; 27 | input.Width = Dim.Fill(2); 28 | Add(input); 29 | } 30 | 31 | public override void OnLoaded() 32 | { 33 | base.OnLoaded(); 34 | 35 | Button ok = new Button("Ok"); 36 | ok.Clicked += () => 37 | { 38 | 39 | if (string.IsNullOrWhiteSpace(input.Text.ToString())) 40 | { 41 | MessageBox.ErrorQuery(Title, "Input cannot be empty.", "Ok"); 42 | return; 43 | } 44 | 45 | Input = input.Text.ToString(); 46 | Application.RequestStop(); 47 | }; 48 | 49 | AddButton(ok); 50 | 51 | Button cancel = new Button("Cancel"); 52 | cancel.Clicked += () => 53 | { 54 | Input = null; 55 | Application.RequestStop(); 56 | }; 57 | 58 | AddButton(cancel); 59 | 60 | input.SetFocus(); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Software/MDToolsUI/MDToolsUI.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Software/MDToolsUI/MDToolsUI.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | <_LastSelectedProfileId>C:\Users\geniw\source\repos\MicroDriveTools\MDToolsUI\Properties\PublishProfiles\FolderProfile.pubxml 5 | 6 | -------------------------------------------------------------------------------- /Software/MDToolsUI/MediaInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Terminal.Gui; 7 | 8 | namespace MDToolsUI 9 | { 10 | public class MediaInfo : Dialog 11 | { 12 | 13 | string? selectedName; 14 | ushort? selectedId; 15 | 16 | public string? MediaName { get { return selectedName; } } 17 | public ushort? MediaId { get { return selectedId; } } 18 | 19 | TextField mediaName; 20 | CheckBox ckSpecify; 21 | TextField mediaId; 22 | 23 | public MediaInfo(string DefaultName) 24 | { 25 | Title = "Media Info"; 26 | Width = Dim.Percent(50); 27 | Height = 12; 28 | 29 | Label prompt = new Label(2, 1, "Media name"); 30 | 31 | Add(prompt); 32 | 33 | mediaName = new TextField(DefaultName); 34 | mediaName.X = 2; 35 | mediaName.Y = 3; 36 | mediaName.Width = Dim.Fill(2); 37 | 38 | Add(mediaName); 39 | 40 | ckSpecify = new CheckBox(2, 5, "Specify media ID"); 41 | ckSpecify.Toggled += (e) => 42 | { 43 | mediaId.Enabled = ckSpecify.Checked; 44 | }; 45 | 46 | Add(ckSpecify); 47 | 48 | mediaId = new TextField("0x0000"); 49 | mediaId.X = 2; 50 | mediaId.Y = 7; 51 | mediaId.Width = Dim.Fill(2); 52 | mediaId.Enabled = false; 53 | Add(mediaId); 54 | 55 | } 56 | 57 | public override void OnLoaded() 58 | { 59 | base.OnLoaded(); 60 | 61 | Button ok = new Button("Ok"); 62 | ok.Clicked += () => 63 | { 64 | 65 | if (string.IsNullOrWhiteSpace(mediaName.Text.ToString())) 66 | { 67 | MessageBox.ErrorQuery(Title, "Media name cannot be empty.", "Ok"); 68 | return; 69 | } 70 | 71 | ushort id = 0; 72 | 73 | if (ckSpecify.Checked)// && !ushort.TryParse(mediaId.Text.ToString(), System.Globalization.NumberStyles.HexNumber, null, out id)) 74 | { 75 | string? strId = mediaId.Text.ToString()?.Trim(); 76 | 77 | if (strId == null || strId.Length == 0) 78 | { 79 | MessageBox.ErrorQuery(Title, "Invalid media ID.", "Ok"); 80 | return; 81 | } 82 | 83 | if (strId.StartsWith("0x")) 84 | strId = strId.Substring(2); 85 | 86 | if (!ushort.TryParse(strId, System.Globalization.NumberStyles.HexNumber, null, out id)) 87 | { 88 | MessageBox.ErrorQuery(Title, "Invalid media ID.", "Ok"); 89 | return; 90 | } 91 | 92 | selectedId = id; 93 | } 94 | else 95 | selectedId = null; 96 | 97 | selectedName = mediaName.Text.ToString(); 98 | Application.RequestStop(); 99 | }; 100 | 101 | AddButton(ok); 102 | 103 | Button cancel = new Button("Cancel"); 104 | cancel.Clicked += () => 105 | { 106 | selectedName = null; 107 | selectedId = null; 108 | Application.RequestStop(); 109 | }; 110 | 111 | AddButton(cancel); 112 | 113 | mediaName.SetFocus(); 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /Software/MDToolsUI/Program.cs: -------------------------------------------------------------------------------- 1 | // See https://aka.ms/new-console-template for more information 2 | using MDToolsUI; 3 | using MicroDriveTools.Classes; 4 | using System.Xml.Serialization; 5 | using Terminal.Gui; 6 | 7 | Application.Run(); 8 | Application.Shutdown(); -------------------------------------------------------------------------------- /Software/MDToolsUI/Properties/PublishProfiles/FolderProfile.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | bin\Release\net7.0\publish\win-x64\ 10 | FileSystem 11 | <_TargetId>Folder 12 | net8.0 13 | win-x64 14 | true 15 | false 16 | true 17 | true 18 | 19 | -------------------------------------------------------------------------------- /Software/MDToolsUI/Properties/PublishProfiles/FolderProfile.pubxml.user: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | True|2023-09-22T12:50:44.5446162Z;True|2023-09-18T15:00:00.1534792+02:00; 8 | 9 | 10 | -------------------------------------------------------------------------------- /Software/MDToolsUI/Properties/PublishProfiles/FolderProfile1.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | bin\Release\net7.0\publish\linux-x64\ 10 | FileSystem 11 | <_TargetId>Folder 12 | net7.0 13 | linux-x64 14 | true 15 | true 16 | true 17 | 18 | -------------------------------------------------------------------------------- /Software/MDToolsUI/Properties/PublishProfiles/FolderProfile1.pubxml.user: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | True|2023-09-22T12:50:19.9512526Z;True|2023-09-18T15:01:33.7322630+02:00; 8 | 9 | 10 | -------------------------------------------------------------------------------- /Software/MDToolsUI/Utils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace MDToolsUI 8 | { 9 | public static class Utils 10 | { 11 | public static int ReplaceDriveNames(byte[] data, string[] names) 12 | { 13 | int occurrences = 0; 14 | 15 | foreach (var name in names) 16 | { 17 | byte[] binName = Encoding.ASCII.GetBytes(name); 18 | 19 | occurrences += ReplaceDriveName(data, binName); 20 | } 21 | 22 | return occurrences; 23 | } 24 | public static int ReplaceDriveName(byte[] data, byte[] binName) 25 | { 26 | int occurrences = 0; 27 | 28 | byte[] finalName = new byte[4]; 29 | Array.Copy(binName, finalName, binName.Length); 30 | 31 | finalName[3] = Encoding.ASCII.GetBytes("1")[0]; 32 | 33 | byte[] replaceName = Encoding.ASCII.GetBytes("mdv1"); 34 | 35 | int[] matches = SearchBytePattern(finalName, data); 36 | 37 | foreach (var match in matches) 38 | Array.Copy(replaceName, 0, data, match, replaceName.Length); 39 | 40 | occurrences += matches.Length; 41 | 42 | finalName[3] = Encoding.ASCII.GetBytes("2")[0]; 43 | replaceName = Encoding.ASCII.GetBytes("mdv2"); 44 | 45 | matches = SearchBytePattern(finalName, data); 46 | 47 | foreach (var match in matches) 48 | Array.Copy(replaceName, 0, data, match, replaceName.Length); 49 | 50 | occurrences += matches.Length; 51 | 52 | return occurrences; 53 | } 54 | 55 | private static int[] SearchBytePattern(byte[] pattern, byte[] bytes) 56 | { 57 | List positions = new List(); 58 | int patternLength = pattern.Length; 59 | int totalLength = bytes.Length; 60 | byte firstMatchByte = pattern[0]; 61 | for (int i = 0; i < totalLength; i++) 62 | { 63 | if (firstMatchByte == bytes[i] && totalLength - i >= patternLength) 64 | { 65 | byte[] match = new byte[patternLength]; 66 | Array.Copy(bytes, i, match, 0, patternLength); 67 | if (match.SequenceEqual(pattern)) 68 | { 69 | positions.Add(i); 70 | i += patternLength - 1; 71 | } 72 | } 73 | } 74 | return positions.ToArray(); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Software/MicroDriveTools.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33213.308 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MicroDriveTools", "MicroDriveTools\MicroDriveTools.csproj", "{843E6436-E020-41AE-B0C5-6EAE9BBAD1BD}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestTools", "TestTools\TestTools.csproj", "{5FB9D59B-0748-45A2-B9B6-37A6ABB662BA}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MDTools", "MDTools\MDTools.csproj", "{A0286626-9BFF-4AC3-A5D1-C0DEA72F1AB3}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MDToolsUI", "MDToolsUI\MDToolsUI.csproj", "{F9B7FDAA-2388-40C8-93DB-C6DBD65DCD9B}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Any CPU = Debug|Any CPU 17 | Release|Any CPU = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {843E6436-E020-41AE-B0C5-6EAE9BBAD1BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {843E6436-E020-41AE-B0C5-6EAE9BBAD1BD}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {843E6436-E020-41AE-B0C5-6EAE9BBAD1BD}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {843E6436-E020-41AE-B0C5-6EAE9BBAD1BD}.Release|Any CPU.Build.0 = Release|Any CPU 24 | {5FB9D59B-0748-45A2-B9B6-37A6ABB662BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {5FB9D59B-0748-45A2-B9B6-37A6ABB662BA}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {5FB9D59B-0748-45A2-B9B6-37A6ABB662BA}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {5FB9D59B-0748-45A2-B9B6-37A6ABB662BA}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {A0286626-9BFF-4AC3-A5D1-C0DEA72F1AB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {A0286626-9BFF-4AC3-A5D1-C0DEA72F1AB3}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {A0286626-9BFF-4AC3-A5D1-C0DEA72F1AB3}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {A0286626-9BFF-4AC3-A5D1-C0DEA72F1AB3}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {F9B7FDAA-2388-40C8-93DB-C6DBD65DCD9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {F9B7FDAA-2388-40C8-93DB-C6DBD65DCD9B}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {F9B7FDAA-2388-40C8-93DB-C6DBD65DCD9B}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {F9B7FDAA-2388-40C8-93DB-C6DBD65DCD9B}.Release|Any CPU.Build.0 = Release|Any CPU 36 | EndGlobalSection 37 | GlobalSection(SolutionProperties) = preSolution 38 | HideSolutionNode = FALSE 39 | EndGlobalSection 40 | GlobalSection(ExtensibilityGlobals) = postSolution 41 | SolutionGuid = {31649371-03D8-4D16-A960-95E1E7713B53} 42 | EndGlobalSection 43 | EndGlobal 44 | -------------------------------------------------------------------------------- /Software/MicroDriveTools/Classes/MicroDriveDirectory.cs: -------------------------------------------------------------------------------- 1 | using MicroDriveTools.Structs; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Linq; 6 | using System.Runtime.InteropServices; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace MicroDriveTools.Classes 11 | { 12 | public class MicroDriveDirectory 13 | { 14 | List files = new List(); 15 | List directoryEntries = new List(); 16 | 17 | public MicroDriveFile[] Files { get { return files.ToArray(); } } 18 | public MicroDriveFileHeader[] DirectoryEntries { get { return directoryEntries.ToArray(); } } 19 | 20 | internal unsafe MicroDriveDirectory(MicroDriveSector[] Sectors, MicroDriveSectorMap Map) 21 | { 22 | List fileBuffer = new List(); 23 | 24 | var directoryMap = Map.GetFileMap(0); 25 | 26 | if (directoryMap == null || directoryMap.Length == 0) 27 | throw new FileNotFoundException("Cannot find directory file."); 28 | 29 | var directory = new MicroDriveFile(directoryMap, Sectors); 30 | 31 | if(directory.Data.Length % 64 != 0) 32 | throw new InvalidDataException($"Damaged directory file."); 33 | 34 | int fileCount = (int)directory.Data.Length / 64; 35 | 36 | var data = directory.Data; 37 | 38 | if (data.Length > 0) 39 | { 40 | fixed (byte* ptr = &data[0]) 41 | { 42 | MicroDriveFileHeader* headerPtr = (MicroDriveFileHeader*)ptr; 43 | 44 | for (int buc = 0; buc < fileCount; buc++) 45 | directoryEntries.Add(headerPtr[buc]); 46 | } 47 | 48 | for (int buc = 0; buc < fileCount; buc++) 49 | { 50 | var map = Map.GetFileMap((byte)(buc + 1)); 51 | 52 | if (map == null || map.Length == 0) 53 | throw new FileNotFoundException($"Cannot find file {buc} map."); 54 | 55 | var file = new MicroDriveFile(map, Sectors); 56 | fileBuffer.Add(file); 57 | } 58 | } 59 | 60 | files.AddRange(fileBuffer); 61 | } 62 | 63 | public MicroDriveDirectory() { } 64 | 65 | public bool AddFile(MicroDriveFile File) 66 | { 67 | if (files.Any(f => f.Header.FileName == File.Header.FileName)) 68 | return false; 69 | 70 | files.Add(File); 71 | var hdr = File.Header; 72 | hdr.BackupDate = 0; 73 | directoryEntries.Add(hdr); 74 | 75 | return true; 76 | } 77 | 78 | public bool RemoveFile(string FileName) 79 | { 80 | var idx = files.FindIndex(f => f.Header.FileName == FileName); 81 | 82 | if(idx == -1) 83 | return false; 84 | 85 | files.RemoveAt(idx); 86 | directoryEntries.RemoveAt(idx); 87 | 88 | return true; 89 | } 90 | 91 | public unsafe byte[] Serialize() 92 | { 93 | int len = (files.Count + 1) * 64; 94 | 95 | byte[] data = new byte[len]; 96 | 97 | MicroDriveFileHeader directoryHeader = new MicroDriveFileHeader(); 98 | directoryHeader.FileLength = (uint)len; 99 | 100 | fixed (byte* ptr = data) 101 | { 102 | MicroDriveFileHeader* hdrPtr = (MicroDriveFileHeader*)ptr; 103 | *hdrPtr = directoryHeader; 104 | hdrPtr++; 105 | 106 | for (int buc = 0; buc < directoryEntries.Count; buc++) 107 | { 108 | *hdrPtr = directoryEntries[buc]; 109 | hdrPtr++; 110 | } 111 | } 112 | 113 | return data; 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /Software/MicroDriveTools/Classes/MicroDriveFile.cs: -------------------------------------------------------------------------------- 1 | using MicroDriveTools.Structs; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Runtime.InteropServices; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace MicroDriveTools.Classes 10 | { 11 | public class MicroDriveFile 12 | { 13 | public MicroDriveFileHeader Header { get; private set; } 14 | public byte[] Data { get; private set; } 15 | public byte FileNumber { get; private set; } 16 | internal unsafe MicroDriveFile(MicroDriveSectorMapEntry[] FileMap, MicroDriveSector[] Sectors) 17 | { 18 | FileNumber = FileMap[0].FileNumber; 19 | 20 | var currentBlock = Sectors.Where(s => s.Header.HeaderFlag == 0xFF && s.Header.SectorNumber == FileMap[0].SectorNumber).FirstOrDefault(); 21 | 22 | if (currentBlock.Header.SectorNumber != FileMap[0].SectorNumber) 23 | throw new FileNotFoundException($"Cannot find file sector {FileMap[0].SectorNumber}"); 24 | 25 | if (currentBlock.Record.FileBlock != FileMap[0].FileBlock || currentBlock.Record.FileNumber != FileMap[0].FileNumber) 26 | throw new FileNotFoundException($"Cannot find file sector {FileMap[0].SectorNumber}"); 27 | 28 | byte* sectorData = currentBlock.Record.Data; 29 | 30 | byte[] headData = new byte[64]; 31 | Marshal.Copy((IntPtr)sectorData, headData, 0, 64); 32 | 33 | MicroDriveFileHeader head = new MicroDriveFileHeader(); 34 | head = *((MicroDriveFileHeader*)sectorData); 35 | Header = head; 36 | 37 | int len = (int)head.FileLength; 38 | 39 | List dataBuffer = new List(); 40 | 41 | for (int buc = 0; buc < FileMap.Length; buc++) 42 | { 43 | 44 | if (len == 0) 45 | break; 46 | 47 | currentBlock = Sectors.Where(s => s.Header.HeaderFlag == 0xFF && s.Header.SectorNumber == FileMap[buc].SectorNumber).FirstOrDefault(); 48 | 49 | if (currentBlock.Header.SectorNumber != FileMap[buc].SectorNumber) 50 | throw new FileNotFoundException($"Cannot find file sector {FileMap[buc].SectorNumber}"); 51 | 52 | if (currentBlock.Record.FileBlock != FileMap[buc].FileBlock || currentBlock.Record.FileNumber != FileMap[buc].FileNumber) 53 | throw new FileNotFoundException($"Cannot find file sector {FileMap[buc].SectorNumber}"); 54 | 55 | int dataLen = 512; 56 | sectorData = currentBlock.Record.Data; 57 | 58 | if (buc == 0) 59 | { 60 | len -= 64; 61 | dataLen -= 64; 62 | sectorData += 64; 63 | } 64 | 65 | byte[] currentData = new byte[Math.Min(dataLen, len)]; 66 | Marshal.Copy((IntPtr)sectorData, currentData, 0, currentData.Length); 67 | dataBuffer.AddRange(currentData); 68 | len -= currentData.Length; 69 | } 70 | 71 | if (len != 0) 72 | throw new InvalidDataException($"Damaged file {FileMap[0].FileNumber}"); 73 | 74 | Data = dataBuffer.ToArray(); 75 | } 76 | public MicroDriveFile(string FileName, byte[] Data, bool Executable = false, uint DataSpace = 0) 77 | { 78 | var header = new MicroDriveFileHeader(); 79 | 80 | header.FileName = FileName.Replace(".", "_"); 81 | header.FileLength = (uint)Data.Length + 64; 82 | header.BackupDate = 3; 83 | 84 | if (Executable) 85 | { 86 | header.FileType = 1; 87 | header.DataSpace = DataSpace; 88 | } 89 | 90 | Header = header; 91 | this.Data = Data; 92 | } 93 | 94 | public void UpdateExecutable(bool IsExecutable, uint DataSpace = 0) 95 | { 96 | var hdr = Header; 97 | hdr.FileType = (byte)(IsExecutable ? 1 : 0); 98 | hdr.DataSpace = DataSpace; 99 | Header = hdr; 100 | } 101 | 102 | public void UpdateFileName(string FileName) 103 | { 104 | var hdr = Header; 105 | hdr.FileName = FileName.Replace(".", "_"); 106 | Header = hdr; 107 | } 108 | 109 | public void UpdateData(byte[] Data) 110 | { 111 | var hdr = Header; 112 | hdr.FileLength = (uint)Data.Length + 64; 113 | Header = hdr; 114 | this.Data = Data; 115 | } 116 | 117 | public unsafe byte[] Serialize() 118 | { 119 | List buffer = new List(); 120 | 121 | byte[] hData = new byte[64]; 122 | MicroDriveFileHeader hdr = Header; 123 | 124 | fixed(void* ptr = hData) 125 | Marshal.StructureToPtr(hdr, (IntPtr)ptr, false); 126 | 127 | buffer.AddRange(hData); 128 | buffer.AddRange(Data); 129 | return buffer.ToArray(); 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /Software/MicroDriveTools/Classes/MicroDriveSectorMap.cs: -------------------------------------------------------------------------------- 1 | using MicroDriveTools.Structs; 2 | using System; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using System.Diagnostics; 6 | using System.Linq; 7 | using System.Runtime.InteropServices; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace MicroDriveTools.Classes 12 | { 13 | public class MicroDriveSectorMap 14 | { 15 | public const byte DAMAGED_SECTOR = 0xFF; 16 | public const byte FREE_SECTOR = 0xFD; 17 | public const byte MAP_FILE = 0xF8; 18 | 19 | private MicroDriveSectorMapEntry[] entries; 20 | public MicroDriveSectorMapEntry this[int index] { get { return entries[index]; } } 21 | public MicroDriveSectorMapEntry[] DamagedSectors { get { return entries.Where(e => e.FileNumber == DAMAGED_SECTOR).ToArray(); } } 22 | public MicroDriveSectorMapEntry[] FreeSectors { get { return entries.Where(e => e.FileNumber == FREE_SECTOR).ToArray(); } } 23 | public byte LastAllocatedSector { get; internal set; } 24 | internal unsafe MicroDriveSectorMap(MicroDriveSector SectorZero) 25 | { 26 | if (SectorZero.Header.HeaderFlag != 0xFF || SectorZero.Header.SectorNumber != 0) 27 | throw new ArgumentException(nameof(SectorZero)); 28 | 29 | List eBuffer = new List(); 30 | 31 | for (int buc = 0; buc < 510; buc += 2) 32 | { 33 | 34 | eBuffer.Add(new MicroDriveSectorMapEntry { SectorNumber = (byte)(buc / 2), FileNumber = SectorZero.Record.Data[buc], FileBlock = SectorZero.Record.Data[buc + 1] }); 35 | 36 | Debug.Print($"Sector {buc / 2} is {SectorZero.Record.Data[buc]}:{SectorZero.Record.Data[buc + 1]}"); 37 | } 38 | 39 | LastAllocatedSector = SectorZero.Record.Data[511]; 40 | 41 | entries = eBuffer.ToArray(); 42 | } 43 | public MicroDriveSectorMap() 44 | { 45 | entries = new MicroDriveSectorMapEntry[255]; 46 | 47 | for (int buc = 0; buc < 255; buc++) 48 | entries[buc] = new MicroDriveSectorMapEntry { SectorNumber = (byte)buc, FileNumber = FREE_SECTOR, FileBlock = 0 }; 49 | 50 | entries[254].FileNumber = DAMAGED_SECTOR; 51 | entries[0].FileNumber = MAP_FILE; 52 | 53 | LastAllocatedSector = 255; 54 | } 55 | public MicroDriveSectorMapEntry[] GetFileMap(byte FileNumber) 56 | { 57 | if (FileNumber >= 0xFD) 58 | throw new ArgumentException("Invalid FileNumber"); 59 | 60 | return entries.Where(e => e.FileNumber == FileNumber).OrderBy(e => e.FileBlock).ToArray(); 61 | } 62 | public void AssignSector(byte SectorNumber, byte FileNumber, byte FileBlock, bool FlagAsLastAllocated = true) 63 | { 64 | entries[SectorNumber] = new MicroDriveSectorMapEntry { SectorNumber = SectorNumber, FileNumber = FileNumber, FileBlock = FileBlock }; 65 | LastAllocatedSector = SectorNumber; 66 | } 67 | public void FlagAsEmpty(byte SectorNumber) 68 | { 69 | entries[SectorNumber] = new MicroDriveSectorMapEntry { SectorNumber = SectorNumber, FileNumber = FREE_SECTOR, FileBlock = 0 }; 70 | } 71 | public void FlagAsDamaged(byte SectorNumber) 72 | { 73 | entries[SectorNumber] = new MicroDriveSectorMapEntry { SectorNumber = SectorNumber, FileNumber = DAMAGED_SECTOR, FileBlock = 0 }; 74 | } 75 | public MicroDriveSector ToSectorZero(string MediumName, ushort MediumId) 76 | { 77 | MicroDriveSector sector = new MicroDriveSector(); 78 | sector.Record.MakeEmpty(); 79 | sector.Header.HeaderFlag = 0xFF; 80 | sector.Header.SectorNumber = 0; 81 | sector.Header.MediumId = MediumId; 82 | sector.Header.MediumName = MediumName; 83 | byte[] data = new byte[512]; 84 | 85 | for (int buc = 0; buc < 255; buc++) 86 | { 87 | int offset = buc * 2; 88 | data[offset] = entries[buc].FileNumber; 89 | data[offset + 1] = entries[buc].FileBlock; 90 | } 91 | 92 | data[510] = 0x01; 93 | data[511] = LastAllocatedSector; 94 | 95 | sector.Record.FileNumber = MAP_FILE; 96 | sector.Record.FileBlock = 0; 97 | sector.Record.ManagedData = data; 98 | sector.Header.ComputeChecksum(); 99 | sector.Record.ComputeChecksums(); 100 | 101 | return sector; 102 | } 103 | 104 | public MicroDriveSectorMapEntry[] ToArray() 105 | { 106 | return entries.Select(e => new MicroDriveSectorMapEntry { SectorNumber = e.SectorNumber, FileBlock = e.FileBlock, FileNumber = e.FileNumber }).ToArray(); 107 | } 108 | 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /Software/MicroDriveTools/Classes/ZIPImporter.cs: -------------------------------------------------------------------------------- 1 | using MicroDriveTools.Structs; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Xamarin.Tools.Zip; 8 | 9 | namespace MicroDriveTools.Classes 10 | { 11 | public static class ZIPImporter 12 | { 13 | public unsafe static MicroDriveDirectory ImportZIPFile(string FileName) 14 | { 15 | var storer = ZipArchive.Open(FileName, FileMode.Open); 16 | 17 | MicroDriveDirectory dir = new MicroDriveDirectory(); 18 | 19 | foreach (var entry in storer) 20 | { 21 | MemoryStream ms = new MemoryStream(); 22 | entry.Extract(ms); 23 | byte[] fileData = ms.ToArray(); 24 | 25 | if (entry.ExtraFieldPresent(0xfb4a)) 26 | { 27 | var data = entry.GetExtraField(0xfb4a); 28 | 29 | if (data != null && data.Count == 1 && data[0].RawData.Length == 72) 30 | { 31 | MicroDriveZipFileHeader fh = new MicroDriveZipFileHeader(); 32 | 33 | fixed (byte* ptr = data[0].RawData) 34 | fh = *((MicroDriveZipFileHeader*)ptr); 35 | 36 | MicroDriveFile nFile = new MicroDriveFile(fh.FileHeader.FileName, fileData, fh.FileHeader.FileType != 0, fh.FileHeader.DataSpace); 37 | dir.AddFile(nFile); 38 | continue; 39 | } 40 | 41 | } 42 | 43 | MicroDriveFile file = new MicroDriveFile(entry.FullName, fileData); 44 | dir.AddFile(file); 45 | 46 | } 47 | 48 | return dir; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Software/MicroDriveTools/ConvertTools.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace MicroDriveTools 8 | { 9 | public static class ConvertTools 10 | { 11 | public static unsafe ushort GetUshort(byte* Input) 12 | { 13 | return (ushort)(Input[0] << 8 | Input[1]); 14 | } 15 | public static unsafe short GetShort(byte* Input) 16 | { 17 | return (short)(Input[0] << 8 | Input[1]); 18 | } 19 | public static unsafe uint GetUint(byte* Input) 20 | { 21 | return (uint)((Input[0] << 24) | (Input[1] << 16) | (Input[2] << 8) | (Input[3] << 0)); 22 | } 23 | public static unsafe int GetInt(byte* Input) 24 | { 25 | return (int)((Input[0] << 24) | (Input[1] << 16) | (Input[2] << 8) | (Input[3] << 0)); 26 | } 27 | 28 | public static unsafe void SetUshort(ushort Input, byte* Output) 29 | { 30 | Output[0] = (byte)((Input >> 8) & 0xFF); 31 | Output[1] = (byte)((Input >> 0) & 0xFF); 32 | } 33 | public static unsafe void SetShort(short Input, byte* Output) 34 | { 35 | Output[0] = (byte)((Input >> 8) & 0xFF); 36 | Output[1] = (byte)((Input >> 0) & 0xFF); 37 | } 38 | public static unsafe void SetUint(uint Input, byte* Output) 39 | { 40 | Output[0] = (byte)((Input >> 24) & 0xFF); 41 | Output[1] = (byte)((Input >> 16) & 0xFF); 42 | Output[2] = (byte)((Input >> 8) & 0xFF); 43 | Output[3] = (byte)((Input >> 0) & 0xFF); 44 | } 45 | public static unsafe void SetInt(int Input, byte* Output) 46 | { 47 | Output[0] = (byte)((Input >> 24) & 0xFF); 48 | Output[1] = (byte)((Input >> 16) & 0xFF); 49 | Output[2] = (byte)((Input >> 8) & 0xFF); 50 | Output[3] = (byte)((Input >> 0) & 0xFF); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Software/MicroDriveTools/MicroDriveTools.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | True 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Software/TestTools/ABACUS.MDV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Software/TestTools/ABACUS.MDV -------------------------------------------------------------------------------- /Software/TestTools/Program.cs: -------------------------------------------------------------------------------- 1 | using MicroDriveTools.Classes; 2 | using MicroDriveTools.Structs; 3 | 4 | //var dir1 = ZIPImporter.ImportZIPFile("mmetropolism.zip"); 5 | 6 | //var md = new MicroDriveCartridge(dir1, "mmetropolism"); 7 | 8 | //var dir = new MicroDriveDirectory(); 9 | 10 | //byte[] b = File.ReadAllBytes("hola"); 11 | 12 | //dir.AddFile(new MicroDriveFile("un_archivo", b)); 13 | 14 | //foreach(var file in dir1.Files) 15 | //{ 16 | // dir.AddFile(new MicroDriveFile(file.Header.FileName, file.Data)); 17 | //} 18 | 19 | //var md = new MicroDriveCartridge(dir, "cosmic"); 20 | 21 | //md.SaveMDV("mmetropolism.mdv"); 22 | 23 | /* 24 | var cart1 = MicroDriveCartridge.LoadMDV("pepe.mdv"); 25 | 26 | var s0md = md.Sectors.Where(s => s.Header.SectorNumber == 0).FirstOrDefault(); 27 | var s0ct = cart1.Sectors.Where(s => s.Header.SectorNumber == 0).FirstOrDefault(); 28 | 29 | unsafe 30 | { 31 | byte* data1 = (byte*)&s0md; 32 | byte* data2 = (byte*)&s0ct; 33 | 34 | for(int buc = 0; buc < sizeof(MicroDriveSector); buc++) 35 | { 36 | if (data1[buc] != data2[buc]) 37 | Console.WriteLine($"Byte {buc} differs: {data1[buc]} - {data2[buc]}"); 38 | } 39 | 40 | Console.WriteLine("Random in sectors"); 41 | 42 | foreach (var sector in md.Sectors) 43 | { 44 | byte* data3 = (byte*)§or; 45 | Console.WriteLine($"{data3[12]}{data3[13]}"); 46 | } 47 | } 48 | 49 | 50 | 51 | foreach (var sector in cart1.Sectors) 52 | { 53 | var sect2 = md.Sectors.Cast().Where(s => s.Value.Header.SectorNumber == sector.Header.SectorNumber).FirstOrDefault(); 54 | 55 | if(sect2 == null) 56 | { 57 | Console.WriteLine($"Sector {sector.Header.MediumName}-{sector.Header.SectorNumber} not found in cart2"); 58 | continue; 59 | } 60 | 61 | if (!sect2.Value.Header.Equals(sector.Header)) 62 | { 63 | Console.WriteLine($"Sector {sector.Header.MediumName}-{sector.Header.SectorNumber} differs in header"); 64 | Console.WriteLine($"{sector.Header.HeaderFlag}-{sector.Header.SectorNumber}-{sector.Header.MediumName}/{sect2.Value.Header.HeaderFlag}-{sect2.Value.Header.SectorNumber}-{sect2.Value.Header.MediumName}"); 65 | } 66 | if (!sect2.Value.Record.Equals(sector.Record)) 67 | { 68 | Console.WriteLine($"Sector {sector.Header.MediumName}-{sector.Header.SectorNumber} differs in record"); 69 | } 70 | } 71 | /* 72 | */ 73 | 74 | //var cart = MicroDriveCartridge.LoadMDV("empty.mdv"); 75 | //var cart = MicroDriveCartridge.LoadMDV("fmt.mdv"); 76 | var cart = MicroDriveCartridge.LoadMDV("d:\\t_fix.mdv"); 77 | 78 | 79 | Console.WriteLine($"Cartridge name: {cart.MediumName}"); 80 | 81 | Console.WriteLine($"Free sectors: {cart.Map.FreeSectors.Length}"); 82 | Console.WriteLine($"Damaged sectors: {cart.Map.DamagedSectors.Length}"); 83 | 84 | foreach(var sector in cart.Map.DamagedSectors) 85 | Console.WriteLine($" - Sector {sector.SectorNumber}, file {sector.FileNumber}, block {sector.FileBlock}"); 86 | 87 | Console.WriteLine($"Last allocated sector: {cart.Map.LastAllocatedSector}"); 88 | 89 | Console.WriteLine($"--DIRECTORY MAP--"); 90 | 91 | foreach (var file in cart.Directory.Files) 92 | { 93 | Console.WriteLine($"File: {file.Header.FileName}, Size: {file.Header.FileLength}, Type: {file.Header.FileType}, DataSpace: {file.Header.DataSpace}, ExtraInfo: {file.Header.ExtraInfo}, UpdateDate: {file.Header.UpdateDate}, ReferenceDate: {file.Header.ReferenceDate}, BackupDate: {file.Header.BackupDate}"); 94 | Console.WriteLine("File map:"); 95 | 96 | var map = cart.Map.GetFileMap(file.FileNumber); 97 | 98 | foreach (var entry in map) 99 | Console.WriteLine($" - Sector {entry.SectorNumber}, Block {entry.FileBlock}"); 100 | 101 | } 102 | 103 | Console.WriteLine($"--RAW SECTORS--"); 104 | 105 | var mapEntries = cart.Map.ToArray(); 106 | 107 | foreach (var sector in cart.Sectors) 108 | { 109 | Console.WriteLine($"Sector { sector.Header.MediumName + "-" + sector.Header.SectorNumber}, File {sector.Record.FileNumber + "-" + sector.Record.FileBlock}, Flag { sector.Header.HeaderFlag}"); 110 | 111 | var entry = mapEntries.Cast().Where(e => e.Value.SectorNumber == sector.Header.SectorNumber).FirstOrDefault(); 112 | 113 | Console.WriteLine($"Sector map: { (entry == null ? "NULL" : $"{entry.Value.FileNumber}-{entry.Value.FileBlock}") }"); 114 | 115 | if(entry?.FileNumber != sector.Record.FileNumber || entry?.FileBlock != sector.Record.FileBlock) 116 | { 117 | Console.WriteLine($"Sector {sector.Header.MediumName}-{sector.Header.SectorNumber} has a different file number/block in the map: {entry?.FileNumber}:{entry?.FileBlock} vs {sector.Record.FileNumber}:{sector.Record.FileBlock}"); 118 | } 119 | } -------------------------------------------------------------------------------- /Software/TestTools/SAVE1.MDV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Software/TestTools/SAVE1.MDV -------------------------------------------------------------------------------- /Software/TestTools/TestTools.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | enable 8 | true 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | PreserveNewest 18 | 19 | 20 | PreserveNewest 21 | 22 | 23 | Always 24 | 25 | 26 | Always 27 | 28 | 29 | Always 30 | 31 | 32 | PreserveNewest 33 | 34 | 35 | Always 36 | 37 | 38 | Always 39 | 40 | 41 | Always 42 | 43 | 44 | PreserveNewest 45 | 46 | 47 | Always 48 | 49 | 50 | Always 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /Software/TestTools/caca.mdv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Software/TestTools/caca.mdv -------------------------------------------------------------------------------- /Software/TestTools/carttest.mdv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Software/TestTools/carttest.mdv -------------------------------------------------------------------------------- /Software/TestTools/carttest2.mdv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Software/TestTools/carttest2.mdv -------------------------------------------------------------------------------- /Software/TestTools/e.txt: -------------------------------------------------------------------------------- 1 | empty 2 | -------------------------------------------------------------------------------- /Software/TestTools/fmt.mdv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Software/TestTools/fmt.mdv -------------------------------------------------------------------------------- /Software/TestTools/mcosmic_m.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Software/TestTools/mcosmic_m.zip -------------------------------------------------------------------------------- /Software/TestTools/mmetropolism.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Software/TestTools/mmetropolism.zip -------------------------------------------------------------------------------- /Software/TestTools/pacman_patched.mdv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Software/TestTools/pacman_patched.mdv -------------------------------------------------------------------------------- /Software/TestTools/pepe.mdv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Software/TestTools/pepe.mdv -------------------------------------------------------------------------------- /Software/TestTools/starplod.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gusmanb/micropicodrive/37b26765e14edfa0348af60c74d8e9f5b8867000/Software/TestTools/starplod.zip --------------------------------------------------------------------------------