Added Marcus first effect, with help from Duuqnd and hugova

This commit is contained in:
Marcus Dicander 2025-04-03 23:22:57 +02:00
parent f93557bfd9
commit 594218d485
17 changed files with 1115 additions and 0 deletions

82
wip-dicander/STARTUP.s Executable file
View file

@ -0,0 +1,82 @@
.scope STARTUP
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
;;Settings positions
CR1 = $d011; ;Graphic settings
VIC_bank_settings = $DD00 ; Vic position
Screen_RAM_settings =$D018 ;Screen RAM position relative to VIC
;;########## VIC_BANK ################
;;# BITMAP | $4000 -$5F3F
;;# Unused? | $5F3F - $6000
;;# SCREAN RAM (color) | $6000 -$63E7
;;# Unused? | $63E8 - $7FFF
;;#
;;####################################
;;Memory positions
VIC_bank = $4000
VIC_bank_end = VIC_bank + $3FFF
Bitmap = VIC_bank
Bitmap_end = $5F3F
Screen_RAM = $2000 + VIC_bank
Screen_RAM_end = Screen_RAM + $03E7
Character_generator_ROM = $D000
;;Free up memory
;;https://www.c64-wiki.com/wiki/Bank_Switching
;;
;;Set graphic mode [Standard bitmap mode]
;;https://www.c64-wiki.com/wiki/Standard_Bitmap_Mode
LDA #%10111111 ; ECM = False Extended color mode
AND CR1
STA CR1
LDA #%00100000; BMM = True Bitmap mode
ORA CR1
STA CR1
;;Set VIC bank to bank 1
;;https://www.c64-wiki.com/wiki/VIC_bank
LDA #%11111110 ;bit_0 = False
AND VIC_bank_settings
STA VIC_bank_settings
LDA #%00000010; bit_1 = True
ORA VIC_bank_settings
STA VIC_bank_settings
;;Set Scren-RAM to offset 8 ;https://www.c64-wiki.com/wiki/53272 (offset is 8k byte = 1024*8-ich)
LDA #%10001111 ; bit_6 =bit_5=bit_4 = Falsw
AND Screen_RAM_settings
STA Screen_RAM_settings
LDA #%10000000; bit_1 = True
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 >B_start, <B_start, #<VIC_bank, #>VIC_bank
Mov_16 >B_end, <B_end, #<$5f3f, #>$5f3f
LDA #$00
jsr memset
;;Sets the screen color to black and white
Mov_16 >B_start, <B_start, #<Screen_RAM, #>Screen_RAM
Mov_16 >B_end, <B_end, #<Screen_RAM_end, #>Screen_RAM_end
LDA #%11110000
jsr memset
SEI ;Disable interups (not all)
;;Disable BASIC ROM mohahaha
LDA #%11111110
AND $0001
STA $0001
;https://www.c64-wiki.com/wiki/Bank_Switching
;Disable IO, CHAREN =0
;LDA #%11111011
;AND $0001
;STA $0001
.endscope

View file

