OpenCores
URL https://opencores.org/ocsvn/ao486/ao486/trunk

Subversion Repositories ao486

[/] [ao486/] [trunk/] [bochsDevs/] [main.cpp] - Blame information for rev 5

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
 
2
#include <cstdio>
3
#include <cstdlib>
4
 
5
#include <dlfcn.h>
6
 
7
#include <sys/mman.h>
8
#include <sys/types.h>
9
#include <sys/stat.h>
10
#include <fcntl.h>
11
#include <unistd.h>
12
 
13
#include "shared_mem.h"
14
 
15
#include "bochs.h"
16
#include "plugin.h"
17
#include "extplugin.h"
18
#include "iodev/iodev.h"
19
#include "iodev/virt_timer.h"
20
 
21
//------------------------------------------------------------------------------
22
//------------------------------------------------------------------------------
23
//------------------------------------------------------------------------------
24
 
25
volatile shared_mem_t *shared_ptr = NULL;
26
 
27
//------------------------------------------------------------------------------
28
//------------------------------------------------------------------------------
29
//------------------------------------------------------------------------------
30
 
31
ioWriteHandler_t io_write_handlers[65537];
32
void *           io_write_this    [65537];
33
uint8            io_write_mask    [65537];
34
ioReadHandler_t  io_read_handlers [65537];
35
void *           io_read_this     [65537];
36
uint8            io_read_mask     [65537];
37
 
38
void  (*pluginRegisterIRQ)(unsigned irq, const char* name) = 0;
39
 
40
int (*pluginRegisterIOReadHandler)(void *thisPtr, ioReadHandler_t callback,
41
                            unsigned base, const char *name, Bit8u mask) = 0;
42
int (*pluginRegisterIOWriteHandler)(void *thisPtr, ioWriteHandler_t callback,
43
                             unsigned base, const char *name, Bit8u mask) = 0;
44
int (*pluginRegisterDefaultIOReadHandler)(void *thisPtr, ioReadHandler_t callback,
45
                            const char *name, Bit8u mask) = 0;
46
int (*pluginRegisterDefaultIOWriteHandler)(void *thisPtr, ioWriteHandler_t callback,
47
                             const char *name, Bit8u mask) = 0;
48
 
49
static void
50
builtinRegisterIRQ(unsigned irq, const char* name)
51
{
52
//bx_devices.register_irq(irq, name);
53
printf("builtinRegisterIRQ(%d, %s)\n", irq, name);
54
}
55
 
56
static int
57
builtinRegisterIOReadHandler(void *thisPtr, ioReadHandler_t callback,
58
                            unsigned base, const char *name, Bit8u mask)
59
{
60
//  int ret;
61
//  BX_ASSERT(mask<8);
62
//  ret = bx_devices.register_io_read_handler (thisPtr, callback, base, name, mask);
63
//  pluginlog->ldebug("plugin %s registered I/O read  address at %04x", name, base);
64
//  return ret;
65
 
66
printf("builtinRegisterIOReadHandler: %s %04x %d\n", name, base, mask);
67
    io_read_handlers[base] = callback;
68
    io_read_mask[base]     = mask;
69
    io_read_this[base]     = thisPtr;
70
 
71
    return 1;
72
}
73
 
74
static int
75
builtinRegisterIOWriteHandler(void *thisPtr, ioWriteHandler_t callback,
76
                             unsigned base, const char *name, Bit8u mask)
77
{
78
//  int ret;
79
//  BX_ASSERT(mask<8);
80
//  ret = bx_devices.register_io_write_handler (thisPtr, callback, base, name, mask);
81
//  pluginlog->ldebug("plugin %s registered I/O write address at %04x", name, base);
82
//  return ret;
83
 
84
printf("builtinRegisterIOWriteHandler: %s %04x %d\n", name, base, mask);
85
    io_write_handlers[base] = callback;
86
    io_write_mask[base]     = mask;
87
    io_write_this[base]     = thisPtr;
88
 
89
    return 1;
90
}
91
 
92
static int
93
builtinRegisterDefaultIOReadHandler(void *thisPtr, ioReadHandler_t callback,
94
                            const char *name, Bit8u mask)
95
{
96
//  BX_ASSERT(mask<8);
97
//  bx_devices.register_default_io_read_handler (thisPtr, callback, name, mask);
98
//  pluginlog->ldebug("plugin %s registered default I/O read ", name);
99
printf("builtinRegisterDefaultIOReadHandler: %s %x\n", name, mask);
100
    io_read_handlers[65536] = callback;
101
    io_read_mask[65536]     = mask;
102
    io_read_this[65536]     = thisPtr;
103
 
104
    return 1;
105
}
106
 
107
static int
108
builtinRegisterDefaultIOWriteHandler(void *thisPtr, ioWriteHandler_t callback,
109
                             const char *name, Bit8u mask)
110
{
111
//  BX_ASSERT(mask<8);
112
//  bx_devices.register_default_io_write_handler (thisPtr, callback, name, mask);
113
//  pluginlog->ldebug("plugin %s registered default I/O write ", name);
114
printf("builtinRegisterDefaultIOWriteHandler: %s %x\n", name, mask);
115
    io_write_handlers[65536] = callback;
116
    io_write_mask[65536]     = mask;
117
    io_write_this[65536]     = thisPtr;
118
 
119
    return 1;
120
}
121
 
122
void pluginRegisterDeviceDevmodel(plugin_t *plugin, plugintype_t type, bx_devmodel_c *devmodel, const char *name) {
123
printf("pluginRegisterDeviceDevmodel() for %s\n", name);
124
 
125
devmodel->init();
126
}
127
 
128
//------------------------------------------------------------------------------
129
//------------------------------------------------------------------------------
130
//------------------------------------------------------------------------------ SIM
131
 
132
const char *enum_choices[] = { "0_choice", "1_choice", NULL };
133
 
134
#define BOCHS_DEVS_IPS 480000
135
 
136
BxEvent *callback(void *theclass, BxEvent *event) {
137
printf("bochsDevs::callback()\n");
138
    return event;
139
}
140
 
141
bxevent_handler bxevent_callback      = callback;
142
void *          bxevent_callback_data = NULL;
143
 
144
class bochsDevs_sim : public bx_simulator_interface_c {
145
 
146
    bx_param_bool_c *get_param_bool(const char *pname, bx_param_c *base) {
147
printf("bochsDevs_sim::get_param_bool(%s, base=%s)\n", pname, (base==NULL)? "(nil)" : (base->get_name() == NULL)? "(nill name)" : base->get_name());
148
 
149
        if(base != NULL) {
150
            bx_param_c *param = ((bx_list_c *)base)->get_by_name(pname);
151
            return (bx_param_bool_c *)param;
152
        }
153
 
154
        if(strcmp(pname, BXPN_PORT_E9_HACK) == 0)           return new bx_param_bool_c(NULL, "port_e9_hack", "", "", 0);
155
        if(strcmp(pname, BXPN_CMOSIMAGE_ENABLED) == 0)      return new bx_param_bool_c(NULL, "enabled",      "", "", 0);
156
 
157
        if(strcmp(pname, BXPN_FLOPPYSIGCHECK) == 0)         return new bx_param_bool_c(NULL, "floppy_sig_check", "", "", 0);
158
        if(strcmp(pname, BXPN_PCI_ENABLED) == 0)            return new bx_param_bool_c(NULL, "enabled",          "", "", 0);
159
 
160
        if(strcmp(pname, BXPN_PRIVATE_COLORMAP) == 0)       return new bx_param_bool_c(NULL, "private_colormap", "", "", 0);
161
 
162
        if(strcmp(pname, BXPN_KBD_USEMAPPING) == 0)         return new bx_param_bool_c(NULL, "use_mapping", "", "", 0);
163
 
164
        if(strcmp(pname, BXPN_MOUSE_ENABLED) == 0)          return new bx_param_bool_c(NULL, "enabled", "", "", 0);
165
 
166
        return NULL;
167
    }
168
    bx_param_string_c *get_param_string(const char *pname, bx_param_c *base) {
169
printf("bochsDevs_sim::get_param_string(%s, base=%s)\n", pname, (base==NULL)? "(nil)" : (base->get_name() == NULL)? "(nill name)" : base->get_name());
170
 
171
        if(base != NULL) {
172
            bx_param_c *param = ((bx_list_c *)base)->get_by_name(pname);
173
            return (bx_param_string_c *)param;
174
        }
175
 
176
        if(strcmp(pname, BXPN_VGA_EXTENSION) == 0)          return new bx_param_string_c(NULL, "vga_extension",      "", "", "none");
177
        if(strcmp(pname, BXPN_DISPLAYLIB_OPTIONS) == 0)     return new bx_param_string_c(NULL, "displaylib_options", "", "", "");
178
 
179
        if(strcmp(pname, BXPN_VGA_ROM_PATH) == 0)     return new bx_param_string_c(NULL, "path", "", "", "");
180
 
181
        return NULL;
182
    }
183
    bx_param_enum_c *get_param_enum(const char *pname, bx_param_c *base) {
184
printf("bochsDevs_sim::get_param_enum(%s, base=%s)\n", pname, (base==NULL)? "(nil)" : (base->get_name() == NULL)? "(nill name)" : base->get_name());
185
 
186
        if(base != NULL) {
187
            bx_param_c *param = ((bx_list_c *)base)->get_by_name(pname);
188
            return (bx_param_enum_c *)param;
189
        }
190
 
191
        if(strcmp(pname, BXPN_CLOCK_SYNC) == 0)       return new bx_param_enum_c(NULL, "clock_sync", "", "", enum_choices, 0);
192
 
193
        if(strcmp(pname, BXPN_FLOPPYA_DEVTYPE) == 0)  return new bx_param_enum_c(NULL, "devtype", "", "", enum_choices, 0);
194
        if(strcmp(pname, BXPN_FLOPPYA_TYPE) == 0)     return new bx_param_enum_c(NULL, "type",    "", "", enum_choices, 0);
195
        if(strcmp(pname, BXPN_FLOPPYA_STATUS) == 0)   return new bx_param_enum_c(NULL, "status",  "", "", enum_choices, 0);
196
 
197
        if(strcmp(pname, BXPN_FLOPPYB_DEVTYPE) == 0)  return new bx_param_enum_c(NULL, "devtype", "", "", enum_choices, 0);
198
        if(strcmp(pname, BXPN_FLOPPYB_TYPE) == 0)     return new bx_param_enum_c(NULL, "type",    "", "", enum_choices, 0);
199
        if(strcmp(pname, BXPN_FLOPPYB_STATUS) == 0)   return new bx_param_enum_c(NULL, "status",  "", "", enum_choices, 0);
200
 
201
        if(strcmp(pname, BXPN_BOOTDRIVE1) == 0)       return new bx_param_enum_c(NULL, "boot_drive1", "", "", enum_choices, BX_BOOT_FLOPPYA);
202
        if(strcmp(pname, BXPN_BOOTDRIVE2) == 0)       return new bx_param_enum_c(NULL, "boot_drive2", "", "", enum_choices, BX_BOOT_FLOPPYA);
203
        if(strcmp(pname, BXPN_BOOTDRIVE3) == 0)       return new bx_param_enum_c(NULL, "boot_drive3", "", "", enum_choices, BX_BOOT_FLOPPYA);
204
 
205
        if(strcmp(pname, BXPN_MOUSE_TYPE) == 0)       return new bx_param_enum_c(NULL, "type", "", "", enum_choices, BX_MOUSE_TYPE_PS2);
206
 
207
        if(strcmp(pname, BXPN_MOUSE_TOGGLE) == 0)      return new bx_param_enum_c(NULL, "toggle", "", "", enum_choices, BX_MOUSE_TOGGLE_CTRL_F10);
208
 
209
        if(strcmp(pname, BXPN_KBD_TYPE) == 0)         return new bx_param_enum_c(NULL, "type", "", "", enum_choices, BX_KBD_AT_TYPE);
210
 
211
        return NULL;
212
    }
213
    bx_param_num_c *get_param_num(const char *pname, bx_param_c *base) {
214
printf("bochsDevs_sim::get_param_num(%s, base=%s)\n", pname, (base==NULL)? "(nil)" : (base->get_name() == NULL)? "(nill name)" : base->get_name());
215
 
216
        if(base != NULL) {
217
            bx_param_c *param = ((bx_list_c *)base)->get_by_name(pname);
218
            return (bx_param_num_c *)param;
219
        }
220
 
221
        if(strcmp(pname, BXPN_CLOCK_TIME0) == 0)  return new bx_param_num_c(NULL, "time0",   "", "", 100,100,100);
222
 
223
        if(strcmp(pname, BXPN_KBD_SERIAL_DELAY) == 0) return new bx_param_num_c(NULL, "serial_delay",   "", "", 100,100,100);
224
        if(strcmp(pname, BXPN_KBD_PASTE_DELAY) == 0)  return new bx_param_num_c(NULL, "paste_delay",   "", "", 100,100,100);
225
        if(strcmp(pname, BXPN_MOUSE_ENABLED) == 0)    return new bx_param_num_c(NULL, "enabled",   "", "", 1,1,1);
226
 
227
        if(strcmp(pname, BXPN_VGA_UPDATE_FREQUENCY) == 0)   return new bx_param_num_c(NULL, "vga_update_frequency",   "", "", 500000,500000,500000);
228
 
229
        if(strcmp(pname, BXPN_IPS) == 0)   return new bx_param_num_c(NULL, "ips",   "", "", BOCHS_DEVS_IPS, BOCHS_DEVS_IPS, BOCHS_DEVS_IPS);
230
        return NULL;
231
    }
232
    bx_param_c *get_param(const char *pname, bx_param_c *base=NULL) {
233
        if(strcmp(pname, BXPN_ATA0_RES) == 0) {
234
            bx_list_c *list = new bx_list_c(NULL);
235
            list->add(new bx_param_bool_c(NULL, "enabled", "", "", 1));
236
            list->add(new bx_param_num_c(NULL,  "ioaddr1", "", "", 0x1f0,0x1f0,0x1f0));
237
            list->add(new bx_param_num_c(NULL,  "ioaddr2", "", "", 0x3f0,0x3f0,0x3f0));
238
            list->add(new bx_param_num_c(NULL,  "irq",     "", "", 14,14,14));
239
            return list;
240
        }
241
        if(strcmp(pname, BXPN_ATA1_RES) == 0 || strcmp(pname, BXPN_ATA2_RES) == 0 || strcmp(pname, BXPN_ATA3_RES) == 0) {
242
            bx_list_c *list = new bx_list_c(NULL);
243
            list->add(new bx_param_bool_c(NULL, "enabled", "", "", 0));
244
            return list;
245
        }
246
        if(strcmp(pname, BXPN_FLOPPYA) == 0 || strcmp(pname, BXPN_FLOPPYB) == 0) {
247
            bx_list_c *list = new bx_list_c(NULL);
248
            list->add(new bx_param_enum_c(NULL,   "status",   "", "", enum_choices, 0));
249
            list->add(new bx_param_bool_c(NULL,   "readonly", "", "", 1));
250
            list->add(new bx_param_string_c(NULL, "path",     "", "", "none"));
251
            return list;
252
        }
253
        if(strcmp(pname, BXPN_ATA0_MASTER) == 0) {
254
            bx_list_c *list = new bx_list_c(NULL);
255
            list->add(new bx_param_enum_c(NULL,   "type",        "", "", enum_choices, BX_ATA_DEVICE_DISK));
256
            list->add(new bx_param_string_c(NULL, "model",       "", "", "HDmodel"));
257
            list->add(new bx_param_num_c(NULL,    "cylinders",   "", "", 1024,1024,1024));
258
            list->add(new bx_param_num_c(NULL,    "heads",       "", "", 16,16,16));
259
            list->add(new bx_param_num_c(NULL,    "spt",         "", "", 63,63,63));
260
            list->add(new bx_param_enum_c(NULL,   "mode",        "", "", enum_choices, BX_HDIMAGE_MODE_FLAT));
261
            list->add(new bx_param_string_c(NULL, "path",        "", "", "/home/alek/temp/bochs-run/hd.img"));
262
            list->add(new bx_param_string_c(NULL, "journal",     "", "", ""));
263
            list->add(new bx_param_enum_c(NULL,   "translation", "", "", enum_choices, BX_ATA_TRANSLATION_NONE));
264
            return list;
265
        }
266
        if(strcmp(pname, BXPN_ATA1_MASTER) == 0 || strcmp(pname, BXPN_ATA2_MASTER) == 0 || strcmp(pname, BXPN_ATA3_MASTER) == 0 ||
267
           strcmp(pname, BXPN_ATA0_SLAVE) == 0  || strcmp(pname, BXPN_ATA1_SLAVE) == 0  || strcmp(pname, BXPN_ATA2_SLAVE) == 0  || strcmp(pname, BXPN_ATA3_SLAVE) == 0)
268
        {
269
            bx_list_c *list = new bx_list_c(NULL);
270
            list->add(new bx_param_enum_c(NULL, "type", "", "", enum_choices, BX_ATA_DEVICE_NONE));
271
            return list;
272
        }
273
        return NULL;
274
    }
275
    void set_notify_callback(bxevent_handler func, void *arg) {
276
        bxevent_callback = func;
277
        bxevent_callback_data = arg;
278
    }
279
 
280
    void get_notify_callback(bxevent_handler *func, void **arg) {
281
        *func = bxevent_callback;
282
        *arg = bxevent_callback_data;
283
    }
284
};
285
 
286
bx_simulator_interface_c *SIM;
287
 
288
//------------------------------------------------------------------------------
289
//------------------------------------------------------------------------------
290
//------------------------------------------------------------------------------ logfunctions
291
 
292
void logfunctions::panic(const char *fmt, ...) {
293
    printf("#bochsDevs::logfunctions::panic(): ");
294
 
295
    va_list ap;
296
    va_start(ap, fmt);
297
    vprintf(fmt, ap);
298
    va_end(ap);
299
 
300
    printf("\n");
301
    fflush(stdout);
302
 
303
    if(strstr(fmt, "exception with no resolution") != NULL) {
304
        printf("start_shutdown: 0\n");
305
        printf("\n");
306
        fflush(stdout);
307
        exit(0);
308
    }
309
    else {
310
        exit(-1);
311
    }
312
}
313
void logfunctions::error(const char *fmt, ...) {
314
    printf("#bochsDevs::logfunctions::error(): ");
315
 
316
    va_list ap;
317
    va_start(ap, fmt);
318
    vprintf(fmt, ap);
319
    va_end(ap);
320
 
321
    printf("\n");
322
    fflush(stdout);
323
}
324
void logfunctions::ldebug(const char *fmt, ...) {
325
    printf("#bochsDevs::logfunctions::debug(): ");
326
 
327
    va_list ap;
328
    va_start(ap, fmt);
329
    vprintf(fmt, ap);
330
    va_end(ap);
331
 
332
    printf("\n");
333
    fflush(stdout);
334
}
335
void logfunctions::info(const char *fmt, ...) {
336
    printf("#bochsDevs::logfunctions::info(): ");
337
 
338
    va_list ap;
339
    va_start(ap, fmt);
340
    vprintf(fmt, ap);
341
    va_end(ap);
342
 
343
    printf("\n");
344
    fflush(stdout);
345
}
346
void logfunctions::put(const char *n, const char *p) {
347
}
348
void logfunctions::put(const char *p) {
349
}
350
logfunctions::logfunctions() {
351
}
352
logfunctions::~logfunctions() {
353
}
354
 
355
static logfunctions theLog;
356
logfunctions *pluginlog         = &theLog;
357
logfunctions *siminterface_log  = &theLog;
358
logfunctions *genlog            = &theLog;
359
 
360
//------------------------------------------------------------------------------
361
//------------------------------------------------------------------------------
362
//------------------------------------------------------------------------------ menu
363
 
364
void bx_param_string_c::text_print(FILE *fp) {
365
printf("#bochsDevs::bx_param_string_c::text_print()\n");
366
}
367
void bx_param_enum_c::text_print(FILE *fp) {
368
printf("bochsDevs::bx_param_enum_c::text_print()\n");
369
}
370
void bx_param_bool_c::text_print(FILE *fp) {
371
printf("bochsDevs::bx_param_bool_c::text_print()\n");
372
}
373
void bx_param_num_c::text_print(FILE *fp) {
374
printf("bochsDevs::bx_param_num_c::text_print()\n");
375
}
376
void bx_list_c::text_print(FILE *fp) {
377
printf("bochsDevs::bx_list_c::text_print()\n");
378
}
379
int bx_param_enum_c::text_ask(FILE *fpin, FILE *fpout) {
380
printf("bochsDevs::bx_param_enum_c::text_ask()\n");
381
    return 0;
382
}
383
int bx_param_bool_c::text_ask(FILE *fpin, FILE *fpout) {
384
printf("bochsDevs::bx_param_bool_c::text_ask()\n");
385
    return 0;
386
}
387
int bx_param_num_c::text_ask(FILE *fpin, FILE *fpout) {
388
printf("bochsDevs::bx_param_num_c::text_ask()\n");
389
    return 0;
390
}
391
int bx_param_string_c::text_ask(FILE *fpin, FILE *fpout) {
392
printf("bochsDevs::bx_param_string_c::text_ask()\n");
393
    return 0;
394
}
395
int bx_list_c::text_ask(FILE *fpin, FILE *fpout) {
396
printf("bochsDevs::bx_list_c::text_ask()\n");
397
    return 0;
398
}
399
 
400
bx_list_c *root_param = NULL;
401
 
402
//------------------------------------------------------------------------------
403
//------------------------------------------------------------------------------
404
//------------------------------------------------------------------------------ memory
405
 
406
memory_handler_t vga_read_memory  = NULL;
407
memory_handler_t vga_write_memory = NULL;
408
void *           vga_param        = NULL;
409
 
410
BX_MEM_C::BX_MEM_C() {
411
}
412
BX_MEM_C::~BX_MEM_C() {
413
}
414
 
415
void BX_MEM_C::dmaReadPhysicalPage(bx_phy_address addr, unsigned len, Bit8u *data)  {
416
printf("bochsDevs::BX_MEM_C::dmaReadPhysicalPage()\n");
417
 
418
    memcpy(data, (void *)(shared_ptr->mem.bytes + addr), len);
419
}
420
 
421
void BX_MEM_C::dmaWritePhysicalPage(bx_phy_address addr, unsigned len, Bit8u *data) {
422
printf("bochsDevs::BX_MEM_C::dmaWritePhysicalPage()\n");
423
 
424
    memcpy((void *)(shared_ptr->mem.bytes + addr), data, len);
425
}
426
 
427
bx_bool
428
BX_MEM_C::registerMemoryHandlers(void *param, memory_handler_t read_handler,
429
                memory_handler_t write_handler, memory_direct_access_handler_t da_handler,
430
                bx_phy_address begin_addr, bx_phy_address end_addr)
