work on interrupts

This commit is contained in:
Kyle Cardoza 2024-03-30 07:12:35 -04:00
parent 8f36498bf5
commit 9751efd22c
9 changed files with 165 additions and 265 deletions

View File

@ -25,7 +25,7 @@
)
(memory MidRAM
(address (#x00F000 . #x00FDFF))
(address (#x00F000 . #x00FFFF))
(section code)
(section cnear)
(section reset)

View File

@ -37,6 +37,7 @@ CFLAGS += --debug \
-Wno-gnu-case-range \
-Wimplicit-fallthrough \
-Wno-gnu-folding-constant
ASFLAGS += --debug
endif

View File

@ -9,29 +9,3 @@
#include "config.h"
extern void interrupts_init(void);
void set_user_nmi_handler(void (*f)(void));
void set_user_brk_handler(void (*f)(void));
void set_user_cop_handler(void (*f)(void));
void set_user_irq_handler(void (*f)(void));
void set_user_vera_irq_handler(void (*f)(void));
void set_user_t7_handler(void (*f)(void));
void set_user_t6_handler(void (*f)(void));
void set_user_t5_handler(void (*f)(void));
void set_user_t4_handler(void (*f)(void));
void set_user_t3_handler(void (*f)(void));
void set_user_t2_handler(void (*f)(void));
void set_user_t1_handler(void (*f)(void));
void set_user_t0_handler(void (*f)(void));

View File

@ -7,6 +7,10 @@
#define long_a rep #0b00100000
#define short_i sep #0b00010000
#define long_i rep #0b00010000
#ifdef __CALYPSI_CODE_MODEL_SMALL__
#define libcode code

46
src/cop_handler.s Normal file
View File

@ -0,0 +1,46 @@
;;*****************************************************************************
;; Sentinel 65X Kernel
;;
;; src/cop_handler.s
;;*****************************************************************************
#include "macros.h"
.section code
.public cop_handler_native
cop_handler_native:
phb
phd
rep #0b00110000
sta long:tmp_register_a
tsc
sta long:external_stack_pointer
lda long:internal_stack_pointer
tcs
lda long:tmp_register_a
; When we get here, the X register contains the function number.
; A and Y may or may not contain parameters. None of those are
; expected to be preserved. The job here is to ID the function
; being called, marshall any parameters, and call it.
tsc
sta long:internal_stack_pointer
lda long:external_stack_pointer
tcs
pld
plb
rti
.section near
tmp_register_a:
.space 2
external_stack_pointer:
.space 2
internal_stack_pointer:
.space 2

View File

@ -1,113 +0,0 @@
//*****************************************************************************
// Sentinel 65X Kernel
//
// src/interrupts.c
//*****************************************************************************
#include <stddef.h>
#include "config.h"
static void (*user_nmi_handler)(void) = NULL;
static void (*user_brk_handler)(void) = NULL;
static void (*user_cop_handler)(void) = NULL;
static void (*user_irq_handler)(void) = NULL;
static void (*user_vera_irq_handler)(void) = NULL;
static void (*user_t7_handler)(void) = NULL;
static void (*user_t6_handler)(void) = NULL;
static void (*user_t5_handler)(void) = NULL;
static void (*user_t4_handler)(void) = NULL;
static void (*user_t3_handler)(void) = NULL;
static void (*user_t2_handler)(void) = NULL;
static void (*user_t1_handler)(void) = NULL;
static void (*user_t0_handler)(void) = NULL;
void
set_user_nmi_handler(void (*f)(void))
{
user_nmi_handler = f;
}
void
set_user_brk_handler(void (*f)(void))
{
user_brk_handler = f;
}
void
set_user_cop_handler(void (*f)(void))
{
user_cop_handler = f;
}
void
set_user_irq_handler(void (*f)(void))
{
user_irq_handler = f;
}
void
set_user_vera_irq_handler(void (*f)(void))
{
user_vera_irq_handler = f;
}
void
set_user_t7_handler(void (*f)(void))
{
user_t7_handler = f;
}
void
set_user_t6_handler(void (*f)(void))
{
user_t6_handler = f;
}
void
set_user_t5_handler(void (*f)(void))
{
user_t5_handler = f;
}
void
set_user_t4_handler(void (*f)(void))
{
user_t4_handler = f;
}
void
set_user_t3_handler(void (*f)(void))
{
user_t3_handler = f;
}
void
set_user_t2_handler(void (*f)(void))
{
user_t2_handler = f;
}
void
set_user_t1_handler(void (*f)(void))
{
user_t1_handler = f;
}
void
set_user_t0_handler(void (*f)(void))
{
user_t0_handler = f;
}

107
src/interrupts.s Normal file
View File

@ -0,0 +1,107 @@
;;*****************************************************************************
;; Sentinel 65X Kernel
;;
;; src/interrupts.s
;;*****************************************************************************
#include "macros.h"
; -----------------------------------------------------------------------------
irq_enter .macro
phb
phd
rep #0b00110000
sta long:tmp_register_a
tsc
sta long:external_stack_pointer
lda long:internal_stack_pointer
tcs
lda long:tmp_register_a
.endm
irq_exit .macro
tsc
sta long:internal_stack_pointer
lda long:external_stack_pointer
tcs
pld
plb
rti
.endm
; -----------------------------------------------------------------------------
.section near
tmp_register_a:
.space 2
external_stack_pointer:
.space 2
internal_stack_pointer:
.space 2
; -----------------------------------------------------------------------------
.section code
.public interrupts_init
; -----------------------------------------------------------------------------
interrupts_init:
long_a
sei
lda #.near(cop_handler_native)
sta 0x00FFB4
rts
; -----------------------------------------------------------------------------
cop_handler_native:
irq_enter
; When we get here, the X register contains the function number.
; A and Y may or may not contain parameters. None of those are
; expected to be preserved. The job here is just to jump to the
; right handler for the particular function being called, without
; modifying anything but the X register.
; First, we multiply the function number by 2, to get the jump
; table offset.
pha
txa
asl a
tax
pla
; Now, we do an indirect, indexed jump through the jump table.
jsr (cop_jump_table,x)
irq_exit
cop_jump_table:
.word .near(cop_reset)
.word .near(cop_get_version)
; -----------------------------------------------------------------------------
cop_reset:
rts
; -----------------------------------------------------------------------------
.extern version_major, version_minor, version_micro
cop_get_version:
lda long:version_micro
tay
lda long:version_minor
tax
lda long:version_major
rts
; -----------------------------------------------------------------------------

View File

@ -1,125 +0,0 @@
;;*****************************************************************************
;; Sentinel 65X Kernel
;;
;; src/interrupts2.s
;;*****************************************************************************
#include "macros.h"
.section code
.public interrupts_init
.extern _Dp
.extern __program_start
;------------------------------------------------------------------------------
interrupts_init:
sei
; 16 bit a/x
rep #0b00110000
; Set the vector for the IRQ handler.
lda #.near(irq_handler)
sta 0x00FF9E
; Set the vector for the NMI handler.
lda #.near(nmi_handler)
sta 0x00FF9E
; Set the vector for the COP handler.
lda #.near(cop_handler)
sta 0x00FFB4
; Set the vector for the VERA IRQ handler.
lda #.near(vera_irq_handler)
sta 0x00FF98
rts
;------------------------------------------------------------------------------
common_irq_return:
; 16 bit a/x
rep #0b00110000
ply
plx
pla
pld
plb
rti
;------------------------------------------------------------------------------
irq_handler:
phb
phd
; 16 bit a/x
rep #0b00110000
pha
phx
phy
bra common_irq_return
;------------------------------------------------------------------------------
vera_irq_handler:
phb
phd
; 16 bit a/x
rep #0b00110000
pha
phx
phy
bra common_irq_return
;------------------------------------------------------------------------------
nmi_handler:
phb
phd
; 16 bit a/x
rep #0b00110000
pha
phx
phy
bra common_irq_return
;------------------------------------------------------------------------------
cop_handler:
phb
phd
; 16 bit a/x
rep #0b00110000
pha
phx
phy
; COP dispatch here
; Function number comes in X, gets multiplied by 2, then
; used as an index to the jump table.
pha
txa
asl a
tax
pla
jmp (cop_dispatch_table,x)
cop_dispatch_table:
.word .near(cop_reset)
;------------------------------------------------------------------------------
cop_reset:
sei
; 16 bit a/x
rep #0b00110000
jmp long:__program_start

View File

@ -4,11 +4,17 @@
// src/main.c
//*****************************************************************************
#include <stdint.h>
#include "config.h"
#include "interrupts.h"
#include "drivers/vera.h"
const uint16_t version_major = 0;
const uint16_t version_minor = 1;
const uint16_t version_micro = 1;
void
main(void)
{