@ -0,0 +1,140 @@
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
;; A file containing 16-bit macro arithmatic.
;; You may add ,! ass a 5:th parameter to skipp flagg clearing.
;; This will make it run faster but will have unintended behavior.
;;Se below for some fast 16bit logic
;;http://6502.org/tutorials/compare_beyond.html
;; Addition always uses the A register
;; a = a + b
.macro Add_16 a_low, a_hi, b_low, b_hi, fast_unsafe
;; IF to run it fast
.ifblank fast_unsafe
CLC
.endif
.if .not .match ({b_low}, a)
LDA b_low
.endif ;;untested
ADC a_low
STA a_low
.if .match ({b_hi}, x) ;;Untested
TXA
.else
LDA b_hi
.endif
ADC a_hi
STA a_hi
.endmacro
;; Subtraction uses always uses A register
;; a = a - b
.macro Sub_16 a_low, a_hi, b_low, b_hi, fast_unsafe
;; IF to run it fast
.ifblank fast_unsafe
SEC
.endif
;; if b_low = A and b_hi =A
.if .match({b_low}, a) .and .match({b_hi}, a) ;;untested
.LOCAL rewrite
.LOCAL rewrite2
STA rewrite +1
STA rewrite2 + 1
LDA a_low
rewrite:
SBC #b_low
STA a_low
LDA a_hi
rewrite2:
SBC #b_hi
STA a_hi
;; if b_low = A
.elseif .match({b_low}, a) ;;untested
.LOCAL rewrite
STA rewrite +1
LDA a_low
rewrite:
SBC #b_low
STA a_low
LDA a_hi
SBC b_hi
STA a_hi
.elseif .match({b_hi}, a) ;;untested
.LOCAL rewrite
STA rewrite +1
LDA a_low
SBC b_low
STA a_low
LDA a_hi
rewrite:
SBC #b_hi
STA a_hi
.else
LDA a_low
SBC b_low
STA a_low
LDA a_hi
SBC b_hi
STA a_hi
.endif
.endmacro
;; Subtraction uses always uses A register
;; a = (A, a_hi) - b
.macro Sub_16_A a_low, a_hi, b_low, b_hi, fast_unsafe
;; IF to run it fast
.ifblank fast_unsafe
SEC
.endif
SBC b_low
STA a_low
LDA a_hi
SBC b_hi
STA a_hi
.endmacro
;; Multiplication of 2
;; a = a*2
.macro Mult_16 low_, hi_, NOT_ROL
;; IF NOT_ROL
.ifblank fast_unsafe
ASL low_
ROL hi_
.else
ROL low_
ROL hi_
.endif
.endmacro
.macro Mov_16 a_low, a_hi, b_low, b_hi
LDA b_low
STA a_low
LDA b_hi
STA a_hi
.endmacro
;;http://www.6502.org/tutorials/compare_beyond.html
;;Larger then operation, uses the A register
;;IF a < b then: jump to label
; C =0 if jump to LABEL
.macro Lag_16 a_low, a_hi, b_low, b_hi, label
.LOCAL LABEL
LDA a_hi
CMP b_hi
BCC label
BNE LABEL
LDA a_low
.if .match ({b_low}, a)
.LOCAL next
STY next +1
next:
CMP #$ff
.else
CMP b_low
.endif
BCC label
LABEL:
.endmacro

View file

@ -0,0 +1,34 @@
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
;; Max 0.9s
;; Exempel i kod:
;;
;; time_start
;; ...
;; time_stop
;;
;; Läs tiden genom att undersöka värdet i $f1 (BSD-format)
time = $f1
.macro time_start
PHA
LDA $DC08 ; Bit 0..3: Tenth seconds in BCD-format, others may be 0 or 1
;;;;Clear all time data and set time =1.
AND #%11110000
STA $DC08
INC $DC08
LDA $DC08
;;Time is only at bit 0 ..3
AND #%00001111
STA time
PLA
.endmacro
.macro time_stop
PHA
LDA $DC08 ; Bit 0..3: Tenth seconds in BCD-format, others may be 0 or 1
AND #%00001111
SEC
SBC time
STA time
PLA
.endmacro

View file

@ -0,0 +1,47 @@
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
.proc line; X_pos =< X_end skall alltid gälla
.include "line.inc"
; dx_ = $0c
; dy_ = $06
;;dx
SEC
LDA X_end
SBC X_pos
STA dx
BCC dx_no_underflow;; X_end >= X_pos
EOR #$ff ; Fix bit underflow
dx_no_underflow:
SEC
LDA Y_pos
SBC Y_end
STA dy
BCC down ;normal Y_pos < Y_end
up:; Y_pos > Y_end
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
steep_:
jsr line_down_inv
RTS
shallow_: ;dy < dx
jsr line_down
RTS
.include "line_down.s"
.include "line_down_inv.s"
.include "line_up.s"
.include "line_up_inv.s"
.endproc