431
{
432
printf("bochsDevs::BX_MEM_C::registerMemoryHandlers(): %llx %llx\n", begin_addr, end_addr);
433
    if(da_handler != NULL) {
434
        printf("bochsDevs::da_handler != NULL\n");
435
        exit(-1);
436
    }
437
    if(begin_addr != 0xA0000 || end_addr != 0xBFFFF) {
438
        printf("bochsDevs::invalid address\n");
439
        exit(-1);
440
    }
441
 
442
    vga_read_memory = read_handler;
443
    vga_write_memory= write_handler;
444
    vga_param       = param;
445
 
446
return 1;
447
}
448
 
449
void BX_MEM_C::load_ROM(const char *path, bx_phy_address romaddress, Bit8u type) {
450
printf("bochsDevs::BX_MEM_C::load_ROM()\n");
451
}
452
 
453
BX_MEM_C bx_mem;
454
 
455
 
456
//------------------------------------------------------------------------------
457
//------------------------------------------------------------------------------
458
//------------------------------------------------------------------------------
459
 
460
bx_bool bx_dbg_register_debug_info(const char *devname, void *dev) {
461
printf("bochsDevs::bx_dbg_register_debug_info() %s\n", devname);
462
return true;
463
}
464
 
465
void dbg_printf(const char *fmt, ...) {
466
printf("bochsDevs::dbg_printf(%s)\n", fmt);
467
}
468
 
469
void bx_dbg_dma_report(bx_phy_address addr, unsigned len, unsigned what, Bit32u val) {
470
printf("bochsDevs::bx_dbg_dma_report()\n");
471
}
472
 
473
void bx_dbg_iac_report(unsigned vector, unsigned irq) {
474
printf("bochsDevs::bx_dbg_iac_report()\n");
475
}
476
 
477
void bx_debug_break() {
478
printf("bochsDevs::bx_debug_break()\n");
479
}
480
 
481
bx_guard_t bx_guard;
482
 
483
//------------------------------------------------------------------------------
484
//------------------------------------------------------------------------------
485
//------------------------------------------------------------------------------
486
 
487
#define MinAllowableTimerPeriod 1
488
 
489
const Bit64u bx_pc_system_c::NullTimerInterval = 0xffffffff;
490
 
491
bx_pc_system_c::bx_pc_system_c() {
492
  this->put("pc_system", "SYS");
493
 
494
  BX_ASSERT(numTimers == 0);
495
 
496
  // Timer[0] is the null timer.  It is initialized as a special
497
  // case here.  It should never be turned off or modified, and its
498
  // duration should always remain the same.
499
  ticksTotal = 0; // Reset ticks since emulator started.
500
  timer[0].inUse      = 1;
501
  timer[0].period     = NullTimerInterval;
502
  timer[0].active     = 1;
503
  timer[0].continuous = 1;
504
  timer[0].funct      = nullTimer;
505
  timer[0].this_ptr   = this;
506
  numTimers = 1; // So far, only the nullTimer.
507
 
508
  //initialize()
509
  ticksTotal = 0;
510
  timer[0].timeToFire = NullTimerInterval;
511
  currCountdown       = NullTimerInterval;
512
  currCountdownPeriod = NullTimerInterval;
513
  lastTimeUsec = 0;
514
  usecSinceLast = 0;
515
  triggeredTimer = 0;
516
  HRQ = 0;
517
  kill_bochs_request = 0;
518
 
519
  // parameter 'ips' is the processor speed in Instructions-Per-Second
520
  m_ips = BOCHS_DEVS_IPS / 1000000.0L;
521
}
522
 
523
void bx_pc_system_c::nullTimer(void* this_ptr) {
524
}
525
 
526
int bx_pc_system_c::register_timer_ticks(void* this_ptr, bx_timer_handler_t funct,
527
    Bit64u ticks, bx_bool continuous, bx_bool active, const char *id)
528
{
529
  unsigned i;
530
 
531
  // If the timer frequency is rediculously low, make it more sane.
532
  // This happens when 'ips' is too low.
533
  if (ticks < MinAllowableTimerPeriod) {
534
    //BX_INFO(("register_timer_ticks: adjusting ticks of %llu to min of %u",
535
    //          ticks, MinAllowableTimerPeriod));
536
    ticks = MinAllowableTimerPeriod;
537
  }
538
 
539
  // search for new timer for i=1, i=0 is reserved for NullTimer
540
  for (i=1; i < numTimers; i++) {
541
    if (timer[i].inUse == 0)
542
      break;
543
  }
544
 
545
  timer[i].inUse      = 1;
546
  timer[i].period     = ticks;
547
  timer[i].timeToFire = (ticksTotal + Bit64u(currCountdownPeriod-currCountdown)) + ticks;
548
  timer[i].active     = active;
549
  timer[i].continuous = continuous;
550
  timer[i].funct      = funct;
551
  timer[i].this_ptr   = this_ptr;
552
  strncpy(timer[i].id, id, BxMaxTimerIDLen);
553
  timer[i].id[BxMaxTimerIDLen-1] = 0; // Null terminate if not already.
554
 
555
  if (active) {
556
    if (ticks < Bit64u(currCountdown)) {
557
      // This new timer needs to fire before the current countdown.
558
      // Skew the current countdown and countdown period to be smaller
559
      // by the delta.
560
      currCountdownPeriod -= (currCountdown - Bit32u(ticks));
561
      currCountdown = Bit32u(ticks);
562
    }
563
  }
564
 
565
printf("bochsDevs::timer id %d registered for '%s'", i, id);
566
  // If we didn't find a free slot, increment the bound, numTimers.
567
  if (i==numTimers)
568
    numTimers++; // One new timer installed.
569
 
570
  // Return timer id.
571
  return(i);
572
}
573
 
574
int bx_pc_system_c::register_timer(void *this_ptr, void (*funct)(void *),
575
  Bit32u useconds, bx_bool continuous, bx_bool active, const char *id)
576
{
577
printf("bochsDevs::bx_pc_system_c::register_timer()\n");
578
 
579
    // Convert useconds to number of ticks.
580
  Bit64u ticks = (Bit64u) (double(useconds) * m_ips);
581
 
582
  return register_timer_ticks(this_ptr, funct, ticks, continuous, active, id);
583
}
584
 
585
void bx_pc_system_c::activate_timer_ticks(unsigned i, Bit64u ticks, bx_bool continuous)
586
{
587
  // If the timer frequency is rediculously low, make it more sane.
588
  // This happens when 'ips' is too low.
589
  if (ticks < MinAllowableTimerPeriod) {
590
    //BX_INFO(("activate_timer_ticks: adjusting ticks of %llu to min of %u",
591
    //          ticks, MinAllowableTimerPeriod));
592
    ticks = MinAllowableTimerPeriod;
593
  }
594
 
595
  timer[i].period = ticks;
596
  timer[i].timeToFire = (ticksTotal + Bit64u(currCountdownPeriod-currCountdown)) + ticks;
597
  timer[i].active     = 1;
598
  timer[i].continuous = continuous;
599
 
600
  if (ticks < Bit64u(currCountdown)) {
601
    // This new timer needs to fire before the current countdown.
602
    // Skew the current countdown and countdown period to be smaller
603
    // by the delta.
604
    currCountdownPeriod -= (currCountdown - Bit32u(ticks));
605
    currCountdown = Bit32u(ticks);
606
  }
607
}
608
 
