OSDN Git Service

cpu, bus and memory r/w cycle implemented.
authorastoria-d <astoria-d@mail.goo.ne.jp>
Sat, 23 Feb 2013 02:14:43 +0000 (11:14 +0900)
committerastoria-d <astoria-d@mail.goo.ne.jp>
Sat, 23 Feb 2013 02:14:43 +0000 (11:14 +0900)
emulator/Makefile
emulator/bus.c
emulator/clock.c
emulator/clock.h
emulator/cpu.c
emulator/emu-main.c
emulator/rom.c
emulator/tools.h

index d04d22c..e8a448d 100644 (file)
@@ -5,7 +5,7 @@ OBJS=emu-main.o clock.o tools.o bus.o cpu.o \
         rom.o cartridge.o 6502core.o
 
 
-LIBS=-L../libs -pthread
+LIBS=-L../libs -pthread -lrt
 
 INCLUDE=-I../include
 
index 10a2637..c4545dc 100644 (file)
@@ -37,6 +37,7 @@ static struct cpu_pin pin_status;
 void set_bus_addr(unsigned short addr) {
     if (addr & ROM_BIT) {
         set_rom_addr(addr & ROM_MASK);
+        set_rom_ce_pin(TRUE);
     }
     else if (addr & IO_APU_BIT) {
     }
@@ -55,7 +56,6 @@ void set_bus_data(unsigned char data){
 
 char get_bus_data(void){
     if (addr_bus & ROM_BIT) {
-        set_rom_ce_pin(TRUE);
         data_bus = get_rom_data();
         set_rom_ce_pin(FALSE);
     }
index ab7cc3b..4d5af70 100644 (file)
@@ -1,13 +1,11 @@
 
 #include <stdlib.h>
-#include <time.h>
-#include <pthread.h>
 
 #include "tools.h"
 #include "clock.h"
 
-static int exit_loop;
-static pthread_t clock_thread_id;
+static int rt_signal;
+static timer_t cpu_clock_timer;
 
 struct clock_handler {
     struct slist l;
@@ -16,57 +14,31 @@ struct clock_handler {
 
 static struct clock_handler *handler_list;
 
-#define DEB_SLOW
-
-static void *clock_loop(void* arg) {
-    struct timespec ts;
+static void cpu_clock_loop(int arg) {
     struct clock_handler *ch;
 
-#ifdef DEB_SLOW
-    ts.tv_sec = 0;
-    ts.tv_nsec = 100000000;
-#else
-    ts.tv_sec = 0;
-    ts.tv_nsec = 1;
-#endif
-
-    while (!exit_loop) {
-        //dprint("loop...\n");
-        ch = handler_list;
-        while (ch != NULL) {
-            if (!ch->handler())
-                return NULL;
-            ch = (struct clock_handler*)ch->l.next;
-        }
-        nanosleep(&ts, NULL);
+    dprint("loop...\n");
+    ch = handler_list;
+    while (ch != NULL) {
+        if (!ch->handler())
+            return;
+        ch = (struct clock_handler*)ch->l.next;
     }
 
-    return NULL;
+    return;
 }
 
+
 int start_clock(void) {
     int ret;
-    pthread_attr_t attr;
+    int sec, nsec;
 
-    ret = pthread_attr_init(&attr);
-    if (ret != RT_OK)
-        return FALSE;
-
-    ret = pthread_create(&clock_thread_id, &attr, clock_loop, NULL);
+    sec = CPU_CLOCK_SEC;
+    nsec = CPU_CLOCK_NSEC;
+    ret = register_timer(sec, nsec, cpu_clock_loop, &cpu_clock_timer);
     return ret == TRUE;
 }
 
-static void end_loop(void) {
-    void* ret;
-    exit_loop = TRUE;
-
-    //join the running thread.
-    pthread_join(clock_thread_id, &ret);
-
-    dprint("clock thread joined.\n");
-
-}
-
 int register_clock_hander(clock_func_t *handler) {
     struct clock_handler *ch;
 
@@ -83,16 +55,62 @@ int register_clock_hander(clock_func_t *handler) {
     return TRUE;
 }
 
+int emu_timer_init(void) {
+    rt_signal = SIGRTMIN;
+    //rt_signal = SIGALRM;
+    return TRUE;
+}
+
+int register_timer(unsigned long int_sec, unsigned long int_nanosec, __sighandler_t func, 
+        timer_t *timerId) {
+    struct sigaction    sigact;
+    struct itimerspec   itval;
+    struct sigevent sev;
+
+
+    //register handler
+    sigact.sa_handler = func;
+    sigact.sa_flags = 0;
+    sigemptyset(&sigact.sa_mask);
+
+    if(sigaction(rt_signal,&sigact,NULL) == -1)
+    {
+        return FALSE;
+    }
+
+    //create timer
+    itval.it_interval.tv_sec = int_sec;
+    itval.it_interval.tv_nsec = int_nanosec;
+    itval.it_value.tv_sec = int_sec;
+    itval.it_value.tv_nsec = int_nanosec;
+
+    sev.sigev_notify = SIGEV_SIGNAL;
+    sev.sigev_signo = rt_signal;
+    sev.sigev_value.sival_ptr = timerId;
+
+    rt_signal++;
+
+    if(timer_create(CLOCK_REALTIME, &sev, timerId) == -1)
+    {
+        return FALSE;
+    }
+    if(timer_settime(*timerId,0,&itval,NULL) == -1)
+    {
+        return FALSE;
+    }
+    return TRUE;
+}
+
 int init_clock(void) {
-    exit_loop = FALSE;
     handler_list = NULL;
+    cpu_clock_timer = 0;
     return TRUE;
 }
 
 void clean_clock(void) {
     struct clock_handler *ch = handler_list;
 
-    end_loop();
+    timer_delete(cpu_clock_timer);
 
     while (ch != NULL) {
         struct clock_handler *pp = ch;
@@ -103,3 +121,4 @@ void clean_clock(void) {
     
 
 }
+
index 732d4e2..0419288 100644 (file)
@@ -1,6 +1,9 @@
 #ifndef __clock_h__
 #define __clock_h__
 
+#include <signal.h>
+#include <time.h>
+
 typedef int (clock_func_t) (void);
 
 int init_clock(void);
@@ -9,5 +12,19 @@ void clean_clock(void);
 int register_clock_hander(clock_func_t *handler);
 int start_clock(void);
 
+int emu_timer_init(void);
+int register_timer(unsigned long int_sec, unsigned long int_nanosec, 
+        __sighandler_t func, timer_t *timerid);
+
+#define DEB_SLOW
+
+#ifdef DEB_SLOW
+#define CPU_CLOCK_SEC   0
+#define CPU_CLOCK_NSEC  100000000
+#else
+#define CPU_CLOCK_SEC   0
+#define CPU_CLOCK_NSEC  100
+#endif
+
 #endif /*__clock_h__*/
 
index 70edaa6..07314ff 100644 (file)
@@ -1,6 +1,7 @@
 #include <string.h>
 #include <stdio.h>
 #include <signal.h>
+#include <time.h>
 #include "tools.h"
 #include "clock.h"
 #include "bus.h"
@@ -72,9 +73,13 @@ int clock_cpu(void) {
 
 static unsigned char load_memory(unsigned short addr) {
     int rw = 0;
+    struct timespec ts = {CPU_CLOCK_SEC, CPU_CLOCK_NSEC / 2};
 
-    set_bus_addr(addr);
     set_rw_pin(rw);
+    set_bus_addr(addr);
+    //must wait half cycle for the bus ready
+    nanosleep(&ts, NULL);
+
     cpu_data_buffer = get_bus_data();
     return cpu_data_buffer;
 }
index 9937491..c922d23 100644 (file)
@@ -32,6 +32,12 @@ static int init_datas(void) {
         return FALSE;
     }
 
+    ret = emu_timer_init();
+    if (!ret) {
+        fprintf(stderr, "timer init err.\n");
+        return FALSE;
+    }
+
     ret = init_cpu();
     if (!ret) {
         fprintf(stderr, "cpu init err.\n");
index 911272a..dd80c7b 100644 (file)
@@ -1,6 +1,11 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <time.h>
+#include <pthread.h>
+#include <semaphore.h>
+
 #include "tools.h"
+#include "clock.h"
 
 struct rom_pin {
     unsigned int rw     :1;     /*assert on write.*/
@@ -10,6 +15,9 @@ struct rom_pin {
 static struct rom_pin rom_pin_status;
 static unsigned short rom_addr;
 static unsigned char rom_data;
+static pthread_t rom_thread_id;
+static int rom_end_loop;
+static sem_t rom_sem_id;
 
 #define ROM_32K 0x8000
 
@@ -37,21 +45,62 @@ unsigned char get_rom_data(void) {
 
 void set_rom_ce_pin(int ce) {
     rom_pin_status.ce = ce;
-    if (rom_pin_status.ce)
-        rom_data = rom_buffer[rom_addr];
+    //let rom write the value on the bus.
+    sem_post(&rom_sem_id);
 }
 
+static void *rom_loop(void* arg) {
+    //rom data load delay is 1/10 (dummy interval)
+    struct timespec ts = {CPU_CLOCK_SEC, CPU_CLOCK_NSEC / 10};
+
+    while (!rom_end_loop) {
+        sem_wait(&rom_sem_id);
+        if (rom_pin_status.ce) {
+            nanosleep(&ts, NULL);
+            rom_data = rom_buffer[rom_addr];
+        }
+    }
+    return NULL;
+}
 
 int init_rom(void) {
+    int ret;
+    pthread_attr_t attr;
+
     rom_buffer = NULL;
     rom_addr = 0;
     rom_data = 0;
     rom_pin_status.rw = 0;
     rom_pin_status.ce = 0;
+
+    rom_end_loop = FALSE;
+
+    ret = pthread_attr_init(&attr);
+    if (ret != RT_OK)
+        return FALSE;
+
+    rom_thread_id = 0;
+    ret = pthread_create(&rom_thread_id, &attr, rom_loop, NULL);
+    if (ret != RT_OK)
+        return FALSE;
+
+    ret = sem_init(&rom_sem_id, 0, 0);
+    if (ret != RT_OK)
+        return FALSE;
+
     return TRUE;
 }
 
 void clear_rom(void) {
+    void* ret;
+    rom_end_loop = TRUE;
+    //join the running thread.
+    sem_post(&rom_sem_id);
+    pthread_join(rom_thread_id, &ret);
+
+    sem_destroy(&rom_sem_id);
+    dprint("rom thread joined.\n");
+
     if (rom_buffer)
         free(rom_buffer);
 }
index 98c8b26..edc5019 100644 (file)
@@ -20,6 +20,7 @@ void dlist_add_prev (struct dlist* dest, struct dlist* node) ;
 int dlist_remove (struct dlist* node) ;
 int dlist_count (struct dlist* head);
 
+
 #define TRUE 1
 #define FALSE 0