Author Topic: Streamlined Asm routines  (Read 8901 times)

0 Members and 1 Guest are viewing this topic.

Offline ACagliano

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 919
  • Rating: +32/-2
    • View Profile
    • ClrHome Productions
Streamlined Asm routines
« on: October 10, 2011, 10:14:06 am »
I need a couple asm routines. They are for a program I am working on. They are as follows. The data the routine reads will be pushed onto the stack. Assuming you pop into hl:

1. Render a circle onto the screen
hl = time to wait, after rendering element, before moving on
hl + 1 = circle center x coord
hl + 2 = circle center y coord
hl + 3 = radius

2. Render a white rectangle with black border onto screen
hl = time to wait, after rendering element, before moving on
hl + 1 = x of upper left corner
hl + 2 = y of upper left corner
hl + 3 = width
hl + 4 = height

3. Render text onto the screen
hl = time to wait...
hl + 1 = x to start display
hl + 2 = y to start display
hl + 3 = width of text display (in chars)
hl + 4 = zero t'ded string

4. Render sprite onto screen
hl = time to wait...
hl + 1 = x to start
hl + 2 = y to start
hl + 3 = width
hl + 4 = height
hl + 5 = sprite data

Any help would be great.

Offline thepenguin77

  • z80 Assembly Master
  • LV10 31337 u53r (Next: 2000)
  • **********
  • Posts: 1594
  • Rating: +823/-5
  • The game in my avatar is bit.ly/p0zPWu
    • View Profile
Re: Streamlined Asm routines
« Reply #1 on: October 10, 2011, 10:53:14 am »
While I'm not necessarily going to write the routines for you (I've already written quite a few) here's how I would go about writing them:

1. I know my house might get bombed for this, but honestly, the only way I can see to do this would be to check out how Axe does it. Axe draws perfect circles very quickly and if I needed a circle routine, I would just copy axe's.

