home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / EXTRA-ST / CPM-80-E / CPM-0.2 / CPM-0 / cpm-0.2 / low.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-21  |  2.8 KB  |  128 lines

  1. #include "cpmemu.h"
  2. #include <ctype.h>
  3. #include <unistd.h>
  4. #include <sys/types.h>
  5. #include <sys/time.h>
  6. #include <signal.h>
  7. #include <sys/mman.h>
  8. #include <fcntl.h>
  9.  
  10. #define HZ 13    /* frequency of screen updates */
  11.  
  12. /* Note: Signal handling is POSIX, not ANSI */
  13.  
  14. static unsigned char *cptr;
  15. static int OFF = 16;
  16. static int WIDTH = 2*80;
  17.  
  18. int slowdown = 0;
  19. int tickercnt = 0;
  20. extern int hardware_access;
  21.  
  22. static void tickerint(int arg) {
  23.     int i, j;
  24.     static int inited = 0;
  25.     unsigned char *r, *w;
  26.     if (z80mem[4] != 0x4f) {
  27.     inited = 0;
  28.     return;
  29.     }
  30.     if (!inited) {
  31.     inited = 1;
  32.     for (i = 0; i < 18; ++i)
  33.         for (j = 0; j < 66; ++j)
  34.         cptr[WIDTH*i+OFF+2*j-1] = 7;
  35.     for (i = 0; i < 66; ++i) {
  36.         cptr[2*i + OFF-2] = 0xb0;
  37.         cptr[2*i + OFF-2+17*WIDTH] = 0x83;
  38.     }
  39.     for (i = 1; i < 17; ++i) {
  40.         cptr[WIDTH*i + OFF-2] = 0xff;
  41.         cptr[WIDTH*i + OFF-2+2*65] = 0xff;
  42.     }
  43.     }
  44.  
  45.     r = z80mem + 0xcc00;
  46.     w = cptr + OFF + WIDTH;
  47.     for (i = 0; i < 16; ++i) {
  48.     for (j = 0; j < 64; ++j) {
  49.         *w = *r++;
  50.         w += 2;
  51.     }
  52.     w += 2*OFF;
  53.     }
  54. #if HZ == 1
  55.     alarm(1);
  56. #endif
  57. }
  58.  
  59. static int childpid;
  60. static void kill_child(void) {
  61.     kill(childpid, SIGTERM);
  62. }
  63.  
  64. void lowlevel_init(void) {
  65.     struct sigaction sa;
  66.     int memfd;
  67.  
  68.     /* get access to sound port */
  69.     cptr = NULL;
  70.     if (ioperm(0x61, 1, 1)) {
  71.     hardware_access = 0;    /* no access to speaker port */
  72.     return;
  73.     }
  74.  
  75.     /* install signal handler */
  76.     sa.sa_handler = tickerint;
  77.     sa.sa_mask = 0;
  78.     sa.sa_flags = 0;
  79.     sigaction(SIGALRM, &sa, NULL);
  80.  
  81.     /* make video memory accessible */
  82.     memfd = open("/dev/mem", O_RDWR);
  83.     if (memfd > 0)
  84.     cptr = mmap((caddr_t)0, (size_t) 2048, PROT_READ|PROT_WRITE,  
  85.            MAP_SHARED, memfd, (off_t) 0xb8000);
  86.     /* printf("fd=%d, ptr=%p\n", memfd, cptr); */
  87.  
  88.     {   char *s;
  89.     if (!(s = getenv("COLUMNS")) || !(WIDTH = 2 * atoi(s)))
  90.         WIDTH = 160;
  91.     OFF = (WIDTH/2-64);    /* horizontally center a 64x16 screen */
  92.     }
  93.  
  94.     /* benchmark */
  95.     {   int i, usecspercall;
  96.     struct timeval tv1, tv2;
  97.     struct timezone tz;
  98.     gettimeofday(&tv1, &tz);
  99.     for (i = 0; i < 100; ++i)
  100.         gettimeofday(&tv2, &tz);
  101.     usecspercall = ((tv2.tv_usec - tv1.tv_usec) + 1000000 * (tv2.tv_sec-tv1.tv_sec))
  102.         / 100;
  103.     if (usecspercall < 3 || usecspercall > 1000000)
  104.         printf("Time for gettimeofday() cannot be determined\n");
  105.     else {
  106.         /* tune down to 2 MHz Z80 */
  107.         slowdown = usecspercall / 4;
  108.         tickercnt = 70 / usecspercall;    /* 10 KHz interrupt */
  109.         printf("Time for gettimeofday() is %d us\n", usecspercall);
  110.         printf("INT performed every %d times\n", tickercnt);
  111.     }
  112.     }
  113. #if HZ == 1
  114.     alarm(1);
  115. #else
  116.     {   pid_t galpid;
  117.     galpid = getpid();
  118.     if (!(childpid = fork())) {
  119.         int usecs = 1000000 / HZ;
  120.         do {
  121.         usleep(usecs);
  122.         } while (!kill(galpid, SIGALRM));
  123.     } else
  124.         atexit(kill_child);
  125.     }
  126. #endif
  127. }
  128.