I'll do that then.
Perhaps calc84 or Runer can assist with the conversion from bit to byte in an effort to gain maximum speed?
I was thinking along the lines of:
ld a,d
sla c ; (or equivilent)
adc a,e
where:
d = $FF
e = 0
c = (hl) ; byte from gbuf
Rolled out 8 times and looped for each row.
You could mess with d and e for different colour combinations I suppose.
You can also take advantage of LCD increment modes to output converted pixels twice per row instead of having to doubly convert each row of pixels. You would need to manually increase each row on the LCD however, though it should work out better overall.
I was thinking along the lines of:
ld a,d
sla c ; (or equivilent)
adc a,e
where:
d = $FF
e = 0
c = (hl) ; byte from gbuf
Rolled out 8 times and looped for each row.
You could mess with d and e for different colour combinations I suppose.
You can also take advantage of LCD increment modes to output converted pixels twice per row instead of having to doubly convert each row of pixels. You would need to manually increase each row on the LCD however, though it should work out better overall.
Ah, thank you tr1p1ea! Using adc like that is pretty nifty. It does appear to have a speed increase. As for the LCD increment modes, I am a little unsure of where to begin with that. Should I set the window to draw the pixel, go down a row, draw the same pixel, and then go back to the top? So I have a window that I would need to increment by 2 on each new line? Thanks for your help!
EDIT: Here's what my current code looks like:
Code:
EDIT: Here's what my current code looks like:
Code:
UpdateScreen:
ld hl,56
ld a,$50 ; min Y
out ($10),a
out ($10),a
ld c,$11
out (c),h
out (c),l
ld a,$20 ; curr Y
out ($10),a
out ($10),a
out (c),h
out (c),l
ld hl,32 ; half-res
ld a,$52
out ($10),a
out ($10),a
out (c),h
out (c),l
ld a,$21 ; curr X
out ($10),a
out ($10),a
out (c),h
out (c),l
ld hl,127
ld a,$53 ; max X
out ($10),a
out ($10),a
out (c),h
out (c),l
ld a,$22
out ($10),a
out ($10),a
ld d,64*2
ld hl,plotsscreen
OuterLoop2:
ld e,12
OuterLoop:
ld c,(hl)
inc hl
push de
ld de,$FF00
ld a,d
sla c
adc a,e
out ($11),a
out ($11),a
ld a,d
sla c
adc a,e
out ($11),a
out ($11),a
ld a,d
sla c
adc a,e
out ($11),a
out ($11),a
ld a,d
sla c
adc a,e
out ($11),a
out ($11),a
ld a,d
sla c
adc a,e
out ($11),a
out ($11),a
ld a,d
sla c
adc a,e
out ($11),a
out ($11),a
ld a,d
sla c
adc a,e
out ($11),a
out ($11),a
ld a,d
sla c
adc a,e
out ($11),a
out ($11),a
pop de
dec e
jr nz,OuterLoop
dec d
ret z
ld a,d
and $01
jp z,OuterLoop2
and a
ld bc,12
sbc hl,bc
jp OuterLoop2
I think what tr1p1ea is referring to is that you can tell the VRAM cursor to move up/down after each write as opposed to left/right as it normally does:
http://wikiti.brandonw.net/index.php?title=84PCSE:LCD_Controller#03:_Entry_Mode
Using this U/D entry mode, for each 12 byte row of gbuf to draw, you could open a 96x2 window (96 because half res mode) and write each bit twice as you work through the 12 bytes, instead of having to process the 12 bytes through once and then again for the second line. It should be a tiny bit quicker I'd say
http://wikiti.brandonw.net/index.php?title=84PCSE:LCD_Controller#03:_Entry_Mode
Using this U/D entry mode, for each 12 byte row of gbuf to draw, you could open a 96x2 window (96 because half res mode) and write each bit twice as you work through the 12 bytes, instead of having to process the 12 bytes through once and then again for the second line. It should be a tiny bit quicker I'd say
JamesV wrote:
I think what tr1p1ea is referring to is that you can tell the VRAM cursor to move up/down after each write as opposed to left/right as it normally does:
http://wikiti.brandonw.net/index.php?title=84PCSE:LCD_Controller#03:_Entry_Mode
Using this U/D entry mode, for each 12 byte row of gbuf to draw, you could open a 96x2 window (96 because half res mode) and write each bit twice as you work through the 12 bytes, instead of having to process the 12 bytes through once and then again for the second line. It should be a tiny bit quicker I'd say
http://wikiti.brandonw.net/index.php?title=84PCSE:LCD_Controller#03:_Entry_Mode
Using this U/D entry mode, for each 12 byte row of gbuf to draw, you could open a 96x2 window (96 because half res mode) and write each bit twice as you work through the 12 bytes, instead of having to process the 12 bytes through once and then again for the second line. It should be a tiny bit quicker I'd say
Thanks James! I'll give that a try; theorettically it could make things run a little smoother and have less iterations too! That is kind of what I was trying to say, I wasn't sure if a 96x2 window would work. Would I then need to increment the window below by two? So that would mean that I would need to reset the window ever time I drew 2 lines though, wouldn't it?
MateoConLechuga wrote:
Thanks James! I'll give that a try; theorettically it could make things run a little smoother and have less iterations too! That is kind of what I was trying to say, I wasn't sure if a 96x2 window would work. Would I then need to increment the window below by two? So that would mean that I would need to reset the window ever time I drew 2 lines though, wouldn't it?
I believe so yes, you would set a 96x2 window 64 times (once for each row of gbuf to be drawn). I think this should still be a slightly faster method though, as you won't have to rotate through 12x8 bits twice, just the once.
Yes you would increase by 2 after processing each row.
When setting entry mode, something like $10B0 should do what you need.
Set your initial window before drawing the first line
During the 12 byte conversion loop, you simply OUT each pixel twice (4 OUT's) as it will draw top, then bottom, then wrap back to top again and move across as well).
After each line, increase Y and reset Window X/Y to 0 (reg $20 & $21)
Another idea is to use IX for the plotsscreen pointer, this will free up HL and allow you to use C again for the LCD port, hopefully speeding things up more (maybe even give you b back as a loop var and get rid of the need to use the stack)
When setting entry mode, something like $10B0 should do what you need.
Set your initial window before drawing the first line
During the 12 byte conversion loop, you simply OUT each pixel twice (4 OUT's) as it will draw top, then bottom, then wrap back to top again and move across as well).
After each line, increase Y and reset Window X/Y to 0 (reg $20 & $21)
Another idea is to use IX for the plotsscreen pointer, this will free up HL and allow you to use C again for the LCD port, hopefully speeding things up more (maybe even give you b back as a loop var and get rid of the need to use the stack)
JamesV wrote:
I think what tr1p1ea is referring to is that you can tell the VRAM cursor to move up/down after each write as opposed to left/right as it normally does:
http://wikiti.brandonw.net/index.php?title=84PCSE:LCD_Controller#03:_Entry_Mode
Using this U/D entry mode, for each 12 byte row of gbuf to draw, you could open a 96x2 window (96 because half res mode) and write each bit twice as you work through the 12 bytes, instead of having to process the 12 bytes through once and then again for the second line. It should be a tiny bit quicker I'd say
http://wikiti.brandonw.net/index.php?title=84PCSE:LCD_Controller#03:_Entry_Mode
Using this U/D entry mode, for each 12 byte row of gbuf to draw, you could open a 96x2 window (96 because half res mode) and write each bit twice as you work through the 12 bytes, instead of having to process the 12 bytes through once and then again for the second line. It should be a tiny bit quicker I'd say
I don't want to go off topic too much, but this is a really helpful trick to know. I'd been struggling conceptually with a related task on one of my projects trying to figure out how to save on I/O, and this is exactly what I needed.
Okay, so I got it working, and here are the results:
Original:
New:
Original:
New:
And here's the code, if anyone can see some more optimizations.
Code:
Original:
New:
Original:
New:
And here's the code, if anyone can see some more optimizations.
Code:
UpdateScreen:
ld hl,$10B0
ld a,$03
out ($10),a
out ($10),a
ld c,$11
out (c),h
out (c),l
ld hl,56
ld (YCounter),hl
ld a,$50 ; min Y
out ($10),a
out ($10),a
out (c),h
out (c),l
ld a,$20 ; curr Y
out ($10),a
out ($10),a
out (c),h
out (c),l
inc hl
ld a,$51 ; curr Y
out ($10),a
out ($10),a
out (c),h
out (c),l
ld hl,32 ; half-res
ld a,$52
out ($10),a
out ($10),a
out (c),h
out (c),l
ld a,$21 ; curr X
out ($10),a
out ($10),a
out (c),h
out (c),l
ld a,$22
out ($10),a
out ($10),a
ld d,64
ld hl,plotsscreen
OuterLoop2:
ld e,12
OuterLoop:
ld b,(hl)
inc hl
push de
ld de,$FF00
ld a,d
sla b
adc a,e
out (c),a
out (c),a
out (c),a
out (c),a
ld a,d
sla b
adc a,e
out (c),a
out (c),a
out (c),a
out (c),a
ld a,d
sla b
adc a,e
out (c),a
out (c),a
out (c),a
out (c),a
ld a,d
sla b
adc a,e
out (c),a
out (c),a
out (c),a
out (c),a
ld a,d
sla b
adc a,e
out (c),a
out (c),a
out (c),a
out (c),a
ld a,d
sla b
adc a,e
out (c),a
out (c),a
out (c),a
out (c),a
ld a,d
sla b
adc a,e
out (c),a
out (c),a
out (c),a
out (c),a
ld a,d
sla b
adc a,e
out (c),a
out (c),a
out (c),a
out (c),a
pop de
dec e
jr nz,OuterLoop
dec d
ret z ; After each line, increase Y and reset Window X/Y to 0 (reg $20 & $21)
push hl
ld hl,(YCounter)
inc hl
inc hl
ld (YCounter),hl
ld a,$50 ; min Y
out ($10),a
out ($10),a
out (c),h
out (c),l
ld a,$20 ; curr Y
out ($10),a
out ($10),a
out (c),h
out (c),l
ld hl,(YCounter)
inc hl
ld a,$51 ; max Y
out ($10),a
out ($10),a
out (c),h
out (c),l
ld hl,32 ; half-res
ld a,$21 ; curr X
out ($10),a
out ($10),a
out (c),h
out (c),l
ld a,$22
out ($10),a
out ($10),a
pop hl
jp OuterLoop2
YCounter:
.dw 0
Hi Mateo, I had a quick look and I think you can get rid of the need for the memory variable, plus using IX might free up some other stuff too:
Note that this is UNTESTED! I chopped it a little, but i did leave the original stuff in there too (commented out). Hopefully this might be of use.
Code:
Note that this is UNTESTED! I chopped it a little, but i did leave the original stuff in there too (commented out). Hopefully this might be of use.
Code:
UpdateScreen:
ld hl,$10B0
ld a,$03
out ($10),a
out ($10),a
ld c,$11
out (c),h
out (c),l
ld hl,56
; ld (YCounter),hl
ld a,$50 ; min Y
out ($10),a
out ($10),a
out (c),h
out (c),l
ld a,$20 ; curr Y
out ($10),a
out ($10),a
out (c),h
out (c),l
inc hl
ld b,l
ld a,$51 ; curr Y
out ($10),a
out ($10),a
out (c),h
out (c),l
ld hl,32 ; half-res
ld a,$52
out ($10),a
out ($10),a
out (c),h
out (c),l
ld a,$21 ; curr X
out ($10),a
out ($10),a
out (c),h
out (c),l
ld a,$22
out ($10),a
out ($10),a
ld l,b
ld de,$FF00
ld b,64
ld ix,plotsscreen
OuterLoop2:
push bc
ld b,12
OuterLoop:
ld h,(ix + 0)
inc ix
ld a,d
sla h
adc a,e
out (c),a
out (c),a
out (c),a
out (c),a
ld a,d
sla h
adc a,e
out (c),a
out (c),a
out (c),a
out (c),a
ld a,d
sla h
adc a,e
out (c),a
out (c),a
out (c),a
out (c),a
ld a,d
sla h
adc a,e
out (c),a
out (c),a
out (c),a
out (c),a
ld a,d
sla h
adc a,e
out (c),a
out (c),a
out (c),a
out (c),a
ld a,d
sla h
adc a,e
out (c),a
out (c),a
out (c),a
out (c),a
ld a,d
sla h
adc a,e
out (c),a
out (c),a
out (c),a
out (c),a
ld a,d
sla h
adc a,e
out (c),a
out (c),a
out (c),a
out (c),a
djnz OuterLoop
; dec d
; ret z ; After each line, increase Y and reset Window X/Y to 0 (reg $20 & $21)
; push hl
; ld hl,(YCounter)
; inc hl
; inc hl
; ld (YCounter),hl
inc l
ld a,$50 ; min Y
out ($10),a
out ($10),a
out (c),e
out (c),l
ld a,$20 ; curr Y
out ($10),a
out ($10),a
out (c),e
out (c),e ; zero should be fine here
; ld hl,(YCounter)
; inc hl
inc l
ld a,$51 ; max Y
out ($10),a
out ($10),a
out (c),e
out (c),l
; ld hl,32 ; half-res
ld a,$21 ; curr X
out ($10),a
out ($10),a
out (c),e
out (c),e ; zero should be fine here
ld a,$22
out ($10),a
out ($10),a
pop bc
dec b
jp nz,OuterLoop2
ret
tr1p1ea++ again! It worked perfectly the first time around. I also learned that I don't need to set the X/Y current to the start... Well, what do you know. Thank you for the help everyone, I'm going to add some more routines and see what becomes of it.
MateoConLechuga wrote:
tr1p1ea++ again! It worked perfectly the first time around. I also learned that I don't need to set the X/Y current to the start... Well, what do you know.
Just make sure that you have the ORG bit set in the entry mode byte (see documentation), otherwise that won't be the case. I believe we generally leave the ORG bit set whenever possible. Anywho, awesome progress on this, gents; the speedup even over two days is extremely impressive.
Cool, thanks for letting me know before I went and did something silly!
Anyhow, I'm working on converting AB5 right now, as you can see there is no text because I still need a font routine that works right... and it crashes right after drawing a level, which I still need to track down. It just freezes. James did like to use that good ol' port 16 for earthquake effects.
Anyhow, I'm working on converting AB5 right now, as you can see there is no text because I still need a font routine that works right... and it crashes right after drawing a level, which I still need to track down. It just freezes. James did like to use that good ol' port 16 for earthquake effects.
MateoConLechuga wrote:
Cool, thanks for letting me know before I went and did something silly!
Anyhow, I'm working on converting AB5 right now, as you can see there is no text because I still need a font routine that works right... and it crashes right after drawing a level, which I still need to track down. It just freezes. James did like to use that good ol' port 16 for earthquake effects.
Hah that's so cool! I should have mentioned last night that on APP page 0 I use the TI-OS _grbufcpy routine, but APP page 1 (the game play) has its own routine to copy gbuf to the LCD (it's ionFastCopy borrowed from Joe).
Anyhow, I'm working on converting AB5 right now, as you can see there is no text because I still need a font routine that works right... and it crashes right after drawing a level, which I still need to track down. It just freezes. James did like to use that good ol' port 16 for earthquake effects.
So I would suggest putting the 84+CSE LCD routine on page 1, and when it's required from page 0 you bcall it (page 1 needs the speed, page 0 not so much )
EDIT: And yes, I do use port $10 for the screen shaking heh, which would have to be done manually on the 84+CSE I imagine.
Indeed. So much fun! Anyhow, I found the offending code, it had to do with the frame checker to make sure the game didn't run to fast. I commented it out for now; time to rewrite it later. Also, for some odd reason, I can go through walls and objects.... And enemies disappeared. Oops. I changed something I wasn't supposed to.
And they said 8-way scrolling on the CSE would be interesting....
It runs a ton smoother on-calc; the gif outputted by wabbit still has some issues.
And they said 8-way scrolling on the CSE would be interesting....
It runs a ton smoother on-calc; the gif outputted by wabbit still has some issues.
Well, at least you can still pick up items! Also, might be worth setting a more general topic title.
You know, it's projects like this that gets me excited to work on PotM
This looks above and beyond amazing.
This looks above and beyond amazing.
Well, fixed the problem with walls and enemies! Now I just need a nice custom small font text routine for the monochrome calcs, basically just something that does the exact same thing as _vputmap, and it will be pretty much all set. Except for earthquakes. That still needs some fixing.
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.
» Go to Registration page
» Go to Registration page
» Goto page Previous 1, 2, 3, 4, 5 Next
» View previous topic :: View next topic
» View previous topic :: View next topic
Page 2 of 5
» All times are UTC - 5 Hours
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Advertisement