したがって、文脈のために、私がこれまでに理解していることをお知らせしたいと思います。
割り込み処理は、命令の実行後に呼び出され、割り込みマスター イネーブル フラグが設定されます。
割り込み処理は、いくつかの「割り込みルーチン」で構成されています (ゲームボーイの場合、Vblank、LCD stat、タイマー、ジョイパッド、およびシリアルがあります)。
CPU は、IE フラグと IF フラグに設定された値に応じて、各割り込みを処理する必要があります。
割り込みルーチンには優先順位があります (私の質問とはあまり関係ありません)。
割り込みルーチンには開始と終了が必要です
したがって、割り込みルーチンを調べると、ルーチンの終了後に保持する必要があるレジスタ値をスタック ポインターにプッシュすることから始めます。これは、割り込みが処理される前に次の命令のアドレスをポップする必要がある割り込みルーチンの終わりであると私は常に考えています。
私は知りたいです:
reti命令は各割り込みルーチンに1回だけ出現し、最後にのみ出現するのが「標準」ですか?これ以上の指示を読むのをやめるかどうかを判断できる唯一の方法だからです。
ret の代わりに reti を使用するのは、ime フラグがまだ有効であることをアサートし、他の割り込みを処理する必要があるかどうかを引き続き確認できるようにするためです。
割り込み処理の開始前に、次の命令のアドレスをスタック ポインターに明示的にプッシュする必要があります。これは、割り込み処理の開始前に次の命令のアドレスをプッシュすることを示すアセンブリ命令がないためです。これは、割り込みの最後にある reti intruction 用です。
編集:
そのため、私の問題についてより多くのコンテキストを提供するために、命令サイクル コードを投稿することにしました。
CPU.cで
#include "InteruptHandler.c"
void main(){
while(){ //No proper argument yet. for fetch-decode-execute cycle
opcode = fetchInstruction();
decodeandExecuteInstruction(opcode); //Lets say an instruction is executed and it enabled the IME_flag. that is IME_flag = ENABLED
//Check if ime_flag is enabled. processInterupt if true.
isInteruptEnabled() ? processInterupts(): 0; //This would fall true.
}
}
InteruptHandler.c 内
processInterupts(){
opcode;
bitmask = 0x01;
//Check each bit for interupt. Bitmask will go 0x00 if the value 0x80 is shifted by 1
for(; bitmask ; bitmask = bitmask << 1){
//CHeck if IE and IF flag for corresponding interupt is set. process interupt if set
IE_flag & bitmask ? (IF_flag & bitmask ? determineInterupt(bitmask) : 0) : 0;
}
}
determineInterupt(bitmask){
//push the next instruction address to stack pointer
push(PC);
//Set PC into corresponding interupt address
//code below is my problem. I stumbled upon how would I end this function and I came up to determining when an interupt routine ends.
//I came up with the reti function.
//But after realizing that I already set the PC somewhere above this code, I just need to discard this code and let the main function do its instruction cycling.
//Thanks to @duskwuff for pointing that out.
//I just added some code to end the bitmask checking when it sees 1 interupt request and is most priotiry.
//Also thanks to @Ped7g for giving me more information about the complexity of interupt handling. I'm not yet seeing where I should implement those. There are still so many thing to implement and yet to know when this excatly can happen.
//My question has been answered nevertheless, which is to end a function code blocks that I discarded at the end :)
//process the corresponding interupt
do{
opcode = fetchInstruction();
decodeandexecuteInstruction(opcode);
}while (opcode != RETI)
}