diff --git a/host/src/STARTUP.s b/host/src/STARTUP.s index 0852267..bc9ebc8 100755 --- a/host/src/STARTUP.s +++ b/host/src/STARTUP.s @@ -58,17 +58,14 @@ ORA Screen_RAM_settings STA Screen_RAM_settings - ;; Paint the bitmap black. More bitmap: https://www.c64-wiki.com/wiki/53272, https://www.c64-wiki.com/wiki/Screen_RAM#Moving_of_screen_RAM - Mov_16 A_start, A_start + 1, #VIC_bank - Mov_16 length, length + 1, #<$1f40, #>$1f40 - LDA #$00 - jsr memset + ;; clear the screen + JSR clear_screen ;; Sets the screen color to black and white Mov_16 A_start, A_start + 1, #Screen_RAM Mov_16 length, length + 1, #<$03E8, #>$03E8 LDA #%11110000 - jsr memset + JSR memset ;; Disable maskeble interups (not all) SEI diff --git a/host/src/routines/circle/circle_test_position.s b/host/src/routines/circle/circle_test_position.s index 1c3ea74..ffa296f 100644 --- a/host/src/routines/circle/circle_test_position.s +++ b/host/src/routines/circle/circle_test_position.s @@ -21,12 +21,8 @@ loop: ; DEY ; BNE delay_point - ;;clear screen - VIC_bank = $4000 - Mov_16 A_start, A_start + 1, #VIC_bank - Mov_16 length, length + 1, #<$1f40, #>$1f40 - LDA #$00 - jsr memset + + JSR clear_screen ;;move circle INC $AD diff --git a/host/src/routines/circle/circle_test_size.s b/host/src/routines/circle/circle_test_size.s index 02f901b..1c9093a 100644 --- a/host/src/routines/circle/circle_test_size.s +++ b/host/src/routines/circle/circle_test_size.s @@ -30,12 +30,7 @@ loop: LDA $AD STA radius - ;; clean the screen - VIC_bank = $4000 - Mov_16 A_start, A_start + 1, #VIC_bank - Mov_16 length, length + 1, #<$1f40, #>$1f40 - LDA #$00 - jsr memset + JSR clear_screen ;; draw the circle JSR circle diff --git a/host/src/routines/line/line.s b/host/src/routines/line/line.s index 9768771..89a50de 100644 --- a/host/src/routines/line/line.s +++ b/host/src/routines/line/line.s @@ -5,26 +5,24 @@ .include "line.inc" ;; Fix line that is too long - LDA Y_pos - CMP #$C8 ;;y_max = $C8 - BCC do_not_fix_y_pos - LDA #$C8 + LDA #$C8 ;y_max = $C8 + CMP Y_pos + BCS do_not_fix_y_pos STA Y_pos do_not_fix_y_pos: - LDA Y_end - CMP #$C8 ;;y_max = $C8 - BCC do_not_fix_y_end LDA #$C8 + CMP Y_pos ;y_max = $C8 + BCS do_not_fix_y_end STA Y_end do_not_fix_y_end: - ;;dx SEC LDA X_end SBC X_pos BCS dx_no_underflow;; X_end >= X_pos EOR #$ff ; Fix bit underflow + ADC #$01 STA dx ;; line_* expect X_pos < X_end and now its not the case. ;; Lets move them around @@ -36,28 +34,27 @@ do_not_fix_y_end: LDY Y_end STX Y_end STY Y_pos - - dx_no_underflow: STA dx + SEC - LDA Y_pos - SBC Y_end - STA dy - BCC down ;normal Y_pos < Y_end + LDA Y_end + SBC Y_pos + BCS down ;normal Y_pos < Y_end up:; Y_pos > Y_end + EOR #$ff ; Fix bit underflow + ADC #$01 STA dy + CMP dx BCC shallow; dy < dx steep: jsr line_up_inv RTS shallow: ;dy =< dx - lda dx jsr line_up RTS down: - EOR #$ff ; Fix bit underflow STA dy CMP dx BCC shallow_; dy < dx diff --git a/host/src/routines/line/line_down.s b/host/src/routines/line/line_down.s index b81a095..6641a0a 100644 --- a/host/src/routines/line/line_down.s +++ b/host/src/routines/line/line_down.s @@ -67,6 +67,7 @@ end_selfmod: STA byte_to_paint ;; X = X_end - X_pos LDX dx + INX ; okay if it overflow to $00 because it will go back to $ff in loop. Sub_16 btp_mem_pos, btp_mem_pos + 1, #$00, #$00,! ;; Y has always a offset of at least 1 = C + $0000 INY for_x: diff --git a/host/src/routines/line/line_down_inv.s b/host/src/routines/line/line_down_inv.s index 465ffdf..4446379 100644 --- a/host/src/routines/line/line_down_inv.s +++ b/host/src/routines/line/line_down_inv.s @@ -55,6 +55,7 @@ end_selfmod: INY Sub_16 btp_mem_pos, btp_mem_pos + 1, #$00, #$00, ! LDX dy + INX CLC for_y: ; C =0 LDA byte_to_paint diff --git a/host/src/routines/line/line_test_extensive.s b/host/src/routines/line/line_test_extensive.s index 4f79005..8438af5 100644 --- a/host/src/routines/line/line_test_extensive.s +++ b/host/src/routines/line/line_test_extensive.s @@ -8,6 +8,8 @@ X_pos_ = $0E Y_end_ = $0F X_end_ = $0C + +full_angle_test: LDA #$d2 STA X_pos_ LDA #$62 @@ -34,23 +36,45 @@ CMP #$ff bne @loop -clear_screen: - ;;Lets clear bitmap - VIC_bank = $4000 - ;;Paint the bitmap black. More bitmap: https://www.c64-wiki.com/wiki/53272, https://www.c64-wiki.com/wiki/Screen_RAM#Moving_of_screen_RAM - Mov_16 A_start, A_start + 1, #VIC_bank - Mov_16 length, length + 1, #<$1f40, #>$1f40 - LDA #$00 - jsr memset +jsr clear_screen + +full_angle_test_pos_end_swapped: +LDA #$d2 +STA X_end_ +LDA #$62 +STA Y_end_ +LDA #$ff +STA X_pos_ +LDA #$0 +STA Y_pos_ + +;; Full angle test +@loop: +LDA Y_end_ +STA Y_end +LDA X_end_ +STA X_end +LDA X_pos_ +STA X_pos +LDA Y_pos_ +STA Y_pos + +jsr line +INC Y_pos_ +LDA Y_pos_ +CMP #$ff +bne @loop + +jsr clear_screen long_line_test_a: - LDA #$00 + LDA #$01 STA X_pos_ LDA #$60 STA Y_pos_ LDA #$ff STA X_end_ - LDA #$0 + LDA #$00 STA Y_end_ @loop: LDA Y_pos_ @@ -68,15 +92,10 @@ long_line_test_a: CMP #$ff BNE @loop -clear_screen_: - ;;Paint the bitmap black. More bitmap: https://www.c64-wiki.com/wiki/53272, https://www.c64-wiki.com/wiki/Screen_RAM#Moving_of_screen_RAM - Mov_16 A_start, A_start + 1, #VIC_bank - Mov_16 length, length + 1, #<$1f40, #>$1f40 - LDA #$00 - jsr memset + jsr clear_screen long_line_test_b: - LDA #$00 + LDA #$01 STA X_pos_ LDA #$00 STA Y_pos_ @@ -99,15 +118,10 @@ long_line_test_b: CMP #$ff BNE @loop -clear_screen__: - ;;Paint the bitmap black. More bitmap: https://www.c64-wiki.com/wiki/53272, https://www.c64-wiki.com/wiki/Screen_RAM#Moving_of_screen_RAM - Mov_16 A_start, A_start + 1, #VIC_bank - Mov_16 length, length + 1, #<$1f40, #>$1f40 - LDA #$00 - jsr memset +jsr clear_screen long_line_test_b_pos_end_swapped: - LDA #$00 + LDA #$01 STA X_end_ LDA #$00 STA Y_end_ diff --git a/host/src/routines/line/line_up.s b/host/src/routines/line/line_up.s index 0edae87..24f1ae1 100644 --- a/host/src/routines/line/line_up.s +++ b/host/src/routines/line/line_up.s @@ -50,6 +50,7 @@ end_selfmod: ;LDY #$01 INY LDX dx + INX for_x: LDA byte_to_paint ORA (btp_mem_pos), Y diff --git a/host/src/routines/line/line_up_inv.s b/host/src/routines/line/line_up_inv.s index 5ad7940..44719e8 100644 --- a/host/src/routines/line/line_up_inv.s +++ b/host/src/routines/line/line_up_inv.s @@ -34,7 +34,7 @@ STA D + 1 ;; because C flag is wrong value we let dy_2 be 1 to small - Sub_16 dy_2, dy_2 +1, #$01,#$00 + Sub_16 dx_2, dx_2 +1, #$01,#$00 selfmod: LDA dx_2 @@ -52,6 +52,7 @@ end_selfmod: Sub_16 btp_mem_pos, btp_mem_pos + 1, #$00, #$00,! CLC LDX dy + INX for_y: LDA byte_to_paint ORA (btp_mem_pos), Y diff --git a/host/src/routines/memory/clear_screen.s b/host/src/routines/memory/clear_screen.s new file mode 100644 index 0000000..e55edb8 --- /dev/null +++ b/host/src/routines/memory/clear_screen.s @@ -0,0 +1,39 @@ +;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*- + +;; Sets memory in 'A'-registry to all addresses from 'A_start' until 'A_start' + 'length' +;; Modifies A, X and A_start +.proc clear_screen + .include "mem.inc" + VIC_bank = $4000 + length_ = $1f40 + low_length_3 = $C0 + $03 ;; we need one more. + Mov_16 A_start, A_start + 1, #VIC_bank + LDA #$00 + ;; big_set sets the memory in $ff chunks. + ;; skipp if length >= $ff + LDX #>length_ + BNE big_set + JMP small_set +big_set: ;sets $ff of memory + ;; Y value do not matter, will go through all anyway! + .repeat $ff + STA (A_start), Y + DEY + .endrepeat + STA (A_start), Y ; dont forget Y =0 +big_set_end: + ;;set all hole $ff memory chunks! + INC A_start + 1 + DEX ;; length +1 -- + BEQ small_set + JMP big_set + +small_set: + LDX big_set + low_length_3 + LDY #$60 + STY big_set + low_length_3 + LDY #= $ff -LDX length +1 -BNE big_set -JMP small_set - -big_set: ;sets $ff of memory - ;; Y value do not matter, will go through all anyway! - .repeat $ff - STA (A_start), Y - DEY - .endrepeat - STA (A_start), Y ; dont forget Y =0 -big_set_end: - ;;set all hole $ff memory chunks! - INC A_start + 1 - DEX ;; length +1 -- - BEQ small_set - JMP big_set - - - -;;sets the rest of the memory -;; note that this can use code above (smc) or the same method. may implement later. -small_set: - LDY length -small_set_loop: - STA (A_start), Y - DEY - BNE small_set_loop - STA (A_start), Y - RTS -.endproc +;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*- + +;; Sets memory in 'A'-registry to all addresses from 'A_start' until 'A_start' + 'length' +;; Modifies A, X and A_start +.proc memset + .include "mem.inc" + +;; big_set sets the memory in $ff chunks. +;; skipp if length >= $ff +LDX length +1 +BNE big_set +JMP small_set + +big_set: ;sets $ff of memory + ;; Y value do not matter, will go through all anyway! + .repeat $ff + STA (A_start), Y + DEY + .endrepeat + STA (A_start), Y ; dont forget Y =0 +big_set_end: + ;;set all hole $ff memory chunks! + INC A_start + 1 + DEX ;; length +1 -- + BEQ small_set + JMP big_set + +;; Note that cpu cykels total: cy_tot = 66 to 69 +;; But we skipp a BNE (cy = 2*) * [length (mod 255)] +;; The BNE case has an avrige of 2*255/2 = 255 so this is faster (on avrige.) + +small_set: + STA data_to_write ; cy = 3 + LDA length ; cy = 3 + STA length_copy ; cy = 3 + + ;; calculate rts-position + LDX #$00 ; cy = 2 + STX length + 1 ; cy = 3 + ;; 3 bytes = STA DEY NOP = seting 1 byte of memory. + ;; So we need to calculate: length*3 + Mult_16 A, length + 1 ; cy = 7 + ; A= length + ADC length_copy ; cy = 3 + TAY + LDA length + 1 ; cy = 3 + ADC #$00 ; cy = 2 + STA length + 1 ; cy = 3 + + ;; Now RTS_pointer + Y = length*3 + big_set_label + LDA #big_set ; cy = 2 + ADC length + 1 ; cy = 3 + STA RTS_pointer + 1 ; cy = 3 + + ;; read data we will change to RTS + STY Y_copy ; cy = 3 + LDA (RTS_pointer), Y ; cy = 5* + TAX ; cy = 2 + + ;; set RTS in big_set + LDA #$60 ; cy = 2 + STA (RTS_pointer), Y ; cy = 5* + + ;; JSR to modified big_set + LDY length_copy ; cy = 3 + DEY ; because we want to count to Y=0 :) + LDA data_to_write ; cy = 3 + JSR big_set ; cy = 6 + + ;; revert changes + LDY Y_copy ; cy = 3 + TXA ; cy = 2 + STA (RTS_pointer), Y ; cy = 5* + + RTS +.endproc diff --git a/host/src/routines/memory/memset_alt.s b/host/src/routines/memory/memset_alt.s deleted file mode 100644 index b2c50b9..0000000 --- a/host/src/routines/memory/memset_alt.s +++ /dev/null @@ -1,75 +0,0 @@ -;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*- - -;; Sets memory in 'A'-registry to all addresses from 'A_start' until 'A_start' + 'length' -;; Modifies A, X and A_start -.proc memset - .include "mem.inc" - -;; big_set sets the memory in $ff chunks. -;; skipp if length >= $ff -LDX length +1 -BNE big_set -JMP small_set - -big_set: ;sets $ff of memory - ;; Y value do not matter, will go through all anyway! - .repeat $ff - STA (A_start), Y - DEY - .endrepeat - STA (A_start), Y ; dont forget Y =0 -big_set_end: - ;;set all hole $ff memory chunks! - INC A_start + 1 - DEX ;; length +1 -- - BEQ small_set - JMP big_set - - -small_set: - STA data_to_write - LDA length - STA length_copy - - ;; calculate rts-position - LDX #$00 - STX length + 1 - ;; 3 bytes = STA DEY NOP = seting 1 byte of memory. - ;; So we need to calculate: length*3 - Mult_16 A, length + 1 - ; A= length - ADC length_copy - TAY - LDA length + 1 - ADC #$00 - STA length + 1 - - ;; Now RTS_pointer + Y = length*3 + big_set_label - LDA #big_set - ADC length + 1 - STA RTS_pointer + 1 - - ;; read data we will change to RTS - STY Y_copy - LDA (RTS_pointer), Y - TAX - - ;; set RTS in big_set - LDA #$60 - STA (RTS_pointer), Y - - ;; JSR to modified big_set - LDY length_copy - DEY ; because we want to count to Y=0 :) - LDA data_to_write - JSR big_set - - ;; revert changes - LDY Y_copy - TXA - STA (RTS_pointer), Y - - RTS -.endproc diff --git a/host/src/source.s b/host/src/source.s index 0d63e58..4768068 100644 --- a/host/src/source.s +++ b/host/src/source.s @@ -39,7 +39,8 @@ JMP exit .include "routines/pixel/pixel_draw.s" .include "routines/pixel/pixel_calc.s" .include "routines/text/char_draw.s" -.include "routines/memory/memset_alt.s" +.include "routines/memory/memset.s" +.include "routines/memory/clear_screen.s" .include "routines/memory/memcpy.s" .include "routines/arithmatic/mult.s" .include "routines/arithmatic/div.s"