Annotation of researchv9/sys/sun3/locore.s, revision 1.1

1.1     ! root        1:        .data
        !             2:        .asciz  "@(#)locore.s 1.1 86/02/03 Copyr 1985 Sun Micro"
        !             3:        .even
        !             4:        .text
        !             5: /*
        !             6:  *     Copyright (c) 1985 by Sun Microsystems, Inc.
        !             7:  */
        !             8: 
        !             9: #include "../h/param.h"
        !            10: #include "../h/vmparam.h"
        !            11: #include "../h/errno.h"
        !            12: /*
        !            13: #include "../netinet/in_systm.h"
        !            14: 
        !            15: #include "../sundev/mbvar.h"
        !            16: */
        !            17: 
        !            18: #include "../machine/asm_linkage.h"
        !            19: #include "../machine/buserr.h"
        !            20: #include "../machine/clock.h"
        !            21: #include "../machine/cpu.h"
        !            22: #include "../machine/diag.h"
        !            23: #include "../machine/enable.h"
        !            24: #include "../machine/interreg.h"
        !            25: #include "../machine/memerr.h"
        !            26: #include "../machine/mmu.h"
        !            27: #include "../machine/pcb.h"
        !            28: #include "../machine/psl.h"
        !            29: #include "../machine/pte.h"
        !            30: #include "../machine/reg.h"
        !            31: #include "../machine/trap.h"
        !            32: 
        !            33: #include "assym.s"
        !            34: 
        !            35: /* 
        !            36:  * Absolute external symbols
        !            37:  */
        !            38:        .globl  _u, _DVMA
        !            39: _u     = UADDR         | 32 bit virtual address for u-area
        !            40: _DVMA  = 0x0FF00000    | 28 bit virtual address for system DVMA
        !            41: 
        !            42: /*
        !            43:  * The interrupt stack.  This must be the first thing in the data
        !            44:  * segment (other than an sccs string) so that we don't stomp
        !            45:  * on anything important during interrupt handling.  We get a
        !            46:  * red zone below this stack for free when the kernel text is
        !            47:  * write protected.  Since the kernel is loaded with the "-N"
        !            48:  * flag, we pad this stack by a page because when the page
        !            49:  * level protection is done, we will lose part of this interrupt
        !            50:  * stack.  Thus the true interrupt stack will be at least MIN_INTSTACK_SZ
        !            51:  * bytes and at most MIN_INTSTACK_SZ+NBPG bytes.  The interrupt entry
        !            52:  * code assumes that the interrupt stack is at a lower address than
        !            53:  * both eintstack and the kernel stack in the u area.
        !            54:  */
        !            55: #define        MIN_INTSTACK_SZ 0x800
        !            56:        .data
        !            57:        .globl _intstack, eintstack
        !            58: _intstack:                             | bottom of interrupt stack
        !            59:        . = . + NBPG + MIN_INTSTACK_SZ
        !            60: eintstack:                             | end (top) of interrupt stack
        !            61: 
        !            62: /*
        !            63:  * System software page tables
        !            64:  */
        !            65: #define vaddr(x)       ((((x)-_Sysmap)/4)*NBPG + KERNELBASE)
        !            66: #define SYSMAP(mname, vname, npte)     \
        !            67:        .globl  mname;                  \
        !            68: mname: .=.+(4*npte);                   \
        !            69:        .globl  vname;                  \
        !            70: vname = vaddr(mname);
        !            71:        SYSMAP(_Sysmap   ,_Sysbase      ,SYSPTSIZE      )
        !            72:        SYSMAP(_Usrptmap ,_usrpt        ,USRPTSIZE      )
        !            73:        SYSMAP(_Forkmap  ,_forkutl      ,UPAGES         )
        !            74:        SYSMAP(_Xswapmap ,_xswaputl     ,UPAGES         )
        !            75:        SYSMAP(_Xswap2map,_xswap2utl    ,UPAGES         )
        !            76:        SYSMAP(_Swapmap  ,_swaputl      ,UPAGES         )
        !            77:        SYSMAP(_Pushmap  ,_pushutl      ,UPAGES         )
        !            78:        SYSMAP(_Vfmap    ,_vfutl        ,UPAGES         )
        !            79:        SYSMAP(_CMAP1    ,_CADDR1       ,1              ) | local tmp
        !            80:        SYSMAP(_CMAP2    ,_CADDR2       ,1              ) | local tmp
        !            81:        SYSMAP(_mmap     ,_vmmap        ,1              )
        !            82:        SYSMAP(_msgbufmap,_msgbuf       ,MSGBUFPTECNT   )
        !            83: /*
        !            84:        SYSMAP(_Mbmap    ,_mbutl        ,NMBCLUSTERS*CLSIZE)
        !            85: */
        !            86:        SYSMAP(_ESysmap  ,_Syslimit     ,0              ) | must be last
        !            87: 
        !            88:        .globl  _Syssize
        !            89: _Syssize = (_ESysmap-_Sysmap)/4
        !            90: 
        !            91: /*
        !            92:  * Software copy of system enable register
        !            93:  * This is always atomically updated
        !            94:  */
        !            95:        .data
        !            96:        .globl  _enablereg
        !            97: _enablereg:    .byte   0                       | UNIX's system enable register
        !            98:        .even
        !            99:        .text
        !           100: 
        !           101: /*
        !           102:  * Macro to save all registers and switch to kernel context
        !           103:  * 1: Save and switch context
        !           104:  * 2: Save all registers
        !           105:  * 3: Save user stack pointer
        !           106:  */
        !           107: #define SAVEALL() \
        !           108:        clrw    sp@-;\
        !           109:        moveml  #0xFFFF,sp@-;\
        !           110:        movl    usp,a0;\
        !           111:        movl    a0,sp@(R_SP)
        !           112: 
        !           113: /* Normal trap sequence */
        !           114: #define TRAP(type) \
        !           115:        SAVEALL();\
        !           116:        movl    #type,sp@-;\
        !           117:        jra     trap
        !           118: 
        !           119: /*
        !           120:  * System initialization
        !           121:  * UNIX receives control at the label `_start' which
        !           122:  * must be at offset zero in this file; this file must
        !           123:  * be the first thing in the boot image.
        !           124:  */
        !           125:        .text
        !           126:        .globl  _start
        !           127: _start:
        !           128: /*
        !           129:  * We should reset the world here, but it screws the UART settings.
        !           130:  *
        !           131:  * Do a halfhearted job of setting up the mmu so that we can run out
        !           132:  * of the high address space.  We do this by reading the current pmegs
        !           133:  * for the `real' locations and using them for the virtual relocation.
        !           134:  * NOTE - Assumes that the real and virtual locations have the same
        !           135:  * segment offsets from 0 and KERNELBASE!!!
        !           136:  *
        !           137:  * We make the following assumptions about our environment
        !           138:  * as set up by the monitor:
        !           139:  *
        !           140:  *     - we have enough memory mapped for the entire kernel + some more
        !           141:  *     - all pages are writable
        !           142:  *     - the last pmeg [SEGINV] has no valid pme's
        !           143:  *     - the highest virtual segment has a pmeg allocated to it
        !           144:  *     - when the monitor's romp->v_memorybitmap points to a zero
        !           145:  *         - each low segment i is mapped to use pmeg i
        !           146:  *         - each page map entry i maps physical page i
        !           147:  *     - the monitor's scb is NOT in low memory
        !           148:  *     - on systems w/ ecc memory, that the monitor has set the base
        !           149:  *         addresses and enabled all the memory cards correctly
        !           150:  *
        !           151:  * We will set the protection properly in startup().
        !           152:  */
        !           153: 
        !           154: /*
        !           155:  * Before we set up the new mapping and start running with the correct
        !           156:  * addresses, all of the code must be carefully written to be position
        !           157:  * independent code, since we are linked for running out of high addresses,
        !           158:  * but we get control running in low addresses.  We continue to run
        !           159:  * off the stack set up by the monitor until after we set up the u area.
        !           160:  */
        !           161:        movw    #SR_HIGH,sr             | lock out interrupts
        !           162:        moveq   #FC_MAP,d0
        !           163:        movc    d0,sfc                  | set default sfc to FC_MAP
        !           164:        movc    d0,dfc                  | set default dfc to FC_MAP
        !           165:        moveq   #KCONTEXT,d0    
        !           166:        movsb   d0,CONTEXTBASE          | now running in KCONTEXT
        !           167: 
        !           168: leax:  lea     pc@(_start-(leax+2)),a2 | a2 = true current location of _start
        !           169:        movl    a2,d2                   | real start address
        !           170:        andl    #SEGMENTADDRBITS,d2     | clear extraneous bits
        !           171:        orl     #SEGMENTBASE,d2         | set to segment map offset
        !           172:        movl    d2,a2                   | a2 = real adddress map pointer
        !           173: 
        !           174:        movl    #_start,d3              | virtual start address
        !           175:        andl    #SEGMENTADDRBITS,d3     | clear extraneous bits
        !           176:        orl     #SEGMENTBASE,d3         | set to segment map offset
        !           177:        movl    d3,a3                   | a3 = virtual address map pointer
        !           178: 
        !           179: /*
        !           180:  * Compute the number used to control the dbra loop.
        !           181:  * By doing ((end - 1) - KERNELBASE) >> SGSHIFT we
        !           182:  * essentially get ctos(btoc(end - KERNELBASE)) - 1
        !           183:  * where the - 1 is adjustment for the dbra loop.
        !           184:  */
        !           185:        movl    #_end-1,d1              | get virtual end
        !           186:        subl    #KERNELBASE,d1          | subtract off base address
        !           187:        movl    #SGSHIFT,d0             | load up segment shift value
        !           188:        lsrl    d0,d1                   | d1 = # of segments to map - 1
        !           189: 
        !           190: /*
        !           191:  * Now loop through the real addresses where we are loaded and set
        !           192:  * up the virtual segments for where we want to be virtually to be the same.
        !           193:  */
        !           194: 0:
        !           195:        movsb   a2@,d0                  | get real segno value
        !           196:        movsb   d0,a3@                  | set virtual segno value
        !           197:        addl    #NBSG,a2                | bump real address map pointer
        !           198:        addl    #NBSG,a3                | bump virtual address map pointer
        !           199:        dbra    d1,0b                   | decrement count and loop
        !           200: 
        !           201:        movl    #CACHE_CLEAR+CACHE_ENABLE,d0
        !           202:        movc    d0,cacr                 | clear (and enable) the cache
        !           203: 
        !           204:        jmp     cont:l                  | force non-PC rel branch
        !           205: cont:
        !           206: 
        !           207: /*
        !           208:  * PHEW!  Now we are running with correct addresses
        !           209:  * and can use non-position independent code.
        !           210:  */
        !           211: 
        !           212: /*
        !           213:  * Now map in our own copies of the eeprom, clock, memory error
        !           214:  * register, interrupt control register, and ecc regs into the
        !           215:  * last virtual segment which already has a pmeg allocated to it
        !           216:  * when we get control from the monitor.
        !           217:  */
        !           218:        lea     EEPROM_ADDR_MAPVAL,a0   | map in eeprom
        !           219:        movl    #EEPROM_ADDR_PTE,d0
        !           220:        movsl   d0,a0@
        !           221: 
        !           222:        lea     CLKADDR_MAPVAL,a0       | map in clock
        !           223:        movl    #CLKADDR_PTE,d0
        !           224:        movsl   d0,a0@
        !           225: 
        !           226:        lea     MEMREG_MAPVAL,a0        | map in memory error register
        !           227:        movl    #MEMREG_PTE,d0
        !           228:        movsl   d0,a0@
        !           229: 
        !           230:        lea     INTERREG_MAPVAL,a0      | map in interrupt control reg
        !           231:        movl    #INTERREG_PTE,d0
        !           232:        movsl   d0,a0@
        !           233: 
        !           234:        lea     ECCREG_MAPVAL,a0        | map in ecc regs
        !           235:        movl    #ECCREG_PTE,d0
        !           236:        movsl   d0,a0@
        !           237: 
        !           238: /*
        !           239:  * Check to see if memory was all mapped in correctly.  On versions >= 'N',
        !           240:  * if ROMP_ROMVEC_VERSION is greater than zero, then ROMP_MEMORYBITMAP
        !           241:  * contains the address of a pointer to an array of bits
        !           242:  * If this pointer is non-zero, then we had some bad pages
        !           243:  * Until we get smarter, we give up if we find this condition.
        !           244:  */
        !           245:        tstl    ROMP_ROMVEC_VERSION
        !           246:        ble     1f                      | field is <= zero, don't do next test
        !           247:        movl    ROMP_MEMORYBITMAP,a0
        !           248:        tstl    a0@
        !           249:        jeq     1f                      | pointer is zero, all ok
        !           250:        pea     0f
        !           251:        jsr     _halt
        !           252:        addqw   #4,sp                   | in case they really want to try this
        !           253:        .data
        !           254: 0:     .asciz "Memory bad"
        !           255:        .even
        !           256:        .text
        !           257: 1:
        !           258: 
        !           259: /*
        !           260:  * Set up mapping for the u page(s) now, using the physical page(s)
        !           261:  * after _end.  This code and uinit() are closely related.
        !           262:  */
        !           263:        movl    #(UPAGES-1),d1          | dbra loop counter
        !           264:        pea     _end-KERNELBASE+NBPG-1  | phys addr of starting page past end
        !           265:        jsr     _getpgmap               | getpgmap(end - KERNELBASE + NBPG - 1)
        !           266:        addqw   #4,sp                   | pop argument
        !           267:        orl     #(PG_S+PG_W),d0         | make a system writable page
        !           268:        lea     _u,a0                   | get addr of u area
        !           269: 0:
        !           270:        movl    d0,sp@-                 | push pte
        !           271:        pea     a0@                     | push addr
        !           272:        jsr     _setpgmap               | setpgmap(u + i*NBPG, pte + i)
        !           273:        addqw   #8,sp                   | pop arguments
        !           274:        addql   #1,d0                   | bump pte to next phys page
        !           275:        addl    #NBPG,a0                | bump addr
        !           276:        dbra    d1,0b
        !           277: 
        !           278: | zero first page which will be scb/usrpt page
        !           279:        movl    #((NBPG-1)/4),d0        | dbra byte count
        !           280:        lea     0,a0                    | start at zero
        !           281: 0:     clrl    a0@+                    | clear long word and increment
        !           282:        dbra    d0,0b                   | decrement count and loop
        !           283: 
        !           284: | zero bss + u page(s) (using low addresses)
        !           285:        movl    #_end-KERNELBASE+(NBPG*(UPAGES+1))-1,d0
        !           286:        andl    #~(NBPG-1),d0           | mask off to page boundary
        !           287:        lea     _edata-KERNELBASE,a0    | get bss start
        !           288:        subl    a0,d0                   | get bss length
        !           289:        lsrl    #2,d0                   | shift for long count
        !           290: 0:     clrl    a0@+                    | clear long word and increment
        !           291:        subql   #1,d0
        !           292:        jne     0b                      | decrement count and loop
        !           293: 
        !           294: /*
        !           295:  * Set up the stack.  From now we continue to use the 68020 ISP
        !           296:  * (interrupt stack pointer).  This is because the MSP (master
        !           297:  * stack pointer) as implemented by Motorola is too painful to
        !           298:  * use since we have to play lots of games and add extra tests
        !           299:  * to set something in the master stack if we running on the
        !           300:  * interrupt stack and we are about to pop off a throw away
        !           301:  * stack frame.
        !           302:  *
        !           303:  * Thus it is possible to having naming conflicts.  In general,
        !           304:  * when the term "interrupt stack" (no pointer) is used, it
        !           305:  * is referring to the software implemented interrupt stack
        !           306:  * and the "kernel stack" is the per user kernel stack in the
        !           307:  * user area.  We handling switching between the two different
        !           308:  * address ranges upon interrupt entry/exit.  We will use ISP
        !           309:  * and MSP if we are referring to the hardstack stack pointers.
        !           310:  */
        !           311:        lea     _u+U_STACK+KERNSTACK,sp | set to top of kernel stack
        !           312: 
        !           313:        /*
        !           314:         * See if we have a 68881 attached.
        !           315:         * _fppstate is 0 if no fpp,
        !           316:         * 1 if fpp is present and enabled,
        !           317:         * and -1 if fpp is present but disabled
        !           318:         * (not currently used).
        !           319:         */
        !           320:        .data
        !           321:        .globl  _fppstate
        !           322: _fppstate:     .word 1         | mark as present until we find out otherwise
        !           323:        .text
        !           324: 
        !           325: flinevec = 0x2c
        !           326:        movsb   ENABLEREG,d0            | get the current enable register
        !           327:        orb     #ENA_FPP,d0             | or in FPP enable bit
        !           328:        movsb   d0,ENABLEREG            | set in the enable register
        !           329:        movl    sp,a1                   | save sp in case of fline fault
        !           330:        movc    vbr,a0                  | get vbr
        !           331:        movl    a0@(flinevec),d1        | save old f line trap handler
        !           332:        movl    #ffault,a0@(flinevec)   | set up f line handler
        !           333:        frestore fnull
        !           334:        jra     1f
        !           335: 
        !           336: fnull: .long   0                       | null fpp internal state
        !           337: 
        !           338: ffault:                                        | handler for no fpp present
        !           339:        movw    #0,_fppstate            | set global to say no fpp
        !           340:        andb    #~ENA_FPP,d0            | clear ENA_FPP enable bit
        !           341:        movl    a1,sp                   | clean up stack
        !           342: 
        !           343: 1:
        !           344:        movl    d1,a0@(flinevec)        | restore old f line trap handler
        !           345:        movsb   d0,ENABLEREG            | set up enable reg
        !           346:        movb    d0,_enablereg           | save soft copy of enable register
        !           347: 
        !           348: | dummy up a stack so process 1 can find saved registers
        !           349:        movl    #USRSTACK,a0            | init user stack pointer
        !           350:        movl    a0,usp
        !           351:        clrw    sp@-                    | dummy fmt & vor
        !           352:        movl    #USRTEXT,sp@-           | push pc
        !           353:        movw    #SR_USER,sp@-           | push sr
        !           354:        lea     0,a6                    | stack frame link 0 in main
        !           355: | invoke main, we will return as process 1 (init)
        !           356:        SAVEALL()
        !           357:        jsr     _main                   | simulate interrupt -> main
        !           358:        clrl    d0                      | fake return value from trap
        !           359:        jra     rei
        !           360: 
        !           361: /*
        !           362:  * Entry points for interrupt and trap vectors
        !           363:  */
        !           364:        .globl  buserr, addrerr, coprocerr, fmterr, illinst, zerodiv, chkinst
        !           365:        .globl  trapv, privvio, trace, emu1010, emu1111, spurious
        !           366:        .globl  badtrap, brkpt, floaterr, level2, level3, level4, level5
        !           367:        .globl  _level7, errorvec
        !           368: 
        !           369: buserr:
        !           370:        TRAP(T_BUSERR)
        !           371: 
        !           372: addrerr:
        !           373:        TRAP(T_ADDRERR)
        !           374: 
        !           375: coprocerr:
        !           376:        TRAP(T_COPROCERR)
        !           377: 
        !           378: fmterr:
        !           379:        TRAP(T_FMTERR)
        !           380: 
        !           381: illinst:
        !           382:        TRAP(T_ILLINST)
        !           383: 
        !           384: zerodiv:
        !           385:        TRAP(T_ZERODIV)
        !           386: 
        !           387: chkinst:
        !           388:        TRAP(T_CHKINST)
        !           389: 
        !           390: trapv:
        !           391:        TRAP(T_TRAPV)
        !           392: 
        !           393: privvio:
        !           394:        TRAP(T_PRIVVIO)
        !           395: 
        !           396: trace:
        !           397:        TRAP(T_TRACE)
        !           398: 
        !           399: emu1010:
        !           400:        TRAP(T_EMU1010)
        !           401: 
        !           402: emu1111:
        !           403:        TRAP(T_EMU1111)
        !           404: 
        !           405: spurious:
        !           406:        TRAP(T_SPURIOUS)
        !           407: 
        !           408: badtrap:
        !           409:        TRAP(T_M_BADTRAP)
        !           410: 
        !           411: brkpt:
        !           412:        TRAP(T_BRKPT)
        !           413: 
        !           414: floaterr:
        !           415:        TRAP(T_M_FLOATERR)
        !           416: 
        !           417: errorvec:
        !           418:        TRAP(T_M_ERRORVEC)
        !           419: 
        !           420: level2:
        !           421:        IOINTR(2)
        !           422: 
        !           423: level3:
        !           424:        IOINTR(3)
        !           425: 
        !           426: level4:
        !           427:        IOINTR(4)
        !           428: 
        !           429:        .data
        !           430:        .globl  _ledcnt
        !           431: ledpat:
        !           432:        .byte   ~0x80
        !           433:        .byte   ~0x40
        !           434:        .byte   ~0x20
        !           435:        .byte   ~0x10
        !           436:        .byte   ~0x08
        !           437:        .byte   ~0x04
        !           438:        .byte   ~0x02
        !           439:        .byte   ~0x01
        !           440:        .byte   ~0x02
        !           441:        .byte   ~0x04
        !           442:        .byte   ~0x08
        !           443:        .byte   ~0x10
        !           444:        .byte   ~0x20
        !           445:        .byte   ~0x40
        !           446: endpat:
        !           447:        .even
        !           448: ledptr:                .long   ledpat
        !           449: flag5:         .word   0
        !           450: flag7:         .word   0
        !           451: _ledcnt:       .word   50              | once per second min LED update rate
        !           452: ledcnt:                .word   0
        !           453:        .text
        !           454: 
        !           455: /*
        !           456:  * This code assumes that the real time clock interrupts 100 times
        !           457:  * a second and that we want to only call hardclock 50 times/sec
        !           458:  * We update the LEDs with new values so at least a user can tell
        !           459:  * that something it still running before calling hardclock().
        !           460:  */
        !           461: level5:                                        | default clock interrupt
        !           462:        tstb    CLKADDR+CLK_INTRREG     | read CLKADDR->clk_intrreg to clear
        !           463:        andb    #~IR_ENA_CLK5,INTERREG  | clear interrupt request
        !           464:        orb     #IR_ENA_CLK5,INTERREG   | and re-enable
        !           465:        tstb    CLKADDR+CLK_INTRREG     | clear interrupt register again,
        !           466:                                        | if we lost interrupt we will
        !           467:                                        | resync later anyway.
        !           468: | for 100 hz operation, comment out from here ...
        !           469:        notw    flag5                   | toggle flag
        !           470:        jeq     0f                      | if result zero skip ahead
        !           471:        rte
        !           472: 0:
        !           473: | ... to here
        !           474:        moveml  #0xC0E0,sp@-            | save d0,d1,a0,a1,a2
        !           475: 
        !           476:        movl    sp,a2                   | save copy of previous sp
        !           477:        cmpl    #eintstack,sp           | on interrupt stack?
        !           478:        jls     1f                      | yes, skip
        !           479:        lea     eintstack,sp            | no, switch to interrupt stack
        !           480: 1:
        !           481: 
        !           482:                        /* check for LED update */
        !           483:        movl    a2@(5*4+2),a1           | get saved pc
        !           484:        cmpl    #idle,a1                | were we idle?
        !           485:        beq     0f                      | yes, do LED update
        !           486:        subqw   #1,ledcnt
        !           487:        bge     2f                      | if positive skip LED update
        !           488: 0:
        !           489:        movw    _ledcnt,ledcnt          | reset counter
        !           490:        movl    ledptr,a0               | get pointer
        !           491:        movb    a0@+,d0                 | get next byte
        !           492:        cmpl    #endpat,a0              | are we at the end?
        !           493:        bne     1f                      | if not, skip
        !           494:        lea     ledpat,a0               | reset pointer
        !           495: 1:
        !           496:        movl    a0,ledptr               | save pointer
        !           497:        movsb   d0,DIAGREG              | d0 to diagnostic LEDs
        !           498: 
        !           499: 2:                                     | call hardclock
        !           500:        movw    a2@(5*4),d0             | get saved sr
        !           501:        movl    d0,sp@-                 | push it as a long
        !           502:        movl    a1,sp@-                 | push saved pc
        !           503:        jsr     _hardclock              | call UNIX routine
        !           504:        movl    a2,sp                   | restore old sp
        !           505:        moveml  sp@+,#0x0703            | restore all saved regs
        !           506:        jra     rei_io                  | all done
        !           507: 
        !           508: /*
        !           509:  * Level 7 interrupts can be caused by parity/ECC errors or the
        !           510:  * clock chip.  The clock chip is tied to level 7 interrupts
        !           511:  * only if we are profiling.  Because of the way nmi's work,
        !           512:  * we clear the any level 7 clock interrupts first before
        !           513:  * checking the memory error register.
        !           514:  */
        !           515: _level7:
        !           516: #ifdef GPROF
        !           517:        tstb    CLKADDR+CLK_INTRREG     | read CLKADDR->clk_intrreg to clear
        !           518:        andb    #~IR_ENA_CLK7,INTERREG  | clear interrupt request
        !           519:        orb     #IR_ENA_CLK7,INTERREG   | and re-enable
        !           520: #endif GPROF
        !           521: 
        !           522:        moveml  #0xC0C0,sp@-            | save C regs
        !           523:        movb    MEMREG,d0               | read memory error register
        !           524:        andb    #ER_INTR,d0             | a parity/ECC interrupt pending?
        !           525:        jeq     0f                      | if not, jmp
        !           526:        jsr     _memerr                 | dump memory error info
        !           527:        /*MAYBE REACHED*/               | if we do return to here, then
        !           528:        jra     1f                      | we had a non-fatal memory problem
        !           529: 0:
        !           530: 
        !           531: #ifdef GPROF
        !           532: | for 100 hz profiling, comment out from here ...
        !           533:        notw    flag7                   | toggle flag
        !           534:        jne     1f                      | if result non-zero return
        !           535: | ... to here
        !           536:        jsr     kprof                   | do the profiling
        !           537: #else GPROF
        !           538:        pea     0f                      | push message printf
        !           539:        jsr     _printf                 | print the message
        !           540:        addqw   #4,sp                   | pop argument
        !           541:        .data
        !           542: 0:     .asciz  "stray level 7 interrupt\012"
        !           543:        .even
        !           544:        .text
        !           545: #endif GPROF
        !           546: 1:
        !           547:        moveml  sp@+,#0x0303            | restore regs
        !           548:        rte
        !           549: 
        !           550: /*
        !           551:  * Called by trap #2 to do an instruction cache flush operation
        !           552:  */
        !           553:        .globl  flush
        !           554: flush:
        !           555:        movl    #CACHE_CLEAR+CACHE_ENABLE,d0
        !           556:        movc    d0,cacr                 | clear (and enable) the cache
        !           557:        rte
        !           558: 
        !           559:        .globl  syscall, trap, rei
        !           560: /*
        !           561:  * Special case for syscall.
        !           562:  * Everything in line because this is by far the most
        !           563:  * common interrupt.
        !           564:  */
        !           565: syscall:
        !           566:        subqw   #2,sp                   | empty space
        !           567:        moveml  #0xFFFF,sp@-            | save all regs
        !           568:        movl    usp,a0                  | get usp
        !           569:        movl    a0,sp@(R_SP)            | save usp
        !           570:        movl    #syserr,_u+U_LOFAULT    | catch a fault if and when
        !           571:        movl    a0@,d0                  | get the syscall code
        !           572: syscont:
        !           573:        clrl    _u+U_LOFAULT            | clear lofault
        !           574:        movl    d0,sp@-                 | push syscall code
        !           575:        jsr     _syscall                | go to C routine
        !           576:        addqw   #4,sp                   | pop arg
        !           577:        orw     #SR_INTPRI,sr           | need to test atomicly, rte will lower
        !           578:        bclr    #AST_STEP_BIT-24,_u+PCB_P0LR | need to single step?
        !           579:        jne     4f
        !           580:        bclr    #AST_SCHED_BIT-24,_u+PCB_P0LR | need to reschedule?
        !           581:        jeq     3f                      | no, get out
        !           582: 4:     bset    #TRACE_AST_BIT-24,_u+PCB_P0LR | say that we're tracing for AST
        !           583:        jne     3f                      | if already doing it, skip
        !           584:        bset    #SR_TRACE_BIT-8,sp@(R_SR) | set trace mode
        !           585:        jeq     3f                      | if wasn't set, continue
        !           586:        bset    #TRACE_USER_BIT-24,_u+PCB_P0LR | save fact that trace was set
        !           587: 3:     movl    sp@(R_SP),a0            | restore user SP
        !           588:        movl    a0,usp
        !           589:        movl    #CACHE_CLEAR+CACHE_ENABLE,d0
        !           590:        movc    d0,cacr                 | clear (and enable) the cache
        !           591: 1:
        !           592:        moveml  sp@,#0x7FFF             | restore all but SP
        !           593:        addw    #R_SR,sp                | pop all saved regs
        !           594:        rte                             | and return!
        !           595: 
        !           596: syserr:
        !           597:        movl    #-1,d0                  | set err code
        !           598:        jra     syscont                 | back to mainline
        !           599: 
        !           600: /*
        !           601:  * We reset the sfc and dfc to FC_MAP in case we came in from
        !           602:  * a trap while in the monitor since the monitor uses movs
        !           603:  * instructions after dorking w/ sfc and dfc during its operation.
        !           604:  */
        !           605: trap:
        !           606:        moveq   #FC_MAP,d0
        !           607:        movc    d0,sfc  
        !           608:        movc    d0,dfc
        !           609:        jsr     _trap                   | Enter C trap routine
        !           610:        addqw   #4,sp                   | Pop trap type
        !           611: 
        !           612: /*
        !           613:  * Return from interrupt or trap, check for AST's.
        !           614:  * d0 contains the size of info to pop (if any)
        !           615:  */
        !           616: rei:
        !           617:        btst    #SR_SMODE_BIT-8,sp@(R_SR) | SR_SMODE ?
        !           618:        bne     1f                      | skip if system
        !           619:        orw     #SR_INTPRI,sr           | need to test atomicly, rte will lower
        !           620:        bclr    #AST_STEP_BIT-24,_u+PCB_P0LR | need to single step?
        !           621:        jne     4f
        !           622:        bclr    #AST_SCHED_BIT-24,_u+PCB_P0LR | need to reschedule?
        !           623:        jeq     3f                      | no, get out
        !           624: 4:     bset    #TRACE_AST_BIT-24,_u+PCB_P0LR | say that we're tracing for AST
        !           625:        bne     3f                      | if already doing it, skip
        !           626:        bset    #SR_TRACE_BIT-8,sp@(R_SR) | set trace mode
        !           627:        jeq     3f                      | if wasn't set, continue
        !           628:        bset    #TRACE_USER_BIT-24,_u+PCB_P0LR | save fact that trace was set
        !           629: 3:     movl    sp@(R_SP),a0            | restore user SP
        !           630:        movl    a0,usp
        !           631:        movl    #CACHE_CLEAR+CACHE_ENABLE,a0
        !           632:        movc    a0,cacr                 | clear (and enable) the cache
        !           633: 1:
        !           634:        tstl    d0                      | any cleanup needed?
        !           635:        beq     2f                      | no, skip
        !           636:        movl    sp,a0                   | get current sp
        !           637:        addw    d0,a0                   | pop off d0 bytes of crud
        !           638:        clrw    a0@(R_VOR)              | dummy VOR
        !           639:        movl    sp@(R_PC),a0@(R_PC)     | move PC
        !           640:        movw    sp@(R_SR),a0@(R_SR)     | move SR
        !           641:        movl    a0,sp@(R_SP)            | stash new sp value
        !           642:        moveml  sp@,#0xFFFF             | restore all including SP
        !           643:        addw    #R_SR,sp                | pop all saved regs
        !           644:        rte                             | and return!
        !           645: 2:
        !           646:        moveml  sp@,#0x7FFF             | restore all but SP
        !           647:        addw    #R_SR,sp                | pop all saved regs
        !           648:        rte                             | and return!
        !           649: 
        !           650: /*
        !           651:  * Return from I/O interrupt, check for AST's.
        !           652:  */
        !           653:        .globl  rei_io
        !           654: rei_iop:
        !           655:        moveml  sp@+,#0x0707            | pop regs <a2,a1,a0,d2,d1,d0>
        !           656: rei_io:
        !           657:        addql   #1,_cnt+V_INTR          | increment io interrupt count
        !           658: rei_si:
        !           659:        btst    #SR_SMODE_BIT-8,sp@     | SR_SMODE?  (SR is atop stack)
        !           660:        jne     3f                      | skip if system
        !           661:        orw     #SR_INTPRI,sr           | need to test atomicly, rte will lower
        !           662:        bclr    #AST_STEP_BIT-24,_u+PCB_P0LR | need to single step?
        !           663:        jne     4f
        !           664:        bclr    #AST_SCHED_BIT-24,_u+PCB_P0LR | need to reschedule?
        !           665:        jeq     3f                      | no, get out
        !           666: 4:     bset    #TRACE_AST_BIT-24,_u+PCB_P0LR | say that we're tracing for AST
        !           667:        jne     3f                      | if already doing it, skip
        !           668:        bset    #SR_TRACE_BIT-8,sp@     | set trace mode in SR atop stack
        !           669:        jeq     3f                      | if wasn't set, continue
        !           670:        bset    #TRACE_USER_BIT-24,_u+PCB_P0LR | save fact that trace was set
        !           671: 3:
        !           672:        rte                             | and return!
        !           673: 
        !           674: /*
        !           675:  * Handle software interrupts
        !           676:  * Just call C routine
        !           677:  */
        !           678:        .globl  softint
        !           679: softint:
        !           680:        moveml  #0xC0E0,sp@-            | save regs we trash <d0,d1,a0,a1,a2>
        !           681:        movl    sp,a2                   | save copy of previous sp
        !           682:        cmpl    #eintstack,sp           | on interrupt stack?
        !           683:        jls     0f                      | yes, skip
        !           684:        lea     eintstack,sp            | no, switch to interrupt stack
        !           685: 0:
        !           686:        bclr    #IR_SOFT_INT1_BIT,INTERREG| clear interrupt request
        !           687:        jsr     _softint                | Call C
        !           688:        movl    a2,sp                   | restore old sp
        !           689:        moveml  sp@+,#0x0703            | restore saved regs <a2,a1,a0,d1,d0>
        !           690:        jra     rei_si
        !           691: 
        !           692: /*
        !           693:  * Turn on a software interrupt (H/W level 1).
        !           694:  */
        !           695:        ENTRY(siron)
        !           696:        bset    #IR_SOFT_INT1_BIT,INTERREG | trigger level 1 intr
        !           697:        rts
        !           698: 
        !           699: /*
        !           700:  * return 1 if an interrupt is being serviced (on interrupt stack),
        !           701:  * otherwise return 0.
        !           702:  */
        !           703:        ENTRY(intsvc)
        !           704:        clrl    d0                      | assume false
        !           705:        cmpl    #eintstack,sp           | on interrupt stack?
        !           706:        bhi     1f                      | no, skip
        !           707:        movl    #1,d0                   | return true
        !           708: 1:
        !           709:        rts
        !           710: 
        !           711: /*
        !           712:  * Enable and disable DVMA.
        !           713:  */
        !           714:        ENTRY(enable_dvma)
        !           715: 1:
        !           716:        orb     #ENA_SDVMA,_enablereg   | enable System DVMA
        !           717:        movb    _enablereg,d0           | get it in a register
        !           718:        movsb   d0,ENABLEREG            | put enable register back
        !           719:        cmpb    _enablereg,d0           | see if someone higher changed it
        !           720:        bne     1b                      | if so, try again
        !           721:        rts
        !           722:        
        !           723:        ENTRY(disable_dvma)
        !           724: 1:
        !           725:        andb    #~ENA_SDVMA,_enablereg  | disable System DVMA
        !           726:        movb    _enablereg,d0           | get it in a register
        !           727:        movsb   d0,ENABLEREG            | put enable register back
        !           728:        cmpb    _enablereg,d0           | see if someone higher changed it
        !           729:        bne     1b                      | if so, try again
        !           730:        rts
        !           731: 
        !           732: /*
        !           733:  * Transfer data to and from user space -
        !           734:  * Note that these routines can cause faults
        !           735:  * It is assumed that the kernel has nothing at
        !           736:  * less than KERNELBASE in the virtual address space.
        !           737:  */
        !           738: | Return length of user string         _fustrlen(address)
        !           739:        ENTRY(fustrlen)
        !           740:        movl    #fsuerr,_u+U_LOFAULT    | catch a fault if and when
        !           741:        movl    sp@(4),a0               | get address
        !           742:        movl    #KERNELBASE-1,a1
        !           743: 1:
        !           744:        cmpl    a1,a0                   | check address range
        !           745:        jhi     fsuerr                  | jmp if greater than
        !           746:        tstb    a0@+                    | is it 0
        !           747:        jne     1b
        !           748:        movl    a0,d0
        !           749:        subl    sp@(4),d0               | compute difference
        !           750:        clrl    _u+U_LOFAULT            | clear lofault
        !           751:        rts
        !           752: 
        !           753: | Fetch user byte              _fubyte(address)
        !           754:        ENTRY2(fubyte,fuibyte)
        !           755:        movl    #fsuerr,_u+U_LOFAULT    | catch a fault if and when
        !           756:        movl    sp@(4),a0               | get address
        !           757:        cmpl    #KERNELBASE-1,a0        | check address range
        !           758:        jhi     fsuerr                  | jmp if greater than
        !           759:        movb    a0@,d0                  | get the byte
        !           760:        andl    #0xFF,d0
        !           761:        clrl    _u+U_LOFAULT            | clear lofault
        !           762:        rts
        !           763: 
        !           764: 
        !           765: | Fetch user (short) word:      _fusword(address)
        !           766:        ENTRY(fusword)
        !           767:        movl    #fsuerr,_u+U_LOFAULT    | catch a fault if and when
        !           768:        movl    sp@(4),a0               | get address
        !           769:        cmpl    #KERNELBASE-2,a0        | check address range
        !           770:        jhi     fsuerr                  | jmp if greater than
        !           771:        movw    a0@,d0                  | get the word
        !           772:        andl    #0xFFFF,d0
        !           773:        clrl    _u+U_LOFAULT            | clear lofault
        !           774:        rts
        !           775: 
        !           776: | Fetch user (long) word:      _fuword(address)
        !           777:        ENTRY2(fuword,fuiword)
        !           778:        movl    #fsuerr,_u+U_LOFAULT    | catch a fault if and when
        !           779:        movl    sp@(4),a0               | get address
        !           780:        cmpl    #KERNELBASE-4,a0        | check address range
        !           781:        jhi     fsuerr                  | jmp if greater than
        !           782:        movl    a0@,d0                  | get the long word
        !           783:        clrl    _u+U_LOFAULT            | clear lofault
        !           784:        rts
        !           785: 
        !           786: | Set user byte:               _subyte(address, value)
        !           787:        ENTRY2(subyte,suibyte)
        !           788:        movl    #fsuerr,_u+U_LOFAULT    | catch a fault if and when
        !           789:        movl    sp@(4),a0               | get address
        !           790:        cmpl    #KERNELBASE-1,a0        | check address range
        !           791:        jhi     fsuerr                  | jmp if greater than
        !           792:        movb    sp@(8+3),a0@            | set the byte
        !           793:        clrl    d0                      | indicate success
        !           794:        clrl    _u+U_LOFAULT            | clear lofault
        !           795:        rts
        !           796: 
        !           797: | Set user short word:         _susword(address, value)
        !           798:        ENTRY(susword)
        !           799:        movl    #fsuerr,_u+U_LOFAULT    | catch a fault if and when
        !           800:        movl    sp@(4),a0               | get address
        !           801:        cmpl    #KERNELBASE-2,a0        | check address range
        !           802:        jhi     fsuerr                  | jmp if greater than
        !           803:        movw    sp@(8+2),a0@            | set the word
        !           804:        clrl    d0                      | indicate success
        !           805:        clrl    _u+U_LOFAULT            | clear lofault
        !           806:        rts
        !           807: 
        !           808: | Set user (long) word:                _suword(address, value)
        !           809:        ENTRY2(suword,suiword)
        !           810:        movl    #fsuerr,_u+U_LOFAULT    | catch a fault if and when
        !           811:        movl    sp@(4),a0               | get address
        !           812:        cmpl    #KERNELBASE-4,a0        | check address range
        !           813:        jhi     fsuerr                  | jmp if greater than
        !           814:        movl    sp@(8+0),a0@            | set the long word
        !           815:        clrl    d0                      | indicate success
        !           816:        clrl    _u+U_LOFAULT            | clear lofault
        !           817:        rts
        !           818: 
        !           819: fsuerr:
        !           820:        movl    #-1,d0                  | return error
        !           821:        clrl    _u+U_LOFAULT            | clear lofault
        !           822:        rts
        !           823: 
        !           824: /*
        !           825:  * copyout() - except for _u+U_LOFAULT and address
        !           826:  * checking this is just bcopy().
        !           827:  */
        !           828:        ENTRY(copyout)
        !           829:        movl    #cpctxerr,_u+U_LOFAULT  | catch faults
        !           830:        movl    sp@(4),a0
        !           831:        movl    sp@(8),a1
        !           832:        movl    sp@(12),d0
        !           833:        jle     7f                      | leave if ridiculous count
        !           834: copyoutcheck:
        !           835:        movl    a1,d1                   | get starting address
        !           836:        cmpl    #KERNELBASE,d1          | check starting address
        !           837:        jpl     cpctxerr                | jmp on error
        !           838:        addl    d0,d1                   | compute ending address
        !           839:        cmpl    #KERNELBASE,d1          | check ending address
        !           840:        jhi     cpctxerr                | jmp on error
        !           841:        cmpl    d1,a1                   | check for wrap around
        !           842:        jhi     cpctxerr                | jmp on error
        !           843: /* If from address is odd, move one byte to make it even */
        !           844:        movl    a0,d1
        !           845:        btst    #0,d1
        !           846:        jeq     1f                      | even, skip
        !           847:        movb    a0@+,a1@+               | move the byte
        !           848:        subql   #1,d0                   | decrement count
        !           849: /* Now if to address is odd, we have to do byte-by-byte moves */
        !           850: 1:     movl    a1,d1
        !           851:        btst    #0,d1
        !           852:        jne     2f                      | if odd go do bytes
        !           853: /* Now both addresses are even and we can do long moves */
        !           854:        rorl    #2,d0                   | get count as longs
        !           855:        jra     5f                      | enter loop at bottom
        !           856: 4:     movl    a0@+,a1@+               | move a long
        !           857: 5:     dbra    d0,4b                   | do until --longcount < 0
        !           858:        roll    #2,d0
        !           859:        andl    #3,d0                   | count %= sizeof (long)
        !           860:        jra     2f
        !           861: /*
        !           862:  * Here for the last 3 bytes or if we have to do byte-by-byte moves
        !           863:  * because the pointers were relatively odd
        !           864:  */
        !           865: 3:     movb    a0@+,a1@+               | move a byte
        !           866: 2:     dbra    d0,3b                   | until --count < 0
        !           867: 7:     clrl    d0                      | indicate success
        !           868:        clrl    _u+U_LOFAULT
        !           869:        rts                             | and return
        !           870: 
        !           871: /*
        !           872:  * copyin() - except for _u+U_LOFAULT and address
        !           873:  * checking this is just bcopy().
        !           874:  */
        !           875:        ENTRY(copyin)
        !           876:        movl    #cpctxerr,_u+U_LOFAULT  | catch faults
        !           877:        movl    sp@(4),a0
        !           878:        movl    sp@(8),a1
        !           879:        movl    sp@(12),d0
        !           880:        jle     7f                      | leave if ridiculous count
        !           881: copyincheck:
        !           882:        movl    a0,d1                   | get starting address
        !           883:        cmpl    #KERNELBASE,d1          | check starting address
        !           884:        jpl     cpctxerr                | jmp on error
        !           885:        addl    d0,d1                   | compute ending address
        !           886:        cmpl    #KERNELBASE,d1          | check ending address
        !           887:        jhi     cpctxerr                | jmp on error
        !           888:        cmpl    d1,a0                   | check for wrap around
        !           889:        jhi     cpctxerr                | jmp on error
        !           890: /* If from address is odd, move one byte to make it even */
        !           891:        movl    a0,d1
        !           892:        btst    #0,d1
        !           893:        jeq     1f                      | even, skip
        !           894:        movb    a0@+,a1@+               | move the byte
        !           895:        subql   #1,d0                   | decrement count
        !           896: /* Now if to address is odd, we have to do byte-by-byte moves */
        !           897: 1:     movl    a1,d1
        !           898:        btst    #0,d1
        !           899:        jne     2f                      | if odd go do bytes
        !           900: /* Now both addresses are even and we can do long moves */
        !           901:        rorl    #2,d0                   | get count as longs
        !           902:        jra     5f                      | enter loop at bottom
        !           903: 4:     movl    a0@+,a1@+               | move a long
        !           904: 5:     dbra    d0,4b                   | do until --longcount < 0
        !           905:        roll    #2,d0
        !           906:        andl    #3,d0                   | count %= sizeof (long)
        !           907:        jra     2f
        !           908: /*
        !           909:  * Here for the last 3 bytes or if we have to do byte-by-byte moves
        !           910:  * because the pointers were relatively odd
        !           911:  */
        !           912: 3:     movb    a0@+,a1@+               | move a byte
        !           913: 2:     dbra    d0,3b                   | until --count < 0
        !           914: 7:     clrl    d0                      | indicate success
        !           915:        clrl    _u+U_LOFAULT
        !           916:        rts                             | and return
        !           917: 
        !           918: cpctxerr:
        !           919:        movl    #EFAULT,d0              | return error
        !           920:        clrl    _u+U_LOFAULT            | clear lofault
        !           921:        rts
        !           922: 
        !           923: /*
        !           924:  * fetch user longwords  -- used by syscall -- faster than copyin
        !           925:  * Doesn't worry about alignment of transfer, let the 68020 worry
        !           926:  * about that - we won't be doing more than 8 long words anyways.
        !           927:  * Use copyin to do more careful checking if we are real close.
        !           928:  * fulwds(uadd, sadd, nlwds)
        !           929:  */
        !           930:        ENTRY(fulwds)
        !           931:        movl    #cpctxerr,_u+U_LOFAULT  | catch a fault if and when
        !           932:        movl    sp@(4),a0               | user address
        !           933:        movl    sp@(8),a1               | system address
        !           934:        movl    sp@(12),d0              | number of words
        !           935:        cmpl    #KERNELBASE-8*4,a0      | check starting address
        !           936:        jls     1f                      | enter loop at bottom if ok
        !           937:        lsll    #2,d0                   | convert to byte count
        !           938:        jra     copyincheck             | let copyin code handle
        !           939: 2:     movl    a0@+,a1@+               | get longword
        !           940: 1:     dbra    d0,2b                   | loop on count
        !           941:        clrl    d0                      | indicate success
        !           942:        clrl    _u+U_LOFAULT            | clear lofault
        !           943:        rts
        !           944: 
        !           945: /*
        !           946:  * Get/Set vector base register
        !           947:  */
        !           948:        ENTRY(getvbr)
        !           949:        movc    vbr,d0
        !           950:        rts
        !           951: 
        !           952:        ENTRY(setvbr)
        !           953:        movl    sp@(4),d0
        !           954:        movc    d0,vbr
        !           955:        rts
        !           956: 
        !           957: /*
        !           958:  * Enter the monitor -- called for console abort
        !           959:  */
        !           960:        ENTRY(montrap)
        !           961:        jsr     _startnmi               | enable monitor nmi routine
        !           962:        movl    sp@(4),a0               | address to trap to
        !           963:        clrw    sp@-                    | dummy VOR
        !           964:        pea     0f                      | return address
        !           965:        movw    sr,sp@-                 | current sr
        !           966:        jra     a0@                     | trap to monitor
        !           967: 0:
        !           968:        jsr     _stopnmi                | disable monitor nmi routine
        !           969:        rts
        !           970: 
        !           971: /*
        !           972:  * Read the ID prom.  This is mapped from IDPROMBASE for IDPROMSIZE
        !           973:  * bytes in the FC_MAP address space for byte access only.  Assumes
        !           974:  * that the sfc has already been set to FC_MAP.
        !           975:  */
        !           976:        ENTRY(getidprom)
        !           977:        movl    sp@(4),a0               | address to copy bytes to
        !           978:        lea     IDPROMBASE,a1           | select id prom
        !           979:        movl    #(IDPROMSIZE-1),d1      | byte loop counter
        !           980: 0:     movsb   a1@+,d0                 | get a byte
        !           981:        movb    d0,a0@+                 | save it
        !           982:        dbra    d1,0b                   | and loop
        !           983:        rts
        !           984: 
        !           985: /*
        !           986:  * Enable and disable video.
        !           987:  */
        !           988:        ENTRY(setvideoenable)
        !           989: 1:     
        !           990:        tstl    sp@(4)                  | is bit on or off
        !           991:        jeq     2f
        !           992:        orb     #ENA_VIDEO,_enablereg   | enable video
        !           993:        jra     3f
        !           994: 2:
        !           995:        andb    #~ENA_VIDEO,_enablereg  | disable video
        !           996: 3:
        !           997:        movb    _enablereg,d0           | get it in a register
        !           998:        movsb   d0,ENABLEREG            | put enable register back
        !           999:        cmpb    _enablereg,d0           | see if someone higher changed it
        !          1000:        bne     1b                      | if so, try again
        !          1001:        rts
        !          1002: 
        !          1003: /*
        !          1004:  * Enable and disable video Copy.
        !          1005:  */
        !          1006:        ENTRY(setcopyenable)
        !          1007: 1:     
        !          1008:        tstl    sp@(4)                  | is bit on or off
        !          1009:        jeq     2f
        !          1010:        orb     #ENA_COPY,_enablereg    | enable video copy
        !          1011:        jra     3f
        !          1012: 2:
        !          1013:        andb    #~ENA_COPY,_enablereg   | disable copy
        !          1014: 3:
        !          1015:        movb    _enablereg,d0           | get it in a register
        !          1016:        movsb   d0,ENABLEREG            | put enable register back
        !          1017:        cmpb    _enablereg,d0           | see if someone higher changed it
        !          1018:        bne     1b                      | if so, try again
        !          1019:        rts
        !          1020: 
        !          1021: /*
        !          1022:  * Enable and disable video interrupt.
        !          1023:  */
        !          1024:        ENTRY(setintrenable)
        !          1025:        tstl    sp@(4)                  | is bit on or off
        !          1026:        jeq     1f
        !          1027:        orb     #IR_ENA_VID4,INTERREG   | enable video interrupt
        !          1028:        rts
        !          1029: 1:     
        !          1030:        andb    #~IR_ENA_VID4,INTERREG  | disable
        !          1031:        rts
        !          1032: 
        !          1033: /*
        !          1034:  * Read the bus error register
        !          1035:  */
        !          1036:        ENTRY(getbuserr)
        !          1037:        clrl    d0
        !          1038:        movsb   BUSERRREG,d0            | get the buserr register
        !          1039:        rts
        !          1040: 
        !          1041: /*
        !          1042:  * Set the fpp registers to the u area values
        !          1043:  */
        !          1044:        ENTRY(setfppregs)
        !          1045:        tstw    _fppstate               | is fpp present and enabled?
        !          1046:        jle     1f                      | branch if not
        !          1047:        fmovem  _u+U_FPS_REGS,fp0-fp7   | set fp data registers
        !          1048:        fmovem  _u+U_FPS_CTRL,fpc/fps/fpi | set control registers
        !          1049: 1:
        !          1050:        rts
        !          1051: 
        !          1052: /*
        !          1053:  * Define some variables used by post-modem debuggers
        !          1054:  * to help them work on kernels with changing structures.
        !          1055:  */
        !          1056:        .globl UPAGES_DEBUG, KERNELBASE_DEBUG, VADDR_MASK_DEBUG
        !          1057:        .globl PGSHIFT_DEBUG, SLOAD_DEBUG
        !          1058: 
        !          1059: UPAGES_DEBUG           = UPAGES
        !          1060: KERNELBASE_DEBUG       = KERNELBASE
        !          1061: VADDR_MASK_DEBUG       = 0x0fffffff
        !          1062: PGSHIFT_DEBUG          = PGSHIFT
        !          1063: SLOAD_DEBUG            = SLOAD

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.