前に作りかけた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命令だけしか解釈できなかったので、次回はこのコードを動かせるところまでがんばってみます。
関連記事
コメントを残す