Project

General

Profile

« Previous | Next » 

Revision 195

Added by markw almost 11 years ago

Merged in cartridge support from Hias. To make space some space improvements were done to freeze and drive emulator. Lots of scope for more

View differences:

firmware/debug.c
#include "debug.h"
#include "pause.h"
int xpos;
int ypos;
int onoff; // perhaps we can plot to another address buffer, which we can scroll through in the monitor?
int debugoffsetval;
void topofscreen()
{
xpos = 0;
ypos = 0;
}
void setxpos(int val)
{
xpos = val;
}
void setypos(int val)
{
ypos = val;
}
void initdebug(int onoff_in)
{
xpos = 0;
ypos = 0;
onoff = onoff_in;
}
void nextline()
{
int i;
xpos=0;
ypos+=1;
if (ypos==24)
ypos = 0;
for (i=0;i!=40;++i)
plot(0,i,ypos);
//Delay100usX(5000);
}
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;
}
unsigned char hextoatarichar(int val)
{
if (val>=0 && val<=9)
{
val+=+16;
}
else if (val>=10 && val<=15)
{
val+=-10+33;
}
return val;
}
void plot(unsigned char val, int x, int y)
{
if (onoff == 0) return;
unsigned char volatile * baseaddr = (unsigned char volatile *)(screen_address + atari_regbase);
*(baseaddr + y*40+x) = val+debugoffsetval;
}
void debugoffset(int x)
{
debugoffsetval = x;
}
void debug(char const * str)
{
while (1)
{
int val = *str++;
if (val==0) break;
if (val=='\n') {nextline();continue;};
plot(toatarichar(val),xpos,ypos);
++xpos;
if (xpos==40)
{
nextline();
}
}
debugoffsetval = 0;
}
void plotnext(unsigned char val)
{
plot(val,xpos,ypos);
++xpos;
if (xpos==40) nextline();
}
void plotnextnumber(unsigned short val)
{
plotnext(hextoatarichar((val&0xf000)>>12));
plotnext(hextoatarichar((val&0x0f00)>>8));
plotnext(hextoatarichar((val&0x00f0)>>4));
plotnext(hextoatarichar((val&0x000f)>>0));
debugoffsetval = 0;
}
void hexdump(unsigned void const * str, int length)
{
nextline();
for (;length>0;--length)
{
unsigned char val= *str++;
// LH 10 cols = char
// RH 20 cols = hex
plot(toatarichar(val),xpos,ypos);
plot(hextoatarichar((val&0xf0) >> 4),xpos*2+20,ypos);
plot(hextoatarichar(val&0xf),xpos*2+21,ypos);
++xpos;
if (xpos==10)
{
nextline();
}
}
nextline();
}
void hexdump_pure(unsigned void const * str, int length)
{
xpos = xpos&0xfffe;
for (;length>0;--length)
{
unsigned char val= *str++;
plot(hextoatarichar((val&0xf0) >> 4),xpos++,ypos);
plot(hextoatarichar(val&0xf),xpos++,ypos);
if (xpos==40)
{
nextline();
}
}
}
firmware/debug.h
#ifndef debug_h
#define debug_h
void topofscreen();
void setxpos(int val);
void setypos(int val);
unsigned char toatarichar(int val);
unsigned char hextoatarichar(int val);
void plot(unsigned char val, int x, int y);
void plotnext(unsigned char val);
void plotnextnumber(unsigned short val);
void debugoffset(int x);
void debug(char const * str);
void hexdump(char const * str, int length);
void hexdump_pure(char const * str, int length);
void initdebug(int onoff_in);
#endif //debug_h
firmware/5200/mainmenu.c
{
if (joy.x_ || joy.fire_)
{
filter = filter_roms;
fil_type = fil_type_rom;
filter = filter_specified;
file_selector(files[5]);
loadosrom();
}
......
{
if (joy.fire_)
{
filter = filter_bins;
fil_type = fil_type_bin;
filter = filter_specified;
file_selector(files[4]);
//loadrom_indir(entries,"acid5200.rom",0x8000,(void *)0x004000); // XXX - just for 5200 test... do not commit!
if (row == 3)
firmware/Makefile
MINSTARTUP_SRC = mycrt0.s
MINSTARTUP_OBJ = $(patsubst $(STARTUP_DIR)/%.s,$(BUILD_DIR)/%.o,$(MINSTARTUP_SRC))
COMMON_SRC = fileutils.c fileselector.c pokey/uart.c hexdump.c printf/printf.c fat/pff_file.c fat/pff.c common/utils.c
COMMON_SRC = cartridge.c fileutils.c fileselector.c pokey/uart.c hexdump.c printf/printf.c fat/pff_file.c fat/pff.c common/utils.c
SDCARD_SRC = sd_direct/diskio_mmc.c sd_direct/spi.c sd_direct/mmc2.c
A800_SRC_LIGHT = a800/freeze.c a800/mainmenu.c atari_drive_emulator.c
A800_SRC = ${A800_SRC_LIGHT} a800/joystick.c a800/regs.c
......
HOST_CFLAGS += -I. -Isd_direct -Iprintf -Ifat -Icommon -Isdram_common -DDISABLE_UART_RX
LFLAGS = -nostartfiles -Wl,--relax -g -Os
LFLAGS = -nostartfiles -Wl,--relax -g -Os -Wl,-Map=out.map
#LFLAGS = -nostartfiles -Os
firmware/a800/freeze.c
// TODO - almost the same as 5200 one
// skctl, chbase and lack of portb to merge into one file...
void memset8(void * address, int value, int length);
// Moving this outside function removes gcc pulling in memcpy
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
};
void freeze_init(void * memory)
{
store_mem = (unsigned volatile char *)memory;
......
atari_base = (unsigned volatile char *)atari_regbase;
}
void memcp8(char const volatile * from, char volatile * to, int offset, int len)
{
from+=offset;
to+=offset;
while (len--)
*to++ = *from++;
}
void freeze()
{
int i;
// store custom chips
store_portb = *atari_portb;
{
//backup last value written to custom chip regs
//gtia
for (i=0xd000; i!=0xd020; i++)
{
store_mem[i] = custom_mirror[i];
atari_base[i] = 0;
}
memcp8(custom_mirror,store_mem,0xd000,0x20);
//pokey1/2
for (i=0xd200; i!=0xd220; i++)
{
store_mem[i] = custom_mirror[i];
atari_base[i] = 0;
}
memcp8(custom_mirror,store_mem,0xd200,0x20);
//antic
for (i=0xd400; i!=0xd410; i++)
{
store_mem[i] = custom_mirror[i];
atari_base[i] = 0;
}
memcp8(custom_mirror,store_mem,0xd400,0x10);
// Write 0 to custom chip regs
memset8(atari_base+0xd000,0,0x20);
memset8(atari_base+0xd200,0,0x20);
memset8(atari_base+0xd400,0,0x10);
}
*atari_portb = 0xff;
// Copy 64k ram to sdram
// Atari screen memory...
for (i=0x0; i!=0xd000; ++i)
{
store_mem[i] = atari_base[i];
}
for (i=0xd800; i!=0x10000; ++i)
{
store_mem[i] = atari_base[i];
}
memcp8(atari_base,store_mem,0,0xd000);
memcp8(atari_base,store_mem,0xd800,0x2800);
//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];
}
memcp8(dl,atari_base+0x600,0,sizeof(dl));
// point antic at my display list
*atari_dlisth = 0x06;
......
void restore()
{
int i;
// Restore memory
for (i=0x0; i!=0xd000; ++i)
{
atari_base[i] = store_mem[i];
}
for (i=0xd800; i!=0x10000; ++i)
{
atari_base[i] = store_mem[i];
}
memcp8(store_mem,atari_base,0,0xd000);
memcp8(store_mem,atari_base,0xd800,0x2800);
// Restore custom chips
{
//gtia
for (i=0xd000; i!=0xd020; i++)
{
atari_base[i] = store_mem[i];
}
//pokey1/2
for (i=0xd200; i!=0xd220; i++)
{
atari_base[i] = store_mem[i];
}
//antic
for (i=0xd400; i!=0xd410; i++)
{
atari_base[i] = store_mem[i];
}
// gtia
memcp8(store_mem,atari_base,0xd000,0x20);
// pokey
memcp8(store_mem,atari_base,0xd200,0x20);
// antic
memcp8(store_mem,atari_base,0xd400,0x10);
}
*atari_portb = store_portb;
firmware/a800/mainmenu.c
debug_pos = 400;
debug_adjust = row==7 ? 128 : 0;
printf("Cartridge 8k simple");
printf("Cart: %s", get_cart_select() ? file_name(files[4]) : "NONE");
debug_pos = 480;
debug_adjust = row==8 ? 128 : 0;
......
{
if (joy.x_ || joy.fire_)
{
filter = filter_roms;
fil_type = fil_type_rom;
filter = filter_specified;
file_selector(files[5]);
loadosrom();
}
......
break;
case 7:
{
if (joy.fire_)
{
filter = filter_roms;
if (joy.x_>0) {
fil_type = fil_type_car;
filter = filter_specified;
file_selector(files[4]);
loadrom(file_name(files[4]),0x2000,0x700000);
return 1;
unsigned char mode = 0; // TODO load_car(files[4]);
set_cart_select(mode);
if (mode) {
return 1;
}
}
else if (joy.x_<0) {
file_init(files[4]);
set_cart_select(0);
}
}
break;
case 8:
firmware/aeon_lite/memory.h
#define DIR_INIT_MEMSIZE 65536
#define FREEZE_MEM (SDRAM_BASE + 0xa0000)
// disabled
#define CARTRIDGE_MEM ((void*) 0)
// offset in SDRAM area
#define ROM_OFS 0xc0000
#define atari_regbase ((void*) 0x10000)
#define atari_regmirror ((void*) 0x20000)
#define config_regbase ((void*) 0x40000)
firmware/atari_drive_emulator.c
void getCommand(struct command * cmd)
{
int expchk;
int i;
//printf("Waiting for command\n");
//USART_Data_Ready();
......
{
actions();
}
cmd->deviceId = USART_Receive_Byte();
for (i=0;i!=5;++i)
((char *)cmd)[i] = USART_Receive_Byte();
/*cmd->deviceId = USART_Receive_Byte();
cmd->command = USART_Receive_Byte();
cmd->aux1 = USART_Receive_Byte();
cmd->aux2 = USART_Receive_Byte();
cmd->chksum = USART_Receive_Byte();
cmd->chksum = USART_Receive_Byte();*/
while (0 == USART_Command_Line())
{
actions();
firmware/cartridge.c
#include "memory.h"
#include "simpledir.h"
#include "cartridge.h"
#include "log.h"
struct CartDef {
unsigned char carttype; // type from CAR header
unsigned char mode; // mode used in cartridge emulation
unsigned short size; // size in k
};
// 8k modes (0xA000-$BFFF)
#define TC_MODE_OFF 0x00 // cart disabled
#define TC_MODE_8K 0x01 // 8k banks at $A000
#define TC_MODE_ATARIMAX1 0x02 // 8k using Atarimax 1MBit compatible banking
#define TC_MODE_ATARIMAX8 0x03 // 8k using Atarimax 8MBit compatible banking
#define TC_MODE_OSS 0x04 // 16k OSS cart, M091 banking
#define TC_MODE_SDX64 0x08 // SDX 64k cart, $D5Ex banking
#define TC_MODE_DIAMOND64 0x09 // Diamond GOS 64k cart, $D5Dx banking
#define TC_MODE_EXPRESS64 0x0A // Express 64k cart, $D57x banking
#define TC_MODE_ATRAX128 0x0C // Atrax 128k cart
#define TC_MODE_WILLIAMS64 0x0D // Williams 64k cart
// 16k modes (0x8000-$BFFF)
//#define TC_MODE_FLEXI 0x20 // flexi mode
#define TC_MODE_16K 0x21 // 16k banks at $8000-$BFFF
#define TC_MODE_MEGAMAX16 0x22 // MegaMax 16k mode (up to 2MB)
#define TC_MODE_BLIZZARD 0x23 // Blizzard 16k
#define TC_MODE_SIC 0x24 // Sic!Cart 512k
#define TC_MODE_MEGA_16 0x28 // switchable MegaCarts
#define TC_MODE_MEGA_32 0x29
#define TC_MODE_MEGA_64 0x2A
#define TC_MODE_MEGA_128 0x2B
#define TC_MODE_MEGA_256 0x2C
#define TC_MODE_MEGA_512 0x2D
#define TC_MODE_MEGA_1024 0x2E
#define TC_MODE_MEGA_2048 0x2F
#define TC_MODE_XEGS_32 0x30 // non-switchable XEGS carts
#define TC_MODE_XEGS_64 0x31
#define TC_MODE_XEGS_128 0x32
#define TC_MODE_XEGS_256 0x33
#define TC_MODE_XEGS_512 0x34
#define TC_MODE_XEGS_1024 0x35
#define TC_MODE_SXEGS_32 0x38 // switchable XEGS carts
#define TC_MODE_SXEGS_64 0x39
#define TC_MODE_SXEGS_128 0x3A
#define TC_MODE_SXEGS_256 0x3B
#define TC_MODE_SXEGS_512 0x3C
#define TC_MODE_SXEGS_1024 0x3D
static struct CartDef cartdef[] = {
{ 1, TC_MODE_8K, 8 },
{ 2, TC_MODE_16K, 16 },
{ 8, TC_MODE_WILLIAMS64, 64 },
{ 9, TC_MODE_EXPRESS64, 64 },
{ 10, TC_MODE_DIAMOND64, 64 },
{ 11, TC_MODE_SDX64, 64 },
{ 12, TC_MODE_XEGS_32, 32 },
{ 13, TC_MODE_XEGS_64, 64 },
{ 14, TC_MODE_XEGS_128, 128 },
{ 15, TC_MODE_OSS, 16 },
{ 17, TC_MODE_ATRAX128, 128 },
{ 23, TC_MODE_XEGS_256, 256 },
{ 24, TC_MODE_XEGS_512, 512 },
{ 26, TC_MODE_MEGA_16, 16 },
{ 27, TC_MODE_MEGA_32, 32 },
{ 28, TC_MODE_MEGA_64, 64 },
{ 29, TC_MODE_MEGA_128, 128 },
{ 30, TC_MODE_MEGA_256, 256 },
{ 31, TC_MODE_MEGA_512, 512 },
{ 33, TC_MODE_SXEGS_32, 32 },
{ 34, TC_MODE_SXEGS_64, 64 },
{ 35, TC_MODE_SXEGS_128, 128 },
{ 36, TC_MODE_SXEGS_256, 256 },
{ 37, TC_MODE_SXEGS_512, 512 },
{ 40, TC_MODE_BLIZZARD, 16 },
{ 41, TC_MODE_ATARIMAX1, 128 },
{ 42, TC_MODE_ATARIMAX8, 1024 },
{ 56, TC_MODE_SIC, 512 },
{ 0, 0, 0 }
};
int load_car(struct SimpleFile* file)
{
if (CARTRIDGE_MEM == 0) {
LOG("no cartridge memory\n");
return 0;
}
int len;
enum SimpleFileStatus ok;
unsigned char header[16];
ok = file_read(file, header, 16, &len);
if (ok != SimpleFile_OK || len != 16) {
LOG("cannot read cart header\n");
return 0;
}
unsigned char carttype = header[7];
// search for cartridge definition
struct CartDef* def = cartdef;
while (def->carttype && def->carttype != carttype) {
def++;
}
if (def->carttype == 0) {
LOG("illegal cart type %d\n", carttype);
return 0;
}
// read data in 8k chunks
unsigned int block;
for(block = 0; block < def->size >> 3; block++) {
ok = file_read(file, CARTRIDGE_MEM + block * 0x2000, 0x2000, &len);
if (ok != SimpleFile_OK || len != 0x2000) {
LOG("cannot read cart data\n");
return 0;
}
}
LOG("cart type: %d size: %dk\n",
def->mode, def->size);
return def->mode;
}
firmware/cartridge.h
#ifndef CARTRIDGE_H
#define CARTRIDGE_H
#include "simplefile.h"
int load_car(struct SimpleFile* file);
#endif
firmware/fat/pff_file.c
file_check_open(file);
pf_lseek(offsetFromStart);
res = pf_lseek(offsetFromStart);
return translateStatus(res);
}
firmware/fileselector.c
return res;
}
int filter_roms(struct SimpleDirEntry * entry)
char const * fil_type = 0;
char const * fil_type_rom = "ROM";
char const * fil_type_bin = "BIN";
char const * fil_type_car = "CAR";
int filter_specified(struct SimpleDirEntry * entry)
{
if (dir_is_subdir(entry)) return 1;
char const * f = dir_filename(entry);
return (compare_ext(f,"ROM"));
return (compare_ext(f,fil_type));
}
int filter_bins(struct SimpleDirEntry * entry)
{
if (dir_is_subdir(entry)) return 1;
char const * f = dir_filename(entry);
return (compare_ext(f,"BIN"));
}
void dir_of(char * dir, char const * path); // TODO - into simpledir
void file_selector(struct SimpleFile * file)
firmware/fileselector.h
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 char const * fil_type;
extern char const * fil_type_rom;
extern char const * fil_type_bin;
extern char const * fil_type_car;
int filter_specified(struct SimpleDirEntry * entry);
extern int (* filter)(struct SimpleDirEntry * entry);
firmware/linux/curses_screen.c
snprintf(tmpstr, MAXSTR, "out1: %08x", out1);
mvwaddstr(status_window, 0, 1, tmpstr);
snprintf(tmpstr, MAXSTR, "- - tur %02x ram %02x rom %02x",
snprintf(tmpstr, MAXSTR, "- - tur %02x ram %02x rom %02x car %02x",
(out1 >> 2) & 0x3f,
(out1 >> 8) & 0x07,
(out1 >> 11) & 0x3f);
(out1 >> 11) & 0x3f,
(out1 >> 17) & 0x3f);
if (out1 & 1) {
tmpstr[0] = 'P';
}
firmware/linux/linux_memory.c
void* atari_regbase;
void* atari_regmirror;
void* config_regbase;
void* CARTRIDGE_MEM;
#define SRAM_SIZE (512*1024)
#define SDRAM_SIZE (8*1024*1024)
#define ATARI_SIZE (64*1024)
#define CONFIG_SIZE (256)
#define CARTRIDGE_SIZE (2*1024*1024)
uint8_t sram_memory[SRAM_SIZE];
uint32_t sdram_memory[SDRAM_SIZE / 4];
uint8_t atari_memory[ATARI_SIZE];
uint8_t atari_mirror_memory[ATARI_SIZE];
uint32_t config_memory[CONFIG_SIZE/4];
uint32_t cartridge_memory[CARTRIDGE_SIZE / 4];
void init_memory(void)
{
......
memset(atari_memory, ATARI_SIZE, 0);
memset(atari_mirror_memory, ATARI_SIZE, 0);
memset(config_memory, CONFIG_SIZE, 0);
memset(cartridge_memory, CARTRIDGE_SIZE, 0);
SRAM_BASE = sram_memory;
SDRAM_BASE = sdram_memory;
atari_regbase = atari_memory;
atari_regmirror = atari_mirror_memory;
config_regbase = config_memory;
CARTRIDGE_MEM = cartridge_memory;
zpu_in1 = (int *)(0*4+config_regbase);
zpu_in2 = (int *)(1*4+config_regbase);
firmware/linux/memory.h
extern void* SDRAM_BASE;
extern void* SRAM_BASE;
extern void* CARTRIDGE_MEM;
// Memory usage...
// 0x410000-0x44FFFF (0xc10000 in zpu space) = directory cache - 256k
firmware/log.h
#ifndef LOG_H
#define LOG_H
#ifdef LINUX_BUILD
#include "curses_screen.h"
#define LOG(x...) print_log(x)
#else
#define LOG(x...) do { } while(0)
#endif
#endif
firmware/main.h
#include "simpledir.h"
#include "simplefile.h"
#include "fileselector.h"
#include "cartridge.h"
#ifdef LINUX_BUILD
#include "curses_screen.h"
......
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(,0x3f,17,cart_select,zpu_out1)
BIT_REG_RO(,0x1,8,hotkey_softboot,zpu_in1)
BIT_REG_RO(,0x1,9,hotkey_coldboot,zpu_in1)
......
set_turbo_6502(1);
set_rom_select(1);
set_ram_select(2);
set_cart_select(0);
init_printf(0, char_out);
firmware/sdram_common/memory.h
#define DIR_INIT_MEM (SDRAM_BASE + 0x410000)
#define DIR_INIT_MEMSIZE 262144
#define FREEZE_MEM (SDRAM_BASE + 0x450000)
#define CARTRIDGE_MEM (SDRAM_BASE + 0x500000)
// offset into SDRAM
#define ROM_OFS 0x700000
firmware/test_freeze.c
#include "memory.h"
#include "regs.h"
void clearscreen()
{
/* unsigned volatile char * screen;
for (screen=(unsigned volatile char *)(screen_address+atari_regbase); screen!=(unsigned volatile char *)(atari_regbase+screen_address+1024); ++screen)
*screen = 0x00;*/
}
#include "stdlib.h"
#include "stdio.h"
void memset8(void * address, int value, int length)
{
char * mem = address;
while (length--)
*mem++=value;
}
#undef atari_regbase
static char * atari_regbase = (char *)malloc(65536);
#undef atari_regmirror
static char * atari_regmirror = (char *)malloc(65536);
#include "freeze.h"
#include "freeze.c"
#include "a800/freeze_ci.c"
#include "regs.c"
int main(void)
......
{
*((atari_regmirror+i)) = i%256-2;
}
freeze();
/*for (int i=0; i!=64*1024; ++i)
for (int i=0; i!=64*1024; ++i)
{
fprintf(stderr,"i:%x val:%x\n",i,*((unsigned char *)(buffer+i)));
if (i%256!=*((unsigned char *)(buffer+i)))
fprintf(stderr,"i:%x stored:%x regbase:%x mirror:%x\n",i,
*((unsigned char *)(buffer+i)),
*((unsigned char *)(atari_regbase+i)),
*((unsigned char *)(atari_regmirror+i))
);
/* if (i%256!=*((unsigned char *)(buffer+i)))
{
fprintf(stderr,"!!FAIL!%d %d %d", i, i%256, *(unsigned char *)(atari_regbase+i));
return -1;
}
}*/
}*/
}
return 0;
for (int i=0;i!=0xd000; ++i)
{

Also available in: Unified diff