summaryrefslogblamecommitdiff
path: root/nuttx/arch/z80/src/ez80/ez80_vectors.asm
blob: d49fc976b6172af0916b80a091fe27b88e3abcc5 (plain) (tree)






































                                                                            









                                                                            

                                                                            
                          


                                                                            
                          




                                                                            



























                                                                                      
                                                                           

                           









































                                                                            
                                        



































































                                                                            
                 








                                                                          

                                                                                         





                                                                  






                                                                                        





                                                                                            

                                                                       
                                                                          




                                                                                      
                                                                                












                                                                                          
                                                                                     






                                                                      
                                                                   
                                                                                           
                                                          




                                                                    
                                                                             


                                                                                  
             









                                                                            
                                   
                      
                      
                            







                                                                      

                     







                                                                                   

                                  

                                                           















                                                                               


                                                                                 
                
                             
;**************************************************************************
; arch/z80/src/ez80/ez80_vectors.asm
;
;   Copyright (C) 2008 Gregory Nutt. All rights reserved.
;   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions
; are met:
;
; 1. Redistributions of source code must retain the above copyright
;    notice, this list of conditions and the following disclaimer.
; 2. Redistributions in binary form must reproduce the above copyright
;    notice, this list of conditions and the following disclaimer in
;    the documentation and/or other materials provided with the
;    distribution.
; 3. Neither the name NuttX nor the names of its contributors may be
;    used to endorse or promote products derived from this software
;    without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
; FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
; COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
; OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
; POSSIBILITY OF SUCH DAMAGE.
;
;**************************************************************************

;**************************************************************************
; Constants
;**************************************************************************

NVECTORS	EQU	64		; max possible interrupt vectors

;* Bits in the Z80 FLAGS register *****************************************

EZ80_C_FLAG	EQU	01h		; Bit 0: Carry flag
EZ80_N_FLAG	EQU	02h		; Bit 1: Add/Subtract flag
EZ80_PV_FLAG	EQU	04h		; Bit 2: Parity/Overflow flag
EZ80_H_FLAG	EQU	10h		; Bit 4: Half carry flag
EZ80_Z_FLAG	EQU	40h		; Bit 5: Zero flag
EZ80_S_FLAG	EQU	80h		; Bit 7: Sign flag

;**************************************************************************
; Global Symbols Imported
;**************************************************************************

	xref	_ez80_startup
	xref	_up_doirq

;**************************************************************************
; Global Symbols Exported
;**************************************************************************

	xdef	_ez80_reset
	xdef	_ez80_initvectors
	xdef	_ez80_handlers
	xdef	_ez80_rstcommon
	xdef	_ez80_initvectors
	xdef	_ez80_vectable

;**************************************************************************
; Macros
;**************************************************************************

; Define one reset handler
;  1. Disable interrupts
;  2. Dlear mixed memory mode (MADL) flag
;  3. jump to initialization procedure with jp.lil to set ADL
rstvector: macro
	di
	rsmix
	jp.lil	_ez80_startup
	endmac	rstvector

; 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_rstcommon		; Remaining RST handling is common
	endmac	irqhandler

;**************************************************************************
; Reset entry points
;**************************************************************************

	define	.RESET, space = ROM
	segment	.RESET

_ez80_reset:
_rst0:
	rstvector
_rst8:
	rstvector
_rst10:
	rstvector
_rst18:
	rstvector
_rst20:
	rstvector
_rst28:
	rstvector
_rst30:
	rstvector
_rst38:
	rstvector
	ds %26
_nmi:
	retn

;**************************************************************************
; Startup logic
;**************************************************************************

	define .STARTUP, space = ROM
	segment .STARTUP
	.assume ADL=1

;**************************************************************************
; Interrupt Vector Handling
;**************************************************************************

_ez80_handlers:
	irqhandler	 0
	handlersize equ $-_ez80handlers
	irqhandler	 1
	irqhandler	 2
	irqhandler	 3
	irqhandler	 4
	irqhandler	 5
	irqhandler	 6
	irqhandler	 7
	irqhandler	 8
	irqhandler	 9
	irqhandler	10
	irqhandler	11
	irqhandler	12
	irqhandler	13
	irqhandler	14
	irqhandler	15
	irqhandler	16
	irqhandler	17
	irqhandler	18
	irqhandler	19
	irqhandler	20
	irqhandler	21
	irqhandler	22
	irqhandler	23
	irqhandler	24
	irqhandler	25
	irqhandler	26
	irqhandler	27
	irqhandler	28
	irqhandler	29
	irqhandler	30
	irqhandler	31
	irqhandler	32
	irqhandler	33
	irqhandler	34
	irqhandler	35
	irqhandler	36
	irqhandler	37
	irqhandler	38
	irqhandler	39
	irqhandler	40
	irqhandler	41
	irqhandler	42
	irqhandler	43
	irqhandler	44
	irqhandler	45
	irqhandler	46
	irqhandler	47
	irqhandler	48
	irqhandler	49
	irqhandler	50
	irqhandler	51
	irqhandler	52
	irqhandler	53
	irqhandler	54
	irqhandler	55
	irqhandler	56
	irqhandler	57
	irqhandler	58
	irqhandler	59
	irqhandler	60
	irqhandler	61
	irqhandler	62
	irqhandler	63

