import em from '@$$emscript'
export const $U = em.$declare('MODULE')
export namespace em$meta {
const NO_VEC = '<NA>'
const core_intrs = [
'NMI',
'HardFault',
NO_VEC,
NO_VEC,
NO_VEC,
NO_VEC,
NO_VEC,
NO_VEC,
NO_VEC,
'SVCall',
NO_VEC,
NO_VEC,
'PendSV',
'SysTick',
]
const intr_list = new Array<string>()
const used_list = new Array<string>()
const used_set = new Set<string>()
export function em$init() {
$U.used()
for (let name of core_intrs) addIntr(name)
}
export function em$generate() {
let out = $outfile('em.arch.arm/intr.cpp')
out.addFrag(`
|-> //
|-> #include <stdbool.h>
|-> #include <stdint.h>
|->
|-> typedef void( *intfunc )( void );
|-> typedef union { intfunc fxn; void* ptr; } intvec_elem;
|->
|-> extern uint32_t __stack_top__;
|-> extern "C" void em__start( void );
|->
|-> extern "C" void DEFAULT_isr$$( void );
|->
|-> extern "C" const intvec_elem __attribute__((section(".intvec"))) __vector_table[35] = {
|-> { .ptr = (void*)&__stack_top__ },
|-> { .fxn = em__start },
`)
for (let n of intr_list) {
const s = n == NO_VEC ? '0' : used_set.has(n) ? `${n}_isr$$` : 'DEFAULT_isr$$'
out.addFrag(`
|-> /**/${s},
`)
}
out.addFrag(`
|-> };
`)
out.close()
}
export function addIntr(name: string) {
intr_list.push(name)
}
export function useIntr(name: string) {
used_list.push(name)
used_set.add(name)
}
}
export function em$startup() {
e$`SCB->VTOR = (uint32_t)(&__vector_table)`
}
export function NVIC_clear(irqN: u8) {
e$`NVIC_ClearPendingIRQ((IRQn_Type)irqN)`
}
export function NVIC_disable(irqN: u8) {
e$`NVIC_DisableIRQ((IRQn_Type)irqN)`
}
export function NVIC_enable(irqN: u8) {
e$`NVIC_EnableIRQ((IRQn_Type)irqN)`
}
export function PRIMASK_get(): u32 {
return e$`__get_PRIMASK()`
}
export function PRIMASK_set(m: u32) {
e$`__set_PRIMASK(m)`
}
export function DEFAULT_isr$$() {
em.$['%%b:'](3)
let vnum = <u32>e$`__get_IPSR()`
em.$['%%>'](vnum)
let fp = <ptr_t<u32>>(e$`__get_MSP()`)
em.$['%%>'](fp.$cur())
for (let i = 0; i < 8; i++) {
em.$['%%b']
em.$['%%>'](fp.$$)
fp.$inc()
}
em.fail#f()
}