Trivial Solutions
                    The LoseThos 64-bit PC Operating System
File:/LT/OSMain/Dsk/Dsk1c.CPZ
This, and all LoseThos files, are public domain.  Do whatever you like.
God is watching; God is just; God is never out-done in generosity.  He talks!

LoseThos code compiles with the 64-bit LoseThos compiler/assembler I wrote.
Boot the LoseThos CD and you can compile it.  Not in Kansas anymore!

Click here for preliminary compiler information you need.

Project: OSMain
U0 DrvDftSelect()
{
  dft_prt=Drv2Prt(dft_drv);
  Fs->cur_prt=INVALID_PTR;  //Null screws-up cache
  Fs->cur_dir=StrNew("/");
  ChgDsk(':');
}

BoolI64 CopySingleZ(U8 *f1,U8 *f2) //Just one file
{
  U8 *file_buf=NULL;
  U64 size,attr=0,c;
  LTDirEntry de;
 
  if (FileFind(f1,&de,FALSE,TRUE)) {
    file_buf=FileRead(f1,&size,&attr);
    attr=FileAttr(f2,attr);
    if (file_buf) {
      PutS("Copying ");
      PutS(f1);
      PutS(" to ");
      PutS(f2);
      CrLf;
      c=FileWrite(f2,file_buf,size,de.datetime,attr);
      Free(file_buf);
      return ToBool(c);
    } else PutDefineErr("ST_FILE_NOT_FOUND");
  } else PutDefineErr("ST_FILE_NOT_FOUND");
  return FALSE;
}

#define COPY_BUF_BLKS   0x80
BoolI64 CopySingle(U8 *f1,U8 *f2) //Just one file
{
  U8 *absf1=FileNameAbs(f1),
     *absf2=FileNameAbs(f2);
  U8 *buf;
  U64 cnt,n,size,attr1=FileAttr(f1),attr2=FileAttr(f2);
  LTFile *in_file=NULL,*out_file=NULL;
  U64 xsum=LT_XSUM,i,j;
  if (!StrCmp(absf1,absf2)) {
    Free(absf1);
    Free(absf2);
    return FALSE;
  }
  Free(absf1);
  Free(absf2);
  if (attr1!=attr2)
    return CopySingleZ(f1,f2);
  buf=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS);
  if (attr1 & LT_ATTR_CONTIGUOUS)
    in_file=FOpen(f1,"rc");
  else
    in_file=FOpen(f1,"r");
  if (in_file) {
    size=FSize(in_file);
    cnt=(size+BLK_SIZE-1)>>BLK_SIZE_BITS;
    if (attr2 & LT_ATTR_CONTIGUOUS)
      out_file=FOpen(f2,"wc",cnt);
    else
      out_file=FOpen(f2,"w",cnt);
    if (out_file) {
      PutS("Copying ");
      PutS(f1);
      PutS(" to ");
      PutS(f2);
      CrLf;
      j=size;
      while (cnt) {
        if (cnt>COPY_BUF_BLKS) {
          n=COPY_BUF_BLKS;
          i=n<<BLK_SIZE_BITS;
        } else {
          n=cnt;
          i=j;
        }
        FRBlks(in_file, buf,LTFB_NEXT_BLK,n);
        xsum^=ArcXSum(buf,i);
        FWBlks(out_file,buf,LTFB_NEXT_BLK,n);
        cnt-=n;
        j-=n<<BLK_SIZE_BITS;
      }
      if (in_file->de.xsum &&
          in_file->de.xsum!=xsum)
        throw(EXCEPT_ARC_XSUM);
      out_file->de.xsum=xsum;
      out_file->flags|=LTF_USE_OLD_DATETIME;
      out_file->de.datetime=in_file->de.datetime;
      out_file->de.size=size;
      out_file->de.expanded_size=in_file->de.expanded_size;
      out_file->de.attr=FileAttr(f2,in_file->de.attr);
      FClose(out_file);
      FClose(in_file);
      Free(buf);
      return TRUE;
    } else PutDefineErr("ST_FILE_NOT_FOUND");
    FClose(in_file);
  } else PutDefineErr("ST_FILE_NOT_FOUND");
  Free(buf);
  return FALSE;
}

