Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Runer112

Pages: 1 ... 98 99 [100] 101 102 ... 153
1486
General Calculator Help / Re: map compression
« on: February 15, 2011, 12:30:36 am »
shmibs, are you thinking of a different compression algorithm maybe? Because I'm pretty sure what you just described isn't Huffman. Huffman compression doesn't employ any tactic involving null-terminated strings of 1s. It relies on an algorithm that simply encodes more common values with smaller strings of bits and less common values with larger strings of bits, with 1s and 0s throughout. It does so by counting the number of occurrences of each value present in a set of data to give each value a "weight." Then, the two units with the smallest total "weight" are paired together, becoming a new unit with the combined weight. The two units with the smallest "weights" are continually paired together until all units have been joined into a tree with one root element. This will result in values with a higher weight being further up the tree and having been assigned a shorter bit string. Here's is an example of a finished Huffman tree that I shamelessly stole from Wikipedia, based on the string: j'aime aller sur le bord de l'eau les jeudis ou les jours impairs





Anyways, back to ralphdspam's question.

Can someone explain how to save a tree for Huffman compression? That would be helpful.

Seeing as you're asking how to save a tree, I'll go ahead assuming you already know how to make a tree like above. If not, feel free to ask how that's done, or you can read the Wikipedia article which is how I learned how Huffman coding works. :P

There may be better ways than the method I'm about to describe, but I'm not very familiar with binary heap/tree storage so I'll just explain the simplest way I could imagine!

I would code the tree starting from the top down as an array consisting of nodes and leaves. Just to clarify some terms before we continue: a node is a point on the tree that branches into two other elements, and a leaf is a terminal element that doesn't branch further. So nodes would be the circles in the above diagram, and leaves would be the ends that represent pieces of data.

I would build the tree into the array by following node branches down to leaves, and after reaching each leaf, backtracking until you reach an unvisited branch and exploring that branch. And every time you visit a node or leaf that hasn't yet been reached, assign it the next element in the array. The above tree could be navigated like so by always navigating 0-branches with priority:

Spoiler For A pretty big step-by-step table explaining how one would determine the order of elements in the array:
Step   Current location   Table so far
0nullnull
10null   0
200null   0   00
3000null   0   00   000
40000null   0   00   000   0000
500000null   0   00   000   0000   00000
6000000null   0   00   000   0000   00000   000000
700000null   0   00   000   0000   00000   000000
8000001null   0   00   000   0000   00000   000000   000001
900000null   0   00   000   0000   00000   000000   000001
100000null   0   00   000   0000   00000   000000   000001
1100001null   0   00   000   0000   00000   000000   000001   00001
120000null   0   00   000   0000   00000   000000   000001   00001
13000null   0   00   000   0000   00000   000000   000001   00001
140001null   0   00   000   0000   00000   000000   000001   00001   0001
15000null   0   00   000   0000   00000   000000   000001   00001   0001
1600null   0   00   000   0000   00000   000000   000001   00001   0001
17001null   0   00   000   0000   00000   000000   000001   00001   0001   001
1800null   0   00   000   0000   00000   000000   000001   00001   0001   001
190null   0   00   000   0000   00000   000000   000001   00001   0001   001
2001null   0   00   000   0000   00000   000000   000001   00001   0001   001   01
21010null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010
220100null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100
2301000null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000
240100null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000
2501001null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001
260100null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001
27010null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001
280101null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101
29010null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101
3001null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101
31011null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011
320110null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110
33011null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110
340111null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111
35011null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111
3601null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111
370null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111
38nullnull   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111
391null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111   1
4010null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111   1   10
41100null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111   1   10   100
421000null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111   1   10   100   1000
43100null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111   1   10   100   1000
441001null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111   1   10   100   1000   1001
45100null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111   1   10   100   1000   1001
4610null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111   1   10   100   1000   1001
47101null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111   1   10   100   1000   1001   101
4810null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111   1   10   100   1000   1001   101
491null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111   1   10   100   1000   1001   101
5011null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111   1   10   100   1000   1001   101   11
51110null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111   1   10   100   1000   1001   101   11   110
5211null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111   1   10   100   1000   1001   101   11   110
53111null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111   1   10   100   1000   1001   101   11   110   111
5411null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111   1   10   100   1000   1001   101   11   110   111
551null   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111   1   10   100   1000   1001   101   11   110   111
56nullnull   0   00   000   0000   00000   000000   000001   00001   0001   001   01   010   0100   01000   01001   0101   011   0110   0111   1   10   100   1000   1001   101   11   110   111
Man that took forever to format right...

