V7M/sys/conf/mch_ov.s
/ machine language assist
/ (OVERLAY KERNEL VERSION)
/ for non-separate I & D space CPU's
/ 11/23, 11/24, 11/34, 11/40, & 11/60 CPUs
/ Fred Canter 8/3/81
/
/ Many thanks to Bill Shannon for the overlay kernel modifications.
/
/ *******************************************************
/ * *
/ * The overlay kernel must be booted via the *
/ * two - stage (standalone) bootstrap code. *
/ * *
/ *******************************************************
/
/ The TS11 vector is autoconfigured, see comments
/ in code below, just prior to calling main().
/
/ The concept of cputype is now defunct,
/ instead the cpu is described by the hardware
/ features present, i.e., unibus map, display register,
/ rh70 controller, and separate I & D space.
/
/ Enable memory parity error traps thru 114
/ Parameter for code size reduction,
/ .fpp in mch0.s header file.
/ non-UNIX instructions
mfpi = 6500^tst
mtpi = 6600^tst
ldfps = 170100^tst
svfps = 170200^tst
stst = 170300^tst
halt = 0
wait = 1
reset = 5
rtt = 6
.globl start, _end, _edata, _main, dump
.globl ovend, ova, ovd
/ Mag tape dump
/ save registers in locore and
/ write all core onto mag tape.
/ entry thru 1000 abs
/ ***************************************
/ * *
/ * The core dump code must be *
/ * the first code in this file. *
/ * *
/ ***************************************
dump:
1:
bit $1,SSR0
bne 1b
/ save regs r0,r1,r2,r3,r4,r5,r6,KIA6
/ starting at abs location 4
inc $-1 / save reg's on first core
bne 1f / dump attempt only.
mov r0,4
mov $6,r0
mov r1,(r0)+
mov r2,(r0)+
mov r3,(r0)+
mov r4,(r0)+
mov r5,(r0)+
mov sp,(r0)+
mov KISA6,(r0)+
1:
/ dump all of core (ie to first mt error)
/ onto mag tape. (9 track or 7 track 'binary')
/ The core dump tape hardware addresses are
/ defined in the mch0.s header file.
.if HTDUMP
/register usage is as follows
/reg 0 holds the CSR address for the tm02/3.
/reg 1 points to UBMAP register 0 low
/reg 2 is used to contain and calculate memory pointer
/ for UBMAP register 0 low
/reg 3 is used to contain and calculate memory pointer
/ for UBMAP register 0 high
/reg 4, r4 = 1 for map used, r4 = 0 for map not used.
/reg 5 is used as an interation counter when mapping is enabled
clr r4 /clear map used indicator
/ cmp _cputype,$44. /is a 44 ?
/ bne 2f /no, UBMAP not used
tst _ubmaps /unibus map present ?
beq 2f /no
tst _rh70ht /yes, rh70 controller ?
bne 2f /yes, don't need to use unibus map
/no, will use map
/this section of code initializes the Unibus map registers
/and the memory management registers.
/UBMAP reg 0 gets updated to point to the current
/memory area.
/Kernal I space 0 points to low memory
/Kernal I space 7 points to the I/O page.
inc r4 /indicate that UB mapping is needed
mov $UBMR0,r1 /point to map register 0
clr r2 /init for low map reg
clr r3 /init for high map reg
mov $77406,*$KISD0 /set KISDR0
mov $77406,*$KISD7 /set KISDR7
clr *$KISA0 /point KISAR0 to low memory
mov $IO,*$KISA7 /point KISAR7 to IO page
inc *$SSR0 /turn on memory mngt
mov $60,*$SSR3 /enable 22 bit mapping
mov r2,(r1) /load map reg 0 low
mov r3,2(r1) /load map reg 0 high
2:
/this section of code initializes the TM02/3
mov $HTCS1,r0 /get tm02/3 CSR addr
mov $40,10(r0) /tm02/3 subsystem clear
mov $1300,32(r0) /800 BPI + pdp11 mode
clr 4(r0) /clear unibus address
mov $1,(r0) /nop command to tm02/3
mov $20,r5 /set up SOB counter for UBMAP
/This section does the write.
/ if mapping is needed the sob loop comes in play here
/ when the sob falls through the UBAMP reg will be
/ updated by 20000 to point to next loop section.
/ if mapping not needed then just let the
/ hardware address registers increment.
3:
mov $-512.,6(r0) /set frame count
mov $-256.,2(r0) /set word count
movb $61,(r0) /set write comand + go
/set ext. mem. bits to 0
1:
tstb (r0) /wait for tm02/3 ready
bge 1b
bit $1,(r0) /wait for go bit clear
bne 1b
bit $40000,(r0) /any error ?
beq 2f /no, continue xfer
bit $4000,10(r0) /yes, must be MXM error
beq . /hang here if not NXM
mov $27,(r0) /error is NXM, write EOF
halt /halt on good dump !
2:
tst r4 /mapping?
beq 3b /branch if not
sob r5,3b /yes continue loop
mov $20,r5 /reset loop count
add $20000,r2 /bump low map
adc r3 /carry to high map
mov r2,(r1) /load map reg 0 low
mov r3,2(r1) /load map reg 0 high
clr 4(r0) /set bus addr to 0
br 3b /do some more
.endif
.if TUDUMP
/register useage is as follows
/reg 0 holds the tm11 CSR address
/reg 1 points to UBMAP register 0 low
/reg 2 is used to contain and calculate memory pointer
/ for UBMAP register 0 low
/reg 3 is used to contain and calculate memory pointer
/ for UBMAP register 0 high
/reg 4, r4 = 1 for map used, r4 = 0 for map not used.
/reg 5 is used as an interation counter when mapping is enabled
clr r4 /clear UB map used indicator
/ cmp _cputype,$44. /is a 44 ?
/ beq 1f /yes, skip next
/ cmp _cputype,$70. /is a 70 ?
/ bne 2f /not a 70 either. no UBMAP
/1:
tst _ubmaps /unibus map present ?
beq 2f /no, skip map init
/this section of code initializes the Unibus map registers
/and the memory management registers.
/UBMAP reg 0 gets updated to point to the current
/memory area.
/Kernal I space 0 points to low memory
/Kernal I space 7 points to the I/O page.
inc r4 /indicate that UB mapping is needed
mov $UBMR0,r1 /point to map register 0
clr r2 /init for low map reg
clr r3 /init for high map reg
mov $77406,*$KISD0 /set KISDR0
mov $77406,*$KISD7 /set KISDR7
clr *$KISA0 /point KISAR0 to low memory
mov $IO,*$KISA7 /point KISAR7 to IO page
inc *$SSR0 /turn on memory mngt
mov $60,*$SSR3 /enable 22 bit mapping
mov r2,(r1) /load map reg 1 low
mov r3,2(r1) /load map reg 1 high
2:
/this section of code initializes the TM11
mov $MTC,r0 /get tm11 CSR address
mov $60004,(r0) /write command, no go
clr 4(r0) /set bus addr to 0
mov $20,r5 /set up SOB counter for UBMAP
/This section does the write.
/ if mapping is needed the sob loop comes in play here
/ when the sob falls through the UBAMP reg will be
/ updated by 20000 to point to next loop section.
/ if mapping not needed then just let
/ bus address register increment.
3:
mov $-512.,2(r0) /set byte count
inc (r0) /start xfer
1:
tstb (r0) /wait for tm11 ready
bge 1b
tst (r0) /any error ?
bge 2f /no, continue xfer
bit $200,-2(r0) /yes, must be NXM error
beq . /hang if not NXM error
reset /error is NXM,
mov $60007,(r0) /write EOF
halt /halt on good dump
2:
tst r4 /mapping?
beq 3b /branch if not
sob r5,3b /yes continue loop
mov $20,r5 /reset loop count
add $20000,r2 /bump low map
adc r3 /carry to high map
mov r2,(r1) /load map reg 0 low
mov r3,2(r1) /load map reg 0 high
clr 4(r0) /set bus address to 0
br 3b /do some more
.endif
.if TSDUMP
/register useage is as follows
/reg 0 points to UBMAP register 1 low
/reg 1 is used to calculate the current memory address
/ for each 512 byte transfer.
/reg 2 is used to contain and calculate memory pointer
/ for UBMAP register 1 low
/reg 3 is used to contain and calculate memory pointer
/ for UBMAP register 1 high
/reg 4 points to the command packet
/reg 5 is used as an interation counter when mapping is enabled
/ cmp _cputype,$44. /is a 44 ?
/ beq 1f /yes, skip next
/ cmp _cputype,$70. /is a 70 ?
/ bne 2f /not a 70 either. no UBMAP
/1:
tst _ubmaps /unibus map present ?
beq 2f /no, skip map init
/this section of code initializes the Unibus map registers
/and the memory management registers.
/UBMAP reg 0 points to low memory for the TS11 command,
/characteristics, and message buffers.
/UBMAP reg 1 gets updated to point to the current
/memory area.
/Kernal I space 0 points to low memory
/Kernal I space 7 points to the I/O page.
inc setmap /indicate that UB mapping is needed
mov $UBMR0,r0 /point to map register 0
clr r2 /init for low map reg
clr r3 /init for high map reg
clr (r0)+ /load map reg 0 low
clr (r0)+ /load map reg 0 high
mov $77406,*$KISD0 /set KISDR0
mov $77406,*$KISD7 /set KISDR7
clr *$KISA0 /point KISAR0 to low memory
mov $IO,*$KISA7 /point KISAR7 to IO page
inc *$SSR0 /turn on memory mngt
mov $60,*$SSR3 /enable 22 bit mapping
mov r2,(r0) /load map reg 1 low
mov r3,2(r0) /load map reg 1 high
2:
/this section of code initializes the TS11
tstb *$TSSR /make sure
bpl 2b /drive is ready
mov $comts,r4 /point to command packet
add $2,r4 /set up mod 4
bic $3,r4 /alignment
mov $140004,(r4) /write characteristics command
mov $chrts,2(r4) /characteristics buffer
clr 4(r4) /clear ext mem addr (packet)
clr tsxma /clear extended memory save loc
mov $10,6(r4) /set byte count for command
mov $mests,*$chrts /show where message buffer is
clr *$chrts+2 /clear extended memory bits here too
mov $16,*$chrts+4 /set message buffer length
mov r4,*$TSDB /start command
mov $20,r5 /set up SOB counter for UBMAP
clr r1 /init r1 beginning memory address
1:
tstb *$TSSR /wait for ready
bpl 1b /not yet
mov *$TSSR,tstcc /error condition (SC) ?
bpl 2f /no error
bic $!16,tstcc /yes error, get TCC
cmp tstcc,$10 /recoverable error ?
bne 8f /no
mov $101005,(r4) /yes, load write data retry command
clr 4(r4) /clear packet ext mem addr
mov r4,*$TSDB /start retry
br 1b
8:
bit $4000,*$TSSR /is error NXM ?
beq . /no, hang (not sure of good dump)
mov $140013,(r4) /load a TS init command
mov r4,*$TSDB /to clear NXM error
6:
tstb *$TSSR /wait for ready
bpl 6b
mov $1,6(r4) /set word count = 1
mov $100011,(r4) /load write EOF command
mov r4,*$TSDB /do write EOF
7:
tstb *$TSSR /wait for ready
bpl 7b
halt /halt after good dump
9:
br 1b
2:
/If mapping is needed this section calculates the
/ base address to be loaded into map reg 1
/ the algorithm is (!(r5 - 21))*1000) | 20000
/ the complement is required because an SOB loop
/ is being used for the counter
/This loop causes 20000 bytes to be written
/before the UBMAP is updated.
tst setmap /UBMAP ?
beq 3f /no map
mov r2,(r0) /load map reg 1 low
mov r3,2(r0) /load map reg 1 high
mov r5,r1 /calculate
sub $21,r1 /address for this pass
com r1 /based on current
mul $1000,r1 /interation
bis $20000,r1 /select map register 1
clr 4(r4) /clear extended memory bits
3:
/This section does the write.
/ if mapping is needed the sob loop comes in play here
/ when the sob falls through the UBAMP reg will be
/ updated by 20000 to point to next loop section.
/ if mapping not needed then just calculate the
/ next 512 byte address pointer
mov r1,2(r4) /load mem address
mov tsxma,4(r4) /load ext mem address
mov $512.,6(r4) /set byte count
mov $100005,(r4) /set write command
mov r4,*$TSDB /initiate xfer
tst setmap /mapping?
beq 4f /branch if not
sob r5,9b /yes continue loop
mov $20,r5 /reset loop count
add $20000,r2 /bump low map
adc r3 /carry to high map
br 1b /do some more
4:
add $512.,r1 /bump address for no mapping
adc tsxma /carry to extended memory bits
br 1b /do again
.endif
1:
halt / halt if no core dump code
br 1b / included in this monitor
start:
bit $1,*$SSR0 / Insure memory management enabled !
beq . / Hang if not !
mov $trap,34
/ Set location 0 and 2 to catch traps and jumps to 0,
/ same for locations 40 and 42.
mov $42,0 / illegal instruction if jump
mov $777,2 / trace trap at high priority if trap
mov $42,40
mov $777,42
/ initialize user segment
mov ovend,KISA6 / ksr6 = sysu
mov $usize-1\<8|6,KISD6
/ get a sp
mov $_u+[usize*64.],sp
/ clear bss
mov $_edata,r0
1:
clr (r0)+
cmp r0,$_end
blo 1b
.if .fpp
/ test for floating point
mov $1f,nofault
setd / jumps to 1f if no fpu
inc fpp
1:
.endif
mov $1f,nofault
tst *$UBMR0 / unibus map present ?
inc _ubmaps / yes, remember it
mov $20,*$SSR3 / also set 22 bit mapping
1:
clr nofault
/ clear user block
mov $_u,r0
1:
clr (r0)+
cmp r0,$_u+[usize*64.]
blo 1b
/ Set up the TS11 interrupt vector
/
/ (mkconf) sets the TS11 vector to 050.
/ The following code copies the vector
/ from 050 to 0224 if the TS11 is the only
/ tape on the system or to 0260 if there
/ is also a TM11 on the system.
/ If the vector at 260 is used, the code halts.
/ This allows the TS11 and TM11 to coexist
/ on the same system, see the comments in the
/ TS11 driver "/sys/dev/ts.c" for more on this
/ strangeness.
mov $50,r0 / pointer to TS11 vector
mov $224,r1 / pointer to first choice
tst 2(r0) / is TS11 configured ?
beq 1f / no, don't copy vector
tst *$226 / yes, is vector at 224 used (TM11) ?
beq 2f / no, copy vector to 0224
tst *$262 / yes, is vector at 260 used ?
beq 3f / no, copy vector to 0260
halt / yes, something is very wrong - HALT !
3:
mov $260,r1 / pointer to second choice
2:
mov (r0)+,(r1)+ / copy vector address
mov (r0)+,(r1)+ / copy new psw
clr -(r0) / clear loc 052
clr -(r0) / clear loc 050
1:
/ load all unused vector locations with the
/ same vector/jump catchers loaded into
/ locations 0 and 2 at start.
mov $40,r0
2:
tst (r0)+
tst (r0)+
3:
tst 2(r0)
bne 2b
mov $42,(r0)+
mov $777,(r0)+
cmp r0,$1000
blt 3b
/ set up previous mode and call main
/ on return, enter user mode at 0R
mov $30000,PS
jsr pc,_main
mov $170000,-(sp)
clr -(sp)
rtt
.globl trap, call
.globl _trap
/ all traps and interrupts are
/ vectored thru this routine.
trap:
mov PS,saveps
tst nofault
bne 1f
mov SSR0,ssr
mov SSR2,ssr+4
mov $1,SSR0
jsr r0,call1; jmp _trap
/ no return
1:
mov $1,SSR0
mov nofault,(sp)
rtt
.text
.globl _runrun
call1:
mov saveps,-(sp)
bic $HIPRI,PS
br 1f
call:
mov PS,-(sp)
1:
/ the following code shuffles the stack so that the overlay number
/ is saved higher on the stack than the other state information.
/ this is so that the C versions of trap, etc. don't have to be
/ changed when running with an overlayed kernel.
mov (sp),-(sp) / move down nps
mov 4(sp),2(sp) / move down r0
mov 6(sp),4(sp) / move down pc
mov 8.(sp),6(sp) / move down ps
mov __ovno,8.(sp) / save overlay number
mov r1,-(sp)
mfpi sp
mov 4(sp),-(sp)
bic $!37,(sp)
bit $30000,PS
beq 1f
jsr pc,(r0)+
tstb _runrun
beq 2f
mov $12.,(sp) / trap 12 is give up cpu
jsr pc,_trap
2:
tst (sp)+
mtpi sp
br 2f
1:
bis $30000,PS
jsr pc,(r0)+
cmp (sp)+,(sp)+
2:
/ restore previous overlay number and mapping.
/ unshuffle stack.
mov 10.(sp),r0 / get saved overlay number
mov PS,-(sp) / save PS
bis $HIPRI,PS / mask all interrupts
mov r0,__ovno
asl r0
mov ova(r0),KISA2
mov ovd(r0),KISD2
mov (sp)+,PS / restore PS, unmask interrupts
mov 8.(sp),10.(sp) / move ps up
mov 6.(sp),8.(sp) / move pc up
mov (sp)+,r1
tst (sp)+
mov (sp)+,r0
tst (sp)+
rtt
.globl _savfp
_savfp:
.if .fpp
tst fpp
beq 8f
mov 2(sp),r1
stfps (r1)+
setd
movf fr0,(r1)+
movf fr1,(r1)+
movf fr2,(r1)+
movf fr3,(r1)+
movf fr4,fr0
movf fr0,(r1)+
movf fr5,fr0
movf fr0,(r1)+
8:
.endif
rts pc
.globl _restfp
_restfp:
.if .fpp
tst fpp
beq 8f
mov 2(sp),r1
mov r1,r0
setd
add $8.+2.,r1
movf (r1)+,fr1
movf (r1)+,fr2
movf (r1)+,fr3
movf (r1)+,fr0
movf fr0,fr4
movf (r1)+,fr0
movf fr0,fr5
movf 2(r0),fr0
ldfps (r0)
8:
.endif
rts pc
/ save floating point error registers
/ argument is a pointer to a two-word
/ structure
.globl _stst
_stst:
.if .fpp
tst fpp
beq 9f
stst *2(sp)
9:
.endif
rts pc
.globl _addupc
_addupc:
mov r2,-(sp)
mov 6(sp),r2 / base of prof with base,leng,off,scale
mov 4(sp),r0 / pc
sub 4(r2),r0 / offset
clc
ror r0
mov 6(r2),r1
clc
ror r1
mul r1,r0 / scale
ashc $-14.,r0
inc r1
bic $1,r1
cmp r1,2(r2) / length
bhis 1f
add (r2),r1 / base
mov nofault,-(sp)
mov $2f,nofault
mfpi (r1)
add 12.(sp),(sp)
mtpi (r1)
br 3f
2:
clr 6(r2)
3:
mov (sp)+,nofault
1:
mov (sp)+,r2
rts pc
.globl _display
_display:
rts pc
/ Character list get/put
/.globl _getc, _putc
/.globl _cfreelist
/
/_getc:
/ mov 2(sp),r1
/ mov PS,-(sp)
/ mov r2,-(sp)
/ bis $HIPRI,PS
/ bic $40,PS
/ mov 2(r1),r2 / first ptr
/ beq 9f / empty
/ movb (r2)+,r0 / character
/ bic $!377,r0
/ mov r2,2(r1)
/ dec (r1)+ / count
/ bne 1f
/ clr (r1)+
/ clr (r1)+ / last block
/ br 2f
/1:
/ bit $7,r2
/ bne 3f
/ mov -10(r2),(r1) / next block
/ add $2,(r1)
/2:
/ dec r2
/ bic $7,r2
/ mov _cfreelist,(r2)
/ mov r2,_cfreelist
/3:
/ mov (sp)+,r2
/ mov (sp)+,PS
/ rts pc
/9:
/ clr 4(r1)
/ mov $-1,r0
/ mov (sp)+,r2
/ mov (sp)+,PS
/ rts pc
/
/_putc:
/ mov 2(sp),r0
/ mov 4(sp),r1
/ mov PS,-(sp)
/ mov r2,-(sp)
/ mov r3,-(sp)
/ bis $HIPRI,PS
/ bic $40,PS
/ mov 4(r1),r2 / last ptr
/ bne 1f
/ mov _cfreelist,r2
/ beq 9f
/ mov (r2),_cfreelist
/ clr (r2)+
/ mov r2,2(r1) / first ptr
/ br 2f
/1:
/ bit $7,r2
/ bne 2f
/ mov _cfreelist,r3
/ beq 9f
/ mov (r3),_cfreelist
/ mov r3,-10(r2)
/ mov r3,r2
/ clr (r2)+
/2:
/ movb r0,(r2)+
/ mov r2,4(r1)
/ inc (r1) / count
/ clr r0
/ mov (sp)+,r3
/ mov (sp)+,r2
/ mov (sp)+,PS
/ rts pc
/9:
/ mov pc,r0
/ mov (sp)+,r3
/ mov (sp)+,r2
/ mov (sp)+,PS
/ rts pc
.globl _backup
.globl _regloc
_backup:
mov 2(sp),ssr+2
mov r2,-(sp)
jsr pc,backup
mov r2,ssr+2
mov (sp)+,r2
movb jflg,r0
bne 2f
mov 2(sp),r0
movb ssr+2,r1
jsr pc,1f
movb ssr+3,r1
jsr pc,1f
movb _regloc+7,r1
asl r1
add r0,r1
mov ssr+4,(r1)
clr r0
2:
rts pc
1:
mov r1,-(sp)
asr (sp)
asr (sp)
asr (sp)
bic $!7,r1
movb _regloc(r1),r1
asl r1
add r0,r1
sub (sp)+,(r1)
rts pc
/ hard part
/ simulate the ssr2 register missing on 11/40
backup:
clr r2 / backup register ssr1
mov $1,bflg / clrs jflg
mov ssr+4,r0
jsr pc,fetch
mov r0,r1
ash $-11.,r0
bic $!36,r0
jmp *0f(r0)
0: t00; t01; t02; t03; t04; t05; t06; t07
t10; t11; t12; t13; t14; t15; t16; t17
t00:
clrb bflg
t10:
mov r1,r0
swab r0
bic $!16,r0
jmp *0f(r0)
0: u0; u1; u2; u3; u4; u5; u6; u7
u6: / single op, m[tf]pi, sxt, illegal
bit $400,r1
beq u5 / all but m[tf], sxt
bit $200,r1
beq 1f / mfpi
bit $100,r1
bne u5 / sxt
/ simulate mtpi with double (sp)+,dd
bic $4000,r1 / turn instr into (sp)+
br t01
/ simulate mfpi with double ss,-(sp)
1:
ash $6,r1
bis $46,r1 / -(sp)
br t01
u4: / jsr
mov r1,r0
jsr pc,setreg / assume no fault
bis $173000,r2 / -2 from sp
rts pc
t07: / EIS
clrb bflg
u0: / jmp, swab
u5: / single op
f5: / movei, movfi
ff1: / ldfps
ff2: / stfps
ff3: / stst
mov r1,r0
br setreg
t01: / mov
t02: / cmp
t03: / bit
t04: / bic
t05: / bis
t06: / add
t16: / sub
clrb bflg
t11: / movb
t12: / cmpb
t13: / bitb
t14: / bicb
t15: / bisb
mov r1,r0
ash $-6,r0
jsr pc,setreg
swab r2
mov r1,r0
jsr pc,setreg
/ if delta(dest) is zero,
/ no need to fetch source
bit $370,r2
beq 1f
/ if mode(source) is R,
/ no fault is possible
bit $7000,r1
beq 1f
/ if reg(source) is reg(dest),
/ too bad.
mov r2,-(sp)
bic $174370,(sp)
cmpb 1(sp),(sp)+
beq u7
/ start source cycle
/ pick up value of reg
mov r1,r0
ash $-6,r0
bic $!7,r0
movb _regloc(r0),r0
asl r0
add ssr+2,r0
mov (r0),r0
/ if reg has been incremented,
/ must decrement it before fetch
bit $174000,r2
ble 2f
dec r0
bit $10000,r2
beq 2f
dec r0
2:
/ if mode is 6,7 fetch and add X(R) to R
bit $4000,r1
beq 2f
bit $2000,r1
beq 2f
mov r0,-(sp)
mov ssr+4,r0
add $2,r0
jsr pc,fetch
add (sp)+,r0
2:
/ fetch operand
/ if mode is 3,5,7 fetch *
jsr pc,fetch
bit $1000,r1
beq 1f
bit $6000,r1
bne fetch
1:
rts pc
t17: / floating point instructions
clrb bflg
mov r1,r0
swab r0
bic $!16,r0
jmp *0f(r0)
0: f0; f1; f2; f3; f4; f5; f6; f7
f0:
mov r1,r0
ash $-5,r0
bic $!16,r0
jmp *0f(r0)
0: ff0; ff1; ff2; ff3; ff4; ff5; ff6; ff7
f1: / mulf, modf
f2: / addf, movf
f3: / subf, cmpf
f4: / movf, divf
ff4: / clrf
ff5: / tstf
ff6: / absf
ff7: / negf
inc fflg
mov r1,r0
br setreg
f6:
bit $400,r1
beq f1 / movfo
br f5 / movie
f7:
bit $400,r1
beq f5 / movif
br f1 / movof
ff0: / cfcc, setf, setd, seti, setl
u1: / br
u2: / br
u3: / br
u7: / illegal
incb jflg
rts pc
setreg:
mov r0,-(sp)
bic $!7,r0
bis r0,r2
mov (sp)+,r0
ash $-3,r0
bic $!7,r0
movb 0f(r0),r0
tstb bflg
beq 1f
bit $2,r2
beq 2f
bit $4,r2
beq 2f
1:
cmp r0,$20
beq 2f
cmp r0,$-20
beq 2f
asl r0
2:
tstb fflg
beq 3f
asl r0
stfps r1
bit $200,r1
beq 3f
asl r0
3:
bisb r0,r2
rts pc
0: .byte 0,0,10,20,-10,-20,0,0
fetch:
bic $1,r0
mov nofault,-(sp)
mov $1f,nofault
mfpi (r0)
mov (sp)+,r0
mov (sp)+,nofault
rts pc
1:
mov (sp)+,nofault
clrb r2 / clear out dest on fault
mov $-1,r0
rts pc
.bss
bflg: .=.+1
jflg: .=.+1
fflg: .=.+1
.text
.globl _fubyte, _subyte
.globl _fuibyte, _suibyte
.globl _fuword, _suword
.globl _fuiword, _suiword
_fuibyte:
_fubyte:
mov 2(sp),r1
bic $1,r1
jsr pc,gword
cmp r1,2(sp)
beq 1f
swab r0
1:
bic $!377,r0
rts pc
_suibyte:
_subyte:
mov 2(sp),r1
bic $1,r1
jsr pc,gword
mov r0,-(sp)
cmp r1,4(sp)
beq 1f
movb 6(sp),1(sp)
br 2f
1:
movb 6(sp),(sp)
2:
mov (sp)+,r0
jsr pc,pword
clr r0
rts pc
_fuiword:
_fuword:
mov 2(sp),r1
fuword:
jsr pc,gword
rts pc
gword:
mov PS,-(sp)
bis $HIPRI,PS
mov nofault,-(sp)
mov $err,nofault
mfpi (r1)
mov (sp)+,r0
br 1f
_suiword:
_suword:
mov 2(sp),r1
mov 4(sp),r0
suword:
jsr pc,pword
rts pc
pword:
mov PS,-(sp)
bis $HIPRI,PS
mov nofault,-(sp)
mov $err,nofault
mov r0,-(sp)
mtpi (r1)
1:
mov (sp)+,nofault
mov (sp)+,PS
rts pc
err:
mov (sp)+,nofault
mov (sp)+,PS
tst (sp)+
mov $-1,r0
rts pc
.globl _copyin, _copyout
.globl _copyiin, _copyiout
_copyiin:
_copyin:
jsr pc,copsu
1:
mfpi (r0)+
mov (sp)+,(r1)+
sob r2,1b
br 2f
_copyiout:
_copyout:
jsr pc,copsu
1:
mov (r0)+,-(sp)
mtpi (r1)+
sob r2,1b
2:
mov (sp)+,nofault
mov (sp)+,r2
clr r0
rts pc
copsu:
mov (sp)+,r0
mov r2,-(sp)
mov nofault,-(sp)
mov r0,-(sp)
mov 10(sp),r0
mov 12(sp),r1
mov 14(sp),r2
asr r2
mov $1f,nofault
rts pc
1:
mov (sp)+,nofault
mov (sp)+,r2
mov $-1,r0
rts pc
.globl _idle, _waitloc
_idle:
mov PS,-(sp)
bic $HIPRI,PS
wait
waitloc:
mov (sp)+,PS
rts pc
.data
_waitloc:
waitloc
.text
.globl _save
_save:
mov (sp)+,r1
mov (sp),r0
mov r2,(r0)+
mov r3,(r0)+
mov r4,(r0)+
mov r5,(r0)+
mov sp,(r0)+
mov __ovno,(r0)+
mov r1,(r0)+
clr r0
jmp (r1)
.globl _resume
_resume:
mov 2(sp),r0 / new process
mov 4(sp),r1 / new stack
bis $HIPRI,PS
mov r0,KISA6 / In new process
mov (r1)+,r2
mov (r1)+,r3
mov (r1)+,r4
mov (r1)+,r5
mov (r1)+,sp
mov (r1)+,r0
mov r0,__ovno
asl r0
mov ova(r0),KISA2
mov ovd(r0),KISD2
mov $1,r0
bic $HIPRI,PS
jmp *(r1)+
.globl _spl0, _spl1, _spl4, _spl5, _spl6, _spl7, _splx
_spl0:
mov PS,r0
bic $HIPRI,PS
rts pc
_spl1:
mov PS,r0
bis $HIPRI,PS
bic $300,PS
rts pc
_spl4:
mov PS,r0
bis $HIPRI,PS
bic $140,PS
rts pc
_spl5:
mov PS,r0
bis $HIPRI,PS
bic $100,PS
rts pc
_spl6:
mov PS,r0
bis $HIPRI,PS
bic $40,PS
rts pc
_spl7:
mov PS,r0
bis $HIPRI,PS
rts pc
_splx:
mov 2(sp),PS
rts pc
.globl _copyseg
_copyseg:
mov PS,-(sp)
mov UISA0,-(sp)
mov UISA1,-(sp)
mov $30340,PS
mov 10(sp),UISA0
mov 12(sp),UISA1
mov UISD0,-(sp)
mov UISD1,-(sp)
mov $6,UISD0
mov $6,UISD1
mov r2,-(sp)
clr r0
mov $8192.,r1
mov $32.,r2
1:
mfpi (r0)+
mtpi (r1)+
sob r2,1b
mov (sp)+,r2
mov (sp)+,UISD1
mov (sp)+,UISD0
mov (sp)+,UISA1
mov (sp)+,UISA0
mov (sp)+,PS
rts pc
.globl _clearseg
_clearseg:
mov PS,-(sp)
mov UISA0,-(sp)
mov $30340,PS
mov 6(sp),UISA0
mov UISD0,-(sp)
mov $6,UISD0
clr r0
mov $32.,r1
1:
clr -(sp)
mtpi (r0)+
sob r1,1b
mov (sp)+,UISD0
mov (sp)+,UISA0
mov (sp)+,PS
rts pc
/ Long quotient
.globl ldiv
ldiv:
jsr r5,csv
mov 10.(r5),r3
sxt r4
bpl 1f
neg r3
1:
cmp r4,8.(r5)
bne hardldiv
mov 6.(r5),r2
mov 4.(r5),r1
bge 1f
neg r1
neg r2
sbc r1
com r4
1:
mov r4,-(sp)
clr r0
div r3,r0
mov r0,r4 /high quotient
mov r1,r0
mov r2,r1
mov r0,-(sp) / *
div r3,r0
bvc 1f
mov r2,r1 / *
mov (sp),r0 / *
sub r3,r0 / this is the clever part
div r3,r0
tst r1
sxt r1
add r1,r0 / cannot overflow!
1:
tst (sp)+
mov r0,r1
mov r4,r0
tst (sp)+
bpl 9f
neg r0
neg r1
sbc r0
9:
jmp cret
hardldiv:
4
/ Long remainder
.globl lrem
lrem:
jsr r5,csv
mov 10.(r5),r3
sxt r4
bpl 1f
neg r3
1:
cmp r4,8.(r5)
bne hardlrem
mov 6.(r5),r2
mov 4.(r5),r1
mov r1,r4
bge 1f
neg r1
neg r2
sbc r1
1:
clr r0
div r3,r0
mov r1,r0
mov r2,r1
mov r0,-(sp) / *
div r3,r0
bvc 1f
mov r2,r1 / *
mov (sp),r0 / *
sub r3,r0
div r3,r0
tst r1
beq 9f
add r3,r1
1:
tst (sp)+ / *
tst r4
bpl 9f
neg r1
9:
sxt r0
jmp cret
/ The divisor is known to be >= 2^15. Only 16 cycles are
/ needed to get a remainder.
hardlrem:
4
/ C register save and restore -- version 7/75
/ modified by wnj && cbh 6/79 for overlayed text registers
/ modified by was 3/80 for use in kernel
/ inter-overlay calls call thunk which calls ovhndlr to
/ save registers. intra-overlay calls call function
/ directly which calls csv to save registers.
.globl csv
.globl cret
.globl ovhndlr
.globl __ovno
.globl _etext
.data
__ovno: 0
.text
csv:
mov r5,r1
mov sp,r5
mov __ovno,-(sp) / overlay is extra (first) word in mark
mov r4,-(sp)
mov r3,-(sp)
mov r2,-(sp)
jsr pc,(r1) / jsr part is sub $2,sp
cret:
mov r5,r2
/ get the overlay out of the mark, and if it is non-zero
/ make sure it is the currently loaded one
mov -(r2),r4
bne 1f / zero is easy
2:
mov -(r2),r4
mov -(r2),r3
mov -(r2),r2
mov r5,sp
mov (sp)+,r5
rts pc
/ not returning to base segment, so check that the right
/ overlay is mapped in, and if not change the mapping
1:
cmp r4,__ovno
beq 2b / lucked out!
/ if return address is in base segment, then nothing to do
cmp 2(r5),$_etext
blt 2b
/ returning to wrong overlay --- do something!
mov PS,-(sp) / save PS
bis $HIPRI,PS / mask interrupts
mov r4,__ovno
asl r4
mov ova(r4),KISA2
mov ovd(r4),KISD2
mov (sp)+,PS / restore PS, unmask interrupts
/ could measure switches[ovno][r4]++ here
jmp 2b
/ ovhndlr makes the argument (in r0) be the current overlay,
/ saves the registers ala csv (but saves the previous overlay number),
/ and then jmp's to the function, skipping the function's initial
/ call to csv.
ovhndlr:
mov (r5),r0 /*
cmp r0,__ovno /*
bne 1f /*
mov r5,r1 /*
mov sp,r5 /*
mov __ovno,-(sp) /*
mov r4,-(sp) /*
mov r3,-(sp) /*
mov r2,-(sp) /*
br 2f /*
1: /*
mov r5,r1
mov sp,r5
mov __ovno,-(sp) / save previous overlay number
mov PS,-(sp) / save PS
bis $HIPRI,PS / mask interrupts
mov r0,__ovno / set new overlay number
asl r0
mov ova(r0),KISA2
mov ovd(r0),KISD2
mov (sp)+,PS / restore PS, unmask interrupts
mov r4,-(sp)
mov r3,-(sp)
mov r2,-(sp)
2: /*
mov 2(r1),r1 /* pick up address of function
jsr pc,4(r1) / skip function's call to csv
.globl _u
_u = 140000
usize = 16.
HIPRI = 340
PS = 177776
SSR0 = 177572
SSR2 = 177576
SSR3 = 172516
KISA0 = 172340
KISA2 = 172344
KISA6 = 172354
KISA7 = 172356
KISD0 = 172300
KISD2 = 172304
KISD6 = 172314
KISD7 = 172316
UISA0 = 177640
UISA1 = 177642
UISD0 = 177600
UISD1 = 177602
UBMR0 = 170200
IO = 177600
.data
.globl _ka6
.globl _sepid, _ubmaps, _cdreg, _nmser
.globl _rh70ml, _rh70hp, _rh70ht, _rh70hs, _rh70hm
_ka6: KISA6
/ The following seven parameters describe the
/ hardware features available on this CPU.
_sepid: 0 / seperate I & D space
/ always zero in mch_i.s
_ubmaps: 0 / unibus map
/ set at startup time
_rh70hs: 0 / hs - massbus controller type
_rh70ml: 0 / ml - " " "
_rh70hp: 0 / hp - " " "
_rh70hm: 0 / hm - " " "
_rh70ht: 0 / ht - " " "
/ RH11 only in mch_i.s,
/ but checked in main.c (binit()) anyway
_nmser: 0 / number of memory system error registers
/ always zero in mch_i.s
_cdreg: 0 / console display register
/ never in mch_i.s
stk: 0
.bss
nofault:.=.+2
ssr: .=.+6
saveps: .=.+2
power: .=.+2
.if TSDUMP
tsxma: .=.+2 /ts11 extended memory address bits
setmap: .=.+2 /UB map usage indicator
tstcc: .=.+2 /ts11 temp location for TCC
comts: .=.+12 /ts11 command packet
chrts: .=.+10 /ts11 characteristics
mests: .=.+16 /ts11 messge buffer
.endif
.if .fpp
fpp: .=.+2
.endif