BoolI64 MkDir(U8 *filename)
{
  BoolI8 result=FALSE;
  U8 *name;
  if (FileFind(filename,NULL,TRUE))
    return FALSE;
  LTFileAccess *fa=LTFileAccessNew(filename);
  if (fa) {
    if (*fa->mask) {
      if (!FileNameChk(fa->mask))
        PutDefineErr("ST_INVALID_FILENAME");
      else {
        PutS("Make Directory:");
        PutS(filename);
        CrLf;
        name=MStrUtil(fa->mask,
        SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
        switch (fa->p->type) {
          case PT_LT:
            result=LTFSMkDir(fa->p,Fs->cur_dir,name);
            break;
          case PT_FAT32:
            result=FAT32MkDir(fa->p,Fs->cur_dir,name);
            break;
          case PT_ISO9660:
            PutDefineErr("ST_NOT_WRITABLE");
            break;
          default:
            PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM");
        }
        Free(name);
      }
    }
    LTFileAccessDel(fa);
  }
  return result;
}

U0 SysDel(U8 *wild,BoolI8 make_mask)    //this is dangerous
{
  LTFileAccess *fa=LTFileAccessNew(wild,make_mask);
  if (fa) {
    switch (fa->p->type) {
      case PT_LT:
        LTFSFilesDel(fa->p,Fs->cur_dir,fa->mask,0,TRUE,TRUE);
        break;
      case PT_FAT32:
        FAT32FilesDel(fa->p,Fs->cur_dir,fa->mask,0,TRUE,TRUE);
        break;
      case PT_ISO9660:
        PutDefineErr("ST_NOT_WRITABLE");
        break;
      default:
        PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM");
    }
    LTFileAccessDel(fa);
  }
}

U0 Fmt(I64 drv_let,BoolI8 quick=TRUE,BoolI8 confirm=TRUE,U64 type=PT_FAT32)
{//See PT_FAT32 for a list of supported file system types.

  LTPrt *p=Drv2Prt(drv_let);
  BoolI8 old_silent=IsSilent;
  if (confirm) {
    if (!AreYouSure)
      return;
  }
  if (!p)  {
    PutDefineErr("ST_INVALID_DRV");
    return;
  }
  switch (type) {
    case PT_LT:
      Silent(ON);
      Drv(drv_let);
      Silent(old_silent);
      LTFSFmt(drv_let,quick);
      DskCacheInvalidate(Drv2Prt(drv_let));
      Drv(drv_let);
      break;
    case PT_FAT32:
      Silent(ON);
      Drv(drv_let);
      Silent(old_silent);
      FAT32Fmt(drv_let,quick);
      DskCacheInvalidate(Drv2Prt(drv_let));
      Drv(drv_let);
      break;
    case PT_ISO9660:
      PutDefineErr("ST_NOT_WRITABLE");
      break;
    default:
      PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM");
  }
}


U0 CDImageRead(U8 cd_drv_let,U8 *out_name)
{
  LTBlkDev *bdev=Drv2BlkDev(cd_drv_let);
  LTPrt *p=Drv2Prt(cd_drv_let);
  U8 *buf=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS);
  U8 *out_name2=DftExt(out_name,"ISO");
  LTFile *f=FOpen(out_name2,"w");
  U64 n,spc=bdev->blk_size>>BLK_SIZE_BITS,blk=0,cnt,retry;
  BlkDevInit(bdev);
  if (bdev->type!=LTBDT_ATAPI)
    throw(EXCEPT_BLKDEV,3);
  if (!out_name)
    out_name=sys_dft_iso_name;
  cnt=CeilU64(p->size,spc);
  while (cnt) {
    if (cnt>COPY_BUF_BLKS)
      n=COPY_BUF_BLKS;
    else
      n=cnt;
    if (n>bdev->max_reads)
      n=bdev->max_reads;
    if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SND],0))
      Snd(bdev->read_freq);

    retry=4;
    while (--retry)
      if (ATAPIReadBlks2(bdev,buf,blk/spc,n/spc,TRUE,
        //n is 0x800 if max_reads.  Up to 8 additional seconds
        BootTime+7*LTDATE_FREQ+n/spc*LTDATE_FREQ/0x100))
        break;

    if (!retry)
      ATAPIReadBlks2(bdev,buf,blk/spc,n/spc,TRUE,0);

    if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SND],0))
      Snd(0);
    FWBlks(f,buf,blk,n);
    cnt-=n;
    blk+=n;
  }
  FClose(f);
  Free(buf);
  Free(out_name2);
}

class LTDualBuf
{
  U8 *buf0,*buf1;
  U64 in_buf,out_buf,cnt;
  U8 *filename;
  LTBlkDev *CD_bdev;
};


