diff --git a/platforms.lisp b/platforms.lisp index 777aef6..3e458c1 100644 --- a/platforms.lisp +++ b/platforms.lisp @@ -9,13 +9,17 @@ (defparameter *platforms* '((:avr - (:types zzero symbol number stream string pair) + (:types zzero symbol code number stream string pair) (:streams serial i2c spi sd) (:keywords ("CPU_ATmega328P" (DIGITALWRITE HIGH LOW) (PINMODE INPUT INPUT_PULLUP OUTPUT) (ANALOGREFERENCE DEFAULT INTERNAL EXTERNAL)) + ("CPU_ATmega1284P" + (DIGITALWRITE HIGH LOW) + (PINMODE INPUT INPUT_PULLUP OUTPUT) + (ANALOGREFERENCE DEFAULT INTERNAL1V1 INTERNAL2V56 EXTERNAL)) ("CPU_ATmega2560" (DIGITALWRITE HIGH LOW) (PINMODE INPUT INPUT_PULLUP OUTPUT) @@ -31,7 +35,7 @@ (ANALOGREFERENCE DEFAULT VDD INTERNAL1V024 INTERNAL2V048 INTERNAL4V096 INTERNAL2V5 EXTERNAL) (ANALOGREAD ADC_DAC0 ADC_TEMPERATURE))) - (:features :dacreference)) + (:features :code :dacreference)) (:arm (:types zzero code number stream float array string pair) (:streams serial i2c spi sd string gfx) @@ -85,10 +89,7 @@ (:types zzero code number stream float array string pair) (:streams serial i2c spi sd string gfx) (:keywords - ("ESP8266" - (DIGITALWRITE HIGH LOW) - (PINMODE INPUT INPUT_PULLUP OUTPUT)) - ("ESP32" + (nil (DIGITALWRITE HIGH LOW) (PINMODE INPUT INPUT_PULLUP INPUT_PULLDOWN OUTPUT))) (:features :float :gfx :code :array :stringstream :write-resolution))) diff --git a/sections/arm/saveimage.c b/sections/arm/saveimage.c index 229f62e..27a5cdd 100644 --- a/sections/arm/saveimage.c +++ b/sections/arm/saveimage.c @@ -196,7 +196,7 @@ int loadimage (object *arg) { else error(LOADIMAGE, PSTR("illegal argument"), arg); if (!file) error2(LOADIMAGE, PSTR("problem loading from SD card")); SDReadInt(file); - int imagesize = SDReadInt(file); + unsigned int imagesize = SDReadInt(file); GlobalEnv = (object *)SDReadInt(file); GCStack = (object *)SDReadInt(file); #if SYMBOLTABLESIZE > BUFFERSIZE @@ -205,7 +205,7 @@ int loadimage (object *arg) { for (int i=0; i>8 & 0xFF); } #elif defined(FLASHWRITESIZE) -#elif defined(FLASHWRITESIZE) -#define BASE_ADDRESS 0x1C000 +#if defined (CPU_ATmega1284P) +// save-image area is the 16K bytes (64 256-byte pages) from 0x1bc00 to 0x1fc00 +const uint32_t BaseAddress = 0x1bc00; +uint8_t FlashCheck() { + return 0; +} -boolean FlashSetup () { - return (Flash.checkWritable() == FLASHWRITE_OK); +void FlashWriteInt (uint32_t *addr, int data) { + if (((*addr) & 0xFF) == 0) optiboot_page_erase(BaseAddress + ((*addr) & 0xFF00)); + optiboot_page_fill(BaseAddress + *addr, data); + if (((*addr) & 0xFF) == 0xFE) optiboot_page_write(BaseAddress + ((*addr) & 0xFF00)); + (*addr)++; (*addr)++; } -boolean FlashBeginWrite (int pages) { - // Erase how many 512K pages we need; must be a power of 2 <= 32. - return Flash.erasePage(BASE_ADDRESS, pages) == 0; +void FlashEndWrite (uint32_t *addr) { + if (((*addr) & 0xFF) != 0) optiboot_page_write((BaseAddress + ((*addr) & 0xFF00))); } -void FlashWriteByte (uint32_t *addr, uint8_t data) { - Flash.writeByte((*addr)++, data); +#elif defined (CPU_AVR128DX48) +// save-image area is the 16K bytes (32 512-byte pages) from 0x1c000 to 0x20000 +const uint32_t BaseAddress = 0x1c000; +uint8_t FlashCheck() { + return Flash.checkWritable(); } void FlashWriteInt (uint32_t *addr, int data) { - Flash.writeWord(*addr, data); + if (((*addr) & 0x1FF) == 0) Flash.erasePage(BaseAddress + ((*addr) & 0xFE00)); + Flash.writeWord(BaseAddress + *addr, data); (*addr)++; (*addr)++; } + +void FlashEndWrite (uint32_t *addr) { +} +#endif #else void EEPROMWriteInt (unsigned int *addr, int data) { EEPROM.write((*addr)++, data & 0xFF); EEPROM.write((*addr)++, data>>8 & 0xFF); @@ -51,6 +65,9 @@ unsigned int saveimage (object *arg) { int SymbolUsed = SymbolTop - SymbolTable; for (int i=0; i FLASHWRITESIZE) error(SAVEIMAGE, PSTR("image too large"), number(imagesize)); - if (!FlashBeginWrite(32)) error2(SAVEIMAGE, PSTR("problem erasing flash")); - uint32_t addr = BASE_ADDRESS; + uint32_t addr = 0; FlashWriteInt(&addr, (uintptr_t)arg); FlashWriteInt(&addr, imagesize); FlashWriteInt(&addr, (uintptr_t)GlobalEnv); FlashWriteInt(&addr, (uintptr_t)GCStack); #if SYMBOLTABLESIZE > BUFFERSIZE FlashWriteInt(&addr, (uintptr_t)SymbolTop); - for (int i=0; i BUFFERSIZE @@ -143,7 +175,10 @@ unsigned int loadimage (object *arg) { int SymbolUsed = SymbolTop - SymbolTable; for (int i=0; i BUFFERSIZE SymbolTop = (char *)FlashReadInt(&addr); - int SymbolUsed = SymbolTop - SymbolTable; - for (int i=0; i #define Serial Serial3 - #define WORKSPACESIZE (2800-SDSIZE) /* Objects (4*bytes) */ + #define WORKSPACESIZE (2750-SDSIZE) /* Objects (4*bytes) */ #define FLASHWRITESIZE 16384 /* Bytes */ #define SYMBOLTABLESIZE 256 /* Bytes */ + #define CODESIZE 96 /* Bytes <= 512 */ #define STACKDIFF 320 #define CPU_AVR128DX48 diff --git a/sections/esp/saveimage.c b/sections/esp/saveimage.c index c2bee20..da6974b 100644 --- a/sections/esp/saveimage.c +++ b/sections/esp/saveimage.c @@ -85,14 +85,14 @@ unsigned int loadimage (object *arg) { else error(LOADIMAGE, PSTR("illegal argument"), arg); if (!file) error2(LOADIMAGE, PSTR("problem loading from SD card")); SDReadInt(file); - int imagesize = SDReadInt(file); + unsigned int imagesize = SDReadInt(file); GlobalEnv = (object *)SDReadInt(file); GCStack = (object *)SDReadInt(file); #if SYMBOLTABLESIZE > BUFFERSIZE SymbolTop = (char *)SDReadInt(file); for (int i=0; i BUFFERSIZE SymbolTop = (char *)EpromReadInt(&addr); for (int i=0; iinteger) & 0xFF) +#define endblock(x) ((x->integer) >> 8 & 0xFF) +#else +#define CODESHIFT 16 #define startblock(x) ((x->integer) & 0xFFFF) #define endblock(x) ((x->integer) >> 16 & 0xFFFF) #endif +#endif // Calling conventions. #define CC_SYMBOL 0x80 diff --git a/sections/print-functions.c b/sections/print-functions.c index cde4519..c0dcd27 100644 --- a/sections/print-functions.c +++ b/sections/print-functions.c @@ -128,6 +128,14 @@ void printhex4 (int i, pfun_t pfun) { } pfun(' '); } + +void printhex2 (int i, pfun_t pfun) { + for (unsigned int d=0x10; d>0; d=d>>4) { + unsigned int j = i/d; + pfun((j<10) ? j+'0' : j+'W'); + i = i - j*d; + } +} #endif #ifdef FLOAT diff --git a/sections/read-functions.c b/sections/read-functions.c index d70657d..29f270d 100644 --- a/sections/read-functions.c +++ b/sections/read-functions.c @@ -128,11 +128,17 @@ int gserial () { KybdAvailable = 0; WritePtr = 0; return '\n'; -#else +#elif defined(CPU_ATmega328P) while (!Serial.available()); char temp = Serial.read(); if (temp != '\n') pserial(temp); return temp; +#else + unsigned long start = millis(); + while (!Serial.available()) if (millis() - start > 1000) clrflag(NOECHO); + char temp = Serial.read(); + if (temp != '\n' && !tstflag(NOECHO)) pserial(temp); + return temp; #endif } @@ -140,10 +146,16 @@ object *nextitem (gfun_t gfun) { int ch = gfun(); while(issp(ch)) ch = gfun(); + #if defined(CPU_ATmeta328P) if (ch == ';') { while(ch != '(') ch = gfun(); - ch = '('; } + #else + if (ch == ';') { + do { ch = gfun(); if (ch == ';' || ch == '(') setflag(NOECHO); } + while(ch != '('); + } + #endif if (ch == '\n') ch = gfun(); if (ch == -1) return nil; if (ch == ')') return (object *)KET; diff --git a/sections/riscv/setup.c b/sections/riscv/setup.c index e7b8758..1d2d14a 100644 --- a/sections/riscv/setup.c +++ b/sections/riscv/setup.c @@ -19,5 +19,5 @@ void setup () { initenv(); initsleep(); initgfx(); - pfstring(PSTR("uLisp 3.5 "), pserial); pln(pserial); + pfstring(PSTR("uLisp 3.6 "), pserial); pln(pserial); } diff --git a/sections/riscv/stream-interface.c b/sections/riscv/stream-interface.c index 9e7cd1e..391262a 100644 --- a/sections/riscv/stream-interface.c +++ b/sections/riscv/stream-interface.c @@ -94,7 +94,10 @@ pfun_t pstreamfun (object *args) { else if (address == 2) pfun = serial2write; else if (address == 3) pfun = serial3write; #endif - } + } + else if (streamtype == STRINGSTREAM) { + pfun = pstr; + } #if defined(sdcardsupport) else if (streamtype == SDSTREAM) pfun = (pfun_t)SDwrite; #endif diff --git a/src/arduino.cc b/src/arduino.cc index bc75052..6b35740 100644 --- a/src/arduino.cc +++ b/src/arduino.cc @@ -4,7 +4,7 @@ object *fn_pinmode (object *args, object *env) { int pin = checkinteger(PINMODE, first(args)); PinMode pm = INPUT; object *arg = second(args); - if (keywordp(arg)) pm = checkkeyword(PINMODE, arg); + if (keywordp(arg)) pm = (PinMode)checkkeyword(PINMODE, arg); else if (intp(arg)) { int mode = getint(arg); if (mode == 1) pm = OUTPUT; else if (mode == 2) pm = INPUT_PULLUP; diff --git a/src/assembler.c b/src/assembler.c index 3bffa0b..a07093d 100644 --- a/src/assembler.c +++ b/src/assembler.c @@ -1,5 +1,11 @@ // Assembler +#if defined(CPU_ATmega1284P) +#define CODE_ADDRESS 0x1bb00 +#elif defined(CPU_AVR128DX48) +#define CODE_ADDRESS 0x1be00 +#endif + object *call (int entry, int nargs, object *args, object *env) { #if defined(CODESIZE) (void) env; @@ -13,7 +19,12 @@ object *call (int entry, int nargs, object *args, object *env) { #ifdef __riscv asm("fence.i"); #endif + #ifdef __AVR__ + uint32_t address = (CODE_ADDRESS + entry)>>1; // Code addresses are word addresses on AVR + int w = ((intfn_ptr_type)address)(param[0], param[1], param[2], param[3]); + #else int w = ((intfn_ptr_type)&MyCode[entry])(param[0], param[1], param[2], param[3]); + #endif return number(w); #else return nil; @@ -76,8 +87,13 @@ int assemble (int pass, int origin, object *entries, object *env, object *pcpair } entries = cdr(entries); } + #ifdef __AVR__ + // Round up to multiple of 2 to give code size + if (pc%2 != 0) pc = pc + 2 - pc%2; + #else // Round up to multiple of 4 to give code size if (pc%4 != 0) pc = pc + 4 - pc%4; + #endif return pc; } @@ -98,6 +114,12 @@ object *sp_defcode (object *args, object *env) { object *params = second(args); if (!symbolp(var)) error(DEFCODE, PSTR("not a symbol"), var); + #ifdef __AVR__ + // Make *p* a local variable for program counter + object *pcpair = cons(newsymbol(pack40((char*)"*p*")), number(0)); + push(pcpair,env); + args = cdr(args); + #else /* ARM or RISC-V */ // Make parameters into synonyms for registers int regn = 0; while (params != NULL) { @@ -112,6 +134,7 @@ object *sp_defcode (object *args, object *env) { object *pcpair = cons(newsymbol(pack40((char*)"*pc*\0")), number(0)); push(pcpair,env); args = cdr(args); + #endif /* end ISA conditional */ // Make labels into local variables object *entries = cdr(args); @@ -158,7 +181,7 @@ object *sp_defcode (object *args, object *env) { if (startblock(codeid) < smallest && startblock(codeid) >= origin) { smallest = startblock(codeid); block = codeid; - } + } } } globals = cdr(globals); @@ -172,7 +195,7 @@ object *sp_defcode (object *args, object *env) { MyCode[target] = MyCode[i]; target++; } - block->integer = target<<16 | origin; + block->integer = target<