add port of aiju's port of games/2600
This commit is contained in:
parent
1195ca910c
commit
abf8c8bf2c
10 changed files with 1224 additions and 0 deletions
35
sys/man/1/atari
Normal file
35
sys/man/1/atari
Normal file
|
@ -0,0 +1,35 @@
|
|||
.SH ATARI 1
|
||||
.SH NAME
|
||||
2600 \- emulator
|
||||
.SH SYNOPSIS
|
||||
.B games/2600
|
||||
[
|
||||
.B -a
|
||||
]
|
||||
.I romfile
|
||||
.SH DESCRIPTION
|
||||
.I 2600
|
||||
is an emulator for the Atari 2600.
|
||||
It exectues the romfile given as an argument,
|
||||
and controls as if using a regular 4-direction 1-button joystick,
|
||||
using \fBspace\fR button and directional keys.
|
||||
The \fBq\fR, \fBw\fR, \fBe\fR, \fBr\fR keys correspond respectively to the reset, select, player 1 difficulty and color mode switches.
|
||||
Other keys:
|
||||
.TP
|
||||
Esc
|
||||
Pause the emulator.
|
||||
.TP
|
||||
Del
|
||||
Exit the emulator.
|
||||
.PP
|
||||
Command line options:
|
||||
.TP
|
||||
.B -a
|
||||
Enable audio output.
|
||||
.SH SOURCE
|
||||
.B /sys/src/games/2600
|
||||
.SH BUGS
|
||||
Yes.
|
||||
.SH HISTORY
|
||||
.I 2600
|
||||
first appeared in 9front (November, 2014).
|
96
sys/src/games/2600/2600.c
Normal file
96
sys/src/games/2600/2600.c
Normal file
|
@ -0,0 +1,96 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <thread.h>
|
||||
#include <draw.h>
|
||||
#include <keyboard.h>
|
||||
#include <emu.h>
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
|
||||
u8int *rom, *rop;
|
||||
u16int bnk[8];
|
||||
int mask = 0xfff;
|
||||
|
||||
void
|
||||
togdifc(void)
|
||||
{
|
||||
p0difc ^= 1<<6;
|
||||
}
|
||||
|
||||
void
|
||||
togbw(void)
|
||||
{
|
||||
bwmod ^= 1<<3;
|
||||
}
|
||||
|
||||
static void
|
||||
loadrom(char *name)
|
||||
{
|
||||
int i, sz, fd;
|
||||
|
||||
fd = open(name, OREAD);
|
||||
if(fd < 0)
|
||||
sysfatal("open: %r");
|
||||
sz = seek(fd, 0, 2);
|
||||
switch(sz){
|
||||
case 0x800: mask = 0x7ff;
|
||||
case 0x1000: break;
|
||||
case 0x3000: bnk[6] = 2<<12;
|
||||
case 0x2000: bnk[5] = 1<<12; break;
|
||||
case 0x4000: for(i=1; i<4; bnk[i+2] = i<<12, i++); break;
|
||||
case 0x8000: for(i=1; i<8; bnk[i] = i<<12, i++); break;
|
||||
default: sysfatal("unsupported ROM size");
|
||||
}
|
||||
rom = malloc(sz);
|
||||
if(rom == nil)
|
||||
sysfatal("malloc: %r");
|
||||
rop = rom;
|
||||
pread(fd, rom, sz, 0);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void
|
||||
threadmain(int argc, char **argv)
|
||||
{
|
||||
ARGBEGIN {
|
||||
case 'a':
|
||||
initaudio();
|
||||
break;
|
||||
default:
|
||||
goto usage;
|
||||
} ARGEND;
|
||||
if(argc != 1){
|
||||
usage:
|
||||
fprint(2, "usage: %s [ -23a ] rom\n", argv0);
|
||||
exits("usage");
|
||||
}
|
||||
loadrom(argv[0]);
|
||||
initemu(PICW, PICH, 4, XRGB32, 1, nil);
|
||||
regkey("a", ' ', 1<<4);
|
||||
regkey("start", 'q', 1<<5);
|
||||
regkey("control", 'w', 1<<6);
|
||||
regkey("up", Kup, 1<<0);
|
||||
regkey("down", Kdown, 1<<1);
|
||||
regkey("left", Kleft, 1<<2);
|
||||
regkey("right", Kright, 1<<3);
|
||||
regkeyfn('e', togdifc);
|
||||
regkeyfn('r', togbw);
|
||||
|
||||
pc = memread(0xFFFC) | memread(0xFFFD) << 8;
|
||||
rP = FLAGI;
|
||||
for(;;){
|
||||
if(paused){
|
||||
qlock(&pauselock);
|
||||
qunlock(&pauselock);
|
||||
}
|
||||
step();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
flush(void)
|
||||
{
|
||||
flushmouse(1);
|
||||
flushscreen();
|
||||
flushaudio(audioout);
|
||||
}
|
81
sys/src/games/2600/aud.c
Normal file
81
sys/src/games/2600/aud.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
|
||||
static int sdiv[2], fdiv[2], cdiv[2], ch[2], sr[2] = {-1,-1};
|
||||
static short sbuf[2000*2], *sbufp;
|
||||
static int audfd;
|
||||
|
||||
#define div(n) if(++cdiv[i] < n) break; cdiv[i] = 0
|
||||
|
||||
static void
|
||||
channel(int i)
|
||||
{
|
||||
sdiv[i] += HZ/114;
|
||||
for(; sdiv[i] >= RATE; sdiv[i] -= RATE)
|
||||
if(fdiv[i] >= (reg[AUDF0 + i] & 31)){
|
||||
fdiv[i] = 0;
|
||||
switch(reg[AUDC0 + i] & 15){
|
||||
case 0: ch[i] = 1; break;
|
||||
case 2: div(15);
|
||||
case 1: ch[i] = sr[i] & 1; sr[i] = sr[i] >> 1 & 7 | (sr[i] << 2 ^ sr[i] << 3) & 8; break;
|
||||
case 4: case 5: ch[i] ^= 1; break;
|
||||
case 12: case 13: div(3); ch[i] ^= 1; break;
|
||||
case 6: case 10: div(16); ch[i] ^= 1; break;
|
||||
case 14: div(46); ch[i] ^= 1; break;
|
||||
case 15: div(3);
|
||||
case 7: case 9: ch[i] = sr[i] & 1; sr[i] = sr[i] >> 1 & 15 | (sr[i] << 2 ^ sr[i] << 4) & 16; break;
|
||||
case 8: ch[i] = sr[i] & 1; sr[i] = sr[i] >> 1 & 255 | (sr[i] << 4 ^ sr[i] << 8) & 256; break;
|
||||
case 3:
|
||||
ch[i] = sr[i] & 1;
|
||||
sr[i] = sr[i] & 15 | sr[i] >> 1 & 240 | (sr[i] << 2 ^ sr[i] << 3) & 256;
|
||||
if((sr[i] & 256) != 0)
|
||||
sr[i] = sr[i] & 496 | sr[i] >> 1 & 7 | (sr[i] << 2 ^ sr[i]) << 3 & 8;
|
||||
break;
|
||||
}
|
||||
}else
|
||||
fdiv[i]++;
|
||||
}
|
||||
|
||||
void
|
||||
sample(void)
|
||||
{
|
||||
int d;
|
||||
|
||||
if(sbufp == nil)
|
||||
return;
|
||||
channel(0);
|
||||
channel(1);
|
||||
d = ch[0] * (reg[AUDV0] & 15) + ch[1] * (reg[AUDV1] & 15);
|
||||
if(sbufp < sbuf + nelem(sbuf) - 1){
|
||||
*sbufp++ = d * 1000;
|
||||
*sbufp++ = d * 1000;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
audioout(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if(sbufp == nil)
|
||||
return -1;
|
||||
if(sbufp == sbuf)
|
||||
return 0;
|
||||
rc = write(audfd, sbuf, (sbufp - sbuf) * 2);
|
||||
if(rc > 0)
|
||||
sbufp -= (rc+1)/2;
|
||||
if(sbufp < sbuf)
|
||||
sbufp = sbuf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
initaudio(void)
|
||||
{
|
||||
audfd = open("/dev/audio", OWRITE);
|
||||
if(audfd < 0)
|
||||
return;
|
||||
sbufp = sbuf;
|
||||
}
|
501
sys/src/games/2600/cpu.c
Normal file
501
sys/src/games/2600/cpu.c
Normal file
|
@ -0,0 +1,501 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <emu.h>
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
|
||||
u16int pc, curpc;
|
||||
u8int rA, rX, rY, rS, rP;
|
||||
int nrdy;
|
||||
|
||||
static u8int
|
||||
fetch8(void)
|
||||
{
|
||||
return memread(pc++);
|
||||
}
|
||||
|
||||
static u16int
|
||||
fetch16(void)
|
||||
{
|
||||
u16int r;
|
||||
|
||||
r = memread(pc++);
|
||||
r |= memread(pc++) << 8;
|
||||
return r;
|
||||
}
|
||||
|
||||
static void
|
||||
push8(u8int v)
|
||||
{
|
||||
memwrite(0x100 | rS--, v);
|
||||
}
|
||||
|
||||
static void
|
||||
push16(u16int v)
|
||||
{
|
||||
memwrite(0x100 | rS--, v >> 8);
|
||||
memwrite(0x100 | rS--, v);
|
||||
}
|
||||
|
||||
static u8int
|
||||
pop8(void)
|
||||
{
|
||||
return memread(0x100 | ++rS);
|
||||
}
|
||||
|
||||
static u16int
|
||||
pop16(void)
|
||||
{
|
||||
u16int v;
|
||||
|
||||
v = memread(0x100 | ++rS);
|
||||
v |= memread(0x100 | ++rS) << 8;
|
||||
return v;
|
||||
}
|
||||
|
||||
#define imm() fetch8()
|
||||
#define zp() memread(fetch8())
|
||||
#define zpX() memread(azpX(rX))
|
||||
#define zpY() memread(azpX(rY))
|
||||
#define abso() memread(fetch16())
|
||||
#define absX() memread(aabsX(rX, 0))
|
||||
#define absY() memread(aabsX(rY, 0))
|
||||
#define indX() memread(aindX())
|
||||
#define indY() memread(aindY(0))
|
||||
|
||||
static u16int
|
||||
azpX(u8int a)
|
||||
{
|
||||
u8int v;
|
||||
|
||||
v = fetch8();
|
||||
memread(v);
|
||||
return v + a;
|
||||
}
|
||||
|
||||
static u16int
|
||||
aabsX(u8int a, int wr)
|
||||
{
|
||||
u16int v, c;
|
||||
|
||||
v = fetch16();
|
||||
c = (u8int)v + a & 0x100;
|
||||
v += a;
|
||||
if(c != 0 || wr)
|
||||
memread(v - c);
|
||||
return v;
|
||||
}
|
||||
|
||||
static u16int
|
||||
aindX(void)
|
||||
{
|
||||
u8int r;
|
||||
u16int a;
|
||||
|
||||
r = fetch8();
|
||||
memread(r);
|
||||
r += rX;
|
||||
a = memread(r++);
|
||||
a |= memread(r) << 8;
|
||||
return a;
|
||||
}
|
||||
|
||||
static u16int
|
||||
aindY(int wr)
|
||||
{
|
||||
u8int r;
|
||||
u16int a, c;
|
||||
|
||||
r = fetch8();
|
||||
a = memread(r++) + rY;
|
||||
c = a & 0x100;
|
||||
a += memread(r) << 8;
|
||||
if(c != 0 || wr)
|
||||
memread(a - c);
|
||||
return a;
|
||||
}
|
||||
|
||||
static void
|
||||
adc(u8int d)
|
||||
{
|
||||
int r;
|
||||
|
||||
if((rP & FLAGD) != 0){
|
||||
r = (rA & 0xf) + (d & 0xf) + (rP & FLAGC);
|
||||
if(r > 0x09)
|
||||
r += 0x06;
|
||||
if(r > 0x1f)
|
||||
r -= 0x10;
|
||||
r += (rA & 0xf0) + (d & 0xf0);
|
||||
}else
|
||||
r = rA + d + (rP & FLAGC);
|
||||
rP &= ~(FLAGN | FLAGZ | FLAGV | FLAGC);
|
||||
if((~(rA ^ d) & (rA ^ r)) & 0x80) rP |= FLAGV;
|
||||
if((rP & FLAGD) != 0 && r > 0x9f)
|
||||
r += 0x60;
|
||||
if(r > 0xFF) rP |= FLAGC;
|
||||
if(r & 0x80) rP |= FLAGN;
|
||||
rA = r;
|
||||
if(rA == 0) rP |= FLAGZ;
|
||||
}
|
||||
|
||||
static u8int
|
||||
nz(u8int d)
|
||||
{
|
||||
rP &= ~(FLAGN | FLAGZ);
|
||||
if(d & 0x80) rP |= FLAGN;
|
||||
if(d == 0) rP |= FLAGZ;
|
||||
return d;
|
||||
}
|
||||
|
||||
static void
|
||||
asl(u16int a)
|
||||
{
|
||||
u8int v;
|
||||
|
||||
rP &= ~(FLAGN | FLAGZ | FLAGC);
|
||||
v = memread(a);
|
||||
memwrite(a, v);
|
||||
if(v & 0x80) rP |= FLAGC;
|
||||
v <<= 1;
|
||||
if(v == 0) rP |= FLAGZ;
|
||||
if(v & 0x80) rP |= FLAGN;
|
||||
memwrite(a, v);
|
||||
}
|
||||
|
||||
static void
|
||||
lsr(u16int a)
|
||||
{
|
||||
u8int v;
|
||||
|
||||
rP &= ~(FLAGN | FLAGZ | FLAGC);
|
||||
v = memread(a);
|
||||
memwrite(a, v);
|
||||
rP |= v & 1;
|
||||
v >>= 1;
|
||||
if(v == 0) rP |= FLAGZ;
|
||||
if(v & 0x80) rP |= FLAGN;
|
||||
memwrite(a, v);
|
||||
}
|
||||
|
||||
static void
|
||||
branch(void)
|
||||
{
|
||||
s8int t;
|
||||
u16int npc;
|
||||
|
||||
t = fetch8();
|
||||
memread(pc);
|
||||
npc = pc + t;
|
||||
if((npc ^ pc) >> 8)
|
||||
memread(pc & 0xff00 | npc & 0xff);
|
||||
pc = npc;
|
||||
}
|
||||
|
||||
static void
|
||||
cmp(u8int a, u8int d)
|
||||
{
|
||||
rP &= ~(FLAGN | FLAGZ | FLAGC);
|
||||
if(a == d) rP |= FLAGZ;
|
||||
if(a >= d) rP |= FLAGC;
|
||||
if((a - d) & 0x80) rP |= FLAGN;
|
||||
}
|
||||
|
||||
static void
|
||||
dec(u16int a)
|
||||
{
|
||||
u8int v;
|
||||
|
||||
v = memread(a);
|
||||
memwrite(a, v);
|
||||
memwrite(a, nz(v - 1));
|
||||
}
|
||||
|
||||
static void
|
||||
inc(u16int a)
|
||||
{
|
||||
u8int v;
|
||||
|
||||
v = memread(a);
|
||||
memwrite(a, v);
|
||||
v = nz(v + 1);
|
||||
memwrite(a, v);
|
||||
}
|
||||
|
||||
static void
|
||||
rol(u16int a)
|
||||
{
|
||||
u8int v, b;
|
||||
|
||||
v = memread(a);
|
||||
memwrite(a, v);
|
||||
b = rP & FLAGC;
|
||||
rP &= ~(FLAGC | FLAGN | FLAGZ);
|
||||
if(v & 0x80) rP |= FLAGC;
|
||||
v = (v << 1) | b;
|
||||
if(v & 0x80) rP |= FLAGN;
|
||||
if(v == 0) rP |= FLAGZ;
|
||||
memwrite(a, v);
|
||||
}
|
||||
|
||||
static void
|
||||
ror(u16int a)
|
||||
{
|
||||
u8int v, b;
|
||||
|
||||
v = memread(a);
|
||||
memwrite(a, v);
|
||||
b = rP & FLAGC;
|
||||
rP &= ~(FLAGC | FLAGN | FLAGZ);
|
||||
rP |= v & 1;
|
||||
v = (v >> 1) | (b << 7);
|
||||
if(v & 0x80) rP |= FLAGN;
|
||||
if(v == 0) rP |= FLAGZ;
|
||||
memwrite(a, v);
|
||||
}
|
||||
|
||||
static void
|
||||
sbc(u8int d)
|
||||
{
|
||||
int r;
|
||||
|
||||
if((rP & FLAGD) != 0){
|
||||
d = ~d;
|
||||
r = (rA & 0xf) + (d & 0xf) + (rP & FLAGC);
|
||||
if(r < 0x10) r -= 0x06;
|
||||
if(r < 0) r += 0x10;
|
||||
r += (rA & 0xf0) + (d & 0xf0);
|
||||
}else
|
||||
r = rA + (u8int)~d + (rP & FLAGC);
|
||||
rP &= ~(FLAGZ | FLAGV | FLAGC | FLAGN);
|
||||
if(((rA ^ d) & (rA ^ r)) & 0x80) rP |= FLAGV;
|
||||
if(r > 0xFF) rP |= FLAGC;
|
||||
else if((rP & FLAGD) != 0)
|
||||
r -= 0x60;
|
||||
rA = r;
|
||||
if(rA == 0) rP |= FLAGZ;
|
||||
if(rA & 0x80) rP |= FLAGN;
|
||||
}
|
||||
|
||||
static void
|
||||
interrupt(int nmi, int brk)
|
||||
{
|
||||
fetch8();
|
||||
push16(pc);
|
||||
push8(rP | 0x20 | (brk << 4));
|
||||
pc = memread(0xFFFA | (!nmi << 2));
|
||||
pc |= memread(0xFFFB | (!nmi << 2)) << 8;
|
||||
rP |= FLAGI;
|
||||
}
|
||||
|
||||
void
|
||||
step(void)
|
||||
{
|
||||
u8int op;
|
||||
u16int a, v;
|
||||
|
||||
if(nrdy){
|
||||
io();
|
||||
return;
|
||||
}
|
||||
curpc = pc;
|
||||
op = fetch8();
|
||||
if(trace)
|
||||
print("%.4x %.2x | %.2x %.2x %.2x | %.2x %.2x | %3d %3d\n", curpc, op, rA, rX, rY, rS, rP, ppux-3, ppuy);
|
||||
switch(op){
|
||||
case 0x00: fetch8(); interrupt(0, 1); return;
|
||||
case 0x01: nz(rA |= indX()); return;
|
||||
case 0x05: nz(rA |= zp()); return;
|
||||
case 0x06: asl(fetch8()); return;
|
||||
case 0x08: memread(pc); push8(rP | 0x30); return;
|
||||
case 0x09: nz(rA |= imm()); return;
|
||||
case 0x0A:
|
||||
rP &= ~(FLAGN | FLAGZ | FLAGC);
|
||||
if(rA & 0x80) rP |= FLAGC;
|
||||
rA <<= 1;
|
||||
if(rA == 0) rP |= FLAGZ;
|
||||
if(rA & 0x80) rP |= FLAGN;
|
||||
memread(pc);
|
||||
return;
|
||||
case 0x0D: nz(rA |= abso()); return;
|
||||
case 0x0E: asl(fetch16()); return;
|
||||
case 0x10: if((rP & FLAGN) == 0) branch(); else fetch8(); return;
|
||||
case 0x11: nz(rA |= indY()); return;
|
||||
case 0x15: nz(rA |= zpX()); return;
|
||||
case 0x16: asl(azpX(rX)); return;
|
||||
case 0x18: rP &= ~FLAGC; memread(pc); return;
|
||||
case 0x19: nz(rA |= absY()); return;
|
||||
case 0x1D: nz(rA |= absX()); return;
|
||||
case 0x1E: asl(aabsX(rX, 1)); return;
|
||||
case 0x20: v = fetch8(); memread(rS|0x100); push16(pc); pc = fetch8() << 8 | v; return;
|
||||
case 0x21: nz(rA &= indX()); return;
|
||||
case 0x24:
|
||||
a = memread(fetch8());
|
||||
rP &= ~(FLAGN | FLAGZ | FLAGV);
|
||||
rP |= a & 0xC0;
|
||||
if((a & rA) == 0) rP |= FLAGZ;
|
||||
return;
|
||||
case 0x25: nz(rA &= zp()); return;
|
||||
case 0x26: rol(fetch8()); return;
|
||||
case 0x28: memread(pc); memread(0x100|rS); rP = pop8() & 0xcf; return;
|
||||
case 0x29: nz(rA &= imm()); return;
|
||||
case 0x2A:
|
||||
a = rP & FLAGC;
|
||||
rP &= ~(FLAGC | FLAGZ | FLAGN);
|
||||
if(rA & 0x80) rP |= FLAGC;
|
||||
rA = (rA << 1) | a;
|
||||
if(rA & 0x80) rP |= FLAGN;
|
||||
if(rA == 0) rP |= FLAGZ;
|
||||
memread(pc);
|
||||
return;
|
||||
case 0x2C:
|
||||
a = memread(fetch16());
|
||||
rP &= ~(FLAGN | FLAGZ | FLAGV);
|
||||
rP |= a & 0xC0;
|
||||
if((a & rA) == 0) rP |= FLAGZ;
|
||||
return;
|
||||
case 0x2D: nz(rA &= abso()); return;
|
||||
case 0x2E: rol(fetch16()); return;
|
||||
case 0x30: if((rP & FLAGN) != 0) branch(); else fetch8(); return;
|
||||
case 0x31: nz(rA &= indY()); return;
|
||||
case 0x35: nz(rA &= zpX()); return;
|
||||
case 0x36: rol(azpX(rX)); return;
|
||||
case 0x38: rP |= FLAGC; memread(pc); return;
|
||||
case 0x39: nz(rA &= absY()); return;
|
||||
case 0x3E: rol(aabsX(rX, 1)); return;
|
||||
case 0x3D: nz(rA &= absX()); return;
|
||||
case 0x40: fetch8(); memread(rS|0x100); rP = pop8() & 0xcf; pc = pop16(); return;
|
||||
case 0x41: nz(rA ^= indX()); return;
|
||||
case 0x45: nz(rA ^= zp()); return;
|
||||
case 0x46: lsr(fetch8()); return;
|
||||
case 0x48: memread(pc); push8(rA); return;
|
||||
case 0x49: nz(rA ^= imm()); return;
|
||||
case 0x4A:
|
||||
rP &= ~(FLAGN | FLAGZ | FLAGC);
|
||||
rP |= rA & 1;
|
||||
rA >>= 1;
|
||||
if(rA == 0) rP |= FLAGZ;
|
||||
if(rA & 0x80) rP |= FLAGN;
|
||||
memread(pc);
|
||||
return;
|
||||
case 0x4C: pc = fetch16(); return;
|
||||
case 0x4D: nz(rA ^= abso()); return;
|
||||
case 0x4E: lsr(fetch16()); return;
|
||||
case 0x51: nz(rA ^= indY()); return;
|
||||
case 0x56: lsr(azpX(rX)); return;
|
||||
case 0x58: rP &= ~FLAGI; memread(pc); return;
|
||||
case 0x50: if((rP & FLAGV) == 0) branch(); else fetch8(); return;
|
||||
case 0x55: nz(rA ^= zpX()); return;
|
||||
case 0x59: nz(rA ^= absY()); return;
|
||||
case 0x5D: nz(rA ^= absX()); return;
|
||||
case 0x5E: lsr(aabsX(rX, 1)); return;
|
||||
case 0x60: fetch8(); memread(rS | 0x100); pc = pop16(); fetch8(); return;
|
||||
case 0x61: adc(indX()); return;
|
||||
case 0x65: adc(zp()); return;
|
||||
case 0x66: ror(fetch8()); return;
|
||||
case 0x68: memread(pc); memread(0x100|rS); nz(rA = pop8()); return;
|
||||
case 0x69: adc(imm()); return;
|
||||
case 0x6A:
|
||||
a = rP & FLAGC;
|
||||
rP &= ~(FLAGC | FLAGN | FLAGZ);
|
||||
rP |= rA & 1;
|
||||
rA = (rA >> 1) | (a << 7);
|
||||
if(rA & 0x80) rP |= FLAGN;
|
||||
if(rA == 0) rP |= FLAGZ;
|
||||
memread(pc);
|
||||
return;
|
||||
case 0x6C: v = fetch16(); pc = memread(v) | (memread((v & 0xFF00) | (u8int)(v+1)) << 8); return;
|
||||
case 0x6D: adc(abso()); return;
|
||||
case 0x6E: ror(fetch16()); return;
|
||||
case 0x70: if((rP & FLAGV) != 0) branch(); else fetch8(); return;
|
||||
case 0x71: adc(indY()); return;
|
||||
case 0x75: adc(zpX()); return;
|
||||
case 0x76: ror(azpX(rX)); return;
|
||||
case 0x78: rP |= FLAGI; memread(pc); return;
|
||||
case 0x79: adc(absY()); return;
|
||||
case 0x7D: adc(absX()); return;
|
||||
case 0x7E: ror(aabsX(rX, 1)); return;
|
||||
case 0x81: memwrite(aindX(), rA); return;
|
||||
case 0x84: memwrite(fetch8(), rY); return;
|
||||
case 0x85: memwrite(fetch8(), rA); return;
|
||||
case 0x86: memwrite(fetch8(), rX); return;
|
||||
case 0x88: nz(--rY); memread(pc); return;
|
||||
case 0x8A: nz(rA = rX); memread(pc); return;
|
||||
case 0x8C: memwrite(fetch16(), rY); return;
|
||||
case 0x8D: memwrite(fetch16(), rA); return;
|
||||
case 0x8E: memwrite(fetch16(), rX); return;
|
||||
case 0x90: if((rP & FLAGC) == 0) branch(); else fetch8(); return;
|
||||
case 0x91: memwrite(aindY(1), rA); return;
|
||||
case 0x94: memwrite(azpX(rX), rY); return;
|
||||
case 0x95: memwrite(azpX(rX), rA); return;
|
||||
case 0x96: memwrite(azpX(rY), rX); return;
|
||||
case 0x98: nz(rA = rY); memread(pc); return;
|
||||
case 0x99: memwrite(aabsX(rY, 1), rA); return;
|
||||
case 0x9A: rS = rX; memread(pc); return;
|
||||
case 0x9D: memwrite(aabsX(rX, 1), rA); return;
|
||||
case 0xA0: nz(rY = imm()); return;
|
||||
case 0xA1: nz(rA = indX()); return;
|
||||
case 0xA2: nz(rX = imm()); return;
|
||||
case 0xA4: nz(rY = zp()); return;
|
||||
case 0xA5: nz(rA = zp()); return;
|
||||
case 0xA6: nz(rX = zp()); return;
|
||||
case 0xA8: nz(rY = rA); memread(pc); return;
|
||||
case 0xA9: nz(rA = imm()); return;
|
||||
case 0xAA: nz(rX = rA); memread(pc); return;
|
||||
case 0xAC: nz(rY = abso()); return;
|
||||
case 0xAE: nz(rX = abso()); return;
|
||||
case 0xAD: nz(rA = abso()); return;
|
||||
case 0xB0: if((rP & FLAGC) != 0) branch(); else fetch8(); return;
|
||||
case 0xB1: nz(rA = indY()); return;
|
||||
case 0xB4: nz(rY = zpX()); return;
|
||||
case 0xB5: nz(rA = zpX()); return;
|
||||
case 0xB6: nz(rX = zpY()); return;
|
||||
case 0xB8: rP &= ~FLAGV; memread(pc); return;
|
||||
case 0xB9: nz(rA = absY()); return;
|
||||
case 0xBA: nz(rX = rS); memread(pc); return;
|
||||
case 0xBC: nz(rY = absX()); return;
|
||||
case 0xBD: nz(rA = absX()); return;
|
||||
case 0xBE: nz(rX = absY()); return;
|
||||
case 0xC1: cmp(rA, indX()); return;
|
||||
case 0xC5: cmp(rA, zp()); return;
|
||||
case 0xC9: cmp(rA, imm()); return;
|
||||
case 0xCD: cmp(rA, abso()); return;
|
||||
case 0xD0: if((rP & FLAGZ) == 0) branch(); else fetch8(); return;
|
||||
case 0xD1: cmp(rA, indY()); return;
|
||||
case 0xD5: cmp(rA, zpX()); return;
|
||||
case 0xD8: rP &= ~FLAGD; memread(pc); return;
|
||||
case 0xD9: cmp(rA, absY()); return;
|
||||
case 0xDD: cmp(rA, absX()); return;
|
||||
case 0xC0: cmp(rY, imm()); return;
|
||||
case 0xC4: cmp(rY, zp()); return;
|
||||
case 0xC6: dec(fetch8()); return;
|
||||
case 0xC8: nz(++rY); memread(pc); return;
|
||||
case 0xCA: nz(--rX); memread(pc); return;
|
||||
case 0xCC: cmp(rY, abso()); return;
|
||||
case 0xCE: dec(fetch16()); return;
|
||||
case 0xD6: dec(azpX(rX)); return;
|
||||
case 0xDE: dec(aabsX(rX, 1)); return;
|
||||
case 0xE0: cmp(rX, imm()); return;
|
||||
case 0xE1: sbc(indX()); return;
|
||||
case 0xE4: cmp(rX, zp()); return;
|
||||
case 0xE5: sbc(zp()); return;
|
||||
case 0xE6: inc(fetch8()); return;
|
||||
case 0xE8: nz(++rX); memread(pc); return;
|
||||
case 0xE9: sbc(imm()); return;
|
||||
case 0xEA: memread(pc); return;
|
||||
case 0xEC: cmp(rX, abso()); return;
|
||||
case 0xED: sbc(abso()); return;
|
||||
case 0xEE: inc(fetch16()); return;
|
||||
case 0xF0: if((rP & FLAGZ) != 0) branch(); else fetch8(); return;
|
||||
case 0xF1: sbc(indY()); return;
|
||||
case 0xF5: sbc(zpX()); return;
|
||||
case 0xF6: inc(azpX(rX)); return;
|
||||
case 0xF8: rP |= FLAGD; memread(pc); return;
|
||||
case 0xF9: sbc(absY()); return;
|
||||
case 0xFD: sbc(absX()); return;
|
||||
case 0xFE: inc(aabsX(rX, 1)); return;
|
||||
default:
|
||||
fprint(2, "undefined %#x (pc %#x)\n", op, curpc);
|
||||
return;
|
||||
}
|
||||
}
|
80
sys/src/games/2600/dat.h
Normal file
80
sys/src/games/2600/dat.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
extern u16int pc, curpc;
|
||||
extern u8int rP;
|
||||
extern int nrdy;
|
||||
extern int p0difc;
|
||||
extern int bwmod;
|
||||
|
||||
extern int ppux, ppuy;
|
||||
extern u8int p0x, p1x, m0x, m1x, blx;
|
||||
extern u16int coll;
|
||||
|
||||
extern u8int *rom, *rop;
|
||||
extern u16int bnk[];
|
||||
extern int mask;
|
||||
extern u8int reg[64];
|
||||
|
||||
enum {
|
||||
FLAGC = 1<<0,
|
||||
FLAGZ = 1<<1,
|
||||
FLAGI = 1<<2,
|
||||
FLAGD = 1<<3,
|
||||
FLAGB = 1<<4,
|
||||
FLAGV = 1<<6,
|
||||
FLAGN = 1<<7,
|
||||
};
|
||||
|
||||
enum {
|
||||
VSYNC,
|
||||
VBLANK,
|
||||
WSYNC,
|
||||
RSYNC,
|
||||
NUSIZ0,
|
||||
NUSIZ1,
|
||||
COLUP0,
|
||||
COLUP1,
|
||||
COLUPF,
|
||||
COLUBK,
|
||||
CTRLPF,
|
||||
REFP0,
|
||||
REFP1,
|
||||
PF0,
|
||||
PF1,
|
||||
PF2,
|
||||
RESP0,
|
||||
RESP1,
|
||||
RESM0,
|
||||
RESM1,
|
||||
RESBL,
|
||||
AUDC0,
|
||||
AUDC1,
|
||||
AUDF0,
|
||||
AUDF1,
|
||||
AUDV0,
|
||||
AUDV1,
|
||||
GRP0,
|
||||
GRP1,
|
||||
ENAM0,
|
||||
ENAM1,
|
||||
ENABL,
|
||||
HMP0,
|
||||
HMP1,
|
||||
HMM0,
|
||||
HMM1,
|
||||
HMBL,
|
||||
VDELP0,
|
||||
VDELP1,
|
||||
VDELBL,
|
||||
RESMP0,
|
||||
RESMP1,
|
||||
HMOVE,
|
||||
HMCLR,
|
||||
CXCLR,
|
||||
};
|
||||
|
||||
enum {
|
||||
PICW = 320,
|
||||
PICH = 222,
|
||||
HZ = 3579545,
|
||||
RATE = 44100,
|
||||
SAMPDIV = HZ / 3 / RATE,
|
||||
};
|
9
sys/src/games/2600/fns.h
Normal file
9
sys/src/games/2600/fns.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
u8int memread(u16int);
|
||||
void memwrite(u16int, u8int);
|
||||
void step(void);
|
||||
void tiastep(void);
|
||||
void flush(void);
|
||||
void io(void);
|
||||
void initaudio(void);
|
||||
void sample(void);
|
||||
int audioout(void);
|
195
sys/src/games/2600/mem.c
Normal file
195
sys/src/games/2600/mem.c
Normal file
|
@ -0,0 +1,195 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <emu.h>
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
|
||||
u8int ram[128], reg[64];
|
||||
static u8int timer, timerun, timerspeed;
|
||||
static u16int timerpre;
|
||||
static u8int grp0d, grp1d, enabld;
|
||||
|
||||
static u8int
|
||||
tiaread(u8int a)
|
||||
{
|
||||
if(a < 8)
|
||||
return coll >> (a << 1 & 14) << 6;
|
||||
if(a == 0xc)
|
||||
return ~keys << 3 & 0x80;
|
||||
return 0x80;
|
||||
}
|
||||
|
||||
static void
|
||||
tiawrite(u8int a, u8int v)
|
||||
{
|
||||
switch(a){
|
||||
case VSYNC:
|
||||
if((v & 2) != 0)
|
||||
flush();
|
||||
return;
|
||||
case VBLANK:
|
||||
if((v & 2) == 0)
|
||||
ppuy = 0;
|
||||
break;
|
||||
case WSYNC: nrdy = 1; break;
|
||||
case RESP0: p0x = ppux >= 160 ? 3 : ppux+5; break;
|
||||
case RESP1: p1x = ppux >= 160 ? 3 : ppux+5; break;
|
||||
case RESM0: m0x = ppux >= 160 ? 2 : ppux+4; break;
|
||||
case RESM1: m1x = ppux >= 160 ? 2 : ppux+4; break;
|
||||
case RESBL: blx = ppux >= 160 ? 2 : ppux+4; break;
|
||||
case HMOVE:
|
||||
p0x = (p0x - ((s8int) reg[HMP0] >> 4)) % 160;
|
||||
p1x = (p1x - ((s8int) reg[HMP1] >> 4)) % 160;
|
||||
m0x = (m0x - ((s8int) reg[HMM0] >> 4)) % 160;
|
||||
m1x = (m1x - ((s8int) reg[HMM1] >> 4)) % 160;
|
||||
blx = (blx - ((s8int) reg[HMBL] >> 4)) % 160;
|
||||
break;
|
||||
case HMCLR: reg[HMP0] = reg[HMP1] = reg[HMM0] = reg[HMM1] = reg[HMBL] = 0; break;
|
||||
case VDELP0:
|
||||
if((v & 1) == 0)
|
||||
reg[GRP0] = grp0d;
|
||||
break;
|
||||
case VDELP1:
|
||||
if((v & 1) == 0)
|
||||
reg[GRP1] = grp1d;
|
||||
break;
|
||||
case VDELBL:
|
||||
if((v & 1) == 0)
|
||||
reg[ENABL] = enabld;
|
||||
break;
|
||||
case GRP0:
|
||||
if((reg[VDELP1] & 1) != 0)
|
||||
reg[GRP1] = grp1d;
|
||||
if((reg[VDELP0] & 1) != 0){
|
||||
grp0d = v;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case GRP1:
|
||||
if((reg[VDELP0] & 1) != 0)
|
||||
reg[GRP0] = grp0d;
|
||||
if((reg[VDELBL] & 1) != 0)
|
||||
reg[ENABL] = enabld;
|
||||
if((reg[VDELP1] & 1) != 0){
|
||||
grp1d = v;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case ENABL:
|
||||
if((reg[VDELBL] & 1) != 0){
|
||||
enabld = v;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case CXCLR:
|
||||
coll = 0;
|
||||
break;
|
||||
}
|
||||
reg[a] = v;
|
||||
}
|
||||
|
||||
static u8int
|
||||
ioread(u8int a)
|
||||
{
|
||||
u8int v;
|
||||
|
||||
switch(a){
|
||||
case 0:
|
||||
return ~(keys << 4);
|
||||
case 2:
|
||||
return keys >> 5 ^ 3 | bwmod | p0difc;
|
||||
case 4:
|
||||
timerspeed = 0;
|
||||
return timer;
|
||||
case 5:
|
||||
v = timerun;
|
||||
timerun &= ~(1<<6);
|
||||
return v;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
iowrite(u8int a, u8int v)
|
||||
{
|
||||
switch(a){
|
||||
case 4:
|
||||
timerpre = 1;
|
||||
goto timer;
|
||||
case 5:
|
||||
timerpre = 8;
|
||||
goto timer;
|
||||
case 6:
|
||||
timerpre = 64;
|
||||
goto timer;
|
||||
case 7:
|
||||
timerpre = 1024;
|
||||
timer:
|
||||
timerun &= ~(1<<7);
|
||||
timerspeed = v == 0;
|
||||
timer = v - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
u8int
|
||||
memread(u16int a)
|
||||
{
|
||||
u8int v;
|
||||
|
||||
if((a & 0x1000) != 0)
|
||||
v = rop[a & mask];
|
||||
else if((a & 1<<7) == 0)
|
||||
v = tiaread(a & 0xf);
|
||||
else if((a & 1<<9) == 0)
|
||||
v = ram[a & 0x7f];
|
||||
else
|
||||
v = ioread(a & 7);
|
||||
if(a > 0xfff3 && a < 0xfffc)
|
||||
rop = rom + bnk[a - 0xfff4];
|
||||
io();
|
||||
return v;
|
||||
}
|
||||
|
||||
void
|
||||
memwrite(u16int a, u8int v)
|
||||
{
|
||||
if((a & 0x1000) != 0){
|
||||
;}
|
||||
else if((a & 1<<7) == 0)
|
||||
tiawrite(a & 0x3f, v);
|
||||
else if((a & 1<<9) == 0)
|
||||
ram[a & 0x7f] = v;
|
||||
else
|
||||
iowrite(a & 7, v);
|
||||
if(a > 0xfff3 && a < 0xfffc)
|
||||
rop = rom + bnk[a - 0xfff4];
|
||||
io();
|
||||
}
|
||||
|
||||
static void
|
||||
timerstep(void)
|
||||
{
|
||||
static int cl;
|
||||
|
||||
cl++;
|
||||
if((timerspeed || (cl & timerpre - 1) == 0) && timer-- == 0){
|
||||
timerspeed = 1;
|
||||
timerun |= 3<<6;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
io(void)
|
||||
{
|
||||
static int snddiv;
|
||||
|
||||
timerstep();
|
||||
tiastep();
|
||||
tiastep();
|
||||
tiastep();
|
||||
if(++snddiv == SAMPDIV){
|
||||
snddiv = 0;
|
||||
sample();
|
||||
}
|
||||
}
|
14
sys/src/games/2600/mkfile
Normal file
14
sys/src/games/2600/mkfile
Normal file
|
@ -0,0 +1,14 @@
|
|||
</$objtype/mkfile
|
||||
|
||||
BIN=/$objtype/bin/games
|
||||
TARG=2600
|
||||
OFILES=\
|
||||
2600.$O\
|
||||
aud.$O\
|
||||
cpu.$O\
|
||||
mem.$O\
|
||||
tia.$O\
|
||||
|
||||
HFILES=dat.h fns.h
|
||||
|
||||
</sys/src/cmd/mkone
|
212
sys/src/games/2600/tia.c
Normal file
212
sys/src/games/2600/tia.c
Normal file
|
@ -0,0 +1,212 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <emu.h>
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
|
||||
int ppux=1, ppuy;
|
||||
int col, pri;
|
||||
u8int p0x, p1x, m0x, m1x, blx;
|
||||
u16int coll;
|
||||
u8int disp;
|
||||
int p0difc;
|
||||
int bwmod = 1<<3;
|
||||
|
||||
enum {
|
||||
SRCPF,
|
||||
SRCP0,
|
||||
SRCP1,
|
||||
SRCM0,
|
||||
SRCM1,
|
||||
SRCBL,
|
||||
};
|
||||
|
||||
static void
|
||||
pixeldraw(u8int v)
|
||||
{
|
||||
u32int c;
|
||||
union { u32int l; u8int c[4]; } u;
|
||||
u32int *p;
|
||||
static u32int col[] = {
|
||||
0x000000, 0x404040, 0x6C6C6C, 0x909090, 0xB0B0B0, 0xC8C8C8, 0xDCDCDC, 0xECECEC,
|
||||
0x444400, 0x646410, 0x848424, 0xA0A034, 0xB8B840, 0xD0D050, 0xE8E85C, 0xFCFC68,
|
||||
0x702800, 0x844414, 0x985C28, 0xAC783C, 0xBC8C4C, 0xCCA05C, 0xDCB468, 0xECC878,
|
||||
0x841800, 0x983418, 0xAC5030, 0xC06848, 0xD0805C, 0xE09470, 0xECA880, 0xFCBC94,
|
||||
0x880000, 0x9C2020, 0xB03C3C, 0xC05858, 0xD07070, 0xE08888, 0xECA0A0, 0xFCB4B4,
|
||||
0x78005C, 0x8C2074, 0xA03C88, 0xB0589C, 0xC070B0, 0xD084C0, 0xDC9CD0, 0xECB0E0,
|
||||
0x480078, 0x602090, 0x783CA4, 0x8C58B8, 0xA070CC, 0xB484DC, 0xC49CEC, 0xD4B0FC,
|
||||
0x140084, 0x302098, 0x4C3CAC, 0x6858C0, 0x7C70D0, 0x9488E0, 0xA8A0EC, 0xBCB4FC,
|
||||
0x000088, 0x1C209C, 0x3840B0, 0x505CC0, 0x6874D0, 0x7C8CE0, 0x90A4EC, 0xA4B8FC,
|
||||
0x00187C, 0x1C3890, 0x3854A8, 0x5070BC, 0x6888CC, 0x7C9CDC, 0x90B4EC, 0xA4C8FC,
|
||||
0x002C5C, 0x1C4C78, 0x386890, 0x5084AC, 0x689CC0, 0x7CB4D4, 0x90CCE8, 0xA4E0FC,
|
||||
0x003C2C, 0x1C5C48, 0x387C64, 0x509C80, 0x68B494, 0x7CD0AC, 0x90E4C0, 0xA4FCD4,
|
||||
0x003C00, 0x205C20, 0x407C40, 0x5C9C5C, 0x74B474, 0x8CD08C, 0xA4E4A4, 0xB8FCB8,
|
||||
0x143800, 0x345C1C, 0x507C38, 0x6C9850, 0x84B468, 0x9CCC7C, 0xB4E490, 0xC8FCA4,
|
||||
0x2C3000, 0x4C501C, 0x687034, 0x848C4C, 0x9CA864, 0xB4C078, 0xCCD488, 0xE0EC9C,
|
||||
0x442800, 0x644818, 0x846830, 0xA08444, 0xB89C58, 0xD0B46C, 0xE8CC7C, 0xFCE08C,
|
||||
};
|
||||
|
||||
c = col[v >> 1];
|
||||
u.c[0] = c;
|
||||
u.c[1] = c >> 8;
|
||||
u.c[2] = c >> 16;
|
||||
u.c[3] = 0xff;
|
||||
p = (u32int *)pic + ppuy * PICW * scale + ppux * 2 * scale;
|
||||
switch(scale){
|
||||
case 16: *p++ = u.l; *p++ = u.l;
|
||||
case 15: *p++ = u.l; *p++ = u.l;
|
||||
case 14: *p++ = u.l; *p++ = u.l;
|
||||
case 13: *p++ = u.l; *p++ = u.l;
|
||||
case 12: *p++ = u.l; *p++ = u.l;
|
||||
case 11: *p++ = u.l; *p++ = u.l;
|
||||
case 10: *p++ = u.l; *p++ = u.l;
|
||||
case 9: *p++ = u.l; *p++ = u.l;
|
||||
case 8: *p++ = u.l; *p++ = u.l;
|
||||
case 7: *p++ = u.l; *p++ = u.l;
|
||||
case 6: *p++ = u.l; *p++ = u.l;
|
||||
case 5: *p++ = u.l; *p++ = u.l;
|
||||
case 4: *p++ = u.l; *p++ = u.l;
|
||||
case 3: *p++ = u.l; *p++ = u.l;
|
||||
case 2: *p++ = u.l; *p++ = u.l;
|
||||
default: *p++ = u.l; *p = u.l;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pixel(u8int v, int p, int s)
|
||||
{
|
||||
if(p > pri){
|
||||
col = v;
|
||||
pri = p;
|
||||
}
|
||||
disp |= 1<<s;
|
||||
}
|
||||
|
||||
static void
|
||||
playfield(void)
|
||||
{
|
||||
int x, p;
|
||||
u8int c;
|
||||
|
||||
x = ppux / 4;
|
||||
if(x >= 20)
|
||||
if((reg[CTRLPF] & 1) != 0)
|
||||
x = 39 - x;
|
||||
else
|
||||
x = x - 20;
|
||||
if(x < 4){
|
||||
if((reg[PF0] & 0x10<<x) == 0)
|
||||
return;
|
||||
}else if(x < 12){
|
||||
if((reg[PF1] & 0x800>>x) == 0)
|
||||
return;
|
||||
}else
|
||||
if((reg[PF2] & 1<<x-12) == 0)
|
||||
return;
|
||||
if((reg[CTRLPF] & 6) == 2)
|
||||
if(ppux < 80){
|
||||
c = reg[COLUP0];
|
||||
p = 3;
|
||||
}else{
|
||||
c = reg[COLUP1];
|
||||
p = 2;
|
||||
}
|
||||
else{
|
||||
c = reg[COLUPF];
|
||||
p = (reg[CTRLPF] & 4) + 1;
|
||||
}
|
||||
pixel(c, p, SRCPF);
|
||||
}
|
||||
|
||||
static void
|
||||
player(int n)
|
||||
{
|
||||
u8int c;
|
||||
int x;
|
||||
|
||||
c = reg[GRP0 + n];
|
||||
x = ppux - (n ? p1x : p0x);
|
||||
if(x < 0)
|
||||
return;
|
||||
switch(reg[NUSIZ0 + n] & 7){
|
||||
default: if(x >= 8) return; break;
|
||||
case 1: if(x >= 8 && (x < 16 || x >= 24)) return; break;
|
||||
case 2: if(x >= 8 && (x < 32 || x >= 40)) return; break;
|
||||
case 3: if(x >= 40 || ((x & 15) >= 8)) return; break;
|
||||
case 4: if(x >= 8 && (x < 64 || x >= 72)) return; break;
|
||||
case 5: if(x >= 16) return; x >>= 1; break;
|
||||
case 6: if(x >= 72 || ((x & 31) >= 8)) return; break;
|
||||
case 7: if(x >= 32) return; x >>= 2; break;
|
||||
}
|
||||
x &= 7;
|
||||
if((reg[REFP0 + n] & 8) == 0)
|
||||
x ^= 7;
|
||||
if((c & 1<<x) == 0)
|
||||
return;
|
||||
c = reg[COLUP0 + n];
|
||||
pixel(c, 3 - n, SRCP0 + n);
|
||||
}
|
||||
|
||||
static void
|
||||
missile(int n)
|
||||
{
|
||||
int x;
|
||||
|
||||
x = ppux - (n ? m1x : m0x);
|
||||
if((reg[RESMP0 + n] & 2) != 0){
|
||||
if(n)
|
||||
m1x = p1x;
|
||||
else
|
||||
m0x = p0x;
|
||||
return;
|
||||
}
|
||||
if(x < 0 || x >= 1<<(reg[NUSIZ0] >> 4 & 3) || (reg[ENAM0 + n] & 2) == 0)
|
||||
return;
|
||||
pixel(reg[COLUP0 + n], 3 - n, SRCM0 + n);
|
||||
}
|
||||
|
||||
static void
|
||||
ball(void)
|
||||
{
|
||||
int x;
|
||||
|
||||
x = ppux - blx;
|
||||
if(x < 0 || x >= 1<<(reg[CTRLPF] >> 4 & 3) || (reg[ENABL] & 2) == 0)
|
||||
return;
|
||||
pixel(reg[COLUPF], (reg[CTRLPF] & 4) + 1, SRCBL);
|
||||
}
|
||||
|
||||
void
|
||||
tiastep(void)
|
||||
{
|
||||
static u16int colltab[64] = {
|
||||
0x0000, 0x0000, 0x0000, 0x0020, 0x0000, 0x0080, 0x8000, 0x80a0,
|
||||
0x0000, 0x0200, 0x0001, 0x0221, 0x0002, 0x0282, 0x8003, 0x82a3,
|
||||
0x0000, 0x0800, 0x0008, 0x0828, 0x0004, 0x0884, 0x800c, 0x88ac,
|
||||
0x4000, 0x4a00, 0x4009, 0x4a29, 0x4006, 0x4a86, 0xc00f, 0xcaaf,
|
||||
0x0000, 0x2000, 0x0010, 0x2030, 0x0040, 0x20c0, 0x8050, 0xa0f0,
|
||||
0x0100, 0x2300, 0x0111, 0x2331, 0x0142, 0x23c2, 0x8153, 0xa3f3,
|
||||
0x0400, 0x2c00, 0x0418, 0x2c38, 0x0444, 0x2cc4, 0x845c, 0xacfc,
|
||||
0x4500, 0x6f00, 0x4519, 0x6f39, 0x4546, 0x6fc6, 0xc55f, 0xefff,
|
||||
};
|
||||
|
||||
if(ppuy < PICH && ppux < 160){
|
||||
col = reg[COLUBK];
|
||||
pri = 0;
|
||||
disp = 0;
|
||||
playfield();
|
||||
player(0);
|
||||
player(1);
|
||||
missile(0);
|
||||
missile(1);
|
||||
ball();
|
||||
coll |= colltab[disp];
|
||||
pixeldraw(col);
|
||||
}
|
||||
if(ppux == 160)
|
||||
nrdy = 0;
|
||||
if(++ppux == 228){
|
||||
ppuy++;
|
||||
ppux = 0;
|
||||
}
|
||||
}
|
|
@ -24,6 +24,7 @@ HFILES=
|
|||
BIN=/$objtype/bin/games
|
||||
|
||||
DIRS=\
|
||||
2600\
|
||||
blabs\
|
||||
blit\
|
||||
c64\
|
||||
|
|
Loading…
Reference in a new issue