View file

@ -0,0 +1,116 @@
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
;;drawing line from 2 cordinates
;;# (X_pos, Y_pos) #
;;# * #
;;# * #
;;# * #
;;# (X_end, Y_end) #
;;NOTE THAT X_pos <= X_end, Y_pos <= Y_end. Max 45deg!
.proc line_down
.include "line.inc"; Defines memory positions, ex X_pos
;;We need to clear this memory
LDA #$00
STA <V
STA <dy_2
STA $FD ; for pixel_draw
;; V = 2*(dx -dy)
SEC
LDA dx
SBC dy
STA >V
Mult_16 >V, <V
;dy_2 = dy*2
Mult_16 >dy_2, <dy_2 ;>dy_2 = dy (same address)
;; This is an Bresenham's line algorithm, se wikipedia bellow.
;;https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
;; We need to compute the Value D = 2*dy - dx,
;; but it may be or get negative.
;; IN the loop we may set D = D -V
;; Because math D needs to be at least >=V.
;; V_max = %00000001 11111111
;; We therefor need to add this offset to V 00000001 11111111
;; and to its branch logic later in the loop.
;;D = 2*dy - dx + 2*255
Mov_16 >D, <D, >dy_2, <dy_2
Add_16 >D, <D, #$ff, #$01, !
Sub_16 >D, <D, dx, #$00
selfmod:
;; Self modifying code. Makes LDA and SBC instructions each take 1 cycle less.
;; You can remove this if you run the loop without # at dy_2 and V.
;;Note: The offsets like +2 etc is because there are instructions betwean the label and the
;address that needs to be modified
;; dy_2
;; Modifies LDA >dy_2
LDA >dy_2
STA case_2 +1
;; Modifies LDA <dy_2
LDA <dy_2
STA case_2 +7
;; V
;;Modidies SBC >V
LDA >V
STA case_1 +1
;; Modifies SBC <V
LDA <V
STA case_1 +7
end_selfmod:
JSR pixel_draw ;;only used first pixel. after this relative position is abused
;; X = X_end - X_pos
LDX dx
LDY #$00
for_x:
;; Paints A to address in |btp_mem_pos* + Y|
;; Y is pixel position in the chunk. Therefor it may be that Y = 0, 1, 2, 3, 4, ,5 ,6 ,7.
LDA byte_to_paint ;A byte containing a single 1. Coresponds to X position in the chunk.
ORA (>btp_mem_pos), Y
STA (>btp_mem_pos), Y
increment_pixel_x:
LSR byte_to_paint ; Rotates the pixel one bit to the left ON THE SCREEN.
BCC increment_pixel_x_end; We need to move to the next chunk
move_8px_left:
;; Next chunk is 8 addresses away. Look in pixel_draw for more detail.
;; -8.
;; C = 1 therefore you se 07
Add_16 >btp_mem_pos, <btp_mem_pos, #$07, #$00, !
;; Restores byte to paint
LDA #%10000000
STA byte_to_paint
increment_pixel_x_end:
DEX
BEQ end ;We keep track on when to stop line draw with the X registry.
;;If D < %00000010 00000000: case_2
;;else case 1.
Lag_16 >D, <D, #$00, #$02, case_2
case_1:
;; D = D - V
;; Because Lag_16:
;; C =1 so we can use !
;; A = >D
Sub_16_A >D, <D, #>V, #<V, !
increment_y_pos:
INY ; Increment Y pos inside the buffer
CPY #$08
BNE for_x
move_8px_down: ; Z=1 --> C=1
LDY #$00
;; Switch to chunk bellow
; C = 1
; So we subtract #$3F, #$01 +C
Add_16 >btp_mem_pos, <btp_mem_pos, #$3F, #$01, !; +320
JMP for_x
increment_y_pos_end:
case_2:
Add_16 >D, <D, #>dy_2, #<dy_2, ! ;D = D + 2*dy
JMP for_x
end:
RTS
.endproc

