Friday, October 11, 2024

Day 11: NOT an Assembler

So, I am getting to the point where I really need some firmware to test out everything and get the breadboarded control system running. The instruction set on the MC14500b is delightfully simple:

It is so simple that I expected that could just write out the control program in hex machine code and I would not need any sort of assembler. In fact, I specifically wanted to avoid writing an assembler to keep the project moving. Well, looking back and forth at the manual to pick out hex codes got old quick. So then I thought I would just write a quick shell script to convert the mnemonics to hex, then, of course, I would want it to ignore comments and output in a listing format OR a binary... Pretty soon I had a useful tool that was NOT an assembler, because if it was an assembler, that would mean I got distracted from building a robot today. (There is a python script to do this in github, but my personal experience with python is that it takes longer to figure out all the dependency and pip version conflict errors than to just do something manually. There is only so much diversion I can justify.) #! /usr/bin/env bash # a145.sh # Simple mini NOT assembler for MC14500B Industrial Control Unit # Example input file contents: : ' ; MC14500B ICU code example LD 1 ;LOAD SENSOR 1 STATUS ANDC 2 ;AND /SENSOR 2 STATUS AND 3 ;AND SENSOR 3 STATUS STO 1 ;IF 1-3 ARE ACTIVE, TURN ON LIGHT NOPF F ;RETURN ' # Listing output : ' 0000: 11 ;LOAD SENSOR 1 STATUS 0001: 42 ;AND /SENSOR 2 STATUS 0002: 33 ;AND SENSOR 3 STATUS 0003: 81 ;IF 1,/2,3 ARE ACTIVE, TURN ON LIGHT 0004: FF ;RETURN ' # Hexdump (| xxd -c1) of binary results: : ' 0000: 11 42 33 81 FF ' # Process: # 1) remove comments # 2) replace mnemonic with hex nibble # 3) insert hex line/byte number # 4) use tee to view the hexdump, and .. # 5) use xxd to turn it into a binary # Set BYTES to width of the program memory in bits divided by 8 BYTES=1 LIDX=0 sed -e '/^ /!d' \ -e "s/ *NOPO */0/; s/ *LD */1/; s/ *LDC */2/; s/ *AND */3/" \ -e "s/ *ANDC */4/; s/ *OR */5/; s/ *ORC */6/; s/ *XNOR */7/" \ -e "s/ *STO */8/; s/ *STOC */9/;s/ *IEN */A/; s/ *OEN */B/" \ -e "s/ *JMP */C/; s/ *RTN */D/; s/ *SK2 */E/; s/ *NOPF */F/" \ $1 | while read n; do printf "%04X: $n\n" $LIDX; LIDX=$(($LIDX+$BYTES)); done \ | tee /dev/tty | xxd -r An array or hashtable probably would have been better for all those sed command opcodes, but this was quick and dirty.

No comments:

Post a Comment