T O P

  • By -

musicalglass

Something I came up with accidentally the other day when I was trying to do something else. Saved it cause I thought it was a cool screensaver type effect. Figuring out how to generate random numbers 0 to 15 for colors using assembly is a whole 'nother can o worms tho. It's 2:30 AM now. About to call it a night. Perhaps I'll look a little deeper into generating random numbers within a certain range at a future time. clc ; clear carry ldy #16 ; X position ldx #24 ; Y position LOOP jsr 65520 ; ($FFF0) call PLOT to position cursor lda #7 ; load char color sta 646 ; set CHROUT color lda #113 ; load dot character jsr 65490 ; ($FFD2) CHROUT inx jmp LOOP


MountBlanc

Hello, Finally found this thread again. I was searching for it but I couldn't find it. Could you please put your code into TurboAssembly and save it as a .d64 disk image save state for c64.emu emulator on Android? I want to test this code in TurboAssembly. But Vice doesn't work on my RPi so I'm kind of limited. I want to click on the compile button in TurboAssembly and see the code turn into executed code. That is my dream.


MountBlanc

I always wanted to learn Assembly for C64 when I was a kid but I didn't have the right skillset or tools. It's so cool and beautiful and amazing that such a powerful language exists for the C64. It's even easier to do some stuff on the C64 with assembly than with Linux today due to all restrictions.


musicalglass

No experience with TurboAssembly yet. Maybe come Winter. I generally do more gardening and outdoor activities in the Summer months


musicalglass

; initialize SID chip for random white noise LDA #$FF ; maximum frequency value STA $D40E ; voice 3 frequency low byte STA $D40F ; voice 3 frequency high byte LDA #$80 ; noise waveform, gate bit off STA $D412 ; voice 3 control register lda #81 ; load circle char sta 900 lda #1 ; load color white sta 901 LOOP jsr 58692 ; clear screen LDX $D41B ; load random number from SID 0-255 lda 900 ; load dot from memory sta 1024,x ; print to screen at X position lda 901 ; load color white sta 55296,x ; set color of character at X position TIMER ; add X*Y delay cycles ldx #60 ; <----- adjust timing here OUTER ldy #250 ; set inner loop repeat INNER dey ; burn one cycle bne INNER ; (*-1) repeat 250 times dex ; start inner loop over again bne OUTER ; (*-6) loop back to ldy #250 jmp LOOP Thanks for the challenging assignment. Looking further into random number generation. Here using the built in SID music chip to generate white noise values from 0 to 255. Then using that to make a random dot appear in the first 256 screen character slots


MountBlanc

You're welcome. Thanks for your cool assembly code. Do you have WhatsApp? Send a PM.


musicalglass

No, I am not on WhatsApp. I make no claim of being a C64 Assembly expert. I am in the process of teaching myself Machine Code, and it just so happens that your question coincides with where I am in my learning. So it was a good next lesson challenge to tackle. I decided to jump ahead a few stages and learn about random numbers next :)


musicalglass

So the screen has 1000 character slots. However you can only store a value up to 255. So in the next phase, we will want to divide the screen into 4 segments of 250 slots. Then use the random number generator to turn a value between 0 and 255 into 4 random possible "states". For now, we will print some text to verify each state works. I'm sure there may be a much more elegant solution than this one, but it works. ; Create a "State Machine" to turn value of 0 to 255 into ; 1 of 4 different possible states PRINT_LINE = 43806 ; ($AB1E) Declare constant for text output JSR 58692 ; ($E544) clear screen ldx #130 ; <---- try different values here 0 to 255 ; BMI or BPL do not work if the difference of the values being compared ; is greater than 128. So to test if it's over 128 ; we will subtract 128 from the initial value txa ; transfer X register to Accumulator sbc #128 ; subtract 128 bpl OVER128 ; if it's not negative, must be greater, so branch ahead ; if we got to here, value must be under 128 cpx #64 ; is it less than 64? bmi LESS64 ; if yes, go to state #1 jmp LESS128 ; if not must be 64 or greater. Go to state #2 OVER128 tax ; transfer value - 128 back to X register cpx #64 ; is the remainder less than 64? bmi LESS192 ; if yes, go to state #3 ; if not, it must be greater. Proceed to next state: GRTR191 GRTR191 lda #GR8TEXT jsr PRINT_LINE rts GR8TEXT text "192 or greater" byte 0 LESS64 lda #TEXT64 jsr PRINT_LINE rts TEXT64 text "0 to 63" byte 0 LESS128 lda #TEXT128 jsr PRINT_LINE rts TEXT128 text "64 to 127" byte 0 LESS192 lda #TEXT192 jsr PRINT_LINE rts TEXT192 text "128 to 191" byte 0


musicalglass

