Posted By
George on 2011-09-11 15:13:18
| Draw a single pixel in assembler
Could you send me an example how to do this in assembler with Csabo's Plus4/IDE:
1) Graphics On 2) clear screen 3) draw a single pixel 3) check if space is pressed 4) graphics off.
Please comment the code if possible.
|
|
Posted By
Csabo on 2011-09-11 15:28:42
| Re: Draw a single pixel in assembler
Sent by email.
Drawing a single pixel is not that hard. Two main steps: get the pointer to the pixel (it's just math), change the byte at that address by adding a bit (OR operation). In my code I cheated a bit, X can only take a value from 0-255 (not 0-319).
Let me know if something is unclear!
|
|
Posted By
George on 2011-09-11 15:43:13
| Re: Draw a single pixel in assembler
Thanks a lot. i do not fully understand this here:
ORG $1001-2 <- this start address, but why -2? DW $1001 <- whats this? <-- what do you do here in this block? DW nextln,0 ; second word is line number DB $9E IF start > 9999 DB "0"+start/10000 ENDIF DB "0"+(start/1000)%10,"0"+(start/100)%10,"0"+(start/10)%10,"0"+start%10,0 nextln DB 0,0
ptr = $D0 <- you set a variable start SEI <- you stop interrupts here? Why? STA $FF3F <- why this here?
|
|
Posted By
gerliczer on 2011-09-11 16:31:03
| Re: Draw a single pixel in assembler
Hi George,
The line ORG $1001-2 will make the code compiled to address $0FFF. This is necessary, because program files start with load address. The next line DW $1001 simply defines this address, but if it is not at the correct position then the complied file will be loaded at the wrong memory area. For example if the first line would be ORG $1001, then everything that follows will be complied at two bytes offset. This would result in JMPs' and JSRs' address having two byte offsets too, so jumps would occur to wrong addresses.
The next block is the definition of one BASIC line that will start the assembly program with a SYS instruction.
The SEI is for stopping the interrupts is necessary because the default interrupt handler is in the KERNAL ROM, and the next STA $FF3F instruction will page in the underneath lying RAM, therefore an incoming interrupt without setting up a proper handler this way quite surely would crash.
Did this help?
|
|
Posted By
George on 2011-09-11 16:36:03
| Re: Draw a single pixel in assembler
Hi gerliczer, Yes, it helped. thank you very much. I think this init will be standard for my examples..
Another question: This is the Code from Csabo which draws the one pixel ; draw a pixel at 160, 100 (center) LDX #160 LDY #100 JSR drawpixel
; ################################################# drawpixel TXA AND #$07 STA tempx+1 ; TXA AND #$F8 STA ptr LDA #$00 STA ptr+1 ; TYA AND #$07 STA tempy+1 ; TYA ; y=y/8 AND #$F8 LSR a LSR a LSR a ASL a ; y=y*2 TAY LDA ptr CLC ADC mul320,y STA ptr LDA ptr+1 ADC mul320+1,y CLC ADC #$20 STA ptr+1
after that i try to make a loop for a line from x=1 to 200, which does not work. What i am doing wrong? Can i compare X or Y register direct with a value? LDX #1 LDY #100 loop01 ; loop JSR drawpixel INX TXA AND #200 BNE loop01
|
|
Posted By
gerliczer on 2011-09-11 17:56:34
| Re: Draw a single pixel in assembler
Hi George,
I'm glad that I could help. I think I see what the problem is with your loop. Try to replace TXA and AND #200 with a single CPX #200.
And one humble request. Please do not omit the 'z' from my name.
|
|
Posted By
George on 2012-11-23 03:29:57
| Re: Draw a single pixel in assembler
Hi gerliczer,
sorry for the name, i did not realized the z.
i tried now this:
LDX #0 LDY #100 loop01 ; loop INX LDY #100 JSR drawpixel CPX #$FF BNE loop01
it draws the line until x=8 than it seems to stop.
Found it my self... i have to store X position in a memory location. And load it again.
Update: 2012-11-23 The Draw-Pixel function above draws a pixel at position xyy in Hires-Mode (320x200). How must the function be changed to draw a pixel in Multicolor mode (160x200)? Couldn't find it out myself.
|
|
Posted By
bubis on 2012-11-23 05:19:22
| Re: Draw a single pixel in assembler
If performance is not critical, you can simply use ROM routines. Like you can use JSR $C1A5 that reads the x coordinate from $02ad-$02ae and y from $02af. You can find plenty of examples using this ROM routine in http://plus4world.powweb.com/software/Your_Daily_128_Byte_Intro
faster routines work like this:
XR: x coord lo $d0: x coord hi YR: y coord
lda row_addr_lo,y sta $d2 clc lda $d0 adc row_addr_hi,y sta $d3 txa and #$f8 tay lda ($d2),y ora bits,x sta ($d2),y rts You have to prepare three tables for this to work: * row_addr_lo/row_addr_hi needs to point to the first byte on the bitmap for the respective y coordinate, so it's like (bitmap_base+(y/8)*320+y&7). * bits is a 256 bytes long periodic sequence of 128,64,32,16,8,4,2,1, 128, ....
|
|
Posted By
George on 2012-11-23 05:21:46
| Re: Draw a single pixel in assembler
Thanks for the hint. But where are the Code-Examples to set a colored pixel?
|
|
Posted By
bubis on 2012-11-23 05:25:49
| Re: Draw a single pixel in assembler
Check harmony.s for example, that works on mc bitmap. You have to set the color in $84 before calling $C1A5.
|
|
Posted By
George on 2012-11-23 09:46:28
| Re: Draw a single pixel in assembler
Sorry to annoy you again, but i am a beginner and not very experienced Please post a working Codeexample like above
|
|
Posted By
bubis on 2012-11-30 04:19:48
| Re: Draw a single pixel in assembler
Try the below code after "GRAPHIC 4,1", it will draw a dot of color 1 at (16,32).
lda #$10 sta $02ad ;x coord low lda #$20 sta $02af ;y coord low lda #$00 sta $02ae ;x coord high sta $02b0 ;y coord high lda #$01 sta $84 ;color jsr $c1a5
|
|
Posted By
SVS on 2012-11-30 03:41:08
| Re: Draw a single pixel in assembler
bubis, you forgot a STA $2b0 after STA $2ae
|
|
Posted By
bubis on 2012-11-30 06:40:22
| Re: Draw a single pixel in assembler
@SVS: The code works fine even without lda #$00+sta $02ae because this mem area is filled with zeros after reset. Otherwise, you are right, safer to set $2b0 as well, so I updated the code. Thanks!
|
|
Posted By
George on 2013-03-31 10:07:11
| Re: Draw a single pixel in assembler
Hi, I implemented the code and of course it works. I move a little sprite around i realize filckering. Any method to synchronize the code with the rasterbeam (V-Sync/H-Sync)? Examples are apreciated.
|
|
Posted By
George on 2013-03-31 10:07:14
| Re: Draw a single pixel in assembler
Hi, I implemented the code and of course it works. I move a little sprite around i realize filckering. Any method to synchronize the code with the rasterbeam (V-Sync/H-Sync)? Examples are apreciated.
|
|
Posted By
MMS on 2013-04-01 04:39:38
| Re: Draw a single pixel in assembler
in the Publications the Raster Split has an example how to wait a specific rasterline in the Loop section. Easy way to take care that you draw the pixel when you are out of 200 pixel high drawging area (sorry, no exact rasterline numbers here), so you draw when you are border area or out of screen. Little more complicated if you take care that the raster is right after the drawing position, so you have a plenty of time, but need an extra register to store drawing positiom. Some more talented programmers may give more exact instructions.
|
|
Posted By
KiCHY on 2013-04-01 10:28:10
| Re: Draw a single pixel in assembler
The "jsr $c1a5" method works for turning on/off individual pixels on screen. Drawing a complete shape from these pixels (drawing each pixel is a complete coordinate/address calculation) costs lots of time and I'm afraid you won't eliminate the blinking completely. For shapes I strongly suggest to use some kind of software sprite routine.
|
|
Posted By
George on 2013-04-02 07:04:36
| Re: Draw a single pixel in assembler
hi Kichy,
its a very small shape of a few pixels. I eliminated the flickering by clearing and drawing only the borders of the shape when moving it to a certain direction.
You gave an example, but i didnt get it to work, because of my lack of experience. How do i use this routine for simple shape? (lets say a square of 4x4 pixels.
XR: x coord lo $d0: x coord hi YR: y coord
lda row_addr_lo,y sta $d2 clc lda $d0 adc row_addr_hi,y sta $d3 txa and #$f8 tay lda ($d2),y ora bits,x sta ($d2),y rts
You have to prepare three tables for this to work: * row_addr_lo/row_addr_hi needs to point to the first byte on the bitmap for the respective y coordinate, so it's like (bitmap_base+(y/8)*320+y&7). * bits is a 256 bytes long periodic sequence of 128,64,32,16,8,4,2,1, 128, ....
UPDATE: No codewizard, who wants to help? How do you want to keep alive the scene for the next generation, if you don't support and document essential programming issues for the less experienced people? Share your knowledge, with executable examples, please.
Greetings George
|
|
Posted By
KiCHY on 2013-04-02 16:02:48
| Re: Draw a single pixel in assembler
Hi George,
I made a small demo, you can download it: http://wikisend.com/download/123630/DrawShape.zip
Not a speedcode, I tried to make it "tutoriallish"
I tried to use Plus4IDE first but it simply couldn't compile anything, got an error message... Then I checked the as65.exe and it said can't run in 64bit OS. So I tried CBM Prg Studio, I zipped its project files.
The DrawShape function uses EOR to draw the shape which means if you call it twice, the second call will remove the shape from bitmap.
I hope it helps
|
|
Posted By
George on 2013-04-19 17:19:09
| Re: Draw a single pixel in assembler
Hi Kichy,
thanks for your example. A little overkill at first view for me. I will try to understand it and will come with questions.
Got it working in 2.4.0. The source does not compile without errors.
Replace the line 136 to 147 with this here: XCoord = $d0 ; X coordinate between 0-156 YCoord = $d1 ; Y coordinate between 0-96 SrcAddr = $d2 ; Address of 2x1char shape to be drawn (normal, or shifted versions) SrcAddrLo = $d2 SrcAddrHi = SrcAddr+1 Dest1Addr = $d4 ; Address of left character of 2x1 shape on bitmap Dest1AddrLo = $d4 Dest1AddrHi = Dest1Addr+1 Dest2Addr = $d6 ; Address of right character of 2x1 shape on bitmap Dest2AddrLo = $d6 Dest2AddrHi = Dest2Addr+1 YMod8 = $d8
In Multicolor mode the shape is drawn blocky.
|
|