Annotation of coherent/d/PS2_KERNEL/i286/as2.s, revision 1.1.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.