View file

@ -0,0 +1,77 @@
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
;;drawing line from 2 cordinates
;;# (X_pos, Y_pos) #
;;# * #
;;# * #
;;# * #
;;# (X_end, Y_end) #
;;NOTE THAT X_pos <= X_end, Y_pos <= Y_end. Min 45deg!
.proc line_down_inv
;; Look at line_down for referense
.include "line.inc"; Defines memory positions, ex X_pos
LDA #$00
STA <V
STA <dx_2
STA $FD
SEC
LDA dy
SBC dx
STA >V
Mult_16 >V, <V
Mult_16 >dx_2, <dx_2
Mov_16 >D, <D, >dx_2, <dx_2
Add_16 >D, <D, #$ff, #$01, !
Sub_16 >D, <D, dy, #$00
selfmod:
LDA >dx_2
STA case_2 +1
LDA <dx_2
STA case_2 +7
LDA >V
STA case_1 +1
LDA <V
STA case_1 +7
end_selfmod:
jsr pixel_draw
LDY #$00
LDX dy
for_y:
LDA byte_to_paint
ORA (>btp_mem_pos), Y
STA (>btp_mem_pos), Y
increment_y_pos:
INY
CPY #$08
BNE increment_y_pos_end
move_8px_down:
LDY #$00
Add_16 >btp_mem_pos, <btp_mem_pos, #$3F ,#$01, !
increment_y_pos_end:
DEX
;CPX Y_end
BEQ end
Lag_16 >D, <D, #$00, #$02, case_2
case_1:
Sub_16_A >D, <D, #>V, #<V, !
increment_pixel_x:
LDA byte_to_paint
LSR byte_to_paint
BCC for_y
move_8px_left:
Add_16 >btp_mem_pos, <btp_mem_pos, #$07, #$00, !
LDA #%10000000
STA byte_to_paint
JMP for_y
case_2:
Add_16 >D, <D, #>dx_2, #<dx_2, ! ;D = D + 2*dx
JMP for_y
end:
RTS
.endproc

View file

@ -0,0 +1,81 @@
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
.scope line_test
.include "line.inc"
;;for testing stuff
Y_pos_ = $0D
X_pos_ = $0E
Y_end_ = $10
X_end_ = $11
LDA #$d2
STA X_pos_
LDA #$62
STA Y_pos_
LDA #$ff
STA X_end
LDA #$0
STA Y_end
;; Short test for timing
@loop:
LDA Y_pos_
STA Y_pos
LDA X_pos_
STA X_pos
jsr line
INC Y_end
LDA Y_end
CMP #$bb
BEQ end__
jmp @loop
end__:
;; Full anfle test
@loop:
LDA Y_pos_
STA Y_pos
LDA X_pos_
STA X_pos
jsr line
INC Y_end
LDA Y_end
CMP #$bb
BEQ end
jmp @loop
end:
;;Long lines
;;Lets cleer bitmap
B_start = $FCFD
B_end = $FEFF
VIC_bank = $4000
VIC_bank_end = VIC_bank + $3FFF
;;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 >B_start, <B_start, #<VIC_bank, #>VIC_bank
Mov_16 >B_end, <B_end, #<$5f3f, #>$5f3f
LDA #$00
jsr memset
LDA #$00
STA X_pos_
LDA #$60
STA Y_pos_
LDA #$ff
STA X_end
LDA #$0
STA Y_end
@loop:
LDA Y_pos_
STA Y_pos
LDA X_pos_
STA X_pos
jsr line
INC Y_end
LDA Y_end
CMP #$bb
BEQ end_
jmp @loop
end_:
jmp exit
.endscope

View file

