272 lines
7.3 KiB
Plaintext
272 lines
7.3 KiB
Plaintext
|
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
|