2017-01-03 20:01:18 +00:00
# include <stdio.h>
# include <stdlib.h>
2017-12-18 17:15:02 +00:00
# include <unistd.h>
2017-01-03 20:01:18 +00:00
# include <termios.h>
# include <time.h>
# include "6502.h"
# include "6850.h"
2017-01-03 20:18:36 +00:00
struct termios initial_termios ;
2017-01-03 20:01:18 +00:00
void step_delay ( )
{
struct timespec req , rem ;
req . tv_sec = 0 ;
req . tv_nsec = STEP_DURATION ;
nanosleep ( & req , & rem ) ;
}
2017-12-18 17:15:02 +00:00
void run_cpu ( int verbose , int mem_dump )
2017-01-03 20:01:18 +00:00
{
2017-01-08 16:28:32 +00:00
int cycles = 0 ;
int cycles_per_step = ( CPU_FREQ / ( ONE_SECOND / STEP_DURATION ) ) ;
for ( ; ; ) {
for ( cycles % = cycles_per_step ; cycles < cycles_per_step ; ) {
2017-12-18 17:15:02 +00:00
if ( mem_dump ) save_memory ( NULL ) ;
cycles + = step_cpu ( verbose ) ;
2017-01-03 20:01:18 +00:00
step_uart ( ) ;
}
step_delay ( ) ; // remove this for more speed
}
}
void restore_stdin ( )
{
2017-01-03 20:18:36 +00:00
tcsetattr ( 0 , TCSANOW , & initial_termios ) ;
2017-01-03 20:01:18 +00:00
}
void raw_stdin ( )
{
2017-01-03 20:18:36 +00:00
struct termios new_termios ;
2017-01-03 20:01:18 +00:00
2017-01-03 20:18:36 +00:00
tcgetattr ( 0 , & initial_termios ) ;
new_termios = initial_termios ;
cfmakeraw ( & new_termios ) ;
tcsetattr ( 0 , TCSANOW , & new_termios ) ;
2017-01-03 20:01:18 +00:00
atexit ( restore_stdin ) ;
}
2017-12-18 17:15:02 +00:00
int hextoint ( char * str ) {
int val ;
if ( * str = = ' $ ' ) str + + ;
val = strtol ( str , NULL , 16 ) ;
return val ;
}
2017-01-03 20:01:18 +00:00
int main ( int argc , char * argv [ ] )
{
2017-12-18 17:15:02 +00:00
int a , x , y , sp , sr , pc ;
int verbose , interactive , mem_dump ;
int opt ;
verbose = 0 ;
interactive = 0 ;
mem_dump = 0 ;
a = 0 ;
x = 0 ;
y = 0 ;
sp = 0 ;
sr = 0 ;
pc = - RST_VEC ; // negative implies indirect
while ( ( opt = getopt ( argc , argv , " vima:x:y:r:p:s:g: " ) ) ! = - 1 ) {
switch ( opt ) {
case ' v ' :
verbose = 1 ;
break ;
case ' i ' :
interactive = 1 ;
break ;
case ' m ' :
mem_dump = 1 ;
break ;
case ' a ' :
a = hextoint ( optarg ) ;
break ;
case ' x ' :
x = hextoint ( optarg ) ;
break ;
case ' y ' :
y = hextoint ( optarg ) ;
break ;
case ' s ' :
sp = hextoint ( optarg ) ;
break ;
case ' p ' :
sr = hextoint ( optarg ) ;
break ;
case ' r ' :
case ' g ' :
pc = hextoint ( optarg ) ;
break ;
default : /* '?' */
fprintf ( stderr , " Usage: %s [-v] [-i] [-a HEX] [-x HEX] [-y HEX] [-s HEX] [-p HEX] [-g|-r ADDR] file.rom \n The first 16k of \" file.rom \" is loaded into the last 16k of memory. \n " ,
argv [ 0 ] ) ;
exit ( EXIT_FAILURE ) ;
}
2017-01-03 20:01:18 +00:00
}
2017-12-18 17:15:02 +00:00
if ( optind > = argc ) {
fprintf ( stderr , " Expected argument after options \n " ) ;
exit ( EXIT_FAILURE ) ;
}
if ( load_rom ( argv [ optind ] ) ! = 0 ) {
printf ( " Error loading \" %s \" . \n " , argv [ optind ] ) ;
2017-01-03 20:01:18 +00:00
return EXIT_FAILURE ;
}
2017-12-18 17:15:02 +00:00
if ( interactive ) raw_stdin ( ) ; // allow individual keystrokes to be detected
2017-01-03 20:01:18 +00:00
init_tables ( ) ;
init_uart ( ) ;
2017-12-18 17:15:02 +00:00
reset_cpu ( a , x , y , sp , sr , pc ) ;
run_cpu ( verbose , mem_dump ) ;
2017-01-03 20:01:18 +00:00
return EXIT_SUCCESS ;
}