116 lines
2.6 KiB
ArmAsm
116 lines
2.6 KiB
ArmAsm
//
|
|
// Copyright 2016 - 2020 gary@drinkingtea.net
|
|
//
|
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
//
|
|
|
|
.section .iwram, "ax", %progbits
|
|
.arm
|
|
.align
|
|
|
|
.extern nostalgia_core_isr_vblank
|
|
.extern nostalgia_core_isr_timer0
|
|
.extern nostalgia_core_isr_timer1
|
|
.extern nostalgia_core_isr_timer2
|
|
.extern nostalgia_core_isr_timer3
|
|
|
|
.equ REG_IFBIOS, 0x03007ff8
|
|
|
|
.equ REG_IE, 0x04000200
|
|
.equ REG_IF, 0x04000202
|
|
.equ REG_IME, 0x04000208
|
|
|
|
.equ Int_vblank, 1
|
|
.equ Int_hblank, 2
|
|
.equ Int_vcount, 4
|
|
.equ Int_timer0, 8
|
|
.equ Int_timer1, 16
|
|
.equ Int_timer2, 32
|
|
.equ Int_timer3, 64
|
|
.equ Int_serial, 128 // link cable
|
|
.equ Int_dma0, 256
|
|
.equ Int_dma1, 512
|
|
.equ Int_dma2, 1024
|
|
.equ Int_dma3, 2048
|
|
.equ Int_dma4, 4096
|
|
.equ Int_dma5, 8192
|
|
.equ Int_input, 16384 // gamepad
|
|
.equ Int_cart, 32768 // cartridge removed
|
|
|
|
|
|
.global isr
|
|
.type isr, %function
|
|
isr:
|
|
// read IE
|
|
ldr r0, =#REG_IE
|
|
ldrh r1, [r0] // r1 becomes IE value
|
|
ldrh r2, [r0, #2] // r2 becomes IF value
|
|
and r1, r1, r2 // r1 becomes IE & IF
|
|
// done with r2 as IF value
|
|
|
|
// Acknowledge IRQ in REG_IF
|
|
strh r1, [r0, #2]
|
|
ldr r0, =#REG_IFBIOS
|
|
// Acknowledge IRQ in REG_IFBIOS
|
|
ldr r2, [r0] // r2 becomes REG_IFBIOS value
|
|
orr r2, r2, r1
|
|
str r2, [r0]
|
|
// done with r2 as IFBIOS value
|
|
// done with r0 as REG_IFBIOS
|
|
|
|
////////////////////////////////////////////////////
|
|
// Interrupt Table Begin //
|
|
////////////////////////////////////////////////////
|
|
|
|
cmp r1, #Int_timer0
|
|
ldreq r0, =nostalgia_core_isr_timer0
|
|
beq isr_call_handler
|
|
|
|
cmp r1, #Int_vblank
|
|
ldreq r0, =nostalgia_core_isr_vblank
|
|
beq isr_call_handler
|
|
|
|
////////////////////////////////////////////////////
|
|
// Interrupt Table End //
|
|
////////////////////////////////////////////////////
|
|
|
|
b isr_end
|
|
|
|
isr_call_handler:
|
|
// clear IME to disable interrupts
|
|
ldr r2, =#REG_IME
|
|
mov r1, #0
|
|
str r1, [r2]
|
|
|
|
// enter system mode
|
|
mrs r1, cpsr
|
|
bic r1, r1, #0xDF
|
|
orr r1, r1, #0x1F
|
|
msr cpsr, r1
|
|
|
|
push {lr}
|
|
ldr lr, =isr_restore
|
|
bx r0
|
|
|
|
isr_restore:
|
|
pop {lr}
|
|
|
|
// re-enter irq mode
|
|
mrs r0, cpsr
|
|
bic r0, r0, #0xDF
|
|
orr r0, r0, #0x92
|
|
msr cpsr, r0
|
|
|
|
// set IME to re-enable interrupts
|
|
ldr r2, =#REG_IME
|
|
mov r0, #1
|
|
str r0, [r2]
|
|
|
|
isr_end:
|
|
|
|
bx lr
|
|
|
|
// vim: ft=armv4
|