U0 CDImageWriteTask(LTDualBuf *d)
{
  U8 *buf;
  U64 n,blk=0,cnt=d->cnt;
  LTFile *f;
  Preempt(ON);
  TaskLocalInit; //needed for disk access
  if (FileAttr(d->filename)&LT_ATTR_CONTIGUOUS)
    f=FOpen(d->filename,"rc");
  else
    f=FOpen(d->filename,"r");
  while (cnt) {
    if (cnt>COPY_BUF_BLKS)
      n=COPY_BUF_BLKS;
    else
      n=cnt;
    if (n>d->CD_bdev->max_writes)
      n=d->CD_bdev->max_writes;
    buf=d->in_buf&1 ? d->buf1:d->buf0;
    while (d->in_buf>d->out_buf+1)
      Yield;
    FRBlks(f,buf,blk,n);
    if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SND],0))
      Snd(d->CD_bdev->write_freq);
    d->in_buf++;
    cnt-=n;
    blk+=n;
  }
  FClose(f);
}

U0 CDImageWrite(U8 cd_drv_let,U8 *in_name=NULL,I64 media_type=MT_CD)
{
  LTDualBuf *d=CAlloc(sizeof(LTDualBuf));
  U8 *buf;
  U8 *in_name2,*in_name3;
  U64 i,n,spc,blk=0,cnt;
  LTPrt *p=Drv2Prt(cd_drv_let);
  LTBlkDev *bdev=p->bdev,*bdev2;
  TaskStruct *task;
  BoolI8 old_preempt;
  LTFile *f;

  if (!in_name)
    in_name=sys_dft_iso_name;
  in_name3=DftExt(in_name,"ISO");
  in_name2=FileNameAbs(in_name3);
  f=FOpen(in_name2,"r");
  if (!f) {
    Free(d);
    return;
  }

  cnt=(FSize(f)+BLK_SIZE-1)>>BLK_SIZE_BITS;
  FClose(f);
  if (bdev->type!=LTBDT_ATAPI)
    throw(EXCEPT_BLKDEV,4);
  bdev2=Drv2BlkDev(*in_name2);
  while (bdev2->lock_forwarding)
    bdev2=bdev2->lock_forwarding;
  if ((bdev2->type==LTBDT_ATA || bdev2->type==LTBDT_ATAPI) &&
       bdev2->base0==bdev->base0) {
    PutS("Can't Burn CD on same ATA ctrller as File.\r\n\r\n");
    throw(EXCEPT_BLKDEV,5);
  }

  bdev->flags|=LTBDF_READ_ONLY_OVERRIDE;
  BlkDevInit(bdev);
  spc=bdev->blk_size>>BLK_SIZE_BITS;
  if (p->size<cnt)
    p->size=cnt;

  d->filename=in_name2;
  d->CD_bdev=bdev;
  d->buf0=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS);
  d->buf1=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS);
  d->cnt=cnt;

  old_preempt=Preempt(OFF);
  task=Spawn(&CDImageWriteTask,d,"Write CD");

  while (d->in_buf<=d->out_buf)
    Yield;

  if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SND],0))
    Snd(bdev->write_freq);
  BlkDevLock(bdev);
  ATAPIWaitReady(bdev,0);

  progress1=0; progress1_max=cnt;
  StrCpy(progress1_desc,"Writing");
  while (cnt) {
    if (cnt>COPY_BUF_BLKS)
      n=COPY_BUF_BLKS;
    else
      n=cnt;
    if (n>bdev->max_writes)
      n=bdev->max_writes;
    buf=d->out_buf&1 ? d->buf1:d->buf0;
    while (d->in_buf<=d->out_buf)
      Yield;
    ATAPIWriteBlks(bdev,buf,blk/spc,(n+spc-1)/spc);
    d->out_buf++;
    cnt-=n;
    blk+=n;
    progress1+=n;
  }
  ATAPISync(bdev);

  progress1=0; progress1_max=2;
  StrCpy(progress1_desc,"Closing");
  for (i=0;i<2;i++) {
    ATAPIClose(bdev,0x100,i); //Close tracks
    progress1++;
  }

  ATAPISync(bdev);

  ATAPIClose(bdev,0x200); //close disk
  ATAPISync(bdev);
  if (media_type==MT_DVD) {
    ATAPIClose(bdev,0x300);
    ATAPISync(bdev);
  }

  *progress1_desc=0;
  progress1=progress1_max=0;

  if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SND],0))
    Snd(0);
  bdev->flags&=~LTBDF_READ_ONLY_OVERRIDE;
  BlkDevUnlock(bdev);
  Free(d->buf0);
  Free(d->buf1);
  Free(in_name2);
  Free(in_name3);
  Preempt(old_preempt);
  Free(d);
}

Historical capture: 2011-10-22. Home | Power on LoseThos | Sources and changes