<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wikidot="http://www.wikidot.com/rss-namespace">

	<channel>
		<title>z80 Heaven - new forum threads</title>
		<link>http://z80-heaven.wikidot.com/forum/start</link>
		<description>Threads in forums of the site &quot;z80 Heaven&quot; - A place for all the z80 info you&#039;ll want</description>
				<copyright></copyright>
		<lastBuildDate>Sun, 06 Sep 2026 05:15:22 +0000</lastBuildDate>
		
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-17034421</guid>
				<title>got an EEPROM, need to de-assemble</title>
				<link>http://z80-heaven.wikidot.com/forum/t-17034421/got-an-eeprom-need-to-de-assemble</link>
				<description>what tool to use to de-assemble or emul</description>
				<pubDate>Mon, 10 Feb 2025 19:05:42 +0000</pubDate>
				<wikidot:authorName>Ramon Bacardi</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Hi. I got an old board I wrote some code for, with a Z80A CPU, a SIO and a CTC.</p> <p>Program is in EEPROM (27C64) - I dumped it using a TL866 into a BIN file (have also the HEX)</p> <p>(1) what de-assembler would you recomend me to get the code in assembler format ?</p> <p>(2) is there any good &quot;emulator&quot; so I can feed the BIN and execute instructions one by one, see the register, the memory, etc ?</p> <p>Thanks. Ramon.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-16607134</guid>
				<title>Correction to PUSH descriptions</title>
				<link>http://z80-heaven.wikidot.com/forum/t-16607134/correction-to-push-descriptions</link>
				<description>The stack pointer is decremented, not incremented.</description>
				<pubDate>Thu, 04 Jan 2024 09:04:12 +0000</pubDate>
				<wikidot:authorName>Andrew Potts</wikidot:authorName>				<wikidot:authorUserId>8968302</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Hi. Firstly, great Website, very helpful!</p> <p>Just a note on the PUSH descriptions - shouldn't it say the stack pointer is DEcremented by 2 bytes?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-16351572</guid>
				<title>Z80 INT pin, connected to GND</title>
				<link>http://z80-heaven.wikidot.com/forum/t-16351572/z80-int-pin-connected-to-gnd</link>
				<description>Hi! Why it is not allowed to connect INT pin to GND, so that later only use EI, DI to control interrupts? I tried to connect INT to GND. Code works until I use EI command, then it seems that execution hangs</description>
				<pubDate>Wed, 20 Sep 2023 16:43:40 +0000</pubDate>
				<wikidot:authorName>Andrei</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Using IM2 mode, jump table is correct (tested without connecting INT to GND), and I=00h.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-14037849</guid>
				<title>Anybody out there?</title>
				<link>http://z80-heaven.wikidot.com/forum/t-14037849/anybody-out-there</link>
				<description></description>
				<pubDate>Tue, 30 Mar 2021 11:38:00 +0000</pubDate>
				<wikidot:authorName>Carlos</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>I'm just curious to how dead this site is. Anyone else out there?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-14024737</guid>
				<title>Question About this Site</title>
				<link>http://z80-heaven.wikidot.com/forum/t-14024737/question-about-this-site</link>
				<description>Just wondering if this site is still active.</description>
				<pubDate>Tue, 09 Mar 2021 01:07:21 +0000</pubDate>
				<wikidot:authorName>J_Walker87</wikidot:authorName>				<wikidot:authorUserId>6818760</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Hey, I use this site to try and learn z80 asm on my Ti-83+. Just wondering if this site currently has an active community of developers centered around it.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-7498472</guid>
				<title>correction to the definition of &#039;res&#039;</title>
				<link>http://z80-heaven.wikidot.com/forum/t-7498472/correction-to-the-definition-of-res</link>
				<description></description>
				<pubDate>Sat, 15 Sep 2018 07:50:15 +0000</pubDate>
				<wikidot:authorName>Allan</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>hi there - on your site when you search for the definition of the 'RES' operator, it says 'reset the specific byte to zero'. In fact it should say 'reset the specific bit to zero'. Just thought I'd mention it as I was learning Z80 and this confused me initially.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-6450547</guid>
				<title>Compile to Assembly</title>
				<link>http://z80-heaven.wikidot.com/forum/t-6450547/compile-to-assembly</link>
				<description></description>
				<pubDate>Wed, 18 Jul 2018 01:06:16 +0000</pubDate>
				<wikidot:authorName>Benjamin Brownlee</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>I was curious if anyone is a aware of another language that can be compiled to z80 assembly and uploaded to a calculator. I know Ti-Basic exists, but (Ti-Basic is slow and limited and) I was looking for something that would be compiled once and then run on the calculator as assembly.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-5323159</guid>
				<title>What programming is this?</title>
				<link>http://z80-heaven.wikidot.com/forum/t-5323159/what-programming-is-this</link>
				<description></description>
				<pubDate>Wed, 21 Feb 2018 15:26:36 +0000</pubDate>
				<wikidot:authorName>GatoradeDC</wikidot:authorName>				<wikidot:authorUserId>3688735</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <div class="code"> <pre><code>.nolist #include &quot;ti83plus.inc&quot; .org userMem-2 .db $BB,$6D .list bcall(_RclAns) bcall(_ConvOp1) ld a,e or a jr z,Install_Interrupt dec a ret nz Uninstall_Interrupt: im 1 ret Install_Interrupt: di ld hl,$9900 ld de,$9901 ld bc,256 ld (hl),$9a ldir ld hl,interrupt_start ld de,$9a9a ld bc,interrupt_end-interrupt_start ldir ld a,$99 ld i,a im 2 ;switch to mode 2 ei ;enable interrupts ret Interrupt_Start: ex af,af' exx in a,($03) and %11111110 out ($03),a call $003A reti Interrupt_End: .end</code></pre></div> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-2518563</guid>
				<title>Z80 Address Line Functioning</title>
				<link>http://z80-heaven.wikidot.com/forum/t-2518563/z80-address-line-functioning</link>
				<description></description>
				<pubDate>Sat, 01 Jul 2017 18:16:41 +0000</pubDate>
				<wikidot:authorName>ajward</wikidot:authorName>				<wikidot:authorUserId>3218039</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Hi All! I just joined the site to hopefully gain some insight into the workings of the Z80. I'm hoping I can build a basic computer around the Z80.<br /> To this point, I've bread-boarded a circuit to verify the CPU iis functioning properly. So far this seems to be the case.<br /> The data lines are all tied low to effect a NOP instruction. All the address lines are driving LEDs through 74LS244 driver ICs.</p> <p>However, there is something that puzzles me. The address lines count up normally to 65535, but when the count passes 255 any active line from A8 through A15 flashes. The flashing is the same frequency as M1, but opposite&#8230; M1 on, A8 - A15 off and vice versa.</p> <p>I'm stumped. I've downloaded about a ream of documents on the Z80, but I'll be darned if I can see anything to unravel this. I've watched numerous videos about testing the CPU, but no one ever seems to monitor more than 4 or 5 address lines.<br /> I suppose this is normal behavior for some reason given the limited setup I'm using.</p> <p>Anyone have any thought on this? I'd be grateful!</p> <p>Amanda - Have a great 4th!<br /> (July 4th - alcohol and explosives. What could wrong?) :-)</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-2244865</guid>
				<title>Calculator Compatibility</title>
				<link>http://z80-heaven.wikidot.com/forum/t-2244865/calculator-compatibility</link>
				<description>How assembly works with newer calculators.</description>
				<pubDate>Tue, 25 Apr 2017 05:18:25 +0000</pubDate>
				<wikidot:authorName>Benjamin</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>I noticed in your basic tutorials on assembly programming that you often reference the TI-83 Plus in set-up downloads and programming but alternate paths for newer calculators are not clear. I was wondering how cross-compatible these tutorials were to newer calculators &#8212; especially the TI-84 CE &#8212; and what modifications if any were necessary to begin programming in assembly.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-2174792</guid>
				<title>Z80 Assembly - Changes to Microsoft Basic v4.7</title>
				<link>http://z80-heaven.wikidot.com/forum/t-2174792/z80-assembly-changes-to-microsoft-basic-v4-7</link>
				<description>Some questions about some changes I&#039;m trying to make to Microsoft Basic for my Z80 SBC.</description>
				<pubDate>Tue, 21 Mar 2017 21:43:46 +0000</pubDate>
				<wikidot:authorName>nockieboy</wikidot:authorName>				<wikidot:authorUserId>3020831</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Hi,</p> <p>Firstly, I haven't looked at Z80 assembly since my childhood back in the late 80's. Whilst I'm quite competent in modern languages, Z80 assembly is something I've never revisited until I recently built a Z80-based single board computer. This runs a version of NASCOM BASIC, which is itself based on Microsoft BASIC from way back in '78.</p> <p>Now I've got the computer up and running, I'm taking a break from building the next piece of hardware to add to it and instead focusing on the software for the moment. I'd like to make a few (relatively minor) changes to the BASIC interpreter running on the ROM, and in the process learn something about Z80 assembly etc.</p> <p>What I'm currently trying to do is make the error messages a little more verbose. My first computer was an Amstrad CPC464, so naturally I'm trying to make the BASIC a little more like what I'm used to (already changed the OK prompt to READY.)</p> <p>I'm hitting a problem with the error messages though. In its untouched form, the error messages are two-character bytes, like so:</p> <div class="code"> <pre><code>ERRORS: .BYTE &quot;NF&quot; ; NEXT without FOR .BYTE &quot;SN&quot; ; Syntax error .BYTE &quot;RG&quot; ; RETURN without GOSUB</code></pre></div> <p>Now the following lines of code handles printing a message:</p> <div class="code"> <pre><code>ERROR: CALL CLREG ; Clear registers and stack LD (CTLOFG),A ; Enable output (A is 0) CALL STTLIN ; Start new line LD HL,ERRORS ; Point to error codes LD D,A ; D = 0 (A is 0) LD A,'?' CALL OUTC ; Output '?' ADD HL,DE ; Offset to correct error code LD A,(HL) ; First character CALL OUTC ; Output it CALL GETCHR ; Get next character CALL OUTC ; Output it LD HL,ERRMSG ; &quot;Error&quot; message ERRIN: CALL PRS ; Output message</code></pre></div> <p>Now initially (and somewhat naively) I thought I could just change the 2-character bytes in ERRORS: from, e.g. &quot;SN&quot; to &quot;Syntax&quot; - the word &quot; Error&quot; is added after each error message. I soon realised that this wasn't working, as there's a lookup table listing the location of each error message. Once I found that, all seemed to be roses for a while. I changed the code above so that instead of printing 2 characters and then moving on, it would loop through printing characters until it hit a 0.</p> <div class="code"> <pre><code>; BASIC ERROR CODE VALUES NF .EQU 00H ; NEXT without FOR SN .EQU 02H ; Syntax error RG .EQU 04H ; RETURN without GOSUB OD .EQU 06H ; Out of DATA FC .EQU 08H ; Function call error OV .EQU 0AH ; Overflow OM .EQU 0CH ; Out of memory</code></pre></div> <p>I added a zero to the end of each message in ERRORS: and changed the 2-char message to a more verbose one (so .BYTE &quot;NF&quot; became .BYTE &quot;NEXT without FOR&quot;,0). I then amended the BASIC ERROR CODE VALUES lookup table (above) to take the length of the verbose error messages into account.</p> <p>Everything was fine for the first few error messages. I'd tested the system and it worked. So I changed the rest of the error messages and updated the lookup table. Some of the values went as high as 124H etc, and I found I had to add a 0 to the lower offsets to avoid errors in TASM. However, I then started getting other errors - unused MS data errors in lines like LD E,(OS). I suspected this was because the offset was too large for a single 8-bit register like E, so where the errors came up I changed the code to LD DE,(&lt;error msg offset label&gt;) to make use of the full 16-bit DE register.</p> <p>Obviously that didn't work - it stopped my ROM completely and locked the computer up. So, my long-winded question is winding to its conclusion - I don't currently know enough about assembly or the Z80 registers or the BASIC code I'm editing to know what I did wrong and why it was locking up the computer. I suspect this next bit of code is the culprit - taken from the message printing code further up:</p> <div class="code"> <pre><code>LD D,A ; D = 0 (A is 0) LD A,'?' CALL OUTC ; Output '?' ADD HL,DE ; Offset to correct error code</code></pre></div> <p>If the error offset is loaded into E, then the first line above doesn't mess with it. But if, after I changed it to load into DE, D is then changed by the above code snippet, then the offset is going to be corrupted. Should I just remove the LD D,A line and the two after it as I'm not bothered about having the ? mark at the start of the error message either&#8230;</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-2153480</guid>
				<title>Z80 compiler question</title>
				<link>http://z80-heaven.wikidot.com/forum/t-2153480/z80-compiler-question</link>
				<description></description>
				<pubDate>Sun, 05 Mar 2017 21:32:24 +0000</pubDate>
				<wikidot:authorName>Doug B</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>I have piece of hardware with a functioning Z80 that was first created in in early 1993. I do have the source code but no documentation. Would anyone know how many compilers there would have been in 1993 for a PC that would compile Z80? I want to be able to compile this project and make some changes to it but I have no idea what it was created with.</p> <p>Thanks,<br /> Doug</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-2128911</guid>
				<title>Read Back program memory</title>
				<link>http://z80-heaven.wikidot.com/forum/t-2128911/read-back-program-memory</link>
				<description>Retrieve code from a programmed chip?</description>
				<pubDate>Thu, 16 Feb 2017 15:31:16 +0000</pubDate>
				<wikidot:authorName>jediengineer</wikidot:authorName>				<wikidot:authorUserId>2984466</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Does anyone know how to, or has anyone successfully retrieved the program memory from a Z80 or Z80A? I have one, and would like to retrieve the code from it, not sure if it's possible or not, but because it's an older chip, I'm assuming that the failsafes we have in today's newer processors are not there.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-1930045</guid>
				<title>incremental loop in Z80</title>
				<link>http://z80-heaven.wikidot.com/forum/t-1930045/incremental-loop-in-z80</link>
				<description></description>
				<pubDate>Thu, 29 Sep 2016 20:41:58 +0000</pubDate>
				<wikidot:authorName>bruno</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>DJNZ can be used to test a counter and loop until it reaches 0, but is there an easy way to loop until a counter reaches a certain value? Like in the following C code:<br /> for (int i=0; i&lt;10;i++) {<br /> // do something with i<br /> }</p> <p>Thank you.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-1797364</guid>
				<title>Which of these is better?</title>
				<link>http://z80-heaven.wikidot.com/forum/t-1797364/which-of-these-is-better</link>
				<description>LD reg,() vs. LD HL,() / EX HL,DE</description>
				<pubDate>Wed, 17 Aug 2016 10:02:22 +0000</pubDate>
				<wikidot:authorName>Ross</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Hello,</p> <p>So what I was wondering was if there were any disadvantages/advantages when it comes to LD DE,(xxxx) and LD HL,(xxxx) / EX HL,DE</p> <p>I've used:</p> <p>LD HL,(xxxx)<br /> EX HL,DE</p> <p>to get my Data into the DE register first, followed by getting the Data HL requires last, which saves using LD DE,(xxxx). At the end of it all it appears the same amount of opcodes are used as well as clock cycles, but was wondering if anyone knows any different?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-1772643</guid>
				<title>Help to understand what the program do</title>
				<link>http://z80-heaven.wikidot.com/forum/t-1772643/help-to-understand-what-the-program-do</link>
				<description>Explain code</description>
				<pubDate>Sat, 30 Jul 2016 16:29:52 +0000</pubDate>
				<wikidot:authorName>geracole</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Hi,<br /> I have received the following code to search a place in France. The game is cistes.net.</p> <div class="code"> <pre><code>LD BC, 11 NOP LD (DE), A NOP LD BC, 22 JR (PC + 8) JR (PC + 4) ADD HL, BC DEC B JR (PC + 6) DEC B NOP LD BC, 33 LD HL, 44 NOP LD D, 6 ADD HL, BC DEC B INC B NOP INC B LD HL, 55 NOP LD (DE), A ADD HL, BC DEC B JR (PC + 8) JR (PC + 4) DEC B NOP INC B DEC B NOP LD (DE), A LD BC, 77 NOP INC BC EX AF, AF' LD BC, 88 LD D, 9 DEC B LD (DE), A LD (DE), A DEC B NOP INC D INC B NOP INC B DEC B NOP INC D ADD HL, BC DEC B LD 12, (HL) JR (PC+8) DEC B NOP LD BC, 21 NOP LD 32, (HL) LD BC, 45 LD HL, 76 INC H NOP DEC B INC D NOP LD (BC), A LD HL, 53 RLCA DEC B DEC H</code></pre></div> <br /> I have no idea what it means. <p>Please, somebody could tell me what that code do.<br /> Thanks.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-1757944</guid>
				<title>Weird Z80 behavior</title>
				<link>http://z80-heaven.wikidot.com/forum/t-1757944/weird-z80-behavior</link>
				<description>A simple NOP and JP program is responding oddly</description>
				<pubDate>Sun, 10 Jul 2016 21:24:25 +0000</pubDate>
				<wikidot:authorName>Michael Latiolais</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Ok, I have a very basic Z80 system wired up with an Arduino and some shift registers. To test, I just had the Arduino look for MREQ, RD and M1 and then write out a byte. This was originally an array, but now I'm just looking for the 1001 location and writing out a JP opcode. Since it otherwise holds everything low, it should jump back to zero, and loop. And it does this. But I'm seeing something else(the first binary number is the data, second is the address requested by the Z80):<br /> Writing: 0 from 1<br /> Writing: 0 from 10<br /> Writing: 0 from 11<br /> Writing: 0 from 100<br /> Writing: 0 from 101<br /> Writing: 0 from 110<br /> Writing: 0 from 111<br /> Writing: 0 from 1000<br /> Writing: 11000011 from 1001 &lt;&#8212; here is my JP opcode<br /> Writing: 0 from 1010 &lt;<span style="text-decoration: line-through;">first part of the address<br /> Writing: 0 from 1011 &lt;</span>second part<br /> Writing: 0 from 0 &lt;<span style="text-decoration: line-through;">YAY! It jumped back to zero like expected!<br /> Writing: 0 from 1010 &lt;</span>What is this?<br /> Writing: 0 from 1 &lt;<span style="text-decoration: line-through;">Why is the address bus incrementing two numbers?<br /> Writing: 0 from 1011<br /> Writing: 0 from 10<br /> Writing: 0 from 1100<br /> Writing: 0 from 11<br /> Writing: 0 from 1101<br /> Writing: 0 from 100<br /> Writing: 0 from 1110<br /> Writing: 0 from 101<br /> Writing: 0 from 1111<br /> Writing: 0 from 110<br /> Writing: 0 from 10000<br /> Writing: 0 from 111<br /> Writing: 0 from 10001<br /> Writing: 0 from 1000<br /> Writing: 0 from 10010<br /> Writing: 11000011 from 1001 &lt;</span>It hit the JP opcode again<br /> Writing: 0 from 10011 &lt;<span style="text-decoration: line-through;">What is this?<br /> Writing: 0 from 1010 &lt;</span> Correct<br /> Writing: 0 from 1011 &lt;&#8212; Correct<br /> Writing: 0 from 0 &lt;<span style="text-decoration: line-through;">jump is still working<br /> Writing: 0 from 10100 &lt;</span> Still counting?<br /> Writing: 0 from 1<br /> Writing: 0 from 10101<br /> Writing: 0 from 10<br /> Writing: 0 from 10110<br /> Writing: 0 from 11<br /> Writing: 0 from 10111<br /> Writing: 0 from 100</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-1340247</guid>
				<title>&quot;Hello World&quot; program not working on TI-84</title>
				<link>http://z80-heaven.wikidot.com/forum/t-1340247/hello-world-program-not-working-on-ti-84</link>
				<description>I am having some problems running my first z80 program on my calculator.</description>
				<pubDate>Fri, 28 Aug 2015 17:00:13 +0000</pubDate>
				<wikidot:authorName>FelisPhasma</wikidot:authorName>				<wikidot:authorUserId>2255661</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Hello all,<br /> I've been trying to learn z80 assembly, and run it on my calculator, but I'm doing something wrong. Here is my tasm folder contents:</p> <ul> <li>asm.bat</li> <li>binpac8x.py</li> <li>TASM.exe</li> <li>TASM80.tab</li> <li>ti83plus.inc</li> </ul> <p>(I use binpac8x rather than DEVPAC8X because I am using a 64-bit version of windows)</p> <p>Here is my ASM code:</p> <div class="code"> <pre><code>.nolist #include &quot;ti83plus.inc&quot; #define ProgStart $9D95 .list .org ProgStart - 2 .db t2ByteTok, tAsmCmp bcall(_ClrLCDFull) ld hl, 0 ld (PenCol), hl ld hl, msg bcall(_PutS) ; Display the text bcall(_NewLine) ret msg: .db &quot;Hello world!&quot;, 0 .end .end</code></pre></div> <p>I am able to compile successfully, and load the .8xp file onto my calculator, but when I run</p> <div class="code"> <pre><code>Asm(prgmHELLO)</code></pre></div> <p>On my ti-84 plus c silver edition, I get an <strong>ERR: INVALID</strong> message, and on my TI-84 plus silver edition, I just get a blank screen with the word &quot;done&quot; at the bottom. What am I doing wrong? Any suggestions?</p> <p>Thanks, Cheers!</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-1046077</guid>
				<title>Interrupt Hexcode</title>
				<link>http://z80-heaven.wikidot.com/forum/t-1046077/interrupt-hexcode</link>
				<description></description>
				<pubDate>Wed, 29 Oct 2014 16:51:35 +0000</pubDate>
				<wikidot:authorName>The Cow</wikidot:authorName>				<wikidot:authorUserId>1356851</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>I am making an interrupt code in hexcode, but I think I may have messed up somewhere.</p> <div class="code"> <pre><code>INTRPT_MASK .EQU %00001011 b_call(_ClrLCDFull) ;EF4045 DI ;F3 ; Load interrupt address vectors LD HL, interrupt ;21XXXX - XXXX should be C49D LD ($993F), HL ;223F99 LD ($997F), HL ;227F99 LD ($99BF), HL ;22BF99 LD ($99FF), HL ;22FF99 LD A, $99 ;3E99 LD I, A ;ED47 LD A, INTRPT_MASK ;3E0B OUT (3), A ;D303 IM 2 ;ED5E EI ;FB ; GetKey and GetCSC only function in Mode 1, ; so gotta use the key port. LD A, %10111111 ;3EBF OUT (1), A ;D301 KeyLoop: IN A, (1) ;DB01 CP %01111111 ;FE7F JR NZ, KeyLoop ;20FA LD A, %00001011 ;3E0B OUT (3), A ;D303 IM 1 ;ED55 RET ;C9 interrupt: ;Address C49D EX AF, AF' ;08 EXX ;D9 XOR A ;AF OUT (3), A ;D303 LD HL, 0 ;210000 LD (CurRow), HL ;224B84 LD HL, (counter) ;21E29D INC HL ;23 LD (counter), HL ;22E29D b_call(_DispHL) ;EF0745 LD A, INTRPT_MASK ;3E0B OUT (3), A ;D303 EX AF, AF' ;08 EXX ;D9 EI ;FB RET ;C9 counter: ;Address E29D .DW $0000</code></pre></div> <p>If you find the problem, could you tell me? Thanks. Also, how would I make the counter a 8 byte integer? I'm bad with the math stuff&#8230;</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-741374</guid>
				<title>5 fun questions.</title>
				<link>http://z80-heaven.wikidot.com/forum/t-741374/5-fun-questions</link>
				<description></description>
				<pubDate>Sun, 01 Dec 2013 20:39:52 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Last wednesday I had that competition and today I received the solutions. I believe I should get 104/108 but depending on how they correct it could be like 90%. Anyway enough for the finals :)<br /> There was one kind of question which I really liked and I thought to share those.<br /> We had to give the shortest way to express following 5 things in function of min(a,b) , max (a,b) (which return respectively the minimum and the maximum of the 2 given parameters) ,+,-,/ and *.</p> <p>1. The greatest of 3 numbers a b and c<br /> 2. The absolute value of any number a.<br /> 3. The difference between a and the one closest to a. (a b and c as inputs)<br /> 4. If a&lt;b: return 0 ; else return b (a and b are positive and a is not b)<br /> 5. same as 4. but a and b are integers. (note that for integers 3/5 is not 0.6 but 0 and a remainder of 3). This one should be shorter than the solution of 4.</p> <p>5 was the only question I didn't answer correctly. Can you find the solutions to all 5?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-732621</guid>
				<title>Useful / important algorithms</title>
				<link>http://z80-heaven.wikidot.com/forum/t-732621/useful-important-algorithms</link>
				<description></description>
				<pubDate>Mon, 25 Nov 2013 18:54:49 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Hello, in 2 days I am participating to a informatics olympiad and I thought it would be useful to know some algorithms.<br /> There is no required knowledge of any programming language, so it's just about the logics behind programming and a few algorithms.<br /> In fact I don't know many of them. The only one I could think of is Dijkstra's algorithm and the shunting yard algorithm.<br /> But I am sure that they won't ask anything about the shunting yard algorithm and dijkstra seems very intresting.<br /> Now my question is if you know a few algorithms which could be useful? I don't think they will ask anything about arithmetic stuff such as karatsuba and fourier(?) for multiplication and stuff.</p> <p>Thanks in advance.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-732123</guid>
				<title>How to debug a program?</title>
				<link>http://z80-heaven.wikidot.com/forum/t-732123/how-to-debug-a-program</link>
				<description></description>
				<pubDate>Sun, 24 Nov 2013 19:26:11 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Hey, I just wrote a program that should be able to add two 32-bit floating point numbers. I omitted the possibility that the numbers could be negative for now. It contains about 160 lines of codes (it might not be the most efficient method) and ofcourse it is not working (the loading thing seems to be stuck and nothing else happens). Now my question is how do I go into debugging something like this?</p> <p>This is my code if you would want to take a look at it yourself:</p> <div class="code"> <pre><code>#include &quot;ti83plus.inc&quot; .org $9D93 .db $BB,$6D ;AsmPrgm start: ld hl,f1 ld de,f2 call f32Add Bcall(_dispHL) inc hl Bcall(_dispHL) inc hl Bcall(_dispHL) inc hl Bcall(_dispHL) ret f32Add: ;Adds 2 32bit floats ;Inputs: ;hl address of first byte of 32 bit float ;de address of first byte of the second 32 bit float ;Outputs: ;Hl contains the sum of hl and de ;Destroys: ;af bc decPt: ld a,(de) cp (hl) jp z,decOk ;zero -&gt; ok jp c,incDe ;carry -&gt; inc (de) ;no carry-&gt; inc (hl) push hl inc (hl) \ inc hl srl (hl) \ push af \ inc hl \ pop af \ rr (hl) \ push af \ inc hl \ pop af \ rr(hl) pop hl jp decPt incDe: push hl ld h,d ld l,e inc (hl) \ inc hl srl (hl) \ push af \ inc hl \ pop af \ rr (hl) \ push af \ inc hl \ pop af \ rr(hl) ld d,h ld e,l pop hl jp decPt decOk: inc hl \ inc hl \ inc hl inc de \ inc de \ inc de ;use last byte first push de push hl ld h,d ld l,e ;ld hl,de ld d,0 ld e,(hl) ;ld de,(hl) pop hl push hl ld h,0 ld l,(hl) ;ld hl,(hl) add hl,de ;hl=hl+de+carry ld b,h ld c,l ;ld bc,hl pop hl pop de ld (hl),c ;b=carry dec hl \ dec de push de push hl ld h,d ld l,e ;ld hl,de ld d,0 ld e,(hl) ;ld de,(hl) pop hl push hl ld h,0 ld l,(hl) ;ld hl,(hl) add hl,de ;hl=hl+de+carry ld c,b ld b,0 add hl,bc ld b,h ld c,l ;ld bc,hl pop hl pop de ld (hl),c ;b=carry dec hl \ dec de push de push hl ld h,d ld l,e ;ld hl,de ld d,0 ld e,(hl) ;ld de,(hl) pop hl push hl ld h,0 ld l,(hl) ;ld hl,(hl) add hl,de ;hl=hl+de+carry ld c,b ld b,0 add hl,bc ld b,h ld c,l ;ld bc,hl pop hl pop de ld (hl),c ;b=carry dec hl \ dec de carryNotOk: push af ld a,b or a jp z,carryOk srl b \ push af inc (hl) \ inc hl \ pop af rr (hl) \ push af \ inc hl \ pop af \ rr (hl) \ push af \ inc hl \ pop af \ rr(hl) push af \ dec hl \ dec hl \ dec hl \ pop af Jp carryNotOk carryOk: ;normalise inc hl pop af normalise: push af bit 0,(hl) jp nz,finished inc hl \ inc hl pop af rl (hl) \ push af \ dec hl \ pop af \ rl (hl) \ push af \ dec hl \ pop af \ rl(hl) jp normalise finished: dec hl ret f1: .db %01000000 .db %10000000 .db %00000000 .db %00000000 f2: .db %01000001 .db %10000000 .db %00000000 .db %00000000</code></pre></div> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-730541</guid>
				<title>Floating point variables</title>
				<link>http://z80-heaven.wikidot.com/forum/t-730541/floating-point-variables</link>
				<description></description>
				<pubDate>Thu, 21 Nov 2013 14:01:43 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>I read this in the tutorial on this site about floating point variables but It doesn't make much sense.</p> <div> <p><strong>Byte 1: Exponent</strong></p> <p>This holds the exponent of the object. The byte is treated as a signed 8-bit integer, except in a strange fashion. $80 is zero, $81-$FF are positive exponents ($81 = 1, $FF = 127), and $00-$7F are negative exponents ($00 = -128, $7F = -1).</p> </div> <p>What is the use of this exponent ? I do not really understand it.<br /> And then after that I read this:</p> <div> <p><strong>Byte 2-8: Data</strong></p> <p>The rest of the bytes are used to hold the data. Each nibble represents the &quot;decimal&quot; digit. The value is treated in scientific notation.</p> <p>Ex.: $00,$80,$31,$41,$59,$26,$54,$00 represents a real value 3.14159265400</p> </div> <p>i do not understand how a hexadecimal number can represent a decimal digit. And in the example given We only get 8 bytes which does not make sense since there should be 9. First I thought byte 0 was omitted but it isn't.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-728930</guid>
				<title>documentation about in and out instructions</title>
				<link>http://z80-heaven.wikidot.com/forum/t-728930/documentation-about-in-and-out-instructions</link>
				<description></description>
				<pubDate>Mon, 18 Nov 2013 19:48:46 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>I have just learned about the in and out instructions but I do not really understand it. If I simply follow the explanation on this site (<a href="http://z80-heaven.wikidot.com/direct-input-output#toc5">http://z80-heaven.wikidot.com/direct-input-output#toc5</a>) I would make this simple program, but it does not work. Is the documentation wrong or did I understand it wrongly?<br /> This is the code:</p> <div class="code"> <pre><code> ld hl,0400h ;210004 ;random value ld a,%11111110 ;3EFE ;group 0 out ($01),a ;D301 ;tell hardware to look for group zero keypress in a,($01) ;DB01 ;receive keypress bit 0,a ;CB47 ;test if down arrow was pressed jr nz,$-8 ;20F6 ;if it was not pressed then return to ld a, for another key press Bcall(_DispHL) ;EF0745 ;If it was pressed then display the value of hl. ret ;C9</code></pre></div> <p>EDIt: If I read the example on this site (<a href="http://wikiti.brandonw.net/?title=83Plus:Ports:01">http://wikiti.brandonw.net/?title=83Plus:Ports:01</a>) it seems like no loops is needed but If I use this code it simply quits the program right after it started so I don't even had the time to press anything.</p> <div class="code"> <pre><code> ld hl,0400h ;210s004 ld a,%11111110 ;3EFE out ($01),a ;D301 in a,($01) ;DB01 bit 0,a ;CB47 call z,disp ;CCA49D ret ;C9 disp: Bcall(_DispHL) ;EF0745 ret ;C9</code></pre></div> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-728499</guid>
				<title>Random Numbers with seeds</title>
				<link>http://z80-heaven.wikidot.com/forum/t-728499/random-numbers-with-seeds</link>
				<description>possible to optimize?</description>
				<pubDate>Mon, 18 Nov 2013 03:43:10 +0000</pubDate>
				<wikidot:authorName>The Cow</wikidot:authorName>				<wikidot:authorUserId>1356851</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Recently I have been trying to get my random number generator (with set seed) to work. I think it works, but there might be some issues I don't know about. Here is my code (I used BRASS):</p> <div class="code"> <pre><code> ; Clear the screen. .bcall _clrLcdFull ; Move cursor to (0,0). ;47 22 96 71 46 ld hl, 0 ld (penCol),hl ld b, 5 ld c, 6;is this the same as ld bc, 0605h? loop: inc c ld a, c push bc .bcall _SetXXOP1 .bcall _StoRand .bcall _Random ld hl, 100 .bcall _SetXXXXOP2 .bcall _FPMult .bcall _Int ld a, 2 .bcall _DispOP1A pop bc djnz loop ; Display the message. ; ld hl,Message ; .bcall _putS ; .bcall _newLine ; Dummy keyboard read. .bcall _getCSC ; Poll the keyboard until we receive a key. - .bcall _getCSC or a jr z,- ; Exit. ret</code></pre></div> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-727837</guid>
				<title>need some help with this program</title>
				<link>http://z80-heaven.wikidot.com/forum/t-727837/need-some-help-with-this-program</link>
				<description></description>
				<pubDate>Sat, 16 Nov 2013 18:06:40 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 Hello I wrote a program but it is not working really good.<br /> I wanted it to be filling up my screen so that I could see it pixel by pixel but instead it loads a few seconds and then it shows me this<br /> <img src="http://img843.imageshack.us/img843/6646/88ss.png" alt="88ss.png" class="image" /> <p>Can anyone tell me how to fix that line in there and how to update my graph everytime I add a pixel? This is my code:</p> <div class="code"> <pre><code>#include &quot;ti83plus.inc&quot; .org $9D93 .db $BB,$6D ; AsmPrgm ;.define bcall(label) rst $28 \ .dw label start: ld c,00h ;y outer: inc c Ld b,00h ;x inner: inc b ;__________pixel-on(b,c)_______________ push bc ;store values of b and c for the loops ld h,00h ld l,b ld d,h ld e,l add hl,hl add hl,de add hl,hl add hl,hl ;b*12 ld d,00h srl c rl d srl c rl d srl c rl d ;c is integer part of c/8 and d is the rest of the division push de ;store the d register ld d,00h ld e,c add hl,de ;hl=b*12 + c/8 ld d,93h ld e,40h add hl,de ;add hl,9340h ;putSScreen pop de ;recall d register push de ;store it again rlc (hl) ;CB06 dec d ;15 jr nz,$-3 ;shift bit to be set to the least significant bit set 0,(hl) ;set that bit pop de ;recall d register again rrc (hl) ;CB0E dec d ;15 ;rotate in other direction to undo previous shifts jr nz,$-3 pop bc ; recall values of b and c ;__________End pixel-on(b,c)_______________ ld a,b cp 3Eh ;if x!=94 then continue inner loop else continue outer loop. jp nz,inner ld a,c cp 5Eh ;if y!=62 then continue outer loop else quit jp nz,outer ret</code></pre></div> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-727511</guid>
				<title>Set with IY</title>
				<link>http://z80-heaven.wikidot.com/forum/t-727511/set-with-iy</link>
				<description></description>
				<pubDate>Sat, 16 Nov 2013 08:35:33 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>I was wondering what this instruction does but I can't find it on the web. Does anyone know it here?</p> <div class="code"> <pre><code>SET D,*,(IY*) CBFD</code></pre></div> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-727297</guid>
				<title>compare a-1</title>
				<link>http://z80-heaven.wikidot.com/forum/t-727297/compare-a-1</link>
				<description></description>
				<pubDate>Fri, 15 Nov 2013 21:16:24 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Hello I wanted to compare the c register to the a register -1<br /> I got this but it has a small error. I need to save the value of my a register so I thought to just use inc a once again before the jp but that wouldn't work since it would change the flags once again.<br /> And the code I have now won't work either because it will restore the flags I had when I used push af. I don't really know how to solve this ._. so can anyone help me out on this? Thanks in advance.</p> <div class="code"> <pre><code>inc c 0C push af F5 dec a 3D cp c B9 pop af F1 jp z,label CA----</code></pre></div> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-722304</guid>
				<title>electric circuits</title>
				<link>http://z80-heaven.wikidot.com/forum/t-722304/electric-circuits</link>
				<description></description>
				<pubDate>Fri, 08 Nov 2013 19:17:44 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 Today I found this program and I made a working xor gate with it.<br /> <img src="http://www.logo-history.be/asm/xor.PNG" alt="xor.PNG" class="image" /><br /> it is a quite good program but it's dated from 2001 I believe, so it is old. I was wondering if there are more programs like this because I have been searching for it for a quite long time but I can not find it.<br /> I would also be interested in some real version of this but I don't know where to find it either.<br /> Can anyone help me out?
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-721530</guid>
				<title>A NOT instruction?</title>
				<link>http://z80-heaven.wikidot.com/forum/t-721530/a-not-instruction</link>
				<description></description>
				<pubDate>Thu, 07 Nov 2013 19:50:55 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Is there any kind of NOT instruction in z80 assembly? It should just flip all register its bytes.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-719543</guid>
				<title>detail... :P</title>
				<link>http://z80-heaven.wikidot.com/forum/t-719543/detail:p</link>
				<description></description>
				<pubDate>Mon, 04 Nov 2013 20:44:58 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Hey I just got bothered by some really small detail and I was wondering if you would be able to change that?<br /> I don't really know how this wikidot sites works so maybe you are able to edit this.<br /> Look at this image.</p> <img src="http://www.logo-history.be/aa/space.PNG" alt="space.PNG" class="image" /> <p>Don't you think that there should be a space between the parenthese and the Jump! ?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-719515</guid>
				<title>efficiency?</title>
				<link>http://z80-heaven.wikidot.com/forum/t-719515/efficiency</link>
				<description></description>
				<pubDate>Mon, 04 Nov 2013 19:26:23 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>I wrote this program as solution for my exercise of my tutorial. This is the exercise<br /> &quot;3. Write another program that calculates the value of 9Ah*08h. You are not allowed to use 2 byte registers. Only at the end you will want to store your value in the H register and in the L register and then you should call Bcall(DispHL) to output the value stored in HL.&quot;</p> <p>The program works but I am not sure if this is a good solution or not. Is there a better solution?</p> <div class="code"> <pre><code>AsmPrgm Ld b,03h 0603 ld l,9Ah 2E9A Ld h,00h 2600 Ld a,h 7C Add a,a 87 Ld h,a 67 Ld a,l 7D Add a,a 87 Ld l,a 6F Jr nc,$+3 3001 Inc h 24 Djnz $-09h 10F5 Bcall(DispHL) EF0745 ret C9</code></pre></div> <p>Note: i haven't taught the bit level instructions like xor and or yet.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-718839</guid>
				<title>jumps vs. calls and rets</title>
				<link>http://z80-heaven.wikidot.com/forum/t-718839/jumps-vs-calls-and-rets</link>
				<description></description>
				<pubDate>Sun, 03 Nov 2013 20:55:15 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>What If I use a jump instead of the call function and then instead of the ret I use another jump.<br /> Would this be slower? or is this just less efficient to code?</p> <p>Well an example here</p> <div class="code"> <pre><code>... return: jp z,prgrm ... prgrm: ... jp return</code></pre></div> <p>or</p> <div class="code"> <pre><code>... call z,prgrm ... prgrm: ... ret</code></pre></div> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-718838</guid>
				<title>output 2 byte numbers.</title>
				<link>http://z80-heaven.wikidot.com/forum/t-718838/output-2-byte-numbers</link>
				<description></description>
				<pubDate>Sun, 03 Nov 2013 20:53:58 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Assume I have some 2 byte number stored in the hl register. How can I check what is the value stored inside my hl register? I don't really know how to do that.</p> <p>EDIT: Would this be of any use? <a href="http://wikiti.brandonw.net/index.php?title=83Plus:BCALLs:51CD">http://wikiti.brandonw.net/index.php?title=83Plus:BCALLs:51CD</a></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-718831</guid>
				<title>new forum categories</title>
				<link>http://z80-heaven.wikidot.com/forum/t-718831/new-forum-categories</link>
				<description></description>
				<pubDate>Sun, 03 Nov 2013 20:20:37 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>I believe that there are not much categories here. Maybe they are enough but at least I would suggest to add an Off topic forum.<br /> My latest post about computer opcodes would be perfect there because it is not about z80 assembly or the ti84+ but it is something that some people from this forum could know.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-718041</guid>
				<title>opcodes for computers?</title>
				<link>http://z80-heaven.wikidot.com/forum/t-718041/opcodes-for-computers</link>
				<description></description>
				<pubDate>Fri, 01 Nov 2013 19:45:39 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Hello today I was to lazy to work a bit on my tutorial so I was playing around with assembly language for computers. I was wondering if there is also some hex translation there and I found that mov eax,fde8h is equal to b8 e8 fd which makes sense.<br /> Well now my question is if there is any list with the hexadecimal translations of the commands? and if so where could that list be found?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-716479</guid>
				<title>Bcall putC</title>
				<link>http://z80-heaven.wikidot.com/forum/t-716479/bcall-putc</link>
				<description></description>
				<pubDate>Tue, 29 Oct 2013 21:45:53 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Bcall(_PutC)<br /> Very handy indeed but imagine that this 'function' would not exist. How would we write this function then? is there no way around than designing the character sprites ourselves and output those? Or are those sprites also stored somewhere in the calculator? If so, where are they stored then ?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-712561</guid>
				<title>(HL+) (HL-) etc</title>
				<link>http://z80-heaven.wikidot.com/forum/t-712561/hl-hl-etc</link>
				<description>Another stupid question</description>
				<pubDate>Mon, 21 Oct 2013 17:45:30 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>What is the difference between (HL) (HL+) and (HL-) ?<br /> Same question for BC and DE.<br /> Does this mean that we are accessing the value of the address HL+1 ?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-712435</guid>
				<title>R register ??</title>
				<link>http://z80-heaven.wikidot.com/forum/t-712435/r-register</link>
				<description></description>
				<pubDate>Mon, 21 Oct 2013 11:04:42 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Hi today i was looking in some hex commands and suddenly I read these two commands.</p> <ul> <li>LD A,R 5FED</li> <li>LD R,A 4FED</li> </ul> <p>What are those ? What is their use ?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-711612</guid>
				<title>3rd and 5th bit of the flag register</title>
				<link>http://z80-heaven.wikidot.com/forum/t-711612/3rd-and-5th-bit-of-the-flag-register</link>
				<description></description>
				<pubDate>Sat, 19 Oct 2013 20:08:48 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>On this website I have read this about the f register:</p> <ul> <li>5th bit The 5th bit of the last 8-bit instruction that altered flags.</li> <li>3th bit The 3rd bit of the last 8-bit instruction that altered flags.</li> </ul> <p>I think this is kinda strange but maybe it might be useful.. I don't know any example though. Does someone know what these can be used for ?</p> <p>Another question. I don't find anything about the nz register on that page. Is it also stored in the f register?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-709162</guid>
				<title>Hex assembly tutorial</title>
				<link>http://z80-heaven.wikidot.com/forum/t-709162/hex-assembly-tutorial</link>
				<description></description>
				<pubDate>Mon, 14 Oct 2013 16:58:05 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Hello I have started writing a tutorial a week ago. In that tutorial I am kinda focussing on the hexadecimal programming so I am not covering labels and what the .org 40339 (I think it is that) is and some other stuff like that.</p> <p>I am writing this because it is good for myself to learn from it and also because I had some problems with actually starting on the language because there was no clear tutorial for it. I hoped that someone might ever find this useful.</p> <p>Right now I have 'finished' the first part of it though I still have to add a few things to that.</p> <p>I was actually wondering if there would be anyone out there who would be interested.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-708190</guid>
				<title>list of registers</title>
				<link>http://z80-heaven.wikidot.com/forum/t-708190/list-of-registers</link>
				<description></description>
				<pubDate>Sat, 12 Oct 2013 10:04:55 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Hello,<br /> Does anyone know where I can find a clear overview of the ti84 plus registers with their specific uses next to it ?<br /> for example register B is used as counter variable in djnz etc..</p> <p>Thanks in advance</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-705955</guid>
				<title>Pathfinding Algorithm</title>
				<link>http://z80-heaven.wikidot.com/forum/t-705955/pathfinding-algorithm</link>
				<description>Not sure how it would be implemented</description>
				<pubDate>Tue, 08 Oct 2013 01:37:34 +0000</pubDate>
				<wikidot:authorName>The Cow</wikidot:authorName>				<wikidot:authorUserId>1356851</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>I've been puzzling over how to implement a fast pathfinding algorithm in assembly. Rather than finding a specific path, I want it to find all possible ending locations, given a certain move distance. For example, if the move distance is 9, we can move at most 9 spaces. I also want to include different terrain costs. For example, moving in a forest takes two moves.</p> <p>I was thinking perhaps doing this:</p> <div class="code"> <pre><code>.......... ....1..... ...121.... ..12321... .1234321.. 123454321. .1234321.. ..12321... ...121.... ....1.....</code></pre></div> <p>Where the move distance is 4. It starts at the five, and looks at each adjacent tile, and marks it with move distance - terrain cost. In this case terrain cost = 1, so 5-1=4. This is done for all the tiles.</p> <p>With different terrain costs, it may be as shown below:</p> <div class="code"> <pre><code>3? 52</code></pre></div> <p>If the ? has a terrain cost of 1, then the 3-&gt;? would be 2, and the 2-&gt;? would be 1. So the ? would be replaced with a 2, since 2 is more optimal.</p> <p>To retrace a path after locating the spaces, we take the last space, and add the move cost of that space. Locate an adjacent tile with the number on the space plus the movement cost of the space, and add that space to a list.</p> <p>Hmm. Now that I have the general idea figured out, I'm not sure how to implement it into code.</p> <p>EDIT: I was also wondering where the random numbers are stored? I wish to be able to access them with a seeded value.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-705295</guid>
				<title>Why does this code crashes ?</title>
				<link>http://z80-heaven.wikidot.com/forum/t-705295/why-does-this-code-crashes</link>
				<description></description>
				<pubDate>Sun, 06 Oct 2013 19:05:16 +0000</pubDate>
				<wikidot:authorName>Jannes Braet</wikidot:authorName>				<wikidot:authorUserId>1738068</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>My code:</p> <div class="code"> <pre><code>ld hl,A99D ;21A99D ld a,hl ;7E or a ;B7 jr z,$+18 ;28A2 Bcall(PutC) ;EF0445 inc hl ;23 ld a,(curcol) ;3A4C84 inc a ;3C ld (curcol),a ;324C84 jr $-15 ;18EF .db &quot;Hey¿&quot;,0 ;486579B900 Bcall(NewLine) ;EF2E45 ret ;C9</code></pre></div> <p>And that there is my output. (note that the calculator is actually first loses power and then I turn it on again and then the crash screen appear But clearly the gif does not record poweroff)</p> <p>img11.imageshack<br /> .us/img11/8546/7y7a.gif</p> <p>Im sorry but I can't send a link because I am a low Karma user&#8230;<br /> Join that link to each other and you can see my gif</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-676164</guid>
				<title>Column-Major Graphics Buffer Format</title>
				<link>http://z80-heaven.wikidot.com/forum/t-676164/column-major-graphics-buffer-format</link>
				<description>This outlines an alternative to the row-major buffer format that is used by the OS and many other programs.</description>
				<pubDate>Sun, 28 Jul 2013 19:10:22 +0000</pubDate>
				<wikidot:authorName>Xeda Elnara</wikidot:authorName>				<wikidot:authorUserId>595803</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>To get some definitions out of the way, row-major order means that data is stored in rows. The OS stores the graph buffer in rows, so the first 12 bytes corresponds to the top row of pixels. What we are going to do here is explore <strong>column-major</strong> order and the advantages and drawbacks of using this method on the T-83+/84+ calculators.</p> <p>The primary disadvantages to using a column-major graph buffer are:</p> <ul> <li>You won't be able to use many of the OS drawing routines if they draw to the buffer.</li> <li>You won't be able to use the OS LCD updating routines.</li> <li>A handful of graphics routines may be slower than with their row-major counterparts.</li> </ul> <p>The main advantages are:</p> <ul> <li>Most graphics routines are faster and some are much faster.</li> <li>Most graphics routines are smaller.</li> </ul> <p>Now lets get started. First note that we are going to store 12 byte-wide columns of 64 bytes. This means that the first 64 bytes of the buffer corresponds to the left-most byte-wide (8 pixels wide) column of pixels. To see the first example of just how useful this is, let's draw an 8x8 tile:</p> <div class="code"> <pre><code> ld hl,tile0 ld de,gBuf ld bc,8 ldir ;10+10+10+8*21-5 = 193 clock cycles, 11 bytes</code></pre></div> <br /> That is all it takes to draw an 8x8 tile at the upper-left corner of the screen. Using row-major order, we would need to do something like: <div class="code"> <pre><code> ld hl,tile0 ld de,gBuf ld bc,11 ld a,8 loop: inc c ldi ex de,hl add hl,bc ex de,hl dec a jr nz,Loop ;10+10+10+7+8(4+16+4+11+4+4+12)-5 = 472 clock cycles, 20 bytes</code></pre></div> <br /> So using column-major order, our routine is about 2.45 times faster and 9 bytes smaller. With those kinds of savings, we might be tempted to actually unroll the first routine to save a few more clock cycles: <div class="code"> <pre><code> ld hl,tile0 ld de,gBuf ldi ldi ldi ldi ldi ldi ldi ldi ;10+10+8*16 = 148 clock cycles, 22 bytes</code></pre></div> <br /> The size doubled for a 45 cc speed gain, but it is now 2 bytes larger than the row-major routine and over 3 times faster. <p>While this provides one of the most significant speed improvements, there are many other speed and size improvements for other graphics routines. For example, to locate a pixel in a buffer using row-major order, given (x,y) you would need to perform 12*y+(x/8) (we are using only integer values). With column major order, we now need to do (x/8)*64+y. To illustrate this in code:<br /> (hint: multiplying by 64 or any power of 2 is easier than a non-power of 2)</p> <div class="code"> <pre><code>;GetPixelOffset: ;row major order ;Input: bc = (x,y) ;Output: nc if out-of-bounds, HL is the offset into a row-major buffer, A is the pixel mask ld a,c cp 64 ret nc ld a,b cp 96 ret nc ld b,0 ; a = x ; bc = y ; multiply y*12 ld h,b ld l,c add hl,hl add hl,bc add hl,hl add hl,hl ; now a = x, we need to add a/8 to hl ; divide by 8, but we need to save x to determine the pixel mask ld c,a sra c sra c sra c add hl,bc ; now HL is the offset into the buffer ; we need to compute the pixel mask and 7 \ inc a ld b,a ld a,1 rrca djnz $-1 scf ret</code></pre></div> <br /> And then column-major: <div class="code"> <pre><code>;GetPixelOffset: ;column-major order ;Input: bc = (x,y) ;Output: nc if out-of-bounds, HL is the offset into a column-major buffer, A is the pixel mask ld a,c cp 64 ret nc ld a,b cp 96 ret nc ; a = x ; compute (x/8)*64 ; dividing by 8 is three right shifts. We then multiply by 64 (6 left shifts). Shifting right 3 times then left 3 times has a net effect of setting the lower three bits to 0. So instead, we just set the lower three bits to 0 and shift left three times. and %11111000 ld h,0 add a,a ;a is less than 128, so no information is lost here, and it is 7 cycles faster than add hl,hl ld l,a ld a,b ;we will need this for later ld b,h ;h = 0 at this point, so now BC =Y add hl,hl add hl,hl add hl,bc ; HL = (x/8)*64+y ; now a = x , HL is the offset into the buffer ; we need to compute the pixel mask and 7 \ inc a ld b,a ld a,1 rrca djnz $-1 scf ret</code></pre></div> <br /> Now we have saved 39 clock cycles and 6 bytes to locate a pixel. Any routines that use pixel plotting will then see a slight speed improvement. <p>One routine that is actually more complicated with column-major format is a left or right shift. However, we can get back some of the speed (at the cost of size) by using index registers whose range can be up to 256 bytes (precisely 4 columns):</p> <div class="code"> <pre><code>shiftright: ;20446 cc's needed ld ix,gbuf+128 ld b,64 shiftrightloop: rr (ix-128) \ rr (ix-64) \ rr (ix) \ rr (ix+64) \ inc ixh ;100 incrementing the MSB of IX is the same as adding 256 rr (ix-128) \ rr (ix-64) \ rr (ix) \ rr (ix+64) \ inc ixh ;100 rr (ix-128) \ rr (ix-64) \ rr (ix) \ rr (ix+64) ;92 dec ixh \ dec ixh \ inc ix ; 26 djnz shiftrightloop ret shiftleft: ld ix,buf0+768-65 ld b,64 shiftleftloop: rl (ix+64) \ rl (ix) \ rl (ix-64) \ rl (ix-128) \ dec ixh ;100 rl (ix+64) \ rl (ix) \ rl (ix-64) \ rl (ix-128) \ dec ixh ;100 rl (ix+64) \ rl (ix) \ rl (ix-64) \ rl (ix-128) ;92 inc ixh \ inc ixh \ dec ix ; 26 djnz shiftleftloop ret</code></pre></div> <p>To update the LCD, there is a rather straight-forward code:</p> <div class="code"> <pre><code>#define lcddelay() in a,(16) \ rlca \ jr c,$-3 ld a,5 out (16),a lcddelay() ld a,80h out (16),a ld hl,9340h lcddelay() ld a,20h col: out (16),a inc a cp 2Ch push af ld bc,4011h row: lcddelay() outi jr nz,row lcddelay() pop af jr nz,col ret</code></pre></div> <br /> Since the OS sets the correct increment mode anyways, you actually shouldn't need the first part of the code: <div class="code"> <pre><code>#define lcddelay() in a,(16) \ rlca \ jr c,$-3 ld a,80h out (16),a ld hl,9340h lcddelay() ld a,20h col: out (16),a inc a cp 2Bh push af ld bc,4011h row: lcddelay() outi jr nz,row lcddelay() pop af jr nz,col ret</code></pre></div> <br /> Both of those are safe-copy routines and save at least 8 bytes over the corresponding row-major version. <p>Here are a handful of other routines that may be useful for anybody that wants to program using column-major buffers:</p> <p><strong>drawtile</strong><br /> Use this to draw a tile aligned to an 8 by 12 grid (as in for a tilemap):</p> <div class="code"> <pre><code>drawtile: ;Inputs : BC = (x,y), DE points to the sprite ; 303 clock cycles ld a,c cp 8 ret nc ld a,b cp 12 ret nc or a ld l,0 rra \ rr l rra \ rr l ld h,a ld a,c add a,a add a,a add a,a add a,l ld l,a ld bc,gBuf add hl,bc ex de,hl ld bc,8 ldir ret</code></pre></div> <br /> It is very fast at just 303 clock cycles and by replacing <strong>ld bc,8 \ ldir</strong> with 8 <strong>ldi</strong> instructions, you can save another 45&#160;t-states. <p><strong>XORSprite8x8</strong><br /> This draws a sprite fairly quickly with XOR logic (it can be easily modified to do OR logic as well) using pixel coordinates.</p> <div class="code"> <pre><code>PutSprite8x8: ;Note: No clipping. ;Inputs: ; BC = (x,y) ; IX points to the sprite ; 1871 worst-case ld a,b and $F8 ld h,0 rla \ rl h rla \ rl h rla \ rl h ld l,a ld a,b ld b,0 add hl,bc ld bc,gbuf add hl,bc ;HL points to the first byte to draw at and 7 jr nz,crossedbound push ix \ pop de ld b,8 ld a,(de) xor (hl) ld (hl),a inc hl inc de djnz $-5 ret crossedbound: ld b,a dec a ld (smc_jump1),a ld (smc_jump2),a ld a,1 rrca djnz $-1 dec a ld e,a ld c,8 ;E is the mask ;IX points to the sprite ;HL points to where to draw drawloop1: ld a,(ix) .db 18h ;start of jr * smc_jump1: .db 0 rlca rlca rlca rlca rlca rlca rlca and e xor (hl) ld (hl),a inc ix inc hl dec c jr nz,drawloop1 ld c,56 add hl,bc ld a,e cpl ld e,a ld c,8 drawloop2: ld a,(ix-8) .db 18h ;start of jr * smc_jump2: .db 0 rlca rlca rlca rlca rlca rlca rlca and e xor (hl) ld (hl),a inc ix inc hl dec c jr nz,drawloop2 ret</code></pre></div> <p><strong>Rectangle Drawing</strong><br /> Here are a handful of rectangle drawing routines:</p> <div class="code"> <pre><code>;RectangleErase can be optimised to be much faster if you make it its own routine using cpl \ and (hl) for logic. Currently, it uses RectangleOR \ RectangleXOR ;Included Routines ;====================== ;Inputs: ; B = Height ; C = Width ; D = X (leftmost) ; E = Y (upper) ;RectangleBoxEraseFill ; Draws a box with a black border, interior is erased. ; Returns B-2, C-2, D+1, E+1 ;RectArrowXOR ; Draws an arrow pointing right with XOR logic ; Returns BC,DE unchanged ;RectangleMenu ; Draws a box with rounded edges ; Returns D+1,C+2, B and E unchanged ;RectangleOR ; Draws a black rectangle ; Returns BC,DE unchanged ;RectangleXOR ; Inverts the region of the screen ; Returns BC,DE unchanged ;RectangleErase ; Draws a white rectangle ; Returns BC,DE unchanged RectangleBoxEraseFill: call RectangleOR inc d inc e dec b dec b dec c dec c jp RectangleXOR RectArrowXOR: push de push bc ld a,b cp c jr c,$+3 ld b,c ld c,1 ;B is now the smaller of the two ;C is 1 call RectangleXOR inc d \ inc e djnz $+5 pop bc pop de ret djnz $-10 jr $-5 RectangleMenu: call RectangleErase push bc \ push de inc e \ dec b \ dec b call RectangleXOR pop de \ pop bc inc d \ dec c \ dec c jr RectangleXOR RectangleErase: call RectangleOR RectangleXOR: ;Inputs: ; DE is (x,y) ; BC is (h,w) ;Outputs: push de push bc call RectMain jr nz,$+11 ld a,c xor (hl) ;logic ld (hl),a inc hl djnz $-4 jp EndRect ld d,a ;number of columns before last col ld e,b ld a,(rect_FirstByte) ld c,a xorrectcol: ld b,e ;height push hl xorrectloop: ld a,(hl) xor c ;logic ld (hl),a inc hl djnz xorrectloop pop hl ld c,64 add hl,bc ld c,-1 dec d jp m,endrect jr nz,xorrectcol ld bc,(rect_LastByte) jp xorrectcol RectangleOR: ;Inputs: ; DE is (x,y) ; BC is (h,w) ;Outputs: push de push bc call RectMain jr nz,$+11 ld a,c or (hl) ;logic ld (hl),a inc hl djnz $-4 jp EndRect ld d,a ;number of columns before last col ld e,b ld a,(rect_FirstByte) ld c,a orrectcol: ld b,e ;height push hl orrectloop: ld a,(hl) or c ;logic ld (hl),a inc hl djnz orrectloop pop hl ld c,64 add hl,bc ld c,-1 dec d jp m,endrect jr nz,orrectcol ld bc,(rect_LastByte) jp orrectcol EndRect: pop bc pop de ret RectMain: ;Inputs: ; DE is (x,y) ; BC is (h,w) ;Outputs: ; returns z if it is all in one column, else it returns the number of columns ; HL points to the start byte ; (rect_FirstByte), (rect_LastByte) ; A is negative the number of columns ; BC is (h,w) ; ;If it is a single column wide, C is the mask, B is the height ld a,d and %11111000 ld h,0 rla \ rl h rla \ rl h rla \ rl h ld l,a ld a,d ld d,0 add hl,de ;HL points to the byte it will start on push hl ld d,a push bc call ComputeByte ld (rect_FirstByte),a ex (sp),hl ld a,d cpl and 7 inc a ld b,a ld a,l sub b ex (sp),hl call ComputeByte cpl ld (rect_LastByte),a ;last and first byte are computed ld a,d and %11111000 ld e,a ld a,d add a,c and %11111000 pop hl ex (sp),hl ld bc,(DrawBufPtr) add hl,bc pop bc sub e rrca rrca rrca and %00011111 ret nz ld de,(rect_FirstByte) ld a,d \ and e ld c,a xor a ret ComputeByte: and 7 ld b,a ld a,80h jr z,$+5 rrca djnz $-1 add a,a dec a ret</code></pre></div> <p><strong>Text Output</strong><br /> Since the OS routines won't work on our buffer, text output will be important. Here are a few routines that use a nibble-packed 4x6 font:</p> <div class="code"> <pre><code>;RAM required: ;fmt_leftmost 1 byte , define the left edge of where text can be drawn ;fmt_rightmost 1 byte , define the right edge of where text can be drawn ;fmt_lower 1 byte , define the lower edge of where text can be drawn ;fmt_upper 1 byte , define the upper edge of where text can be drawn ;bit wordrawp,(iy+textflags) ;define your own location and whatnot ;textcol 1 byte ;textrow 1 byte ;fontptr 2 bytes points to the nibble packed 4x6 fontset ;DrawBufPtr 2 bytes, points to the buffer where text gets drawn ;lFont_record is defined by the ti83plus.inc. 6 bytes are used ; ;Sample Fontset included ;Inlcuded Routines, Input: ; IGPutSFmt null-terminated string, directly following the call ; GPutSFmt HL points to the null terminated string ; GPutCFmt A is the character to display (all formatting applied) ; GPutC B is the character to display (some formatting applied) ; ;All text is written to the buffer with OR logic. ;These routines are modified for vertically aligned buffers, not the way the OS does it. IGPutSFmt: ;Inputs: ; The null-terminated string to display immediately follows the call. ;Example: ; call IGPutSFmt ; .db &quot;Hello World!&quot;,0 pop hl call GPutSFmt jp (hl) GPutSFmt: ;Inputs: ; HL points to the zero-terminated string to display ;The following define a rectangular region for where text is allowed: ; (fmt_leftmost) ; (fmt_rightmost) ; (fmt_lower) ; (fmt_upper) ; bit wordwrap,(iy+textflags) ld a,(hl) inc hl or a ret z push de push hl call GPutCFmt pop hl pop de jr GPutSFmt GPutCFmt: ;Input: ; A is the char to display ld b,a call GPutC ;perform formatting based on indents, wordwrap bit wordwrap,(iy+textflags) ret z ld hl,(textcol) ld de,(fmt_rightmost) ld a,e sub l ret nc ld a,d sub h ret c ld a,(fmt_leftmost) ld l,a ld a,h add a,6 ld h,a ld (textcol),hl ret GPutC: ;Inputs: ; (fontptr) ; (textcol) ; (textrow) ; B is the char to display ld a,$D6 cp b jr nz,charreg nextline: ld a,(fmt_leftmost) ld (textcol),a ld a,(textrow) add a,6 ld (textrow),a ret charreg: ld hl,(fontptr) ld a,b ld c,b ld b,0 add hl,bc add hl,bc add hl,bc ld de,lFont_record ld b,3 ld a,(hl) and $F0 ld (de),a inc e ld a,(hl) rrca \ rrca rrca \ rrca and $F0 ld (de),a inc e inc hl djnz $-15 ld ix,lFont_record ld de,0406h ld bc,(textcol) ld hl,fmt_lower ld a,b cp (hl) \ ret nc ;e is height add a,e sub (hl) jr c,$+6 neg add a,e ld e,a ld a,c dec l cp (hl) \ ret nc ld a,c add a,4 ld (textcol),a ld a,b ld b,c ld c,a ORSprite8xY: ;Note: No clipping. ;Inputs: ; BC = (x,y) ; IX points to the sprite ; E is the height ld a,b and $F8 ld h,0 rla \ rl h rla \ rl h rla \ rl h ld l,a ld a,b ld b,0 add hl,bc ld bc,(DrawBufPtr) add hl,bc ;HL points to the first byte to draw at and 7 jr nz,crossedbound ld b,e push ix \ pop de ld a,(de) xor (hl) ld (hl),a inc hl inc de djnz $-5 ret crossedbound: ld b,a ld d,a ld a,1 rrca djnz $-1 dec a ld c,e push bc ld e,a ;E is the mask ;IX points to the sprite ;HL points to where to draw drawloop1: ld a,(ix) ld b,d \ rrca \ djnz $-1 and e or (hl) ld (hl),a inc ix inc hl dec c jr nz,drawloop1 ld c,64 add hl,bc ld a,e cpl ld e,a pop bc drawloop2: dec ix dec hl ld a,(ix) ld b,d \ rrca \ djnz $-1 and e or (hl) ld (hl),a dec c jr nz,drawloop2 ret ;=============================================================== FontSet: ;=============================================================== ;00~7F .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$8C,$EC,$80,$00,$00,$00,$00,$00,$00 .db $24,$44,$20,$0A,$4A,$00,$00,$EA,$E0,$00,$4E,$40,$00,$04,$00,$00,$E4,$44,$E4,$2C,$00,$EC,$EC,$C0 .db $74,$4C,$40,$62,$A2,$00,$C2,$4E,$00,$02,$48,$E0,$69,$96,$00,$AC,$88,$00,$E4,$40,$00,$68,$60,$E0 .db $2E,$4E,$80,$C2,$C0,$E0,$06,$00,$00,$E8,$C8,$E0,$42,$F2,$40,$AD,$DD,$A0,$4E,$44,$40,$44,$4E,$40 .db $00,$00,$00,$44,$40,$40,$AA,$A0,$00,$00,$00,$00,$00,$00,$00,$A2,$48,$A0,$4A,$4A,$50,$88,$80,$00 .db $24,$44,$20,$84,$44,$80,$00,$40,$00,$04,$E4,$00,$00,$44,$80,$00,$E0,$00,$00,$00,$80,$22,$48,$80 ;FontNumbers .db $4A,$AA,$40,$4C,$44,$E0,$C2,$48,$E0,$C2,$42,$C0,$AA,$E2,$20,$E8,$C2,$C0,$68,$EA,$E0,$E2,$44,$40,$EA,$EA,$E0,$EA,$E2,$20 ;3Ah~3Fh .db $04,$04,$00,$04,$04,$80,$24,$84,$20,$0E,$0E,$00,$84,$24,$80,$C2,$40,$40 .db $00,$00,$00,$4A,$EA,$A0,$CA,$CA,$C0,$68,$88,$60,$CA,$AA,$C0,$E8,$C8,$E0,$E8,$C8,$80,$68,$AA,$60 .db $AA,$EA,$A0,$E4,$44,$E0,$62,$2A,$40,$AA,$CA,$A0,$88,$88,$E0,$AE,$AA,$A0,$CA,$AA,$A0,$EA,$AA,$E0 .db $CA,$C8,$80,$EA,$AE,$60,$CA,$CA,$A0,$68,$42,$C0,$E4,$44,$40,$AA,$AA,$E0,$AA,$AA,$40,$AA,$AE,$A0 .db $AA,$4A,$A0,$AA,$44,$40,$E2,$48,$E0,$4A,$EA,$40,$88,$42,$20,$C4,$44,$C0,$4A,$00,$00,$00,$00,$E0 .db $84,$00,$00,$06,$AA,$60,$88,$CA,$C0,$06,$88,$60,$22,$6A,$60,$04,$AC,$60,$48,$C8,$80,$06,$A6,$2C .db $88,$CA,$A0,$40,$44,$40,$20,$22,$A4,$8A,$CA,$A0,$88,$88,$40,$0A,$EA,$A0,$0C,$AA,$A0,$04,$AA,$40 .db $0C,$AC,$80,$06,$A6,$22,$0A,$C8,$80,$0C,$84,$C0,$4E,$44,$20,$0A,$AA,$E0,$0A,$AA,$40,$0A,$AE,$A0 .db $0A,$44,$A0,$0A,$A6,$24,$0E,$24,$E0,$64,$84,$60,$44,$44,$40,$C4,$24,$C0,$05,$A0,$00,$E0,$E0,$E0 ;FontNumbers2 .db $04,$AA,$A4,$04,$C4,$4E,$0C,$24,$8E,$0C,$24,$2C,$0A,$AE,$22,$0E,$8C,$2C,$06,$8E,$AE,$0E,$24,$44 .db $0E,$AE,$AE,$0E,$AE,$22 ;Accented A .db $24,$AE,$A0,$84,$AE,$A0,$00,$00,$00,$A4,$AE,$A0 ;Accented a .db $24,$06,$A5,$42,$06,$A5,$4A,$06,$A5,$A0,$6A,$60 ;Accented E .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;Accented e .db $48,$4A,$C6,$42,$4A,$C6,$4A,$4A,$C6,$A0,$4A,$C6 ;Accented I .db $24,$0E,$4E,$84,$0E,$4E,$4A,$0E,$4E,$A0,$E4,$E0 ;Accented i .db $24,$04,$44,$84,$04,$44,$4A,$04,$44,$A0,$44,$40 ;Bombs... er, accented O .db $24,$69,$96,$84,$69,$96,$4A,$69,$96,$A0,$69,$96 ;Lowercase bombs .db $24,$06,$96,$84,$06,$96,$4A,$06,$96,$A0,$06,$96 ;Accented U .db $24,$AA,$A6,$84,$AA,$A6,$4A,$AA,$A6,$A0,$AA,$A6 ;Accented u .db $24,$0A,$A6,$84,$0A,$A6,$4A,$0A,$A6,$A0,$0A,$A6 ;Accented C,c,N,n .db $4A,$8A,$48,$06,$88,$6C,$5A,$0C,$AA,$5A,$0C,$AA ;Other Puntuation .db $24,$00,$00,$84,$00,$00,$A0,$00,$00,$40,$48,$60 ;Upside-Down Exclamation Point Identical to lowercase i ;Change to something else? .db $00,$00,$00 ;Greek .db $05,$AA,$50,$25,$65,$A0,$05,$A2,$20,$00,$4A,$E0,$34,$27,$96,$68,$E8,$60 ;[ .db $64,$44,$60 ;Greek (continued) .db $84,$25,$90,$0A,$AD,$80,$0F,$55,$90,$25,$56,$48,$F4,$24,$F0 .db $07,$55,$40,$07,$A2,$10 ;Idunno howta do these .db $4E,$AE,$40,$69,$99,$69 ;CC~CF .db $E0,$A4,$A0,$E0,$A6,$24,$52,$50,$00,$00,$00,$A0,$26,$E6,$20 ;D0~D5 .db $44,$40,$00,$22,$48,$80,$00,$60,$00,$C4,$8C,$00,$EA,$E0,$00,$E4,$2C,$00 ;D6 .db $00,$00,$00 ;D7~DF .db $40,$44,$20,$04,$CA,$C8,$8A,$4A,$20,$E9,$AE,$A8,$69,$E8,$60,$00,$44,$60,$9D,$FB,$90,$A5,$55,$A0,$4E,$FE,$40 ;Overwrite Cursor .db $FF,$FF,$FF,$FB,$1B,$BF,$FB,$51,$5F,$FF,$95,$9F ;Insert Cursor .db $00,$00,$0F,$4E,$EE,$0F,$4A,$EA,$0F,$06,$A6,$0F ;E8~EF .db $00,$84,$20,$00,$C6,$20,$00,$E6,$20,$00,$8C,$E0,$25,$D5,$20,$4A,$AA,$40,$4E,$44,$40 ;F0~F4 .db $44,$4E,$40,$5A,$5A,$5A,$27,$A6,$3E,$4E,$44,$00,$69,$A9,$A0 ;male/female .db $73,$5E,$AE,$EA,$E4,$E4 ;BlockEater Down $F7 .db $6F,$96,$90 ;BlockEater Left $F8 .db $6F,$16,$90 ;BlockEater Right $F9 .db $6F,$86,$90 ;BlockEater Up $FA .db $69,$96,$90 ;FB~FE .db $09,$AC,$E0,$08,$53,$70,$EC,$A1,$00,$73,$58,$00 ;FF .db $A5,$A5,$A5</code></pre></div> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-675609</guid>
				<title>Fire Animation Tutorial</title>
				<link>http://z80-heaven.wikidot.com/forum/t-675609/fire-animation-tutorial</link>
				<description>A tutorial on a method of creating a fire animation.</description>
				<pubDate>Sat, 27 Jul 2013 15:40:51 +0000</pubDate>
				<wikidot:authorName>Xeda Elnara</wikidot:authorName>				<wikidot:authorUserId>595803</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p><strong>Fire Animation</strong><br /> Fire animations are always neat to watch, and luckily, creating such an animation is relatively easy.</p> <ul> <li>The Algorithm <ul> <li>If a pixel is ON (or OFF, depending on which state you choose), give it a 1/n chance of surviving.</li> <li>If the pixel dies, toggle it OFF (or ON).</li> <li>Move the pixel up</li> <li>Randomly set pixels on the bottom row once you have scanned the whole image</li> </ul> </li> </ul> <p>You will want to scan from top to bottom and it will be easier to read pixels from left to right. let's create some pseudo-code:</p> <div class="code"> <pre><code>Set Y = 1 While Y&lt;64 Set X = 0 While X&lt;96 Set pxl = pxl-test(Y,X) If (pxl=1) and (0=randInt(0,N-1)) Set pxl = 0 pxl-set(Y-1,X,pxl) Set X = X+1 EndWhile Set Y = Y+1 EndWhile</code></pre></div> <br /> On our calculators, the corresponding assembly code is a rather ugly code (and by ugly, I mean inelegant). Plotting and testing individual pixels on the B/W models takes several hundred t-states each and we will be checking 96*63 = 6048 pixels. On a 6MHz calc, we would only be getting about 1FPS and I am sure you aren't learning assembly to achieve BASIC speeds.<br /> We can modify 8 pixels at a time if we can somehow easily compute and use the 1/n chance of dying and storing those chances as bits in a byte. <ul> <li>Platform Specific Optimisation <ul> <li>Use a 1/8 chance of dying.</li> <li>create the following LUT:</li> </ul> </li> </ul> <div class="code"> <pre><code>.db %11111110 .db %11111101 .db %11111011 .db %11110111 .db %11101111 .db %11011111 .db %10111111 .db %01111111</code></pre></div> <br /> * Now we select a random integer from 0 to 7 and locate the corresponding byte in the LUT. Use this value to turn one of the 8 pixels off with a simple logic instruction. <p>It is true that we slightly modified the algorithm, but it is much, much faster, allowing us to evolve the whole screen in about 1/70th of a second (at 6MHz). So now to implement this scheme&#8230;</p> <p>We will start with a straight-forward approach and then we will tweak the algorithm to get more speed from it.<br /> <strong>Note:</strong>In the following examples, <strong>ld a,r</strong>will be used to obtain &quot;pseudo-random numbers&quot; but unfortunately, the effect is quite boring and predictable. Instead, it is encouraged that the reader use their own routine to generate a better value, though it can be a significant hit to speed. Here is an example that works rather nicely and is used in the screenshots:</p> <div class="code"> <pre><code> ld hl,seed ld a,r ;9 ;get a pseudo-random number in A add a,(hl) ld h,a add a,(hl) ld l,a add a,(hl) ld (seed),a</code></pre></div> <br /> As well, the screenshots include code for initially drawing to the bottom row of pixels, or for loading in images. <p><strong>Attempt 1 :</strong> 'Beginner'<br /> <strong>Note:</strong> the numbers to the right of the instructions are the number of clock cycles required for the instruction. At 6MHz, the calculator runs 6 million cycles worth of code per second.</p> <div class="code"> <pre><code> ei ;4 ;we are going to need the interrupts for reading the keyboard Main: ld bc,756 ;10 ;we are going to read through 756 bytes worth of the screen at a time ld ix,plotSScreen+12 ;14 ;IX points to row 1 of the graph buffer FireLoop: ld hl,LUT ;10 ;This is our LUT for the pixel mask. ld a,r ;9 ;get a pseudo-random number in A and 7 ;7 ;mask it with %00000111 to get it in the range of 000 to 111 (0 to 7) add a,l ;4 ;add this value to HL ld l,a ;4 ; jr nc,$+3 ;12|11 ;check if there was overflow to correct inc h ;-- ld a,(hl) ;7 ;get the value of the byte in the LUT and (ix) ;19 ;mask it with the byte of pixels at IX ld (ix-12),a ;19 ;load the updated value into the previous row of pixels inc ix ;10 ;IX is now incremented dec bc ;6 ;decrement BC which is our counter ld a,b ;4 ;we need to check if BC = 0 or c ;4 ;returns z when A and C are 0 (so when BC = 0) jr nz,FireLoop;12|7 ;12*2+7 bcall(_GrBufCpy) ;? ;copy the graph buf to the LCD ld a,(kbdScanCode) ;13 ;read the last read keyboard value by the OS interrupt cp 15 ;7 ;test if CLEAR is pressed jr nz,Main ;12|7 ret ;10 LUT: .db %11111110 .db %11111101 .db %11111011 .db %11110111 .db %11101111 .db %11011111 .db %10111111 .db %01111111</code></pre></div> <br /> As you may see, we did not update the bottom row of pixels with new pixels. Any ON pixels will remain ON and flames will rise from them.<br /> <img src="http://img.omnimaga.org//Z80Fire_0.gif" alt="Z80Fire_0.gif" class="image" /> <p><strong>Attempt 2</strong><br /> The previous code, excluding everything starting at the first bcall(), takes 96031&#160;t-states, which isn't bad for an animation like this. However, let's introduce a trick that will save us a little on t-states.<br /> First note that that <strong>dec [reg8] \ jr nz,label</strong>is 3 bytes and 16 cycles if it jumps, 11 if it doesn't, whereas <strong>djnz label</strong>is 2 bytes and 13 cycles if it jumps, 8 if it doesn't. Of course, djnz is limited to just b, but we can work around that.<br /> The optimisation here will essentially let B be the counter in the main loop and C be the counter in the outside loop. If B is 0, initially, <strong>djnz label</strong>will loop 256 times. Preliminary calculations!</p> <ul> <li>Let C = 1</li> <li>Let B = 10</li> </ul> <div class="code"> <pre><code> ld hl,0 Loop: inc hl djnz Loop ;loops 10 times dec c ;Here, B is now 0, C gets decremented to 0 jr nz,Loop ;we don't jump back again</code></pre></div> <br /> So now HL = 10. If you let C = 2, though, then the DJNZ loop is executed 10 times, then another 256, and if C = 3, it is 10 times and another 512. Now we move on to the code at hand:<br /> (note that 756=2*256 + 244 <div class="code"> <pre><code> ei ;4 Main: ld bc,$F403 ;10 ;B = 244, C = 3 ld ix,plotSScreen+12 ;14 ;IX points to row 1 of the graph buffer FireLoop: ld hl,LUT ;10 ;This is our LUT for the pixel mask. ld a,r ;9 ;get a pseudo-random number in A and 7 ;7 ;mask it with %00000111 to get it in the range of 000 to 111 (0 to 7) add a,l ;4 ;add this value to HL ld l,a ;4 ; jr nc,$+3 ;12|11 ;check if there was overflow to correct inc h ;-- ld a,(hl) ;7 ;get the value of the byte in the LUT and (ix) ;19 ;mask it with the byte of pixels at IX ld (ix-12),a ;19 ;load the updated value into the previous row of pixels inc ix ;10 ;IX is now incremented djnz FireLoop ;13|8 dec c ;4 jr nz,FireLoop;12|7 bcall(_GrBufCpy) ;? ;copy the graph buf to the LCD ld a,(kbdScanCode) ;13 ;read the last read keyboard value by the OS interrupt cp 15 ;7 ;test if CLEAR is pressed jr nz,Main ;12|7 ret ;10 LUT: .db %11111110 .db %11111101 .db %11111011 .db %11110111 .db %11101111 .db %11011111 .db %10111111 .db %01111111</code></pre></div> <br /> So we removed 26&#160;t-states from the main loop and replaced it with 13&#160;t-states the <strong>dec c \ jr nz,FireLoop</strong>executes a total of 3 times all for the same size. So we saved 756*(26-13) t-states in the main loop and in all added 33 extra t-states for no extra cost in size. The total speed savings were 9795&#160;t-states for a total of 86236&#160;t-states for one fire loop. <p><strong>Attempt 3</strong><br /> Every cycle that we optimise out of the main loop translates to 756 cycles saved in all.<br /> Our current routine is straight forward with how IX is being used. On these calculators, the graph buffer is made up of 12-byte rows, so to access the previous row, you use ix-12. However, the IX register is slow and in our uses so far, <em>very slow</em>. The simple ld a,(ix+const) takes 19&#160;t-states and 3 bytes, compared to 7&#160;t-states for ld a,(hl) or ld a,(bc) or ld a,(de) which are 1 byte.<br /> Now we are going to obfuscate our code a little, but hopefully you catch the trick:</p> <div class="code"> <pre><code> ei ;4 Main: ld bc,$F403 ;10 ld de,plotSScreen ;10 Loop: ld hl,LUT ;10 ld a,r ;9 and 7 ;7 add a,l ;4 ld l,a ;4 jr nc,$+3 ;12|11 inc h ;-- ld a,(hl) ;7 ld hl,12 ;10 add hl,de ;11 ;Now HL points to the byte that we want to read, and DE is HL-12... the row above! and (hl) ;7 ld (de),a ;7 inc de ;6 djnz Loop ;13|8 dec c ;4 jr nz,Loop ;12|7 bcall(_GrBufCpy) ;? ;copy the graph buf to the LCD ld a,(kbdScanCode) ;13 ;read the last read keyboard value by the OS interrupt cp 15 ;7 ;test if CLEAR is pressed jr nz,Main ;12|7 ret ;10 LUT: .db %11111110 .db %11111101 .db %11111011 .db %11110111 .db %11101111 .db %11011111 .db %10111111 .db %01111111</code></pre></div> <br /> In all we saved 7 cycles from the main loop and 4 from overhead, saving a total of 5296 more t-states, bringing the speed of the fire code to 80940&#160;t-states at most.<br /> But can we save more? <p><strong>Attempt 4 :</strong> Intermediate<br /> Of course we can make it faster, but now we have to add more code. The part that I am not liking about the code in the main loop is this part:</p> <div class="code"> <pre><code> jr nc,$+3 ;12|11 inc h ;--</code></pre></div> <br /> If we can get rid of that, then we can knock off 12*756&#160;t-states from our calculation and have it precise. Another 9072&#160;t-states sounds worth it, but how can we get rid of it? If we can make sure that our LUT is never within 8 bytes of a 256-byte boundary, we won't need to worry about incrementing H. Luckily, in our current code, we actually don't need to worry about that since the code starts at 9D95h, but what if this was part of a bigger program and we weren't sure precisely where the LUT would end up, or what if it is run from a non-standard location? What we can do, then, is create our LUT elsewhere and if we choose wisely, we can make an even better optimisation! If we make sure L = 0, then add a,l is just A. Our LUT is only 8 bytes, so let's put it in saveSScreen at 8700h: <div class="code"> <pre><code> ld a,7Fh ;7 ;just have 1 bit reset ld hl,8708h ;10 rlca ;4 *8 dec l ;4 *8 ld (hl),a ;7 *8 jr nz,$-3 ;12|7 *8 (12*8-5 in all)</code></pre></div> <br /> There were some tricks there, so to be sure you understand it, not only did we use <strong>dec l</strong>to adjust HL, we also used it as a counter so that we knew when HL = 8700h. We also used rlca to make sure that all of our masks were loaded. Now the optimisations will start to get more difficult to follow: <div class="code"> <pre><code> ld a,7Fh ;7 ;just have 1 bit reset ld hl,8708h ;10 rlca ;4 *8 dec l ;4 *8 ld (hl),a ;7 *8 jr nz,$-3 ;12|7 *8 (12*8-5 in all) ei ;4 Main: ld bc,$F403 ;10 ld de,plotSScreen ;10 Loop: ld h,87h ;7 ld a,r ;9 and 7 ;7 ; add a,l ;4 ld l,a ;4 ; jr nc,$+3 ;12|11 ; inc h ;-- ld a,(hl) ;7 ld hl,12 ;10 add hl,de ;11 ;Now HL points to the byte that we want to read, and DE is HL-12... the row above! and (hl) ;7 ld (de),a ;7 inc de ;6 djnz Loop ;13|8 dec c ;4 jr nz,Loop ;12|7 bcall(_GrBufCpy) ;? ;copy the graph buf to the LCD ld a,(kbdScanCode) ;13 ;read the last read keyboard value by the OS interrupt cp 15 ;7 jr nz,Main ;12|7 ret ;10</code></pre></div> <br /> I commented out the code that we got rid of, and ld hl,LUT turned into an 8-bit load, so we saved 19&#160;t-states from the main loop, but we added in more overhead. Was it worth it?<br /> The overhead code takes 228&#160;t-states but only needs to be copied once, the 19 cycles saved from the main loop save 14364&#160;t-states. Speed-wise, it was very much worth it. Memory-wise, we got rid of 5 bytes in the main loop, and 8 bytes for the built in LUT, and added 10 bytes in overhead, so in all 3 bytes more were saved. It was definitely worth it.<br /> So we currently have a routine that is 66576&#160;t-states, plus a bcall and 32 more t-states to test if clear is pressed. The total size of this program is a tiny 47 bytes and you can expect around 20FPS at 6MHz, since the bcall() takes just under 200&#160;000&#160;t-states. <em>That</em> is pretty good by most standards and will provide a nice, smooth visual graphic. All you should really need to modify now is possibly making a better pseudo-random number generator (PRNG), or, if you are ready to <em>really</em> make it fast, you can move on to the advanced level.<br /> <img src="http://img.omnimaga.org//Z80Fire_3.gif" alt="Z80Fire_3.gif" class="image" /> <p>**Attempt 5 **: Advanced<br /> We will start off with a little modification that will add bytes to the code, but possibly speed things up a little more by getting rid of interrupts. However, this means that our use of kbdScanCode will no longer work since the OS interrupt routine is what updates that. We will need to directly poll the keyboard hardware, but this only adds 18&#160;t-states to the overhead once, and -2&#160;t-state every frame:</p> <div class="code"> <pre><code> di ;4 ;disable interrupts ld a,FDh ;7 ;This is the key group that includes [CLEAR] and [ENTER] out (1),a ;11 ;tell the keyboard to poll that keygroup ;another optimisation-- since A has only 1-bit reset, why not resuse it? ld hl,8708h ;10 rlca ;4 *8 dec l ;4 *8 ld (hl),a ;7 *8 jr nz,$-3 ;12|7 *8 (12*8-5 in all) Main: ld bc,$F403 ;10 ld de,plotSScreen ;10 Loop: ld h,87h ;7 ld a,r ;9 and 7 ;7 ld l,a ;4 ld a,(hl) ;7 ld hl,12 ;10 add hl,de ;11 ;Now HL points to the byte that we want to read, and DE is HL-12... the row above! and (hl) ;7 ld (de),a ;7 inc de ;6 djnz Loop ;13|8 dec c ;4 jr nz,Loop ;12|7 bcall(_GrBufCpy) ;? ;copy the graph buf to the LCD in a,(1) ;11 ;check the keyboard and 40h ;7 ;check if Clear was pressed jr nz,Main ;12|7 ret ;10</code></pre></div> <br /> I cheated, actually. By reusing A in the beginning, I removed 2 bytes and 7-tstates of the dent that we put into the program. The total cost was 2 bytes and 15 tstates, minus 2&#160;t-state for every iteration of fire. <p><strong>Attempt 6</strong> (long intro)<br /> The LCD can be a monster to work with for beginners, so don't worry if you don't quite follow this! What you should understand, though, is that we are working with a particularly slow responding LCD. Many games and graphics programs created for these calcualtors experience a huge bottleneck with dealing with the LCD and that is because you have to wait for some time between each read or write to the LCD. The worst part is that the waiting time is not constant and it is independent of processor speed. This means that regardless of how fast your calc is clocked (6MHz or 15MHz), the LCD will still take a given amount of time to respond and some LCDs will naturally take longer than others (for example, I have two calculators that respond very quickly to most writes, but another that repsonds about 4 times slower).</p> <p>Unfortunately, the OS bcall is not very fast, even compared to 'safecopy' routines written by the community that work on all LCDs. Fortunately, for a routine like this, we get two perks. The first is that running at 15MHz will only slightly boost performance and will just drain more battery power because of the LCD bottleneck (15MHz is better if you don't have any bottlenecks, like when you are just running computations). So we can leave our routine in 6MHz mode and TI-83+ users can enjoy our program just as well as TI-83+SE and TI-84+ users. As well, we can write a much faster LCD updating routine to push the limits of the LCDs ability.</p> <ul> <li>Updating the LCD <ul> <li>To update the whole LCD, we will typically start by writing 80h and 20h to the LCD instruction port, to set the coordinates.</li> <li>We will also need to make sure that the LCD is in the proper increment mode so we write 5 to the LCD port. This will cause the LCD's data pointer to increment downward</li> </ul> </li> </ul> <p>for every read/write to the LCD data port (for us, the Y direction, but the official documents call this the X direction).</p> <ul> <li>Optimisations with code organisation <ul> <li>The wait time between LCD writes is usually around 60&#160;t-states, so the fewer writes that need to be done, the less time will be wasted (and the faster the code will be).</li> <li>We only need to write 5 to the instruction port once to set the mode. So instead of keeping this inside our LCD updating routine, we can keep it outside of the main loop, at the beginning of the program. As well, we usually don't need an LCD delay at the beginning of our program because program loading code usually takes much longer than any necessary delay between LCD writes. However, to be safe&#8230;</li> </ul> </li> </ul> <div class="code"> <pre><code> di ;4 ;disable interrupts ld a,FDh ;7 ;This is the key group that includes [CLEAR] and [ENTER] out (1),a ;11 ;tell the keyboard to poll that keygroup ;another optimisation-- since A has only 1-bit reset, why not resuse it? ld hl,8708h ;10 rlca ;4 *8 dec l ;4 *8 ld (hl),a ;7 *8 jr nz,$-3 ;12|7 *8 (12*8-5 in all) ld a,5 ;7 out (10h),a ;11 ;write A to the LCD Instruction port (port 16) Main: ld bc,$F403 ;10 ld de,plotSScreen ;10 Loop: ld h,87h ;7 ld a,r ;9 and 7 ;7 ld l,a ;4 ld a,(hl) ;7 ld hl,12 ;10 add hl,de ;11 ;Now HL points to the byte that we want to read, and DE is HL-12... the row above! and (hl) ;7 ld (de),a ;7 inc de ;6 djnz Loop ;13|8 dec c ;4 jr nz,Loop ;12|7 ;================= ;Update LCD ;This is a traditional-ish fastcopy routine ;Don't worry about an initial delay. 60000 t-states is more than enough. ld a,80h ;7 set the LCD X coordinate (we would call it Y) to 0 out (16),a ;11 ld hl,plotSScreen ld de,11 ;10 we will use this later to increment HL through plotSScreen line-by-line in a,(16) \ rlca \ jr c,$-3 ;this will wait until the LCD tells us it is ready for another write ld a,20h ;7 this will set the LCD Y-coordinate (we would call it X) col: out (16),a ;11 push af ;11 ld bc,4011h ;10 B=64 (number of pixels tall the screen is), C=11h, corresponding to the LCD Data port row: in a,(16) \ rlca \ jr c,$-3 outi ;16 writes the byte at (hl) to the port pointed to by C, increments HL, decrements B, if B = 0, set z flag add hl,de ;11 HL points to the next line, this doesn't affect the z flag, either jr nz,row ;12|7 in a,(16) \ rlca \ jr c,$-3 pop af ;10 inc a ;4 ;decrement HL by 768 dec h ;4 dec h ;4 dec h ;4 ;increment HL, since L won't go past a 256-byte boundary inc l ;4 cp 2Ch ;7 ;see if we are finished jr nz,col ;12|7 ;================= in a,(1) ;11 ;check the keyboard and 40h ;7 ;check if Clear was pressed jr nz,Main ;12|7 ret ;10</code></pre></div> <br /> Now if you run the code, you will probably notice a significant speed improvement (almost doubling the FPS to around 50), but the cost was 49 more bytes (doubling the size of the code). <p><strong>Attempt 7</strong><br /> Lowering the number of LCD writes can improve performance, so I will point out that if you set the LCD X-coordinate to 0 with 80h and update the LCD, the X-coordiante will wrap around, back to 0 after 64 increments. Interrupts are disabled, so they won't interfere with LCD settings or keyboard settings, so we can put that part of the code outside th main loop. We only save an imperceptible 18&#160;t-states, but it will be useful later and is a useful trick to keep in mind for your own programs.</p> <div class="code"> <pre><code> di ;4 ;disable interrupts ld a,80h ;7 ;set the LCD X coordinate (we would call it Y) to 0 out (16),a ;11 ld a,FDh ;7 ;This is the key group that includes [CLEAR] and [ENTER] out (1),a ;11 ;tell the keyboard to poll that keygroup ;another optimisation-- since A has only 1-bit reset, why not resuse it? ld hl,8708h ;10 rlca ;4 *8 dec l ;4 *8 ld (hl),a ;7 *8 jr nz,$-3 ;12|7 *8 (12*8-5 in all) ld a,5 ;7 out (10h),a ;11 ;write A to the LCD Instruction port (port 16) Main: ld bc,$F403 ;10 ld de,plotSScreen ;10 Loop: ld h,87h ;7 ld a,r ;9 and 7 ;7 ld l,a ;4 ld a,(hl) ;7 ld hl,12 ;10 add hl,de ;11 ;Now HL points to the byte that we want to read, and DE is HL-12... the row above! and (hl) ;7 ld (de),a ;7 inc de ;6 djnz Loop ;13|8 dec c ;4 jr nz,Loop ;12|7 ;================= ;Update LCD ;This is a traditional-ish fastcopy routine ;Don't worry about an initial delay. 60000 t-states is more than enough. ld hl,plotSScreen ld de,11 ;10 we will use this later to increment HL through plotSScreen line-by-line write ld a,20h ;7 this will set the LCD Y-coordinate (we would call it X) col: out (16),a ;11 push af ;11 ld bc,4011h ;10 B=64 (number of pixels tall the screen is), C=11h, corresponding to the LCD Data port row: in a,(16) \ rlca \ jr c,$-3 outi ;16 writes the byte at (hl) to the port pointed to by C, increments HL, decrements B, if B = 0, set z flag add hl,de ;11 HL points to the next line, this doesn't affect the z flag, either jr nz,row ;12|7 in a,(16) \ rlca \ jr c,$-3 pop af ;10 inc a ;4 ;decrement HL by 768 dec h ;4 dec h ;4 dec h ;4 ;increment HL, since L won't go past a 256-byte boundary inc l ;4 cp 2Ch ;7 ;see if we are finished jr nz,col ;12|7 ;================= in a,(1) ;11 ;check the keyboard and 40h ;7 ;check if Clear was pressed jr nz,Main ;12|7 ret ;10</code></pre></div> <br /> Since we don't need an initial delay on our LCD updating code, we actually got rid of even more cycles and 5 bytes. It is difficult to estimate the speed, now, because of the LCD's volatile timings, but we might have saved around 78&#160;t-states on some models on average.<br /> <img src="http://img.omnimaga.org//Z80Fire_6.gif" alt="Z80Fire_6.gif" class="image" /> <p><strong>Attempt 8 :</strong> Expert Level<br /> On the advanced levels, we boosted performance to around double the FPS to 50FPS with a flame animation. On the Expert level, we are going to boost it well beyond what a BASIC programmer would dream of and make a fledgling programmer (intermediate) envy the day they achieve this level. The trick with full screen graphics like this, to boost performance, is to cut out about 50000&#160;t-states which may sound absurd&#8212; that is close to half of our current program! This technique is not often used except in the most crucial situations where speed is of utmost importance because it can get very complicated.</p> <ul> <li>Interleaving an LCD Update <ul> <li>For Graphics, interleaving an LCD update means adding around 10&#160;000&#160;t-states to the part of the code that excludes LCD updating, and removing the LCD updating code. This can be the difference between a 50FPS animation and an 80FPS animation. It essentially involves writing to the LCD at key parts of your normal algorithm in such a way that it provides a substantial delay between writes. The fastest that should be expected from this is around 100FPS to account for particularly slow models.</li> </ul> </li> </ul> <p>To imagine the code, take your LCD updating routine and try to put our flame code in the main loop.</p> <p>Also, just because it makes the code easier, we are finally going to put in code to randomly fill the bottom row of pixels.</p> <div class="code"> <pre><code> di ;4 ;disable interrupts ld a,80h ;7 ;set the LCD X coordinate (we would call it Y) to 0 out (16),a ;11 ld a,FDh ;7 ;This is the key group that includes [CLEAR] and [ENTER] out (1),a ;11 ;tell the keyboard to poll that keygroup ;another optimisation-- since A has only 1-bit reset, why not resuse it? ld hl,8708h ;10 rlca ;4 *8 dec l ;4 *8 ld (hl),a ;7 *8 jr nz,$-3 ;12|7 *8 (12*8-5 in all) ld a,5 ;7 out (10h),a ;11 ;write A to the LCD Instruction port (port 16) in a,(16) \ rlca \ jr c,$-3 ld de,12 Main: ld ix,plotSScreen ;14 ld a,20h ;7 col: out (16),a ;11 push af ;11 ld b,3Fh ;7 row: ld h,87h ;7 ld a,r ;9 and 7 ;7 ld l,a ;4 ld a,(hl) ;7 and (ix+12) ;19 ld (ix),a ;7 add ix,de ;15 out (17),a ;11 ;99 t-states between LCD writes is good for 6MHz djnz row ;13|8 ld a,r ;9 add a,c ;4 ld c,a ;4 ld a,r ;9 adc a,c ;4 ld (ix),a ;19 add ix,de ;15 out (17),a ;11 pop af ;10 dec ixh ;8 dec ixh ;8 dec ixh ;8 inc ixl ;8 inc a ;4 cp 2Ch ;7 jr nz,col ;12|7 ;80 t-states *should* be good enough in a,(1) ;11 ;check the keyboard and 40h ;7 ;check if Clear was pressed jr nz,Main ;12|7 ret ;10</code></pre></div> <br /> So now the main loop takes precisely 76858&#160;t-states which is only about 10000&#160;t-states more than just the fire routine from before (without the LCD update) and should run at about 78FPS at 6MHz. As well, the size is now 98 bytes in total.<br /> Translation: we essentially made the LCD updating code about 10000&#160;t-states which is a huge speed saving. <p><strong>Modifications</strong><br /> One modification that you can do is to have white flames on a black background. The way this will work is you will use an LUT of bytes with only 1 bit set, and instead of using AND logic, you will use OR logic.</p> <p>While having flames rise from the bottom of your screen is kind of cool, a burning image is often a more powerful animation. To do this, we need to somehow keep the image from disappearing while it burns and the simple method for doing this is to redraw the image back on the screen with OR logic. If your image is at AppBackUpScreen, you can include this at the beginning of your main loop:</p> <div class="code"> <pre><code> ld de,AppbackUpScreen+768 ld hl,plotSScreen+768 ld bc,3 ORLoop: dec de dec hl ld a,(de) or (hl) ld (hl),a djnz ORLoop dec c jr nz,ORLoop</code></pre></div> <br /> The cost is 35386&#160;t-states, but HL=plotSScreen by the end of it, so you can use <strong>ex de,hl</strong>directly after it to set DE=plotSScreen instead of using <strong>ld de,plotSScreen</strong>(this is for some of the routines). For the interleaving routine, you can obfuscate your code more by including shadow registers (since interrupts are off): <div class="code"> <pre><code> di ;4 ;disable interrupts ld a,80h ;7 ;set the LCD X coordinate (we would call it Y) to 0 out (16),a ;11 ld a,FDh ;7 ;This is the key group that includes [CLEAR] and [ENTER] out (1),a ;11 ;tell the keyboard to poll that keygroup ld hl,8708h ;10 rlca ;4 *8 dec l ;4 *8 ld (hl),a ;7 *8 jr nz,$-3 ;12|7 *8 (12*8-5 in all) ld de,12 ;10 exx ;4 ld bc,12 ;10 exx ;4 Main: exx ;4 ld de,plotSScreen ;10 ld ix,appBackUpScreen ;10 exx ;4 ld a,20h ;7 col: out (16),a ;11 push af ;11 ld b,3Fh ;7 row: ld h,87h ;7 ld a,r ;9 and 7 ;7 ld l,a ;4 ld a,(hl) ;7 exx ;4 ld h,d ;4 ld l,e ;4 add hl,bc ;11 and (hl) ;7 or (ix) ;19 ld (de),a ;7 ex de,hl ;4 add ix,bc ;15 exx ;4 out (17),a ;11 djnz row ;13|8 exx ;4 ld a,(ix) ;19 ld h,d ;4 ld l,e ;4 add hl,bc ;11 ld (hl),a ;4 add ix,bc ;15 ex de,hl ;4 dec d ;4 out (17),a ;11 dec d ;4 dec d ;4 inc e ;4 exx ;4 pop af ;10 dec ixh ;8 dec ixh ;8 dec ixh ;8 inc ixl ;8 inc a ;4 cp 2Ch ;7 jr nz,col ;12|7 in a,(1) ;11 and 40h ;7 jr nz,Main ;12|7 ret ;10</code></pre></div> <br /> The main fire code is now 105852&#160;t-states, so you can get about 56FPS at 6MHz. You saved 6392&#160;t-states over ORing the two buffers in a separate loop.<br /> <img src="http://img.omnimaga.org//Z80Fire_8.gif" alt="Z80Fire_8.gif" class="image" /> <p><strong>Final Routines</strong><br /> These are the final routines using actual PRNGs for better flames. Speed is decreased quite a bit in some cases, but the flames look nice and that was the goal. These two get about 40FPS and here is the final code for regular flames:</p> <div class="code"> <pre><code>.nolist plotSScreen = 9340h seed = 8008h #define bcall(xx) rst 28h \ .dw xx .list .org 9D93h .db $BB,6Dh di ;4 ;disable interrupts ld hl,8008h ;10 ld a,h ;4 ;set the LCD X coordinate (we would call it Y) to 0 out (16),a ;11 ld a,FDh ;7 ;This is the key group that includes [CLEAR] and [ENTER] out (1),a ;11 ;tell the keyboard to poll that keygroup rlca ;4 *8 dec l ;4 *8 ld (hl),a ;7 *8 jr nz,$-3 ;12|7 *8 (12*8-5 in all) ld de,12 Main: ld ix,plotSScreen ;14 ld a,20h ;7 col: out (16),a ;11 push af ;11 ld b,3Fh ;7 row: ld hl,seed ld a,r ;9 ;get a pseudo-random number in A add a,(hl) ld (seed),a and 7 ;7 ld l,a ;4 ld a,(hl) ;7 and (ix+12) ;19 ld (ix),a ;7 add ix,de ;15 out (17),a ;11 ;99 t-states between LCD writes is good for 6MHz djnz row ;13|8 ld hl,seed ld a,r ;9 ;get a pseudo-random number in A add a,(hl) ld h,a adc a,(hl) ld l,a adc a,(hl) ld (seed),a ld (ix),a ;19 add ix,de ;15 out (17),a ;11 pop af ;10 dec ixh ;8 dec ixh ;8 dec ixh ;8 inc ixl ;8 inc a ;4 cp 2Ch ;7 jr nz,col ;12|7 ;80 t-states *should* be good enough in a,(1) ;11 ;check the keyboard and 40h ;7 ;check if Clear was pressed jr nz,Main ;12|7 ret ;10</code></pre></div> <p>And for using the graph screen as a background image:<br /> (note that this code may be able to run at 15MHz, too, without LCD glitches)</p> <div class="code"> <pre><code>.nolist plotSScreen = 9340h AppBackUpScreen = 9872h seed = 8008h .list .org 9D93h .db $BB,6Dh ld de,AppBackUpScreen ld hl,plotSScreen ld bc,768 ldir di ;4 ;disable interrupts ;another optimisation-- since A has only 1-bit reset, why not resuse it? ld hl,8008h ;10 ld a,h ;4 ;set the LCD X coordinate (we would call it Y) to 0 out (16),a ;11 ld a,FDh ;7 ;This is the key group that includes [CLEAR] and [ENTER] out (1),a ;11 ;tell the keyboard to poll that keygroup rlca ;4 *8 dec l ;4 *8 ld (hl),a ;7 *8 jr nz,$-3 ;12|7 *8 (12*8-5 in all) ld de,12 ;10 exx ;4 ld bc,12 ;10 exx ;4 Main: exx ;4 ld de,plotSScreen ;10 ld ix,appBackUpScreen ;10 exx ;4 ld a,20h ;7 col: out (16),a ;11 push af ;11 ld b,3Fh ;7 row: ld hl,seed ld a,r ;9 ;get a pseudo-random number in A add a,(hl) ld h,a adc a,(hl) ld l,a adc a,(hl) ld (seed),a ld h,80h and 7 ;7 ld l,a ;4 ld a,(hl) ;7 exx ;4 ld h,d ;4 ld l,e ;4 add hl,bc ;11 and (hl) ;7 or (ix) ;19 ld (de),a ;7 ex de,hl ;4 add ix,bc ;15 exx ;4 out (17),a ;11 djnz row ;13|8 exx ;4 ld a,(ix) ;19 ld h,d ;4 ld l,e ;4 add hl,bc ;11 ld (hl),a ;4 add ix,bc ;15 ex de,hl ;4 dec d ;4 out (17),a ;11 dec d ;4 dec d ;4 inc e ;4 exx ;4 pop af ;10 dec ixh ;8 dec ixh ;8 dec ixh ;8 inc ixl ;8 inc a ;4 cp 2Ch ;7 jr nz,col ;12|7 in a,(1) ;11 and 40h ;7 jr nz,Main ;12|7 ret ;10</code></pre></div> <br /> <img src="http://img.omnimaga.org/Z80Fire_9.gif" alt="Z80Fire_9.gif" class="image" /> <p><strong>EDIT:</strong> To the concerned about the omission of writing 5 to the LCD instruction port in the latter routines, the OS already has it in this mode before calling a program. It was only there as a formality and in case others wanted to port this for community OSes or shells that don't leave the calc in this mode.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-665266</guid>
				<title>Graphics</title>
				<link>http://z80-heaven.wikidot.com/forum/t-665266/graphics</link>
				<description>4-level greyscale</description>
				<pubDate>Tue, 25 Jun 2013 17:49:11 +0000</pubDate>
				<wikidot:authorName>The Cow</wikidot:authorName>				<wikidot:authorUserId>1356851</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>I got lazy in my graphics design, so I made a program to convert regular images to 4-level greyscale images in Racket. The source code is below, for anyone who cares.</p> <div class="code"> <pre><code>#lang racket (require picturing-programs) (require racket/math) (require racket/draw) (define (draw image) (define (grey-function x y red green blue) (define n (floor (+ (* .587 green) (* .299 red) (* .114 blue)))) (cond [(&lt; n 42.5) 0] [(&lt; n 127.5) 85] [(&lt; n 212.5) 170] [else 255] )) (map3-image grey-function grey-function grey-function (scale .5 image)))</code></pre></div> <p>I scaled the images down, since the calculator screen is so small. This can be adjusted. The brightness/darkness can be adjusted by changing the 42.5, 127.5, and 212.5.</p> <p>To run the program, you would need an environment (DrRacket). A bit annoying, but oh well.</p> <p>I might make a similar program in Java soon.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-633872</guid>
				<title>Opcode Reference Chart</title>
				<link>http://z80-heaven.wikidot.com/forum/t-633872/opcode-reference-chart</link>
				<description>Permission</description>
				<pubDate>Fri, 15 Mar 2013 03:39:37 +0000</pubDate>
				<wikidot:authorName>The Cow</wikidot:authorName>				<wikidot:authorUserId>1356851</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>@Xeda, I hope you will not mind if I, The Cow, include ZORC (Zeda's Opcode Reference Chart) into this website. I might be convert several simple programs into machine code for demonstration, and this would be a convenience. Is that fine by you? You will be cited as the source.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-633807</guid>
				<title>z80 Mini Challenge</title>
				<link>http://z80-heaven.wikidot.com/forum/t-633807/z80-mini-challenge</link>
				<description>These challenges aren&#039;t meant to be difficult. Instead, they are meant to get you thinking!</description>
				<pubDate>Thu, 14 Mar 2013 21:14:37 +0000</pubDate>
				<wikidot:authorName>Xeda Elnara</wikidot:authorName>				<wikidot:authorUserId>595803</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Okay, so here is my first challenge: Multiply HL by 2100.</p> <p>What is the fastest code you can come up with?<br /> What is the smallest code you can come up with?</p> <p>Alternatively, try this for multiplying HL by 60.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-633735</guid>
				<title>Negative numbers</title>
				<link>http://z80-heaven.wikidot.com/forum/t-633735/negative-numbers</link>
				<description>How do they work?</description>
				<pubDate>Thu, 14 Mar 2013 14:27:48 +0000</pubDate>
				<wikidot:authorName>sourcefolder</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>I am confused on how negative numbers work. For example,</p> <div class="code"> <pre><code>xor a ld b,255;-1? cp b</code></pre></div> <p>Will it count as a being greater or b being greater?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-632934</guid>
				<title>External Links</title>
				<link>http://z80-heaven.wikidot.com/forum/t-632934/external-links</link>
				<description></description>
				<pubDate>Tue, 12 Mar 2013 03:42:08 +0000</pubDate>
				<wikidot:authorName>Xeda Elnara</wikidot:authorName>				<wikidot:authorUserId>595803</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Since The Cow might be restructuring the site, I would like to point out that in the External Links navigation board, , UnitedTI.org is still there. Unfortunately, it closed for good last year. The link now redirects to Cemetech, since ownership was transferred to KermM. The site is in a read-only state, but it still does contain quite a bit of information.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-632926</guid>
				<title>UPDATES</title>
				<link>http://z80-heaven.wikidot.com/forum/t-632926/updates</link>
				<description></description>
				<pubDate>Tue, 12 Mar 2013 03:21:58 +0000</pubDate>
				<wikidot:authorName>The Cow</wikidot:authorName>				<wikidot:authorUserId>1356851</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>The website is recieving major updates. We encourage new members. Basic information can be found on the top and side bars.</p> <p>Please note!: Do not post in the news group unless you have updated the site in a way worth mentioning. Repeated unnecessary posts can result in a ban. You have been warned.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-143713</guid>
				<title>Getting Started</title>
				<link>http://z80-heaven.wikidot.com/forum/t-143713/getting-started</link>
				<description></description>
				<pubDate>Wed, 01 Apr 2009 22:33:58 +0000</pubDate>
				<wikidot:authorName>rhombus p</wikidot:authorName>				<wikidot:authorUserId>240559</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>so, it's kinda ironic, but even though i started the movement over here, i happen to know no Asm, and was wondering were to start.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-143423</guid>
				<title>Emulator&#039;s</title>
				<link>http://z80-heaven.wikidot.com/forum/t-143423/emulator-s</link>
				<description></description>
				<pubDate>Tue, 31 Mar 2009 21:17:54 +0000</pubDate>
				<wikidot:authorName>rhombus p</wikidot:authorName>				<wikidot:authorUserId>240559</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>i added another Emulator to the emulator page and noticed that you didn't have the 84+/SE models included in the supported model section, and i thought you might want to add those. i went ahead and added columns for then since my emulator supports both.</p> <p>EDIT: thought you might want to know that Calcgames is now <a href="http://calcg.org">http://calcg.org</a> for the links page.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-143129</guid>
				<title>new members!!!</title>
				<link>http://z80-heaven.wikidot.com/forum/t-143129/new-members</link>
				<description></description>
				<pubDate>Mon, 30 Mar 2009 22:53:26 +0000</pubDate>
				<wikidot:authorName>rhombus p</wikidot:authorName>				<wikidot:authorUserId>240559</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>hey, i think you'll be happy to know that this site has come to light over at TI|BD, and many people who want to learn asm are coming over here to learn and help out. also, we would like if you wanted your site to partner up with TI|BD and have a premium TI database!</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-11833</guid>
				<title>United Ti</title>
				<link>http://z80-heaven.wikidot.com/forum/t-11833/united-ti</link>
				<description></description>
				<pubDate>Tue, 19 Jun 2007 00:00:35 +0000</pubDate>
				<wikidot:authorName>Baorder54</wikidot:authorName>				<wikidot:authorUserId>9221</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>United Ti Misses you. I am still working on Picasso.</p> <p>Btw, in the contacts page, it says something about a pm, I can't find that though.</p> <p>Edit: oh I see, You said left, not right&#8230;.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-9093</guid>
				<title>Bread Crumbs?</title>
				<link>http://z80-heaven.wikidot.com/forum/t-9093/bread-crumbs</link>
				<description></description>
				<pubDate>Tue, 08 May 2007 04:02:03 +0000</pubDate>
				<wikidot:authorName>Baorder54</wikidot:authorName>				<wikidot:authorUserId>9221</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>5/07 Started of bread-crumbs feature for z80-heaven.</p> <p>But what does this mean?!?</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-8515</guid>
				<title>Flash Apps</title>
				<link>http://z80-heaven.wikidot.com/forum/t-8515/flash-apps</link>
				<description></description>
				<pubDate>Sun, 29 Apr 2007 03:23:38 +0000</pubDate>
				<wikidot:authorName>Baorder54</wikidot:authorName>				<wikidot:authorUserId>9221</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>I've gone through as many tutorials as I can and looked as a bunch of forum topics relating to flash apps, so I started writing that. There is one part that I don't know about the Structure and Overlays, but I am researching that right now.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-7842</guid>
				<title>Forum Rules</title>
				<link>http://z80-heaven.wikidot.com/forum/t-7842/forum-rules</link>
				<description>Read first before posting</description>
				<pubDate>Wed, 18 Apr 2007 00:08:14 +0000</pubDate>
				<wikidot:authorName>WikiGuru</wikidot:authorName>				<wikidot:authorUserId>7176</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>As with any forum, there are a few rules that need to be followed. If they are not, please feel free to change your post, or we will do it for you and give you a warning. If you receive enough warnings (case-by-case), we will happily ban you from the forums and remove all inappropriate materials.</p> <p>1. Respect others</p> <p>It is also strongly discouraged to not make any negative remarks that will attack another's ethnic/cultural/religious affiliation. This includes individuals as well as groups. This does not mean that you can't point out that something is wrong. You must provide some evidence for your reasoning.</p> <p>Ok: I think Bush has a bad Iraq policy, as well as a bad domestic policy.</p> <p>Not OK: Bush is stupid.</p> <p>2. Illicit Materials are strictly forbidden</p> <p>This includes illegal copies of anything, pornography, instructions on assembling anything illegal, and any advertising of products.</p> <p>3. Keep on topic</p> <p>Try to keep on topic as much as possible. If the topic is about creating the ultimate calculator, don't start talking about how bad you did on your English final.</p> <p>4. Profanity</p> <p>Profanity is allowed, but we ask you to not use it or use it in moderation. Find alternative words that express your opinion, but also are not quite as offensive to others.</p> <p>5. Double posting</p> <p>Don't double post. Use the edit button instead. Double posts will be merged with the previous post.</p> <p>6. Repeat Topics</p> <p>If you think your topic is a repeat of one that has already been started, look there first to see if you can find what you need. We don't need 50 topics on who you think is going to win the Super Bowl.</p> <p>Thank you for reading this first. This forum is designed specifically to allow for general coding discussion. This includes TI-Basic, C(++) Java, VB, etc. Please keep this in mind before starting a new topic in this forum. If you think anything is missing, please contact a site administrator.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://z80-heaven.wikidot.com/forum/t-7841</guid>
				<title>Forum Rules</title>
				<link>http://z80-heaven.wikidot.com/forum/t-7841/forum-rules</link>
				<description>See here before posting</description>
				<pubDate>Wed, 18 Apr 2007 00:06:32 +0000</pubDate>
				<wikidot:authorName>WikiGuru</wikidot:authorName>				<wikidot:authorUserId>7176</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>As with any forum, there are a few rules that need to be followed. If they are not, please feel free to change your post, or we will do it for you and give you a warning. If you receive enough warnings (case-by-case), we will happily ban you from the forums and remove all inappropriate materials.</p> <p>1. Respect others</p> <p>It is also strongly discouraged to not make any negative remarks that will attack another's ethnic/cultural/religious affiliation. This includes individuals as well as groups. This does not mean that you can't point out that something is wrong. You must provide some evidence for your reasoning.</p> <p>Ok: I think Bush has a bad Iraq policy, as well as a bad domestic policy.</p> <p>Not OK: Bush is stupid.</p> <p>2. Illicit Materials are strictly forbidden</p> <p>This includes illegal copies of anything, pornography, instructions on assembling anything illegal, and any advertising of products.</p> <p>3. Keep on topic</p> <p>Try to keep on topic as much as possible. If the topic is about creating the ultimate calculator, don't start talking about how bad you did on your English final.</p> <p>4. Profanity</p> <p>Profanity is allowed, but we ask you to not use it or use it in moderation. Find alternative words that express your opinion, but also are not quite as offensive to others.</p> <p>5. Double posting</p> <p>Don't double post. Use the edit button instead. Double posts will be merged with the previous post.</p> <p>6. Repeat Topics</p> <p>If you think your topic is a repeat of one that has already been started, look there first to see if you can find what you need. We don't need 50 topics on who you think is going to win the Super Bowl.</p> <p>Thank you for reading this first. This forum is designed to allow users to give or receive help regarding z80 assembly programming. Please keep that in mind before starting a new topic in this forum. If you think anything is missing, please contact a site administrator.</p> 
				 	]]>
				</content:encoded>							</item>
				</channel>
</rss>