gpt4 book ai didi

c - 确定 Gameboy GB 仿真的中断例程何时结束

转载 作者:太空宇宙 更新时间:2023-11-04 02:29:46 24 4
gpt4 key购买 nike

所以对于上下文,我想让你知道我到目前为止的理解:

  • 在一条指令执行后调用中断处理并设置中断主控启用标志。

  • 中断处理由几个“中断例程”组成(对于 gameboy,它有 Vblank、LCD stat、定时器、游戏 handle 和串口)。

  • CPU 需要根据 IE 标志和 IF 标志上设置的值来处理每个中断。

  • 中断例程有优先级(与我的问题无关)。

  • 中断例程必须有开始和结束

因此,在研究中断例程时,它首先将在例程结束后应保留的寄存器值压入堆栈指针。现在它总是有 reti 指令,我认为它总是是中断例程的结尾,它应该在处理中断之前弹出下一条指令的地址。

我想知道是否:

  • reti 指令在每个中断例程中只出现一次并且在结束时出现,这是否是一个“标准”?因为这是我确定是否会结束阅读进一步说明的唯一方法,

  • 它使用 reti 而不是 ret,因为我们想断言 ime 标志仍然启用,因此可以继续检查是否需要提供任何其他中断,

  • 在中断处理开始之前,我需要明确地将下一条指令的地址压入堆栈指针,因为没有汇编指令指示在中断处理开始之前压入它。顺便说一下,这是在中断结束时进行 reti 指令。

编辑:

因此,为了提供有关我的问题的更多背景信息,我决定发布我的指令周期代码。

在 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)
}

最佳答案

  • Interrupt routines must have start and end

这不是真的。您不应该对代码在内存中的布局做出任何假设——只需运行您遇到的指令即可。

在某些情况下,中断服务例程有可能在返回之前重新启用中断,以允许同时处理另一个中断。您的设计应该考虑到这一点。

it uses reti instead of ret because we want to assert that ime flag is still enabled and thus can continue checking if any other interupt needs to be served,

没有。 RETI 指令在返回时重新启用中断——它实际上是 EI 和 RET 的组合。不涉及断言。

关于c - 确定 Gameboy GB 仿真的中断例程何时结束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45024113/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com