About 4D Systems PTY LTD
4D Systems, Australia
Home Company Products 4DGL Developers Center Support forum Distributors News & Events Contact us App Notes
4DGL - Sharing our bytes to the world

MediaEditor1.4DG


Codebase / PICASO-GFX / PICASO-GFX2 and 4DGL Display Modules / Device Specific Examples

This program enables you to edit sectors on a uSD card.
The program uses the Workshop terminal to get keyboard
commands, so it should be saved to FLASH so reset wont lose it.

The footprint is quite small,

CODESIZE = 4439
MEMSIZE = 352
About this code
Author: The 4D team
Uploaded on: 24/03/2011

Back to previous page

Pictures:

Previous Next

Source code:

#platform "uVGA-II_GFX2"
#inherit "4DGL_16bitColours.fnc"

//========================================================================
//========================================================================
//========================================================================
// uSD card editor,  first draft
// Designed to run on uVGAII
// The screen is set to 640x480 mode.
//
// BE CAREFULL, IT IS EASY TO DESTROY A FORMATTED DISK
// IF WRONG THINGS ARE EDITED!
//========================================================================
//========================================================================
//========================================================================

// This program enables you to edit sectors on a uSD card.
// The program uses the Workshop terminal to get keyboard
// commands, so it should be saved to FLASH so reset wont lose it
// unless it is being executed as a sub prog that is already running terminal.
// The editor edits one sector at a time. If any alterations
// are made within a sector, it is necessary to save the alterations
// with ^W, however, if you try and move forward or backward
// to next or previous sector, you will be prompted to save changes
// if any changes have been made.
// Any changes that are made are colour coded within the sector.
// When any hex ke (0-F) is pressed, it automatically enters BYTE
// field edit mode, which is terminated with any non hex key (usually ESC).
// When ^K is presse, 'ASCII' edit mode is entered which is terminated
// wnen any non ascii key is hit (usually ESC).
// When ^A pressed, enter new sector address.
// When ^G pressed, checks the integrity of a formatted disk,
// and indicates if it is mountable as FAT16.
// This test also indicates the partition addresses - if any.
// In all cases, helper messages are shown.
//
// The following keys are used to control the cursor movement etc.

// UP           ^E                          move secsor up
// DOWN         ^X                          move cursor down
// LEFT         ^S                          meve cursor left
// LEFT         BS (BACKSPACE)              move cursor left
// RIGHT        ^D                          move cursor down
// KEYUP      0x80 (terminal mapped up key)
// KEYDOWN    0x81 (terminal mapped down key))
// KEYLEFT    0x82 (terminal mapped left key)
// KEYLEFT    0x83 (terminal mapped)
// SECT-        ^R                          back 1 sector
// SECT+        ^C                          forward 1 sector
// PGUP       0x84 terminal mapped)
// PGDWN      0x85 terminal mapped)
// IMAGE        ^I                          show image at current sector *
// FILES        ^F                          (not implemented)
// ADDRESS      ^A                          set sector address
// MEDIACHECK   ^G                          check for valid mountable media
// EDIT ASCII   ^K                          enter ascii edit mode
// WRITEBACK    ^W                          write current sector back to uSD

// * an image will only be shown if there is a valid image header at that point


// TBD readback and verify sector when written
// TBD improve ^I image function to include stepping through frams,
// and following GCI chain, reporting more info etc
// TBD Make a fancy mouse / touch driven version.

//========================================================================
//========================================================================
//========================================================================


#CONST
    SPACE       0x20
    UNDERLINE   0x5F
    ESC         0x1B
    CR          13
    TAB         9
    LF          10
    BS          8
#END


// hexedit function codes
#constant INITIALIZE        1
#constant REDRAW            2
#constant REFRESH           3
#constant CHANGE_ADDRESS    4
#constant CHANGE_DATA       5
#constant CHANGE_ASCII      6


