kernel/traps.68k

272 lines
7.3 KiB
Plaintext
Raw Normal View History

2024-03-19 09:23:45 -05:00
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