投稿日: Mar 30, 2017 2:23:48 PM
80系cpuはこの手のことがアイディア次第でどうとでもなる
すくなくともi8080には jp (hl)はあれど、call (hl)はないので自分でどうにかします。
そういう命令があれば モニタプログラムから go した後にretで戻ってこられるのでぜひ実装したい、というかしなければ。 しました。
cmd_go: call getaddress ld hl,calladd+1 ld (hl),e inc hl ld (hl),d call calladd jp lp1
address: db 0,0 calladd: db 0xcd,0,0,0xc9
addressには別のルーチンで飛び先のアドレスが格納されます。
getaddressというファンクションはそのアドレスをdeレジスタにロードするものです。
最初の1行でdeレジスタにはアドレスが格納されました。
calladdというデータ領域にはあらかじめcall 0 / ret というバイナリが書き込まれています。
このアドレスのところにレジスタの内容を書き写してやります。
あとはcalladdというデータ領域をプログラムとしてcallしてやる。
と言う具合ですね。
飛び先でretされればモニタプログラムに復帰出来るわけです。
だいぶ楽になりますねー。
・・・。
釈然としない。というか無駄に気づいてしまった。
表題とは少し内容がかわってしまいますが。コードを圧縮します。
データ領域addressにはアドレスが格納されています。
それをわざわざcalladdに書き写してコールしてる。
むだじゃね?
つまりこうすればもっと簡単なんじゃないの? という。
データ領域。
calladd: db 0xcd address: db 0,0 db 0xc9
呼出側。
cmd_go: call calladd jp lp1
シンプルイズベスト。
・・・・と思っていたら。
jp(hl) を callすればいいんじゃないの? と。
ああ、直前にbdosコールどうなってんの?って調べて jp xxxxをcallしてjpの飛び先でretするってのを なるほど! とか言ってた矢先に。 そうだ、その方が断然良い。
変なトリック使うよりスマート!
ってことでここは改修します。
ああ、なんてこった。