Ok so for a game I'm programming I have a grayscale routine and I'd like to know if I can make it better. I haven't actually had a chance to test it yet because I'm still working on the game but I need to have it done very soon so I'm asking about it now. Heres the code -



Code:

.deflong   sprite1()
   ld   a,(hl)
   inc   hl
   xor   (hl)
   and   c
   xor   (hl)
   out   (11),a
   inc   hl
.enddeflong

.deflong   sprite2()
   ld   a,(hl)
   inc   hl
   xor   (hl)
   and   d
   xor   (hl)
   out   (11),a
   inc   hl
.enddeflong

.deflong   sprite3()
   ld   a,(hl)
   inc   hl
   xor   (hl)
   and   e
   xor   (hl)
   out   (11),a
   inc   hl
.enddeflong



Grayscale:   ;x = 16/40/64 y = 21
   exx
   ex   af,af'
   push   af
   sub   0
   jr   z,grycont
   pop   af
   ld   a,3
   push   af
   ld   c,%01101101
   ld   d,%10110110
   ld   e,%11011011
   jr   grycont3
grycont
   dec   a
   jr   z,grycont2
   ld   c,%10110110
   ld   d,%11011011
   ld   e,%01101101
   jr   grycont3
grycont2
   ld   c,%11011011
   ld   d,%01101101
   ld   e,%10110110
grycont3
   
   ld   a,$94   ;only displaying sprites in set locations
   out   (10),a

   ld   b,2
   
   ld   hl,monsprite1
   ld   a,$22
   out   (10),a

Gryloop:
   sprite1()
   sprite2()
   sprite3()
   sprite1()
   sprite2()
   sprite3()
   sprite1()
   sprite2()   ;8 times
   
   sprite3()
   sprite1()
   sprite2()
   sprite3()
   sprite1()
   sprite2()
   sprite3()
   sprite1()   ;16 times
   
   ld   a,$07   ;go right
   out   (10),a
   
   sprite2()
   
   ld   a,$04
   out   (10),a   ;go up
   
   sprite3()
   sprite1()
   sprite2()
   sprite3()
   sprite1()
   sprite2()
   sprite3()
   sprite1()   ;8
   
   sprite2()
   sprite3()
   sprite1()
   sprite2()
   sprite3()
   sprite1()
   sprite2()   ;15
   
   ld   a,$05   ;go down
   out   (10),a
GryWaitloop:
   in   a,(10)
   jr   m,grywaitloop
   
   dec   b   ;1st go b = 1, 2nd b=0 3rd = 255 + c
   jr   z,grymon3
   jr   c,gryret
   
   ld   a,$25   ;row is set at the right spot
   out   (10),a
   jr   gryloop
grymon3:
   ld   a,$28
   out   (10),a
   
   
gryret:
   pop   af
   dec   a
   ex   af,af'
   exx
   ret
Are you sure that add hl,a is a valid instruction? I don't have tasm80.tab in front of me, and adding an 8-bit and a 16-bit register together isn't something I remember the z80 supporting.
It's not, and that code in general doesn't look like it'll work. I haven't looked closely at it, but given you don't seem to do anything with interrupts, it probably won't work at all as you hope it will.
While we're talking about instructions that don't exist, ld (hl),(iy+0) is completely invalid, as the z80's memory stage certainly does not support double-indirection. You have to ld a,(iy+0) / ld (hl),a, which takes a fairly nontrivial number of cycles. I recall anything involving offsetting ix and iy being particularly expensive.
ok I fixed the double indirection and adding a 1 byte register into a 2 byte one. I wasn't sure if they worked or not, I was just going to compile it when it was done and see if I got an error.
KermMartian wrote:
I recall anything involving offsetting ix and iy being particularly expensive.

It is. Take the additional overhead for accessing (hl) (3 cycles or so, generally), then add 8-ish more for the additional fetches of the instruction prefix, offset, and addition of the offset.

