kopia lustrzana https://github.com/Jean-MarcHarvengt/MCUME
565 wiersze
12 KiB
C
565 wiersze
12 KiB
C
#include "atari800.h"
|
|
#include <string.h>
|
|
#include "memory.h"
|
|
#include "cpu.h"
|
|
#include "atari.h"
|
|
#include "akey.h"
|
|
#include "pokey.h"
|
|
#include <Arduino.h>
|
|
//#include "romatariosa.h"
|
|
#include "romatariosb.h"
|
|
//#include "romatarixl.h"
|
|
#include "antic.h"
|
|
#include "gtia.h"
|
|
#include "pia.h"
|
|
#include "colours.h"
|
|
#include "emuapi.h"
|
|
#if HAS_SND
|
|
#include "pokeysnd.h"
|
|
#endif
|
|
|
|
|
|
// Controllers
|
|
typedef struct
|
|
{
|
|
// All values are 1 or 0, or perhaps not...
|
|
int left;
|
|
int right;
|
|
int up;
|
|
int down;
|
|
int trig;
|
|
|
|
} CONTROLLER;
|
|
|
|
|
|
// global variables
|
|
//EXTMEM static unsigned char MemPool[8*1024*1024];
|
|
unsigned char * memory=NULL; //&MemPool[0];
|
|
int tv_mode = TV_PAL;
|
|
UBYTE INPUT_key_consol;
|
|
|
|
|
|
// local variables
|
|
static CONTROLLER cont1, cont2;
|
|
static int INPUT_key_code = AKEY_NONE;
|
|
static int INPUT_key_shift = 0;
|
|
|
|
/* MEMORY MAP INDEX (0 is invalid)
|
|
* 0-3FFF RAM (read/write)
|
|
* 4000-7FFF RAM (read/write)
|
|
* 8000-9FFF BASIC right CART 8K
|
|
* A000-BFFF BASIC left CART 8K
|
|
* D000-D0FF GTIA regs
|
|
* D200-D2FF POKEY regs
|
|
* D300-D3FF PIA regs
|
|
* D400-D4FF ANTIC regs
|
|
* D800-FFFF OS ROM (ro)
|
|
* E000 I/O expansion
|
|
*/
|
|
|
|
|
|
// memory CPU read (load) handler
|
|
uint8 Atari_GetByte(uint16 addr)
|
|
{
|
|
if (addr < MEMORY_SIZE) { // MAPPER_RAM
|
|
return(memory[addr]);
|
|
}
|
|
else if ( (addr >= 0xD000) && (addr < 0xD100) ) { // MAPPER_GTIA
|
|
return GTIA_GetByte(addr,1);
|
|
}
|
|
else if ( (addr >= 0xD200) && (addr < 0xD300) ) { // MAPPER_POKEY
|
|
return POKEY_GetByte(addr,1);
|
|
}
|
|
else if ( (addr >= 0xD300) && (addr < 0xD400) ) { // MAPPER_PIA
|
|
return PIA_GetByte(addr);
|
|
}
|
|
else if ( (addr >= 0xD400) && (addr < 0xD500) ) { // MAPPER_ANTIC
|
|
return ANTIC_GetByte(addr,1);
|
|
}
|
|
else if ((addr >= 0xD800) && (addr < 0x10000)) { // MAPPER_ROM (bios)
|
|
//return(memory[addr]);
|
|
return(romos[addr-0xD800]);
|
|
}
|
|
|
|
//case MAPPER_IOEXP: // I/O exp read
|
|
// return IOEXPread(addr);
|
|
|
|
return 0xff;
|
|
}
|
|
|
|
// memory CPU write (store) handler
|
|
void Atari_PutByte(uint16 addr, uint8 byte)
|
|
{
|
|
if (addr < 0x8000) { // MAPPER_RAM
|
|
memory[addr] = byte;
|
|
}
|
|
else if (addr < 0xC000) { // MAPPER_ROM
|
|
}
|
|
else if ( (addr >= 0xD000) && (addr < 0xD100) ) { // MAPPER_GTIA
|
|
GTIA_PutByte(addr, byte);
|
|
}
|
|
else if ( (addr >= 0xD200) && (addr < 0xD300) ) { // MAPPER_POKEY
|
|
POKEY_PutByte(addr, byte);
|
|
}
|
|
else if ( (addr >= 0xD300) && (addr < 0xD400) ) { // MAPPER_PIA
|
|
PIA_PutByte(addr, byte);
|
|
}
|
|
else if ( (addr >= 0xD400) && (addr < 0xD500) ) { // MAPPER_ANTIC
|
|
ANTIC_PutByte(addr, byte);
|
|
}
|
|
|
|
//case MAPPER_IOEXP: // I/O exp write
|
|
// IOEXPwrite(addr, byte);
|
|
}
|
|
|
|
|
|
static void INPUT_Frame(void)
|
|
{
|
|
int i;
|
|
static int last_key_code = AKEY_NONE;
|
|
static int last_key_break = 0;
|
|
|
|
if (cont1.trig) GTIA_TRIG[0]=0; else GTIA_TRIG[0]=1;
|
|
|
|
|
|
i = (INPUT_key_code == AKEY_BREAK);
|
|
if (i && !last_key_break) {
|
|
if (POKEY_IRQEN & 0x80) {
|
|
POKEY_IRQST &= ~0x80;
|
|
CPU_GenerateIRQ();
|
|
}
|
|
}
|
|
last_key_break = i;
|
|
POKEY_SKSTAT |= 0xc;
|
|
if (INPUT_key_shift)
|
|
POKEY_SKSTAT &= ~8;
|
|
|
|
if (INPUT_key_code < 0) {
|
|
//if (CASSETTE_press_space) {
|
|
// INPUT_key_code = AKEY_SPACE;
|
|
// CASSETTE_press_space = 0;
|
|
//}
|
|
//else {
|
|
last_key_code = AKEY_NONE;
|
|
//}
|
|
}
|
|
if ((INPUT_key_code&~0x17) == AKEY_SHFTCTRL) {
|
|
INPUT_key_code = AKEY_NONE;
|
|
}
|
|
if (INPUT_key_code >= 0) {
|
|
//emu_printi(INPUT_key_code);
|
|
POKEY_SKSTAT &= ~4;
|
|
if ((INPUT_key_code ^ last_key_code) & ~AKEY_SHFTCTRL) {
|
|
/* ignore if only shift or control has changed its state */
|
|
last_key_code = INPUT_key_code;
|
|
POKEY_KBCODE = (UBYTE) INPUT_key_code;
|
|
if (POKEY_IRQEN & 0x40) {
|
|
if (POKEY_IRQST & 0x40) {
|
|
POKEY_IRQST &= ~0x40;
|
|
CPU_GenerateIRQ();
|
|
}
|
|
else {
|
|
/* keyboard over-run */
|
|
POKEY_SKSTAT &= ~0x40;
|
|
/* assert(CPU_IRQ != 0); */
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// check keyboard and set kbcode on VBI (not for A800)
|
|
void INPUT_Scanline(void)
|
|
{
|
|
// if (cont1.trig) GTIA_TRIG[0]=0; else GTIA_TRIG[0]=1;
|
|
}
|
|
|
|
|
|
static void load_CART(char * cartname)
|
|
{
|
|
int flen = emu_FileSize(cartname);
|
|
int f = emu_FileOpen(cartname, "r+b");
|
|
if (flen < 16384) {
|
|
//emu_FileRead(&memory[0xA000], flen, f);
|
|
emu_printf("8k");
|
|
for(int i=0; i<flen; i++) memory[0xA000 + i] = emu_FileGetc(f);
|
|
}
|
|
else {
|
|
emu_printf("16k");
|
|
//emu_FileRead(&memory[0x8000], flen, f);
|
|
for(int i=0; i<flen; i++) memory[0x8000 + i] = emu_FileGetc(f);
|
|
}
|
|
|
|
emu_FileClose(f);
|
|
}
|
|
|
|
|
|
|
|
|
|
void add_esc(UWORD address, UBYTE esc_code)
|
|
{
|
|
memory[address++] = 0xf2; /* ESC */
|
|
memory[address++] = esc_code; /* ESC CODE */
|
|
memory[address] = 0x60; /* RTS */
|
|
}
|
|
|
|
int Atari_PORT(int num)
|
|
{
|
|
int nibble_0 = 0xff;
|
|
int nibble_1 = 0xff;
|
|
|
|
if (num == 0)
|
|
{
|
|
if (cont1.left) nibble_0 &= ~0x04;
|
|
if (cont1.right) nibble_0 &= ~0x08;
|
|
if (cont1.up) nibble_0 &= ~0x01;
|
|
if (cont1.down) nibble_0 &= ~0x02;
|
|
if (cont2.left) nibble_1 &= ~0x04;
|
|
if (cont2.right) nibble_1 &= ~0x08;
|
|
if (cont2.up) nibble_1 &= ~0x01;
|
|
if (cont2.down) nibble_1 &= ~0x02;
|
|
}
|
|
return (nibble_1 << 4) | nibble_0;
|
|
}
|
|
|
|
static void Initialise(void)
|
|
{
|
|
int i;
|
|
|
|
emu_printf("Initialising ...");
|
|
|
|
// Set up memory area
|
|
memset(memory, 0, MEMORY_SIZE);
|
|
memset(memory+0x8000, 0xff, 0x4000);
|
|
|
|
// init controllers
|
|
memset(&cont1, 0, sizeof(CONTROLLER));
|
|
memset(&cont2, 0, sizeof(CONTROLLER));
|
|
|
|
|
|
// Load bios to address 0xF800
|
|
//for (i = 0; i < 0x2800; i++)
|
|
//{
|
|
// memory[0xD800 + i] = romos[i];
|
|
//}
|
|
//add_esc(0xe459, ESC_SIOV);
|
|
}
|
|
|
|
#define INV_KEY 0
|
|
|
|
const int16_t keyboardAsciiConv[] = // Ascii to Spectrum keys
|
|
{
|
|
/* 0x00 */ INV_KEY,
|
|
/* 0x01 */ INV_KEY,
|
|
/* 0x02 */ INV_KEY,
|
|
/* 0x03 */ INV_KEY,
|
|
/* 0x04 */ INV_KEY,
|
|
/* 0x05 */ INV_KEY,
|
|
/* 0x06 */ INV_KEY,
|
|
/* 0x07 */ INV_KEY,
|
|
/* 0x08 */ INV_KEY,
|
|
/* 0x09 */ 0x2C, // tab
|
|
/* 0x0A */ 0x0C, // enter
|
|
/* 0x0B */ INV_KEY,
|
|
/* 0x0C */ INV_KEY,
|
|
/* 0x0D */ INV_KEY,
|
|
/* 0x0E */ INV_KEY,
|
|
/* 0x0F */ INV_KEY,
|
|
/* 0x10 */ INV_KEY,
|
|
/* 0x11 */ INV_KEY,
|
|
/* 0x12 */ INV_KEY,
|
|
/* 0x13 */ INV_KEY,
|
|
/* 0x14 */ INV_KEY,
|
|
/* 0x15 */ INV_KEY,
|
|
/* 0x16 */ INV_KEY,
|
|
/* 0x17 */ INV_KEY,
|
|
/* 0x18 */ INV_KEY,
|
|
/* 0x19 */ INV_KEY,
|
|
/* 0x1A */ INV_KEY,
|
|
/* 0x1B */ INV_KEY, // esc
|
|
/* 0x1C */ INV_KEY,
|
|
/* 0x1D */ INV_KEY,
|
|
/* 0x1E */ INV_KEY,
|
|
/* 0x1F */ INV_KEY,
|
|
/* 0x20 */ 0x21, // space
|
|
/* 0x21 */ 95, // ! exclamation mark
|
|
/* 0x22 */ 94, // " double quote
|
|
/* 0x23 */ 90, // # dies
|
|
/* 0x24 */ 88, // $ dollar
|
|
/* 0x25 */ 93, // % percent
|
|
/* 0x26 */ 91, // & ampercent
|
|
/* 0x27 */ INV_KEY, // ' singlequote
|
|
/* 0x28 */ 112, // ( bracket left
|
|
/* 0x29 */ 114, // ) bracket right
|
|
/* 0x2A */ 0x0E, // * mult
|
|
/* 0x2B */ 0x06, // + plus
|
|
/* 0x2C */ 0x20, // , comma
|
|
/* 0x2D */ 0x0E, // - minus
|
|
/* 0x2E */ 0x22, // . period
|
|
/* 0x2F */ 0x26, // / slash
|
|
/* 0x30 */ 0x32, // 0
|
|
/* 0x31 */ 0x1F, // 1
|
|
/* 0x32 */ 0x1E, // 2
|
|
/* 0x33 */ 0x1A, // 3
|
|
/* 0x34 */ 0x18, // 4
|
|
/* 0x35 */ 0x1D, // 5
|
|
/* 0x36 */ 0x1B, // 6
|
|
/* 0x37 */ 0x33, // 7
|
|
/* 0x38 */ 0x35, // 8
|
|
/* 0x39 */ 0x30, // 9
|
|
/* 0x3A */ 66, // : colon
|
|
/* 0x3B */ 0x02, // ; semi colon
|
|
/* 0x3C */ 0x36, // <
|
|
/* 0x3D */ 0x0F, // = equal
|
|
/* 0x3E */ 0x37, // >
|
|
/* 0x3F */ 102, // ?
|
|
/* 0x40 */ 117, // @
|
|
/* 0x41 */ INV_KEY, // A
|
|
/* 0x42 */ INV_KEY, // B
|
|
/* 0x43 */ INV_KEY, // C
|
|
/* 0x44 */ INV_KEY, // D
|
|
/* 0x45 */ INV_KEY, // E
|
|
/* 0x46 */ INV_KEY, // F
|
|
/* 0x47 */ INV_KEY, // G
|
|
/* 0x48 */ INV_KEY, // H
|
|
/* 0x49 */ INV_KEY, // I
|
|
/* 0x4A */ INV_KEY, // J
|
|
/* 0x4B */ INV_KEY, // K
|
|
/* 0x4C */ INV_KEY, // L
|
|
/* 0x4D */ INV_KEY, // M
|
|
/* 0x4E */ INV_KEY, // N
|
|
/* 0x4F */ INV_KEY, // O
|
|
/* 0x50 */ INV_KEY, // P
|
|
/* 0x51 */ INV_KEY, // Q
|
|
/* 0x52 */ INV_KEY, // R
|
|
/* 0x53 */ INV_KEY, // S
|
|
/* 0x54 */ INV_KEY, // T
|
|
/* 0x55 */ INV_KEY, // U
|
|
/* 0x56 */ INV_KEY, // V
|
|
/* 0x57 */ INV_KEY, // W
|
|
/* 0x58 */ INV_KEY, // X
|
|
/* 0x59 */ INV_KEY, // Y
|
|
/* 0x5A */ INV_KEY, // Z
|
|
/* 0x5B */ INV_KEY, // square bracket open
|
|
/* 0x5C */ INV_KEY, // backslach
|
|
/* 0x5D */ INV_KEY, // square braquet close
|
|
/* 0x5E */ INV_KEY, // ^ circonflex
|
|
/* 0x5F */ INV_KEY, // _ undescore
|
|
/* 0x60 */ INV_KEY, // `backquote
|
|
/* 0x61 */ 0x3F, // a
|
|
/* 0x62 */ 0x15, // b
|
|
/* 0x63 */ 0x12, // c
|
|
/* 0x64 */ 0x3A, // d
|
|
/* 0x65 */ 0x2A, // e
|
|
/* 0x66 */ 0x38, // f
|
|
/* 0x67 */ 0x3D, // g
|
|
/* 0x68 */ 0x39, // h
|
|
/* 0x69 */ 0x0D, // i
|
|
/* 0x6A */ 0x01, // j
|
|
/* 0x6B */ 0x05, // k
|
|
/* 0x6C */ 0x00, // l
|
|
/* 0x6D */ 0x25, // m
|
|
/* 0x6E */ 0x23, // n
|
|
/* 0x6F */ 0x08, // o
|
|
/* 0x70 */ 0x0A, // p
|
|
/* 0x71 */ 0x2F, // q
|
|
/* 0x72 */ 0x28, // r
|
|
/* 0x73 */ 0x3E, // s
|
|
/* 0x74 */ 0x2D, // t
|
|
/* 0x75 */ 0x0B, // u
|
|
/* 0x76 */ 0x10, // v
|
|
/* 0x77 */ 0x2E, // w
|
|
/* 0x78 */ 0x15, // x
|
|
/* 0x79 */ 0x2B, // y
|
|
/* 0x7A */ 0x17, // z
|
|
/* 0x7B */ INV_KEY, // curly bracket open
|
|
/* 0x7C */ INV_KEY, // or
|
|
/* 0x7D */ INV_KEY, // curly bracket close
|
|
/* 0x7E */ INV_KEY, // tilt
|
|
/* 0x7F */ 0x34, // backspace
|
|
|
|
/* 0xC0 */ INV_KEY,
|
|
/* 0xC1 */ INV_KEY,
|
|
/* 0xC2 */ INV_KEY, // F1
|
|
/* 0xC3 */ INV_KEY, // F2
|
|
/* 0xC4 */ INV_KEY, // F3
|
|
/* 0xC5 */ INV_KEY, // F4
|
|
/* 0xC6 */ INV_KEY, // F5
|
|
/* 0xC7 */ INV_KEY, // F6
|
|
/* 0xC8 */ INV_KEY, // F7
|
|
/* 0xC9 */ INV_KEY, // F8
|
|
/* 0xCA */ INV_KEY, // F9
|
|
/* 0xCB */ INV_KEY, // F10
|
|
/* 0xCC */ INV_KEY,
|
|
/* 0xCD */ INV_KEY,
|
|
/* 0xCE */ INV_KEY,
|
|
/* 0xCF */ INV_KEY,
|
|
/* 0xD0 */ INV_KEY,
|
|
/* 0xD1 */ INV_KEY,
|
|
/* 0xD2 */ INV_KEY,
|
|
/* 0xD3 */ INV_KEY,
|
|
/* 0xD4 */ INV_KEY, // DEL
|
|
/* 0xD5 */ INV_KEY,
|
|
/* 0xD6 */ INV_KEY,
|
|
/* 0xD7 */ INV_KEY, // U
|
|
/* 0xD8 */ INV_KEY, // L
|
|
/* 0xD9 */ INV_KEY, // R
|
|
/* 0xDA */ INV_KEY, // D
|
|
/* 0xDB */ INV_KEY,
|
|
/* 0xDC */ INV_KEY,
|
|
/* 0xDD */ INV_KEY,
|
|
/* 0xDE */ INV_KEY,
|
|
/* 0xDF */ INV_KEY
|
|
};
|
|
|
|
|
|
static int ik; // joypad key
|
|
static int ihk; // I2C keyboard key
|
|
static int iusbhk; // USB keyboard key
|
|
static int prevhk; // previous keyboard key
|
|
|
|
void emu_KeyboardOnDown(int keymodifer, int key) {
|
|
int keyCode = -1; //INV_KEY;
|
|
if ((key >=0xc0) && (key <=0xdf)) {
|
|
keyCode = ((key-0xc0) & 0x1f) + 0x80;
|
|
}
|
|
else {
|
|
keyCode = key & 0x7f;
|
|
}
|
|
|
|
//emu_printh(key);
|
|
//emu_printh(keyCode);
|
|
|
|
if (keyCode != -1) {
|
|
iusbhk = keyCode;
|
|
}
|
|
}
|
|
|
|
void emu_KeyboardOnUp(int keymodifer, int key) {
|
|
iusbhk = 0;
|
|
}
|
|
|
|
void at8_Input(int click) {
|
|
ik = emu_GetPad();
|
|
ihk = emu_ReadI2CKeyboard();
|
|
}
|
|
|
|
void at8_Init(void)
|
|
{
|
|
int i;
|
|
|
|
// Palette
|
|
for (i = 0; i < PALETTE_SIZE; i++)
|
|
{
|
|
emu_SetPaletteEntry(R32(colourtable[i]), G32(colourtable[i]), B32(colourtable[i]), i);
|
|
}
|
|
|
|
#if HAS_SND
|
|
emu_sndInit();
|
|
POKEYSND_Init(POKEYSND_FREQ_17_APPROX, 44100, 1, POKEYSND_BIT16);
|
|
#endif
|
|
|
|
emu_printf("Allocating RAM");
|
|
if (memory == NULL) memory = emu_Malloc(MEMORY_SIZE);
|
|
|
|
Initialise();
|
|
}
|
|
|
|
|
|
|
|
void at8_Step(void)
|
|
{
|
|
int k = ik;
|
|
int hk = ihk;
|
|
if (iusbhk) hk = iusbhk;
|
|
|
|
CONTROLLER * which;
|
|
|
|
if (k & 0x8000) which=&cont2;
|
|
else which=&cont1;
|
|
|
|
// Start
|
|
if (k & MASK_KEY_USER1)
|
|
INPUT_key_consol &= ~0x01;
|
|
else
|
|
INPUT_key_consol |= 0x01;
|
|
|
|
// Select
|
|
if (k & MASK_KEY_USER2)
|
|
INPUT_key_consol &= ~0x02;
|
|
else
|
|
INPUT_key_consol |= 0x02;
|
|
|
|
// OPTION
|
|
if (k & MASK_KEY_USER3)
|
|
INPUT_key_consol &= ~0x04;
|
|
else
|
|
INPUT_key_consol |= 0x04;
|
|
|
|
if (hk != 0) {
|
|
int key = keyboardAsciiConv[hk];
|
|
if (key != INV_KEY) INPUT_key_code = key;
|
|
}
|
|
else {
|
|
INPUT_key_code = AKEY_NONE;
|
|
}
|
|
|
|
// Keyboard
|
|
INPUT_Frame();
|
|
|
|
// Joystick side button, trigger and directions
|
|
if (k & MASK_JOY2_BTN)
|
|
which->trig = 1;
|
|
else
|
|
which->trig = 0;
|
|
if (k & MASK_JOY2_DOWN)
|
|
which->down = 1;
|
|
else
|
|
which->down = 0;
|
|
if (k & MASK_JOY2_UP)
|
|
which->up = 1;
|
|
else
|
|
which->up = 0;
|
|
if (k & MASK_JOY2_RIGHT)
|
|
which->left = 1;
|
|
else
|
|
which->left = 0;
|
|
if (k & MASK_JOY2_LEFT)
|
|
which->right = 1;
|
|
else
|
|
which->right = 0;
|
|
|
|
GTIA_Frame();
|
|
ANTIC_Frame(1);
|
|
emu_DrawVsync();
|
|
POKEY_Frame();
|
|
}
|
|
|
|
|
|
|
|
void at8_Start(char * cartname)
|
|
{
|
|
load_CART(cartname);
|
|
|
|
emu_printf("antic");
|
|
ANTIC_Initialise();
|
|
emu_printf("gtia");
|
|
GTIA_Initialise();
|
|
emu_printf("pia");
|
|
PIA_Initialise();
|
|
emu_printf("pokey");
|
|
POKEY_Initialise();
|
|
PORTA = 0x00;
|
|
ANTIC_NMIEN = 0x00;
|
|
ANTIC_NMIST = 0x00;
|
|
memory[0x244] = 1;
|
|
GTIA_TRIG[0]=1;
|
|
GTIA_TRIG[1]=1;
|
|
GTIA_TRIG[2]=1;
|
|
GTIA_TRIG[3]=1;
|
|
emu_printf("6502 reset");
|
|
CPU_Reset();
|
|
|
|
emu_printf("init done");
|
|
}
|