609
void bx_pc_system_c::activate_timer(unsigned i, Bit32u useconds, bx_bool continuous)
610
{
611
//printf("bochsDevs::bx_pc_system_c::activate_timer(%d, %d, %d)\n", i, useconds, continuous);
612
 
613
  Bit64u ticks;
614
 
615
  // if useconds = 0, use default stored in period field
616
  // else set new period from useconds
617
  if (useconds==0) {
618
    ticks = timer[i].period;
619
  }
620
  else {
621
    // convert useconds to number of ticks
622
    ticks = (Bit64u) (double(useconds) * m_ips);
623
 
624
    // If the timer frequency is rediculously low, make it more sane.
625
    // This happens when 'ips' is too low.
626
    if (ticks < MinAllowableTimerPeriod) {
627
      //BX_INFO(("activate_timer: adjusting ticks of %llu to min of %u",
628
      //          ticks, MinAllowableTimerPeriod));
629
      ticks = MinAllowableTimerPeriod;
630
    }
631
 
632
    timer[i].period = ticks;
633
  }
634
 
635
  activate_timer_ticks(i, ticks, continuous);
636
}
637
 
638
void bx_pc_system_c::deactivate_timer(unsigned i) {
639
//printf("bochsDevs::bx_pc_system_c::deactivate_timer(%d)\n", i);
640
 
641
    timer[i].active = 0;
642
}
643
 
644
Bit64u bx_pc_system_c::time_usec() {
645
  return (Bit64u) (((double)(Bit64s)time_ticks()) / m_ips);
646
}
647
 
648
void bx_pc_system_c::countdownEvent(void) {
649
  unsigned i;
650
  Bit64u   minTimeToFire;
651
  bx_bool  triggered[BX_MAX_TIMERS];
652
 
653
  // Increment global ticks counter by number of ticks which have
654
  // elapsed since the last update.
655
  ticksTotal += Bit64u(currCountdownPeriod);
656
  minTimeToFire = (Bit64u) -1;
657
 
658
  for (i=0; i < numTimers; i++) {
659
    triggered[i] = 0; // Reset triggered flag.
660
    if (timer[i].active) {
661
      if (ticksTotal == timer[i].timeToFire) {
662
        // This timer is ready to fire.
663
        triggered[i] = 1;
664
 
665
        if (timer[i].continuous==0) {
666
          // If triggered timer is one-shot, deactive.
667
          timer[i].active = 0;
668
        }
669
        else {
670
          // Continuous timer, increment time-to-fire by period.
671
          timer[i].timeToFire += timer[i].period;
672
          if (timer[i].timeToFire < minTimeToFire)
673
            minTimeToFire = timer[i].timeToFire;
674
        }
675
      }
676
      else {
677
        // This timer is not ready to fire yet.
678
        if (timer[i].timeToFire < minTimeToFire)
679
          minTimeToFire = timer[i].timeToFire;
680
      }
681
    }
682
  }
683
 
684
  // Calculate next countdown period.  We need to do this before calling
685
  // any of the callbacks, as they may call timer features, which need
686
  // to be advanced to the next countdown cycle.
687
  currCountdown = currCountdownPeriod =
688
      Bit32u(minTimeToFire - ticksTotal);
689
 
690
  for (i=0; i < numTimers; i++) {
691
    // Call requested timer function.  It may request a different
692
    // timer period or deactivate etc.
693
    if (triggered[i]) {
694
      triggeredTimer = i;
695
      timer[i].funct(timer[i].this_ptr);
696
      triggeredTimer = 0;
697
    }
698
  }
699
}
700
 
701
//------------------------------------------------------------------------------
702
 
703
bool a20_state = true;
704
 
705
void bx_pc_system_c::set_HRQ(bx_bool val) {
706
printf("bochsDevs::bx_pc_system_c::set_HRQ() %d\n", val);
707
 
708
    if(val) {
709
        bx_devices.pluginDmaDevice->raise_HLDA();
710
    }
711
}
712
 
713
int bx_pc_system_c::Reset(unsigned type) {
714
printf("bochsDevs::bx_pc_system_c::Reset() %d\n", type);
715
std::exit(-1);
716
    return 0;
717
}
718
 
719
bx_bool bx_pc_system_c::get_enable_a20(void) {
720
printf("bochsDevs::bx_pc_system_c::get_enable_a20() %d\n", a20_state);
721
  return a20_state;
722
}
723
 
724
void bx_pc_system_c::set_enable_a20(bx_bool value) {
725
printf("bochsDevs::bx_pc_system_c::set_enable_a20(%d) %d\n", value, a20_state);
726
    a20_state = value;
727
}
728
 
729
void bx_pc_system_c::clear_INTR(void) {
730
printf("bochsDevs::bx_pc_system_c::clear_INTR()\n");
731
    shared_ptr->interrupt_at_counter = 0;
732
}
733
 
734
void bx_pc_system_c::raise_INTR(void) {
735
printf("bochsDevs::bx_pc_system_c::raise_INTR()\n");
736
 
737
    uint32 last = shared_ptr->interrupt_at_counter;
738
 
739
    shared_ptr->interrupt_vector = bx_devices.pluginPicDevice->IAC();
740
 
741
    uint32 v1 = shared_ptr->bochs486_pc.instr_counter + 5;
742
    uint32 v2 = shared_ptr->ao486.instr_counter + 5;
743
 
744
    shared_ptr->interrupt_at_counter = (v1 > v2)? v1 : v2;
745
 
746
printf("interrupt: %02x\n", shared_ptr->interrupt_vector);
747
 
748
    FILE *interrupt_fp = fopen("interrupt.txt", "a");
749
    fprintf(interrupt_fp, "irq %02x at %d (%d %d) %d\n", shared_ptr->interrupt_vector, shared_ptr->interrupt_at_counter, v1, v2, shared_ptr->interrupt_at_counter - last);
750
    fclose(interrupt_fp);
751
}
752
 
753
class capture_pic_stub_c : public bx_pic_stub_c {
754
public:
755
    capture_pic_stub_c(bx_pic_stub_c *orig) {
756
        this->orig = orig;
757
    }
758
 
759
    virtual void raise_irq(unsigned irq_no) {
760
        FILE *fp = fopen("track.txt", "a");
761
        fprintf(fp, "raise_irq %d\n", irq_no);
762
        fclose(fp);
763
 
764
        orig->raise_irq(irq_no);
765
    }
766
 
767
    virtual void lower_irq(unsigned irq_no) {
768
        FILE *fp = fopen("track.txt", "a");
769
        fprintf(fp, "lower_irq %d\n", irq_no);
770
        fclose(fp);
771
 
772
        orig->lower_irq(irq_no);
773
    }
774
 
775
    virtual void set_mode(bx_bool ma_sl, Bit8u mode) {
776
        FILE *fp = fopen("track.txt", "a");
777
        fprintf(fp, "set_mode %d %d\n", ma_sl, mode);
778
        fclose(fp);
779
 
780
        orig->set_mode(ma_sl, mode);
781
    }
782
 
783
    virtual Bit8u IAC(void) {
784
        Bit8u ret = orig->IAC();
785
 
786
        FILE *fp = fopen("track.txt", "a");
787
        fprintf(fp, "IAC %d\n", ret);
788
        fclose(fp);
789
 
790
        return ret;
791
    }
792
 
793
private:
794
    bx_pic_stub_c *orig;
795
};
796
 
797
bx_pc_system_c bx_pc_system;
798
 
799
//------------------------------------------------------------------------------
800
//------------------------------------------------------------------------------
801
//------------------------------------------------------------------------------
802
 
803
Bit64u bx_get_realtime64_usec(void)
804
{
805
  timeval thetime;
806
  gettimeofday(&thetime,0);
807
  Bit64u mytime;
808
  mytime=(Bit64u)thetime.tv_sec*(Bit64u)1000000+(Bit64u)thetime.tv_usec;
809
  return mytime;
810
}
811
 
812
//------------------------------------------------------------------------------
813
//------------------------------------------------------------------------------
814
//------------------------------------------------------------------------------
815
 
816
bx_devices_c::bx_devices_c() {
817
}
818
bx_devices_c::~bx_devices_c() {
819
}
820
 