#constant BUFSIZE           20  // text entry buffer size, 4 chars
#constant TEXT_FIELD        32  // text entry print field width
#constant SECTORSIZE        512

var Textbuf[BUFSIZE];           // text entry buffer
var TempBuf[BUFSIZE];           // temp holding buffer
var sectormap[SECTORSIZE/16];   // change map, 32 words, 1 bit reperesents 1 byte
var sectorbuf[SECTORSIZE/2];



// cmd values.
// 1 Initialize
// 2 redraw
// 3 refresh
// 4 changeaddress
// 5 alter data
// 6 alter ascii
func hexdump(var cmd)
    #constant TITLEBG       GRAY            // title bar colour
    #constant STATUSBG      GRAY            // status pane background colour

    #constant TXTBG         NAVY            // hex text background colour
    #constant TXTFG         KHAKI           // hex text foreground colour
    #constant CURSBG        YELLOW          // hex cursor background colour
    #constant CURSFG        RED             // hex cursor foreground colour
    #constant TXTCHANGED    MAGENTA            // colour to indicate byte has been changed

    var *p, *q;
    var edbyte[2];
    var private xpos, ypos;
    var private oldcurpos := -1;
    var private sectorLO, sectorHI, thisSectorLO, thisSectorHI;
    var private cursor, thisbyte, editchar;
    var n, x, y, w, h, ch, val, r;


    txt_FontID(FONT1);
    txt_Ygap(0);
    txt_Opacity(OPAQUE);

    w := charwidth('W');  // get width and height so we can scale size depending on font size
    h := charheight('W');

    // check commands

    //#########################################################
    if(cmd == CHANGE_ASCII) // edit ascii?
        gfx_MoveTo(xpos+10,ypos+h*38 + 10);
        txt_FGcolour(RED);
        putstr("ASCII editing, non ASCII exits edit mode...");
        n:=1;
        repeat
            txt_FGcolour(CURSBG);                                // use inverse cursor colours
            txt_BGcolour(CURSFG);
            p := cursor;
            gosub setAsciiPos;                                  // set ascii field cursor pos
            putch('_');                                         // set cursor
            while((ch := serin()) < 0);                         // wait for kbd
            if(ch < SPACE) break;                               // break on non ascii
            sectormap[cursor>>4] |= 1<<(cursor&15);             // mark changed
            str_PutByte(str_Ptr(sectorbuf) + cursor, ch);       // write new char
            cursor++;                                           // next cursor pos
            cursor &= 511;
            gosub updateCursor;
            oldcurpos := cursor;
        forever
        gosub menu;
        cmd := REFRESH;
    endif

    //#########################################################
    if(cmd == CHANGE_DATA) // edit data?
        gfx_MoveTo(xpos+10,ypos+h*38 + 10);
        txt_FGcolour(RED);
        putstr("BYTE editing, non HEX key exits edit mode...");
        n:=1;
