.section ".ubc.handler", "awx", @progbits .global _ubc_handler_pre .type _ubc_handler_pre, @function .extern _ubc_handler .extern _ubc_module_handler .align 2 _ubc_handler_pre: ! Generate "programme" context (used by the UBC handler) sts.l pr, @-r15 ! Save pr regsiter. 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. .word 0b0100111100110010 ! Get SGR register (save r15 address befor break) "stc.l sgr, @-r15" 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. 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. ! Get which channel is trigger ! and clear interrupt flags. mov.l .ubc_ccmfr, r0 ! get UBC.CCMFR register mov.l @r0, r9 ! r9 = UBC.CCMFR. (save register) 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" ! Save all hardware context and restore ! Vhex environement mov.l .drivers_install, r0 jsr @r0 mov #0, r4 ! Allow / unblock interrupt and switch register bank ! stc sr, r8 ! save SR register. mov r8, r1 ! get SR register. 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. mov r9, r5 ! Send which channel is trigger. mov.l .ubc_handler, r0 ! Get high-level abstraction address jsr @r0 ! Jump into it. nop ! (db) nop. ! Block interrupt and switch ! register bank ldc r8, sr ! Restore SR register (with SR.BL = 1, SR.IMASK = 0b1111, SR.RB = 1) ! Retore Casio's environement mov.l .drivers_uninstall, r0 jsr @r0 mov #0, r4 ! 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. .word 0b0100111100110110 ! Restore SGR regsiter. "ldc.l @r15+, sgr" ldc.l @r15+, gbr ! Get GBR register. lds.l @r15+, macl ! Get MACL register. lds.l @r15+, mach ! Get MACH register. ldc.l @r15+, ssr ! Restore SSR regsiter. ldc.l @r15+, spc ! Restore SPC regsiter. lds.l @r15+, pr ! Restor PR register. ! Clean exit. rte ! Interrupt Exit. nop ! (db) Safety first. .align 4 .ubc_handler: .long _ubc_handler .drivers_install: .long _drivers_install .drivers_uninstall: .long _drivers_uninstall .ubc_ccmfr: .long 0xff200600 .icbi_addr: .long 0xa0000000 .sr_mask: .long ~(0x300000f0) .end