А что мешает сделать простой переход в область адресов загрузчика из "стандартной"?
Привязка к аппаратной поддержке совсем не обязательна.
Просто делаем свой раздел в защищенной области к которому обращаются команды указателей адреса перехода из основного раздела " по умолчанию"...
Исходная таблица "по умолчанию" будет обслуживать переходы на вновь созданную, но не средствами аппаратной поддержки, а средствами программной поддержки автором программы.
Мы же вторичные (целевые) указатели можем размещать где угодно. Другое дело, что при написании целевой программы нужно учитывать параметры разметки бутлоадера - знать адреса размещения векторов по листингу бутлоадера и задавать их затем вручную при написании целевой программы.
Но это уже стандартная специфика для комплекта базового бутлоадера с набором минимальных общих функций и целевой программы, которая может как пользоваться подпрограммами бутлоадера (прием/передача, типовые преобразования и т.п.) так и своими аналогами таких же подпрограмм.
Это привычнее с оперативно подгружаемыми программами на самоделке с единой общей базой. Меняем модуль аппаратного расширения и загружаем соответствующую этому аппаратному модулю прикладную часть программы. А в самой "мамке" сидит только базовый загрузчик и утилиты управления аппаратным ядром устройства.
Некоторая аналогия ПК - сначала запускается биос аппаратной части, затем программа пользователя, которая также использует и ресурсы биос и ресурсы собственные, которые можно модифицировать при необходимости.
Отличие только в режиме модификации ячеек памяти программ - для ОЗУ мгновенная запись, по флеш ПЗУ требуется некоторое время и спецпроцедуры для перезаписи.