@ -0,0 +1,49 @@
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
.scope line_test_time
.include "line.inc"
;;START TIME HERE
;;for testing stuff
Y_pos_ = $0D
X_pos_ = $0E
Y_end_ = $10
X_end_ = $11
LDA #$00
STA X_pos_
LDA #$30
STA Y_pos_
LDA #$ff
STA X_end
LDA #$30
STA Y_end
@loop:;; mem f1
LDA Y_pos_
STA Y_pos
LDA X_pos_
STA X_pos
jsr line
INC Y_end
LDA Y_end
CMP #$50
BEQ end__
jmp @loop
end__:
;;Lets cleer bitmap
B_start = $FCFD
B_end = $FEFF
VIC_bank = $4000
VIC_bank_end = VIC_bank + $3FFF
;;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 >B_start, <B_start, #<VIC_bank, #>VIC_bank
Mov_16 >B_end, <B_end, #<$5f3f, #>$5f3f
LDA #$00
jsr memset
jmp exit
.endscope

View file

@ -0,0 +1,78 @@
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
;;drawing line from 2 cordinates
;;# * (X_end, Y_end) #
;;# #
;;# * #
;;# * #
;;# (X_pos, Y_pos) #
;;
;;NOTE THAT X_pos <= X_end, Y_pos >= Y_end. Max 45deg!
.proc line_up
;; Look at line_down for referense
.include "line.inc"; Defines memory positions, ex X_pos
LDA #$00
STA <V
STA <dy_2
STA $FD
SEC
LDA dx
SBC dy
STA >V
Mult_16 >V, <V
Mult_16 >dy_2, <dy_2
Mov_16 >D, <D, >dy_2, <dy_2
Add_16 >D, <D, #$ff, #$01, !
Sub_16 >D, <D, dx, #$00
selfmod:
LDA >dy_2
STA case_2 +1
LDA <dy_2
STA case_2 +7
LDA >V
STA case_1 +1
LDA <V
STA case_1 +7
end_selfmod:
jsr pixel_draw
Sub_16 >btp_mem_pos, <btp_mem_pos, #$01, #$00 ;; Y has always a offset of at least 1
LDY #$01
LDX dx
for_x:
LDA byte_to_paint
ORA (>btp_mem_pos), Y
STA (>btp_mem_pos), Y
increment_pixel_x:
LSR byte_to_paint
BCC increment_pixel_x_end
move_8px_left:
Add_16 >btp_mem_pos, <btp_mem_pos, #$07, #$00,!
LDA #%10000000
STA byte_to_paint
increment_pixel_x_end:
DEX
;CPX X_end
BEQ end
Lag_16 >D, <D, #$00, #$02, case_2
case_1:
Sub_16_A >D, <D, #>V, #<V,!
decrement_y_pos:
DEY
BNE for_x
move_8px_up:
LDY #$08
Sub_16 >btp_mem_pos, <btp_mem_pos, #$40, #$01, !
jmp for_x
decrement_y_pos_end:
case_2:
Add_16 >D, <D, #>dy_2, #<dy_2,!
JMP for_x
end:
RTS
.endproc

View file

