784
782
Bit16u di, si, bp, sp;
785
783
Bit16u bx, dx, cx, ax;
788
786
Bit16u filler[4];
789
787
Bit8u bl, bh, dl, dh, cl, ch, al, ah;
797
795
Bit32u edi, esi, ebp, esp;
798
796
Bit32u ebx, edx, ecx, eax;
801
799
Bit16u di, filler1, si, filler2, bp, filler3, sp, filler4;
802
800
Bit16u bx, filler5, dx, filler6, cx, filler7, ax, filler8;
805
803
Bit32u filler[4];
1118
1115
{ none, none, none, none, none },
1119
1116
{ none, none, none, none, none },
1120
1117
{ 0x565c, 0x567c, none, none, none }, /* \| */
1121
{ 0x5700, 0x5700, none, none, none }, /* F11 */
1122
{ 0x5800, 0x5800, none, none, none } /* F12 */
1118
{ 0x8500, 0x8700, 0x8900, 0x8b00, none }, /* F11 */
1119
{ 0x8600, 0x8800, 0x8a00, 0x8c00, none }, /* F12 */
1695
1692
for (i=format_width-1; i>=0; i--) {
1696
1693
nibble = ((((Bit32u) hibyte <<16) | arg) >> (4 * i)) & 0x000f;
1697
1694
send (action, (nibble<=9)? (nibble+'0') : (nibble-10+hexadd));
1701
1698
else if (c == 'd') {
1702
1699
if (arg & 0x8000)
1703
1700
put_int(action, -arg, format_width - 1, 1);
1705
1702
put_int(action, arg, format_width, 0);
1707
1704
else if (c == 's') {
1708
1705
put_str(action, get_CS(), arg);
1710
1707
else if (c == 'S') {
1713
1710
arg = read_word(arg_seg, arg_ptr);
1714
1711
put_str(action, hibyte, arg);
1716
1713
else if (c == 'c') {
1717
1714
send(action, arg);
1720
1717
BX_PANIC("bios_printf: unknown format\n");
1725
1722
send(action, c);
1730
1727
if (action & BIOS_PRINTF_HALT) {
1731
1728
// freeze in a busy loop.
2198
2201
outb(0xfedc, 0x00);
2207
Bit32u s3_wakeup_vector;
2208
Bit8u s3_resume_flag;
2210
s3_resume_flag = read_byte(0x40, 0xb0);
2211
s3_wakeup_vector = read_dword(0x40, 0xb2);
2213
BX_INFO("S3 resume called %x 0x%lx\n", s3_resume_flag, s3_wakeup_vector);
2214
if (s3_resume_flag != 0xFE || !s3_wakeup_vector)
2217
write_byte(0x40, 0xb0, 0);
2219
/* setup wakeup vector */
2220
write_word(0x40, 0xb6, (s3_wakeup_vector & 0xF)); /* IP */
2221
write_word(0x40, 0xb8, (s3_wakeup_vector >> 4)); /* CS */
2223
BX_INFO("S3 resume jump to %x:%x\n", (s3_wakeup_vector >> 4),
2224
(s3_wakeup_vector & 0xF));
2201
2231
#if BX_USE_ATADRV
2203
2233
// ---------------------------------------------------------------------------
2376
2406
write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_low,0L);
2377
2407
write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_high,0L);
2380
// hdidmap and cdidmap init.
2410
// hdidmap and cdidmap init.
2381
2411
for (device=0; device<BX_MAX_ATA_DEVICES; device++) {
2382
2412
write_byte(ebda_seg,&EbdaData->ata.hdidmap[device],BX_MAX_ATA_DEVICES);
2383
2413
write_byte(ebda_seg,&EbdaData->ata.cdidmap[device],BX_MAX_ATA_DEVICES);
2386
2416
write_byte(ebda_seg,&EbdaData->ata.hdcount,0);
2387
2417
write_byte(ebda_seg,&EbdaData->ata.cdcount,0);
2696
2728
if(read_byte(get_SS(),model+i)==0x20)
2697
2729
write_byte(get_SS(),model+i,0x00);
2733
write_byte(get_SS(),model+36,0x00);
2735
write_byte(get_SS(),model+i,0x2E);
2703
2741
switch (type) {
2704
2742
case ATA_TYPE_ATA:
2705
2743
printf("ata%d %s: ",channel,slave?" slave":"master");
2706
i=0; while(c=read_byte(get_SS(),model+i++)) printf("%c",c);
2707
if (sizeinmb < (1UL<<16))
2745
while(c=read_byte(get_SS(),model+i++))
2747
if (sizeinmb < (1UL<<16))
2708
2748
printf(" ATA-%d Hard-Disk (%4u MBytes)\n", version, (Bit16u)sizeinmb);
2710
2750
printf(" ATA-%d Hard-Disk (%4u GBytes)\n", version, (Bit16u)(sizeinmb>>10));
2712
2752
case ATA_TYPE_ATAPI:
3561
3602
// Find out the first cdrom
3562
3603
for (device=0; device<BX_MAX_ATA_DEVICES;device++) {
3563
3604
if (atapi_is_cdrom(device)) break;
3608
if(device >= BX_MAX_ATA_DEVICES) return 2;
3566
3610
if(error = atapi_is_ready(device) != 0)
3567
3611
BX_INFO("ata_is_ready returned %d\n",error);
3570
if(device >= BX_MAX_ATA_DEVICES) return 2;
3572
3613
// Read the Boot Record Volume Descriptor
3573
3614
memsetb(get_SS(),atacmd,0,12);
3574
3615
atacmd[0]=0x28; // READ command
3584
3625
// Validity checks
3585
if(buffer[0]!=0)return 4;
3626
if(buffer[0]!=0) return 4;
3586
3627
for(i=0;i<5;i++){
3587
if(buffer[1+i]!=read_byte(0xf000,&isotag[i]))return 5;
3628
if(buffer[1+i]!=read_byte(0xf000,&isotag[i])) return 5;
3589
3630
for(i=0;i<23;i++)
3590
if(buffer[7+i]!=read_byte(0xf000,&eltorito[i]))return 6;
3631
if(buffer[7+i]!=read_byte(0xf000,&eltorito[i])) return 6;
3592
3633
// ok, now we calculate the Boot catalog address
3593
3634
lba=buffer[0x4A]*0x1000000+buffer[0x49]*0x10000+buffer[0x48]*0x100+buffer[0x47];
3698
3738
// ---------------------------------------------------------------------------
3699
3739
#endif // BX_ELTORITO_BOOT
3702
int14_function(regs, ds, iret_addr)
3741
void int14_function(regs, ds, iret_addr)
3703
3742
pusha_regs_t regs; // regs pushed from PUSHA instruction
3704
3743
Bit16u ds; // previous DS:, DS set to 0x0000 by asm wrapper
3705
3744
iret_addr_t iret_addr; // CS,IP,Flags pushed from original INT call
3707
3746
Bit16u addr,timer,val16;
3714
3753
addr = read_word(0x0040, (regs.u.r16.dx << 1));
3715
timeout = read_byte(0x0040, 0x007C + regs.u.r16.dx);
3754
counter = read_byte(0x0040, 0x007C + regs.u.r16.dx);
3716
3755
if ((regs.u.r16.dx < 4) && (addr > 0)) {
3717
3756
switch (regs.u.r8.ah) {
3734
3773
timer = read_word(0x0040, 0x006C);
3735
while (((inb(addr+5) & 0x60) != 0x60) && (timeout)) {
3774
while (((inb(addr+5) & 0x60) != 0x60) && (counter)) {
3736
3775
val16 = read_word(0x0040, 0x006C);
3737
3776
if (val16 != timer) {
3742
if (timeout) outb(addr, regs.u.r8.al);
3743
regs.u.r8.ah = inb(addr+5);
3744
if (!timeout) regs.u.r8.ah |= 0x80;
3782
outb(addr, regs.u.r8.al);
3783
regs.u.r8.ah = inb(addr+5);
3785
regs.u.r8.ah = 0x80;
3745
3787
ClearCF(iret_addr.flags);
3748
3790
timer = read_word(0x0040, 0x006C);
3749
while (((inb(addr+5) & 0x01) == 0) && (timeout)) {
3791
while (((inb(addr+5) & 0x01) == 0) && (counter)) {
3750
3792
val16 = read_word(0x0040, 0x006C);
3751
3793
if (val16 != timer) {
3799
regs.u.r8.ah = inb(addr+5);
3758
3800
regs.u.r8.al = inb(addr);
3760
regs.u.r8.ah = inb(addr+5);
3802
regs.u.r8.ah = 0x80;
3762
3804
ClearCF(iret_addr.flags);
4400
4442
regs.u.r8.ah = UNSUPPORTED_FUNCTION;
4404
4446
#endif // BX_USE_PS2_MOUSE
4407
void set_e820_range(ES, DI, start, end, type)
4449
void set_e820_range(ES, DI, start, end, extra_start, extra_end, type)
4414
4458
write_word(ES, DI, start);
4415
4459
write_word(ES, DI+2, start >> 16);
4416
write_word(ES, DI+4, 0x00);
4460
write_word(ES, DI+4, extra_start);
4417
4461
write_word(ES, DI+6, 0x00);
4464
extra_end -= extra_start;
4420
4465
write_word(ES, DI+8, end);
4421
4466
write_word(ES, DI+10, end >> 16);
4422
write_word(ES, DI+12, 0x0000);
4467
write_word(ES, DI+12, extra_end);
4423
4468
write_word(ES, DI+14, 0x0000);
4425
4470
write_word(ES, DI+16, type);
4506
4552
extended_memory_size += (1L * 1024 * 1024);
4555
extra_lowbits_memory_size = inb_cmos(0x5c);
4556
extra_lowbits_memory_size <<= 8;
4557
extra_lowbits_memory_size |= inb_cmos(0x5b);
4558
extra_lowbits_memory_size *= 64;
4559
extra_lowbits_memory_size *= 1024;
4560
extra_highbits_memory_size = inb_cmos(0x5d);
4509
4562
switch(regs.u.r16.bx)
4512
4565
set_e820_range(ES, regs.u.r16.di,
4513
0x0000000L, 0x0009fc00L, 1);
4566
0x0000000L, 0x0009f000L, 0, 0, 1);
4514
4567
regs.u.r32.ebx = 1;
4515
regs.u.r32.eax = 0x534D4150;
4516
regs.u.r32.ecx = 0x14;
4521
4570
set_e820_range(ES, regs.u.r16.di,
4522
0x0009fc00L, 0x000a0000L, 2);
4571
0x0009f000L, 0x000a0000L, 0, 0, 2);
4523
4572
regs.u.r32.ebx = 2;
4524
regs.u.r32.eax = 0x534D4150;
4525
regs.u.r32.ecx = 0x14;
4530
4575
set_e820_range(ES, regs.u.r16.di,
4531
0x000e8000L, 0x00100000L, 2);
4576
0x000e8000L, 0x00100000L, 0, 0, 2);
4532
4577
regs.u.r32.ebx = 3;
4533
regs.u.r32.eax = 0x534D4150;
4534
regs.u.r32.ecx = 0x14;
4539
4580
#if BX_ROMBIOS32
4540
4581
set_e820_range(ES, regs.u.r16.di,
4542
extended_memory_size - ACPI_DATA_SIZE, 1);
4583
extended_memory_size - ACPI_DATA_SIZE, 0, 0, 1);
4543
4584
regs.u.r32.ebx = 4;
4545
4586
set_e820_range(ES, regs.u.r16.di,
4547
extended_memory_size, 1);
4588
extended_memory_size, 0, 0, 1);
4548
4589
regs.u.r32.ebx = 5;
4550
regs.u.r32.eax = 0x534D4150;
4551
regs.u.r32.ecx = 0x14;
4556
4593
set_e820_range(ES, regs.u.r16.di,
4557
4594
extended_memory_size - ACPI_DATA_SIZE,
4558
extended_memory_size, 3); // ACPI RAM
4595
extended_memory_size, 0, 0, 3); // ACPI RAM
4559
4596
regs.u.r32.ebx = 5;
4560
regs.u.r32.eax = 0x534D4150;
4561
regs.u.r32.ecx = 0x14;
4566
4599
/* 256KB BIOS area at the end of 4 GB */
4567
4600
set_e820_range(ES, regs.u.r16.di,
4568
0xfffc0000L, 0x00000000L, 2);
4601
0xfffc0000L, 0x00000000L, 0, 0, 2);
4602
if (extra_highbits_memory_size || extra_lowbits_memory_size)
4608
/* Maping of memory above 4 GB */
4609
set_e820_range(ES, regs.u.r16.di, 0x00000000L,
4610
extra_lowbits_memory_size, 1, extra_highbits_memory_size
4569
4612
regs.u.r32.ebx = 0;
4570
regs.u.r32.eax = 0x534D4150;
4571
regs.u.r32.ecx = 0x14;
4574
4614
default: /* AX=E820, DX=534D4150, BX unrecognized */
4575
4615
goto int15_unimplemented;
4618
regs.u.r32.eax = 0x534D4150;
4619
regs.u.r32.ecx = 0x14;
4579
4622
// if DX != 0x534D4150)
4580
4623
goto int15_unimplemented;
5110
5152
if (buffer_tail == buffer_head) {
5114
write_byte(0x0040, temp_tail, ascii_code);
5115
write_byte(0x0040, temp_tail+1, scan_code);
5116
write_word(0x0040, 0x001C, buffer_tail);
5156
write_byte(0x0040, temp_tail, ascii_code);
5157
write_byte(0x0040, temp_tail+1, scan_code);
5158
write_word(0x0040, 0x001C, buffer_tail);
5122
5163
int74_function(make_farcall, Z, Y, X, status)
5123
5164
Bit16u make_farcall, Z, Y, X, status;
5238
5280
nlspt = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.spt);
5240
5282
// sanity check on cyl heads, sec
5241
if( (cylinder >= nlc) || (head >= nlh) || (sector > nlspt )) {
5283
if( (cylinder >= nlc) || (head >= nlh) || (sector > nlspt) ) {
5242
5284
BX_INFO("int13_harddisk: function %02x, parameters out of range %04x/%04x/%04x!\n", GET_AH(), cylinder, head, sector);
5243
5285
goto int13_fail;
5246
5288
// FIXME verify
5247
if ( GET_AH() == 0x04 ) goto int13_success;
5289
if (GET_AH() == 0x04) goto int13_success;
5249
5291
nph = read_word(ebda_seg, &EbdaData->ata.devices[device].pchs.heads);
5250
5292
npspt = read_word(ebda_seg, &EbdaData->ata.devices[device].pchs.spt);
5254
5296
lba_low = ((((Bit32u)cylinder * (Bit32u)nlh) + (Bit32u)head) * (Bit32u)nlspt) + (Bit32u)sector - 1;
5256
5298
sector = 0; // this forces the command to be lba
5259
if ( GET_AH() == 0x02 )
5301
if (GET_AH() == 0x02)
5260
5302
status=ata_cmd_data_in(device, ATA_CMD_READ_SECTORS, count, cylinder, head, sector, lba_low, lba_high, segment, offset);
5262
5304
status=ata_cmd_data_out(device, ATA_CMD_WRITE_SECTORS, count, cylinder, head, sector, lba_low, lba_high, segment, offset);
5358
5400
&& lba_low >= read_dword(ebda_seg, &EbdaData->ata.devices[device].sectors_low) ) {
5359
5401
BX_INFO("int13_harddisk: function %02x. LBA out of range\n",GET_AH());
5360
5402
goto int13_fail;
5363
5405
// If verify or seek
5364
5406
if (( GET_AH() == 0x44 ) || ( GET_AH() == 0x47 ))
5365
5407
goto int13_success;
5367
5409
// Execute the command
5368
if ( GET_AH() == 0x42 )
5410
if (GET_AH() == 0x42)
5369
5411
status=ata_cmd_data_in(device, ATA_CMD_READ_SECTORS, count, 0, 0, 0, lba_low, lba_high, segment, offset);
5371
5413
status=ata_cmd_data_out(device, ATA_CMD_WRITE_SECTORS, count, 0, 0, 0, lba_low, lba_high, segment, offset);
5493
5535
write_byte(DS, SI+(Bit16u)&Int13DPT->host_bus[1], 'S');
5494
5536
write_byte(DS, SI+(Bit16u)&Int13DPT->host_bus[2], 'A');
5495
5537
write_byte(DS, SI+(Bit16u)&Int13DPT->host_bus[3], 0);
5500
5542
write_byte(DS, SI+(Bit16u)&Int13DPT->iface_type[0], 'A');
5501
5543
write_byte(DS, SI+(Bit16u)&Int13DPT->iface_type[1], 'T');
5502
5544
write_byte(DS, SI+(Bit16u)&Int13DPT->iface_type[2], 'A');
5506
5548
write_word(DS, SI+(Bit16u)&Int13DPT->iface_path[0], iobase1);
5507
5549
write_word(DS, SI+(Bit16u)&Int13DPT->iface_path[2], 0);
5508
5550
write_dword(DS, SI+(Bit16u)&Int13DPT->iface_path[4], 0L);
5513
5555
write_byte(DS, SI+(Bit16u)&Int13DPT->device_path[0], device%2);
5514
5556
write_byte(DS, SI+(Bit16u)&Int13DPT->device_path[1], 0);
5515
5557
write_word(DS, SI+(Bit16u)&Int13DPT->device_path[2], 0);
5555
5597
BX_INFO("int13_harddisk: function %02xh unsupported, returns fail\n", GET_AH());
5556
5598
goto int13_fail;
5561
SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
5603
SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
5562
5604
int13_fail_noah:
5563
SET_DISK_RET_STATUS(GET_AH());
5605
SET_DISK_RET_STATUS(GET_AH());
5564
5606
int13_fail_nostatus:
5565
SET_CF(); // error occurred
5607
SET_CF(); // error occurred
5569
SET_AH(0x00); // no error
5611
SET_AH(0x00); // no error
5570
5612
int13_success_noah:
5571
SET_DISK_RET_STATUS(0x00);
5572
CLEAR_CF(); // no error
5613
SET_DISK_RET_STATUS(0x00);
5614
CLEAR_CF(); // no error
5576
5617
// ---------------------------------------------------------------------------
5841
5883
write_byte(DS, SI+(Bit16u)&Int13DPT->host_bus[1], 'S');
5842
5884
write_byte(DS, SI+(Bit16u)&Int13DPT->host_bus[2], 'A');
5843
5885
write_byte(DS, SI+(Bit16u)&Int13DPT->host_bus[3], 0);
5848
5890
write_byte(DS, SI+(Bit16u)&Int13DPT->iface_type[0], 'A');
5849
5891
write_byte(DS, SI+(Bit16u)&Int13DPT->iface_type[1], 'T');
5850
5892
write_byte(DS, SI+(Bit16u)&Int13DPT->iface_type[2], 'A');
5854
5896
write_word(DS, SI+(Bit16u)&Int13DPT->iface_path[0], iobase1);
5855
5897
write_word(DS, SI+(Bit16u)&Int13DPT->iface_path[2], 0);
5856
5898
write_dword(DS, SI+(Bit16u)&Int13DPT->iface_path[4], 0L);
5861
5903
write_byte(DS, SI+(Bit16u)&Int13DPT->device_path[0], device%2);
5862
5904
write_byte(DS, SI+(Bit16u)&Int13DPT->device_path[1], 0);
5863
5905
write_word(DS, SI+(Bit16u)&Int13DPT->device_path[2], 0);
5904
5946
BX_INFO("int13_cdrom: unsupported AH=%02x\n", GET_AH());
5905
5947
goto int13_fail;
5910
SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
5952
SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
5911
5953
int13_fail_noah:
5912
SET_DISK_RET_STATUS(GET_AH());
5954
SET_DISK_RET_STATUS(GET_AH());
5913
5955
int13_fail_nostatus:
5914
SET_CF(); // error occurred
5956
SET_CF(); // error occurred
5918
SET_AH(0x00); // no error
5960
SET_AH(0x00); // no error
5919
5961
int13_success_noah:
5920
SET_DISK_RET_STATUS(0x00);
5921
CLEAR_CF(); // no error
5962
SET_DISK_RET_STATUS(0x00);
5963
CLEAR_CF(); // no error
5925
5966
// ---------------------------------------------------------------------------
5978
6019
BX_INFO("int13_eltorito: unsupported AH=%02x\n", GET_AH());
5979
6020
goto int13_fail;
5984
SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
5985
SET_DISK_RET_STATUS(GET_AH());
5986
SET_CF(); // error occurred
6025
SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
6026
SET_DISK_RET_STATUS(GET_AH());
6027
SET_CF(); // error occurred
5990
SET_AH(0x00); // no error
5991
SET_DISK_RET_STATUS(0x00);
5992
CLEAR_CF(); // no error
6031
SET_AH(0x00); // no error
6032
SET_DISK_RET_STATUS(0x00);
6033
CLEAR_CF(); // no error
5996
6036
// ---------------------------------------------------------------------------
6024
6064
SET_DISK_RET_STATUS(0x00);
6026
6066
/* basic checks : emulation should be active, dl should equal the emulated drive */
6027
if( (read_byte(ebda_seg,&EbdaData->cdemu.active) ==0 )
6028
|| (read_byte(ebda_seg,&EbdaData->cdemu.emulated_drive ) != GET_DL())) {
6067
if( (read_byte(ebda_seg,&EbdaData->cdemu.active) ==0) ||
6068
(read_byte(ebda_seg,&EbdaData->cdemu.emulated_drive ) != GET_DL())) {
6029
6069
BX_INFO("int13_cdemu: function %02x, emulation not active for DL= %02x\n", GET_AH(), GET_DL());
6030
6070
goto int13_fail;
6033
6073
switch (GET_AH()) {
6128
6168
vcylinders=read_word(ebda_seg,&EbdaData->cdemu.vdevice.cylinders) - 1;
6129
6169
vheads=read_word(ebda_seg,&EbdaData->cdemu.vdevice.heads) - 1;
6133
SET_CH( vcylinders & 0xff );
6134
SET_CL((( vcylinders >> 2) & 0xc0) | ( vspt & 0x3f ));
6136
SET_DL( 0x02 ); // FIXME ElTorito Various. should send the real count of drives 1 or 2
6173
SET_CH(vcylinders & 0xff);
6174
SET_CL(((vcylinders >> 2) & 0xc0) | (vspt & 0x3f));
6176
SET_DL(0x02); // FIXME ElTorito Various. should send the real count of drives 1 or 2
6137
6177
// FIXME ElTorito Harddisk. should send the HD count
6139
6179
switch(read_byte(ebda_seg,&EbdaData->cdemu.media)) {
6140
6180
case 0x01: SET_BL( 0x02 ); break;
6141
6181
case 0x02: SET_BL( 0x04 ); break;
6142
6182
case 0x03: SET_BL( 0x06 ); break;
6179
6219
BX_INFO("int13_cdemu function AH=%02x unsupported, returns fail\n", GET_AH());
6180
6220
goto int13_fail;
6185
SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
6225
SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
6186
6226
int13_fail_noah:
6187
SET_DISK_RET_STATUS(GET_AH());
6227
SET_DISK_RET_STATUS(GET_AH());
6188
6228
int13_fail_nostatus:
6189
SET_CF(); // error occurred
6229
SET_CF(); // error occurred
6193
SET_AH(0x00); // no error
6233
SET_AH(0x00); // no error
6194
6234
int13_success_noah:
6195
SET_DISK_RET_STATUS(0x00);
6196
CLEAR_CF(); // no error
6235
SET_DISK_RET_STATUS(0x00);
6236
CLEAR_CF(); // no error
6200
6239
// ---------------------------------------------------------------------------
6376
6414
SET_DISK_RET_STATUS(0);
6381
6419
status = inb(0x1f7);
6382
6420
if (status & 0x80) {
6383
6421
BX_PANIC("hard drive BIOS:(read/verify) BUSY bit set\n");
6385
6423
outb(0x01f2, num_sectors);
6386
6424
/* activate LBA? (tomv) */
6387
6425
if (hd_heads > 16) {
6388
6426
BX_DEBUG_INT13_HD("CHS: %x %x %x\n", cylinder, head, sector);
6389
6427
outLBA(cylinder,hd_heads,head,hd_sectors,sector,drive);
6392
6430
outb(0x01f3, sector);
6393
6431
outb(0x01f4, cylinder & 0x00ff);
6394
6432
outb(0x01f5, cylinder >> 8);
6395
6433
outb(0x01f6, 0xa0 | ((drive & 0x01)<<4) | (head & 0x0f));
6397
6435
outb(0x01f7, 0x20);
6400
6438
status = inb(0x1f7);
6401
if ( !(status & 0x80) ) break;
6439
if (!(status & 0x80)) break;
6404
6442
if (status & 0x01) {
6405
6443
BX_PANIC("hard drive BIOS:(read/verify) read error\n");
6406
} else if ( !(status & 0x08) ) {
6444
} else if (!(status & 0x08)) {
6407
6445
BX_DEBUG_INT13_HD("status was %02x\n", (unsigned) status);
6408
6446
BX_PANIC("hard drive BIOS:(read/verify) expected DRQ=1\n");
6528
6565
if (hd_heads > 16) {
6529
6566
BX_DEBUG_INT13_HD("CHS (write): %x %x %x\n", cylinder, head, sector);
6530
6567
outLBA(cylinder,hd_heads,head,hd_sectors,sector,GET_ELDL());
6533
6570
outb(0x01f3, sector);
6534
6571
outb(0x01f4, cylinder & 0x00ff);
6535
6572
outb(0x01f5, cylinder >> 8);
6536
6573
outb(0x01f6, 0xa0 | ((GET_ELDL() & 0x01)<<4) | (head & 0x0f));
6538
6575
outb(0x01f7, 0x30);
6540
6577
// wait for busy bit to turn off after seeking
6542
6579
status = inb(0x1f7);
6543
if ( !(status & 0x80) ) break;
6580
if (!(status & 0x80)) break;
6546
if ( !(status & 0x08) ) {
6583
if (!(status & 0x08)) {
6547
6584
BX_DEBUG_INT13_HD("status was %02x\n", (unsigned) status);
6548
6585
BX_PANIC("hard drive BIOS:(write) data-request bit not set\n");
6551
6588
sector_count = 0;
6966
7002
// 111 all other formats/drives
6968
7004
drive_type = inb_cmos(0x10);
6969
7006
if (drive == 0)
6970
7007
drive_type >>= 4;
6972
7009
drive_type &= 0x0f;
6973
if ( drive_type == 1 ) {
7011
if (drive_type == 1) {
6974
7012
// 360K 5.25" drive
6975
7013
config_data = 0x00; // 0000 0000
6976
7014
media_state = 0x25; // 0010 0101
6979
else if ( drive_type == 2 ) {
7017
else if (drive_type == 2) {
6980
7018
// 1.2 MB 5.25" drive
6981
7019
config_data = 0x00; // 0000 0000
6982
7020
media_state = 0x25; // 0010 0101 // need double stepping??? (bit 5)
6985
else if ( drive_type == 3 ) {
7023
else if (drive_type == 3) {
6986
7024
// 720K 3.5" drive
6987
7025
config_data = 0x00; // 0000 0000 ???
6988
7026
media_state = 0x17; // 0001 0111
6991
else if ( drive_type == 4 ) {
7029
else if (drive_type == 4) {
6992
7030
// 1.44 MB 3.5" drive
6993
7031
config_data = 0x00; // 0000 0000
6994
7032
media_state = 0x17; // 0001 0111
6997
else if ( drive_type == 5 ) {
7035
else if (drive_type == 5) {
6998
7036
// 2.88 MB 3.5" drive
6999
7037
config_data = 0xCC; // 1100 1100
7000
7038
media_state = 0xD7; // 1101 0111
7004
7041
// Extended floppy size uses special cmos setting
7005
else if ( drive_type == 6 ) {
7042
else if (drive_type == 6) {
7006
7043
// 160k 5.25" drive
7007
7044
config_data = 0x00; // 0000 0000
7008
7045
media_state = 0x27; // 0010 0111
7011
else if ( drive_type == 7 ) {
7048
else if (drive_type == 7) {
7012
7049
// 180k 5.25" drive
7013
7050
config_data = 0x00; // 0000 0000
7014
7051
media_state = 0x27; // 0010 0111
7017
else if ( drive_type == 8 ) {
7054
else if (drive_type == 8) {
7018
7055
// 320k 5.25" drive
7019
7056
config_data = 0x00; // 0000 0000
7020
7057
media_state = 0x27; // 0010 0111
7025
7061
// not recognized
7026
7062
config_data = 0x00; // 0000 0000
7027
7063
media_state = 0x00; // 0000 0000
7031
7067
if (drive == 0)
7032
7068
media_state_offset = 0x90;
10194
10268
mov ax, 2[bx]
10195
10269
cmp ax, #0x506e
10272
mov ax, 0x16[bx] ;; 0x16 is the offset of Boot Connection Vector
10276
;; Option ROM has BCV. Run it now.
10277
push cx ;; Push seg
10278
push ax ;; Push offset
10280
;; Point ES:DI at "$PnP", which tells the ROM that we are a PnP BIOS.
10284
/* jump to BCV function entry pointer */
10285
mov bp, sp ;; Call ROM BCV routine using seg:off on stack
10286
db 0xff ;; call_far ss:[bp+0]
10289
cli ;; In case expansion ROM BIOS turns IF on
10290
add sp, #2 ;; Pop offset value
10291
pop cx ;; Pop seg value (restore CX)
10197
10295
mov ax, 0x1a[bx] ;; 0x1A is also the offset into the expansion header of...
10198
10296
cmp ax, #0x0000 ;; the Bootstrap Entry Vector, or zero if there is none.
10291
10409
cmp al, #0x05
10292
10410
je eoi_jmp_post
10412
;; 0x0A = jmp via [0x40:0x67] jump
10416
;; 0x0B = iret via [0x40:0x67]
10420
;; 0x0C = retf via [0x40:0x67]
10294
10424
;; Examine CMOS shutdown status.
10295
;; 0x01,0x02,0x03,0x04,0x06,0x07,0x08, 0x0a, 0x0b, 0x0c = Unimplemented shutdown status.
10425
;; 0x01,0x02,0x03,0x04,0x06,0x07,0x08 = Unimplemented shutdown status.
10297
10427
call _shutdown_status_panic