Basically, you'll at least double the required time for most instructions.
I guess I'd be better rewriting it from scratch...
My first idea was to just copy the sprites to the screen so I wouldn't have to copy the whole buffer but I don't know enough about ports and I haven't found any good tutorials on them...
The whole concept with greyscale on the 83+ series requires several display buffers, which are each rendered many times per second. The flipping between buffers is what gives the illusion of grey.

The usual approach goes something like this:
  1. putSprite takes a sprite which holds data for both buffers. Some of the data is written to buffer 1, and the other data to buffer 2.
  2. The interrupt handler maintains track of which buffer is currently displayed, and flips which buffer is onscreen every time (or every couple times) it fires.
  3. When a pixel is set on only one buffer, it will be seen as grey. Set on both, it's black, and reset on both, it's white.
  4. Additional levels of grey can be done by either displaying one buffer more often than the other (say, buffer 1 stays up for two interrupts, then buffer 2 for only one), and/or adding more buffers. If n is the number of buffers, you can get 2^n-1 colors out of the display (black, white, a couple shades of grey).
Well I was thinking the first half of it would display the pixels that would be either black, light gray or white...

like if
1st 2nd
white/white = white
black/white = light gray
white/black = dark gray
black/black = black

I guess it would be too much to display both on the screen in 1 interrupt though

It would really help to have a tutorial on ports or something though, I'd like to make my own routine to copy only sections of a buffer to the screen.
There are some posts on other forums:

[TI-ASM] Understanding Greyscale:
http://www.junemann.nl/maxcoderz/viewtopic.php?f=5&t=2692

newmask:
http://www.junemann.nl/maxcoderz/viewtopic.php?t=1668

To see some code check RGP in Revsoft by Jim e.
The buffers can be arranged many ways... Normally the first buffer is the "dark layer" and the second the "ligth layer" buffer.
Thanks for the link. I think I understand it better now. Also I posted the code I just wrote and would like to know if it would work.

The data is stored like this -
byte1buf1, byte1buf2,byte2buf1, byte2buf2 ect
lindenk wrote:
Thanks for the link. I think I understand it better now. Also I posted the code I just wrote and would like to know if it would work.

The data is stored like this -
byte1buf1, byte1buf2,byte2buf1, byte2buf2 ect
I doubt it, I see a whole set of problems or things that need clarification for me to understand what exactly you're trying to do. (1) Why do you xor the contents meant for buf1 with those meant for buf2? (2) Why is there only one inc hl; don't you need a second one at the end of each deflong routine? (3) Can you explain what c, d, and e are for? I see in total each bit location has two 1s and one 0, but the purpose is escaping me. Is that some kind of flicker prevention?
whoops, i did forget an inc hl.

the first buffer xors with the second giving you all blacks and whites as 0s and grays and 1s, then and with the mask knocking out every third bit, then xor again with the second buffer to make all your blacks black, your light grays 0 unless they were effected by the mask, your dark grays 1 unless effected by the mask and your whites white

edit - c, d and e are the masks. The value loaded in them is changed every time the interrupt runs by the first part. The interrupt itself is loaded into safe ram ($858F) because I'll be swapping rom pages during the interrupt so I offset where to load the next masks by the start of the safe ram

BWDLBDLW
10101100 - first buffer
10011010 - second buffer

10101100
10011010 xor

00110110
11011011 and

00010010
10011010 xor

10001000 - first disp


10101100
10011010 xor

00110110
01101101 and

00100100
10011010 xor

10111110 - second disp


10101100
10011010 xor

00110110
10110110 and

00110110
10011010 xor

10101100 - third disp

the three displays would be

10001000
10111110
10101100
BWDLBDLW

(black = b, white = w, light = l, dark = d)
Sorry for asking for so much help but for some reason brass isnt working right...

On the second pass brass is giving me a bunch of "could not parse (invalid number)" errors for about half of my code including all of my off page and system calls.....

Edit:

