From c40499b83f238de9b1a88a080261546149784586 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Thu, 3 Dec 2020 19:03:08 +0100 Subject: some more opcodes for delay 7-seg example --- emu/6502.c | 68 +++++++++++++++++++++++++++- emu/6502.h | 10 ++++- emu/memory.c | 2 +- roms/7seg_print_loop_delay.asm | 90 ++++++++++++++++++++++++++++++++++++++ roms/7seg_print_one_subroutine.asm | 6 +-- 5 files changed, 170 insertions(+), 6 deletions(-) create mode 100644 roms/7seg_print_loop_delay.asm 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 -- cgit v1.2.3-54-g00ecf