mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 00:14:25 +00:00
371 lines
7.4 KiB
Plaintext
371 lines
7.4 KiB
Plaintext
;************ biostrap.z8k **************************
|
||
;*
|
||
;* Trap handlers for P-CP/M (tm) BIOS
|
||
;*
|
||
;* 821013 S. Savitzky (Zilog) -- created
|
||
;* 821123 D. Dunlop (Zilog) -- added Olivetti M20-
|
||
;* specific code to invalidate track buffer
|
||
;* contents when disk drive motor stops
|
||
;* (fixes directory-overwrite on disk change)
|
||
;* 830305 D. Sallume (Zilog) -- added FPE trap
|
||
;* code.
|
||
;*
|
||
|
||
__text: .sect
|
||
|
||
;****************************************************
|
||
;*
|
||
;* NOTE
|
||
;* Trap and interrupt handlers are started up
|
||
;* in segmented mode.
|
||
;*
|
||
;****************************************************
|
||
|
||
.input "biosdefs.z8k"
|
||
|
||
|
||
;****************************************************
|
||
;*
|
||
;* Externals
|
||
;*
|
||
;****************************************************
|
||
|
||
.global _bios ;C portion of BIOS
|
||
.global memsc ;memory-management SC
|
||
.global _tbvalid ;disk track buff valid
|
||
.global _tbdirty ;disk track buff is dirty
|
||
|
||
.global _sysseg, _usrseg, _sysstk, _psap
|
||
|
||
;****************************************************
|
||
;*
|
||
;* M-20 ROM scratchpad RAM addresses
|
||
;*
|
||
;****************************************************
|
||
|
||
rtc_ext: .equ 82000022h ;Place to put address
|
||
; of list of functions
|
||
; for each clock tick
|
||
motor_on: .equ 82000020h ;Disk motor timeout
|
||
|
||
;****************************************************
|
||
;*
|
||
;* Global declarations
|
||
;*
|
||
;****************************************************
|
||
|
||
.global _trapinit
|
||
.global _trapvec
|
||
.global _trap
|
||
|
||
.global xfersc
|
||
|
||
;****************************************************
|
||
;*
|
||
;* Trap vector table
|
||
;*
|
||
;* entries 0..31 are misc. system traps
|
||
;* entries 32..47 are system calls 0..15
|
||
;*
|
||
;****************************************************
|
||
|
||
__bss: .sect
|
||
|
||
_trapvec:
|
||
.block NTRAPS*4
|
||
|
||
;****************************************************
|
||
;*
|
||
;* System Call and General Trap Handler And Dispatch
|
||
;*
|
||
;* It is assumed that the system runs
|
||
;* non-segmented on a segmented CPU.
|
||
;*
|
||
;* _trap is jumped to segmented, with the
|
||
;* following information on the stack:
|
||
;*
|
||
;* trap type: WORD
|
||
;* reason: WORD
|
||
;* fcw: WORD
|
||
;* pc: LONG
|
||
;*
|
||
;* The trap handler is called as a subroutine,
|
||
;* with all registers saved on the stack,
|
||
;* IN SEGMENTED MODE. This allows the trap
|
||
;* handler to be in another segment (with some
|
||
;* care). This is useful mainly to the debugger.
|
||
;*
|
||
;* All registers except rr0 are also passed
|
||
;* intact to the handler.
|
||
;*
|
||
;****************************************************
|
||
|
||
__text: .sect
|
||
|
||
sc_trap: ;system call trap server
|
||
|
||
push @r14,@r14
|
||
|
||
|
||
_trap:
|
||
|
||
sub r15,#30 ; push caller state
|
||
ldm @r14,r0,#14
|
||
NONSEG ; go nonsegmented
|
||
ldctl r1,NSP
|
||
ld nr14(r15),r14
|
||
ex r1,nr15(r15)
|
||
|
||
; trap# now in r1
|
||
cpb rh1,#7Fh ; system call?
|
||
jr ne trap_disp ; no
|
||
; yes: map it
|
||
clrb rh1
|
||
add r1,#SC0TRAP
|
||
|
||
;=== need range check ===
|
||
|
||
trap_disp: ; dispatch
|
||
sll r1,#2
|
||
ldl rr0,_trapvec(r1)
|
||
testl rr0
|
||
jr z _trap_ret ; zero -- no action
|
||
; else call seg @rr0
|
||
pushl @r15,rr0 ; (done via kludge)
|
||
SEG
|
||
popl rr0,@r14
|
||
calr trap_1
|
||
jr _trap_ret
|
||
|
||
trap_1: ; jp @rr0
|
||
pushl @r14,rr0
|
||
ret
|
||
|
||
|
||
_trap_ret: ;return from trap or interrupt
|
||
|
||
NONSEG
|
||
ld r1,nr15(r15) ; pop state
|
||
ld r14,nr14(r15)
|
||
ldctl NSP,r1
|
||
SEG ; go segmented for the iret.
|
||
ldm r0,@r14,#14
|
||
add r15,#32
|
||
|
||
iret ; return from interrupt
|
||
|
||
|
||
|
||
;****************************************************
|
||
;*
|
||
;* Assorted Trap Handlers
|
||
;*
|
||
;****************************************************
|
||
|
||
epu_trap:
|
||
push @r14,#EPUTRAP
|
||
jr _trap
|
||
|
||
pi_trap:
|
||
push @r14,#PITRAP
|
||
jr _trap
|
||
|
||
seg_trap:
|
||
push @r14,#SEGTRAP
|
||
jr _trap
|
||
|
||
nmi_trap:
|
||
push @r14,#NMITRAP
|
||
jr _trap
|
||
|
||
|
||
|
||
;****************************************************
|
||
;*
|
||
;* Bios system call handler
|
||
;*
|
||
;****************************************************
|
||
|
||
|
||
;biossc: ;call bios
|
||
; NONSEG
|
||
; ; r3 = operation code
|
||
; ; rr4= P1
|
||
; ; rr6= P2
|
||
;
|
||
; ld r0,scfcw+4(r15) ; if caller nonseg, normal
|
||
; and r0,#0C000h
|
||
; jr nz seg_ok
|
||
;
|
||
; ld r4,scseg+4(r15) ; then add seg to P1, P2
|
||
; ld r6,r4
|
||
;seg_ok:
|
||
; ; set up C stack frame
|
||
;;===
|
||
; pushl @r15,rr6
|
||
; pushl @r15,rr4
|
||
; push @r15,r3
|
||
;
|
||
; ; call C program
|
||
; call _bios
|
||
;
|
||
; ; clean stack & return
|
||
; add r15,#10
|
||
; ldl cr6+4(r15),rr6 ; with long in rr6
|
||
;
|
||
; SEG
|
||
; ret
|
||
;
|
||
|
||
;****************************************************
|
||
;*
|
||
;* Context Switch System Call
|
||
;*
|
||
;* xfer(context)
|
||
;* long context;
|
||
;*
|
||
;* context is the physical (long) address of:
|
||
;* r0
|
||
;* ...
|
||
;* r13
|
||
;* r14 (normal r14)
|
||
;* r15 (normal r15)
|
||
;* ignored word
|
||
;* FCW (had better specify normal mode)
|
||
;* PC segment
|
||
;* PC offset
|
||
;*
|
||
;* The system stack pointer is not affected.
|
||
;*
|
||
;* Control never returns to the caller.
|
||
;*
|
||
;****************************************************
|
||
|
||
xfersc: ;enter here from system call
|
||
SEG
|
||
|
||
; build frame on system stack
|
||
|
||
; when called from system call, the frame replaces
|
||
; the caller's context, which will never be resumed.
|
||
|
||
inc r15,#4 ;discard return addr
|
||
ldl rr4,rr14 ;move context
|
||
ld r2,#FRAMESZ/2
|
||
ldir @r4,@r6,r2
|
||
jr _trap_ret ;restore context
|
||
|
||
|
||
;****************************************************
|
||
;*
|
||
;* _motor_c -- check if disk motor still running.
|
||
;* Entered each clock tick. Invalidates
|
||
;* track buffer when motor stops
|
||
;* (Note: runs segmented)
|
||
;*
|
||
;****************************************************
|
||
|
||
_motor_c:
|
||
ldl rr4,#motor_on ;Motor running?
|
||
test @r4
|
||
ret nz ;Yes: do nothing
|
||
ldar r4,$
|
||
ld r5,#_tbdirty ; Is track buff dirty?
|
||
test @r4 ; Yes...
|
||
ret nz ; ...return without invalidating
|
||
ld r5,#_tbvalid
|
||
clr @r4 ;No: mark track buffer
|
||
ret ; invalid
|
||
|
||
; Table of functions run each real time clock tick
|
||
|
||
_ticktab:
|
||
.long -1 ;Will contain _motor_c
|
||
.word 0ffffh ;Terminator
|
||
|
||
;****************************************************
|
||
;*
|
||
;* _trapinit -- initialize trap system
|
||
;*
|
||
;****************************************************
|
||
|
||
|
||
;*
|
||
;* PSA (Program Status Area) structure
|
||
;*
|
||
ps .equ 8 ; size of a program status entry
|
||
; --- segmented ---
|
||
|
||
psa_epu .equ 1*ps ; EPU trap offset
|
||
psa_prv .equ 2*ps ; priviledged instruction trap
|
||
psa_sc .equ 3*ps ; system call trap
|
||
psa_seg .equ 4*ps ; segmentation trap
|
||
psa_nmi .equ 5*ps ; non-maskable interrupt
|
||
psa_nvi .equ 6*ps ; non-vectored interrupt
|
||
psa_vi .equ 7*ps ; vectored interrupt
|
||
psa_vec .equ psa_vi+(ps/2) ; vectors
|
||
|
||
|
||
_trapinit:
|
||
|
||
; initialize trap table
|
||
|
||
lda r2,_trapvec
|
||
ld r0,#NTRAPS
|
||
subl rr4,rr4
|
||
clrtraps:
|
||
ldl @r2,rr4
|
||
inc r2,#4
|
||
djnz r0,clrtraps
|
||
|
||
ld r2,_sysseg
|
||
; lda r3,biossc
|
||
; ldl _trapvec+(BIOS_SC+SC0TRAP)*4,rr2
|
||
lda r3,memsc
|
||
ldl _trapvec+(MEM_SC+SC0TRAP)*4,rr2
|
||
; lda r3,fp_epu
|
||
; ldl _trapvec+EPUTRAP*4,rr2
|
||
|
||
|
||
; initialize some PSA entries.
|
||
; rr0 PSA entry: FCW (ints ENABLED)
|
||
; rr2 PSA entry: PC
|
||
; rr4 -> PSA slot
|
||
|
||
ldl rr4,_psap
|
||
SEG
|
||
ldl rr0,#0000D800h
|
||
|
||
add r5,#ps ; EPU trap
|
||
ldar r2,epu_trap
|
||
ldm @r4,r0,#4
|
||
|
||
add r5,#ps ; Priviledged Inst
|
||
ldar r2,pi_trap
|
||
ldm @r4,r0,#4
|
||
|
||
add r5,#ps ; System Call
|
||
ldar r2,sc_trap
|
||
ldm @r4,r0,#4
|
||
|
||
add r5,#ps ; segmentation
|
||
ldar r2,seg_trap
|
||
ldm @r4,r0,#4
|
||
|
||
add r5,#ps ; Non-Maskable Int.
|
||
ldar r2,nmi_trap
|
||
ldm @r4,r0,#4
|
||
|
||
; Set up Real-Time Clock external call loc
|
||
|
||
ldar r2,_motor_c
|
||
ldar r4,_ticktab
|
||
ldl @r4,rr2
|
||
ldl rr2,#rtc_ext
|
||
ldl @r2,rr4
|
||
NONSEG
|
||
ret
|
||
|
||
;****************************************************
|
||
;****************************************************
|
||
|