nxtchar:
        edbyte[0] := editchar<<8 | '_';
        txt_FGcolour(CURSBG);                                       // use inverse cursor colours
        txt_BGcolour(CURSFG);
        repeat
            p := cursor;
            gosub setBytePos;
            putch(HIbyte(edbyte[0]));
            putch(LObyte(edbyte[0]));
            while((ch := serin()) < 0);                             // wait for kbd
            if(!isxdigit(ch)) break;                                // break on non hex digit
            edbyte[0] := edbyte[0]>>8 | toupper(ch)<<8;

            if(++n == 2)
                sectormap[cursor>>4] |= 1<<(cursor&15);             // mark changed
                p := str_Ptr(edbyte);
                str_GetHexW(&p, &val);
                str_PutByte(str_Ptr(sectorbuf) + cursor, val);      // write new value
                cursor++;                                           // next cursor pos
                cursor &= 511;
                gosub updateCursor;
                oldcurpos := cursor;
                editchar := '_';
                n:=0;
                goto nxtchar;
            endif
        forever
        gosub menu;
        cmd := REFRESH;
    endif

    //#########################################################
    if(cmd == CHANGE_ADDRESS) // edit address?
        gfx_Panel(PANEL_RAISED, xpos,ypos, w*72,h*2+2, TITLEBG);    // blank the title bar
        edit.xpos := hexdump.xpos+w*27;                             // set edit X position
        edit.ypos := hexdump.ypos+6;                                // set edit X position
        edit.process := 0;                                          // we dont want a buffer RETURN process
        edit.width := 20;                                           // 20 chars max to edit
        edit.text := TempBuf;                                       // set text to edit
        //to(TempBuf); print("0x",[HEX4]sectorHI,[HEX4]sectorLO);     // copy existing value

        gfx_MoveTo(xpos+w, ypos+6);
        txt_FGcolour(YELLOW);
        txt_BGcolour(TITLEBG);
        print("Sector Addr? (dec or hex)");                         // prompt

        gfx_Panel(PANEL_SUNKEN, edit.xpos-2, edit.ypos-2, w*edit.width+4, 12, GRAY+3); // draw edit window

        repeat
            edit(INITIALIZE);                                       // initialize the line editor

            repeat
                ch := serin();                                      // wait for kbd
                if (ch != -1)
                    if(ch == ESC || ch == CR) break;                // break on ESC or ENTER key
                    edit(ch);                                       // else update editor
                endif
            forever

            if(ch != CR)  break;                                    // if edit exited by RETURN key
            p := str_Ptr(Textbuf);
            if(str_GetD(&p, & sectorLO)) break;                      // get a standard bin,hex or decimal number, break if ok

        forever         // else stay in loop, bad bumber

        gfx_Panel(PANEL_RAISED, xpos,ypos, w*72,h*2+2, TITLEBG);    // blank the title bar
        cmd := REDRAW;                                              // refresh so we update entire field
    endif

    //#########################################################
    if(cmd == INITIALIZE) // if init, redraw entire window
        gfx_Panel(PANEL_RAISED, xpos,   ypos,       w*72,   h*2+2, TITLEBG);     // draw panel for 'title'
        gfx_Panel(PANEL_SUNKEN, xpos,   ypos+h*2,   w*72,   h*34,  TITLEBG);     // draw outer panel for 'window'
        gfx_Panel(PANEL_RAISED, xpos+3, ypos+h*2+3, w*72-6, h*34-6,  TXTBG);     // draw outer panel for 'window'
        gosub menu;
        cmd := REDRAW;
    endif


    //#########################################################
    if(cmd == REDRAW)                                   // if redraw, update entire sector
        n := 0;                                         // see if any bytes were changed
        r := 0;
        while(n < 32) r |= sectormap[n++];              // in case we need to do a write back

        if(r)                                           // if sector has changed
            gfx_MoveTo(xpos+10,ypos+h*38 + 10);
            txt_FGcolour(RED);
            txt_BGcolour(GRAY);
            putstr("Changes have been made, save sector? ");
            while((ch := serin()) <=0);                 // wait for kbd
            if(toupper(ch) == 'Y')                      // ask
                media_SetSector(thisSectorHI, thisSectorLO);
                media_WrSector(sectorbuf);              // if Y write sector back
             endif
             gosub menu;
        endif

        thisSectorLO := sectorLO;                       // save current sector address
        thisSectorHI := sectorHI;
        media_SetSector(sectorHI, sectorLO);
        media_RdSector(sectorbuf);                      // read the sector

        n := 0;
        while(n < 32) sectormap[n++] := 0;              // clear the sector change map

        oldcurpos := -1;                                // invalidate old cursor pos

        p := 0;                                         // point to start of buffer
        q := cursor;                                    // get current cursor pos
        gfx_MoveTo(xpos+w, ypos+h*3);                   // start hex dump here
        for(y:=0; y<32; y++)

            txt_FGcolour(LIME);
            txt_BGcolour(TXTBG);
            print([HEX3] y<<4,"  ");                    // print sector offset

            txt_FGcolour(TXTFG);

            x := 16; while(x--) gosub setByteChars;     // print line of hex bytes

            putch(' ');
            p -= 16;

            x := 16; while(x--) gosub setAsciiChar;     // finish line with ascii chars

            putch('\n');
        next
    endif

    //#########################################################
   if(cmd == REFRESH)
        gosub updateCursor;
    endif


    // finally refresh addres field
    oldcurpos := cursor;

    // print address and data
    gfx_MoveTo(xpos+w, ypos+6);
    txt_FGcolour(CYAN);
    txt_BGcolour(TITLEBG);
    print("Sector Addr ",[HEX4]sectorHI,":",[HEX4]sectorLO);
    p := str_Ptr(& sectorLO);
    str_Printf(&p,"(dec %lu)");  // print hex address
    print(" offset=", cursor, " byte=",thisbyte,"            ");

    return; // function exits here

