adding some functions

This commit is contained in:
Kyle Isom 2025-04-09 20:46:40 -07:00
parent 268b8f2ee2
commit 2cb940a546
5 changed files with 342 additions and 69 deletions

View File

@ -180,6 +180,33 @@ Appends item to list destructively; lst will be altered with
itm appended to the end of the list." itm appended to the end of the list."
(nconc lst (list itm))) (nconc lst (list itm)))
(defun user-symbols ()
"(user-symbols)
Returns a list of all the symbols add by a user after boot."
(let ((library (list-library2)))
(remove-if (lambda (sym) (member sym library)) (globals))))
(defun reset-user-environment ()
"(reset-user-environment)
Removes all user-defined symbols."
(mapcar 'makunbound (user-symbols)))
(defun keyword-string (k)
"(keyword-string k)
Returns the keyword as a string, or nil if the arg isn't a keyword."
(when (keywordp k)
(subseq (string k) 1)))
(defun load-platform ()
"(load-platform)
Load-platform specific code if present, found on the SD card as
platform.lsp (e.g. picocalc.lsp)."
(let ((platform-file (concatenate 'string (keyword-string (platform)) ".lsp")))
(when (sd-exists-p platform-file)
(load platform-file))))
(load-platform)
(defvar *pkg* nil) (defvar *pkg* nil)
(defun lp () (defun lp ()

View File

@ -21,4 +21,4 @@
(defun add-to-package (filename list) (defun add-to-package (filename list)
(with-sd-card (str filename 1) (with-sd-card (str filename 1)
(dolist (f lst) (dolist (f lst)
(symbol-def f str)))) (symdef str))))

View File

@ -25,6 +25,6 @@ the stream, which follows the 'format directives."
(defun i2c-scan2 (port) (defun i2c-scan2 (port)
(dotimes (addr 127) (dotimes (addr 127)
(with-i2c (str port addr) (with-i2c (str port addr)
(format t "~2,0'x: " addr) (format t "~,20'x: " addr)
(if str (print t) (if str (print t)
(print nil))))) (print nil)))))

View File

@ -11,7 +11,7 @@
// Compile options // Compile options
#define resetautorun #define resetautorun
// #define printfreespace #define printfreespace
// #define printgcs // #define printgcs
#define sdcardsupport #define sdcardsupport
#define gfxsupport #define gfxsupport
@ -21,7 +21,7 @@
#define vt100 #define vt100
#define extensions #define extensions
#define CPI_PICOCALC 1 #define PLATFORM_PICOCALC 1
#define i2ckbd #define i2ckbd
#define BAUDRATE 96 #define BAUDRATE 96
@ -39,7 +39,7 @@
defined(ARDUINO_RASPBERRY_PI_PICO_W) || \ defined(ARDUINO_RASPBERRY_PI_PICO_W) || \
defined(ARDUINO_RASPBERRY_PI_PICO_2) defined(ARDUINO_RASPBERRY_PI_PICO_2)
#define RASPBERRY_PI_PICO_PLATFORM #define RASPBERRY_PI_PICO_PLATFORM
#if defined(CPI_PICOCALC) #if defined(PLATFORM_PICOCALC)
#define IS_PICOCALC #define IS_PICOCALC
#endif #endif
#endif #endif
@ -245,7 +245,7 @@
#define CPU_RP2040 #define CPU_RP2040
#if defined(gfxsupport) #if defined(gfxsupport)
#include <TFT_eSPI.h> // Hardware-specific library #include <TFT_eSPI.h> // Hardware-specific library
#if defined(CPI_PICOCALC) #if defined(PLATFORM_PICOCALC)
#include <PCKeyboard.h> #include <PCKeyboard.h>
PCKeyboard pc_kbd; PCKeyboard pc_kbd;
TFT_eSPI tft = TFT_eSPI(320,320); TFT_eSPI tft = TFT_eSPI(320,320);
@ -318,7 +318,7 @@
#define CPU_RP2350j #define CPU_RP2350j
#if defined(gfxsupport) #if defined(gfxsupport)
#include <TFT_eSPI.h> // Hardware-specific library #include <TFT_eSPI.h> // Hardware-specific library
#if defined(CPI_PICOCALC) #if defined(PLATFORM_PICOCALC)
#include <PCKeyboard.h> #include <PCKeyboard.h>
PCKeyboard pc_kbd; PCKeyboard pc_kbd;
TFT_eSPI tft = TFT_eSPI(320,320); TFT_eSPI tft = TFT_eSPI(320,320);
@ -1575,7 +1575,7 @@ saveimage(object *arg)
#if defined(sdcardsupport) #if defined(sdcardsupport)
unsigned int imagesize = compactimage(&arg); unsigned int imagesize = compactimage(&arg);
#if defined(RASPBERRY_PI_PICO_PLATFORM) #if defined(RASPBERRY_PI_PICO_PLATFORM)
#if defined(CPI_PICOCALC) #if defined(PLATFORM_PICOCALC)
if(!SD.begin(SDCARD_SS_PIN, (uint32_t) SPI_HALF_SPEED, SPI)){ if(!SD.begin(SDCARD_SS_PIN, (uint32_t) SPI_HALF_SPEED, SPI)){
error2(PSTR("failed to init SD card")); error2(PSTR("failed to init SD card"));
@ -1728,7 +1728,7 @@ loadimage(object *arg)
{ {
#if defined(sdcardsupport) #if defined(sdcardsupport)
#if defined(RASPBERRY_PI_PICO_PLATFORM) #if defined(RASPBERRY_PI_PICO_PLATFORM)
#if defined(CPI_PICOCALC) #if defined(PLATFORM_PICOCALC)
if(!SD.begin(SDCARD_SS_PIN,(uint32_t) SPI_HALF_SPEED, SPI)){ if(!SD.begin(SDCARD_SS_PIN,(uint32_t) SPI_HALF_SPEED, SPI)){
error2(PSTR("failed to init SD card")); error2(PSTR("failed to init SD card"));
return 0; return 0;
@ -1743,11 +1743,16 @@ loadimage(object *arg)
File file; File file;
if (stringp(arg)) { if (stringp(arg)) {
char buffer[BUFFERSIZE]; char buffer[BUFFERSIZE];
file = SD.open(MakeFilename(arg, buffer)); file = SD.open(MakeFilename(arg, buffer));
if (!file) { if (!file) {
error2("problem loading from SD card or invalid filename"); error2("problem loading from SD card or invalid filename");
} }
} else if (arg == NULL) { } else if (arg == NULL) {
if (!SD.exists("/ULISP.IMG")) {
error2("workspace image not found");
}
file = SD.open("/ULISP.IMG"); file = SD.open("/ULISP.IMG");
if (!file) { if (!file) {
error2("problem loading from SD card"); error2("problem loading from SD card");
@ -1868,7 +1873,7 @@ autorunimage()
{ {
#if defined(sdcardsupport) #if defined(sdcardsupport)
#if defined(RASPBERRY_PI_PICO_PLATFORM) #if defined(RASPBERRY_PI_PICO_PLATFORM)
#if defined(CPI_PICOCALC) #if defined(PLATFORM_PICOCALC)
if(!SD.begin(SDCARD_SS_PIN, (uint32_t) SPI_HALF_SPEED, SPI)){ if(!SD.begin(SDCARD_SS_PIN, (uint32_t) SPI_HALF_SPEED, SPI)){
error2(PSTR("failed to init SD card")); error2(PSTR("failed to init SD card"));
return; return;
@ -3587,7 +3592,7 @@ void serialbegin (int address, int baud) {
if (address == 1) Serial1.begin((long)baud*100); if (address == 1) Serial1.begin((long)baud*100);
else if (address == 2) Serial2.begin((long)baud*100); else if (address == 2) Serial2.begin((long)baud*100);
#elif defined(ULISP_SERIAL1) #elif defined(ULISP_SERIAL1)
#if defined(CPI_PICOCALC) #if defined(PLATFORM_PICOCALC)
// Waveshare uses Serial1 for default. // Waveshare uses Serial1 for default.
if (address == 1) {} if (address == 1) {}
#else #else
@ -3609,7 +3614,7 @@ void serialend (int address) {
if (address == 1) {Serial1.flush(); Serial1.end(); } if (address == 1) {Serial1.flush(); Serial1.end(); }
else if (address == 2) {Serial2.flush(); Serial2.end(); } else if (address == 2) {Serial2.flush(); Serial2.end(); }
#elif defined(ULISP_SERIAL1) #elif defined(ULISP_SERIAL1)
#if defined(CPI_PICOCALC) #if defined(PLATFORM_PICOCALC)
if (address == 1) {Serial1.flush();} if (address == 1) {Serial1.flush();}
#else #else
if (address == 1) {Serial1.flush(); Serial1.end(); } if (address == 1) {Serial1.flush(); Serial1.end(); }
@ -4706,7 +4711,7 @@ object *sp_withsdcard (object *args, object *env) {
if (!stringp(filename)) error("filename is not a string", filename); if (!stringp(filename)) error("filename is not a string", filename);
params = cdr(params); params = cdr(params);
#if defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_2W) #if defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_2W)
#if defined(CPI_PICOCALC) #if defined(PLATFORM_PICOCALC)
if(!SD.begin(SDCARD_SS_PIN,(uint32_t) SPI_HALF_SPEED, SPI )){ if(!SD.begin(SDCARD_SS_PIN,(uint32_t) SPI_HALF_SPEED, SPI )){
error2(PSTR("failed to init SD card")); error2(PSTR("failed to init SD card"));
return nil; return nil;
@ -7837,30 +7842,6 @@ object *fn_invertdisplay (object *args, object *env) {
return nil; return nil;
} }
char getKey () {
char temp;
if (pc_kbd.keyCount() > 0) {
do {
const PCKeyboard::KeyEvent key = pc_kbd.keyEvent();
if (key.state == PCKeyboard::StatePress) {
char temp = key.key;
if ((temp != 0) && (temp !=255) && (temp != 0xA1) && (temp != 0xA2) && (temp != 0xA3) && (temp != 0xA4) && (temp != 0xA5)) {
ProcessKey(temp);
}
}
} while ((temp == 0) || (temp ==255));
if (temp == '@') temp = '~';
if (temp == '_') temp = '\\';
}
return temp;
}
object *fn_getkey (object *args, object *env) {
(void) env, (void) args;
return character(getKey());
}
// Built-in symbol names // Built-in symbol names
const char string0[] = "nil"; const char string0[] = "nil";
const char string1[] = "t"; const char string1[] = "t";
@ -8111,7 +8092,6 @@ const char string245[] = "invert-display";
const char string246[] = ":led-builtin"; const char string246[] = ":led-builtin";
const char string247[] = ":high"; const char string247[] = ":high";
const char string248[] = ":low"; const char string248[] = ":low";
const char string262[] = "get-key";
#if defined(CPU_ATSAMD21) #if defined(CPU_ATSAMD21)
const char string249[] = ":input"; const char string249[] = ":input";
const char string250[] = ":input-pullup"; const char string250[] = ":input-pullup";
@ -8864,8 +8844,6 @@ const char doc244[] = "(set-rotation option)\n"
"Sets the display orientation for subsequent graphics commands; values are 0, 1, 2, or 3."; "Sets the display orientation for subsequent graphics commands; values are 0, 1, 2, or 3.";
const char doc245[] = "(invert-display boolean)\n" const char doc245[] = "(invert-display boolean)\n"
"Mirror-images the display."; "Mirror-images the display.";
const char doc262[] = "(get-key)\n"
"Get the next key from the keyboard.";
// Built-in symbol lookup table // Built-in symbol lookup table
const tbl_entry_t lookup_table[] = { const tbl_entry_t lookup_table[] = {
@ -9118,7 +9096,6 @@ const tbl_entry_t lookup_table[] = {
{ string246, (fn_ptr_type)LED_BUILTIN, 0, NULL }, { string246, (fn_ptr_type)LED_BUILTIN, 0, NULL },
{ string247, (fn_ptr_type)HIGH, DIGITALWRITE, NULL }, { string247, (fn_ptr_type)HIGH, DIGITALWRITE, NULL },
{ string248, (fn_ptr_type)LOW, DIGITALWRITE, NULL }, { string248, (fn_ptr_type)LOW, DIGITALWRITE, NULL },
{ string262, fn_getkey, 0200, doc262 },
#if defined(CPU_ATSAMD21) #if defined(CPU_ATSAMD21)
{ string249, (fn_ptr_type)INPUT, PINMODE, NULL }, { string249, (fn_ptr_type)INPUT, PINMODE, NULL },
{ string250, (fn_ptr_type)INPUT_PULLUP, PINMODE, NULL }, { string250, (fn_ptr_type)INPUT_PULLUP, PINMODE, NULL },
@ -10474,7 +10451,7 @@ initgfx()
digitalWrite(34, HIGH); digitalWrite(34, HIGH);
#elif defined(RASPBERRY_PI_PICO_PLATFORM) #elif defined(RASPBERRY_PI_PICO_PLATFORM)
tft.init(); tft.init();
#if defined(CPI_PICOCALC) #if defined(PLATFORM_PICOCALC)
tft.setRotation(0); tft.setRotation(0);
tft.invertDisplay(1); tft.invertDisplay(1);
#endif #endif
@ -10505,7 +10482,7 @@ void setup () {
} }
#if defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_2W) #if defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_2W)
#if defined(sdcardsupport) && defined(CPI_PICOCALC) #if defined(sdcardsupport) && defined(PLATFORM_PICOCALC)
// picocalc doesn't have touch screen // picocalc doesn't have touch screen
pinMode(SDCARD_SS_PIN,OUTPUT); pinMode(SDCARD_SS_PIN,OUTPUT);
digitalWrite(SDCARD_SS_PIN,1); digitalWrite(SDCARD_SS_PIN,1);
@ -10521,7 +10498,6 @@ void setup () {
initkybd(); initkybd();
#endif #endif
pfstring(PSTR("uLisp 4.7b "), pserial); pln(pserial); pfstring(PSTR("uLisp 4.7b "), pserial); pln(pserial);
loadimage(NULL);
} }
// Read/Evaluate/Print loop // Read/Evaluate/Print loop

View File

@ -22,7 +22,61 @@ bcd_to_dec(uint8_t n)
return ((n>>4) * 10) + (n&0x0f); return ((n>>4) * 10) + (n&0x0f);
} }
// Definitions /*
* Standard definitions
*
* These definitions should be the same on every platform.
*/
object *
fn_platform(object *args, object *env)
{
(void) args;
(void) env;
#if defined(PLATFORM_PICOCALC)
const char platformName[] = ":picocalc";
#elif defined(TDECK_PERI_POWERON) /* first t-deck define */
const char platformName[] = ":t-deck";
#elif defined(ARDUINO_TEENSY41)
const char platformName[] = ":teensy41";
#else
const char platformName[] = ":unknown";
#endif
return internlong((char *)platformName);
}
object *
fn_bcd_to_dec(object *args, object *env)
{
(void) env;
object *arg = car(args);
int n = checkinteger(arg);
if ((n < 0) || (n > 153)) {
error2("number not in the range [0...#x99].");
}
uint8_t result = bcd_to_dec(static_cast<uint8_t>(n));
return number(static_cast<int>(result));
}
object *
fn_dec_to_bcd(object *args, object *env)
{
(void) env;
object *arg = car(args);
int n = checkinteger(arg);
if ((n < 0) || (n > 99)) {
error2("number not in the range [0...99].");
}
uint8_t result = dec_to_bcd(static_cast<uint8_t>(n));
return number(static_cast<int>(result));
}
object * object *
fn_now(object *args, object *env) fn_now(object *args, object *env)
{ {
@ -130,6 +184,27 @@ fn_sym_def(object *args, object *env)
return bsymbol(NOTHING); return bsymbol(NOTHING);
} }
object *
fn_listlibrary2(object *args, object *env)
{
(void) args, (void) env;
object *lst = nil;
GlobalStringIndex = 0;
object *line = read(glibrary);
while (line != NULL) {
builtin_t bname = builtin(first(line)->name);
if (bname == DEFUN || bname == DEFVAR) {
lst = cons(second(line), lst);
}
line = read(glibrary);
}
return lst;
}
object * object *
fn_lambdap(object *arg, object *env) fn_lambdap(object *arg, object *env)
{ {
@ -146,35 +221,190 @@ fn_lambdap(object *arg, object *env)
return nil; return nil;
} }
// SD card standard library.
#if defined(sdcardsupport)
object *
fn_sd_rename(object *args, object *env)
{
(void) env;
char buffer1[BUFFERSIZE];
char buffer2[BUFFERSIZE];
object *pathFrom = car(args);
if (!stringp(pathFrom)) {
error2("filenames must be strings.");
}
object *pathTo = car(cdr(args));
if (!stringp(pathTo)) {
error2("filenames must be strings.");
}
if (!SD.rename((const char *)MakeFilename(pathFrom, buffer1),
(const char *)MakeFilename(pathTo, buffer2))) {
return nil;
}
return tee;
}
object * object *
fn_backlight(object *args, object *env) fn_sd_remove(object *args, object *env)
{
(void) env;
char buffer[BUFFERSIZE];
object *arg = car(args);
if (!SD.remove(MakeFilename(arg, buffer))) {
return nil;
}
return tee;
}
object *
fn_sd_existsp(object *args, object *env)
{ {
(void) env; (void) env;
char buffer[BUFFERSIZE];
object *arg = car(args); object *arg = car(args);
if (!SD.exists(MakeFilename(arg, buffer))) {
if (arg != nil) { return nil;
if (!(floatp(arg))) {
error2(notanumber);
}
pc_kbd.setBacklight(arg->single_float);
} }
float level = pc_kbd.backlight(); return tee;
}
return makefloat(level);
/*
(sd-make-dir path)
Create a directory on the SD card.
This will also create any intermediate directories that dont already exists;
e.g. SD.mkdir("a/b/c") will create a, b, and c.
*/
object *
fn_sd_mkdir(object *args, object *env)
{
(void) env;
char buffer[BUFFERSIZE];
object *arg = car(args);
if (SD.mkdir(MakeFilename(arg, buffer))) {
return tee;
}
return nil;
} }
// Symbol names /*
const char stringlambdap[] PROGMEM = "lambdap"; (sd-remove-dir path)
const char stringnow[] PROGMEM = "now"; Remove a directory from the SD card. The directory must be empty.
const char string_sym_def[] PROGMEM = "symbol-def"; */
const char string_backlight[] PROGMEM = "backlight"; object *
fn_sd_rmdir(object *args, object *env)
{
(void) env;
// Documentation strings char buffer[BUFFERSIZE];
object *arg = car(args);
if (SD.rmdir(MakeFilename(arg, buffer))) {
return tee;
}
return nil;
}
/*
* (sd-list)
*/
object *
fn_sd_list(object *args, object *env)
{
(void) env;
char *sd_path_buf = NULL;
SDBegin();
File root;
object *result = cons(NULL, NULL);
object *ptr = result;
if (args != NULL) {
object *arg1 = checkstring(first(args));
int len = stringlength(arg1) + 2; //make it longer for the initial slash and the null terminator
sd_path_buf = (char*)malloc(len);
if (sd_path_buf != NULL) {
cstring(arg1, &sd_path_buf[1], len-1);
sd_path_buf[0] = '/'; //really weird way to add a slash at the front...
root = SD.open(sd_path_buf);
}
} else{
root = SD.open("/");
}
while (true) {
File entry = root.openNextFile();
if (!entry) {
break; // no more files
}
object *filename = lispstring((char*)entry.name());
if (entry.isDirectory()) {
cdr(ptr) = cons(filename, NULL);
} else{
cdr(ptr) = cons(cons(filename, number(entry.size())), NULL);
}
ptr = cdr(ptr);
entry.close();
}
if (sd_path_buf != NULL) {
free(sd_path_buf);
}
root.close();
return cdr(result);
}
#endif
/*
* SYMBOL NAMES
*
* Define symbol names as const char[] PROGMEM here.
*/
const char stringlambdap[] PROGMEM = "lambdap";
const char stringnow[] PROGMEM = "now";
const char string_sym_def[] PROGMEM = "symdef";
const char stringbcd_to_dec[] PROGMEM = "bcd-to-dec";
const char stringdec_to_bcd[] PROGMEM = "dec-to-bcd";
const char stringlist_library2[] PROGMEM = "list-library2";
const char stringplatform[] PROGMEM = "platform";
#if defined(sdcardsupport)
const char stringsd_rename[] PROGMEM = "sd-rename";
const char stringsd_remove[] PROGMEM = "sd-remove";
const char stringsd_existsp[] PROGMEM = "sd-exists-p";
const char stringsd_mkdir[] PROGMEM = "sd-make-dir";
const char stringsd_rmdir[] PROGMEM = "sd-remove-dir";
const char stringsd_dir[] PROGMEM = "sd-list";
#endif
/*
* DOCUMENTATION STRINGS
*
* Define documentation strings as const char[] PROGMEM here.
*/
const char doclambdap[] PROGMEM = "(lambdap x)" const char doclambdap[] PROGMEM = "(lambdap x)"
"Returns t if the form passed in is a lambda."; "Returns t if the form passed in is a lambda.";
@ -183,18 +413,46 @@ const char docnow[] PROGMEM = "(now [hh mm ss])\n"
"Sets the current time, or with no arguments returns the current time\n" "Sets the current time, or with no arguments returns the current time\n"
"as a list of three integers (hh mm ss)."; "as a list of three integers (hh mm ss).";
const char docpform[] PROGMEM = "(pform form str)\n"
"Print a form to a stream in a manner suitable for writing to storage.";
const char doc_sym_def[] PROGMEM = "(symbol-def symbol [str])\n" const char doc_sym_def[] PROGMEM = "(symbol-def symbol [str])\n"
"Prints the definition of a symbol (variable or function) defined in\n" "Prints the definition of a symbol (variable or function) defined in\n"
"ulisp using the pretty printer." "ulisp using the pretty printer."
"If str is specified it prints to the specified stream.\n" "If str is specified it prints to the specified stream.\n"
"It returns no value."; "It returns no value.";
const char doc_backlight[] PROGMEM = "(backlight level)\n" const char doc_bcd_to_dec[] PROGMEM = "(bcd-to-dec n)\n"
"If level is nil, return the current backlight level. Otherwise, set" "Convert the BCD-encoded number n to decimal.";
"the backlight to the level. Returns the current backlight level.";
const char doc_dec_to_bcd[] PROGMEM = "(dec-to-bcd n)\n"
"BCD encode n.";
const char doc_list_library2[] PROGMEM = "(list-library2)\n"
"Return a list of all symbols in the current Lisp library.";
const char doc_platform[] PROGMEM = "(platform)\n"
"Returns a keyword with the current platform. Supports :picocalc,\n"
":t-deck, and :teensy41. Otherwise, returns :unknown.";
#if defined(sdcardsupport)
const char docsd_rename[] PROGMEM = "(sd-rename from to)\n"
"Renames the file named by 'from' to 'to.'";
const char docsd_remove[] PROGMEM = "(sd-remove file)\n"
"Removes the named file from the filesystem. Returns t if the file\n"
"was remove successfully.";
const char docsd_existsp[] PROGMEM = "(sd-exists-p file)\n"
"Returns t if the named file exists.";
const char docsd_dir[] PROGMEM = "(sd-list [directory])\n"
"Returns a list of filenames in the root or named directory.";
const char docsd_mkdir[] PROGMEM = "(sd-make-dir directory)\n"
"Create a directory with the specified name. Returns t if \n"
"successful, otherwise nil.";
const char docsd_rmdir[] PROGMEM = "(sd-remove-dir directory)\n"
"Remove the named directory. Returns t if successful, otherwise nil.";
#endif
// Symbol lookup table // Symbol lookup table
@ -202,7 +460,19 @@ const tbl_entry_t lookup_table2[] PROGMEM = {
{ stringlambdap, fn_lambdap, 0211, doclambdap }, { stringlambdap, fn_lambdap, 0211, doclambdap },
{ stringnow, fn_now, 0203, docnow }, { stringnow, fn_now, 0203, docnow },
{ string_sym_def, fn_sym_def, 0212, doc_sym_def }, { string_sym_def, fn_sym_def, 0212, doc_sym_def },
{ string_backlight, fn_backlight, 0201, doc_backlight }, { stringbcd_to_dec, fn_bcd_to_dec, 0211, doc_bcd_to_dec },
{ stringdec_to_bcd, fn_dec_to_bcd, 0211, doc_dec_to_bcd },
{ stringlist_library2, fn_listlibrary2, 0200, doc_list_library2 },
{ stringplatform, fn_platform, 0200, doc_platform },
#if defined(sdcardsupport)
{ stringsd_rename, fn_sd_rename, 0222, docsd_rename },
{ stringsd_remove, fn_sd_remove, 0211, docsd_remove },
{ stringsd_existsp, fn_sd_existsp, 0211, docsd_existsp },
{ stringsd_dir, fn_sd_list, 0201, docsd_dir },
{ stringsd_mkdir, fn_sd_mkdir, 0211, docsd_mkdir },
{ stringsd_rmdir, fn_sd_rmdir, 0211, docsd_rmdir },
#endif
}; };
// Table cross-reference functions // Table cross-reference functions