home *** CD-ROM | disk | FTP | other *** search
- #include "cpmemu.h"
- #include <ctype.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/time.h>
- #include <signal.h>
- #include <sys/mman.h>
- #include <fcntl.h>
-
- #define HZ 13 /* frequency of screen updates */
-
- /* Note: Signal handling is POSIX, not ANSI */
-
- static unsigned char *cptr;
- static int OFF = 16;
- static int WIDTH = 2*80;
-
- int slowdown = 0;
- int tickercnt = 0;
- extern int hardware_access;
-
- static void tickerint(int arg) {
- int i, j;
- static int inited = 0;
- unsigned char *r, *w;
- if (z80mem[4] != 0x4f) {
- inited = 0;
- return;
- }
- if (!inited) {
- inited = 1;
- for (i = 0; i < 18; ++i)
- for (j = 0; j < 66; ++j)
- cptr[WIDTH*i+OFF+2*j-1] = 7;
- for (i = 0; i < 66; ++i) {
- cptr[2*i + OFF-2] = 0xb0;
- cptr[2*i + OFF-2+17*WIDTH] = 0x83;
- }
- for (i = 1; i < 17; ++i) {
- cptr[WIDTH*i + OFF-2] = 0xff;
- cptr[WIDTH*i + OFF-2+2*65] = 0xff;
- }
- }
-
- r = z80mem + 0xcc00;
- w = cptr + OFF + WIDTH;
- for (i = 0; i < 16; ++i) {
- for (j = 0; j < 64; ++j) {
- *w = *r++;
- w += 2;
- }
- w += 2*OFF;
- }
- #if HZ == 1
- alarm(1);
- #endif
- }
-
- static int childpid;
- static void kill_child(void) {
- kill(childpid, SIGTERM);
- }
-
- void lowlevel_init(void) {
- struct sigaction sa;
- int memfd;
-
- /* get access to sound port */
- cptr = NULL;
- if (ioperm(0x61, 1, 1)) {
- hardware_access = 0; /* no access to speaker port */
- return;
- }
-
- /* install signal handler */
- sa.sa_handler = tickerint;
- sa.sa_mask = 0;
- sa.sa_flags = 0;
- sigaction(SIGALRM, &sa, NULL);
-
- /* make video memory accessible */
- memfd = open("/dev/mem", O_RDWR);
- if (memfd > 0)
- cptr = mmap((caddr_t)0, (size_t) 2048, PROT_READ|PROT_WRITE,
- MAP_SHARED, memfd, (off_t) 0xb8000);
- /* printf("fd=%d, ptr=%p\n", memfd, cptr); */
-
- { char *s;
- if (!(s = getenv("COLUMNS")) || !(WIDTH = 2 * atoi(s)))
- WIDTH = 160;
- OFF = (WIDTH/2-64); /* horizontally center a 64x16 screen */
- }
-
- /* benchmark */
- { int i, usecspercall;
- struct timeval tv1, tv2;
- struct timezone tz;
- gettimeofday(&tv1, &tz);
- for (i = 0; i < 100; ++i)
- gettimeofday(&tv2, &tz);
- usecspercall = ((tv2.tv_usec - tv1.tv_usec) + 1000000 * (tv2.tv_sec-tv1.tv_sec))
- / 100;
- if (usecspercall < 3 || usecspercall > 1000000)
- printf("Time for gettimeofday() cannot be determined\n");
- else {
- /* tune down to 2 MHz Z80 */
- slowdown = usecspercall / 4;
- tickercnt = 70 / usecspercall; /* 10 KHz interrupt */
- printf("Time for gettimeofday() is %d us\n", usecspercall);
- printf("INT performed every %d times\n", tickercnt);
- }
- }
- #if HZ == 1
- alarm(1);
- #else
- { pid_t galpid;
- galpid = getpid();
- if (!(childpid = fork())) {
- int usecs = 1000000 / HZ;
- do {
- usleep(usecs);
- } while (!kill(galpid, SIGALRM));
- } else
- atexit(kill_child);
- }
- #endif
- }
-