BritLion's Putchars - britlion - 06-04-2010
LCD play with this.
The question is, this doesn't do attributes right now. How would you want that handled?
1> Assume it's at the end of the data block? (So if you use putchars for one character, it's the 9th byte. For a 2X2 block, it's the 65th, 66th, 67th and 68th...
2> A separate putAttribs function that works the same way
3> Leave it up to the user to do print at y,x, over 1, paper x, ink y;"<space>"
Something else?
I haven't tested mine against yours, I'm just assuming because of code efficiency, this is faster screen handling.
Edit: See below for test results
Edit: Fixed a bug - in BLPutCharNextThird add HL,DE and POP DE were backwards. Thanks to Compiuter for reporting this.
Edit: Shaved a few clock cycles off the graphics printing, and added a paint sub
Edit: Added a paintData sub
Code: SUB paint (x as uByte,y as uByte, width as uByte, height as uByte, attribute as ubyte)
asm
ld a,(IX+7) ;ypos
rrca
rrca
rrca ; Multiply by 32
ld l,a ; Pass to L
and 3 ; Mask with 00000011
add a,88 ; 88 * 256 = 22528 - start of attributes. Change this if you are working with a buffer or somesuch.
ld h,a ; Put it in the High Byte
ld a,l ; We get y value *32
and 224 ; Mask with 11100000
ld l,a ; Put it in L
ld a,(IX+5) ; xpos
add a,l ; Add it to the Low byte
ld l,a ; Put it back in L, and we're done. HL=Address.
push HL ; save address
LD A, (IX+13) ; attribute
LD DE,32
LD c,(IX+11) ; height
BLPaintHeightLoop:
LD b,(IX+9) ; width
BLPaintWidthLoop:
LD (HL),a ; paint a character
INC L ; Move to the right (Note that we only would have to inc H if we are crossing from the right edge to the left, and we shouldn't be needing to do that)
DJNZ BLPaintWidthLoop
BLPaintWidthExitLoop:
POP HL ; recover our left edge
DEC C
JR Z, BLPaintHeightExitLoop
ADD HL,DE ; move 32 down
PUSH HL ; save it again
JP BLPaintHeightLoop
BLPaintHeightExitLoop:
end asm
END SUB
SUB paintData (x as uByte,y as uByte, width as uByte, height as uByte, address as uInteger)
asm
ld a,(IX+7) ;ypos
rrca
rrca
rrca ; Multiply by 32
ld l,a ; Pass to L
and 3 ; Mask with 00000011
add a,88 ; 88 * 256 = 22528 - start of attributes. Change this if you are working with a buffer or somesuch.
ld h,a ; Put it in the High Byte
ld a,l ; We get y value *32
and 224 ; Mask with 11100000
ld l,a ; Put it in L
ld a,(IX+5) ; xpos
add a,l ; Add it to the Low byte
ld l,a ; Put it back in L, and we're done. HL=Address.
push HL ; save address
LD D, (IX+13)
LD E, (IX+12)
LD c,(IX+11) ; height
BLPaintDataHeightLoop:
LD b,(IX+9) ; width
BLPaintDataWidthLoop:
LD a,(DE)
LD (HL),a ; paint a character
INC L ; Move to the right (Note that we only would have to inc H if we are crossing from the right edge to the left, and we shouldn't be needing to do that)
INC DE
DJNZ BLPaintDataWidthLoop
BLPaintDataWidthExitLoop:
POP HL ; recover our left edge
DEC C
JR Z, BLPaintDataHeightExitLoop
PUSH DE
LD DE,32
ADD HL,DE ; move 32 down
POP DE
PUSH HL ; save it again
JP BLPaintDataHeightLoop
BLPaintDataHeightExitLoop:
end asm
END SUB
SUB putChars(x as uByte,y as uByte, width as uByte, height as uByte, dataAddress as uInteger)
asm
BLPutChar:
LD a,(IX+5)
;AND 31
ld l,a
ld a,(IX+7) ; Y value
ld d,a
AND 24
add a,64 ; 256 byte "page" for screen - 256*64=16384. Change this if you are working with a screen address elsewhere, such as a buffer.
ld h,a
ld a,d
AND 7
rrca
rrca
rrca
OR l
ld l,a
PUSH HL ; save our address
LD E,(IX+12) ; data address
LD D,(IX+13)
LD B,(IX+9) ; width
PUSH BC ; save our column count
BLPutCharColumnLoop:
LD B,(IX+11) ; height
BLPutCharInColumnLoop:
; gets screen address in HL, and bytes address in DE. Copies the 8 bytes to the screen
ld a,(DE) ; First Row
LD (HL),a
INC DE
INC H
ld a,(DE)
LD (HL),a ; second Row
INC DE
INC H
ld a,(DE)
LD (HL),a ; Third Row
INC DE
INC H
ld a,(DE)
LD (HL),a ; Fourth Row
INC DE
INC H
ld a,(DE)
LD (HL),a ; Fifth Row
INC DE
INC H
ld a,(DE)
LD (HL),a ; Sixth Row
INC DE
INC H
ld a,(DE)
LD (HL),a ; Seventh Row
INC DE
INC H
ld a,(DE)
LD (HL),a ; Eigth Row
INC DE ; Move to next data item.
DEC B
JR Z,BLPutCharNextColumn
;The following code calculates the address of the next line down below current HL address.
PUSH DE ; save DE
ld a,l
and 224
cp 224
jp z,BLPutCharNextThird
BLPutCharSameThird:
ld de,-1760
;and a
add hl,de
POP DE ; get our data point back.
jp BLPutCharInColumnLoop
BLPutCharNextThird:
ld de,32
;and a
add hl,de
POP DE ; get our data point back.
JP BLPutCharInColumnLoop
BLPutCharNextColumn:
POP BC
POP HL
DEC B
JP Z, BLPutCharsEnd
INC L ; Note this would normally be Increase HL - but block painting should never need to increase H, since that would wrap around.
PUSH HL
PUSH BC
JP BLPutCharColumnLoop
BLPutCharsEnd:
end asm
END SUB
goto start
datapoint:
asm
defb 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32
defb 33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64
defb 65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96
defb 97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128
end asm
start:
cls
putChars(10,10,3,3,@datapoint)
paint(10,10,3,3,79)
Re: BritLion's Putchars - Speed Test - britlion - 06-04-2010
LCD, you wanted fast screen handling?
I tested your routine against mine. And against PRINT.
Perhaps I did something wrong, but according to my tests "PRINT AT" is faster than your routine...
(obviously, you are including attributes, and I'm not; yet.)
Code: 10,000 loop test:
PRINT AT 10,10;"A" 289 Frames
PRINT AT 10,10;"AA" 473 Frames
PRINT AT 10,10;"A";AT 11,10;"A" 526 Frames
PRINT AT 10,10;"AA";AT 11,10;"AA" 896 Frames
BL Putchars - 1X1 163 frames
2x1 211 frames
1x2 211 Frames
2X2 301 Frames
3X3 534 Frames
4X4 853 Frames
8X8 3074 Frames
BL's PutTile 2X2 276 Frames* - Best estimate. This can't be frame timed
*See other thread for this code. May make it into the wiki library.
LCD's 1X1 346 Frames
1X2 658 Frames
2X1 658 Frames
2X2 1294 Frames
For repeating the tests, here's the whole code I used:
EDIT: This code is bugged. My bugfixed version is above!
Code: '===========================
'= putchar lcd compiuter =
'= version 1.100603 <-date =
'===========================
'#include <sinclair.bas>
'#include <memcopy.bas>
'#include <keys.bas>
'#include <print42.bas>
'#include <attr.bas>
'---
'cls
'border 5
'-------------------------------------
sub putcharLcd1x1(x as Uinteger,y as Uinteger,adr as Uinteger)
dim scr as Uinteger
dim a as Uinteger
a=peek(@linebuffer+y)
scr=(a<<5)+x+16384
poke ubyte scr,peek(adr)
poke ubyte scr+256,peek(adr+1)
poke ubyte scr+512,peek(adr+2)
poke ubyte scr+768,peek(adr+3)
poke ubyte scr+1024,peek(adr+4)
poke ubyte scr+1280,peek(adr+5)
poke ubyte scr+1536,peek(adr+6)
poke ubyte scr+1792,peek(adr+7)
poke ubyte 22528+x+(y<<5),peek (adr+8)
End sub
'-------------------------------------------
sub putcharLcd1x2(x as Uinteger,y as Uinteger,adr as Uinteger)
dim scr as Uinteger
dim a as Uinteger
a=peek(@linebuffer+y)
scr=(a<<5)+x+16384
poke ubyte scr,peek(adr)
poke ubyte scr+256,peek(adr+1)
poke ubyte scr+512,peek(adr+2)
poke ubyte scr+768,peek(adr+3)
poke ubyte scr+1024,peek(adr+4)
poke ubyte scr+1280,peek(adr+5)
poke ubyte scr+1536,peek(adr+6)
poke ubyte scr+1792,peek(adr+7)
poke ubyte 22528+x+(y<<5),peek (adr+8)
x=x+1
a=peek(@linebuffer+y)
scr=(a<<5)+x+16384
poke ubyte scr,peek(adr+9)
poke ubyte scr+256,peek(adr+10)
poke ubyte scr+512,peek(adr+11)
poke ubyte scr+768,peek(adr+12)
poke ubyte scr+1024,peek(adr+13)
poke ubyte scr+1280,peek(adr+14)
poke ubyte scr+1536,peek(adr+15)
poke ubyte scr+1792,peek(adr+16)
poke ubyte 22528+x+(y<<5),peek (adr+17)
End sub
'-------------------------------------------
sub putcharLcd2x1(x as Uinteger,y as Uinteger,adr as Uinteger)
dim scr as Uinteger
dim a as Uinteger
a=peek(@linebuffer+y)
scr=(a<<5)+x+16384
poke ubyte scr,peek(adr)
poke ubyte scr+256,peek(adr+1)
poke ubyte scr+512,peek(adr+2)
poke ubyte scr+768,peek(adr+3)
poke ubyte scr+1024,peek(adr+4)
poke ubyte scr+1280,peek(adr+5)
poke ubyte scr+1536,peek(adr+6)
poke ubyte scr+1792,peek(adr+7)
poke ubyte 22528+x+(y<<5),peek (adr+8)
y=y+1
a=peek(@linebuffer+y)
scr=(a<<5)+x+16384
poke ubyte scr,peek(adr+9)
poke ubyte scr+256,peek(adr+10)
poke ubyte scr+512,peek(adr+11)
poke ubyte scr+768,peek(adr+12)
poke ubyte scr+1024,peek(adr+13)
poke ubyte scr+1280,peek(adr+14)
poke ubyte scr+1536,peek(adr+15)
poke ubyte scr+1792,peek(adr+16)
poke ubyte 22528+x+(y<<5),peek (adr+17)
End sub
'-------------------------------------------
sub putcharLcd2x2(x as Uinteger,y as Uinteger,adr as Uinteger)
dim scr as Uinteger
dim a as Uinteger
a=peek(@linebuffer+y)
scr=(a<<5)+x+16384
poke ubyte scr,peek(adr)
poke ubyte scr+256,peek(adr+1)
poke ubyte scr+512,peek(adr+2)
poke ubyte scr+768,peek(adr+3)
poke ubyte scr+1024,peek(adr+4)
poke ubyte scr+1280,peek(adr+5)
poke ubyte scr+1536,peek(adr+6)
poke ubyte scr+1792,peek(adr+7)
poke ubyte 22528+x+(y<<5),peek (adr+8)
x=x+1
a=peek(@linebuffer+y)
scr=(a<<5)+x+16384
poke ubyte scr,peek(adr+9)
poke ubyte scr+256,peek(adr+10)
poke ubyte scr+512,peek(adr+11)
poke ubyte scr+768,peek(adr+12)
poke ubyte scr+1024,peek(adr+13)
poke ubyte scr+1280,peek(adr+14)
poke ubyte scr+1536,peek(adr+15)
poke ubyte scr+1792,peek(adr+16)
poke ubyte 22528+x+(y<<5),peek (adr+17)
x=x-1
y=y+1
a=peek(@linebuffer+y)
scr=(a<<5)+x+16384
poke ubyte scr,peek(adr+18)
poke ubyte scr+256,peek(adr+19)
poke ubyte scr+512,peek(adr+20)
poke ubyte scr+768,peek(adr+21)
poke ubyte scr+1024,peek(adr+22)
poke ubyte scr+1280,peek(adr+23)
poke ubyte scr+1536,peek(adr+24)
poke ubyte scr+1792,peek(adr+25)
poke ubyte 22528+x+(y<<5),peek (adr+26)
x=x+1
a=peek(@linebuffer+y)
scr=(a<<5)+x+16384
poke ubyte scr,peek(adr+27)
poke ubyte scr+256,peek(adr+28)
poke ubyte scr+512,peek(adr+29)
poke ubyte scr+768,peek(adr+30)
poke ubyte scr+1024,peek(adr+31)
poke ubyte scr+1280,peek(adr+32)
poke ubyte scr+1536,peek(adr+33)
poke ubyte scr+1792,peek(adr+34)
poke ubyte 22528+x+(y<<5),peek (adr+35)
End sub
'---next will be probably putcharlcd1x3
'---
goto start
linebuffer:
asm
defb 0,1,2,3,4,5,6,7,64,65,66,67,68,69,70,71,128,129,130,131,132,133,134,135
end asm
'--------------------------
'start:
'---fin---
END
'----------------------------------------
'gfx1a:
'ASM
'DEFB 0,8,8,8,8,8,8,0,00010001B
'DEFB 0,60,4,4,60,32,60,0,00011001B
'DEFB 0,60,4,4,60,4,60,0,00100001B
'DEFB 0,36,36,36,60,4,4,0,00101001B
'END ASM
'-----------------------------------------
FUNCTION t() as uLong
asm
LD DE,(23674)
LD D,0
LD HL,(23672)
end asm
end function
SUB putChars(x as uByte,y as uByte,height as uByte,width as uByte,dataAddress as uInteger)
DIM columns as uByte
REM Let's put our variables into our code:
POKE @BLPutCharWidth+1,width
POKE @BLPutCharHeight+1,height
POKE @BLPutCharX+1, x
POKE @BLPutCharY+1, y
POKE uInteger @BLPutCharData+1,dataAddress
asm
call BLPutChar
end asm
return
BLPutCharX:
asm
BLPutChar:
LD a,1
AND 31
ld l,a
end asm
BLPutCharY:
asm
ld a,2 ; Y value
ld d,a
AND 24
add a,64
ld h,a
ld a,d
AND 7
rrca
rrca
rrca
OR l
ld l,a
PUSH HL ; save our address.
end asm
BLPutCharData:
asm
LD DE,16384 ; Marker - This will be poked for the data address by the subroutine
end asm
BLPutCharWidth:
asm
LD B,3 ; Marker - this will be poked for the width
PUSH BC ; save our column count.
BLPutCharColumnLoop:
end asm
BLPutCharHeight:
asm
LD B,1 ; Marker - this will be poked for the height by the subroutine.
BLPutCharInColumnLoop:
call BLPutBytes
DEC B
JR Z,BLPutCharNextColumn
;The following code calculates the address of the next line down below current HL address.
PUSH DE ; save DE
ld a,l
and 224
cp 224
jp z,BLPutCharSameThird
BLPutCharNextThird:
ld de,-1760
;and a
add hl,de
POP DE ; get our data point back.
jp BLPutCharInColumnLoop
BLPutCharSameThird:
ld de,32
;and a
POP DE ; get our data point back.
add hl,de
JP BLPutCharInColumnLoop
BLPutCharNextColumn:
POP BC
POP HL
DEC B
RET Z
INC HL
PUSH HL
PUSH BC
JP BLPutCharColumnLoop
end asm
asm
BLPutBytes:
; gets screen address in HL, and bytes address in DE. Copies the 8 bytes to the screen.
ld a,(DE)
LD (HL),a
INC DE
INC H
ld a,(DE)
LD (HL),a
INC DE
INC H
ld a,(DE)
LD (HL),a
INC DE
INC H
ld a,(DE)
LD (HL),a
INC DE
INC H
ld a,(DE)
LD (HL),a
INC DE
INC H
ld a,(DE)
LD (HL),a
INC DE
INC H
ld a,(DE)
LD (HL),a
INC DE
INC H
ld a,(DE)
LD (HL),a
INC DE
ret
end asm
END SUB
goto start
datapoint:
asm
defb 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32
defb 33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64
defb 65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96
defb 97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128
end asm
start:
cls
DIM time as uLong
DIM i as uInteger
time=t()
for i=1 to 10000
'putChars(10,10,1,1,@datapoint) : REM Uncomment these lines as you need them.
'print at 10,10;"AA"; AT 11,10;"AA"
'putcharLcd1x1(10,10,@datapoint)
'putcharLcd1x2(10,10,@datapoint)
'putcharLcd2x1(10,10,@datapoint)
putcharLcd2x2(10,10,@datapoint)
next i
print t()-time
Re: BritLion's Putchars - compiuter - 06-04-2010
It seems to be clear that your putchar is faster and handly.
Now We need to go for another parameter for atributtes.
Or another sub created for this that suply this.
I´m trying to access your routine for this,
but I acces the position but not atributtes.
I´´m accesin this with Lcd´s function attraddress.
Re: BritLion's Putchars - boriel - 06-04-2010
compiuter Wrote:It seems to be clear that your putchar is faster and handly.
Now We need to go for another parameter for atributtes.
Or another sub created for this that suply this.
I´m trying to access your routine for this,
but I acces the position but not atributtes.
I´´m accesin this with Lcd´s function attraddress. You can also try SETATTR(x, y, aTTR) routine from the library.
Just use
Re: BritLion's Putchars - compiuter - 06-04-2010
Ok, thx,I try tomorrow.
Re: BritLion's Putchars - britlion - 06-04-2010
compiuter Wrote:It seems to be clear that your putchar is faster and handly.
Now We need to go for another parameter for atributtes.
Or another sub created for this that suply this.
I´m trying to access your routine for this,
but I acces the position but not atributtes.
I´´m accesin this with Lcd´s function attraddress.
As I said, it doesn't do attributes yet. I was waiting for LCD's opinion on how that should be done - and as Boriel has pointed out, there's a utility for it already. (*evil grin* More speed trials ahead!)
Looking at setAttr - it would be hard to improve on it by much, speedwise. Some, maybe. I can compare optimizations in getting the ATTR address (which Boriel is looking at), and make assumptions about the location of the attributes file, and that if we're called with numbers outside the screen area, we are entitled to crash. (that is, we don't do error checking). Not sure how big a difference it will make though.
Re: BritLion's Putchars - LCD - 06-05-2010
I know that the speed of my routine is not optimal, but unlike PRINT it allows to use more then 96 Characters+blocks+UDGs. In fact you can use fonts of 256 Characters or even more. BorIDE has now a font editow which allows to define such large fonts of 256 characters. I have added all fonts available in Retro-X and can add more later. It can also be used for small tiles. I can also display special characters like kana, german, polish, etc.
My Opinion: I would prefer to have multiple versions to choose from. One with attributes, one without. This will allow to choose speedwise the best routine. Thanks to you Britlion for optimising.
Re: BritLion's Putchars - britlion - 06-05-2010
You are quite welcome, LCD. My routine beats out the print routine purely because it's special purposed to copy data to the screen.
I think I rather like the fact that by looping columns and then rows it can do up to 8X8 blocks too. I was quite proud of that - all with just one screen address search. The downside is it has NO error trapping at all. It will happily try to write off the bottom or right hand sides of the screen.
(Though don't forget that exactly the same data could be put on the screen by changing CHARS and using print as well - and by rotating the CHARS system variable, you can print as many graphics characters to the screen at a time as you wish!)
As for attributes, it could be built into the routine as well, LCD. I just wasn't sure how you'd want to handle the data. If you're determined to make it 8+1 bytes per character, then honestly it's faster to skip the attributes on one pass, and then go back and put every 9th byte in as an attribute afterwards. That could be done as two subroutines, called by a third, one after the other, pointed at the same data.
Re: BritLion's Putchars - compiuter - 06-05-2010
It seems cut the sprites on screen thirds.
Code: SUB putChars(x as uByte,y as uByte,height as uByte,width as uByte,dataAddress as uInteger)
DIM columns as uByte
REM Let's put our variables into our code:
POKE @BLPutCharWidth+1,width
POKE @BLPutCharHeight+1,height
POKE @BLPutCharX+1, x
POKE @BLPutCharY+1, y
POKE uInteger @BLPutCharData+1,dataAddress
asm
call BLPutChar
end asm
return
BLPutCharX:
asm
BLPutChar:
LD a,1
AND 31
ld l,a
end asm
BLPutCharY:
asm
ld a,2 ; Y value
ld d,a
AND 24
add a,64
ld h,a
ld a,d
AND 7
rrca
rrca
rrca
OR l
ld l,a
PUSH HL ; save our address.
end asm
BLPutCharData:
asm
LD DE,16384 ; Marker - This will be poked for the data address by the subroutine
end asm
BLPutCharWidth:
asm
LD B,3 ; Marker - this will be poked for the width
PUSH BC ; save our column count.
BLPutCharColumnLoop:
end asm
BLPutCharHeight:
asm
LD B,1 ; Marker - this will be poked for the height by the subroutine.
BLPutCharInColumnLoop:
call BLPutBytes
DEC B
JR Z,BLPutCharNextColumn
;The following code calculates the address of the next line down below current HL address.
PUSH DE ; save DE
ld a,l
and 224
cp 224
jp z,BLPutCharSameThird
BLPutCharNextThird:
ld de,-1760
;and a
add hl,de
POP DE ; get our data point back.
jp BLPutCharInColumnLoop
BLPutCharSameThird:
ld de,32
;and a
POP DE ; get our data point back.
add hl,de
JP BLPutCharInColumnLoop
BLPutCharNextColumn:
POP BC
POP HL
DEC B
RET Z
INC HL
PUSH HL
PUSH BC
JP BLPutCharColumnLoop
end asm
asm
BLPutBytes:
; gets screen address in HL, and bytes address in DE. Copies the 8 bytes to the screen.
ld a,(DE)
LD (HL),a
INC DE
INC H
ld a,(DE)
LD (HL),a
INC DE
INC H
ld a,(DE)
LD (HL),a
INC DE
INC H
ld a,(DE)
LD (HL),a
INC DE
INC H
ld a,(DE)
LD (HL),a
INC DE
INC H
ld a,(DE)
LD (HL),a
INC DE
INC H
ld a,(DE)
LD (HL),a
INC DE
INC H
ld a,(DE)
LD (HL),a
INC DE
ret
end asm
END SUB
goto start
datapoint:
asm
defb 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32
defb 33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64
end asm
start:
cls
putChars(0,0,2,2,@datapoint)
putChars(0,7,2,2,@datapoint)
putChars(0,15,2,2,@datapoint)
print at 19,0;"error when line=7 or line=15"
Re: BritLion's Putchars - britlion - 06-06-2010
I will have to look into this. Thanks for spotting bugs!
Re: BritLion's Putchars - britlion - 06-06-2010
compiuter Wrote:It seems cut the sprites on screen thirds.
Got it. The pop DE was in the wrong place, so it wasn't working across thirds. Think it's fixed now. Try it again please!
Re: BritLion's Putchars - compiuter - 06-06-2010
Waiting for something better ...
In 10-06-10 I modified this routine because Britlion suggest that atributtes are readed better per files instead of per columns, as the cathodic ray bright the pixels in the tv(I say first all the chars of file 0, all chars file 1, ...)for see this uncomment the pause demo besides setattr commands
Code: '===========================
'= putchat britlion =
'===========================
'thx2Boriel idea using setattr
'modified by compiuter
'version 2.100609 <-date
#include <attr.bas>
'===========================================
SUB putChars(x as uByte,y as uByte,height as uByte,width as uByte,dataAddress as uInteger)
DIM columns as uByte
REM Let's put our variables into our code:
POKE @BLPutCharWidth+1,width
POKE @BLPutCharHeight+1,height
POKE @BLPutCharX+1, x
POKE @BLPutCharY+1, y
POKE uInteger @BLPutCharData+1,dataAddress
asm
call BLPutChar
end asm
return
BLPutCharX:
asm
BLPutChar:
LD a,1
AND 31
ld l,a
end asm
BLPutCharY:
asm
ld a,2 ; Y value
ld d,a
AND 24
add a,64
ld h,a
ld a,d
AND 7
rrca
rrca
rrca
OR l
ld l,a
PUSH HL ; save our address.
end asm
BLPutCharData:
asm
LD DE,16384 ; Marker - This will be poked for the data address by the subroutine
end asm
BLPutCharWidth:
asm
LD B,3 ; Marker - this will be poked for the width
PUSH BC ; save our column count.
BLPutCharColumnLoop:
end asm
BLPutCharHeight:
asm
LD B,1 ; Marker - this will be poked for the height by the subroutine.
BLPutCharInColumnLoop:
call BLPutBytes
DEC B
JR Z,BLPutCharNextColumn
;The following code calculates the address of the next line down below current HL address.
PUSH DE ; save DE
ld a,l
and 224
cp 224
jp z,BLPutCharSameThird
BLPutCharNextThird:
ld de,-1760
;and a
add hl,de
POP DE ; get our data point back.
jp BLPutCharInColumnLoop
BLPutCharSameThird:
ld de,32
;and a
add hl,de
POP DE ; get our data point back.
JP BLPutCharInColumnLoop
BLPutCharNextColumn:
POP BC
POP HL
DEC B
RET Z
INC HL
PUSH HL
PUSH BC
JP BLPutCharColumnLoop
end asm
asm
BLPutBytes:
; gets screen address in HL, and bytes address in DE. Copies the 8 bytes to the screen.
ld a,(DE)
LD (HL),a
INC DE
INC H
ld a,(DE)
LD (HL),a
INC DE
INC H
ld a,(DE)
LD (HL),a
INC DE
INC H
ld a,(DE)
LD (HL),a
INC DE
INC H
ld a,(DE)
LD (HL),a
INC DE
INC H
ld a,(DE)
LD (HL),a
INC DE
INC H
ld a,(DE)
LD (HL),a
INC DE
INC H
ld a,(DE)
LD (HL),a
INC DE
ret
end asm
END SUB
'=====================================
'### version atr x files #############
'#####################################
SUB putCharsAtr(x as uByte,y as uByte,height as uByte,width as uByte,Atr as Ubyte)
dim f,n as ubyte
for g=0 to height-1
for f=0 to width-1
setattr(y+g,x+f,Atr) 'for demo pause(10)
next
next
END SUB
'#####################################
'### version atr x columns ###########
' SUB putCharsAtr(x as uByte,y as uByte,height as uByte,width as uByte,Atr as Ubyte)
' dim f,g as ubyte
' for g=0 to width-1
' for f=0 to height-1
' setattr(y+f,x+g,Atr) 'for demo pause(10)
' pause(10)
' next
' next
' END SUB
'#####################################
'=====================================
SUB putChAt(x as uByte,y as uByte,height as uByte,width as uByte,dataAddress as uInteger,Atr as Ubyte)
putChars(x,y,height,width,dataAddress)
putCharsAtr(x,y,height,width,Atr)
END SUB
'=====================================
start:
cls
dim f as ubyte
for f=1 to 19 step 4
putChAt(0+f,0,2,3,@gfx1a,11110011b)
putChAt(0+f,2+f,3,9,@gfx1a,11100010b)
putChAt(0+f,18,3,2,@gfx1a,11000110b)
next
END
'----------------------------------------
gfx1a:
ASM
DEFB 8,8,8,8,8,8,8,8
DEFB 0,60,4,4,60,32,60,0
DEFB 0,60,4,4,60,4,60,0
DEFB 0,36,36,36,60,4,4,0
datapoint:
defb 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32
defb 33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64
end asm
'-----------------------------------------
Re: BritLion's Putchars - britlion - 06-06-2010
compiuter Wrote:Waiting for something better ...
And that would be....?
Just posting code doesn't tell me what's wrong with what you have...
What do you actually need it to do? I suspect you have some issue with attributes; but LCD hasn't mentioned what he wanted on that front either; so I'm a bit stuck for what additions or changes to make. If any.
Re: BritLion's Putchars - LCD - 06-07-2010
britlion Wrote:What do you actually need it to do? I suspect you have some issue with attributes; but LCD hasn't mentioned what he wanted on that front either; so I'm a bit stuck for what additions or changes to make. If any.
For 2x2 char I'm happy with your version BritLion as it is extremly fast. For 1x1 char I prefer to have two versions: One where you read 9 bytes inclusive chars, and one with 8 bytes, where the attribute byte is handed over in SUB call (PutChar(x,y,@adress,attribute))
Oh, I have a nice one for bigger blocks:
Code: FUNCTION scrAddress(x as uByte, y as uByte) as Uinteger
asm
;' This fn returns the address into HL of the screen address
;' x,y in character grid notation.
;' Original code was extracted by BloodBaz - Adapted for ZX BASiC by Britlion from Na_TH_AN's fourspriter
; x Arrives in A, y is in stack.
and 31
ld l,a
ld a,(IX+7) ; Y value
ld d,a
and 24
add a,64
ld h,a
ld a,d
and 7
rrca
rrca
rrca
or l
ld l,a
end asm
END FUNCTION
FUNCTION attrAddress(x as uByte, y as uByte) as uInteger
';; This function returns the memory address of the Character Position
';; x,y in the attribute screen memory.
';; Adapted from code by Jonathan Cauldwell - Adapted for ZX BASiC by Britlion from Na_TH_AN's fourspriter
asm
ld a,(IX+7) ;ypos
rrca
rrca
rrca ; Multiply by 32
ld l,a ; Pass to L
and 3 ; Mask with 00000011
add a,88 ; 88 * 256 = 22528 - start of attributes.
ld h,a ; Put it in the High Byte
ld a,l ; We get y value *32
and 224 ; Mask with 11100000
ld l,a ; Put it in L
ld a,(IX+5) ; xpos
add a,l ; Add it to the Low byte
ld l,a ; Put it back in L, and we're done. HL=Address.
end asm
END FUNCTION
sub putblock(x as Ubyte,y as ubyte,wid as ubyte,hgt as ubyte,adr as Uinteger)
dim scr,attribute as Uinteger
dim x1,y1 as Ubyte
dim a as Ubyte
poke uinteger @putblock1+7,wid
poke uinteger @putblock2+7,wid
for y1=0 to hgt-1
scr=scrAddress(x,y+y1)
for a=0 to 7
poke uinteger @putblock1+1,adr
poke uinteger @putblock1+4,scr
putblock1:
asm
ld hl,1
ld de,2
ld bc,3
ldir
end asm
adr=adr+wid
scr=scr+256
next a
next y1
attribute=attrAddress(x,y)
for y1=0 to hgt-1
poke uinteger @putblock2+1,adr
poke uinteger @putblock2+4,attribute
adr=adr+wid
attribute=attribute+32
putblock2:
asm
ld hl,4
ld de,5
ld bc,6
ldir
end asm
next y1
End sub
start:
putblock(0,18,8,6,0)
putblock(24,18,8,6,0)
putblock(24,0,8,6,0)
putblock(0,0,24,18,0)
pause 0
The speed is much better than the one I coded ten years ago.
Re: BritLion's Putchars - britlion - 06-07-2010
LCD Wrote:For 2x2 char I'm happy with your version BritLion as it is extremly fast. For 1x1 char I prefer to have two versions: One where you read 9 bytes inclusive chars, and one with 8 bytes, where the attribute byte is handed over in SUB call
You do realise that mine should be able to do anything from 1 character to a whole screen just by changing height and width (and making sure there's enough data at the address given!) ?
I'll see about tweaking it to accept attributes....
Do you need FLASH? It might be clever to assume you won't want to set a flashing attribute and have it assume that an attribute >128 (or negative) means that the attributes are in the data...
|