Add files to repository
This commit is contained in:
parent
443c63b64d
commit
12553eeeb1
7 changed files with 1489 additions and 1 deletions
48
Install.HC
Normal file
48
Install.HC
Normal file
|
@ -0,0 +1,48 @@
|
|||
U0 Install() {
|
||||
"Primary IDE base0 (0x01F0): ";
|
||||
U8 *pri_base0 = GetStr;
|
||||
if (!StrCmp(pri_base0, ""))
|
||||
pri_base0 = "0x01F0";
|
||||
"Primary IDE base1 (0x03F6): ";
|
||||
U8 *pri_base1 = GetStr;
|
||||
if (!StrCmp(pri_base1, ""))
|
||||
pri_base1 = "0x03F6";
|
||||
"Secondary IDE base0 (0x0170): ";
|
||||
U8 *sec_base0 = GetStr;
|
||||
if (!StrCmp(sec_base0, ""))
|
||||
sec_base0 = "0x0170";
|
||||
"Secondary IDE base1 (0x0376): ";
|
||||
U8 *sec_base1 = GetStr;
|
||||
if (!StrCmp(sec_base1, ""))
|
||||
sec_base1 = "0x0376";
|
||||
Copy("T:/KMain.HC", "::/Kernel/KMain.HC");
|
||||
Copy("T:/Src/DskAddDev.HC", "::/Kernel/BlkDev/DskAddDev.HC.Z");
|
||||
Copy("T:/Src/DskATA.HC", "::/Kernel/BlkDev/DskATA.HC.Z");
|
||||
Copy("T:/Src/BootHelper.HC", "::/Home/BootHelper.HC.Z");
|
||||
CDoc *doc1 = DocNew("::/Kernel/BlkDev/DskATAId.HC.Z");
|
||||
CDoc *doc2 = DocRead("T:/Src/DskATAId.HC");
|
||||
DocPrint(doc1, "#define BMIK_PRI_BASE0 %s\n", pri_base0);
|
||||
DocPrint(doc1, "#define BMIK_PRI_BASE1 %s\n", pri_base1);
|
||||
DocPrint(doc1, "#define BMIK_SEC_BASE0 %s\n", sec_base0);
|
||||
DocPrint(doc1, "#define BMIK_SEC_BASE1 %s\n", sec_base1);
|
||||
DocInsDoc(doc1, doc2);
|
||||
DocDel(doc2);
|
||||
DocWrite(doc1);
|
||||
DocDel(doc1);
|
||||
doc1 = DocNew("::/Home/Once.HC.Z");
|
||||
doc2 = DocRead("::/Home/Once.HC.Z");
|
||||
DocPrint(doc1, "#include \"BootHelper\"\n\n");
|
||||
DocInsDoc(doc1, doc2);
|
||||
DocDel(doc2);
|
||||
DocWrite(doc1);
|
||||
DocDel(doc1);
|
||||
XTalkWait(Fs, "Cd;\n");
|
||||
XTalkWait(Fs, "BootHDIns;\n");
|
||||
XTalkWait(Fs, "\n");
|
||||
XTalkWait(Fs, "C\ns");
|
||||
XTalkWait(Fs, "0x01F0\n");
|
||||
XTalkWait(Fs, "0x03F6\n");
|
||||
XTalkWait(Fs, "0\n\n\n");
|
||||
}
|
||||
|
||||
Install;
|
38
README.md
38
README.md
|
@ -1,3 +1,39 @@
|
|||
# bmik
|
||||
|
||||
Bare-Metal Installation Kit - Easily install TempleOS on bare-metal
|
||||
Bare-Metal Installation Kit - Easily install TempleOS on bare-metal
|
||||
|
||||
# Details
|
||||
|
||||
The goal for this project is to provide an easy way to create a hard disk image that can be booted on bare-metal hardware and QEMU seamlessly, to allow for transfer of files between PCs while developing software projects.
|
||||
|
||||
The intended usage is to create a disk image that can be copied to a hard disk mounted in a removable enclosure, and the hard disk transferred between the virtual environment and a bare-metal machine.
|
||||
|
||||
# Usage
|
||||
|
||||
- Create a raw disk image, at least large enough to hold 2*1G TempleOS RedSea partitions + partition table `qemu-img create -f raw disk_img.raw 4G`
|
||||
|
||||
- Run the VM install wizard, then re-run install wizard w/o VM option from each partition and choose RedSea format for each install
|
||||
|
||||
OR
|
||||
|
||||
- Use the provided disk image `disk_img.raw.xz` which skips these steps for you.
|
||||
|
||||
THEN
|
||||
|
||||
- Clone the repo, add files to `bmik.ISO.C`
|
||||
|
||||
- `qemu-system-x86_64 -drive format=raw,file=disk_img.raw -m 1024 -cdrom bmik.ISO.C`
|
||||
|
||||
FINALLY, for each partition:
|
||||
|
||||
- Mount the CDROM, if it is not mounted already `Mount;` - drive letter 'T', 'p' for probe, number '2' for Secondary IDE
|
||||
|
||||
- `Cd("T:"); #include "Install";`
|
||||
|
||||
- Enter your Primary/Secondary base0, base1 I/O ports from `lspci -v`
|
||||
|
||||
- Reboot
|
||||
|
||||
# Done
|
||||
|
||||
`dd` the resulting `disk_img.raw` to your target HDD, and you now have a TempleOS RedSea installation with 2 partitions, bootable on bare-metal and QEMU.
|
26
Src/BootHelper.HC
Normal file
26
Src/BootHelper.HC
Normal file
|
@ -0,0 +1,26 @@
|
|||
// This script will clean up non-existent removable drives when booting in QEMU
|
||||
|
||||
U0 BootHelper() {
|
||||
I64 i;
|
||||
Bool is_qemu = FALSE;
|
||||
U8 *drv_model = DrvModelNum(':');
|
||||
if (!MemCmp("QEMU", drv_model, 4))
|
||||
is_qemu = TRUE;
|
||||
Free(drv_model);
|
||||
if (is_qemu) {
|
||||
// Remove non-existent removable drives
|
||||
for (i = 'T'; i < 'X'; i++) {
|
||||
if (Let2Drv(i, 0))
|
||||
DrvDel(Let2Drv(i));
|
||||
}
|
||||
// Add default QEMU CDROM
|
||||
CBlkDev *bd = CAlloc(sizeof(CBlkDev));
|
||||
bd = BlkDevNextFreeSlot('T', 5);
|
||||
bd->unit = 0;
|
||||
bd->base0 = 0x170;
|
||||
bd->base1 = 0x374;
|
||||
BlkDevAdd(bd, , 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
BootHelper;
|
601
Src/DskATA.HC
Normal file
601
Src/DskATA.HC
Normal file
|
@ -0,0 +1,601 @@
|
|||
U0 ATABlkSel(CBlkDev *bd, I64 blk, I64 cnt) {
|
||||
if (bd->type != BDT_ATAPI && bd->base1)
|
||||
OutU8(bd->base1 + ATAR1_CTRL, 0x8);
|
||||
if (bd->flags & BDF_EXT_SIZE) { // 48 Bit LBA?
|
||||
OutU8(bd->base0 + ATAR0_NSECT, cnt.u8[1]);
|
||||
OutU8(bd->base0 + ATAR0_SECT, blk.u8[3]);
|
||||
OutU8(bd->base0 + ATAR0_LCYL, blk.u8[4]);
|
||||
OutU8(bd->base0 + ATAR0_HCYL, blk.u8[5]);
|
||||
OutU8(bd->base0 + ATAR0_NSECT, cnt);
|
||||
OutU8(bd->base0 + ATAR0_SECT, blk);
|
||||
OutU8(bd->base0 + ATAR0_LCYL, blk.u8[1]);
|
||||
OutU8(bd->base0 + ATAR0_HCYL, blk.u8[2]);
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xEF | bd->unit << 4);
|
||||
} else { // 28 Bit LBA
|
||||
OutU8(bd->base0 + ATAR0_NSECT, cnt);
|
||||
OutU8(bd->base0 + ATAR0_SECT, blk);
|
||||
OutU8(bd->base0 + ATAR0_LCYL, blk.u8[1]);
|
||||
OutU8(bd->base0 + ATAR0_HCYL, blk.u8[2]);
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xE0 | bd->unit << 4 | blk.u8[3]);
|
||||
}
|
||||
}
|
||||
|
||||
Bool ATAWaitNotBUSY(CBlkDev *bd, F64 timeout) {
|
||||
I64 i;
|
||||
do {
|
||||
for (i = 0; i < 3; i++)
|
||||
if (!(InU8(bd->base0 + ATAR0_STAT) & ATAS_BSY))
|
||||
return TRUE;
|
||||
Yield;
|
||||
} while (!(0 < timeout < tS));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bool ATAWaitDRQ(CBlkDev *bd, F64 timeout) {
|
||||
I64 i;
|
||||
do {
|
||||
for (i = 0; i < 3; i++)
|
||||
if (InU8(bd->base0 + ATAR0_STAT) & ATAS_DRQ)
|
||||
return TRUE;
|
||||
Yield;
|
||||
} while (!(0 < timeout < tS));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bool ATANop(CBlkDev *bd, F64 timeout) {
|
||||
if (bd->flags & BDF_EXT_SIZE)
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xEF | bd->unit << 4);
|
||||
else
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xE0 | bd->unit << 4);
|
||||
OutU8(bd->base0 + ATAR0_FEAT, 0);
|
||||
OutU8(bd->base0 + ATAR0_CMD, ATA_NOP);
|
||||
return ATAWaitNotBUSY(bd, timeout);
|
||||
}
|
||||
|
||||
U0 ATACmd(CBlkDev *bd, U8 cmd) {
|
||||
OutU8(bd->base0 + ATAR0_FEAT, 0);
|
||||
OutU8(bd->base0 + ATAR0_CMD, cmd);
|
||||
bd->last_time = tS;
|
||||
PortNop;
|
||||
}
|
||||
|
||||
Bool ATAGetRes(CBlkDev *bd, F64 timeout, U8 *buf, I64 cnt, I64 _avail,
|
||||
Bool one_read) {
|
||||
I64 avail, overflow;
|
||||
bd->flags &= ~BDF_LAST_WAS_WRITE;
|
||||
MemSet(buf, 0, cnt);
|
||||
while (cnt > 0) {
|
||||
if (!ATAWaitDRQ(bd, timeout))
|
||||
return FALSE;
|
||||
if (_avail)
|
||||
avail = _avail;
|
||||
else
|
||||
avail = InU8(bd->base0 + ATAR0_HCYL) << 8 + InU8(bd->base0 + ATAR0_LCYL);
|
||||
if (avail) {
|
||||
if (avail > cnt) {
|
||||
overflow = avail - cnt;
|
||||
avail = cnt;
|
||||
} else
|
||||
overflow = 0;
|
||||
if (avail & 2)
|
||||
RepInU16(buf, avail >> 1, bd->base0 + ATAR0_DATA);
|
||||
else
|
||||
RepInU32(buf, avail >> 2, bd->base0 + ATAR0_DATA);
|
||||
cnt -= avail;
|
||||
buf += avail;
|
||||
while (overflow > 0) {
|
||||
InU16(bd->base0 + ATAR0_DATA);
|
||||
overflow -= 2;
|
||||
if (0 < timeout < tS)
|
||||
return FALSE;
|
||||
}
|
||||
if (one_read)
|
||||
break;
|
||||
} else
|
||||
Yield;
|
||||
}
|
||||
return ATAWaitNotBUSY(bd, timeout);
|
||||
}
|
||||
|
||||
Bool ATAPIWritePktWord(CBlkDev *bd, F64 timeout, ...) {
|
||||
I64 i;
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (!ATAWaitDRQ(bd, timeout))
|
||||
return FALSE;
|
||||
OutU16(bd->base0 + ATAR0_DATA, EndianU16(argv[i]));
|
||||
bd->last_time = tS;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool ATAPISetMaxSpeed(CBlkDev *bd) {
|
||||
if (bd->flags & BDF_EXT_SIZE)
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xEF | bd->unit << 4);
|
||||
else
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xE0 | bd->unit << 4);
|
||||
OutU8(bd->base0 + ATAR0_LCYL, 0);
|
||||
OutU8(bd->base0 + ATAR0_HCYL, 0);
|
||||
ATACmd(bd, ATA_PACKET);
|
||||
ATAPIWritePktWord(bd, 0, 0xBB00, 0xFFFF, 0xFFFF, 0, 0, 0);
|
||||
return ATAWaitNotBUSY(bd, 0);
|
||||
}
|
||||
|
||||
Bool ATAPISeek(CBlkDev *bd, I64 native_blk) {
|
||||
if (bd->flags & BDF_EXT_SIZE)
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xEF | bd->unit << 4);
|
||||
else
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xE0 | bd->unit << 4);
|
||||
OutU8(bd->base0 + ATAR0_LCYL, 0);
|
||||
OutU8(bd->base0 + ATAR0_HCYL, 0);
|
||||
ATACmd(bd, ATA_PACKET);
|
||||
ATAPIWritePktWord(bd, 0, 0x2B00, native_blk >> 16, native_blk, 0, 0, 0);
|
||||
return ATAWaitNotBUSY(bd, 0);
|
||||
}
|
||||
|
||||
Bool ATAPIStartStop(CBlkDev *bd, F64 timeout, Bool start) {
|
||||
I64 i;
|
||||
if (start)
|
||||
i = 0x100;
|
||||
else
|
||||
i = 0;
|
||||
if (bd->flags & BDF_EXT_SIZE)
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xEF | bd->unit << 4);
|
||||
else
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xE0 | bd->unit << 4);
|
||||
ATACmd(bd, ATA_PACKET);
|
||||
// Start/Stop
|
||||
if (ATAPIWritePktWord(bd, timeout, 0x1B00, 0, i, 0, 0, 0))
|
||||
return ATAWaitNotBUSY(bd, timeout);
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
I64 ATAGetDevId(CBlkDev *bd, F64 timeout, Bool keep_id_record) {
|
||||
I64 res = BDT_NULL;
|
||||
U16 *id_record = NULL;
|
||||
if (bd->type != BDT_ATAPI && bd->base1)
|
||||
OutU8(bd->base1 + ATAR1_CTRL, 0x8);
|
||||
if (bd->flags & BDF_EXT_SIZE)
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xEF | bd->unit << 4);
|
||||
else
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xE0 | bd->unit << 4);
|
||||
ATACmd(bd, ATA_ID_DEV);
|
||||
ATAWaitNotBUSY(bd, timeout);
|
||||
if (InU8(bd->base0 + ATAR0_STAT) & ATAS_ERR)
|
||||
res = BDT_ATAPI;
|
||||
else {
|
||||
id_record = ACAlloc(512);
|
||||
if (ATAGetRes(bd, timeout, id_record, 512, 512, FALSE))
|
||||
res = BDT_ATA;
|
||||
else {
|
||||
Free(id_record);
|
||||
id_record = NULL;
|
||||
}
|
||||
}
|
||||
if (keep_id_record) {
|
||||
Free(bd->dev_id_record);
|
||||
bd->dev_id_record = id_record;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
I64 ATAReadNativeMax(CBlkDev *bd, F64 timeout) { // Returns zero on err
|
||||
I64 res = 0;
|
||||
Bool okay = TRUE;
|
||||
if (bd->type == BDT_ATAPI) {
|
||||
if (bd->flags & BDF_EXT_SIZE)
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xEF | bd->unit << 4);
|
||||
else
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xE0 | bd->unit << 4);
|
||||
ATACmd(bd, ATA_DEV_RST);
|
||||
if (!ATAWaitNotBUSY(bd, 0))
|
||||
okay = FALSE;
|
||||
} else {
|
||||
while (InU8(bd->base0 + ATAR0_STAT) & ATAS_BSY) {
|
||||
if (bd->flags & BDF_LAST_WAS_WRITE)
|
||||
OutU16(bd->base0 + ATAR0_DATA, 0);
|
||||
else
|
||||
InU16(bd->base0 + ATAR0_DATA);
|
||||
Yield;
|
||||
if (0 < timeout < tS)
|
||||
return FALSE;
|
||||
}
|
||||
if (ATAGetDevId(bd, timeout, TRUE) == BDT_NULL)
|
||||
okay = FALSE;
|
||||
else
|
||||
BEqu(&bd->flags, BDf_EXT_SIZE, Bt(&bd->dev_id_record[86], 10));
|
||||
}
|
||||
if (okay) {
|
||||
if (bd->flags & BDF_EXT_SIZE && bd->base1) {
|
||||
OutU8(bd->base1 + ATAR1_CTRL, 0x8);
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xEF | bd->unit << 4);
|
||||
ATACmd(bd, ATA_READ_NATIVE_MAX_EXT);
|
||||
if (ATAWaitNotBUSY(bd, timeout)) {
|
||||
res.u8[0] = InU8(bd->base0 + ATAR0_SECT);
|
||||
res.u8[1] = InU8(bd->base0 + ATAR0_LCYL);
|
||||
res.u8[2] = InU8(bd->base0 + ATAR0_HCYL);
|
||||
|
||||
OutU8(bd->base1 + ATAR1_CTRL, 0x80);
|
||||
res.u8[3] = InU8(bd->base0 + ATAR0_SECT);
|
||||
res.u8[4] = InU8(bd->base0 + ATAR0_LCYL);
|
||||
res.u8[5] = InU8(bd->base0 + ATAR0_HCYL);
|
||||
|
||||
if (res >> 24 == res & 0xFFFFFF) { // Kludge to make QEMU work
|
||||
bd->flags &= ~BDF_EXT_SIZE;
|
||||
res &= 0xFFFFFF;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (bd->type != BDT_ATAPI && bd->base1)
|
||||
OutU8(bd->base1 + ATAR1_CTRL, 0x8);
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xE0 | bd->unit << 4);
|
||||
ATACmd(bd, ATA_READ_NATIVE_MAX);
|
||||
if (ATAWaitNotBUSY(bd, timeout)) {
|
||||
res.u8[0] = InU8(bd->base0 + ATAR0_SECT);
|
||||
res.u8[1] = InU8(bd->base0 + ATAR0_LCYL);
|
||||
res.u8[2] = InU8(bd->base0 + ATAR0_HCYL);
|
||||
res.u8[3] = InU8(bd->base0 + ATAR0_SEL) & 0xF;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bd->max_blk = res;
|
||||
}
|
||||
|
||||
I64 ATAPIReadCapacity(
|
||||
CBlkDev *bd,
|
||||
I64 *_blk_size = NULL) { // Supposedly this can return a res +/- 75 sects.
|
||||
// Error might just be for music.
|
||||
Bool unlock = BlkDevLock(bd);
|
||||
U32 buf[2];
|
||||
if (ATAWaitNotBUSY(bd, 0)) {
|
||||
if (bd->flags & BDF_EXT_SIZE)
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xEF | bd->unit << 4);
|
||||
else
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xE0 | bd->unit << 4);
|
||||
OutU8(bd->base0 + ATAR0_LCYL, 8);
|
||||
OutU8(bd->base0 + ATAR0_HCYL, 0);
|
||||
ATACmd(bd, ATA_PACKET);
|
||||
ATAPIWritePktWord(bd, 0, 0x2500, 0, 0, 0, 0, 0);
|
||||
if (!ATAGetRes(bd, 0, buf, 8, 0, TRUE))
|
||||
buf[0] = buf[1] = 0;
|
||||
} else
|
||||
buf[0] = buf[1] = 0;
|
||||
|
||||
if (unlock)
|
||||
BlkDevUnlock(bd);
|
||||
if (_blk_size)
|
||||
*_blk_size = EndianU32(buf[1]);
|
||||
return EndianU32(buf[0]);
|
||||
}
|
||||
|
||||
CATAPITrack *ATAPIReadTrackInfo(CBlkDev *bd, I64 blk) {
|
||||
CATAPITrack *res = CAlloc(sizeof(CATAPITrack));
|
||||
Bool unlock = BlkDevLock(bd);
|
||||
if (ATAWaitNotBUSY(bd, 0)) {
|
||||
if (bd->flags & BDF_EXT_SIZE)
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xEF | bd->unit << 4);
|
||||
else
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xE0 | bd->unit << 4);
|
||||
OutU8(bd->base0 + ATAR0_LCYL, sizeof(CATAPITrack) & 0xFF);
|
||||
OutU8(bd->base0 + ATAR0_HCYL, sizeof(CATAPITrack) >> 8);
|
||||
ATACmd(bd, ATA_PACKET);
|
||||
ATAPIWritePktWord(bd, 0, 0x5200, blk.u16[1], blk.u16[0],
|
||||
(sizeof(CATAPITrack) & 0xFF00) >> 8,
|
||||
(sizeof(CATAPITrack) & 0x00FF) << 8, 0);
|
||||
if (!ATAGetRes(bd, 0, res, sizeof(CATAPITrack), 0, TRUE)) {
|
||||
Free(res);
|
||||
res = NULL;
|
||||
}
|
||||
} else {
|
||||
Free(res);
|
||||
res = NULL;
|
||||
}
|
||||
if (unlock)
|
||||
BlkDevUnlock(bd);
|
||||
return res;
|
||||
}
|
||||
|
||||
Bool ATAInit(CBlkDev *bd) {
|
||||
Bool unlock = BlkDevLock(bd), okay = FALSE;
|
||||
|
||||
if (bd->type == BDT_ATAPI)
|
||||
bd->flags &= ~BDF_EXT_SIZE;
|
||||
else
|
||||
bd->flags |= BDF_EXT_SIZE;
|
||||
|
||||
if (ATAReadNativeMax(bd, tS + 0.1)) {
|
||||
ATABlkSel(bd, bd->max_blk, 0);
|
||||
if (bd->flags & BDF_EXT_SIZE)
|
||||
ATACmd(bd, ATA_SET_MAX_EXT);
|
||||
else
|
||||
ATACmd(bd, ATA_SET_MAX);
|
||||
if (ATAWaitNotBUSY(bd, 0)) {
|
||||
okay = TRUE;
|
||||
if (bd->type == BDT_ATAPI) {
|
||||
if (ATAPIStartStop(bd, 0, TRUE)) {
|
||||
if (!ATAPISetMaxSpeed(bd))
|
||||
okay = FALSE;
|
||||
} else
|
||||
okay = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (unlock)
|
||||
BlkDevUnlock(bd);
|
||||
return okay;
|
||||
}
|
||||
|
||||
Bool ATAPIWaitReady(CBlkDev *bd, F64 timeout) {
|
||||
do {
|
||||
if (!ATAWaitNotBUSY(bd, timeout) || !ATANop(bd, timeout) ||
|
||||
!ATAPIStartStop(bd, timeout, TRUE))
|
||||
return FALSE;
|
||||
if (InU8(bd->base0 + ATAR0_STAT) & ATAS_DRDY &&
|
||||
!InU8(bd->base0 + ATAR0_FEAT))
|
||||
;
|
||||
return TRUE;
|
||||
ATAInit(bd);
|
||||
Yield;
|
||||
} while (!(0 < timeout < tS));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
U0 ATAReadBlks(CBlkDev *bd, U8 *buf, I64 blk, I64 cnt) {
|
||||
I64 retries = 3;
|
||||
Bool unlock = BlkDevLock(bd);
|
||||
|
||||
retry:
|
||||
ATABlkSel(bd, blk, cnt);
|
||||
if (bd->flags & BDF_EXT_SIZE)
|
||||
ATACmd(bd, ATA_READ_MULTI_EXT);
|
||||
else
|
||||
ATACmd(bd, ATA_READ_MULTI);
|
||||
if (!ATAGetRes(bd, tS + 1.0, buf, cnt * bd->blk_size, BLK_SIZE, FALSE)) {
|
||||
if (retries--) {
|
||||
ATAWaitNotBUSY(bd, 0);
|
||||
goto retry;
|
||||
} else
|
||||
throw('BlkDev');
|
||||
}
|
||||
|
||||
blkdev.read_cnt += (cnt * bd->blk_size) >> BLK_SIZE_BITS;
|
||||
if (unlock)
|
||||
BlkDevUnlock(bd);
|
||||
}
|
||||
|
||||
I64 ATAProbe(I64 base0, I64 base1, I64 unit) {
|
||||
CBlkDev bd;
|
||||
MemSet(&bd, 0, sizeof(CBlkDev));
|
||||
bd.type = BDT_ATAPI;
|
||||
bd.base0 = base0;
|
||||
bd.base1 = base1;
|
||||
bd.unit = unit;
|
||||
bd.blk_size = DVD_BLK_SIZE;
|
||||
return ATAGetDevId(&bd, tS + 0.1, FALSE);
|
||||
}
|
||||
|
||||
Bool ATAPIReadBlks2(CBlkDev *bd, F64 timeout, U8 *buf, I64 native_blk, I64 cnt,
|
||||
Bool lock) {
|
||||
Bool res = FALSE, unlock;
|
||||
if (cnt <= 0)
|
||||
return FALSE;
|
||||
if (lock)
|
||||
unlock = BlkDevLock(bd);
|
||||
if (ATAPIWaitReady(bd, timeout)) {
|
||||
if (bd->flags & BDF_EXT_SIZE)
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xEF | bd->unit << 4);
|
||||
else
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xE0 | bd->unit << 4);
|
||||
OutU8(bd->base0 + ATAR0_LCYL, bd->blk_size);
|
||||
OutU8(bd->base0 + ATAR0_HCYL, bd->blk_size.u8[1]);
|
||||
ATACmd(bd, ATA_PACKET);
|
||||
if (ATAPIWritePktWord(bd, timeout, 0xA800, native_blk.u16[1], native_blk,
|
||||
cnt.u16[1], cnt, 0) &&
|
||||
ATAGetRes(bd, timeout, buf, cnt * bd->blk_size, 0, FALSE)) {
|
||||
blkdev.read_cnt += (cnt * bd->blk_size) >> BLK_SIZE_BITS;
|
||||
res = TRUE;
|
||||
}
|
||||
}
|
||||
// ATAPIStartStop(bd,0,FALSE);
|
||||
if (lock && unlock)
|
||||
BlkDevUnlock(bd);
|
||||
return res;
|
||||
}
|
||||
|
||||
U0 ATAPIReadBlks(CBlkDev *bd, U8 *buf, I64 blk, I64 cnt) {
|
||||
CDrv *dv = Let2Drv(bd->first_drv_let);
|
||||
I64 retry, spc = bd->blk_size >> BLK_SIZE_BITS, n, blk2,
|
||||
l2 = bd->max_reads << 1 + spc << 1;
|
||||
U8 *dvd_buf = MAlloc(l2 << BLK_SIZE_BITS);
|
||||
if (cnt > 0) {
|
||||
if (blk <= bd->max_reads)
|
||||
blk2 = 0;
|
||||
else
|
||||
blk2 = FloorU64(blk - bd->max_reads, spc);
|
||||
if (blk2 + l2 > dv->size + dv->drv_offset)
|
||||
l2 = dv->size + dv->drv_offset - blk2;
|
||||
n = (l2 + spc - 1) / spc;
|
||||
|
||||
retry = 4;
|
||||
while (--retry)
|
||||
if (ATAPIReadBlks2(bd, tS + 7.0 + 0.004 * n, dvd_buf, blk2 / spc, n,
|
||||
TRUE))
|
||||
// n is 0x800 if max_reads. Up to 8 additional seconds
|
||||
break;
|
||||
if (!retry)
|
||||
ATAPIReadBlks2(bd, 0, dvd_buf, blk2 / spc, n, TRUE);
|
||||
if (bd->flags & BDF_READ_CACHE)
|
||||
DskCacheAdd(dv, dvd_buf, blk2, n * spc);
|
||||
MemCpy(buf, dvd_buf + (blk - blk2) << BLK_SIZE_BITS, cnt << BLK_SIZE_BITS);
|
||||
}
|
||||
Free(dvd_buf);
|
||||
}
|
||||
|
||||
Bool ATARBlks(CDrv *dv, U8 *buf, I64 blk, I64 cnt) {
|
||||
I64 n;
|
||||
CBlkDev *bd = dv->bd;
|
||||
while (cnt > 0) {
|
||||
n = cnt;
|
||||
if (n > bd->max_reads)
|
||||
n = bd->max_reads;
|
||||
if (bd->type == BDT_ATAPI)
|
||||
ATAPIReadBlks(bd, buf, blk, n);
|
||||
else
|
||||
ATAReadBlks(bd, buf, blk, n);
|
||||
buf += n << BLK_SIZE_BITS;
|
||||
blk += n;
|
||||
cnt -= n;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
U0 ATAWriteBlks(CBlkDev *bd, U8 *buf, I64 blk,
|
||||
I64 cnt) { // For low level disk access.
|
||||
// Use BlkWrite() instead.
|
||||
I64 i, U32s_avail, sects_avail, retries = 3;
|
||||
F64 timeout;
|
||||
Bool unlock = BlkDevLock(bd);
|
||||
retry:
|
||||
ATABlkSel(bd, blk, cnt);
|
||||
if (bd->flags & BDF_EXT_SIZE)
|
||||
ATACmd(bd, ATA_WRITE_MULTI_EXT);
|
||||
else
|
||||
ATACmd(bd, ATA_WRITE_MULTI);
|
||||
bd->flags |= BDF_LAST_WAS_WRITE;
|
||||
while (cnt > 0) {
|
||||
timeout = tS + 1.0;
|
||||
while (TRUE) {
|
||||
i = InU8(bd->base0 + ATAR0_STAT);
|
||||
if (!(i & ATAS_DRDY) || !(i & ATAS_DRQ)) {
|
||||
Yield;
|
||||
} else
|
||||
break;
|
||||
if (/* i&ATAS_ERR||*/ tS > timeout) {
|
||||
if (retries--) {
|
||||
ATAWaitNotBUSY(bd, 0);
|
||||
goto retry;
|
||||
} else
|
||||
throw('BlkDev');
|
||||
}
|
||||
}
|
||||
sects_avail = 1;
|
||||
U32s_avail = sects_avail << BLK_SIZE_BITS >> 2;
|
||||
RepOutU32(buf, U32s_avail, bd->base0 + ATAR0_DATA);
|
||||
buf += U32s_avail << 2;
|
||||
cnt -= sects_avail;
|
||||
retries = 3;
|
||||
}
|
||||
ATAWaitNotBUSY(bd, 0);
|
||||
if (unlock)
|
||||
BlkDevUnlock(bd);
|
||||
}
|
||||
|
||||
Bool ATAPISync(CBlkDev *bd) {
|
||||
Bool okay = TRUE;
|
||||
if (!ATAWaitNotBUSY(bd, 0))
|
||||
okay = FALSE;
|
||||
else {
|
||||
if (bd->flags & BDF_EXT_SIZE)
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xEF | bd->unit << 4);
|
||||
else
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xE0 | bd->unit << 4);
|
||||
OutU8(bd->base0 + ATAR0_LCYL, 0);
|
||||
OutU8(bd->base0 + ATAR0_HCYL, 0);
|
||||
ATACmd(bd, ATA_PACKET);
|
||||
ATAPIWritePktWord(bd, 0, 0x3500, 0, 0, 0, 0, 0);
|
||||
if (!ATAWaitNotBUSY(bd, 0))
|
||||
okay = FALSE;
|
||||
}
|
||||
return okay;
|
||||
}
|
||||
|
||||
U0 ATAPIClose(CBlkDev *bd, I64 close_field = 0x200,
|
||||
I64 track = 0) { // 0x200 CD/DVD part 1
|
||||
// 0x300 DVD part 2
|
||||
if (bd->flags & BDF_EXT_SIZE)
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xEF | bd->unit << 4);
|
||||
else
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xE0 | bd->unit << 4);
|
||||
OutU8(bd->base0 + ATAR0_LCYL, 0);
|
||||
OutU8(bd->base0 + ATAR0_HCYL, 0);
|
||||
ATACmd(bd, ATA_PACKET);
|
||||
ATAPIWritePktWord(bd, 0, 0x5B00, close_field, track, 0, 0, 0);
|
||||
ATAWaitNotBUSY(bd, 0);
|
||||
}
|
||||
|
||||
U0 ATAPIWriteBlks(CBlkDev *bd, U8 *buf, I64 native_blk, I64 cnt) {
|
||||
I64 U32s_avail;
|
||||
U8 *buf2;
|
||||
ATAWaitNotBUSY(bd, 0);
|
||||
ATAPISeek(bd, native_blk);
|
||||
|
||||
OutU8(bd->base0 + ATAR0_FEAT, 0);
|
||||
OutU8(bd->base0 + ATAR0_LCYL, bd->blk_size);
|
||||
OutU8(bd->base0 + ATAR0_HCYL, bd->blk_size.u8[1]);
|
||||
if (bd->flags & BDF_EXT_SIZE)
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xEF | bd->unit << 4);
|
||||
else
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xE0 | bd->unit << 4);
|
||||
OutU8(bd->base0 + ATAR0_CMD, ATA_PACKET);
|
||||
ATAPIWritePktWord(bd, 0, 0x0400, native_blk.u16[1], native_blk, cnt.u16[1],
|
||||
cnt, 0);
|
||||
bd->flags |= BDF_LAST_WAS_WRITE;
|
||||
ATAWaitNotBUSY(bd, 0);
|
||||
|
||||
ATAPISeek(bd, native_blk);
|
||||
|
||||
if (bd->flags & BDF_EXT_SIZE)
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xEF | bd->unit << 4);
|
||||
else
|
||||
OutU8(bd->base0 + ATAR0_SEL, 0xE0 | bd->unit << 4);
|
||||
OutU8(bd->base0 + ATAR0_LCYL, bd->blk_size);
|
||||
OutU8(bd->base0 + ATAR0_HCYL, bd->blk_size.u8[1]);
|
||||
ATACmd(bd, ATA_PACKET);
|
||||
ATAPIWritePktWord(bd, 0, 0xAA00, native_blk.u16[1], native_blk, cnt.u16[1],
|
||||
cnt, 0);
|
||||
buf2 = buf + bd->blk_size * cnt;
|
||||
while (buf < buf2) {
|
||||
ATAWaitDRQ(bd, 0);
|
||||
U32s_avail =
|
||||
(InU8(bd->base0 + ATAR0_HCYL) << 8 + InU8(bd->base0 + ATAR0_LCYL)) >> 2;
|
||||
if (buf + U32s_avail << 2 > buf2)
|
||||
U32s_avail = (buf2 - buf) >> 2;
|
||||
if (U32s_avail) {
|
||||
RepOutU32(buf, U32s_avail, bd->base0 + ATAR0_DATA);
|
||||
buf += U32s_avail << 2;
|
||||
blkdev.write_cnt += U32s_avail >> (BLK_SIZE_BITS - 2);
|
||||
}
|
||||
}
|
||||
ATAWaitNotBUSY(bd, 0);
|
||||
}
|
||||
|
||||
Bool ATAWBlks(CDrv *dv, U8 *buf, I64 blk, I64 cnt) {
|
||||
I64 n, spc;
|
||||
CBlkDev *bd = dv->bd;
|
||||
Bool unlock;
|
||||
spc = bd->blk_size >> BLK_SIZE_BITS;
|
||||
if (bd->type == BDT_ATAPI) {
|
||||
unlock = BlkDevLock(bd);
|
||||
ATAPIWaitReady(bd, 0);
|
||||
}
|
||||
while (cnt > 0) {
|
||||
n = cnt;
|
||||
if (n > bd->max_writes)
|
||||
n = bd->max_writes;
|
||||
if (bd->type == BDT_ATAPI)
|
||||
ATAPIWriteBlks(bd, buf, blk / spc, (n + spc - 1) / spc);
|
||||
else
|
||||
ATAWriteBlks(bd, buf, blk, n);
|
||||
buf += n << BLK_SIZE_BITS;
|
||||
blk += n;
|
||||
cnt -= n;
|
||||
blkdev.write_cnt += n;
|
||||
}
|
||||
if (bd->type == BDT_ATAPI) {
|
||||
ATAPISync(bd);
|
||||
// ATAPIStartStop(bd,0,FALSE);
|
||||
if (unlock)
|
||||
BlkDevUnlock(bd);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
301
Src/DskATAId.HC
Normal file
301
Src/DskATAId.HC
Normal file
|
@ -0,0 +1,301 @@
|
|||
Bool BootDVDProbe(CBlkDev *bd) {
|
||||
U8 *img = CAlloc(DVD_BLK_SIZE);
|
||||
I64 i;
|
||||
Bool res = FALSE;
|
||||
"Port:%04X,%04XUnit:%02X", bd->base0, bd->base1, bd->unit;
|
||||
if (ATAProbe(bd->base0, bd->base1, bd->unit) == BDT_ATAPI) {
|
||||
"ATAPI";
|
||||
if (ATAPIStartStop(bd, tS + 5.0, TRUE)) {
|
||||
"Started";
|
||||
for (i = 0; i < 2; i++) { // Retry
|
||||
if (ATAPIReadBlks2(bd, tS + 7.0, img, sys_boot_blk, 1, FALSE)) {
|
||||
if ((img + sys_boot_src.u16[1] << BLK_SIZE_BITS)(CKernel *)
|
||||
->compile_time == sys_compile_time) {
|
||||
"Found\n";
|
||||
return TRUE;
|
||||
} else
|
||||
"Read";
|
||||
} else
|
||||
"NoRead";
|
||||
}
|
||||
}
|
||||
}
|
||||
"Nope\n";
|
||||
Free(img);
|
||||
return res;
|
||||
}
|
||||
|
||||
Bool BootDVDProbeAll(CBlkDev *bd) {
|
||||
I64 d1, d2, i, j, k;
|
||||
|
||||
bd->base1 = 0;
|
||||
for (k = 0; k < 256; k++) {
|
||||
i = -1;
|
||||
while (TRUE) {
|
||||
j = PCIClassFind(0x010100 + k, ++i);
|
||||
if (j < 0)
|
||||
break;
|
||||
"Subcode:0x%X Bus:0x%X Dev:0x%X Fun:0x%X\n", k, j.u8[2], j.u8[1], j.u8[0];
|
||||
d1 = PCIReadU32(j.u8[2], j.u8[1], j.u8[0], 0x10);
|
||||
d2 = PCIReadU32(j.u8[2], j.u8[1], j.u8[0], 0x14);
|
||||
if (d1 & 1 && d2 & 1) {
|
||||
if (bd->base0 = d1 & ~7) {
|
||||
bd->unit = 0;
|
||||
if (BootDVDProbe(bd))
|
||||
return TRUE;
|
||||
bd->unit = 1;
|
||||
if (BootDVDProbe(bd))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
d1 = PCIReadU32(j.u8[2], j.u8[1], j.u8[0], 0x18);
|
||||
d2 = PCIReadU32(j.u8[2], j.u8[1], j.u8[0], 0x1C);
|
||||
if (d1 & 1 && d2 & 1) {
|
||||
if (bd->base0 = d1 & ~7) {
|
||||
bd->unit = 0;
|
||||
if (BootDVDProbe(bd))
|
||||
return TRUE;
|
||||
bd->unit = 1;
|
||||
if (BootDVDProbe(bd))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
d1 = BMIK_PRI_BASE0;
|
||||
d2 = BMIK_PRI_BASE1;
|
||||
if (bd->base0 = d1 & ~7) {
|
||||
bd->unit = 0;
|
||||
if (BootDVDProbe(bd))
|
||||
return TRUE;
|
||||
bd->unit = 1;
|
||||
if (BootDVDProbe(bd))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
d1 = BMIK_SEC_BASE0;
|
||||
d2 = BMIK_SEC_BASE1;
|
||||
if (bd->base0 = d1 & ~7) {
|
||||
bd->unit = 0;
|
||||
if (BootDVDProbe(bd))
|
||||
return TRUE;
|
||||
bd->unit = 1;
|
||||
if (BootDVDProbe(bd))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
U0 ATARepEntry(I64 base0, I64 base1, I64 unit, U8 *msg, CATARep **_head,
|
||||
I64 *num_hints) {
|
||||
I64 type;
|
||||
base0 &= -8;
|
||||
base1 &= -4;
|
||||
CATARep *tmpha;
|
||||
if (type = ATAProbe(base0, base1, unit)) {
|
||||
*num_hints += 1;
|
||||
"\n$$PURPLE$$$$BT+X,\"%d\",LM=\"%d\\n\"$$$$FG$$$$LM,4$$", *num_hints,
|
||||
*num_hints;
|
||||
if (type == BDT_ATA)
|
||||
"$$RED$$HardDrive$$LTBLUE$$ATA";
|
||||
else
|
||||
"$$RED$$CD/DVDDrive$$LTBLUE$$ATAPI";
|
||||
"%s$$FG$$\n", msg;
|
||||
if (base0 == blkdev.ins_base0 && unit == blkdev.ins_unit)
|
||||
"$$PURPLE$$(Drive originally installed from.)$$FG$$\n";
|
||||
"Base0:0x%04XBase1:0x%04XUnit:%d$$LM,0$$\n", base0, base1, unit;
|
||||
if (_head) {
|
||||
tmpha = CAlloc(sizeof(CATARep));
|
||||
tmpha->next = *_head;
|
||||
*_head = tmpha;
|
||||
tmpha->num = *num_hints;
|
||||
tmpha->type = type;
|
||||
tmpha->base0 = base0;
|
||||
tmpha->base1 = base1;
|
||||
tmpha->unit = unit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Bool ATARepExitAllApplications() {
|
||||
"\nWe're going to probe hardware.\n"
|
||||
"$$RED$$Exit all other applications.$$FG$$\n"
|
||||
"Press '$$PURPLE$$p$$FG$$' to probe or '$$PURPLE$$s$$FG$$' to skip.\n";
|
||||
if (ToUpper(GetChar(, FALSE)) == 'S')
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public
|
||||
I64 ATARep(Bool pmt = TRUE, Bool just_ide = FALSE,
|
||||
CATARep **_head = NULL) { // Report possible ATA devices by probing.
|
||||
// Hard disks and CD/DVDs.
|
||||
I64 d1, d2, i, j, k, cnt = 0, unlock_flags = 0, num_hints = 0;
|
||||
#assert BLKDEVS_NUM <= 64
|
||||
if (_head)
|
||||
*_head = NULL;
|
||||
|
||||
if (pmt && ATARepExitAllApplications)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < BLKDEVS_NUM; i++)
|
||||
if (blkdev.blkdevs[i].bd_signature == BD_SIGNATURE_VAL)
|
||||
BEqu(&unlock_flags, i, BlkDevLock(&blkdev.blkdevs[i]));
|
||||
|
||||
if (!just_ide)
|
||||
for (k = 0; k < 256; k++) {
|
||||
i = -1;
|
||||
while (TRUE) {
|
||||
j = PCIClassFind(0x010100 + k, ++i);
|
||||
if (j < 0)
|
||||
break;
|
||||
|
||||
"\nSubcode:0x%X Bus:0x%X Dev:0x%X Fun:0x%X\n", k, j.u8[2], j.u8[1],
|
||||
j.u8[0];
|
||||
cnt++;
|
||||
|
||||
d1 = PCIReadU32(j.u8[2], j.u8[1], j.u8[0], 0x10);
|
||||
d2 = PCIReadU32(j.u8[2], j.u8[1], j.u8[0], 0x14);
|
||||
if (d1 & 1 && d2 & 1) {
|
||||
ATARepEntry(d1, d2, 0, "Primary IDE", _head, &num_hints);
|
||||
ATARepEntry(d1, d2, 1, "Primary IDE", _head, &num_hints);
|
||||
} else {
|
||||
d1 = BMIK_PRI_BASE0;
|
||||
d2 = BMIK_PRI_BASE1;
|
||||
ATARepEntry(d1, d2, 0, "Primary IDE", _head, &num_hints);
|
||||
ATARepEntry(d1, d2, 1, "Primary IDE", _head, &num_hints);
|
||||
}
|
||||
d1 = PCIReadU32(j.u8[2], j.u8[1], j.u8[0], 0x18);
|
||||
d2 = PCIReadU32(j.u8[2], j.u8[1], j.u8[0], 0x1C);
|
||||
if (d1 & 1 && d2 & 1) {
|
||||
ATARepEntry(d1, d2, 0, "Secondary IDE", _head, &num_hints);
|
||||
ATARepEntry(d1, d2, 1, "Secondary IDE", _head, &num_hints);
|
||||
} else {
|
||||
d1 = BMIK_SEC_BASE0;
|
||||
d2 = BMIK_SEC_BASE1;
|
||||
ATARepEntry(d1, d2, 0, "Secondary IDE", _head, &num_hints);
|
||||
ATARepEntry(d1, d2, 1, "Secondary IDE", _head, &num_hints);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!cnt) {
|
||||
d1 = BMIK_PRI_BASE0;
|
||||
d2 = BMIK_PRI_BASE1;
|
||||
ATARepEntry(d1, d2, 0, "Primary IDE", _head, &num_hints);
|
||||
ATARepEntry(d1, d2, 1, "Primary IDE", _head, &num_hints);
|
||||
|
||||
d1 = BMIK_SEC_BASE0;
|
||||
d2 = BMIK_SEC_BASE1;
|
||||
ATARepEntry(d1, d2, 0, "Secondary IDE", _head, &num_hints);
|
||||
ATARepEntry(d1, d2, 1, "Secondary IDE", _head, &num_hints);
|
||||
}
|
||||
'\n\n';
|
||||
for (i = 0; i < BLKDEVS_NUM; i++)
|
||||
if (Bt(&unlock_flags, i))
|
||||
BlkDevUnlock(&blkdev.blkdevs[i]);
|
||||
return num_hints;
|
||||
}
|
||||
|
||||
CATARep *ATARepFind(CATARep *haystack_head, I64 needle_num) {
|
||||
while (haystack_head) {
|
||||
if (haystack_head->num == needle_num)
|
||||
return haystack_head;
|
||||
haystack_head = haystack_head->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CATARep *
|
||||
ATAIDDrvs(CATARep *head, CATARep **_ata_drv,
|
||||
CATARep **_atapi_drv) { // This is for when trying to sort-out main
|
||||
// hard drives and CD/DVD drives.
|
||||
CATARep *res = NULL, *tmpha = head, *ata_drv = NULL, *atapi_drv = NULL;
|
||||
CBlkDev *bd;
|
||||
Bool was_silent = Silent, ins_found = FALSE;
|
||||
bd = Let2BlkDev(':', FALSE);
|
||||
Silent(was_silent);
|
||||
while (tmpha) {
|
||||
if (!res && bd && bd->type == tmpha->type) {
|
||||
if (bd->type == BDT_ATAPI && bd->base0 == tmpha->base0 &&
|
||||
bd->unit == tmpha->unit)
|
||||
res = atapi_drv = tmpha;
|
||||
else if (bd->type == BDT_ATA && bd->base0 == tmpha->base0 &&
|
||||
bd->base1 == tmpha->base1 && bd->unit == tmpha->unit)
|
||||
res = ata_drv = tmpha;
|
||||
}
|
||||
if (!res || res->type != tmpha->type) {
|
||||
if (tmpha->type == BDT_ATA) {
|
||||
if (!ata_drv || tmpha->unit < ata_drv->unit ||
|
||||
tmpha->unit == ata_drv->unit && tmpha->num < ata_drv->num)
|
||||
ata_drv = tmpha;
|
||||
} else if (tmpha->type == BDT_ATAPI) {
|
||||
if (!atapi_drv || !ins_found && (tmpha->unit < atapi_drv->unit ||
|
||||
tmpha->unit == atapi_drv->unit &&
|
||||
tmpha->num < atapi_drv->num))
|
||||
atapi_drv = tmpha;
|
||||
}
|
||||
}
|
||||
if (tmpha->type == BDT_ATAPI && bd && bd->type == BDT_ATA &&
|
||||
tmpha->base0 == blkdev.ins_base0 && tmpha->unit == blkdev.ins_unit) {
|
||||
if (!ins_found) {
|
||||
atapi_drv = tmpha;
|
||||
ins_found = TRUE;
|
||||
}
|
||||
}
|
||||
tmpha = tmpha->next;
|
||||
}
|
||||
if (_ata_drv)
|
||||
*_ata_drv = ata_drv;
|
||||
if (_atapi_drv)
|
||||
*_atapi_drv = atapi_drv;
|
||||
return res;
|
||||
}
|
||||
|
||||
CBlkDev *ATAMount(U8 first_drv_let, I64 type, I64 base0, I64 base1, I64 unit) {
|
||||
CBlkDev *res;
|
||||
if (0 <= first_drv_let - 'A' < DRVS_NUM &&
|
||||
(type == BDT_ATA || type == BDT_ATAPI) && 0 <= unit <= 1) {
|
||||
res = BlkDevNextFreeSlot(first_drv_let, type);
|
||||
res->unit = unit;
|
||||
res->base0 = base0;
|
||||
res->base1 = base1;
|
||||
if (BlkDevAdd(res, , FALSE, FALSE))
|
||||
return res;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
I64 MountIDEAuto() { // Try to mount hard drive and CD/DVD, automatically.
|
||||
// (Kernel.Cfg option).
|
||||
// It uses 'C' and 'T' as first drive letters or whatever you set
|
||||
// in config when compiling Kernel.BIN.
|
||||
I64 res = 0;
|
||||
CATARep *head = NULL, *ata_drv = NULL, *atapi_drv = NULL, *tmpha;
|
||||
ATARep(FALSE, TRUE, &head);
|
||||
ATAIDDrvs(head, &ata_drv, &atapi_drv);
|
||||
if (ata_drv && ATAMount(blkdev.first_hd_drv_let, BDT_ATA, ata_drv->base0,
|
||||
ata_drv->base1, ata_drv->unit))
|
||||
res++;
|
||||
if (atapi_drv &&
|
||||
ATAMount(blkdev.first_dvd_drv_let, BDT_ATAPI, atapi_drv->base0,
|
||||
atapi_drv->base1, atapi_drv->unit))
|
||||
res++;
|
||||
tmpha = head;
|
||||
while (tmpha) {
|
||||
if (tmpha != ata_drv && tmpha != atapi_drv) {
|
||||
if (tmpha->type == BDT_ATA &&
|
||||
ATAMount(blkdev.first_hd_drv_let, BDT_ATA, tmpha->base0, tmpha->base1,
|
||||
tmpha->unit))
|
||||
res++;
|
||||
else if (tmpha->type == BDT_ATAPI &&
|
||||
ATAMount(blkdev.first_dvd_drv_let, BDT_ATAPI, tmpha->base0,
|
||||
tmpha->base1, tmpha->unit))
|
||||
res++;
|
||||
}
|
||||
tmpha = tmpha->next;
|
||||
}
|
||||
LinkedLstDel(head);
|
||||
blkdev.mount_ide_auto_cnt = res;
|
||||
return res;
|
||||
}
|
238
Src/DskAddDev.HC
Normal file
238
Src/DskAddDev.HC
Normal file
|
@ -0,0 +1,238 @@
|
|||
U0 BlkDevLockFwdingSet(
|
||||
CBlkDev *bd) { // If two blkdevs on same controller, use just one lock
|
||||
CBlkDev *bd1;
|
||||
I64 i;
|
||||
switch (bd->type) {
|
||||
case BDT_RAM:
|
||||
break;
|
||||
case BDT_ISO_FILE_READ:
|
||||
case BDT_ISO_FILE_WRITE:
|
||||
bd->lock_fwding = Let2BlkDev(*bd->file_dsk_name);
|
||||
break;
|
||||
case BDT_ATA:
|
||||
case BDT_ATAPI:
|
||||
for (i = 0; i < BLKDEVS_NUM; i++) {
|
||||
bd1 = &blkdev.blkdevs[i];
|
||||
if (bd1->bd_signature == BD_SIGNATURE_VAL && bd != bd1 &&
|
||||
(bd1->type == BDT_ATAPI || bd1->type == BDT_ATA) &&
|
||||
bd1->base0 == bd->base0) {
|
||||
bd->lock_fwding = bd1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
I64 BlkDevAdd(
|
||||
CBlkDev *bd, I64 prt_num = I64_MIN, Bool whole_drv,
|
||||
Bool make_free) { // It will mount just one partition of prt_num>=0.
|
||||
// When repartitioing whole drive, whole_drv=TRUE.
|
||||
I64 i, j, ext_base, offset, res = 0, num = 0;
|
||||
CDrv *dv;
|
||||
CRedSeaBoot br;
|
||||
CMasterBoot mbr;
|
||||
|
||||
bd->bd_signature = BD_SIGNATURE_VAL;
|
||||
if (make_free)
|
||||
dv = DrvMakeFreeSlot(bd->first_drv_let);
|
||||
else
|
||||
dv = DrvMakeFreeSlot(DrvNextFreeLet(bd->first_drv_let));
|
||||
dv->bd = bd;
|
||||
dv->drv_offset = bd->drv_offset;
|
||||
dv->size = bd->max_blk + 1 - bd->drv_offset;
|
||||
switch (bd->type) {
|
||||
case BDT_RAM:
|
||||
case BDT_ISO_FILE_READ:
|
||||
case BDT_ISO_FILE_WRITE:
|
||||
dv->dv_signature = DRV_SIGNATURE_VAL;
|
||||
dv->prt_num = num;
|
||||
dv->fs_type = FSt_REDSEA;
|
||||
// This is to force creation of a RAM
|
||||
// drive during boot, so it is probably
|
||||
// MAlloced to the same addr and can
|
||||
// be assumed to be already formatted.
|
||||
// If this line is removed, RAM Drives
|
||||
// will be alloced on a just-in-time
|
||||
// basis.
|
||||
if (BlkDevInit(bd))
|
||||
res++;
|
||||
else
|
||||
dv->dv_signature = 0;
|
||||
break;
|
||||
case BDT_ATA:
|
||||
dv->dv_signature = DRV_SIGNATURE_VAL; // Temporarily validate
|
||||
if (!BlkDevInit(bd))
|
||||
dv->dv_signature = 0; // Revoke validation
|
||||
else {
|
||||
dv->dv_signature = 0; // Revoke validation
|
||||
if (whole_drv) {
|
||||
dv->dv_signature = DRV_SIGNATURE_VAL;
|
||||
dv->prt_num = num;
|
||||
res++;
|
||||
dv->fs_type = FSt_REDSEA;
|
||||
dv->size = bd->max_blk + 1 - bd->drv_offset;
|
||||
// The following read is a test read.
|
||||
// if it hangs, the drive is not supported.
|
||||
ATAReadBlks(bd, &mbr, 0, 1);
|
||||
break;
|
||||
}
|
||||
offset = 0;
|
||||
ext_base = INVALID_CLUS;
|
||||
while (prt_num < 0 || num <= prt_num) {
|
||||
ATAReadBlks(bd, &mbr, offset, 1);
|
||||
if (mbr.signature != 0xAA55)
|
||||
break;
|
||||
j = -1;
|
||||
for (i = 0; i < 4 && (prt_num < 0 || num <= prt_num); i++) {
|
||||
if (mbr.p[i].type) {
|
||||
if (make_free)
|
||||
dv = DrvMakeFreeSlot(bd->first_drv_let + res);
|
||||
else
|
||||
dv = DrvMakeFreeSlot(DrvNextFreeLet(bd->first_drv_let + res));
|
||||
dv->bd = bd;
|
||||
dv->drv_offset = mbr.p[i].offset + offset;
|
||||
dv->size = mbr.p[i].size;
|
||||
switch (mbr.p[i].type) {
|
||||
case MBR_PT_REDSEA:
|
||||
dv->dv_signature = DRV_SIGNATURE_VAL;
|
||||
dv->prt_num = num;
|
||||
res++;
|
||||
dv->fs_type = FSt_REDSEA;
|
||||
RedSeaInit(dv);
|
||||
break;
|
||||
case MBR_PT_FAT32a:
|
||||
case MBR_PT_FAT32b:
|
||||
case MBR_PT_FAT32c:
|
||||
case MBR_PT_FAT32d:
|
||||
case MBR_PT_FAT32e:
|
||||
case MBR_PT_FAT32f:
|
||||
ATAReadBlks(bd, &br, dv->drv_offset, 1);
|
||||
dv->dv_signature = DRV_SIGNATURE_VAL;
|
||||
dv->prt_num = num;
|
||||
res++;
|
||||
if (br.signature == MBR_PT_REDSEA) {
|
||||
dv->fs_type = FSt_REDSEA;
|
||||
RedSeaInit(dv);
|
||||
} else {
|
||||
dv->fs_type = FSt_FAT32;
|
||||
FAT32Init(dv);
|
||||
}
|
||||
break;
|
||||
case MBR_PT_NTFS:
|
||||
dv->dv_signature = DRV_SIGNATURE_VAL;
|
||||
dv->prt_num = num;
|
||||
res++;
|
||||
dv->fs_type = FSt_NTFS;
|
||||
break;
|
||||
case 5:
|
||||
case 15:
|
||||
j = i;
|
||||
break;
|
||||
default:
|
||||
dv->dv_signature = DRV_SIGNATURE_VAL;
|
||||
dv->prt_num = num;
|
||||
res++;
|
||||
dv->fs_type = FSt_UNKNOWN;
|
||||
}
|
||||
num++;
|
||||
}
|
||||
}
|
||||
if (Let2BlkDevType(bd->first_drv_let + res) != bd->type)
|
||||
break;
|
||||
if (j < 0)
|
||||
break;
|
||||
if (!mbr.p[j].offset)
|
||||
break;
|
||||
if (ext_base == INVALID_CLUS) {
|
||||
offset = mbr.p[j].offset;
|
||||
ext_base = offset;
|
||||
} else
|
||||
offset = mbr.p[j].offset + ext_base;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BDT_ATAPI:
|
||||
dv->dv_signature = DRV_SIGNATURE_VAL;
|
||||
dv->prt_num = num;
|
||||
res++;
|
||||
dv->fs_type = FSt_ISO9660; // Start with this
|
||||
dv->size = 0;
|
||||
break;
|
||||
}
|
||||
if (res)
|
||||
BlkDevLockFwdingSet(bd);
|
||||
else
|
||||
BlkDevDel(bd);
|
||||
return res;
|
||||
}
|
||||
|
||||
Bool DrvEnable(
|
||||
U8 drv_let,
|
||||
Bool val) { // Can unmount or remount, but not mount the first time.
|
||||
CDrv *dv;
|
||||
if (dv = Let2Drv(drv_let, FALSE))
|
||||
return !LBEqu(&dv->fs_type, FStf_DISABLE, !val);
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
I64 SysGetI64() {
|
||||
U8 st[STR_LEN];
|
||||
GetS(st, STR_LEN, FALSE);
|
||||
return Str2I64(st, 16);
|
||||
}
|
||||
|
||||
Bool GetBaseUnit(CBlkDev *bd) {
|
||||
I64 ch;
|
||||
Bool probe;
|
||||
#exe {
|
||||
if (kernel_cfg->opts[CFG_DONT_PROBE])
|
||||
StreamPrint("probe=FALSE;");
|
||||
else
|
||||
StreamPrint("probe=TRUE;");
|
||||
};
|
||||
if (!probe || !BootDVDProbeAll(bd)) {
|
||||
"\nDon't worry. This is not a product\n"
|
||||
"registration. TempleOS just needs the\n"
|
||||
"I/O port numbers for the CD/DVD.\n"
|
||||
"\nRetry the ports above or check Windows\n"
|
||||
"system information under I/O ports for\n"
|
||||
"'IDE', 'ATA' or 'SATA'.\n"
|
||||
"In Linux, use 'lspci -v' for ports.\n"
|
||||
"\n\nEnter 4-digit hex I/O Port number.\n"
|
||||
"CD/DVD I/O Port Base0: 0x";
|
||||
bd->base0 = SysGetI64;
|
||||
bd->base1 = 0;
|
||||
bd->unit = 0;
|
||||
if (bd->base0) {
|
||||
"\nUnit (0 or 1): ";
|
||||
do
|
||||
ch = GetChar(, FALSE);
|
||||
while (!('0' <= ch <= '1'));
|
||||
'' ch;
|
||||
bd->unit = ch - '0';
|
||||
blkdev.dvd_boot_is_good = BootDVDProbe(bd);
|
||||
return TRUE;
|
||||
} else {
|
||||
blkdev.dvd_boot_is_good = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
U0 BlkDevsInitAll() {
|
||||
CBlkDev *bd;
|
||||
I64 i;
|
||||
blkdev.blkdevs = CAlloc(sizeof(CBlkDev) * BLKDEVS_NUM);
|
||||
blkdev.drvs = CAlloc(sizeof(CDrv) * DRVS_NUM);
|
||||
for (i = 0; i < DRVS_NUM; i++)
|
||||
blkdev.let_to_drv[i] = &blkdev.drvs[i];
|
||||
#exe {
|
||||
StreamPrint("MountIDEAuto;");
|
||||
StreamPrint("#exe {Option(OPTf_WARN_PAREN,OFF);}");
|
||||
StreamDoc(kernel_cfg->add_dev);
|
||||
StreamPrint("#exe {Option(OPTf_WARN_PAREN,ON);}");
|
||||
};
|
||||
}
|
238
Src/KMain.HC
Normal file
238
Src/KMain.HC
Normal file
|
@ -0,0 +1,238 @@
|
|||
U0 SysGlblsInit() {
|
||||
I64 i, j;
|
||||
CRAXRBCRCXRDX ee;
|
||||
|
||||
CPUId(0x1, &ee);
|
||||
sys_cache_line_width = ee.rbx.u8[1] * 8;
|
||||
|
||||
sys_focus_task = Fs;
|
||||
QueInit(&sys_macro_head);
|
||||
|
||||
blkdev.dft_iso_filename = AStrNew(DFT_ISO_FILENAME);
|
||||
blkdev.dft_iso_c_filename = AStrNew(DFT_ISO_C_FILENAME);
|
||||
blkdev.tmp_filename = AStrNew("~/Tmp.DD.Z");
|
||||
blkdev.dvd_boot_is_good = TRUE;
|
||||
#exe {
|
||||
if (!kernel_cfg->mount_ide_auto_hd_let)
|
||||
kernel_cfg->mount_ide_auto_hd_let = 'C';
|
||||
if (!kernel_cfg->mount_ide_auto_cd_let)
|
||||
kernel_cfg->mount_ide_auto_cd_let = 'T';
|
||||
StreamPrint("blkdev.first_hd_drv_let=%d;", kernel_cfg->mount_ide_auto_hd_let);
|
||||
StreamPrint("blkdev.first_dvd_drv_let=%d;",
|
||||
kernel_cfg->mount_ide_auto_cd_let);
|
||||
}
|
||||
|
||||
DbgMode(ON);
|
||||
rev_bits_table = CAlloc(256);
|
||||
set_bits_table = CAlloc(256);
|
||||
for (i = 0; i < 256; i++)
|
||||
for (j = 0; j < 8; j++) {
|
||||
if (Bt(&i, 7 - j))
|
||||
LBts(rev_bits_table + i, j);
|
||||
if (Bt(&i, j))
|
||||
set_bits_table[i]++;
|
||||
}
|
||||
|
||||
ext = CAlloc(EXT_EXTS_NUM * sizeof(U8 *));
|
||||
fp_getstr2 = &SysGetStr2;
|
||||
KeyDevInit;
|
||||
|
||||
#exe {
|
||||
StreamPrint("blkdev.boot_drv_let='%C';", kernel_cfg->boot_drv_let);
|
||||
StreamPrint("#exe{Option(OPTf_WARN_PAREN,OFF);}");
|
||||
StreamPrint("DskCacheInit(%s);", kernel_cfg->dsk_cache_size_exp);
|
||||
StreamPrint("#exe{Option(OPTf_WARN_PAREN,ON);}");
|
||||
}
|
||||
;
|
||||
|
||||
pow10_I64 = CAlloc(sizeof(F64) * (308 + 308 + 1));
|
||||
for (i = -308; i < 309; i++)
|
||||
pow10_I64[i + 309] = Pow10(i);
|
||||
|
||||
QueInit(&scrncast.snd_head);
|
||||
scrncast.t0_now = Now;
|
||||
scrncast.t0_tS = tS;
|
||||
scrncast.ona = scrncast.snd_head.ona = 0;
|
||||
|
||||
ProgressBarsRst;
|
||||
|
||||
QueInit(&dev.pci_head);
|
||||
dev.mem64_ptr = mem_mapped_space;
|
||||
|
||||
dbg.fun_seg_cache = CAlloc(FUN_SEG_CACHE_SIZE * sizeof(CFunSegCache));
|
||||
dbg.int_fault_code = IntFaultHndlrsNew;
|
||||
}
|
||||
|
||||
U0 SysGrInit() {
|
||||
text.font = sys_font_std;
|
||||
text.aux_font = sys_font_cyrillic;
|
||||
text.vga_alias = dev.uncached_alias + VGAM_GRAPHICS;
|
||||
text.vga_text_alias = dev.uncached_alias + VGAM_TEXT;
|
||||
if (!Bt(&sys_run_level, RLf_VGA)) { // if text mode
|
||||
text.cols = 80;
|
||||
text.rows = 25;
|
||||
MemSet(text.vga_text_alias, 0, text.rows * text.cols << 1);
|
||||
text.border_chars[2](I64) = '<EFBFBD>ͳ<EFBFBD><EFBFBD>ɿ<EFBFBD>';
|
||||
text.border_chars[10](U32) = '<EFBFBD><EFBFBD>ټ';
|
||||
} else { // if 640x480 16 color
|
||||
text.cols = GR_WIDTH / FONT_WIDTH;
|
||||
text.rows = GR_HEIGHT / FONT_HEIGHT;
|
||||
OutU8(VGAP_IDX, VGAR_MAP_MASK);
|
||||
OutU8(VGAP_DATA, 0x0F);
|
||||
MemSet(text.vga_alias, 0, GR_WIDTH * GR_HEIGHT >> 3);
|
||||
text.raw_scrn_image = CAlloc(GR_WIDTH * GR_HEIGHT / 8);
|
||||
text.border_chars[2](I64) = 0x0908070605040302;
|
||||
text.border_chars[10](U32) = 0x0D0C0B0A;
|
||||
}
|
||||
}
|
||||
|
||||
U0 TimersInit() {
|
||||
I64 i, *_q;
|
||||
U32 *_d;
|
||||
|
||||
OutU8(0x43, 0x34);
|
||||
OutU8(0x40, SYS_TIMER0_PERIOD);
|
||||
OutU8(0x40, SYS_TIMER0_PERIOD >> 8);
|
||||
|
||||
// High Precision Event Timer
|
||||
if (PCIReadU16(0, 31, 0, 0) == 0x8086) { // Intel?
|
||||
// D31 F0, cfg 0xF0=RCBA of PCI-LPC Bridge
|
||||
_d = PCIReadU32(0, 31, 0, 0xF0)(U8 *) & ~0x3FFF + 0x3404; // HPET cfg
|
||||
// 7 enable
|
||||
// 1:0 HPET is at 0xFED00000,0xFED01000, 0xFED02000 or 0xFED03000.
|
||||
*_d = *_d & 3 | 0x80;
|
||||
}
|
||||
|
||||
_q = dev.uncached_alias + HPET_GCAP_ID;
|
||||
i = *_q; // i.u32[1]= period in femtoS (10e-15)
|
||||
if (100000 < i.u32[1] < 1000000000) {
|
||||
cnts.HPET_freq = 1000000000000000 / i.u32[1];
|
||||
cnts.HPET_kHz_freq = 1000000000000 / i.u32[1];
|
||||
_q = dev.uncached_alias + HPET_GEN_CONF;
|
||||
*_q |= 1; // Enable counting
|
||||
cnts.HPET_initial = HPET;
|
||||
} else {
|
||||
cnts.HPET_freq = 0;
|
||||
cnts.HPET_kHz_freq = 0;
|
||||
cnts.HPET_initial = 0;
|
||||
}
|
||||
}
|
||||
|
||||
U0 Reboot() { // Hardware reset.
|
||||
CLI if (mp_cnt > 1) MPHalt;
|
||||
*0x472(U16 *) = 0;
|
||||
OutU8(0x70, 0x8F);
|
||||
OutU8(0x71, 0x00);
|
||||
OutU8(0x70, 0x00);
|
||||
OutU8(0x92, InU8(0x92) | 1);
|
||||
SysHlt;
|
||||
}
|
||||
|
||||
U0 KMain() { // Continued from $LK,"KStart64.HC",A="FF:::/Kernel/KStart64.HC,I32
|
||||
// &KMain"$
|
||||
CBlkDev *bd;
|
||||
OutU8(0x61, InU8(0x61) & ~3); // Snd;
|
||||
adam_task = Fs;
|
||||
BlkPoolsInit;
|
||||
SysGlblsInit;
|
||||
Mem32DevInit;
|
||||
UncachedAliasAlloc;
|
||||
LoadKernel;
|
||||
SysGrInit;
|
||||
StrCpy(Fs->task_name, "Adam Task CPU00");
|
||||
StrCpy(Fs->task_title, Fs->task_name);
|
||||
Fs->title_src = TTS_TASK_NAME;
|
||||
Fs->win_right = text.cols - 2;
|
||||
Fs->win_top++;
|
||||
TaskDerivedValsUpdate;
|
||||
|
||||
SysDefinesLoad;
|
||||
Core0Init;
|
||||
IntInit1;
|
||||
|
||||
// Before this point use $LK,"Snd",A="MN:Snd"$() and $LK,"Busy",A="MN:Busy"$()
|
||||
// to debug.After this point, use $LK,"RawPrint",A="MN:RawPrint"$()
|
||||
LBts(&sys_run_level, RLf_RAW);
|
||||
"TempleOS V%5.3f\t%D %T\n\n", sys_os_version, sys_compile_time,
|
||||
sys_compile_time;
|
||||
|
||||
TimersInit;
|
||||
if (BIOSTotalMem < ToI64(0.95 * MEM_MIN_MEG * 0x100000))
|
||||
RawPrint(4000, "!!! Requires $TX," 512Meg ",D=" DD_MEM_MIN_MEG
|
||||
"$ of RAM Memory !!!");
|
||||
|
||||
IntsInit;
|
||||
"Enable IRQ's\n";
|
||||
SetRFlags(RFLAGG_NORMAL);
|
||||
Busy(2000);
|
||||
IntInit2;
|
||||
LBts(&sys_run_level, RLf_INTERRUPTS);
|
||||
|
||||
TimeCal;
|
||||
|
||||
KbdMsInit;
|
||||
MsInit;
|
||||
KbdInit;
|
||||
Spawn(&MsHardDrvrInstall);
|
||||
|
||||
BlkDevsInitAll;
|
||||
"DskChg(':');\n";
|
||||
DskChg(':');
|
||||
#exe {
|
||||
StreamPrint("HomeSet(\"%s\");\n"
|
||||
"blkdev.ins_base0=%d;blkdev.ins_base1=%d;blkdev.ins_unit =%d;\n",
|
||||
kernel_cfg->home_dir, blkdev.ins_base0, blkdev.ins_base1,
|
||||
blkdev.ins_unit);
|
||||
}
|
||||
Gs->idle_task->cur_dv = blkdev.let_to_drv[*blkdev.home_dir - 'A'];
|
||||
DrvRep;
|
||||
if (blkdev.dvd_boot_is_good) {
|
||||
bd = Let2BlkDev(':');
|
||||
if (bd->type == BDT_ATAPI) {
|
||||
blkdev.ins_base0 = bd->base0;
|
||||
blkdev.ins_base1 = bd->base1;
|
||||
blkdev.ins_unit = bd->unit;
|
||||
}
|
||||
}
|
||||
LBts(&sys_run_level, RLf_BLKDEV);
|
||||
|
||||
#exe {
|
||||
if (!kernel_cfg->opts[CFG_NO_MP])
|
||||
StreamPrint("\"MultiCore Start\\n\\n\";"
|
||||
"Core0StartMP;"
|
||||
"LBts(&sys_run_level,RLf_MP);");
|
||||
}
|
||||
;
|
||||
|
||||
"Loading Compiler\n";
|
||||
Cd("/Compiler");
|
||||
Load("Compiler", LDF_SILENT);
|
||||
LBts(&sys_run_level, RLf_COMPILER);
|
||||
|
||||
DbgMode(OFF);
|
||||
cnts.time_stamp_freq_initial = TimeCal;
|
||||
Cd("/");
|
||||
try ExeFile("StartOS"); // Continues $LK,"/StartOS.HC",A="FL:/StartOS.HC,1"$
|
||||
catch {
|
||||
Raw(ON);
|
||||
Silent(OFF);
|
||||
GetOutOfDollar;
|
||||
PutExcept;
|
||||
Dbg;
|
||||
}
|
||||
|
||||
LBts(&sys_run_level, RLf_ADAM_SERVER);
|
||||
SrvTaskCont; // Never to return
|
||||
}
|
||||
|
||||
asm { ALIGN 16,OC_NOP
|
||||
SYS_KERNEL_END::
|
||||
#exe {
|
||||
if (kernel_cfg->opts[CFG_DBG_DISTRO])
|
||||
StreamPrint("DU8 0x%X-(SYS_KERNEL_END-SYS_KERNEL+"
|
||||
"BOOT_RAM_BASE+sizeof(CBinFile)) DUP (0);"
|
||||
"BINFILE \"%s\";",kernel_cfg->dbg_distro_start,
|
||||
kernel_cfg->dbg_distro_file);
|
||||
}
|
||||
;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue