kopia lustrzana https://github.com/Jean-MarcHarvengt/MCUME
786 wiersze
14 KiB
C
786 wiersze
14 KiB
C
/*****************************************************************************
|
|
|
|
This file is part of x2600, the Atari 2600 Emulator
|
|
===================================================
|
|
|
|
Copyright 1996 Alex Hornby. For contributions see the file CREDITS.
|
|
|
|
This software is distributed under the terms of the GNU General Public
|
|
License. This is free software with ABSOLUTELY NO WARRANTY.
|
|
|
|
See the file COPYING for Details.
|
|
|
|
$Id: memory.c,v 2.23 1997/04/06 02:19:12 ahornby Exp $
|
|
******************************************************************************/
|
|
//This file was modified from its original version for use in PocketVCS
|
|
// by Stuart Russell
|
|
|
|
/*
|
|
* Holds the memory access routines to both memory and memory mapped
|
|
* i/o, hence memory.c
|
|
*
|
|
* Uses GNU C extensions.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include "types.h"
|
|
#include "address.h"
|
|
#include "vmachine.h"
|
|
#include "display.h"
|
|
#include "raster.h"
|
|
#include "tiasound.h"
|
|
#include "collision.h"
|
|
#include "col_mask.h"
|
|
#include "options.h"
|
|
#include "keyboard.h"
|
|
#include "sound.h"
|
|
#include "resource.h"
|
|
|
|
|
|
extern CLOCK clkcount;
|
|
extern CLOCK clk;
|
|
extern int beamadj;
|
|
//extern keyboard_keypad();
|
|
extern keytrig();
|
|
extern keyjoy();
|
|
extern keycons();
|
|
extern int nOptions_Landscape;
|
|
extern int nOptions_SoundOn;
|
|
|
|
|
|
/* Undecoded Read, for executable code etc. */
|
|
/* a: address to read */
|
|
/* returns: byte at address a */
|
|
BYTE
|
|
undecRead (ADDRESS a)
|
|
{
|
|
if (a & 0x1000)
|
|
return theRom[a & 0xfff];
|
|
else
|
|
return theRam[a & 0x7f];
|
|
}
|
|
|
|
|
|
__inline void
|
|
bank_switch_write (ADDRESS a, BYTE b)
|
|
{
|
|
a&=0xfff;
|
|
switch (base_opts.bank)
|
|
{
|
|
|
|
case 1:
|
|
/* Atari 8k F8 */
|
|
switch (a)
|
|
{
|
|
case 0xff8:
|
|
theRom = &theCart[0];
|
|
break;
|
|
case 0xff9:
|
|
theRom = &theCart[4096];
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
/* Atari 16k F6 */
|
|
switch (a)
|
|
{
|
|
case 0xff6:
|
|
theRom = &theCart[0];
|
|
break;
|
|
case 0xff7:
|
|
theRom = &theCart[4096];
|
|
break;
|
|
case 0xff8:
|
|
theRom = &theCart[8192];
|
|
break;
|
|
case 0xff9:
|
|
theRom = &theCart[12288];
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
/* Parker Brothers 8k E0 */
|
|
{
|
|
ADDRESS a1;
|
|
if (a > 0xfdf && a < 0xfe8)
|
|
{
|
|
a1=(a&0x07)<<10;
|
|
memcpy(&cartScratch[0],&theCart[a1],0x400);
|
|
}
|
|
else if (a > 0xfe7 && a < 0xff0)
|
|
{
|
|
a1=(a&0x07)<<10;
|
|
memcpy(&cartScratch[0x400],&theCart[a1],0x400);
|
|
}
|
|
else if (a > 0xfef && a < 0xff8)
|
|
{
|
|
a1=(a&0x07)<<10;
|
|
memcpy(&cartScratch[0x800],&theCart[a1],0x400);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 4:
|
|
/* CBS Ram Plus FA */
|
|
if (a < 0x100)
|
|
cartRam[a & 0xff]=b;
|
|
else
|
|
{
|
|
switch (a)
|
|
{
|
|
case 0xff8:
|
|
theRom = &theCart[0];
|
|
break;
|
|
case 0xff9:
|
|
theRom = &theCart[4096];
|
|
break;
|
|
case 0xffa:
|
|
theRom = &theCart[8192];
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 5:
|
|
/* Atari 16k + super chip ram F6SC */
|
|
if (a < 0x80)
|
|
cartRam[a & 0x7f] = b;
|
|
else
|
|
{
|
|
switch (a)
|
|
{
|
|
case 0xff6:
|
|
theRom = &theCart[0];
|
|
break;
|
|
case 0xff7:
|
|
theRom = &theCart[4096];
|
|
break;
|
|
case 0xff8:
|
|
theRom = &theCart[8192];
|
|
break;
|
|
case 0xff9:
|
|
theRom = &theCart[12288];
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
__inline BYTE
|
|
bank_switch_read (ADDRESS a)
|
|
{
|
|
BYTE res;
|
|
|
|
a&=0xfff;
|
|
switch (base_opts.bank)
|
|
{
|
|
case 1:
|
|
/* Atari 8k F8 */
|
|
switch (a)
|
|
{
|
|
case 0xff8:
|
|
theRom = &theCart[0];
|
|
break;
|
|
case 0xff9:
|
|
theRom = &theCart[4096];
|
|
break;
|
|
}
|
|
res=theRom[a];
|
|
break;
|
|
|
|
case 2:
|
|
/* Atari 16k F6 */
|
|
switch (a)
|
|
{
|
|
case 0xff6:
|
|
theRom = &theCart[0];
|
|
break;
|
|
case 0xff7:
|
|
theRom = &theCart[4096];
|
|
break;
|
|
case 0xff8:
|
|
theRom = &theCart[8192];
|
|
break;
|
|
case 0xff9:
|
|
theRom = &theCart[12288];
|
|
break;
|
|
}
|
|
res=theRom[a];
|
|
break;
|
|
|
|
case 3:
|
|
/* Parker Brothers 8k E0 */
|
|
/* Parker Brothers 8k E0 */
|
|
{
|
|
ADDRESS a1;
|
|
if (a > 0xfdf && a < 0xfe8)
|
|
{
|
|
a1=(a&0x07)<<10;
|
|
memcpy(&cartScratch[0],&theCart[a1],0x400);
|
|
}
|
|
else if (a > 0xfe7 && a < 0xff0)
|
|
{
|
|
a1=(a&0x07)<<10;
|
|
memcpy(&cartScratch[0x400],&theCart[a1],0x400);
|
|
}
|
|
else if (a > 0xfef && a < 0xff8)
|
|
{
|
|
a1=(a&0x07)<<10;
|
|
memcpy(&cartScratch[0x800],&theCart[a1],0x400);
|
|
}
|
|
}
|
|
res=theRom[a];
|
|
break;
|
|
|
|
case 4:
|
|
/* CBS Ram Plus FA */
|
|
if (a > 0xff && a < 0x200)
|
|
res=cartRam[a & 0xff];
|
|
else
|
|
{
|
|
switch (a)
|
|
{
|
|
case 0xff8:
|
|
theRom = &theCart[0];
|
|
break;
|
|
case 0xff9:
|
|
theRom = &theCart[4096];
|
|
break;
|
|
case 0xffa:
|
|
theRom = &theCart[8192];
|
|
break;
|
|
}
|
|
res=theRom[a];
|
|
}
|
|
break;
|
|
|
|
case 5:
|
|
/* Atari 16k + super chip ram F6SC */
|
|
if (a > 0x7f && a < 0x100)
|
|
res=cartRam[a & 0x7f];
|
|
else
|
|
{
|
|
switch (a)
|
|
{
|
|
case 0xff6:
|
|
theRom = &theCart[0];
|
|
break;
|
|
case 0xff7:
|
|
theRom = &theCart[4096];
|
|
break;
|
|
case 0xff8:
|
|
theRom = &theCart[8192];
|
|
break;
|
|
case 0xff9:
|
|
theRom = &theCart[12288];
|
|
break;
|
|
}
|
|
res=theRom[a];
|
|
}
|
|
break;
|
|
default:
|
|
res=theRom[a];
|
|
break;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
|
|
/* Decoded write to memory */
|
|
/* a: address written to */
|
|
/* b: byte value written */
|
|
void
|
|
decWrite (ADDRESS a, BYTE b)
|
|
{
|
|
int i;
|
|
|
|
/* A Write to the ROM area */
|
|
if (a & 0x1000)
|
|
{
|
|
bank_switch_write (a,b);
|
|
}
|
|
/* A Write to the RAM area in Page 0 and 1 */
|
|
else if ((a & 0x280) == 0x80)
|
|
{
|
|
theRam[a & 0x7f] = b;
|
|
}
|
|
/* TIA */
|
|
else if (!(a & 0x80))
|
|
{
|
|
switch (a & 0x7f)
|
|
{
|
|
case VSYNC:
|
|
if (b & 0x02)
|
|
{
|
|
/* Start vertical sync */
|
|
vbeam_state = VSYNCSTATE;
|
|
}
|
|
break;
|
|
case VBLANK:
|
|
do_vblank (b);
|
|
/* Ground paddle pots */
|
|
if (b & 0x80)
|
|
{
|
|
/* Grounded ports */
|
|
tiaRead[INPT0] = 0x00;
|
|
tiaRead[INPT1] = 0x00;
|
|
}
|
|
else
|
|
{
|
|
/* Processor now measures time for a logic 1 to appear
|
|
at each paddle port */
|
|
tiaRead[INPT0] = 0x80;
|
|
tiaRead[INPT1] = 0x80;
|
|
paddle[0].val = clk;
|
|
paddle[1].val = clk;
|
|
}
|
|
/* Logic for dumped input ports */
|
|
if (b & 0x40)
|
|
{
|
|
if (tiaWrite[VBLANK] & 0x40)
|
|
{
|
|
tiaRead[INPT4] = 0x80;
|
|
tiaRead[INPT5] = 0x80;
|
|
}
|
|
// else
|
|
// {
|
|
// //read_trigger ();
|
|
// }
|
|
}
|
|
tiaWrite[VBLANK] = b;
|
|
break;
|
|
case WSYNC:
|
|
/* Skip to HSYNC pulse */
|
|
do_hsync ();
|
|
break;
|
|
case RSYNC:
|
|
/* used in chip testing */
|
|
//dbg_message(DBG_LOTS,"ARGHH an undocumented RSYNC!\n");
|
|
break;
|
|
case NUSIZ0:
|
|
/*
|
|
printf("P0 nusize: ebeamx=%d, ebeamy=%d, nusize=%02x\n",
|
|
ebeamx, ebeamy, (int)b);
|
|
*/
|
|
pl[0].nusize = b & 0x07;
|
|
ml[0].width = (b & 0x30) >> 4;
|
|
break;
|
|
case NUSIZ1:
|
|
/*
|
|
printf("P1 nusize: ebeamx=%d, ebeamy=%d, nusize=%02x\n",
|
|
ebeamx, ebeamy, (int)b);
|
|
*/
|
|
pl[1].nusize = b & 0x07;
|
|
ml[1].width = (b & 0x30) >> 4;
|
|
break;
|
|
case COLUP0:
|
|
do_unified_change (0, b);
|
|
break;
|
|
case COLUP1:
|
|
do_unified_change (1, b);
|
|
break;
|
|
case COLUPF:
|
|
do_unified_change (2, b);
|
|
break;
|
|
case COLUBK:
|
|
/*printf("BKcolour = %d, line=%d\n", (int)(b>>1), ebeamy); */
|
|
do_unified_change (3, b);
|
|
break;
|
|
case CTRLPF:
|
|
tiaWrite[CTRLPF] = b & 0x37; /* Bitmask 00110111 */
|
|
do_pfraster_change (0, 3, b & 0x01); /* Reflection */
|
|
|
|
/* Normal/Alternate priority */
|
|
do_unified_change(4, (b & 0x04));
|
|
|
|
/* Scores/Not scores */
|
|
do_unified_change(5, (b & 0x02));
|
|
|
|
break;
|
|
case REFP0:
|
|
pl[0].reflect = (b & 0x08) >> 3;
|
|
break;
|
|
case REFP1:
|
|
pl[1].reflect = (b & 0x08) >> 3;
|
|
break;
|
|
case PF0:
|
|
do_pfraster_change (0, 0, b & 0xf0);
|
|
break;
|
|
case PF1:
|
|
do_pfraster_change (0, 1, b);
|
|
break;
|
|
case PF2:
|
|
do_pfraster_change (0, 2, b);
|
|
break;
|
|
case RESP0:
|
|
/* Ghost in pacman!
|
|
if(beamadj == 0) {
|
|
printf("RESP0: ebeamx=%d, ebeamy=%d\n",
|
|
ebeamx, ebeamy);
|
|
show();
|
|
} */
|
|
pl[0].x = ebeamx + beamadj;
|
|
/* As per page 20 Stella Programmers Guide */
|
|
if (pl[0].x < 0)
|
|
pl[0].x = 0;
|
|
break;
|
|
case RESP1:
|
|
/*if(beamadj == 0) {
|
|
printf("RESP1: ebeamx=%d, ebeamy=%d\n",
|
|
ebeamx, ebeamy);
|
|
show();
|
|
} */
|
|
pl[1].x = ebeamx + beamadj;
|
|
/* As per page 20 Stella Programmers Guide */
|
|
if (pl[1].x < 0)
|
|
pl[1].x = 0;
|
|
break;
|
|
case RESM0:
|
|
ml[0].x = ebeamx + beamadj;
|
|
/* As per page 20 Stella Programmers Guide */
|
|
if (ml[0].x < 0)
|
|
ml[0].x = 0;
|
|
break;
|
|
case RESM1:
|
|
ml[1].x = ebeamx + beamadj;
|
|
/* As per page 20 Stella Programmers Guide */
|
|
if (ml[1].x < 0)
|
|
ml[1].x = 0;
|
|
break;
|
|
case RESBL:
|
|
ml[2].x = ebeamx + beamadj;
|
|
/* As per page 20 Stella Programmers Guide */
|
|
if (ml[2].x < 0)
|
|
ml[2].x = 0;
|
|
break;
|
|
case AUDC0:
|
|
if (nOptions_SoundOn) Update_tia_sound(AUDC0,b & 0x0f);
|
|
break;
|
|
case AUDC1:
|
|
if (nOptions_SoundOn) Update_tia_sound(AUDC1,b & 0x0f);
|
|
break;
|
|
case AUDF0:
|
|
if (nOptions_SoundOn) Update_tia_sound(AUDF0,b & 0x1f);
|
|
break;
|
|
case AUDF1:
|
|
if (nOptions_SoundOn) Update_tia_sound(AUDF1,b & 0x1f);
|
|
break;
|
|
case AUDV0:
|
|
if (nOptions_SoundOn) Update_tia_sound(AUDV0 , b & 0x0f);
|
|
break;
|
|
case AUDV1:
|
|
if (nOptions_SoundOn) Update_tia_sound(AUDV1 , b & 0x0f);
|
|
break;
|
|
case GRP0:
|
|
do_plraster_change (0, 0, b);
|
|
do_plraster_change (1, 1, b);
|
|
break;
|
|
case GRP1:
|
|
do_plraster_change (1, 0, b);
|
|
do_plraster_change (0, 1, b);
|
|
ml[2].vdel = ml[2].enabled;
|
|
break;
|
|
case ENAM0:
|
|
ml[0].enabled = b & 0x02;
|
|
if (tiaWrite[RESMP0])
|
|
ml[0].enabled = 0;
|
|
break;
|
|
case ENAM1:
|
|
ml[1].enabled = b & 0x02;
|
|
if (tiaWrite[RESMP1])
|
|
ml[1].enabled = 0;
|
|
break;
|
|
case ENABL:
|
|
ml[2].enabled = b & 0x02;
|
|
break;
|
|
case HMP0:
|
|
pl[0].hmm = (b >> 4);
|
|
break;
|
|
case HMP1:
|
|
pl[1].hmm = (b >> 4);
|
|
break;
|
|
case HMM0:
|
|
ml[0].hmm = (b >> 4);
|
|
break;
|
|
case HMM1:
|
|
ml[1].hmm = (b >> 4);
|
|
break;
|
|
case HMBL:
|
|
ml[2].hmm = (b >> 4);
|
|
break;
|
|
case VDELP0:
|
|
pl[0].vdel_flag = b & 0x01;
|
|
break;
|
|
case VDELP1:
|
|
pl[1].vdel_flag = b & 0x01;
|
|
break;
|
|
case VDELBL:
|
|
ml[2].vdel_flag = b & 0x01;
|
|
break;
|
|
case RESMP0:
|
|
tiaWrite[RESMP0] = b & 0x02;
|
|
if (b & 0x02)
|
|
{
|
|
ml[0].x = pl[0].x + 4;
|
|
ml[0].enabled = 0;
|
|
}
|
|
break;
|
|
case RESMP1:
|
|
tiaWrite[RESMP1] = b & 0x02;
|
|
if (b & 0x02)
|
|
{
|
|
ml[1].x = pl[1].x + 4;
|
|
ml[1].enabled = 0;
|
|
}
|
|
break;
|
|
case HMOVE:
|
|
/* Player 0 */
|
|
if (pl[0].hmm & 0x08)
|
|
pl[0].x += ((pl[0].hmm ^ 0x0f) + 1);
|
|
else
|
|
pl[0].x -= pl[0].hmm;
|
|
if (pl[0].x > 160)
|
|
pl[0].x = -68;
|
|
else if (pl[0].x < -68)
|
|
pl[0].x = 160;
|
|
|
|
/* Player 2 */
|
|
if (pl[1].hmm & 0x08)
|
|
pl[1].x += ((pl[1].hmm ^ 0x0f) + 1);
|
|
else
|
|
pl[1].x -= pl[1].hmm;
|
|
if (pl[1].x > 160)
|
|
pl[1].x = -68;
|
|
else if (pl[1].x < -68)
|
|
pl[1].x = 160;
|
|
|
|
/* Missiles */
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
if (ml[i].hmm & 0x08)
|
|
ml[i].x += ((ml[i].hmm ^ 0x0f) + 1);
|
|
else
|
|
ml[i].x -= ml[i].hmm;
|
|
if (ml[i].x > 160)
|
|
ml[i].x = -68;
|
|
else if (ml[i].x < -68)
|
|
ml[i].x = 160;
|
|
}
|
|
break;
|
|
case HMCLR:
|
|
pl[0].hmm = 0;
|
|
pl[1].hmm = 0;
|
|
for (i = 0; i < 3; i++)
|
|
ml[i].hmm = 0;
|
|
break;
|
|
case CXCLR:
|
|
col_state=0;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (a & 0x2ff)
|
|
{
|
|
/* RIOT I/O ports */
|
|
case SWCHA:
|
|
riotWrite[SWCHA] = b;
|
|
break;
|
|
case SWACNT:
|
|
riotWrite[SWACNT] = b;
|
|
break;
|
|
case SWCHB:
|
|
case SWBCNT:
|
|
/* Do nothing */
|
|
break;
|
|
|
|
/* Timer ports */
|
|
case TIM1T:
|
|
set_timer (0, b, clkcount);
|
|
break;
|
|
case TIM8T:
|
|
set_timer (3, b, clkcount);
|
|
break;
|
|
case TIM64T:
|
|
set_timer (6, b, clkcount);
|
|
break;
|
|
case T1024T:
|
|
set_timer (10, b, clkcount);
|
|
break;
|
|
default:
|
|
//printf ("Unknown write %x\n", a);
|
|
//show ();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* Decoded read from memory */
|
|
/* a: address to read */
|
|
/* returns: byte value from address a */
|
|
BYTE
|
|
decRead (ADDRESS a)
|
|
{
|
|
BYTE res = 65;
|
|
|
|
if (a & 0x1000)
|
|
{
|
|
a = a & 0xfff;
|
|
if (base_opts.bank != 0)
|
|
res= bank_switch_read (a);
|
|
else
|
|
res = theRom[a];
|
|
}
|
|
else if ((a & 0x280) == 0x80)
|
|
{
|
|
res = theRam[a & 0x7f];
|
|
}
|
|
else if (!(a & 0x80))
|
|
{
|
|
switch (a & 0x0f)
|
|
{
|
|
/* TIA */
|
|
case CXM0P:
|
|
res = (col_state & CXM0P_MASK) << 6;
|
|
break;
|
|
case CXM1P:
|
|
res = (col_state & CXM1P_MASK) << 4;
|
|
break;
|
|
case CXP0FB:
|
|
res = (col_state & CXP0FB_MASK) << 2;
|
|
break;
|
|
case CXP1FB:
|
|
res = (col_state & CXP1FB_MASK);
|
|
break;
|
|
case CXM0FB:
|
|
res = (col_state & CXM0FB_MASK) >> 2;
|
|
break;
|
|
case CXM1FB:
|
|
res = (col_state & CXM1FB_MASK) >> 4;
|
|
break;
|
|
case CXBLPF:
|
|
res = (col_state & CXBLPF_MASK) >> 5;
|
|
break;
|
|
case CXPPMM:
|
|
res = (col_state & CXPPMM_MASK) >> 7;
|
|
break;
|
|
case INPT0:
|
|
if (base_opts.lcon== PADDLE)
|
|
{
|
|
tiaRead[INPT0] = do_paddle (0);
|
|
}
|
|
else if (base_opts.lcon== KEYPAD)
|
|
tiaRead[INPT0] = do_keypad (0, 0);
|
|
res = tiaRead[INPT0];
|
|
break;
|
|
case INPT1:
|
|
if (base_opts.lcon== PADDLE)
|
|
{
|
|
tiaRead[INPT1] = do_paddle (1);
|
|
}
|
|
if (base_opts.lcon== KEYPAD)
|
|
tiaRead[INPT1]=do_keypad (0, 1);
|
|
res = tiaRead[INPT1];
|
|
break;
|
|
case INPT2:
|
|
if (base_opts.rcon == KEYPAD)
|
|
tiaRead[INPT1]=do_keypad (1, 0);
|
|
res = tiaRead[INPT2];
|
|
break;
|
|
case INPT3:
|
|
if (base_opts.rcon == KEYPAD)
|
|
tiaRead[INPT3]=do_keypad ( 1, 1);
|
|
res = tiaRead[INPT3];
|
|
break;
|
|
case INPT4:
|
|
switch (base_opts.lcon)
|
|
{
|
|
case KEYPAD:
|
|
tiaRead[INPT4]=do_keypad ( 0, 2);
|
|
break;
|
|
case STICK:
|
|
case PADDLE:
|
|
keytrig();
|
|
res=tiaRead[INPT4];
|
|
break;
|
|
}
|
|
res =tiaRead[INPT4];
|
|
break;
|
|
case INPT5:
|
|
switch (base_opts.rcon)
|
|
{
|
|
case KEYPAD:
|
|
tiaRead[INPT5]=do_keypad (1, 2);
|
|
break;
|
|
case STICK:
|
|
case PADDLE:
|
|
keytrig();
|
|
res=tiaRead[INPT5];
|
|
break;
|
|
}
|
|
res = tiaRead[INPT5];
|
|
break;
|
|
case 0x0e:
|
|
case 0x0f:
|
|
res = 0x0f;
|
|
/* RAM, mapped to page 0 and 1 */
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (a & 0x2ff)
|
|
{
|
|
/* Timer output */
|
|
case INTIM:
|
|
case 0x285:
|
|
case 0x286:
|
|
case TIM1T:
|
|
case TIM8T:
|
|
case TIM64T:
|
|
case T1024T:
|
|
res = do_timer (clkcount);
|
|
/*printf("Timer is %d res is %d\n", res, timer_res); */
|
|
break;
|
|
case SWCHA:
|
|
switch (base_opts.lcon)
|
|
{
|
|
case PADDLE:
|
|
if (base_opts.lcon == PADDLE)
|
|
{
|
|
keytrig();
|
|
res=tiaRead[INPT4];
|
|
}
|
|
else if (base_opts.rcon == PADDLE)
|
|
{
|
|
keytrig();
|
|
res=tiaRead[INPT4];
|
|
}
|
|
break;
|
|
case STICK:
|
|
keyjoy();
|
|
res=riotRead[SWCHA];
|
|
break;
|
|
}
|
|
res = riotRead[SWCHA];
|
|
break;
|
|
/* Switch B is hardwired to input */
|
|
case SWCHB:
|
|
case SWCHB + 0x100:
|
|
keycons ();
|
|
res = riotRead[SWCHB];
|
|
break;
|
|
default:
|
|
//printf ("Unknown read 0x%x\n", a & 0x2ff);
|
|
//show ();
|
|
res = 65;
|
|
break;
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|