Annotation of qemu/roms/SLOF/clients/net-snk/app/biosemu/interrupt.c, revision 1.1

1.1     ! root        1: /******************************************************************************
        !             2:  * Copyright (c) 2004, 2008 IBM Corporation
        !             3:  * All rights reserved.
        !             4:  * This program and the accompanying materials
        !             5:  * are made available under the terms of the BSD License
        !             6:  * which accompanies this distribution, and is available at
        !             7:  * http://www.opensource.org/licenses/bsd-license.php
        !             8:  *
        !             9:  * Contributors:
        !            10:  *     IBM Corporation - initial implementation
        !            11:  *****************************************************************************/
        !            12: 
        !            13: #include <stdio.h>
        !            14: 
        !            15: #include <rtas.h>
        !            16: 
        !            17: #include "biosemu.h"
        !            18: #include "mem.h"
        !            19: #include "device.h"
        !            20: #include "debug.h"
        !            21: 
        !            22: #include <x86emu/x86emu.h>
        !            23: #include <x86emu/prim_ops.h>
        !            24: 
        !            25: 
        !            26: 
        !            27: //setup to run the code at the address, that the Interrupt Vector points to...
        !            28: void
        !            29: setupInt(int intNum)
        !            30: {
        !            31:        DEBUG_PRINTF_INTR("%s(%x): executing interrupt handler @%08x\n",
        !            32:                          __FUNCTION__, intNum, my_rdl(intNum * 4));
        !            33:        // push current R_FLG... will be popped by IRET
        !            34:        push_word((u16) M.x86.R_FLG);
        !            35:        CLEAR_FLAG(F_IF);
        !            36:        CLEAR_FLAG(F_TF);
        !            37:        // push current CS:IP to the stack, will be popped by IRET
        !            38:        push_word(M.x86.R_CS);
        !            39:        push_word(M.x86.R_IP);
        !            40:        // set CS:IP to the interrupt handler address... so the next executed instruction will
        !            41:        // be the interrupt handler
        !            42:        M.x86.R_CS = my_rdw(intNum * 4 + 2);
        !            43:        M.x86.R_IP = my_rdw(intNum * 4);
        !            44: }
        !            45: 
        !            46: // handle int10 (VGA BIOS Interrupt)
        !            47: void
        !            48: handleInt10()
        !            49: {
        !            50:        // the data for INT10 is stored in BDA (0000:0400h) offset 49h-66h
        !            51:        // function number in AH
        !            52:        //DEBUG_PRINTF_CS_IP("%s:\n", __FUNCTION__);
        !            53:        //x86emu_dump_xregs();
        !            54:        //if ((M.x86.R_IP == 0x32c2) && (M.x86.R_SI == 0x1ce2)){
        !            55:        //X86EMU_trace_on();
        !            56:        //M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F;
        !            57:        //}
        !            58:        switch (M.x86.R_AH) {
        !            59:        case 0x00:
        !            60:                // set video mode
        !            61:                // BDA offset 49h is current video mode
        !            62:                my_wrb(0x449, M.x86.R_AL);
        !            63:                if (M.x86.R_AL > 7)
        !            64:                        M.x86.R_AL = 0x20;
        !            65:                else if (M.x86.R_AL == 6)
        !            66:                        M.x86.R_AL = 0x3f;
        !            67:                else
        !            68:                        M.x86.R_AL = 0x30;
        !            69:                break;
        !            70:        case 0x01:
        !            71:                // set cursor shape
        !            72:                // ignore
        !            73:                break;
        !            74:        case 0x02:
        !            75:                // set cursor position
        !            76:                // BH: pagenumber, DX: cursor_pos (DH:row, DL:col)
        !            77:                // BDA offset 50h-60h are 8 cursor position words for
        !            78:                // eight possible video pages
        !            79:                my_wrw(0x450 + (M.x86.R_BH * 2), M.x86.R_DX);
        !            80:                break;
        !            81:        case 0x03:
        !            82:                //get cursor position
        !            83:                // BH: pagenumber
        !            84:                // BDA offset 50h-60h are 8 cursor position words for
        !            85:                // eight possible video pages
        !            86:                M.x86.R_AX = 0;
        !            87:                M.x86.R_CH = 0; // start scan line ???
        !            88:                M.x86.R_CL = 0; // end scan line ???
        !            89:                M.x86.R_DX = my_rdw(0x450 + (M.x86.R_BH * 2));
        !            90:                break;
        !            91:        case 0x05:
        !            92:                // set active page
        !            93:                // BDA offset 62h is current page number
        !            94:                my_wrb(0x462, M.x86.R_AL);
        !            95:                break;
        !            96:        case 0x06:
        !            97:                //scroll up windows
        !            98:                break;
        !            99:        case 0x07:
        !           100:                //scroll down windows
        !           101:                break;
        !           102:        case 0x08:
        !           103:                //read character and attribute at position
        !           104:                M.x86.R_AH = 0x07;      // white-on-black
        !           105:                M.x86.R_AL = 0x20;      // a space...
        !           106:                break;
        !           107:        case 0x09:
        !           108:                // write character and attribute
        !           109:                //AL: char, BH: page number, BL: attribute, CX: number of times to write
        !           110:                //BDA offset 62h is current page number
        !           111:                CHECK_DBG(DEBUG_PRINT_INT10) {
        !           112:                        uint32_t i = 0;
        !           113:                        if (M.x86.R_BH == my_rdb(0x462)) {
        !           114:                                for (i = 0; i < M.x86.R_CX; i++)
        !           115:                                        printf("%c", M.x86.R_AL);
        !           116:                        }
        !           117:                }
        !           118:                break;
        !           119:        case 0x0a:
        !           120:                // write character
        !           121:                //AL: char, BH: page number, BL: attribute, CX: number of times to write
        !           122:                //BDA offset 62h is current page number
        !           123:                CHECK_DBG(DEBUG_PRINT_INT10) {
        !           124:                        uint32_t i = 0;
        !           125:                        if (M.x86.R_BH == my_rdb(0x462)) {
        !           126:                                for (i = 0; i < M.x86.R_CX; i++)
        !           127:                                        printf("%c", M.x86.R_AL);
        !           128:                        }
        !           129:                }
        !           130:                break;
        !           131:        case 0x0e:
        !           132:                // teletype output: write character and advance cursor...
        !           133:                //AL: char, BH: page number, BL: attribute
        !           134:                //BDA offset 62h is current page number
        !           135:                CHECK_DBG(DEBUG_PRINT_INT10) {
        !           136:                        // we ignore the pagenumber on this call...
        !           137:                        //if (M.x86.R_BH == my_rdb(0x462))
        !           138:                        {
        !           139:                                printf("%c", M.x86.R_AL);
        !           140:                                // for debugging, to read all lines
        !           141:                                //if (M.x86.R_AL == 0xd) // carriage return
        !           142:                                //      printf("\n");
        !           143:                        }
        !           144:                }
        !           145:                break;
        !           146:        case 0x0f:
        !           147:                // get video mode
        !           148:                // BDA offset 49h is current video mode
        !           149:                // BDA offset 62h is current page number
        !           150:                // BDA offset 4ah is columns on screen
        !           151:                M.x86.R_AH = 80;        //number of character columns... we hardcode it to 80
        !           152:                M.x86.R_AL = my_rdb(0x449);
        !           153:                M.x86.R_BH = my_rdb(0x462);
        !           154:                break;
        !           155:        default:
        !           156:                printf("%s(): unknown function (%x) for int10 handler.\n",
        !           157:                       __FUNCTION__, M.x86.R_AH);
        !           158:                DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n",
        !           159:                                  M.x86.R_AX, M.x86.R_BX, M.x86.R_CX,
        !           160:                                  M.x86.R_DX);
        !           161:                HALT_SYS();
        !           162:                break;
        !           163:        }
        !           164: }
        !           165: 
        !           166: // this table translates ASCII chars into their XT scan codes:
        !           167: static uint8_t keycode_table[256] = {
        !           168:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 - 7
        !           169:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8 - 15
        !           170:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 16 - 23
        !           171:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 24 - 31
        !           172:        0x39, 0x02, 0x28, 0x04, 0x05, 0x06, 0x08, 0x28, // 32 - 39
        !           173:        0x0a, 0x0b, 0x09, 0x2b, 0x33, 0x0d, 0x34, 0x35, // 40 - 47
        !           174:        0x0b, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // 48 - 55
        !           175:        0x09, 0x0a, 0x27, 0x27, 0x33, 0x2b, 0x34, 0x35, // 56 - 63
        !           176:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 64 - 71
        !           177:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 72 - 79
        !           178:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 80 - 87
        !           179:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 88 - 95
        !           180:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 96 - 103
        !           181:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 104 - 111
        !           182:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 112 - 119
        !           183:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 120 - 127
        !           184:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ...
        !           185:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           186:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           187:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           188:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           189:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           190:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           191:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           192:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           193:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           194:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           195:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           196:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           197:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           198:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           199:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           200: }
        !           201: 
        !           202: ;
        !           203: 
        !           204: void
        !           205: translate_keycode(uint64_t * keycode)
        !           206: {
        !           207:        uint8_t scan_code = 0;
        !           208:        uint8_t char_code = 0;
        !           209:        if (*keycode < 256) {
        !           210:                scan_code = keycode_table[*keycode];
        !           211:                char_code = (uint8_t) * keycode & 0xff;
        !           212:        } else {
        !           213:                switch (*keycode) {
        !           214:                case 0x1b50:
        !           215:                        // F1
        !           216:                        scan_code = 0x3b;
        !           217:                        char_code = 0x0;
        !           218:                        break;
        !           219:                default:
        !           220:                        printf("%s(): unknown multibyte keycode: %llx\n",
        !           221:                               __FUNCTION__, *keycode);
        !           222:                        break;
        !           223:                }
        !           224:        }
        !           225:        //assemble scan/char code in keycode
        !           226:        *keycode = (uint64_t) ((((uint16_t) scan_code) << 8) | char_code);
        !           227: }
        !           228: 
        !           229: // handle int16 (Keyboard BIOS Interrupt)
        !           230: void
        !           231: handleInt16()
        !           232: {
        !           233:        // keyboard buffer is in BIOS Memory Area:
        !           234:        // offset 0x1a (WORD) pointer to next char in keybuffer
        !           235:        // offset 0x1c (WORD) pointer to next insert slot in keybuffer
        !           236:        // offset 0x1e-0x3e: 16 WORD Ring Buffer
        !           237:        // since we currently always read the char from the FW buffer,
        !           238:        // we misuse the ring buffer, we use it as pointer to a uint64_t that stores
        !           239:        // multi-byte keys (e.g. special keys in VT100 terminal)
        !           240:        // and as long as a key is available (not 0) we dont read further keys
        !           241:        uint64_t *keycode = (uint64_t *) (M.mem_base + 0x41e);
        !           242:        int8_t c;
        !           243:        // function number in AH
        !           244:        DEBUG_PRINTF_INTR("%s(): Keyboard Interrupt: function: %x.\n",
        !           245:                          __FUNCTION__, M.x86.R_AH);
        !           246:        DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", M.x86.R_AX,
        !           247:                          M.x86.R_BX, M.x86.R_CX, M.x86.R_DX);
        !           248:        switch (M.x86.R_AH) {
        !           249:        case 0x00:
        !           250:                // get keystroke
        !           251:                if (*keycode) {
        !           252:                        M.x86.R_AX = (uint16_t) * keycode;
        !           253:                        // clear keycode
        !           254:                        *keycode = 0;
        !           255:                } else {
        !           256:                        M.x86.R_AH = 0x61;      // scancode for space key
        !           257:                        M.x86.R_AL = 0x20;      // a space
        !           258:                }
        !           259:                break;
        !           260:        case 0x01:
        !           261:                // check keystroke
        !           262:                // ZF set = no keystroke
        !           263:                // read first byte of key code
        !           264:                if (*keycode) {
        !           265:                        // already read, but not yet taken
        !           266:                        CLEAR_FLAG(F_ZF);
        !           267:                        M.x86.R_AX = (uint16_t) * keycode;
        !           268:                } else {
        !           269:                        c = getchar();
        !           270:                        if (c == -1) {
        !           271:                                // no key available
        !           272:                                SET_FLAG(F_ZF);
        !           273:                        } else {
        !           274:                                *keycode = c;
        !           275: 
        !           276:                                // since after an ESC it may take a while to receive the next char,
        !           277:                                // we send something that is not shown on the screen, and then try to get
        !           278:                                // the next char
        !           279:                                // TODO: only after ESC?? what about other multibyte keys
        !           280:                                printf("tt%c%c", 0x08, 0x08);   // 0x08 == Backspace
        !           281: 
        !           282:                                while ((c = getchar()) != -1) {
        !           283:                                        *keycode = (*keycode << 8) | c;
        !           284:                                        DEBUG_PRINTF(" key read: %0llx\n",
        !           285:                                                     *keycode);
        !           286:                                }
        !           287:                                translate_keycode(keycode);
        !           288:                                DEBUG_PRINTF(" translated key: %0llx\n",
        !           289:                                             *keycode);
        !           290:                                if (*keycode == 0) {
        !           291:                                        //not found
        !           292:                                        SET_FLAG(F_ZF);
        !           293:                                } else {
        !           294:                                        CLEAR_FLAG(F_ZF);
        !           295:                                        M.x86.R_AX = (uint16_t) * keycode;
        !           296:                                        //X86EMU_trace_on();
        !           297:                                        //M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F;
        !           298:                                }
        !           299:                        }
        !           300:                }
        !           301:                break;
        !           302:        default:
        !           303:                printf("%s(): unknown function (%x) for int16 handler.\n",
        !           304:                       __FUNCTION__, M.x86.R_AH);
        !           305:                DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n",
        !           306:                                  M.x86.R_AX, M.x86.R_BX, M.x86.R_CX,
        !           307:                                  M.x86.R_DX);
        !           308:                HALT_SYS();
        !           309:                break;
        !           310:        }
        !           311: }
        !           312: 
        !           313: // handle int1a (PCI BIOS Interrupt)
        !           314: void
        !           315: handleInt1a()
        !           316: {
        !           317:        // function number in AX
        !           318:        uint8_t bus, devfn, offs;
        !           319:        switch (M.x86.R_AX) {
        !           320:        case 0xb101:
        !           321:                // Installation check
        !           322:                CLEAR_FLAG(F_CF);       // clear CF
        !           323:                M.x86.R_EDX = 0x20494350;       // " ICP" endian swapped "PCI "
        !           324:                M.x86.R_AL = 0x1;       // Config Space Mechanism 1 supported
        !           325:                M.x86.R_BX = 0x0210;    // PCI Interface Level Version 2.10
        !           326:                M.x86.R_CL = 0xff;      // number of last PCI Bus in system TODO: check!
        !           327:                break;
        !           328:        case 0xb102:
        !           329:                // Find PCI Device
        !           330:                // NOTE: we currently only allow the device to find itself...
        !           331:                // it SHOULD be all we ever need...
        !           332:                // device_id in CX, vendor_id in DX
        !           333:                // device index in SI (i.e. if multiple devices with same vendor/device id
        !           334:                // are connected). We currently only support device index 0
        !           335:                DEBUG_PRINTF_INTR("%s(): function: %x: PCI Find Device\n",
        !           336:                                  __FUNCTION__, M.x86.R_AX);
        !           337:                if ((M.x86.R_CX == bios_device.pci_device_id)
        !           338:                    && (M.x86.R_DX == bios_device.pci_vendor_id)
        !           339:                    // device index must be 0
        !           340:                    && (M.x86.R_SI == 0)) {
        !           341:                        CLEAR_FLAG(F_CF);
        !           342:                        M.x86.R_AH = 0x00;      // return code: success
        !           343:                        M.x86.R_BH = bios_device.bus;
        !           344:                        M.x86.R_BL = bios_device.devfn;
        !           345:                        DEBUG_PRINTF_INTR
        !           346:                            ("%s(): function %x: PCI Find Device --> 0x%04x\n",
        !           347:                             __FUNCTION__, M.x86.R_AX, M.x86.R_BX);
        !           348:                } else {
        !           349:                        DEBUG_PRINTF_INTR
        !           350:                            ("%s(): function %x: invalid device/vendor/device index! (%04x/%04x/%02x expected: %04x/%04x/0) \n",
        !           351:                             __FUNCTION__, M.x86.R_AX, M.x86.R_CX, M.x86.R_DX,
        !           352:                             M.x86.R_SI, bios_device.pci_device_id,
        !           353:                             bios_device.pci_vendor_id);
        !           354:                        SET_FLAG(F_CF);
        !           355:                        M.x86.R_AH = 0x86;      // return code: device not found
        !           356:                }
        !           357:                break;
        !           358:        case 0xb108:            //read configuration byte
        !           359:        case 0xb109:            //read configuration word
        !           360:        case 0xb10a:            //read configuration dword
        !           361:                bus = M.x86.R_BH;
        !           362:                devfn = M.x86.R_BL;
        !           363:                offs = M.x86.R_DI;
        !           364:                if ((bus != bios_device.bus)
        !           365:                    || (devfn != bios_device.devfn)) {
        !           366:                        // fail accesses to any device but ours...
        !           367:                        printf
        !           368:                            ("%s(): Config read access invalid! bus: %x (%x), devfn: %x (%x), offs: %x\n",
        !           369:                             __FUNCTION__, bus, bios_device.bus, devfn,
        !           370:                             bios_device.devfn, offs);
        !           371:                        SET_FLAG(F_CF);
        !           372:                        M.x86.R_AH = 0x87;      //return code: bad pci register
        !           373:                        HALT_SYS();
        !           374:                        return;
        !           375:                } else {
        !           376:                        switch (M.x86.R_AX) {
        !           377:                        case 0xb108:
        !           378:                                M.x86.R_CL =
        !           379:                                    (uint8_t) rtas_pci_config_read(bios_device.
        !           380:                                                                   puid, 1,
        !           381:                                                                   bus, devfn,
        !           382:                                                                   offs);
        !           383:                                DEBUG_PRINTF_INTR
        !           384:                                    ("%s(): function %x: PCI Config Read @%02x --> 0x%02x\n",
        !           385:                                     __FUNCTION__, M.x86.R_AX, offs,
        !           386:                                     M.x86.R_CL);
        !           387:                                break;
        !           388:                        case 0xb109:
        !           389:                                M.x86.R_CX =
        !           390:                                    (uint16_t) rtas_pci_config_read(bios_device.
        !           391:                                                                    puid, 2,
        !           392:                                                                    bus, devfn,
        !           393:                                                                    offs);
        !           394:                                DEBUG_PRINTF_INTR
        !           395:                                    ("%s(): function %x: PCI Config Read @%02x --> 0x%04x\n",
        !           396:                                     __FUNCTION__, M.x86.R_AX, offs,
        !           397:                                     M.x86.R_CX);
        !           398:                                break;
        !           399:                        case 0xb10a:
        !           400:                                M.x86.R_ECX =
        !           401:                                    (uint32_t) rtas_pci_config_read(bios_device.
        !           402:                                                                    puid, 4,
        !           403:                                                                    bus, devfn,
        !           404:                                                                    offs);
        !           405:                                DEBUG_PRINTF_INTR
        !           406:                                    ("%s(): function %x: PCI Config Read @%02x --> 0x%08x\n",
        !           407:                                     __FUNCTION__, M.x86.R_AX, offs,
        !           408:                                     M.x86.R_ECX);
        !           409:                                break;
        !           410:                        }
        !           411:                        CLEAR_FLAG(F_CF);
        !           412:                        M.x86.R_AH = 0x0;       // return code: success
        !           413:                }
        !           414:                break;
        !           415:        case 0xb10b:            //write configuration byte
        !           416:        case 0xb10c:            //write configuration word
        !           417:        case 0xb10d:            //write configuration dword
        !           418:                bus = M.x86.R_BH;
        !           419:                devfn = M.x86.R_BL;
        !           420:                offs = M.x86.R_DI;
        !           421:                if ((bus != bios_device.bus)
        !           422:                    || (devfn != bios_device.devfn)) {
        !           423:                        // fail accesses to any device but ours...
        !           424:                        printf
        !           425:                            ("%s(): Config read access invalid! bus: %x (%x), devfn: %x (%x), offs: %x\n",
        !           426:                             __FUNCTION__, bus, bios_device.bus, devfn,
        !           427:                             bios_device.devfn, offs);
        !           428:                        SET_FLAG(F_CF);
        !           429:                        M.x86.R_AH = 0x87;      //return code: bad pci register
        !           430:                        HALT_SYS();
        !           431:                        return;
        !           432:                } else {
        !           433:                        switch (M.x86.R_AX) {
        !           434:                        case 0xb10b:
        !           435:                                rtas_pci_config_write(bios_device.puid, 1, bus,
        !           436:                                                      devfn, offs, M.x86.R_CL);
        !           437:                                DEBUG_PRINTF_INTR
        !           438:                                    ("%s(): function %x: PCI Config Write @%02x <-- 0x%02x\n",
        !           439:                                     __FUNCTION__, M.x86.R_AX, offs,
        !           440:                                     M.x86.R_CL);
        !           441:                                break;
        !           442:                        case 0xb10c:
        !           443:                                rtas_pci_config_write(bios_device.puid, 2, bus,
        !           444:                                                      devfn, offs, M.x86.R_CX);
        !           445:                                DEBUG_PRINTF_INTR
        !           446:                                    ("%s(): function %x: PCI Config Write @%02x <-- 0x%04x\n",
        !           447:                                     __FUNCTION__, M.x86.R_AX, offs,
        !           448:                                     M.x86.R_CX);
        !           449:                                break;
        !           450:                        case 0xb10d:
        !           451:                                rtas_pci_config_write(bios_device.puid, 4, bus,
        !           452:                                                      devfn, offs, M.x86.R_ECX);
        !           453:                                DEBUG_PRINTF_INTR
        !           454:                                    ("%s(): function %x: PCI Config Write @%02x <-- 0x%08x\n",
        !           455:                                     __FUNCTION__, M.x86.R_AX, offs,
        !           456:                                     M.x86.R_ECX);
        !           457:                                break;
        !           458:                        }
        !           459:                        CLEAR_FLAG(F_CF);
        !           460:                        M.x86.R_AH = 0x0;       // return code: success
        !           461:                }
        !           462:                break;
        !           463:        default:
        !           464:                printf("%s(): unknown function (%x) for int1a handler.\n",
        !           465:                       __FUNCTION__, M.x86.R_AX);
        !           466:                DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n",
        !           467:                                  M.x86.R_AX, M.x86.R_BX, M.x86.R_CX,
        !           468:                                  M.x86.R_DX);
        !           469:                HALT_SYS();
        !           470:                break;
        !           471:        }
        !           472: }
        !           473: 
        !           474: // main Interrupt Handler routine, should be registered as x86emu interrupt handler
        !           475: void
        !           476: handleInterrupt(int intNum)
        !           477: {
        !           478:        uint8_t int_handled = 0;
        !           479: #ifndef DEBUG_PRINT_INT10
        !           480:        // this printf makes output by int 10 unreadable...
        !           481:        // so we only enable it, if int10 print is disabled
        !           482:        DEBUG_PRINTF_INTR("%s(%x)\n", __FUNCTION__, intNum);
        !           483: #endif
        !           484:        switch (intNum) {
        !           485:        case 0x10:              //BIOS video interrupt
        !           486:        case 0x42:              // INT 10h relocated by EGA/VGA BIOS
        !           487:        case 0x6d:              // INT 10h relocated by VGA BIOS
        !           488:                // get interrupt vector from IDT (4 bytes per Interrupt starting at address 0
        !           489:                if ((my_rdl(intNum * 4) == 0xF000F065) ||       //F000:F065 is default BIOS interrupt handler address
        !           490:                    (my_rdl(intNum * 4) == 0xF4F4F4F4)) //invalid
        !           491:                {
        !           492: #if 0
        !           493:                        // ignore interrupt...
        !           494:                        DEBUG_PRINTF_INTR
        !           495:                            ("%s(%x): invalid interrupt Vector (%08x) found, interrupt ignored...\n",
        !           496:                             __FUNCTION__, intNum, my_rdl(intNum * 4));
        !           497:                        DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n",
        !           498:                                          M.x86.R_AX, M.x86.R_BX, M.x86.R_CX,
        !           499:                                          M.x86.R_DX);
        !           500:                        //HALT_SYS();
        !           501: #endif
        !           502:                        handleInt10();
        !           503:                        int_handled = 1;
        !           504:                }
        !           505:                break;
        !           506:        case 0x16:
        !           507:                // Keyboard BIOS Interrupt
        !           508:                handleInt16();
        !           509:                int_handled = 1;
        !           510:                break;
        !           511:        case 0x1a:
        !           512:                // PCI BIOS Interrupt
        !           513:                handleInt1a();
        !           514:                int_handled = 1;
        !           515:                break;
        !           516:        default:
        !           517:                printf("Interrupt %#x (Vector: %x) not implemented\n", intNum,
        !           518:                       my_rdl(intNum * 4));
        !           519:                DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n",
        !           520:                                  M.x86.R_AX, M.x86.R_BX, M.x86.R_CX,
        !           521:                                  M.x86.R_DX);
        !           522:                int_handled = 1;
        !           523:                HALT_SYS();
        !           524:                break;
        !           525:        }
        !           526:        // if we did not handle the interrupt, jump to the interrupt vector...
        !           527:        if (!int_handled) {
        !           528:                setupInt(intNum);
        !           529:        }
        !           530: }
        !           531: 
        !           532: // prepare and execute Interrupt 10 (VGA Interrupt)
        !           533: void
        !           534: runInt10()
        !           535: {
        !           536:        // Initialize stack and data segment
        !           537:        M.x86.R_SS = STACK_SEGMENT;
        !           538:        M.x86.R_DS = DATA_SEGMENT;
        !           539:        M.x86.R_SP = STACK_START_OFFSET;
        !           540: 
        !           541:        // push a HLT instruction and a pointer to it onto the stack
        !           542:        // any return will pop the pointer and jump to the HLT, thus
        !           543:        // exiting (more or less) cleanly
        !           544:        push_word(0xf4f4);      //F4=HLT
        !           545:        //push_word(M.x86.R_SS);
        !           546:        //push_word(M.x86.R_SP + 2);
        !           547: 
        !           548:        // setupInt will push the current CS and IP to the stack to return to it,
        !           549:        // but we want to halt, so set CS:IP to the HLT instruction we just pushed
        !           550:        // to the stack
        !           551:        M.x86.R_CS = M.x86.R_SS;
        !           552:        M.x86.R_IP = M.x86.R_SP;        // + 4;
        !           553: 
        !           554:        CHECK_DBG(DEBUG_TRACE_X86EMU) {
        !           555:                X86EMU_trace_on();
        !           556:        }
        !           557:        CHECK_DBG(DEBUG_JMP) {
        !           558:                M.x86.debug |= DEBUG_TRACEJMP_REGS_F;
        !           559:                M.x86.debug |= DEBUG_TRACEJMP_REGS_F;
        !           560:                M.x86.debug |= DEBUG_TRACECALL_F;
        !           561:                M.x86.debug |= DEBUG_TRACECALL_REGS_F;
        !           562:        }
        !           563:        setupInt(0x10);
        !           564:        DEBUG_PRINTF_INTR("%s(): starting execution of INT10...\n",
        !           565:                          __FUNCTION__);
        !           566:        X86EMU_exec();
        !           567:        DEBUG_PRINTF_INTR("%s(): execution finished\n", __FUNCTION__);
        !           568: }
        !           569: 
        !           570: // prepare and execute Interrupt 13 (Disk Interrupt)
        !           571: void
        !           572: runInt13()
        !           573: {
        !           574:        // Initialize stack and data segment
        !           575:        M.x86.R_SS = STACK_SEGMENT;
        !           576:        M.x86.R_DS = DATA_SEGMENT;
        !           577:        M.x86.R_SP = STACK_START_OFFSET;
        !           578: 
        !           579:        // push a HLT instruction and a pointer to it onto the stack
        !           580:        // any return will pop the pointer and jump to the HLT, thus
        !           581:        // exiting (more or less) cleanly
        !           582:        push_word(0xf4f4);      //F4=HLT
        !           583:        //push_word(M.x86.R_SS);
        !           584:        //push_word(M.x86.R_SP + 2);
        !           585: 
        !           586:        // setupInt will push the current CS and IP to the stack to return to it,
        !           587:        // but we want to halt, so set CS:IP to the HLT instruction we just pushed
        !           588:        // to the stack
        !           589:        M.x86.R_CS = M.x86.R_SS;
        !           590:        M.x86.R_IP = M.x86.R_SP;
        !           591: 
        !           592:        CHECK_DBG(DEBUG_TRACE_X86EMU) {
        !           593:                X86EMU_trace_on();
        !           594:        }
        !           595:        CHECK_DBG(DEBUG_JMP) {
        !           596:                M.x86.debug |= DEBUG_TRACEJMP_REGS_F;
        !           597:                M.x86.debug |= DEBUG_TRACEJMP_REGS_F;
        !           598:                M.x86.debug |= DEBUG_TRACECALL_F;
        !           599:                M.x86.debug |= DEBUG_TRACECALL_REGS_F;
        !           600:        }
        !           601: 
        !           602:        setupInt(0x13);
        !           603:        DEBUG_PRINTF_INTR("%s(): starting execution of INT13...\n",
        !           604:                          __FUNCTION__);
        !           605:        X86EMU_exec();
        !           606:        DEBUG_PRINTF_INTR("%s(): execution finished\n", __FUNCTION__);
        !           607: }

unix.superglobalmegacorp.com

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