;**************************************************************************
; arch/z80/src/ez80/ez80f92_loader.asm
;
; Licensed to the Apache Software Foundation (ASF) under one or more
; contributor license agreements. See the NOTICE file distributed with
; this work for additional information regarding copyright ownership. The
; ASF licenses this file to you under the Apache License, Version 2.0 (the
; "License"); you may not use this file except in compliance with the
; License. You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
; WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
; License for the specific language governing permissions and limitations
; under the License.
;
;**************************************************************************
;**************************************************************************
; Global Symbols Imported
;**************************************************************************
xref __vecstart
xref __vecend
xref _ez80_irq_common
;**************************************************************************
; Global Symbols Exported
;**************************************************************************
xdef _ez80_initvectors
;**************************************************************************
; Constants
;**************************************************************************
NVECTORS EQU 64 ; Max possible interrupt vectors
EZ80_UNUSED EQU 64 ; Denotes an unused vector
; RAM Memory map
;
; __vecstart Beginning of Interrupt Redirection information. This is
; used to hand off to RAM-based handlers for interrupts
; caught by FLASH interrupt vectors.
; __vecend End of the Interrupt Redirection information.
; __loaderstart Start of RAM used exclusively by the bootloader. This
; memory region an be recovered by the RAM-based program.
; __loaderend End of the bootloader RAM.
; __progstart Start of CODE for the RAM-based program. The program can
; freely use the memory region from _progstart-_progend and
; can recover the memory for _loaderstart-_loaderend for heap
; usage.
; __progend End of RAM/End of the RAM-based program
VECSTART EQU __vecstart ; Start of interrupt redirection area
VECSIZE EQU __vecend - __vecstart ; Size of interrupt redirection area
;**************************************************************************
; Macros
;**************************************************************************
; Define one interrupt handler
irqhandler: macro vectno
; Save AF on the stack, set the interrupt number and jump to the
; common reset handling logic.
; Offset 8: Return PC is already on the stack
push af ; Offset 7: AF (retaining flags)
ld a, #vectno ; A = vector number
jp _ez80_irq_common ; Remaining RST handling is common
endmac irqhandler
;**************************************************************************
; Vector Table
;**************************************************************************
; This segment must be aligned on a 256 byte boundary anywhere in RAM
; Each entry will be a 2-byte address in a 2-byte space. The vector table
; will always reside in FLASH memory; Only the loader in FLASH provides
; the vector table.
define .IVECTS, space = ROM, align = 100h
segment .IVECTS
; Vector table is a 2-bit address. The MSB is the I register; the LSB is
; the vector number. The vector table lies in FLASH. The addresses
; contained in the refers to an entry in the handler table that re-
; directs the interrupt to common interrupt handling logic.
_ez80_vectable:
dw _ez80_redirect + 0*_redirsize
dw _ez80_redirect + 1*_redirsize
dw _ez80_redirect + 2*_redirsize
dw _ez80_redirect + 3*_redirsize
dw _ez80_redirect + 4*_redirsize
dw _ez80_redirect + 5*_redirsize
dw _ez80_redirect + 6*_redirsize
dw _ez80_redirect + 7*_redirsize
dw _ez80_redirect + 8*_redirsize
dw _ez80_redirect + 9*_redirsize
dw _ez80_redirect + 10*_redirsize
dw _ez80_redirect + 11*_redirsize
dw _ez80_redirect + 12*_redirsize
dw _ez80_redirect + 13*_redirsize
dw _ez80_redirect + 14*_redirsize
dw _ez80_redirect + 15*_redirsize
dw _ez80_redirect + 16*_redirsize
dw _ez80_redirect + 17*_redirsize
dw _ez80_redirect + 18*_redirsize
dw _ez80_redirect + 19*_redirsize
dw _ez80_redirect + 20*_redirsize
dw _ez80_redirect + 21*_redirsize
dw _ez80_redirect + 22*_redirsize
dw _ez80_redirect + 23*_redirsize
dw _ez80_redirect + 24*_redirsize
dw _ez80_redirect + 25*_redirsize
dw _ez80_redirect + 26*_redirsize
dw _ez80_redirect + 27*_redirsize
dw _ez80_redirect + 28*_redirsize
dw _ez80_redirect + 29*_redirsize
dw _ez80_redirect + 30*_redirsize
dw _ez80_redirect + 31*_redirsize
dw _ez80_redirect + 32*_redirsize
dw _ez80_redirect + 33*_redirsize
dw _ez80_redirect + 34*_redirsize
dw _ez80_redirect + 35*_redirsize
dw _ez80_redirect + 36*_redirsize
dw _ez80_redirect + 37*_redirsize
dw _ez80_redirect + 38*_redirsize
dw _ez80_redirect + 39*_redirsize
dw _ez80_redirect + 40*_redirsize
dw _ez80_redirect + 41*_redirsize
dw _ez80_redirect + 42*_redirsize
dw _ez80_redirect + 43*_redirsize
dw _ez80_redirect + 44*_redirsize
dw _ez80_redirect + 45*_redirsize
dw _ez80_redirect + 46*_redirsize
dw _ez80_redirect + 47*_redirsize
dw _ez80_redirect + 48*_redirsize
dw _ez80_redirect + 49*_redirsize
dw _ez80_redirect + 50*_redirsize
dw _ez80_redirect + 51*_redirsize
dw _ez80_redirect + 52*_redirsize
dw _ez80_redirect + 53*_redirsize
dw _ez80_redirect + 54*_redirsize
dw _ez80_redirect + 55*_redirsize
dw _ez80_redirect + 56*_redirsize
dw _ez80_redirect + 57*_redirsize
dw _ez80_redirect + 58*_redirsize
dw _ez80_redirect + 59*_redirsize
dw _ez80_redirect + 60*_redirsize
dw _ez80_redirect + 61*_redirsize
dw _ez80_redirect + 62*_redirsize
dw _ez80_redirect + 63*_redirsize
;**************************************************************************
; Interrupt Redirection Table
;**************************************************************************
; Still in .IVECTS section
.assume ADL=1
; The redirection table is an intermediate step in interrupt processing.
; When the interrupt occurs, the address in the corresponding entry in the
; vector table (_ez80_vectable) will execute. That will be an entry in
; this table. That entry will simply to the handler entry which has been
; related in RAM at VECSTART. The reason for this redirection is so that
; RAM-based programs and receive the interrupts vectored through the ROM-
; based loader code.
_ez80_redirect:
jp VECSTART + 0*_handlersize
_redirsize EQU $-_ez80_redirect
jp VECSTART + 1*_handlersize
jp VECSTART + 2*_handlersize
jp VECSTART + 3*_handlersize
jp VECSTART + 4*_handlersize
jp VECSTART + 5*_handlersize
jp VECSTART + 6*_handlersize
jp VECSTART + 7*_handlersize
jp VECSTART + 8*_handlersize
jp VECSTART + 9*_handlersize
jp VECSTART + 10*_handlersize
jp VECSTART + 11*_handlersize
jp VECSTART + 12*_handlersize
jp VECSTART + 13*_handlersize
jp VECSTART + 14*_handlersize
jp VECSTART + 15*_handlersize
jp VECSTART + 16*_handlersize
jp VECSTART + 17*_handlersize
jp VECSTART + 18*_handlersize
jp VECSTART + 19*_handlersize
jp VECSTART + 20*_handlersize
jp VECSTART + 21*_handlersize
jp VECSTART + 22*_handlersize
jp VECSTART + 23*_handlersize
jp VECSTART + 24*_handlersize
jp VECSTART + 25*_handlersize
jp VECSTART + 26*_handlersize
jp VECSTART + 27*_handlersize
jp VECSTART + 28*_handlersize
jp VECSTART + 29*_handlersize
jp VECSTART + 30*_handlersize
jp VECSTART + 31*_handlersize
jp VECSTART + 32*_handlersize
jp VECSTART + 33*_handlersize
jp VECSTART + 34*_handlersize
jp VECSTART + 35*_handlersize
jp VECSTART + 36*_handlersize
jp VECSTART + 37*_handlersize
jp VECSTART + 38*_handlersize
jp VECSTART + 39*_handlersize
jp VECSTART + 40*_handlersize
jp VECSTART + 41*_handlersize
jp VECSTART + 42*_handlersize
jp VECSTART + 43*_handlersize
jp VECSTART + 44*_handlersize
jp VECSTART + 45*_handlersize
jp VECSTART + 46*_handlersize
jp VECSTART + 47*_handlersize
jp VECSTART + 48*_handlersize
jp VECSTART + 49*_handlersize
jp VECSTART + 50*_handlersize
jp VECSTART + 51*_handlersize
jp VECSTART + 52*_handlersize
jp VECSTART + 53*_handlersize
jp VECSTART + 54*_handlersize
jp VECSTART + 55*_handlersize
jp VECSTART + 56*_handlersize
jp VECSTART + 57*_handlersize
jp VECSTART + 58*_handlersize
jp VECSTART + 59*_handlersize
jp VECSTART + 60*_handlersize
jp VECSTART + 61*_handlersize
jp VECSTART + 62*_handlersize
jp VECSTART + 63*_handlersize
;**************************************************************************
; Interrupt Vector Handlers
;**************************************************************************
define .STARTUP, space = ROM
segment .STARTUP
.assume ADL=1
; This is a copy of the handler table that will be copied into RAM at the
; address given by VECSTART by _ez80_initvectors. FLASH based interrupt
; handling will vector here to support interrupts in the RAM-based program.
; Symbol Val VecNo VecOffset
;----------------- --- ----- ---------
_ez80_handlers:
irqhandler EZ80_UNUSED ; 0 0x000
_handlersize EQU $-_ez80_handlers
irqhandler EZ80_UNUSED+1 ; 1 0x002
irqhandler EZ80_UNUSED+2 ; 2 0x004
irqhandler EZ80_UNUSED+3 ; 3 0x006
irqhandler 0 ; EZ80_FLASH_IRQ 0 4 0x008
irqhandler 1 ; EZ80_TIMER0_IRQ 1 5 0x00a
irqhandler 2 ; EZ80_TIMER1_IRQ 2 6 0x00c
irqhandler 3 ; EZ80_TIMER2_IRQ 3 7 0x00e
irqhandler 4 ; EZ80_TIMER3_IRQ 4 8 0x010
irqhandler 5 ; EZ80_TIMER4_IRQ 5 9 0x012
irqhandler 6 ; EZ80_TIMER5_IRQ 6 10 0x014
irqhandler 7 ; EZ80_RTC_IRQ 7 11 0x016
irqhandler 8 ; EZ80_UART0_IRQ 8 12 0x018
irqhandler 9 ; EZ80_UART1_IRQ 9 13 0x01a
irqhandler 10 ; EZ80_I2C_IRQ 10 14 0x01c
irqhandler 11 ; EZ80_SPI_IRQ 11 15 0x01e
irqhandler EZ80_UNUSED+4 ; 16 0x020
irqhandler EZ80_UNUSED+5 ; 17 0x022
irqhandler EZ80_UNUSED+6 ; 18 0x024
irqhandler EZ80_UNUSED+7 ; 19 0x026
irqhandler EZ80_UNUSED+8 ; 16 0x028
irqhandler EZ80_UNUSED+9 ; 17 0x02a
irqhandler EZ80_UNUSED+10 ; 18 0x02c
irqhandler EZ80_UNUSED+11 ; 19 0x02e
irqhandler 12 ; EZ80_PORTB0_IRQ 12 24 0x030
irqhandler 13 ; EZ80_PORTB1_IRQ 13 25 0x032
irqhandler 14 ; EZ80_PORTB2_IRQ 14 26 0x034
irqhandler 15 ; EZ80_PORTB3_IRQ 15 27 0x036
irqhandler 16 ; EZ80_PORTB4_IRQ 16 28 0x038
irqhandler 17 ; EZ80_PORTB5_IRQ 17 29 0x03a
irqhandler 18 ; EZ80_PORTB6_IRQ 18 20 0x03c
irqhandler 19 ; EZ80_PORTB7_IRQ 19 21 0x03e
irqhandler 20 ; EZ80_PORTC0_IRQ 20 22 0x040
irqhandler 21 ; EZ80_PORTC1_IRQ 21 23 0x042
irqhandler 22 ; EZ80_PORTC2_IRQ 22 24 0x044
irqhandler 23 ; EZ80_PORTC3_IRQ 23 25 0x046
irqhandler 24 ; EZ80_PORTC4_IRQ 24 26 0x048
irqhandler 25 ; EZ80_PORTC5_IRQ 25 27 0x04a
irqhandler 26 ; EZ80_PORTC6_IRQ 26 28 0x04c
irqhandler 27 ; EZ80_PORTC7_IRQ 27 29 0x04e
irqhandler 28 ; EZ80_PORTD0_IRQ 28 40 0x050
irqhandler 29 ; EZ80_PORTD1_IRQ 29 41 0x052
irqhandler 30 ; EZ80_PORTD2_IRQ 30 42 0x054
irqhandler 31 ; EZ80_PORTD3_IRQ 31 43 0x056
irqhandler 32 ; EZ80_PORTD4_IRQ 32 44 0x058
irqhandler 33 ; EZ80_PORTD5_IRQ 33 45 0x05a
irqhandler 34 ; EZ80_PORTD6_IRQ 34 46 0x05c
irqhandler 35 ; EZ80_PORTD7_IRQ 35 47 0x05e
irqhandler EZ80_UNUSED+12 ; 48 0x060
irqhandler EZ80_UNUSED+13 ; 49 0x062
irqhandler EZ80_UNUSED+14 ; 50 0x064
irqhandler EZ80_UNUSED+15 ; 51 0x066
irqhandler EZ80_UNUSED+16 ; 52 0x068
irqhandler EZ80_UNUSED+17 ; 53 0x06a
irqhandler EZ80_UNUSED+18 ; 54 0x06c
irqhandler EZ80_UNUSED+19 ; 55 0x06e
irqhandler EZ80_UNUSED+20 ; 56 0x070
irqhandler EZ80_UNUSED+21 ; 57 0x072
irqhandler EZ80_UNUSED+22 ; 58 0x074
irqhandler EZ80_UNUSED+23 ; 59 0x076
irqhandler EZ80_UNUSED+24 ; 60 0x078
irqhandler EZ80_UNUSED+25 ; 61 0x07a
irqhandler EZ80_UNUSED+26 ; 62 0x07c
irqhandler EZ80_UNUSED+27 ; 63 0x07e
_copysize EQU $-_ez80_handlers
;**************************************************************************
; Vector Setup Logic
;**************************************************************************
; Still in the .STARTUP segment.
_ez80_initvectors:
; The interrupt vector and redirection tables reside in FLASH, but the
; handlers must be copied to into the VECSTART region in RAM. This
; is necessary to support interrupt hand-off from FLASH-based interrupt
; vectors to RAM-based programs.
; Copy the initialized data section
ld bc, _copysize ; [bc] = data length
ld hl, _ez80_handlers ; [hl] = data source
ld de, VECSTART ; [de] = data destination
ldir ; Copy the interrupt handlers
; Select interrupt mode 2
im 2 ; Interrupt mode 2
; Write the address of the vector table into the interrupt vector base
ld a, _ez80_vectable >> 8 & 0ffh
ld i, a
ret
end