По конкретике...
Допустим я взял мегу8а...
Оставил исходную таблицу векторов на своем месте...
А прикладные вектора хочу разместить в области бутлоадера (на всякий случай беру бутлоадер максимального размера)...
Т.е. у меня область бутлоадера от 0хС00 и далее...
ставлю вот такой добавок в дефайне (m8adef.inc):
Спойлер
Код: Выделить всё
; ***** my INTERRUPT VECTORS ************************************************
; причем софтовая таблица может иметь и другие адреса начального размещения внутри области бутлоадера
; а не только самые первые (от FOURTHBOOTSTART)
.equ INT0addr_r = FOURTHBOOTSTART + 0x0001 ; External Interrupt Request 0
.equ INT1addr_r = FOURTHBOOTSTART + 0x0002 ; External Interrupt Request 1
.equ OC2addr_r = FOURTHBOOTSTART + 0x0003 ; Timer/Counter2 Compare Match
.equ OVF2addr_r = FOURTHBOOTSTART + 0x0004 ; Timer/Counter2 Overflow
.equ ICP1addr_r = FOURTHBOOTSTART + 0x0005 ; Timer/Counter1 Capture Event
.equ OC1Aaddr_r = FOURTHBOOTSTART + 0x0006 ; Timer/Counter1 Compare Match A
.equ OC1Baddr_r = FOURTHBOOTSTART + 0x0007 ; Timer/Counter1 Compare Match B
.equ OVF1addr_r = FOURTHBOOTSTART + 0x0008 ; Timer/Counter1 Overflow
.equ OVF0addr_r = FOURTHBOOTSTART + 0x0009 ; Timer/Counter0 Overflow
.equ SPIaddr_r = FOURTHBOOTSTART + 0x000a ; Serial Transfer Complete
.equ URXCaddr_r = FOURTHBOOTSTART + 0x000b ; USART, Rx Complete
.equ UDREaddr_r = FOURTHBOOTSTART + 0x000c ; USART Data Register Empty
.equ UTXCaddr_r = FOURTHBOOTSTART + 0x000d ; USART, Tx Complete
.equ ADCCaddr_r = FOURTHBOOTSTART + 0x000e ; ADC Conversion Complete
.equ ERDYaddr_r = FOURTHBOOTSTART + 0x000f ; EEPROM Ready
.equ ACIaddr_r = FOURTHBOOTSTART + 0x0010 ; Analog Comparator
.equ TWIaddr_r = FOURTHBOOTSTART + 0x0011 ; 2-wire Serial Interface
.equ SPMRaddr_r = FOURTHBOOTSTART + 0x0012 ; Store Program Memory Ready
; .equ INT_VECTORS_SIZE = 19 ; size in words
А в своей программе ставлю сначала
Код: Выделить всё
.org 0x0000
INT0addr: jmp INT0addr_r ; External Interrupt Request 0
INT1addr: jmp INT1addr_r ; External Interrupt Request 1
OC2addr: jmp OC2addr_r ; Timer/Counter2 Compare Match
OVF2addr: jmp OVF2addr_r ; Timer/Counter2 Overflow
ICP1addr: jmp ICP1addr_r ; Timer/Counter1 Capture Event
OC1Aaddr: jmp OC1Aaddr_r ; Timer/Counter1 Compare Match A
OC1Baddr: jmp OC1Baddr_r ; Timer/Counter1 Compare Match B
OVF1addr: jmp OVF1addr_r ; Timer/Counter1 Overflow
OVF0addr: jmp OVF0addr_r ; Timer/Counter0 Overflow
SPIaddr: jmp SPIaddr_r ; Serial Transfer Complete
URXCaddr: jmp URXCaddr_r ; USART, Rx Complete
UDREaddr: jmp UDREaddr_r ; USART Data Register Empty
UTXCaddr: jmp UTXCaddr_r ; USART, Tx Complete
ADCCaddr: jmp ADCCaddr_r ; ADC Conversion Complete
ERDYaddr: jmp ERDYaddr_r ; EEPROM Ready
ACIaddr: jmp ACIaddr_r ; Analog Comparator
TWIaddr: jmp TWIaddr_r ; 2-wire Serial Interface
SPMRaddr: jmp SPMRaddr_r ; Store Program Memory Ready
; далее текст программы при необходимости
...............
; теперь область бутлоадера:
.org FOURTHBOOTSTART ; или иная область внутри области ПЗУ бутлоадера - это софт, а не аппаратная разметка***
INT0addr_r: jmp my_INT0 ; External Interrupt Request 0
INT1addr_r: jmp my_INT1 ; External Interrupt Request 1
OC2addr_r: jmp my_OC2 ; Timer/Counter2 Compare Match
OVF2addr_r: jmp my_OVF2 ; Timer/Counter2 Overflow
ICP1addr_r: jmp my_ICP1 ; Timer/Counter1 Capture Event
OC1Aaddr_r: jmp my_OC1A ; Timer/Counter1 Compare Match A
OC1Baddr_r: jmp my_OC1B ; Timer/Counter1 Compare Match B
OVF1addr_r: jmp my_OVF1 ; Timer/Counter1 Overflow
OVF0addr_r: jmp my_OVF0 ; Timer/Counter0 Overflow
SPIaddr_r: jmp my_SPI ; Serial Transfer Complete
URXCaddr_r: jmp my_URXC ; USART, Rx Complete
UDREaddr_r: jmp my_UDRE ; USART Data Register Empty
UTXCaddr_r: jmp my_UTXC ; USART, Tx Complete
ADCCaddr_r: jmp my_ADCC ; ; ADC Conversion Complete
ERDYaddr_r: jmp my_ERDY ; ; EEPROM Ready
ACIaddr_r: jmp my_ACI ; Analog Comparator
TWIaddr_r: jmp my_TWI ; 2-wire Serial Interface
SPMRaddr_r: jmp my_SPMR ; Store Program Memory Ready
; далее сам бутлоадер с соответствующими подпрограммами:
...................
my_INT0: reti ; External Interrupt Request 0
my_INT1: reti ; External Interrupt Request 1
my_OC2: reti ; Timer/Counter2 Compare Match
my_OVF2: reti ; Timer/Counter2 Overflow
my_ICP1: reti ; Timer/Counter1 Capture Event
my_OC1A: reti ; Timer/Counter1 Compare Match A
my_OC1B: reti ; Timer/Counter1 Compare Match B
my_OVF1: reti ; Timer/Counter1 Overflow
my_OVF0: reti ; Timer/Counter0 Overflow
my_SPI: reti ; Serial Transfer Complete
my_URXC: reti ; USART, Rx Complete
my_UDRE: reti ; USART Data Register Empty
my_UTXC: reti ; USART, Tx Complete
my_ADCC: reti ; ; ADC Conversion Complete
my_ERDY: reti ; ; EEPROM Ready
my_ACI: reti ; Analog Comparator
my_TWI: reti ; 2-wire Serial Interface
my_SPMR: reti ; Store Program Memory Ready
В принципе... если у меня есть несколько вариантов на один вектор
обработки и несколько подпрограмм требующих быстрого переключения...
Тогда где-нибудь храню адреса тех подпрограмм а по точке вектора
ставлю:
Код: Выделить всё
URXCaddr_r: ijmp ; USART, Rx Complete
UDREaddr_r: ijmp ; USART Data Register Empty
UTXCaddr_r: ijmp ; USART, Tx Complete
при этом надо позаботиться о предварительной загрузке прикладных адресов
в Z регистр, что обеспечит возможность запуска нескольких вариантов
подпрограмм для каждого из прерываний.
для аппаратной поддержки возможны и "обратные" варианты - когда основная
таблица в бутлоадере, а "софтовая" в любом месте прикладной программы.