//=====================================================
// function subroutines
//=====================================================

// undraw old cursor, draw new cursor
updateCursor:
    if(oldcurpos >= 0)                              // if there is a valid old cursor
        p := oldcurpos;
        q := -1;
        gosub placeCursors;                         // undraw old
    endif
    p := cursor;
    q := p;
    gosub placeCursors;                             // then redraw new
    endsub;

// place both cursors
placeCursors:
    gosub setBytePos;               // byte cursor
    gosub setByteChars;
    p--;                            // restore address
    gosub setAsciiPos;
    gosub setAsciiChar;             // ascii cursor
    endsub;

// set correct cursor pos for HEX2 byte field
setBytePos:
    gfx_MoveTo(xpos+(6+(p&15)*3)*w, ypos+(3+(p/16))*h);
    endsub;

// print a HEX2 byte at required pos
setByteChars:
    gosub setColour;
    thisbyte := str_GetByte(str_Ptr(sectorbuf) + p++);
    print([HEX2] thisbyte);
    txt_FGcolour(TXTFG);
    txt_BGcolour(TXTBG);
    putch(' ');
    endsub;

// set correct cursor pos for ascii field
setAsciiPos:
    gfx_MoveTo(xpos+(55+(p&15))*w, ypos+(3+(p/16))*h);
    endsub;

// print ascii at required pos
setAsciiChar:
    gosub setColour;
    ch := str_GetByte(str_Ptr(sectorbuf) + p++);
    if(!isprint(ch)) ch := '.';
    putch(ch);
    txt_FGcolour(TXTFG);
    txt_BGcolour(TXTBG);
    endsub;

// set required colour, normal, cursor or changed
setColour:
    if(p == q)                                  // if cursor matches current pos
        txt_FGcolour(CURSFG);
        txt_BGcolour(CURSBG);                   // use cursor colours
    else
        if(sectormap[p>>4] & (1<<(p&15)))       // else see if byte has been changed
            txt_FGcolour(TXTCHANGED);           // if so, use hilite colour
        else
            txt_FGcolour(TXTFG);                // else use normal colour
        endif
        txt_BGcolour(TXTBG);
    endif
    endsub;

// redraw the menu panel
menu:
    gfx_Panel(PANEL_SUNKEN, xpos,   ypos+h*36,  w*72,   h*5,  STATUSBG);     // draw panel for 'status'
    txt_FontID(FONT1);
    txt_FGcolour(WHITE);
    txt_BGcolour(STATUSBG);
    gfx_MoveTo(xpos+10,ypos+h*36 + 4);
    putstr("LEFT ^S  RIGHT ^D   NEXT ^C  ADDRESS   ^A  MOUNT TEST ^G  IMAGE ^I");
    gfx_MoveTo(xpos+10,ypos+h*37 + 6);
    putstr("UP   ^E  DOWN  ^X   PREV ^R  WRITEBACK ^W  EDIT ASCII ^K");
    endsub;

endfunc

