rom.o cartridge.o 6502core.o
-LIBS=-L../libs -pthread
+LIBS=-L../libs -pthread -lrt
INCLUDE=-I../include
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) {
}
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);
}
#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;
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;
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;
}
+
#ifndef __clock_h__
#define __clock_h__
+#include <signal.h>
+#include <time.h>
+
typedef int (clock_func_t) (void);
int init_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__*/
#include <string.h>
#include <stdio.h>
#include <signal.h>
+#include <time.h>
#include "tools.h"
#include "clock.h"
#include "bus.h"
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;
}
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");
#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.*/
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
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);
}
int dlist_remove (struct dlist* node) ;
int dlist_count (struct dlist* head);
+
#define TRUE 1
#define FALSE 0