basic 'joypad' functionality

This commit is contained in:
cr0sd 2020-03-03 14:31:12 -06:00
parent 0addfa6ca0
commit 1a6995f15b
11 changed files with 96 additions and 155 deletions

27
65.c
View File

@ -15,6 +15,7 @@ void print_memory(cpu_t*cpu,ram_t*ram,uint16_t offset);
void print_disassembly(cpu_t*cpu,ram_t*ram);
uint16_t prompt_address(char*prompt,cpu_t*cpu);
uint16_t linear_search(uint16_t from,ram_t*ram);
uint8_t prompt_byte(char*prompt,uint16_t from,ram_t*ram,char*prev,char*b);
// Entry point
int main(int argc,char**argv)
@ -122,6 +123,16 @@ int main(int argc,char**argv)
hex_offset=linear_search(hex_offset,ram);
break;
// Set byte at address
case 'b':
{
uint16_t addr=prompt_address("Set byte at address: ",cpu);
char b[512];
char prev[8];
ram->ram[addr]=prompt_byte("Set byte: ",addr,ram,prev,b);
break;
}
// Quit command
case 'q':
goto quit;
@ -236,15 +247,13 @@ uint16_t prompt_address(char*prompt,cpu_t*cpu)
return gowh;
}
uint16_t linear_search(uint16_t from,ram_t*ram)
uint8_t prompt_byte(char*prompt,uint16_t from,ram_t*ram,char*prev,char*b)
{
char b[8];
static char prev[8];
uint8_t byte=0;
// Prompt for desired byte to find
mvclr(STATUSLINE,0);
mvprintw(STATUSLINE,0,"Search for byte (00-ff,n): ");
mvprintw(STATUSLINE,0,"%s (00-ff,n): ",prompt);
getnstr(b,2);
// Special values
@ -277,8 +286,16 @@ uint16_t linear_search(uint16_t from,ram_t*ram)
// Convert to integer and notify
byte=strtol(b,NULL,16);
mvclr(STATUSLINE,0);
mvprintw(STATUSLINE,0,"Search for $%X",
mvprintw(STATUSLINE,0,"Byte: $%X",
byte);
return byte;
}
uint16_t linear_search(uint16_t from,ram_t*ram)
{
static char prev[8];
char b[8];
uint8_t byte=prompt_byte("Search for byte",from,ram,prev,b);
// Search (linearly, until $ffff) from hex_offset
for(int i=from+1;i<0xffff;++i)

3
65.h
View File

@ -12,13 +12,14 @@ WINDOW*win;
#define new(x) malloc(sizeof(x))
#define mvclr(y,x) do{move(y,x);clrtoeol();}while(0)
#define STATUSLINE 21
#define STATUSLINE 22
#define TOPROWHEIGHT 7
#define LASTHEXOFFSET (0x10000-TOPROWHEIGHT*8)
// Memory
#define VRAM 0x6000
#define PRGROM 0x8000
#define JOYPREG 0x0010
// Print error
void puterr(const char*msg,...);

11
65v.c
View File

@ -11,13 +11,16 @@
#include<unistd.h>
#include<pthread.h>
// 65 with VRAM display
// instead of disassembly, registers & memory
// Entry point
int main(int argc,char**argv)
{
cpu_t*cpu=cpu_init();
rom_t*rom=new(rom_t);
ram_t*ram=ram_init();
joy_t*joy=joy_init(0x10,2);
joy_t*joy=joy_init(JOYPREG,2);
pthread_t thread;
//printf("ram->ram:\t%p\njoy->ram->ram:\t%p\n",ram->ram,joy->ram->ram);
@ -61,7 +64,11 @@ int main(int argc,char**argv)
vis_display(cpu,ram);
mvclr(15,0);
mvprintw(15,0,"joy button: $%02X",joy->button);
mvprintw(15,0,"joy button: $%02X",joy->buttons.reg);
mvclr(16,0);
mvprintw(16,0,"$%04X: $%02X (%c)",
JOYPREG,ram->ram[JOYPREG],
(ram->ram[JOYPREG]<0x20)?('.'):(ram->ram[JOYPREG]));
refresh();
usleep(1);
}

View File

@ -1,6 +1,5 @@
CFLAGS = -Wfatal-errors
LDFLAGS += -lncurses -lpthread -pthread
AS65 = xa -C
RM = rm -f # for BSDmake
PROG = 65
OBJS = cpu.o ram.o rom.o disasm.o joy.o vis.o

2
cpu.c
View File

@ -84,7 +84,7 @@ void cpu_exec(cpu_t*cpu,ram_t*ram)
// Load a
case 0xA1: lda( deref( deref( fetch() + cpu->x ) ) ); sr_nz(cpu->a); incpc(); break;
case 0xB1: lda( deref( deref( fetch() + cpu->y ) ) ); sr_nz(cpu->a); incpc(); break;
case 0xA5: lda( fetch() ); sr_nz(cpu->a); incpc(); break;
case 0xA5: lda( deref( fetch() ) ); sr_nz(cpu->a); incpc(); break;
case 0xA9: lda( fetch() ); sr_nz(cpu->a); incpc(); break;
case 0xAD: lda( fetch16() ); sr_nz(cpu->a); incpc(); break;
case 0xB5: lda( deref( fetch() + cpu->x ) ); sr_nz(cpu->a); incpc(); break;

28
joy.c
View File

@ -26,7 +26,7 @@ void joy_del(joy_t*joy)
void joy_update_ram(joy_t*joy,ram_t*ram)
{
pthread_mutex_lock(&(joy->mut));
ram->ram[joy->mem_addr]=(uint8_t)joy->button;
ram->ram[joy->mem_addr]=(uint8_t)joy->buttons.reg;
pthread_mutex_unlock(&(joy->mut));
}
@ -43,22 +43,26 @@ void*joy_thread_update(void*d)
{
read(1,b,1);
// Update joy_t information
pthread_mutex_lock(&(joy->mut));
// Get multi-byte codes
if(*b=='\033')
{
read(1,b,2);
if(b[1]=='A') x=K_UP;
else if(b[1]=='B') x=K_DOWN;
else if(b[1]=='D') x=K_RIGHT;
else if(b[1]=='C') x=K_LEFT;
else
x=0;
if(b[1]=='A') joy->buttons.bits.up=1;//x=K_UP;
else if(b[1]=='B') joy->buttons.bits.down=1;//x=K_DOWN;
else if(b[1]=='D') joy->buttons.bits.right=1;//x=K_RIGHT;
else if(b[1]=='C') joy->buttons.bits.left=1;//x=K_LEFT;
//else
//x=0;
}
else
x=*b;
// Update joy_t information
pthread_mutex_lock(&(joy->mut));
joy->button=x;
if(*b==JOY_A) joy->buttons.bits.a=1;
else if(*b==JOY_B) joy->buttons.bits.b=1;
else if(*b==JOY_X) joy->buttons.bits.x=1;
else if(*b==JOY_Y) joy->buttons.bits.y=1;
pthread_mutex_unlock(&(joy->mut));
}

24
joy.h
View File

@ -12,11 +12,33 @@
#define K_LEFT 0x83
#define K_RIGHT 0x84
#define JOY_A 'z'
#define JOY_B 'x'
#define JOY_X 'a'
#define JOY_Y 's'
typedef struct joy_t
{
uint16_t mem_addr;
pthread_mutex_t mut;
int button;
// Buttons
union
{
uint8_t reg;
struct
{
int up:1;
int down:1;
int left:1;
int right:1;
int a:1;
int b:1;
int x:1;
int y:1;
}bits;
}buttons;
}joy_t;
joy_t*joy_init(uint16_t addr,int n);

View File

@ -1,18 +1,22 @@
CC65 = cc65
CCAS65 = asmx -C 6502 -b 8000-10000
AS65 = xa -C
CCAS65 = asmx
AS65 = xa
RM = rm -f # for BSD
OBJS = nes.nes asciitest.nes ctest.nes vram.nes
all: $(OBJS)
all: checks $(OBJS)
@cp $(OBJS) ..
checks:
@echo "Checking for $(CC65)..." `which $(CC65)`
@echo "Checking for $(AS65)..." `which $(AS65)`
@echo "Checking for $(CCAS65)..." `which $(CCAS65)`
.a65.nes:
@echo "AS65 $*.nes"
@$(AS65) $(AS65FLAGS) $*.a65 -o $*.nes
@$(AS65) -C $*.a65 -o $*.nes
.c65.nes:
@echo "CC65 $*.nes"
@$(CC65) $*.c65
@-$(CCAS65) -b 0-10000 -o $*.o65 $*.s
@-$(CCAS65) -C 6502 -b 8000-10000 -o $*.o65 $*.s
@cat ines_header $*.o65 > $*.nes
@$(RM) $*.o65 $*.s
clean:

View File

@ -9,129 +9,18 @@ DELAY = $000F
*=$8000
main:
.(
; setup stack
ldx #$ff
txs
lda #$24+30
sta me
; main loop
loop:
jsr drawbg
jsr drawme
jsr moveme
jsr wait
; clear player pos
ldx me
lda #0
sta VRAM,x
; move player
lda me
adc #2
sta me
jmp loop
.)
; draw bg in VRAM
drawbg:
.(
ldx #0
top:
lda #$ff
sta VRAM,x
inx
txa
cmp #30
bcs top
ldx #0
bot:
lda #$ff
sta VRAM+30*7,x
inx
txa
cmp #30
bcs bot
ldx #0
left:
lda #$ff
sta VRAM,x
txa
adc #30
tax
cmp #30*8
bcs left
ldx #0
right:
lda #$ff
sta VRAM+29,x
txa
adc #30
tax
cmp #30*8
bcs right
rts
.)
; draw 'character' in VRAM
drawme:
.(
ldx me
lda #$21
sta VRAM,x
rts
.)
; check joypad inputs, move character
moveme:
.(
; clear player pos
ldx me
lda #0
sta VRAM,x
; check keyboard input
lda JOYP
cmp #$82
beq down
jmp end
and #1
cmp #1
bne loop
down:
end:
lda #0
sta JOYP
lda me
adc #30
sta me
end:
rts
.)
; delay for 256 cycles or something
wait:
.(
lda #0
ldx #0
loop:
adc #1
cmp #$ff
bcs loop
rts
jmp end
.)

View File

@ -28,11 +28,6 @@ loop:
lda #0
sta VRAM,x
; move player
lda me
adc #2
sta me
jmp loop
.)
@ -108,16 +103,17 @@ moveme:
lda JOYP
cmp #$82
beq down
jmp end
down:
lda #0
sta JOYP
lda me
adc #30
sta me
lda #0
sta JOYP
end:
rts
.)

8
vis.c
View File

@ -12,10 +12,12 @@ int vis_display(cpu_t*cpu,ram_t*ram)
int b=ram->ram[VRAM+i];
move(i/w,i%w);
if(b==0xff)
addch((ram->ram[VRAM+i])?(ACS_CKBOARD):(' '));
addch(b?(ACS_CKBOARD):(' '));
else if(b==0x21)
addch('@');
//mvprintw(i/w,i%w,"%c",(ram->ram[i])?(ACS_CKBOARD):(' '));
//mvprintw(i/w,i%w,"%c",ram->ram[i]);
//mvprintw(i/w,i%w,"%c",b?(ACS_CKBOARD):(' '));
//mvprintw(i/w,i%w,"%c",b);
//mvprintw(i/w,i%w,"%c",(b<0x20)?('.'):(b));
}
}