Re: Writing contents of a memory address to screen
Posted: Tue Jun 17, 2014 10:20 pm
Thank you all for valuable help.
Firstly on the overflow flag, I realise now I shouldn't have been using it. Now I learn that is only used with BVC when you are working with a signed number. I should have been checking the carry flag instead.
Satpro you also pulled me up on how I was storing the CPU register. There was no need to double it up to a memory address too! I see now that as long as the stack is used properly, you can pull it back off again at the right time.
Anyway, I now have kind of what I wanted. A small program to test idea of using double precision to control speed of a sprite. It needs a lot of work to be more than this of course. But I play with one idea at a time until I think I've grasped it.
Here is my entire code, written for ACME in C64 Studio. BTW conv2dec is a routine to output the value of sprite0yprecision to screen. which helped me debug what was going wrong. The movement speed of the sprite down the screen can be controlled by changing the value of sprite0speed, currently set to $ff (fastest speed).
Any comments welcome.
Firstly on the overflow flag, I realise now I shouldn't have been using it. Now I learn that is only used with BVC when you are working with a signed number. I should have been checking the carry flag instead.
Satpro you also pulled me up on how I was storing the CPU register. There was no need to double it up to a memory address too! I see now that as long as the stack is used properly, you can pull it back off again at the right time.
Anyway, I now have kind of what I wanted. A small program to test idea of using double precision to control speed of a sprite. It needs a lot of work to be more than this of course. But I play with one idea at a time until I think I've grasped it.
Here is my entire code, written for ACME in C64 Studio. BTW conv2dec is a routine to output the value of sprite0yprecision to screen. which helped me debug what was going wrong. The movement speed of the sprite down the screen can be controlled by changing the value of sprite0speed, currently set to $ff (fastest speed).
Any comments welcome.
Code: Select all
!to "doublePrecision.prg",cbm
bordercolor = $d020
backgroundcolor = $d021
interruptcontrol = $d01a
interruptroutineaddress1 = $0314
interruptroutineaddress2 = $0315
rasterline = $d012
spriteonoff = $d015
spritemode = $d01c
spritepointer0 = $07f8
spritecolor1 = $d025
spritecolor2 = $d026
sprite0color = $d027
sprite0xpos = $d000
sprite0ypos = $d001
sprite0ybuffer = $c000
frameReadyFlag = $c001
sprite0speed = $ff
sprite0yPrecision = $c002
sprite0yPrecision2 = $c003
div_lo = $c005
div_hi = $c006
*= $0801
!byte $0d,$08,$00,$01,$9e,$20,$34,$30,$39,$36,$00,$00,$00 ; Types the basic program SYS 4096 into memory for more convenient running
*= $1000
lda #$00
sta frameReadyFlag
lda #$0B ; Set foreground and border colour to dark grey
sta bordercolor
sta backgroundcolor
lda #$93 ; Clear the screen by loading clear screen character and then calling a kernel routine
jsr $ffd2
lda #$00 ; Load black into first shared sprite colour
sta spritecolor1
lda #$01 ; Load white into second shared sprite colour
sta spritecolor2
lda #$05 ; Load green into sprite 0 unique colour
sta sprite0color
lda #$80 ; Load first sprite pointer to point at $2000 ($2000 / $40 = $80)
sta spritepointer0 ; The VIC-IIs default memory address for sprite pointer 0
lda #$01 ; Enable sprite 0 by turning on first bit of $d015
sta spriteonoff
sta spritemode ; Set sprite 0 to multicolor mode
lda #$96 ; Load coordinates to place sprite (in this case W150,H150)
sta sprite0xpos
sta sprite0ypos
sei ; Disable the CPU responding to interrupts
lda #$7f ; Keep some other random interrupts off
sta $dc0d
sta $dd0d
lda $dc0d ; Acknowledge any CIA 1 interrupts
lda $dd0d ; Acknowledge any CIA 2 interrupts
lda #$01 ; Turn on VIC raster interrupts
sta interruptcontrol
lda #$fa ; Generate interrupt on line fa
sta rasterline
lda #$1b ;Not sure what this does exactly?
sta $d011
lda #<spriteControl ;set the correct address for the interrupt routine
sta interruptroutineaddress1
lda #>spriteControl
sta interruptroutineaddress2
cli ; turn all interrupts back on
mainLoop
lda #sprite0speed ; get the sprite speed and add it to the precision buffer
clc
adc sprite0yPrecision
sta sprite0yPrecision
php
jsr conv2dec
plp
bcc mainLoop ; loop again if didn't overflow
lda #$08 ; we did carry so add eight to the next buffer
clc
adc sprite0yPrecision2
sta sprite0yPrecision2
bcc mainLoop ; loop again if didn’t over flow
lda #$01
clc
adc sprite0ybuffer
sta sprite0ybuffer
inc bordercolor
jmp mainLoop ; Sit idle until interrupted
spriteControl
asl $d019 ; Acknowledge (clear) raster interrupt
inc bordercolor ; Start a raster time status bar
lda sprite0ybuffer ;copy buffers to actual locations
sta sprite0ypos
dec bordercolor ; stop raster time status bar
jmp $ea81 ; Kernal routine to return to main program
conv2dec
LDY #$00
LDX sprite0yPrecision
STX div_lo
STY div_hi
LDY #$04
next
JSR div10
ORA #$30
STA $0400,Y
DEY
BPL next
RTS
div10
LDX #$11
LDA #$00
CLC
loop
ROL
CMP #$0A
BCC skip
SBC #$0A
CLV
skip
ROL div_lo
ROL div_hi
DEX
BNE loop
RTS
*= $2000
!BIN "greenman.spr"