2019-12-09 15:57:06 +01:00
|
|
|
.section ".ubc.handler", "awx", @progbits
|
|
|
|
|
2019-12-06 23:45:04 +01:00
|
|
|
.global _ubc_handler_pre
|
|
|
|
.type _ubc_handler_pre, @function
|
|
|
|
|
|
|
|
.extern _ubc_handler
|
2019-12-09 15:57:06 +01:00
|
|
|
.extern _ubc_module_handler
|
2019-12-06 23:45:04 +01:00
|
|
|
|
|
|
|
|
|
|
|
.align 2
|
|
|
|
_ubc_handler_pre:
|
|
|
|
! Stack management.
|
|
|
|
mov.l r9, @-r15 ! Save r9 register.
|
2019-12-09 15:57:06 +01:00
|
|
|
mov.l r8, @-r15 ! Save r8 register.
|
2019-12-06 23:45:04 +01:00
|
|
|
sts.l pr, @-r15 ! Save pr regsiter.
|
|
|
|
|
2019-12-09 15:57:06 +01:00
|
|
|
! Generate "programe" context (used by the UBC handler)
|
2019-12-06 23:45:04 +01:00
|
|
|
stc.l spc, @-r15 ! Get SPC register.
|
|
|
|
stc.l ssr, @-r15 ! Get SSR register.
|
|
|
|
sts.l mach, @-r15 ! Get MACH register.
|
|
|
|
sts.l macl, @-r15 ! Get MACL register.
|
|
|
|
stc.l gbr, @-r15 ! Get GBR register.
|
2019-12-07 15:51:12 +01:00
|
|
|
.word 0b0100111100110010 ! Get SGR register (save r15 address befor break) "stc.l sgr, @-r15"
|
2019-12-09 15:57:06 +01:00
|
|
|
mov.l r14, @-r15 ! Get "program" r14 register.
|
|
|
|
mov.l r13, @-r15 ! Get "program" r13 register.
|
|
|
|
mov.l r12, @-r15 ! Get "program" r12 register.
|
|
|
|
mov.l r11, @-r15 ! Get "program" r11 register.
|
|
|
|
mov.l r10, @-r15 ! Get "program" r10 register.
|
|
|
|
mov.l r9, @-r15 ! Get "program" r9 register.
|
2019-12-06 23:45:04 +01:00
|
|
|
mov.l r8, @-r15 ! Get "program" r8 register.
|
|
|
|
stc.l R7_BANK, @-r15 ! Get "program" r7 regsiter.
|
|
|
|
stc.l R6_BANK, @-r15 ! Get "program" r6 regsiter.
|
|
|
|
stc.l R5_BANK, @-r15 ! Get "program" r5 regsiter.
|
|
|
|
stc.l R4_BANK, @-r15 ! Get "program" r4 regsiter.
|
|
|
|
stc.l R3_BANK, @-r15 ! Get "program" r3 regsiter.
|
|
|
|
stc.l R2_BANK, @-r15 ! Get "program" r2 regsiter.
|
|
|
|
stc.l R1_BANK, @-r15 ! Get "program" r1 regsiter.
|
|
|
|
stc.l R0_BANK, @-r15 ! Get "program" r0 regsiter.
|
|
|
|
|
2019-12-09 15:57:06 +01:00
|
|
|
! We need to stop (and save) all clocks / timers
|
|
|
|
! before do any job.
|
|
|
|
mov.l .ubc_module_handler, r0 ! Get high level abstraction for handle hardware module.
|
|
|
|
jsr @r0 ! call ubc_module(MODULE_STOP)
|
|
|
|
mov #0, r4 ! (db) r4 = MODULE_STOP
|
2019-12-06 23:45:04 +01:00
|
|
|
|
|
|
|
! Get which channel is trigger and clear interrupt Flags.
|
|
|
|
mov.l .ubc_ccmfr, r0 ! Get UBC.CCMFR register
|
2019-12-09 15:57:06 +01:00
|
|
|
mov.l @r0, r9 ! r5 = UBC.CCMFR. (save register)
|
2019-12-06 23:45:04 +01:00
|
|
|
mov #0, r1 ! r2 = 0x00000000 (clear flags)
|
|
|
|
mov.l r1, @r0 ! Clear UBC.CCMFR.MF1 = 0 and UBC.CCMFR.MF1 = 0
|
|
|
|
mov.l .icbi_addr, r2 ! Get P2 area for ICBI instruction.
|
|
|
|
.word 0b0000001011100011 ! SH4 instruction "icbi @r2"
|
|
|
|
|
|
|
|
! Allow / unblock interrupt and switch register bank !
|
2019-12-09 15:57:06 +01:00
|
|
|
stc sr, r8 ! Save SR register.
|
|
|
|
mov r8, r1 ! Get SR register.
|
2019-12-06 23:45:04 +01:00
|
|
|
mov.l .sr_mask, r0 ! Get SR mask for SR.BL, SR.IMASK and SR.RB
|
|
|
|
and r0, r1 ! SR.BL = 0, SR.IMASK = 0b0000 and SR.RB = 0
|
|
|
|
ldc r1, sr ! Update SR register.
|
|
|
|
|
|
|
|
! Call high-level abstraction
|
|
|
|
mov r15, r4 ! Send UBC context object to the abstraction.
|
2019-12-09 15:57:06 +01:00
|
|
|
mov r9, r5 ! Send which channel is trigger.
|
2019-12-06 23:45:04 +01:00
|
|
|
mov.l .ubc_handler, r0 ! Get high-level abstraction address
|
|
|
|
jsr @r0 ! Jump into it.
|
|
|
|
nop ! (db) nop.
|
|
|
|
|
2019-12-09 15:57:06 +01:00
|
|
|
! Block interrupt and switch
|
|
|
|
! register bank
|
|
|
|
ldc r8, sr ! Restore SR register (with SR.BL = 1, SR.IMASK = 0b1111, SR.RB = 1)
|
2019-12-06 23:45:04 +01:00
|
|
|
|
2019-12-09 15:57:06 +01:00
|
|
|
! Restore "program" context.
|
|
|
|
ldc.l @r15+, R0_BANK ! Restore "program" r0 regsiter.
|
|
|
|
ldc.l @r15+, R1_BANK ! Restore "program" r1 regsiter.
|
|
|
|
ldc.l @r15+, R2_BANK ! Restore "program" r2 regsiter.
|
|
|
|
ldc.l @r15+, R3_BANK ! Restore "program" r3 regsiter.
|
|
|
|
ldc.l @r15+, R4_BANK ! Restore "program" r4 regsiter.
|
|
|
|
ldc.l @r15+, R5_BANK ! Restore "program" r5 regsiter.
|
|
|
|
ldc.l @r15+, R6_BANK ! Restore "program" r6 regsiter.
|
|
|
|
ldc.l @r15+, R7_BANK ! Restore "program" r7 regsiter.
|
|
|
|
mov.l @r15+, r8 ! Restore "program" r8 regsiter.
|
|
|
|
mov.l @r15+, r9 ! Restore "program" r9 regsiter.
|
|
|
|
mov.l @r15+, r10 ! Restore "program" r10 regsiter.
|
|
|
|
mov.l @r15+, r11 ! Restore "program" r11 regsiter.
|
|
|
|
mov.l @r15+, r12 ! Restore "program" r12 regsiter.
|
|
|
|
mov.l @r15+, r13 ! Restore "program" r13 regsiter.
|
|
|
|
mov.l @r15+, r14 ! Restore "program" r14 regsiter.
|
2019-12-07 15:51:12 +01:00
|
|
|
.word 0b0100111100110110 ! Restore SGR regsiter. "ldc.l @r15+, sgr"
|
2019-12-09 15:57:06 +01:00
|
|
|
ldc.l @r15+, gbr ! Get GBR register.
|
|
|
|
lds.l @r15+, macl ! Get MACL register.
|
|
|
|
lds.l @r15+, mach ! Get MACH register.
|
2019-12-07 15:51:12 +01:00
|
|
|
ldc.l @r15+, ssr ! Restore SSR regsiter.
|
|
|
|
ldc.l @r15+, spc ! Restore SPC regsiter.
|
2019-12-09 15:57:06 +01:00
|
|
|
|
|
|
|
! Retore and restart clock / timers
|
|
|
|
stc spc, r4 ! (db) r4 = MODULE_START
|
|
|
|
mov.l .ubc_module_handler, r0 ! Get high level abstraction for handle hardware module.
|
|
|
|
jsr @r0 ! call ubc_module(MODULE_START)
|
|
|
|
nop
|
|
|
|
|
|
|
|
! Clean exit.
|
|
|
|
lds.l @r15+, pr ! Restor PR register.
|
|
|
|
mov.l @r15+, r8 ! Restore r8 register.
|
|
|
|
mov.l @r15+, r9 ! Restore r8 register.
|
2019-12-06 23:45:04 +01:00
|
|
|
rte ! Interrupt Exit.
|
2019-12-07 15:51:12 +01:00
|
|
|
nop ! (db) Safety first.
|
2019-12-06 23:45:04 +01:00
|
|
|
|
|
|
|
|
|
|
|
.align 4
|
2019-12-09 15:57:06 +01:00
|
|
|
.ubc_handler: .long _ubc_handler
|
|
|
|
.ubc_module_handler: .long _ubc_module_handler
|
|
|
|
.ubc_ccmfr: .long 0xff200600
|
|
|
|
.icbi_addr: .long 0xa0000000
|
|
|
|
.sr_mask: .long ~(0x300000f0)
|
2019-12-06 23:45:04 +01:00
|
|
|
.end
|