/* hw_mem.c (emx+gcc) */

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <io.h>
#include <sys/hw.h>

int main (int argc, char *argv[])
{
  unsigned char *p;
  unsigned long address, length, base, end, i;
  char *q;

  if (_osmode != DOS_MODE)
    {
      printf ("This programs runs under DOS, only.\n");
      return 1;
    }
  if (argc != 3)
    {
      printf ("Usage: hw_mem <address> <length>\n");
      return 1;
    }
  errno = 0;
  address = strtoul (argv[1], &q, 16);
  if (errno != 0 || *q != 0)
    {
      printf ("hw_mem: invalid address\n");
      return 1;
    }
  length = strtoul (argv[2], &q, 16);
  if (errno != 0 || *q != 0 || length == 0)
    {
      printf ("hw_mem: invalid length\n");
      return 1;
    }
  base = address & ~0xfff;
  end = (address + length - 1) | 0xfff;
  p = _memaccess (base, end, 0);
  if (p == NULL)
    {
      perror ("hw_mem: _memaccess");
      return 2;
    }
  p += address - base;
  if (_isterm (fileno (stdout)))
    setvbuf (stdout, NULL, _IOLBF, BUFSIZ);
  printf ("%.8lx:", address & ~0x0f);
  for (i = 0; i < (address & 0x0f); ++i)
    printf ("   ");
  for (i = 0; i < length; ++i)
    {
      printf (" %.2x", *p++);
      ++address;
      if ((address & 0xf) == 0)
        {
          putchar ('\n');
          if (i + 1 < length)
            printf ("%.8lx:", address);
        }
    }
  if ((address & 0xf) != 0)
    putchar ('\n');
  return 0;
}