2. This one has actually been done for you, bcall(_DrawRectBorderClear) draws a rectangle with a white inner section. (Page 142 if your browser doesn't redirect you)

3. If you mean just draw text, then bcall(_vPutS) is your routine. But, if you mean draw text within a certain boundary area, bcall(_SFont_Len) will tell you how long an individual letter is. From there, you can draw the letters 1 by 1 with bcall(_vPutMap) and start a new line whenever you run out of space. (bcall(_SFont_Len) is on page 47 of that pdf I linked above)

4. There are so many sprite rendering routines, there's no need to make a new one. Here is a page for 8-bit wide sprites and here is a page for 16-bit wide sprites. However, if you want just a single routine to do all of your sprites no matter how big they are, this is your routine. Of course, picking one of the smaller ones would be faster than this though.


As for the delays, your best bet is to make a single delay routine and call it.  In all honesty this routine right here is probably all you need:
Code: [Select]
Delay:
dec hl
ld a, h
or l
jr nz, delay
ret
zStart v1.3.013 9-20-2013 
All of my utilities
TI-Connect Help
You can build a statue out of either 1'x1' blocks or 12'x12' blocks. The 1'x1' blocks will take a lot longer, but the final product is worth it.
       -Runer112

Offline ACagliano

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 919
  • Rating: +32/-2
    • View Profile
    • ClrHome Productions
Re: Streamlined Asm routines
« Reply #2 on: October 10, 2011, 01:30:43 pm »
Quote
1. I know my house might get bombed for this, but honestly, the only way I can see to do this would be to check out how Axe does it. Axe draws perfect circles very quickly and if I needed a circle routine, I would just copy axe's.

Ok. Will do.

Quote
2. This one has actually been done for you, bcall(_DrawRectBorderClear) draws a rectangle with a white inner section. (Page 142 if your browser doesn't redirect you)

Awesome. Thanks.

Quote
3. If you mean just draw text, then bcall(_vPutS) is your routine. But, if you mean draw text within a certain boundary area, bcall(_SFont_Len) will tell you how long an individual letter is. From there, you can draw the letters 1 by 1 with bcall(_vPutMap) and start a new line whenever you run out of space. (bcall(_SFont_Len) is on page 47 of that pdf I linked above)

Yeah, I'll be drawing text of the small font within a boundary area.

Quote
4. There are so many sprite rendering routines, there's no need to make a new one. Here is a page for 8-bit wide sprites and here is a page for 16-bit wide sprites. However, if you want just a single routine to do all of your sprites no matter how big they are, this is your routine. Of course, picking one of the smaller ones would be faster than this though.

I need one routine to draw sprites of different sizes. Thanks.

Quote
As for the delays, your best bet is to make a single delay routine and call it.  In all honesty this routine right here is probably all you need:
Code: [Select]
Delay:
dec hl
ld a, h
or l
jr nz, delay
ret

Yeah. I think I can handle that. How many 'nop' or 'halt' cycles would equal 1 second, in fast mode?

Offline thepenguin77

  • z80 Assembly Master
  • LV10 31337 u53r (Next: 2000)
  • **********
  • Posts: 1594
  • Rating: +823/-5
  • The game in my avatar is bit.ly/p0zPWu
    • View Profile
Re: Streamlined Asm routines
« Reply #3 on: October 10, 2011, 02:44:39 pm »
Yeah. I think I can handle that. How many 'nop' or 'halt' cycles would equal 1 second, in fast mode?

For nops, you need whole heck of a lot. Each nop takes 4 t-states. And you figure the median calculator is running at 15,500,000 t-states per second so... 3.7 million nops.

If you want to use instructions to slow down your program, here's a routine you can use:
Code: [Select]

;hl = milliseconds of delay

milliDelay:
ld b, 174 ;7
innerLoop:
ex (sp), hl    ;19*174 ;3306
ex (sp), hl    ;19*174 ;3306
ex (sp), hl    ;19*174 ;3306
ex (sp), hl    ;19*174 ;3306
djnz innerLoop   ;13*173+8 ;2257

dec hl ;6
ld a, h ;4
or l ;4
jr nz, milliDelay ;13
ret ;15,515

Halts work entirely different though. Halts wait for an interrupt and the interrupts run at a constant speed. That speed is 118 Hz on an 83+ and 107.79 Hz on everything else. But since you said you're running in fast mode, clearly you are not on an 83+ so you would need 108 halts to wait for one second.


(I said "median" calculator up above because calculators run anywhere from 14.5 MHz to 17.0 MHz in fast mode)
zStart v1.3.013 9-20-2013 
All of my utilities
TI-Connect Help
You can build a statue out of either 1'x1' blocks or 12'x12' blocks. The 1'x1' blocks will take a lot longer, but the final product is worth it.
       -Runer112

Offline ACagliano

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 919
  • Rating: +32/-2
    • View Profile
    • ClrHome Productions
Re: Streamlined Asm routines
« Reply #4 on: October 10, 2011, 10:03:21 pm »
Yeah. I think I can handle that. How many 'nop' or 'halt' cycles would equal 1 second, in fast mode?

For nops, you need whole heck of a lot. Each nop takes 4 t-states. And you figure the median calculator is running at 15,500,000 t-states per second so... 3.7 million nops.

If you want to use instructions to slow down your program, here's a routine you can use:
Code: [Select]

;hl = milliseconds of delay

milliDelay:
ld b, 174 ;7
innerLoop:
ex (sp), hl    ;19*174 ;3306
ex (sp), hl    ;19*174 ;3306
ex (sp), hl    ;19*174 ;3306
ex (sp), hl    ;19*174 ;3306
djnz innerLoop   ;13*173+8 ;2257

dec hl ;6
ld a, h ;4
or l ;4
jr nz, milliDelay ;13
ret ;15,515

Halts work entirely different though. Halts wait for an interrupt and the interrupts run at a constant speed. That speed is 118 Hz on an 83+ and 107.79 Hz on everything else. But since you said you're running in fast mode, clearly you are not on an 83+ so you would need 108 halts to wait for one second.


(I said "median" calculator up above because calculators run anywhere from 14.5 MHz to 17.0 MHz in fast mode)


Well, this may be the delay I utilize. Let me clarify...by "fast mode" I mean that I have opened the program with this...

Code: [Select]

in a,($2E)              ;initialize faster processing
push af
ld a,0
out ($2E),a
call Start              ;jump to main program. the main program will return here when 'ret' is called
pop af
out ($2E),a
ret

Offline thepenguin77

  • z80 Assembly Master
  • LV10 31337 u53r (Next: 2000)
  • **********
  • Posts: 1594
  • Rating: +823/-5
  • The game in my avatar is bit.ly/p0zPWu
    • View Profile
Re: Streamlined Asm routines
« Reply #5 on: October 10, 2011, 10:22:20 pm »
Oh, well, that's not really fast mode. Doing that will get you a 15% speed increase in the best case scenario, and that scenario is that you are running from flash in 15Mhz mode.

Port ($2E) is actually just a delay port that TI added. What it does is it takes away the 1 t-states per read from flash delay that TI added. Furthermore, it's effects are only seen if you are running in 15 Mhz mode, it has no effect in 6Mhz mode. (Unless you do some other stuff. Check WikiTI for the full interaction between ports 29, 2A, 2B, and 2E.)

This code however:
Code: [Select]
ld a, 3
out ($20), a

Will make the calculator run 250% faster. This is all it takes to put the calculator into 15Mhz mode. In all honesty, you really don't even need your code. The only reason you might need it is if you are running a very time-sensitive app. But, since you know about it, you might as well zero port ($2E) anyways. Also, you are 100% allowed to leave port ($20) at 03 (default 00) because the OS is going to throw it in 03 when you return anyways. Leaving port ($2E) at 00 should be fine as well ;)
zStart v1.3.013 9-20-2013 
All of my utilities
TI-Connect Help
You can build a statue out of either 1'x1' blocks or 12'x12' blocks. The 1'x1' blocks will take a lot longer, but the final product is worth it.
       -Runer112

Offline ACagliano

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 919
  • Rating: +32/-2
    • View Profile
    • ClrHome Productions
Re: Streamlined Asm routines
« Reply #6 on: October 11, 2011, 07:14:50 pm »
Code: [Select]
;hl = milliseconds of delay

milliDelay:
ld b, 174 ;7
innerLoop:
ex (sp), hl    ;19*174 ;3306
ex (sp), hl    ;19*174 ;3306
ex (sp), hl    ;19*174 ;3306
ex (sp), hl    ;19*174 ;3306
djnz innerLoop   ;13*173+8 ;2257

dec hl ;6
ld a, h ;4
or l ;4
jr nz, milliDelay ;13
ret ;15,515

What would I do if hl is in seconds, rather than milliseconds? And, actually, my code holds the number of seconds to delay in 'a'.
« Last Edit: October 11, 2011, 07:16:43 pm by ACagliano »

Offline AngelFish

  • Is this my custom title?
  • Administrator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 3242
  • Rating: +270/-27
  • I'm a Fishbot
    • View Profile
Re: Streamlined Asm routines
« Reply #7 on: October 11, 2011, 07:18:16 pm »
Multiply hl by 1000 to turn it into milliseconds. If you don't need all of the precision, leftshifting hl by 10 is approximately the same.
∂²Ψ    -(2m(V(x)-E)Ψ
---  = -------------
∂x²        ℏ²Ψ

Offline ACagliano

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 919
  • Rating: +32/-2
    • View Profile
    • ClrHome Productions
Re: Streamlined Asm routines
« Reply #8 on: October 11, 2011, 07:20:50 pm »
Multiply hl by 1000 to turn it into milliseconds. If you don't need all of the precision, leftshifting hl by 10 is approximately the same.

Can I use a for this, rather than hl? And what routines can I use to draw a line between two pixel coords?
« Last Edit: October 11, 2011, 07:48:28 pm by ACagliano »

Offline ralphdspam

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 841
  • Rating: +38/-1
  • My name is actually Matt.
    • View Profile
Re: Streamlined Asm routines
« Reply #9 on: October 11, 2011, 08:15:28 pm »
Can I use a for this, rather than hl?
Code: [Select]
;a = milliseconds of delay
milliDelay:
ld b, 174 ;7 <-Increase this for larger delay increments.
innerLoop:
ex (sp), hl    ;19*174 ;3306
ex (sp), hl    ;19*174 ;3306
ex (sp), hl    ;19*174 ;3306
ex (sp), hl    ;19*174 ;3306
djnz innerLoop   ;13*173+8 ;2257

dec a ;4
nop
nop ;Left here to keep similar timing.
jr nz, milliDelay ;13
ret ;15,515

Or you can use A as the high byte of HL
Code: [Select]
;a = high byte of milliseconds of delay
ld l, 0 ;7
ld h, a ;4
milliDelay:
ld b, 174 ;7
innerLoop:
ex (sp), hl    ;19*174 ;3306
ex (sp), hl    ;19*174 ;3306
ex (sp), hl    ;19*174 ;3306
ex (sp), hl    ;19*174 ;3306
djnz innerLoop   ;13*173+8 ;2257

dec hl ;6
ld a, h ;4
or l ;4
jr nz, milliDelay ;13
ret ;15,515
« Last Edit: October 11, 2011, 08:21:54 pm by ralphdspam »
ld a, 0
ld a, a

Offline ACagliano

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 919
  • Rating: +32/-2
    • View Profile
    • ClrHome Productions
Re: Streamlined Asm routines
« Reply #10 on: October 11, 2011, 08:21:42 pm »
Ok, now, all I have to do is figure out...right now 'a' is in milliseconds. My 'a' is in seconds.

Offline Xeda112358

  • they/them
  • Moderator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 4704
  • Rating: +719/-6
  • Calc-u-lator, do doo doo do do do.
    • View Profile
Re: Streamlined Asm routines
« Reply #11 on: October 11, 2011, 08:24:12 pm »
So if you want to delay for approximately 'a' seconds you can try this:
Code: [Select]
     ld b,107
     halt
     djnz $-1
     dec a
     jr nz,$-6
     ret
Does this help?

Offline ACagliano

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 919
  • Rating: +32/-2
    • View Profile
    • ClrHome Productions
Re: Streamlined Asm routines
« Reply #12 on: October 11, 2011, 08:25:38 pm »
So if you want to delay for approximately 'a' seconds you can try this:
Code: [Select]
     ld b,107
     halt
     djnz $-1
     dec a
     jr nz,$-6
     ret
Does this help?

What does $-6 mean? $-1?

Offline calc84maniac

  • eZ80 Guru
  • Coder Of Tomorrow
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2912
  • Rating: +471/-17
    • View Profile
    • TI-Boy CE
Re: Streamlined Asm routines
« Reply #13 on: October 11, 2011, 08:41:45 pm »
So if you want to delay for approximately 'a' seconds you can try this:
Code: [Select]
     ld b,107
     halt
     djnz $-1
     dec a
     jr nz,$-6
     ret
Does this help?

What does $-6 mean? $-1?

$ refers to the address of the current instruction. We usually use that if we're too lazy to use label names. This code is equivalent:
Code: [Select]
delayLoop:
     ld b,107
haltLoop:
     halt
     djnz haltLoop
     dec a
     jr nz,delayLoop
     ret
"Most people ask, 'What does a thing do?' Hackers ask, 'What can I make it do?'" - Pablos Holman

Offline ralphdspam

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 841
  • Rating: +38/-1
  • My name is actually Matt.
    • View Profile
Re: Streamlined Asm routines
« Reply #14 on: October 11, 2011, 08:59:02 pm »
So if you want to delay for approximately 'a' seconds you can try this:
Code: [Select]
     ld b,107
     halt
     djnz $-1
     dec a
     jr nz,$-6
     ret
Does this help?
Remember to have interrupts enabled.  ;)
ld a, 0
ld a, a