Annotation of coherent/d/PS2_KERNEL/i286/as2.s, revision 1.1

1.1     ! root        1: / $Header: /kernel/kersrc/i286/RCS/as2.s,v 1.1 92/07/17 15:21:20 bin Exp Locker: bin $
        !             2: /
        !             3: / (lgl-
        !             4: /      The information contained herein is a trade secret of Mark Williams
        !             5: /      Company, and  is confidential information.  It is provided  under a
        !             6: /      license agreement,  and may be  copied or disclosed  only under the
        !             7: /      terms of  that agreement.  Any  reproduction or disclosure  of this
        !             8: /      material without the express written authorization of Mark Williams
        !             9: /      Company or persuant to the license agreement is unlawful.
        !            10: /
        !            11: /      COHERENT Version 2.3.37
        !            12: /      Copyright (c) 1982, 1983, 1984.
        !            13: /      An unpublished work by Mark Williams Company, Chicago.
        !            14: /      All rights reserved.
        !            15: / -lgl)
        !            16: ////////
        !            17: /
        !            18: / Machine language assist for
        !            19: / Coherent on the IBM personal computer.
        !            20: /
        !            21: / $Log:        as2.s,v $
        !            22: / Revision 1.1  92/07/17  15:21:20  bin
        !            23: / Initial revision
        !            24: /
        !            25: / Revision 1.3  92/01/21  16:10:37  hal
        !            26: / Use read_cmos_ routine.
        !            27: / Allows merged 386 C code compatibility.
        !            28: / 
        !            29: / Revision 1.2  91/06/06  18:14:46  norm
        !            30: / Get memory size by reading CMOS.
        !            31: 
        !            32: / Revision 1.3 88/08/05  15:37:32      src
        !            33: / AMD 286 hardware specific fixes removed - hardware now correct.
        !            34: / Virtual Selector F000 initialized to access ROM at F0000.
        !            35: / Normal kernel stack now used during initialization.
        !            36: / 
        !            37: / Revision 1.2 88/06/29  19:05:31      src
        !            38: / AT Coherent can now come up in real-mode by patching 'realmode' variable.
        !            39: / 
        !            40: / Revision 1.1 88/03/24  17:33:18      src
        !            41: / Initial revision
        !            42: / 
        !            43: / 88/03/10     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !            44: / Numerous temporary fixes due to AMD 286 chip being buggy in protected mode.
        !            45: / These partial fixes will be removed once all CPU's are replaced.
        !            46: /
        !            47: / 88/03/07     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !            48: / Obsolete video() function deleted - not used, or usable in protected mode.
        !            49: / Auto-increment mode no longer assumed, but enforced on block moves.
        !            50: /
        !            51: / 88/03/04     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !            52: / Memory sizing now flushes instruction pipeline before read-verify.
        !            53: / Otherwise bus capacitance on some machines gives invalid memory indication.
        !            54: / plrcopy, prlcopy, pclear, upcopy, kpcopy, pucopy, and pkcopy now ensure
        !            55: / registers DS and ES refer to kernel data before calling ptov() or vrelse().
        !            56: / MAXMEM variable added to specify maximum low memory in clicks.
        !            57: /
        !            58: / 87/11/22     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !            59: / Added check for extended memory in protected mode.
        !            60: /
        !            61: / 87/11/14     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !            62: / boot() now requests 8042 controller to initiate processor reset.
        !            63: /
        !            64: / 87/11/05     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !            65: / slrcopy/srlcopy/sclear renamed plrcopy/prlcopy/pclear and moved here.
        !            66: /
        !            67: / 87/10/27     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !            68: / System stack/data segments now setup here rather than in as1.s
        !            69: / System stack/data moved to next 128 byte boundary for protected mode.
        !            70: /
        !            71: / 87/08/31     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !            72: / Timer channel 1 now reprogrammed for memory refresh.
        !            73: /
        !            74: / 87/07/08     Allan Cornish           /usr/src/sys/i8086/ibm_at/as2.s
        !            75: / Timer chip now programmed for 100 hz clock interrupt rather than 20 hz.
        !            76: /
        !            77: ////////
        !            78: 
        !            79: EFAULT =       14                      / Bad argument
        !            80: EXTMEML =      0x17                    / Ext. mem size (low) offset in CMOS
        !            81: EXTMEMH =      0x18                    /               (high)
        !            82: PFLAGS =       0x22                    / Offset int PROC.
        !            83: PFKERN =       0x80                    / Kernel process flag bit.
        !            84: PIC    =       0x20                    / 8259 CSR  I/O port.
        !            85: PICM   =       0x21                    / 8259 IMR  I/O port.
        !            86: PIT    =       0x40                    / 8253 base I/O port.
        !            87: KBDATA =       0x60                    / 8042 keyboard mpu data I/O port.
        !            88: KBCTRL =       0x64                    / 8042 keyboard mpu ctrl I/O port.
        !            89: CMOSA  =       0x70                    / Real-time Clock/CMOS addr I/O port.
        !            90: CMOSD  =       0x71                    / Real-time Clock/CMOS data I/O port.
        !            91: SPIC   =       0xA0                    / Slave 8259 CSR I/O port.
        !            92: SPICM  =       0xA1                    / Slave 8259 IMR I/O port.
        !            93: UPASIZE        =       1024                    / Size of uproc and stack
        !            94: 
        !            95: ////////
        !            96: /
        !            97: / System entry point. Under PC-DOS,
        !            98: / which thinks that Coherent is just a large
        !            99: / user program, the code is offset by 0x100
        !           100: / to allow space for the base page.
        !           101: /
        !           102: ////////
        !           103: 
        !           104:        .blkb   0x0100                  / PC-DOS base page. | MLK --\
        !           105:        call    iabios_r_   / Before we go into protected mode, init the abios
        !           106: 
        !           107:        cli                             / No interrupts, please.
        !           108:        int     0x11                    / Obtain int 11 value before printf().
        !           109:        mov     cs:val11, ax            /Use boot block's stack for last time.
        !           110: /
        !           111: / Enable the A20 address line, which is normally disabled by the ROM BIOS.
        !           112: / This line is under the control of the 8042 keyboard interface controller.
        !           113: /
        !           114:        sub     cx, cx                  /
        !           115: 0:     inb     al, KBCTRL              / Wait for 8042 input buffer to empty.
        !           116:        testb   al, $2                  /
        !           117:        loopne  0b                      /
        !           118:        jmp     .+2             / DELAY /
        !           119:                                        /
        !           120:        movb    al, $0xD1               / Request next output byte to be
        !           121:        outb    KBCTRL, al              /       sent to the 8042 output port.
        !           122:                                        /
        !           123:        sub     cx, cx                  /
        !           124: 0:     inb     al, KBCTRL              / Wait for 8042 input buffer to empty.
        !           125:        testb   al, $2                  /
        !           126:        loopne  0b                      /
        !           127:        jmp     .+2             / DELAY /
        !           128:                                        /
        !           129:        movb    al, $0xDF               / Enable A20 address line.
        !           130:        outb    KBDATA, al              / See Page 1-44, IBM-AT Tech Ref.
        !           131:                                        /
        !           132:        sub     cx, cx                  /
        !           133: 0:     inb     al, KBCTRL              / Wait for 8042 input buffer to empty.
        !           134:        testb   al, $2                  / NOTE: A20 not enabled for up to 20 us.
        !           135:        loopne  0b                      /
        !           136: 
        !           137: /
        !           138: / Reprogram the 8253 timer so that channel 0, 
        !           139: / which is used as the clock, interrupts at exactly
        !           140: / 100 HZ, instead of 18.2 HZ.
        !           141: /
        !           142:        movb    al, $0x36               / Timer 0, LSB, MSB, mode 3
        !           143:        outb    PIT+3, al
        !           144:        jmp     .+2             / DELAY /
        !           145:        jmp     .+2             / DELAY /
        !           146:        movb    al, $0x9C               / Lsb of 59659/5 = 11932
        !           147:        outb    PIT, al
        !           148:        jmp     .+2             / DELAY /
        !           149:        jmp     .+2             / DELAY /
        !           150:        movb    al, $0x2E               / Msb of 59659/5 = 11932
        !           151:        outb    PIT, al
        !           152:        jmp     .+2             / DELAY /
        !           153:        jmp     .+2             / DELAY /
        !           154: 
        !           155: / Reprogram channel 1 on the 8253 timer which is used for memory refresh.
        !           156: /      movb    al, $0x54               / Timer 1, LSB, mode 2
        !           157: /      outb    PIT+3, al
        !           158: /      jmp     .+2             / DELAY /
        !           159: /      jmp     .+2             / DELAY /
        !           160: /      movb    al, $18                 / LSB of 18.
        !           161: /      outb    PIT+1, al
        !           162: /      jmp     .+2             / DELAY /
        !           163: /      jmp     .+2             / DELAY /
        !           164: 
        !           165: / Reprogram the 1st programmable interrupt controller.
        !           166: / It's default vector table collides with iAPX 286 protection vectors.
        !           167: 
        !           168: /      movb    al, $0x11               / ICW1 - edge, master, ICW4
        !           169:        movb    al, $0x19               / ICW1 - level, master, ICW4 MLK
        !           170:        outb    PIC, al
        !           171:        jmp     .+2             / DELAY /
        !           172:        jmp     .+2             / DELAY /
        !           173:        movb    al, $0x20               / ICW2 - Reserve 1st 32 vectors for 286
        !           174:        outb    PICM, al
        !           175:        jmp     .+2             / DELAY /
        !           176:        jmp     .+2             / DELAY /
        !           177:        movb    al, $0x04               / ICW3 - master level 2
        !           178:        outb    PICM, al
        !           179:        jmp     .+2             / DELAY /
        !           180:        jmp     .+2             / DELAY /
        !           181:        movb    al, $0x01               / ICW4 - 8086 mode, master.
        !           182:        outb    PICM, al
        !           183:        jmp     .+2             / DELAY /
        !           184:        jmp     .+2             / DELAY /
        !           185: 
        !           186:        movb    al, $0xFE               / Disable interrupts from master PIC.
        !           187:        outb    PICM, al                / (except for clock interrupt).
        !           188: 
        !           189:        movb    al, $0xFF
        !           190:        outb    SPICM, al               / Disable interrupts from slave PIC.
        !           191: 
        !           192: 
        !           193: / Set up all trap vectors.
        !           194: / The machine traps all have their own
        !           195: / linkages. We have to steal the clock from
        !           196: / the ROM, because the stacks might get switched
        !           197: / during the INT 1C, and the EOI would get sent
        !           198: / to the 8259 at a strange time.
        !           199: 
        !           200:        sub     ax, ax                  / Map DS over the 8088
        !           201:        mov     ds, ax                  / vector area.
        !           202: 
        !           203:        mov     0x0000, $trap0          / Divide error vector
        !           204:        mov     0x0002, cs
        !           205:        mov     0x0004, $trap1          / Single step.
        !           206:        mov     0x0006, cs
        !           207:        mov     0x0008, $trap2          / NMI
        !           208:        mov     0x000A, cs
        !           209:        mov     0x000C, $trap3          / INT 3 (break)
        !           210:        mov     0x000E, cs
        !           211:        mov     0x0010, $trap4          / Overflow.
        !           212:        mov     0x0012, cs
        !           213:        mov     0x0014, $trap5          / Bound range exceeded.
        !           214:        mov     0x0016, cs
        !           215:        mov     0x0018, $trap6          / Invalid Opcode
        !           216:        mov     0x001A, cs
        !           217:        mov     0x001C, $trap7          / Processor extension not available
        !           218:        mov     0x001E, cs
        !           219:        mov     0x0020, $trap8          / Double exception detected.
        !           220:        mov     0x0022, cs
        !           221:        mov     0x0024, $trap9          / Processor extension segment overrun.
        !           222:        mov     0x0026, cs
        !           223:        mov     0x0028, $trap10         / Invalid task state segment.
        !           224:        mov     0x002A, cs
        !           225:        mov     0x002C, $trap11         / Segment not present.
        !           226:        mov     0x002E, cs
        !           227:        mov     0x0030, $trap12         / Stack segment overrun or not present.
        !           228:        mov     0x0032, cs
        !           229:        mov     0x0034, $trap13         / General protection.
        !           230:        mov     0x0036, cs
        !           231: 
        !           232:        mov     0x0080, $clk_ps         / Clock for PS2  MLK
        !           233: /      mov     0x0080, $clk            / Clock.
        !           234:        mov     0x0082, cs
        !           235:        mov     0x0084, $dev1           / Device 1
        !           236:        mov     0x0086, cs
        !           237:        mov     0x0088, $dev9           / Device 2 maps into Device 9
        !           238:        mov     0x008A, cs
        !           239:        mov     0x008C, $dev3           / Device 3
        !           240:        mov     0x008E, cs
        !           241:        mov     0x0090, $dev4           / Device 4
        !           242:        mov     0x0092, cs
        !           243:        mov     0x0094, $dev5           / Device 5
        !           244:        mov     0x0096, cs
        !           245:        mov     0x0098, $dev6           / Device 6
        !           246:        mov     0x009A, cs
        !           247:        mov     0x009C, $dev7           / Device 7
        !           248:        mov     0x009E, cs
        !           249: 
        !           250:        mov     0x01C0, $dev8           / Device 8
        !           251:        mov     0x01C2, cs
        !           252:        mov     0x01C4, $dev9           / Device 9
        !           253:        mov     0x01C6, cs
        !           254:        mov     0x01C8, $dev10          / Device 10
        !           255:        mov     0x01CA, cs
        !           256:        mov     0x01CC, $dev11          / Device 11
        !           257:        mov     0x01CE, cs
        !           258:        mov     0x01D0, $dev12          / Device 12
        !           259:        mov     0x01D2, cs
        !           260:        mov     0x01D4, $dev13          / Device 13
        !           261:        mov     0x01D6, cs
        !           262:        mov     0x01D8, $dev14          / Device 14
        !           263:        mov     0x01DA, cs
        !           264:        mov     0x01DC, $dev15          / Device 15
        !           265:        mov     0x01DE, cs
        !           266: 
        !           267:        mov     bx, $0x0200             / INT 80 (sys 0)
        !           268: 0:     mov     (bx), $syc              / Set up the system call
        !           269:        mov     2(bx), cs               / trap vector.
        !           270:        add     bx, $4                  / Move to next vector and
        !           271:        cmp     bx, $0x0400             / loop until all
        !           272:        jb      0b                      / vectors are reset.
        !           273: 
        !           274: / Set up the system stack and data segments, by looking at the size of
        !           275: / the text and adding this to the base address already in the CS.
        !           276: / Relocate the stack and data to a 128 byte boundary.
        !           277: 
        !           278:        mov     ax, $etext_+15          / End of text segment
        !           279:        shr     ax, $4                  / Convert to paragraphs.
        !           280:        mov     cx, cs                  / Get code segment base.
        !           281:        add     ax, cx                  /
        !           282:        mov     ds, ax                  / Current data segment
        !           283:        add     ax, $31                 / Allow virtual-physical alignment
        !           284:        and     ax, $~31                /       [use 512 byte, need 128 byte]
        !           285:                                        /
        !           286:        cmp     realmode_, $0           / Virtual Addressing enabled?
        !           287:        jne     0f                      /
        !           288:        mov     idtsel_, ax             / Interrupt descriptor table [2 Kbytes]
        !           289:        add     ax, $0x0080             /       2K >> 4
        !           290:        mov     gdtsel_, ax             / Global descriptor table [64 Kbytes]
        !           291:        add     ax, $0x1000             /       64K >> 4
        !           292: 0:                                     /
        !           293:        mov     es, ax                  /
        !           294:        mov     si, $edata_-1           / Copy data to new location, backwards.
        !           295:        mov     di, $edata_-1           /
        !           296:        mov     cx, $edata_             /
        !           297:        std                             /
        !           298:        rep                             /
        !           299:        movsb                           /
        !           300:                                        /
        !           301:        mov     ds, ax                  / Update data segment,
        !           302:        mov     ss, ax                  / and stack segment.
        !           303:        mov     sp, $u_+UPASIZE-32      / Set up initial stack.
        !           304:        mov     scs_, cs                / Save code segment and
        !           305:        mov     sds_, ds                / data segment bases.
        !           306:        mov     cs:cds, ds              / For interrupts.
        !           307: 
        !           308: / Size up memory, starting just above the system.
        !           309: / The memory is cleared, because somebody has to do a write
        !           310: / to set up the parity bits.
        !           311: 
        !           312:        mov     di, $edata_             / Clear at edata...
        !           313:        mov     cx, $512                / for 1 Kbyte
        !           314:        sub     ax, ax
        !           315:        cld
        !           316:        rep
        !           317:        stosw
        !           318: 
        !           319:        mov     bp, $edata_+1023        / Compute base.
        !           320:        shr     bp, $4
        !           321:        add     bp, sds_
        !           322:        shr     bp, $6                  / Round down to a Kbyte boundary
        !           323:        shl     bp, $6                  / so's we're in sync.
        !           324: 
        !           325: 0:     sub     di, di                  / Destination.
        !           326:        mov     es, bp                  / Set extra segment and
        !           327:        mov     es:(di), ax             / clear a word.
        !           328:        jmp     .+2             / FLUSH /
        !           329:        cmp     es:(di), ax             / Should be zero now.
        !           330:        jne     0f                      / Branch if memory end
        !           331: 
        !           332:        mov     cx, $512                / 1K bytes, in words.
        !           333:        cld
        !           334:        rep
        !           335:        stosw                           / Clear this 1K
        !           336:        add     bp, $64                 / Move along by 1K
        !           337:        cmp     bp, MAXMEM
        !           338:        jb      0b                      / If not at video ram yet
        !           339: 
        !           340: 0:     mov     es, sds_                / Map extra.
        !           341: 
        !           342:        mov     ax, bp                  / Calculate top of low memory.
        !           343:        rol     ax, $4                  /
        !           344:        mov     dx, ax                  /
        !           345:        and     ax, $0xFFF0             /
        !           346:        xor     dx, ax                  /
        !           347: 
        !           348:        cmp     realmode_, $0           / Real Addressing Mode?
        !           349:        je      0f                      /
        !           350:        mov     coretop_, ax            / Yes, Record top of memory,
        !           351:        mov     coretop_+2, dx          /
        !           352:        jmp     start                   / and bring up system.
        !           353: 0:
        !           354:        mov     holebot_, ax            / Record bottom of I/O memory.
        !           355:        mov     holebot_+2, dx          /
        !           356: 
        !           357:        mov     ax, gdtsel_             / Format global descriptor table map.
        !           358:        rol     ax, $4                  /
        !           359:        mov     dx, ax                  /
        !           360:        and     ax, $0xFFF0             /
        !           361:        xor     dx, ax                  /
        !           362:        mov     gdtmap_+0, $0xFFFF      / Limit: 64K bytes.
        !           363:        mov     gdtmap_+2, ax           /
        !           364:        mov     gdtmap_+4, dx           /
        !           365:                                        /
        !           366:        sub     ax, ax                  / Erase global descriptor table.
        !           367:        mov     cx, $0x8000             /       [32K words = 64K bytes]
        !           368:        mov     es, gdtsel_             /
        !           369:        sub     di, di                  /
        !           370:        cld                             /
        !           371:        rep                             /
        !           372:        stosw                           /
        !           373:                                        /
        !           374:        mov     ax, idtsel_             / Format interrupt descriptor table map
        !           375:        rol     ax, $4                  /
        !           376:        mov     dx, ax                  /
        !           377:        and     ax, $0xFFF0             /
        !           378:        xor     dx, ax                  /
        !           379:        mov     idtmap_+0, $2047        / Limit: 2K bytes.
        !           380:        mov     idtmap_+2, ax           /
        !           381:        mov     idtmap_+4, dx           /
        !           382:                                        /
        !           383:        sub     ax, ax                  / Erase interrupt descriptor table.
        !           384:        mov     cx, $1024               /       [1K words = 2K bytes]
        !           385:        mov     es, idtsel_             /
        !           386:        sub     di, di                  /
        !           387:        cld                             /
        !           388:        rep                             /
        !           389:        stosw                           /
        !           390:                                        /
        !           391:        mov     es, gdtsel_             /
        !           392:        mov     di, cs                  / Define kernel code global selector.
        !           393:        mov     ax, $etext_-1           /       Limit: etext.
        !           394:        stosw                           /
        !           395:        mov     dx, $0x9A00             /       Flags: Present, executable.
        !           396:        mov     ax, cs                  /       Base:  cs << 4.
        !           397:        rol     ax, $4                  /
        !           398:        xor     dx, ax                  /
        !           399:        and     ax, $0xFFF0             /
        !           400:        stosw                           /
        !           401:        xor     ax, dx                  /
        !           402:        stosw                           /
        !           403:        sub     ax, ax                  /
        !           404:        stosw                           /
        !           405:                                        /
        !           406:        mov     di, ss                  / Define kernel data global selector.
        !           407:        mov     ax, $0xFFFF             /       Limit: 64K bytes.
        !           408:        stosw                           /
        !           409:        mov     dx, $0x9200             /       Flags: Present, writable.
        !           410:        mov     ax, ss                  /       Base:  ss << 4.
        !           411:        rol     ax, $4                  /
        !           412:        xor     dx, ax                  /
        !           413:        and     ax, $0xFFF0             /
        !           414:        stosw                           /
        !           415:        xor     ax, dx                  /
        !           416:        stosw                           /
        !           417:        sub     ax, ax                  /
        !           418:        stosw                           /
        !           419:                                        /
        !           420:        mov     di, $8                  / Define task state segment selector[8]
        !           421:        mov     ax, $43                 /       Limit: 44 bytes.
        !           422:        stosw                           /
        !           423:        mov     dx, $0x8100             /       Flags: Present, avail tss seg.
        !           424:        mov     ax, ss                  /       Base:  (ss << 4) + &tss.
        !           425:        rol     ax, $4                  /
        !           426:        xor     dx, ax                  /
        !           427:        and     ax, $0xFFF0             /
        !           428:        xor     dx, ax                  /
        !           429:        add     ax, $tss_               /
        !           430:        adc     dx, $0                  /
        !           431:        stosw                           /
        !           432:        mov     ax, dx                  /
        !           433:        stosw                           /
        !           434:        sub     ax, ax                  /
        !           435:        stosw                           /
        !           436:                                        /
        !           437:        mov     di, gdtsel_             / Define gdt access global selector.
        !           438:        mov     ax, $0xFFFF             /       Limit: 64K bytes.
        !           439:        stosw                           /
        !           440:        mov     dx, $0x9200             /       Flags: Present, writable.
        !           441:        mov     ax, gdtsel_             /       Base: gdtsel << 4.
        !           442:        rol     ax, $4                  /
        !           443:        xor     dx, ax                  /
        !           444:        and     ax, $0xFFF0             /
        !           445:        stosw                           /
        !           446:        xor     ax, dx                  /
        !           447:        stosw                           /
        !           448:        sub     ax, ax                  /
        !           449:        stosw                           /
        !           450:                                        /
        !           451:        mov     di, idtsel_             / Define idt access global selector.
        !           452:        mov     ax, $2047               /       Limit: 2K bytes.
        !           453:        stosw                           /
        !           454:        mov     dx, $0x9200             /       Flags: Present, writable.
        !           455:        mov     ax, idtsel_             /       Base: idtsel << 4.
        !           456:        rol     ax, $4                  /
        !           457:        xor     dx, ax                  /
        !           458:        and     ax, $0xFFF0             /
        !           459:        stosw                           /
        !           460:        xor     ax, dx                  /
        !           461:        stosw                           /
        !           462:        sub     ax, ax                  /
        !           463:        stosw                           /
        !           464:                                        /
        !           465:        mov     di, $0xB000             / Define video access global selector.
        !           466:        mov     ax, $0xFFFF             /       Limit: 64K bytes.
        !           467:        stosw                           /
        !           468:        mov     dx, $0x9200             /       Flags: Present, writable.
        !           469:        mov     ax, $0xB000             /       Base:  0xB000 << 4.
        !           470:        rol     ax, $4                  /
        !           471:        xor     dx, ax                  /
        !           472:        and     ax, $0xFFF0             /
        !           473:        stosw                           /
        !           474:        xor     ax, dx                  /
        !           475:        stosw                           /
        !           476:        sub     ax, ax                  /
        !           477:        stosw                           /
        !           478:                                        /
        !           479:        mov     di, $0xB800             / Define video access global selector.
        !           480:        mov     ax, $0x7FFF             /       Limit: 32 Kbytes.
        !           481:        stosw                           /
        !           482:        mov     dx, $0x9200             /       Flags: Present, writable.
        !           483:        mov     ax, $0xB800             /       Base:  0xB800 << 4.
        !           484:        rol     ax, $4                  /
        !           485:        xor     dx, ax                  /
        !           486:        and     ax, $0xFFF0             /
        !           487:        stosw                           /
        !           488:        xor     ax, dx                  /
        !           489:        stosw                           /
        !           490:        sub     ax, ax                  /
        !           491:        stosw                           /
        !           492: 
        !           493:        mov     di, $0xF000             / Define ROM access global selector.
        !           494:        mov     ax, $0xFFFF             /       Limit: 64 Kbytes.
        !           495:        stosw                           /
        !           496:        mov     dx, $0x9000             /       Flags: Present, read only.
        !           497:        mov     ax, $0xF000             /       Base:  0xF000 << 4.
        !           498:        rol     ax, $4                  /
        !           499:        xor     dx, ax                  /
        !           500:        and     ax, $0xFFF0             /
        !           501:        stosw                           /
        !           502:        xor     ax, dx                  /
        !           503:        stosw                           /
        !           504:        sub     ax, ax                  /
        !           505:        stosw                           /
        !           506: 
        !           507:        mov     es, idtsel_             / Map ES over the intr descr table.
        !           508:        sub     ax, ax                  / Map DS over the 8088 vector area.
        !           509:        mov     ds, ax                  /
        !           510:        sub     si, si                  /
        !           511:        sub     di, di                  /
        !           512:        mov     bx, cs                  / Make CS available for comparison.
        !           513:        mov     cx, $256                / Install 256 interrupt descriptors.
        !           514:                                        /
        !           515: 0:     lodsw                           / Copy interrupt IP
        !           516:        stosw                           /
        !           517:        lodsw                           / Copy interrupt CS
        !           518:        stosw                           /
        !           519:                                        /
        !           520:        cmp     ax, bx                  / Coherent interrupt handler?
        !           521:        mov     ax, $0x8600             /
        !           522:        je      1f                      /
        !           523:        sub     ax, ax                  / No, clear flags.
        !           524:                                        /
        !           525: 1:     stosw                           / Define IDT flags.
        !           526:        sub     ax, ax                  / Reserved IDT word.
        !           527:        stosw                           /
        !           528:        loop    0b                      / Repeat for all 256 entries.
        !           529:                                        /
        !           530:        mov     ax, ss                  / Restore data and extra segments.
        !           531:        mov     ds, ax                  /
        !           532:        mov     es, ax                  /
        !           533:                                        /
        !           534:        clts                            / Clear task switched flag.
        !           535:        lgdt    gdtmap_                 / Load global descriptor table map.
        !           536:        lidt    idtmap_                 / Load interrupt descriptor table map.
        !           537:                                        /
        !           538:        smsw    ax                      / Enter protected mode.
        !           539:        or      ax, $1                  /
        !           540:        lmsw    ax                      /
        !           541:        jmp     .+2                     / Clear pipeline.
        !           542:                                        /
        !           543:        mov     ax, $0x0008             / Load task state segment register.
        !           544:        ltr     ax                      /
        !           545:        sub     ax, ax                  / Load local descriptor table register.
        !           546:        lldt    ax                      /
        !           547:                                        /
        !           548:                                        /
        !           549:                                        / Register usage:
        !           550:                                        / DX:AX = extended mem physical addr.
        !           551:                                        / BX = scratch, then 0.
        !           552:                                        / SI = selector into extended memory.
        !           553:                                        / ES = selector into extended memory.
        !           554:                                        / DS = selector into global descr table
        !           555:                                        /
        !           556:        push    $EXTMEMH                / high byte of pair
        !           557:        call    read_cmos_              / result in ax
        !           558:        add     sp, $2                  / pop argument
        !           559:        movb    bl, al                  / save al to bl
        !           560:        push    $EXTMEML                / low byte of pair
        !           561:        call    read_cmos_              / result in ax
        !           562:        add     sp, $2                  / pop argument
        !           563:        movb    ah, bl                  / restore high byte to ah
        !           564:        shr     ax, $6                  / K -> 64K conversion
        !           565:        add     ax, $0x0010             / bias up to 1MB
        !           566:        mov     CMOSmax_, ax            / save count of 64K hunks
        !           567:        sub     ax, ax                  /
        !           568:        mov     dx, $0x0010             / Initial 64 Kbyte bank of extended mem.
        !           569:        mov     holetop_, ax            / Recorded extended memory bot in bytes.
        !           570:        mov     holetop_+2, dx          /
        !           571:                                        /
        !           572:        mov     ds, gdtsel_             / Map DS onto global descr table.
        !           573:        mov     si, $0xFFF8             / Define scratch access global selector.
        !           574:        mov     0(si), $0xFFFF          /       Limit: 64K bytes.
        !           575:        mov     2(si), $0x0000          /       Base:  1 Mbyte.
        !           576:        mov     4(si), $0x9210          /       Flags: Present, writable.
        !           577:        mov     6(si), $0x0000          /
        !           578:                                        /
        !           579:        sub     bx, bx                  /
        !           580: 0:     sub     di, di                  / Destination.
        !           581:        mov     cx, $0x8000             / 64K bytes, in words.
        !           582:        mov     2(si), ax               / Adjust gdt to desired DX:AX mem locn.
        !           583:        movb    4(si), dl               /
        !           584:        mov     es, si                  / Map ES onto 64K bank of extended mem.
        !           585:        mov     es:(di), bx             / Write word of extended memory.
        !           586:        jmp     .+2             / FLUSH /
        !           587:        cmp     es:(di), bx             / Verify word was correctly written.
        !           588:        jne     0f                      / Branch if memory end.
        !           589:                                        /
        !           590:        cld                             /
        !           591:        rep                             /
        !           592:        stosw                           / Clear this 64K of extended memory.
        !           593:                                        /
        !           594:        inc     dx                      / Step to next 64K bank.
        !           595:        cmp     dx, ss:CMOSmax_         / See if we're beyond what the CMOS
        !           596:        jge     0f                      /    says we have.
        !           597:        cmp     dx, $0x00F0             / Stop at 15 Mbyte boundary; the last
        !           598:        jl      0b                      /    Mbyte is a dup of the 1st Mbyte.
        !           599:                                        /
        !           600: 0:     movb    5(si), $0               / Free the scratch selector.
        !           601:                                        /
        !           602:        mov     bx, ss                  / Restore data and extra segments.
        !           603:        mov     ds, bx                  / NOTE: Do not modify DX:AX.
        !           604:        mov     es, bx                  /
        !           605:                                        /
        !           606:        mov     coretop_, ax            / Recorded top of extended core memory.
        !           607:        mov     coretop_+2, dx          /
        !           608:        jmp     start                   / Bring up system.
        !           609: 
        !           610: ////////
        !           611: /
        !           612: / Trap an interrupt linkage.
        !           613: / Each of the machine traps has a special little
        !           614: / linkage, that sets up the type code and sends
        !           615: / control off to the common trap processor. Device
        !           616: / interrupts, other than the clock (IR0), are
        !           617: / done here.
        !           618: /
        !           619: ////////
        !           620: 
        !           621: trap0:
        !           622:        call    tsave
        !           623:        mov     16(bx), $0x0000         / Divide error.
        !           624:        jmp     trap_
        !           625: 
        !           626: trap1:
        !           627:        call    tsave
        !           628:        mov     16(bx), $0x0100         / Single step.
        !           629:        jmp     trap_
        !           630: 
        !           631: trap2:
        !           632:        call    tsave
        !           633:        mov     16(bx), $0x0200         / Non-maskable interrupt.
        !           634:        jmp     trap_
        !           635: 
        !           636: trap3:
        !           637:        call    tsave
        !           638:        mov     16(bx), $0x0300         / INT 3 (breakpoint).
        !           639:        jmp     trap_
        !           640: 
        !           641: trap4:
        !           642:        call    tsave
        !           643:        mov     16(bx), $0x0400         / Overflow.
        !           644:        jmp     trap_
        !           645: 
        !           646: trap5:
        !           647:        call    tsave
        !           648:        mov     16(bx), $0x0500         / Bound check.
        !           649:        jmp     trap_
        !           650: 
        !           651: trap6:
        !           652:        call    tsave
        !           653:        mov     16(bx), $0x0600         / Invalid opcode.
        !           654:        jmp     trap_
        !           655: 
        !           656: trap7:
        !           657:        call    tsave
        !           658:        mov     16(bx), $0x0700         / Processor Extension not available.
        !           659:        jmp     trap_
        !           660: 
        !           661: trap8:
        !           662:        pop     ax                      / Get error code from stack [always 0]
        !           663:        call    tsave
        !           664:        mov     16(bx), $0x0800         / Double Exception detected
        !           665:        jmp     trap_
        !           666: 
        !           667: trap9:
        !           668:        call    tsave
        !           669:        mov     16(bx), $0x0900         / Processor extension segment overrun
        !           670:        jmp     trap_
        !           671: 
        !           672: trap10:
        !           673:        pop     ax                      / Get error code from stack
        !           674:        call    tsave
        !           675:        mov     16(bx), $0x0A00         / Invalid task state segment
        !           676:        jmp     trap_
        !           677: 
        !           678: trap11:
        !           679:        pop     ax                      / Get error code from stack
        !           680:        call    tsave
        !           681:        mov     16(bx), $0x0B00         / Segment not present
        !           682:        jmp     trap_
        !           683: 
        !           684: trap12:
        !           685:        pop     ax                      / Get error code from stack
        !           686:        call    tsave
        !           687:        mov     16(bx), $0x0C00         / Stack segment overrun or not present
        !           688:        jmp     trap_
        !           689: 
        !           690: trap13:
        !           691:        pop     ax                      / Get error code from stack
        !           692:        call    tsave
        !           693:        mov     16(bx), $0x0D00         / General protection
        !           694:        jmp     trap_
        !           695: 
        !           696:        .globl  syc
        !           697: 
        !           698: syc:
        !           699:        call    tsave
        !           700:        mov     16(bx), $0x2000         / System calls.
        !           701:        jmp     trap_
        !           702: 
        !           703: ran:
        !           704:        call    tsave
        !           705:        mov     16(bx), $0x2100         / Random trap.
        !           706:        jmp     trap_
        !           707: 
        !           708: dev1:
        !           709:        call    tsave
        !           710:        mov     16(bx), $0x4001         / Device 1: keyboard
        !           711:        ijmp    vecs_+[2*1]
        !           712: 
        !           713: /dev2: call    tsave                   / Device 2: mapped into device 9
        !           714: /      mov     16(bx), $0x4002
        !           715: /      ijmp    vecs_+[2*2]
        !           716: 
        !           717: dev3:
        !           718:        call    tsave
        !           719:        mov     16(bx), $0x4003         / Device 3: al1
        !           720:        ijmp    vecs_+[2*3]
        !           721: 
        !           722: dev4:
        !           723:        call    tsave
        !           724:        mov     16(bx), $0x4004         / Device 4: al0
        !           725:        ijmp    vecs_+[2*4]
        !           726: 
        !           727: dev5:
        !           728:        call    tsave
        !           729:        mov     16(bx), $0x4005         / Device 5: hard disk
        !           730:        ijmp    vecs_+[2*5]
        !           731: 
        !           732: dev6:
        !           733:        call    tsave
        !           734:        mov     16(bx), $0x4006         / Device 6: floppy
        !           735:        ijmp    vecs_+[2*6]
        !           736: 
        !           737: dev7:
        !           738:        call    tsave
        !           739:        mov     16(bx), $0x4007         / Device 7: lp
        !           740:        ijmp    vecs_+[2*7]
        !           741: 
        !           742: dev8:
        !           743:        call    tsave
        !           744:        mov     16(bx), $0x4008         / Device 8:
        !           745:        ijmp    vecs_+[2*8]
        !           746: 
        !           747: dev9:
        !           748:        call    tsave
        !           749:        mov     16(bx), $0x4009         / Device 9:
        !           750:        ijmp    vecs_+[2*9]
        !           751: 
        !           752: dev10:
        !           753:        call    tsave
        !           754:        mov     16(bx), $0x400A         / Device 10:
        !           755:        ijmp    vecs_+[2*10]
        !           756: 
        !           757: dev11:
        !           758:        call    tsave
        !           759:        mov     16(bx), $0x400B         / Device 11:
        !           760:        ijmp    vecs_+[2*11]
        !           761: 
        !           762: dev12:
        !           763:        call    tsave
        !           764:        mov     16(bx), $0x400C         / Device 12:
        !           765:        ijmp    vecs_+[2*12]
        !           766: 
        !           767: dev13:
        !           768:        call    tsave
        !           769:        mov     16(bx), $0x400D         / Device 13:
        !           770:        ijmp    vecs_+[2*13]
        !           771: 
        !           772: dev14:
        !           773:        call    tsave
        !           774:        mov     16(bx), $0x400E         / Device 14:
        !           775:        ijmp    vecs_+[2*14]
        !           776: 
        !           777: dev15:
        !           778:        call    tsave
        !           779:        mov     16(bx), $0x400F         / Device 15:
        !           780:        ijmp    vecs_+[2*15]
        !           781: 
        !           782: ////////
        !           783: /
        !           784: / Clock interrupt.
        !           785: / The clock interrupt is stolen from the ROM;
        !           786: / if you don't do this the EOI sequence for the 8259
        !           787: / may get mangled on context switches.
        !           788: /
        !           789: ////////
        !           790: 
        !           791: clk_ps:                                        / MLK
        !           792:        push    ax
        !           793:        inb     al, 0x61                / PS/2 8259 needs to be told to 
        !           794:        jmp     .+2                     / stop interrupting the CPU, or
        !           795:        jmp     .+2
        !           796:        orb     al,$0x80                / we will hang.
        !           797:        outb    0x61,al
        !           798:        pop     ax                      / MLK
        !           799: 
        !           800: clk:
        !           801:        call    tsave                   / Perform trap save.
        !           802:        mov     16(bx), $0x4000
        !           803: 
        !           804:        sub     ax, ax                  / Assume system mode, push user flag
        !           805:        push    ax
        !           806:        push    18(bx)                  / IP at tick time
        !           807: 
        !           808:        cmpb    depth_, $0              / Correct ?
        !           809:        jne     0f                      / If ne, yes.
        !           810:        mov     bx, cprocp_             / User depth, check if the
        !           811:        test    PFLAGS(bx), $PFKERN     / current process is a kernel process.
        !           812:        jne     0f                      / If ne, yes.
        !           813:        mov     bx, sp                  / Load stack index
        !           814:        inc     2(bx)                   / and set user mode.
        !           815: 
        !           816: 0:     call    clock_                  / Call common clock and
        !           817:        add     sp, $4                  / pop arguments.
        !           818: 
        !           819:        ret                             / Back to "tsave".
        !           820: 
        !           821: ////////
        !           822: /
        !           823: / This routine is called by "tsave" to dismiss an interrupt.
        !           824: / The interrupt code is in "ax".
        !           825: /
        !           826: ////////
        !           827: 
        !           828:        .globl  eoi
        !           829: 
        !           830: eoi:
        !           831:        cmpb    al, $8                  / Is this on the slave PIC?
        !           832:        jb      0f                      / Jump if not.
        !           833:        movb    al, $0x20               / Send a non specific EOI
        !           834:        outb    SPIC, al                / to the slave PIC.
        !           835: 0:     movb    al, $0x20               / Send a non specific EOI
        !           836:        outb    PIC, al                 / to the master PIC.
        !           837:        ret                             / Done.
        !           838: 
        !           839: ////////
        !           840: /
        !           841: / Block I/O to ports.
        !           842: / Mainly used to read and write the silo memories in the discs.
        !           843: / Delibrately only transfers 1 byte per loop to avoid
        !           844: / timing problems on AT I/O chips.
        !           845: /
        !           846: / void outcopy(port, off, seg, n);
        !           847: / int  port;                   /* Port address */
        !           848: / char *off;                   /* Offset in segment */
        !           849: / unsigned seg;                        /* Segment register base */
        !           850: / int  n;                      /* Byte count */
        !           851: / 
        !           852: / void incopy(port, off, seg, n);
        !           853: / int  port;                   /* Device */
        !           854: / char *off;                   /* Offset */
        !           855: / unsigned seg;                        /* Segment register base */
        !           856: / int  n;                      /* Byte count */
        !           857: /
        !           858: ////////
        !           859: 
        !           860:        .globl  incopy_
        !           861:        .globl  outcopy_
        !           862: 
        !           863: incopy_:
        !           864:        push    di
        !           865:        push    es
        !           866:        push    bp
        !           867:        mov     bp, sp
        !           868:        mov     dx, 8(bp)               /device port
        !           869:        les     di, 10(bp)              /seg,off pair
        !           870:        mov     cx, 14(bp)              /n bytes
        !           871:        jcxz    1f
        !           872: 
        !           873:        cld                             /auto-increment
        !           874: 0:     inb     al, dx
        !           875:        stosb
        !           876:        loop    0b
        !           877: 
        !           878: 1:     pop     bp
        !           879:        pop     es                      /restore regs
        !           880:        pop     di
        !           881:        ret
        !           882: 
        !           883: outcopy_:
        !           884:        push    si
        !           885:        push    ds
        !           886:        push    bp
        !           887:        mov     bp, sp
        !           888:        mov     dx, 8(bp)               /device port
        !           889:        lds     si, 10(bp)              /offset
        !           890:        mov     cx, 14(bp)              /count
        !           891:        jcxz    1f
        !           892: 
        !           893:        cld                             /auto-increment
        !           894: 0:     lodsb
        !           895:        outb    dx, al
        !           896:        loop    0b
        !           897: 
        !           898: 1:     pop     bp
        !           899:        pop     ds
        !           900:        pop     si
        !           901:        ret
        !           902: 
        !           903: ////////
        !           904: /
        !           905: / Copy "n" bytes of memory from base "p1" to base "p2".
        !           906: / The copy must be done from left to right.
        !           907: /
        !           908: / plrcopy(p1, p2, n)
        !           909: / paddr_t p1, p2;
        !           910: / size_t n;
        !           911: /
        !           912: ////////
        !           913: 
        !           914:        .globl  plrcopy_
        !           915: 
        !           916: plrcopy_:
        !           917:        push    si                      / Save sequence
        !           918:        push    di
        !           919:        push    bp
        !           920:        mov     bp, sp
        !           921: 
        !           922:        push    ds                      / Save ds
        !           923:        push    es                      / Save es
        !           924: 
        !           925:        push    18(bp)                  / Map SI:DI at destination ptov(p2,n).
        !           926:        push    16(bp)
        !           927:        push    14(bp)
        !           928:        push    12(bp)
        !           929:        call    ptov_
        !           930:        add     sp, $8
        !           931:        mov     si, dx
        !           932:        mov     di, ax
        !           933: 
        !           934:        push    18(bp)                  / Map DX:AX at source   ptov(p1,n);
        !           935:        push    16(bp)
        !           936:        push    10(bp)
        !           937:        push    8(bp)
        !           938:        call    ptov_
        !           939:        add     sp, $8
        !           940: 
        !           941:        mov     es, si                  / Map ES:DI at destination.
        !           942:        mov     ds, dx                  / Map DS:SI at source.
        !           943:        mov     si, ax
        !           944: 
        !           945:        mov     cx, 16(bp)              / Transfer count in bytes.
        !           946:        cld                             / Auto Increment.
        !           947:        clc                             /
        !           948:        rcr     cx, $1                  / Word count
        !           949:        rep                             /
        !           950:        movsw                           / Move words
        !           951:        rcl     cx, $1                  /
        !           952:        rep                             /
        !           953:        movsb                           / Move odd byte
        !           954: 
        !           955:        mov     si, es                  / Remember mapped selectors.
        !           956:        mov     di, ds                  /
        !           957:        pop     es                      / Restore es
        !           958:        pop     ds                      / Restore ds
        !           959: 
        !           960:        push    si                      / Release mapped selectors.
        !           961:        push    ax                      / NOTE: Offset is ignored.
        !           962:        call    vrelse_                 /
        !           963:        add     sp, $4                  /
        !           964:                                        /
        !           965:        push    di                      /
        !           966:        push    ax                      /
        !           967:        call    vrelse_                 /
        !           968:        add     sp, $4                  /
        !           969: 
        !           970:        pop     bp                      / Standard return
        !           971:        pop     di
        !           972:        pop     si
        !           973:        ret                             / Return
        !           974: 
        !           975: ////////
        !           976: /
        !           977: / Copy "n" bytes of memory from base "p1" to base "p2".
        !           978: / The copy must be done from right to left.
        !           979: /
        !           980: / prlcopy(p1, p2, n)
        !           981: / paddr_t p1, p2;
        !           982: / size_t n;
        !           983: /
        !           984: ////////
        !           985: 
        !           986:        .globl  prlcopy_
        !           987: 
        !           988: prlcopy_:
        !           989:        push    si                      / Save sequence
        !           990:        push    di
        !           991:        push    bp
        !           992:        mov     bp, sp
        !           993: 
        !           994:        push    ds                      / Save ds
        !           995:        push    es                      / Save es
        !           996: 
        !           997:        push    18(bp)                  / Map SI:DI at destination ptov(p2,n).
        !           998:        push    16(bp)
        !           999:        push    14(bp)
        !          1000:        push    12(bp)
        !          1001:        call    ptov_
        !          1002:        add     sp, $8
        !          1003:        mov     si, dx
        !          1004:        mov     di, ax
        !          1005: 
        !          1006:        push    18(bp)                  / Map DX:AX at source   ptov(p1,n);
        !          1007:        push    16(bp)
        !          1008:        push    10(bp)
        !          1009:        push    8(bp)
        !          1010:        call    ptov_
        !          1011:        add     sp, $8
        !          1012: 
        !          1013:        mov     es, si                  / Map ES:DI at destination.
        !          1014:        mov     ds, dx                  / Map DS:SI at source.
        !          1015:        mov     si, ax
        !          1016: 
        !          1017:        mov     cx, 16(bp)              / Transfer count in bytes
        !          1018:        add     si, cx                  / Point DS:SI at the end
        !          1019:        dec     si                      / of the source.
        !          1020:        add     di, cx                  / Point ES:DI at the end
        !          1021:        dec     di                      / of the destination.
        !          1022: 
        !          1023:        std                             / Auto decrement
        !          1024:        clc                             /
        !          1025:        rcr     cx, $1                  / Word Count
        !          1026:        rep                             /
        !          1027:        movsw                           / Move words
        !          1028:        rcl     cx, $1                  /
        !          1029:        rep                             /
        !          1030:        movsb                           / Move odd byte
        !          1031:        cld                             / Auto increment
        !          1032: 
        !          1033:        mov     si, es                  / Remember mapped selectors.
        !          1034:        mov     di, ds                  /
        !          1035:        pop     es                      / Restore es
        !          1036:        pop     ds                      / Restore ds
        !          1037: 
        !          1038:        push    si                      / Release mapped selectors.
        !          1039:        push    ax                      / NOTE: Offset is ignored.
        !          1040:        call    vrelse_                 /
        !          1041:        add     sp, $4                  /
        !          1042:                                        /
        !          1043:        push    di                      /
        !          1044:        push    ax                      /
        !          1045:        call    vrelse_                 /
        !          1046:        add     sp, $4                  /
        !          1047:                                        /
        !          1048:        mov     ax, 16(bp)              / Return transfer count.
        !          1049:        pop     bp                      / Standard return
        !          1050:        pop     di
        !          1051:        pop     si
        !          1052:        ret
        !          1053: 
        !          1054: ////////
        !          1055: /
        !          1056: / Clear "n" bytes of memory starting at physical address "p".
        !          1057: /
        !          1058: / pclear( p, n )
        !          1059: / paddr_t p;
        !          1060: / size_t n;
        !          1061: /
        !          1062: /
        !          1063: /      Notes:  At most 64K bytes of memory can be cleared.
        !          1064: /
        !          1065: ////////
        !          1066: 
        !          1067:        .globl  pclear_
        !          1068: 
        !          1069: pclear_:
        !          1070:        push    si                      / Standard save
        !          1071:        push    di
        !          1072:        push    bp
        !          1073:        mov     bp, sp
        !          1074: 
        !          1075:        push    es                      / Save es
        !          1076: 
        !          1077:        push    14(bp)                  / Map ES:DI at ptov(p2,n).
        !          1078:        push    12(bp)
        !          1079:        push    10(bp)
        !          1080:        push    8(bp)
        !          1081:        call    ptov_
        !          1082:        add     sp, $8
        !          1083:        mov     es, dx
        !          1084:        mov     di, ax
        !          1085: 
        !          1086:        shr     14(bp), $1              / Convert count from bytes to words.
        !          1087:        rcr     12(bp), $1
        !          1088:        mov     cx, 12(bp)              / Count in words.
        !          1089: 
        !          1090:        sub     ax, ax                  / Get a 0.
        !          1091:        cld                             / Zero the block.
        !          1092:        rep
        !          1093:        stosw
        !          1094: 
        !          1095:        mov     ax, es                  / Remember mapped selector.
        !          1096:        pop     es                      / Restore es.
        !          1097: 
        !          1098:        push    ax                      / Release mapped selector.
        !          1099:        push    ax                      / NOTE: Offset is ignored.
        !          1100:        call    vrelse_                 /
        !          1101:        add     sp, $4                  /
        !          1102: 
        !          1103:        pop     bp                      / Standard return.
        !          1104:        pop     di
        !          1105:        pop     si
        !          1106:        ret
        !          1107: 
        !          1108: ////////
        !          1109: /
        !          1110: / Block copy chunks of memory to a physical
        !          1111: / location from a location in either the system
        !          1112: / or user data space.
        !          1113: /
        !          1114: / upcopy(u, p, n)
        !          1115: / char *u;
        !          1116: / paddr_t p;
        !          1117: / int n;
        !          1118: /
        !          1119: / kpcopy(k, p, n);
        !          1120: / char *k;
        !          1121: / paddr_t p;
        !          1122: / int n;
        !          1123: /
        !          1124: ////////
        !          1125: 
        !          1126:        .globl  upcopy_
        !          1127: 
        !          1128: upcopy_:
        !          1129:        mov     bx, sp                  / Get set for stack index.
        !          1130:        mov     ax, 2(bx)               / User address
        !          1131:        dec     ax                      / Don't wrap too soon
        !          1132:        add     ax, 8(bx)               / Count
        !          1133:        jc      kuerr                   / Out of bounds
        !          1134:        cmp     ax, udl_                / In range?
        !          1135:        ja      kuerr                   / No
        !          1136:        push    uds_                    / Mark transfer ds as being user ds.
        !          1137:        jmp     1f                      / Finish in common code.
        !          1138: 
        !          1139:        .globl  kpcopy_
        !          1140: 
        !          1141: kpcopy_:
        !          1142:        push    ds                      / Mark transfer ds as being kernel ds.
        !          1143: 
        !          1144: 1:     push    si                      / Standard save
        !          1145:        push    di
        !          1146:        push    bp
        !          1147:        mov     bp, sp
        !          1148: 
        !          1149:        push    ds                      / Save ds, es
        !          1150:        push    es
        !          1151: 
        !          1152:        sub     ax, ax                  / ES:DI = ptov(p,n).
        !          1153:        push    ax                      /
        !          1154:        push    16(bp)                  /
        !          1155:        push    14(bp)                  /
        !          1156:        push    12(bp)                  /
        !          1157:        call    ptov_                   /
        !          1158:        add     sp, $8                  /
        !          1159:        mov     es, dx                  /
        !          1160:        mov     di, ax                  /
        !          1161:                                        /
        !          1162:        mov     ds, 6(bp)               / DS:SI = source address.
        !          1163:        mov     si, 10(bp)              /
        !          1164:        mov     cx, 16(bp)              / Byte count
        !          1165:                                        /
        !          1166:        cld                             / Auto Increment
        !          1167:        clc                             /
        !          1168:        rcr     cx, $1                  / Word count
        !          1169:        rep                             /
        !          1170:        movsw                           / Move words
        !          1171:        rcl     cx, $1                  / Move odd byte
        !          1172:        rep                             /
        !          1173:        movsb                           /
        !          1174:                                        /
        !          1175:        mov     ax, es                  / Remember mapped selector.
        !          1176:        pop     es                      / Restore es, ds.
        !          1177:        pop     ds                      /
        !          1178:                                        /
        !          1179:        push    ax                      / Release mapped selector.
        !          1180:        push    ax                      / NOTE: Offset is ignored.
        !          1181:        call    vrelse_                 /
        !          1182:        add     sp, $4                  /
        !          1183:                                        /
        !          1184:        mov     ax, 16(bp)              / Return transfer count.
        !          1185:                                        /
        !          1186:        pop     bp                      / Standard return.
        !          1187:        pop     di
        !          1188:        pop     si
        !          1189:        add     sp, $2                  / Discard marked transfer ds.
        !          1190:        ret
        !          1191: 
        !          1192: ////////
        !          1193: /
        !          1194: / Block copy memory from physical address "p"
        !          1195: / to either user or system data space.
        !          1196: /
        !          1197: / pucopy(p, u, n)
        !          1198: / paddr_t p;
        !          1199: / char *u;
        !          1200: / int n;
        !          1201: /
        !          1202: / pkcopy(p, k, n);
        !          1203: / paddr_t p;
        !          1204: / char *k;
        !          1205: / int n;
        !          1206: /
        !          1207: ////////
        !          1208: 
        !          1209:        .globl  pucopy_
        !          1210: 
        !          1211: pucopy_:
        !          1212:        mov     bx, sp                  / Stack index
        !          1213:        mov     ax, 6(bx)               / User address
        !          1214:        dec     ax                      / Don't wrap too soon
        !          1215:        add     ax, 8(bx)               / Count
        !          1216:        jc      kuerr                   / Out of bounds
        !          1217:        cmp     ax, udl_                / In range?
        !          1218:        ja      kuerr                   / No
        !          1219:        push    uds_                    / Mark transfer es as being user ds.
        !          1220:        jmp     1f                      / Common code
        !          1221: 
        !          1222:        .globl  pkcopy_
        !          1223: 
        !          1224: pkcopy_:
        !          1225:        push    ds                      / Mark transfer es as being kernel ds.
        !          1226: 
        !          1227: 1:     push    si                      / Standard save
        !          1228:        push    di
        !          1229:        push    bp
        !          1230:        mov     bp, sp
        !          1231: 
        !          1232:        push    ds                      / Save ds, es.
        !          1233:        push    es
        !          1234: 
        !          1235:        sub     ax, ax                  / DS:SI = ptov(p,n).
        !          1236:        push    ax
        !          1237:        push    16(bp)
        !          1238:        push    12(bp)
        !          1239:        push    10(bp)
        !          1240:        call    ptov_
        !          1241:        add     sp, $8
        !          1242:        mov     ds, dx
        !          1243:        mov     si, ax
        !          1244: 
        !          1245:        mov     es, 6(bp)               / ES:DI = destination.
        !          1246:        mov     di, 14(bp)              /
        !          1247:        mov     cx, 16(bp)              / Count
        !          1248: 
        !          1249:        cld                             / Incremental move
        !          1250:        clc                             /
        !          1251:        rcr     cx, $1                  / Word count
        !          1252:        rep                             /
        !          1253:        movsw                           / Move words.
        !          1254:        rcl     cx, $1                  / Move odd byte.
        !          1255:        rep                             /
        !          1256:        movsb                           /
        !          1257:                                        /
        !          1258:        mov     ax, ds                  / Rememember mapped selector.
        !          1259:        pop     es                      / Restore es, ds.
        !          1260:        pop     ds                      /
        !          1261:                                        /
        !          1262:        push    ax                      / Release mapped selector.
        !          1263:        push    ax                      / NOTE: Offset is ignored.
        !          1264:        call    vrelse_                 /
        !          1265:        add     sp, $4                  /
        !          1266:                                        /
        !          1267:        mov     ax, 16(bp)              / Return transfer count.
        !          1268:                                        /
        !          1269:        pop     bp                      / Restore registers.
        !          1270:        pop     di                      /
        !          1271:        pop     si                      /
        !          1272:        add     sp, $2                  / Discard marked transfer es.
        !          1273:        ret                             / Fin
        !          1274: 
        !          1275: ////////
        !          1276: /
        !          1277: / All of the above copy routines jump to
        !          1278: / "kuerr", with the stack untouched, if they detect
        !          1279: / a bounds error on a user address.
        !          1280: /
        !          1281: ////////
        !          1282: 
        !          1283: kuerr:
        !          1284:        mov     bx,$u_                  / Pointer to user area
        !          1285:        movb    (bx),$EFAULT            / Bad parameter error
        !          1286:        sub     ax,ax                   / Didn't copy anything
        !          1287:        ret                             / Return
        !          1288: 
        !          1289: ////////
        !          1290: /       Read a byte from the CMOS.  Takes one argument--the
        !          1291: /       CMOS address to read from as an int; returns the
        !          1292: /       value read in ax.
        !          1293: /
        !          1294: /      int read_cmos(addr)
        !          1295: /      int addr;
        !          1296: /
        !          1297: ////////
        !          1298:         .globl read_cmos_
        !          1299: read_cmos_:
        !          1300:         push    bp
        !          1301:         mov     bp, sp
        !          1302:         movb    al, 4(bp)      / Fetch address from stack.
        !          1303:         outb    CMOSA, al      / Send address to CMOS.
        !          1304:         jmp     .+2             / DELAY
        !          1305:        sub     ax, ax          / Zero out everything we don't want.
        !          1306:         inb     al, CMOSD      / Get Value from CMOS into al.
        !          1307:         pop     bp
        !          1308:         ret                     / Return from read_cmos().
        !          1309: 
        !          1310: 
        !          1311: / Read timer channel 0 into int value.  
        !          1312: / Clock counts down from 11932 to 0 with each clock tick.
        !          1313:        .globl  read_t0_
        !          1314: read_t0_:
        !          1315:        pushf
        !          1316:        cli
        !          1317:        xor     ax,ax   / Counter latch timer 0 and clear return val
        !          1318:        outb    PIT+3,al
        !          1319:        jmp     .+2             / DELAY /
        !          1320:        jmp     .+2             / DELAY /
        !          1321:        inb     al,PIT          / low byte of counter latch
        !          1322:        movb    ah,al
        !          1323:        jmp     .+2             / DELAY /
        !          1324:        jmp     .+2             / DELAY /
        !          1325:        inb     al,PIT          / high byte of counter latch
        !          1326:        xchgb   al,ah
        !          1327:        jmp     .+2             / DELAY /
        !          1328:        jmp     .+2             / DELAY /
        !          1329:        popf
        !          1330:        ret
        !          1331: 
        !          1332: / return current contents of psw
        !          1333:        .globl  read_psw_
        !          1334: read_psw_:
        !          1335:        pushf
        !          1336:        pop     ax
        !          1337:        ret
        !          1338: 
        !          1339: ////////
        !          1340: /
        !          1341: / Read the equipment description. Use
        !          1342: / the "int 11" interface, so that the IBM
        !          1343: / ROM will do all the details.
        !          1344: /
        !          1345: ////////
        !          1346: 
        !          1347:        .globl  int11_
        !          1348: 
        !          1349: int11_:        mov     ax, cs:val11            / Ask the ROM
        !          1350:        ret                             / to put stuff in AX
        !          1351: 
        !          1352: ////////
        !          1353: /
        !          1354: / Bootstrap.
        !          1355: / Called by the keyboard driver on control-alt-del.
        !          1356: / Requests the 8042 controller to initiate a processor reset,
        !          1357: / which is the only way to terminate protected mode operation.
        !          1358: /
        !          1359: /      Reference: IBM-AT Technical Reference Manual,
        !          1360: /                      Real-time Clock/CMOS RAM [Page 1-45]
        !          1361: /                      Keyboard controller [Page 1-40]
        !          1362: /                      Test 3, Page 5-68.
        !          1363: /
        !          1364: ////////
        !          1365: 
        !          1366:        .globl  boot_
        !          1367: boot_:
        !          1368:        cli                             / Disable interrupts.
        !          1369:                                        /
        !          1370:        sub     cx, cx                  /
        !          1371: 0:     inb     al, KBCTRL              / Wait for 8042 input buffer to empty.
        !          1372:        testb   al, $2                  /
        !          1373:        loopne  0b                      /
        !          1374:        jmp     .+2             / DELAY /
        !          1375:                                        /
        !          1376:        movb    al, $0xFE               / Issue a shutdown command
        !          1377:        outb    KBCTRL, al              / to the 8042 control port.
        !          1378:                                        /
        !          1379: 0:     hlt                             / Halt until processor reset occurs.
        !          1380:        jmp     0b
        !          1381: 
        !          1382: ////////
        !          1383: /
        !          1384: / Data.
        !          1385: /
        !          1386: ////////
        !          1387: 
        !          1388:        .globl  MAXMEM
        !          1389:        .globl  vecs_
        !          1390:        .globl  realmode_
        !          1391:        .globl  gdtsel_, gdtmap_
        !          1392:        .globl  idtsel_, idtmap_
        !          1393:        .globl  CMOSmax_
        !          1394: 
        !          1395:        .shri
        !          1396: val11: .word   0                       / Value obtained from int11 [in code].
        !          1397: 
        !          1398:        .prvd
        !          1399: MAXMEM:        .word   0xA000                  / In paragraphs, must be mult. of 64
        !          1400: CMOSmax_:.word 0x0000                  / Max extended memory according ...
        !          1401:                                        / ... to CMOS bytes 0x17 and 0x18 ...
        !          1402:                                        / ... in 64K chunks.
        !          1403: realmode_:.word        0                       / Virtual Addressing Mode Enabled
        !          1404: gdtmap_:.blkw  3                       / Global descriptor table definition
        !          1405: idtmap_:.blkw  3                       / Interrupt descriptor table definition
        !          1406: gdtsel_:.word  0                       / Global descriptor table selector
        !          1407: idtsel_:.word  0                       / Interrupt descriptor table selector
        !          1408: vecs_: .word   vret_                   / Interrupt vector table
        !          1409:        .word   vret_
        !          1410:        .word   vret_
        !          1411:        .word   vret_
        !          1412:        .word   vret_
        !          1413:        .word   vret_
        !          1414:        .word   vret_
        !          1415:        .word   vret_
        !          1416:        .word   vret_
        !          1417:        .word   vret_
        !          1418:        .word   vret_
        !          1419:        .word   vret_
        !          1420:        .word   vret_
        !          1421:        .word   vret_
        !          1422:        .word   vret_
        !          1423:        .word   vret_
        !          1424: 
        !          1425: ////////
        !          1426: /
        !          1427: / Task State Segment - Coherent runs as a single protected mode task.
        !          1428: /
        !          1429: ////////
        !          1430:        .globl  tss_
        !          1431: 
        !          1432:        .prvd
        !          1433: tss_:                          / Task State Segment.
        !          1434: tss_lnk:.word  0               /  0: Back link selector to TSS.
        !          1435: tss_sp0:.word  0               /  2: SP for CPL 0.
        !          1436: tss_ss0:.word  0               /  4: SS for CPL 0.
        !          1437: tss_sp1:.word  0               /  6: SP for CPL 1.
        !          1438: tss_ss1:.word  0               /  8: SS for CPL 1.
        !          1439: tss_sp2:.word  0               / 10: SP for CPL 2.
        !          1440: tss_ss2:.word  0               / 12: SS for CPL 2.
        !          1441: tss_ip:        .word   0               / 14: IP (Entry point).
        !          1442: tss_psw:.word  0               / 16: Flag word.
        !          1443: tss_ax:        .word   0               / 18: Register AX.
        !          1444: tss_cx:        .word   0               / 20: Register CX.
        !          1445: tss_dx:        .word   0               / 22: Register DX.
        !          1446: tss_bx:        .word   0               / 24: Register BX.
        !          1447: tss_bp:        .word   0               / 26: Register BP.
        !          1448: tss_sp:        .word   0               / 28: Register SP.
        !          1449: tss_si:        .word   0               / 30: Register SI.
        !          1450: tss_di:        .word   0               / 32: Register DI.
        !          1451: tss_es:        .word   0               / 34: Register ES.
        !          1452: tss_cs:        .word   0               / 36: Register CS.
        !          1453: tss_ss:        .word   0               / 38: Register SS.
        !          1454: tss_ds:        .word   0               / 40: Register DS.
        !          1455: tss_ldt:.word  0               / 42: Task LDT Selector.

unix.superglobalmegacorp.com

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