home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Bug_Fixes / V7_on11-34 / mch11.s next >
Encoding:
Text File  |  2001-02-27  |  24.6 KB  |  1,734 lines

  1. /    @(#)mch11.s    1.6    (Chemeng) 83/10/11
  2. /
  3. /    Machine language assist for small pdp11's
  4. /    11/23, 11/34, 11/35, 11/40, 11/60
  5.  
  6. / non-UNIX instructions
  7. mfpi    = 006500^tst
  8. mtpi    = 006600^tst
  9. mfps    = 106700^tst
  10. mtps    = 106400^tst
  11. stst    = 170300^tst
  12. halt    = 0
  13. wait    = 1
  14. reset    = 5
  15. rtt    = 6
  16.  
  17. .if    RKDUMP
  18. /
  19. / Parameters for RK dump routine.
  20. /
  21. drive    = 2
  22. block    = 0
  23. .endif    /RKDUMP
  24.  
  25. .if    BIGUNIX - 1
  26.  
  27.     .globl    start, _end, _edata, _main
  28. start:
  29.     mov    $trap,34
  30.  
  31. / Set location 0 and 2 to catch traps and jumps to 0
  32.  
  33.     mov    $42,0        / illegal instruction if jump
  34.     mov    $777,2        / trace trap at high priority if trap
  35.  
  36. / initialize systems segments
  37.  
  38.     mov    $KISA0,r0
  39.     mov    $KISD0,r1
  40.     mov    $200,r4
  41.     clr    r2
  42.     mov    $6,r3
  43. 1:
  44.     mov    r2,(r0)+
  45.     mov    $77406,(r1)+        / 4k rw
  46.     add    r4,r2
  47.     sob    r3,1b
  48.  
  49. / initialize user segment
  50.  
  51.     mov    $_end+63.,r2
  52.     ash    $-6,r2
  53.     bic    $!1777,r2
  54.     mov    r2,(r0)+        / ksr6 = sysu
  55.     mov    $usize-1\<8|6,(r1)+
  56.  
  57. / initialize io segment
  58. / set up counts on supervisor segments
  59.  
  60.     mov    $IO,(r0)+
  61.     mov    $77406,(r1)+        / rw 4k
  62.  
  63. / get a sp and start segmentation
  64.  
  65.     mov    $_u+[usize*64.],sp
  66.     inc    SSR0
  67.  
  68. / clear bss
  69.  
  70.     mov    $_edata,r0
  71.     clr    r1
  72. 1:
  73.     mov    r1,(r0)+
  74.     cmp    r0,$_end
  75.     blo    1b
  76.  
  77. / clear user block
  78.  
  79.     mov    $_u,r0
  80. 1:
  81.     mov    r1,(r0)+
  82.     cmp    r0,$_u+[usize*64.]
  83.     blo    1b
  84.  
  85. .if    BUFMAP
  86. /
  87. / set up buffer pointer
  88. /
  89.     mov    $-1,KISA5        / illegal address initially
  90. .endif
  91.  
  92. / set up previous mode and call main
  93. / on return, enter user mode at 0R
  94.  
  95.     mov    $PUMODE,PS
  96.     jsr    pc,_main
  97.     mov    $UMODE,-(sp)
  98.     clr    -(sp)
  99.     rtt
  100. .endif
  101.  
  102.  
  103. .if    BIGUNIX
  104.  
  105.     .globl    start, _end, _edata, _main
  106.     .globl    _etfo, _etfa, _eu, _eto, _etoa, _ers, _eos
  107. start:
  108.     mov    $trap,34
  109.  
  110. / Set location 0 and 2 to catch traps and jumps to 0
  111.  
  112.     mov    $42,0        / illegal instruction if jump
  113.     mov    $777,2        / trace trap at high priority if trap
  114.  
  115. / initialize systems segments
  116. / set up all kernel regs to be 4Kw R/W
  117. / and mapping virual direct to physical
  118.  
  119.     mov    $KISA0,r0
  120.     mov    $KISD0,r1
  121.     clr    r2
  122.     mov    $8.,r3
  123. 1:
  124.     mov    r2,(r0)+
  125.     mov    $77406,(r1)+        / 4k rw
  126.     add    $200,r2
  127.     sob    r3,1b
  128.  
  129.  
  130. /
  131. / map IO page
  132. / and set page 6 length to usize
  133. /
  134.     mov    $IO,-(r0)
  135.     mov    $[usize-1\<8]+6,-4(r1)
  136. /
  137. / now set up to copy overlays
  138. / using ka5 as source, ka6 as destination
  139. /
  140.     mov    $_eto,-(r0)        / eto is seg address of overlay code destination
  141.     mov    r0,r1
  142.     mov    $_etfo,-(r0)        / etfo is seg address of overlay code source
  143.     inc    SSR0            / enable mapping
  144.     mov    $1,r5            / region count, 1=onceonly, 0=ovly
  145.     mov    $_etoa,r4        / init destination virtual addr
  146.     mov    $_etfa,r3        / init source virtual addr
  147.     mov    $_eos,r2        / get onceonly seg size (words)
  148.     beq    2f
  149. /
  150. / copy segments up to their final resting place
  151. /
  152. 0:
  153.     tstb    r3
  154.     bne    1f
  155.     add    $100,r3
  156.     dec    (r0)
  157. 1:
  158.     tstb    r4
  159.     bne    1f
  160.     add    $100,r4
  161.     dec    (r1)
  162. 1:
  163.     mov    -(r3),-(r4)
  164.     sob    r2,0b
  165. 2:
  166.     dec    r5
  167.     bmi    2f    / all done!
  168. /
  169. / done- now leave gap for proc 0,1 u areas (sysld knows the magic size)
  170. /
  171.     sub    $[3*usize]+3,(r1)
  172. /
  173. / now copy other overlay segs to their places
  174. /
  175.     mov    $_ers,r2        / get size in words
  176.     bne    0b
  177. /
  178. / all done
  179. /
  180. 2:
  181. /
  182. / now set up for call to main
  183. /
  184.     mov    $IO,(r0)        / done with ka5
  185.     mov    $_eu,(r1)        / proc0 ka6
  186.  
  187. .if    BUFMAP
  188. /
  189. / set up buffer pointer
  190. /
  191.     mov    $-1,-(r0)        / illegal address initially
  192. .endif
  193. / clear bss
  194.  
  195.     clr    r2
  196.     mov    $_end,r1
  197.     mov    $_edata,r0
  198.     sub    r0,r1
  199.     asr    r1            / size of bss in words
  200.     beq    2f
  201. 1:
  202.     mov    r2,(r0)+
  203.     sob    r1,1b
  204. 2:
  205.  
  206. / clear user block
  207. / and get initial ksp
  208.  
  209.     mov    $usize*40,r1
  210.     mov    $_u,r5
  211. 1:
  212.     mov    r2,(r5)+
  213.     sob    r1,1b
  214.     mov    r5,sp
  215.  
  216. / set up previous mode and call main
  217. / on return, enter user mode at 0R
  218.  
  219.     mov    $PUMODE,PS
  220.     jsr    pc,_main
  221.     mov    $170000,-(sp)
  222.     clr    -(sp)
  223.     rtt
  224. .endif
  225.  
  226.  
  227.  
  228.     .globl    dump
  229. dump:
  230. /
  231. / Save regs in low memory and dump
  232. / core to tape.
  233. /
  234.     mov    r0,4
  235.     mov    $6,r0
  236.     mov    r1,(r0)+
  237.     mov    r2,(r0)+
  238.     mov    r3,(r0)+
  239.     mov    r4,(r0)+
  240.     mov    r5,(r0)+
  241.     mov    sp,(r0)+
  242.     mov    KISA6,(r0)+
  243. .if    [BIGUNIX | BUFMAP]
  244.     mov    KISA5,(r0)+
  245. .endif
  246. .if    [BIGUNIX * BUFMAP]
  247.     mov    KISA4,(r0)+
  248. .endif
  249.  
  250. .if    RKDUMP
  251.     mov    $RKCS,r0
  252.     mov    $2,(r0)+
  253.     clr    2(r0)
  254.     mov    $rkaddr,4(r0)
  255. 1:
  256.     mov    $-256.,(r0)
  257.     inc    -(r0)
  258. 2:
  259.     tstb    (r0)
  260.     bge    2b
  261.     tst    (r0)+
  262.     bge    1b
  263.     halt
  264.  
  265. RKCS    = 177404
  266. sec    = block%12
  267. cyl    = block\/12
  268. rkaddr    = [drive*20000]+[cyl*20]+sec
  269.  
  270. .endif
  271.  
  272. .if    TUDUMP
  273.     mov    $MTC,r0
  274.     mov    $60004,(r0)+
  275.     clr    2(r0)
  276. 1:
  277.     mov    $-512.,(r0)
  278.     inc    -(r0)
  279. 2:
  280.     tstb    (r0)
  281.     bge    2b
  282.     tst    (r0)+
  283.     bge    1b
  284.     reset
  285.  
  286. / end of file and loop
  287.  
  288.     mov    $60007,-(r0)
  289.     br     .
  290.  
  291. MTC    =    172522
  292.  
  293. .endif
  294.  
  295. .if    HTDUMP
  296.     reset
  297.     mov    $1300,*$HTTC
  298.     mov    $HTCS1,r0
  299.     mov    $60,(r0)
  300. 1:
  301.     mov    $177000,*$HTFC
  302.     mov    $177400,*$HTWC
  303.     inc    (r0)
  304. 2:
  305.     tstb    (r0)
  306.     bge    2b
  307.     tst    (r0)
  308.     bge    1b
  309.     mov    $27,(r0)
  310.     br    .
  311.  
  312. HTCS1    =    172440
  313. HTWC    =    172442
  314. HTBA    =    172444
  315. HTFC    =    172446
  316. HTCS2    =    172450
  317. HTTC    =    172472
  318.  
  319. .endif
  320.  
  321. .if    HPBOOT
  322. HPADDR    =    176700
  323. .globl    hpboot
  324. hpboot:
  325.     mov    $HPADDR,r0
  326.     mov    $21,(r0)
  327. 1:
  328.     bit    $200,(r0)
  329.     beq    1b
  330.     mov    $177400,2(r0)
  331.     mov    $71,(r0)
  332. 1:
  333.     bit    $200,(r0)
  334.     beq    1b
  335.     clr    pc
  336.     halt
  337. .endif
  338.     halt
  339.  
  340.  
  341.     .globl    trap, call
  342.     .globl    _trap, _calltime
  343.  
  344. / all traps and interrupts are
  345. / vectored thru this routine.
  346.  
  347. trap:
  348.     mov    PS,saveps
  349.     tst    nofault
  350.     bne    1f
  351.     mov    SSR0,ssr
  352.     mov    SSR2,ssr+4
  353.     mov    $1,SSR0
  354.     jsr    r0,call1; jmp _trap
  355.     / no return
  356. 1:
  357.     mov    $1,SSR0
  358.     mov    nofault,(sp)
  359.     rtt
  360. .text
  361.  
  362.     .globl    _runrun
  363. call1:
  364.     mov    saveps,-(sp)
  365. .if    MOVPS - 1
  366.     clrb    PS
  367. .endif    /MOVPS - 1
  368. .if    MOVPS
  369.     mtps    $BR0
  370. .endif    /MOVPS
  371.     br    1f
  372.  
  373. call:
  374.     mov    PS,-(sp)
  375. 1:
  376.     mov    r1,-(sp)
  377.     mfpi    sp
  378.     mov    4(sp),-(sp)
  379.     bic    $!37,(sp)
  380.     bit    $PUMODE,PS
  381.     beq    1f
  382.     jsr    pc,(r0)+
  383.     tstb    _runrun
  384.     beq    2f
  385.     mov    $12.,(sp)        / trap 12 is give up cpu
  386.     jsr    pc,_trap
  387. 2:
  388.     tst    (sp)+
  389.     mtpi    sp
  390.     br    2f
  391. 1:
  392.     bis    $PUMODE,PS
  393.     jsr    pc,(r0)+
  394.     cmp    (sp)+,(sp)+
  395. 2:
  396.     tst    _dotime
  397.     beq    2f
  398.     bit    $BR7,10(sp)        / test return priority bits
  399.     bne    2f
  400.     jsr    pc,_calltime
  401. 2:
  402.     mov    (sp)+,r1
  403.     tst    (sp)+
  404.     mov    (sp)+,r0
  405.     rtt
  406.  
  407. .if    FPU
  408.     .globl    _savfp
  409. _savfp:
  410.     mov    2(sp),r1
  411.     stfps    (r1)+
  412.     setd
  413.     movf    fr0,(r1)+
  414.     movf    fr1,(r1)+
  415.     movf    fr2,(r1)+
  416.     movf    fr3,(r1)+
  417.     movf    fr4,fr0
  418.     movf    fr0,(r1)+
  419.     movf    fr5,fr0
  420.     movf    fr0,(r1)+
  421.     rts    pc
  422.  
  423.     .globl    _restfp
  424. _restfp:
  425.     mov    2(sp),r1
  426.     mov    r1,r0
  427.     setd
  428.     add    $8.+2.,r1
  429.     movf    (r1)+,fr1
  430.     movf    (r1)+,fr2
  431.     movf    (r1)+,fr3
  432.     movf    (r1)+,fr0
  433.     movf    fr0,fr4
  434.     movf    (r1)+,fr0
  435.     movf    fr0,fr5
  436.     movf    2(r0),fr0
  437.     ldfps    (r0)
  438.     rts    pc
  439.  
  440.     .globl    _stst
  441. _stst:
  442.     stst    r0
  443.     mov    r0,*2(sp)
  444.     rts    pc
  445.  
  446. .endif    /FPU
  447.  
  448.  
  449.     .globl    _addupc
  450. _addupc:
  451.     mov    r2,-(sp)
  452.     mov    6(sp),r2        / base of prof with base,leng,off,scale
  453.     mov    4(sp),r0        / pc
  454.     sub    4(r2),r0        / offset
  455.     clc
  456.     ror    r0
  457.     mov    6(r2),r1
  458.     clc
  459.     ror    r1
  460.     mul    r1,r0        / scale
  461.     ashc    $-14.,r0
  462.     inc    r1
  463.     bic    $1,r1
  464.     cmp    r1,2(r2)        / length
  465.     bhis    1f
  466.     add    (r2),r1        / base
  467.     mov    nofault,-(sp)
  468.     mov    $2f,nofault
  469.     mfpi    (r1)
  470.     add    12.(sp),(sp)
  471.     mtpi    (r1)
  472.     br    3f
  473. 2:
  474.     clr    6(r2)
  475. 3:
  476.     mov    (sp)+,nofault
  477. 1:
  478.     mov    (sp)+,r2
  479.     rts    pc
  480.  
  481.  
  482. /
  483. / back up from a segmentation violation (called from trap.c)
  484. /   backup(u.u_ar0) == 0 if backup assumed to be successful
  485. /
  486. / Almost all processors of the PDP-11 series behave differently
  487. / with respect to segmentation violation backup.
  488. / This backup routine can handle all these
  489. / processors if the correct options are set.
  490.  
  491.     .globl    _backup
  492.     .globl    _regloc
  493.  
  494. _backup:
  495.     mov    2(sp),ssr+2
  496.     mov    r2,-(sp)
  497.     jsr    pc,backup
  498.     mov    r2,ssr+2
  499.     mov    (sp)+,r2
  500.     movb    jflg,r0
  501.     bne    2f
  502.     mov    2(sp),r0
  503.     movb    ssr+2,r1
  504.     jsr    pc,1f
  505.     movb    ssr+3,r1
  506.     jsr    pc,1f
  507.     movb    _regloc+7,r1
  508.     asl    r1
  509.     add    r0,r1
  510.     mov    ssr+4,(r1)
  511.     clr    r0
  512. 2:
  513.     rts    pc
  514. 1:
  515.     mov    r1,-(sp)
  516.     asr    (sp)
  517.     asr    (sp)
  518.     asr    (sp)
  519.     bic    $!7,r1
  520.     movb    _regloc(r1),r1
  521.     asl    r1
  522.     add    r0,r1
  523.     sub    (sp)+,(r1)
  524.     rts    pc
  525.  
  526. /    Hard part - simulate the SSR1 register which DEC fail to
  527. /    provide on the /23, /34, /40 and /60. This version of
  528. /    "backup" was concocted from the V6 m40.s, the V7 m40.s,
  529. /    the Stanford m34.s, and the Edinburgh m60.s.
  530. /        D.S.H. Rosenthal    Dec '79
  531. /        EdCAAD Studies, Dept. of Architecture,
  532. /        22 Chambers St., Edinburgh.
  533. /    Some changes for the VU system by
  534. /        Johan Stevenson, Vrije Universiteit, Amsterdam.
  535. /
  536. /    The basic cases are as follows:-
  537. /
  538. / 1.    op dd
  539. /    The fault happened on the dd.
  540. /
  541. / 2.    op ss,dd
  542. /    The fault may have happened on either the ss or dd. "backup"
  543. /    evaluates and fetches the ss. If this process faults, the
  544. /    adjustment of the dd register [delta(dd)] is zeroed. Things
  545. /    would be easier if the hardware recorded what it was fetching.
  546. /    If both the ss and dd refer to the same register, and if delta(dd)
  547. /    is non-zero, it is impossible to distinguish an ss from a dd fault.
  548. /    Define REGREG = 1 to assume:-
  549. /        If delta(ss) == 0 then dd fault else failure.
  550. /    This permits, for example, a push fault in mov (sp),-(sp) to be
  551. /    backed-up correctly. However, a source fault would be backed-up
  552. /    incorrectly, and without warning. Remove REGREG unless you are
  553. /    absolutely certain.
  554. /
  555. / 3.    mfp[id]    ss
  556. /    Handled like mov ss,-(sp).
  557. /
  558. / 4.    mtp[id] dd
  559. /    Handled like mov (sp)+,dd.
  560. /
  561. / 5.    jsr r,dd
  562. /    The hardware evaluates, but does not fetch, dd and then pushes
  563. /    the initial value of r onto the stack. "backup" assumes that the
  564. /    fault is in the stack push (you shouldn't be jsr-ing via non-
  565. /    existent locations!) and adjusts both the dd register and the sp.
  566. /
  567. / 6.    FP11 op
  568. /    The operands may be 2, 4 or 8 bytes long, depending upon the
  569. /    particular operation and the "floating double" and "long integer"
  570. /    bits.
  571. /
  572. / 7.    illegal stuff like "mark"
  573.  
  574. /    Enter here with address of register save area in ssr+2.
  575. /    First sort out op-code.
  576.  
  577. backup:
  578.     clr    r2        /r2 stands for SSR1
  579.     clr    bflg        /jflg = 0; bflg = 0 for byte op.
  580.     mov    ssr+4,r0    /r0 = virtual pc.
  581.     jsr    pc,fetch    /get instruction word.
  582.     mov    r0,r1
  583.     ash    $-11.,r0
  584.     bic    $!36,r0
  585.     mov    0f(r0),pc    /switch on xx----
  586.  
  587. /    Note that DEC's frequency-driven micro-code design means that
  588. /    mov is usually faster than jmp, but it zaps the condition codes!
  589.  
  590. 0:    t00;    t01;    t02;    t03;    t04;    t05;    t06;    t07
  591.     t10;    t11;    t12;    t13;    t14;    t15;    t16;    t17
  592.  
  593. t00:
  594.     incb    bflg        /bflg = 1 for 2 byte op.
  595. t10:
  596.     mov    r1,r0
  597.     swab    r0
  598.     bic    $!16,r0
  599.     mov    0f(r0),pc    /switch on 00x--- or 10x---
  600.  
  601. 0:    u0;    u1;    u2;    u3;    u4;    u5;    u6;    u7
  602.  
  603. u6:
  604.     mov    r1,r0
  605.     ash    $-5,r0
  606.     bic    $!16,r0
  607.     mov    0f(r0),pc    /switch on 006x-- or 106x--
  608.  
  609. u60 = u5    / ror, rorb
  610. u61 = u5    / rol, rolb
  611. u62 = u5    / asr, asrb
  612. u63 = u5    / asl, aslb
  613. u64 = u7    / mark, mtps
  614. u67 = u5    / sxt, mfps
  615.  
  616. 0:    u60;    u61;    u62;    u63;    u64;    u65;    u66;    u67
  617.  
  618. u66:    / simulate mtp[id] with mov (sp)+,dd
  619.     bic    $4000,r1    / make mode (sp)+
  620.     br    1f
  621.  
  622. u65:    / simulate mfp[id] with mov ss,-(sp)
  623.     ash    $6,r1        / move dd to ss
  624.     bis    $46,r1        / make dd -(sp)
  625. 1:    clrb    bflg        / 2 byte ops - bflg ends up 1.
  626.     br    t01        / treat as mov
  627.  
  628. u4:    / jsr = x04---
  629.     mov    r1,r0
  630.     jsr    pc,setreg    /set up dd adjust
  631.     bis    $173000,r2    /delta(sp) = 2
  632.     rts    pc
  633.  
  634. t07:    / EIS = 07----
  635.     incb    bflg        /bflg = 1 for 2 byte op
  636.  
  637. u0:    / swab, jmp = x00---
  638. u5:    / single operand = x05-dd
  639. .if    MODE2D
  640.     mov    r1,r0        / (r)+ faults to
  641.     ash    $-3,r0        / INITIAL state
  642.     bic    $!7,r0
  643.     cmp    r0,$2        / mode 2?
  644.     bne    1f
  645.     mov    $fixstk,pc    / yes - fix stack
  646. 1:
  647. .endif    /MODE2D
  648.     mov    r1,r0
  649.  
  650. /    setreg - put reg + delta into low byte of r2
  651.  
  652. setreg:
  653.     mov    r0,-(sp)    / mode+reg in r0
  654.     bic    $!7,r0
  655.     bis    r0,r2        /put reg in r2
  656.     mov    (sp)+,r0
  657.     ash    $-3,r0
  658.     bic    $!7,r0        /mode in r0
  659.     movb    adj(r0),r0    /adjust in r0
  660.     movb    bflg,-(sp)    /push shift count
  661.     bne    1f        /not byte operand - skip
  662.     bit    $2,r2        /byte operand with
  663.     beq    3f        /sp or pc
  664.     bit    $4,r2        /is really word op
  665.     beq    3f        /so drop thru
  666. 1:
  667.     bit    $10,r0        /length dependent?
  668.     beq    3f        /no - dont shift
  669. 2:
  670.     asl    r0        /delta = 2**bflg
  671.     decb    (sp)
  672.     bgt    2b
  673. 3:
  674.     tst    (sp)+        /clean stack
  675.     bisb    r0,r2        /put delta in r2
  676.     rts    pc
  677.  
  678. adj:    .byte    0, 0, 10, 20, -10, -20, 0, 0
  679.  
  680. t01:    / mov
  681. t02:    / cmp
  682. t03:    / bit
  683. t04:    / bic
  684. t05:    / bis
  685. t06:    / add
  686. t16:    / sub
  687.     incb    bflg        /bflg = 1 for 2 byte op
  688. t11:    / movb
  689. t12:    / cmpb
  690. t13:    / bitb
  691. t14:    / bicb
  692. t15:    / bisb
  693.     mov    r1,r0        / op ss,dd
  694.     ash    $-6,r0
  695.     jsr    pc,setreg    / for ss
  696.     swab    r2
  697.     mov    r1,r0
  698.     jsr    pc,setreg    / for dd
  699.  
  700. /    r2 now has delta(ss) in hi byte and delta(dd) in low byte.
  701. /    Evaluate and fetch ss, zeroing delta(dd) if a fault occurs.
  702. /    See fetch for details of how this happens.
  703. / 1.    If delta(dd) == 0 dont bother.
  704.  
  705.     bit    $370,r2
  706.     beq    1f
  707.  
  708. / 2.    If mode(ss) is R, it can't have faulted.
  709.  
  710.     bit    $7000,r1
  711.     beq    1f
  712.  
  713. / 3.    register(ss) == register(dd)?
  714.  
  715.     mov    r2,-(sp)
  716.     bic    $174370,(sp)
  717.     cmpb    1(sp),(sp)+
  718.     bne    3f
  719.  
  720. / 4.    Yes, but if delta(ss) == 0 we may assume a dd fault
  721.  
  722.     mov    $u7,pc
  723. 1:
  724.     rts    pc
  725. 3:
  726.  
  727. .if    MODE2S
  728. /    Try to deal with problems caused by /34 etc. faulting op (r)+,dd
  729. /    source to INITIAL state.
  730.  
  731.     mov    r1,r0
  732.     bic    $!7000,r0    /r0 = mode(ss)
  733.     cmp    $2000,r0    / (r)+?
  734.     beq    4f        /yes - problems
  735.     jsr    pc,1f        /no - get r
  736.     jsr    pc,2f        /adjust for increment
  737.     jsr    pc,3f        /fetch it
  738.     rts    pc        /and quit
  739. 4:
  740.  
  741. /    Its an op (r)+,dd. If a fetch on r fails to fault, then it was
  742. /    a destination fault.
  743.  
  744.     mov    r2,-(sp)    /save SSR1
  745.     jsr    pc,1f        /get r
  746.                 /NB - no adjust
  747.     jsr    pc,3f        /fetch it
  748.     tstb    r2        /did it fault?
  749.     beq    4f        /yes - try r-2
  750.     tst    (sp)+        /no - clean up
  751.     rts    pc        /its a dd fault
  752. 4:
  753.  
  754. /    Fetch on r faults. If fetch on r-2 also faults, then its an ss fault.
  755.  
  756.     mov    (sp)+,r2    /restore SSR1
  757.     jsr    pc,1f        /get r
  758.     jsr    pc,2f        /adjust for increment
  759.     jsr    pc,3f        /fetch it
  760.     tstb    r2        /did it fault?
  761.     bne    u7        /no - failure
  762.     ash    $-6,r1        /yes - place ss
  763.     br    fixstk        /and fix stack
  764. 1:
  765. .endif    /MODE2S
  766.  
  767. /    Zero delta(dd) if the ss faults (see fetch).
  768. /    Start ss cycle by picking up the register value.
  769.  
  770.     mov    r1,r0
  771.     ash    $-6,r0
  772.     bic    $!7,r0        /r0 = reg no.
  773.     movb    _regloc(r0),r0
  774.     asl    r0
  775.     add    ssr+2,r0
  776.     mov    (r0),r0        /r0 = contents reg(ss)
  777. .if    MODE2S
  778.     rts    pc
  779. 2:
  780. .endif    /MODE2S
  781.  
  782. /    If register incremented, must decrement before fetch. If register
  783. /    decremented, happened before fetch.
  784.  
  785.     bit    $174000,r2
  786.     ble    4f
  787.     dec    r0
  788.     bit    $10000,r2
  789.     beq    4f        /delta = 1
  790.     dec    r0        /delta = 2
  791. 4:
  792. .if    MODE2S
  793.     rts    pc
  794. 3:
  795. .endif    /MODE2S
  796.  
  797. /    If mode 6 or 7 fetch and add X(r)
  798.  
  799.     bit    $4000,r1
  800.     beq    4f
  801.     bit    $2000,r1
  802.     beq    4f
  803.     mov    r0,-(sp)    /mode 6 or 7
  804.     mov    ssr+4,r0    /virtual pc
  805.     add    $2,r0
  806.     jsr    pc,fetch    /get X
  807.     add    (sp)+,r0    /add it in
  808. 4:
  809.  
  810. /    Fetch operand
  811.  
  812.     jsr    pc,fetch
  813.  
  814. /    If mode 3, 5 or 7 fetch *.
  815.  
  816.     bit    $1000,r1
  817.     beq    4f
  818.     bit    $6000,r1
  819.     bne    fetch
  820. 4:
  821.     rts    pc
  822.  
  823.  
  824. t17:    / FP11 op
  825. .if    FPU
  826.     incb    bflg        /assume 2 bytes
  827.     mov    r1,r0
  828.     ash    $-7,r0
  829.     bic    $!36,r0
  830.     mov    0f(r0),pc    /switch on 17x(x..)--
  831.  
  832. fp50 = u5    / stexp is 2 bytes
  833. fp64 = u5    / ldexp is 2 bytes (Check this sometime!)
  834.  
  835. 0:    fp00;    fp04;    fp10;    fp14;    fp20;    fp24;    fp30;    fp34;
  836.     fp40;    fp44;    fp50;    fp54;    fp60;    fp64;    fp70;    fp74;
  837.  
  838. fp00:    / ldfps, stfps, stst + others which can't fault.
  839.     cmp    r1,$170300    /stst?
  840.     bhis    1f        /stst is 4 bytes (for this purpose)
  841.     mov    $u5,pc        /ldfps, stfps are 2 bytes.
  842.  
  843. fp54:    / stcfi
  844. fp70:    / ldcif
  845.     stfps    r0        /if long integer mode
  846.     bit    $100,r0
  847.     bne    1f        /its 4 bytes
  848.     mov    $u5,pc        /else its really 2 bytes
  849.  
  850. fp60:    / stcfd
  851. fp74:    / ldcfd
  852.     incb    bflg        /assume 4 bytes
  853.     stfps    r0
  854.     tstb    r0        /if floating double
  855.     bmi    0f        /its really is
  856.     br    1f        /else its 8 bytes
  857.  
  858. fp04:    / clrf tstf, absf, negf
  859. fp10:    / mulf
  860. fp14:    / modf
  861. fp20:    / addf
  862. fp24:    / ldf
  863. fp30:    / subf
  864. fp34:    / cmpf
  865. fp40:    / stf
  866. fp44:    / divf
  867.     incb    bflg        /assume 4 bytes
  868.     stfps    r0
  869.     tstb    r0        /if not floating double
  870.     bpl    0f        /it really is
  871. 1:    incb    bflg        /else its 8 bytes
  872. 0:
  873. .if    FPPNOT
  874.     br    fixstk
  875. .endif    /FPPNOT
  876. .if    FPPNOT - 1
  877.     mov    r1,r0
  878.     mov    $setreg,pc
  879. .endif    /FPPNOT - 1
  880. .endif    /FPU
  881. u1:    /br
  882. u2:
  883. u3:
  884. u7:    /illegal
  885.     incb    jflg
  886.     rts    pc
  887.  
  888. .if    FIXSP
  889. /    Operation was aborted with registers in INITIAL state, so
  890. /    no backup is required (why don't they all work that way?).
  891. /    However, "grow()" examines the sp, and grows the stack iff it
  892. /    points outside the valid stack. If the sp is in its INITIAL
  893. /    state, it will point to a valid stack address, and SIGSEG will
  894. /    occur. To avoid this, the sp seen by "grow()" must be adjusted
  895. /    to its FINAL state. The sp seen by "grow()" is kept in the
  896. /    external variable _backsp during the call to _backup().
  897.  
  898.     .globl _backsp
  899.  
  900. fixstk:
  901.     mov    r1,r0
  902.     bic    $!7,r0
  903.     cmp    $6,r0        /affecting sp?
  904.     bne    3f        /no - quit
  905.     mov    r1,r0
  906.     ash    $-3,r0
  907.     bic    $!7,r0        /r0 = mode
  908.     movb    adj(r0),r0    /get adjust
  909.     tstb    bflg        /byte op?
  910.     bne    0f        /no - skip
  911.     incb    bflg        /yes - on sp is word op
  912. 0:    ash    $-3,r0        /r0 = adjust proper
  913.     bit    $1,r0        /1 or -1
  914.     beq    2f        /no - deferred or zero
  915. 1:    asl    r0        /exponentiate
  916.     decb    bflg        /bflg times
  917.     bgt    1b
  918. 2:    add    r0,_backsp    /adjust the saved sp
  919. 3:    clr    r2        /no register adjust
  920.     rts    pc
  921. .endif    /FIXSP
  922.  
  923. fetch:
  924.     bic    $1,r0
  925.     mov    nofault,-(sp)
  926.     mov    $1f,nofault
  927.     mfpi    (r0)
  928.     mov    (sp)+,r0
  929.     mov    (sp)+,nofault
  930.     rts    pc
  931.  
  932. 1:
  933.     mov    (sp)+,nofault
  934.     clrb    r2            / clear out dest on fault
  935.     mov    $-1,r0
  936.     rts    pc
  937.  
  938. .bss
  939. bflg:    .=.+1
  940. jflg:    .=.+1
  941. .text
  942.  
  943.     .globl    _fubyte, _subyte
  944.     .globl    _fuibyte, _suibyte
  945.     .globl    _fuword, _suword
  946.     .globl    _fuiword, _suiword
  947. _fuibyte:
  948. _fubyte:
  949.     mov    2(sp),r1
  950.     bic    $1,r1
  951.     jsr    pc,gword
  952.     cmp    r1,2(sp)
  953.     beq    1f
  954.     swab    r0
  955. 1:
  956.     bic    $!377,r0
  957.     rts    pc
  958.  
  959. _suibyte:
  960. _subyte:
  961.     mov    2(sp),r1
  962.     bic    $1,r1
  963.     jsr    pc,gword
  964.     mov    r0,-(sp)
  965.     cmp    r1,4(sp)
  966.     beq    1f
  967.     movb    6(sp),1(sp)
  968.     br    2f
  969. 1:
  970.     movb    6(sp),(sp)
  971. 2:
  972.     mov    (sp)+,r0
  973.     jsr    pc,pword
  974.     clr    r0
  975.     rts    pc
  976. _fuiword:
  977. _fuword:
  978.     mov    2(sp),r1
  979. fuword:
  980.     jsr    pc,gword
  981.     rts    pc
  982.  
  983. gword:
  984. .if    MOVPS - 1
  985.     mov    PS,-(sp)
  986.     movb    $BR7,PS
  987. .endif    /MOVPS - 1
  988. .if    MOVPS
  989.     mfps    -(sp)
  990.     mtps    $BR7
  991. .endif    /MOVPS
  992.     mov    nofault,-(sp)
  993.     mov    $err,nofault
  994.     mfpi    (r1)
  995.     mov    (sp)+,r0
  996.     br    1f
  997.  
  998. _suiword:
  999. _suword:
  1000.     mov    2(sp),r1
  1001.     mov    4(sp),r0
  1002. suword:
  1003.     jsr    pc,pword
  1004.     rts    pc
  1005.  
  1006. pword:
  1007. .if    MOVPS - 1
  1008.     mov    PS,-(sp)
  1009.     movb    $BR7,PS
  1010. .endif    /MOVPS - 1
  1011. .if    MOVPS
  1012.     mfps    -(sp)
  1013.     mtps    $BR7
  1014. .endif    /MOVPS
  1015.     mov    nofault,-(sp)
  1016.     mov    $err,nofault
  1017.     mov    r0,-(sp)
  1018.     mtpi    (r1)
  1019. 1:
  1020.     mov    (sp)+,nofault
  1021. .if    MOVPS - 1
  1022.     mov    (sp)+,PS
  1023. .endif    /MOVPS - 1
  1024. .if    MOVPS
  1025.     mtps    (sp)+
  1026. .endif    /MOVPS
  1027.     rts    pc
  1028.  
  1029. err:
  1030.     mov    (sp)+,nofault
  1031. .if    MOVPS - 1
  1032.     mov    (sp)+,PS
  1033. .endif    /MOVPS - 1
  1034. .if    MOVPS
  1035.     mtps    (sp)+
  1036. .endif    /MOVPS
  1037.     tst    (sp)+
  1038.     mov    $-1,r0
  1039.     rts    pc
  1040.     rts    pc
  1041.  
  1042.     .globl    _copyin, _copyout
  1043.     .globl    _copyiin, _copyiout
  1044. _copyiin:
  1045. _copyin:
  1046.     jsr    pc,copsu
  1047. 1:
  1048.     mfpi    (r0)+
  1049.     mov    (sp)+,(r1)+
  1050.     sob    r2,1b
  1051.     br    2f
  1052.  
  1053. _copyiout:
  1054. _copyout:
  1055.     jsr    pc,copsu
  1056. 1:
  1057.     mov    (r0)+,-(sp)
  1058.     mtpi    (r1)+
  1059.     sob    r2,1b
  1060. 2:
  1061.     mov    (sp)+,nofault
  1062.     mov    (sp)+,r2
  1063.     clr    r0
  1064.     rts    pc
  1065.  
  1066. copsu:
  1067.     mov    (sp)+,r0
  1068.     mov    r2,-(sp)
  1069.     mov    nofault,-(sp)
  1070.     mov    r0,-(sp)
  1071.     mov    10(sp),r0
  1072.     mov    12(sp),r1
  1073.     mov    14(sp),r2
  1074.     asr    r2
  1075.     mov    $1f,nofault
  1076.     rts    pc
  1077.  
  1078. 1:
  1079.     mov    (sp)+,nofault
  1080.     mov    (sp)+,r2
  1081.     mov    $-1,r0
  1082.     rts    pc
  1083.  
  1084.     .globl    _idle, _waitloc
  1085. _idle:
  1086. .if    MOVPS - 1
  1087.     mov    PS,-(sp)
  1088.     clrb    PS
  1089. .endif    /MOVPS - 1
  1090. .if    MOVPS
  1091.     mfps    -(sp)
  1092.     mtps    $BR0
  1093. .endif    /MOVPS
  1094.     wait
  1095. waitloc:
  1096. .if    MOVPS - 1
  1097.     mov    (sp)+,PS
  1098. .endif    /MOVPS - 1
  1099. .if    MOVPS
  1100.     mtps    (sp)+
  1101. .endif    /MOVPS
  1102.     rts    pc
  1103.     .data
  1104. _waitloc:
  1105.     waitloc
  1106.     .text
  1107.  
  1108.     .globl    _save
  1109. _save:
  1110.     mov    (sp)+,r1
  1111.     mov    (sp),r0
  1112. .if    [BIGUNIX | BUFMAP]
  1113.     mov    KISA5,(r0)+
  1114. .endif
  1115. .if    [BIGUNIX * BUFMAP]
  1116.     mov    KISA4,(r0)+
  1117. .endif
  1118.     mov    r2,(r0)+
  1119.     mov    r3,(r0)+
  1120.     mov    r4,(r0)+
  1121.     mov    r5,(r0)+
  1122.     mov    sp,(r0)+
  1123.     mov    r1,(r0)+
  1124.     clr    r0
  1125.     jmp    (r1)
  1126.  
  1127.     .globl    _resume
  1128. _resume:
  1129.     mov    2(sp),r0        / new process
  1130.     mov    4(sp),r1        / new stack
  1131. .if    MOVPS - 1
  1132.     movb    $BR7,PS
  1133. .endif    /MOVPS - 1
  1134. .if    MOVPS
  1135.     mtps    $BR7
  1136. .endif    /MOVPS
  1137.     mov    r0,KISA6        / In new process
  1138. .if    [BIGUNIX | BUFMAP]
  1139.     mov    (r1)+,KISA5
  1140. .endif
  1141. .if    [BIGUNIX * BUFMAP]
  1142.     mov    (r1)+,KISA4
  1143. .endif
  1144.     mov    (r1)+,r2
  1145.     mov    (r1)+,r3
  1146.     mov    (r1)+,r4
  1147.     mov    (r1)+,r5
  1148.     mov    (r1)+,sp
  1149.     mov    $1,r0
  1150. .if    MOVPS - 1
  1151.     clrb    PS
  1152. .endif    /MOVPS - 1
  1153. .if    MOVPS
  1154.     mtps    $BR0
  1155. .endif    /MOVPS
  1156.     jmp    *(r1)+
  1157.  
  1158. .if    SPLFIX - 1
  1159.     .globl    _spl0, _spl1, _spl3, _spl4, _spl5, _spl6, _spl7, _splx
  1160. .if    MOVPS - 1
  1161. _spl0:
  1162.     mov    PS,r0
  1163.     clrb    PS
  1164.     rts    pc
  1165.  
  1166. _spl1:
  1167.     mov    PS,r0
  1168.     movb    $BR1,PS
  1169.     rts    pc
  1170.  
  1171. _spl3:
  1172.     mov    PS,r0
  1173.     movb    $BR3,PS
  1174.     rts    pc
  1175.  
  1176. _spl4:
  1177.     mov    PS,r0
  1178.     movb    $BR4,PS
  1179.     rts    pc
  1180.  
  1181. _spl5:
  1182.     mov    PS,r0
  1183.     movb    $BR5,PS
  1184.     rts    pc
  1185.  
  1186. _spl6:
  1187.     mov    PS,r0
  1188.     movb    $BR6,PS
  1189.     rts    pc
  1190.  
  1191. _spl7:
  1192.     mov    PS,r0
  1193.     movb    $BR7,PS
  1194.     rts    pc
  1195.  
  1196. _splx:
  1197.     mov    PS,r0
  1198.     mov    2(sp),PS
  1199.     rts    pc
  1200. .endif    /MOVPS - 1
  1201. .if    MOVPS
  1202. _spl0:
  1203.     mfps    r0
  1204.     mtps    $BR0
  1205.     rts    pc
  1206.  
  1207. _spl1:
  1208.     mfps    r0
  1209.     mtps    $BR1
  1210.     rts    pc
  1211.  
  1212. _spl3:
  1213.     mov    PS,r0
  1214.     movb    $BR3,PS
  1215.     rts    pc
  1216.  
  1217. _spl4:
  1218.     mfps    r0
  1219.     mtps    $BR4
  1220.     rts    pc
  1221.  
  1222. _spl5:
  1223.     mfps    r0
  1224.     mtps    $BR5
  1225.     rts    pc
  1226.  
  1227. _spl6:
  1228.     mfps    r0
  1229.     mtps    $BR6
  1230.     rts    pc
  1231.  
  1232. _spl7:
  1233.     mfps    r0
  1234.     mtps    $BR7
  1235.     rts    pc
  1236.  
  1237. _splx:
  1238.     mfps    r0
  1239.     mtps    2(sp)
  1240.     rts    pc
  1241. .endif    /MOVPS
  1242. .endif    /SPLFIX - 1
  1243.  
  1244.     .globl    _copyseg
  1245. _copyseg:
  1246. .if    [BIGUNIX * BUFMAP] - 1
  1247.     mov    PS,-(sp)
  1248.     mov    UISA0,-(sp)
  1249.     mov    UISA1,-(sp)
  1250.     mov    $PUMODE+BR7,PS
  1251.     mov    10(sp),UISA0
  1252.     mov    12(sp),UISA1
  1253.     mov    UISD0,-(sp)
  1254.     mov    UISD1,-(sp)
  1255.     mov    $6,UISD0
  1256.     mov    $6,UISD1
  1257.     mov    r2,-(sp)
  1258.     clr    r0
  1259.     mov    $8192.,r1
  1260.     mov    $32.,r2
  1261. 1:
  1262.     mfpi    (r0)+
  1263.     mtpi    (r1)+
  1264.     sob    r2,1b
  1265.     mov    (sp)+,r2
  1266.     mov    (sp)+,UISD1
  1267.     mov    (sp)+,UISD0
  1268.     mov    (sp)+,UISA1
  1269.     mov    (sp)+,UISA0
  1270.     mov    (sp)+,PS
  1271.     rts    pc
  1272. .endif
  1273. .if    [BIGUNIX * BUFMAP]
  1274. .if    MOVPS - 1
  1275.     mov    PS,-(sp)
  1276. .endif    /MOVPS - 1
  1277. .if    MOVPS
  1278.     mfps    -(sp)
  1279. .endif    /MOVPS
  1280.     mov    KISA5,-(sp)
  1281.     mov    KISA4,-(sp)
  1282.     mov    r2,-(sp)
  1283. .if    MOVPS - 1
  1284.     movb    $BR7,PS
  1285. .endif    /MOVPS - 1
  1286. .if    MOVPS
  1287.     mtps    $BR7
  1288. .endif    /MOVPS
  1289.     mov    14(sp),KISA5    / where to
  1290.     mov    $120000,r1
  1291.     mov    12(sp),KISA4    / where from
  1292.     mov    $100000,r0
  1293.     mov    $10,r2        / how much
  1294. 0:
  1295.     mov    (r0)+,(r1)+
  1296.     mov    (r0)+,(r1)+
  1297.     mov    (r0)+,(r1)+
  1298.     mov    (r0)+,(r1)+
  1299.     sob    r2,0b
  1300.     mov    (sp)+,r2
  1301.     mov    (sp)+,KISA4
  1302.     mov    (sp)+,KISA5
  1303. .if    MOVPS - 1
  1304.     mov    (sp)+,PS
  1305. .endif    /MOVPS - 1
  1306. .if    MOVPS
  1307.     mtps    (sp)+
  1308. .endif    /MOVPS
  1309.     rts    pc
  1310. .endif
  1311.  
  1312.     .globl    _clearseg
  1313. _clearseg:
  1314. .if    [BIGUNIX | BUFMAP] - 1
  1315.     mov    PS,-(sp)
  1316.     mov    UISA0,-(sp)
  1317.     mov    $PUMODE+BR7,PS
  1318.     mov    6(sp),UISA0
  1319.     mov    UISD0,-(sp)
  1320.     mov    $6,UISD0
  1321.     clr    r0
  1322.     mov    $32.,r1
  1323. 1:
  1324.     clr    -(sp)
  1325.     mtpi    (r0)+
  1326.     sob    r1,1b
  1327.     mov    (sp)+,UISD0
  1328.     mov    (sp)+,UISA0
  1329.     mov    (sp)+,PS
  1330.     rts    pc
  1331. .endif
  1332. .if    [BIGUNIX | BUFMAP]
  1333. .if    MOVPS - 1
  1334.     mov    PS,-(sp)
  1335. .endif    /MOVPS - 1
  1336. .if    MOVPS
  1337.     mfps    -(sp)
  1338. .endif    /MOVPS
  1339.     mov    KISA5,-(sp)
  1340.     mov    r2,-(sp)
  1341.     mov    $10,r2
  1342.     mov    $120000,r1
  1343.     clr    r0
  1344. .if    MOVPS - 1
  1345.     movb    $BR7,PS
  1346. .endif    /MOVPS - 1
  1347. .if    MOVPS
  1348.     mtps    $BR7
  1349. .endif    /MOVPS
  1350.     mov    10(sp),KISA5
  1351. 0:
  1352.     mov    r0,(r1)+
  1353.     mov    r0,(r1)+
  1354.     mov    r0,(r1)+
  1355.     mov    r0,(r1)+
  1356.     sob    r2,0b
  1357.     mov    (sp)+,r2
  1358.     mov    (sp)+,KISA5
  1359. .if    MOVPS - 1
  1360.     mov    (sp)+,PS
  1361. .endif    /MOVPS - 1
  1362. .if    MOVPS
  1363.     mtps    (sp)+
  1364. .endif    /MOVPS
  1365. .endif    /MOVPS - 1
  1366.     rts    pc
  1367. .endif
  1368.  
  1369. .if    PIGET
  1370.     .globl    _piget, _piput
  1371. _piget:
  1372.     mov    PS,-(sp)
  1373.     mov    UISA0,-(sp)
  1374.     mov    UISD0,-(sp)
  1375.     jsr    pc,2f
  1376.     mfpi    (r0)
  1377.     mov    (sp)+,r0
  1378. 1:
  1379.     mov    (sp)+,UISD0
  1380.     mov    (sp)+,UISA0
  1381.     mov    (sp)+,PS
  1382.     rts    pc
  1383.  
  1384. _piput:
  1385.     mov    PS,-(sp)
  1386.     mov    UISA0,-(sp)
  1387.     mov    UISD0,-(sp)
  1388.     jsr    pc,2f
  1389.     mov    14(sp),r1
  1390.     mov    r1,-(sp)
  1391.     mtpi    (r0)
  1392.     br    1b
  1393. 2:
  1394.     mov    12(sp),r0
  1395.     mov    14(sp),r1
  1396.     ashc    $-6,r0
  1397.     mov    $PUMODE+BR7,PS
  1398.     mov    r1,UISA0
  1399.     mov    $6,UISD0    / 1 click r/w
  1400.     mov    14(sp),r0
  1401.     bic    $!77,r0
  1402.     rts    pc
  1403. .endif
  1404.  
  1405.     .globl    _printn, _putchar
  1406.     / printn
  1407.     /
  1408.     / printn(num, base)
  1409.     / unsigned long    num;
  1410.     / int        base;
  1411.     /
  1412.     / print out the long 'num' in unsigned form in base 'base'.
  1413.     /
  1414.  
  1415. _printn:
  1416.     mov    r5,-(sp)
  1417.     mov    sp,r5
  1418.     mov    r4,-(sp)
  1419.     mov    r3,-(sp)
  1420.     mov    r2,-(sp)
  1421.     mov    10(r5),r4        / base
  1422.     mov    6(r5),r1        / get low part of 'num'
  1423.     mov    4(r5),r0        / get high part of 'num'
  1424. 0:
  1425.     mov    r1,r3
  1426.     mov    r0,r1            / do high part of division
  1427.     clr    r0
  1428.     div    r4,r0
  1429.     mov    r1,r2            / followed by low part
  1430.     div    r4,r2
  1431.     mov    r2,r1            / r0,r1 contain dividend, r3 remainder
  1432.     add    $'0,r3            / convert to ascii
  1433.     cmp    $'9,r3
  1434.     bge    1f
  1435.     add    $'A-'0-10.,r3
  1436. 1:
  1437.     mov    r3,-(sp)
  1438.     ashc    $0,r0            / loop until num == 0
  1439.     bne    0b
  1440.     mov    $_putchar,r4
  1441.     mov    r5,r3
  1442.     sub    $6,r3            / end of number
  1443. 0:
  1444.     jsr    pc,*r4
  1445.     tst    (sp)+
  1446.     cmp    sp,r3
  1447.     bne    0b
  1448.     mov    (sp)+,r2
  1449.     mov    (sp)+,r3
  1450.     mov    (sp)+,r4
  1451.     mov    (sp)+,r5
  1452.     rts    pc
  1453.  
  1454. / Long multiply
  1455.  
  1456.     .globl    lmul
  1457. lmul:
  1458.     jsr    r5,csv
  1459.     mov    6(r5),r2
  1460.     sxt    r1
  1461.     sub    4(r5),r1
  1462.     mov    10.(r5),r0
  1463.     sxt    r3
  1464.     sub    8.(r5),r3
  1465.     mul    r0,r1
  1466.     mul    r2,r3
  1467.     add    r1,r3
  1468.     mul    r2,r0
  1469.     sub    r3,r0
  1470.     jmp    cret
  1471.  
  1472. / Long quotient
  1473.  
  1474.     .globl    ldiv
  1475. ldiv:
  1476.     jsr    r5,csv
  1477.     mov    10.(r5),r3
  1478.     sxt    r4
  1479.     bpl    1f
  1480.     neg    r3
  1481. 1:
  1482.     cmp    r4,8.(r5)
  1483.     bne    hardldiv
  1484.     mov    6.(r5),r2
  1485.     mov    4.(r5),r1
  1486.     bge    1f
  1487.     neg    r1
  1488.     neg    r2
  1489.     sbc    r1
  1490.     com    r4
  1491. 1:
  1492.     mov    r4,-(sp)
  1493.     clr    r0
  1494.     div    r3,r0
  1495.     mov    r0,r4        /high quotient
  1496.     mov    r1,r0
  1497.     mov    r2,r1
  1498.     div    r3,r0
  1499.     bvc    1f
  1500.     mov    r2,r1        / 11/23 clobbers this
  1501.     sub    r3,r0        / this is the clever part
  1502.     div    r3,r0
  1503.     tst    r1
  1504.     sxt    r1
  1505.     add    r1,r0        / cannot overflow!
  1506. 1:
  1507.     mov    r0,r1
  1508.     mov    r4,r0
  1509.     tst    (sp)+
  1510.     bpl    9f
  1511.     neg    r0
  1512.     neg    r1
  1513.     sbc    r0
  1514. 9:
  1515.     jmp    cret
  1516.  
  1517. hardldiv:
  1518.     clr    -(sp)
  1519.     mov    6.(r5),r2
  1520.     mov    4.(r5),r1
  1521.     bpl    1f
  1522.     com    (sp)
  1523.     neg    r1
  1524.     neg    r2
  1525.     sbc    r1
  1526. 1:
  1527.     clr    r0
  1528.     mov    8.(r5),r3
  1529.     bge    1f
  1530.     neg    r3
  1531.     neg    10.(r5)
  1532.     sbc    r3
  1533.     com    (sp)
  1534. 1:
  1535.     mov    $16.,r4
  1536. 1:
  1537.     clc
  1538.     rol    r2
  1539.     rol    r1
  1540.     rol    r0
  1541.     cmp    r3,r0
  1542.     bgt    3f
  1543.     blt    2f
  1544.     cmp    10.(r5),r1
  1545.     blos    2f
  1546. 3:
  1547.     sob    r4,1b
  1548.     br    1f
  1549. 2:
  1550.     sub    10.(r5),r1
  1551.     sbc    r0
  1552.     sub    r3,r0
  1553.     inc    r2
  1554.     sob    r4,1b
  1555. 1:
  1556.     mov    r2,r1
  1557.     clr    r0
  1558.     tst    (sp)+
  1559.     beq    1f
  1560.     neg    r0
  1561.     neg    r1
  1562.     sbc    r0
  1563. 1:
  1564.     jmp    cret
  1565.  
  1566. / Long remainder
  1567.  
  1568.     .globl    lrem
  1569. lrem:
  1570.     jsr    r5,csv
  1571.     mov    10.(r5),r3
  1572.     sxt    r4
  1573.     bpl    1f
  1574.     neg    r3
  1575. 1:
  1576.     cmp    r4,8.(r5)
  1577.     bne    hardlrem
  1578.     mov    6.(r5),r2
  1579.     mov    4.(r5),r1
  1580.     mov    r1,r4
  1581.     bge    1f
  1582.     neg    r1
  1583.     neg    r2
  1584.     sbc    r1
  1585. 1:
  1586.     clr    r0
  1587.     div    r3,r0
  1588.     mov    r1,r0
  1589.     mov    r2,r1
  1590.     div    r3,r0
  1591.     bvc    1f
  1592.     mov    r2,r1        / 11/23 clobbers this
  1593.     sub    r3,r0
  1594.     div    r3,r0
  1595.     tst    r1
  1596.     beq    9f
  1597.     add    r3,r1
  1598. 1:
  1599.     tst    r4
  1600.     bpl    9f
  1601.     neg    r1
  1602. 9:
  1603.     sxt    r0
  1604.     jmp    cret
  1605.  
  1606. / The divisor is known to be >= 2^15.    Only 16 cycles are
  1607. / needed to get a remainder.
  1608. hardlrem:
  1609.     mov    6.(r5),r2
  1610.     mov    4.(r5),r1
  1611.     bpl    1f
  1612.     neg    r1
  1613.     neg    r2
  1614.     sbc    r1
  1615. 1:
  1616.     clr    r0
  1617.     mov    8.(r5),r3
  1618.     bge    1f
  1619.     neg    r3
  1620.     neg    10.(r5)
  1621.     sbc    r3
  1622. 1:
  1623.     mov    $16.,r4
  1624. 1:
  1625.     clc
  1626.     rol    r2
  1627.     rol    r1
  1628.     rol    r0
  1629.     cmp    r3,r0
  1630.     blt    2f
  1631.     bgt    3f
  1632.     cmp    10.(r5),r1
  1633.     blos    2f
  1634. 3:
  1635.     sob    r4,1b
  1636.     br    1f
  1637. 2:
  1638.     sub    10.(r5),r1
  1639.     sbc    r0
  1640.     sub    r3,r0
  1641.     sob    r4,1b
  1642. 1:
  1643.     tst    4(r5)
  1644.     bge    1f
  1645.     neg    r0
  1646.     neg    r1
  1647.     sbc    r0
  1648. 1:
  1649.     jmp    cret
  1650.  
  1651.     .globl    csv
  1652. csv:
  1653.     mov    r5,r0
  1654.     mov    sp,r5
  1655.     mov    r4,-(sp)
  1656.     mov    r3,-(sp)
  1657.     mov    r2,-(sp)
  1658.     jsr    pc,(r0)
  1659.  
  1660.     .globl cret
  1661. cret:
  1662.     mov    r5,r2
  1663.     mov    -(r2),r4
  1664.     mov    -(r2),r3
  1665.     mov    -(r2),r2
  1666.     mov    r5,sp
  1667.     mov    (sp)+,r5
  1668.     rts    pc
  1669.  
  1670.     .globl _display, _mpid
  1671. _display:
  1672.     mov    _mpid, CSWR
  1673.     rts    pc
  1674.  
  1675.     .globl    _u
  1676. _u    = 140000
  1677. usize    = 16.
  1678.  
  1679. .if    BUFMAP
  1680.     .globl    _maparea
  1681. .if    BIGUNIX
  1682. _maparea    = 100000
  1683. .endif
  1684. .if    BIGUNIX - 1
  1685. _maparea    = 120000
  1686. .endif
  1687. .endif
  1688.  
  1689. PS    = 177776
  1690. BR0    = 000000
  1691. BR1    = 000040
  1692. BR3    = 000140
  1693. BR4    = 000200
  1694. BR5    = 000240
  1695. BR6    = 000300
  1696. BR7    = 000340
  1697. PUMODE    = 030000
  1698. UMODE    = 170000
  1699.  
  1700. SSR0    = 177572
  1701. SSR2    = 177576
  1702. CSWR    = 177570
  1703. KISA0    = 172340
  1704. KISA4    = 172350
  1705. KISA5    = 172352
  1706. KISA6    = 172354
  1707. KISA7    = 172356
  1708. KISD0    = 172300
  1709. KISD4    = 172310
  1710. KISD5    = 172312
  1711. UISA0    = 177640
  1712. UISA1    = 177642
  1713. UISD0    = 177600
  1714. UISD1    = 177602
  1715. IO    = 7600
  1716.  
  1717. .data
  1718.     .globl    _ka6
  1719. _ka6:    KISA6
  1720.  
  1721.     .globl    _cputype
  1722. _cputype:34.
  1723.  
  1724. stk:    0
  1725.  
  1726. .bss
  1727.     .globl    nofault
  1728. nofault:.=.+2
  1729. ssr:    .=.+6
  1730. saveps: .=.+2
  1731. power:    .=.+2
  1732.     .globl    _dotime
  1733. _dotime: .=.+2
  1734.