Anyway. Once you have finished that process, the final table that you have will tell you the placement in which to fill in the real data in the real table! Yay, we're almost done! Now go through the list you came up with from the above process element by element, looking at what the bit string corresponds to in the Huffman tree. If the element is a node, encode that element in the array with the first bit being a 0 and the following bits representing the distance minus one between this element and the element containing the current bit string with an additional 1 at the end (I'll explain this later). If the element is a leaf, encode the data with the first bit being a 1 and the following bits being the uncompressed data represented by that bit string. The example I've been using throughout this post would generate a table like so:

Data is represented as 8 bits in the form of [Type bit]:[Data], so the actual data would be 7 bits. A number for [Data] means these 7 bits should be the binary representation of the number, which will be added to the table pointer if the current table entry is of this type and the bit read is a 1. This, along with the mandated pointer+1 every iteration, will simulate a jump to the 1-branch of the node. A symbol for [Data] means the 7 bits should be the ASCII value of the symbol (disregarding the high bit, because none of our ASCII characters have this bit set anyway)

Offset in table:   0      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      
Data at location:   0:190:90:70:50:30:11:b1:p1:j1:u1:space0:50:30:11:'1:m1:r0:11:a1:i0:50:30:11:o1:d1:e0:11:l1:s

The decompressor can then decompress the data stream by repeating the following steps for each compressed value:
  • Set a variable indicating the length, in number of bits, of the data stream
  • Set a variable to point to the start of the table
  • Halt decompression if bits left to read equals zero
  • Check the table entry currently pointed to
  • If the first bit is a 1, pull out and handle uncompressed data from current table entry, and then jump back to the second step
  • (The first bit is a 0) Read a bit from the data stream and decrease the variable containing the number of bits left to read
  • If the bit read is a 1, add the value of the current table entry to the table pointer
  • Increase the table pointer by 1 entry
  • Jump back to the third step





And that's it! Wasn't that simple? ;D

But I'm sure that was confusing as hell, so please ask me what I mean by something if you get confused by any of this.

1487
Axe / Re: Full-Byte Tilemapping
« on: February 14, 2011, 01:40:27 am »
I was thinking about that, but for some reason I thought it was a scrolling tilemapper and that that wouldn't work. But you're right, that's smaller and faster, so I've adjusted my code for that.

1488
Axe / Re: Full-Byte Tilemapping
« on: February 14, 2011, 01:35:30 am »
By the way, loops like these:
:18While -1->X
:12While -1->Y

Will break as soon as the variable becomes 0, so a row and column of sprites would be missing.

Also, you using Pt-Off() to draw a 5*5 tilemap could (in this case will) overwrite already drawn tiles as it draws other tiles, so it's best (and faster anyways) to use Pt-On().


Here's the code I would use. It's size-optimized, but is still also quite speed-optimized, too.

Code: [Select]
Lbl MAP
  ClrDraw
  12*18+L₁→Z
  12*256
  Repeat 0
    -256→Y
    18
    Repeat 0
      -1→X
      Pt-On(*5,{°Y+1}ʳ*5,{Z-1→Z}*16+Pic1)
    End!If X
  End!If Y
  StorePic
Return

EDIT: 432 cycles saved with some pretty sweet high/low byte abuse of Y.

1489
Axe / Re: The Optimization Compilation
« on: February 13, 2011, 11:59:10 pm »
If you are pixel testing a constant pixel, like pxl-Test(20,20), you can more than halve the speed of this command with the following optimization:
Code: [Select]
{20*12+L6+2}e4

Remember, storing or recalling two-byte values at a constant address is always smaller and faster than storing or recalling one-byte values!
Code: [Select]
{20*12+L₆+2}ʳe4