;**************************************************************************
; Common Interrupt handler
;**************************************************************************

_ez80_rstcommon:
	; Create a register frame.  SP points to top of frame + 4, pushes
	; decrement the stack pointer.  Already have
	;
	;   Offset 8: Return PC is already on the stack
	;   Offset 7: AF (retaining flags)
	;
	; IRQ number is in A

	push	hl			; Offset 6: HL
	ld	hl, #(3*3)		;    HL is the value of the stack pointer before
	add	hl, sp			;    the interrupt occurred (3 for PC, AF, HL)
	push	hl			; Offset 5: Stack pointer
	push	iy			; Offset 4: IY
	push	ix			; Offset 3: IX
	push	de			; Offset 2: DE
	push	bc			; Offset 1: BC

	; At this point, we know that interrupts were enabled (or we wouldn't be here
	; so we can save a fake indicationn that will cause interrupts to restored when
	; this context is restored

	ld	bc, #EZ80_PV_FLAG	; Parity bit.  1=parity odd, IEF2=1
	push	bc			; Offset 0: I with interrupt state in carry
	di				; (not necessary)

	; Call the interrupt decode logic. SP points to the beggining of the reg structure

	ld	hl, #0			; Argument #2 is the beginning of the reg structure
	add	hl, sp			;
	push	hl			; Place argument #2 at the top of stack
        ld      bc, #0			; BC = reset number
	ld	c, a			;   Save the reset number in C
	push	bc			; Argument #1 is the Reset number
	call	_up_doirq		; Decode the IRQ

	; On return, HL points to the beginning of the reg structure to restore
	; Note that (1) the arguments pushed on the stack are not popped, and (2) the
	; original stack pointer is lost.  In the normal case (no context switch),
	; HL will contain the value of the SP before the arguments were pushed.

	ld	sp, hl			; Use the new stack pointer

	; Restore registers.  HL points to the beginning of the reg structure to restore

	ex	af, af'			; Select alternate AF
	pop	af			; Offset 0: AF' = I with interrupt state in carry
	ex	af, af'			;   Restore original AF
	pop	bc			; Offset 1: BC
	pop	de			; Offset 2: DE
	pop	ix			; Offset 3: IX
	pop	iy			; Offset 4: IY
	exx				;   Use alternate BC/DE/HL
	pop	hl			; Offset 5: HL' = Stack pointer after return
	exx				;   Restore original BC/DE/HL
	pop	hl			; Offset 6: HL
	pop	af			; Offset 7: AF

	; Restore the stack pointer

	exx				; Use alternate BC/DE/HL
	pop	de			; Offset 8: Return address
	ld	sp, hl			; Set SP = saved stack pointer value before return
	push	de			; Set up for reti
	exx				; Restore original BC/DE/HL

	; Restore interrupt state

	ex	af, af'			; Recover interrupt state
	jp	po, nointenable		; Odd parity, IFF2=0, means disabled
	ex	af, af'			; Restore AF (before enabling interrupts)
	ei				; yes
	reti
nointenable:
	ex	af, af'			; Restore AF
	reti

;**************************************************************************
; Vector Setup Logic
;**************************************************************************

_ez80_initvectors:
	; Initialize the vector table

	ld	iy, _ez80_vectable
	ld	ix, 4
	ld	bc, 4
	ld	b, NVECTORS
	xor	a, a			; Clear carry
	ld	hl, handlersize
	ld	de, _ez80_handlers
	sbc	hl, de			; Length of irq handler in hl
	ld	d, h
	ld	e, l
	ld	hl, _ez80_handlers 	; Start of handlers in hl

	ld	a, 0
$1:
	ld	(iy), hl		; Store IRQ handler
	ld	(iy+3), a		; Pad to 4 bytes
	add	hl, de			; Point to next handler
	push	de
	ld	de, 4
	add	iy, de			; Point to next entry in vector table
	pop	de
	djnz	$1			; Loop until all vectors have been written

	; Select interrupt mode 2

	im	2			; Interrupt mode 2

	; Write the address of the vector table into the interrupt vector base

	ld	hl, _ez80_vectable >> 8
	ld	i, hl
	ret

;**************************************************************************
; Vector Table
;**************************************************************************
; This segment must be aligned on a 512 byte boundary anywhere in RAM
; Each entry will be a 3-byte address in a 4-byte space

	define	.IVECTS, space = RAM, align = 200h
	segment	.IVECTS

	; The first 64 bytes are not used... the vectors actually start at +0x40
_ez80_vecreserve:
	ds	64
_ez80_vectable:
	ds	NVECTORS * 4