@ -0,0 +1,76 @@
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
;drawing line from 2 cordinates
;;# (X_end, Y_end) #
;;# * #
;;# * #
;;# * #
;;# (X_pos, Y_pos) #
;;NOTE THAT Y_pos >) Y_end, X_pos <= X_end. Min 45deg!
.proc line_up_inv
;; Look at line_down for referense
.include "line.inc"; Defines memory positions, ex X_pos
LDA #$00
STA <V
STA <dx_2
STA $FD
SEC
LDA dy
SBC dx
STA >V
Mult_16 >V, <V
Mult_16 >dx_2, <dx_2
Mov_16 >D, <D, >dx_2, <dx_2
Add_16 >D, <D, #$ff, #$01, !
Sub_16 >D, <D, dy, #$00
selfmod:
LDA >dx_2
STA case_2 +1
LDA <dx_2
STA case_2 +7
LDA >V
STA case_1 +1
LDA <V
STA case_1 +7
end_selfmod:
jsr pixel_draw
LDY #$00
LDX dy
for_y:
LDA byte_to_paint
ORA (>btp_mem_pos), Y
STA (>btp_mem_pos), Y
decrement_y_pos:
DEY
CPY #$ff
BNE decrement_y_pos_end
move_8px_up:
LDY #$07
Sub_16>btp_mem_pos, <btp_mem_pos,#$40 , #$01, !
decrement_y_pos_end:
DEX
BEQ end
Lag_16 >D, <D, #$00, #$02, case_2
case_1:
Sub_16_A >D, <D, #>V, #<V, !
increment_pixel_x:
LDA byte_to_paint
LSR byte_to_paint
BCC for_y
move_8px_left:
Add_16 >btp_mem_pos, <btp_mem_pos, #$07, #$00,!
LDA #%10000000
STA byte_to_paint
JMP for_y
case_2:
Add_16 >D, <D, #>dx_2, #<dx_2, !
JMP for_y
end:
RTS
.endproc

View file

@ -0,0 +1,33 @@
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
;;Move memory from B_start B_end to A_start , (implied address)
;;Modifies A,X and B_start gets modified
.proc memcpy
.include "mem.inc"
;; Let Y + A_start lower nibble represent A_start
;; therefor: A_start = Y - A_start
;; With Y we mean what Y will represent later aka >B_start
Sub_16 >A_start, <A_start, >B_start, #$00
;;Lets move B_start lover-nibble to Y
LDY >B_start
LDA #$00
STA >B_start
loop:
Lag_16 >B_end, <B_end, A, <B_start, end_loop
LDA (>B_start), Y
STA (>A_start), Y
;Tip save time by counting downward, fast to check if Y ==0 // hugo
INY
TYA
CMP #$ff
BNE loop
;; Fix overflow
LDY #$00
INC <A_start
INC <B_start
JMP loop
end_loop:
RTS
.endproc

View file

@ -0,0 +1,28 @@
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
;; test for memcpy
.scope memcpy_test
charset = $FB
code = $FE
petski_position = $FEFF ;reuses code:s memory
screen_position = $FCFD
Mov_16 >B_start, <B_start, #<$D000, #>$D000
;#### TEMP INIT DATA ####
Mov_16 >B_end, <B_end, #<($D000+$1F3F), #>($D000 +$1F3F)
LDA #$10
STA code
LDA #$10
STA X_pos
STA Y_pos
VIC_bank = $4000
VIC_bank_end = VIC_bank + $3FFF
Mov_16 >A_start, <A_start, #<VIC_bank, #>VIC_bank
;We first need to clear some memory
;Mov_16 >A_end, >A_end, #<(VIC_bank+100), #>(VIC_bank +100)
LDA #$00
JSR memcpy
STA <petski_position
jmp exit
.endscope

View file

@ -0,0 +1,31 @@
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
;; Sets memory in A to all addresses from B_start to B_end
;; Modifies A, X and B_start
.proc memset
.include "mem.inc"
;;put what to recursive write in Y.
LDX #$0
TAY
loop:
;;write to byte
TYA
STA (>B_start ,X)
Add_16 >B_start, <B_start, #$01, #$00
LDA >B_start
CMP >B_end
BEQ test
jmp loop
test:
LDA <B_start
CMP <B_end
BEQ end
jmp loop
end:
;;Dont forget to rewrite last byte
TYA
STA (>B_start, X)
RTS
.endproc

View file

