HACKING DuinoMite BASIC


Image

There is FIRMWARE WISHLIST on Ken Segler Designs forum and I post there a lot with requests for this or that command to be add 🙂

As the DM-BASIC code is over 30 000 lines I never looked at it in detail, just if wanted to see how some command works I was looking at the specific code which implements it.

Overall I though it’s difficult and confusing to touch in so big code as I could easily mess up something with the other commands.

Iggy from KSD forum did some commands recently for me and when he submited them to Ken to include in the mainstream code I was amazed how simple was to add command to DM-BASIC.

For instance he implemented function DM.VMEM which returns the first address of the video RAM as Nick requested on TBS forum, the code insertion was:

in graphics.h there is one line to add:

// Ingmar
{ “DM.VMEM”, T_FNA | T_NBR, 0, fun_vmem },

this row define the name of the new statement: “DM.VMEM” then define it as FUNCTION returning NUMBER and will call fun_vmem() to get it’s value

and in graphics.c there is this code snip to add:

/////////////////////////////////////////////
// Returns lower 16 bits of video buffer.
// This assumes the upper 16 bits always start 0xa000, maybe we should return all 32 bits?
/////////////////////////////////////////////
void fun_vmem(void) {
int vmem = (int)VA;

vmem &= 0x0000ffff;
fret = (float)vmem;
}

so with adding 5 lines of code we already have new DM.VMEM function which returns the address of the Video buffer!

WOW! I didn’t expect it to be SO easy!

now let’s see how he implemented SHIFTOUT:

first define it in external.h
// Ingmar
{ “SHIFTOUT”, T_CMD, 0, cmd_shiftout },

this time this is COMMAND i.e. do not return value and the code is at cmd_shiftout()

and the code is put in external.c

///////////////////////////////////////////////
// This is invoked as a command (ie, shiftout(Dpin, Clkpin, Mode, OutStr, NumBits) )
// Remember that the string returned in outstr will have the length in byte 0, outstr[0]

#define uDly(a) {WriteCoreTimer(0); while(ReadCoreTimer() < a);}

void cmd_shiftout(void) {
int dpin, cpin, mode, nbits;
int ix, iy; // loop counter
int cnt; // number of bytes to output.
unsigned char mybyte;

char * outstr;

const int BDLY = 3; // Determines clocking rate. # of CoreTimer cycles.

getargs(&cmdline, 9, “,”); // Get the arguments, we should have five, comma seperated.

if (argc < 9) error(“Invalid syntax”); // Test number of arguments given.

dpin = getinteger(argv[0]); // Data pin
cpin = getinteger(argv[2]); // Clock pin
mode = getinteger(argv[4]); // Mode
outstr = getstring(argv[6]); // String to clock out,treated as an array of bytes.
nbits = getinteger(argv[8]); // Number of bits to clock out

if (nbits < 1 || nbits > (outstr[0] * 8)) error(“Too many/few bits”);

if (dpin < 0 || dpin > NBRPINS || cpin < 0 || cpin > NBRPINS) error(“Invalid pin number”);
if (ExtCurrentConfig[dpin] >= EXT_COM_RESERVED || ExtCurrentConfig[cpin] >= EXT_COM_RESERVED) error(“Pin is allocated to a communications function”);

// At this point we should have a valid number of arguments and some possibly valid IO pins.

cnt = (nbits – 1) / 8; // Tells us who many complete bytes to loop over.
cnt++; // at least one byte even if it is a partial byte.

ExtSet(cpin,0); // CLK pin low
uDly(BDLY);

if (mode == 0) { // shift bits out LSB first starting at the END of the string.

for (ix=0; ix<nbits; ix++) { // loop through all bits
iy = ix / 8; // byte offset

mybyte = outstr[outstr[0]-iy]; // current byte being output

if (mybyte & (1 << (ix & 0x07))) {
ExtSet(dpin,1); // output a 1
} else {
ExtSet(dpin,0);
}

uDly(BDLY);
ExtSet(cpin,1); // CLK high
uDly(BDLY);
ExtSet(cpin,0); // CLK low
uDly(BDLY);

} // next bit

} else { // shift bits out MSB first starting at the BEGINNING of the string.

for (ix=0; ix<nbits; ix++) { // loop through all bits
iy = (ix / 8) + 1; // byte offset

mybyte = outstr[iy]; // current byte being output

if (mybyte & (128 >> (ix & 0x07))) {
ExtSet(dpin,1); // output a 1
} else {
ExtSet(dpin,0);
}

uDly(BDLY);
ExtSet(cpin,1); // CLK high
uDly(BDLY);
ExtSet(cpin,0); // CLK low
uDly(BDLY);

} // next bit
}

}

/**********************************************/

the code above is well commented and do not need my comments, again it was very simple to add!

Now let’s hack a bit! I wanted to make my own command to prove the concept!

If you want to do the same:

First you have to obtain the tools to compile DM sources from Microchip web

Download MPLAB 8.80 (166MB) and PIC C32 compiler v1.11b (73 MB) and install them

Then download DM-BASIC latest sources from Olimex Web page http://www.olimex.com/dev/

Unpack them in working directory and try the project. Note I had to setup the C32 locations manually and to change search path for Olimex.h to build the project successfully. The HEX is compiled and located in OUTPUT directory and named OLIMEX.HEX, use the Bootloader tool to burn in DuinoMite.

I compiled the source first and downloaded to DuinoMite. Everything works OK!

OK then let me try to add HELLO command which writes “Hello World” on the screen

I add in misc.h this line which defines my command:

{ “HELLO”, T_CMD, 0, cmd_hello },

and in misc.c the code to be executed when HELLO is met in BASIC:

void cmd_hello(void) {

MMPrintString(“Hello world!\r\n”);
}

Now let’s compile everything and bootload and try!

Image
it works!

So using this approach you can define ANYTHING you want to have in DM but you miss it, only you should have some basic C knowledge, then to be not afraid of learning new stuff and hacking.

I will personally try to implement next: RCTIME command which will measure capacitance on the GPIO pin in the next days and post the result.

This way you can build your own version of DM-BASIC which to add specific functionallity which is not possible to be done otherwise in pure BASIC. Do not forget DM-BASIC is open source project with GPL 3.0 licensee so whatever you do do not forget to make your sources also available, so the community can benefit from your contribution and the project move forward!

Happy hacking!

2 Comments (+add yours?)

  1. Trackback: HACKING DuinoMite BASIC | Wizard From Oz
  2. jumpjack
    Jun 21, 2012 @ 22:51:18

    once you jack the basic, how do you upload it to the board?
    I’ve seen around an additional command to turn duinomite into an SD Card reader! How could I do it?

    Reply

Leave a comment