Skip to content

Commit

Permalink
Some tidying, starting to work on a cooler demo.
Browse files Browse the repository at this point in the history
  • Loading branch information
haldean committed Jan 17, 2014
1 parent 1bf1257 commit 7c37fb1
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 22 deletions.
3 changes: 3 additions & 0 deletions cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
#define FLAG_ZERO 0x02
#define FLAG_CARRY 0x01

// set if memory was modified during processing of the last instruction
#define EMU_FLAG_DIRTY 0x01
// set if the emulator should wait for an interrupt before continuing
#define EMU_FLAG_WAIT_FOR_INTERRUPT 0x02

typedef struct {
// program counter
Expand Down
30 changes: 15 additions & 15 deletions debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ void dump_cpu(cpu *m) {
init_names();

int i;
printf("pc %04X\nx %02X y %02X sp %02X sr %02X ac %02X",
fprintf(stderr, "pc %04X\nx %02X y %02X sp %02X sr %02X ac %02X",
m->pc, m->x, m->y, m->sp, m->sr, m->ac);

printf("\nlast opcode: %s (%02X)",
fprintf(stderr, "\nlast opcode: %s (%02X)",
inst_names[m->last_opcode], m->last_opcode);
printf(", next opcode: %s (%02X)",
fprintf(stderr, ", next opcode: %s (%02X)",
inst_names[m->mem[m->pc]], m->mem[m->pc]);

printf("\nflags n %d o %d b %d d %d i %d z %d c %d",
fprintf(stderr, "\nflags n %d o %d b %d d %d i %d z %d c %d",
(m->sr & FLAG_NEGATIVE) > 0,
(m->sr & FLAG_OVERFLOW) > 0,
(m->sr & FLAG_BREAK) > 0,
Expand All @@ -26,35 +26,35 @@ void dump_cpu(cpu *m) {
(m->sr & FLAG_ZERO) > 0,
(m->sr & FLAG_CARRY) > 0);

printf("\nmem ");
fprintf(stderr, "\nmem ");

int mem_offset = m->pc - MEM_PRINT_BYTES / 2;
// clamp to [0, MAX_MEM_OFFSET]
mem_offset = mem_offset < 0 ? 0 : (
mem_offset > MAX_MEM_OFFSET ? MAX_MEM_OFFSET : mem_offset);

for (i = 0; i < MEM_PRINT_BYTES; i++) {
printf("%02X ", m->mem[i + mem_offset]);
fprintf(stderr, "%02X ", m->mem[i + mem_offset]);
}

printf("\n ");
fprintf(stderr, "\n ");
for (i = 0; i < m->pc - mem_offset; i++) {
printf(" ");
fprintf(stderr, " ");
}
printf("^^ (%04x)", m->pc);
fprintf(stderr, "^^ (%04x)", m->pc);

printf("\nstack ");
fprintf(stderr, "\nstack ");
for (i = 0; i < MEM_PRINT_BYTES; i++) {
printf("%02X ", m->mem[STACK_START + 0xFF - i]);
fprintf(stderr, "%02X ", m->mem[STACK_START + 0xFF - i]);
}
int off = 0xFF - m->sp;
if (off < MEM_PRINT_BYTES) {
printf("\n ");
fprintf(stderr, "\n ");
for (i = 0; i < off; i++) {
printf(" ");
fprintf(stderr, " ");
}
printf("^^");
fprintf(stderr, "^^");
}

printf("\n\n");
fprintf(stderr, "\n\n");
}
11 changes: 5 additions & 6 deletions emu.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ void main_loop(cpu *m) {
// after we move to the next instruction
int8_t branch_offset = 0;

// if set to true, the next instruction will not be executed until an
// interrupt is fired from the IO bus and handled.
uint8_t wait_for_interrupt = 0;

init_io();

for (;;) {
Expand Down Expand Up @@ -81,8 +77,11 @@ void main_loop(cpu *m) {

do {
handle_io(m);
} while (wait_for_interrupt && !m->interrupt_waiting);
wait_for_interrupt = 0;
// clear dirty memory flag immediately so that subsequent runs don't
// redo whatever I/O operation is associated with the dirty memaddr
m->emu_flags &= ~EMU_FLAG_DIRTY;
} while ((m->emu_flags & EMU_FLAG_WAIT_FOR_INTERRUPT) &&
!m->interrupt_waiting);

if (m->interrupt_waiting && !get_flag(m, FLAG_INTERRUPT)) {
STACK_PUSH(m) = (m->pc & 0xFF00) >> 8;
Expand Down
3 changes: 3 additions & 0 deletions io.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ void init_io() {
noecho();
nodelay(stdscr, TRUE);
keypad(stdscr, TRUE);
curs_set(0);

io_supports_paint = (has_colors() != FALSE);
if (io_supports_paint) {
Expand All @@ -50,6 +51,7 @@ void finish_io() {
void init_vterm() {
window = newwin(VTERM_ROWS + 2, VTERM_COLS + 2, 0, 0);
box(window, 0, 0);
wrefresh(window);
}

void finish_vterm() {
Expand All @@ -59,6 +61,7 @@ void finish_vterm() {
void update_modeflags(uint8_t old_flags, uint8_t new_flags) {
io_modeflags = new_flags;

// if the vterm flag changed (avoids reinit every time flags change)
if ((new_flags ^ old_flags) & IO_MODEFLAG_VTERM) {
if (new_flags & IO_MODEFLAG_VTERM) {
init_vterm();
Expand Down
2 changes: 1 addition & 1 deletion opcode_handlers/interrupts.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ case RTI:
break;

case WAI:
wait_for_interrupt = 1;
m->emu_flags |= EMU_FLAG_WAIT_FOR_INTERRUPT;
break;
91 changes: 91 additions & 0 deletions sample_programs/minigame.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#include <stdio.s>

rows = 25
cols = 40

; load location of ISR
lda #<isr
sta $FFFE
lda #>isr
sta $FFFF

; activate vterm mode
lda #$01
sta $FF02

; shiny pretty colors
lda #$04
sta paint

; register and addressing init
lda #$00
sta $00
lda #$FB
sta $01

lda #$A4
ldy #$00

cli

loop
sta ($00),Y
wai
jmp loop

isr:
pha

; clear existing character
lda #$20
sta ($00),Y

lda getc

cmp #$71 ; 71 == 'q'
bne checkj
ext

checkj:
cmp #$6A ; 6A == 'j'
bne checkk
; it's a j. move down.
tya
clc
adc #cols
jmp checkbounds

checkk:
cmp #$6B ; 6B == 'k'
bne checkh
; it's a k. move up.
tya
sec
sbc #cols
jmp checkbounds

checkh:
cmp #$68 ; 68 == 'h'
bne checkl
; it's an h. move left.
tya
sec
sbc #$02
jmp checkbounds

checkl:
cmp #$6C ; 6C == 'l'
bne done
; it's an h. move left.
tya
clc
adc #$02
jmp checkbounds

checkbounds:
; TODO
tay

done:
pla
rti
2 changes: 2 additions & 0 deletions stdlib/stdio.s
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

putc = $FF00
getc = $FF01
iomode = $FF02
paint = $FEE8

#define debug .byt $FC
#define ext .byt $FF
Expand Down

0 comments on commit 7c37fb1

Please sign in to comment.