821
void bx_devices_c::mouse_motion(int delta_x, int delta_y, int delta_z, unsigned button_state, bx_bool absxy) {
822
printf("bochsDevs::bx_devices_c::mouse_motion()\n");
823
  // If mouse events are disabled on the GUI headerbar, don't
824
  // generate any mouse data
825
  if (!mouse_captured)
826
    return;
827
 
828
  // if a removable mouse is connected, redirect mouse data to the device
829
  if (bx_mouse[1].dev != NULL) {
830
    bx_mouse[1].enq_event(bx_mouse[1].dev, delta_x, delta_y, delta_z, button_state, absxy);
831
    return;
832
  }
833
 
834
  // if a mouse is connected, direct mouse data to the device
835
  if (bx_mouse[0].dev != NULL) {
836
    bx_mouse[0].enq_event(bx_mouse[0].dev, delta_x, delta_y, delta_z, button_state, absxy);
837
  }
838
}
839
 
840
bx_bool bx_devices_c::optional_key_enq(Bit8u *scan_code) {
841
printf("bochsDevs::bx_devices_c::optional_key_enq()\n");
842
  if (bx_keyboard.dev != NULL) {
843
    return bx_keyboard.enq_event(bx_keyboard.dev, scan_code);
844
  }
845
  return 0;
846
}
847
 
848
void bx_devices_c::mouse_enabled_changed(bx_bool enabled) {
849
printf("bochsDevs::bx_devices_c::mouse_enabled_changed()\n");
850
  mouse_captured = enabled;
851
 
852
  if ((bx_mouse[1].dev != NULL) && (bx_mouse[1].enabled_changed != NULL)) {
853
    bx_mouse[1].enabled_changed(bx_mouse[1].dev, enabled);
854
    return;
855
  }
856
 
857
  if ((bx_mouse[0].dev != NULL) && (bx_mouse[0].enabled_changed != NULL)) {
858
    bx_mouse[0].enabled_changed(bx_mouse[0].dev, enabled);
859
  }
860
}
861
 
862
void bx_devices_c::register_default_mouse(void *dev, bx_mouse_enq_t mouse_enq,
863
                                          bx_mouse_enabled_changed_t mouse_enabled_changed)
864
{
865
printf("bochsDevs::bx_devices_c::register_default_mouse()\n");
866
  if (bx_mouse[0].dev == NULL) {
867
    bx_mouse[0].dev = dev;
868
    bx_mouse[0].enq_event = mouse_enq;
869
    bx_mouse[0].enabled_changed = mouse_enabled_changed;
870
  }
871
}
872
 
873
bx_devices_c bx_devices;
874
 
875
//------------------------------------------------------------------------------
876
//------------------------------------------------------------------------------
877
//------------------------------------------------------------------------------
878
 
879
const char *hdimage_mode_names[] = {
880
  "flat",
881
  "concat",
882
  "external",
883
  "dll",
884
  "sparse",
885
  "vmware3",
886
  "vmware4",
887
  "undoable",
888
  "growing",
889
  "volatile",
890
  "vvfat",
891
  "vpc",
892
  NULL
893
};
894
 
895
void bx_stop_simulation() {
896
printf("bochsDevs::bx_stop_simulation()\n");
897
}
898
 
899
class BX_CPU_C : public logfunctions {
900
};
901
 
902
BX_CPU_C bx_cpu;
903
 
904
bx_bool bx_user_quit;
905
 
906
//------------------------------------------------------------------------------
907
//------------------------------------------------------------------------------
908
//------------------------------------------------------------------------------
909
 
910
void register_plugin(const char *libname, const char *initname) {
911
 
912
    void *handle;
913
 
914
    handle = dlopen(libname, RTLD_NOW | RTLD_GLOBAL);
915
 
916
    if(handle == NULL) {
917
        char *error = dlerror();
918
 
919
        printf("dlopen() error: %s\n", error);
920
        exit(-1);
921
    }
922
 
923
 
924
    plugin_init_t plugin_init = (plugin_init_t)dlsym(handle, initname);
925
    if(plugin_init == NULL) {
926
        char *error = dlerror();
927
 
928
        printf("dlsym() error: %s\n", error);
929
 
930
        dlclose(handle);
931
        exit(-2);
932
    }
933
 
934
    plugin_init(NULL, PLUGTYPE_CORE, 0,NULL);
935
 
936
    //dlclose(handle);
937
}
938
 
