////////////////
//file bank 0 address 0x000~0x7ff
////////////////
static volatile uint8_t s_addr_low;
static volatile uint8_t s_addr_high;
void bank00_EntryPoint00()
{
s_addr_low = 0;
s_addr_high = 0;
asm("return");
}
uint16_t goto_bank01()
{
volatile uint16_t backvalue = (uint16_t)(&bank00_EntryPoint00);
s_addr_low = (uint8_t)(backvalue & 0x00ff);
s_addr_high = (uint8_t)(backvalue >> 8);
asm("bsf PCLATH,3");
asm("bcf PCLATH,4");
asm("bcf PCLATH,5");
asm("bcf PCLATH,6");
__asm__ volatile(
"movf _s_addr_low,W \n"
"movwf FSR0L \n"
"movf _s_addr_high,W \n"
"movwf FSR0H \n"
"call 0x3a0 \n"
);
__asm__ volatile(
"movf FSR0L,W \n"
"movwf _s_addr_low \n"
"movf FSR0H,W \n"
"movwf _s_addr_high \n"
);
backvalue = s_addr_high;
backvalue = (backvalue << 8) | s_addr_low;
return backvalue;
}
int16_t zeroJob()
{
int16_t ret = 0;
return ret;
}
//keep code bank00_EntryPoint00, bank00_EntryPoint01
void bank00_InitFunction(int16_t value)
{
switch(value)
{
case -1:
bank00_EntryPoint00();
bank00_EntryPoint01();
break;
default:
break;
}
}
int main(void)
{
bank00_InitFunction(zeroJob()); //must use it to keep symbol address
SYSTEM_Initialize();
goto_bank01();
while(1)
{
__delay_us(1000);
}
return 0;
}
////////////////
//file bank 1 link address 0x800~0xfff
////////////////
static volatile uint8_t s_addr_low;
static volatile uint8_t s_addr_high;
void bank01_Jump(uint16_t addrfunc)
{
s_addr_low = (uint8_t)(addrfunc & 0x00ff);
s_addr_high = (uint8_t)(addrfunc >> 8);
__asm__ volatile("movf _s_addr_high,W \n"
"movwf PCLATH \n"
"movf _s_addr_low,W \n"
"movwf PCL \n");
}
void bank01_Call(uint16_t addrfunc)
{
s_addr_low = (uint8_t)(addrfunc & 0x00ff);
s_addr_high = (uint8_t)(addrfunc >> 8);
__asm__ volatile("movlw 0xED \n"
"movwf FSR0L \n"
"movlw 0x0F \n"
"movwf FSR0H \n"
"movf INDF0,W \n"
"incf WREG, F \n"
"movwf INDF0 \n"
"movlw 0xEE \n"
"movwf FSR0L \n"
"movlw 0x0F \n"
"movwf FSR0H \n"
"movlw (bank01_back_label & 0x00ff) \n"
"movwf INDF0 \n"
"movlw 0xEF \n"
"movwf FSR0L \n"
"movlw 0x0F \n"
"movwf FSR0H \n"
"movlw ((bank01_back_label >> 8) & 0x00ff) \n"
"movwf INDF0 \n"
"movf _s_addr_high,W \n"
"movwf PCLATH \n"
"movf _s_addr_low,W \n"
"movwf PCL \n"
"bank01_back_label: \n");
}
void bank01_EntryPoint01() __at(0x0ba0) //offset 0x3a0
{
volatile uint16_t backvalue;
__asm__ volatile("movf FSR0L,W \n"
"movwf _s_addr_low \n"
"movf FSR0H,W \n"
"movwf _s_addr_high \n");
backvalue = s_addr_high;
backvalue = (backvalue << 8) | s_addr_low;
bank01_Call(backvalue); //test
asm("bcf PCLATH,3");
asm("bcf PCLATH,4");
asm("bcf PCLATH,5");
asm("bcf PCLATH,6");
s_addr_low = backvalue & 0xFF; // Low byte of the parameter
s_addr_high = (backvalue >> 8) & 0xFF; // High byte of the parameter
s_addr_low++; //test
__asm__ volatile("movf _s_addr_low,W \n"
"movwf FSR0L \n"
"movf _s_addr_high,W \n"
"movwf FSR0H \n");
asm("return");
}
int16_t zeroJob()
{
int16_t ret = 0;
return ret;
}
void bank01_InitFunction(int16_t value)
{
switch(value)
{
case -1:
bank01_EntryPoint00();
bank01_EntryPoint01(0);
break;
default:
break;
}
}
int main(void)
{
bank01_InitFunction(zeroJob()); //must use it to load symbol address
return 0;
}
explain:
1. select page, one page 2k size
asm("bcf PCLATH,3");
asm("bcf PCLATH,4");
asm("bcf PCLATH,5");
asm("bcf PCLATH,6");
2. assembly of bank01_Call
must use indirect reg INDF0 copy value
add STKPRT content +1
low bank01_back_label address move to TOL
high bank01_back_label address move to TOH
PCLATH select page
PCL jump to address
3. assembly of bank00_EntryPoint00
asm("return");
will return to bank01_back_label
4.
volatile uint16_t backvalue;
__asm__ volatile("movf FSR0L,W \n"
"movwf _s_addr_low \n"
"movf FSR0H,W \n"
"movwf _s_addr_high \n");
backvalue = s_addr_high;
backvalue = (backvalue << 8) | s_addr_low;
pass backaddr to bank01_Call
沒有留言:
張貼留言