@ -0,0 +1,83 @@
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
;;Screen print. Draws a pixel at a specified position.
;; Destroys A X Y
.proc pixel_draw; Draws a pixel at [Y = FB , X = FC, FD]. Y = 0 - 320, X= 0 - 200
.include "mem.inc"
Bitmap = $4000
Bitmap_end = $5F3F
;; X = X_pos (mod 8)
LDA >X_pos ; X (mod 8)
AND #%00000111
TAX
;;Store pixel in byte_to_paint
LDA #%10000000
INX
@shift_btp: ;; check out SMB instruction here! //Hugo
DEX
BEQ end__;X=0 end this
CLC
ROR A
jmp @shift_btp
end__:
STA byte_to_paint
;;FIND THE POSITION IN MEMORY TO WRITE PIXEL
;; + + + + + > X
;; +
;; +
;;\/
;; Y
;;
;;pos = x_offset
LDA #%11111000
AND >X_pos
STA >btp_mem_pos
LDA <X_pos
STA <btp_mem_pos
;;The y_pos adds offset because chunk offsets + inside chunk offset.
;; Adding inside chunk offset
LDA #%00000111 ; A = y (mod 8)
AND Y_pos ;; offset to add
TAY
LDA #$00
STA $4B
;;y =8 translates to 320 bytes.
CLC
LDA #%11111000 ; A = y - [y (mod 8)]
AND Y_pos
STA >C
STA >B
LDA #$00
STA <C
STA <B
;;We need to calculate C*40. 40 = 2*2*2*(2^2 +1)
;; _*2^2
Mult_16 >C, <C
Mult_16 >C, <C
;; + _*1
Add_16 >C, <C, >B, <B, !
;; *2*2*2
Mult_16 >C, <C
Mult_16 >C, <C
Mult_16 >C, <C
Add_16 >btp_mem_pos, <btp_mem_pos, >C, <C, !
;;add offset for where bitmap is
Add_16 >btp_mem_pos, <btp_mem_pos, #<Bitmap, #>Bitmap, !
;;Let draw some stuff
LDA byte_to_paint ;; note that both bytes are used!
ORA (>btp_mem_pos), Y
STA (>btp_mem_pos), Y
RTS
.endproc

View file

@ -0,0 +1,83 @@
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
;; petski: https://www.c64-wiki.com/wiki/File:ASCII-Codes.gif
;;https://www.c64-wiki.com/wiki/Character_set
;; Takes in a PETSKI-code in CODE
;; And prints it ON X_pos, Y_pos
;; Note that this is the real positions divided by 8
.proc char_draw
Character_generator_ROM = $D000
Y_pos_offset = $F9F8 ;Reuses from Y_pos
X_pos_offset = $FAF7
X_pos = $FA
Y_pos = $F9
charset = $FB
code = $FE
petski_position = $FEFF ;reuses code:s memory
screen_position = $FCFD
;#### TEMP INIT DATA ####
LDA #$10
STA code
LDA #04
STA X_pos
LDA #02
STA Y_pos
;;Do arithimatic to know where to read and write bytes.
initial:
;We first need to clear some memory
LDA #$00
STA <petski_position
STA <Y_pos_offset
STA <X_pos_offset
;;We need the relative offset for bytes to read and write.
;; This is code *8 because 8byte is one character
;; *8 = 2*2*2
ASL code ;Will never owerflow, therefore 8byte
Mult_16 >petski_position, <petski_position
Mult_16 >petski_position, <petski_position
;; Add starting position
Add_16 >petski_position, <petski_position, #<Character_generator_ROM , #>Character_generator_ROM, !
;;Calculate screen_position to use
Mov_16 >screen_position, <screen_position, #<VIC_bank, #>VIC_bank
;; Add the X_pos has a offset multiplier of *8 because 1 chunk = 8 addresses
;; *8
Mult_16 >X_pos_offset, <X_pos_offset
Mult_16 >X_pos_offset, <X_pos_offset
Mult_16 >X_pos_offset, <X_pos_offset
;; Add
Add_16 >screen_position, <screen_position, X_pos, #$00, !
;; And Y_pos has a offset multiplier of "screen length" = 320 = (2*2 +1)*2^6
;;Y_pos*2*2 +1 |Lets reuse X_pos for storage
LDA Y_pos
STA X_pos
Mult_16 >Y_pos_offset, <Y_pos_offset
Mult_16 >Y_pos_offset, <Y_pos_offset
Add_16 >Y_pos_offset, <Y_pos_offset, X_pos, #$00, !
;; *2^6
Mult_16 >Y_pos_offset, <Y_pos_offset
Mult_16 >Y_pos_offset, <Y_pos_offset
Mult_16 >Y_pos_offset, <Y_pos_offset
Mult_16 >Y_pos_offset, <Y_pos_offset
Mult_16 >Y_pos_offset, <Y_pos_offset
Mult_16 >Y_pos_offset, <Y_pos_offset
;; Add
Add_16 >screen_position, <screen_position, >Y_pos_offset, <Y_pos_offset, !
initial_end:
;; One character is 8 byte, move these bytes to screen
LDY #$07
@loop:
LDA (>petski_position), Y
STA (>screen_position), Y
DEY
BNE @loop
LDA (>petski_position), Y
STA (>screen_position), Y
RTS
.endproc

