Project

General

Profile

« Previous | Next » 

Revision 179

Added by markw about 11 years ago

Fork of firmware for 5200 - will be merged back in soon...

View differences:

firmware_5200/Makefile
BASE = zpu-elf
CC = $(BASE)-gcc
LD = $(BASE)-gcc
AS = $(BASE)-as
CP = $(BASE)-objcopy
DUMP = $(BASE)-objdump
# we use mincrt0.s from here
STARTUP_DIR = .
# we fetch ROM prologue / epilogue from here
RTL_DIR = $(ZPUFLEXDIR)/RTL/
BUILD_DIR=zpu_obj
#MINSTARTUP_SRC = mincrt0.s
MINSTARTUP_SRC = mycrt0.s
MINSTARTUP_OBJ = $(patsubst $(STARTUP_DIR)/%.s,$(BUILD_DIR)/%.o,$(MINSTARTUP_SRC))
AEON_LITE_PRJ = AEON_LITE
AEON_LITE_SRC = main_aeon_lite.c regs.c freeze.c joystick.c fileutils.c fileselector.c pokey/uart.c hexdump.c printf/printf.c fat/pff_file.c fat/pff.c common/utils.c sd_direct/diskio_mmc.c sd_direct/spi.c sd_direct/mmc2.c de1/dirs.c
AEON_LITE_OBJ = $(patsubst %.c,$(BUILD_DIR)/%.o,$(AEON_LITE_SRC))
DE1_PRJ = DE1
DE1_SRC = main.c regs.c freeze.c joystick.c fileutils.c fileselector.c pokey/uart.c hexdump.c printf/printf.c fat/pff_file.c fat/pff.c common/utils.c sd_direct/diskio_mmc.c sd_direct/spi.c sd_direct/mmc2.c de1/dirs.c
DE1_OBJ = $(patsubst %.c,$(BUILD_DIR)/%.o,$(DE1_SRC))
CHAMELEON_PRJ = CHAMELEON
CHAMELEON_SRC = main.c regs.c freeze.c joystick.c fileutils.c fileselector.c pokey/uart.c hexdump.c printf/printf.c fat/pff_file.c fat/pff.c common/utils.c sd_direct/diskio_mmc.c sd_direct/spi.c sd_direct/mmc2.c chameleon/dirs.c
CHAMELEON_OBJ = $(patsubst %.c,$(BUILD_DIR)/%.o,$(CHAMELEON_SRC))
MCC_PRJ = MCC216
MCC_SRC = main.c regs.c freeze.c joystick.c fileutils.c fileselector.c pokey/uart.c hexdump.c printf/printf.c fat/pff_file.c fat/pff.c common/utils.c sd_direct/diskio_mmc.c sd_direct/spi.c sd_direct/mmc2.c mcc/dirs.c
MCC_OBJ = $(patsubst %.c,$(BUILD_DIR)/%.o,$(MCC_SRC))
MIST_PRJ = MIST
MIST_SRC = main.c regs.c freeze.c joystick.c fileutils.c fileselector.c pokey/uart.c hexdump.c printf/printf.c fat/pff_file.c fat/pff.c common/utils.c mist/diskio_sectorrequest.c mist/dirs.c
MIST_OBJ = $(patsubst %.c,$(BUILD_DIR)/%.o,$(MIST_SRC))
LINKMAP = ./standalone_simple.ld
# Commandline options for each tool.
#ZPUOPTS= -mno-poppcrel -mno-pushspadd -mno-callpcrel -mno-shortop -mno-neg # No-neg requires bugfixed toolchain
#Include everything -> need to include emulation rom...
ZPUOPTS =
CFLAGS = -I. -Isd_direct -Iprintf -Ifat -Icommon -c -g -Os $(ZPUOPTS) -DDISABLE_UART_RX
LFLAGS = -nostartfiles -Wl,--relax -g -Os
#LFLAGS = -nostartfiles -Os
# Our target.
all: mcc mist de1 aeon_lite chameleon
install:
cd ../common/romgen && ./createall && cd ../../firmware
aeon_lite: $(BUILD_DIR) $(AEON_LITE_PRJ).bin $(AEON_LITE_PRJ).rpt
de1: $(BUILD_DIR) $(DE1_PRJ).bin $(DE1_PRJ).rpt
chameleon: $(BUILD_DIR) $(CHAMELEON_PRJ).bin $(CHAMELEON_PRJ).rpt
mcc: $(BUILD_DIR) $(MCC_PRJ).bin $(MCC_PRJ).rpt
mist: $(BUILD_DIR) $(MIST_PRJ).bin $(MIST_PRJ).rpt
clean:
rm -rf $(BUILD_DIR)/* *.hex *.elf *.map *.lst *.srec *.bin *.rpt
# Convert ELF binary to bin file.
%.bin: %.elf
$(CP) -O binary $< $@
%.rpt: %.elf
echo >$@ -n "End of code:\t"
$(DUMP) -x $< | grep >>$@ _romend
echo >>$@ -n "Start of BSS:\t"
$(DUMP) -x $< | grep >>$@ __bss_start__
echo >>$@ -n "End of BSS:\t"
$(DUMP) -x $< | grep >>$@ __bss_end__
cat $@
# Link - this produces an ELF binary.
$(AEON_LITE_PRJ).elf: $(MINSTARTUP_OBJ) $(AEON_LITE_OBJ)
$(LD) $(LFLAGS) -T $(LINKMAP) -o $@ $+ $(LIBS)
$(DE1_PRJ).elf: $(MINSTARTUP_OBJ) $(DE1_OBJ)
$(LD) $(LFLAGS) -T $(LINKMAP) -o $@ $+ $(LIBS)
$(CHAMELEON_PRJ).elf: $(MINSTARTUP_OBJ) $(CHAMELEON_OBJ)
$(LD) $(LFLAGS) -T $(LINKMAP) -o $@ $+ $(LIBS)
$(MCC_PRJ).elf: $(MINSTARTUP_OBJ) $(MCC_OBJ)
$(LD) $(LFLAGS) -T $(LINKMAP) -o $@ $+ $(LIBS)
$(MIST_PRJ).elf: $(MINSTARTUP_OBJ) $(MIST_OBJ)
$(LD) $(LFLAGS) -T $(LINKMAP) -o $@ $+ $(LIBS)
$(BUILD_DIR)/%.o: %.c Makefile
mkdir -p `dirname $@`
$(CC) $(CFLAGS) -o $@ -c $<
$(BUILD_DIR)/%.o: %.s
$(AS) -o $@ $<
$(BUILD_DIR)/%.o: $(STARTUP_DIR)/%.s
$(AS) -o $@ $<
$(BUILD_DIR):
mkdir $(BUILD_DIR)
firmware_5200/TODO
DONE i) Test writes at pf_file level on PC
DONE! ii) When file selected, boot rather than just printing something!
DONE iii) Add settings
DONE iv) Try out writes on Atari side
v) Check that read-only works...
DONE!--vi) Show selected file clearly!
firmware_5200/actions.c
int bit_set(int var, int bit)
{
return (((1<<bit)&var)!=0);
}
void actions()
{
unsigned int i = 0;
//unsigned volatile char * store = 0xf00000; // SDRAM - fails!!
//unsigned volatile char * store = 0xf80000; // SRAM...
//unsigned volatile char * store2 = 0xfc0000; // custom chips...
// cold start (need to clear a few key locations to make OS cold start)
// file selector (where applicable)
// options (where applicable)
int keys = *zpu_in;
if (bit_set(keys,0))
{
coldstart();
}
else if (bit_set(keys,1))
{
set_pause_6502(1);
freeze();
menu_options();
restore();
set_pause_6502(0);
}
else if (bit_set(keys,2))
{
set_pause_6502(1);
freeze();
menu_fileselector();
coldstart();
}
}
void menu_options()
{
// title
// memory
// rom
// turbo
// disks
// exit/reboot
// simple state machine for menu, so I set up a small data structure then it just runs from that...
}
void menu_fileselector()
{
// title
// loads of stuff, filtered by type
// directories can be selected
// initial directory set, after that starts where it was left
}
firmware_5200/aeon_lite/memory.h
#pragma once
// Memory usage...
// 0x90000-0x9FFFF (0x890000 in zpu space) = directory cache - 64k
// 0xA0000-0xBFFFF (0x8a0000 in zpu space) = freeze backup
// 0xC0000-0xDFFFF (0x8c0000 in zpu space) = os rom/basic rom
#define DIR_INIT_MEM 0x890000
#define DIR_INIT_MEMSIZE 65536
#define FREEZE_MEM 0x8a0000
#define ROM_MEM 0xc0000
firmware_5200/build
zpu-elf-gcc -I. -Isd_direct -Iprintf -Ifat -Icommon -c -g -O2 -DDISABLE_UART_RX -o zpu_obj/uart.o -c pokey/uart.c
zpu-elf-gcc -I. -Isd_direct -Iprintf -Ifat -Icommon -c -g -O2 -DDISABLE_UART_RX -o zpu_obj/hexdump.o -c hexdump.c
zpu-elf-gcc -I. -Isd_direct -Iprintf -Ifat -Icommon -c -g -O2 -DDISABLE_UART_RX -o zpu_obj/printf.o -c printf/printf.c
zpu-elf-gcc -I. -Isd_direct -Iprintf -Ifat -Icommon -c -g -O2 -DDISABLE_UART_RX -o zpu_obj/pff_file.o -c fat/pff_file.c
zpu-elf-gcc -I. -Isd_direct -Iprintf -Ifat -Icommon -c -g -O2 -DDISABLE_UART_RX -o zpu_obj/pff.o -c fat/pff.c
zpu-elf-gcc -I. -Isd_direct -Iprintf -Ifat -Icommon -c -g -O2 -DDISABLE_UART_RX -o zpu_obj/utils.o -c common/utils.c
zpu-elf-gcc -I. -Isd_direct -Iprintf -Ifat -Icommon -c -g -O2 -DDISABLE_UART_RX -o zpu_obj/diskio_mmc.o -c diskio_mmc.c
zpu-elf-gcc -nostartfiles -Wl,--relax -g -Os -T ./standalone_simple.ld -o JustStartAtari.elf mycrt0.s zpu_obj/main.o zpu_obj/regs.o zpu_obj/atari_drive_emulator.o zpu_obj/pokey/uart.o zpu_obj/hexdump.o zpu_obj/printf/printf.o zpu_obj/fat/pff_file.o zpu_obj/fat/pff.o zpu_obj/common/utils.o zpu_obj/diskio_mmc.o
zpu-elf-objcopy -O binary JustStartAtari.elf JustStartAtari.bin
echo >JustStartAtari.rpt -n "End of code:\t"
zpu-elf-objdump -x JustStartAtari.elf | grep >>JustStartAtari.rpt _romend
echo >>JustStartAtari.rpt -n "Start of BSS:\t"
zpu-elf-objdump -x JustStartAtari.elf | grep >>JustStartAtari.rpt __bss_start__
echo >>JustStartAtari.rpt -n "End of BSS:\t"
zpu-elf-objdump -x JustStartAtari.elf | grep >>JustStartAtari.rpt __bss_end__
cat JustStartAtari.rpt
firmware_5200/fileutils.c
#include "printf.h"
#include "utils.h"
int compare_ext(char const * filename, char const * ext)
{
int dot = 0;
//printf("WTFA:%s %s\n",filenamein, extin);
//printf("WTFB:%s %s\n",filename, ext);
char const * end = strlen(filename) + filename;
while (--end != filename)
{
if (*end == '.')
break;
}
if (0==stricmp(end+1,ext)) return 1;
return 0;
}
firmware_5200/freeze.h
#pragma once
// Allow us to take over the system
// NB: CPU should be frozen before calling these!
// Provide 128K of RAM...
void freeze_init(void * memory);
// Set hardware registers to 'neutral'
// Back up system ram
void freeze();
// Restore system ram
// Restore hardware registers
void restore();
firmware_5200/joystick.c
#include "joystick.h"
#include "regs.h"
//#include <stdio.h>
void joystick_poll(struct joystick_status * status)
{
status->x_ = 0;
status->y_ = 0;
status->fire_ = 0;
unsigned char kbcode = *atari_kbcode;
kbcode &= 0x1e;
unsigned char key_held = *atari_skctl;
if ((key_held&0x4) != 0)
{
kbcode = 0x0;
}
status->y_ = (0x8==(kbcode&0x18)) -((unsigned int)(0x18==(kbcode&0x18)));
status->x_ = (0x2==(kbcode&0x6)) -((unsigned int)(0x6==(kbcode&0x6)));
//status->fire_ = !(1&*atari_trig0);
status->fire_ = kbcode==0x14;
//if (porta != 0xff)
//printf("%02x %x %x %x\n",porta,status->x_,status->y_,status->fire_);
/*
if (0==(porta&0x2)) // down
{
status->y_ =1;
}
else if (0==(porta&0x1)) // up
{
status->y_ =-1;
}
if (0==(porta&0x8)) // right
{
status->x_ = 1;
}
else if (0==(porta&0x4)) // left
{
status->x_ = -1;
}
if (0==(1&*atari_trig0)) // fire
{
status->fire_ = 1;
}
*/
}
void joystick_wait(struct joystick_status * status, enum JoyWait waitFor)
{
while (1)
{
joystick_poll(status);
switch (waitFor)
{
case WAIT_QUIET:
if (status->x_ == 0 && status->y_ == 0 && status->fire_ == 0) return;
break;
case WAIT_FIRE:
if (status->fire_ == 1) return;
break;
case WAIT_EITHER:
if (status->fire_ == 1) return;
// fall through
case WAIT_MOVE:
if (status->x_ !=0 || status->y_ != 0) return;
break;
}
}
}
firmware_5200/main.c
#include "sdram_common/memory.h"
#include "main_real.c"
firmware_5200/defunct/test.c
unsigned char toatarichar(int val)
{
if (val>='A' && val<='Z')
{
val+=-'A'+33;
}
else if (val>='a' && val<='z')
{
val+=-'a'+33+64;
}
else if (val>='0' && val<='9')
{
val+=-'0'+16;
}
else
{
val = 0;
}
return val;
}
int xpos = 0;
int ypos = 0;
void nextline()
{
xpos=0;
ypos+=1;
if (ypos==24)
ypos = 0;
}
void plot(unsigned char a, int x, int y)
{
printf("%d %d %d\n",a,x,y);
}
void debug(char const * str)
{
// char buffer[256];
// buffer[0] = 'W';
// buffer[1] = 'T';
// buffer[2] = 'F';
// buffer[3] = 0;
// str = buffer;
while (1)
{
int val = *str++;
if (val==0) break;
plot(toatarichar(val),xpos,ypos);
++xpos;
if (xpos==40)
{
nextline();
}
}
nextline();
//Delay100usX(10000);
}
int main(void)
{
printf("%d %d\n", 'H', toatarichar('H'));
debug("Goodbye sweet world!");
return 0;
}
firmware_5200/fat/diskio.h
/*-----------------------------------------------------------------------
/ PFF - Low level disk interface modlue include file (C)ChaN, 2009
/-----------------------------------------------------------------------*/
#ifndef _DISKIO
#include "integer.h"
/* Status of Disk Functions */
typedef BYTE DSTATUS;
/* Results of Disk Functions */
typedef enum {
RES_OK = 0, /* 0: Function succeeded */
RES_ERROR, /* 1: Disk error */
RES_NOTRDY, /* 2: Not ready */
RES_PARERR /* 3: Invalid parameter */
} DRESULT;
/*---------------------------------------*/
/* Prototypes for disk control functions */
DSTATUS disk_initialize (void);
DRESULT disk_readp (BYTE*, DWORD, WORD, WORD);
DRESULT disk_writep (const BYTE* buff, DWORD sofs, DWORD count);
void disk_writeflush();
#define STA_NOINIT 0x01 /* Drive not initialized */
#define STA_NODISK 0x02 /* No medium in the drive */
/* Card type flags (CardType) */
#define CT_MMC 0x01 /* MMC ver 3 */
#define CT_SD1 0x02 /* SD ver 1 */
#define CT_SD2 0x04 /* SD ver 2 */
#define CT_SDC (CT_SD1|CT_SD2) /* SD */
#define CT_BLOCK 0x08 /* Block addressing */
#define _DISKIO
#endif
firmware_5200/fat/pff.h
/*---------------------------------------------------------------------------/
/ Petit FatFs - FAT file system module include file R0.02a (C)ChaN, 2010
/----------------------------------------------------------------------------/
/ Petit FatFs module is an open source software to implement FAT file system to
/ small embedded systems. This is a free software and is opened for education,
/ research and commercial developments under license policy of following trems.
/
/ Copyright (C) 2010, ChaN, all right reserved.
/
/ * The Petit FatFs module is a free software and there is NO WARRANTY.
/ * No restriction on use. You can use, modify and redistribute it for
/ personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
/ * Redistributions of source code must retain the above copyright notice.
/
/----------------------------------------------------------------------------*/
#include "integer.h"
/*---------------------------------------------------------------------------/
/ Petit FatFs Configuration Options
/
/ CAUTION! Do not forget to make clean the project after any changes to
/ the configuration options.
/
/----------------------------------------------------------------------------*/
#ifndef _FATFS
#define _FATFS
#define _USE_READ 1 /* 1:Enable pf_read() */
#define _USE_DIR 1 /* 1:Enable pf_opendir() and pf_readdir() */
#define _USE_LSEEK 1 /* 1:Enable pf_lseek() */
#define _USE_WRITE 0 /* 1:Enable pf_write() */
#define _FS_FAT12 1 /* 1:Enable FAT12 support */
#define _FS_FAT32 1 /* 1:Enable FAT32 support */
#define _CODE_PAGE 1
/* Defines which code page is used for path name. Supported code pages are:
/ 932, 936, 949, 950, 437, 720, 737, 775, 850, 852, 855, 857, 858, 862, 866,
/ 874, 1250, 1251, 1252, 1253, 1254, 1255, 1257, 1258 and 1 (ASCII only).
/ SBCS code pages except for 1 requiers a case conversion table. This
/ might occupy 128 bytes on the RAM on some platforms, e.g. avr-gcc. */
#define _WORD_ACCESS 0
/* The _WORD_ACCESS option defines which access method is used to the word
/ data in the FAT structure.
/
/ 0: Byte-by-byte access. Always compatible with all platforms.
/ 1: Word access. Do not choose this unless following condition is met.
/
/ When the byte order on the memory is big-endian or address miss-aligned
/ word access results incorrect behavior, the _WORD_ACCESS must be set to 0.
/ If it is not the case, the value can also be set to 1 to improve the
/ performance and code efficiency. */
/* End of configuration options. Do not change followings without care. */
/*--------------------------------------------------------------------------*/
#if _FS_FAT32
#define CLUST DWORD
#else
#define CLUST WORD
#endif
/* File system object structure */
typedef struct {
BYTE fs_type; /* FAT sub type */
BYTE flag; /* File status flags */
BYTE csize; /* Number of sectors per cluster */
BYTE pad1;
WORD n_rootdir; /* Number of root directory entries (0 on FAT32) */
CLUST n_fatent; /* Number of FAT entries (= number of clusters + 2) */
DWORD fatbase; /* FAT start sector */
DWORD dirbase; /* Root directory start sector (Cluster# on FAT32) */
DWORD database; /* Data start sector */
DWORD fptr; /* File R/W pointer */
DWORD fsize; /* File size */
CLUST org_clust; /* File start cluster */
CLUST curr_clust; /* File current cluster */
DWORD dsect; /* File current data sector */
} FATFS;
/* Directory object structure */
typedef struct {
WORD index; /* Current read/write index number */
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
CLUST sclust; /* Table start cluster (0:Static table) */
CLUST clust; /* Current cluster */
DWORD sect; /* Current sector */
} DIR;
/* File status structure */
typedef struct {
DWORD fsize; /* File size */
WORD fdate; /* Last modified date */
WORD ftime; /* Last modified time */
BYTE fattrib; /* Attribute */
char fname[13]; /* File name */
char lfname[256]; /* File name */
} FILINFO;
/* File function return code (FRESULT) */
typedef enum {
FR_OK = 0, /* 0 */
FR_DISK_ERR, /* 1 */
FR_NOT_READY, /* 2 */
FR_NO_FILE, /* 3 */
FR_NO_PATH, /* 4 */
FR_NOT_OPENED, /* 5 */
FR_NOT_ENABLED, /* 6 */
FR_NO_FILESYSTEM /* 7 */
} FRESULT;
/*--------------------------------------------------------------*/
/* Petit FatFs module application interface */
FRESULT pf_mount (FATFS*); /* Mount/Unmount a logical drive */
FRESULT pf_open (const char*); /* Open a file */
FRESULT pf_read (void*, WORD, WORD*); /* Read data from the open file */
FRESULT pf_write (const void*, WORD, WORD*); /* Write data to the open file */
FRESULT pf_lseek (DWORD); /* Move file pointer of the open file */
FRESULT pf_opendir (DIR*, const char*); /* Open a directory */
FRESULT pf_readdir (DIR*, FILINFO*); /* Read a directory item from the open directory */
/*--------------------------------------------------------------*/
/* Flags and offset address */
/* File status flag (FATFS.flag) */
#define FA_OPENED 0x01
#define FA_WPRT 0x02
#define FA__WIP 0x40
/* FAT sub type (FATFS.fs_type) */
#define FS_FAT12 1
#define FS_FAT16 2
#define FS_FAT32 3
/* File attribute bits for directory entry */
#define AM_RDO 0x01 /* Read only */
#define AM_HID 0x02 /* Hidden */
#define AM_SYS 0x04 /* System */
#define AM_VOL 0x08 /* Volume label */
#define AM_LFN 0x0F /* LFN entry */
#define AM_DIR 0x10 /* Directory */
#define AM_ARC 0x20 /* Archive */
#define AM_MASK 0x3F /* Mask of defined bits */
/*--------------------------------*/
/* Multi-byte word access macros */
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
#else /* Use byte-by-byte access to the FAT structure */
#define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr))
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8)
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24)
#endif
#endif /* _FATFS */
firmware_5200/fat/pff_file.h
#pragma once
#include "simplefile.h"
#include "simpledir.h"
#define MAX_DIR_LENGTH (9*5+1)
#define MAX_FILE_LENGTH (8+3+1+1)
#define MAX_PATH_LENGTH (9*5 + 8+3+1 + 1)
// Do not access these directly... They vary by architecture, just the simplefile/simpledir interface is the same
struct SimpleFile
{
char path[MAX_PATH_LENGTH];
int is_readonly;
int size;
};
struct SimpleDirEntry
{
char path[MAX_PATH_LENGTH];
char * filename_ptr;
char lfn[256];
int size;
int is_subdir;
int is_readonly;
struct SimpleDirEntry * next; // as linked list - want to allow sorting...
};
firmware_5200/fileselector.h
#pragma once
void file_selector(struct SimpleFile * file);
int filter_disks(struct SimpleDirEntry * entry);
int filter_roms(struct SimpleDirEntry * entry);
int filter_bins(struct SimpleDirEntry * entry);
extern int (* filter)(struct SimpleDirEntry * entry);
firmware_5200/freeze.c
#include "freeze.h"
#include "regs.h"
unsigned char store_portb;
unsigned volatile char * store_mem;
unsigned volatile char * custom_mirror;
unsigned volatile char * atari_base;
void freeze_init(void * memory)
{
store_mem = (unsigned volatile char *)memory;
custom_mirror = (unsigned volatile char *)atari_regmirror;
atari_base = (unsigned volatile char *)atari_regbase;
}
void freeze()
{
int i;
// store custom chips
//store_portb = *atari_portb;
{
//gtia
for (i=0xc000; i!=0xc020; i++)
{
store_mem[i] = custom_mirror[i];
atari_base[i] = 0;
}
//pokey1/2
for (i=0xe800; i!=0xe820; i++)
{
store_mem[i] = custom_mirror[i];
atari_base[i] = 0;
}
//antic
for (i=0xd400; i!=0xd410; i++)
{
store_mem[i] = custom_mirror[i];
atari_base[i] = 0;
}
}
//*atari_portb = 0xff;
// Copy 16k ram to sdram
// Atari screen memory...
for (i=0x0; i!=0x4000; ++i)
{
store_mem[i] = atari_base[i];
}
//Clear, except dl (first 0x40 bytes)
clearscreen();
// Put custom chips in a safe state
// write a display list at 0600
unsigned char dl[] = {
0x70,
0x70,
0x47,0x40,0x2c,
0x70,
0x42,0x68,0x2c,
0x2,0x2,0x2,0x2,0x2,
0x2,0x2,0x2,0x2,0x2,
0x2,0x2,0x2,0x2,0x2,
0x2,0x2,0x2,0x2,0x2,
0x2,0x2,
0x41,0x00,0x06
};
int j = 0;
for (i=0x0600; j!=sizeof(dl); ++i,++j)
{
atari_base[i] = dl[j];
}
// point antic at my display list
*atari_dlisth = 0x06;
*atari_dlistl = 0x00;
*atari_colbk = 0x00;
*atari_colpf0 = 0x2f;
*atari_colpf1 = 0x3f;
*atari_colpf2 = 0x00;
*atari_colpf3 = 0x1f;
*atari_prior = 0x00;
*atari_chbase = 0xf8;
*atari_dmactl = 0x22;
*atari_skctl = 0x2;
*atari_chactl = 0x2;
}
void restore()
{
int i;
// Restore memory
for (i=0x0; i!=0x4000; ++i)
{
atari_base[i] = store_mem[i];
}
// Restore custom chips
{
//gtia
for (i=0xc000; i!=0xc020; i++)
{
atari_base[i] = store_mem[i];
}
//pokey1/2
for (i=0xe800; i!=0xe820; i++)
{
atari_base[i] = store_mem[i];
}
//antic
for (i=0xd400; i!=0xd410; i++)
{
atari_base[i] = store_mem[i];
}
}
//*atari_portb = store_portb;
}
firmware_5200/hexdump.h
#pragma once
void hexdump_pure(void const * str, int length);
firmware_5200/main.c_DISKDEBUG
#include "integer.h"
#include "regs.h"
#include "pause.h"
#include "printf.h"
#include "joystick.h"
#include "freeze.h"
#include "simpledir.h"
#include "simplefile.h"
#include "fileselector.h"
#include "atari_drive_emulator.h"
extern char ROM_DIR[];
// FUNCTIONS in here
// i) pff init - NOT USED EVERYWHERE
// ii) file selector - kind of crap, no fine scrolling - NOT USED EVERYWHERE
// iii) cold reset atari (clears base ram...)
// iv) start atari (begins paused)
// v) freeze/resume atari - NOT USED EVERYWHERE!
// vi) menu for various options - NOT USED EVERYWHERE!
// vii) pause - TODO - base this on pokey clock...
// standard ZPU IN/OUT use...
// OUT1 - 6502 settings (pause,reset,speed)
// pause_n: bit 0
// reset_n: bit 1
// turbo: bit 2-4: meaning... 0=1.79Mhz,1=3.58MHz,2=7.16MHz,3=14.32MHz,4=28.64MHz,5=57.28MHz,etc.
// ram_select: bit 5-7:
// RAM_SELECT : in std_logic_vector(2 downto 0); -- 64K,128K,320KB Compy, 320KB Rambo, 576K Compy, 576K Rambo, 1088K, 4MB
// rom_select: bit 8-13:
// ROM_SELECT : in std_logic_vector(5 downto 0); -- 16KB ROM Bank
#define BIT_REG(op,mask,shift,name,reg) \
int get_ ## name() \
{ \
int val = *reg; \
return op((val>>shift)&mask); \
} \
void set_ ## name(int param) \
{ \
int val = *reg; \
\
val = (val&~(mask<<shift)); \
val |= op(param)<<shift; \
\
*reg = val; \
}
#define BIT_REG_RO(op,mask,shift,name,reg) \
int get_ ## name() \
{ \
int val = *reg; \
return op((val>>shift)&mask); \
}
BIT_REG(,0x1,0,pause_6502,zpu_out1)
BIT_REG(,0x1,1,reset_6502,zpu_out1)
BIT_REG(,0x3f,2,turbo_6502,zpu_out1)
BIT_REG(,0x7,8,ram_select,zpu_out1)
BIT_REG(,0x3f,11,rom_select,zpu_out1)
BIT_REG_RO(,0x1,8,hotkey_softboot,zpu_in1)
BIT_REG_RO(,0x1,9,hotkey_coldboot,zpu_in1)
BIT_REG_RO(,0x1,10,hotkey_fileselect,zpu_in1)
BIT_REG_RO(,0x1,11,hotkey_settings,zpu_in1)
void
wait_us(int unsigned num)
{
// pause counter runs at pokey frequency - should be 1.79MHz
int unsigned cycles = (num*230)>>7;
*zpu_pause = cycles;
}
void memset8(void * address, int value, int length)
{
char * mem = address;
while (length--)
*mem++=value;
}
void memset32(void * address, int value, int length)
{
int * mem = address;
while (length--)
*mem++=value;
}
void clear_64k_ram()
{
memset8((void *)0x200000, 0, 65536); // SRAM, if present (TODO)
memset32((void *)0x800000, 0, 16384);
}
void
reboot(int cold)
{
set_pause_6502(1);
if (cold)
{
clear_64k_ram();
}
set_reset_6502(1);
// Do nothing in here - this resets the memory controller!
set_reset_6502(0);
set_pause_6502(0);
}
unsigned char toatarichar(int val)
{
int inv = val>=128;
if (inv)
{
val-=128;
}
if (val>='A' && val<='Z')
{
val+=-'A'+33;
}
else if (val>='a' && val<='z')
{
val+=-'a'+33+64;
}
else if (val>='0' && val<='9')
{
val+=-'0'+16;
}
else if (val>=32 && val<=47)
{
val+=-32;
}
else
{
val = 0;
}
if (inv)
{
val+=128;
}
return val;
}
int debug_pos;
int debug_adjust;
unsigned char volatile * baseaddr;
void clearscreen()
{
unsigned volatile char * screen;
for (screen=(unsigned volatile char *)40000+atari_regbase; screen!=(unsigned volatile char *)(atari_regbase+40000+1024); ++screen)
*screen = 0x00;
}
void char_out ( void* p, char c)
{
unsigned char val = toatarichar(c);
if (debug_pos>=0)
{
*(baseaddr+debug_pos) = val|debug_adjust;
++debug_pos;
}
}
// Memory usage...
// 0x410000-0x41FFFF (0xc10000 in zpu space) = directory cache - 64k
// 0x420000-0x43FFFF (0xc20000 in zpu space) = freeze backup
struct SimpleFile * files[6];
void loadromfile(struct SimpleFile * file, int size, void * ram_address)
{
ram_address += 0x800000;
int read = 0;
file_read(file, ram_address, size, &read);
}
void loadrom(char const * path, int size, void * ram_address)
{
if (SimpleFile_OK == file_open_name(path, files[4]))
{
loadromfile(files[4], size, ram_address);
}
}
void loadrom_indir(struct SimpleDirEntry * entries, char const * filename, int size, void * ram_address)
{
if (SimpleFile_OK == file_open_name_in_dir(entries, filename, files[4]))
{
loadromfile(files[4], size, ram_address);
}
}
void loadosrom()
{
if (file_size(files[5]) == 0x4000)
{
loadromfile(files[5],0x4000, (void *)0x704000);
}
else if (file_size(files[5]) ==0x2800)
{
loadromfile(files[5],0x2800, (void *)0x705800);
}
}
int main(void)
{
{
char buffer[512];
freeze_init((void*)0xc20000); // 128k
debug_pos = -1;
debug_adjust = 0;
baseaddr = (unsigned char volatile *)(40000 + atari_regbase);
set_pause_6502(1);
set_reset_6502(1);
set_reset_6502(0);
set_turbo_6502(1);
set_rom_select(1);
set_ram_select(0);
init_printf(0, char_out);
reboot(1);
// for (;;);
wait_us(5000000);
disk_debug();
//for (;;);
wait_us(10000000);
}
/* disk_initialize();
{
char buffer[512];
freeze_init((void*)0xc20000); // 128k
debug_pos = -1;
debug_adjust = 0;
baseaddr = (unsigned char volatile *)(40000 + atari_regbase);
set_pause_6502(1);
set_reset_6502(1);
set_reset_6502(0);
set_turbo_6502(1);
set_rom_select(1);
set_ram_select(0);
init_printf(0, char_out);
reboot(1);
// for (;;);
wait_us(5000000);
set_pause_6502(1);
freeze();
debug_pos = 0;
printf("Hello world 3");
debug_pos = 40;
int i;
for (i=0;i!=512; ++i)
{
buffer[i] = i;
}
int volatile * x = (int volatile *)0x4000;
int volatile * y = (int volatile *)&buffer[0];
for (i=0;i!=128; ++i)
{
x[i] = y[i];
}
hexdump_pure(0x4000,8);
hexdump_pure(0x41f8,8);
debug_pos = 120;
printf(" Writing sector ");
n_actual_mmc_sector = 30;
disk_writeflush();
printf(" Wrote sector ");
for (i=0;i!=128; ++i)
{
x[i] = 0;
}
n_actual_mmc_sector = -1;
disk_readp(&buffer[0],30,0,512);
hexdump_pure(0x4000,8);
hexdump_pure(0x41f8,8);
debug_pos = 200;
disk_readp(&buffer[0],0x103,0,512);
hexdump_pure(0x4000,8);
hexdump_pure(0x41f8,8);
debug_pos = 280;
disk_readp(&buffer[0],0,0,512);
hexdump_pure(0x4000,8);
hexdump_pure(0x41f8,8);
debug_pos = 360;
printf("OK...");
//for (;;);
wait_us(10000000);
}*/
/* spiInit();
set_spi_clock_freq();
mmcReadLoop();*/
/* spiInit();
set_spi_clock_freq();
char buffer[512];
while (1)
{
mmcReadLoop();
wait_us(500);
}*/
int i;
for (i=0; i!=6; ++i)
{
files[i] = (struct SimpleFile *)alloca(file_struct_size());
file_init(files[i]);
}
freeze_init((void*)0xc20000); // 128k
debug_pos = -1;
debug_adjust = 0;
baseaddr = (unsigned char volatile *)(40000 + atari_regbase);
set_pause_6502(1);
set_reset_6502(1);
set_reset_6502(0);
set_turbo_6502(1);
set_rom_select(1);
set_ram_select(2);
init_printf(0, char_out);
// TODO...
if (SimpleFile_OK == dir_init((void *)0xc10000, 65536))
{
// printf("DIR init ok\n");
init_drive_emulator();
struct SimpleDirEntry * entries = dir_entries(ROM_DIR);
//loadrom_indir(entries,"atarixl.rom",0x4000, (void *)0x704000);
if (SimpleFile_OK == file_open_name_in_dir(entries, "atarixl.rom", files[5]))
{
loadosrom();
}
/*loadrom_indir(entries,"xlhias.rom",0x4000, (void *)0x708000);
loadrom_indir(entries,"ultimon.rom",0x4000, (void *)0x70c000);
loadrom_indir(entries,"osbhias.rom",0x4000, (void *)0x710000);
loadrom_indir(entries,"osborig.rom",0x2800, (void *)0x715800);
loadrom_indir(entries,"osaorig.rom",0x2800, (void *)0x719800);*/
loadrom_indir(entries,"ataribas.rom",0x2000,(void *)0x700000);
//ROM = xlorig.rom,0x4000, (void *)0x704000
//ROM = xlhias.rom,0x4000, (void *)0x708000
//ROM = ultimon.rom,0x4000, (void *)0x70c000
//ROM = osbhias.rom,0x4000, (void *)0x710000
//ROM = osborig.rom,0x2800, (void *)0x715800
//ROM = osaorig.rom,0x2800, (void *)0x719800
//
//ROM = ataribas.rom,0x2000,(void *)0x700000
//--SDRAM_BASIC_ROM_ADDR <= "111"&"000000" &"00000000000000";
//--SDRAM_OS_ROM_ADDR <= "111"&rom_select &"00000000000000";
reboot(1);
run_drive_emulator();
}
else
{
//printf("DIR init failed\n");
}
reboot(1);
for (;;) actions();
}
// struct SimpleFile * file = alloca(file_struct_size());
// printf("Opening file\n");
// if (SimpleFile_OK == file_open_name("GUNPOWDR.ATR",file))
// {
// printf("FILE open ok\n");
//
// set_drive_status(0,file);
//
// }
// else
// {
// printf("FILE open failed\n");
// }
char const * get_ram()
{
static char const * ram[] =
{
"64K",
"128K",
"320K(Compy)",
"320K(Rambo)",
"576K(Compy)",
"576K(Rambo)",
"1MB",
"4MB"
};
return ram[get_ram_select()];
/*switch(get_ram_select())
{
case 0:
return "64K";
case 1:
return "128K";
case 2:
return "320K(Compy)";
case 3:
return "320K(Rambo)";
case 4:
return "576K(Compy)";
case 5:
return "576K(Rambo)";
case 6:
return "1MB";
case 7:
return "4MB";
}*/
}
/*
int settings()
{
struct joystick_status joy;
joy.x_ = joy.y_ = joy.fire_ = 0;
int row = 0;
int done = 0;
for (;!done;)
{
// Render
clearscreen();
debug_pos = 0;
debug_adjust = 0;
printf("Se");
debug_adjust = 128;
printf("ttings");
debug_pos = 80;
debug_adjust = row==0 ? 128 : 0;
printf("Turbo:%dx", get_turbo_6502());
debug_pos = 120;
debug_adjust = row==1 ? 128 : 0;
printf("Ram:%s", get_ram());
debug_pos = 160;
debug_adjust = row==2 ? 128 : 0;
{
printf("Rom:%s", file_name(files[5]));
}
debug_pos = 240;
int i;
for (i=1;i!=5;++i)
{
int temp = debug_pos;
debug_adjust = row==i+2 ? 128 : 0;
char buffer[20];
describe_disk(i-1,&buffer[0]);
printf("Drive %d:%s %s", i, file_name(files[i-1]), &buffer[0]);
debug_pos = temp+40;
}
debug_pos = 400;
debug_adjust = row==7 ? 128 : 0;
printf("Cartridge 8k simple");
debug_pos = 480;
debug_adjust = row==8 ? 128 : 0;
printf("Exit");
// Slow it down a bit
wait_us(100000);
// move
joystick_wait(&joy,WAIT_QUIET);
joystick_wait(&joy,WAIT_EITHER);
row+=joy.y_;
if (row<0) row = 0;
if (row>8) row = 8;
switch (row)
{
case 0:
{
int turbo = get_turbo_6502();
if (joy.x_==1) turbo<<=1;
if (joy.x_==-1) turbo>>=1;
if (turbo>16) turbo = 16;
if (turbo<1) turbo = 1;
set_turbo_6502(turbo);
}
break;
case 1:
{
int ram_select = get_ram_select();
ram_select+=joy.x_;
if (ram_select<0) ram_select = 0;
if (ram_select>7) ram_select = 7;
set_ram_select(ram_select);
}
break;
case 2:
{
if (joy.x_ || joy.fire_)
{
filter = filter_roms;
file_selector(files[5]);
loadosrom();
}
}
break;
case 3:
case 4:
case 5:
case 6:
{
if (joy.x_>0)
{
// Choose new disk
filter = filter_disks;
file_selector(files[row-3]);
set_drive_status(row-3,files[row-3]);
}
else if(joy.x_<0)
{
// Remove disk
file_init(files[row-3]);
set_drive_status(row-3,0);
}
else if (joy.fire_)
{
{
// Swap files
struct SimpleFile * temp = files[row-3];
files[row-3] = files[0];
files[0] = temp;
}
{
// Swap disks
struct SimpleFile * temp = get_drive_status(row-3);
set_drive_status(row-3, get_drive_status(0));
set_drive_status(0,temp);
}
}
}
break;
case 7:
{
if (joy.fire_)
{
filter = filter_roms;
file_selector(files[4]);
loadrom(file_name(files[4]),0x2000,(void *)0x700000);
return 1;
}
}
break;
case 8:
if (joy.fire_)
{
done = 1;
}
break;
}
}
return 0;
}
*/
void actions()
{
// Show some activity!
//*atari_colbk = *atari_random;
// Hot keys
/* if (get_hotkey_softboot())
{
reboot(0);
}
else */if (get_hotkey_coldboot())
{
reboot(1);
}
/* else if (get_hotkey_settings())
{
set_pause_6502(1);
freeze();
debug_pos = 0;
int do_reboot = settings();
debug_pos = -1;
restore();
if (do_reboot)
reboot(1);
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff