diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9da9ebc --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +rust/target +c64/*.vs diff --git a/c64/main.asm b/c64/main.asm new file mode 100644 index 0000000..0f578b5 --- /dev/null +++ b/c64/main.asm @@ -0,0 +1,137 @@ +// vim: filetype=kickass +#import "math.inc" + +* = $0801 // BASIC start address (#2049) +.byte $0d,$08,$dc,$07,$9e,$20,$34,$39 // BASIC loader to start at $c000... +.byte $31,$35,$32,$00,$00,$00 // puts BASIC line 2012 SYS 49152 + +* = $c000 + +.const SCREEN_RAM = $0400 +.const COLOR_RAM = $d800 + +.const kernal_scinit = $ff81 +.const kernal_chrout = $ffd2 +.const kernal_write_byte = $e716 + +.const zp_temp = $02 +.const cursor_pointer_lo = $05 +.const cursor_pointer_hi = $06 + +// +// main +// +main: + jsr clear_screen + + // lda #0 + // sta $d020 + // sta $d021 + + jsr day01 + +!loop: + // inc $d020 + jmp !loop- + +string: + .text "The quick brown newline jumped over the lazy dog." + .byte '\n' + .byte 0 + +string_cr: + .text "The quick brown carriage return jumped over the lazy dog." + .byte '\r' + .byte 0 + + +day01: + lda #str_input + sta $04 + jsr write_string + + lda #day01_input + sta $04 + jsr write_string + + lda #str_converted + sta $04 + jsr write_string + + + lda #day01_input + sta $04 + +.break + ldy #0 + +!line: + lda #0 + sta $22 + sta $23 + +!digit: + lda ($03), y + cmp #'\n' + beq !break+ + + i16_mul10($22, $23) + + lda ($03), y + + sec + sbc #'0' + + i16_i8_add_a($22, $23) + + iny + jmp !digit- + +!break: + sty $24 + + lda $23 + jsr print_hex_0x + lda $22 + jsr print_hex + + jsr print_newline + jsr print_carriage_return + + ldy $24 + iny + + lda ($03), y + bne !line- + +!done: + rts + + +day01_input: + .import text "../rust/inputs/day01_example" + .byte 0 + +str_input: + .text "# Input" + .byte '\n', 0 + +str_converted: + .byte '\n' + .text "# Converted" + .byte '\n', 0 + + +buffer: + .fill $0100, 0 + + +#import "screen.asm" diff --git a/c64/main.prg b/c64/main.prg new file mode 100644 index 0000000..a67a645 Binary files /dev/null and b/c64/main.prg differ diff --git a/c64/math.inc b/c64/math.inc new file mode 100644 index 0000000..7bae2dc --- /dev/null +++ b/c64/math.inc @@ -0,0 +1,94 @@ +// vim: filetype=kickass + +.macro i8_div5_a() { + sta zp_temp + lsr + adc #13 + adc zp_temp + ror + lsr + lsr + adc zp_temp + ror + adc zp_temp + ror + lsr + lsr +} + +.macro i16_div8(lo, hi) { + lsr cursor_pointer_hi + ror cursor_pointer_lo + + lsr cursor_pointer_hi + ror cursor_pointer_lo + + lsr cursor_pointer_hi + ror cursor_pointer_lo +} + +.macro i8_mul5_a() { + sta zp_temp + asl + asl + clc + adc zp_temp +} + +// Destroys: lo, hi +.macro i16_mul2(lo, hi) { + asl lo + rol hi +} + +// Destroys: lo, hi +.macro i16_mul4(lo, hi) { + i16_mul2(lo, hi) + i16_mul2(lo, hi) +} + +// Destroys: lo, hi +.macro i16_mul8(lo, hi) { + i16_mul4(lo, hi) + i16_mul2(lo, hi) +} + +// Destroys: a, lo, hi, $fd, $fe +.macro i16_mul10(lo, hi) { + i16_mul2(lo, hi) + + lda lo + sta $fd + lda hi + sta $fe + + i16_mul4(lo, hi) + i16_i16_add(lo, hi, $fd, $fe) +} + +// Destroys: a, dst_lo, dst_hi +.macro i16_i8_add_a(dst_lo, dst_hi) { + clc + adc dst_lo + sta dst_lo + bcc !cc+ + inc dst_hi +!cc: +} + +// Destroys: a, dst_lo, dst_hi +.macro i16_i16_add(dst_lo, dst_hi, src_lo, src_hi) { + clc + lda dst_lo + adc src_lo + sta dst_lo + lda dst_hi + adc src_hi + sta dst_hi +} + +// Destroys: a, dst_lo, dst_hi +.macro i16_inc(lo, hi) { + lda #1 + i16_i8_add_a(lo, hi) +} diff --git a/c64/screen.asm b/c64/screen.asm new file mode 100644 index 0000000..458ba4e --- /dev/null +++ b/c64/screen.asm @@ -0,0 +1,182 @@ +// vim: filetype=kickass + +// +// clear_screen +// +// Destroys: a, y +// +clear_screen: + ldy #0 + +!loop: + lda #' ' + sta SCREEN_RAM, y + sta SCREEN_RAM + $0100, y + sta SCREEN_RAM + $0200, y + sta SCREEN_RAM + $0300, y + sta SCREEN_RAM + $03e7, y + + lda #1 + sta COLOR_RAM, y + sta COLOR_RAM + $0100, y + sta COLOR_RAM + $0200, y + sta COLOR_RAM + $0300, y + sta COLOR_RAM + $03e7, y + + iny + bne !loop- + + lda #SCREEN_RAM + sta cursor_pointer_hi + + lda #23 + sta $d018 + + rts + + +// +// print_carriage_return +// +// Input: +// - cursor_pointer_{lo,hi} - Cursor pointer. +// +// Destroys: a, zp_temp +// +print_newline: + sec + lda $05 + adc #40 + sta cursor_pointer_lo + bcc !done+ + inc cursor_pointer_hi + +!done: + rts + + +// +// print_carriage_return +// +// Input: +// - cursor_pointer_{lo,hi} - Cursor pointer. +// +// Destroys: a, zp_temp +// +print_carriage_return: + // Subtract SCREEN_RAM from cursor pointer + sec + lda cursor_pointer_hi + sbc #>SCREEN_RAM + sta cursor_pointer_hi + + // Divide the cursor position by 40 (one row) + i16_div8(cursor_pointer_lo, cursor_pointer_hi) + + // At this point, the pointer fits in a 8-bit register + lda cursor_pointer_lo + i8_div5_a() + + // Multiply it by 40 again + i8_mul5_a() + sta cursor_pointer_lo + + i16_mul8(cursor_pointer_lo, cursor_pointer_hi) + + // Add SCREEN_RAM back + clc + lda cursor_pointer_hi + adc #>SCREEN_RAM + sta cursor_pointer_hi + + rts + + +// +// write_string +// +// Input: +// - $03-$04 - Pointer to null-terminated string. +// - $05-$06 - Cursor pointer. +// +// Destroys: a, x, y +// +write_string: + ldx #0 + ldy #0 + +!loop: + lda ($03), y + beq !done+ + + cmp #'\r' + beq !carriage_return+ + cmp #'\n' + beq !newline+ + + sta (cursor_pointer_lo, x) + + i16_inc(cursor_pointer_lo, cursor_pointer_hi) + + iny + jmp !loop- + +!newline: + jsr print_newline + +!carriage_return: + jsr print_carriage_return + + iny + jmp !loop- + +!done: + rts + + +print_hex_0x: + sta zp_temp + + ldx #0 + + lda #'0' + sta (cursor_pointer_lo, x) + i16_inc(cursor_pointer_lo, cursor_pointer_hi) + + lda #'x' + sta (cursor_pointer_lo, x) + i16_inc(cursor_pointer_lo, cursor_pointer_hi) + + lda zp_temp + + // fallthrough + +print_hex: + ldx #0 + sta zp_temp + + lsr + lsr + lsr + lsr + tay + + lda !hex_chars+, y + sta (cursor_pointer_lo, x) + i16_inc(cursor_pointer_lo, cursor_pointer_hi) + + lda zp_temp + and #$0f + tay + + lda !hex_chars+, y + sta (cursor_pointer_lo, x) + i16_inc(cursor_pointer_lo, cursor_pointer_hi) + + rts + +!hex_chars: + .text "0123456789ABCDEF" +