BRANCHING IN ASSEMBLER - START INFO - PART 1 --------------------------------------------------------------------------------------------------------------------------------- TOOL: Built-In ML-Monitor {Commodore C128} Language: Assembler Extra: none Author: Misel Zivanovic Note: (C) 15th DEC 2025 - www.lived.ch, mzretro.ch --------------------------------------------------------------------------------------------------------------------------------- THERE IS MORE BUT WE WILL START WITH THESE FELLOWS HERE: BCS - Branch if the actual accumulator value is BIGGER than the compared value { BRANCH IF CARRY IS SET } BCC - Branch if the actual accumulator value is SMALLER than the compared value. { BRANCH IF CARRY IS CLEAR } BEQ - Branch if EQUAL to Zero BNE - Branch if NOT EQUAL to Zero We already have had BNE which is branching as long as the result isn't ZERO or NOT true in that case! We won't do regular examples, but a bit more modern style state-of-the-art shows! ;-) That way you will learn how to use them together/combined! EXAMPLE 1: BEQ and BCC brothers! FIRST STEP : ------------ Type-in this BASIC part or copy/paste it {VICE C128-Emulator} 10 bank 15 15 scnclr 20 char 1,10,10,"press/hold any key!" 25 char 1,11,12,"run/stop to quit!" 30 for a=1 to 1024 40 sys 2816 50 next 60 cursor 13,1 DO NOT RUN IT YET! SECOND STEP : ------------- You could type in this too, but i suggest to copy/paste it, as you have probably done with the BASIC part above. Keep in mind. It is the Machine-Language code and first you must open the built-in ML-Monitor with the MONITOR command. >00b00 a9 ff 8d 0e d4 8d 0f d4:I...T..T >00b08 a5 d4 c9 58 f0 fa a9 80:ETIxPZI. >00b10 8d 12 d4 ad 1b d4 aa c9:..TM.TJI >00b18 a0 90 01 60 9d 00 04 9d:........ >00b20 a0 04 a9 80 8d 12 d4 ad:..I...TM >00b28 1b d4 aa c9 a0 90 01 60:.TJI.... >00b30 9d 00 d8 9d a0 d8 60 00:..X..X.. Now that you have done this, return to BASIC with 'X' and type RUN... That's it {see also the screenshots} --------------------------------------------------------------------------------------------------------------------------------- ALL EXPLAINED: Now let's check what do we have here and what it is doing? BASIC part is pretty much very clear. No need to explain it. Our focus is on the assembly part. Old C64/C128 user will immediately notice the SID-CHIP addresses and its involvement in order to get the random numbers! 54286/$040E Frequency register for voice 3 (low byte) 54287/$040F Frequency register for voice 3 (high byte) 54290/$0412 Control register for voice 3 54299/$041B Voice 3 oscillator output Ergo, SID-CHIP is used to generate/get random numbers. Additional info: This will also work with C64. It is the same routine. However, the same assembler routine coming from C64, will not work with C128! Now you wonder, haha...! Here is why! -> It is because default C128 BANK is 0, but to get the random numbers from the SID-CHIP, your C128 must be set to BANK 15 We are using here BASIC command BANK 15 to set this! To do it in assembler you practically need to additional lines: lda #$00 sta $ff00 This is setting BANK 15 as default in assembler {in RAM BLOCK 0} We will talk about RAM-BLOCK{s} in due time. Okay, now it is clear, let's continue! . 00b00 a9 ff lda #$ff Accumulator value #$ff, dec 255 . 00b02 8d 0e d4 sta $d40e Write to low . 00b05 8d 0f d4 sta $d40f and high byte of the frequency register . 00b08 a5 d4 lda $d4 This register {dec 212} is doing something completely else. . 00b0a c9 58 cmp #$58 It is holding the keyboard matrix value of the button we are pressing. . 00b0c f0 fa beq $0b08 Default value is #$58, dec 88. If nothing is pressed, it will go to check it again! . 00b0e a9 80 lda #$80 As soon as something is pressed, it will go here and the program execution continues. . 00b10 8d 12 d4 sta $d412 We are putting the value from above #$80, dec 128 into control register . 00b13 ad 1b d4 lda $d41b and are loading the value from the oscillator to accumulator . 00b16 aa tax then we are transferring that value to X-register! {used for {$0400,x}, = $0400 + x} . 00b17 c9 a0 cmp #$a0 If accumulator value was less than #$a0, dec 160 . 00b19 90 01 bcc $0b1c we are brunching to $0b1c and are writing the result to $0400+x, $04a0+x {screen} . 00b1b 60 rts If values were higher, then back to BASIC where the FOR-NEXT-LOOP can continue! . 00b1c 9d 00 04 sta $0400,x This is the screen start address + x, left upper corner {1st 4 rows, 160 characters} . 00b1f 9d a0 04 sta $04a0,x The next screen address + x, 5th row to continue the sequence, 5-6-7-8, 4x40 = 160} . 00b22 a9 80 lda #$80 Then we are generating/getting a new number for the color registers . 00b24 8d 12 d4 sta $d412 - . 00b27 ad 1b d4 lda $d41b - . 00b2a aa tax - . 00b2b c9 a0 cmp #$a0 You notice how we are able to use color values over #$0f, dec 15 {16 incl. zero} because . 00b2d 90 01 bcc $0b30 #$10, dec 16 {17 incl. 0} is reset to 0 {black color}. All < #$160 is a branch to $00b30 . 00b2f 60 rts if higher, back to BASIC for the FOR-NEXT-LOOP until it ends. . 00b30 9d 00 d8 sta $d800,x This is the color map of C128 {same as on C64}, dec 55296 - 56295, hex $0dbe7} . 00b33 9d a0 d8 sta $d8a0,x 5th row of the color map + #$a0, dec 160, {4 rows, 5-6-7-8} . 00b36 60 rts Back to BASIC! FOR-NEXT-LOOP until it ends. --------------------------------------------------------------------------------------------------------------------------------- Maybe you are just asking yourself, what if I replace BCC with BCS!? So what are you waiting for! --------------------------------------------------------------------------------------------------------------------------------- Few words to regard of SCREEN and COLOR MAP DEFAULT SCREEN MEMORY {relocatable} is from $0400 - $07E7, 1000 BYTES! But from 0-999! It is NOT 1024+1000 = 2024 {because 2024 is not the screen area any more!} It is 1024+ 999 = 2023 {This is the DEFAULT SCREEN AREA $0400 - $07E7, dec 1024 - 2023} COLOR MAP is not relocatable! The same as above, just different location: $0d800 - $0dbe7, dec 55296 - 56295 So it is NOT + 1000, IT IS + 999 Yes, there are more color maps, but not here!!! {HIGH RESOLUTION GRAPHICS. More in due time} Now all this was pretty clear and straight forward, right! Why would you need that? Well, image you are making a game and have your level data somewhere in the memory, then you could use this to randomly blend-in your screen data into the screen memory and have a cool effect. Most likely i will have to show you how to do it! Things like that are always good to speed up the execution. Especially if you write a BASIC game and want to give it some extra touch! I had fun making this, hope the same for you! ---------------------------------------------------------------------------------------------------------------------------------