10
wip-dicander/run.sh Executable file
View file

@ -0,0 +1,10 @@
# !/bin/bash
killall x64sc
#Note that program start at $080D
cl65 -o file.prg -u __EXEHDR__ -t c64 -C c64-asm.cfg -l file.list source.s \
&& nohup flatpak run net.sf.VICE -windowypos 0 -windowxpos 960 -windowwidth 945 -windowheight 720 file.prg </dev/null &>/dev/null &
sleep 2
rm source.o
rm file.prg

67
wip-dicander/source.s Executable file
View file

@ -0,0 +1,67 @@
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
.debuginfo + ; Generate debug info
;;Macros
.include "macros/16bitarithmetic.s"
;;inc files
.include "routines/memory/mem.inc"
;;Code to run
.include "STARTUP.s"
;.include "routines/line/line_test_time.s"
;;.include "routines/memory/memcpy_test.s"
;.include "fillscreen.s"
;Hacky hardcoding. I pick FC and FD to contain the 16 bit offset to the screen
LDA #$40 ;Remember kids, C64 is a little endian computer. Why, why why! Big endian makes more sense!
STA $FD ;THis means that the bitmap starts at $4000
LDA #$00
LDX #$60
STA $FC
mainloop:
;fill screen with white pixels
LDY #$00
LDA #%10000000 ; Start out with setting the leftmost pixel to white in every byte in the bitmap
STA $FF ;$FF contains the pattern we are writing to part if the bitmap memory
STA $FE ;$FE conatins the most recent bit/pixel we are adding
;The idea is now to bitshift this to the right, until A is 0. When this happens it is time to update which byte we are working on
pixel_setting_loop:
LDA $FF
STA ($FC),Y
LDA $FE ;FE contains the most recent bit/pixel we are adding
LSR a
BNE more_pixels_in_byte
INC $FC
; if this overflows
BNE not_incrementing_other_byte
INC $FD
CPX $FD
; if the carry flag is zero, branch
BCC done_pixels
not_incrementing_other_byte:
LDA #%10000000
STA $FE
STA $FF
more_pixels_in_byte:
STA $FE ;$FE conatins the most recent bit/pixel we are adding
ORA $FF ;Add the previous pixels.
STA $FF
JMP pixel_setting_loop
done_pixels:
;check is somebody has pressed space and if so exit, code blatantly stolen from Duuqnd
LDX #%01111111
LDY #%00010000
LDA #$ff
STA $DC02
LDA #$00
STA $DC03
STX $DC00
TYA
AND $DC01
;Check if A is 0
BEQ die
jmp mainloop
die:
;.include "routines/line/line.s"
;.include "routines/memory/pixel_draw.s"
.include "routines/memory/memset.s"
;.include "routines/memory/memcpy.s"