Close

SD Card Reading Works!

A project log for OSI SD Card Operating System (OSISDOS)

Ohio Scientific / UK101 SD Card based Operating System under Multicomp FPGA Computer

land-boardscomland-boards.com 08/03/2020 at 23:560 Comments

I had the wrong address for the SD controller registers in my code. Fixed it and it works now.

The C code reads a 512 byte block from sector 0 into SRAM starting at 0xE000 (Bank 0).

/* OSISDOS.c - Minimal Operating System for OSI C1P/SuperBoard ][     */
/* SDHC card based disk operating system                            */
/* 8KB Microsoft BASIC-In-ROM has I/O support routines                */
/* CEGMON has various hooks to the I/O in BASIC                        */
/* Uses Banked SRAM from $E000-$EFFF to buffer SD card data.        */
/* Intended to fit within a small ROM space below CEGMON            */
/*    Target ROM space goes from $F100-$F7FF (1.75kb)                    */
/*                                                                    */
/* Compiled using CC65 toolchain                                     */

/* 
Memory Map
    $0000-$9FFF - SRAM (40KB)
    $A000-$BFFF - Microsoft BASIC-in-ROM (8KB)
        $D000-$D3FF - 1KB Display RAM
        $DC00 - PS/2 Keyboard
        $E000-$EFFF - Bank Selectable SRAM (not detectable as BASIC RAM)
        $F000-$FFFF - CEGMON Monitor ROM 4K
        $F000-$F001 - ACIA (UART) 61440-61441 dec
        $F002 - J6 I/O Connector 61442 dec
        $F003 - J8 I/O Connector 61443 dec
     $F004 - LEDS 61444 dec
        d0-d1 LEDs are on the FPGA card
     $F005 - Bank Select Register 61445 dec
        d0..d3 used for 128KB SRAMs
    $F010-$F017 - SD card
           0    SDDATA        read/write data
        1    SDSTATUS      read
        1    SDCONTROL     write
        2    SDLBA0        write-only
        3    SDLBA1        write-only
        4    SDLBA2        write-only (only bits 6:0 are valid)
*/

//#include "osic1p.h"

#define READ_BUFFER_START    0xE000    /* Banked SRAM            */
#define WRITE_BUFFER_START    0xE200    
#define LED_BITS_01            0xF004
#define BANK_SELECT_REG_ADR    0xF005
#define START_BANKED_RAM     0xE000
#define SD_DATA                0xF010
#define SD_CTRL                0xF011
#define SD_STATUS            0xF011
#define SD_LBA0                0xF012
#define SD_LBA1                0xF013
#define SD_LBA2                0xF014
#define READ_COMMMAND        0x00
#define WRITE_COMMMAND        0x01

extern void main(void);
extern void setLBA0(unsigned char);
extern void setLBA1(unsigned char);
extern void setLBA2(unsigned char);
extern void readBlock(void);

/* main - Test the SD Card interface                                */
void main(void)
{
    /* Set to first bank of the banked SRAM */ 
    *(unsigned char*) BANK_SELECT_REG_ADR = 0x00;
    setLBA0(0);
    setLBA1(0);
    setLBA2(0);
    readBlock();
}

/* issueSDCardCommand - Send read or write command to SD Card        */
void issueSDCardCommand(unsigned char rwCmd)
{
    *(unsigned char *) SD_CTRL = rwCmd;
}

/* setLBA0 - Set the least significant logical block address bits    */
void setLBA0(unsigned char lba0)
{
    *(unsigned char *) SD_LBA0 = lba0;
}

/* setLBA1 - Set the middle 8 bits of the logical block addr bits    */
void setLBA1(unsigned char lba1)
{
    *(unsigned char *) SD_LBA1 = lba1; 
}

/* setLBA2 - Set the upper 8 bits of the logical block addr bits    */
void setLBA2(unsigned char lba2)
{
    *(unsigned char *) SD_LBA2 = lba2;
}

/* waitSDCardReady - Wait for the SD Card to be ready                */
void waitSDCardReady(void)
{
    * (unsigned char *) LED_BITS_01 = 0x1;
    while (*(unsigned char *) SD_STATUS != 0x80);
    * (unsigned char *) LED_BITS_01 = 0x0;
}

/* waitSDCardRcvDataReady - Wait for the SD Card to have data ready    */
void waitSDCardRcvDataReady(void)
{
    while (*(unsigned char *) SD_STATUS != 0xE0);
}

/* waitSDCardTxDataEmpty - Wait for transmit ready from SD ctrlr    */
void waitSDCardTxDataEmpty(void)
{
    while (*(unsigned char *) SD_STATUS != 0xA0);
}

/* readByteFromSDCard - Read a byte from the SD Card                */
unsigned char readByteFromSDCard(void)
{
    char rdChar;
    waitSDCardRcvDataReady();
    rdChar = *(unsigned char *) SD_DATA;
    return(rdChar);
}

/* writeByteToSDCard - Write a byte to the SD Card                    */
void writeByteToSDCard(unsigned char outChar)
{
    waitSDCardTxDataEmpty();
    *(unsigned char *) SD_DATA = outChar;
}

/* readBlock - -Read a block from the SD Card                        */
void readBlock(void)
{
    unsigned short loopCount;
    unsigned char * inBuffer;
    inBuffer = (unsigned char *) READ_BUFFER_START;
    waitSDCardReady();
    issueSDCardCommand(READ_COMMMAND);
    for (loopCount = 0; loopCount < 512; loopCount++)
    {
        *inBuffer++ = readByteFromSDCard();
    }
}

/* writeBlock - Write a block to the SD Card                        */
void writeBlock(void)
{
    unsigned short loopCount;
    unsigned char * outBuffer;
    outBuffer = (unsigned char *) WRITE_BUFFER_START;
    waitSDCardReady();
    issueSDCardCommand(WRITE_COMMMAND);
    for (loopCount = 0; loopCount < 512; loopCount++)
    {
        writeByteToSDCard(*outBuffer++);
    }
}

The program starts at 0x0300. 

Type TE000,E05F in CEGMON to dump the buffer to the screen. It worked.

Compiler commands are:

cl65 --start-addr 0x300 -Wl -D,__HIMEM__=$2000,-D,__STACKSIZE__=$0200 -t osic1p -vm -m OSISDOS.map -o OSISDOS.o OSISDOS.c

"..\..\..\..\..\PC Tools\srecord\srec_cat.exe" OSISDOS.o -bin -of 0x300 -o OSISDOS.c1p -os -esa=0x300

"C:\Users\HPz420\Documents\GitHub\Doug Gilliland\Retro-Computers\6502\RetroAssembler\retroassembler.exe" -d -D=0x0300 OSISDOS.o OSISDOS.DIS

 Now, on to figuring out the FAT32 DOS directory structure.

Discussions