Compare commits

...

2 commits
main ... devel

6 changed files with 202 additions and 66 deletions

View file

@ -495,13 +495,18 @@ uint32 _HardwareIn(const uint32 Port) {
/* Console abstraction functions */ /* Console abstraction functions */
/*===============================================================================*/ /*===============================================================================*/
#include "arduino_hooks.h"
int _kbhit(void) { int _kbhit(void) {
return(Serial.available()); if (_kbhit_hook && _kbhit_hook()) { return true; }
return(Serial.available());
} }
uint8 _getch(void) { uint8 _getch(void) {
while (!Serial.available()); while(true) {
return(Serial.read()); if(_kbhit_hook && _kbhit_hook()) { return _getch_hook(); }
if(Serial.available()) { return Serial.read(); }
}
} }
uint8 _getche(void) { uint8 _getche(void) {
@ -512,6 +517,7 @@ uint8 _getche(void) {
void _putch(uint8 ch) { void _putch(uint8 ch) {
Serial.write(ch); Serial.write(ch);
if(_putch_hook) _putch_hook(ch);
} }
void _clrscr(void) { void _clrscr(void) {

View file

@ -1,5 +1,8 @@
#pragma once #pragma once
#include <stdbool.h>
#include <stdint.h>
extern bool (*_kbhit_hook)(void); extern bool (*_kbhit_hook)(void);
extern uint8_t (*_getch_hook)(void); extern uint8_t (*_getch_hook)(void);
extern void (*_putch_hook)(uint8_t ch); extern void (*_putch_hook)(uint8_t ch);

View file

@ -47,4 +47,14 @@ void _puthex16(uint16 w) // puts a HHHH hex string
_puthex8(w & 0x00ff); _puthex8(w & 0x00ff);
} }
void _putdec(uint16_t w) {
char buf[] = " 0";
size_t i=sizeof(buf)-1;
while(w) {
assert(i > 0);
buf[--i] = '0' + (w % 10);
w /= 10;
}
_puts(buf);
}
#endif #endif

106
hardware/pico/feather_dvi.h Normal file
View file

@ -0,0 +1,106 @@
#include <SdFat.h> // SDFat - Adafruit Fork
#include <Adafruit_TinyUSB.h>
#include <PicoDVI.h>
#include "../../console.h"
#include "../../arduino_hooks.h"
#undef USE_DISPLAY
#define USE_DISPLAY (1)
#if USE_DISPLAY
DVItext1 display(DVI_RES_800x240p60, adafruit_feather_dvi_cfg);
#endif
#define SPI_CLOCK (20'000'000)
#define SD_CS_PIN (10)
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
DedicatedSpiCard blockdevice;
FatFileSystem SD; // Filesystem object from SdFat
Adafruit_USBD_MSC usb_msc; // USB mass storage object
// =========================================================================================
// Define Board-Data
// GP25 green onboard LED
// =========================================================================================
#define LED (13)
#define LEDinv (false)
#define board_pico
#define board_analog_io
#define board_digital_io
// FUNCTIONS REQUIRED FOR USB MASS STORAGE ---------------------------------
static bool msc_changed = true; // Is set true on filesystem changes
// Callback on READ10 command.
int32_t msc_read_cb(uint32_t lba, void *buffer, uint32_t bufsize) {
return blockdevice.readBlocks(lba, (uint8_t *)buffer, bufsize / 512) ? bufsize : -1;
}
// Callback on WRITE10 command.
int32_t msc_write_cb(uint32_t lba, uint8_t *buffer, uint32_t bufsize) {
digitalWrite(LED_BUILTIN, HIGH);
return blockdevice.writeBlocks(lba, buffer, bufsize / 512) ? bufsize : -1;
}
// Callback on WRITE10 completion.
void msc_flush_cb(void) {
blockdevice.syncBlocks(); // Sync with blockdevice
SD.cacheClear(); // Clear filesystem cache to force refresh
digitalWrite(LED_BUILTIN, LOW);
msc_changed = true;
}
void _puthex32(uint32_t x) {
_puthex16(x >> 16);
_puthex16(x & 0xffff);
}
#if USE_DISPLAY
uint16_t underCursor = ' ';
void putch_display(uint8_t ch) {
auto x = display.getCursorX();
auto y = display.getCursorY();
display.drawPixel(x, y, underCursor);
if(ch == 8) {
if(x > 0) {
display.setCursor(--x, y);
display.drawPixel(x, y, ' ');
}
} else {
display.write(ch);
}
x = display.getCursorX();
y = display.getCursorY();
underCursor = display.getPixel(x, y);
display.drawPixel(x, y, 0xDB);
}
#endif
bool port_init_early() {
#if USE_DISPLAY
// vreg_set_voltage(VREG_VOLTAGE_1_30);
if (!display.begin()) { return false; }
_putch_hook = putch_display;
#endif
// USB mass storage / filesystem setup (do BEFORE Serial init)
if (!blockdevice.begin(SD_CONFIG)) { _puts("!blockdevice.begin()"); return false; }
// Set disk vendor id, product id and revision
usb_msc.setID("Adafruit", "Internal Flash", "1.0");
// Set disk size, block size is 512 regardless of blockdevice page size
usb_msc.setCapacity(blockdevice.sectorCount(), 512);
usb_msc.setReadWriteCallback(msc_read_cb, msc_write_cb, msc_flush_cb);
usb_msc.setUnitReady(true); // MSC is ready for read/write
if (!usb_msc.begin()) {
_puts("!usb_msc.begin()"); return false;
}
return true;
}
bool port_flash_begin() {
if (!SD.begin(&blockdevice, true, 1)) { // Start filesystem on the blockdevice
_puts("!SD.begin()"); return false;
}
return true;
}

View file

@ -1,13 +1,17 @@
// ========================================================================================= #include <SdFat.h> // SDFat - Adafruit Fork
// Define SdFat as alias for SD
// =========================================================================================
#include <SdFat.h> // One SD library to rule them all - Greinman SdFat from Library Manager
#include <Adafruit_SPIFlash.h> #include <Adafruit_SPIFlash.h>
#include <Adafruit_TinyUSB.h> #include <Adafruit_TinyUSB.h>
#include <PicoDVI.h>
#include "../../console.h" #include "../../console.h"
#include "../../arduino_hooks.h"
Adafruit_FlashTransport_RP2040 flashTransport; #undef USE_DISPLAY
Adafruit_SPIFlash flash(&flashTransport); #define USE_DISPLAY (1)
#if USE_DISPLAY
DVItext1 display(DVI_RES_800x240p30, adafruit_feather_dvi_cfg);
#endif
DedicatedSpiCard spisd;
FatFileSystem SD; // Filesystem object from SdFat FatFileSystem SD; // Filesystem object from SdFat
Adafruit_USBD_MSC usb_msc; // USB mass storage object Adafruit_USBD_MSC usb_msc; // USB mass storage object
@ -15,7 +19,7 @@ Adafruit_USBD_MSC usb_msc; // USB mass storage object
// Define Board-Data // Define Board-Data
// GP25 green onboard LED // GP25 green onboard LED
// ========================================================================================= // =========================================================================================
#define LED 25 // GPIO25 #define LED 13 // GPIO13
#define LEDinv 0 #define LEDinv 0
#define board_pico #define board_pico
#define board_analog_io #define board_analog_io
@ -50,42 +54,59 @@ void _puthex32(uint32_t x) {
_puthex16(x & 0xffff); _puthex16(x & 0xffff);
} }
#if USE_DISPLAY
uint16_t underCursor = ' ';
void putch_display(uint8_t ch) {
auto x = display.getCursorX();
auto y = display.getCursorY();
display.drawPixel(x, y, underCursor);
if(ch == 8) {
if(x > 0) {
display.setCursor(--x, y);
display.drawPixel(x, y, ' ');
}
} else {
display.write(ch);
}
x = display.getCursorX();
y = display.getCursorY();
underCursor = display.getPixel(x, y);
display.drawPixel(x, y, 0xDB);
}
#endif
bool port_init_early() { bool port_init_early() {
_puts("port_init_early()"); #if USE_DISPLAY
_puts("X"); // vreg_set_voltage(VREG_VOLTAGE_1_30);
if (!display.begin()) { return false; }
_putch_hook = putch_display;
#endif
// USB mass storage / filesystem setup (do BEFORE Serial init) // USB mass storage / filesystem setup (do BEFORE Serial init)
if (!flash.begin()) { _puts("!flash_begin()"); return false; } if (!flash.begin()) { _puts("!flash_begin()"); return false; }
_puts("Y");
// Set disk vendor id, product id and revision // Set disk vendor id, product id and revision
usb_msc.setID("Adafruit", "Internal Flash", "1.0"); usb_msc.setID("Adafruit", "Internal Flash", "1.0");
_puts("Z");
// Set disk size, block size is 512 regardless of spi flash page size // Set disk size, block size is 512 regardless of spi flash page size
_puthex32(flash.pageSize()); _puthex32(flash.pageSize());
_putcon(' '); _putcon('x');
_puthex32(flash.numPages()); _puthex32(flash.numPages());
usb_msc.setCapacity(flash.pageSize() * flash.numPages() / 512, 512); usb_msc.setCapacity(flash.pageSize() * flash.numPages() / 512, 512);
_puts("A");
usb_msc.setReadWriteCallback(msc_read_cb, msc_write_cb, msc_flush_cb); usb_msc.setReadWriteCallback(msc_read_cb, msc_write_cb, msc_flush_cb);
_puts("B");
usb_msc.setUnitReady(true); // MSC is ready for read/write usb_msc.setUnitReady(true); // MSC is ready for read/write
_puts("C");
if (!usb_msc.begin()) { if (!usb_msc.begin()) {
_puts("!usb_msc.begin()"); return false; _puts("!usb_msc.begin()"); return false;
} else {
_puts("usb_msc.begin() OK");
} }
_puts("D");
return true; return true;
} }
bool port_flash_begin() { bool port_flash_begin() {
_puts("port_flash_begin()"); if (!spisd.begin(&spiconfig)) {
if (!SD.begin(&flash)) { // Start filesystem on the flash _puts("!spisd.begin()"); return false;
}
if (!SD.begin(&spisd)) { // Start filesystem on the flash
_puts("!SD.begin()"); return false; _puts("!SD.begin()"); return false;
} }
_puts("E");
_puts("port_flash_begin success");
return true; return true;
} }

View file

@ -1,16 +1,3 @@
/*
SD card connection
This example shows how to read and write data to and from an SD card file
The circuit:
SD card attached to SPI bus as follows:
// Arduino-pico core
** MISO - Pin 21 - GPIO 16
** MOSI - Pin 25 - GPIO 19
** CS - Pin 22 - GPIO 17
** SCK - Pin 24 - GPIO 18
*/
// only AVR and ARM CPU // only AVR and ARM CPU
// #include <MemoryFree.h> // #include <MemoryFree.h>
@ -27,14 +14,22 @@
#include <Adafruit_SPIFlash.h> #include <Adafruit_SPIFlash.h>
#include <Adafruit_TinyUSB.h> #include <Adafruit_TinyUSB.h>
#define TEXT_BOLD "\033[1m"
#define TEXT_NORMAL "\033[0m"
// ========================================================================================= // =========================================================================================
// Board definitions go into the "hardware" folder, if you use a board different than the // Board definitions go into the "hardware" folder, if you use a board different than the
// Arduino DUE, choose/change a file from there and reference that file here // Arduino DUE, choose/change a file from there and reference that file here
// ========================================================================================= // =========================================================================================
// Raspberry Pi Pico - normal (LED = GPIO25) // Raspberry Pi Pico - normal (LED = GPIO25)
#include "hardware/pico/pico_internalflash.h" #include "hardware/pico/feather_dvi.h"
#ifndef BOARD_TEXT
#define BOARD_TEXT USB_MANUFACTURER " " USB_PRODUCT
#endif
#include "abstraction_arduino.h"
// Raspberry Pi Pico W(iFi) (LED = GPIO32) // Raspberry Pi Pico W(iFi) (LED = GPIO32)
// #include "hardware/pico/pico_w_sd_spi.h" // #include "hardware/pico/pico_w_sd_spi.h"
@ -44,7 +39,6 @@
#define sDELAY 100 #define sDELAY 100
#define DELAY 1200 #define DELAY 1200
#include "abstraction_arduino.h"
// ========================================================================================= // =========================================================================================
// Serial port speed // Serial port speed
@ -79,7 +73,7 @@ int lst_open = FALSE;
void setup(void) { void setup(void) {
pinMode(LED, OUTPUT); pinMode(LED, OUTPUT);
digitalWrite(LED, LOW); digitalWrite(LED, LOW^LEDinv);
// ========================================================================================= // =========================================================================================
@ -102,8 +96,9 @@ void setup(void) {
// Serial2.setTX(20); // Pin 26 // Serial2.setTX(20); // Pin 26
// ========================================================================================= // =========================================================================================
port_init_early(); if (!port_init_early()) { return; }
#if defined(WAIT_SERIAL)
// _clrscr(); // _clrscr();
// _puts("Opening serial-port...\r\n"); // _puts("Opening serial-port...\r\n");
Serial.begin(SERIALSPD); Serial.begin(SERIALSPD);
@ -113,7 +108,7 @@ void setup(void) {
digitalWrite(LED, LOW^LEDinv); digitalWrite(LED, LOW^LEDinv);
delay(DELAY); delay(DELAY);
} }
#endif
#ifdef DEBUGLOG #ifdef DEBUGLOG
_sys_deletefile((uint8 *)LogName); _sys_deletefile((uint8 *)LogName);
@ -127,49 +122,44 @@ void setup(void) {
_clrscr(); _clrscr();
// if (bootup_press == 1) // if (bootup_press == 1)
// { _puts("Recognized \e[1m#\e[0m key as pressed! :)\r\n\r\n"); // { _puts("Recognized " TEXT_BOLD "#" TEXT_NORMAL " key as pressed! :)\r\n\r\n");
// } // }
_puts("CP/M Emulator \e[1mv" VERSION "\e[0m by \e[1mMarcelo Dantas\e[0m\r\n"); _puts("CP/M Emulator " TEXT_BOLD "v" VERSION "" TEXT_NORMAL " by " TEXT_BOLD "Marcelo Dantas\e[0m\r\n");
_puts("----------------------------------------------\r\n"); _puts("----------------------------------------------\r\n");
_puts(" running on Raspberry Pi [\e[1m Pico \e[0m]\r\n"); _puts(" running on [" TEXT_BOLD BOARD_TEXT TEXT_NORMAL "]\r\n");
_puts("----------------------------------------------\r\n"); _puts("----------------------------------------------\r\n");
_puts("\e[0m]\r\n");
_puts("BIOS at [\e[1m0x"); _puts("BIOS at [" TEXT_BOLD "0x");
_puthex16(BIOSjmppage); _puthex16(BIOSjmppage);
// _puts(" - "); // _puts(" - ");
_puts("\e[0m]\r\n"); _puts("" TEXT_NORMAL "]\r\n");
_puts("BDOS at [\e[1m0x"); _puts("BDOS at [" TEXT_BOLD "0x");
_puthex16(BDOSjmppage); _puthex16(BDOSjmppage);
_puts("\e[0m]\r\n"); _puts("" TEXT_NORMAL "]\r\n");
_puts("CCP " CCPname " at [\e[1m0x"); _puts("CCP " CCPname " at [" TEXT_BOLD "0x");
_puthex16(CCPaddr); _puthex16(CCPaddr);
_puts("\e[0m]\r\n"); _puts("" TEXT_NORMAL "]\r\n");
#if BANKS > 1 #if BANKS > 1
_puts("Banked Memory [\e[1m"); _puts("Banked Memory [" TEXT_BOLD "");
_puthex8(BANKS); _puthex8(BANKS);
_puts("\e[0m]banks\r\n"); _puts("" TEXT_NORMAL "]banks\r\n");
#else
_puts("Banked Memory [\e[1m");
_puthex8(BANKS);
_puts("\e[0m]bank\r\n");
#endif #endif
// Serial.printf("Free Memory [\e[1m%d bytes\e[0m]\r\n", freeMemory()); // Serial.printf("Free Memory [" TEXT_BOLD "%d bytes" TEXT_NORMAL "]\r\n", freeMemory());
_puts("CPU-Clock [\e[1m250Mhz\e[0m]\r\n"); _puts("CPU-Clock [" TEXT_BOLD);
_putdec((clock_get_hz( clk_sys ) + 500'000) / 1'000'000);
_puts(TEXT_NORMAL "] MHz\r\n");
_puts("Init Storage [ " TEXT_BOLD "");
_puts("Init Storage [ \e[1m");
if (port_flash_begin()) { if (port_flash_begin()) {
_puts("OK \e[0m]\r\n"); _puts("OK " TEXT_NORMAL "]\r\n");
_puts("----------------------------------------------"); _puts("----------------------------------------------");
if (VersionCCP >= 0x10 || SD.exists(CCPname)) { if (VersionCCP >= 0x10 || SD.exists(CCPname)) {
while (true) { while (true) {
_puts(CCPHEAD); _puts(CCPHEAD);
@ -202,7 +192,7 @@ void setup(void) {
_puts("Unable to load CP/M CCP.\r\nCPU halted.\r\n"); _puts("Unable to load CP/M CCP.\r\nCPU halted.\r\n");
} }
} else { } else {
_puts("ERR \e[0m]\r\nUnable to initialize SD card.\r\nCPU halted.\r\n"); _puts("ERR " TEXT_NORMAL "]\r\nUnable to initialize SD card.\r\nCPU halted.\r\n");
} }
} }