前に作りかけたPic16f84のCPUシミュレータですが、暇が出来たので開発を再開させます。
ずいぶん久しぶりなので、何をやってたかを思い出すのを兼ねて、動作確認用サンプルのhexファイルを作る事にします。
今回の対象はHI-TECH Cのコンパイラをインストールしたときに一緒に入っているサンプルPGです。
ファイルは、標準インストールだと以下の辺りに入ってます。
C:\Program Files\HI-TECH Software\PICC\9.83\samples\misc\led.c |
このプログラムはLEDの点滅プログラムで、コードは以下の通りのシンプルなものです。
“Freely distributable.”らしいので、ソースを全文転記します。
#include <htc.h> /* * Demo program * * Flashes LEDs on Port B, responds to switch press * on RA1. Usable on PICDEM board. * * Copyright (C)1997 HI-TECH Software. * Freely distributable. */ #define BUTTON RC1 //bit 1 of PORTC main(void) { unsigned char i, j; TRISB = 0; /* all bits output */ j = 0; for(;;) { PORTB = 0x00; /* turn all on */ for(i = 100 ; --i ;) continue; PORTB = ~j; /* output value of j */ for(i = 100 ; --i ;) continue; if(BUTTON == 0) /* if switch pressed, increment */ j++; } } |
コメントにも有りますが、このプログラムでは以下の処理をしています。
1. ポートBのLEDを点滅させます。 2. RA1のスイッチを押すと点滅する値が変わります。 |
…なはずですが、このコード、コメントはRA1にボタンが繋がっている書かれてるのに、#defineがRC1になってます。16F84AにPORTCは無いので、これはRA1に書き換えておきます。
#define BUTTON RC1 //bit 1 of PORTC |
↓
#define BUTTON RA1 //bit 1 of PORTA |
で、MPLABでプロジェクトを作ってコンパイルした結果は以下の通りです。
--- C:\home\project\pic\16F84A_Example_LED\16F84A_Example_LED.as ------------------------------- 1: opt subtitle "HI-TECH Software Omniscient Code Generator (Lite mode) build 10920" 2: 3: opt pagewidth 120 4: 5: opt lm 6: 7: processor 16F84A 8: clrc macro 9: bcf 3,0 10: endm 11: clrz macro 12: bcf 3,2 13: endm 14: setc macro 15: bsf 3,0 16: endm 17: setz macro 18: bsf 3,2 19: endm 20: skipc macro 21: btfss 3,0 22: endm 23: skipz macro 24: btfss 3,2 25: endm 26: skipnc macro 27: btfsc 3,0 28: endm 29: skipnz macro 30: btfsc 3,2 31: endm 32: indf equ 0 33: indf0 equ 0 34: pc equ 2 35: pcl equ 2 36: status equ 3 37: fsr equ 4 38: fsr0 equ 4 39: c equ 1 40: z equ 0 41: pclath equ 10 42: FNROOT _main 43: global _EEADR 44: psect maintext,global,class=CODE,delta=2 45: global __pmaintext 46: __pmaintext: 47: _EEADR set 9 48: global _EEDATA 49: _EEDATA set 8 50: global _PORTB 51: _PORTB set 6 52: global _CARRY 53: _CARRY set 24 54: global _GIE 55: _GIE set 95 56: global _RA1 57: _RA1 set 41 58: global _EECON1 59: _EECON1 set 136 60: global _EECON2 61: _EECON2 set 137 62: global _TRISB 63: _TRISB set 134 64: global _RD 65: _RD set 1088 66: global _WR 67: _WR set 1089 68: global _WREN 69: _WREN set 1090 70: file "16F84A_Example_LED.as" 71: line # 72: psect cinit,class=CODE,delta=2 73: global start_initialization 74: start_initialization: 75: 76: psect cinit,class=CODE,delta=2 77: global end_of_initialization 78: 79: ;End of C runtime variable initialization code 80: 81: end_of_initialization: 82: clrf status 3D1 0183 CLRF 0x3 83: ljmp _main ;jump to C main() function 3D2 2BD3 GOTO 0x3d3 --- C:\home\project\pic\16F84A_Example_LED\led.c ----------------------------------------------- 1: #include <htc.h> 2: 3: /* 4: * Demo program 5: * 6: * Flashes LEDs on Port B, responds to switch press 7: * on RA1. Usable on PICDEM board. 8: * 9: * Copyright (C)1997 HI-TECH Software. 10: * Freely distributable. 11: */ 12: 13: //#define BUTTON RC1 //bit 1 of PORTC 14: #define BUTTON RA1 //bit 1 of PORTA 15: 16: main(void) 17: { 18: unsigned char i, j; 19: 20: TRISB = 0; /* all bits output */ 3D3 1683 BSF 0x3, 0x5 3D4 0186 CLRF 0x6 21: j = 0; 3D5 1283 BCF 0x3, 0x5 3D6 018D CLRF 0xd 22: for(;;) { 23: PORTB = 0x00; /* turn all on */ 3D7 0186 CLRF 0x6 24: for(i = 100 ; --i ;) 3D8 3064 MOVLW 0x64 3D9 008C MOVWF 0xc 3DA 080C MOVF 0xc, W 3DB 008E MOVWF 0xe 3DC 2BDF GOTO 0x3df 3DF 3001 MOVLW 0x1 3E0 028E SUBWF 0xe, F 3E1 1D03 BTFSS 0x3, 0x2 3E2 2BE4 GOTO 0x3e4 3E3 2BE5 GOTO 0x3e5 3E4 2BDF GOTO 0x3df 3E5 2BE6 GOTO 0x3e6 25: continue; 3DD 2BDF GOTO 0x3df 3DE 2BDF GOTO 0x3df 26: PORTB = ~j; /* output value of j */ 3E6 090D COMF 0xd, W 3E7 0086 MOVWF 0x6 27: for(i = 100 ; --i ;) 3E8 3064 MOVLW 0x64 3E9 008C MOVWF 0xc 3EA 080C MOVF 0xc, W 3EB 008E MOVWF 0xe 3EC 2BEF GOTO 0x3ef 3EF 3001 MOVLW 0x1 3F0 028E SUBWF 0xe, F 3F1 1D03 BTFSS 0x3, 0x2 3F2 2BF4 GOTO 0x3f4 3F3 2BF5 GOTO 0x3f5 3F4 2BEF GOTO 0x3ef 28: continue; 3ED 2BEF GOTO 0x3ef 3EE 2BEF GOTO 0x3ef 29: if(BUTTON == 0) /* if switch pressed, increment */ 3F5 1885 BTFSC 0x5, 0x1 3F6 2BF8 GOTO 0x3f8 3F7 2BF9 GOTO 0x3f9 3F8 2BD7 GOTO 0x3d7 30: j++; 3F9 3001 MOVLW 0x1 3FA 008C MOVWF 0xc 3FB 080C MOVF 0xc, W 3FC 078D ADDWF 0xd, F 3FD 2BD7 GOTO 0x3d7 31: } 3FE 2BD7 GOTO 0x3d7 32: } 3FF 2800 GOTO 0 |
実際のプログラムはmainだけですが、スタートアップルーチンが有るのでかなり長くなってます。
最初のスタートアップの*.asファイルは83行も有りますが、ほとんどはアセンブラ(MPASM.exe)に対する指示で、実際のコードは以下の2つだけです。
82: clrf status 3D1 0183 CLRF 0x3 83: ljmp _main ;jump to C main() function 3D2 2BD3 GOTO 0x3d3 |
MPLABでプログラムメモリを見ると、最初の命令は”GOTO 0x03d1″なのでこのコードに飛んでいます。
で、スタートアップルーチンはステータスレジスタをクリア(CLRF 0x3)した後、main()にジャンプするだけ(GOTO 0x3d3)なので、理解するのは楽勝です。
プログラム本体は、Program Memoryウィンドウ上でもぎりぎり1画面に表示できるレベルでした。
HI-TECH Cはコードを0x03FFの上位番地側に詰めて配置するようです。
hexファイルは、たったこれだけです。
:02000000D12B02 :1007A2008301D32B8316860183128D018601643067 :1007B2008C000C088E00DF2BDF2BDF2B01308E022A :1007C200031DE42BE52BDF2BE62B0D09860064309D :1007D2008C000C088E00EF2BEF2BEF2B01308E02DA :1007E200031DF42BF52BEF2B8518F82BF92BD72BA8 :0E07F20001308C000C088D07D72BD72B002868 :00000001FF |
このhexファイルを、以前作った逆アセンブラで処理させてみます。
…驚くべき事に、ちゃんと処理されったっぽいです。
前回作ったシミュレータは、GOTOとADD命令だけしか解釈できなかったので、次回はこのコードを動かせるところまでがんばってみます。
関連記事
コメントを残す