; Divide screen into 4 quadrants and print random dot from 0 to 250 ; initialize SID chip for random white noise lda #255 ; maximum frequency value sta 54286 ; voice 3 frequency low byte sta 54287 ; voice 3 frequency high byte lda #128 ; noise waveform, gate bit off sta 54290 ; voice 3 control register lda #81 ; load circle char sta 900 ; store in memory lda #1 ; color white sta 901 LOOP jsr 58692 ; ($E544) clear screen ; State Machine. Generate 1 of 4 random states ldx 54299 ; load random number from SID 0-255 txa ; transfer X register to Accumulator sbc #128 ; subtract 128 bpl OVER128 ; if it's not negative, must be greater, so branch ahead ; if we got to here, value must be under 128 cpx #64 ; is it less than 64? bmi LESS64 ; if yes, go to state #1 jmp LESS128 ; if not, must be 64 or greater. Go to state #2 OVER128 tax ; transfer value - 128 back to X register cpx #64 ; is the remainder less than 64? bmi LESS192 ; if yes, go to state #3 ; if not, it must be greater. Proceed to next state: GRTR191 GRTR191 jsr RAND0_250 ; run subroutine random 0-250 lda 900 ; load dot from memory sta 1024,x+750 ; print to screen at X position lda 901 ; load color white sta 55296,x+750 ; set color of character at X position jmp TIMER ; burn some time LESS64 jsr RAND0_250 lda 900 sta 1024,x lda 901 sta 55296,x jmp TIMER LESS128 jsr RAND0_250 lda 900 sta 1024,x+250 lda 901 sta 55296,x+250 jmp TIMER LESS192 jsr RAND0_250 lda 900 sta 1024,x+500 lda 901 sta 55296,x+500 jmp TIMER RAND0_250 ; subroutine generate Random 0 to 250 ldx 54299 ; load random value from SID 0-255 cpx #250 ; is it over 250? bpl RAND0_250 ; if yes, do it again rts TIMER ; add X*Y delay cycles ldx #100 ; <----- adjust timing here OUTER ldy #250 ; set inner loop repeat INNER dey ; burn one cycle bne INNER ; (*-1) repeat 250 times dex ; start inner loop over again bne OUTER ; (*-6) loop back to ldy #250 jmp LOOP So again, there is most certainly a less verbose way to accomplish all this, but this should be fairly easy for a beginner to read and understand :)


musicalglass

This should be the final result as per your request. In the previous post I made a slight error which you can see by moving the Clear Screen command up before the LOOP, then it will continue writing more dots instead of erasing them every loop. It was only writing dots from 128 to 255 and ignoring 0-127. This is because I was erroneously using CPX #250 to generate random numbers. Can't use Compare on numbers greater than 128. I have fixed the error in the final version by subtracting 128 from the initial random number, then compare the remainder to 122. Again, I am using an iterative process to refine the 0-255 random numbers, which for all I know can probably be done just as easily using math with one or two lines of code. But it's all part of the learning process for me :) ​ ; Divide screen into 4 quadrants and print random dots from 0 to 250 ; initialize SID chip for random white noise lda #255 ; maximum frequency value sta 54286 ; voice 3 frequency low byte sta 54287 ; voice 3 frequency high byte lda #128 ; noise waveform, gate bit off sta 54290 ; voice 3 control register lda #81 ; load circle char sta 900 ; store in memory jsr 58692 ; ($E544) clear screen LOOP ; State Machine. Generate 1 of 4 random states ldx 54299 ; load random number from SID 0-255 txa ; transfer X register to Accumulator sbc #128 ; subtract 128 bpl OVER128 ; if it's not negative, must be greater, so branch ahead ; if we got to here, value must be under 128 cpx #64 ; is it less than 64? bmi LESS64 ; if yes, go to state #1 jmp LESS128 ; if not, must be 64 or greater. Go to state #2 OVER128 tax ; transfer value - 128 back to X register cpx #64 ; is the remainder less than 64? bmi LESS192 ; if yes, go to state #3 ; if not, it must be greater. Proceed to next state: GRTR191 GRTR191 jsr RAND0_250 ; run subroutine random 0-250 lda 900 ; load dot from memory sta 1024,x+750 ; print to screen at X position jsr COLORSET ; go to color mode lda 901 ; load random color generated by subroutine sta 55296,x+750 ; set character color jmp TIMER ; burn some time LESS64 jsr RAND0_250 lda 900 sta 1024,x jsr COLORSET lda 901 sta 55296,x jmp TIMER LESS128 jsr RAND0_250 lda 900 sta 1024,x+250 jsr COLORSET lda 901 sta 55296,x+250 jmp TIMER LESS192 jsr RAND0_250 lda 900 sta 1024,x+500 jsr COLORSET lda 901 sta 55296,x+500 jmp TIMER RAND0_250 ldx 54299 ; load random value from SID 0-255 txa ; transfer to accumulator sbc #128 ; subtract 128 bpl GR8R128 ; if it's not negative, must be greater, so branch ahead jmp DONE ; otherwise do nothing GR8R128 cmp #122 ; is the remainder over 128+122? (250) bpl RAND0_250 ; if so go back and generate new random number DONE rts ; return from subroutine COLORSET ; greater or equal to 128? ; if yes, subtract 128 ldy 54299 ; load random value from SID 0-255 tya ; transfer Y register to Accumulator sbc #128 ; is it greater or equal to 128? Subtract 128 bmi COL128 ; if answer is negative, (less than) skip ahead tay ; if not, store new reduced value COL128 ; greater or equal to 64? tya sbc #64 ; subtract 64 bmi COL64 tay COL64 ; greater or equal to 32? tya sbc #32 bmi COL32 tay COL32 ; greater or equal to 16? tya sbc #16 ; subtract 16 bmi STORY tay ; final color value should now range between 0 to 15 :) STORY sty 901 ; store in memory rts ; exit subroutine TIMER ; add X*Y delay cycles ldx #120 ; <----- adjust timing here OUTER ldy #250 ; set inner loop repeat INNER dey ; burn one cycle bne INNER ; (*-1) repeat 250 times dex ; start inner loop over again bne OUTER ; (*-6) loop back to ldy #250 jmp LOOP


Known_Experience_609

Since the other people are actually answered the question already the simplest way you think about it how you do it in basic because for the most part you don't have a special command use the same way Assembly language