don't click here

ASM Enabling and Disabling Interrupts - The Why

Discussion in 'Engineering & Reverse Engineering' started by Kilo, Feb 5, 2024.

Tags:
  1. Kilo

    Kilo

    Deathly afraid of the YM2612 Tech Member
    1,048
    1,041
    93
    Canada
    Sonic 1 Source Code Recreation + Source Code Wiki Page
    This was something I was going to initially ask in the basic questions and answer thread. But then I figured to do the research myself and thought it to be interesting enough to share for other intermediately skilled 68k programmers here.

    Every now and then while making a hack, you'll run into these instructions.
    Code (Text):
    1.         move    #$2700,sr    ; Disable interrupts.
    2.         move    #$2300,sr    ; Enable interrupts.

    So... what does it do? Well it disables vertical interrupts and horizontal interrupts, that's simple enough to understand.

    And why would we do that, aren't interrupts important for things like executing DMA transfers? If you pay attention to the code that follows when interrupts get disabled it's usually done when we're tinkering with the VDP, specifically setting VDP registers and copying large amounts of data to VRAM, or even clearing VRAM. This makes sense, copying large amounts of data takes time, and could even cause lag, and still be working at interrupt time, so we wouldn't want this interrupted by anything else as it could have detrimental effects to what we're doing. So now we know how to stop and start interrupts, and why you would want to do that. But that's not the question I had, when I thought about this today I wanted to know what significance the numbers $2700 and $2300 had, and what the sr is. Let's start with the latter.

    The sr is short for "Status register", it is a 16 bit bitfield containing flags on of course, the status of the CPU. Let's look into what these flags are.
    Code (Text):
    1. T | 0 | S | 0 | 0 | IPM2 | IPM1| IPM0 | 0 | 0 | 0 | X | N | Z | V | C

    Now while I mentioned that the register is 16 bits the lower byte isn't important for this explanation, they're just condition flags used for math related functions and conditional branches.

    That leaves us with 5 flags, trace mode, supervisor state, and interrupt priority masks 2-0. As you could imagine those interrupt priority masks are of great interest to this explanation. When we look at the values $2700 and $2300 we should actually be looking at them in binary since they're flags. And in binary (masking out the lower byte because again it's irrelevant here) we get %00100111 and %00100011. So here we can see that the culprit is setting interrupt priority mask 2, setting it seems to disable interrupts.

    Now this is where my research seems to fall apart as the implementation of the 68k and how it uses the sr can vary from device to device. But IPM1 and 0 seem to be set just as a formality and the Mega Drive seems to not take these into account??? Please I'd like a tech member to debunk that. And I assume that the supervisor mode needs to be enabled to modify these interrupt masks.
    Please see Devon's explanation on how setting these bits interacts with interrupt layers.

    So yeah, that's my dive into explaining what's going on when we disable and enable interrupts. Hope this was as helpful or as enlightening to someone as it was for me.
     
    Last edited: Feb 5, 2024
  2. Devon

    Devon

    La mer va embrassé moi et délivré moi lakay. Tech Member
    1,424
    1,740
    93
    your mom
    The IPM (IPL) bits actually make up a 3-bit value that indicates the range of interrupt requests that get ignored. Putting in 7 ignores all IRQs (except for IRQ7, which is non-maskable, so it's always processed. Though, that's not relevant to the Genesis), while 3 means IRQ1 to IRQ3 get ignored.

    [​IMG]
    Source

    In the case of the Genesis, IRQ2 is assigned to the external interrupt, IRQ4 is assigned to the horizontal blank interrupt, and IRQ6 is assigned to the vertical blank interrupt. Setting the IPL bits to 3 basically just has external interrupt requests ignored, since it falls in range of IRQ1-3. You would wanna set the IPL bits to 0 or 1 if you wanna use external interrupts.
     
    Last edited: Feb 5, 2024
    • Useful Useful x 4
    • Like Like x 1
    • List
  3. Kilo

    Kilo

    Deathly afraid of the YM2612 Tech Member
    1,048
    1,041
    93
    Canada
    Sonic 1 Source Code Recreation + Source Code Wiki Page
    That's the fix I was looking for, thank you!
    Now I don't know why I solely sourced my info on 68k interrupt from Atari and NeoGeo forums when we've always had these documents. Derp.
     
    Last edited: Feb 5, 2024