Files
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

371 lines
7.4 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.

;************ 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
;****************************************************
;****************************************************