// vim: filetype=kickass *=* "Screen Routines" // // clear_screen // // Destroys: a, y // clear_screen: lda #$06 sta $d021 lda #$0e sta $d020 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 cursor_pointer_lo adc #40 sta cursor_pointer_lo bcc !done+ inc cursor_pointer_hi !done: // fallthrough // // 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, $02 // write_string: ldx #0 ldy #0 !loop: lda ($03), y beq !done+ iny cmp #'\r' beq !carriage_return+ cmp #'\n' beq !newline+ sta (cursor_pointer_lo, x) i16_inc(cursor_pointer_lo) jmp !loop- !newline: jsr print_newline jmp !loop- !carriage_return: jsr print_carriage_return jmp !loop- !done: rts .macro i16_print_hex_0x(addr) { lda addr + 1 jsr print_hex_0x lda addr jsr print_hex } // Destroys: a, x, y, zp_temp ($02) print_hex_0x: sta zp_temp ldx #0 lda #'0' sta (cursor_pointer_lo, x) i16_inc(cursor_pointer_lo) lda #'x' sta (cursor_pointer_lo, x) i16_inc(cursor_pointer_lo) 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) lda zp_temp and #$0f tay lda !hex_chars+, y sta (cursor_pointer_lo, x) i16_inc(cursor_pointer_lo) rts !hex_chars: .text "0123456789ABCDEF" // Input: // - $03..$04: The number to print // // Destroys: a, y, $24..$25 print_decimal_u16: ldy #6 // Null-terminate the buffer lda #0 sta !buffer+, y !loop: u16_div10() u16_u16_move($22, $24) i16_mul10($22) i16_i16_sub($22, $23, $03, $04, $22, $23) u16_u16_move($03, $24) lda $22 clc adc #'0' sta !buffer+ - 1, y dey bne !loop- // Find the first digit ldy #0 !: lda !buffer+, y iny cmp #'0' beq !- dey tya clc adc #<(!buffer+) sta $03 lda #0 adc #>(!buffer+) sta $04 jsr write_string rts // // Input: // - udivmod32_dividend - Number to print // // Destroys: a, y, $02..$04, $10..$2b // print_decimal_u32: ldy #11 // Null-terminate the buffer lda #0 sta !buffer+, y lda #0 sta udivmod32_divisor + 3 sta udivmod32_divisor + 2 sta udivmod32_divisor + 1 lda #10 sta udivmod32_divisor + 0 !loop: jsr udivmod32 lda udivmod32_remainder clc adc #'0' sta !buffer+ - 1, y lda udivmod32_result + 0 sta udivmod32_dividend + 0 lda udivmod32_result + 1 sta udivmod32_dividend + 1 lda udivmod32_result + 2 sta udivmod32_dividend + 2 lda udivmod32_result + 3 sta udivmod32_dividend + 3 dey bne !loop- // Find the first digit ldy #0 !: lda !buffer+, y iny cmp #'0' beq !- dey tya clc adc #<(!buffer+) sta $03 lda #0 adc #>(!buffer+) sta $04 jsr write_string rts !buffer: .fill 12, 0 wait_space_then_reset: ldx #$ff stx $dc02 ldy #$00 sty $dc03 !: lda #$7f sta $dc00 lda $dc01 and #$10 bne !- move_16_imm($03, !str_resetting+) jsr write_string // Reset lda #%00110111 sta $01 jmp $fce2 rts !str_resetting: .byte '\n' .text "Resetting..." .byte 0 str_part2: .byte '\n' .text "Part 2: " .byte 0 str_done: .byte '\n', '\n' .text "* Done" .byte '\n', 0