169
169
#define EBDA_SIZE 1 // In KiB
170
170
#define BASE_MEM_IN_K (640 - EBDA_SIZE)
172
// Define the application NAME
174
# define BX_APPNAME "QEMU"
175
#elif defined(PLEX86)
176
# define BX_APPNAME "Plex86"
178
# define BX_APPNAME "Bochs"
172
/* 256 bytes at 0x9ff00 -- 0x9ffff is used for the IPL boot table. */
173
#define IPL_SEG 0x9ff0
174
#define IPL_TABLE_OFFSET 0x0000
175
#define IPL_TABLE_ENTRIES 8
176
#define IPL_COUNT_OFFSET 0x0080 /* u16: number of valid table entries */
177
#define IPL_SEQUENCE_OFFSET 0x0082 /* u16: next boot device */
178
#define IPL_SIZE 0xff
179
#define IPL_TYPE_FLOPPY 0x01
180
#define IPL_TYPE_HARDDISK 0x02
181
#define IPL_TYPE_CDROM 0x03
182
#define IPL_TYPE_BEV 0x80
182
185
#if BX_USE_ATADRV && BX_CPU<3
657
658
Bit8u device; // Detected type of attached devices (hd/cd/none)
658
659
Bit8u removable; // Removable device flag
659
660
Bit8u lock; // Locks for removable devices
660
// Bit8u lba_capable; // LBA capable flag - always yes for bochs devices
661
Bit8u mode; // transfert mode : PIO 16/32 bits - IRQ - ISADMA - PCIDMA
661
Bit8u mode; // transfer mode : PIO 16/32 bits - IRQ - ISADMA - PCIDMA
662
662
Bit16u blksize; // block size
664
664
Bit8u translation; // type of translation
1104
1112
{ 0x5300, 0x532e, none, none, 0x20 }, /* Del */
1105
1113
{ none, none, none, none, none },
1106
1114
{ none, none, none, none, none },
1107
{ 0x565c, 0x567c, none, none, none }, /* \| */
1115
{ 0x565c, 0x567c, none, none, none }, /* \| */
1108
1116
{ 0x5700, 0x5700, none, none, none }, /* F11 */
1109
1117
{ 0x5800, 0x5800, none, none, none } /* F12 */
1524
1532
//--------------------------------------------------------------------------
1525
1533
// bios_printf()
1526
// A compact variable argument printf function which prints its output via
1527
// an I/O port so that it can be logged by Bochs/Plex.
1528
// Currently, only %x is supported (or %02x, %04x, etc).
1534
// A compact variable argument printf function.
1530
// Supports %[format_width][format]
1531
// where format can be d,x,c,s
1536
// Supports %[format_width][length]format
1537
// where format can be x,X,u,d,s,c
1538
// and the optional length modifier is l (ell)
1532
1539
//--------------------------------------------------------------------------
1534
1541
bios_printf(action, s)
1580
1591
else if (c == 'l') {
1593
c = read_byte(get_CS(), s); /* is it ld,lx,lu? */
1582
1594
arg_ptr++; /* increment to next arg */
1583
1595
hibyte = read_word(arg_seg, arg_ptr);
1584
put_luint(action, ((Bit32u) hibyte << 16) | arg, format_width, 0);
1597
if (hibyte & 0x8000)
1598
put_luint(action, 0L-(((Bit32u) hibyte << 16) | arg), format_width-1, 1);
1600
put_luint(action, ((Bit32u) hibyte << 16) | arg, format_width, 0);
1602
else if (c == 'u') {
1603
put_luint(action, ((Bit32u) hibyte << 16) | arg, format_width, 0);
1605
else if (c == 'x' || c == 'X')
1607
if (format_width == 0)
1613
for (i=format_width-1; i>=0; i--) {
1614
nibble = ((((Bit32u) hibyte <<16) | arg) >> (4 * i)) & 0x000f;
1615
send (action, (nibble<=9)? (nibble+'0') : (nibble-10+hexadd));
1586
1619
else if (c == 'd') {
1587
1620
if (arg & 0x8000)
1836
1869
// http://www.phoenix.com/en/Customer+Services/White+Papers-Specs/pc+industry+specifications.htm
1837
1870
//--------------------------------------------------------------------------
1839
/* 256 bytes at 0x9ff00 -- 0x9ffff is used for the IPL boot table. */
1840
#define IPL_SEG 0x9ff0
1841
#define IPL_TABLE_OFFSET 0x0000
1842
#define IPL_TABLE_ENTRIES 8
1843
#define IPL_COUNT_OFFSET 0x0080 /* u16: number of valid table entries */
1844
#define IPL_SEQUENCE_OFFSET 0x0082 /* u16: next boot device */
1858
1877
Bit16u count = 0;
1859
1878
Bit16u ss = get_SS();
1861
1880
/* Clear out the IPL table. */
1862
memsetb(IPL_SEG, IPL_TABLE_OFFSET, 0, 0xff);
1881
memsetb(IPL_SEG, IPL_TABLE_OFFSET, 0, IPL_SIZE);
1864
1883
/* Floppy drive */
1865
e.type = 1; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0;
1884
e.type = IPL_TYPE_FLOPPY; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0;
1866
1885
memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e));
1869
1888
/* First HDD */
1870
e.type = 2; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0;
1889
e.type = IPL_TYPE_HARDDISK; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0;
1871
1890
memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e));
1874
1893
#if BX_ELTORITO_BOOT
1876
e.type = 3; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0;
1895
e.type = IPL_TYPE_CDROM; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0;
1877
1896
memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e));
2189
2210
write_byte(ebda_seg,&EbdaData->ata.cdcount,0);
2216
#define NOT_BSY_DRQ 3
2217
#define NOT_BSY_NOT_DRQ 4
2218
#define NOT_BSY_RDY 5
2220
#define IDE_TIMEOUT 32000u //32 seconds max for IDE ops
2223
static int await_ide(when_done,base,timeout)
2228
Bit32u time=0,last=0;
2231
status = inb(base + ATA_CB_STAT); // for the times you're supposed to throw one away
2233
status = inb(base+ATA_CB_STAT);
2235
if (when_done == BSY)
2236
result = status & ATA_CB_STAT_BSY;
2237
else if (when_done == NOT_BSY)
2238
result = !(status & ATA_CB_STAT_BSY);
2239
else if (when_done == NOT_BSY_DRQ)
2240
result = !(status & ATA_CB_STAT_BSY) && (status & ATA_CB_STAT_DRQ);
2241
else if (when_done == NOT_BSY_NOT_DRQ)
2242
result = !(status & ATA_CB_STAT_BSY) && !(status & ATA_CB_STAT_DRQ);
2243
else if (when_done == NOT_BSY_RDY)
2244
result = !(status & ATA_CB_STAT_BSY) && (status & ATA_CB_STAT_RDY);
2245
else if (when_done == TIMEOUT)
2248
if (result) return 0;
2249
if (time>>16 != last) // mod 2048 each 16 ms
2252
BX_DEBUG_ATA("await_ide: (TIMEOUT,BSY,!BSY,!BSY_DRQ,!BSY_!DRQ,!BSY_RDY) %d time= %ld timeout= %d\n",when_done,time>>11, timeout);
2254
if (status & ATA_CB_STAT_ERR)
2256
BX_DEBUG_ATA("await_ide: ERROR (TIMEOUT,BSY,!BSY,!BSY_DRQ,!BSY_!DRQ,!BSY_RDY) %d time= %ld timeout= %d\n",when_done,time>>11, timeout);
2259
if ((timeout == 0) || ((time>>11) > timeout)) break;
2261
BX_INFO("IDE time out\n");
2192
2265
// ---------------------------------------------------------------------------
2193
2266
// ATA/ATAPI driver : device detection
2194
2267
// ---------------------------------------------------------------------------
2447
2520
case ATA_TYPE_ATA:
2448
2521
printf("ata%d %s: ",channel,slave?" slave":"master");
2449
2522
i=0; while(c=read_byte(get_SS(),model+i++)) printf("%c",c);
2450
if (sizeinmb < 1UL<<16)
2451
printf(" ATA-%d Hard-Disk (%04u MBytes)\n",version,(Bit16u)sizeinmb);
2453
printf(" ATA-%d Hard-Disk (%04u GBytes)\n",version,(Bit16u)(sizeinmb>>10));
2523
if (sizeinmb < (1UL<<16))
2524
printf(" ATA-%d Hard-Disk (%4u MBytes)\n", version, (Bit16u)sizeinmb);
2526
printf(" ATA-%d Hard-Disk (%4u GBytes)\n", version, (Bit16u)(sizeinmb>>10));
2455
2528
case ATA_TYPE_ATAPI:
2456
2529
printf("ata%d %s: ",channel,slave?" slave":"master");
2506
2580
outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN | ATA_CB_DC_SRST);
2508
2582
// 8.2.1 (b) -- wait for BSY
2511
Bit8u status = inb(iobase1+ATA_CB_STAT);
2512
if ((status & ATA_CB_STAT_BSY) != 0) break;
2583
await_ide(BSY, iobase1, 20);
2515
2585
// 8.2.1 (f) -- clear SRST
2516
2586
outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
2518
if (read_byte(ebda_seg,&EbdaData->ata.devices[device].type) != ATA_TYPE_NONE) {
2588
type=read_byte(ebda_seg,&EbdaData->ata.devices[device].type);
2589
if (type != ATA_TYPE_NONE) {
2520
2591
// 8.2.1 (g) -- check for sc==sn==0x01
2521
2592
// select device
2524
2595
sn = inb(iobase1+ATA_CB_SN);
2526
2597
if ( (sc==0x01) && (sn==0x01) ) {
2598
if (type == ATA_TYPE_ATA) //ATA
2599
await_ide(NOT_BSY_RDY, iobase1, IDE_TIMEOUT);
2601
await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
2528
2604
// 8.2.1 (h) -- wait for not BSY
2531
Bit8u status = inb(iobase1+ATA_CB_STAT);
2532
if ((status & ATA_CB_STAT_BSY) == 0) break;
2537
// 8.2.1 (i) -- wait for DRDY
2540
Bit8u status = inb(iobase1+ATA_CB_STAT);
2541
if ((status & ATA_CB_STAT_RDY) != 0) break;
2605
await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
2544
2608
// Enable interrupts
2620
2682
outb(iobase1 + ATA_CB_DH, (slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | (Bit8u) head );
2621
2683
outb(iobase1 + ATA_CB_CMD, command);
2624
status = inb(iobase1 + ATA_CB_STAT);
2625
if ( !(status & ATA_CB_STAT_BSY) ) break;
2685
await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT);
2686
status = inb(iobase1 + ATA_CB_STAT);
2628
2688
if (status & ATA_CB_STAT_ERR) {
2629
2689
BX_DEBUG_ATA("ata_cmd_data_in : read error\n");
2774
2833
outb(iobase1 + ATA_CB_DH, (slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | (Bit8u) head );
2775
2834
outb(iobase1 + ATA_CB_CMD, command);
2778
status = inb(iobase1 + ATA_CB_STAT);
2779
if ( !(status & ATA_CB_STAT_BSY) ) break;
2836
await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT);
2837
status = inb(iobase1 + ATA_CB_STAT);
2782
2839
if (status & ATA_CB_STAT_ERR) {
2783
2840
BX_DEBUG_ATA("ata_cmd_data_out : read error\n");
2916
2973
if (status & ATA_CB_STAT_BSY) return 2;
2918
2975
outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
2919
// outb(iobase1 + ATA_CB_FR, 0x00);
2920
// outb(iobase1 + ATA_CB_SC, 0x00);
2921
// outb(iobase1 + ATA_CB_SN, 0x00);
2976
outb(iobase1 + ATA_CB_FR, 0x00);
2977
outb(iobase1 + ATA_CB_SC, 0x00);
2978
outb(iobase1 + ATA_CB_SN, 0x00);
2922
2979
outb(iobase1 + ATA_CB_CL, 0xfff0 & 0x00ff);
2923
2980
outb(iobase1 + ATA_CB_CH, 0xfff0 >> 8);
2924
2981
outb(iobase1 + ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0);
2925
2982
outb(iobase1 + ATA_CB_CMD, ATA_CMD_PACKET);
2927
2984
// Device should ok to receive command
2929
status = inb(iobase1 + ATA_CB_STAT);
2930
if ( !(status & ATA_CB_STAT_BSY) ) break;
2985
await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT);
2986
status = inb(iobase1 + ATA_CB_STAT);
2933
2988
if (status & ATA_CB_STAT_ERR) {
2934
2989
BX_DEBUG_ATA("ata_cmd_packet : error, status is %02x\n",status);
2966
3021
if (inout == ATA_DATA_NO) {
3022
await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
2967
3023
status = inb(iobase1 + ATA_CB_STAT);
3030
if (loops == 0) {//first time through
3031
status = inb(iobase2 + ATA_CB_ASTAT);
3032
await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT);
3035
await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
2972
3038
status = inb(iobase1 + ATA_CB_STAT);
3039
sc = inb(iobase1 + ATA_CB_SC);
2974
3041
// Check if command completed
2975
if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_DRQ) ) ==0 ) break;
3042
if(((inb(iobase1 + ATA_CB_SC)&0x7)==0x3) &&
3043
((status & (ATA_CB_STAT_RDY | ATA_CB_STAT_ERR)) == ATA_CB_STAT_RDY)) break;
2977
3045
if (status & ATA_CB_STAT_ERR) {
2978
3046
BX_DEBUG_ATA("ata_cmd_packet : error (status %02x)\n",status);
2982
// Device must be ready to send data
2983
if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
2984
!= (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
2985
BX_DEBUG_ATA("ata_cmd_packet : not ready (status %02x)\n", status);
2989
3050
// Normalize address
2990
3051
bufseg += (bufoff / 16);
3144
3205
// ---------------------------------------------------------------------------
3147
atapi_get_sense(device)
3208
atapi_get_sense(device, seg, asc, ascq)
3150
3211
Bit8u atacmd[12];
3154
3215
memsetb(get_SS(),atacmd,0,12);
3156
3217
// Request SENSE
3159
if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 16L, ATA_DATA_IN, get_SS(), buffer) != 0)
3218
atacmd[0]=ATA_CMD_REQUEST_SENSE;
3219
atacmd[4]=sizeof(buffer);
3220
if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 18L, ATA_DATA_IN, get_SS(), buffer) != 0)
3162
if ((buffer[0] & 0x7e) == 0x70) {
3163
return (((Bit16u)buffer[2]&0x0f)*0x100)+buffer[12];
3223
write_byte(seg,asc,buffer[12]);
3224
write_byte(seg,ascq,buffer[13]);
3170
3230
atapi_is_ready(device)
3176
memsetb(get_SS(),atacmd,0,12);
3179
if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 0L, ATA_DATA_NO, get_SS(), buffer) != 0)
3182
if (atapi_get_sense(device) !=0 ) {
3183
memsetb(get_SS(),atacmd,0,12);
3185
// try to send Test Unit Ready again
3186
if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 0L, ATA_DATA_NO, get_SS(), buffer) != 0)
3189
return atapi_get_sense(device);
3237
Bit32u timeout; //measured in ms
3241
Bit16u ebda_seg = read_word(0x0040,0x000E);
3242
if (read_byte(ebda_seg,&EbdaData->ata.devices[device].type) != ATA_TYPE_ATAPI) {
3243
printf("not implemented for non-ATAPI device\n");
3247
BX_DEBUG_ATA("ata_detect_medium: begin\n");
3248
memsetb(get_SS(),packet, 0, sizeof packet);
3249
packet[0] = 0x25; /* READ CAPACITY */
3251
/* Retry READ CAPACITY 50 times unless MEDIUM NOT PRESENT
3252
* is reported by the device. If the device reports "IN PROGRESS",
3253
* 30 seconds is added. */
3257
while (time < timeout) {
3258
if (ata_cmd_packet(device, sizeof(packet), get_SS(), packet, 0, 8L, ATA_DATA_IN, get_SS(), buf) == 0)
3261
if (atapi_get_sense(device, get_SS(), &asc, &ascq) == 0) {
3262
if (asc == 0x3a) { /* MEDIUM NOT PRESENT */
3263
BX_DEBUG_ATA("Device reports MEDIUM NOT PRESENT\n");
3267
if (asc == 0x04 && ascq == 0x01 && !in_progress) {
3268
/* IN PROGRESS OF BECOMING READY */
3269
printf("Waiting for device to detect medium... ");
3270
/* Allow 30 seconds more */
3277
BX_DEBUG_ATA("read capacity failed\n");
3281
block_len = (Bit32u) buf[4] << 24
3282
| (Bit32u) buf[5] << 16
3283
| (Bit32u) buf[6] << 8
3284
| (Bit32u) buf[7] << 0;
3285
BX_DEBUG_ATA("block_len=%u\n", block_len);
3287
if (block_len!= 2048 && block_len!= 512)
3289
printf("Unsupported sector size %u\n", block_len);
3292
write_dword(ebda_seg,&EbdaData->ata.devices[device].blksize, block_len);
3294
sectors = (Bit32u) buf[0] << 24
3295
| (Bit32u) buf[1] << 16
3296
| (Bit32u) buf[2] << 8
3297
| (Bit32u) buf[3] << 0;
3299
BX_DEBUG_ATA("sectors=%u\n", sectors);
3300
if (block_len == 2048)
3301
sectors <<= 2; /* # of sectors in 512-byte "soft" sector */
3302
if (sectors != read_dword(ebda_seg,&EbdaData->ata.devices[device].sectors))
3303
printf("%dMB medium detected\n", sectors>>(20-9));
3304
write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors, sectors);
5040
5154
case 0x15: /* read disk drive size */
5042
// Get physical geometry from table
5043
npc = read_word(ebda_seg, &EbdaData->ata.devices[device].pchs.cylinders);
5044
nph = read_word(ebda_seg, &EbdaData->ata.devices[device].pchs.heads);
5045
npspt = read_word(ebda_seg, &EbdaData->ata.devices[device].pchs.spt);
5156
// Get logical geometry from table
5157
nlc = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.cylinders);
5158
nlh = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.heads);
5159
nlspt = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.spt);
5047
5161
// Compute sector count seen by int13
5048
lba = (Bit32u)(npc - 1) * (Bit32u)nph * (Bit32u)npspt;
5162
lba = (Bit32u)(nlc - 1) * (Bit32u)nlh * (Bit32u)nlspt;
5049
5163
CX = lba >> 16;
5050
5164
DX = lba & 0xffff;
5133
5247
blksize = read_word(ebda_seg, &EbdaData->ata.devices[device].blksize);
5135
5249
write_word(DS, SI+(Bit16u)&Int13DPT->size, 0x1a);
5136
write_word(DS, SI+(Bit16u)&Int13DPT->infos, 0x02); // geometry is valid
5137
write_dword(DS, SI+(Bit16u)&Int13DPT->cylinders, (Bit32u)npc);
5250
if ((lba/npspt)/nph > 0x3fff)
5252
write_word(DS, SI+(Bit16u)&Int13DPT->infos, 0x00); // geometry is invalid
5253
write_dword(DS, SI+(Bit16u)&Int13DPT->cylinders, 0x3fff);
5257
write_word(DS, SI+(Bit16u)&Int13DPT->infos, 0x02); // geometry is valid
5258
write_dword(DS, SI+(Bit16u)&Int13DPT->cylinders, (Bit32u)npc);
5138
5260
write_dword(DS, SI+(Bit16u)&Int13DPT->heads, (Bit32u)nph);
5139
5261
write_dword(DS, SI+(Bit16u)&Int13DPT->spt, (Bit32u)npspt);
5140
5262
write_dword(DS, SI+(Bit16u)&Int13DPT->sector_count1, lba); // FIXME should be Bit64
5160
5282
mode = read_byte(ebda_seg, &EbdaData->ata.devices[device].mode);
5161
5283
translation = read_byte(ebda_seg, &EbdaData->ata.devices[device].translation);
5163
options = (translation==ATA_TRANSLATION_NONE?0:1<<3); // chs translation
5285
options = (translation==ATA_TRANSLATION_NONE?0:1)<<3; // chs translation
5164
5286
options |= (1<<4); // lba translation
5165
options |= (mode==ATA_MODE_PIO32?1:0<<7);
5166
options |= (translation==ATA_TRANSLATION_LBA?1:0<<9);
5167
options |= (translation==ATA_TRANSLATION_RECHS?3:0<<9);
5287
options |= (mode==ATA_MODE_PIO32?1:0)<<7;
5288
options |= (translation==ATA_TRANSLATION_LBA?1:0)<<9;
5289
options |= (translation==ATA_TRANSLATION_RECHS?3:0)<<9;
5169
5291
write_word(ebda_seg, &EbdaData->ata.dpte.iobase1, iobase1);
5170
write_word(ebda_seg, &EbdaData->ata.dpte.iobase2, iobase2);
5292
write_word(ebda_seg, &EbdaData->ata.dpte.iobase2, iobase2 + ATA_CB_DC);
5171
5293
write_byte(ebda_seg, &EbdaData->ata.dpte.prefix, (0xe | (device % 2))<<4 );
5172
5294
write_byte(ebda_seg, &EbdaData->ata.dpte.unused, 0xcb );
5173
5295
write_byte(ebda_seg, &EbdaData->ata.dpte.irq, irq );
5176
5298
write_byte(ebda_seg, &EbdaData->ata.dpte.pio, 0 );
5177
5299
write_word(ebda_seg, &EbdaData->ata.dpte.options, options);
5178
5300
write_word(ebda_seg, &EbdaData->ata.dpte.reserved, 0);
5179
write_byte(ebda_seg, &EbdaData->ata.dpte.revision, 0x11);
5302
write_byte(ebda_seg, &EbdaData->ata.dpte.revision, 0x11);
5304
write_byte(ebda_seg, &EbdaData->ata.dpte.revision, 0x10);
5182
for (i=0; i<15; i++) checksum+=read_byte(ebda_seg, (&EbdaData->ata.dpte) + i);
5307
for (i=0; i<15; i++) checksum+=read_byte(ebda_seg, ((Bit8u*)(&EbdaData->ata.dpte)) + i);
5183
5308
checksum = ~checksum;
5184
5309
write_byte(ebda_seg, &EbdaData->ata.dpte.checksum, checksum);
5515
5640
options |= (mode==ATA_MODE_PIO32?1:0<<7);
5517
5642
write_word(ebda_seg, &EbdaData->ata.dpte.iobase1, iobase1);
5518
write_word(ebda_seg, &EbdaData->ata.dpte.iobase2, iobase2);
5643
write_word(ebda_seg, &EbdaData->ata.dpte.iobase2, iobase2 + ATA_CB_DC);
5519
5644
write_byte(ebda_seg, &EbdaData->ata.dpte.prefix, (0xe | (device % 2))<<4 );
5520
5645
write_byte(ebda_seg, &EbdaData->ata.dpte.unused, 0xcb );
5521
5646
write_byte(ebda_seg, &EbdaData->ata.dpte.irq, irq );
6816
#if BX_SUPPORT_FLOPPY
6818
6943
int13_diskette_function(DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS)
6819
6944
Bit16u DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS;
9890
10006
add sp, #2 ;; Pop offset value
9891
10007
pop cx ;; Pop seg value (restore CX)
9893
;; Look at the ROM's PnP Expansion header. Properly, we're supposed
9894
;; to init all the ROMs and then go back and build an IPL table of
10009
;; Look at the ROM's PnP Expansion header. Properly, we're supposed
10010
;; to init all the ROMs and then go back and build an IPL table of
9895
10011
;; all the bootable devices, but we can get away with one pass.
9896
10012
mov ds, cx ;; ROM base
9897
10013
mov bx, 0x001a ;; 0x1A is the offset into ROM header that contains...
9899
10015
cmp ax, #0x5024 ;; we look for signature "$PnP"
9904
10020
mov ax, 0x1a[bx] ;; 0x1A is also the offset into the expansion header of...
9905
10021
cmp ax, #0x0000 ;; the Bootstrap Entry Vector, or zero if there is none.
9908
;; Found a device that thinks it can boot the system. Record its BEV.
9909
mov bx, #IPL_SEG ;; Go to the segment where the IPL table lives
10024
;; Found a device that thinks it can boot the system. Record its BEV and product name string.
10025
mov di, 0x10[bx] ;; Pointer to the product name string or zero if none
10026
mov bx, #IPL_SEG ;; Go to the segment where the IPL table lives
9911
10028
mov bx, IPL_COUNT_OFFSET ;; Read the number of entries so far
9912
10029
cmp bx, #IPL_TABLE_ENTRIES
9913
10030
je no_bev ;; Get out if the table is full
9914
10031
shl bx, #0x4 ;; Turn count into offset (entries are 16 bytes)
9915
mov 0[bx], #0x80 ;; This entry is a BEV device
10032
mov 0[bx], #IPL_TYPE_BEV ;; This entry is a BEV device
9916
10033
mov 6[bx], cx ;; Build a far pointer from the segment...
9917
10034
mov 4[bx], ax ;; and the offset
10037
mov 0xA[bx], cx ;; Build a far pointer from the segment...
10038
mov 8[bx], di ;; and the offset
9918
10040
shr bx, #0x4 ;; Turn the offset back into a count
9919
10041
inc bx ;; We have one more entry now
9920
10042
mov IPL_COUNT_OFFSET, bx ;; Remember that.