// main dispatch loop
func KeyHandler(var ch)

    #constant MAXPOS SECTORSIZE-16
    var n;

    gosub(lookup8(ch,
        /* UP           ^E */  0x05,
        /* DOWN         ^X */  0x18,
        /* LEFT         ^S */  0x13,
        /* LEFT         BS */  0x08,
        /* RIGHT        ^D */  0x04,
        /* KEYUP      0x80 */  0x80, // terminal mapped
        /* KEYDOWN    0x81 */  0x81, // terminal mapped
        /* KEYLEFT    0x82 */  0x82, // terminal mapped
        /* KEYLEFT    0x83 */  0x83, // terminal mapped
        /* SECT-        ^R */  0x12,
        /* SECT+        ^C */  0x03,
        /* PGUP       0x84 */  0x84, // terminal mapped
        /* PGDWN      0x85 */  0x85, // terminal mapped
        /* IMAGE        ^I */  0x09,
        /* FILES        ^F */  0x06,
        /* ADDRESS      ^A */  0x01,
        /* MEDIACHECK   ^G */  0x07,
        /* EDIT ASCII   ^K */  0x0B,
        /* WRITEBACK    ^W */  0x17
        )),
    (
    KEY_VOID,
    KEY_UP,
    KEY_DOWN,
    KEY_LEFT,
    KEY_LEFT,
    KEY_RIGHT,
    KEY_UP,
    KEY_DOWN,
    KEY_LEFT,
    KEY_RIGHT,
    KEY_PREV_SECTOR,
    KEY_NEXT_SECTOR,
    KEY_PREV_SECTOR,
    KEY_NEXT_SECTOR,
    KEY_IMAGE,
    KEY_FILES,
    KEY_ADDRESS,
    KEY_MEDIA_CHECK,
    KEY_EDIT_ASCII,
    KEY_WRITEBACK
    );


    hexdump(n);
    return;

KEY_VOID:
    if(isxdigit(ch))                    // wasnt a control key, see if hex digit
        hexdump.editchar := ch;
        n := CHANGE_DATA;
    endif
    endsub;                     // key invalid

KEY_EDIT_ASCII:
    n := CHANGE_ASCII;             // send ascii edit command to hexedit
    endsub;

KEY_UP:
    if(hexdump.cursor > 15) hexdump.cursor -= 16;
    n := REFRESH;
    endsub;

KEY_DOWN:
    if(hexdump.cursor < MAXPOS) hexdump.cursor += 16;
    n := REFRESH;
    endsub;

KEY_LEFT:
    if(hexdump.cursor) hexdump.cursor--;
    n := REFRESH;
    endsub;

KEY_RIGHT:
    if(hexdump.cursor < SECTORSIZE-1) hexdump.cursor++;
    n := REFRESH;
    endsub;

KEY_PREV_SECTOR:
    if(hexdump.sectorLO | hexdump.sectorHI)
        if(!hexdump.sectorLO) hexdump.sectorHI--;
        hexdump.sectorLO--;
    endif
    n := REDRAW;
    endsub;

KEY_NEXT_SECTOR:
    hexdump.sectorLO++;
    if(!hexdump.sectorLO) hexdump.sectorHI++;
    n := REDRAW;
    endsub;

KEY_WRITEBACK:
    sectormap[0] := 1;      // dirty the map to force a write
    n := REDRAW;
    endsub;

KEY_ADDRESS:
    n := CHANGE_ADDRESS;             // send edit command to hexedit
    endsub;

KEY_FILES:
    if (media_Init())                // get rid of or improve
        file_Dir("*.*");
    endif
    pause(3000);
    n := INITIALIZE;
    endsub;