Is using Rect( to draw straight horizontal/vertical lines faster than Line( ?

Definitely. Here are the results I got for vertical lines. Also note the 3 bytes saved in the Rect() arguments with some nice hl "abuses." :P
  • Line(A,0,A,63): ~6132 cycles
  • Rect(A,0,+1,-2): ~3354 cycles

The results are even more profound for horizontal lines. Also, 1 byte saved in the Rect() arguments.
  • Line(0,A,95,A): 9809 cycles
  • Rect(0,A,-1,+2): 2579 cycles

But if you really want a blazingly fast horizontal line drawer in pure Axe, use the following. It has a check to make sure that the y-value is valid, and if so, the whole process of calling the routine, checking the y-value, and drawing the line takes only 497 cycles. You would call it with something like Ysub(HL). Also, note the trick employed to check that the y-value is less than 64. That saves a few bytes and cycles over a normal comparison by utilizing the fact that we want a value precisely in the 6-bit range. By simply resetting these 6 bits and leaving any other bits unchanged, any 6-bit values will become zero and any out of range values will become nonzero, resulting in easy checking.
Code: [Select]
Lbl HL
  →r₆
  ReturnIf and b11000000
  ᴇFFFF→{r₆*12+L₆}ʳ
  Fill(,10)
Return

1490
Axe / Re: Documentation of the Speed and Size of (Almost) Every Axe Command
« on: February 13, 2011, 05:33:38 pm »
Attached an updated file for version 0.5.0 to the original post.

1491
Axe / Re: Axe Q&A
« on: February 12, 2011, 11:56:36 pm »
Yes, that would work. Although it would be more optimized as follows, because multiplying by 3 is an optimized calculation:

B>C*3+A→A


EDIT: And yes, multiplying by negative 1 negates the number as you would expect. Remember that the result is only treated as negative if you use a signed comparison or something else that uses signed numbers. Otherwise as far as the processor knows it's just a really big positive number. -6 is just 65530 interpreted differently.

1492
The Axe Parser Project / Re: Assembly Programmers - Help Axe Optimize!
« on: February 06, 2011, 08:45:09 pm »
:-[ It looks like yet another error has been discovered with my attempts to optimize things. The nibble retrieval routines and the nibble storage routine that I posted treat low and high nibbles in opposite ways. I'm pretty sure that the nibble retrieval routines are backwards and that the conditional jr c jumps should be changed to jr nc.

1493
Axe / Re: The Optimization Compilation
« on: February 05, 2011, 11:53:46 pm »
Epic. I love return'd value hacks :D

My favorite Axe optimization trick! ;D


:crazy: That's amazing, Runer. Do you always come up with code like this? :P

I am so familiar with using optimized loops that I pretty much automatically come up with maximally optimized loops. ;) The rest of the stuff, though, just takes a bit of thinking and comparing potential command sizes/speeds. This file I assembled a while ago actually helps a good deal when assessing options.

1494
Axe / Re: The Optimization Compilation
« on: February 05, 2011, 11:46:14 pm »
Here's the fastest code I could come up with. It uses optimized loop structures and even more pre-calculation.

Also, did you mean to use B as the y value in your code squidgetx? Because looping from 0-11 wouldn't make much sense for y, so I changed it. :P

Code: (Code) [Select]
Y and ᴇF8*2+(X/2/2/2)+L₁→D
⁻(X^8)→I
⁻(Y^8)→J
12→B
Lbl LB
  64
  Lbl LA
    →A
    If {*2+B+D}
      →C
      Pt-On(B*8+I,A+J,C*8+Pic0)
    End
  If A
    -8
    Goto LA
  End
If {°B-1}ʳ
  -256→{°B-1}ʳ
  Goto LB
End

   
Code: (Comments) [Select]
Tilemap offset; optimized version of Y/8*16+(X/8)+L₁→D
X offset;
Y offset
For(B,12,0,⁻1)

For(A,64,0,⁻8)


If tile != 0
Store tile value
Display tile

Second part of For(A) loop



Second part of For(B) loop
Utilizes the fact that the second byte of A is 0 and -256 is faster than -1





1495
The Axe Parser Project / Re: Bug Reports
« on: February 03, 2011, 03:34:39 pm »
Hopefully somebody notices it here...I'm pretty sure it's an axe bug b/c pretty much the exact same thing worked before (in TWHG).  Ever since I've updated to Axe 0.4.8, I've been having one problem after another of this nature, also with some problems with RotC( and RotCC( which didn't work when I tried to use them.
So, I was wondering...what changed?  Because data storage to lists and external appvars wasn't failing like this before, and now it fails more often than it works. ???

After close inspection, I noticed a few things that could be causing problems in the code you posted. Firstly, the End:If {L1+D}=2 in subroutine D should just be replaced with an Else. Otherwise, the first if statement may activate and change {L1+D} to 2, thus also activating the following if statement, effectively negating the change you want. The other problem I noticed is that the data isn't being generated correctly for how you step through it later. To generate the data, you loop through Y values inside of a loop through X values, thus making X the "major" direction. However, in all other places in your program, you assign Y as the "major" direction. You should change the data generation code so the X loop is inside of the Y loop. Hopefully these two things will solve your problems!

I also can explain the bugs in Axe 0.4.8 with rotC() and rotCC(), as those are my fault. I supplied Quigibo with optimized routines for them, but neither of us noticed until it was too late that the code had a slight fault. Instead of returning the pointer to the rotated sprite, they return the pointer plus eight. For a temporary fix you can add -8 after any rotate commands in Axe 0.4.8. Hopefully this problem will be fixed in the next version though, so if it is, make sure to get rid of any -8's that you may have added.

Quigibo: If you're reading this and haven't already fixed the rotate problem, I posted the corrected code a while back here.

1496
The Axe Parser Project / Re: Axe Parser
« on: February 02, 2011, 11:23:19 pm »
Want these? They were for the InsertMem/DelMem axiom I made a short while ago, so if you're making VAT commands, they could be useful to you. I didn't heavily test them, but they looked pretty good to me.


Code: (InsertMem) [Select]
;---------> InsertMem <---------;
;B_CALL(_InsertMem) with checks to make sure there is enough RAM and the insertion address is okay
;
;INPUTS: Arg1: Pointer to start of variable according to GetCalc()
; Arg2: Offset in variable to insert RAM
; Arg3: Number of bytes to attempt to insert
;
;OUTPUTS: 0 if not enough RAM or Arg2 is out of range
; Nonzero if successful

p_InsertMem:
;REGISTERS: hl=Arg3
;STACK: | Ret | Arg2 | Arg1 | ...
B_CALL(_EnoughMem) ;Check if enough RAM
;REGISTERS: de=Arg3
;STACK: | Ret | Arg2 | Arg1 | ...
pop hl ;Rearrange arguments and stack
pop bc
ex (sp),hl
;REGISTERS: bc=Arg2 de=Arg3 hl=Arg1
;STACK: | Ret | ...
jr c,__InsertMemFail0Args ;Return failure if not enough RAM
dec hl ;Get current variable size
ld a,(hl)
dec hl
push hl
ld l,(hl)
ld h,a
;REGISTERS: bc=Arg2 de=Arg3 hl=current variable size
;STACK: | Arg1-2 | Ret | ...
sbc hl,bc ;Check if offset is outside of variable
jr c,__InsertMemFail1Arg ;Return failure if offset is outside of variable
add hl,bc
;REGISTERS: bc=Arg2 de=Arg3 hl=current variable size
;STACK: | Arg1-2 | Ret | ...
add hl,de ;Calculate final variable size
ex de,hl
ex (sp),hl
;REGISTERS: bc=Arg2 de=final variable size hl=Arg1-2
;STACK: | Arg3 | Ret | ...
ld (hl),e ;Store final variable size
inc hl
ld (hl),d
inc hl
;REGISTERS: bc=Arg2 de=final variable size hl=Arg1
;STACK: | Arg3 | Ret | ...
add hl,bc ;Calculate RAM insertion address
ex de,hl ;Prepare arguments for _InsertMem
pop hl
;REGISTERS: bc=Arg2 de=Arg1+Arg2 (RAM insertion address) hl=Arg3 (bytes to insert)
;STACK: | Ret | ...
B_CALL(_InsertMem) ;Insert memory
;REGISTERS: de=RAM insertion address hl=a lot (negative size of a VAT entry?)
;STACK: | Ret | ...
ret ;Result is always nonzero
__InsertMemFail1Arg:
pop hl
__InsertMemFail0Args:
ld hl,0
ret
__InsertMemEnd:

Code: (DelMem) [Select]
;---------> DelMem <---------;
;B_CALL(_DelMem) with checks to make sure that the deletion address and size are okay
;
;INPUTS: Arg1: Pointer to start of variable according to GetCalc()
; Arg2: Offset in variable to delete RAM
; Arg3: Number of bytes to attempt to delete
;
;OUTPUTS: 0 if Arg2+Arg3 is out of range
; Nonzero if successful

p_DelMem:
;REGISTERS: hl=Arg3
;STACK: | Ret | Arg2 | Arg1 | ...
pop af ;Rearrange arguments and stack
pop bc
pop de
push af
push hl
;REGISTERS: bc=Arg2 de=Arg1 hl=Arg3
;STACK: | Arg3 | Ret | ...
add hl,bc ;Calculate offset of end of deletion
jr c,__DelMemFail ;Return failure if offset+size was so big that it overflowed
ex de,hl
;REGISTERS: bc=Arg2 de=Arg2+Arg3 hl=Arg1
;STACK: | Arg3 | Ret | ...
dec hl ;Get current variable size
ld a,(hl)
dec hl
push hl
ld l,(hl)
ld h,a
;REGISTERS: bc=Arg2 de=Arg2+Arg3 hl=current variable size
;STACK: | Arg1-2 | Arg3 | Ret | ...
sbc hl,de ;Check if end is outside of variable
pop de ;Early pop to avoid having fail condition requiring 2 pops
;REGISTERS: bc=Arg2 de=Arg1-2 hl=current variable size - (Arg2+Arg3)
;STACK: | Arg3 | Ret | ...
jr c,__DelMemFail ;Return failure if end is outside of variable
add hl,bc ;Add back offset to get final variable size
;REGISTERS: bc=Arg2 de=Arg1-2 hl=final variable size
;STACK: | Arg3 | Ret | ...
ex de,hl ;Store final variable size
ld (hl),e
inc hl
ld (hl),d
inc hl
;REGISTERS: bc=Arg2 de=final variable size hl=Arg1
;STACK: | Arg3 | Ret | ...
add hl,bc ;Calculate RAM deletion address
pop de ;Prepare size argument for _DelMem
;REGISTERS: bc=Arg2 de=Arg3 (bytes to delete) hl=Arg1+Arg2 (RAM deletion address)
;STACK: | Ret | ...
B_CALL(_DelMem) ;Delete memory
;REGISTERS: de=Arg3 (bytes to delete) hl=a lot (negative size of a VAT entry?)
;STACK: | Ret | ...
ret ;Result is always nonzero
__DelMemFail:
pop hl
ld hl,0
ret
__DelMemEnd:

1497
TI Z80 / Re: Online Z80 Table
« on: February 02, 2011, 04:51:18 pm »
If you look at the CLASS column in TASM80.TAB, you will see that IN0 and OUT0 are class 2 instructions. Class 2 instructions aren't available on the z80 processors found in TI calculators, so adding them would probably just cause confusion with people wondering why they don't work. Although it would be nice if they were and we could use such class 2 instructions as TST and MLT, unfortunately we can't.

1498
News / Re: Z80 to HEX conversion and vice-versa now available on IRC
« on: January 28, 2011, 01:36:24 am »
Just wanted to let everyone know how mine works, since it's not really explained anywhere. It has become quite a massive project. :o

To use it, you can either enter your queries into OmnomIRC right on the forums or through a normal IRC client. If you use the latter, you can also /msg me with your queries. Anyways, to use this, start a message with one of the following: .z80, !z80, or @z80. After this, you can then enter one of four things for different effects:

  • Enter the hex for an instruction to see detailed information about the instruction (mnemonic, hex, bytes, cycles, flag effects, and description)
  • Enter the mnemonic for an instruction to see detailed information about the instruction
  • Enter the hex for multiple instructions to receive disassembled mnemonics
  • Enter the mnemonics for multiple instructions separated by backslashes to receive compiled hex (Note that backslashes work oddly in OmnomIRC and require about five of them in a row to be entered)

I believe this should support every instruction on the z80, including all undocumented instructions and bcalls. I'm particularly proud of my recent number handling system for assembling code, as it supports all equates defined in ti83plus.inc and math functions like a real assembler! ;D


If you notice any bugs or have any other feedback, please tell me! And if you use it heavily in a short period of time and it stops responding to you, that's not a bug, that's flood control. :P If you're using an IRC client, you can avoid flood control by /msg'ing me with as many queries as you want.




EDIT: Examples of the four main ways to use this. If you're using OmnomIRC, the bot will always respond publicly like in the first example. If you're an IRC user, you have a few more options.

You enter: @z80 CB30
I respond: <Runer112> [Z80] Instruction \ Main: sll reg8 \ Instance: sll b [CB30]\ Bytes: 2 \ Cycles: 8/15 \ Flags: SZ-0-P0C \ Undocumented \ Description: The contents of reg8 are shifted left one bit position. The contents of bit 7 are put into the carry flag and a one is put into bit 0.

You enter: .z80 jr nz,$-14
I respond: -Runer112- [Z80] Instruction \ Main: jr cc,ofs8 \ Instance: jr nz,$-14 [20F0] \ Bytes: 2 \ Cycles: 12/7 \ Flags: -------- \ Description: If condition cc is true, the signed value imm8 is added to pc. The jump is measured from the start of the instruction opcode.

You enter: !Z80 E3EF9247218384D1010900EDB0
I respond: -Runer112- [Z80] Disassembly \ http://z80.pastebin.com/D0SRU5X5 \ ex (sp),hl \ B_CALL(_SetXXXXOP2) \ ld hl,$8483 \ pop de \ ld bc,$0009 \ ldir

You enter: /msg Runer112 .Z80 B_CALL(_RunIndicOn) \ set donePrgm,(iy+doneFlags) \ ret \ .db 19,$37,%10101010,plotSScreen % 256 >> (7/2)
I respond in a private message: <Runer112> [Z80] Assembly \ http://z80.pastebin.com/KDbM1xHq \ EF6D45FDCB00EEC91337AA08

1499
Axe / Re: The Optimization Compilation
« on: January 24, 2011, 09:15:05 pm »
If you only need to initialize five or fewer 2-byte values like variables, it is best to initialize them without any special commands. With this method, you can also avoid changing the values of any memory locations that you don't want to initialize between values you do want to initialize.

Code: (18 bytes) [Select]
0→A→B→X→Y→{L₁}ʳ


However, if you need to initialize more than five values, it is best to use the Fill() method, like you suggested for zeroing out every variable. However, a few slight changes:
  • Storing 2 bytes to a constant address (e.g. °A) is more optimized than storing 1 byte.
  • Because of the above modification and the first two bytes now being equal to 0, the start address for Fill() can be increased by 1 (e.g. °A+1) to save some clock cycles by reducing the total number of bytes needed to be filled by 1.
  • There are only 27 variables, for a total of 54 bytes. Subtracting 1 for the above reason and 1 more due to the fact that the size argument of Fill() doesn't count the starting byte gives a grand total of 52 bytes to fill.

Code: (20 bytes) [Select]
0→{°A}ʳ
Fill(°A+1,52)


The above method can also be used to initialize 1-byte values by adjusting the size parameter of Fill() accordingly. Note, though, that it will only work for initializing 2-byte values whose low and high bytes are equal, like 0. To initialize six or fewer 2-byte values that do not adhere to this, use the first method mentioned in this post. To initialize more than six 2-byte values that do not adhere to this, use something like the following method. This example will initialize all 27 variables to the hex value 1337:

Code: (21 bytes) [Select]
ᴇ1337→{°A}ʳ
Copy(°A,+2,52)

1500
Axe / Re: application question
« on: January 24, 2011, 06:09:17 pm »
All of the main variables (A-θ) were moved. Because of this, L1 also no longer points to the same location. As for the other variables, I'm not sure, but my guess is that none of them were moved.

Pages: 1 ... 98 99 [100] 101 102 ... 153