TempleOSCDV4.08.ISO
This commit is contained in:
1 parent
b632ab9a4f
commit
2d56cda5f3
258 files changed
+6973
-5476
No files matched your search
@@ -0,0 +1,186 @@
|
||||
#help_index "File/CD DVD"
|
||||
|
||||
U0 FillU16Palindrome(CPalindromeU16 *dst,U16 w)
|
||||
{
|
||||
dst->big=EndianU16(w);
|
||||
dst->little=w;
|
||||
}
|
||||
|
||||
U0 FillU32Palindrome(CPalindromeU32 *dst,I64 d)
|
||||
{
|
||||
dst->big=EndianU32(d);
|
||||
dst->little=d;
|
||||
}
|
||||
|
||||
class CElTorito
|
||||
{
|
||||
U16 w[16];
|
||||
U8 bootable; //88=bootable 00=not bootable
|
||||
U8 media_type; //0=no emulation 4=hard disk
|
||||
U16 load_seg; //0000->07C0
|
||||
U8 sys_type;
|
||||
U8 zero;
|
||||
U16 sect_cnt;
|
||||
U32 load_rba; //start addr of virtual disk
|
||||
U8 zero2[20];
|
||||
};
|
||||
|
||||
U0 RedSeaISO9660(U8 *iso_filename,U8 drv_let,I64 stage2_blk=0,I64 stage2_size=0)
|
||||
{
|
||||
CDrv *dv=Let2Drv(drv_let);
|
||||
CISO1PriDesc *iso_pri=CAlloc(DVD_BLK_SIZE),
|
||||
*iso_boot=CAlloc(DVD_BLK_SIZE),
|
||||
*iso_sup=CAlloc(DVD_BLK_SIZE),
|
||||
*iso_term=CAlloc(DVD_BLK_SIZE);
|
||||
I64 iso_size=0,i,j;
|
||||
U32 *d;
|
||||
CElTorito *et=CAlloc(DVD_BLK_SIZE);
|
||||
U8 *stage1_buf=CAlloc(DVD_BOOT_LOADER_SIZE),
|
||||
*zero_buf=CAlloc(DVD_BLK_SIZE);
|
||||
CFile *out_file=NULL;
|
||||
|
||||
if (out_file=FOpen(iso_filename,"wc+")) {
|
||||
iso_size=FSize(out_file)/DVD_BLK_SIZE;
|
||||
for (i=0;i<dv->bd->drv_offset;i+=4)
|
||||
FWBlks(out_file,zero_buf,i,4);
|
||||
|
||||
iso_pri->type=ISO1T_PRI_VOL_DESC;
|
||||
StrCpy(iso_pri->id,"CD001");
|
||||
iso_pri->version=1;
|
||||
FillU16Palindrome(&iso_pri->vol_set_size,1);
|
||||
FillU16Palindrome(&iso_pri->vol_seq_num,1);
|
||||
FillU16Palindrome(&iso_pri->log_block_size,DVD_BLK_SIZE);
|
||||
FillU32Palindrome(&iso_pri->vol_space_size,iso_size);
|
||||
FillU32Palindrome(&iso_pri->root_dir_record,dv->root_cluster);
|
||||
iso_pri->file_structure_version=1;
|
||||
StrCpy(iso_pri->publisher_id,"TempleOS RedSea");
|
||||
|
||||
MemCpy(iso_sup,iso_pri,DVD_BLK_SIZE);
|
||||
iso_sup->type=ISO1T_SUPPLEMENTARY_DESC;
|
||||
|
||||
iso_boot->type=ISO1T_BOOT_RECORD;
|
||||
StrCpy(iso_boot->id,"CD001");
|
||||
iso_boot->version=1;
|
||||
StrCpy(iso_boot(U8 *)+7,"EL TORITO SPECIFICATION");
|
||||
|
||||
FWBlks(out_file,iso_pri,16<<2,4);
|
||||
iso_term->type=ISO1T_TERMINATOR;
|
||||
StrCpy(iso_term->id,"CD001");
|
||||
iso_term->version=1;
|
||||
if (stage2_blk) {
|
||||
d=iso_boot(U8 *)+0x47;
|
||||
*d=20<<2>>2;
|
||||
FWBlks(out_file,iso_boot,17<<2,4);
|
||||
|
||||
FWBlks(out_file,iso_sup,18<<2,4);
|
||||
FWBlks(out_file,iso_term,19<<2,4);
|
||||
|
||||
et->w[0]=1;
|
||||
StrCpy(&et->w[2],"TempleOS");
|
||||
et->w[15]=0xAA55;
|
||||
j=0;
|
||||
for (i=0;i<16;i++) //Checksum
|
||||
j+=et->w[i];
|
||||
et->w[14]=-j;
|
||||
et->bootable=0x88;
|
||||
et->media_type=0;//0=no emu 2=1.44meg 4=hard drive
|
||||
et->sect_cnt=4; //5 seems like the limit, 4 is safer
|
||||
et->load_rba=20<<2>>2+1;
|
||||
FWBlks(out_file,et,20<<2,4);
|
||||
|
||||
MemCpy(stage1_buf,BDVD_START,BDVD_END-BDVD_START);
|
||||
*(BDVD_BLK_LO -BDVD_START+stage1_buf)(U32 *)=stage2_blk>>2;
|
||||
*(BDVD_BLK_CNT -BDVD_START+stage1_buf)(U16 *)=
|
||||
(stage2_size+DVD_BLK_SIZE-1)>>(BLK_SIZE_BITS+2);
|
||||
*(BDVD_SHIFT_BLKS -BDVD_START+stage1_buf)(U16 *)=stage2_blk&3;
|
||||
if (stage2_blk&3)
|
||||
*(BDVD_BLK_CNT -BDVD_START+stage1_buf)(U16 *)+=1;
|
||||
FWBlks(out_file,stage1_buf,
|
||||
20<<2+1<<2,DVD_BOOT_LOADER_SIZE/BLK_SIZE);
|
||||
} else {
|
||||
FWBlks(out_file,iso_sup,17<<2,4);
|
||||
FWBlks(out_file,iso_term,18<<2,4);
|
||||
}
|
||||
FClose(out_file);
|
||||
}
|
||||
Free(zero_buf);
|
||||
Free(stage1_buf);
|
||||
Free(et);
|
||||
Free(iso_pri);
|
||||
Free(iso_boot);
|
||||
Free(iso_sup);
|
||||
Free(iso_term);
|
||||
}
|
||||
|
||||
I64 RedSeaISOPass1(CDirEntry *tempde)
|
||||
{
|
||||
I64 dir_entry_cnt=3+LinkedLstCnt(tempde),res=0;
|
||||
while (tempde) {
|
||||
if (tempde->attr & RS_ATTR_DIR) {
|
||||
if (tempde->sub)
|
||||
res+=RedSeaISOPass1(tempde->sub);
|
||||
else
|
||||
res+=BLK_SIZE; //Empty dir
|
||||
} else
|
||||
res+=CeilU64(tempde->size,BLK_SIZE);
|
||||
tempde=tempde->next;
|
||||
}
|
||||
res+=CeilU64(dir_entry_cnt<<6,BLK_SIZE); //Size in bytes
|
||||
#assert CDIR_SIZE==64
|
||||
return res;
|
||||
}
|
||||
public I64 RedSeaISO(U8 *_iso_filename=NULL,U8 *_src_dir,
|
||||
U8 *_stage2_filename=NULL)
|
||||
{//See $LK,"::/Misc/DoDistro.CPP"$. Must be ISO.C
|
||||
I64 i,res,root_cnt,root_dir_blks,bitmap_blks,bitmap_blks1;
|
||||
CDirEntry *tempde,de;
|
||||
U8 buf[STR_LEN],*iso_filename,*src_dir,*stage2_filename;
|
||||
CDrv *dv=DrvNextFree('M'); //First $LK,"BDT_FILE",A="MN:BDT_FILE"$
|
||||
CBlkDev *bd=BlkDevNextFree(dv->drv_let,BDT_FILE);
|
||||
|
||||
if (!_iso_filename)
|
||||
_iso_filename=blkdev.dft_iso_filename;
|
||||
iso_filename=ChgExt(_iso_filename,"ISO.C");
|
||||
src_dir=DirNameAbs(_src_dir);
|
||||
if (_stage2_filename) {
|
||||
stage2_filename=FileNameAbs(_stage2_filename);
|
||||
*stage2_filename=dv->drv_let;
|
||||
i=StrLen(src_dir);
|
||||
if (i!=3) //If not root
|
||||
i++; //Skip slash
|
||||
StrCpy(stage2_filename+3,stage2_filename+i);
|
||||
} else
|
||||
stage2_filename=NULL;
|
||||
tempde=FilesFind(src_dir,FUF_RECURSE);
|
||||
root_cnt=LinkedLstCnt(tempde)+3;
|
||||
root_dir_blks=CeilU64(root_cnt<<6,BLK_SIZE)>>BLK_SIZE_BITS;
|
||||
if (res=RedSeaISOPass1(tempde)>>BLK_SIZE_BITS) {
|
||||
bd->drv_offset=19<<2;
|
||||
if (stage2_filename) //preboot and bootloader
|
||||
bd->drv_offset+=(DVD_BLK_SIZE*2+DVD_BOOT_LOADER_SIZE)/BLK_SIZE;
|
||||
|
||||
bitmap_blks=1;
|
||||
do {
|
||||
bitmap_blks1=bitmap_blks;
|
||||
bitmap_blks=(res+bitmap_blks+BLK_SIZE<<3-1)/BLK_SIZE<<3;
|
||||
} while (bitmap_blks!=bitmap_blks1);
|
||||
|
||||
bd->max_blk=CeilI64(bd->drv_offset+1+bitmap_blks+res,4);
|
||||
bd->max_blk--; //Inclusive.
|
||||
bd->file_dsk_name=AStrNew(iso_filename);
|
||||
bd->init_root_dir_blks=root_dir_blks;
|
||||
BlkDevAdd(bd,TRUE,TRUE);
|
||||
StrPrint(buf,"%C:/",dv->drv_let);
|
||||
CopyTree(src_dir,buf,TRUE);
|
||||
if (FileFind(stage2_filename,&de))
|
||||
RedSeaISO9660(iso_filename,dv->drv_let,de.cluster,de.size);
|
||||
else
|
||||
RedSeaISO9660(iso_filename,dv->drv_let);
|
||||
DrvDel(dv);
|
||||
BlkDevDel(bd);
|
||||
}
|
||||
Free(stage2_filename);
|
||||
Free(src_dir);
|
||||
Free(iso_filename);
|
||||
return res;
|
||||
}
|
||||
Reference in new issue
Block a user