KEY_MEDIA_CHECK:
    // TBD could be expanded here,
    // but best to call another process
    txt_Ygap(3);
    hexdump.xpos := 20;
    hexdump.ypos := 90;
    gfx_Panel(PANEL_RAISED, hexdump.xpos+40, hexdump.ypos+40,240, 130, GRAY);     // draw panel for disk info
    gfx_MoveTo(hexdump.xpos+46, hexdump.ypos+46);
    txt_FGcolour(BLACK);
    txt_BGcolour(GRAY);                   // use cursor colours
    DiskCheck();
    txt_FGcolour(RED);
    putstr("\n\n\nPress any key to exit....");
    while((ch := serin()) <=0);                 // wait for kbd
    n := REDRAW;
    endsub;


KEY_IMAGE: // TBD improve
gfx_Cls();
    media_SetSector(hexdump.sectorHI, hexdump.sectorLO);
    media_VideoFrame(20, 20, 0); // show image
    gfx_MoveTo(0,470);
    n := INITIALIZE;
    txt_FGcolour(RED);
    putstr("Press any key to exit....");
    while((ch := serin()) <=0);                 // wait for kbd
    gfx_Cls();
    endsub;
endfunc





func main()
    var ch;
    txt_FontID(FONT1);
    media_Init();

    // position the hex edit window, set start address
    hexdump.xpos := 20;
    hexdump.ypos := 90;
    //hexdump.sectorHI := 0;
    //hexdump.sectorLO := 0;
    hexdump(INITIALIZE);

    KeyHandler(0);          // first draw

    // keyboard dispatch loop
    repeat
        ch := serin();                               // scan for kbd
        if (ch != -1)
        KeyHandler(ch);
    endif

    forever
endfunc


//======================================================================
// update the text window, process text if CR received
// TBD expand so line can be longer than window.
//======================================================================
func edit(var ch)

    var private text;                                       // text to edit
    var private process;                                    // process to call when ENTER key hit
    var private width := TEXT_FIELD;                        // charcter width of edit field
    var private xpos, ypos, fgcolour:=WHITE, bgcolour;
    var private *p, cursor, full;

    if (ch == INITIALIZE)
        mem_Set(Textbuf, SPACE, width);                     // clear the buffer to all spaces
        cursor := MIN(strlen(text), width-1);               // copy the source string, limited by field width
        mem_Copy(text, Textbuf, cursor);                    // copy the source string
        p := str_Ptr(Textbuf);                              // reset the pointer
        p += cursor;
        str_PutByte(p, UNDERLINE);                          // place the cursor

    else if (ch == CR)                                      // if carriage return
        str_PutByte(p, 0);                                  // terminate the buffer
        if(process) process();                              // process the text
        p := str_Ptr(Textbuf);                              // reset the pointer
        mem_Set(Textbuf, SPACE, TEXT_FIELD);                // clear the buffer to all spaces
        str_PutByte(p+width, 0);                            // terminate it
        str_PutByte(p, UNDERLINE);                          // place the cursor
        cursor := 0;                                        // reset cursor

    else if (ch == BS)
        str_PutByte(p, SPACE);                              // blank current pos
        if(!full)                                           // if buffer not full
            if (cursor)
                cursor--;
                p--;                                        // backup
            endif
        endif
        str_PutByte(p, UNDERLINE);                          // place the cursor
        full := 0;                                          // reset flag
    else if (ch >= SPACE)
        str_PutByte(p, ch);
        if (cursor < width-1)
            cursor++;
            p++;
            str_PutByte(p, UNDERLINE);
            full := 0;
        else
            full := 1;
        endif
    endif
    // now print buffer contents
    txt_FGcolour(fgcolour);
    txt_BGcolour(bgcolour);
    gfx_MoveTo(xpos, ypos);
    putstr(Textbuf);

endfunc



#DATA
    byte partidx  0, 1, 1, 1, 2, 2, 3
#END

var FATtypes[4] ;
FATtypes[0] := "FAT 12" ;
FATtypes[1] := "FAT 16" ;
FATtypes[2] := "FAT 32" ;
FATtypes[3] := "NTFS (or exFAT)" ;

#constant BSI_BOOTSIG        38       // boot sector boot signature offset
#constant BSI_FSTYPE         54       // boot sector file system type string offset
#constant SYSTEM_ID          0x1C2    // Partition type ID
//    0x1      * FAT12 primary partition or logical drive (fewer than 32,680 sectors in the volume)
//    0x4      * FAT16 partition or logical drive (32,680–65,535 sectors or 16 MB–33 MB)
//    0x6      * BIGDOS FAT16 partition or logical drive (33MB – 4 GB)
//    0x7      * Installable File System (NTFS partition or logical drive)
//    0xB      * FAT32 partition or logical drive
//    0xC      * FAT32 partition or logical drive using BIOS INT 13h extensions
//    0xE      * BIGDOS FAT16 partition or logical drive using BIOS INT 13h extensions

// returns
// 0 no valid MBR or partition
// 0 MBR FAT12
// 1 partitioned fat16
// 1 MBR FAT16
// 3 NTFS or EXFAT

func DiskCheck()
    var *p, r, j, k, n, id ;

    if(!media_Init())                    // initialize uSD card
        print("media_Init failed\n") ;
        repeat forever
    endif

    print("media_Init sucessful\n") ;
    media_SetSector(0, 0);              // set stream sector address
    if(!media_RdSector(sectorbuf))
        print("media_RdSector failed\n") ;
        repeat forever
    endif

    if (sectorbuf[255] == 0xAA55)
        id := -1 ;

        // check for boot sector
        // if FAT12, r = 0
        // if FAT16, r = 1
        // if FAT32, r = 2
        // else r = -1
        r := -1;
        if (str_GetByte(str_Ptr(sectorbuf) + BSI_BOOTSIG) == 0x29)      // check for valid MBR boot sig

            p := str_Ptr(sectorbuf) + BSI_FSTYPE;       // MBR FAT type?
            if (str_Match(&p, "FAT12"))
                r := 0 ;
            else if (str_Match(&p, "FAT16"))
                r := 1 ;
            else if (str_Match(&p, "FAT32"))
                r := 2 ;
            endif
        else
            p := str_Ptr(sectorbuf) + 3;                // NTFS type?
            if (str_Match(&p, "NTFS    "))
                r := 3 ;
            else if (str_Match(&p, "EXFAT   "))
                r := 3 ;
            endif

        endif

        if(r >= 0)
            print("MBR ",[STR] FATtypes[r]);       // yes its MBR type
            id := 0;
        else
            p := str_Ptr(sectorbuf) + SYSTEM_ID;       // MBR FAT type?
            if(!(id := lookup8(str_GetByte(p) , 0x01, 0x04, 0x06, 0x0E, 0x0B, 0x0C, 0x07)))
                print("Unrecognised Partition id 0x", [HEX2] str_GetByte(p)) ;
            else
                id--;
                print("Partitioned ") ;
                r := partidx[id] ;
                putstr(FATtypes[r]) ;

                print("\n# Type Start    Length\n") ;

                j := 0x1C6;     // byte offset for partition info
                k := 0xE1;      // word offset for partition type
                n := 0;
                while(n++ < 4)
                    print(n,"  ", [HEX2]sectorbuf[k]);      // print partition number and type
                    p := str_Ptr(sectorbuf) + j;
                    str_Printf(&p,"  %08lX %08lX\n");       // print partition start address and size
                    j += 16;    // next info
                    k += 8;     // next type
                wend
            endif
        endif
     else
        print("No Valid MBR or Partition\nTable found\n") ;
    endif
    if(r==1)
        putstr("\nMountable.....\n");
        if(file_Mount())
            putstr("\nMount test OK");
            file_Unmount();
        else
            putstr("\nMount test failed");
        endif
    else
        putstr("\nUnmountable");
    endif
    return id;
endfunc

//=================================================================================
//=================================================================================
//=================================================================================
//=================================================================================
//=================================================================================
//=================================================================================




Copyright © 2007 4D Systems Pty Ltd, Sydney, Australia - All Rights Reserved | Terms and Conditions