''[JM] 14 Nov 2012'' - After "[Playing Assembler]" a little bit, and looking at the [RS] comments that says: "Of course this is no real assembler. The memory model is constant-size instructions...", that just sounded like how the PIC microcontroller is arranged [http://en.wikipedia.org/wiki/PIC_micro#Code_space]<
> So I took a section of a working code (a loop that fills a RAM buffer for a later transfer to a LCD), again, this is not quite ready yet, for example, the command addwf chrix,w was now written as addwf chrix implying that the destiny is the W register the example shows a RAM buffer (from 48d to 63d) filled with values descending from 30H to 21H. The real thing in hardware shows all the possible charactes a LCD can display. console show namespace eval asm { proc asm body { variable mem catch {unset mem} ;# good for repeated sourcing foreach line [split $body \n] { foreach i {label op args} {set $i ""} regexp {([^;]*);} $line -> line ;# strip off comments regexp {^ *(([A-Z0-9]+):)? *([A-Z]*) +(.*)} [string toupper $line]\ -> - label op args puts label=$label,op=$op,args=$args if {$label!=""} {set sym($label) $PC} if {$op==""} continue if {$op=="DB"} {set mem($PC) [convertHex $args]; incr PC; continue} if {$op=="EQU"} {set sym($label) [convertHex $args]; continue} if {$op=="ORG"} { set PC [convertHex $args] continue } regsub -all ", *" $args " " args ;# normalize commas set mem($PC) "$op $args" incr PC } substituteSymbols sym dump sym } proc convertHex s { set s [string trim $s] if [regexp {^([0-9A-F]+)H$} [string trim $s] -> s] {set s [expr 0x$s]} set s set s } proc substituteSymbols {_sym} { variable mem upvar $_sym sym foreach i [array names mem] { set tmp [lindex $mem($i) 0] foreach j [lrange $mem($i) 1 end] { if {[array names sym $j]==$j} {set j $sym($j)} lappend tmp $j } set mem($i) $tmp } } proc dump {_sym} { variable mem variable ram upvar $_sym sym puts "dump..." foreach i [lsort -integer [array names mem]] { puts [format "%04d %s" $i $mem($i)] } foreach i [lsort [array names sym]] { puts [format "%-10s: %04x" $i $sym($i)] } } proc run {{pc 256}} { puts "run..." incr pc -1 variable mem foreach i {A B C D E Z W} {set ::$i 0} while {$pc>=0} { incr pc #puts "$mem($pc)\tA:$::A B:$::B C:$::C D:$::D E:$::E Z:$::Z" #tk_messageBox -message "$mem($pc)\tA:$::A B:$::B C:$::C D:$::D E:$::E Z:$::Z" eval $mem($pc) #incr pc } } #----------------- "machine opcodes" implemented as procs proc SHOWRAM dummyNr { variable ram puts "---RAM dump" foreach i [lsort [array names ram]] { puts "$i: $ram($i)" } } proc ADDWF adr { variable ram set ::W [expr $ram($adr) + $::W] } proc CALL {name} {[string tolower $name] $::W} proc GOTO adr {uplevel 1 set pc [expr $adr - 1]} proc INCF adr { variable ram set ram($adr) [expr $ram($adr) + 1] } proc DECFSZ adr { variable ram set ram($adr) [expr $ram($adr) - 1] if {$ram($adr) == 0} {uplevel 1 set pc [expr [uplevel 1 set pc] +1]} } proc MOV {reg adr} {variable mem; set ::$reg $mem($adr)} proc MOVWF adr { variable ram if {$adr == "INDF"} { set fsrC $ram(FSR) set ram($fsrC) $::W } else { set ram($adr) $::W } } proc MOVFW adr { variable ram set ::W $ram($adr) } proc MVI {reg value} {set ::$reg $value} proc MOVLW value {set ::W $value} } #-- Now testing: asm::asm { org 100 ; the canonical start address in CP/M goto START ; idiomatic: get over the initial variable(s) DONE: equ 0 ; warm start in CP/M ;-) MAX: equ 5 INCR: db 2 ; a variable (though we won't vary it) ;; here we go... START: movlw 0 movwf offset movlw 32 movwf chrix movlw 48 movwf FSR movlw 16 movwf counter WEER: movfw counter addwf chrix movwf INDF ;call puts incf FSR decfsz counter goto weer incf offset incf chrix goto DONE end } asm::run 100 puts "RAM after run:" foreach i [lsort [array names asm::ram]] { puts [format "%-10s: %04x" $i $asm::ram($i)] } When running the example, the outputs is: label=,op=,args= label=,op=ORG,args=100 label=,op=GOTO,args=START label=DONE,op=EQU,args=0 label=MAX,op=EQU,args=5 label=INCR,op=DB,args=2 label=,op=,args= label=START,op=MOVLW,args=0 label=,op=MOVWF,args=OFFSET label=,op=MOVLW,args=32 label=,op=MOVWF,args=CHRIX label=,op=MOVLW,args=48 label=,op=MOVWF,args=FSR label=,op=MOVLW,args=16 label=,op=MOVWF,args=COUNTER label=WEER,op=MOVFW,args=COUNTER label=,op=ADDWF,args=CHRIX label=,op=MOVWF,args=INDF label=,op=,args= label=,op=INCF,args=FSR label=,op=DECFSZ,args=COUNTER label=,op=GOTO,args=WEER label=,op=INCF,args=OFFSET label=,op=INCF,args=CHRIX label=,op=GOTO,args=DONE label=,op=,args=END label=,op=,args= dump... 0100 GOTO 102 0101 2 0102 MOVLW 0 0103 MOVWF OFFSET 0104 MOVLW 32 0105 MOVWF CHRIX 0106 MOVLW 48 0107 MOVWF FSR 0108 MOVLW 16 0109 MOVWF COUNTER 0110 MOVFW COUNTER 0111 ADDWF CHRIX 0112 MOVWF INDF 0113 INCF FSR 0114 DECFSZ COUNTER 0115 GOTO 110 0116 INCF OFFSET 0117 INCF CHRIX 0118 GOTO 0 DONE : 0000 INCR : 0065 MAX : 0005 START : 0066 WEER : 006e run... RAM after run: 48 : 0030 49 : 002f 50 : 002e 51 : 002d 52 : 002c 53 : 002b 54 : 002a 55 : 0029 56 : 0028 57 : 0027 58 : 0026 59 : 0025 60 : 0024 61 : 0023 62 : 0022 63 : 0021 CHRIX : 0021 COUNTER : 0000 FSR : 0040 OFFSET : 0001 (code) 1 % <>Enter Category Here