DRAWING-A-LINE-IN-ASSEMBLER --------------------------------------------------------------------------------------------------- TOOL: Built-in ML-Monitor {Commodore C128} Language: Machine Language {Assembler} Extra: none Author: Misel Zivanovic Note: (C) 23rd of OCTOBER 2026 - www.lived.ch, mzretro.ch Doc Revision: 1.1 Last update: 19:35 25.10.2026 --------------------------------------------------------------------------------------------------- DIRECTORY: 0 "mzretro.ch 2026 " mz 2a 0 "edass-128 " seq 0 "source code file" seq 4 "asmbas.asm" prg 0 "----------------" seq 0 "basic demos-----" seq 2 "version1.bas" prg 2 "version2.bas" prg 2 "version3.bas" prg 0 "----------------" seq 0 "assembler demo--" seq 1 "version4.bas" prg 1 "lines.bl" prg 0 "----------------" seq 0 "www.mzretro.ch " seq 0 "www.lived.ch " seq 0 "----------------" seq 0 "commodore c128 " seq 0 "for edass-128- " seq 0 "editor-assembler" seq 0 "and basic 7.0 " seq 0 "----------------" seq 652 blocks free. *************************************************************************************************** Drawing a line in assembler should be much faster than doing the same thing in BASIC, or? *************************************************************************************************** This was challenging and fun at the same time. Results actually surprised me. When we consider the fact that even when BASIC is used, the drawing itself is happening in assembler with this BASIC program. We can literally see how BASIC 7.0 is slowing down the whole process, even if BASIC involvement is reduced just to this small task. BASIC is just sending the coordinates to it, however already this small effort from the BASIC part, made it be around 3 times slower than assembly only. No, that's not it... As you will see soon, when you compare POKE {pixel} and DRAW {pixel} then DRAW command is flying and is close to 3.5x faster than POKE commands doing the same. No,no! There is more!: Check also the VERSION 2 of the same code and see how well BASIC 7.0 can be optimized it almost reaches the must faster DRAW command. --------------------------------------------------------------------------------------------------- BASIC 7.0 - SOURCE CODE EASY - Just a pixel drawing. Usually, that is something you would call a DRAW command for help. As you can see, it can be also done with POKE command. But to see if there is any difference, also DRAW command is tested! --------------------------------------------------------------------------------------------------- VERSION 1: normal? speed --------------------------------------------------------------------------------------------------- 10 poke 131,1:graphic 1,1 11 ti$="000000":poke 994,39:sys 27440 14 for x=100 to 220 16 poke4405,x:rem target x 18 poke4407,100:rem target y 20 sys 40434:sys 44917 30 next 40 na=ti/60 45 ti$="000000" 50 for x=100 to 220 60 draw 1,x,110 70 next 80 nb=ti/60 90 print:print "poke speed:";na 95 print:print "draw speed:";nb 96 graphic 0 poke speed: 4.4 draw speed: 1.28333333 --------------------------------------------------------------------------------------------------- VERSION 2: much faster than before {2.5 times faster} and all that was needed is some minor code adaptation and changes. Now it's almost as fast as at the DRAW command itself. --------------------------------------------------------------------------------------------------- list 10 f=220:poke 131,1:bank15:graphic 1,1 15 a=4405:b=4407:c=404434:d=44917:e=100 17 c=dec("9df2"):d=dec("af75"):g=110 20 ti$="000000":poke 994,39:sys 27440 25 forx=etof 30 pokea,x:pokeb,e:sys c:sys d:next 35 na=ti/60 40 ti$="000000" 45 forx=etof:draw1,x,g:next 50 nb=ti/60 55 print:print "poke speed:";na 60 print:print "draw speed:";nb 65 graphic 0 poke speed: 1.78333333 draw speed: 1.01 Note: Commodore plus 4 needs 0.8 second for the DRAW command! 20% better result than C128. --------------------------------------------------------------------------------------------------- BASIC 7.0 - SOURCE CODE COMPLEX - drawing lines without any drawing commands {C128} I didn't do the optimized version of this code as previously. But you can if your curiosity is strong enough! --------------------------------------------------------------------------------------------------- VERSION 3: No optimization, more complex --------------------------------------------------------------------------------------------------- 10 bank 15: poke 131,1:graphic 1,1 12 ti$="000000":poke 994,39:rem col/bkg 14 sys 27440 16 poke4405,160:rem target x 18 poke4407,100:rem target y 20 sys 40434:sys44917 22 for x =100 to 220 step 20 24 for y =10 to 190 step 10 26 poke4401,x:poke4402,0:rem x, x high 28 poke4403,y:poke4404,0:rem y, y high 30 sys 44914:rem initiate drawing 32 next: next: rt=ti/60 34 char 1,1,1,str$(rt):l=len(str$(rt)) 36 char 1,1,5,"hit enter" 38 getkeya$:if a$=chr$(13) then 42 40 goto 38 42 gosub 50 44 print "done!":print rt: graphic 0 46 gosub 50:end 50 fora=1tol+1:print"-";:next 52 print: return ready. 9.3 seconds! {different results, but around 9.3} -------------------------------------------------------------------------------------------------- Explanation to line 12 and 10! --------------------------------------------------------------------------------------------------- 12 POKE 994,xy This is very you define a drawing color and the background color! In our case that is 112 decimal, or hexadecimal #$70 From the decimal # you don't really can understand what's going on. However, hexadecimal is more clear: 1st number is the drawing color {yellow} 2nd is the background color {black} The values are $00 to $0f for x and y Example: POKE 994,39 = red drawing, yellow background hexadecimal value = $27 2 = red - drawing 7 = yellow- background 10 bank 15: poke 131,1:graphic 1,1 VERY INTERESTING IS THE FACT THAT LINES WON'T BE VISIBLE IF YOU DO NOT MAKE POKE 131,{x} ENTRY! AND X MUST BE HIGHER THAN ZERO! {0} BANK 15 is here out of precaution in case someone used different BANK before. Than a SYS call would give an error {would not work} *************************************************************************************************** --------------------------------------------------------------------------------------------------- ALL RIGHT PEOPLE! - ASSEMBLER TIME! --------------------------------------------------------------------------------------------------- After peeking and poking here, we are ready for the assembly version of it! Let's see how fast it can be drawn there. You notice, it was actually assembly that we used to draw these lines and nothing else. The only thing that stood in our way was the Microsoft BASIC interpreter. Now we will see how much fast can this get without involving Microsoft in our business! --------------------------------------------------------------------------------------------------- EDASS-128 ASSEMBLY SOURCE CODE {Commodore C128, drawing lines in assembler} --------------------------------------------------------------------------------------------------- VERSION 4: Assembler version of the previous {version 3} example! --------------------------------------------------------------------------------------------------- asmbas.asm -a:0010-a: -e: ;version 1.0 ;-------------------------------------- ;24.10.2026 ;assembler versus basic ;drawing speed ;www.mzretro.ch, www.lived.ch ;-------------------------------------- ; *= $1300 .obj m .bank 15 ; lda #$00 ;bank 15 sta $ff00 ; lda #$6 ;mandatory entry sta $83 ;or it won't do! ; ;color register! ; lda #$27 ;white/green sta $03e2 ; jsr $6b30 ;del gfx screen lda #$20 sta $d8 ; lda #$a0 ;set target sta $1135 ;coordinates lda #$64 ;x=160, y=100 sta $1137 jsr $af75 ;confirm ; ldx #$00 ;x register loop loop ldy #$00 ;y register loop stx xsave ;save it sty ysave ; xrun lda #$64 ;start pos. x sta $1131 yrun lda #$0a ;start pos. y sta $1133 jsr $af72 ;confirm ; lda yrun+1 ;add dec 10 to y clc adc #$0a sta yrun+1 ldy ysave iny sty ysave cpy #$12 bne xrun ; lda xrun+1 ;adding +20 to clc ;x register adc #$14 sta xrun+1 lda #$0a ;and set y to def sta yrun+1 ;value of #$0a ldx xsave inx stx xsave cpx #$07 bne loop ; inc $d020 ; spc jsr $ffe4 ;hit enter key cmp #$0d ;to exit beq exit ;(was space) jmp spc ; exit lda #$00 sta $d8 lda #$64 ; def x sta xrun+1 lda #$0a ; def y sta yrun+1 rts ; ;------------------------------------- ; xsave .byte $00 ysave .byte $00 --------------------------------------------------------------------------------------------------- ML-CODE: --------------------------------------------------------------------------------------------------- Commodore C128, drawing lines in assembler! This is the 1:1 ML-CODE of the EDASS-Source Code above. Ready to be copy/pasted into ML-Monitor of C128. No need to install EDASS-128 to try it out! And because there is so little available for the C128, i bet there is no other place where you can or could find this code! >01300 a9 00 8d 00 ff a9 06 85:I...?I.. >01308 83 a9 27 8d e2 03 20 30:.I%.B. 0 >01310 6b a9 20 85 d8 a9 a0 8d:KI .XIX. >01318 35 11 a9 64 8d 37 11 20:5.ID.7. >01320 75 af a2 00 a0 00 8e 82:UOB.?... >01328 13 8c 83 13 a9 64 8d 31:....ID.1 >01330 11 a9 0a 8d 33 11 20 72:.I..3. R >01338 af ad 32 13 18 69 0a 8d:OM2..I.. >01340 32 13 ac 83 13 c8 8c 83:2.L..H.. >01348 13 c0 12 d0 df ad 2d 13:.?.P?M-. >01350 18 69 14 8d 2d 13 a9 0a:.I..-.I. >01358 8d 32 13 ae 82 13 e8 8e:.2.N..H. >01360 82 13 e0 07 d0 be ee 20:..?.P?N >01368 d0 20 e4 ff c9 0d f0 03:P D?I.P. >01370 4c 69 13 a9 00 85 d8 a9:lI.I..XI >01378 64 8d 2d 13 a9 0a 8d 32:D.-.I..2 >01380 13 60 00 00 00 00 00 00:.?...... >01388 00 00 00 00 00 00 00 00:........ *************************************************************************************************** --------------------------------------------------------------------------------------------------- ML-CODE to test the speed versus the BASIC version. --------------------------------------------------------------------------------------------------- NOTE: this is basically the same version as above with the exception of the wait routine to press ENTER key to exit. It is exiting directly to BASIC and showing time that was needed to do the job! USE BASIC LINES below to test the speed! >01300 a9 00 8d 00 ff a9 06 85:I...?I.. >01308 83 a9 27 8d e2 03 20 30:.I'.B. 0 >01310 6b a9 20 85 d8 a9 a0 8d:KI .XI?. >01318 35 11 a9 64 8d 37 11 20:5.ID.7. >01320 75 af a2 00 a0 00 8e 82:UOB.?... >01328 13 8c 83 13 a9 64 8d 31:....ID.1 >01330 11 a9 0a 8d 33 11 20 72:.I..3. R >01338 af ad 32 13 18 69 0a 8d:OM2..I.. >01340 32 13 ac 83 13 c8 8c 83:2.L..H.. >01348 13 c0 12 d0 df ad 2d 13:.?.P?M-. >01350 18 69 14 8d 2d 13 a9 0a:.I..-.I. >01358 8d 32 13 ae 82 13 e8 8e:.2.N..H. >01360 82 13 e0 07 d0 be ee 20:..?.P?N >01368 d0 a9 00 85 d8 a9 64 8d:PI..XID. >01370 2d 13 a9 0a 8d 32 13 60:-.I..2.? >01378 00 00 00 00 00 00 00 00:........ I tested the code and compared to BASIC version, the assembly code is approximately 3x faster. Didn't tested with the FAST command, but i assume it should go down to around 2 seconds or less. Never before I was doing this so I cannot tell if that is great or not, but for 1985 it probably isn't or wasn't bad at all! Below is the BASIC code to test the ML-CODE {BASIC test version} NOTE: - the assembly part above must be in the memory before you run the BASIC part - line 10 is mandatory or you'll messed up BASIC! it is making sure the BASIC start address is moved to $4000 and clears some registers to have the start {drawing} address set correctly. {not needed if only assembler is called and BASIC not used} 10 graphic 1,1:graphic 0 15 ti$="000000" 20 sys 4864 30 print ti/60 run 3.65 seconds It would be interesting to see, if Commodore Plus4 also this can manage this faster/better. It has a faster CPU, so it actually should... The question is, how much! --------------------------------------------------------------------------------------------------- *************************************************************************************************** --------------------------------------------------------------------------------------------------- WOW! Amazing graphics journey on Commodore C128... It is literally screaming for the part 2... And I guess, that's what I am gonna do as next... ---------------------------------------------------------------------------------------------------