diff --git a/examples/Makefile b/examples/Makefile index ad80afd..5cd4e79 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -15,7 +15,7 @@ RK6502LIB=../src/librk65c02.a VASM=vasm6502_std VASMFLAGS=-Fbin -wdc02 -EXAMPLES=min3 +EXAMPLES=min3 mul_8bit_to_8bits EXAMPLES_ROMS:=$(addsuffix .rom,$(basename $(wildcard *.s))) all : $(EXAMPLES) $(EXAMPLES_ROMS) @@ -23,6 +23,9 @@ all : $(EXAMPLES) $(EXAMPLES_ROMS) min3 : min3.o $(RK6502LIB) $(CC) -o $@ $(LDFLAGS) $< $(RK6502LIB) +mul_8bit_to_8bits : mul_8bit_to_8bits.o $(RK6502LIB) + $(CC) -o $@ $(LDFLAGS) $< $(RK6502LIB) + %.rom : %.s $(VASM) $(VASMFLAGS) -o $@ $< diff --git a/examples/mul_8bit_to_8bits.c b/examples/mul_8bit_to_8bits.c new file mode 100644 index 0000000..f75946c --- /dev/null +++ b/examples/mul_8bit_to_8bits.c @@ -0,0 +1,32 @@ +#include +#include + +#include "rk65c02.h" +#include "bus.h" +#include "log.h" +#include "instruction.h" + +static const uint16_t load_addr = 0xC000; + +int main(void) +{ + uint8_t num1, num2; + uint8_t res; + + rk65c02emu_t e; + + e = rk65c02_load_rom("mul_8bit_to_8bits.rom", load_addr, NULL); + + e.regs.SP = 0xFF; + e.regs.PC = load_addr; + num1 = 4; num2 = 8; + + stack_push(&e, num1); + stack_push(&e, num2); + + rk65c02_start(&e); + + res = stack_pop(&e); + printf("Result of multiplication: %d\n", res); +} + diff --git a/examples/mul_8bit_to_8bits.s b/examples/mul_8bit_to_8bits.s new file mode 100644 index 0000000..a07a5da --- /dev/null +++ b/examples/mul_8bit_to_8bits.s @@ -0,0 +1,50 @@ +.org 0xC000 +start: jsr mul_8bit_to_8bits + stp + +; mul_8bit_to_8bits +; Multiplies 2 numbers (passed on stack) and returns result on stack. + +; General 8bit * 8bit = 8bit multiply +; by White Flame 20030207 +; adapted as rk65c02 example by rkujawa + +; Instead of using a bit counter, this routine early-exits when num2 reaches +; zero, thus saving iterations. + +; .X and .Y are preserved +; num1 and num2 get clobbered +.set num1,0x10 +.set num2,0x11 +.set retl,0x12 +.set reth,0x13 + +mul_8bit_to_8bits: + pla ; pull return address + sta retl + pla + sta reth + pla ; pull num1 from stack + sta num1 + pla ; pull num2 from stack + sta num2 + + lda #0x00 + beq enterl +doAdd: clc + adc num1 +loop: asl num1 +; For an accumulating multiply (A = A + num1 * num2), +; set up num1 and num2, then enter here. +enterl: lsr num2 + bcs doAdd + bne loop +end: + pha ; save result to stack + lda reth ; restore return address + pha + lda retl + pha + rts ; return from function + +