Programming Without A Toolchain; Crafting PIC Op Code By Hand

We’ve been living a life of luxury, writing our microcontroller code in a text editor and using — of all things — a compiler to turn it into something the chip can use. [Dan Amlund Thomsen] shows us a different way of doing things. He’s actually crafting the operation codes for a PIC microcontroller by hand. We’re glad he’s explained this in-depth because right now we feel way over our heads.

His program is pretty simple, it blinks a single LED and he’s chosen t work with a PIC 12F1840. The first order of business is to issues the words that configure the chip using 14-bit binary values from the datasheet. From there he goes on to write the program in assembly code. At this point he could pretty much just run this through the assembler, but he’s really just getting started now. He walks through the format necessary to package the configuration words, then goes on to illustrate the translation of assembly commands to binary op codes. We’re not sure we’ll ever get around to trying this ourselves, but it was certainly fun to read about it.

32 thoughts on “Programming Without A Toolchain; Crafting PIC Op Code By Hand

  1. It’s archaic, but I believe that those of us who learned how to code like this better understand what the machine is actually doing as opposed to those who learn very high level abstracted languages.

    Does that matter for someone say doing php for web sites? Probably not. But in the embedded world, it matters. It always seems to me that it is easier for embedded programmers to learn their way up than for high level folks to learn their way down.

    Why back in my day we used to hand patch .hex files…

    Neat stuff, and a great learning experience for those who have never done it.

    1. You need to learn both, preferably at the same time, and with some theory on the side.

      All the people I know who just learned high level languages don’t understand how things work under the hood and constantly shoot themselves in the foot.

      All the people I know who just learned low level stuff frequently get bogged down in minutia, or are blissfully unaware that there are tools that would make their hobby projects drastically less painful (it’s one thing to choose the hard road, but it’s another entirely to not know another road exists).

      Regardless of where you start, I’ve found that without a solid foundation in theory it’s drastically more difficult to go outside of the level of abstraction you first called home. Even those who do go beyond often fall prey to cargo cult thinking, or waste time trying to do something provably impossible (eg come up with a regex to parse arbitrary html).

  2. Not that impressive, in my school we teach assembly and use opcode for making several robots we use in the RoboCup Junior competition.

    And we did it quit well, since we get at least one first place, either soccer rescue or dance competition.

    1. LOL. Me too. A whopping 256 bytes of RAM and 8 toggle switches. Although with the write-protect switch you could go in and edit individual locations. I still think the idea of making any of the data registers the PC was kinda cool.

  3. This is what I used to do for the longest time. I still hate most IDEs with a passion, though back in the mid 80’s I developed what we would now call a visual programming language; was for assembly programming to make my job a bit easier.

    1. Yep – give me a serial port && I am in hog heaven. The only reason I usually use an IDE is to compile and load the code.

      Want to learn assembly? write an assembler. I honestly don’t care to hand compile – did that on an 8080 (remember when “patching” used the debugger to modify code to jump to an area where your hand-assembled code was && then jump back, and you saved the binary?

      Do you *need* the toolchain? No. Is there a reason they exist – yep. This is a bit too retro for me.

  4. It’s interesting that someone actually cared about translation of assembly to machine code enough to write a tutorial and I personally think that’s great. There’s definitely a small, but justifiable merit to going beyond just understanding the human-readable mnemonics, especially when you are doing stuff where you have to care about how many bytes are involved in each instruction.

    Also, sometimes, assemblers suck. I used avra to assemble code for the Attiny4/5/9/10 series, but it apparently won’t support certain instructions with relation to loading data from memory and incrementing pointers. So, I had to dig into some datasheets and even ended up disassembling a few pieces of a hex file to find the instructions I wanted. (Rant: https://github.com/jwcxz/bcard/blob/master/src/bcard.asm#L374 )

    I think that extracting meaning out of hex files is definitely something that most embedded engineers end up having to do sooner or later. It can help catch lots of entertaining errors that assemblers may or may not be designed to look out for.

    1. Wrote an 8031 (8051 without flash) assembler in 1986 in turbo pascal, much better than the Intel one IMHO and quite easy as I remember as it was almost a 1:1 translation of op-code to instruction byte, basically a lookup table with a bit of math to put in forward jump addresses on a second pass.

      I did it then as the toolchain was $$$ Not so sure I’d bother now but it was fun.

      1. Hehe, That was my 8085 College course, assembly programming paper (I was special) and hand written assembler and op codes.

        I went a similar route and wrote a Z80 assembler on my Atari 800 (2 pass). Then burned the eprom (4K) on the burner hooked to the joystick ports shift, clock & write. Took forever but worked.

        I was later spoiled by OS9 (Microware, not Apple) where we had cross assemblers and nice burners.

        I’ll take flash any day!

        Now get off my lawn you lazy punk kids!

  5. Dumping load addresses and rolling out raw images is easy.. Reverse Engineering libraries to figure out interface setup and handling isn’t and is usually illegal..

    They use to do this stuff when programming was as simple as labor, chip instructions and bus interfaces are wwwaaaayyyyy more complex now..

  6. I had an assembly language class (on S-100 bus machines running a Z-80, which dates me), where about 30% of the final exam was translating assembler to machine code like this. If you’re going to do much assembler work, it’s important to understand the process well enough to assemble by hand. But after doing it just a little bit, I quickly learned that keeping track of all those details really is a job better suited to a computer.

    I suspect you don’t REALLY understand a task thoroughly unless you understand it well enough to program a computer to do it. If that’s true, the better learning exercise is to write your own assembler, rather than to hand-translate assembly code to hex. I’ll leave that as an exercise for the reader.

    Either way, it’s admirable to understand the process well, not just with a passing acquaintence that’s sufficient to get your immediate practical job done.

    1. Reminds me of my final test when I learned assembly back in the day. I had to write the assembly software mnemonics on paper and enter the hex opcodes by hand on a Z80 board using a keypad. Mine was one of the 2 programs that worked (and passed the exam). Teacher kept the paper.

      I like compilers today and wouldn’t touch a lot of stuff without them, as things got a lot more sophisticated. I rarely need to get in “by hand” and tweak something using assembly because compilers do a very good job most of the time.

  7. If you do enough of this coding, you will still remember the op-codes 36 years later.

    I know. I can recite most of the 6502 op codes, still.

    Anyone know how I can delete them as I am running out of memory and need to garbage collect and defrag my brain? It is full of useless knowledge like op-codes to computers I don’t use and lyrics to innumerable pop songs from the 1960s.

    50 65 74 65 72

  8. And if you like programming this way, you would have loved programming with toggle switches on the Altair and Imsai.

    The fastest guy I knew was also a concert pianist. He could toggle 10 switches at once to enter 8080 code. Both hands with the right fingers up set all the 1s. Both hands down set all the 0s.

  9. This reminds me you can demonstrably write any program on an 8086 in paged mode using just two 8-bit opcodes. I think they are 0x4d and 0x55 from memory. (The trick is to manipulate a particular register and repeatedly push it onto the stack, which grows downwards until you crash into it and start executing it.)

  10. I am taking computer science at university and compilers is a second year course.

    The assignments start with writing programs in a hex editor and by the end you will have written a full assembler, linker, compiler toolchain from scratch.

    1. when I was in 6th form (college) (age 16-18) -(as there seems to be no general definition of what year this applies to.

      I took Electronics as an A level, (this was the last year before A+ came along.

      we have to do this at that age.
      in the exam you were given the opcode manual for the chip and a program written in hex.

      1 question, What does this program do?
      (that was something like 50% of the paper)

  11. I did this on a 6809, a Coco, when Tandy was late releasing hhe assembler cartridge. I still have the 6809 manual I used. (And yes I got OS-9 later on but never really got to use it much.)

    Dunno if I would do that now, but I can read assembly code of almost any CPU and get the gist, whether I know it already or not.

    Next time you are in any compiled project, look at the assembler output. Do that often enough and maybe you’ll hand assemble too!

  12. I wanna thank to Dan Amlund Thomsen, I needed these information to finish my project. I had learned convert assembly code to opcode from datasheet, but I didn’t know how to convert this opcodes to hex32 format. This working example is perfect for me to learn and use, special thanks to Dan Amlund Thomsen.

  13. Absolutely world-class article, great to see that someone appreciates the need for being able to program devices out of the box without resorting to pre-written software or even a PC at all – a 37-hex pair program can be written in by hand, on a breadboard powered by a 9V battery, during a power cut. Beat that. Best article I’ve seen on hardware ever.

Leave a Reply to DanJCancel reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.