picbsc 0.9 readme Read usage.txt for a quick start, but if you don't even want to do that, the format is: picbsc file.bsc which if successful will create two files: file.asm -- assembly file suitable for compilation in MPLAB file.hex -- hex file suitable for loading by Rick Farmer's PIC loader alternately, picbsc -norickpic file.bsc will create files suitable for loading directly onto the PIC that doesn't have Rick's loader. The differences in the two versions: Rick's Loader Support -norickpic ========================================================================== program begins at 0x0003 program begins at 0x0000 1st instruction must be goto 1st instruction can be anything memory limited to 6K memory limited to 8K The compiler output is similar to that produced by the GNU tools, so if you're using ViM or EMACs for your editor, you're in luck. Important : starting with version 0.91 the PIC configuration is done with include files. You should read the include files for your PIC. Any important notes will be at the top. Most PIC specific include files will also include the related PIC family include file, so it wouldn't hurt to at least glance there also. For example, the default PIC is the 16f877. The files included when compiling for this PIC are: p16f877.inc ' 16f877 specific defines p16f87x.inc ' defines common to the 16f873/4/6/7 * What is this? This is a BASIC compiler with a syntax similar to CH-Basic, see syntax.txt for a complete syntax. It only works for the PIC16F876 and PIC16F877. It wouldn't take much to have it work on other PIC devices, but I haven't any other devices on which to test it. It's written in ANSI C and has been tested under Linux (using gcc) and MS-DOS (using Turbo-C 2.0). * Why did I write this? CH-Basic is slow, requires multiple steps (though these were automated somewhat by batch files), gives a completely useless error message, has some really annoying limitations, occassionally puts out incorrect code, crashes *a lot*, and only works on Windows. I tried a few other compilers but wasn't terribly happy with any of them, so I thought I'd try my hand at writing one. This is the result of the second try. * Why didn't I implement command xxx? I implement commands on an as-needed basis. What you see is what I've needed. * Where will this go? Who knows? It's currently sufficient for my needs, but as I advance I suspect my needs will grow. Somewhere I've an EEPROM and when I get it into place I'll likely add EEPROM support. All registers are available to the program, so true support isn't mandatory. * What all is in the assembly file? Read the accompanying document, ``assembly.txt,'' for a description. All of this information made it easier to debug the compiler. * Why do the DOS and Linux versions create different ASM and HEX files? I've noticed two differences in the code creation between DOS and Linux as follows: delay -- this uses a double to convert us to instruction cyclces and can be +/-1 instruction cycle, so the code generated might be be slightly different in some cases lookup tables -- lookup tables are sorted by size to minimize wasted space (since they cannot cross 8-bit boundaries). Tables of the same size might not be in the same order when sorted due to differences in qsort() * Warranty? None! Absolutely, positively none! I've done my best but for all I know this is absolutely useless & should be tossed. * Bugs? No doubt, but I've not run into any. Please let me know if you find any. * Future? Here's what I see in the future: * block local variables Like C, each block could define variables that could only be accessed by that block. This would mean each procedure could have its own local variables. This cries for a full call-tree analysis because if two variables are never in scope at the same time they can use a shared data location. I don't know how effieciently this could be done and I'm still trying to keep this small enough to be useful under DOS. * a minor, but useful change in the procedure definition as follows: PROC name([VAL] [type] var1[, [VAL] [type] var2[, ...]]) VAL is optional and if present means the parameter is passed by value. Currently, PICbsc passes parameters by reference so if one is changed in the procedure, the change is reflected in the parameter when the procedure returns. type is optional and if present creates a new procedure-local variable named name * common sub-expression elimination. this is a big one especially when using arrays. something like a(i) = a(i) + 1 would benefit greatly here. * function calls that can be used in expressions, for example: x = x * userfunc(y) This turns out to be a rather hairy problem on the PIC family especially where temporaries are concerned. There are a couple of choices: 1. All functions get their own temporaries This works, but wastes data space. 2. Use the analysis mentioned under ``block variables'' above. * inlined procedures Once I've inlined procedures, then much of the parser goes away as follows: First, change the parser a bit so a procedure can be called two ways: call pinhigh(a, 5) or pinhigh a, 5 Now let's look at the command PINHIGH. It can be *completely* written as a BASIC procedure as follows: proc PINHIGH(BYTE port, BYTE bit) _port[port] = _port[port] | (1 << bit) end proc This could be done today but would cause a code size explosion. For example, the command: pinhigh a, 5 requires a single instruction, whereas the procedure PINHIGH above requires at least 24 instructions.