939
int main(int argc, char **argv) {
940
 
941
    //map shared memory
942
    int fd = open("./../sim/sim_pc/shared_mem.dat", O_RDWR, S_IRUSR | S_IWUSR);
943
 
944
    if(fd == -1) {
945
        perror("open() failed for shared_mem.dat");
946
        return -1;
947
    }
948
 
949
    shared_ptr = (shared_mem_t *)mmap(NULL, sizeof(shared_mem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
950
 
951
    if(shared_ptr == MAP_FAILED) {
952
        perror("mmap() failed");
953
        close(fd);
954
        return -2;
955
    }
956
 
957
    //wait for ack
958
 
959
    shared_ptr->bochsDevs_starting = STEP_REQ;
960
    printf("Waiting for startup ack...");
961
    fflush(stdout);
962
    while(shared_ptr->bochsDevs_starting != STEP_ACK) {
963
        usleep(100000);
964
    }
965
    printf("done.\n");
966
 
967
    //--------------------------------------------------------------------------
968
 
969
    printf("bochsDevs\n");
970
 
971
    FILE *debug_fp = fopen("output.txt", "w");
972
 
973
    pluginRegisterIRQ = builtinRegisterIRQ;
974
 
975
    pluginRegisterIOReadHandler = builtinRegisterIOReadHandler;
976
    pluginRegisterIOWriteHandler = builtinRegisterIOWriteHandler;
977
 
978
    pluginRegisterDefaultIOReadHandler = builtinRegisterDefaultIOReadHandler;
979
    pluginRegisterDefaultIOWriteHandler = builtinRegisterDefaultIOWriteHandler;
980
 
981
 
982
    SIM = new bochsDevs_sim();
983
 
984
    bx_virt_timer.init();
985
 
986
    register_plugin("/opt/bochs-2.6.2/lib/bochs/plugins/libbx_unmapped.so.0.0.0",   "libunmapped_LTX_plugin_init");
987
    register_plugin("/opt/bochs-2.6.2/lib/bochs/plugins/libbx_biosdev.so.0.0.0",    "libbiosdev_LTX_plugin_init");
988
    register_plugin("/opt/bochs-2.6.2/lib/bochs/plugins/libbx_cmos.so.0.0.0",       "libcmos_LTX_plugin_init");
989
    register_plugin("/opt/bochs-2.6.2/lib/bochs/plugins/libbx_dma.so.0.0.0",        "libdma_LTX_plugin_init");
990
    register_plugin("/opt/bochs-2.6.2/lib/bochs/plugins/libbx_x.so.0.0.0",          "libx_LTX_plugin_init");
991
    register_plugin("/opt/bochs-2.6.2/lib/bochs/plugins/libbx_floppy.so.0.0.0",     "libfloppy_LTX_plugin_init");
992
    register_plugin("/opt/bochs-2.6.2/lib/bochs/plugins/libbx_hdimage.so.0.0.0",    "libhdimage_LTX_plugin_init");
993
    register_plugin("/opt/bochs-2.6.2/lib/bochs/plugins/libbx_harddrv.so.0.0.0",    "libharddrv_LTX_plugin_init");
994
    register_plugin("/opt/bochs-2.6.2/lib/bochs/plugins/libbx_iodebug.so.0.0.0",    "libiodebug_LTX_plugin_init");
995
    register_plugin("/opt/bochs-2.6.2/lib/bochs/plugins/libbx_keyboard.so.0.0.0",   "libkeyboard_LTX_plugin_init");
996
    register_plugin("/opt/bochs-2.6.2/lib/bochs/plugins/libbx_pic.so.0.0.0",        "libpic_LTX_plugin_init");
997
    register_plugin("/opt/bochs-2.6.2/lib/bochs/plugins/libbx_pit.so.0.0.0",        "libpit_LTX_plugin_init");
998
    register_plugin("/opt/bochs-2.6.2/lib/bochs/plugins/libbx_speaker.so.0.0.0",    "libspeaker_LTX_plugin_init");
999
    register_plugin("/opt/bochs-2.6.2/lib/bochs/plugins/libbx_vga.so.0.0.0",        "libvga_LTX_plugin_init");
1000
 
1001
    // misc. CMOS
1002
    Bit64u memory_in_bytes = sizeof(shared_ptr->mem.bytes);
1003
    Bit64u BASE_MEMORY_IN_K = 640;
1004
 
1005
    Bit64u memory_in_k = memory_in_bytes / 1024;
1006
    Bit64u extended_memory_in_k = memory_in_k > 1024 ? (memory_in_k - 1024) : 0;
1007
    if (extended_memory_in_k > 0xfc00) extended_memory_in_k = 0xfc00;
1008
 
1009
    DEV_cmos_set_reg(0x15, (Bit8u) BASE_MEMORY_IN_K);
1010
    DEV_cmos_set_reg(0x16, (Bit8u) (BASE_MEMORY_IN_K >> 8));
1011
    DEV_cmos_set_reg(0x17, (Bit8u) (extended_memory_in_k & 0xff));
1012
    DEV_cmos_set_reg(0x18, (Bit8u) ((extended_memory_in_k >> 8) & 0xff));
1013
    DEV_cmos_set_reg(0x30, (Bit8u) (extended_memory_in_k & 0xff));
1014
    DEV_cmos_set_reg(0x31, (Bit8u) ((extended_memory_in_k >> 8) & 0xff));
1015
 
1016
    Bit64u extended_memory_in_64k = memory_in_k > 16384 ? (memory_in_k - 16384) / 64 : 0;
1017
    // Limit to 3 GB - 16 MB. PCI Memory Address Space starts at 3 GB.
1018
    if (extended_memory_in_64k > 0xbf00) extended_memory_in_64k = 0xbf00;
1019
 
1020
    DEV_cmos_set_reg(0x34, (Bit8u) (extended_memory_in_64k & 0xff));
1021
    DEV_cmos_set_reg(0x35, (Bit8u) ((extended_memory_in_64k >> 8) & 0xff));
1022
 
1023
    Bit64u memory_above_4gb = (memory_in_bytes > BX_CONST64(0x100000000)) ?
1024
                                (memory_in_bytes - BX_CONST64(0x100000000)) : 0;
1025
    if (memory_above_4gb) {
1026
        DEV_cmos_set_reg(0x5b, (Bit8u)(memory_above_4gb >> 16));
1027
        DEV_cmos_set_reg(0x5c, (Bit8u)(memory_above_4gb >> 24));
1028
        DEV_cmos_set_reg(0x5d, memory_above_4gb >> 32);
1029
    }
1030
 
1031
    /* now perform checksum of CMOS memory */
1032
    DEV_cmos_checksum();
1033
 
1034
    //replace pic with capture
1035
    capture_pic_stub_c *capture = new capture_pic_stub_c(bx_devices.pluginPicDevice);
1036
    bx_devices.pluginPicDevice = capture;
1037
 
1038
    uint32 last_instr_counter = 0;
1039
    while(true) {
1040
 
1041
        //---------------------------------------------------------------------- stop
1042
 
1043
        if(shared_ptr->bochsDevs_stop == STEP_REQ) {
1044
            shared_ptr->bochsDevs_stop = STEP_ACK;
1045
            while(shared_ptr->bochsDevs_stop != STEP_IDLE) {
1046
                usleep(500);
1047
            }
1048
        }
1049
 
1050
        //---------------------------------------------------------------------- irq
1051
 
1052
        static step_t last_pit_irq_step = STEP_IDLE;
1053
 
1054
        if(last_pit_irq_step == STEP_IDLE && shared_ptr->pit_irq_step == STEP_REQ) {
1055
            bx_devices.pluginPicDevice->raise_irq(0);
1056
            last_pit_irq_step = STEP_REQ;
1057
        }
1058
        else if(last_pit_irq_step == STEP_REQ && shared_ptr->pit_irq_step == STEP_IDLE) {
1059
            bx_devices.pluginPicDevice->lower_irq(0);
1060
            last_pit_irq_step = STEP_IDLE;
1061
        }
1062
 
1063
        static step_t last_rtc_irq_step = STEP_IDLE;
1064
 
1065
        if(last_rtc_irq_step == STEP_IDLE && shared_ptr->rtc_irq_step == STEP_REQ) {
1066
            bx_devices.pluginPicDevice->raise_irq(8);
1067
            last_rtc_irq_step = STEP_REQ;
1068
        }
1069
        else if(last_rtc_irq_step == STEP_REQ && shared_ptr->rtc_irq_step == STEP_IDLE) {
1070
            bx_devices.pluginPicDevice->lower_irq(8);
1071
            last_rtc_irq_step = STEP_IDLE;
1072
        }
1073
 
1074
        static step_t last_floppy_irq_step = STEP_IDLE;
1075
 
1076
        if(last_floppy_irq_step == STEP_IDLE && shared_ptr->floppy_irq_step == STEP_REQ) {
1077
            bx_devices.pluginPicDevice->raise_irq(6);
1078
            last_floppy_irq_step = STEP_REQ;
1079
        }
1080
        else if(last_floppy_irq_step == STEP_REQ && shared_ptr->floppy_irq_step == STEP_IDLE) {
1081
            bx_devices.pluginPicDevice->lower_irq(6);
1082
            last_floppy_irq_step = STEP_IDLE;
1083
        }
1084
 
1085
        static step_t last_keyboard_irq_step = STEP_IDLE;
1086
 
1087
        if(last_keyboard_irq_step == STEP_IDLE && shared_ptr->keyboard_irq_step == STEP_REQ) {
1088
            bx_devices.pluginPicDevice->raise_irq(1);
1089
            last_keyboard_irq_step = STEP_REQ;
1090
        }
1091
        else if(last_keyboard_irq_step == STEP_REQ && shared_ptr->keyboard_irq_step == STEP_IDLE) {
1092
            bx_devices.pluginPicDevice->lower_irq(1);
1093
            last_keyboard_irq_step = STEP_IDLE;
1094
        }
1095
 
1096
        static step_t last_mouse_irq_step = STEP_IDLE;
1097
 
1098
        if(last_mouse_irq_step == STEP_IDLE && shared_ptr->mouse_irq_step == STEP_REQ) {
1099
            bx_devices.pluginPicDevice->raise_irq(12);
1100
            last_mouse_irq_step = STEP_REQ;
1101
        }
1102
        else if(last_mouse_irq_step == STEP_REQ && shared_ptr->mouse_irq_step == STEP_IDLE) {
1103
            bx_devices.pluginPicDevice->lower_irq(12);
1104
            last_mouse_irq_step = STEP_IDLE;
1105
        }
1106
 
1107
        //---------------------------------------------------------------------- service io
1108
 
1109
        if(shared_ptr->combined.io_step == STEP_REQ) {
1110
 
1111
            uint32 address = shared_ptr->combined.io_address & 0xFFFF;
1112
            uint32 byteena = shared_ptr->combined.io_byteenable;
1113
            uint32 value   = shared_ptr->combined.io_data;
1114
            uint32 shifted = 0;
1115
 
1116
            if(address == 0x01F0 || address == 0x01F4 || (address == 0x03F4 && byteena == 0x4) || address == 0x0040 || (address == 0x0060 && byteena == 0x2) ||
1117
               (address == 0x0070 && (byteena == 0x1 || byteena == 0x02)) || (address == 0x03F4 && ((byteena >> 2) & 1) == 0) || address == 0x03F0 ||
1118
               address == 0x0000 || address == 0x0004 || address == 0x0008 || address == 0x000C ||
1119
               address == 0x0080 || address == 0x0084 || address == 0x0088 || address == 0x008C ||
1120
               address == 0x00C0 || address == 0x00C4 || address == 0x00C8 || address == 0x00CC ||
1121
               address == 0x00D0 || address == 0x00D4 || address == 0x00D8 || address == 0x00DC ||
1122
               address == 0x03B0 || address == 0x03B4 || address == 0x03B8 || address == 0x03BC ||
1123
               address == 0x03C0 || address == 0x03C4 || address == 0x03C8 || address == 0x03CC ||
1124
               address == 0x03D0 || address == 0x03D4 || address == 0x03D8 || address == 0x03DC ||
1125
               (address == 0x0060 && ((byteena >> 1) & 1) == 0) || address == 0x0064 ||
1126
               address == 0x0090 || address == 0x0094 || address == 0x0098 || address == 0x009C ||
1127
               (address == 0x0020 && ((byteena >> 2) & 3) == 0) || (address == 0x00A0 && ((byteena >> 2) & 3) == 0) ||
1128
               address == 0x8888 || address == 0x888C)
1129
            {
1130
                //
1131
            }
1132
            else {
1133
                if(shared_ptr->combined.io_is_write) {
1134
                    FILE *fp = fopen("track.txt", "a");
1135
                    fprintf(fp, "io wr %04x %x %08x\n", address, byteena, value);
1136
                    fclose(fp);
1137
                }
1138
 
1139
                for(uint32 i=0; i<4; i++) {
1140
                    if(byteena & 1) break;
1141
 
1142
                    shifted++;
1143
                    address++;
1144
                    byteena >>= 1;
1145
                    value >>= 8;
1146
                }
1147
                uint32 length = 0;
1148
                for(uint32 i=0; i<4; i++) {
1149
                    if(byteena & 1) length++;
1150
 
1151
                    byteena >>= 1;
1152
                }
1153
 
1154
                if(shared_ptr->combined.io_is_write) {
1155
                    ioWriteHandler_t handler = io_write_handlers[address];
1156
                    uint8 mask = io_write_mask[address];
1157
                    void *this_ptr = io_write_this[address];
1158
 
1159
                    if(handler == NULL) {
1160
                        handler = io_write_handlers[65536];
1161
                        mask = io_write_mask[65536];
1162
                    }
1163
 
1164
                    if(mask & length) {
1165
                        ((bx_write_handler_t)handler)(this_ptr, address, value, length);
1166
                    }
1167
                    else {
1168
                        printf("bochsDevs::io write mismatch: mask=%d, length=%d, address=%04x\n", mask, length, address);
1169
                    }
1170
 
1171
                    if(address == 0x92) {
1172
                        a20_state = (value & 2)? 1 : 0;
1173
                    }
1174
 
1175
                    /*
1176
                    if(address == 0x8888) {
1177
                        fprintf(debug_fp, "%c", value & 0xFF);
1178
                        fflush(debug_fp);
1179
                    }
1180
                    */
1181
                }
1182
                else {
1183
                    ioReadHandler_t handler = io_read_handlers[address];
1184
                    uint8 mask = io_read_mask[address];
1185
                    void *this_ptr = io_read_this[address];
1186
 
1187
                    if(handler == NULL) {
1188
                        handler = io_read_handlers[65536];
1189
                        mask = io_read_mask[65536];
1190
                    }
1191
 
1192
                    uint32 ret = 0xFFFFFF;
1193
 
1194
                    if(mask & length) {
1195
                        ret = ((bx_read_handler_t)handler)(this_ptr, address, length);
1196
                    }
1197
                    else {
1198
                        printf("bochsDevs::io read mismatch: mask=%d, length=%d, address=%04x\n", mask, length, address);
1199
                        ret = (length == 1)? 0xFF : (length == 2)? 0xFFFF : 0xFFFFFFFF;
1200
                    }
1201
 
1202
                    if(address == 0x92) {
1203
                        ret = (a20_state)? 0x02 : 0x00;
1204
                    }
1205
 
1206
                    ret &= (length == 1)? 0xFF : (length == 2)? 0xFFFF : (length == 3)? 0xFFFFFF : 0xFFFFFFFF;
1207
                    shared_ptr->combined.io_data = ret << (8*shifted);
1208
 
1209
                    FILE *fp = fopen("track.txt", "a");
1210
                    fprintf(fp, "io rd %04x %x %08x\n", shared_ptr->combined.io_address & 0xFFFF, shared_ptr->combined.io_byteenable, shared_ptr->combined.io_data);
1211
                    fclose(fp);
1212
                }
1213
                shared_ptr->combined.io_step = STEP_ACK;
1214
            }
1215
        }
1216
 
1217
        //---------------------------------------------------------------------- service vga memory
1218
 
1219
        /*
1220
        if(shared_ptr->combined.mem_step == STEP_REQ) {
1221
            uint32 address = shared_ptr->combined.mem_address;
1222
            uint32 byteena = shared_ptr->combined.mem_byteenable;
1223
            uint32 value   = shared_ptr->combined.mem_data;
1224
            uint32 shifted = 0;
1225
 
1226
            for(uint32 i=0; i<4; i++) {
1227
                if(byteena & 1) break;
1228
 
1229
                shifted++;
1230
                address++;
1231
                byteena >>= 1;
1232
                value >>= 8;
1233
            }
1234
            uint32 length = 0;
1235
            for(uint32 i=0; i<4; i++) {
1236
                if(byteena & 1) length++;
1237
 
1238
                byteena >>= 1;
1239
            }
1240
 
1241
            if(address >= 0xA0000 && address < 0xC0000) {
1242
                if(shared_ptr->combined.mem_is_write) {
1243
                    (vga_write_memory)(address, length, &value, vga_param);
1244
 
1245
                    FILE *fp = fopen("track.txt", "a");
1246
                    fprintf(fp, "vga wr %08x %x %08x\n", address, byteena, value);
1247
                    fclose(fp);
1248
                }
1249
                else {
1250
                    uint32 ret = 0xFFFFFF;
1251
                    (vga_read_memory)(address, length, &ret, vga_param);
1252
 
1253
                    ret &= (length == 1)? 0xFF : (length == 2)? 0xFFFF : (length == 3)? 0xFFFFFF : 0xFFFFFFFF;
1254
                    shared_ptr->combined.mem_data = ret << (8*shifted);
1255
 
1256
                    FILE *fp = fopen("track.txt", "a");
1257
                    fprintf(fp, "vga rd %08x %x %08x\n", shared_ptr->combined.mem_address, shared_ptr->combined.mem_byteenable, shared_ptr->combined.mem_data);
1258
                    fclose(fp);
1259
                }
1260
                shared_ptr->combined.mem_step = STEP_ACK;
1261
            }
1262
        }
1263
        */
1264
 
1265
        //----------------------------------------------------------------------
1266
 
1267
        bx_gui->handle_events();
1268
 
1269
        //bx_pc_system.tickn(1);
1270
        //usleep(100);
1271
        uint32 snapshot = shared_ptr->bochs486_pc.instr_counter;
1272
        if(snapshot > last_instr_counter) {
1273
            bx_pc_system.tickn(snapshot - last_instr_counter); //500 -- hang (too fast interrupt), 100 -- ok
1274
            last_instr_counter = snapshot;
1275
        }
1276
        usleep(10);
1277
    }
1278
 
1279
    return 0;
1280
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.