kernel/traps.68k
2024-03-19 09:24:10 -05:00

272 lines
7.3 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

include syscall.i
include term.i
include string.i
section .text,text
public traps_init
; Initialize trap handling
traps_init:
move.l #trap_table, a0
movec a0, VBR
rts
generic_handler:
; Read the format/vector word and isolate the interrupt vector
move.w ($6,a7), d0
andi.l #$FF, d0
cmpi.l #$20, d0
; Only the first 32 traps are named, print generic message for the rest
bge.b unk_trap
; Get the pointer to the trap name in a0
lsl.w #2, d0
move.l #trap_name_table, a0
move.l (a0,d0), a0
jsr term_print ; Print it
; Print " Trap"
move.l #trap_string, a0
jsr term_print
; Print where the PC was when the trap occured
move.l ($2,a7), a0
jsr print_pc
; Halt
stop #$2700
unk_trap:
; Print the unknown trap message
move.l #unk_trap_msg, a0
jsr term_print
; Convert the trap number to a hex string
move.w ($6,a7), d0
andi.l #$FF, d0
move.l #string_buffer, a0
jsr hex_to_ascii
; Print it
move.l #string_buffer, a0
jsr term_print
; Print where the PC was when the trap occured
move.l ($2,a7), a0
jsr print_pc
; Halt
stop #$2700
berr_handler:
; Select the correct prefix based on whether the error was in supervisor or user mode
move.w ($8,a7), d0
andi.w #$4, d0
cmpi.w #0, d0
beq.b .1
move.l #berr_supervisor_pfx, a0
bra.b .2
.1:
move.l #berr_user_pfx, a0
.2:
jsr term_print ; Print the prefi
; Print " bus error "
move.l #berr_msg, a0
jsr term_print
; Get the error kind out of the special status word (end up with ins flag, word flag, and write flg in that order, shifted left by 2 and put in d0)
move.l #0, d1
move.w ($8,a7), d0
andi.w #$100, d0
cmpi.w #0, d0
beq.b .3
move.l #$4, d1
.3:
move.w ($8,a7), d0
andi.w #$200, d0
cmpi.w #0, d0
beq.b .4
ori.l #$8, d1
.4:
move.w ($8,a7), d0
andi.w #$2000, d0
cmpi.w #0, d0
beq.b .5
ori.l #$10, d1
.5:
; Get the pointer to the correct message for this kind of bus error in a0
move.l #berr_table, a0
adda.l d1, a0
move.l (a0), a0
jsr term_print ; Print it
; Convert the triggering address to a hex string
move.l ($a,a7), d0
move.l #string_buffer, a0
jsr hex_to_ascii
; Print it
move.l #string_buffer, a0
jsr term_print
; Print where the PC was when the trap occured
move.l ($2,a7), a0
jsr print_pc
stop #$2700
int_vector_handler:
movem.l d0-d7/a0-a6,-(a7)
lea.l (60,a7), a6
; Print "Interrupt Vector "
move.l #int_vector_msg, a0
jsr term_print
; Get the interrupt vector offset
move.w ($6,a6), d0
andi.l #$FF, d0
subi.l #$40, d0
; Convert it to a hex string
move.l #string_buffer, a0
jsr hex_to_ascii
; Print it
move.l #string_buffer, a0
jsr term_println
movem.l (a7)+, d0-d7/a0-a6
rte
user_trap_handler:
movem.l d2-d7/a2-a6,-(a7)
jsr handle_syscall
movem.l (a7)+, d2-d7/a2-a6
rte
; Print " (PC: {a0})\n"
; Clobbers d0, a0, a1, a2
print_pc:
; Print the message up to the first variable
move.l a0, a2
move.l #pc_string_start, a0
jsr term_print
; Convert the PC value to a hex string
move.l a2, d0
move.l #string_buffer, a0
jsr hex_to_ascii
; Print it
move.l #string_buffer, a0
jsr term_print
; Print the rest of the message
move.l #pc_string_end, a0
jsr term_println
rts
section .bss,bss
string_buffer:
ds.b 11
section .data,data
unk_trap_msg: dc.b "Unknown trap ",0
trap_string: dc.b " Trap",0
berr_msg: dc.b "bus error ",0
pc_string_start: dc.b " (PC: ",0
pc_string_end: dc.b ")",0
int_vector_msg: dc.b "Interrupt Vector ",0
user_trap_msg: dc.b "User Trap ",0
berr_supervisor_pfx: dc.b "Supervsior ",0
berr_user_pfx: dc.b "User ",0
align 1
berr_table:
dc.l berr_rdw_msg
dc.l berr_wdw_msg
dc.l berr_rdb_msg
dc.l berr_wdb_msg
dc.l berr_riw_msg
dc.l berr_wiw_msg
dc.l berr_rib_msg
dc.l berr_wib_msg
berr_rdw_msg: dc.b "reading word from ",0
berr_wdw_msg: dc.b "writing word to ",0
berr_rdb_msg: dc.b "reading byte from ",0
berr_wdb_msg: dc.b "writing byte to ",0
berr_riw_msg: dc.b "reading instruction word from ",0
berr_wiw_msg: dc.b "writing instruction word to ",0
berr_rib_msg: dc.b "reading instruction byte from ",0
berr_wib_msg: dc.b "writing instruction byte to ",0
align 1
trap_name_table:
dc.l $0
dc.l $0
dc.l berr_msg
dc.l address_trap_name
dc.l ill_ins_trap_name
dc.l zero_div_trap_name
dc.l chk_ins_trap_name
dc.l trapv_trap_name
dc.l priv_viol_trap_name
dc.l trace_trap_name
dc.l line_1010_emu_trap_name
dc.l line_1111_emu_trap_name
dc.l reserved_trap_name
dc.l reserved_trap_name
dc.l format_error_trap_name
dc.l uninit_int_vect_trap_name
dc.l reserved_trap_name
dc.l reserved_trap_name
dc.l reserved_trap_name
dc.l reserved_trap_name
dc.l reserved_trap_name
dc.l reserved_trap_name
dc.l reserved_trap_name
dc.l reserved_trap_name
dc.l spur_interrupt_trap_name
dc.l lev_1_autovec_trap_name
dc.l lev_2_autovec_trap_name
dc.l lev_3_autovec_trap_name
dc.l lev_4_autovec_trap_name
dc.l lev_5_autovec_trap_name
dc.l lev_6_autovec_trap_name
dc.l lev_7_autovec_trap_name
address_trap_name: dc.b "Address Error",0
ill_ins_trap_name: dc.b "Illegal Instruction",0
zero_div_trap_name: dc.b "Zero Divide",0
chk_ins_trap_name: dc.b "CHK Instruction",0
trapv_trap_name: dc.b "TRAPV Instruction",0
priv_viol_trap_name: dc.b "Privilege Violation",0
trace_trap_name: dc.b "Trace",0
line_1010_emu_trap_name: dc.b "Line 1010 Emulator",0
line_1111_emu_trap_name: dc.b "Line 1111 Emulator",0
reserved_trap_name: dc.b "Reserved",0
format_error_trap_name: dc.b "Format Error",0
uninit_int_vect_trap_name: dc.b "Uninitialized Interrupt Vector",0
spur_interrupt_trap_name: dc.b "Spurious Interrupt",0
lev_1_autovec_trap_name: dc.b "Level 1 Interrupt Autovector",0
lev_2_autovec_trap_name: dc.b "Level 2 Interrupt Autovector",0
lev_3_autovec_trap_name: dc.b "Level 3 Interrupt Autovector",0
lev_4_autovec_trap_name: dc.b "Level 4 Interrupt Autovector",0
lev_5_autovec_trap_name: dc.b "Level 5 Interrupt Autovector",0
lev_6_autovec_trap_name: dc.b "Level 6 Interrupt Autovector",0
lev_7_autovec_trap_name: dc.b "Level 7 Interrupt Autovector",0
align 10
trap_table:
dc.l generic_handler ; Reset initial SSP, should never be called
dc.l generic_handler ; Reset initial PC, should never be called
dc.l berr_handler ; Bus Error
dc.l generic_handler ; Address Error
dc.l generic_handler ; Illegal Instruction
dc.l generic_handler ; Zero Divide
dc.l generic_handler ; CHK Instruction
dc.l generic_handler ; TRAPV Instruction
dc.l generic_handler ; Privilege Violation
dc.l generic_handler ; Trace
dc.l generic_handler ; Line 1010 Emulator
dc.l generic_handler ; Line 1111 Emulator
dc.l generic_handler ; Reserved
dc.l generic_handler ; Reserved
dc.l generic_handler ; Format Error
dc.l generic_handler ; Uninitialized Interrupt Vector
rept 8
dc.l generic_handler ; Reserved
endr
dc.l generic_handler ; Spurious Interrupt
dc.l generic_handler ; Level 1 Interrupt Autovector
dc.l generic_handler ; Level 2 Interrupt Autovector
dc.l generic_handler ; Level 3 Interrupt Autovector
dc.l generic_handler ; Level 4 Interrupt Autovector
dc.l generic_handler ; Level 5 Interrupt Autovector
dc.l generic_handler ; Level 6 Interrupt Autovector
dc.l generic_handler ; Level 7 Interrupt Autovector
rept 16
dc.l user_trap_handler
endr
rept 16
dc.l generic_handler ; Reserved
endr
rept 192
dc.l int_vector_handler
endr