mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-28 10:54:18 +00:00
Upload
Digital Research
This commit is contained in:
@@ -0,0 +1,273 @@
|
||||
title 'Software Interrupt Init & Handlers'
|
||||
|
||||
include system.lib
|
||||
include sysdat.lib
|
||||
|
||||
include flags.equ
|
||||
|
||||
OVEC1 equ 1 * 4 ;; Equates for SID's interrupt vector.
|
||||
SVEC1 equ OVEC1 + 2 ;; They are used during initialization.
|
||||
|
||||
OVEC3 equ 3 * 4
|
||||
SVEC3 equ OVEC3 + 2
|
||||
|
||||
OVECE1 equ 0E1H * 4
|
||||
SVECE1 equ OVECE1 + 2
|
||||
|
||||
LOW_NIBBLE EQU 0FH ;; used by outbyte
|
||||
|
||||
dseg
|
||||
|
||||
extrn debugflag:byte
|
||||
|
||||
cseg
|
||||
|
||||
public nmiint, int_init
|
||||
|
||||
extrn sysdat:word
|
||||
extrn supif:near
|
||||
extrn dispatch:dword
|
||||
extrn pmsg:near
|
||||
|
||||
;;======
|
||||
nmiint:
|
||||
;;======
|
||||
;;
|
||||
;; Non-maskable interrupt handler
|
||||
;;
|
||||
;; This handler sets a flag when an NMI is executed.
|
||||
;; A process is expected to be sleeping on this flag.
|
||||
|
||||
push ds ;; establish a data segment
|
||||
mov ds, sysdat
|
||||
|
||||
mov nmi_ssreg,ss ;; establish a stack
|
||||
mov nmi_spreg,sp
|
||||
mov ss,sysdat
|
||||
mov sp,offset nmi_tos
|
||||
|
||||
push ax ! push bx ;; save the environment
|
||||
push cx ! push dx
|
||||
push di ! push si
|
||||
push bp ! push es
|
||||
|
||||
mov dx, nmi_flag ;; wake up the sleeping NMI
|
||||
mov cl, f_flagset ;; process
|
||||
call supif
|
||||
|
||||
pop es ! pop bp ;; restore the environment
|
||||
pop si ! pop di
|
||||
pop dx ! pop cx
|
||||
pop bx ! pop ax
|
||||
|
||||
mov ss,nmi_ssreg ;; restore the stack
|
||||
mov sp,nmi_spreg
|
||||
|
||||
pop ds ;; restore the data segment
|
||||
|
||||
jmpf cs:dispatch ;; exit through the dispatcher
|
||||
|
||||
eject
|
||||
|
||||
|
||||
int_trap: ;;unknown interrupts go here ...
|
||||
;;-------
|
||||
;;
|
||||
;; We will terminate the process that caused this
|
||||
;; after writing a message to the process's default
|
||||
;; console. If the process is in KEEP mode, we will
|
||||
;; force it to terminate anyway...
|
||||
;;
|
||||
;; We don't need to save any registers since we are
|
||||
;; not going to return to the process.
|
||||
|
||||
mov ds,sysdat
|
||||
;; print first 6 chars of PD Name
|
||||
mov bx,rlr ;; get the PD
|
||||
add bx,p_name ;; get the process name
|
||||
mov byte ptr 6[bx],':' ;; step on the process name
|
||||
mov byte ptr 7[bx],0ffh
|
||||
call pmsg ;; print the first 6 letters
|
||||
|
||||
;; calculate and print the
|
||||
;; Illegal Interrupt message
|
||||
pop ax ;; get the addr of the int 3
|
||||
sub ax,offset int_work + 1 ;; subtract from this addr
|
||||
;; the base of the INT 3 table
|
||||
mov bx,offset int_trpcode ;; point to where the ascii will go
|
||||
call outbyte ;; convert the int number to ascii
|
||||
mov bx,offset int_trp ;; print the message
|
||||
call pmsg
|
||||
;; terminate process
|
||||
mov bx,rlr ;; get the PD
|
||||
and p_flag[bx], not pf_keep ;; turn off the process's keep flag
|
||||
mov cx,f_terminate ;; set the terminate code
|
||||
mov dx,0ffffh ;; free its memory
|
||||
int 224 ;; go to the system
|
||||
|
||||
hlt ;; this instruction should
|
||||
;; never execute
|
||||
|
||||
|
||||
outbyte:
|
||||
;;-------
|
||||
;; ENTRY: al = binary of an unsigned byte
|
||||
;; bx = where to put the ascii
|
||||
;;
|
||||
;; EXIT: [bx] = ascii of high nibble of byte
|
||||
;; [bx+1] = ascii of low nibble of byte
|
||||
|
||||
push ax ;; save the byte
|
||||
mov di, bx ;; save where to put the ascii
|
||||
mov bx, offset xlate_tbl
|
||||
mov cl, 4
|
||||
|
||||
shr al, cl ;; move the high nibble into place
|
||||
xlat xlate_tbl ;; translate the highest nibble
|
||||
mov [di], al ;; stash it, di -> destination
|
||||
inc di ;; next ascii position
|
||||
|
||||
pop ax ;; get the byte back
|
||||
and al, LOW_NIBBLE ;; mask out the upper nibble
|
||||
xlat xlate_tbl ;; tanslate the lower nibble
|
||||
mov [di], al ;; di -> destination
|
||||
|
||||
ret
|
||||
|
||||
eject
|
||||
|
||||
;;========
|
||||
int_init:
|
||||
;;========
|
||||
;;
|
||||
;; Un-initialized interrupt initialization
|
||||
;;
|
||||
|
||||
cli ;; interrupts should be off on entry,but...
|
||||
;; setup an INT 3 for each possible interrupt
|
||||
|
||||
mov cx,256 ;; # of interrupt vectors
|
||||
mov di,offset int_work ;; base of the INT 3 table
|
||||
mov al,0cch ;; opcode for INT 3
|
||||
rep stosb ;; store INT 3 in interrupt table
|
||||
|
||||
push ds ;; Setup all interrupt vectors in low
|
||||
xor ax,ax ;; memory to their respective INT 3 in the INT 3 table
|
||||
mov ds,ax ;; set DS to zero
|
||||
;; save SID's interrupt vectors
|
||||
mov ax, word ptr .OVEC1 ;; vector 1
|
||||
mov es:vec1_off, ax
|
||||
mov ax, word ptr.SVEC1
|
||||
mov es:vec1_seg, ax
|
||||
|
||||
mov ax, word ptr.OVEC3 ;; vector 3
|
||||
mov es:vec3_off, ax
|
||||
mov ax, word ptr.SVEC3
|
||||
mov es:vec3_seg, ax
|
||||
|
||||
mov ax, word ptr.OVECE1 ;; vector E1
|
||||
mov es:vece1_off, ax
|
||||
mov ax, word ptr.SVECE1
|
||||
mov es:vece1_seg, ax
|
||||
|
||||
xor di,di ;; start with vector 0
|
||||
mov bx,offset int_work ;; bx -> base of interrupt 3 table
|
||||
mov cx,256 ;; cx = # of interrupt vectors
|
||||
setint:
|
||||
mov word ptr [di],bx ;; interrupt vector offset
|
||||
mov word ptr 2[di],cs ;; interrupt vector segment (INT 3 table)
|
||||
|
||||
add di,004H ;; next vector
|
||||
inc bx ;; next table entry
|
||||
loop setint ;; initialize all the int vectors ...
|
||||
|
||||
mov word ptr .0008h,offset nmiint
|
||||
mov word ptr .000ah,cs ;; initialize the NMI
|
||||
|
||||
;; if we're in a debugging environment put sids interrupt vectors
|
||||
;; back. If we're not in an interrupt environment then make
|
||||
;; the interrupt 3 vector point to the un-initialized interrupt
|
||||
;; handler.
|
||||
|
||||
test es:debugflag, 002H ;; do we want to put SID'S vector back ?
|
||||
jz set_int_trap ;; no ...
|
||||
|
||||
mov ax, es:vec1_off ;; yes, do vector 1
|
||||
mov word ptr .OVEC1, ax
|
||||
mov ax, es:vec1_seg
|
||||
mov word ptr .SVEC1, ax
|
||||
|
||||
mov ax, es:vec3_off ;; vector 3
|
||||
mov word ptr .OVEC3, ax
|
||||
mov ax, es:vec3_seg
|
||||
mov word ptr .SVEC3, ax
|
||||
|
||||
mov ax, es:vece1_off ;; vector E1
|
||||
mov word ptr .OVECE1, ax
|
||||
mov ax, es:vece1_seg
|
||||
mov word ptr .SVECE1, ax
|
||||
|
||||
jmps intie
|
||||
|
||||
set_int_trap:
|
||||
;; point to our trap.
|
||||
mov word ptr .OVEC3, offset int_trap ;; setup INT 3's offset
|
||||
mov word ptr .SVEC3, cs ;; and segment
|
||||
intie:
|
||||
pop ds ;; restore the data segment
|
||||
ret
|
||||
|
||||
eject
|
||||
|
||||
dseg
|
||||
|
||||
nmi_tos rw 80
|
||||
nmi_ssreg rw 1 ;; nonmaskable interrupt stack
|
||||
nmi_spreg rw 1
|
||||
nmi_instk rb 1
|
||||
|
||||
rw 48 ;; tick's interrupt stack
|
||||
tick_tos rw 0
|
||||
tick_ssreg rw 1
|
||||
tick_spreg rw 1
|
||||
|
||||
;; this translate table is used by outbyte
|
||||
;; to translate from binary to ascii
|
||||
xlate_tbl db '0123456789ABCDEF'
|
||||
|
||||
;; this message is printed by the uninitialized interrupt
|
||||
;; routine.
|
||||
int_trp db ' Uninitialized interrupt, code = 0'
|
||||
int_trpcode db 'xxH',0dh,0ah,0ffh
|
||||
|
||||
|
||||
;; SID's interrupt vectors are stored
|
||||
;; here during initialization.
|
||||
vec1_off dw 0 ;; interrupt vector 1
|
||||
vec1_seg dw 0
|
||||
|
||||
vec3_off dw 0 ;; interrupt vector 3
|
||||
vec3_seg dw 0
|
||||
|
||||
vece1_off dw 0 ;; interrupt vector E1
|
||||
vece1_seg dw 0
|
||||
|
||||
;; scratch area
|
||||
;;
|
||||
dw 0cccch,0cccch,0cccch
|
||||
dw 0cccch,0cccch,0cccch
|
||||
dw 0cccch,0cccch,0cccch
|
||||
dw 0cccch,0cccch,0cccch
|
||||
dw 0cccch,0cccch,0cccch
|
||||
dw 0cccch,0cccch,0cccch
|
||||
dw 0cccch,0cccch,0cccch
|
||||
|
||||
;; Int 3 table for the unintialized interrupts
|
||||
int_work rb 256 ;;interrupt vector routines
|
||||
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user