#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <bios.h>
#include <time.h>
#include <dir.h>
#include <io.h>
#include "rtos.h"

#define MODE_SAME           0
#define MODE_SEQUENTIAL     1
#define MODE_RANDOM         2

// 64k data buffer for transfer tests
//
static far char buf[65535u];

static char *modename[] = {"same sector", "sequential", "random access" };

void fread_test(FILE *file, long blocksize, long nblocks, int mode)
{
  long ofs, maxofs;
  maxofs = (filelength(fileno(file))-blocksize);

  unsigned long t1, t2, t;
  RTX_Get_System_Ticks(&t1);
  if (blocksize > sizeof(buf))
    blocksize = sizeof(buf);

  printf("  reading %ld blocks of %ld bytes... ", nblocks, blocksize);
  for (int i=0; i<nblocks; i++) {
    if (kbhit())
      break;
    switch(mode) {
      case MODE_SAME:
        fseek(file, 0, SEEK_SET);
        break;
      case MODE_RANDOM:
        ofs = ((long)rand()*1024L) % maxofs;
        fseek(file, ofs, SEEK_SET);
        break;
      case MODE_SEQUENTIAL:
        break;
    }
    fread(buf, (unsigned)blocksize, 1, file);
  }

  RTX_Get_System_Ticks(&t2);

  t = t2-t1;
  unsigned long bps = (blocksize*nblocks*1000)/t;
  printf("%lu ms, %lu kb/s\n", t, bps>>10);
}


void fwrite_test(FILE *file, long blocksize, long nblocks)
{
  unsigned long t1, t2, t;
  RTX_Get_System_Ticks(&t1);
  if (blocksize > sizeof(buf))
    blocksize = sizeof(buf);

  printf("  writing %ld blocks of %ld bytes... ", nblocks, blocksize);
  for (int i=0; i<nblocks; i++) {
    if (kbhit())
      break;
    fwrite(buf, (unsigned)blocksize, 1, file);
  }
  RTX_Get_System_Ticks(&t2);

  t = t2-t1;
  unsigned long bps = (blocksize*nblocks*1000)/t;
  printf("%lu ms, %lu kb/s\n", t, bps>>10);
}



void readtest(char *filename)
{
  FILE *file = fopen(filename, "rb");
  if (!file) {
    perror("readtest: ");
    return;
  }

  long blocksize, nblocks;
  for (int j=0; j<=2; j++) {
    printf("%s read tests -----\n", modename[j]);
    blocksize = 65536L;
    nblocks   = 16;
    for (int i=0; i<8; i++) {
      fseek(file, 0, SEEK_SET);
      fread_test( file, blocksize, nblocks, j );
      blocksize >>= 1;
      nblocks   <<= 1;
    }

  }
  fclose(file);
  printf("done.\n");
}


void writetest(char *filename)
{
  FILE *file = fopen(filename, "wb");
  if (!file) {
    perror("writetest: ");
    return;
  }

  long blocksize, nblocks;

  printf("write tests -----\n");
  blocksize = 65536L;
  nblocks   = 16;
  for (int i=0; i<8; i++) {
    fseek(file, 0, SEEK_SET);
    fwrite_test( file, blocksize, nblocks );
    blocksize >>= 1;
    nblocks   <<= 1;
  }

  fclose(file);
  printf("done.\n");
}


int main(int argc, char *argv[])
{
  printf("IDE speed test v1.0\n");
  printf("using 64k buffer at %p\n", buf);

  writetest("b:\\idespeed.tmp");
  readtest("b:\\idespeed.tmp");
  return 0;
}
