( avr assembler ) ( daniel j kruszyna ) ( http://krue.net/avr/ ) ( 2006.11.20 ) hex : << lshift ; : >> rshift ; : lo ff and ; : hi 8 >> lo ; : 2^ 1 swap << ; ( target memory ) 20 constant regsize 0 constant regstart 1f constant regend 20 constant iostart iostart iosize + 1- constant ioend ioend 1+ constant ramstart ioend ramsize + constant ramend 0 constant flashstart flashsize 1- constant flashend 0 constant eepromstart eepromsize 1- constant eepromend create tflash flashsize 2* allot tflash flashsize 2* ff fill create tram ramsize allot tram ramsize 00 fill create teeprom eepromsize allot teeprom eepromsize ff fill variable idp variable tdp variable edp : ihere idp @ ; : there tdp @ ; : ehere edp @ ; : itarget 2* tflash + ; : target tram + regsize - iosize - ; : etarget teeprom + ; 1 constant icell : icells icell * ; : icell+ icell + ; : i@ ( ta -- x ) itarget dup c@ swap 1 + c@ 8 << or ; : i! ( x ta -- ) itarget over lo over c! swap hi swap 1 + c! ; : iallot idp +! ; : i, ihere i! 1 icells iallot ; 2 constant tcell : tcells tcell * ; : tcell+ tcell + ; : tc@ ( ta -- c ) target c@ ; : tc! ( c ta -- ) target c! ; : t@ ( ta -- x ) target dup c@ swap 1 + c@ 8 << or ; : t! ( x ta -- ) target over ff and over c! swap 8 >> ff and swap 1 + c! ; : tallot tdp +! ; : tc, there tc! 1 tallot ; : t, there t! 1 tcells tallot ; 2 constant ecell : ecells ecell * ; : ecell+ ecell + ; : ec@ ( ta -- c ) etarget c@ ; : ec! ( c ta -- ) etarget c! ; : e@ ( ta -- x ) etarget dup c@ swap 1 + c@ 8 << or ; : e! ( x ta -- ) etarget over ff and over c! swap 8 >> ff and swap 1 + c! ; : eallot edp +! ; : ec, ehere ec! 1 eallot ; : e, ehere e! 1 ecells eallot ; ( opcodes ) ( sreg bits ) 0 constant c 1 constant z 2 constant n 3 constant v 4 constant s 5 constant h 6 constant t 7 constant i ( inherent ) ( op ) ( oooo oooo oooo oooo ) : inherent i, ; : break, 9598 inherent ; : clc, 9488 inherent ; : clh, 94d8 inherent ; : cli, 94f8 inherent ; : cln, 94a8 inherent ; : cls, 94c8 inherent ; : clt, 94e8 inherent ; : clv, 94b8 inherent ; : clz, 9498 inherent ; : eicall, 9519 inherent ; : eijmp, 9419 inherent ; : elpm, 95d8 inherent ; : espm, 95f8 inherent ; : icall, 9509 inherent ; : ijmp, 9409 inherent ; : lpm, 95c8 inherent ; : nop, 0000 inherent ; : ret, 9508 inherent ; : reti, 9518 inherent ; : sec, 9408 inherent ; : seh, 9458 inherent ; : sei, 9478 inherent ; : sen, 9428 inherent ; : ses, 9448 inherent ; : set, 9468 inherent ; : sev, 9438 inherent ; : sez, 9418 inherent ; : sleep, 9588 inherent ; : spm, 95e8 inherent ; : wdr, 95a8 inherent ; ( two 5-bit registers ) ( d r op ) ( oooo oord dddd rrrr ) : 2reg5bit ( d r op -- ) >r dup 0010 and 5 << r> or >r 000f and r> or >r 001f and 4 << r> or i, ; : adc, 1c00 2reg5bit ; : add, 0c00 2reg5bit ; : and, 2000 2reg5bit ; : cp, 1400 2reg5bit ; : cpc, 0400 2reg5bit ; : cpse, 1000 2reg5bit ; : eor, 2400 2reg5bit ; : mov, 2c00 2reg5bit ; : mul, 9c00 2reg5bit ; : or, 2800 2reg5bit ; : sbc, 0800 2reg5bit ; : sub, 1800 2reg5bit ; : clr, dup eor, ; : lsl, dup add, ; : rol, dup adc, ; : tst, dup and, ; ( one 5-bit register ) ( d op ) ( oooo oood dddd oooo ) : 1reg5bit ( d op -- ) >r 001f and 4 << r> or i, ; : asr, 9405 1reg5bit ; : com, 9400 1reg5bit ; : dec, 940a 1reg5bit ; : elpmz, 9006 1reg5bit ; : elpmz+, 9007 1reg5bit ; : inc, 9403 1reg5bit ; : ldx, 900c 1reg5bit ; : ldx+, 900d 1reg5bit ; : ld-x, 900e 1reg5bit ; : ldy, 8008 1reg5bit ; : ldy+, 9009 1reg5bit ; : ld-y, 900a 1reg5bit ; : ldz, 8000 1reg5bit ; : ldz+, 9001 1reg5bit ; : ld-z, 9002 1reg5bit ; : lpmz, 9004 1reg5bit ; : lpmz+, 9005 1reg5bit ; : lsr, 9406 1reg5bit ; : neg, 9401 1reg5bit ; : pop, 900f 1reg5bit ; : push, 920f 1reg5bit ; : ror, 9407 1reg5bit ; : stx, 920c 1reg5bit ; : stx+, 920d 1reg5bit ; : st-x, 920e 1reg5bit ; : sty, 8208 1reg5bit ; : sty+, 9209 1reg5bit ; : st-y, 920a 1reg5bit ; : stz, 8200 1reg5bit ; : stz+, 9201 1reg5bit ; : st-z, 9202 1reg5bit ; : swap, 9402 1reg5bit ; ( one 4-bit register with immediate data ) ( d k op ) ( oooo kkkk dddd kkkk ) : 1reg4bitimm ( d k op -- ) >r dup 00f0 and 4 << r> or >r 000f and r> or >r 000f and 4 << r> or i, ; : andi, 7000 1reg4bitimm ; : cpi, 3000 1reg4bitimm ; : ldi, e000 1reg4bitimm ; : ori, 6000 1reg4bitimm ; : sbci, 4000 1reg4bitimm ; : subi, 5000 1reg4bitimm ; : cbr, invert andi, ; : sbr, ori, ; ( one 2-bit word with immediate data ) ( d k op ) ( oooo oooo kkdd kkkk ) : 1word2bitimm ( d k op -- ) >r dup 0030 and 2 << r> or >r 000f and r> or >r 0006 and 3 << r> or i, ; : adiw, 9600 1word2bitimm ; : sbiw, 9700 1word2bitimm ; ( one 4-bit register ) ( d op ) ( oooo oooo dddd oooo ) : 1reg4bit ( d op -- ) >r 000f and 4 << r> or i, ; : ser, ef0f 1reg4bit ; ( branch ) ( s k op ) ( k op ) ( oooo ookk kkkk ksss ) : branch ( s k op -- ) >r ihere - 1- 007f and 3 << r> or >r 0007 and r> or i, ; : brbc, f400 branch ; : brcc, c swap brbc, ; : brsh, brcc, ; : brne, z swap brbc, ; : brpl, n swap brbc, ; : brvc, v swap brbc, ; : brge, s swap brbc, ; : brhc, h swap brbc, ; : brtc, t swap brbc, ; : brid, i swap brbc, ; : brbs, f000 branch ; : brcs, c swap brbs, ; : brlo, brcs, ; : breq, z swap brbs, ; : brmi, n swap brbs, ; : brvs, v swap brbs, ; : brli, s swap brbs, ; : brhs, h swap brbs, ; : brts, t swap brbs, ; : brie, i swap brbs, ; ( sreg ) ( s op ) ( oooo oooo osss oooo ) : sregbit ( s op -- ) >r 0007 and 4 << r> or i, ; : bclr, 9488 sregbit ; : bsei, 9408 sregbit ; ( one 5-bit register with i/o location ) ( d a op ) ( oooo oaad dddd aaaa ) : 1reg5bitio ( d a op -- ) >r dup 0030 and 5 << r> or >r 000f and r> or >r 001f and 4 << r> or i, ; : in, b000 1reg5bitio ; : out, swap b800 1reg5bitio ; ( two 4-bit registers ) ( d r op ) ( oooo oooo dddd rrrr ) : 2reg4bit ( d r op -- ) >r 000f and r> or >r 000f and 4 << r> or i, ; : muls, 0200 2reg4bit ; ( two 3-bit registers ) ( d r op ) ( oooo oooo oddd orrr ) : 2reg3bit ( d r op -- ) >r 0007 and r> or >r 0007 and 4 << r> or i, ; : mulsu, 0300 2reg3bit ; : fmul, 0308 2reg3bit ; : fmuls, 0380 2reg3bit ; : fmulsu, 0388 2reg3bit ; ( relative ) ( k op ) ( oooo kkkk kkkk kkkk ) : relative ( k op -- ) >r ihere - 1- 0fff and r> or i, ; : rcall, d000 relative ; : rjmp, c000 relative ; ( one 5-bit register bit operation ) ( d b op ) ( oooo oood dddd obbb ) : 1reg5bitbit ( d b op -- ) >r 0007 and r> or >r 001f and 4 << r> or i, ; : bld, f800 1reg5bitbit ; : bst, fa00 1reg5bitbit ; : sbrc, fc00 1reg5bitbit ; : sbrs, fe00 1reg5bitbit ; ( absolute ) ( doesn't handle 22-bit addresses yet ) ( k op ) ( oooo oook kkkk oook ) ( kkkk kkkk kkkk kkkk ) : absolute ( k op -- ) i, i, ; : call, 940e absolute ; : jmp, 940c absolute ; ( one i/o register bit operation ) ( a b op ) ( oooo oooo aaaa abbb ) : 1iobit ( a b op -- ) >r 0007 and r> or >r 001f and 3 << r> or i, ; : cbi, 9800 1iobit ; : sbi, 9a00 1iobit ; : sbic, 9900 1iobit ; : sbis, 9b00 1iobit ; ( direct ) ( k r op ) ( oooo oood dddd oooo ) ( kkkk kkkk kkkk kkkk ) : direct ( k r op -- ) >r 001f and 4 << r> or i, i, ; : sts, 9200 direct ; : lds, swap 9000 direct ; ( two words ) ( d r op ) ( oooo oooo dddd rrrr ) : 2words ( d r op -- ) >r 001e and 1 >> r> or >r 001e and 3 << r> or i, ; : movw, 0100 2words ; ( indirect with displacement ) ( d q op ) ( ooqo qqod dddd oqqq ) : displacement ( d q op -- ) >r dup 0020 and 8 << r> or >r dup 0018 and 7 << r> or >r 0007 and r> or >r 001f and 4 << r> or i, ; : lddy, 8008 displacement ; : lddz, 8000 displacement ; : stdy, swap 8208 displacement ; : stdz, swap 8200 displacement ; start idp ! ramstart tdp ! eepromstart edp ! ( binary file output ) 0 Value flash-file : write-flash ( ca n -- ) w/o bin open-file throw to flash-file tflash flashsize 2* flash-file write-file throw flash-file close-file throw ; 0 Value eeprom-file : write-eeprom ( ca n -- ) w/o bin open-file throw to eeprom-file teeprom eepromsize eeprom-file write-file throw eeprom-file close-file throw ; ( structured assembler constructs ) ( fetch and store ) : fetch dup 20 60 within if 20 - in, else lds, then ; : store over 20 60 within if swap 20 - swap out, else sts, then ; : load over 0 20 within if over 10 20 within if ldi, else as swap ldi, as mov, then else as swap ldi, as store then ; ( bit operations ) : skip-bit-clear over 20 40 within if swap 20 - swap sbic, else as rot fetch as swap sbrc, then ; : skip-bit-set over 20 40 within if swap 20 - swap sbis, else as rot fetch as swap sbrs, then ; : set-bit over 20 40 within if swap 20 - swap sbi, else over as swap fetch as swap 2^ ori, as store then ; : clear-bit over 20 40 within if swap 20 - swap cbi, else over as swap fetch as swap 2^ invert andi, as store then ; ( address labels ) : label create ihere , does> @ ; ( subroutines ) : rel? ( dest src -- f ) - 1- -800 800 within ; : call dup ihere rel? if rcall, else call, then ; : jump dup ihere rel? if rjmp, else jmp, then ; ( variables ) : var create there , tallot does> @ ; : evar create ehere , eallot does> @ ; ( conditionals ) : if, ( cc -- a ) 0007 and f400 or i, ihere 1- ; : ~if, ( cc -- a ) 0007 and f000 or i, ihere 1- ; : then, ( a -- ) ihere over - 1- 007f and 3 << over i@ or swap i! ; : then, ( a -- ) dup i@ dup f800 and f000 = if drop ihere over - 1- 007f and 3 << over i@ or swap i! else c000 = if ihere over - 1- 0fff and over i@ or swap i! then then ; : else, ( a -- a' ) c000 i, ihere 1- swap then, ; ( loops ) : begin, ( -- a ) ihere ; : again, ( a -- ) rjmp, ; : until, ( a cc -- ) swap brbc, ; : ~until, ( a cc -- ) swap brbs, ; : do, ( -- a ) ihere ; : loop, ( a r -- ) dec, brne, ; : while, ( a cc -- a a ) if, swap ; : ~while, ( a cc -- a a ) ~if, swap ; : repeat, ( a a -- ) again, then, ; \ ( jump table ) \ : jump, ( r -- ) \ ihere 5 + \ zl over lo ldi, \ zh swap hi ldi, \ zl swap add, \ zh zero adc, \ ijmp, ; ( shift z : for accessing program memory ) : szl, zl lsl, zh rol, ; : szr, zh lsr, zl ror, ; ( interrupts ) : vector idp @ swap idp ! dup jump idp ! ; : inton sei, ; : intoff cli, ; ( save/restore sreg in isrs ) : pushsreg as push, as sreg fetch as push, ; : popsreg as pop, sreg as store as pop, ; \ ( copy initial ram contents ) \ : mirror ramstart target flashsize itarget ramsize - ramsize move ; \ : mirror, \ zh flashend 2* ramsize - hi ldi, \ zl flashend 2* ramsize - lo ldi, \ yh ramstart hi ldi, \ yl ramstart lo ldi, \ xh flashend 2* hi ldi, \ xl flashend 2* lo ldi, \ \ begin, \ zl xl cp, \ zh xh cpc, \ z ~while, \ wh lpmz+, \ wh sty+, \ repeat, ;