Please, I desperately need help. I've been working on this for like 2 weeks straight and just want get it over with at this point. I have no clue where to go from here; almost every time I'm ready to compile and assemble something, whatever assembler I use just doesn't work correctly...

I just need someone to tell me how to turn this -
http://www.datafilehost.com/download-e5418b3c.html
into a flash app
Sounds like there might be a problem with the bcalls. Check the ti83plus.inc file and see how it defines bcalls (some versions say b_call)
I checked it and its defined as bcall
the error I'm getting is for rst28h(which means it defined the macro) and almost every other number or register used for a command.

I haven't fixed my relative jump errors yet because I can barely read them through other errors but a few of them don't make sense, some say they would be offset by almost 24k when the label is only a few bytes away
Do you have the proper .org directive? Are you defining the correct architecture (z80 or tasm80)?
My .org is at $4000 and I've tried both tasm80.tab and the default for brass and they both give me the same errors. Now my off page calls work but its giving me an error for every command that uses hl or a

Heres a small bit of what I'm getting -



Error: Could not parse expression 'a,64' (Invalid number). [XSummoner.z80:281]
Error: Could not parse expression 'a,80' (Invalid number). [XSummoner.z80:291]
Error: Could not parse expression 'a' (Invalid number). [XSummoner.z80:297]
Error: Could not parse expression 'a,128' (Invalid number). [XSummoner.z80:304]
Error: Could not parse expression 'a' (Invalid number). [XSummoner.z80:312]
Error: Could not parse expression 'a,64' (Invalid number). [XSummoner.z80:319]
Error: Could not parse expression 'a' (Invalid number). [XSummoner.z80:327]
Error: Could not parse expression 'a,64' (Invalid number). [XSummoner.z80:334]
Error: Could not parse expression 'a,2' (Invalid number). [XElementist.z80:15]
Error: Could not parse expression 'a,2' (Invalid number). [XElementist.z80:17]
Error: Could not parse expression 'a,10' (Invalid number). [XElementist.z80:30]
Error: Could not parse expression 'a,5' (Invalid number). [XElementist.z80:31]
Error: Could not parse expression 'a' (Invalid number). [XElementist.z80:107]
Error: Could not parse expression 'a' (Invalid number). [XElementist.z80:121]
Error: Could not parse expression 'a,30' (Invalid number). [XElementist.z80:146]

Error: Could not parse expression 'a,50' (Invalid number). [XElementist.z80:161]

Error: Could not parse expression 'a' (Invalid number). [XElementist.z80:169]
Error: Could not parse expression 'a,77' (Invalid number). [XElementist.z80:176]

Error: Could not parse expression 'a' (Invalid number). [XElementist.z80:184]
Error: Could not parse expression 'a,77' (Invalid number). [XElementist.z80:191]

Error: Could not parse expression 'a' (Invalid number). [XElementist.z80:199]
Error: Could not parse expression 'a,77' (Invalid number). [XElementist.z80:206]

Error: Could not parse expression 'a,50' (Invalid number). [XElementist.z80:216]

Error: Could not parse expression 'a' (Invalid number). [XElementist.z80:226]
Error: Could not parse expression 'hl' (Invalid number). [XElementist.z80:226]
Error: Could not parse expression 'a' (Invalid number). [XElementist.z80:231]
Error: Could not parse expression 'hl' (Invalid number). [XElementist.z80:231]
Error: Could not parse expression 'a' (Invalid number). [XElementist.z80:236]
Error: Could not parse expression 'hl' (Invalid number). [XElementist.z80:236]
Pass 2 complete. (15671ms).
Errors: 595, Warnings: 11.
Build failed.

C:\Documents and Settings\Compaq_Owner\Desktop\Fightmode3 code>
I've debugged every error other than the ones in my last post. I have no clue what to do now...
Check instruction syntaxes? (SUB and ADD are "strange" sometimes)

This may seem ridiculous, but maybe you should try putting a space between the comma and the number?
  
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
Page 1 of 2
» 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

 

Advertisement