debug用関数を作る
アセンブラやCを使っているとデバックがとても難しい。
そこでDOSデバッカがなくとも使える簡易型のデバック表示機能を作る。
使いかたはソースコード中でデバックしたい場所に関数を書いて実行すればよい。
Cプログラムなどからアセンブラなどを呼び出す場合のデバックに使うと便利だ。
DOS1/2だけでなくCPM汎用なので様々な機種で動作する。
この機能が呼ばれるとCPU状態をメモリに保存しデバック表示するとともに
コンピュータの実行を停止する。
CPU状態の保存箇所はデフォルトでメモリアドレスの0xC000となる。MSX以外の
ハードではアドレスを変えて使うことも可能だ。
アセンブラのソースコード部分を工夫すればsdcc以外でもビルドできるかもしれない。
stopdebug.asm
;
_stopdebugtrace::
;
di ;disable interrupt
;
ld (0xC000),a ;save registers
;
ld (0xC002),bc
ld (0xC004),de
ld (0xC006),hl
;
ld (0xC008),ix
ld (0xC00a),iy
;
ld (0xC00c),sp
;
ei
ret
;
debug.c
#include <stdio.h>
extern void stopdebugtrace();
//extern void cls();
void debugdump();
//このソースはdebug機能サンプルです
void main(void){
//asmで書かれたコードで実行中レジスタを保存する
//デバックしたいコードラインの直前や直後にこの関数を書くこと
stopdebugtrace();
//debug結果を表示
debugdump();
//割り込み停止、実行を止める
__asm
DI
HALT
__endasm;
while(1);
}
void debugdump(void){
unsigned char * reg_a=(unsigned char *)0xC000;
unsigned int * reg_bc=(unsigned int *)0xC002;
unsigned int * reg_de=(unsigned int *)0xC004;
unsigned int * reg_hl=(unsigned int *)0xC006;
unsigned int * reg_ix=(unsigned int *)0xC008;
unsigned int * reg_iy=(unsigned int *)0xC00a;
unsigned int * reg_sp=(unsigned int *)0xC00c;
unsigned int i;
unsigned char *p_stack;
// cls();
printf("*** STOP (HALT_DUMP_CPU_DEBUG) \r\n");
printf("\r\n");
printf("A problem has been detected\r\n");
printf("If this is the first time you've seen this Stop debug screen,\r\n");
printf("Press RESET to restart your computer.\r\n\r\n");
//
printf("Techincal information:\r\n");
printf("REG: A=%02x BC=%04x DE=%04x \r\n",*reg_a, *reg_bc, *reg_de);
printf(" HL=%04x IX=%04x IY=%04x SP=%x",*reg_hl, *reg_ix, *reg_iy, *reg_sp);
p_stack=(unsigned char *)*reg_sp;
printf(" PC=%02x%02x \r\n\r\n",p_stack[1],p_stack[0]);
printf("STACK(%x): ",*reg_sp);
for(i=0; i<16; i++){
printf("%02x ",p_stack[i]);
}
printf("\r\n");
}
実行結果画面
*** STOP (HALT_DUMP_CPU_DEBUG)
A problem has been detected
If this is the first time you've seen this Stop debug screen,
Press RESET to restart your computer.
Techincal information:
REG: A=00 BC=0000 DE=0000
HL=0000 IX=0000 IY=0000 SP=fcfc PC=0106
STACK(fcfc): 06 01 00 fd 76 00 00 00 00 00 00 00 00 00 00 00
CPUレジスタをダンプして停止するほかにもメモリをダンプして停止することもできる。
こちらはC言語だけで実装可能だ。デバックした箇所でメモリアドレスを指定して使う。
#include <stdio.h>
void memdump(unsigned int);
void main(void){
//コードライン中ダンプするタイミングでアドレス指定し関数を実行
memdump(0x0100);
//割り込み停止し実行を止める。
__asm
DI
HALT
__endasm;
while(1);
}
void memdump(unsigned int address){
unsigned int i;
unsigned int j;
unsigned char *p_stack;
// cls();
printf("*** STOP (HALT_DUMP_MEMORY) \r\n");
printf("\r\n");
printf("A problem has been detected\r\n");
printf("If this is the first time you've seen this Stop debug screen,\r\n");
printf("Press RESET to restart your computer.\r\n\r\n");
//
printf("Technical information:\r\n");
p_stack=(unsigned char *)address;
printf("Address(%04x): \r\n",address);
for(j=0; j<128; j=j+16){
for(i=0; i<16; i++){
printf("%02x ",p_stack[i+j]);
}
for(i=0; i<16; i++){
if (p_stack[i]>0x20) {
printf("%c",p_stack[i+j]);
} else {
printf(".");
}
}
printf("\r\n");
}
}
実行結果
*** STOP (HALT_DUMP_MEMORY)
A problem has been detected
If this is the first time you've seen this Stop debug screen,
Press RESET to restart your computer.
Technical information:
Address(0100):
21 00 01 e5 cd 0c 01 f1 f3 76 18 fe dd e5 dd 21 !..袁..v.ン袿!
00 00 dd 39 21 f8 ff 39 f9 21 56 02 e5 cd 82 03 ..9!..9・.袁・
21 75 02 e3 cd 82 03 21 78 02 e3 cd 82 03 21 96 !..耋..!x.ヘ・!・
02 e3 cd 82 03 21 d6 02 e3 cd 82 03 21 00 03 e3 ..・..耋.!・
cd 82 03 f1 dd 7e 04 dd 77 fa dd 7e 05 dd 77 fb ヘ....ンw・~ンw・
dd 6e 04 dd 66 05 e5 21 19 03 e5 cd 82 03 f1 f1 ン..ンf..!.ヘ・
dd 36 fc 00 dd 36 fd 00 dd 7e fc d6 80 dd 7e fd ン..ン..ン~.ヨン~
de 00 d2 51 02 dd 36 fe 00 dd 36 ff 00 dd 7e fe ゙..Q..ン.ン~
最終更新:2015年09月06日 14:51