summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2020-12-03 19:03:08 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2020-12-03 19:03:08 +0100
commitc40499b83f238de9b1a88a080261546149784586 (patch)
tree0baf7b5dee58d2929cd43000a0b0782e68e0d847
parentc7b0b280339064ab1b673ab7767d0318b2e9b72a (diff)
download6502-c40499b83f238de9b1a88a080261546149784586.tar.gz
6502-c40499b83f238de9b1a88a080261546149784586.tar.bz2
some more opcodes for delay 7-seg example
-rw-r--r--emu/6502.c68
-rw-r--r--emu/6502.h10
-rw-r--r--emu/memory.c2
-rw-r--r--roms/7seg_print_loop_delay.asm90
-rw-r--r--roms/7seg_print_one_subroutine.asm6
5 files changed, 170 insertions, 6 deletions
diff --git a/emu/6502.c b/emu/6502.c
index e39dc38..877f3f5 100644
--- a/emu/6502.c
+++ b/emu/6502.c
@@ -252,16 +252,41 @@ void cpu_6502_step( cpu_6502_t *cpu )
update_negative_and_sign( cpu, cpu->A );
break;
+ case STX_ZERO:
+ operand8 = cpu_6502_read_byte( cpu, cpu->PC );
+ cpu->PC++;
+ cpu_6502_write_byte( cpu, operand8, cpu->X );
+ break;
+
case STX_ABS:
operand16 = cpu_6502_read_word( cpu, cpu->PC );
cpu->PC += 2;
cpu_6502_write_byte( cpu, operand16, cpu->X );
break;
-
+
+ case DEX_IMPL:
+ cpu->X--;
+ update_negative_and_sign( cpu, cpu->X );
+ break;
+
case DEY_IMPL:
cpu->Y--;
update_negative_and_sign( cpu, cpu->Y );
break;
+
+ case INY_IMPL:
+ cpu->Y++;
+ update_negative_and_sign( cpu, cpu->Y );
+ break;
+
+ case INC_IMPL:
+ operand8 = cpu_6502_read_byte( cpu, cpu->PC );
+ cpu->PC++;
+ tmp = cpu_6502_read_byte( cpu, operand8 );
+ tmp++;
+ cpu_6502_write_byte( cpu, operand8, tmp );
+ update_negative_and_sign( cpu, tmp );
+ break;
case ROL_ACC:
tmp = ( cpu->A << 1 ) | is_carry( cpu );
@@ -274,6 +299,36 @@ void cpu_6502_step( cpu_6502_t *cpu )
update_negative_and_sign( cpu, cpu->A );
break;
+ case CPX_IMM:
+ operand8 = cpu_6502_read_byte( cpu, cpu->PC );
+ cpu->PC++;
+ tmp = ( cpu->X - operand8 ) & 0xFF;
+ if( cpu->X >= operand8 ) {
+ cpu->PS |= PS_C;
+ } else {
+ cpu->PS &= ~PS_C;
+ }
+ update_negative_and_sign( cpu, tmp );
+ break;
+
+ case SBC_IMM:
+ operand8 = cpu_6502_read_byte( cpu, cpu->PC );
+ cpu->PC++;
+ tmp = cpu->A - operand8 - ( is_carry( cpu ) ? 0 : 1 );
+ update_negative_and_sign( cpu, tmp );
+ if( tmp & 0xFF00 ) {
+ cpu->PS |= PS_C;
+ } else {
+ cpu->PS &= ~PS_C;
+ }
+ if( ( ( cpu->A ^ tmp ) & 0x80 ) && ( ( cpu->A ^ operand8 ) & 0x80 ) ) {
+ cpu->PS |= PS_V;
+ } else {
+ cpu->PS &= ~PS_V;
+ }
+ cpu->A = tmp & 0xFF;
+ break;
+
case BNE_REL:
operand8 = cpu_6502_read_byte( cpu, cpu->PC );
cpu->PC++;
@@ -289,6 +344,14 @@ void cpu_6502_step( cpu_6502_t *cpu )
cpu->PC += (int8_t)operand8;
}
break;
+
+ case BCS_REL:
+ operand8 = cpu_6502_read_byte( cpu, cpu->PC );
+ cpu->PC++;
+ if( is_carry( cpu ) ) {
+ cpu->PC += (int8_t)operand8;
+ }
+ break;
case JMP_ABS:
cpu->PC = cpu_6502_read_word( cpu, cpu->PC );
@@ -308,6 +371,9 @@ void cpu_6502_step( cpu_6502_t *cpu )
cpu->SP = cpu->X;
break;
+ case NOP_IMPL:
+ break;
+
default:
fprintf( stderr, "ERROR: Illegal opcode %02X at PC %04X\n", opcode, cpu->PC );
exit( EXIT_FAILURE );
diff --git a/emu/6502.h b/emu/6502.h
index baefd0f..bfc8314 100644
--- a/emu/6502.h
+++ b/emu/6502.h
@@ -48,15 +48,23 @@ enum {
LDY_ZERO = 0xA4,
LDA_IMM = 0xA9,
LDA_ZERO = 0xA5,
+ STX_ZERO = 0x86,
STX_ABS = 0x8E,
+ DEX_IMPL = 0xCA,
DEY_IMPL = 0x88,
+ INY_IMPL = 0xC8,
+ INC_IMPL = 0xE6,
ROL_ACC = 0x2A,
BNE_REL = 0xD0,
BCC_REL = 0x90,
+ BCS_REL = 0xB0,
JMP_ABS = 0x4C,
JSR_ABS = 0x20,
RTS_IMPL = 0x60,
- TXS_IMPL = 0x9A
+ TXS_IMPL = 0x9A,
+ CPX_IMM = 0xE0,
+ SBC_IMM = 0xE9,
+ NOP_IMPL = 0xEA
};
void cpu_6502_init( cpu_6502_t *cpu, bus_t *bus, bool initialize );
diff --git a/emu/memory.c b/emu/memory.c
index e879edd..620261b 100644
--- a/emu/memory.c
+++ b/emu/memory.c
@@ -54,7 +54,7 @@ void memory_write( void *obj, uint16_t addr, uint8_t data )
{
memory_t *memory = (memory_t *)obj;
- if( memory->type && MEMORY_ROM ) {
+ if( memory->type & MEMORY_ROM ) {
// ignore writes to ROM
} else {
memory->cell[addr-memory->addr] = data;
diff --git a/roms/7seg_print_loop_delay.asm b/roms/7seg_print_loop_delay.asm
new file mode 100644
index 0000000..82ec4db
--- /dev/null
+++ b/roms/7seg_print_loop_delay.asm
@@ -0,0 +1,90 @@
+PORTA = $6001
+DDRA = $6003
+
+SER = %00000001
+RCLK = %00000010
+SRCLK = %00000100
+
+COUNTER = $0
+
+ .org #$f800
+
+reset:
+ ldx #$FF ; initialize call stack to $1FF
+ txs
+
+ ldx #%00000111 ; set output on 7seg control pins of PORTA
+ stx DDRA
+
+ ldx #$0 ; initialize 8-bit counter
+ stx COUNTER
+
+mainloop: ; main loop, load counter and print it
+ jsr print7seg
+ ldx #0 ; ca 500'000 cycles, at 1 Mhz 2 ticks per second
+ ldy #0
+ lda #150
+ jsr delay
+ inc COUNTER
+ lda COUNTER
+ jmp mainloop
+
+print7seg:
+ ldy #$8 ; 8 bits to shift
+loop7seg:
+ rol a
+ bcc zerobit ; C=0, bang a zero to SER
+onebit:
+ ldx #(SER) ; C=1, bang a one to SER
+ stx PORTA
+ ldx #(SER | SRCLK)
+ stx PORTA
+ ldx #(SER)
+ stx PORTA
+ jmp next
+zerobit:
+ ldx #$0 ; C=0, bang a zero to SER
+ stx PORTA
+ ldx #SRCLK
+ stx PORTA
+ ldx #$0
+ stx PORTA
+ jmp next
+next:
+ dey
+ bne loop7seg
+ rol a ; restore A register
+output:
+ ldx #0 ; bang RCLK to store output in latch
+ stx PORTA
+ ldx #RCLK
+ stx PORTA
+ ldx #0
+ stx PORTA
+ rts
+
+; delay 18+13(65536Y+256A+X) cycles
+delay:
+ iny
+delay1:
+ nop
+ nop
+delay2:
+ cpx #$1
+ dex
+ sbc #$0
+ bcs delay1
+ dey
+ bne delay2
+ rts
+
+nmi:
+ rti
+
+irq:
+ rti
+
+ .org #$fffa
+ .word nmi
+ .word reset
+ .word irq
diff --git a/roms/7seg_print_one_subroutine.asm b/roms/7seg_print_one_subroutine.asm
index 4a1839f..2310e02 100644
--- a/roms/7seg_print_one_subroutine.asm
+++ b/roms/7seg_print_one_subroutine.asm
@@ -17,6 +17,9 @@ reset:
lda #$a5 ; 10100101, data to show
jsr print7seg
+term:
+ jmp term
+
print7seg:
ldy #$8 ; 8 bits to shift
loop:
@@ -51,9 +54,6 @@ output:
stx PORTA
rts
-term:
- jmp term
-
nmi:
rti