<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="https://wikiti.brandonw.net/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://wikiti.brandonw.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=MateoConLechuga</id>
		<title>WikiTI - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://wikiti.brandonw.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=MateoConLechuga"/>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=Special:Contributions/MateoConLechuga"/>
		<updated>2026-06-09T21:03:57Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.23.5</generator>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Syscalls:00035C</id>
		<title>84PCE:Syscalls:00035C</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Syscalls:00035C"/>
				<updated>2020-09-11T21:22:19Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: Created page with &amp;quot;Sha256Init 00035C - Sha256Init == Synopsis == '''Hypothesized Official Name:''' Sha256Init  '''Sysca...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Syscalls:By Name|Sha256Init]]&lt;br /&gt;
[[Category:84PCE:Syscalls:By Address|00035C - Sha256Init]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Hypothesized Official Name:''' Sha256Init&lt;br /&gt;
&lt;br /&gt;
'''Syscall Address:''' 00035Ch&lt;br /&gt;
&lt;br /&gt;
Initializes the SHA256 hardware.&lt;br /&gt;
&lt;br /&gt;
=== Inputs ===&lt;br /&gt;
* None&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
* None&lt;br /&gt;
&lt;br /&gt;
=== Registers Destroyed ===&lt;br /&gt;
* Assume all&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications</id>
		<title>84PCE:OS:Applications</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications"/>
				<updated>2020-09-11T20:43:45Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Application File Type */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:OS_Information]]&lt;br /&gt;
[[Category:84PCE:OS_Information]]&lt;br /&gt;
==Application File Type==&lt;br /&gt;
Applications for the CE calculator have the extension 8ek.&lt;br /&gt;
&lt;br /&gt;
Relocations exist to place the app correctly in the archive, 6 bytes per block (2+22 bits):&lt;br /&gt;
&lt;br /&gt;
0b00 indicates a reference to the code segment executing from Flash, and 0b10 indicates a reference to the data/bss segment in RAM.&lt;br /&gt;
0b01 and 0b11 are a reserved format; &lt;br /&gt;
&lt;br /&gt;
Applications can be of arbitrary size, no longer multiples of 16kB.&lt;br /&gt;
&lt;br /&gt;
==Applications in the Archive==&lt;br /&gt;
Applications are stored beginning at the address 03B0000h and grow downwards. 3 bytes are used as offsets to the start of the app, since the search is backwards. The following status bytes represent what might be found when parsing for applications:&lt;br /&gt;
&lt;br /&gt;
081h = valid Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
000h = deleted Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
Some search code may look like this (Will locate the start of all the app headers):&lt;br /&gt;
&lt;br /&gt;
 _FindValidLocation:&lt;br /&gt;
 	ld	hl,03B0000h            ; applications start here&lt;br /&gt;
 find:	&lt;br /&gt;
 	dec	hl&lt;br /&gt;
  	dec	hl&lt;br /&gt;
 	dec	hl&lt;br /&gt;
 	push	hl&lt;br /&gt;
 	ld	de,(hl)&lt;br /&gt;
 	ld	hl,0FFFFFFh            ; check for end&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de&lt;br /&gt;
 	pop	hl&lt;br /&gt;
 	ret	z                      ; found end of applications&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de                  ; hl points to the start of the app header here if found&lt;br /&gt;
 	jr	find&lt;br /&gt;
&lt;br /&gt;
The actual App header contains certain fields which correspond to the type of data they represent. TI dropped the ball and even though these are variable length fields, the OS code can only handle headers that are padded to 256 bytes in length.&lt;br /&gt;
&lt;br /&gt;
810(F)h = Master field, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
811(2)h = Signing key ID. On the CE, this is 2 bytes in length with the value 0130Fh, indicating it was signed with the '130F' key.&lt;br /&gt;
&lt;br /&gt;
812(D)h = Version information. Begins with the length of the version string, followed by the string itself. This is a minimum compatible version.&lt;br /&gt;
&lt;br /&gt;
813(2)h = Unknown, but contains the 2 byte data 05900h.&lt;br /&gt;
&lt;br /&gt;
814(N)h = Name of App. In this case, 'N' represents the length of the name in bytes. This field is then followed by the name of the app.&lt;br /&gt;
&lt;br /&gt;
817(F)h = End app header information, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
81A(1)h = Unknown, but contains the 1 byte data 007h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other fields:&lt;br /&gt;
&lt;br /&gt;
003h &amp;amp; 2(6)h &amp;amp; 009h &amp;amp; 0(4)h = Time stamp field. 4 bytes long; represents the number of seconds since January 1st 1997, 00:00:00 in some timezone, and some step of the build process.&lt;br /&gt;
&lt;br /&gt;
00Dh &amp;amp; 0NNh = This (NN) represents how much padding until the next field, as app headers must be padded to 256 bytes.&lt;br /&gt;
&lt;br /&gt;
002h &amp;amp; 03(E)h = Signature field. The is followed by the two bytes containing the value 0100h, the length of the 2048 bit signature&lt;br /&gt;
&lt;br /&gt;
At the end of the signature is 3 bytes representing the size of the application. (These bytes are not included however)&lt;br /&gt;
&lt;br /&gt;
App size calculation is as follows: [Length of master header + offset to signature field in (810)] + [4 bytes of signature field + 256 bytes of signature] + [3 bytes application size]&lt;br /&gt;
&lt;br /&gt;
This is pretty much the same as adding 269 to the value in the big endian master field.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an example of such a header:&lt;br /&gt;
&lt;br /&gt;
 ; Master Field -- This app is 102247 + 269 (102516) bytes in size&lt;br /&gt;
 .db	081h, 00Fh, 000h, 001h, 08fh, 067h&lt;br /&gt;
 ; Signing Key Field&lt;br /&gt;
 .db	081h, 012h, 013h, 00Fh&lt;br /&gt;
 ; Version information -- 00Bh represnets the length until the next field&lt;br /&gt;
 .db	081h, 02Dh, 00Bh, &amp;quot;5.0.0.0089&amp;quot;, 000h&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 032h, 059h, 000h&lt;br /&gt;
 ; Name Field -- Name is 7 bytes long, so that is where the 047h comes from&lt;br /&gt;
 .db	081h, 047h, &amp;quot;CabriJr&amp;quot;&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 0A1h, 007h&lt;br /&gt;
 ; Time stamp -- Who knows what time is was?&lt;br /&gt;
 .db	003h, 026h, 009h, 004h&lt;br /&gt;
 .db	021h, 0BBh, 06Eh, 0DCh&lt;br /&gt;
 ; Amount of pading (This is so, so silly)&lt;br /&gt;
 .db	000h, 00Dh, 0C7h&lt;br /&gt;
 ; Padding of 0C7h (199) bytes&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0&lt;br /&gt;
 ; Final field&lt;br /&gt;
 .db	081h, 07Fh, 000h, 001h, 08Eh, 06dh&lt;br /&gt;
 ; End of 256 byte header&lt;br /&gt;
&lt;br /&gt;
==Additional App Structure==&lt;br /&gt;
&lt;br /&gt;
However, apps are also made up of a certain sequence of bytes following the header. Offsets are calculated from the posistion after the header, in addition to the offsets derived from offsets.&lt;br /&gt;
&lt;br /&gt;
Offset after 256 byte header:&lt;br /&gt;
&lt;br /&gt;
000h = The ASCII string &amp;quot;eZ8&amp;quot;, potentially signifying an eZ80 application&lt;br /&gt;
&lt;br /&gt;
003h = Null terminated Application name (zero padded to be 9 bytes in length with terminator byte)&lt;br /&gt;
&lt;br /&gt;
00Ch = Flag&lt;br /&gt;
&lt;br /&gt;
 [Bit 0 - Disable TI splash screen]&lt;br /&gt;
 [Bit 1 - App can use OpenLib]&lt;br /&gt;
&lt;br /&gt;
00Eh = Flag&lt;br /&gt;
&lt;br /&gt;
 [Bit 0 - Use offset 01Eh for languages]&lt;br /&gt;
 [Bit 1 - Integrated app]&lt;br /&gt;
 [Bit 2 - Unknown]&lt;br /&gt;
 [Bits 3-5 control something]&lt;br /&gt;
&lt;br /&gt;
012h = Main section&lt;br /&gt;
&lt;br /&gt;
015h = Initialized data section (Can be at most 4kB in size)&lt;br /&gt;
&lt;br /&gt;
018h = Initialized data section Length&lt;br /&gt;
&lt;br /&gt;
01Bh = Execution entry point (usually same as 012h)&lt;br /&gt;
&lt;br /&gt;
01Eh = Unknown 3 byte offset used in Language apps (See 00Eh)&lt;br /&gt;
&lt;br /&gt;
021h = Offset to ExecLib jump table&lt;br /&gt;
&lt;br /&gt;
024h = Offset to the string used to display a message in the memory screen (Usually a copyright, i.e. &amp;quot;(c) 2005-2015 Texas Instruments&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
027h = Reserved word&lt;br /&gt;
&lt;br /&gt;
02Ah = Start of relocation table&lt;br /&gt;
&lt;br /&gt;
== ExecLib ==&lt;br /&gt;
&lt;br /&gt;
In order to use ExecLib properly from BASIC programs, you must:&lt;br /&gt;
&lt;br /&gt;
1. Set the proper bit at offset 00Ch.&lt;br /&gt;
&lt;br /&gt;
2. Initialize offset 021h to the start of the library jump table&lt;br /&gt;
&lt;br /&gt;
3. Ensure that the jump table offsets are stored in the relocation table&lt;br /&gt;
&lt;br /&gt;
The format for the jump table is shown below: (Note that you store AppLibraryTable offset to 021h).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;	.db	&amp;quot;LIB&amp;quot;&lt;br /&gt;
	.dl	NUMBER_OF_FUNCTIONS_IN_JUMP_TABLE&lt;br /&gt;
AppLibraryTable:&lt;br /&gt;
	.dl	Function_1&lt;br /&gt;
	.dl	Function_2&lt;br /&gt;
	...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relocations ==&lt;br /&gt;
&lt;br /&gt;
Because apps are stored at a fixed memory address, they require a relocation table to relocate them during sending and defragmentation.&lt;br /&gt;
&lt;br /&gt;
The relocation map consists of a six-byte entry for each location which needs to be updated.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Offset&lt;br /&gt;
! Length&lt;br /&gt;
! Contents&lt;br /&gt;
|-&lt;br /&gt;
| 000h&lt;br /&gt;
| 003h&lt;br /&gt;
| Hole offset&lt;br /&gt;
|-&lt;br /&gt;
| 003h&lt;br /&gt;
| 003h&lt;br /&gt;
| base (2 bits) and relative value to place in hole (22 bits)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''Relocation Map Format'''&lt;br /&gt;
&lt;br /&gt;
The hole offset specifies where in the application code or initial data table an absolute address needs to be updated.&lt;br /&gt;
The value to store in the hole is calculated from the base and relative value. The base is 00 for code-segment relative and 10 for data-segment relative. Base values 01 and 11 are reserved.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
Here is a full demo program demonstrating finding each application, displaying the name, size, version, and copyright information&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;quot;ti84pce.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	.db	tExtTok,tAsm84CECmp&lt;br /&gt;
	.org	usermem&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
; Finds all the apps and displays info&lt;br /&gt;
_FINDAPPS:&lt;br /&gt;
	ld	ix,0&lt;br /&gt;
	add	ix,sp&lt;br /&gt;
	ld	hl,ExecuteApp&lt;br /&gt;
	ld	de,cursorImage&lt;br /&gt;
	ld	bc,ExecuteApp_End-ExecuteApp_Start&lt;br /&gt;
	ldir&lt;br /&gt;
	call	_ZeroOP3&lt;br /&gt;
	ld	a,appObj&lt;br /&gt;
	ld	(OP3),a&lt;br /&gt;
_:	call	_HomeUp&lt;br /&gt;
	call	_ClrScrn&lt;br /&gt;
	call	_OP3ToOP1&lt;br /&gt;
	call	_FindAppUp		; find the app&lt;br /&gt;
	ret	c&lt;br /&gt;
	call	_OP1ToOP3		; store name&lt;br /&gt;
	ld	hl,OP1+1&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_PutS			; put name of app&lt;br /&gt;
	pop	hl			; don't need this push/pop (here for readability)&lt;br /&gt;
	call	_FindAppStart		; find the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	GetAppSize&lt;br /&gt;
	call	_DispHL			; display the size of the app&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_os_GetAppVersionString&lt;br /&gt;
	pop	bc&lt;br /&gt;
	call	_PutS&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	call	FindAppInfoString	; Get the information&lt;br /&gt;
	call	_PutS&lt;br /&gt;
_:	call	_GetCSC&lt;br /&gt;
	or	a,a&lt;br /&gt;
	jr	z,-_&lt;br /&gt;
	cp	a,sk2nd&lt;br /&gt;
	jr	nz,--_&lt;br /&gt;
	ld	hl,OP3+1&lt;br /&gt;
	jp	cursorImage&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
ExecuteApp:&lt;br /&gt;
; HL -&amp;gt; name of app (0 terminated)&lt;br /&gt;
	.org	cursorImage&lt;br /&gt;
ExecuteApp_Start:&lt;br /&gt;
	ld	de,progToEdit&lt;br /&gt;
	ld	bc,8&lt;br /&gt;
	ldir&lt;br /&gt;
	ld	a,cxExtApps&lt;br /&gt;
	jp	_NewContext&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindAppInfoString:&lt;br /&gt;
; Finds the information string about an App&lt;br /&gt;
; i.e. (c) 2005-2014 Texas Instruments&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains start of app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$24&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)			; load location of info string&lt;br /&gt;
	add	hl,de &lt;br /&gt;
	or	a,a &lt;br /&gt;
	sbc	hl,de			; check if HL is 0&lt;br /&gt;
	ret	z&lt;br /&gt;
	add	hl,de			; add extra bytes&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindStartOfAppCode:&lt;br /&gt;
; Finds the start of the actual executable from the start of an App&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains the start of the app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$1B			; offset&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
DeletePgrmFromUserMem:&lt;br /&gt;
	ld	de,(asm_prgm_size)	; load total program prgmSize&lt;br /&gt;
	or	a,a&lt;br /&gt;
	sbc	hl,hl&lt;br /&gt;
	ld	(asm_prgm_size),hl	; delete whatever current program was there&lt;br /&gt;
	ld	hl,userMem&lt;br /&gt;
	jp	_DelMem			; HL-&amp;gt;place to delete, DE=amount to delete&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
GetAppSize:&lt;br /&gt;
; Gets the size of an app based from the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_NextFieldFromType	; move to start of signature&lt;br /&gt;
	call	_NextFieldFromType	; move to end of signature&lt;br /&gt;
	pop	de&lt;br /&gt;
	or	a&lt;br /&gt;
	sbc	hl,de&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl			; bypass app size bytes&lt;br /&gt;
	ret				; haha, we're probably looking at another app here&lt;br /&gt;
ExecuteApp_End:&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Credits and Contribution==&lt;br /&gt;
Matt &amp;quot;MateoConLechuga&amp;quot; Waltz&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications</id>
		<title>84PCE:OS:Applications</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications"/>
				<updated>2018-10-27T01:07:15Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Relocations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:OS_Information]]&lt;br /&gt;
[[Category:84PCE:OS_Information]]&lt;br /&gt;
==Application File Type==&lt;br /&gt;
Applications for the CE calculator have the extension 8ek.&lt;br /&gt;
&lt;br /&gt;
Relocations exist to place the app correctly in the archive, 6 bytes per block (2+22 bits):&lt;br /&gt;
&lt;br /&gt;
0b00 indicates a reference to the code segment executing from Flash, and 0b10 indicates a reference to the data/bss segment in RAM.&lt;br /&gt;
0b01 and 0b11 are a reserved format; &lt;br /&gt;
&lt;br /&gt;
Applications can be of arbitrary size, no longer multiples of 16kB.&lt;br /&gt;
&lt;br /&gt;
You can find code for creating an application; along with other fancy items [https://github.com/mateoconlechuga/app-inc here]&lt;br /&gt;
&lt;br /&gt;
==Applications in the Archive==&lt;br /&gt;
Applications are stored beginning at the address 03B0000h and grow downwards. 3 bytes are used as offsets to the start of the app, since the search is backwards. The following status bytes represent what might be found when parsing for applications:&lt;br /&gt;
&lt;br /&gt;
081h = valid Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
000h = deleted Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
Some search code may look like this (Will locate the start of all the app headers):&lt;br /&gt;
&lt;br /&gt;
 _FindValidLocation:&lt;br /&gt;
 	ld	hl,03B0000h            ; applications start here&lt;br /&gt;
 find:	&lt;br /&gt;
 	dec	hl&lt;br /&gt;
  	dec	hl&lt;br /&gt;
 	dec	hl&lt;br /&gt;
 	push	hl&lt;br /&gt;
 	ld	de,(hl)&lt;br /&gt;
 	ld	hl,0FFFFFFh            ; check for end&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de&lt;br /&gt;
 	pop	hl&lt;br /&gt;
 	ret	z                      ; found end of applications&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de                  ; hl points to the start of the app header here if found&lt;br /&gt;
 	jr	find&lt;br /&gt;
&lt;br /&gt;
The actual App header contains certain fields which correspond to the type of data they represent. TI dropped the ball and even though these are variable length fields, the OS code can only handle headers that are padded to 256 bytes in length.&lt;br /&gt;
&lt;br /&gt;
810(F)h = Master field, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
811(2)h = Signing key ID. On the CE, this is 2 bytes in length with the value 0130Fh, indicating it was signed with the '130F' key.&lt;br /&gt;
&lt;br /&gt;
812(D)h = Version information. Begins with the length of the version string, followed by the string itself. This is a minimum compatible version.&lt;br /&gt;
&lt;br /&gt;
813(2)h = Unknown, but contains the 2 byte data 05900h.&lt;br /&gt;
&lt;br /&gt;
814(N)h = Name of App. In this case, 'N' represents the length of the name in bytes. This field is then followed by the name of the app.&lt;br /&gt;
&lt;br /&gt;
817(F)h = End app header information, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
81A(1)h = Unknown, but contains the 1 byte data 007h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other fields:&lt;br /&gt;
&lt;br /&gt;
003h &amp;amp; 2(6)h &amp;amp; 009h &amp;amp; 0(4)h = Time stamp field. 4 bytes long; represents the number of seconds since January 1st 1997, 00:00:00 in some timezone, and some step of the build process.&lt;br /&gt;
&lt;br /&gt;
00Dh &amp;amp; 0NNh = This (NN) represents how much padding until the next field, as app headers must be padded to 256 bytes.&lt;br /&gt;
&lt;br /&gt;
002h &amp;amp; 03(E)h = Signature field. The is followed by the two bytes containing the value 0100h, the length of the 2048 bit signature&lt;br /&gt;
&lt;br /&gt;
At the end of the signature is 3 bytes representing the size of the application. (These bytes are not included however)&lt;br /&gt;
&lt;br /&gt;
App size calculation is as follows: [Length of master header + offset to signature field in (810)] + [4 bytes of signature field + 256 bytes of signature] + [3 bytes application size]&lt;br /&gt;
&lt;br /&gt;
This is pretty much the same as adding 269 to the value in the big endian master field.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an example of such a header:&lt;br /&gt;
&lt;br /&gt;
 ; Master Field -- This app is 102247 + 269 (102516) bytes in size&lt;br /&gt;
 .db	081h, 00Fh, 000h, 001h, 08fh, 067h&lt;br /&gt;
 ; Signing Key Field&lt;br /&gt;
 .db	081h, 012h, 013h, 00Fh&lt;br /&gt;
 ; Version information -- 00Bh represnets the length until the next field&lt;br /&gt;
 .db	081h, 02Dh, 00Bh, &amp;quot;5.0.0.0089&amp;quot;, 000h&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 032h, 059h, 000h&lt;br /&gt;
 ; Name Field -- Name is 7 bytes long, so that is where the 047h comes from&lt;br /&gt;
 .db	081h, 047h, &amp;quot;CabriJr&amp;quot;&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 0A1h, 007h&lt;br /&gt;
 ; Time stamp -- Who knows what time is was?&lt;br /&gt;
 .db	003h, 026h, 009h, 004h&lt;br /&gt;
 .db	021h, 0BBh, 06Eh, 0DCh&lt;br /&gt;
 ; Amount of pading (This is so, so silly)&lt;br /&gt;
 .db	000h, 00Dh, 0C7h&lt;br /&gt;
 ; Padding of 0C7h (199) bytes&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0&lt;br /&gt;
 ; Final field&lt;br /&gt;
 .db	081h, 07Fh, 000h, 001h, 08Eh, 06dh&lt;br /&gt;
 ; End of 256 byte header&lt;br /&gt;
&lt;br /&gt;
==Additional App Structure==&lt;br /&gt;
&lt;br /&gt;
However, apps are also made up of a certain sequence of bytes following the header. Offsets are calculated from the posistion after the header, in addition to the offsets derived from offsets.&lt;br /&gt;
&lt;br /&gt;
Offset after 256 byte header:&lt;br /&gt;
&lt;br /&gt;
000h = The ASCII string &amp;quot;eZ8&amp;quot;, potentially signifying an eZ80 application&lt;br /&gt;
&lt;br /&gt;
003h = Null terminated Application name (zero padded to be 9 bytes in length with terminator byte)&lt;br /&gt;
&lt;br /&gt;
00Ch = Flag&lt;br /&gt;
&lt;br /&gt;
 [Bit 0 - Disable TI splash screen]&lt;br /&gt;
 [Bit 1 - App can use OpenLib]&lt;br /&gt;
&lt;br /&gt;
00Eh = Flag&lt;br /&gt;
&lt;br /&gt;
 [Bit 0 - Use offset 01Eh for languages]&lt;br /&gt;
 [Bit 1 - Integrated app]&lt;br /&gt;
 [Bit 2 - Unknown]&lt;br /&gt;
 [Bits 3-5 control something]&lt;br /&gt;
&lt;br /&gt;
012h = Main section&lt;br /&gt;
&lt;br /&gt;
015h = Initialized data section (Can be at most 4kB in size)&lt;br /&gt;
&lt;br /&gt;
018h = Initialized data section Length&lt;br /&gt;
&lt;br /&gt;
01Bh = Execution entry point (usually same as 012h)&lt;br /&gt;
&lt;br /&gt;
01Eh = Unknown 3 byte offset used in Language apps (See 00Eh)&lt;br /&gt;
&lt;br /&gt;
021h = Offset to ExecLib jump table&lt;br /&gt;
&lt;br /&gt;
024h = Offset to the string used to display a message in the memory screen (Usually a copyright, i.e. &amp;quot;(c) 2005-2015 Texas Instruments&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
027h = Reserved word&lt;br /&gt;
&lt;br /&gt;
02Ah = Start of relocation table&lt;br /&gt;
&lt;br /&gt;
== ExecLib ==&lt;br /&gt;
&lt;br /&gt;
In order to use ExecLib properly from BASIC programs, you must:&lt;br /&gt;
&lt;br /&gt;
1. Set the proper bit at offset 00Ch.&lt;br /&gt;
&lt;br /&gt;
2. Initialize offset 021h to the start of the library jump table&lt;br /&gt;
&lt;br /&gt;
3. Ensure that the jump table offsets are stored in the relocation table&lt;br /&gt;
&lt;br /&gt;
The format for the jump table is shown below: (Note that you store AppLibraryTable offset to 021h).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;	.db	&amp;quot;LIB&amp;quot;&lt;br /&gt;
	.dl	NUMBER_OF_FUNCTIONS_IN_JUMP_TABLE&lt;br /&gt;
AppLibraryTable:&lt;br /&gt;
	.dl	Function_1&lt;br /&gt;
	.dl	Function_2&lt;br /&gt;
	...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relocations ==&lt;br /&gt;
&lt;br /&gt;
Because apps are stored at a fixed memory address, they require a relocation table to relocate them during sending and defragmentation.&lt;br /&gt;
&lt;br /&gt;
The relocation map consists of a six-byte entry for each location which needs to be updated.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Offset&lt;br /&gt;
! Length&lt;br /&gt;
! Contents&lt;br /&gt;
|-&lt;br /&gt;
| 000h&lt;br /&gt;
| 003h&lt;br /&gt;
| Hole offset&lt;br /&gt;
|-&lt;br /&gt;
| 003h&lt;br /&gt;
| 003h&lt;br /&gt;
| base (2 bits) and relative value to place in hole (22 bits)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''Relocation Map Format'''&lt;br /&gt;
&lt;br /&gt;
The hole offset specifies where in the application code or initial data table an absolute address needs to be updated.&lt;br /&gt;
The value to store in the hole is calculated from the base and relative value. The base is 00 for code-segment relative and 10 for data-segment relative. Base values 01 and 11 are reserved.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
Here is a full demo program demonstrating finding each application, displaying the name, size, version, and copyright information&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;quot;ti84pce.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	.db	tExtTok,tAsm84CECmp&lt;br /&gt;
	.org	usermem&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
; Finds all the apps and displays info&lt;br /&gt;
_FINDAPPS:&lt;br /&gt;
	ld	ix,0&lt;br /&gt;
	add	ix,sp&lt;br /&gt;
	ld	hl,ExecuteApp&lt;br /&gt;
	ld	de,cursorImage&lt;br /&gt;
	ld	bc,ExecuteApp_End-ExecuteApp_Start&lt;br /&gt;
	ldir&lt;br /&gt;
	call	_ZeroOP3&lt;br /&gt;
	ld	a,appObj&lt;br /&gt;
	ld	(OP3),a&lt;br /&gt;
_:	call	_HomeUp&lt;br /&gt;
	call	_ClrScrn&lt;br /&gt;
	call	_OP3ToOP1&lt;br /&gt;
	call	_FindAppUp		; find the app&lt;br /&gt;
	ret	c&lt;br /&gt;
	call	_OP1ToOP3		; store name&lt;br /&gt;
	ld	hl,OP1+1&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_PutS			; put name of app&lt;br /&gt;
	pop	hl			; don't need this push/pop (here for readability)&lt;br /&gt;
	call	_FindAppStart		; find the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	GetAppSize&lt;br /&gt;
	call	_DispHL			; display the size of the app&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_os_GetAppVersionString&lt;br /&gt;
	pop	bc&lt;br /&gt;
	call	_PutS&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	call	FindAppInfoString	; Get the information&lt;br /&gt;
	call	_PutS&lt;br /&gt;
_:	call	_GetCSC&lt;br /&gt;
	or	a,a&lt;br /&gt;
	jr	z,-_&lt;br /&gt;
	cp	a,sk2nd&lt;br /&gt;
	jr	nz,--_&lt;br /&gt;
	ld	hl,OP3+1&lt;br /&gt;
	jp	cursorImage&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
ExecuteApp:&lt;br /&gt;
; HL -&amp;gt; name of app (0 terminated)&lt;br /&gt;
	.org	cursorImage&lt;br /&gt;
ExecuteApp_Start:&lt;br /&gt;
	ld	de,progToEdit&lt;br /&gt;
	ld	bc,8&lt;br /&gt;
	ldir&lt;br /&gt;
	ld	a,cxExtApps&lt;br /&gt;
	jp	_NewContext&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindAppInfoString:&lt;br /&gt;
; Finds the information string about an App&lt;br /&gt;
; i.e. (c) 2005-2014 Texas Instruments&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains start of app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$24&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)			; load location of info string&lt;br /&gt;
	add	hl,de &lt;br /&gt;
	or	a,a &lt;br /&gt;
	sbc	hl,de			; check if HL is 0&lt;br /&gt;
	ret	z&lt;br /&gt;
	add	hl,de			; add extra bytes&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindStartOfAppCode:&lt;br /&gt;
; Finds the start of the actual executable from the start of an App&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains the start of the app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$1B			; offset&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
DeletePgrmFromUserMem:&lt;br /&gt;
	ld	de,(asm_prgm_size)	; load total program prgmSize&lt;br /&gt;
	or	a,a&lt;br /&gt;
	sbc	hl,hl&lt;br /&gt;
	ld	(asm_prgm_size),hl	; delete whatever current program was there&lt;br /&gt;
	ld	hl,userMem&lt;br /&gt;
	jp	_DelMem			; HL-&amp;gt;place to delete, DE=amount to delete&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
GetAppSize:&lt;br /&gt;
; Gets the size of an app based from the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_NextFieldFromType	; move to start of signature&lt;br /&gt;
	call	_NextFieldFromType	; move to end of signature&lt;br /&gt;
	pop	de&lt;br /&gt;
	or	a&lt;br /&gt;
	sbc	hl,de&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl			; bypass app size bytes&lt;br /&gt;
	ret				; haha, we're probably looking at another app here&lt;br /&gt;
ExecuteApp_End:&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Credits and Contribution==&lt;br /&gt;
Matt &amp;quot;MateoConLechuga&amp;quot; Waltz&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:OS:Certificate</id>
		<title>84PCE:OS:Certificate</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:OS:Certificate"/>
				<updated>2017-10-18T23:26:43Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Certificate Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:OS_Information]]&lt;br /&gt;
==Certificate Overview==&lt;br /&gt;
The certificate is a critical region of flash memory which holds information that should persist across reboots and resets. It can be entirely cleared and reset; as is demonstrated by the bootcode itself. The following discusses particular fields and structures contained within the certificate.&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:OS:Certificate</id>
		<title>84PCE:OS:Certificate</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:OS:Certificate"/>
				<updated>2017-10-18T23:26:23Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: Created page with &amp;quot;Category:84PCE:OS_Information ==Certificate Overview== The certificate is a critical region of flash memory which stores critical information that should persist across re...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:OS_Information]]&lt;br /&gt;
==Certificate Overview==&lt;br /&gt;
The certificate is a critical region of flash memory which stores critical information that should persist across reboots and resets. It can be entirely cleared and reset; as is demonstrated by the bootcode itself. The following discusses particular fields and structures contained within the certificate.&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications</id>
		<title>84PCE:OS:Applications</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications"/>
				<updated>2017-10-16T06:27:07Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Additional App Structure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:OS_Information]]&lt;br /&gt;
[[Category:84PCE:OS_Information]]&lt;br /&gt;
==Application File Type==&lt;br /&gt;
Applications for the CE calculator have the extension 8ek.&lt;br /&gt;
&lt;br /&gt;
Relocations exist to place the app correctly in the archive, 6 bytes per block (2+22 bits):&lt;br /&gt;
&lt;br /&gt;
0b00 indicates a reference to the code segment executing from Flash, and 0b10 indicates a reference to the data/bss segment in RAM.&lt;br /&gt;
0b01 and 0b11 are a reserved format; &lt;br /&gt;
&lt;br /&gt;
Applications can be of arbitrary size, no longer multiples of 16kB.&lt;br /&gt;
&lt;br /&gt;
You can find code for creating an application; along with other fancy items [https://github.com/mateoconlechuga/app-inc here]&lt;br /&gt;
&lt;br /&gt;
==Applications in the Archive==&lt;br /&gt;
Applications are stored beginning at the address 03B0000h and grow downwards. 3 bytes are used as offsets to the start of the app, since the search is backwards. The following status bytes represent what might be found when parsing for applications:&lt;br /&gt;
&lt;br /&gt;
081h = valid Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
000h = deleted Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
Some search code may look like this (Will locate the start of all the app headers):&lt;br /&gt;
&lt;br /&gt;
 _FindValidLocation:&lt;br /&gt;
 	ld	hl,03B0000h            ; applications start here&lt;br /&gt;
 find:	&lt;br /&gt;
 	dec	hl&lt;br /&gt;
  	dec	hl&lt;br /&gt;
 	dec	hl&lt;br /&gt;
 	push	hl&lt;br /&gt;
 	ld	de,(hl)&lt;br /&gt;
 	ld	hl,0FFFFFFh            ; check for end&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de&lt;br /&gt;
 	pop	hl&lt;br /&gt;
 	ret	z                      ; found end of applications&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de                  ; hl points to the start of the app header here if found&lt;br /&gt;
 	jr	find&lt;br /&gt;
&lt;br /&gt;
The actual App header contains certain fields which correspond to the type of data they represent. TI dropped the ball and even though these are variable length fields, the OS code can only handle headers that are padded to 256 bytes in length.&lt;br /&gt;
&lt;br /&gt;
810(F)h = Master field, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
811(2)h = Signing key ID. On the CE, this is 2 bytes in length with the value 0130Fh, indicating it was signed with the '130F' key.&lt;br /&gt;
&lt;br /&gt;
812(D)h = Version information. Begins with the length of the version string, followed by the string itself. This is a minimum compatible version.&lt;br /&gt;
&lt;br /&gt;
813(2)h = Unknown, but contains the 2 byte data 05900h.&lt;br /&gt;
&lt;br /&gt;
814(N)h = Name of App. In this case, 'N' represents the length of the name in bytes. This field is then followed by the name of the app.&lt;br /&gt;
&lt;br /&gt;
817(F)h = End app header information, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
81A(1)h = Unknown, but contains the 1 byte data 007h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other fields:&lt;br /&gt;
&lt;br /&gt;
003h &amp;amp; 2(6)h &amp;amp; 009h &amp;amp; 0(4)h = Time stamp field. 4 bytes long; represents the number of seconds since January 1st 1997, 00:00:00 in some timezone, and some step of the build process.&lt;br /&gt;
&lt;br /&gt;
00Dh &amp;amp; 0NNh = This (NN) represents how much padding until the next field, as app headers must be padded to 256 bytes.&lt;br /&gt;
&lt;br /&gt;
002h &amp;amp; 03(E)h = Signature field. The is followed by the two bytes containing the value 0100h, the length of the 2048 bit signature&lt;br /&gt;
&lt;br /&gt;
At the end of the signature is 3 bytes representing the size of the application. (These bytes are not included however)&lt;br /&gt;
&lt;br /&gt;
App size calculation is as follows: [Length of master header + offset to signature field in (810)] + [4 bytes of signature field + 256 bytes of signature] + [3 bytes application size]&lt;br /&gt;
&lt;br /&gt;
This is pretty much the same as adding 269 to the value in the big endian master field.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an example of such a header:&lt;br /&gt;
&lt;br /&gt;
 ; Master Field -- This app is 102247 + 269 (102516) bytes in size&lt;br /&gt;
 .db	081h, 00Fh, 000h, 001h, 08fh, 067h&lt;br /&gt;
 ; Signing Key Field&lt;br /&gt;
 .db	081h, 012h, 013h, 00Fh&lt;br /&gt;
 ; Version information -- 00Bh represnets the length until the next field&lt;br /&gt;
 .db	081h, 02Dh, 00Bh, &amp;quot;5.0.0.0089&amp;quot;, 000h&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 032h, 059h, 000h&lt;br /&gt;
 ; Name Field -- Name is 7 bytes long, so that is where the 047h comes from&lt;br /&gt;
 .db	081h, 047h, &amp;quot;CabriJr&amp;quot;&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 0A1h, 007h&lt;br /&gt;
 ; Time stamp -- Who knows what time is was?&lt;br /&gt;
 .db	003h, 026h, 009h, 004h&lt;br /&gt;
 .db	021h, 0BBh, 06Eh, 0DCh&lt;br /&gt;
 ; Amount of pading (This is so, so silly)&lt;br /&gt;
 .db	000h, 00Dh, 0C7h&lt;br /&gt;
 ; Padding of 0C7h (199) bytes&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0&lt;br /&gt;
 ; Final field&lt;br /&gt;
 .db	081h, 07Fh, 000h, 001h, 08Eh, 06dh&lt;br /&gt;
 ; End of 256 byte header&lt;br /&gt;
&lt;br /&gt;
==Additional App Structure==&lt;br /&gt;
&lt;br /&gt;
However, apps are also made up of a certain sequence of bytes following the header. Offsets are calculated from the posistion after the header, in addition to the offsets derived from offsets.&lt;br /&gt;
&lt;br /&gt;
Offset after 256 byte header:&lt;br /&gt;
&lt;br /&gt;
000h = The ASCII string &amp;quot;eZ8&amp;quot;, potentially signifying an eZ80 application&lt;br /&gt;
&lt;br /&gt;
003h = Null terminated Application name (zero padded to be 9 bytes in length with terminator byte)&lt;br /&gt;
&lt;br /&gt;
00Ch = Flag&lt;br /&gt;
&lt;br /&gt;
 [Bit 0 - Disable TI splash screen]&lt;br /&gt;
 [Bit 1 - App can use OpenLib]&lt;br /&gt;
&lt;br /&gt;
00Eh = Flag&lt;br /&gt;
&lt;br /&gt;
 [Bit 0 - Use offset 01Eh for languages]&lt;br /&gt;
 [Bit 1 - Integrated app]&lt;br /&gt;
 [Bit 2 - Unknown]&lt;br /&gt;
 [Bits 3-5 control something]&lt;br /&gt;
&lt;br /&gt;
012h = Main section&lt;br /&gt;
&lt;br /&gt;
015h = Initialized data section (Can be at most 4kB in size)&lt;br /&gt;
&lt;br /&gt;
018h = Initialized data section Length&lt;br /&gt;
&lt;br /&gt;
01Bh = Execution entry point (usually same as 012h)&lt;br /&gt;
&lt;br /&gt;
01Eh = Unknown 3 byte offset used in Language apps (See 00Eh)&lt;br /&gt;
&lt;br /&gt;
021h = Offset to ExecLib jump table&lt;br /&gt;
&lt;br /&gt;
024h = Offset to the string used to display a message in the memory screen (Usually a copyright, i.e. &amp;quot;(c) 2005-2015 Texas Instruments&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
027h = Reserved word&lt;br /&gt;
&lt;br /&gt;
02Ah = Start of relocation table&lt;br /&gt;
&lt;br /&gt;
== ExecLib ==&lt;br /&gt;
&lt;br /&gt;
In order to use ExecLib properly from BASIC programs, you must:&lt;br /&gt;
&lt;br /&gt;
1. Set the proper bit at offset 00Ch.&lt;br /&gt;
&lt;br /&gt;
2. Initialize offset 021h to the start of the library jump table&lt;br /&gt;
&lt;br /&gt;
3. Ensure that the jump table offsets are stored in the relocation table&lt;br /&gt;
&lt;br /&gt;
The format for the jump table is shown below: (Note that you store AppLibraryTable offset to 021h).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;	.db	&amp;quot;LIB&amp;quot;&lt;br /&gt;
	.dl	NUMBER_OF_FUNCTIONS_IN_JUMP_TABLE&lt;br /&gt;
AppLibraryTable:&lt;br /&gt;
	.dl	Function_1&lt;br /&gt;
	.dl	Function_2&lt;br /&gt;
	...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relocations ==&lt;br /&gt;
&lt;br /&gt;
Because apps are not stored at a fixed memory address, they require a relocation table to relocate them during sending and defragmentation.&lt;br /&gt;
&lt;br /&gt;
The relocation map consists of a six-byte entry for each location which needs to be updated.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Offset&lt;br /&gt;
! Length&lt;br /&gt;
! Contents&lt;br /&gt;
|-&lt;br /&gt;
| 000h&lt;br /&gt;
| 003h&lt;br /&gt;
| Hole offset&lt;br /&gt;
|-&lt;br /&gt;
| 003h&lt;br /&gt;
| 003h&lt;br /&gt;
| base (2 bits) and relative value to place in hole (22 bits)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''Relocation Map Format'''&lt;br /&gt;
&lt;br /&gt;
The hole offset specifies where in the application code or initial data table an absolute address needs to be updated.&lt;br /&gt;
The value to store in the hole is calculated from the base and relative value. The base is 00 for code-segment relative and 10 for data-segment relative. Base values 01 and 11 are reserved.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
Here is a full demo program demonstrating finding each application, displaying the name, size, version, and copyright information&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;quot;ti84pce.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	.db	tExtTok,tAsm84CECmp&lt;br /&gt;
	.org	usermem&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
; Finds all the apps and displays info&lt;br /&gt;
_FINDAPPS:&lt;br /&gt;
	ld	ix,0&lt;br /&gt;
	add	ix,sp&lt;br /&gt;
	ld	hl,ExecuteApp&lt;br /&gt;
	ld	de,cursorImage&lt;br /&gt;
	ld	bc,ExecuteApp_End-ExecuteApp_Start&lt;br /&gt;
	ldir&lt;br /&gt;
	call	_ZeroOP3&lt;br /&gt;
	ld	a,appObj&lt;br /&gt;
	ld	(OP3),a&lt;br /&gt;
_:	call	_HomeUp&lt;br /&gt;
	call	_ClrScrn&lt;br /&gt;
	call	_OP3ToOP1&lt;br /&gt;
	call	_FindAppUp		; find the app&lt;br /&gt;
	ret	c&lt;br /&gt;
	call	_OP1ToOP3		; store name&lt;br /&gt;
	ld	hl,OP1+1&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_PutS			; put name of app&lt;br /&gt;
	pop	hl			; don't need this push/pop (here for readability)&lt;br /&gt;
	call	_FindAppStart		; find the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	GetAppSize&lt;br /&gt;
	call	_DispHL			; display the size of the app&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_os_GetAppVersionString&lt;br /&gt;
	pop	bc&lt;br /&gt;
	call	_PutS&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	call	FindAppInfoString	; Get the information&lt;br /&gt;
	call	_PutS&lt;br /&gt;
_:	call	_GetCSC&lt;br /&gt;
	or	a,a&lt;br /&gt;
	jr	z,-_&lt;br /&gt;
	cp	a,sk2nd&lt;br /&gt;
	jr	nz,--_&lt;br /&gt;
	ld	hl,OP3+1&lt;br /&gt;
	jp	cursorImage&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
ExecuteApp:&lt;br /&gt;
; HL -&amp;gt; name of app (0 terminated)&lt;br /&gt;
	.org	cursorImage&lt;br /&gt;
ExecuteApp_Start:&lt;br /&gt;
	ld	de,progToEdit&lt;br /&gt;
	ld	bc,8&lt;br /&gt;
	ldir&lt;br /&gt;
	ld	a,cxExtApps&lt;br /&gt;
	jp	_NewContext&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindAppInfoString:&lt;br /&gt;
; Finds the information string about an App&lt;br /&gt;
; i.e. (c) 2005-2014 Texas Instruments&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains start of app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$24&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)			; load location of info string&lt;br /&gt;
	add	hl,de &lt;br /&gt;
	or	a,a &lt;br /&gt;
	sbc	hl,de			; check if HL is 0&lt;br /&gt;
	ret	z&lt;br /&gt;
	add	hl,de			; add extra bytes&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindStartOfAppCode:&lt;br /&gt;
; Finds the start of the actual executable from the start of an App&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains the start of the app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$1B			; offset&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
DeletePgrmFromUserMem:&lt;br /&gt;
	ld	de,(asm_prgm_size)	; load total program prgmSize&lt;br /&gt;
	or	a,a&lt;br /&gt;
	sbc	hl,hl&lt;br /&gt;
	ld	(asm_prgm_size),hl	; delete whatever current program was there&lt;br /&gt;
	ld	hl,userMem&lt;br /&gt;
	jp	_DelMem			; HL-&amp;gt;place to delete, DE=amount to delete&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
GetAppSize:&lt;br /&gt;
; Gets the size of an app based from the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_NextFieldFromType	; move to start of signature&lt;br /&gt;
	call	_NextFieldFromType	; move to end of signature&lt;br /&gt;
	pop	de&lt;br /&gt;
	or	a&lt;br /&gt;
	sbc	hl,de&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl			; bypass app size bytes&lt;br /&gt;
	ret				; haha, we're probably looking at another app here&lt;br /&gt;
ExecuteApp_End:&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Credits and Contribution==&lt;br /&gt;
Matt &amp;quot;MateoConLechuga&amp;quot; Waltz&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications</id>
		<title>84PCE:OS:Applications</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications"/>
				<updated>2017-10-14T05:14:27Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:OS_Information]]&lt;br /&gt;
[[Category:84PCE:OS_Information]]&lt;br /&gt;
==Application File Type==&lt;br /&gt;
Applications for the CE calculator have the extension 8ek.&lt;br /&gt;
&lt;br /&gt;
Relocations exist to place the app correctly in the archive, 6 bytes per block (2+22 bits):&lt;br /&gt;
&lt;br /&gt;
0b00 indicates a reference to the code segment executing from Flash, and 0b10 indicates a reference to the data/bss segment in RAM.&lt;br /&gt;
0b01 and 0b11 are a reserved format; &lt;br /&gt;
&lt;br /&gt;
Applications can be of arbitrary size, no longer multiples of 16kB.&lt;br /&gt;
&lt;br /&gt;
You can find code for creating an application; along with other fancy items [https://github.com/mateoconlechuga/app-inc here]&lt;br /&gt;
&lt;br /&gt;
==Applications in the Archive==&lt;br /&gt;
Applications are stored beginning at the address 03B0000h and grow downwards. 3 bytes are used as offsets to the start of the app, since the search is backwards. The following status bytes represent what might be found when parsing for applications:&lt;br /&gt;
&lt;br /&gt;
081h = valid Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
000h = deleted Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
Some search code may look like this (Will locate the start of all the app headers):&lt;br /&gt;
&lt;br /&gt;
 _FindValidLocation:&lt;br /&gt;
 	ld	hl,03B0000h            ; applications start here&lt;br /&gt;
 find:	&lt;br /&gt;
 	dec	hl&lt;br /&gt;
  	dec	hl&lt;br /&gt;
 	dec	hl&lt;br /&gt;
 	push	hl&lt;br /&gt;
 	ld	de,(hl)&lt;br /&gt;
 	ld	hl,0FFFFFFh            ; check for end&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de&lt;br /&gt;
 	pop	hl&lt;br /&gt;
 	ret	z                      ; found end of applications&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de                  ; hl points to the start of the app header here if found&lt;br /&gt;
 	jr	find&lt;br /&gt;
&lt;br /&gt;
The actual App header contains certain fields which correspond to the type of data they represent. TI dropped the ball and even though these are variable length fields, the OS code can only handle headers that are padded to 256 bytes in length.&lt;br /&gt;
&lt;br /&gt;
810(F)h = Master field, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
811(2)h = Signing key ID. On the CE, this is 2 bytes in length with the value 0130Fh, indicating it was signed with the '130F' key.&lt;br /&gt;
&lt;br /&gt;
812(D)h = Version information. Begins with the length of the version string, followed by the string itself. This is a minimum compatible version.&lt;br /&gt;
&lt;br /&gt;
813(2)h = Unknown, but contains the 2 byte data 05900h.&lt;br /&gt;
&lt;br /&gt;
814(N)h = Name of App. In this case, 'N' represents the length of the name in bytes. This field is then followed by the name of the app.&lt;br /&gt;
&lt;br /&gt;
817(F)h = End app header information, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
81A(1)h = Unknown, but contains the 1 byte data 007h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other fields:&lt;br /&gt;
&lt;br /&gt;
003h &amp;amp; 2(6)h &amp;amp; 009h &amp;amp; 0(4)h = Time stamp field. 4 bytes long; represents the number of seconds since January 1st 1997, 00:00:00 in some timezone, and some step of the build process.&lt;br /&gt;
&lt;br /&gt;
00Dh &amp;amp; 0NNh = This (NN) represents how much padding until the next field, as app headers must be padded to 256 bytes.&lt;br /&gt;
&lt;br /&gt;
002h &amp;amp; 03(E)h = Signature field. The is followed by the two bytes containing the value 0100h, the length of the 2048 bit signature&lt;br /&gt;
&lt;br /&gt;
At the end of the signature is 3 bytes representing the size of the application. (These bytes are not included however)&lt;br /&gt;
&lt;br /&gt;
App size calculation is as follows: [Length of master header + offset to signature field in (810)] + [4 bytes of signature field + 256 bytes of signature] + [3 bytes application size]&lt;br /&gt;
&lt;br /&gt;
This is pretty much the same as adding 269 to the value in the big endian master field.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an example of such a header:&lt;br /&gt;
&lt;br /&gt;
 ; Master Field -- This app is 102247 + 269 (102516) bytes in size&lt;br /&gt;
 .db	081h, 00Fh, 000h, 001h, 08fh, 067h&lt;br /&gt;
 ; Signing Key Field&lt;br /&gt;
 .db	081h, 012h, 013h, 00Fh&lt;br /&gt;
 ; Version information -- 00Bh represnets the length until the next field&lt;br /&gt;
 .db	081h, 02Dh, 00Bh, &amp;quot;5.0.0.0089&amp;quot;, 000h&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 032h, 059h, 000h&lt;br /&gt;
 ; Name Field -- Name is 7 bytes long, so that is where the 047h comes from&lt;br /&gt;
 .db	081h, 047h, &amp;quot;CabriJr&amp;quot;&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 0A1h, 007h&lt;br /&gt;
 ; Time stamp -- Who knows what time is was?&lt;br /&gt;
 .db	003h, 026h, 009h, 004h&lt;br /&gt;
 .db	021h, 0BBh, 06Eh, 0DCh&lt;br /&gt;
 ; Amount of pading (This is so, so silly)&lt;br /&gt;
 .db	000h, 00Dh, 0C7h&lt;br /&gt;
 ; Padding of 0C7h (199) bytes&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0&lt;br /&gt;
 ; Final field&lt;br /&gt;
 .db	081h, 07Fh, 000h, 001h, 08Eh, 06dh&lt;br /&gt;
 ; End of 256 byte header&lt;br /&gt;
&lt;br /&gt;
==Additional App Structure==&lt;br /&gt;
&lt;br /&gt;
However, apps are also made up of a certain sequence of bytes following the header. Offsets are calculated from the posistion after the header, in addition to the offsets derived from offsets.&lt;br /&gt;
&lt;br /&gt;
Offset after 256 byte header:&lt;br /&gt;
&lt;br /&gt;
000h = The ASCII string &amp;quot;eZ8&amp;quot;, potentially signifying an eZ80 application&lt;br /&gt;
&lt;br /&gt;
003h = Null terminated Application name (zero padded to be 9 bytes in length with terminator byte)&lt;br /&gt;
&lt;br /&gt;
00Ch = Flag, [Bit 0 set - don't draw the TI splash screen] [Bit 1 set - app can use OpenLib]&lt;br /&gt;
&lt;br /&gt;
00Eh = Flag, [Bit 0 set - use the offset in 01Eh] [Bit 3 controls something]&lt;br /&gt;
&lt;br /&gt;
012h = Main section&lt;br /&gt;
&lt;br /&gt;
015h = Initialized data section (Can be at most 4kB in size)&lt;br /&gt;
&lt;br /&gt;
018h = Initialized data section Length&lt;br /&gt;
&lt;br /&gt;
01Bh = Execution entry point (usually same as 012h)&lt;br /&gt;
&lt;br /&gt;
01Eh = Unknown 3 byte offset (See 00Eh)&lt;br /&gt;
&lt;br /&gt;
021h = Offset to ExecLib jump table&lt;br /&gt;
&lt;br /&gt;
024h = Offset to the string used to display a message in the memory screen (Usually a copyright, i.e. &amp;quot;(c) 2005-2015 Texas Instruments&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
027h = Reserved word&lt;br /&gt;
&lt;br /&gt;
02Ah = Start of relocation table&lt;br /&gt;
&lt;br /&gt;
== ExecLib ==&lt;br /&gt;
&lt;br /&gt;
In order to use ExecLib properly from BASIC programs, you must:&lt;br /&gt;
&lt;br /&gt;
1. Set the proper bit at offset 00Ch.&lt;br /&gt;
&lt;br /&gt;
2. Initialize offset 021h to the start of the library jump table&lt;br /&gt;
&lt;br /&gt;
3. Ensure that the jump table offsets are stored in the relocation table&lt;br /&gt;
&lt;br /&gt;
The format for the jump table is shown below: (Note that you store AppLibraryTable offset to 021h).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;	.db	&amp;quot;LIB&amp;quot;&lt;br /&gt;
	.dl	NUMBER_OF_FUNCTIONS_IN_JUMP_TABLE&lt;br /&gt;
AppLibraryTable:&lt;br /&gt;
	.dl	Function_1&lt;br /&gt;
	.dl	Function_2&lt;br /&gt;
	...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relocations ==&lt;br /&gt;
&lt;br /&gt;
Because apps are not stored at a fixed memory address, they require a relocation table to relocate them during sending and defragmentation.&lt;br /&gt;
&lt;br /&gt;
The relocation map consists of a six-byte entry for each location which needs to be updated.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Offset&lt;br /&gt;
! Length&lt;br /&gt;
! Contents&lt;br /&gt;
|-&lt;br /&gt;
| 000h&lt;br /&gt;
| 003h&lt;br /&gt;
| Hole offset&lt;br /&gt;
|-&lt;br /&gt;
| 003h&lt;br /&gt;
| 003h&lt;br /&gt;
| base (2 bits) and relative value to place in hole (22 bits)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''Relocation Map Format'''&lt;br /&gt;
&lt;br /&gt;
The hole offset specifies where in the application code or initial data table an absolute address needs to be updated.&lt;br /&gt;
The value to store in the hole is calculated from the base and relative value. The base is 00 for code-segment relative and 10 for data-segment relative. Base values 01 and 11 are reserved.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
Here is a full demo program demonstrating finding each application, displaying the name, size, version, and copyright information&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;quot;ti84pce.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	.db	tExtTok,tAsm84CECmp&lt;br /&gt;
	.org	usermem&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
; Finds all the apps and displays info&lt;br /&gt;
_FINDAPPS:&lt;br /&gt;
	ld	ix,0&lt;br /&gt;
	add	ix,sp&lt;br /&gt;
	ld	hl,ExecuteApp&lt;br /&gt;
	ld	de,cursorImage&lt;br /&gt;
	ld	bc,ExecuteApp_End-ExecuteApp_Start&lt;br /&gt;
	ldir&lt;br /&gt;
	call	_ZeroOP3&lt;br /&gt;
	ld	a,appObj&lt;br /&gt;
	ld	(OP3),a&lt;br /&gt;
_:	call	_HomeUp&lt;br /&gt;
	call	_ClrScrn&lt;br /&gt;
	call	_OP3ToOP1&lt;br /&gt;
	call	_FindAppUp		; find the app&lt;br /&gt;
	ret	c&lt;br /&gt;
	call	_OP1ToOP3		; store name&lt;br /&gt;
	ld	hl,OP1+1&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_PutS			; put name of app&lt;br /&gt;
	pop	hl			; don't need this push/pop (here for readability)&lt;br /&gt;
	call	_FindAppStart		; find the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	GetAppSize&lt;br /&gt;
	call	_DispHL			; display the size of the app&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_os_GetAppVersionString&lt;br /&gt;
	pop	bc&lt;br /&gt;
	call	_PutS&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	call	FindAppInfoString	; Get the information&lt;br /&gt;
	call	_PutS&lt;br /&gt;
_:	call	_GetCSC&lt;br /&gt;
	or	a,a&lt;br /&gt;
	jr	z,-_&lt;br /&gt;
	cp	a,sk2nd&lt;br /&gt;
	jr	nz,--_&lt;br /&gt;
	ld	hl,OP3+1&lt;br /&gt;
	jp	cursorImage&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
ExecuteApp:&lt;br /&gt;
; HL -&amp;gt; name of app (0 terminated)&lt;br /&gt;
	.org	cursorImage&lt;br /&gt;
ExecuteApp_Start:&lt;br /&gt;
	ld	de,progToEdit&lt;br /&gt;
	ld	bc,8&lt;br /&gt;
	ldir&lt;br /&gt;
	ld	a,cxExtApps&lt;br /&gt;
	jp	_NewContext&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindAppInfoString:&lt;br /&gt;
; Finds the information string about an App&lt;br /&gt;
; i.e. (c) 2005-2014 Texas Instruments&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains start of app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$24&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)			; load location of info string&lt;br /&gt;
	add	hl,de &lt;br /&gt;
	or	a,a &lt;br /&gt;
	sbc	hl,de			; check if HL is 0&lt;br /&gt;
	ret	z&lt;br /&gt;
	add	hl,de			; add extra bytes&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindStartOfAppCode:&lt;br /&gt;
; Finds the start of the actual executable from the start of an App&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains the start of the app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$1B			; offset&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
DeletePgrmFromUserMem:&lt;br /&gt;
	ld	de,(asm_prgm_size)	; load total program prgmSize&lt;br /&gt;
	or	a,a&lt;br /&gt;
	sbc	hl,hl&lt;br /&gt;
	ld	(asm_prgm_size),hl	; delete whatever current program was there&lt;br /&gt;
	ld	hl,userMem&lt;br /&gt;
	jp	_DelMem			; HL-&amp;gt;place to delete, DE=amount to delete&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
GetAppSize:&lt;br /&gt;
; Gets the size of an app based from the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_NextFieldFromType	; move to start of signature&lt;br /&gt;
	call	_NextFieldFromType	; move to end of signature&lt;br /&gt;
	pop	de&lt;br /&gt;
	or	a&lt;br /&gt;
	sbc	hl,de&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl			; bypass app size bytes&lt;br /&gt;
	ret				; haha, we're probably looking at another app here&lt;br /&gt;
ExecuteApp_End:&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Credits and Contribution==&lt;br /&gt;
Matt &amp;quot;MateoConLechuga&amp;quot; Waltz&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications</id>
		<title>84PCE:OS:Applications</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications"/>
				<updated>2017-10-08T12:04:05Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:OS_Information]]&lt;br /&gt;
[[Category:84PCE:OS_Information]]&lt;br /&gt;
==Application File Type==&lt;br /&gt;
Applications for the CE calculator have the extension 8ek.&lt;br /&gt;
&lt;br /&gt;
Relocations exist to place the app correctly in the archive, 6 bytes per block (2+22 bits):&lt;br /&gt;
&lt;br /&gt;
0b00 indicates a reference to the code segment executing from Flash, and 0b10 indicates a reference to the data/bss segment in RAM.&lt;br /&gt;
0b01 and 0b11 are a reserved format; &lt;br /&gt;
&lt;br /&gt;
Applications can be of arbitrary size, no longer multiples of 16kB.&lt;br /&gt;
&lt;br /&gt;
You can find code for creating an application; along with other fancy items [https://github.com/mateoconlechuga/app-inc here]&lt;br /&gt;
&lt;br /&gt;
==Applications in the Archive==&lt;br /&gt;
Applications are stored beginning at the address 03B0000h and grow downwards. 3 bytes are used as offsets to the start of the app, since the search is backwards. The following status bytes represent what might be found when parsing for applications:&lt;br /&gt;
&lt;br /&gt;
081h = valid Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
000h = deleted Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
Some search code may look like this (Will locate the start of all the app headers):&lt;br /&gt;
&lt;br /&gt;
 _FindValidLocation:&lt;br /&gt;
 	ld	hl,03B0000h            ; applications start here&lt;br /&gt;
 find:	&lt;br /&gt;
 	dec	hl&lt;br /&gt;
  	dec	hl&lt;br /&gt;
 	dec	hl&lt;br /&gt;
 	push	hl&lt;br /&gt;
 	ld	de,(hl)&lt;br /&gt;
 	ld	hl,0FFFFFFh            ; check for end&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de&lt;br /&gt;
 	pop	hl&lt;br /&gt;
 	ret	z                      ; found end of applications&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de                  ; hl points to the start of the app header here if found&lt;br /&gt;
 	jr	find&lt;br /&gt;
&lt;br /&gt;
The actual App header contains certain fields which correspond to the type of data they represent. TI dropped the ball and even though these are variable length fields, the OS code can only handle headers that are padded to 256 bytes in length.&lt;br /&gt;
&lt;br /&gt;
810(F)h = Master field, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
811(2)h = Signing key ID. On the CE, this is 2 bytes in length with the value 0130Fh, indicating it was signed with the '130F' key.&lt;br /&gt;
&lt;br /&gt;
812(D)h = Version information. Begins with the length of the version string, followed by the string itself. This is a minimum compatible version.&lt;br /&gt;
&lt;br /&gt;
813(2)h = Unknown, but contains the 2 byte data 05900h.&lt;br /&gt;
&lt;br /&gt;
814(N)h = Name of App. In this case, 'N' represents the length of the name in bytes. This field is then followed by the name of the app.&lt;br /&gt;
&lt;br /&gt;
817(F)h = End app header information, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
81A(1)h = Unknown, but contains the 1 byte data 007h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other fields:&lt;br /&gt;
&lt;br /&gt;
003h &amp;amp; 2(6)h &amp;amp; 009h &amp;amp; 0(4)h = Time stamp field. 4 bytes long; represents the number of seconds since January 1st 1997, 00:00:00 in some timezone, and some step of the build process.&lt;br /&gt;
&lt;br /&gt;
00Dh &amp;amp; 0NNh = This (NN) represents how much padding until the next field, as app headers must be padded to 256 bytes.&lt;br /&gt;
&lt;br /&gt;
002h &amp;amp; 03(E)h = Signature field. The is followed by the two bytes containing the value 0100h, the length of the 2048 bit signature&lt;br /&gt;
&lt;br /&gt;
At the end of the signature is 3 bytes representing the size of the application. (These bytes are not included however)&lt;br /&gt;
&lt;br /&gt;
App size calculation is as follows: [Length of master header + offset to signature field in (810)] + [4 bytes of signature field + 256 bytes of signature] + [3 bytes application size]&lt;br /&gt;
&lt;br /&gt;
This is pretty much the same as adding 269 to the value in the big endian master field.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an example of such a header:&lt;br /&gt;
&lt;br /&gt;
 ; Master Field -- This app is 102247 + 269 (102516) bytes in size&lt;br /&gt;
 .db	081h, 00Fh, 000h, 001h, 08fh, 067h&lt;br /&gt;
 ; Signing Key Field&lt;br /&gt;
 .db	081h, 012h, 013h, 00Fh&lt;br /&gt;
 ; Version information -- 00Bh represnets the length until the next field&lt;br /&gt;
 .db	081h, 02Dh, 00Bh, &amp;quot;5.0.0.0089&amp;quot;, 000h&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 032h, 059h, 000h&lt;br /&gt;
 ; Name Field -- Name is 7 bytes long, so that is where the 047h comes from&lt;br /&gt;
 .db	081h, 047h, &amp;quot;CabriJr&amp;quot;&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 0A1h, 007h&lt;br /&gt;
 ; Time stamp -- Who knows what time is was?&lt;br /&gt;
 .db	003h, 026h, 009h, 004h&lt;br /&gt;
 .db	021h, 0BBh, 06Eh, 0DCh&lt;br /&gt;
 ; Amount of pading (This is so, so silly)&lt;br /&gt;
 .db	000h, 00Dh, 0C7h&lt;br /&gt;
 ; Padding of 0C7h (199) bytes&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0&lt;br /&gt;
 ; Final field&lt;br /&gt;
 .db	081h, 07Fh, 000h, 001h, 08Eh, 06dh&lt;br /&gt;
 ; End of 256 byte header&lt;br /&gt;
&lt;br /&gt;
==Additional App Structure==&lt;br /&gt;
&lt;br /&gt;
However, apps are also made up of a certain sequence of bytes following the header. Offsets are calculated from the posistion after the header, in addition to the offsets derived from offsets.&lt;br /&gt;
&lt;br /&gt;
Offset after 256 byte header:&lt;br /&gt;
&lt;br /&gt;
000h = The ASCII string &amp;quot;eZ8&amp;quot;, potentially signifying an eZ80 application&lt;br /&gt;
&lt;br /&gt;
003h = Null terminated Application name (zero padded to be 9 bytes in length with terminator byte)&lt;br /&gt;
&lt;br /&gt;
00Ch = Flag, [Bit 0 set - don't draw the TI splash screen] [Bit 1 set - app can use OpenLib]&lt;br /&gt;
&lt;br /&gt;
00Eh = Flag, [Bit 0 set - use the offset in 01Eh] [Bit 3 controls something]&lt;br /&gt;
&lt;br /&gt;
012h = Main section&lt;br /&gt;
&lt;br /&gt;
015h = Initialized data section (Can be at most 4kB in size)&lt;br /&gt;
&lt;br /&gt;
018h = Initialized data section Length&lt;br /&gt;
&lt;br /&gt;
01Bh = Execution entry point (usually same as 012h)&lt;br /&gt;
&lt;br /&gt;
01Eh = Unknown 3 byte offset (See 00Eh)&lt;br /&gt;
&lt;br /&gt;
021h = Offset to ExecLib jump table&lt;br /&gt;
&lt;br /&gt;
024h = Offset to the string used to display a message in the memory screen (Usually a copyright, i.e. &amp;quot;(c) 2005-2015 Texas Instruments&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
027h = Reserved word&lt;br /&gt;
&lt;br /&gt;
02Ah = Start of relocation table&lt;br /&gt;
&lt;br /&gt;
== ExecLib ==&lt;br /&gt;
&lt;br /&gt;
In order to use ExecLib properly from BASIC programs, you must:&lt;br /&gt;
&lt;br /&gt;
1. Set the proper bit at offset 00Ch.&lt;br /&gt;
&lt;br /&gt;
2. Initialize offset 021h to the start of the library jump table&lt;br /&gt;
&lt;br /&gt;
3. Ensure that the jump table offsets are stored in the relocation table&lt;br /&gt;
&lt;br /&gt;
The format for the jump table is shown below: (Note that you store AppLibraryTable offset to 021h).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;	.db	&amp;quot;LIB&amp;quot;&lt;br /&gt;
	.dl	NUMBER_OF_FUNCTIONS_IN_JUMP_TABLE&lt;br /&gt;
AppLibraryTable:&lt;br /&gt;
	.dl	Function_1&lt;br /&gt;
	.dl	Function_2&lt;br /&gt;
	...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relocations ==&lt;br /&gt;
&lt;br /&gt;
Because apps are not stored at a fixed memory address, they require a relocation table to relocate them during sending and defragmentation.&lt;br /&gt;
&lt;br /&gt;
The relocation map consists of a six-byte entry for each location which needs to be updated.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Offset&lt;br /&gt;
! Length&lt;br /&gt;
! Contents&lt;br /&gt;
|-&lt;br /&gt;
| 000h&lt;br /&gt;
| 003h&lt;br /&gt;
| Hole offset&lt;br /&gt;
|-&lt;br /&gt;
| 003h&lt;br /&gt;
| 003h&lt;br /&gt;
| base (2 bits) and relative value to place in hole (22 bits)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''Relocation Map Format'''&lt;br /&gt;
&lt;br /&gt;
The hole offset specifies where in the application code or initial data table an absolute address needs to be updated.&lt;br /&gt;
The value to store in the hole is calculated from the base and relative value. The base is 00 for code-segment relative and 10 for data-segment relative. Base values 01 and 11 are reserved.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
Here is a full demo program demonstrating finding each application, displaying the name, size, version, and copyright information&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;quot;ti84pce.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	.db	tExtTok,tAsm84CECmp&lt;br /&gt;
	.org	usermem&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
; Finds all the apps and displays info&lt;br /&gt;
_FINDAPPS:&lt;br /&gt;
	ld	ix,0&lt;br /&gt;
	add	ix,sp&lt;br /&gt;
	ld	hl,ExecuteApp&lt;br /&gt;
	ld	de,cursorImage&lt;br /&gt;
	ld	bc,ExecuteApp_End-ExecuteApp_Start&lt;br /&gt;
	ldir&lt;br /&gt;
	call	_ZeroOP3&lt;br /&gt;
	ld	a,appObj&lt;br /&gt;
	ld	(OP3),a&lt;br /&gt;
_:	call	_HomeUp&lt;br /&gt;
	call	_ClrScrn&lt;br /&gt;
	call	_OP3ToOP1&lt;br /&gt;
	call	_FindAppUp		; find the app&lt;br /&gt;
	ret	c&lt;br /&gt;
	call	_OP1ToOP3		; store name&lt;br /&gt;
	ld	hl,OP1+1&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_PutS			; put name of app&lt;br /&gt;
	pop	hl			; don't need this push/pop (here for readability)&lt;br /&gt;
	call	_FindAppStart		; find the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	GetAppSize&lt;br /&gt;
	call	_DispHL			; display the size of the app&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_os_GetAppVersionString&lt;br /&gt;
	pop	bc&lt;br /&gt;
	call	_PutS&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	call	FindAppInfoString	; Get the information&lt;br /&gt;
	call	_PutS&lt;br /&gt;
_:	call	_GetCSC&lt;br /&gt;
	or	a,a&lt;br /&gt;
	jr	z,-_&lt;br /&gt;
	cp	a,sk2nd&lt;br /&gt;
	jr	nz,--_&lt;br /&gt;
	ld	hl,OP3+1&lt;br /&gt;
	jp	cursorImage&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
ExecuteApp:&lt;br /&gt;
; HL -&amp;gt; name of app (0 terminated)&lt;br /&gt;
; An alternative would be to copy to progtoedit and call _NewConext0&lt;br /&gt;
	.org	cursorImage&lt;br /&gt;
ExecuteApp_Start:&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	DeletePgrmFromUserMem&lt;br /&gt;
	ld	hl,$100&lt;br /&gt;
	call	_EnoughMem&lt;br /&gt;
	pop	hl&lt;br /&gt;
	jp	c, _ErrMemory&lt;br /&gt;
	call	_FindAppStart		; This locates the start of executable code for an app&lt;br /&gt;
	ld	a,E_Validation&lt;br /&gt;
	jp	c,_JError		; If we can't find it, that's a problem (throw a validation error)&lt;br /&gt;
	push	hl			; push location of start of app&lt;br /&gt;
	call	_ReloadAppEntryVecs&lt;br /&gt;
	call	_AppSetup&lt;br /&gt;
	set	appRunning,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	set	6,(iy+$28)&lt;br /&gt;
	res	0,(iy+$2C)		; set some app flags&lt;br /&gt;
	set	appAllowContext,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	ld	hl,$D1787C		; copy to ram data location&lt;br /&gt;
	ld	bc,$FFF&lt;br /&gt;
	call	_MemClear		; zero out the ram data section&lt;br /&gt;
	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	push	hl			; de -&amp;gt; start of code for app&lt;br /&gt;
	ld	bc,$100			; bypass header information&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ex	de,hl&lt;br /&gt;
	ld	hl,$18			; find the start of the data to copy to ram&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	call	__icmpzero		; initialize the bss if it exists&lt;br /&gt;
	jr	z,+_&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	bc&lt;br /&gt;
	ld	hl,$15&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	de,$D1787C		; copy it in&lt;br /&gt;
	ldir&lt;br /&gt;
_:	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	call	FindStartOfAppCode	; After this, hl -&amp;gt; start of code for app&lt;br /&gt;
	jp	(hl)&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindAppInfoString:&lt;br /&gt;
; Finds the information string about an App&lt;br /&gt;
; i.e. (c) 2005-2014 Texas Instruments&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains start of app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$24&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)			; load location of info string&lt;br /&gt;
	add	hl,de &lt;br /&gt;
	or	a,a &lt;br /&gt;
	sbc	hl,de			; check if HL is 0&lt;br /&gt;
	ret	z&lt;br /&gt;
	add	hl,de			; add extra bytes&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindStartOfAppCode:&lt;br /&gt;
; Finds the start of the actual executable from the start of an App&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains the start of the app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$1B			; offset&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
DeletePgrmFromUserMem:&lt;br /&gt;
	ld	de,(asm_prgm_size)	; load total program prgmSize&lt;br /&gt;
	or	a,a&lt;br /&gt;
	sbc	hl,hl&lt;br /&gt;
	ld	(asm_prgm_size),hl	; delete whatever current program was there&lt;br /&gt;
	ld	hl,userMem&lt;br /&gt;
	jp	_DelMem			; HL-&amp;gt;place to delete, DE=amount to delete&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
GetAppSize:&lt;br /&gt;
; Gets the size of an app based from the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_NextFieldFromType	; move to start of signature&lt;br /&gt;
	call	_NextFieldFromType	; move to end of signature&lt;br /&gt;
	pop	de&lt;br /&gt;
	or	a&lt;br /&gt;
	sbc	hl,de&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl			; bypass app size bytes&lt;br /&gt;
	ret				; haha, we're probably looking at another app here&lt;br /&gt;
ExecuteApp_End:&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Credits and Contribution==&lt;br /&gt;
Matt &amp;quot;MateoConLechuga&amp;quot; Waltz&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83PCE:Hooks:D0260E</id>
		<title>83PCE:Hooks:D0260E</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83PCE:Hooks:D0260E"/>
				<updated>2017-10-08T04:19:56Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83PCE:Hooks:By_Name|Token Hook]] [[Category:83PCE:Hooks:By_Address|D0260E - Token Hook]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Name:''' Token Hook&lt;br /&gt;
&lt;br /&gt;
'''Hook Pointer Block Address:''' D0260E&lt;br /&gt;
&lt;br /&gt;
'''Hook Enable BCALL:''' 0213F8&lt;br /&gt;
&lt;br /&gt;
'''Hook Disable BCALL:''' 0213FC&lt;br /&gt;
&lt;br /&gt;
'''Hook Call BCALL:''' ''(none known)''&lt;br /&gt;
&lt;br /&gt;
'''Hook Active Flag:''' [[83Plus:Flags:35#Bit_0|0, (iy + 35h)]]&lt;br /&gt;
&lt;br /&gt;
This hook allows you to change the strings displayed for TIOS tokens. It is called every time the OS is about to display a one- or 2-byte token.&lt;br /&gt;
&lt;br /&gt;
== Using the Hook ==&lt;br /&gt;
* DE = token number * 3 (DEU = 0)&lt;br /&gt;
** 1-byte:     0000 to 02FD&lt;br /&gt;
** Matrix:     0300 to 031B&lt;br /&gt;
** List:       031E to 032D&lt;br /&gt;
** Equation:   0330 to 038A&lt;br /&gt;
** Picture:    038D to 03A8&lt;br /&gt;
** GDB:        03AB to 03C6&lt;br /&gt;
** String:     03C9 to 03E4&lt;br /&gt;
** Statistics: 03E7 to 049B&lt;br /&gt;
** Window/finance: 049E to 0546&lt;br /&gt;
** Graph format: 0549 to 057F&lt;br /&gt;
** Miscellaneous: 0582 to 0861&lt;br /&gt;
** Extra tokens: 0864 to *&lt;br /&gt;
* HL points to the default string&lt;br /&gt;
** Change HL to display another string. The format of that string should be:&lt;br /&gt;
 &amp;lt;keypress of token&amp;gt;,&amp;lt;length string&amp;gt;,&amp;quot;string&amp;quot;&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications</id>
		<title>84PCE:OS:Applications</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications"/>
				<updated>2017-10-02T06:41:09Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Relocations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:OS_Information]]&lt;br /&gt;
[[Category:84PCE:OS_Information]]&lt;br /&gt;
==Application File Type==&lt;br /&gt;
Applications for the CE calculator have the extension 8ek.&lt;br /&gt;
&lt;br /&gt;
Relocations exist to place the app correctly in the archive, 6 bytes per block (2+22 bits):&lt;br /&gt;
&lt;br /&gt;
0b00 indicates a reference to the code segment executing from Flash, and 0b10 indicates a reference to the data/bss segment in RAM.&lt;br /&gt;
0b01 and 0b11 are a reserved format; &lt;br /&gt;
&lt;br /&gt;
Applications can be of arbitrary size, no longer multiples of 16kB.&lt;br /&gt;
&lt;br /&gt;
==Applications in the Archive==&lt;br /&gt;
Applications are stored beginning at the address 03B0000h and grow downwards. 3 bytes are used as offsets to the start of the app, since the search is backwards. The following status bytes represent what might be found when parsing for applications:&lt;br /&gt;
&lt;br /&gt;
081h = valid Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
000h = deleted Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
Some search code may look like this (Will locate the start of all the app headers):&lt;br /&gt;
&lt;br /&gt;
 _FindValidLocation:&lt;br /&gt;
 	ld	hl,03B0000h            ; applications start here&lt;br /&gt;
 find:	&lt;br /&gt;
 	dec	hl&lt;br /&gt;
  	dec	hl&lt;br /&gt;
 	dec	hl&lt;br /&gt;
 	push	hl&lt;br /&gt;
 	ld	de,(hl)&lt;br /&gt;
 	ld	hl,0FFFFFFh            ; check for end&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de&lt;br /&gt;
 	pop	hl&lt;br /&gt;
 	ret	z                      ; found end of applications&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de                  ; hl points to the start of the app header here if found&lt;br /&gt;
 	jr	find&lt;br /&gt;
&lt;br /&gt;
The actual App header contains certain fields which correspond to the type of data they represent. TI dropped the ball and even though these are variable length fields, the OS code can only handle headers that are padded to 256 bytes in length.&lt;br /&gt;
&lt;br /&gt;
810(F)h = Master field, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
811(2)h = Signing key ID. On the CE, this is 2 bytes in length with the value 0130Fh, indicating it was signed with the '130F' key.&lt;br /&gt;
&lt;br /&gt;
812(D)h = Version information. Begins with the length of the version string, followed by the string itself. This is a minimum compatible version.&lt;br /&gt;
&lt;br /&gt;
813(2)h = Unknown, but contains the 2 byte data 05900h.&lt;br /&gt;
&lt;br /&gt;
814(N)h = Name of App. In this case, 'N' represents the length of the name in bytes. This field is then followed by the name of the app.&lt;br /&gt;
&lt;br /&gt;
817(F)h = End app header information, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
81A(1)h = Unknown, but contains the 1 byte data 007h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other fields:&lt;br /&gt;
&lt;br /&gt;
003h &amp;amp; 2(6)h &amp;amp; 009h &amp;amp; 0(4)h = Time stamp field. 4 bytes long; represents the number of seconds since January 1st 1997, 00:00:00 in some timezone, and some step of the build process.&lt;br /&gt;
&lt;br /&gt;
00Dh &amp;amp; 0NNh = This (NN) represents how much padding until the next field, as app headers must be padded to 256 bytes.&lt;br /&gt;
&lt;br /&gt;
002h &amp;amp; 03(E)h = Signature field. The is followed by the two bytes containing the value 0100h, the length of the 2048 bit signature&lt;br /&gt;
&lt;br /&gt;
At the end of the signature is 3 bytes representing the size of the application. (These bytes are not included however)&lt;br /&gt;
&lt;br /&gt;
App size calculation is as follows: [Length of master header + offset to signature field in (810)] + [4 bytes of signature field + 256 bytes of signature] + [3 bytes application size]&lt;br /&gt;
&lt;br /&gt;
This is pretty much the same as adding 269 to the value in the big endian master field.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an example of such a header:&lt;br /&gt;
&lt;br /&gt;
 ; Master Field -- This app is 102247 + 269 (102516) bytes in size&lt;br /&gt;
 .db	081h, 00Fh, 000h, 001h, 08fh, 067h&lt;br /&gt;
 ; Signing Key Field&lt;br /&gt;
 .db	081h, 012h, 013h, 00Fh&lt;br /&gt;
 ; Version information -- 00Bh represnets the length until the next field&lt;br /&gt;
 .db	081h, 02Dh, 00Bh, &amp;quot;5.0.0.0089&amp;quot;, 000h&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 032h, 059h, 000h&lt;br /&gt;
 ; Name Field -- Name is 7 bytes long, so that is where the 047h comes from&lt;br /&gt;
 .db	081h, 047h, &amp;quot;CabriJr&amp;quot;&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 0A1h, 007h&lt;br /&gt;
 ; Time stamp -- Who knows what time is was?&lt;br /&gt;
 .db	003h, 026h, 009h, 004h&lt;br /&gt;
 .db	021h, 0BBh, 06Eh, 0DCh&lt;br /&gt;
 ; Amount of pading (This is so, so silly)&lt;br /&gt;
 .db	000h, 00Dh, 0C7h&lt;br /&gt;
 ; Padding of 0C7h (199) bytes&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0&lt;br /&gt;
 ; Final field&lt;br /&gt;
 .db	081h, 07Fh, 000h, 001h, 08Eh, 06dh&lt;br /&gt;
 ; End of 256 byte header&lt;br /&gt;
&lt;br /&gt;
==Additional App Structure==&lt;br /&gt;
&lt;br /&gt;
However, apps are also made up of a certain sequence of bytes following the header. Offsets are calculated from the posistion after the header, in addition to the offsets derived from offsets.&lt;br /&gt;
&lt;br /&gt;
Offset after 256 byte header:&lt;br /&gt;
&lt;br /&gt;
000h = The ASCII string &amp;quot;eZ8&amp;quot;, potentially signifying an eZ80 application&lt;br /&gt;
&lt;br /&gt;
003h = Null terminated Application name (zero padded to be 9 bytes in length with terminator byte)&lt;br /&gt;
&lt;br /&gt;
00Ch = Flag, [Bit 0 set - don't draw the TI splash screen] [Bit 1 set - app can use OpenLib]&lt;br /&gt;
&lt;br /&gt;
00Eh = Flag, [Bit 0 set - use the offset in 01Eh] [Bit 3 controls something]&lt;br /&gt;
&lt;br /&gt;
012h = Main section&lt;br /&gt;
&lt;br /&gt;
015h = Initialized data section (Can be at most 4kB in size)&lt;br /&gt;
&lt;br /&gt;
018h = Initialized data section Length&lt;br /&gt;
&lt;br /&gt;
01Bh = Execution entry point (usually same as 012h)&lt;br /&gt;
&lt;br /&gt;
01Eh = Unknown 3 byte offset (See 00Eh)&lt;br /&gt;
&lt;br /&gt;
021h = Offset to ExecLib jump table&lt;br /&gt;
&lt;br /&gt;
024h = Offset to the string used to display a message in the memory screen (Usually a copyright, i.e. &amp;quot;(c) 2005-2015 Texas Instruments&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
027h = Reserved word&lt;br /&gt;
&lt;br /&gt;
02Ah = Start of relocation table&lt;br /&gt;
&lt;br /&gt;
== ExecLib ==&lt;br /&gt;
&lt;br /&gt;
In order to use ExecLib properly from BASIC programs, you must:&lt;br /&gt;
&lt;br /&gt;
1. Set the proper bit at offset 00Ch.&lt;br /&gt;
&lt;br /&gt;
2. Initialize offset 021h to the start of the library jump table&lt;br /&gt;
&lt;br /&gt;
3. Ensure that the jump table offsets are stored in the relocation table&lt;br /&gt;
&lt;br /&gt;
The format for the jump table is shown below: (Note that you store AppLibraryTable offset to 021h).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;	.db	&amp;quot;LIB&amp;quot;&lt;br /&gt;
	.dl	NUMBER_OF_FUNCTIONS_IN_JUMP_TABLE&lt;br /&gt;
AppLibraryTable:&lt;br /&gt;
	.dl	Function_1&lt;br /&gt;
	.dl	Function_2&lt;br /&gt;
	...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relocations ==&lt;br /&gt;
&lt;br /&gt;
Because apps are not stored at a fixed memory address, they require a relocation table to relocate them during sending and defragmentation.&lt;br /&gt;
&lt;br /&gt;
The relocation map consists of a six-byte entry for each location which needs to be updated.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Offset&lt;br /&gt;
! Length&lt;br /&gt;
! Contents&lt;br /&gt;
|-&lt;br /&gt;
| 000h&lt;br /&gt;
| 003h&lt;br /&gt;
| Hole offset&lt;br /&gt;
|-&lt;br /&gt;
| 003h&lt;br /&gt;
| 003h&lt;br /&gt;
| base (2 bits) and relative value to place in hole (22 bits)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''Relocation Map Format'''&lt;br /&gt;
&lt;br /&gt;
The hole offset specifies where in the application code or initial data table an absolute address needs to be updated.&lt;br /&gt;
The value to store in the hole is calculated from the base and relative value. The base is 00 for code-segment relative and 10 for data-segment relative. Base values 01 and 11 are reserved.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
Here is a full demo program demonstrating finding each application, displaying the name, size, version, and copyright information&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;quot;ti84pce.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	.db	tExtTok,tAsm84CECmp&lt;br /&gt;
	.org	usermem&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
; Finds all the apps and displays info&lt;br /&gt;
_FINDAPPS:&lt;br /&gt;
	ld	ix,0&lt;br /&gt;
	add	ix,sp&lt;br /&gt;
	ld	hl,ExecuteApp&lt;br /&gt;
	ld	de,cursorImage&lt;br /&gt;
	ld	bc,ExecuteApp_End-ExecuteApp_Start&lt;br /&gt;
	ldir&lt;br /&gt;
	call	_ZeroOP3&lt;br /&gt;
	ld	a,appObj&lt;br /&gt;
	ld	(OP3),a&lt;br /&gt;
_:	call	_HomeUp&lt;br /&gt;
	call	_ClrScrn&lt;br /&gt;
	call	_OP3ToOP1&lt;br /&gt;
	call	_FindAppUp		; find the app&lt;br /&gt;
	ret	c&lt;br /&gt;
	call	_OP1ToOP3		; store name&lt;br /&gt;
	ld	hl,OP1+1&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_PutS			; put name of app&lt;br /&gt;
	pop	hl			; don't need this push/pop (here for readability)&lt;br /&gt;
	call	_FindAppStart		; find the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	GetAppSize&lt;br /&gt;
	call	_DispHL			; display the size of the app&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_os_GetAppVersionString&lt;br /&gt;
	pop	bc&lt;br /&gt;
	call	_PutS&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	call	FindAppInfoString	; Get the information&lt;br /&gt;
	call	_PutS&lt;br /&gt;
_:	call	_GetCSC&lt;br /&gt;
	or	a,a&lt;br /&gt;
	jr	z,-_&lt;br /&gt;
	cp	a,sk2nd&lt;br /&gt;
	jr	nz,--_&lt;br /&gt;
	ld	hl,OP3+1&lt;br /&gt;
	jp	cursorImage&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
ExecuteApp:&lt;br /&gt;
; HL -&amp;gt; name of app (0 terminated)&lt;br /&gt;
; An alternative would be to copy to progtoedit and call _NewConext0&lt;br /&gt;
	.org	cursorImage&lt;br /&gt;
ExecuteApp_Start:&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	DeletePgrmFromUserMem&lt;br /&gt;
	ld	hl,$100&lt;br /&gt;
	call	_EnoughMem&lt;br /&gt;
	pop	hl&lt;br /&gt;
	jp	c, _ErrMemory&lt;br /&gt;
	call	_FindAppStart		; This locates the start of executable code for an app&lt;br /&gt;
	ld	a,E_Validation&lt;br /&gt;
	jp	c,_JError		; If we can't find it, that's a problem (throw a validation error)&lt;br /&gt;
	push	hl			; push location of start of app&lt;br /&gt;
	call	_ReloadAppEntryVecs&lt;br /&gt;
	call	_AppSetup&lt;br /&gt;
	set	appRunning,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	set	6,(iy+$28)&lt;br /&gt;
	res	0,(iy+$2C)		; set some app flags&lt;br /&gt;
	set	appAllowContext,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	ld	hl,$D1787C		; copy to ram data location&lt;br /&gt;
	ld	bc,$FFF&lt;br /&gt;
	call	_MemClear		; zero out the ram data section&lt;br /&gt;
	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	push	hl			; de -&amp;gt; start of code for app&lt;br /&gt;
	ld	bc,$100			; bypass header information&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ex	de,hl&lt;br /&gt;
	ld	hl,$18			; find the start of the data to copy to ram&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	call	__icmpzero		; initialize the bss if it exists&lt;br /&gt;
	jr	z,+_&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	bc&lt;br /&gt;
	ld	hl,$15&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	de,$D1787C		; copy it in&lt;br /&gt;
	ldir&lt;br /&gt;
_:	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	call	FindStartOfAppCode	; After this, hl -&amp;gt; start of code for app&lt;br /&gt;
	jp	(hl)&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindAppInfoString:&lt;br /&gt;
; Finds the information string about an App&lt;br /&gt;
; i.e. (c) 2005-2014 Texas Instruments&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains start of app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$24&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)			; load location of info string&lt;br /&gt;
	add	hl,de &lt;br /&gt;
	or	a,a &lt;br /&gt;
	sbc	hl,de			; check if HL is 0&lt;br /&gt;
	ret	z&lt;br /&gt;
	add	hl,de			; add extra bytes&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindStartOfAppCode:&lt;br /&gt;
; Finds the start of the actual executable from the start of an App&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains the start of the app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$1B			; offset&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
DeletePgrmFromUserMem:&lt;br /&gt;
	ld	de,(asm_prgm_size)	; load total program prgmSize&lt;br /&gt;
	or	a,a&lt;br /&gt;
	sbc	hl,hl&lt;br /&gt;
	ld	(asm_prgm_size),hl	; delete whatever current program was there&lt;br /&gt;
	ld	hl,userMem&lt;br /&gt;
	jp	_DelMem			; HL-&amp;gt;place to delete, DE=amount to delete&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
GetAppSize:&lt;br /&gt;
; Gets the size of an app based from the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_NextFieldFromType	; move to start of signature&lt;br /&gt;
	call	_NextFieldFromType	; move to end of signature&lt;br /&gt;
	pop	de&lt;br /&gt;
	or	a&lt;br /&gt;
	sbc	hl,de&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl			; bypass app size bytes&lt;br /&gt;
	ret				; haha, we're probably looking at another app here&lt;br /&gt;
ExecuteApp_End:&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Credits and Contribution==&lt;br /&gt;
Matt &amp;quot;MateoConLechuga&amp;quot; Waltz&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications</id>
		<title>84PCE:OS:Applications</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications"/>
				<updated>2017-10-02T06:37:03Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Additional App Structure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:OS_Information]]&lt;br /&gt;
[[Category:84PCE:OS_Information]]&lt;br /&gt;
==Application File Type==&lt;br /&gt;
Applications for the CE calculator have the extension 8ek.&lt;br /&gt;
&lt;br /&gt;
Relocations exist to place the app correctly in the archive, 6 bytes per block (2+22 bits):&lt;br /&gt;
&lt;br /&gt;
0b00 indicates a reference to the code segment executing from Flash, and 0b10 indicates a reference to the data/bss segment in RAM.&lt;br /&gt;
0b01 and 0b11 are a reserved format; &lt;br /&gt;
&lt;br /&gt;
Applications can be of arbitrary size, no longer multiples of 16kB.&lt;br /&gt;
&lt;br /&gt;
==Applications in the Archive==&lt;br /&gt;
Applications are stored beginning at the address 03B0000h and grow downwards. 3 bytes are used as offsets to the start of the app, since the search is backwards. The following status bytes represent what might be found when parsing for applications:&lt;br /&gt;
&lt;br /&gt;
081h = valid Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
000h = deleted Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
Some search code may look like this (Will locate the start of all the app headers):&lt;br /&gt;
&lt;br /&gt;
 _FindValidLocation:&lt;br /&gt;
 	ld	hl,03B0000h            ; applications start here&lt;br /&gt;
 find:	&lt;br /&gt;
 	dec	hl&lt;br /&gt;
  	dec	hl&lt;br /&gt;
 	dec	hl&lt;br /&gt;
 	push	hl&lt;br /&gt;
 	ld	de,(hl)&lt;br /&gt;
 	ld	hl,0FFFFFFh            ; check for end&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de&lt;br /&gt;
 	pop	hl&lt;br /&gt;
 	ret	z                      ; found end of applications&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de                  ; hl points to the start of the app header here if found&lt;br /&gt;
 	jr	find&lt;br /&gt;
&lt;br /&gt;
The actual App header contains certain fields which correspond to the type of data they represent. TI dropped the ball and even though these are variable length fields, the OS code can only handle headers that are padded to 256 bytes in length.&lt;br /&gt;
&lt;br /&gt;
810(F)h = Master field, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
811(2)h = Signing key ID. On the CE, this is 2 bytes in length with the value 0130Fh, indicating it was signed with the '130F' key.&lt;br /&gt;
&lt;br /&gt;
812(D)h = Version information. Begins with the length of the version string, followed by the string itself. This is a minimum compatible version.&lt;br /&gt;
&lt;br /&gt;
813(2)h = Unknown, but contains the 2 byte data 05900h.&lt;br /&gt;
&lt;br /&gt;
814(N)h = Name of App. In this case, 'N' represents the length of the name in bytes. This field is then followed by the name of the app.&lt;br /&gt;
&lt;br /&gt;
817(F)h = End app header information, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
81A(1)h = Unknown, but contains the 1 byte data 007h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other fields:&lt;br /&gt;
&lt;br /&gt;
003h &amp;amp; 2(6)h &amp;amp; 009h &amp;amp; 0(4)h = Time stamp field. 4 bytes long; represents the number of seconds since January 1st 1997, 00:00:00 in some timezone, and some step of the build process.&lt;br /&gt;
&lt;br /&gt;
00Dh &amp;amp; 0NNh = This (NN) represents how much padding until the next field, as app headers must be padded to 256 bytes.&lt;br /&gt;
&lt;br /&gt;
002h &amp;amp; 03(E)h = Signature field. The is followed by the two bytes containing the value 0100h, the length of the 2048 bit signature&lt;br /&gt;
&lt;br /&gt;
At the end of the signature is 3 bytes representing the size of the application. (These bytes are not included however)&lt;br /&gt;
&lt;br /&gt;
App size calculation is as follows: [Length of master header + offset to signature field in (810)] + [4 bytes of signature field + 256 bytes of signature] + [3 bytes application size]&lt;br /&gt;
&lt;br /&gt;
This is pretty much the same as adding 269 to the value in the big endian master field.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an example of such a header:&lt;br /&gt;
&lt;br /&gt;
 ; Master Field -- This app is 102247 + 269 (102516) bytes in size&lt;br /&gt;
 .db	081h, 00Fh, 000h, 001h, 08fh, 067h&lt;br /&gt;
 ; Signing Key Field&lt;br /&gt;
 .db	081h, 012h, 013h, 00Fh&lt;br /&gt;
 ; Version information -- 00Bh represnets the length until the next field&lt;br /&gt;
 .db	081h, 02Dh, 00Bh, &amp;quot;5.0.0.0089&amp;quot;, 000h&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 032h, 059h, 000h&lt;br /&gt;
 ; Name Field -- Name is 7 bytes long, so that is where the 047h comes from&lt;br /&gt;
 .db	081h, 047h, &amp;quot;CabriJr&amp;quot;&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 0A1h, 007h&lt;br /&gt;
 ; Time stamp -- Who knows what time is was?&lt;br /&gt;
 .db	003h, 026h, 009h, 004h&lt;br /&gt;
 .db	021h, 0BBh, 06Eh, 0DCh&lt;br /&gt;
 ; Amount of pading (This is so, so silly)&lt;br /&gt;
 .db	000h, 00Dh, 0C7h&lt;br /&gt;
 ; Padding of 0C7h (199) bytes&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0&lt;br /&gt;
 ; Final field&lt;br /&gt;
 .db	081h, 07Fh, 000h, 001h, 08Eh, 06dh&lt;br /&gt;
 ; End of 256 byte header&lt;br /&gt;
&lt;br /&gt;
==Additional App Structure==&lt;br /&gt;
&lt;br /&gt;
However, apps are also made up of a certain sequence of bytes following the header. Offsets are calculated from the posistion after the header, in addition to the offsets derived from offsets.&lt;br /&gt;
&lt;br /&gt;
Offset after 256 byte header:&lt;br /&gt;
&lt;br /&gt;
000h = The ASCII string &amp;quot;eZ8&amp;quot;, potentially signifying an eZ80 application&lt;br /&gt;
&lt;br /&gt;
003h = Null terminated Application name (zero padded to be 9 bytes in length with terminator byte)&lt;br /&gt;
&lt;br /&gt;
00Ch = Flag, [Bit 0 set - don't draw the TI splash screen] [Bit 1 set - app can use OpenLib]&lt;br /&gt;
&lt;br /&gt;
00Eh = Flag, [Bit 0 set - use the offset in 01Eh] [Bit 3 controls something]&lt;br /&gt;
&lt;br /&gt;
012h = Main section&lt;br /&gt;
&lt;br /&gt;
015h = Initialized data section (Can be at most 4kB in size)&lt;br /&gt;
&lt;br /&gt;
018h = Initialized data section Length&lt;br /&gt;
&lt;br /&gt;
01Bh = Execution entry point (usually same as 012h)&lt;br /&gt;
&lt;br /&gt;
01Eh = Unknown 3 byte offset (See 00Eh)&lt;br /&gt;
&lt;br /&gt;
021h = Offset to ExecLib jump table&lt;br /&gt;
&lt;br /&gt;
024h = Offset to the string used to display a message in the memory screen (Usually a copyright, i.e. &amp;quot;(c) 2005-2015 Texas Instruments&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
027h = Reserved word&lt;br /&gt;
&lt;br /&gt;
02Ah = Start of relocation table&lt;br /&gt;
&lt;br /&gt;
== ExecLib ==&lt;br /&gt;
&lt;br /&gt;
In order to use ExecLib properly from BASIC programs, you must:&lt;br /&gt;
&lt;br /&gt;
1. Set the proper bit at offset 00Ch.&lt;br /&gt;
&lt;br /&gt;
2. Initialize offset 021h to the start of the library jump table&lt;br /&gt;
&lt;br /&gt;
3. Ensure that the jump table offsets are stored in the relocation table&lt;br /&gt;
&lt;br /&gt;
The format for the jump table is shown below: (Note that you store AppLibraryTable offset to 021h).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;	.db	&amp;quot;LIB&amp;quot;&lt;br /&gt;
	.dl	NUMBER_OF_FUNCTIONS_IN_JUMP_TABLE&lt;br /&gt;
AppLibraryTable:&lt;br /&gt;
	.dl	Function_1&lt;br /&gt;
	.dl	Function_2&lt;br /&gt;
	...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relocations ==&lt;br /&gt;
&lt;br /&gt;
Because apps are not stored at a fixed memory address, they require a relocation table to relocate them during sending and defragmentation.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
Here is a full demo program demonstrating finding each application, displaying the name, size, version, and copyright information&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;quot;ti84pce.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	.db	tExtTok,tAsm84CECmp&lt;br /&gt;
	.org	usermem&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
; Finds all the apps and displays info&lt;br /&gt;
_FINDAPPS:&lt;br /&gt;
	ld	ix,0&lt;br /&gt;
	add	ix,sp&lt;br /&gt;
	ld	hl,ExecuteApp&lt;br /&gt;
	ld	de,cursorImage&lt;br /&gt;
	ld	bc,ExecuteApp_End-ExecuteApp_Start&lt;br /&gt;
	ldir&lt;br /&gt;
	call	_ZeroOP3&lt;br /&gt;
	ld	a,appObj&lt;br /&gt;
	ld	(OP3),a&lt;br /&gt;
_:	call	_HomeUp&lt;br /&gt;
	call	_ClrScrn&lt;br /&gt;
	call	_OP3ToOP1&lt;br /&gt;
	call	_FindAppUp		; find the app&lt;br /&gt;
	ret	c&lt;br /&gt;
	call	_OP1ToOP3		; store name&lt;br /&gt;
	ld	hl,OP1+1&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_PutS			; put name of app&lt;br /&gt;
	pop	hl			; don't need this push/pop (here for readability)&lt;br /&gt;
	call	_FindAppStart		; find the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	GetAppSize&lt;br /&gt;
	call	_DispHL			; display the size of the app&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_os_GetAppVersionString&lt;br /&gt;
	pop	bc&lt;br /&gt;
	call	_PutS&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	call	FindAppInfoString	; Get the information&lt;br /&gt;
	call	_PutS&lt;br /&gt;
_:	call	_GetCSC&lt;br /&gt;
	or	a,a&lt;br /&gt;
	jr	z,-_&lt;br /&gt;
	cp	a,sk2nd&lt;br /&gt;
	jr	nz,--_&lt;br /&gt;
	ld	hl,OP3+1&lt;br /&gt;
	jp	cursorImage&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
ExecuteApp:&lt;br /&gt;
; HL -&amp;gt; name of app (0 terminated)&lt;br /&gt;
; An alternative would be to copy to progtoedit and call _NewConext0&lt;br /&gt;
	.org	cursorImage&lt;br /&gt;
ExecuteApp_Start:&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	DeletePgrmFromUserMem&lt;br /&gt;
	ld	hl,$100&lt;br /&gt;
	call	_EnoughMem&lt;br /&gt;
	pop	hl&lt;br /&gt;
	jp	c, _ErrMemory&lt;br /&gt;
	call	_FindAppStart		; This locates the start of executable code for an app&lt;br /&gt;
	ld	a,E_Validation&lt;br /&gt;
	jp	c,_JError		; If we can't find it, that's a problem (throw a validation error)&lt;br /&gt;
	push	hl			; push location of start of app&lt;br /&gt;
	call	_ReloadAppEntryVecs&lt;br /&gt;
	call	_AppSetup&lt;br /&gt;
	set	appRunning,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	set	6,(iy+$28)&lt;br /&gt;
	res	0,(iy+$2C)		; set some app flags&lt;br /&gt;
	set	appAllowContext,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	ld	hl,$D1787C		; copy to ram data location&lt;br /&gt;
	ld	bc,$FFF&lt;br /&gt;
	call	_MemClear		; zero out the ram data section&lt;br /&gt;
	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	push	hl			; de -&amp;gt; start of code for app&lt;br /&gt;
	ld	bc,$100			; bypass header information&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ex	de,hl&lt;br /&gt;
	ld	hl,$18			; find the start of the data to copy to ram&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	call	__icmpzero		; initialize the bss if it exists&lt;br /&gt;
	jr	z,+_&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	bc&lt;br /&gt;
	ld	hl,$15&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	de,$D1787C		; copy it in&lt;br /&gt;
	ldir&lt;br /&gt;
_:	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	call	FindStartOfAppCode	; After this, hl -&amp;gt; start of code for app&lt;br /&gt;
	jp	(hl)&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindAppInfoString:&lt;br /&gt;
; Finds the information string about an App&lt;br /&gt;
; i.e. (c) 2005-2014 Texas Instruments&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains start of app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$24&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)			; load location of info string&lt;br /&gt;
	add	hl,de &lt;br /&gt;
	or	a,a &lt;br /&gt;
	sbc	hl,de			; check if HL is 0&lt;br /&gt;
	ret	z&lt;br /&gt;
	add	hl,de			; add extra bytes&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindStartOfAppCode:&lt;br /&gt;
; Finds the start of the actual executable from the start of an App&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains the start of the app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$1B			; offset&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
DeletePgrmFromUserMem:&lt;br /&gt;
	ld	de,(asm_prgm_size)	; load total program prgmSize&lt;br /&gt;
	or	a,a&lt;br /&gt;
	sbc	hl,hl&lt;br /&gt;
	ld	(asm_prgm_size),hl	; delete whatever current program was there&lt;br /&gt;
	ld	hl,userMem&lt;br /&gt;
	jp	_DelMem			; HL-&amp;gt;place to delete, DE=amount to delete&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
GetAppSize:&lt;br /&gt;
; Gets the size of an app based from the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_NextFieldFromType	; move to start of signature&lt;br /&gt;
	call	_NextFieldFromType	; move to end of signature&lt;br /&gt;
	pop	de&lt;br /&gt;
	or	a&lt;br /&gt;
	sbc	hl,de&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl			; bypass app size bytes&lt;br /&gt;
	ret				; haha, we're probably looking at another app here&lt;br /&gt;
ExecuteApp_End:&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Credits and Contribution==&lt;br /&gt;
Matt &amp;quot;MateoConLechuga&amp;quot; Waltz&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications</id>
		<title>84PCE:OS:Applications</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications"/>
				<updated>2017-10-02T04:54:32Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Additional App Structure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:OS_Information]]&lt;br /&gt;
[[Category:84PCE:OS_Information]]&lt;br /&gt;
==Application File Type==&lt;br /&gt;
Applications for the CE calculator have the extension 8ek.&lt;br /&gt;
&lt;br /&gt;
Relocations exist to place the app correctly in the archive, 6 bytes per block (2+22 bits):&lt;br /&gt;
&lt;br /&gt;
0b00 indicates a reference to the code segment executing from Flash, and 0b10 indicates a reference to the data/bss segment in RAM.&lt;br /&gt;
0b01 and 0b11 are a reserved format; &lt;br /&gt;
&lt;br /&gt;
Applications can be of arbitrary size, no longer multiples of 16kB.&lt;br /&gt;
&lt;br /&gt;
==Applications in the Archive==&lt;br /&gt;
Applications are stored beginning at the address 03B0000h and grow downwards. 3 bytes are used as offsets to the start of the app, since the search is backwards. The following status bytes represent what might be found when parsing for applications:&lt;br /&gt;
&lt;br /&gt;
081h = valid Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
000h = deleted Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
Some search code may look like this (Will locate the start of all the app headers):&lt;br /&gt;
&lt;br /&gt;
 _FindValidLocation:&lt;br /&gt;
 	ld	hl,03B0000h            ; applications start here&lt;br /&gt;
 find:	&lt;br /&gt;
 	dec	hl&lt;br /&gt;
  	dec	hl&lt;br /&gt;
 	dec	hl&lt;br /&gt;
 	push	hl&lt;br /&gt;
 	ld	de,(hl)&lt;br /&gt;
 	ld	hl,0FFFFFFh            ; check for end&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de&lt;br /&gt;
 	pop	hl&lt;br /&gt;
 	ret	z                      ; found end of applications&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de                  ; hl points to the start of the app header here if found&lt;br /&gt;
 	jr	find&lt;br /&gt;
&lt;br /&gt;
The actual App header contains certain fields which correspond to the type of data they represent. TI dropped the ball and even though these are variable length fields, the OS code can only handle headers that are padded to 256 bytes in length.&lt;br /&gt;
&lt;br /&gt;
810(F)h = Master field, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
811(2)h = Signing key ID. On the CE, this is 2 bytes in length with the value 0130Fh, indicating it was signed with the '130F' key.&lt;br /&gt;
&lt;br /&gt;
812(D)h = Version information. Begins with the length of the version string, followed by the string itself. This is a minimum compatible version.&lt;br /&gt;
&lt;br /&gt;
813(2)h = Unknown, but contains the 2 byte data 05900h.&lt;br /&gt;
&lt;br /&gt;
814(N)h = Name of App. In this case, 'N' represents the length of the name in bytes. This field is then followed by the name of the app.&lt;br /&gt;
&lt;br /&gt;
817(F)h = End app header information, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
81A(1)h = Unknown, but contains the 1 byte data 007h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other fields:&lt;br /&gt;
&lt;br /&gt;
003h &amp;amp; 2(6)h &amp;amp; 009h &amp;amp; 0(4)h = Time stamp field. 4 bytes long; represents the number of seconds since January 1st 1997, 00:00:00 in some timezone, and some step of the build process.&lt;br /&gt;
&lt;br /&gt;
00Dh &amp;amp; 0NNh = This (NN) represents how much padding until the next field, as app headers must be padded to 256 bytes.&lt;br /&gt;
&lt;br /&gt;
002h &amp;amp; 03(E)h = Signature field. The is followed by the two bytes containing the value 0100h, the length of the 2048 bit signature&lt;br /&gt;
&lt;br /&gt;
At the end of the signature is 3 bytes representing the size of the application. (These bytes are not included however)&lt;br /&gt;
&lt;br /&gt;
App size calculation is as follows: [Length of master header + offset to signature field in (810)] + [4 bytes of signature field + 256 bytes of signature] + [3 bytes application size]&lt;br /&gt;
&lt;br /&gt;
This is pretty much the same as adding 269 to the value in the big endian master field.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an example of such a header:&lt;br /&gt;
&lt;br /&gt;
 ; Master Field -- This app is 102247 + 269 (102516) bytes in size&lt;br /&gt;
 .db	081h, 00Fh, 000h, 001h, 08fh, 067h&lt;br /&gt;
 ; Signing Key Field&lt;br /&gt;
 .db	081h, 012h, 013h, 00Fh&lt;br /&gt;
 ; Version information -- 00Bh represnets the length until the next field&lt;br /&gt;
 .db	081h, 02Dh, 00Bh, &amp;quot;5.0.0.0089&amp;quot;, 000h&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 032h, 059h, 000h&lt;br /&gt;
 ; Name Field -- Name is 7 bytes long, so that is where the 047h comes from&lt;br /&gt;
 .db	081h, 047h, &amp;quot;CabriJr&amp;quot;&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 0A1h, 007h&lt;br /&gt;
 ; Time stamp -- Who knows what time is was?&lt;br /&gt;
 .db	003h, 026h, 009h, 004h&lt;br /&gt;
 .db	021h, 0BBh, 06Eh, 0DCh&lt;br /&gt;
 ; Amount of pading (This is so, so silly)&lt;br /&gt;
 .db	000h, 00Dh, 0C7h&lt;br /&gt;
 ; Padding of 0C7h (199) bytes&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0&lt;br /&gt;
 ; Final field&lt;br /&gt;
 .db	081h, 07Fh, 000h, 001h, 08Eh, 06dh&lt;br /&gt;
 ; End of 256 byte header&lt;br /&gt;
&lt;br /&gt;
==Additional App Structure==&lt;br /&gt;
&lt;br /&gt;
However, apps are also made up of a certain sequence of bytes following the header. Offsets are calculated from the posistion after the header, in addition to the offsets derived from offsets.&lt;br /&gt;
&lt;br /&gt;
Offset after 256 byte header:&lt;br /&gt;
&lt;br /&gt;
000h = The ASCII string &amp;quot;eZ8&amp;quot;, potentially signifying an eZ80 application&lt;br /&gt;
&lt;br /&gt;
003h = Null terminated Application name (zero padded to be 9 bytes in length with terminator byte)&lt;br /&gt;
&lt;br /&gt;
00Ch = Flag, [Bit 0 set - don't draw the TI splash screen] [Bit 1 set - app can use OpenLib]&lt;br /&gt;
&lt;br /&gt;
00Eh = Flag, [Bit 0 set - use the offset in 01Eh] [Bit 3 controls something]&lt;br /&gt;
&lt;br /&gt;
012h = Main section&lt;br /&gt;
&lt;br /&gt;
015h = Initialized data section (Can be at most 4kB in size)&lt;br /&gt;
&lt;br /&gt;
018h = Initialized data section Length&lt;br /&gt;
&lt;br /&gt;
01Bh = Execution entry point (usually same as 012h)&lt;br /&gt;
&lt;br /&gt;
01Eh = Unknown 3 byte offset (See 00Eh)&lt;br /&gt;
&lt;br /&gt;
021h = Offset to ExecLib jump table&lt;br /&gt;
&lt;br /&gt;
024h = Offset to the string used to display a message in the memory screen (Usually a copyright, i.e. &amp;quot;(c) 2005-2015 Texas Instruments&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
027h = Relocation information or something?&lt;br /&gt;
&lt;br /&gt;
== ExecLib ==&lt;br /&gt;
&lt;br /&gt;
In order to use ExecLib properly from BASIC programs, you must:&lt;br /&gt;
&lt;br /&gt;
1. Set the proper bit at offset 00Ch.&lt;br /&gt;
&lt;br /&gt;
2. Initialize offset 021h to the start of the library jump table&lt;br /&gt;
&lt;br /&gt;
3. Ensure that the jump table offsets are stored in the relocation table&lt;br /&gt;
&lt;br /&gt;
The format for the jump table is shown below: (Note that you store AppLibraryTable offset to 021h).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;	.db	&amp;quot;LIB&amp;quot;&lt;br /&gt;
	.dl	NUMBER_OF_FUNCTIONS_IN_JUMP_TABLE&lt;br /&gt;
AppLibraryTable:&lt;br /&gt;
	.dl	Function_1&lt;br /&gt;
	.dl	Function_2&lt;br /&gt;
	...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relocations ==&lt;br /&gt;
&lt;br /&gt;
Because apps are not stored at a fixed memory address, they require a relocation table to relocate them during sending and defragmentation.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
Here is a full demo program demonstrating finding each application, displaying the name, size, version, and copyright information&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;quot;ti84pce.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	.db	tExtTok,tAsm84CECmp&lt;br /&gt;
	.org	usermem&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
; Finds all the apps and displays info&lt;br /&gt;
_FINDAPPS:&lt;br /&gt;
	ld	ix,0&lt;br /&gt;
	add	ix,sp&lt;br /&gt;
	ld	hl,ExecuteApp&lt;br /&gt;
	ld	de,cursorImage&lt;br /&gt;
	ld	bc,ExecuteApp_End-ExecuteApp_Start&lt;br /&gt;
	ldir&lt;br /&gt;
	call	_ZeroOP3&lt;br /&gt;
	ld	a,appObj&lt;br /&gt;
	ld	(OP3),a&lt;br /&gt;
_:	call	_HomeUp&lt;br /&gt;
	call	_ClrScrn&lt;br /&gt;
	call	_OP3ToOP1&lt;br /&gt;
	call	_FindAppUp		; find the app&lt;br /&gt;
	ret	c&lt;br /&gt;
	call	_OP1ToOP3		; store name&lt;br /&gt;
	ld	hl,OP1+1&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_PutS			; put name of app&lt;br /&gt;
	pop	hl			; don't need this push/pop (here for readability)&lt;br /&gt;
	call	_FindAppStart		; find the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	GetAppSize&lt;br /&gt;
	call	_DispHL			; display the size of the app&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_os_GetAppVersionString&lt;br /&gt;
	pop	bc&lt;br /&gt;
	call	_PutS&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	call	FindAppInfoString	; Get the information&lt;br /&gt;
	call	_PutS&lt;br /&gt;
_:	call	_GetCSC&lt;br /&gt;
	or	a,a&lt;br /&gt;
	jr	z,-_&lt;br /&gt;
	cp	a,sk2nd&lt;br /&gt;
	jr	nz,--_&lt;br /&gt;
	ld	hl,OP3+1&lt;br /&gt;
	jp	cursorImage&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
ExecuteApp:&lt;br /&gt;
; HL -&amp;gt; name of app (0 terminated)&lt;br /&gt;
; An alternative would be to copy to progtoedit and call _NewConext0&lt;br /&gt;
	.org	cursorImage&lt;br /&gt;
ExecuteApp_Start:&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	DeletePgrmFromUserMem&lt;br /&gt;
	ld	hl,$100&lt;br /&gt;
	call	_EnoughMem&lt;br /&gt;
	pop	hl&lt;br /&gt;
	jp	c, _ErrMemory&lt;br /&gt;
	call	_FindAppStart		; This locates the start of executable code for an app&lt;br /&gt;
	ld	a,E_Validation&lt;br /&gt;
	jp	c,_JError		; If we can't find it, that's a problem (throw a validation error)&lt;br /&gt;
	push	hl			; push location of start of app&lt;br /&gt;
	call	_ReloadAppEntryVecs&lt;br /&gt;
	call	_AppSetup&lt;br /&gt;
	set	appRunning,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	set	6,(iy+$28)&lt;br /&gt;
	res	0,(iy+$2C)		; set some app flags&lt;br /&gt;
	set	appAllowContext,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	ld	hl,$D1787C		; copy to ram data location&lt;br /&gt;
	ld	bc,$FFF&lt;br /&gt;
	call	_MemClear		; zero out the ram data section&lt;br /&gt;
	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	push	hl			; de -&amp;gt; start of code for app&lt;br /&gt;
	ld	bc,$100			; bypass header information&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ex	de,hl&lt;br /&gt;
	ld	hl,$18			; find the start of the data to copy to ram&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	call	__icmpzero		; initialize the bss if it exists&lt;br /&gt;
	jr	z,+_&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	bc&lt;br /&gt;
	ld	hl,$15&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	de,$D1787C		; copy it in&lt;br /&gt;
	ldir&lt;br /&gt;
_:	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	call	FindStartOfAppCode	; After this, hl -&amp;gt; start of code for app&lt;br /&gt;
	jp	(hl)&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindAppInfoString:&lt;br /&gt;
; Finds the information string about an App&lt;br /&gt;
; i.e. (c) 2005-2014 Texas Instruments&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains start of app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$24&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)			; load location of info string&lt;br /&gt;
	add	hl,de &lt;br /&gt;
	or	a,a &lt;br /&gt;
	sbc	hl,de			; check if HL is 0&lt;br /&gt;
	ret	z&lt;br /&gt;
	add	hl,de			; add extra bytes&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindStartOfAppCode:&lt;br /&gt;
; Finds the start of the actual executable from the start of an App&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains the start of the app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$1B			; offset&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
DeletePgrmFromUserMem:&lt;br /&gt;
	ld	de,(asm_prgm_size)	; load total program prgmSize&lt;br /&gt;
	or	a,a&lt;br /&gt;
	sbc	hl,hl&lt;br /&gt;
	ld	(asm_prgm_size),hl	; delete whatever current program was there&lt;br /&gt;
	ld	hl,userMem&lt;br /&gt;
	jp	_DelMem			; HL-&amp;gt;place to delete, DE=amount to delete&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
GetAppSize:&lt;br /&gt;
; Gets the size of an app based from the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_NextFieldFromType	; move to start of signature&lt;br /&gt;
	call	_NextFieldFromType	; move to end of signature&lt;br /&gt;
	pop	de&lt;br /&gt;
	or	a&lt;br /&gt;
	sbc	hl,de&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl			; bypass app size bytes&lt;br /&gt;
	ret				; haha, we're probably looking at another app here&lt;br /&gt;
ExecuteApp_End:&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Credits and Contribution==&lt;br /&gt;
Matt &amp;quot;MateoConLechuga&amp;quot; Waltz&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications</id>
		<title>84PCE:OS:Applications</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications"/>
				<updated>2017-10-02T04:51:35Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Additional App Structure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:OS_Information]]&lt;br /&gt;
[[Category:84PCE:OS_Information]]&lt;br /&gt;
==Application File Type==&lt;br /&gt;
Applications for the CE calculator have the extension 8ek.&lt;br /&gt;
&lt;br /&gt;
Relocations exist to place the app correctly in the archive, 6 bytes per block (2+22 bits):&lt;br /&gt;
&lt;br /&gt;
0b00 indicates a reference to the code segment executing from Flash, and 0b10 indicates a reference to the data/bss segment in RAM.&lt;br /&gt;
0b01 and 0b11 are a reserved format; &lt;br /&gt;
&lt;br /&gt;
Applications can be of arbitrary size, no longer multiples of 16kB.&lt;br /&gt;
&lt;br /&gt;
==Applications in the Archive==&lt;br /&gt;
Applications are stored beginning at the address 03B0000h and grow downwards. 3 bytes are used as offsets to the start of the app, since the search is backwards. The following status bytes represent what might be found when parsing for applications:&lt;br /&gt;
&lt;br /&gt;
081h = valid Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
000h = deleted Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
Some search code may look like this (Will locate the start of all the app headers):&lt;br /&gt;
&lt;br /&gt;
 _FindValidLocation:&lt;br /&gt;
 	ld	hl,03B0000h            ; applications start here&lt;br /&gt;
 find:	&lt;br /&gt;
 	dec	hl&lt;br /&gt;
  	dec	hl&lt;br /&gt;
 	dec	hl&lt;br /&gt;
 	push	hl&lt;br /&gt;
 	ld	de,(hl)&lt;br /&gt;
 	ld	hl,0FFFFFFh            ; check for end&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de&lt;br /&gt;
 	pop	hl&lt;br /&gt;
 	ret	z                      ; found end of applications&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de                  ; hl points to the start of the app header here if found&lt;br /&gt;
 	jr	find&lt;br /&gt;
&lt;br /&gt;
The actual App header contains certain fields which correspond to the type of data they represent. TI dropped the ball and even though these are variable length fields, the OS code can only handle headers that are padded to 256 bytes in length.&lt;br /&gt;
&lt;br /&gt;
810(F)h = Master field, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
811(2)h = Signing key ID. On the CE, this is 2 bytes in length with the value 0130Fh, indicating it was signed with the '130F' key.&lt;br /&gt;
&lt;br /&gt;
812(D)h = Version information. Begins with the length of the version string, followed by the string itself. This is a minimum compatible version.&lt;br /&gt;
&lt;br /&gt;
813(2)h = Unknown, but contains the 2 byte data 05900h.&lt;br /&gt;
&lt;br /&gt;
814(N)h = Name of App. In this case, 'N' represents the length of the name in bytes. This field is then followed by the name of the app.&lt;br /&gt;
&lt;br /&gt;
817(F)h = End app header information, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
81A(1)h = Unknown, but contains the 1 byte data 007h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other fields:&lt;br /&gt;
&lt;br /&gt;
003h &amp;amp; 2(6)h &amp;amp; 009h &amp;amp; 0(4)h = Time stamp field. 4 bytes long; represents the number of seconds since January 1st 1997, 00:00:00 in some timezone, and some step of the build process.&lt;br /&gt;
&lt;br /&gt;
00Dh &amp;amp; 0NNh = This (NN) represents how much padding until the next field, as app headers must be padded to 256 bytes.&lt;br /&gt;
&lt;br /&gt;
002h &amp;amp; 03(E)h = Signature field. The is followed by the two bytes containing the value 0100h, the length of the 2048 bit signature&lt;br /&gt;
&lt;br /&gt;
At the end of the signature is 3 bytes representing the size of the application. (These bytes are not included however)&lt;br /&gt;
&lt;br /&gt;
App size calculation is as follows: [Length of master header + offset to signature field in (810)] + [4 bytes of signature field + 256 bytes of signature] + [3 bytes application size]&lt;br /&gt;
&lt;br /&gt;
This is pretty much the same as adding 269 to the value in the big endian master field.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an example of such a header:&lt;br /&gt;
&lt;br /&gt;
 ; Master Field -- This app is 102247 + 269 (102516) bytes in size&lt;br /&gt;
 .db	081h, 00Fh, 000h, 001h, 08fh, 067h&lt;br /&gt;
 ; Signing Key Field&lt;br /&gt;
 .db	081h, 012h, 013h, 00Fh&lt;br /&gt;
 ; Version information -- 00Bh represnets the length until the next field&lt;br /&gt;
 .db	081h, 02Dh, 00Bh, &amp;quot;5.0.0.0089&amp;quot;, 000h&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 032h, 059h, 000h&lt;br /&gt;
 ; Name Field -- Name is 7 bytes long, so that is where the 047h comes from&lt;br /&gt;
 .db	081h, 047h, &amp;quot;CabriJr&amp;quot;&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 0A1h, 007h&lt;br /&gt;
 ; Time stamp -- Who knows what time is was?&lt;br /&gt;
 .db	003h, 026h, 009h, 004h&lt;br /&gt;
 .db	021h, 0BBh, 06Eh, 0DCh&lt;br /&gt;
 ; Amount of pading (This is so, so silly)&lt;br /&gt;
 .db	000h, 00Dh, 0C7h&lt;br /&gt;
 ; Padding of 0C7h (199) bytes&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0&lt;br /&gt;
 ; Final field&lt;br /&gt;
 .db	081h, 07Fh, 000h, 001h, 08Eh, 06dh&lt;br /&gt;
 ; End of 256 byte header&lt;br /&gt;
&lt;br /&gt;
==Additional App Structure==&lt;br /&gt;
&lt;br /&gt;
However, apps are also made up of a certain sequence of bytes following the header. Offsets are calculated from the posistion after the header, in addition to the offsets derived from offsets.&lt;br /&gt;
&lt;br /&gt;
Offset after 256 byte header:&lt;br /&gt;
&lt;br /&gt;
000h = The ASCII string &amp;quot;eZ8&amp;quot;, potentially signifying an eZ80 application&lt;br /&gt;
&lt;br /&gt;
003h = Null terminated Application name (zero padded to be 9 bytes in length with terminator byte)&lt;br /&gt;
&lt;br /&gt;
00Ch = Flag, [Bit 0 set - don't draw the TI splash screen] [Bit 1 set - app can use OpenLib]&lt;br /&gt;
&lt;br /&gt;
00Eh = Flag, [Bit 0 set - use the offset in 01Eh] [Bit 3 controls something]&lt;br /&gt;
&lt;br /&gt;
012h = Main section (this also points to the end of the relocations table)&lt;br /&gt;
&lt;br /&gt;
015h = Initialized data section (Can be at most 4kB in size)&lt;br /&gt;
&lt;br /&gt;
018h = Initialized data section Length&lt;br /&gt;
&lt;br /&gt;
01Bh = Execution entry point&lt;br /&gt;
&lt;br /&gt;
01Eh = Unknown 3 byte offset (See 00Eh)&lt;br /&gt;
&lt;br /&gt;
021h = Offset to ExecLib jump table&lt;br /&gt;
&lt;br /&gt;
024h = Offset to the string used to display a message in the memory screen (Usually a copyright, i.e. &amp;quot;(c) 2005-2015 Texas Instruments&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
027h = Relocation information or something?&lt;br /&gt;
&lt;br /&gt;
== ExecLib ==&lt;br /&gt;
&lt;br /&gt;
In order to use ExecLib properly from BASIC programs, you must:&lt;br /&gt;
&lt;br /&gt;
1. Set the proper bit at offset 00Ch.&lt;br /&gt;
&lt;br /&gt;
2. Initialize offset 021h to the start of the library jump table&lt;br /&gt;
&lt;br /&gt;
3. Ensure that the jump table offsets are stored in the relocation table&lt;br /&gt;
&lt;br /&gt;
The format for the jump table is shown below: (Note that you store AppLibraryTable offset to 021h).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;	.db	&amp;quot;LIB&amp;quot;&lt;br /&gt;
	.dl	NUMBER_OF_FUNCTIONS_IN_JUMP_TABLE&lt;br /&gt;
AppLibraryTable:&lt;br /&gt;
	.dl	Function_1&lt;br /&gt;
	.dl	Function_2&lt;br /&gt;
	...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relocations ==&lt;br /&gt;
&lt;br /&gt;
Because apps are not stored at a fixed memory address, they require a relocation table to relocate them during sending and defragmentation.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
Here is a full demo program demonstrating finding each application, displaying the name, size, version, and copyright information&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;quot;ti84pce.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	.db	tExtTok,tAsm84CECmp&lt;br /&gt;
	.org	usermem&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
; Finds all the apps and displays info&lt;br /&gt;
_FINDAPPS:&lt;br /&gt;
	ld	ix,0&lt;br /&gt;
	add	ix,sp&lt;br /&gt;
	ld	hl,ExecuteApp&lt;br /&gt;
	ld	de,cursorImage&lt;br /&gt;
	ld	bc,ExecuteApp_End-ExecuteApp_Start&lt;br /&gt;
	ldir&lt;br /&gt;
	call	_ZeroOP3&lt;br /&gt;
	ld	a,appObj&lt;br /&gt;
	ld	(OP3),a&lt;br /&gt;
_:	call	_HomeUp&lt;br /&gt;
	call	_ClrScrn&lt;br /&gt;
	call	_OP3ToOP1&lt;br /&gt;
	call	_FindAppUp		; find the app&lt;br /&gt;
	ret	c&lt;br /&gt;
	call	_OP1ToOP3		; store name&lt;br /&gt;
	ld	hl,OP1+1&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_PutS			; put name of app&lt;br /&gt;
	pop	hl			; don't need this push/pop (here for readability)&lt;br /&gt;
	call	_FindAppStart		; find the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	GetAppSize&lt;br /&gt;
	call	_DispHL			; display the size of the app&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_os_GetAppVersionString&lt;br /&gt;
	pop	bc&lt;br /&gt;
	call	_PutS&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	call	FindAppInfoString	; Get the information&lt;br /&gt;
	call	_PutS&lt;br /&gt;
_:	call	_GetCSC&lt;br /&gt;
	or	a,a&lt;br /&gt;
	jr	z,-_&lt;br /&gt;
	cp	a,sk2nd&lt;br /&gt;
	jr	nz,--_&lt;br /&gt;
	ld	hl,OP3+1&lt;br /&gt;
	jp	cursorImage&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
ExecuteApp:&lt;br /&gt;
; HL -&amp;gt; name of app (0 terminated)&lt;br /&gt;
; An alternative would be to copy to progtoedit and call _NewConext0&lt;br /&gt;
	.org	cursorImage&lt;br /&gt;
ExecuteApp_Start:&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	DeletePgrmFromUserMem&lt;br /&gt;
	ld	hl,$100&lt;br /&gt;
	call	_EnoughMem&lt;br /&gt;
	pop	hl&lt;br /&gt;
	jp	c, _ErrMemory&lt;br /&gt;
	call	_FindAppStart		; This locates the start of executable code for an app&lt;br /&gt;
	ld	a,E_Validation&lt;br /&gt;
	jp	c,_JError		; If we can't find it, that's a problem (throw a validation error)&lt;br /&gt;
	push	hl			; push location of start of app&lt;br /&gt;
	call	_ReloadAppEntryVecs&lt;br /&gt;
	call	_AppSetup&lt;br /&gt;
	set	appRunning,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	set	6,(iy+$28)&lt;br /&gt;
	res	0,(iy+$2C)		; set some app flags&lt;br /&gt;
	set	appAllowContext,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	ld	hl,$D1787C		; copy to ram data location&lt;br /&gt;
	ld	bc,$FFF&lt;br /&gt;
	call	_MemClear		; zero out the ram data section&lt;br /&gt;
	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	push	hl			; de -&amp;gt; start of code for app&lt;br /&gt;
	ld	bc,$100			; bypass header information&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ex	de,hl&lt;br /&gt;
	ld	hl,$18			; find the start of the data to copy to ram&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	call	__icmpzero		; initialize the bss if it exists&lt;br /&gt;
	jr	z,+_&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	bc&lt;br /&gt;
	ld	hl,$15&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	de,$D1787C		; copy it in&lt;br /&gt;
	ldir&lt;br /&gt;
_:	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	call	FindStartOfAppCode	; After this, hl -&amp;gt; start of code for app&lt;br /&gt;
	jp	(hl)&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindAppInfoString:&lt;br /&gt;
; Finds the information string about an App&lt;br /&gt;
; i.e. (c) 2005-2014 Texas Instruments&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains start of app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$24&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)			; load location of info string&lt;br /&gt;
	add	hl,de &lt;br /&gt;
	or	a,a &lt;br /&gt;
	sbc	hl,de			; check if HL is 0&lt;br /&gt;
	ret	z&lt;br /&gt;
	add	hl,de			; add extra bytes&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindStartOfAppCode:&lt;br /&gt;
; Finds the start of the actual executable from the start of an App&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains the start of the app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$1B			; offset&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
DeletePgrmFromUserMem:&lt;br /&gt;
	ld	de,(asm_prgm_size)	; load total program prgmSize&lt;br /&gt;
	or	a,a&lt;br /&gt;
	sbc	hl,hl&lt;br /&gt;
	ld	(asm_prgm_size),hl	; delete whatever current program was there&lt;br /&gt;
	ld	hl,userMem&lt;br /&gt;
	jp	_DelMem			; HL-&amp;gt;place to delete, DE=amount to delete&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
GetAppSize:&lt;br /&gt;
; Gets the size of an app based from the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_NextFieldFromType	; move to start of signature&lt;br /&gt;
	call	_NextFieldFromType	; move to end of signature&lt;br /&gt;
	pop	de&lt;br /&gt;
	or	a&lt;br /&gt;
	sbc	hl,de&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl			; bypass app size bytes&lt;br /&gt;
	ret				; haha, we're probably looking at another app here&lt;br /&gt;
ExecuteApp_End:&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Credits and Contribution==&lt;br /&gt;
Matt &amp;quot;MateoConLechuga&amp;quot; Waltz&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications</id>
		<title>84PCE:OS:Applications</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications"/>
				<updated>2017-10-02T03:41:53Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Additional App Structure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:OS_Information]]&lt;br /&gt;
[[Category:84PCE:OS_Information]]&lt;br /&gt;
==Application File Type==&lt;br /&gt;
Applications for the CE calculator have the extension 8ek.&lt;br /&gt;
&lt;br /&gt;
Relocations exist to place the app correctly in the archive, 6 bytes per block (2+22 bits):&lt;br /&gt;
&lt;br /&gt;
0b00 indicates a reference to the code segment executing from Flash, and 0b10 indicates a reference to the data/bss segment in RAM.&lt;br /&gt;
0b01 and 0b11 are a reserved format; &lt;br /&gt;
&lt;br /&gt;
Applications can be of arbitrary size, no longer multiples of 16kB.&lt;br /&gt;
&lt;br /&gt;
==Applications in the Archive==&lt;br /&gt;
Applications are stored beginning at the address 03B0000h and grow downwards. 3 bytes are used as offsets to the start of the app, since the search is backwards. The following status bytes represent what might be found when parsing for applications:&lt;br /&gt;
&lt;br /&gt;
081h = valid Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
000h = deleted Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
Some search code may look like this (Will locate the start of all the app headers):&lt;br /&gt;
&lt;br /&gt;
 _FindValidLocation:&lt;br /&gt;
 	ld	hl,03B0000h            ; applications start here&lt;br /&gt;
 find:	&lt;br /&gt;
 	dec	hl&lt;br /&gt;
  	dec	hl&lt;br /&gt;
 	dec	hl&lt;br /&gt;
 	push	hl&lt;br /&gt;
 	ld	de,(hl)&lt;br /&gt;
 	ld	hl,0FFFFFFh            ; check for end&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de&lt;br /&gt;
 	pop	hl&lt;br /&gt;
 	ret	z                      ; found end of applications&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de                  ; hl points to the start of the app header here if found&lt;br /&gt;
 	jr	find&lt;br /&gt;
&lt;br /&gt;
The actual App header contains certain fields which correspond to the type of data they represent. TI dropped the ball and even though these are variable length fields, the OS code can only handle headers that are padded to 256 bytes in length.&lt;br /&gt;
&lt;br /&gt;
810(F)h = Master field, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
811(2)h = Signing key ID. On the CE, this is 2 bytes in length with the value 0130Fh, indicating it was signed with the '130F' key.&lt;br /&gt;
&lt;br /&gt;
812(D)h = Version information. Begins with the length of the version string, followed by the string itself. This is a minimum compatible version.&lt;br /&gt;
&lt;br /&gt;
813(2)h = Unknown, but contains the 2 byte data 05900h.&lt;br /&gt;
&lt;br /&gt;
814(N)h = Name of App. In this case, 'N' represents the length of the name in bytes. This field is then followed by the name of the app.&lt;br /&gt;
&lt;br /&gt;
817(F)h = End app header information, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
81A(1)h = Unknown, but contains the 1 byte data 007h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other fields:&lt;br /&gt;
&lt;br /&gt;
003h &amp;amp; 2(6)h &amp;amp; 009h &amp;amp; 0(4)h = Time stamp field. 4 bytes long; represents the number of seconds since January 1st 1997, 00:00:00 in some timezone, and some step of the build process.&lt;br /&gt;
&lt;br /&gt;
00Dh &amp;amp; 0NNh = This (NN) represents how much padding until the next field, as app headers must be padded to 256 bytes.&lt;br /&gt;
&lt;br /&gt;
002h &amp;amp; 03(E)h = Signature field. The is followed by the two bytes containing the value 0100h, the length of the 2048 bit signature&lt;br /&gt;
&lt;br /&gt;
At the end of the signature is 3 bytes representing the size of the application. (These bytes are not included however)&lt;br /&gt;
&lt;br /&gt;
App size calculation is as follows: [Length of master header + offset to signature field in (810)] + [4 bytes of signature field + 256 bytes of signature] + [3 bytes application size]&lt;br /&gt;
&lt;br /&gt;
This is pretty much the same as adding 269 to the value in the big endian master field.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an example of such a header:&lt;br /&gt;
&lt;br /&gt;
 ; Master Field -- This app is 102247 + 269 (102516) bytes in size&lt;br /&gt;
 .db	081h, 00Fh, 000h, 001h, 08fh, 067h&lt;br /&gt;
 ; Signing Key Field&lt;br /&gt;
 .db	081h, 012h, 013h, 00Fh&lt;br /&gt;
 ; Version information -- 00Bh represnets the length until the next field&lt;br /&gt;
 .db	081h, 02Dh, 00Bh, &amp;quot;5.0.0.0089&amp;quot;, 000h&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 032h, 059h, 000h&lt;br /&gt;
 ; Name Field -- Name is 7 bytes long, so that is where the 047h comes from&lt;br /&gt;
 .db	081h, 047h, &amp;quot;CabriJr&amp;quot;&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 0A1h, 007h&lt;br /&gt;
 ; Time stamp -- Who knows what time is was?&lt;br /&gt;
 .db	003h, 026h, 009h, 004h&lt;br /&gt;
 .db	021h, 0BBh, 06Eh, 0DCh&lt;br /&gt;
 ; Amount of pading (This is so, so silly)&lt;br /&gt;
 .db	000h, 00Dh, 0C7h&lt;br /&gt;
 ; Padding of 0C7h (199) bytes&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0&lt;br /&gt;
 ; Final field&lt;br /&gt;
 .db	081h, 07Fh, 000h, 001h, 08Eh, 06dh&lt;br /&gt;
 ; End of 256 byte header&lt;br /&gt;
&lt;br /&gt;
==Additional App Structure==&lt;br /&gt;
&lt;br /&gt;
However, apps are also made up of a certain sequence of bytes following the header. Offsets are calculated from the posistion after the header, in addition to the offsets derived from offsets.&lt;br /&gt;
&lt;br /&gt;
Offset after 256 byte header:&lt;br /&gt;
&lt;br /&gt;
000h = The ASCII string &amp;quot;eZ8&amp;quot;, potentially signifying an eZ80 application&lt;br /&gt;
&lt;br /&gt;
003h = Null terminated Application name (zero padded to be 9 bytes in length with terminator byte)&lt;br /&gt;
&lt;br /&gt;
00Ch = Flag, [Bit 0 set - don't draw the TI splash screen] [Bit 1 set - app can use OpenLib]&lt;br /&gt;
&lt;br /&gt;
00Eh = Flag, [Bit 0 set - use the offset in 01Eh] [Bit 3 controls something]&lt;br /&gt;
&lt;br /&gt;
012h = Main section (this also points to the end of the relocations table)&lt;br /&gt;
&lt;br /&gt;
015h = Initialized data section (Can be at most 4kB in size)&lt;br /&gt;
&lt;br /&gt;
018h = Initialized data section Length&lt;br /&gt;
&lt;br /&gt;
01Bh = Execution entry point&lt;br /&gt;
&lt;br /&gt;
01Eh = Unknown 3 byte offset (See 00Eh)&lt;br /&gt;
&lt;br /&gt;
021h = Offset to ExecLib jump table&lt;br /&gt;
&lt;br /&gt;
024h = Offset to the string used to display a message in the memory screen (Usually a copyright, i.e. &amp;quot;(c) 2005-2015 Texas Instruments&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
027h = Offset to relocation information&lt;br /&gt;
&lt;br /&gt;
02Ah = If no relocations this location should be what 012h offsets to&lt;br /&gt;
&lt;br /&gt;
== ExecLib ==&lt;br /&gt;
&lt;br /&gt;
In order to use ExecLib properly from BASIC programs, you must:&lt;br /&gt;
&lt;br /&gt;
1. Set the proper bit at offset 00Ch.&lt;br /&gt;
&lt;br /&gt;
2. Initialize offset 021h to the start of the library jump table&lt;br /&gt;
&lt;br /&gt;
3. Ensure that the jump table offsets are stored in the relocation table&lt;br /&gt;
&lt;br /&gt;
The format for the jump table is shown below: (Note that you store AppLibraryTable offset to 021h).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;	.db	&amp;quot;LIB&amp;quot;&lt;br /&gt;
	.dl	NUMBER_OF_FUNCTIONS_IN_JUMP_TABLE&lt;br /&gt;
AppLibraryTable:&lt;br /&gt;
	.dl	Function_1&lt;br /&gt;
	.dl	Function_2&lt;br /&gt;
	...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relocations ==&lt;br /&gt;
&lt;br /&gt;
Because apps are not stored at a fixed memory address, they require a relocation table to relocate them during sending and defragmentation.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
Here is a full demo program demonstrating finding each application, displaying the name, size, version, and copyright information&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;quot;ti84pce.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	.db	tExtTok,tAsm84CECmp&lt;br /&gt;
	.org	usermem&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
; Finds all the apps and displays info&lt;br /&gt;
_FINDAPPS:&lt;br /&gt;
	ld	ix,0&lt;br /&gt;
	add	ix,sp&lt;br /&gt;
	ld	hl,ExecuteApp&lt;br /&gt;
	ld	de,cursorImage&lt;br /&gt;
	ld	bc,ExecuteApp_End-ExecuteApp_Start&lt;br /&gt;
	ldir&lt;br /&gt;
	call	_ZeroOP3&lt;br /&gt;
	ld	a,appObj&lt;br /&gt;
	ld	(OP3),a&lt;br /&gt;
_:	call	_HomeUp&lt;br /&gt;
	call	_ClrScrn&lt;br /&gt;
	call	_OP3ToOP1&lt;br /&gt;
	call	_FindAppUp		; find the app&lt;br /&gt;
	ret	c&lt;br /&gt;
	call	_OP1ToOP3		; store name&lt;br /&gt;
	ld	hl,OP1+1&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_PutS			; put name of app&lt;br /&gt;
	pop	hl			; don't need this push/pop (here for readability)&lt;br /&gt;
	call	_FindAppStart		; find the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	GetAppSize&lt;br /&gt;
	call	_DispHL			; display the size of the app&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_os_GetAppVersionString&lt;br /&gt;
	pop	bc&lt;br /&gt;
	call	_PutS&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	call	FindAppInfoString	; Get the information&lt;br /&gt;
	call	_PutS&lt;br /&gt;
_:	call	_GetCSC&lt;br /&gt;
	or	a,a&lt;br /&gt;
	jr	z,-_&lt;br /&gt;
	cp	a,sk2nd&lt;br /&gt;
	jr	nz,--_&lt;br /&gt;
	ld	hl,OP3+1&lt;br /&gt;
	jp	cursorImage&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
ExecuteApp:&lt;br /&gt;
; HL -&amp;gt; name of app (0 terminated)&lt;br /&gt;
; An alternative would be to copy to progtoedit and call _NewConext0&lt;br /&gt;
	.org	cursorImage&lt;br /&gt;
ExecuteApp_Start:&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	DeletePgrmFromUserMem&lt;br /&gt;
	ld	hl,$100&lt;br /&gt;
	call	_EnoughMem&lt;br /&gt;
	pop	hl&lt;br /&gt;
	jp	c, _ErrMemory&lt;br /&gt;
	call	_FindAppStart		; This locates the start of executable code for an app&lt;br /&gt;
	ld	a,E_Validation&lt;br /&gt;
	jp	c,_JError		; If we can't find it, that's a problem (throw a validation error)&lt;br /&gt;
	push	hl			; push location of start of app&lt;br /&gt;
	call	_ReloadAppEntryVecs&lt;br /&gt;
	call	_AppSetup&lt;br /&gt;
	set	appRunning,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	set	6,(iy+$28)&lt;br /&gt;
	res	0,(iy+$2C)		; set some app flags&lt;br /&gt;
	set	appAllowContext,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	ld	hl,$D1787C		; copy to ram data location&lt;br /&gt;
	ld	bc,$FFF&lt;br /&gt;
	call	_MemClear		; zero out the ram data section&lt;br /&gt;
	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	push	hl			; de -&amp;gt; start of code for app&lt;br /&gt;
	ld	bc,$100			; bypass header information&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ex	de,hl&lt;br /&gt;
	ld	hl,$18			; find the start of the data to copy to ram&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	call	__icmpzero		; initialize the bss if it exists&lt;br /&gt;
	jr	z,+_&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	bc&lt;br /&gt;
	ld	hl,$15&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	de,$D1787C		; copy it in&lt;br /&gt;
	ldir&lt;br /&gt;
_:	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	call	FindStartOfAppCode	; After this, hl -&amp;gt; start of code for app&lt;br /&gt;
	jp	(hl)&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindAppInfoString:&lt;br /&gt;
; Finds the information string about an App&lt;br /&gt;
; i.e. (c) 2005-2014 Texas Instruments&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains start of app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$24&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)			; load location of info string&lt;br /&gt;
	add	hl,de &lt;br /&gt;
	or	a,a &lt;br /&gt;
	sbc	hl,de			; check if HL is 0&lt;br /&gt;
	ret	z&lt;br /&gt;
	add	hl,de			; add extra bytes&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindStartOfAppCode:&lt;br /&gt;
; Finds the start of the actual executable from the start of an App&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains the start of the app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$1B			; offset&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
DeletePgrmFromUserMem:&lt;br /&gt;
	ld	de,(asm_prgm_size)	; load total program prgmSize&lt;br /&gt;
	or	a,a&lt;br /&gt;
	sbc	hl,hl&lt;br /&gt;
	ld	(asm_prgm_size),hl	; delete whatever current program was there&lt;br /&gt;
	ld	hl,userMem&lt;br /&gt;
	jp	_DelMem			; HL-&amp;gt;place to delete, DE=amount to delete&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
GetAppSize:&lt;br /&gt;
; Gets the size of an app based from the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_NextFieldFromType	; move to start of signature&lt;br /&gt;
	call	_NextFieldFromType	; move to end of signature&lt;br /&gt;
	pop	de&lt;br /&gt;
	or	a&lt;br /&gt;
	sbc	hl,de&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl			; bypass app size bytes&lt;br /&gt;
	ret				; haha, we're probably looking at another app here&lt;br /&gt;
ExecuteApp_End:&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Credits and Contribution==&lt;br /&gt;
Matt &amp;quot;MateoConLechuga&amp;quot; Waltz&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications</id>
		<title>84PCE:OS:Applications</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications"/>
				<updated>2017-10-02T03:06:07Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:OS_Information]]&lt;br /&gt;
[[Category:84PCE:OS_Information]]&lt;br /&gt;
==Application File Type==&lt;br /&gt;
Applications for the CE calculator have the extension 8ek.&lt;br /&gt;
&lt;br /&gt;
Relocations exist to place the app correctly in the archive, 6 bytes per block (2+22 bits):&lt;br /&gt;
&lt;br /&gt;
0b00 indicates a reference to the code segment executing from Flash, and 0b10 indicates a reference to the data/bss segment in RAM.&lt;br /&gt;
0b01 and 0b11 are a reserved format; &lt;br /&gt;
&lt;br /&gt;
Applications can be of arbitrary size, no longer multiples of 16kB.&lt;br /&gt;
&lt;br /&gt;
==Applications in the Archive==&lt;br /&gt;
Applications are stored beginning at the address 03B0000h and grow downwards. 3 bytes are used as offsets to the start of the app, since the search is backwards. The following status bytes represent what might be found when parsing for applications:&lt;br /&gt;
&lt;br /&gt;
081h = valid Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
000h = deleted Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
Some search code may look like this (Will locate the start of all the app headers):&lt;br /&gt;
&lt;br /&gt;
 _FindValidLocation:&lt;br /&gt;
 	ld	hl,03B0000h            ; applications start here&lt;br /&gt;
 find:	&lt;br /&gt;
 	dec	hl&lt;br /&gt;
  	dec	hl&lt;br /&gt;
 	dec	hl&lt;br /&gt;
 	push	hl&lt;br /&gt;
 	ld	de,(hl)&lt;br /&gt;
 	ld	hl,0FFFFFFh            ; check for end&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de&lt;br /&gt;
 	pop	hl&lt;br /&gt;
 	ret	z                      ; found end of applications&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de                  ; hl points to the start of the app header here if found&lt;br /&gt;
 	jr	find&lt;br /&gt;
&lt;br /&gt;
The actual App header contains certain fields which correspond to the type of data they represent. TI dropped the ball and even though these are variable length fields, the OS code can only handle headers that are padded to 256 bytes in length.&lt;br /&gt;
&lt;br /&gt;
810(F)h = Master field, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
811(2)h = Signing key ID. On the CE, this is 2 bytes in length with the value 0130Fh, indicating it was signed with the '130F' key.&lt;br /&gt;
&lt;br /&gt;
812(D)h = Version information. Begins with the length of the version string, followed by the string itself. This is a minimum compatible version.&lt;br /&gt;
&lt;br /&gt;
813(2)h = Unknown, but contains the 2 byte data 05900h.&lt;br /&gt;
&lt;br /&gt;
814(N)h = Name of App. In this case, 'N' represents the length of the name in bytes. This field is then followed by the name of the app.&lt;br /&gt;
&lt;br /&gt;
817(F)h = End app header information, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
81A(1)h = Unknown, but contains the 1 byte data 007h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other fields:&lt;br /&gt;
&lt;br /&gt;
003h &amp;amp; 2(6)h &amp;amp; 009h &amp;amp; 0(4)h = Time stamp field. 4 bytes long; represents the number of seconds since January 1st 1997, 00:00:00 in some timezone, and some step of the build process.&lt;br /&gt;
&lt;br /&gt;
00Dh &amp;amp; 0NNh = This (NN) represents how much padding until the next field, as app headers must be padded to 256 bytes.&lt;br /&gt;
&lt;br /&gt;
002h &amp;amp; 03(E)h = Signature field. The is followed by the two bytes containing the value 0100h, the length of the 2048 bit signature&lt;br /&gt;
&lt;br /&gt;
At the end of the signature is 3 bytes representing the size of the application. (These bytes are not included however)&lt;br /&gt;
&lt;br /&gt;
App size calculation is as follows: [Length of master header + offset to signature field in (810)] + [4 bytes of signature field + 256 bytes of signature] + [3 bytes application size]&lt;br /&gt;
&lt;br /&gt;
This is pretty much the same as adding 269 to the value in the big endian master field.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an example of such a header:&lt;br /&gt;
&lt;br /&gt;
 ; Master Field -- This app is 102247 + 269 (102516) bytes in size&lt;br /&gt;
 .db	081h, 00Fh, 000h, 001h, 08fh, 067h&lt;br /&gt;
 ; Signing Key Field&lt;br /&gt;
 .db	081h, 012h, 013h, 00Fh&lt;br /&gt;
 ; Version information -- 00Bh represnets the length until the next field&lt;br /&gt;
 .db	081h, 02Dh, 00Bh, &amp;quot;5.0.0.0089&amp;quot;, 000h&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 032h, 059h, 000h&lt;br /&gt;
 ; Name Field -- Name is 7 bytes long, so that is where the 047h comes from&lt;br /&gt;
 .db	081h, 047h, &amp;quot;CabriJr&amp;quot;&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 0A1h, 007h&lt;br /&gt;
 ; Time stamp -- Who knows what time is was?&lt;br /&gt;
 .db	003h, 026h, 009h, 004h&lt;br /&gt;
 .db	021h, 0BBh, 06Eh, 0DCh&lt;br /&gt;
 ; Amount of pading (This is so, so silly)&lt;br /&gt;
 .db	000h, 00Dh, 0C7h&lt;br /&gt;
 ; Padding of 0C7h (199) bytes&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0&lt;br /&gt;
 ; Final field&lt;br /&gt;
 .db	081h, 07Fh, 000h, 001h, 08Eh, 06dh&lt;br /&gt;
 ; End of 256 byte header&lt;br /&gt;
&lt;br /&gt;
==Additional App Structure==&lt;br /&gt;
&lt;br /&gt;
However, apps are also made up of a certain sequence of bytes following the header. Offsets are calculated from the posistion after the header, in addition to the offsets derived from offsets.&lt;br /&gt;
&lt;br /&gt;
Offset after 256 byte header:&lt;br /&gt;
&lt;br /&gt;
000h = The ASCII string &amp;quot;eZ8&amp;quot;, potentially signifying an eZ80 application&lt;br /&gt;
&lt;br /&gt;
003h = Null terminated Application name (zero padded to be 9 bytes in length with terminator byte)&lt;br /&gt;
&lt;br /&gt;
00Ch = Flag, [Bit 0 set - don't draw the TI splash screen] [Bit 1 set - app can use OpenLib]&lt;br /&gt;
&lt;br /&gt;
00Eh = Flag, [Bit 0 set - use the offset in 01Eh]&lt;br /&gt;
&lt;br /&gt;
012h = Main section (this also points to the end of the relocations table)&lt;br /&gt;
&lt;br /&gt;
015h = Initialized data section (Can be at most 4kB in size)&lt;br /&gt;
&lt;br /&gt;
018h = Initialized data section Length&lt;br /&gt;
&lt;br /&gt;
01Bh = Execution entry point&lt;br /&gt;
&lt;br /&gt;
01Eh = Unknown 3 byte offset (See 00Eh)&lt;br /&gt;
&lt;br /&gt;
021h = Offset to ExecLib jump table&lt;br /&gt;
&lt;br /&gt;
024h = Offset to the string used to display a message in the memory screen (Usually a copyright, i.e. &amp;quot;(c) 2005-2015 Texas Instruments&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
027h = Offset to relocation information&lt;br /&gt;
&lt;br /&gt;
02Ah = If no relocations this location should be what 012h offsets to&lt;br /&gt;
&lt;br /&gt;
== ExecLib ==&lt;br /&gt;
&lt;br /&gt;
In order to use ExecLib properly from BASIC programs, you must:&lt;br /&gt;
&lt;br /&gt;
1. Set the proper bit at offset 00Ch.&lt;br /&gt;
&lt;br /&gt;
2. Initialize offset 021h to the start of the library jump table&lt;br /&gt;
&lt;br /&gt;
3. Ensure that the jump table offsets are stored in the relocation table&lt;br /&gt;
&lt;br /&gt;
The format for the jump table is shown below: (Note that you store AppLibraryTable offset to 021h).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;	.db	&amp;quot;LIB&amp;quot;&lt;br /&gt;
	.dl	NUMBER_OF_FUNCTIONS_IN_JUMP_TABLE&lt;br /&gt;
AppLibraryTable:&lt;br /&gt;
	.dl	Function_1&lt;br /&gt;
	.dl	Function_2&lt;br /&gt;
	...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relocations ==&lt;br /&gt;
&lt;br /&gt;
Because apps are not stored at a fixed memory address, they require a relocation table to relocate them during sending and defragmentation.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
Here is a full demo program demonstrating finding each application, displaying the name, size, version, and copyright information&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;quot;ti84pce.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	.db	tExtTok,tAsm84CECmp&lt;br /&gt;
	.org	usermem&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
; Finds all the apps and displays info&lt;br /&gt;
_FINDAPPS:&lt;br /&gt;
	ld	ix,0&lt;br /&gt;
	add	ix,sp&lt;br /&gt;
	ld	hl,ExecuteApp&lt;br /&gt;
	ld	de,cursorImage&lt;br /&gt;
	ld	bc,ExecuteApp_End-ExecuteApp_Start&lt;br /&gt;
	ldir&lt;br /&gt;
	call	_ZeroOP3&lt;br /&gt;
	ld	a,appObj&lt;br /&gt;
	ld	(OP3),a&lt;br /&gt;
_:	call	_HomeUp&lt;br /&gt;
	call	_ClrScrn&lt;br /&gt;
	call	_OP3ToOP1&lt;br /&gt;
	call	_FindAppUp		; find the app&lt;br /&gt;
	ret	c&lt;br /&gt;
	call	_OP1ToOP3		; store name&lt;br /&gt;
	ld	hl,OP1+1&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_PutS			; put name of app&lt;br /&gt;
	pop	hl			; don't need this push/pop (here for readability)&lt;br /&gt;
	call	_FindAppStart		; find the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	GetAppSize&lt;br /&gt;
	call	_DispHL			; display the size of the app&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_os_GetAppVersionString&lt;br /&gt;
	pop	bc&lt;br /&gt;
	call	_PutS&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	call	FindAppInfoString	; Get the information&lt;br /&gt;
	call	_PutS&lt;br /&gt;
_:	call	_GetCSC&lt;br /&gt;
	or	a,a&lt;br /&gt;
	jr	z,-_&lt;br /&gt;
	cp	a,sk2nd&lt;br /&gt;
	jr	nz,--_&lt;br /&gt;
	ld	hl,OP3+1&lt;br /&gt;
	jp	cursorImage&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
ExecuteApp:&lt;br /&gt;
; HL -&amp;gt; name of app (0 terminated)&lt;br /&gt;
; An alternative would be to copy to progtoedit and call _NewConext0&lt;br /&gt;
	.org	cursorImage&lt;br /&gt;
ExecuteApp_Start:&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	DeletePgrmFromUserMem&lt;br /&gt;
	ld	hl,$100&lt;br /&gt;
	call	_EnoughMem&lt;br /&gt;
	pop	hl&lt;br /&gt;
	jp	c, _ErrMemory&lt;br /&gt;
	call	_FindAppStart		; This locates the start of executable code for an app&lt;br /&gt;
	ld	a,E_Validation&lt;br /&gt;
	jp	c,_JError		; If we can't find it, that's a problem (throw a validation error)&lt;br /&gt;
	push	hl			; push location of start of app&lt;br /&gt;
	call	_ReloadAppEntryVecs&lt;br /&gt;
	call	_AppSetup&lt;br /&gt;
	set	appRunning,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	set	6,(iy+$28)&lt;br /&gt;
	res	0,(iy+$2C)		; set some app flags&lt;br /&gt;
	set	appAllowContext,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	ld	hl,$D1787C		; copy to ram data location&lt;br /&gt;
	ld	bc,$FFF&lt;br /&gt;
	call	_MemClear		; zero out the ram data section&lt;br /&gt;
	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	push	hl			; de -&amp;gt; start of code for app&lt;br /&gt;
	ld	bc,$100			; bypass header information&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ex	de,hl&lt;br /&gt;
	ld	hl,$18			; find the start of the data to copy to ram&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	call	__icmpzero		; initialize the bss if it exists&lt;br /&gt;
	jr	z,+_&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	bc&lt;br /&gt;
	ld	hl,$15&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	de,$D1787C		; copy it in&lt;br /&gt;
	ldir&lt;br /&gt;
_:	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	call	FindStartOfAppCode	; After this, hl -&amp;gt; start of code for app&lt;br /&gt;
	jp	(hl)&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindAppInfoString:&lt;br /&gt;
; Finds the information string about an App&lt;br /&gt;
; i.e. (c) 2005-2014 Texas Instruments&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains start of app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$24&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)			; load location of info string&lt;br /&gt;
	add	hl,de &lt;br /&gt;
	or	a,a &lt;br /&gt;
	sbc	hl,de			; check if HL is 0&lt;br /&gt;
	ret	z&lt;br /&gt;
	add	hl,de			; add extra bytes&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindStartOfAppCode:&lt;br /&gt;
; Finds the start of the actual executable from the start of an App&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains the start of the app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$1B			; offset&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
DeletePgrmFromUserMem:&lt;br /&gt;
	ld	de,(asm_prgm_size)	; load total program prgmSize&lt;br /&gt;
	or	a,a&lt;br /&gt;
	sbc	hl,hl&lt;br /&gt;
	ld	(asm_prgm_size),hl	; delete whatever current program was there&lt;br /&gt;
	ld	hl,userMem&lt;br /&gt;
	jp	_DelMem			; HL-&amp;gt;place to delete, DE=amount to delete&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
GetAppSize:&lt;br /&gt;
; Gets the size of an app based from the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_NextFieldFromType	; move to start of signature&lt;br /&gt;
	call	_NextFieldFromType	; move to end of signature&lt;br /&gt;
	pop	de&lt;br /&gt;
	or	a&lt;br /&gt;
	sbc	hl,de&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl			; bypass app size bytes&lt;br /&gt;
	ret				; haha, we're probably looking at another app here&lt;br /&gt;
ExecuteApp_End:&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Credits and Contribution==&lt;br /&gt;
Matt &amp;quot;MateoConLechuga&amp;quot; Waltz&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications</id>
		<title>84PCE:OS:Applications</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications"/>
				<updated>2017-10-02T03:01:22Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:OS_Information]]&lt;br /&gt;
[[Category:84PCE:OS_Information]]&lt;br /&gt;
==Application File Type==&lt;br /&gt;
Applications for the CE calculator have the extension 8ek.&lt;br /&gt;
&lt;br /&gt;
Relocations exist to place the app correctly in the archive, 6 bytes per block (2+22 bits):&lt;br /&gt;
&lt;br /&gt;
0b00 indicates a reference to the code segment executing from Flash, and 0b10 indicates a reference to the data/bss segment in RAM.&lt;br /&gt;
0b01 and 0b11 are a reserved format; &lt;br /&gt;
&lt;br /&gt;
Applications can be of arbitrary size, no longer multiples of 16kB.&lt;br /&gt;
&lt;br /&gt;
==Applications in the Archive==&lt;br /&gt;
Applications are stored beginning at the address 03B0000h and grow downwards. 3 bytes are used as offsets to the start of the app, since the search is backwards. The following status bytes represent what might be found when parsing for applications:&lt;br /&gt;
&lt;br /&gt;
081h = valid Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
000h = deleted Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
Some search code may look like this (Will locate the start of all the app headers):&lt;br /&gt;
&lt;br /&gt;
 _FindValidLocation:&lt;br /&gt;
 	ld	hl,03B0000h            ; applications start here&lt;br /&gt;
 find:	&lt;br /&gt;
 	dec	hl&lt;br /&gt;
  	dec	hl&lt;br /&gt;
 	dec	hl&lt;br /&gt;
 	push	hl&lt;br /&gt;
 	ld	de,(hl)&lt;br /&gt;
 	ld	hl,0FFFFFFh            ; check for end&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de&lt;br /&gt;
 	pop	hl&lt;br /&gt;
 	ret	z                      ; found end of applications&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de                  ; hl points to the start of the app header here if found&lt;br /&gt;
 	jr	find&lt;br /&gt;
&lt;br /&gt;
The actual App header contains certain fields which correspond to the type of data they represent. TI dropped the ball and even though these are variable length fields, the OS code can only handle headers that are padded to 256 bytes in length.&lt;br /&gt;
&lt;br /&gt;
810(F)h = Master field, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
811(2)h = Signing key ID. On the CE, this is 2 bytes in length with the value 0130Fh, indicating it was signed with the '130F' key.&lt;br /&gt;
&lt;br /&gt;
812(D)h = Version information. Begins with the length of the version string, followed by the string itself. This is a minimum compatible version.&lt;br /&gt;
&lt;br /&gt;
813(2)h = Unknown, but contains the 2 byte data 05900h.&lt;br /&gt;
&lt;br /&gt;
814(N)h = Name of App. In this case, 'N' represents the length of the name in bytes. This field is then followed by the name of the app.&lt;br /&gt;
&lt;br /&gt;
817(F)h = End app header information, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
81A(1)h = Unknown, but contains the 1 byte data 007h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other fields:&lt;br /&gt;
&lt;br /&gt;
003h &amp;amp; 2(6)h &amp;amp; 009h &amp;amp; 0(4)h = Time stamp field. 4 bytes long; represents the number of seconds since January 1st 1997, 00:00:00 in some timezone, and some step of the build process.&lt;br /&gt;
&lt;br /&gt;
00Dh &amp;amp; 0NNh = This (NN) represents how much padding until the next field, as app headers must be padded to 256 bytes.&lt;br /&gt;
&lt;br /&gt;
002h &amp;amp; 03(E)h = Signature field. The is followed by the two bytes containing the value 0100h, the length of the 2048 bit signature&lt;br /&gt;
&lt;br /&gt;
At the end of the signature is 3 bytes representing the size of the application. (These bytes are not included however)&lt;br /&gt;
&lt;br /&gt;
App size calculation is as follows: [Length of master header + offset to signature field in (810)] + [4 bytes of signature field + 256 bytes of signature] + [3 bytes application size]&lt;br /&gt;
&lt;br /&gt;
This is pretty much the same as adding 269 to the value in the big endian master field.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an example of such a header:&lt;br /&gt;
&lt;br /&gt;
 ; Master Field -- This app is 102247 + 269 (102516) bytes in size&lt;br /&gt;
 .db	081h, 00Fh, 000h, 001h, 08fh, 067h&lt;br /&gt;
 ; Signing Key Field&lt;br /&gt;
 .db	081h, 012h, 013h, 00Fh&lt;br /&gt;
 ; Version information -- 00Bh represnets the length until the next field&lt;br /&gt;
 .db	081h, 02Dh, 00Bh, &amp;quot;5.0.0.0089&amp;quot;, 000h&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 032h, 059h, 000h&lt;br /&gt;
 ; Name Field -- Name is 7 bytes long, so that is where the 047h comes from&lt;br /&gt;
 .db	081h, 047h, &amp;quot;CabriJr&amp;quot;&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 0A1h, 007h&lt;br /&gt;
 ; Time stamp -- Who knows what time is was?&lt;br /&gt;
 .db	003h, 026h, 009h, 004h&lt;br /&gt;
 .db	021h, 0BBh, 06Eh, 0DCh&lt;br /&gt;
 ; Amount of pading (This is so, so silly)&lt;br /&gt;
 .db	000h, 00Dh, 0C7h&lt;br /&gt;
 ; Padding of 0C7h (199) bytes&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0&lt;br /&gt;
 ; Final field&lt;br /&gt;
 .db	081h, 07Fh, 000h, 001h, 08Eh, 06dh&lt;br /&gt;
 ; End of 256 byte header&lt;br /&gt;
&lt;br /&gt;
==Additional App Structure==&lt;br /&gt;
&lt;br /&gt;
However, apps are also made up of a certain sequence of bytes following the header. Offsets are calculated from the posistion after the header, in addition to the offsets derived from offsets.&lt;br /&gt;
&lt;br /&gt;
Offset after 256 byte header:&lt;br /&gt;
&lt;br /&gt;
000h = The ASCII string &amp;quot;eZ8&amp;quot;, potentially signifying an eZ80 application&lt;br /&gt;
&lt;br /&gt;
003h = Null terminated Application name (zero padded to be 9 bytes in length with terminator byte)&lt;br /&gt;
&lt;br /&gt;
00Ch = Flag, [Bit 0 set - don't draw the TI splash screen] [Bit 1 set - app can use OpenLib]&lt;br /&gt;
&lt;br /&gt;
00Eh = Flag, [Bit 0 set - use the offset in 01Eh]&lt;br /&gt;
&lt;br /&gt;
012h = Main section (this also points to the end of the relocations table)&lt;br /&gt;
&lt;br /&gt;
015h = Initialized data section (Can be at most 4kB in size)&lt;br /&gt;
&lt;br /&gt;
018h = Initialized data section Length&lt;br /&gt;
&lt;br /&gt;
01Bh = Execution entry point&lt;br /&gt;
&lt;br /&gt;
01Eh = Unknown 3 byte offset (See 00Eh)&lt;br /&gt;
&lt;br /&gt;
021h = Offset to ExecLib jump table&lt;br /&gt;
&lt;br /&gt;
024h = Offset to the string used to display a message in the memory screen (Usually a copyright, i.e. &amp;quot;(c) 2005-2015 Texas Instruments&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
027h = Relocation information (Not an offset, relocation information starts here)&lt;br /&gt;
&lt;br /&gt;
02Ah = If no relocations this location should be what 012h offsets to&lt;br /&gt;
&lt;br /&gt;
== ExecLib ==&lt;br /&gt;
&lt;br /&gt;
In order to use ExecLib properly from BASIC programs, you must:&lt;br /&gt;
&lt;br /&gt;
1. Set the proper bit at offset 00Ch.&lt;br /&gt;
&lt;br /&gt;
2. Initialize offset 021h to the start of the library jump table&lt;br /&gt;
&lt;br /&gt;
3. Ensure that the jump table offsets are stored in the relocation table&lt;br /&gt;
&lt;br /&gt;
The format for the jump table is shown below: (Note that you store AppLibraryTable offset to 021h).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;	.db	&amp;quot;LIB&amp;quot;&lt;br /&gt;
	.dl	NUMBER_OF_FUNCTIONS_IN_JUMP_TABLE&lt;br /&gt;
AppLibraryTable:&lt;br /&gt;
	.dl	Function_1&lt;br /&gt;
	.dl	Function_2&lt;br /&gt;
	...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relocations ==&lt;br /&gt;
&lt;br /&gt;
Because apps are not stored at a fixed memory address, they require a relocation table to relocate them during sending and defragmentation.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
Here is a full demo program demonstrating finding each application, displaying the name, size, version, and copyright information&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;quot;ti84pce.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	.db	tExtTok,tAsm84CECmp&lt;br /&gt;
	.org	usermem&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
; Finds all the apps and displays info&lt;br /&gt;
_FINDAPPS:&lt;br /&gt;
	ld	ix,0&lt;br /&gt;
	add	ix,sp&lt;br /&gt;
	ld	hl,ExecuteApp&lt;br /&gt;
	ld	de,cursorImage&lt;br /&gt;
	ld	bc,ExecuteApp_End-ExecuteApp_Start&lt;br /&gt;
	ldir&lt;br /&gt;
	call	_ZeroOP3&lt;br /&gt;
	ld	a,appObj&lt;br /&gt;
	ld	(OP3),a&lt;br /&gt;
_:	call	_HomeUp&lt;br /&gt;
	call	_ClrScrn&lt;br /&gt;
	call	_OP3ToOP1&lt;br /&gt;
	call	_FindAppUp		; find the app&lt;br /&gt;
	ret	c&lt;br /&gt;
	call	_OP1ToOP3		; store name&lt;br /&gt;
	ld	hl,OP1+1&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_PutS			; put name of app&lt;br /&gt;
	pop	hl			; don't need this push/pop (here for readability)&lt;br /&gt;
	call	_FindAppStart		; find the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	GetAppSize&lt;br /&gt;
	call	_DispHL			; display the size of the app&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_os_GetAppVersionString&lt;br /&gt;
	pop	bc&lt;br /&gt;
	call	_PutS&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	call	FindAppInfoString	; Get the information&lt;br /&gt;
	call	_PutS&lt;br /&gt;
_:	call	_GetCSC&lt;br /&gt;
	or	a,a&lt;br /&gt;
	jr	z,-_&lt;br /&gt;
	cp	a,sk2nd&lt;br /&gt;
	jr	nz,--_&lt;br /&gt;
	ld	hl,OP3+1&lt;br /&gt;
	jp	cursorImage&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
ExecuteApp:&lt;br /&gt;
; HL -&amp;gt; name of app (0 terminated)&lt;br /&gt;
; An alternative would be to copy to progtoedit and call _NewConext0&lt;br /&gt;
	.org	cursorImage&lt;br /&gt;
ExecuteApp_Start:&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	DeletePgrmFromUserMem&lt;br /&gt;
	ld	hl,$100&lt;br /&gt;
	call	_EnoughMem&lt;br /&gt;
	pop	hl&lt;br /&gt;
	jp	c, _ErrMemory&lt;br /&gt;
	call	_FindAppStart		; This locates the start of executable code for an app&lt;br /&gt;
	ld	a,E_Validation&lt;br /&gt;
	jp	c,_JError		; If we can't find it, that's a problem (throw a validation error)&lt;br /&gt;
	push	hl			; push location of start of app&lt;br /&gt;
	call	_ReloadAppEntryVecs&lt;br /&gt;
	call	_AppSetup&lt;br /&gt;
	set	appRunning,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	set	6,(iy+$28)&lt;br /&gt;
	res	0,(iy+$2C)		; set some app flags&lt;br /&gt;
	set	appAllowContext,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	ld	hl,$D1787C		; copy to ram data location&lt;br /&gt;
	ld	bc,$FFF&lt;br /&gt;
	call	_MemClear		; zero out the ram data section&lt;br /&gt;
	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	push	hl			; de -&amp;gt; start of code for app&lt;br /&gt;
	ld	bc,$100			; bypass header information&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ex	de,hl&lt;br /&gt;
	ld	hl,$18			; find the start of the data to copy to ram&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	call	__icmpzero		; initialize the bss if it exists&lt;br /&gt;
	jr	z,+_&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	bc&lt;br /&gt;
	ld	hl,$15&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	de,$D1787C		; copy it in&lt;br /&gt;
	ldir&lt;br /&gt;
_:	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	call	FindStartOfAppCode	; After this, hl -&amp;gt; start of code for app&lt;br /&gt;
	jp	(hl)&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindAppInfoString:&lt;br /&gt;
; Finds the information string about an App&lt;br /&gt;
; i.e. (c) 2005-2014 Texas Instruments&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains start of app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$24&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)			; load location of info string&lt;br /&gt;
	add	hl,de &lt;br /&gt;
	or	a,a &lt;br /&gt;
	sbc	hl,de			; check if HL is 0&lt;br /&gt;
	ret	z&lt;br /&gt;
	add	hl,de			; add extra bytes&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindStartOfAppCode:&lt;br /&gt;
; Finds the start of the actual executable from the start of an App&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains the start of the app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$1B			; offset&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
DeletePgrmFromUserMem:&lt;br /&gt;
	ld	de,(asm_prgm_size)	; load total program prgmSize&lt;br /&gt;
	or	a,a&lt;br /&gt;
	sbc	hl,hl&lt;br /&gt;
	ld	(asm_prgm_size),hl	; delete whatever current program was there&lt;br /&gt;
	ld	hl,userMem&lt;br /&gt;
	jp	_DelMem			; HL-&amp;gt;place to delete, DE=amount to delete&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
GetAppSize:&lt;br /&gt;
; Gets the size of an app based from the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_NextFieldFromType	; move to start of signature&lt;br /&gt;
	call	_NextFieldFromType	; move to end of signature&lt;br /&gt;
	pop	de&lt;br /&gt;
	or	a&lt;br /&gt;
	sbc	hl,de&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl			; bypass app size bytes&lt;br /&gt;
	ret				; haha, we're probably looking at another app here&lt;br /&gt;
ExecuteApp_End:&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Credits and Contribution==&lt;br /&gt;
Matt &amp;quot;MateoConLechuga&amp;quot; Waltz&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications</id>
		<title>84PCE:OS:Applications</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications"/>
				<updated>2017-09-30T16:33:47Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* ExecLib */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:OS_Information]]&lt;br /&gt;
[[Category:84PCE:OS_Information]]&lt;br /&gt;
==Application File Type==&lt;br /&gt;
Applications for the CE calculator have the extension 8ek.&lt;br /&gt;
&lt;br /&gt;
Relocations exist to place the app correctly in the archive, 6 bytes per block (2+22 bits):&lt;br /&gt;
&lt;br /&gt;
0b00 indicates a reference to the code segment executing from Flash, and 0b10 indicates a reference to the data/bss segment in RAM.&lt;br /&gt;
0b01 and 0b11 are a reserved format; &lt;br /&gt;
&lt;br /&gt;
Applications can be of arbitrary size, no longer multiples of 16kB.&lt;br /&gt;
&lt;br /&gt;
==Applications in the Archive==&lt;br /&gt;
Applications are stored beginning at the address 03B0000h and grow downwards. 3 bytes are used as offsets to the start of the app, since the search is backwards. The following status bytes represent what might be found when parsing for applications:&lt;br /&gt;
&lt;br /&gt;
081h = valid Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
000h = deleted Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
Some search code may look like this (Will locate the start of all the app headers):&lt;br /&gt;
&lt;br /&gt;
 _FindValidLocation:&lt;br /&gt;
 	ld	hl,03B0000h            ; applications start here&lt;br /&gt;
 find:	&lt;br /&gt;
 	dec	hl&lt;br /&gt;
  	dec	hl&lt;br /&gt;
 	dec	hl&lt;br /&gt;
 	push	hl&lt;br /&gt;
 	ld	de,(hl)&lt;br /&gt;
 	ld	hl,0FFFFFFh            ; check for end&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de&lt;br /&gt;
 	pop	hl&lt;br /&gt;
 	ret	z                      ; found end of applications&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de                  ; hl points to the start of the app header here if found&lt;br /&gt;
 	jr	find&lt;br /&gt;
&lt;br /&gt;
The actual App header contains certain fields which correspond to the type of data they represent. TI dropped the ball and even though these are variable length fields, the OS code can only handle headers that are padded to 256 bytes in length.&lt;br /&gt;
&lt;br /&gt;
810(F)h = Master field, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
811(2)h = Signing key ID. On the CE, this is 2 bytes in length with the value 0130Fh, indicating it was signed with the '130F' key.&lt;br /&gt;
&lt;br /&gt;
812(D)h = Version information. Begins with the length of the version string, followed by the string itself. This is a minimum compatible version.&lt;br /&gt;
&lt;br /&gt;
813(2)h = Unknown, but contains the 2 byte data 05900h.&lt;br /&gt;
&lt;br /&gt;
814(N)h = Name of App. In this case, 'N' represents the length of the name in bytes. This field is then followed by the name of the app.&lt;br /&gt;
&lt;br /&gt;
817(F)h = End app header information, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
81A(1)h = Unknown, but contains the 1 byte data 007h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other fields:&lt;br /&gt;
&lt;br /&gt;
003h &amp;amp; 2(6)h &amp;amp; 009h &amp;amp; 0(4)h = Time stamp field. 4 bytes long; represents the number of seconds since January 1st 1997, 00:00:00 in some timezone, and some step of the build process.&lt;br /&gt;
&lt;br /&gt;
00Dh &amp;amp; 0NNh = This (NN) represents how much padding until the next field, as app headers must be padded to 256 bytes.&lt;br /&gt;
&lt;br /&gt;
002h &amp;amp; 03(E)h = Signature field. The is followed by the two bytes containing the value 0100h, the length of the 2048 bit signature&lt;br /&gt;
&lt;br /&gt;
At the end of the signature is 3 bytes representing the size of the application. (These bytes are not included however)&lt;br /&gt;
&lt;br /&gt;
App size calculation is as follows: [Length of master header + offset to signature field in (810)] + [4 bytes of signature field + 256 bytes of signature] + [3 bytes application size]&lt;br /&gt;
&lt;br /&gt;
This is pretty much the same as adding 269 to the value in the big endian master field.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an example of such a header:&lt;br /&gt;
&lt;br /&gt;
 ; Master Field -- This app is 102247 + 269 (102516) bytes in size&lt;br /&gt;
 .db	081h, 00Fh, 000h, 001h, 08fh, 067h&lt;br /&gt;
 ; Signing Key Field&lt;br /&gt;
 .db	081h, 012h, 013h, 00Fh&lt;br /&gt;
 ; Version information -- 00Bh represnets the length until the next field&lt;br /&gt;
 .db	081h, 02Dh, 00Bh, &amp;quot;5.0.0.0089&amp;quot;, 000h&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 032h, 059h, 000h&lt;br /&gt;
 ; Name Field -- Name is 7 bytes long, so that is where the 047h comes from&lt;br /&gt;
 .db	081h, 047h, &amp;quot;CabriJr&amp;quot;&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 0A1h, 007h&lt;br /&gt;
 ; Time stamp -- Who knows what time is was?&lt;br /&gt;
 .db	003h, 026h, 009h, 004h&lt;br /&gt;
 .db	021h, 0BBh, 06Eh, 0DCh&lt;br /&gt;
 ; Amount of pading (This is so, so silly)&lt;br /&gt;
 .db	000h, 00Dh, 0C7h&lt;br /&gt;
 ; Padding of 0C7h (199) bytes&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0&lt;br /&gt;
 ; Final field&lt;br /&gt;
 .db	081h, 07Fh, 000h, 001h, 08Eh, 06dh&lt;br /&gt;
 ; End of 256 byte header&lt;br /&gt;
&lt;br /&gt;
==Additional App Structure==&lt;br /&gt;
&lt;br /&gt;
However, apps are also made up of a certain sequence of bytes following the header. Offsets are calculated from the posistion after the header, in addition to the offsets derived from offsets.&lt;br /&gt;
&lt;br /&gt;
Offset after 256 byte header:&lt;br /&gt;
&lt;br /&gt;
000h = The ASCII string &amp;quot;eZ8&amp;quot;, potentially signifying an eZ80 application&lt;br /&gt;
&lt;br /&gt;
003h = Null terminated Application name (zero padded to be 9 bytes in length with terminator byte)&lt;br /&gt;
&lt;br /&gt;
00Ch = Flag, [Bit 0 set - don't draw the TI splash screen] [Bit 1 set - app can use OpenLib]&lt;br /&gt;
&lt;br /&gt;
00Eh = Flag, [Bit 0 set - use the offset in 01Eh]&lt;br /&gt;
&lt;br /&gt;
012h = Offset to main code block section (this also points to the end of the relocations table)&lt;br /&gt;
&lt;br /&gt;
015h = Offset to the initialized data section which should be copied to ram (Can be at most 4kB in size)&lt;br /&gt;
&lt;br /&gt;
018h = Length of the initialized data section&lt;br /&gt;
&lt;br /&gt;
01Bh = Offset to the execution entry point (usually same as 012h)&lt;br /&gt;
&lt;br /&gt;
01Eh = Unknown 3 byte offset (See 00Eh)&lt;br /&gt;
&lt;br /&gt;
021h = Offset used for ExecLib&lt;br /&gt;
&lt;br /&gt;
024h = Offset to the string used to display a message in the memory screen (Usually a copyright, i.e. &amp;quot;(c) 2005-2015 Texas Instruments&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
027h = Offset to perhaps the start of data to be relocated?&lt;br /&gt;
&lt;br /&gt;
== ExecLib ==&lt;br /&gt;
&lt;br /&gt;
In order to use ExecLib properly from BASIC programs, you must:&lt;br /&gt;
&lt;br /&gt;
1. Set the proper bit at offset 00Ch.&lt;br /&gt;
&lt;br /&gt;
2. Initialize offset 021h to the start of the library jump table&lt;br /&gt;
&lt;br /&gt;
3. Ensure that the jump table offsets are stored in the relocation table&lt;br /&gt;
&lt;br /&gt;
The format for the jump table is shown below: (Note that you store AppLibraryTable offset to 021h).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;	.db	&amp;quot;LIB&amp;quot;&lt;br /&gt;
	.dl	NUMBER_OF_FUNCTIONS_IN_JUMP_TABLE&lt;br /&gt;
AppLibraryTable:&lt;br /&gt;
	.dl	Function_1&lt;br /&gt;
	.dl	Function_2&lt;br /&gt;
	...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relocations ==&lt;br /&gt;
&lt;br /&gt;
Because apps are not stored at a fixed memory address, they require a relocation table to relocate them during sending and defragmentation.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
Here is a full demo program demonstrating finding each application, displaying the name, size, version, and copyright information&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;quot;ti84pce.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	.db	tExtTok,tAsm84CECmp&lt;br /&gt;
	.org	usermem&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
; Finds all the apps and displays info&lt;br /&gt;
_FINDAPPS:&lt;br /&gt;
	ld	ix,0&lt;br /&gt;
	add	ix,sp&lt;br /&gt;
	ld	hl,ExecuteApp&lt;br /&gt;
	ld	de,cursorImage&lt;br /&gt;
	ld	bc,ExecuteApp_End-ExecuteApp_Start&lt;br /&gt;
	ldir&lt;br /&gt;
	call	_ZeroOP3&lt;br /&gt;
	ld	a,appObj&lt;br /&gt;
	ld	(OP3),a&lt;br /&gt;
_:	call	_HomeUp&lt;br /&gt;
	call	_ClrScrn&lt;br /&gt;
	call	_OP3ToOP1&lt;br /&gt;
	call	_FindAppUp		; find the app&lt;br /&gt;
	ret	c&lt;br /&gt;
	call	_OP1ToOP3		; store name&lt;br /&gt;
	ld	hl,OP1+1&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_PutS			; put name of app&lt;br /&gt;
	pop	hl			; don't need this push/pop (here for readability)&lt;br /&gt;
	call	_FindAppStart		; find the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	GetAppSize&lt;br /&gt;
	call	_DispHL			; display the size of the app&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_os_GetAppVersionString&lt;br /&gt;
	pop	bc&lt;br /&gt;
	call	_PutS&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	call	FindAppInfoString	; Get the information&lt;br /&gt;
	call	_PutS&lt;br /&gt;
_:	call	_GetCSC&lt;br /&gt;
	or	a,a&lt;br /&gt;
	jr	z,-_&lt;br /&gt;
	cp	a,sk2nd&lt;br /&gt;
	jr	nz,--_&lt;br /&gt;
	ld	hl,OP3+1&lt;br /&gt;
	jp	cursorImage&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
ExecuteApp:&lt;br /&gt;
; HL -&amp;gt; name of app (0 terminated)&lt;br /&gt;
; An alternative would be to copy to progtoedit and call _NewConext0&lt;br /&gt;
	.org	cursorImage&lt;br /&gt;
ExecuteApp_Start:&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	DeletePgrmFromUserMem&lt;br /&gt;
	ld	hl,$100&lt;br /&gt;
	call	_EnoughMem&lt;br /&gt;
	pop	hl&lt;br /&gt;
	jp	c, _ErrMemory&lt;br /&gt;
	call	_FindAppStart		; This locates the start of executable code for an app&lt;br /&gt;
	ld	a,E_Validation&lt;br /&gt;
	jp	c,_JError		; If we can't find it, that's a problem (throw a validation error)&lt;br /&gt;
	push	hl			; push location of start of app&lt;br /&gt;
	call	_ReloadAppEntryVecs&lt;br /&gt;
	call	_AppSetup&lt;br /&gt;
	set	appRunning,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	set	6,(iy+$28)&lt;br /&gt;
	res	0,(iy+$2C)		; set some app flags&lt;br /&gt;
	set	appAllowContext,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	ld	hl,$D1787C		; copy to ram data location&lt;br /&gt;
	ld	bc,$FFF&lt;br /&gt;
	call	_MemClear		; zero out the ram data section&lt;br /&gt;
	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	push	hl			; de -&amp;gt; start of code for app&lt;br /&gt;
	ld	bc,$100			; bypass header information&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ex	de,hl&lt;br /&gt;
	ld	hl,$18			; find the start of the data to copy to ram&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	call	__icmpzero		; initialize the bss if it exists&lt;br /&gt;
	jr	z,+_&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	bc&lt;br /&gt;
	ld	hl,$15&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	de,$D1787C		; copy it in&lt;br /&gt;
	ldir&lt;br /&gt;
_:	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	call	FindStartOfAppCode	; After this, hl -&amp;gt; start of code for app&lt;br /&gt;
	jp	(hl)&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindAppInfoString:&lt;br /&gt;
; Finds the information string about an App&lt;br /&gt;
; i.e. (c) 2005-2014 Texas Instruments&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains start of app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$24&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)			; load location of info string&lt;br /&gt;
	add	hl,de &lt;br /&gt;
	or	a,a &lt;br /&gt;
	sbc	hl,de			; check if HL is 0&lt;br /&gt;
	ret	z&lt;br /&gt;
	add	hl,de			; add extra bytes&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindStartOfAppCode:&lt;br /&gt;
; Finds the start of the actual executable from the start of an App&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains the start of the app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$1B			; offset&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
DeletePgrmFromUserMem:&lt;br /&gt;
	ld	de,(asm_prgm_size)	; load total program prgmSize&lt;br /&gt;
	or	a,a&lt;br /&gt;
	sbc	hl,hl&lt;br /&gt;
	ld	(asm_prgm_size),hl	; delete whatever current program was there&lt;br /&gt;
	ld	hl,userMem&lt;br /&gt;
	jp	_DelMem			; HL-&amp;gt;place to delete, DE=amount to delete&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
GetAppSize:&lt;br /&gt;
; Gets the size of an app based from the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_NextFieldFromType	; move to start of signature&lt;br /&gt;
	call	_NextFieldFromType	; move to end of signature&lt;br /&gt;
	pop	de&lt;br /&gt;
	or	a&lt;br /&gt;
	sbc	hl,de&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl			; bypass app size bytes&lt;br /&gt;
	ret				; haha, we're probably looking at another app here&lt;br /&gt;
ExecuteApp_End:&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Credits and Contribution==&lt;br /&gt;
Matt &amp;quot;MateoConLechuga&amp;quot; Waltz&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications</id>
		<title>84PCE:OS:Applications</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications"/>
				<updated>2017-09-30T16:33:20Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* ExecLib */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:OS_Information]]&lt;br /&gt;
[[Category:84PCE:OS_Information]]&lt;br /&gt;
==Application File Type==&lt;br /&gt;
Applications for the CE calculator have the extension 8ek.&lt;br /&gt;
&lt;br /&gt;
Relocations exist to place the app correctly in the archive, 6 bytes per block (2+22 bits):&lt;br /&gt;
&lt;br /&gt;
0b00 indicates a reference to the code segment executing from Flash, and 0b10 indicates a reference to the data/bss segment in RAM.&lt;br /&gt;
0b01 and 0b11 are a reserved format; &lt;br /&gt;
&lt;br /&gt;
Applications can be of arbitrary size, no longer multiples of 16kB.&lt;br /&gt;
&lt;br /&gt;
==Applications in the Archive==&lt;br /&gt;
Applications are stored beginning at the address 03B0000h and grow downwards. 3 bytes are used as offsets to the start of the app, since the search is backwards. The following status bytes represent what might be found when parsing for applications:&lt;br /&gt;
&lt;br /&gt;
081h = valid Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
000h = deleted Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
Some search code may look like this (Will locate the start of all the app headers):&lt;br /&gt;
&lt;br /&gt;
 _FindValidLocation:&lt;br /&gt;
 	ld	hl,03B0000h            ; applications start here&lt;br /&gt;
 find:	&lt;br /&gt;
 	dec	hl&lt;br /&gt;
  	dec	hl&lt;br /&gt;
 	dec	hl&lt;br /&gt;
 	push	hl&lt;br /&gt;
 	ld	de,(hl)&lt;br /&gt;
 	ld	hl,0FFFFFFh            ; check for end&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de&lt;br /&gt;
 	pop	hl&lt;br /&gt;
 	ret	z                      ; found end of applications&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de                  ; hl points to the start of the app header here if found&lt;br /&gt;
 	jr	find&lt;br /&gt;
&lt;br /&gt;
The actual App header contains certain fields which correspond to the type of data they represent. TI dropped the ball and even though these are variable length fields, the OS code can only handle headers that are padded to 256 bytes in length.&lt;br /&gt;
&lt;br /&gt;
810(F)h = Master field, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
811(2)h = Signing key ID. On the CE, this is 2 bytes in length with the value 0130Fh, indicating it was signed with the '130F' key.&lt;br /&gt;
&lt;br /&gt;
812(D)h = Version information. Begins with the length of the version string, followed by the string itself. This is a minimum compatible version.&lt;br /&gt;
&lt;br /&gt;
813(2)h = Unknown, but contains the 2 byte data 05900h.&lt;br /&gt;
&lt;br /&gt;
814(N)h = Name of App. In this case, 'N' represents the length of the name in bytes. This field is then followed by the name of the app.&lt;br /&gt;
&lt;br /&gt;
817(F)h = End app header information, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
81A(1)h = Unknown, but contains the 1 byte data 007h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other fields:&lt;br /&gt;
&lt;br /&gt;
003h &amp;amp; 2(6)h &amp;amp; 009h &amp;amp; 0(4)h = Time stamp field. 4 bytes long; represents the number of seconds since January 1st 1997, 00:00:00 in some timezone, and some step of the build process.&lt;br /&gt;
&lt;br /&gt;
00Dh &amp;amp; 0NNh = This (NN) represents how much padding until the next field, as app headers must be padded to 256 bytes.&lt;br /&gt;
&lt;br /&gt;
002h &amp;amp; 03(E)h = Signature field. The is followed by the two bytes containing the value 0100h, the length of the 2048 bit signature&lt;br /&gt;
&lt;br /&gt;
At the end of the signature is 3 bytes representing the size of the application. (These bytes are not included however)&lt;br /&gt;
&lt;br /&gt;
App size calculation is as follows: [Length of master header + offset to signature field in (810)] + [4 bytes of signature field + 256 bytes of signature] + [3 bytes application size]&lt;br /&gt;
&lt;br /&gt;
This is pretty much the same as adding 269 to the value in the big endian master field.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an example of such a header:&lt;br /&gt;
&lt;br /&gt;
 ; Master Field -- This app is 102247 + 269 (102516) bytes in size&lt;br /&gt;
 .db	081h, 00Fh, 000h, 001h, 08fh, 067h&lt;br /&gt;
 ; Signing Key Field&lt;br /&gt;
 .db	081h, 012h, 013h, 00Fh&lt;br /&gt;
 ; Version information -- 00Bh represnets the length until the next field&lt;br /&gt;
 .db	081h, 02Dh, 00Bh, &amp;quot;5.0.0.0089&amp;quot;, 000h&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 032h, 059h, 000h&lt;br /&gt;
 ; Name Field -- Name is 7 bytes long, so that is where the 047h comes from&lt;br /&gt;
 .db	081h, 047h, &amp;quot;CabriJr&amp;quot;&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 0A1h, 007h&lt;br /&gt;
 ; Time stamp -- Who knows what time is was?&lt;br /&gt;
 .db	003h, 026h, 009h, 004h&lt;br /&gt;
 .db	021h, 0BBh, 06Eh, 0DCh&lt;br /&gt;
 ; Amount of pading (This is so, so silly)&lt;br /&gt;
 .db	000h, 00Dh, 0C7h&lt;br /&gt;
 ; Padding of 0C7h (199) bytes&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0&lt;br /&gt;
 ; Final field&lt;br /&gt;
 .db	081h, 07Fh, 000h, 001h, 08Eh, 06dh&lt;br /&gt;
 ; End of 256 byte header&lt;br /&gt;
&lt;br /&gt;
==Additional App Structure==&lt;br /&gt;
&lt;br /&gt;
However, apps are also made up of a certain sequence of bytes following the header. Offsets are calculated from the posistion after the header, in addition to the offsets derived from offsets.&lt;br /&gt;
&lt;br /&gt;
Offset after 256 byte header:&lt;br /&gt;
&lt;br /&gt;
000h = The ASCII string &amp;quot;eZ8&amp;quot;, potentially signifying an eZ80 application&lt;br /&gt;
&lt;br /&gt;
003h = Null terminated Application name (zero padded to be 9 bytes in length with terminator byte)&lt;br /&gt;
&lt;br /&gt;
00Ch = Flag, [Bit 0 set - don't draw the TI splash screen] [Bit 1 set - app can use OpenLib]&lt;br /&gt;
&lt;br /&gt;
00Eh = Flag, [Bit 0 set - use the offset in 01Eh]&lt;br /&gt;
&lt;br /&gt;
012h = Offset to main code block section (this also points to the end of the relocations table)&lt;br /&gt;
&lt;br /&gt;
015h = Offset to the initialized data section which should be copied to ram (Can be at most 4kB in size)&lt;br /&gt;
&lt;br /&gt;
018h = Length of the initialized data section&lt;br /&gt;
&lt;br /&gt;
01Bh = Offset to the execution entry point (usually same as 012h)&lt;br /&gt;
&lt;br /&gt;
01Eh = Unknown 3 byte offset (See 00Eh)&lt;br /&gt;
&lt;br /&gt;
021h = Offset used for ExecLib&lt;br /&gt;
&lt;br /&gt;
024h = Offset to the string used to display a message in the memory screen (Usually a copyright, i.e. &amp;quot;(c) 2005-2015 Texas Instruments&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
027h = Offset to perhaps the start of data to be relocated?&lt;br /&gt;
&lt;br /&gt;
== ExecLib ==&lt;br /&gt;
&lt;br /&gt;
In order to use ExecLib properly from BASIC programs, you must:&lt;br /&gt;
&lt;br /&gt;
1. Set the proper bit at offset 00Ch.&lt;br /&gt;
&lt;br /&gt;
2. Initialize offset 021h to the start of the library jump table&lt;br /&gt;
&lt;br /&gt;
3. Ensure that the offsets are stored in the relocation table&lt;br /&gt;
&lt;br /&gt;
The format for the jump table is shown below: (Note that you store AppLibraryTable offset to 021h).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;	.db	&amp;quot;LIB&amp;quot;&lt;br /&gt;
	.dl	NUMBER_OF_FUNCTIONS_IN_JUMP_TABLE&lt;br /&gt;
AppLibraryTable:&lt;br /&gt;
	.dl	Function_1&lt;br /&gt;
	.dl	Function_2&lt;br /&gt;
	...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relocations ==&lt;br /&gt;
&lt;br /&gt;
Because apps are not stored at a fixed memory address, they require a relocation table to relocate them during sending and defragmentation.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
Here is a full demo program demonstrating finding each application, displaying the name, size, version, and copyright information&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;quot;ti84pce.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	.db	tExtTok,tAsm84CECmp&lt;br /&gt;
	.org	usermem&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
; Finds all the apps and displays info&lt;br /&gt;
_FINDAPPS:&lt;br /&gt;
	ld	ix,0&lt;br /&gt;
	add	ix,sp&lt;br /&gt;
	ld	hl,ExecuteApp&lt;br /&gt;
	ld	de,cursorImage&lt;br /&gt;
	ld	bc,ExecuteApp_End-ExecuteApp_Start&lt;br /&gt;
	ldir&lt;br /&gt;
	call	_ZeroOP3&lt;br /&gt;
	ld	a,appObj&lt;br /&gt;
	ld	(OP3),a&lt;br /&gt;
_:	call	_HomeUp&lt;br /&gt;
	call	_ClrScrn&lt;br /&gt;
	call	_OP3ToOP1&lt;br /&gt;
	call	_FindAppUp		; find the app&lt;br /&gt;
	ret	c&lt;br /&gt;
	call	_OP1ToOP3		; store name&lt;br /&gt;
	ld	hl,OP1+1&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_PutS			; put name of app&lt;br /&gt;
	pop	hl			; don't need this push/pop (here for readability)&lt;br /&gt;
	call	_FindAppStart		; find the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	GetAppSize&lt;br /&gt;
	call	_DispHL			; display the size of the app&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_os_GetAppVersionString&lt;br /&gt;
	pop	bc&lt;br /&gt;
	call	_PutS&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	call	FindAppInfoString	; Get the information&lt;br /&gt;
	call	_PutS&lt;br /&gt;
_:	call	_GetCSC&lt;br /&gt;
	or	a,a&lt;br /&gt;
	jr	z,-_&lt;br /&gt;
	cp	a,sk2nd&lt;br /&gt;
	jr	nz,--_&lt;br /&gt;
	ld	hl,OP3+1&lt;br /&gt;
	jp	cursorImage&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
ExecuteApp:&lt;br /&gt;
; HL -&amp;gt; name of app (0 terminated)&lt;br /&gt;
; An alternative would be to copy to progtoedit and call _NewConext0&lt;br /&gt;
	.org	cursorImage&lt;br /&gt;
ExecuteApp_Start:&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	DeletePgrmFromUserMem&lt;br /&gt;
	ld	hl,$100&lt;br /&gt;
	call	_EnoughMem&lt;br /&gt;
	pop	hl&lt;br /&gt;
	jp	c, _ErrMemory&lt;br /&gt;
	call	_FindAppStart		; This locates the start of executable code for an app&lt;br /&gt;
	ld	a,E_Validation&lt;br /&gt;
	jp	c,_JError		; If we can't find it, that's a problem (throw a validation error)&lt;br /&gt;
	push	hl			; push location of start of app&lt;br /&gt;
	call	_ReloadAppEntryVecs&lt;br /&gt;
	call	_AppSetup&lt;br /&gt;
	set	appRunning,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	set	6,(iy+$28)&lt;br /&gt;
	res	0,(iy+$2C)		; set some app flags&lt;br /&gt;
	set	appAllowContext,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	ld	hl,$D1787C		; copy to ram data location&lt;br /&gt;
	ld	bc,$FFF&lt;br /&gt;
	call	_MemClear		; zero out the ram data section&lt;br /&gt;
	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	push	hl			; de -&amp;gt; start of code for app&lt;br /&gt;
	ld	bc,$100			; bypass header information&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ex	de,hl&lt;br /&gt;
	ld	hl,$18			; find the start of the data to copy to ram&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	call	__icmpzero		; initialize the bss if it exists&lt;br /&gt;
	jr	z,+_&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	bc&lt;br /&gt;
	ld	hl,$15&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	de,$D1787C		; copy it in&lt;br /&gt;
	ldir&lt;br /&gt;
_:	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	call	FindStartOfAppCode	; After this, hl -&amp;gt; start of code for app&lt;br /&gt;
	jp	(hl)&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindAppInfoString:&lt;br /&gt;
; Finds the information string about an App&lt;br /&gt;
; i.e. (c) 2005-2014 Texas Instruments&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains start of app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$24&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)			; load location of info string&lt;br /&gt;
	add	hl,de &lt;br /&gt;
	or	a,a &lt;br /&gt;
	sbc	hl,de			; check if HL is 0&lt;br /&gt;
	ret	z&lt;br /&gt;
	add	hl,de			; add extra bytes&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindStartOfAppCode:&lt;br /&gt;
; Finds the start of the actual executable from the start of an App&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains the start of the app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$1B			; offset&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
DeletePgrmFromUserMem:&lt;br /&gt;
	ld	de,(asm_prgm_size)	; load total program prgmSize&lt;br /&gt;
	or	a,a&lt;br /&gt;
	sbc	hl,hl&lt;br /&gt;
	ld	(asm_prgm_size),hl	; delete whatever current program was there&lt;br /&gt;
	ld	hl,userMem&lt;br /&gt;
	jp	_DelMem			; HL-&amp;gt;place to delete, DE=amount to delete&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
GetAppSize:&lt;br /&gt;
; Gets the size of an app based from the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_NextFieldFromType	; move to start of signature&lt;br /&gt;
	call	_NextFieldFromType	; move to end of signature&lt;br /&gt;
	pop	de&lt;br /&gt;
	or	a&lt;br /&gt;
	sbc	hl,de&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl			; bypass app size bytes&lt;br /&gt;
	ret				; haha, we're probably looking at another app here&lt;br /&gt;
ExecuteApp_End:&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Credits and Contribution==&lt;br /&gt;
Matt &amp;quot;MateoConLechuga&amp;quot; Waltz&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications</id>
		<title>84PCE:OS:Applications</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications"/>
				<updated>2017-09-30T16:33:06Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Additional App Structure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:OS_Information]]&lt;br /&gt;
[[Category:84PCE:OS_Information]]&lt;br /&gt;
==Application File Type==&lt;br /&gt;
Applications for the CE calculator have the extension 8ek.&lt;br /&gt;
&lt;br /&gt;
Relocations exist to place the app correctly in the archive, 6 bytes per block (2+22 bits):&lt;br /&gt;
&lt;br /&gt;
0b00 indicates a reference to the code segment executing from Flash, and 0b10 indicates a reference to the data/bss segment in RAM.&lt;br /&gt;
0b01 and 0b11 are a reserved format; &lt;br /&gt;
&lt;br /&gt;
Applications can be of arbitrary size, no longer multiples of 16kB.&lt;br /&gt;
&lt;br /&gt;
==Applications in the Archive==&lt;br /&gt;
Applications are stored beginning at the address 03B0000h and grow downwards. 3 bytes are used as offsets to the start of the app, since the search is backwards. The following status bytes represent what might be found when parsing for applications:&lt;br /&gt;
&lt;br /&gt;
081h = valid Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
000h = deleted Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
Some search code may look like this (Will locate the start of all the app headers):&lt;br /&gt;
&lt;br /&gt;
 _FindValidLocation:&lt;br /&gt;
 	ld	hl,03B0000h            ; applications start here&lt;br /&gt;
 find:	&lt;br /&gt;
 	dec	hl&lt;br /&gt;
  	dec	hl&lt;br /&gt;
 	dec	hl&lt;br /&gt;
 	push	hl&lt;br /&gt;
 	ld	de,(hl)&lt;br /&gt;
 	ld	hl,0FFFFFFh            ; check for end&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de&lt;br /&gt;
 	pop	hl&lt;br /&gt;
 	ret	z                      ; found end of applications&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de                  ; hl points to the start of the app header here if found&lt;br /&gt;
 	jr	find&lt;br /&gt;
&lt;br /&gt;
The actual App header contains certain fields which correspond to the type of data they represent. TI dropped the ball and even though these are variable length fields, the OS code can only handle headers that are padded to 256 bytes in length.&lt;br /&gt;
&lt;br /&gt;
810(F)h = Master field, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
811(2)h = Signing key ID. On the CE, this is 2 bytes in length with the value 0130Fh, indicating it was signed with the '130F' key.&lt;br /&gt;
&lt;br /&gt;
812(D)h = Version information. Begins with the length of the version string, followed by the string itself. This is a minimum compatible version.&lt;br /&gt;
&lt;br /&gt;
813(2)h = Unknown, but contains the 2 byte data 05900h.&lt;br /&gt;
&lt;br /&gt;
814(N)h = Name of App. In this case, 'N' represents the length of the name in bytes. This field is then followed by the name of the app.&lt;br /&gt;
&lt;br /&gt;
817(F)h = End app header information, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
81A(1)h = Unknown, but contains the 1 byte data 007h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other fields:&lt;br /&gt;
&lt;br /&gt;
003h &amp;amp; 2(6)h &amp;amp; 009h &amp;amp; 0(4)h = Time stamp field. 4 bytes long; represents the number of seconds since January 1st 1997, 00:00:00 in some timezone, and some step of the build process.&lt;br /&gt;
&lt;br /&gt;
00Dh &amp;amp; 0NNh = This (NN) represents how much padding until the next field, as app headers must be padded to 256 bytes.&lt;br /&gt;
&lt;br /&gt;
002h &amp;amp; 03(E)h = Signature field. The is followed by the two bytes containing the value 0100h, the length of the 2048 bit signature&lt;br /&gt;
&lt;br /&gt;
At the end of the signature is 3 bytes representing the size of the application. (These bytes are not included however)&lt;br /&gt;
&lt;br /&gt;
App size calculation is as follows: [Length of master header + offset to signature field in (810)] + [4 bytes of signature field + 256 bytes of signature] + [3 bytes application size]&lt;br /&gt;
&lt;br /&gt;
This is pretty much the same as adding 269 to the value in the big endian master field.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an example of such a header:&lt;br /&gt;
&lt;br /&gt;
 ; Master Field -- This app is 102247 + 269 (102516) bytes in size&lt;br /&gt;
 .db	081h, 00Fh, 000h, 001h, 08fh, 067h&lt;br /&gt;
 ; Signing Key Field&lt;br /&gt;
 .db	081h, 012h, 013h, 00Fh&lt;br /&gt;
 ; Version information -- 00Bh represnets the length until the next field&lt;br /&gt;
 .db	081h, 02Dh, 00Bh, &amp;quot;5.0.0.0089&amp;quot;, 000h&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 032h, 059h, 000h&lt;br /&gt;
 ; Name Field -- Name is 7 bytes long, so that is where the 047h comes from&lt;br /&gt;
 .db	081h, 047h, &amp;quot;CabriJr&amp;quot;&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 0A1h, 007h&lt;br /&gt;
 ; Time stamp -- Who knows what time is was?&lt;br /&gt;
 .db	003h, 026h, 009h, 004h&lt;br /&gt;
 .db	021h, 0BBh, 06Eh, 0DCh&lt;br /&gt;
 ; Amount of pading (This is so, so silly)&lt;br /&gt;
 .db	000h, 00Dh, 0C7h&lt;br /&gt;
 ; Padding of 0C7h (199) bytes&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0&lt;br /&gt;
 ; Final field&lt;br /&gt;
 .db	081h, 07Fh, 000h, 001h, 08Eh, 06dh&lt;br /&gt;
 ; End of 256 byte header&lt;br /&gt;
&lt;br /&gt;
==Additional App Structure==&lt;br /&gt;
&lt;br /&gt;
However, apps are also made up of a certain sequence of bytes following the header. Offsets are calculated from the posistion after the header, in addition to the offsets derived from offsets.&lt;br /&gt;
&lt;br /&gt;
Offset after 256 byte header:&lt;br /&gt;
&lt;br /&gt;
000h = The ASCII string &amp;quot;eZ8&amp;quot;, potentially signifying an eZ80 application&lt;br /&gt;
&lt;br /&gt;
003h = Null terminated Application name (zero padded to be 9 bytes in length with terminator byte)&lt;br /&gt;
&lt;br /&gt;
00Ch = Flag, [Bit 0 set - don't draw the TI splash screen] [Bit 1 set - app can use OpenLib]&lt;br /&gt;
&lt;br /&gt;
00Eh = Flag, [Bit 0 set - use the offset in 01Eh]&lt;br /&gt;
&lt;br /&gt;
012h = Offset to main code block section (this also points to the end of the relocations table)&lt;br /&gt;
&lt;br /&gt;
015h = Offset to the initialized data section which should be copied to ram (Can be at most 4kB in size)&lt;br /&gt;
&lt;br /&gt;
018h = Length of the initialized data section&lt;br /&gt;
&lt;br /&gt;
01Bh = Offset to the execution entry point (usually same as 012h)&lt;br /&gt;
&lt;br /&gt;
01Eh = Unknown 3 byte offset (See 00Eh)&lt;br /&gt;
&lt;br /&gt;
021h = Offset used for ExecLib&lt;br /&gt;
&lt;br /&gt;
024h = Offset to the string used to display a message in the memory screen (Usually a copyright, i.e. &amp;quot;(c) 2005-2015 Texas Instruments&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
027h = Offset to perhaps the start of data to be relocated?&lt;br /&gt;
&lt;br /&gt;
== ExecLib ==&lt;br /&gt;
&lt;br /&gt;
In order to use ExecLib properly from BASIC programs, you must:&lt;br /&gt;
&lt;br /&gt;
1. Set the proper bit at offset 00Ch.&lt;br /&gt;
2. Initialize offset 021h to the start of the library jump table&lt;br /&gt;
3. Ensure that the offsets are stored in the relocation table&lt;br /&gt;
&lt;br /&gt;
The format for the jump table is shown below: (Note that you store AppLibraryTable offset to 021h).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;	.db	&amp;quot;LIB&amp;quot;&lt;br /&gt;
	.dl	NUMBER_OF_FUNCTIONS_IN_JUMP_TABLE&lt;br /&gt;
AppLibraryTable:&lt;br /&gt;
	.dl	Function_1&lt;br /&gt;
	.dl	Function_2&lt;br /&gt;
	...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relocations ==&lt;br /&gt;
&lt;br /&gt;
Because apps are not stored at a fixed memory address, they require a relocation table to relocate them during sending and defragmentation.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
Here is a full demo program demonstrating finding each application, displaying the name, size, version, and copyright information&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;quot;ti84pce.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	.db	tExtTok,tAsm84CECmp&lt;br /&gt;
	.org	usermem&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
; Finds all the apps and displays info&lt;br /&gt;
_FINDAPPS:&lt;br /&gt;
	ld	ix,0&lt;br /&gt;
	add	ix,sp&lt;br /&gt;
	ld	hl,ExecuteApp&lt;br /&gt;
	ld	de,cursorImage&lt;br /&gt;
	ld	bc,ExecuteApp_End-ExecuteApp_Start&lt;br /&gt;
	ldir&lt;br /&gt;
	call	_ZeroOP3&lt;br /&gt;
	ld	a,appObj&lt;br /&gt;
	ld	(OP3),a&lt;br /&gt;
_:	call	_HomeUp&lt;br /&gt;
	call	_ClrScrn&lt;br /&gt;
	call	_OP3ToOP1&lt;br /&gt;
	call	_FindAppUp		; find the app&lt;br /&gt;
	ret	c&lt;br /&gt;
	call	_OP1ToOP3		; store name&lt;br /&gt;
	ld	hl,OP1+1&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_PutS			; put name of app&lt;br /&gt;
	pop	hl			; don't need this push/pop (here for readability)&lt;br /&gt;
	call	_FindAppStart		; find the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	GetAppSize&lt;br /&gt;
	call	_DispHL			; display the size of the app&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_os_GetAppVersionString&lt;br /&gt;
	pop	bc&lt;br /&gt;
	call	_PutS&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	call	FindAppInfoString	; Get the information&lt;br /&gt;
	call	_PutS&lt;br /&gt;
_:	call	_GetCSC&lt;br /&gt;
	or	a,a&lt;br /&gt;
	jr	z,-_&lt;br /&gt;
	cp	a,sk2nd&lt;br /&gt;
	jr	nz,--_&lt;br /&gt;
	ld	hl,OP3+1&lt;br /&gt;
	jp	cursorImage&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
ExecuteApp:&lt;br /&gt;
; HL -&amp;gt; name of app (0 terminated)&lt;br /&gt;
; An alternative would be to copy to progtoedit and call _NewConext0&lt;br /&gt;
	.org	cursorImage&lt;br /&gt;
ExecuteApp_Start:&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	DeletePgrmFromUserMem&lt;br /&gt;
	ld	hl,$100&lt;br /&gt;
	call	_EnoughMem&lt;br /&gt;
	pop	hl&lt;br /&gt;
	jp	c, _ErrMemory&lt;br /&gt;
	call	_FindAppStart		; This locates the start of executable code for an app&lt;br /&gt;
	ld	a,E_Validation&lt;br /&gt;
	jp	c,_JError		; If we can't find it, that's a problem (throw a validation error)&lt;br /&gt;
	push	hl			; push location of start of app&lt;br /&gt;
	call	_ReloadAppEntryVecs&lt;br /&gt;
	call	_AppSetup&lt;br /&gt;
	set	appRunning,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	set	6,(iy+$28)&lt;br /&gt;
	res	0,(iy+$2C)		; set some app flags&lt;br /&gt;
	set	appAllowContext,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	ld	hl,$D1787C		; copy to ram data location&lt;br /&gt;
	ld	bc,$FFF&lt;br /&gt;
	call	_MemClear		; zero out the ram data section&lt;br /&gt;
	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	push	hl			; de -&amp;gt; start of code for app&lt;br /&gt;
	ld	bc,$100			; bypass header information&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ex	de,hl&lt;br /&gt;
	ld	hl,$18			; find the start of the data to copy to ram&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	call	__icmpzero		; initialize the bss if it exists&lt;br /&gt;
	jr	z,+_&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	bc&lt;br /&gt;
	ld	hl,$15&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	de,$D1787C		; copy it in&lt;br /&gt;
	ldir&lt;br /&gt;
_:	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	call	FindStartOfAppCode	; After this, hl -&amp;gt; start of code for app&lt;br /&gt;
	jp	(hl)&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindAppInfoString:&lt;br /&gt;
; Finds the information string about an App&lt;br /&gt;
; i.e. (c) 2005-2014 Texas Instruments&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains start of app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$24&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)			; load location of info string&lt;br /&gt;
	add	hl,de &lt;br /&gt;
	or	a,a &lt;br /&gt;
	sbc	hl,de			; check if HL is 0&lt;br /&gt;
	ret	z&lt;br /&gt;
	add	hl,de			; add extra bytes&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindStartOfAppCode:&lt;br /&gt;
; Finds the start of the actual executable from the start of an App&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains the start of the app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$1B			; offset&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
DeletePgrmFromUserMem:&lt;br /&gt;
	ld	de,(asm_prgm_size)	; load total program prgmSize&lt;br /&gt;
	or	a,a&lt;br /&gt;
	sbc	hl,hl&lt;br /&gt;
	ld	(asm_prgm_size),hl	; delete whatever current program was there&lt;br /&gt;
	ld	hl,userMem&lt;br /&gt;
	jp	_DelMem			; HL-&amp;gt;place to delete, DE=amount to delete&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
GetAppSize:&lt;br /&gt;
; Gets the size of an app based from the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_NextFieldFromType	; move to start of signature&lt;br /&gt;
	call	_NextFieldFromType	; move to end of signature&lt;br /&gt;
	pop	de&lt;br /&gt;
	or	a&lt;br /&gt;
	sbc	hl,de&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl			; bypass app size bytes&lt;br /&gt;
	ret				; haha, we're probably looking at another app here&lt;br /&gt;
ExecuteApp_End:&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Credits and Contribution==&lt;br /&gt;
Matt &amp;quot;MateoConLechuga&amp;quot; Waltz&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Syscalls:021320</id>
		<title>84PCE:Syscalls:021320</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Syscalls:021320"/>
				<updated>2017-09-26T01:54:03Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Syscalls:By Name|GetStringInput]]&lt;br /&gt;
[[Category:84PCE:Syscalls:By Address|021320 - GetStringInput]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Hypothesized Official Name:''' GetStringInput&lt;br /&gt;
&lt;br /&gt;
'''Syscall Address:''' 021320h&lt;br /&gt;
&lt;br /&gt;
Gets a string of input from the user, much like the common 'Input' command used in TI-Basic programs. This system call does not return until after the user presses enter, but allows for use of all OS menus and input variations, including the Alpha and 2nd Keys special abilities. It works by creating a temporary equation which it then makes the edit buffer. It can also display an optional prompt for the user, in order to be more user friendly. Note that when using this routine, the system monitor completely takes over, so it will act exactly as it does in TI-Basic programs, which may have unintended side effects. It is highly recommended you call [[84PCE:Syscalls:021578|DeleteTempEditEqu]] once you are finished with your input parsing. It basically calls _NewContext with 50h, _Mon, then _NewContext with 3Fh.&lt;br /&gt;
&lt;br /&gt;
=== Inputs ===&lt;br /&gt;
* [[84PCE:RAM:D00879|ioPrompt]] - Copy the optional prompt string here, or write a null byte for no prompt&lt;br /&gt;
* [[84PCE:RAM:D00595|curRow]],[[84PCE:RAM:D00596|curCol]] - Set to the appropriate values for the location where to display the prompt and input string&lt;br /&gt;
* [[84PCE:RAM:D00596|curUnder]] - This is the character that is first displayed under the cursor. You should set it to 0, unless you want something under the cursor&lt;br /&gt;
* '''NOTE:''' You must reset 6,(iy+28) and set 7,(iy+9) before calling this function!&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
* [[84PCE:RAM:D0244E|editSym]] - Contains the VAT pointer to the temporary variable used for editing the input string. Can be used with [[84PCE:Syscalls:020AE8|VarNameToOP1HL]] to lookup the actual input data.&lt;br /&gt;
&lt;br /&gt;
=== Destroys ===&lt;br /&gt;
* All&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
 	call	_ClrScrn&lt;br /&gt;
 	call	_HomeUp					; clean up things&lt;br /&gt;
 	ld	hl,inputPrompt&lt;br /&gt;
 	ld	bc,inputPrompt_end-inputPrompt&lt;br /&gt;
 	ld	de,ioPrompt&lt;br /&gt;
 	ldir						; copy the input prompt here&lt;br /&gt;
 	xor	a,a&lt;br /&gt;
 	ld	(curUnder),a&lt;br /&gt;
 	ld	b,(iy+9)&lt;br /&gt;
 	ld	c,(iy+28)				;back up old flag values&lt;br /&gt;
 	res	6,(iy+28)&lt;br /&gt;
 	set	7,(iy+9)&lt;br /&gt;
 	push	bc&lt;br /&gt;
 	call	_GetStringInput				; get the input from the user&lt;br /&gt;
 	pop	bc&lt;br /&gt;
 	res	4,b					;restore old flag values&lt;br /&gt;
 	ld	(iy+9),b&lt;br /&gt;
 	ld	(iy+28),c&lt;br /&gt;
 	ld	hl,(editSym)&lt;br /&gt;
 	call	_VarNameToOP1HL				; lookup the temporary input symbol&lt;br /&gt;
 	call	_ChkFindSym&lt;br /&gt;
 	jr	c,SomeError&lt;br /&gt;
 	ex	de,hl &lt;br /&gt;
 	call	_LoadDEInd_s				; get the size of the the string&lt;br /&gt;
 	push	de&lt;br /&gt;
 	pop	bc&lt;br /&gt;
 	ld	de,pixelshadow				; copy it to saferam&lt;br /&gt;
 	ldir&lt;br /&gt;
 	xor	a,a&lt;br /&gt;
 	ld	(de),a					; null terminate the string&lt;br /&gt;
 SomeError:&lt;br /&gt;
 	call	_DeleteTempEditEqu			; delete the temporary input&lt;br /&gt;
 	call	_ClrScrn&lt;br /&gt;
 	jp	_HomeUp					; clean up and leave&lt;br /&gt;
 &lt;br /&gt;
 inputPrompt:&lt;br /&gt;
 	.db &amp;quot;Input:&amp;quot;,0					; Input prompt&lt;br /&gt;
 inputPrompt_end:&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Syscalls:021320</id>
		<title>84PCE:Syscalls:021320</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Syscalls:021320"/>
				<updated>2017-09-26T01:50:53Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Inputs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Syscalls:By Name|GetStringInput]]&lt;br /&gt;
[[Category:84PCE:Syscalls:By Address|021320 - GetStringInput]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Hypothesized Official Name:''' GetStringInput&lt;br /&gt;
&lt;br /&gt;
'''Syscall Address:''' 021320h&lt;br /&gt;
&lt;br /&gt;
Gets a string of input from the user, much like the common 'Input' command used in TI-Basic programs. This system call does not return until after the user presses enter, but allows for use of all OS menus and input variations, including the Alpha and 2nd Keys special abilities. It works by creating a temporary equation which it then makes the edit buffer. It can also display an optional prompt for the user, in order to be more user friendly. Note that when using this routine, the system monitor completely takes over, so it will act exactly as it does in TI-Basic programs, which may have unintended side effects. It is highly recommended you call [[84PCE:Syscalls:021578|DeleteTempEditEqu]] once you are finished with your input parsing.&lt;br /&gt;
&lt;br /&gt;
=== Inputs ===&lt;br /&gt;
* [[84PCE:RAM:D00879|ioPrompt]] - Copy the optional prompt string here, or write a null byte for no prompt&lt;br /&gt;
* [[84PCE:RAM:D00595|curRow]],[[84PCE:RAM:D00596|curCol]] - Set to the appropriate values for the location where to display the prompt and input string&lt;br /&gt;
* [[84PCE:RAM:D00596|curUnder]] - This is the character that is first displayed under the cursor. You should set it to 0, unless you want something under the cursor&lt;br /&gt;
* '''NOTE:''' You must reset 6,(iy+28) and set 7,(iy+9) before calling this function!&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
* [[84PCE:RAM:D0244E|editSym]] - Contains the VAT pointer to the temporary variable used for editing the input string. Can be used with [[84PCE:Syscalls:020AE8|VarNameToOP1HL]] to lookup the actual input data.&lt;br /&gt;
&lt;br /&gt;
=== Destroys ===&lt;br /&gt;
* All&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
 	call	_ClrScrn&lt;br /&gt;
 	call	_HomeUp					; clean up things&lt;br /&gt;
 	ld	hl,inputPrompt&lt;br /&gt;
 	ld	bc,inputPrompt_end-inputPrompt&lt;br /&gt;
 	ld	de,ioPrompt&lt;br /&gt;
 	ldir						; copy the input prompt here&lt;br /&gt;
 	xor	a,a&lt;br /&gt;
 	ld	(curUnder),a&lt;br /&gt;
 	call	_GetStringInput				; get the input from the user&lt;br /&gt;
 	ld	hl,(editSym)&lt;br /&gt;
 	call	_VarNameToOP1HL				; lookup the temporary input symbol&lt;br /&gt;
 	call	_ChkFindSym&lt;br /&gt;
 	jr	c,SomeError&lt;br /&gt;
 	ex	de,hl &lt;br /&gt;
 	call	_LoadDEInd_s				; get the size of the the string&lt;br /&gt;
 	push	de&lt;br /&gt;
 	pop	bc&lt;br /&gt;
 	ld	de,pixelshadow				; copy it to saferam&lt;br /&gt;
 	ldir&lt;br /&gt;
 	xor	a,a&lt;br /&gt;
 	ld	(de),a					; null terminate the string&lt;br /&gt;
 SomeError:&lt;br /&gt;
 	call	_DeleteTempEditEqu			; delete the temporary input&lt;br /&gt;
 	call	_ClrScrn&lt;br /&gt;
 	jp	_HomeUp					; clean up and leave&lt;br /&gt;
 &lt;br /&gt;
 inputPrompt:&lt;br /&gt;
 	.db &amp;quot;Input:&amp;quot;,0					; Input prompt&lt;br /&gt;
 inputPrompt_end:&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=83Plus:Ports:89</id>
		<title>83Plus:Ports:89</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=83Plus:Ports:89"/>
				<updated>2017-09-24T21:31:52Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Synopsis */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:83Plus:Ports:By Address|89 - USB Input-Enabled Pipes]] [[Category:83Plus:Ports:By Name|USB Input-Enabled Pipes]]&lt;br /&gt;
{{84P-Only Port|01}}&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 89h&lt;br /&gt;
&lt;br /&gt;
'''Function:''' USB Input-Enabled Pipes&lt;br /&gt;
&lt;br /&gt;
This port is a bitmap of which pipes in the A0h-A7h range are enabled for input. Similar to [[83Plus:Ports:8A|port 8A]].&lt;br /&gt;
&lt;br /&gt;
=== Read Values ===&lt;br /&gt;
* Bit 0: Probably always 0. (Just a guess)&lt;br /&gt;
* Bit 1: Set if pipe 1 is enabled for input.&lt;br /&gt;
* Bit 2: Set if pipe 2 is enabled for input.&lt;br /&gt;
* Bit 3: Set if pipe 3 is enabled for input.&lt;br /&gt;
* Bit 4: Hypothetically, set if pipe 4 is enabled for input.&lt;br /&gt;
* Bit 5: Hypothetically, set if pipe 5 is enabled for input.&lt;br /&gt;
* Bit 6: Hypothetically, set if pipe 6 is enabled for input.&lt;br /&gt;
* Bit 7: Hypothetically, set if pipe 7 is enabled for input.&lt;br /&gt;
&lt;br /&gt;
=== Write Values ===&lt;br /&gt;
* No effect&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0006</id>
		<title>84PCE:Ports:0006</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0006"/>
				<updated>2017-08-06T18:07:32Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Details */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|0006 - Unknown]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0006&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Unknown&lt;br /&gt;
&lt;br /&gt;
== Details ==&lt;br /&gt;
&lt;br /&gt;
This port seems to affect the display refresh.&lt;br /&gt;
&lt;br /&gt;
=== Bit [0] ===&lt;br /&gt;
Latches value written, no apparent effect.&lt;br /&gt;
&lt;br /&gt;
=== Bit [1] ===&lt;br /&gt;
Reset this bit to disable display upadates.&lt;br /&gt;
&lt;br /&gt;
=== Bit [2] ===&lt;br /&gt;
Set this bit to enable display updates if bit 1 is ever reset.&lt;br /&gt;
&lt;br /&gt;
=== Bit [3] ===&lt;br /&gt;
Writes do not latch; no apparent effect.&lt;br /&gt;
&lt;br /&gt;
=== Bit [4] ===&lt;br /&gt;
Flash lock status.&lt;br /&gt;
&lt;br /&gt;
=== Bits [7:3] ===&lt;br /&gt;
Writes do not latch; no apparent effect.&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0002</id>
		<title>84PCE:Ports:0002</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0002"/>
				<updated>2017-08-06T18:00:17Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|0002 - Unknown]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0002&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Unknown&lt;br /&gt;
&lt;br /&gt;
== Details ==&lt;br /&gt;
&lt;br /&gt;
This port is read only; it appears to be based off of the battery level.&lt;br /&gt;
&lt;br /&gt;
=== Bits [7:0] ===&lt;br /&gt;
Writes have no apparent effect, value does not latch.&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0000</id>
		<title>84PCE:Ports:0000</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0000"/>
				<updated>2017-08-06T17:22:56Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Bit [6] */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|0000 - System Config]] [[Category:84PCE:Ports:By_Name|System Config]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0000&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Controls interrupt speed and power&lt;br /&gt;
&lt;br /&gt;
=== Bits [1:0]: OS Timer Rate ===&lt;br /&gt;
This controls the rate of interrupt source 4, which seems to be some kind of timer. Changing this changes the cursor blink rate. It's probably some kind of interrupt speed. 11b is the slowest, 00b is the fastest. If this is anything like the timers on the Z80 models, its source is the 32768 Hz quartz crystal. A frequency table is below, along with probable divisors if this really is from the 32768 Hz crystal.&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Value&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Rate (Hz)&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Probable Divisor&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|00&lt;br /&gt;
|~442.81&lt;br /&gt;
|32768/74&lt;br /&gt;
|-&lt;br /&gt;
|01&lt;br /&gt;
|~212.78&lt;br /&gt;
|32768/154&lt;br /&gt;
|-&lt;br /&gt;
|02&lt;br /&gt;
|~150.31&lt;br /&gt;
|32768/218&lt;br /&gt;
|-&lt;br /&gt;
|03&lt;br /&gt;
|~104.36&lt;br /&gt;
|32768/314&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Bits [3:2] ===&lt;br /&gt;
Writes have no apparent effect, value does not latch.&lt;br /&gt;
&lt;br /&gt;
=== Bit [4] ===&lt;br /&gt;
Set this bit to crash. The bootcode uses this to crash when catching a non-maskable interrupt.&lt;br /&gt;
&lt;br /&gt;
=== Bit [5] ===&lt;br /&gt;
Writes have no apparent effect, value does not latch.&lt;br /&gt;
&lt;br /&gt;
=== Bit [6] ===&lt;br /&gt;
Set this bit to turn calc and screen off until next ON key. Value does not latch.&lt;br /&gt;
&lt;br /&gt;
=== Bit [7] ===&lt;br /&gt;
Latches value written, no apparent effect. Used when reading battery status.&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0000</id>
		<title>84PCE:Ports:0000</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0000"/>
				<updated>2017-08-06T17:14:21Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Bit [7] */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|0000 - System Config]] [[Category:84PCE:Ports:By_Name|System Config]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0000&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Controls interrupt speed and power&lt;br /&gt;
&lt;br /&gt;
=== Bits [1:0]: OS Timer Rate ===&lt;br /&gt;
This controls the rate of interrupt source 4, which seems to be some kind of timer. Changing this changes the cursor blink rate. It's probably some kind of interrupt speed. 11b is the slowest, 00b is the fastest. If this is anything like the timers on the Z80 models, its source is the 32768 Hz quartz crystal. A frequency table is below, along with probable divisors if this really is from the 32768 Hz crystal.&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Value&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Rate (Hz)&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Probable Divisor&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|00&lt;br /&gt;
|~442.81&lt;br /&gt;
|32768/74&lt;br /&gt;
|-&lt;br /&gt;
|01&lt;br /&gt;
|~212.78&lt;br /&gt;
|32768/154&lt;br /&gt;
|-&lt;br /&gt;
|02&lt;br /&gt;
|~150.31&lt;br /&gt;
|32768/218&lt;br /&gt;
|-&lt;br /&gt;
|03&lt;br /&gt;
|~104.36&lt;br /&gt;
|32768/314&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Bits [3:2] ===&lt;br /&gt;
Writes have no apparent effect, value does not latch.&lt;br /&gt;
&lt;br /&gt;
=== Bit [4] ===&lt;br /&gt;
Set this bit to crash. The bootcode uses this to crash when catching a non-maskable interrupt.&lt;br /&gt;
&lt;br /&gt;
=== Bit [5] ===&lt;br /&gt;
Writes have no apparent effect, value does not latch.&lt;br /&gt;
&lt;br /&gt;
=== Bit [6] ===&lt;br /&gt;
Set this bit to turn calc and screen off until next ON key.&lt;br /&gt;
&lt;br /&gt;
=== Bit [7] ===&lt;br /&gt;
Latches value written, no apparent effect. Used when reading battery status.&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications</id>
		<title>84PCE:OS:Applications</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:OS:Applications"/>
				<updated>2017-08-06T11:45:53Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Applications in the Archive */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:OS_Information]]&lt;br /&gt;
[[Category:84PCE:OS_Information]]&lt;br /&gt;
==Application File Type==&lt;br /&gt;
Applications for the CE calculator have the extension 8ek.&lt;br /&gt;
&lt;br /&gt;
Relocations exist to place the app correctly in the archive, 6 bytes per block (2+22 bits):&lt;br /&gt;
&lt;br /&gt;
0b00 indicates a reference to the code segment executing from Flash, and 0b10 indicates a reference to the data/bss segment in RAM.&lt;br /&gt;
0b01 and 0b11 are a reserved format; &lt;br /&gt;
&lt;br /&gt;
Applications can be of arbitrary size, no longer multiples of 16kB.&lt;br /&gt;
&lt;br /&gt;
==Applications in the Archive==&lt;br /&gt;
Applications are stored beginning at the address 03B0000h and grow downwards. 3 bytes are used as offsets to the start of the app, since the search is backwards. The following status bytes represent what might be found when parsing for applications:&lt;br /&gt;
&lt;br /&gt;
081h = valid Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
000h = deleted Flash application (part of the app header)&lt;br /&gt;
&lt;br /&gt;
Some search code may look like this (Will locate the start of all the app headers):&lt;br /&gt;
&lt;br /&gt;
 _FindValidLocation:&lt;br /&gt;
 	ld	hl,03B0000h            ; applications start here&lt;br /&gt;
 find:	&lt;br /&gt;
 	dec	hl&lt;br /&gt;
  	dec	hl&lt;br /&gt;
 	dec	hl&lt;br /&gt;
 	push	hl&lt;br /&gt;
 	ld	de,(hl)&lt;br /&gt;
 	ld	hl,0FFFFFFh            ; check for end&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de&lt;br /&gt;
 	pop	hl&lt;br /&gt;
 	ret	z                      ; found end of applications&lt;br /&gt;
 	or	a,a&lt;br /&gt;
 	sbc	hl,de                  ; hl points to the start of the app header here if found&lt;br /&gt;
 	jr	find&lt;br /&gt;
&lt;br /&gt;
The actual App header contains certain fields which correspond to the type of data they represent. TI dropped the ball and even though these are variable length fields, the OS code can only handle headers that are padded to 256 bytes in length.&lt;br /&gt;
&lt;br /&gt;
810(F)h = Master field, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
811(2)h = Signing key ID. On the CE, this is 2 bytes in length with the value 0130Fh, indicating it was signed with the '130F' key.&lt;br /&gt;
&lt;br /&gt;
812(D)h = Version information. Begins with the length of the version string, followed by the string itself. This is a minimum compatible version.&lt;br /&gt;
&lt;br /&gt;
813(2)h = Unknown, but contains the 2 byte data 05900h.&lt;br /&gt;
&lt;br /&gt;
814(N)h = Name of App. In this case, 'N' represents the length of the name in bytes. This field is then followed by the name of the app.&lt;br /&gt;
&lt;br /&gt;
817(F)h = End app header information, 4 bytes in length, which contains the offset to the signature field. (Big Endian)&lt;br /&gt;
&lt;br /&gt;
81A(1)h = Unknown, but contains the 1 byte data 007h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Other fields:&lt;br /&gt;
&lt;br /&gt;
003h &amp;amp; 2(6)h &amp;amp; 009h &amp;amp; 0(4)h = Time stamp field. 4 bytes long; represents the number of seconds since January 1st 1997, 00:00:00 in some timezone, and some step of the build process.&lt;br /&gt;
&lt;br /&gt;
00Dh &amp;amp; 0NNh = This (NN) represents how much padding until the next field, as app headers must be padded to 256 bytes.&lt;br /&gt;
&lt;br /&gt;
002h &amp;amp; 03(E)h = Signature field. The is followed by the two bytes containing the value 0100h, the length of the 2048 bit signature&lt;br /&gt;
&lt;br /&gt;
At the end of the signature is 3 bytes representing the size of the application. (These bytes are not included however)&lt;br /&gt;
&lt;br /&gt;
App size calculation is as follows: [Length of master header + offset to signature field in (810)] + [4 bytes of signature field + 256 bytes of signature] + [3 bytes application size]&lt;br /&gt;
&lt;br /&gt;
This is pretty much the same as adding 269 to the value in the big endian master field.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an example of such a header:&lt;br /&gt;
&lt;br /&gt;
 ; Master Field -- This app is 102247 + 269 (102516) bytes in size&lt;br /&gt;
 .db	081h, 00Fh, 000h, 001h, 08fh, 067h&lt;br /&gt;
 ; Signing Key Field&lt;br /&gt;
 .db	081h, 012h, 013h, 00Fh&lt;br /&gt;
 ; Version information -- 00Bh represnets the length until the next field&lt;br /&gt;
 .db	081h, 02Dh, 00Bh, &amp;quot;5.0.0.0089&amp;quot;, 000h&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 032h, 059h, 000h&lt;br /&gt;
 ; Name Field -- Name is 7 bytes long, so that is where the 047h comes from&lt;br /&gt;
 .db	081h, 047h, &amp;quot;CabriJr&amp;quot;&lt;br /&gt;
 ; Unknown field&lt;br /&gt;
 .db	081h, 0A1h, 007h&lt;br /&gt;
 ; Time stamp -- Who knows what time is was?&lt;br /&gt;
 .db	003h, 026h, 009h, 004h&lt;br /&gt;
 .db	021h, 0BBh, 06Eh, 0DCh&lt;br /&gt;
 ; Amount of pading (This is so, so silly)&lt;br /&gt;
 .db	000h, 00Dh, 0C7h&lt;br /&gt;
 ; Padding of 0C7h (199) bytes&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
 .db	0,0,0,0,0,0,0&lt;br /&gt;
 ; Final field&lt;br /&gt;
 .db	081h, 07Fh, 000h, 001h, 08Eh, 06dh&lt;br /&gt;
 ; End of 256 byte header&lt;br /&gt;
&lt;br /&gt;
==Additional App Structure==&lt;br /&gt;
&lt;br /&gt;
However, apps are also made up of a certain sequence of bytes following the header. Offsets are calculated from the posistion after the header, in addition to the offsets derived from offsets.&lt;br /&gt;
&lt;br /&gt;
Offset after 256 byte header:&lt;br /&gt;
&lt;br /&gt;
000h = The ASCII string &amp;quot;eZ8&amp;quot;, potentially signifying an eZ80 application&lt;br /&gt;
&lt;br /&gt;
003h = Null terminated Application name (zero padded to be 9 bytes in length with terminator byte)&lt;br /&gt;
&lt;br /&gt;
00Ch = Flag, [Bit 0 set - don't draw the TI splash screen] [Bit 1 set - app can use OpenLib]&lt;br /&gt;
&lt;br /&gt;
00Eh = Flag, [Bit 0 set - use the offset in 01Eh]&lt;br /&gt;
&lt;br /&gt;
012h = Offset to main code block section (this also points to the end of the relocations table)&lt;br /&gt;
&lt;br /&gt;
015h = Offset to the initialized data section which should be copied to ram (Can be at most 4kB in size)&lt;br /&gt;
&lt;br /&gt;
018h = Length of the initialized data section&lt;br /&gt;
&lt;br /&gt;
01Bh = Offset to the execution entry point (usually same as 012h)&lt;br /&gt;
&lt;br /&gt;
01Eh = Unknown 3 byte offset (See 00Eh)&lt;br /&gt;
&lt;br /&gt;
021h = Offset used for ExecLib&lt;br /&gt;
&lt;br /&gt;
024h = Offset to the string used to display a message in the memory screen (Usually a copyright, i.e. &amp;quot;(c) 2005-2015 Texas Instruments&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
027h = Offset to perhaps the start of data to be relocated?&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
Here is a full demo program demonstrating finding each application, displaying the name, size, version, and copyright information&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;quot;ti84pce.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	.db	tExtTok,tAsm84CECmp&lt;br /&gt;
	.org	usermem&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
; Finds all the apps and displays info&lt;br /&gt;
_FINDAPPS:&lt;br /&gt;
	ld	ix,0&lt;br /&gt;
	add	ix,sp&lt;br /&gt;
	ld	hl,ExecuteApp&lt;br /&gt;
	ld	de,cursorImage&lt;br /&gt;
	ld	bc,ExecuteApp_End-ExecuteApp_Start&lt;br /&gt;
	ldir&lt;br /&gt;
	call	_ZeroOP3&lt;br /&gt;
	ld	a,appObj&lt;br /&gt;
	ld	(OP3),a&lt;br /&gt;
_:	call	_HomeUp&lt;br /&gt;
	call	_ClrScrn&lt;br /&gt;
	call	_OP3ToOP1&lt;br /&gt;
	call	_FindAppUp		; find the app&lt;br /&gt;
	ret	c&lt;br /&gt;
	call	_OP1ToOP3		; store name&lt;br /&gt;
	ld	hl,OP1+1&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_PutS			; put name of app&lt;br /&gt;
	pop	hl			; don't need this push/pop (here for readability)&lt;br /&gt;
	call	_FindAppStart		; find the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	GetAppSize&lt;br /&gt;
	call	_DispHL			; display the size of the app&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_os_GetAppVersionString&lt;br /&gt;
	pop	bc&lt;br /&gt;
	call	_PutS&lt;br /&gt;
	call	_NewLine&lt;br /&gt;
	pop	hl&lt;br /&gt;
	call	FindAppInfoString	; Get the information&lt;br /&gt;
	call	_PutS&lt;br /&gt;
_:	call	_GetCSC&lt;br /&gt;
	or	a,a&lt;br /&gt;
	jr	z,-_&lt;br /&gt;
	cp	a,sk2nd&lt;br /&gt;
	jr	nz,--_&lt;br /&gt;
	ld	hl,OP3+1&lt;br /&gt;
	jp	cursorImage&lt;br /&gt;
&lt;br /&gt;
;--------------------------------------------------------------------&lt;br /&gt;
ExecuteApp:&lt;br /&gt;
; HL -&amp;gt; name of app (0 terminated)&lt;br /&gt;
; An alternative would be to copy to progtoedit and call _NewConext0&lt;br /&gt;
	.org	cursorImage&lt;br /&gt;
ExecuteApp_Start:&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	DeletePgrmFromUserMem&lt;br /&gt;
	ld	hl,$100&lt;br /&gt;
	call	_EnoughMem&lt;br /&gt;
	pop	hl&lt;br /&gt;
	jp	c, _ErrMemory&lt;br /&gt;
	call	_FindAppStart		; This locates the start of executable code for an app&lt;br /&gt;
	ld	a,E_Validation&lt;br /&gt;
	jp	c,_JError		; If we can't find it, that's a problem (throw a validation error)&lt;br /&gt;
	push	hl			; push location of start of app&lt;br /&gt;
	call	_ReloadAppEntryVecs&lt;br /&gt;
	call	_AppSetup&lt;br /&gt;
	set	appRunning,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	set	6,(iy+$28)&lt;br /&gt;
	res	0,(iy+$2C)		; set some app flags&lt;br /&gt;
	set	appAllowContext,(iy+APIFlg)	; turn on apps&lt;br /&gt;
	ld	hl,$D1787C		; copy to ram data location&lt;br /&gt;
	ld	bc,$FFF&lt;br /&gt;
	call	_MemClear		; zero out the ram data section&lt;br /&gt;
	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	push	hl			; de -&amp;gt; start of code for app&lt;br /&gt;
	ld	bc,$100			; bypass header information&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ex	de,hl&lt;br /&gt;
	ld	hl,$18			; find the start of the data to copy to ram&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	call	__icmpzero		; initialize the bss if it exists&lt;br /&gt;
	jr	z,+_&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	bc&lt;br /&gt;
	ld	hl,$15&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ld	de,$D1787C		; copy it in&lt;br /&gt;
	ldir&lt;br /&gt;
_:	pop	hl			; hl -&amp;gt; start of app&lt;br /&gt;
	call	FindStartOfAppCode	; After this, hl -&amp;gt; start of code for app&lt;br /&gt;
	jp	(hl)&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindAppInfoString:&lt;br /&gt;
; Finds the information string about an App&lt;br /&gt;
; i.e. (c) 2005-2014 Texas Instruments&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains start of app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$24&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)			; load location of info string&lt;br /&gt;
	add	hl,de &lt;br /&gt;
	or	a,a &lt;br /&gt;
	sbc	hl,de			; check if HL is 0&lt;br /&gt;
	ret	z&lt;br /&gt;
	add	hl,de			; add extra bytes&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------&lt;br /&gt;
FindStartOfAppCode:&lt;br /&gt;
; Finds the start of the actual executable from the start of an App&lt;br /&gt;
; Arguments:&lt;br /&gt;
;  HL : contains the start of the app address&lt;br /&gt;
	ld	bc,$100			; bypass some header info&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	push	hl&lt;br /&gt;
	pop	de&lt;br /&gt;
	ld	bc,$1B			; offset&lt;br /&gt;
	add	hl,bc&lt;br /&gt;
	ld	hl,(hl)&lt;br /&gt;
	add	hl,de&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
DeletePgrmFromUserMem:&lt;br /&gt;
	ld	de,(asm_prgm_size)	; load total program prgmSize&lt;br /&gt;
	or	a,a&lt;br /&gt;
	sbc	hl,hl&lt;br /&gt;
	ld	(asm_prgm_size),hl	; delete whatever current program was there&lt;br /&gt;
	ld	hl,userMem&lt;br /&gt;
	jp	_DelMem			; HL-&amp;gt;place to delete, DE=amount to delete&lt;br /&gt;
&lt;br /&gt;
;----------------------------------------------------------------------------	&lt;br /&gt;
GetAppSize:&lt;br /&gt;
; Gets the size of an app based from the start of the app&lt;br /&gt;
	push	hl&lt;br /&gt;
	call	_NextFieldFromType	; move to start of signature&lt;br /&gt;
	call	_NextFieldFromType	; move to end of signature&lt;br /&gt;
	pop	de&lt;br /&gt;
	or	a&lt;br /&gt;
	sbc	hl,de&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl&lt;br /&gt;
	inc	hl			; bypass app size bytes&lt;br /&gt;
	ret				; haha, we're probably looking at another app here&lt;br /&gt;
ExecuteApp_End:&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Credits and Contribution==&lt;br /&gt;
Matt &amp;quot;MateoConLechuga&amp;quot; Waltz&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control</id>
		<title>84PCE:Ports:Control</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control"/>
				<updated>2017-08-06T11:37:33Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|Control]] [[Category:84PCE:Ports:By_Name|Control]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0000-0fff&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Master Control&lt;br /&gt;
&lt;br /&gt;
This port range is used to configure and control important things; possibly the reason why it does not have a memory-mapped address. It is mirrored every 0x100 bytes.&lt;br /&gt;
&lt;br /&gt;
If a port is not listed; it indicates that writes have no effect and do not latch, and that reads are 0. Note that this may not be true one hundred percent.&lt;br /&gt;
&lt;br /&gt;
== Port Address Space ==&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0000|0000]]&lt;br /&gt;
|03&lt;br /&gt;
|CPU Speed Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0001|0001]]&lt;br /&gt;
|03&lt;br /&gt;
|OS Timer Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0002|0002]]&lt;br /&gt;
|&lt;br /&gt;
|Read only, value can change&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0003|0003]]&lt;br /&gt;
|00&lt;br /&gt;
|Hardware ID&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0005|0005]]&lt;br /&gt;
|76&lt;br /&gt;
|Set bit 5 to freeze, bit 6 affects backlight&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0006|0006]]&lt;br /&gt;
|03&lt;br /&gt;
|Display refresh&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0007|0007]]&lt;br /&gt;
|B7&lt;br /&gt;
|Latches values written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0008|0008]]&lt;br /&gt;
|7F&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0009|0009]]&lt;br /&gt;
|37&lt;br /&gt;
|Power control system&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000A|000A]]&lt;br /&gt;
|FD&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000B|000B]]&lt;br /&gt;
|F8&lt;br /&gt;
|Charging Status&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000C|000C]]&lt;br /&gt;
|00&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000D|000D]]&lt;br /&gt;
|FF&lt;br /&gt;
|Bit 0: Freeze if reset&amp;lt;br /&amp;gt;Bit 1: Crash if reset&amp;lt;br /&amp;gt;Bit 2: No apparent effect if reset&amp;lt;br /&amp;gt;Bit 3: Reset to disable VRAM. Upon set, VRAM is garbage&amp;lt;br /&amp;gt;Bits [7:4]Possibly last value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000E|000E]]&lt;br /&gt;
|0A&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000F|000F]]&lt;br /&gt;
|42&lt;br /&gt;
|High nibble may be a status, low 2 bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001C|001C]]&lt;br /&gt;
|80&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001D|001D]]&lt;br /&gt;
|A7&lt;br /&gt;
|Privileged address&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0020|0020]]&lt;br /&gt;
|7C&lt;br /&gt;
|Memory protection&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0028|0028]]&lt;br /&gt;
|&lt;br /&gt;
|Bit 1 is always 0&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0029|0029]]&lt;br /&gt;
|00&lt;br /&gt;
|Bit 0 latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002A|002A]]&lt;br /&gt;
|70&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002B|002B]]&lt;br /&gt;
|FE&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002C|002C]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 002C-0031 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0032|0032]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0033|0033]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0034|0034]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0035|0035]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0036|0036]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 0036-0039 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control</id>
		<title>84PCE:Ports:Control</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control"/>
				<updated>2017-08-06T11:33:58Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Port Address Space */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|Control]] [[Category:84PCE:Ports:By_Name|Control]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0000-0fff&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Master Control&lt;br /&gt;
&lt;br /&gt;
This port range is used to configure and control important things; possibly the reason why it does not have a memory-mapped address.&lt;br /&gt;
&lt;br /&gt;
If a port is not listed; it indicates that writes have no effect and do not latch, and that reads are 0. Note that this may not be true one hundred percent.&lt;br /&gt;
&lt;br /&gt;
== Port Address Space ==&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0000|0000]]&lt;br /&gt;
|03&lt;br /&gt;
|CPU Speed Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0001|0001]]&lt;br /&gt;
|03&lt;br /&gt;
|OS Timer Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0002|0002]]&lt;br /&gt;
|&lt;br /&gt;
|Read only, value can change&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0003|0003]]&lt;br /&gt;
|00&lt;br /&gt;
|Hardware ID&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0005|0005]]&lt;br /&gt;
|76&lt;br /&gt;
|Set bit 5 to freeze, bit 6 affects backlight&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0006|0006]]&lt;br /&gt;
|03&lt;br /&gt;
|Display refresh&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0007|0007]]&lt;br /&gt;
|B7&lt;br /&gt;
|Latches values written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0008|0008]]&lt;br /&gt;
|7F&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0009|0009]]&lt;br /&gt;
|37&lt;br /&gt;
|Power control system&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000A|000A]]&lt;br /&gt;
|FD&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000B|000B]]&lt;br /&gt;
|F8&lt;br /&gt;
|Charging Status&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000C|000C]]&lt;br /&gt;
|00&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000D|000D]]&lt;br /&gt;
|FF&lt;br /&gt;
|Bit 0: Freeze if reset&amp;lt;br /&amp;gt;Bit 1: Crash if reset&amp;lt;br /&amp;gt;Bit 2: No apparent effect if reset&amp;lt;br /&amp;gt;Bit 3: Reset to disable VRAM. Upon set, VRAM is garbage&amp;lt;br /&amp;gt;Bits [7:4]Possibly last value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000E|000E]]&lt;br /&gt;
|0A&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000F|000F]]&lt;br /&gt;
|42&lt;br /&gt;
|High nibble may be a status, low 2 bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001C|001C]]&lt;br /&gt;
|80&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001D|001D]]&lt;br /&gt;
|A7&lt;br /&gt;
|Privileged address&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0020|0020]]&lt;br /&gt;
|7C&lt;br /&gt;
|Memory protection&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0028|0028]]&lt;br /&gt;
|&lt;br /&gt;
|Bit 1 is always 0&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0029|0029]]&lt;br /&gt;
|00&lt;br /&gt;
|Bit 0 latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002A|002A]]&lt;br /&gt;
|70&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002B|002B]]&lt;br /&gt;
|FE&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002C|002C]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 002C-0031 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0032|0032]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0033|0033]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0034|0034]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0035|0035]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0036|0036]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 0036-0039 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control</id>
		<title>84PCE:Ports:Control</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control"/>
				<updated>2017-08-06T11:32:22Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Port Address Space */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|Control]] [[Category:84PCE:Ports:By_Name|Control]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0000-0fff&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Master Control&lt;br /&gt;
&lt;br /&gt;
This port range is used to configure and control important things; possibly the reason why it does not have a memory-mapped address.&lt;br /&gt;
&lt;br /&gt;
If a port is not listed; it indicates that writes have no effect and do not latch, and that reads are 0. Note that this may not be true one hundred percent.&lt;br /&gt;
&lt;br /&gt;
== Port Address Space ==&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0000|0000]]&lt;br /&gt;
|03&lt;br /&gt;
|CPU Speed Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0001|0001]]&lt;br /&gt;
|03&lt;br /&gt;
|OS Timer Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0002|0002]]&lt;br /&gt;
|&lt;br /&gt;
|Read only, value can change&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0003|0003]]&lt;br /&gt;
|00&lt;br /&gt;
|Hardware ID&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0005|0005]]&lt;br /&gt;
|76&lt;br /&gt;
|Set bit 5 to freeze, bit 6 affects backlight&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0006|0006]]&lt;br /&gt;
|03&lt;br /&gt;
|Display refresh&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0007|0007]]&lt;br /&gt;
|B7&lt;br /&gt;
|Latches values written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0008|0008]]&lt;br /&gt;
|7F&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0009|0009]]&lt;br /&gt;
|37&lt;br /&gt;
|Power control system&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000A|000A]]&lt;br /&gt;
|FD&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000B|000B]]&lt;br /&gt;
|F8&lt;br /&gt;
|Charging Status&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000C|000C]]&lt;br /&gt;
|00&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000D|000D]]&lt;br /&gt;
|FF&lt;br /&gt;
|Bit 0: Freeze if reset&amp;lt;br /&amp;gt;Bit 1: Crash if reset&amp;lt;br /&amp;gt;Bit 2: No apparent effect if reset&amp;lt;br /&amp;gt;Bit 3: Reset to disable VRAM? Upon set, VRAM is garbage.&amp;lt;br /&amp;gt;Bits [7:4]Possibly last value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000E|000E]]&lt;br /&gt;
|0A&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000F|000F]]&lt;br /&gt;
|42&lt;br /&gt;
|High nibble may be a status, low 2 bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001C|001C]]&lt;br /&gt;
|80&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001D|001D]]&lt;br /&gt;
|A7&lt;br /&gt;
|Privileged address&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0020|0020]]&lt;br /&gt;
|7C&lt;br /&gt;
|Memory protection&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0028|0028]]&lt;br /&gt;
|&lt;br /&gt;
|Bit 1 is always 0&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0029|0029]]&lt;br /&gt;
|00&lt;br /&gt;
|Bit 0 latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002A|002A]]&lt;br /&gt;
|70&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002B|002B]]&lt;br /&gt;
|FE&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002C|002C]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 002C-0031 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0032|0032]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0033|0033]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0034|0034]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0035|0035]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0036|0036]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 0036-0039 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0028</id>
		<title>84PCE:Ports:0028</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0028"/>
				<updated>2017-08-06T11:31:57Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: Created page with &amp;quot;0028 - Unknown == Synopsis == '''Port Number:''' 0028  '''Function:''' Unknown  == Details ==  This port's function is unknown.  === Bit [0...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|0028 - Unknown]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0028&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Unknown&lt;br /&gt;
&lt;br /&gt;
== Details ==&lt;br /&gt;
&lt;br /&gt;
This port's function is unknown.&lt;br /&gt;
&lt;br /&gt;
=== Bit [0] ===&lt;br /&gt;
Latches value written, no apparent effect.&lt;br /&gt;
&lt;br /&gt;
=== Bit [1] ===&lt;br /&gt;
Always 0, writes do not latch.&lt;br /&gt;
&lt;br /&gt;
=== Bit [2] ===&lt;br /&gt;
Latches value written, no apparent effect.&lt;br /&gt;
&lt;br /&gt;
=== Bits [7:3] ===&lt;br /&gt;
Writes do not latch, no apparent effect.&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control</id>
		<title>84PCE:Ports:Control</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control"/>
				<updated>2017-08-06T11:26:19Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|Control]] [[Category:84PCE:Ports:By_Name|Control]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0000-0fff&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Master Control&lt;br /&gt;
&lt;br /&gt;
This port range is used to configure and control important things; possibly the reason why it does not have a memory-mapped address.&lt;br /&gt;
&lt;br /&gt;
If a port is not listed; it indicates that writes have no effect and do not latch, and that reads are 0. Note that this may not be true one hundred percent.&lt;br /&gt;
&lt;br /&gt;
== Port Address Space ==&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0000|0000]]&lt;br /&gt;
|03&lt;br /&gt;
|CPU Speed Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0001|0001]]&lt;br /&gt;
|03&lt;br /&gt;
|OS Timer Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0002|0002]]&lt;br /&gt;
|&lt;br /&gt;
|Read only, value can change&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0003|0003]]&lt;br /&gt;
|00&lt;br /&gt;
|Hardware ID&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0005|0005]]&lt;br /&gt;
|76&lt;br /&gt;
|Set bit 5 to freeze, bit 6 affects backlight&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0006|0006]]&lt;br /&gt;
|03&lt;br /&gt;
|Display refresh&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0007|0007]]&lt;br /&gt;
|B7&lt;br /&gt;
|Latches values written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0008|0008]]&lt;br /&gt;
|7F&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0009|0009]]&lt;br /&gt;
|37&lt;br /&gt;
|Power control system&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000A|000A]]&lt;br /&gt;
|FD&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000B|000B]]&lt;br /&gt;
|F8&lt;br /&gt;
|Charging Status&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000C|000C]]&lt;br /&gt;
|00&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000D|000D]]&lt;br /&gt;
|FF&lt;br /&gt;
|Bit 0: Freeze if reset&amp;lt;br /&amp;gt;Bit 1: Crash if reset&amp;lt;br /&amp;gt;Bit 2: No apparent effect if reset&amp;lt;br /&amp;gt;Bit 3: Reset to disable VRAM? Upon set, VRAM is garbage.&amp;lt;br /&amp;gt;Bits [7:4]Possibly last value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000E|000E]]&lt;br /&gt;
|0A&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000F|000F]]&lt;br /&gt;
|42&lt;br /&gt;
|High nibble may be a status, low 2 bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001C|001C]]&lt;br /&gt;
|80&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001D|001D]]&lt;br /&gt;
|A7&lt;br /&gt;
|Privileged address&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0020|0020]]&lt;br /&gt;
|7C&lt;br /&gt;
|Memory protection&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0028|0028]]&lt;br /&gt;
|&lt;br /&gt;
|Bit 1 is always 0, other bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0029|0029]]&lt;br /&gt;
|00&lt;br /&gt;
|Bit 0 latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002A|002A]]&lt;br /&gt;
|70&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002B|002B]]&lt;br /&gt;
|FE&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002C|002C]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 002C-0031 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0032|0032]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0033|0033]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0034|0034]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0035|0035]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0036|0036]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 0036-0039 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control</id>
		<title>84PCE:Ports:Control</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control"/>
				<updated>2017-08-06T11:25:58Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|Control]] [[Category:84PCE:Ports:By_Name|Control]]&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0000-0fff&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Master Control&lt;br /&gt;
&lt;br /&gt;
This port range is used to configure and control important things; possibly the reason why it does not have a memory-mapped address.&lt;br /&gt;
&lt;br /&gt;
If a port is not listed; it indicates that writes have no effect and do not latch, and that reads are 0. Note that this may not be true one hundred percent.&lt;br /&gt;
&lt;br /&gt;
== Port Address Space ==&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0000|0000]]&lt;br /&gt;
|03&lt;br /&gt;
|CPU Speed Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0001|0001]]&lt;br /&gt;
|03&lt;br /&gt;
|OS Timer Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0002|0002]]&lt;br /&gt;
|&lt;br /&gt;
|Read only, value can change&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0003|0003]]&lt;br /&gt;
|00&lt;br /&gt;
|Hardware ID&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0005|0005]]&lt;br /&gt;
|76&lt;br /&gt;
|Set bit 5 to freeze, bit 6 affects backlight&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0006|0006]]&lt;br /&gt;
|03&lt;br /&gt;
|Display refresh&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0007|0007]]&lt;br /&gt;
|B7&lt;br /&gt;
|Latches values written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0008|0008]]&lt;br /&gt;
|7F&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0009|0009]]&lt;br /&gt;
|37&lt;br /&gt;
|Power control system&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000A|000A]]&lt;br /&gt;
|FD&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000B|000B]]&lt;br /&gt;
|F8&lt;br /&gt;
|Charging Status&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000C|000C]]&lt;br /&gt;
|00&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000D|000D]]&lt;br /&gt;
|FF&lt;br /&gt;
|Bit 0: Freeze if reset&amp;lt;br /&amp;gt;Bit 1: Crash if reset&amp;lt;br /&amp;gt;Bit 2: No apparent effect if reset&amp;lt;br /&amp;gt;Bit 3: Reset to disable VRAM? Upon set, VRAM is garbage.&amp;lt;br /&amp;gt;Bits [7:4]Possibly last value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000E|000E]]&lt;br /&gt;
|0A&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000F|000F]]&lt;br /&gt;
|42&lt;br /&gt;
|High nibble may be a status, low 2 bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001C|001C]]&lt;br /&gt;
|80&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001D|001D]]&lt;br /&gt;
|A7&lt;br /&gt;
|Privileged address&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0020|0020]]&lt;br /&gt;
|7C&lt;br /&gt;
|Memory protection&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0028|0028]]&lt;br /&gt;
|&lt;br /&gt;
|Bit 1 is always 0, other bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0029|0029]]&lt;br /&gt;
|00&lt;br /&gt;
|Bit 0 latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002A|002A]]&lt;br /&gt;
|70&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002B|002B]]&lt;br /&gt;
|FE&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002C|002C]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 002C-0031 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0032|0032]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0033|0033]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0034|0034]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0035|0035]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0036|0036]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 0036-0039 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control</id>
		<title>84PCE:Ports:Control</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control"/>
				<updated>2017-08-06T11:12:58Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Synopsis */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|Control]] [[Category:84PCE:Ports:By_Name|Control]]&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0000-0fff&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Master Control&lt;br /&gt;
&lt;br /&gt;
This port range is used to configure and control important things; possibly the reason why it does not have a memory-mapped address.&lt;br /&gt;
&lt;br /&gt;
If a port is not listed; it indicates that writes have no effect and do not latch, and that reads are 0. Note that this may not be true one hundred percent.&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0000|0000]]&lt;br /&gt;
|03&lt;br /&gt;
|CPU Speed Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0001|0001]]&lt;br /&gt;
|03&lt;br /&gt;
|OS Timer Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0002|0002]]&lt;br /&gt;
|&lt;br /&gt;
|Read only, value can change&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0003|0003]]&lt;br /&gt;
|00&lt;br /&gt;
|Hardware ID&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0005|0005]]&lt;br /&gt;
|76&lt;br /&gt;
|Set bit 5 to freeze, bit 6 affects backlight&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0006|0006]]&lt;br /&gt;
|03&lt;br /&gt;
|Display refresh&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0007|0007]]&lt;br /&gt;
|B7&lt;br /&gt;
|Latches values written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0008|0008]]&lt;br /&gt;
|7F&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0009|0009]]&lt;br /&gt;
|37&lt;br /&gt;
|Power control system&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000A|000A]]&lt;br /&gt;
|FD&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000B|000B]]&lt;br /&gt;
|F8&lt;br /&gt;
|Charging Status&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000C|000C]]&lt;br /&gt;
|00&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000D|000D]]&lt;br /&gt;
|FF&lt;br /&gt;
|Bit 0: Freeze if reset&amp;lt;br /&amp;gt;Bit 1: Crash if reset&amp;lt;br /&amp;gt;Bit 2: No apparent effect if reset&amp;lt;br /&amp;gt;Bit 3: Reset to disable VRAM? Upon set, VRAM is garbage.&amp;lt;br /&amp;gt;Bits [7:4]Possibly last value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000E|000E]]&lt;br /&gt;
|0A&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000F|000F]]&lt;br /&gt;
|42&lt;br /&gt;
|High nibble may be a status, low 2 bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001C|001C]]&lt;br /&gt;
|80&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0028|0028]]&lt;br /&gt;
|&lt;br /&gt;
|Bit 1 is always 0, other bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0029|0029]]&lt;br /&gt;
|00&lt;br /&gt;
|Bit 0 latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002A|002A]]&lt;br /&gt;
|70&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002B|002B]]&lt;br /&gt;
|FE&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002C|002C]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 002C-0031 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0032|0032]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0033|0033]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0034|0034]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0035|0035]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0036|0036]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 0036-0039 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control</id>
		<title>84PCE:Ports:Control</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control"/>
				<updated>2017-08-06T11:12:48Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Synopsis */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|Control]] [[Category:84PCE:Ports:By_Name|Control]]&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0000-0fff&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Master Control&lt;br /&gt;
&lt;br /&gt;
This port range is used to configure and control important things; possibly the reason why it does not have a memory-mapped address.&lt;br /&gt;
&lt;br /&gt;
If a port is not listed; it indicates that writes have no effect and do not latch, and that reads are 0. Note that this may not be true one hundred percent.&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0000|0000]]&lt;br /&gt;
|03&lt;br /&gt;
|CPU Speed Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0001|0001]]&lt;br /&gt;
|03&lt;br /&gt;
|OS Timer Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0002|0002]]&lt;br /&gt;
|&lt;br /&gt;
|Read only, value can change&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0003|0003]]&lt;br /&gt;
|&lt;br /&gt;
|Hardware ID&lt;br /&gt;
|00&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0005|0005]]&lt;br /&gt;
|76&lt;br /&gt;
|Set bit 5 to freeze, bit 6 affects backlight&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0006|0006]]&lt;br /&gt;
|03&lt;br /&gt;
|Display refresh&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0007|0007]]&lt;br /&gt;
|B7&lt;br /&gt;
|Latches values written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0008|0008]]&lt;br /&gt;
|7F&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0009|0009]]&lt;br /&gt;
|37&lt;br /&gt;
|Power control system&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000A|000A]]&lt;br /&gt;
|FD&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000B|000B]]&lt;br /&gt;
|F8&lt;br /&gt;
|Charging Status&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000C|000C]]&lt;br /&gt;
|00&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000D|000D]]&lt;br /&gt;
|FF&lt;br /&gt;
|Bit 0: Freeze if reset&amp;lt;br /&amp;gt;Bit 1: Crash if reset&amp;lt;br /&amp;gt;Bit 2: No apparent effect if reset&amp;lt;br /&amp;gt;Bit 3: Reset to disable VRAM? Upon set, VRAM is garbage.&amp;lt;br /&amp;gt;Bits [7:4]Possibly last value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000E|000E]]&lt;br /&gt;
|0A&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000F|000F]]&lt;br /&gt;
|42&lt;br /&gt;
|High nibble may be a status, low 2 bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001C|001C]]&lt;br /&gt;
|80&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0028|0028]]&lt;br /&gt;
|&lt;br /&gt;
|Bit 1 is always 0, other bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0029|0029]]&lt;br /&gt;
|00&lt;br /&gt;
|Bit 0 latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002A|002A]]&lt;br /&gt;
|70&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002B|002B]]&lt;br /&gt;
|FE&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002C|002C]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 002C-0031 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0032|0032]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0033|0033]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0034|0034]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0035|0035]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0036|0036]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 0036-0039 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control</id>
		<title>84PCE:Ports:Control</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control"/>
				<updated>2017-08-06T11:12:36Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Synopsis */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|Control]] [[Category:84PCE:Ports:By_Name|Control]]&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0000-0fff&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Master Control&lt;br /&gt;
&lt;br /&gt;
This port range is used to configure and control important things; possibly the reason why it does not have a memory-mapped address.&lt;br /&gt;
&lt;br /&gt;
If a port is not listed; it indicates that writes have no effect and do not latch, and that reads are 0. Note that this may not be true one hundred percent.&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0000|0000]]&lt;br /&gt;
|03&lt;br /&gt;
|CPU Speed Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0001|0001]]&lt;br /&gt;
|03&lt;br /&gt;
|OS Timer Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0002|0002]]&lt;br /&gt;
|&lt;br /&gt;
|Read only, value can change&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0003|0003]]&lt;br /&gt;
|&lt;br /&gt;
|Hardware ID&lt;br /&gt;
|00&lt;br /&gt;
|[[:84PCE:Ports:0005|0005]]&lt;br /&gt;
|76&lt;br /&gt;
|Set bit 5 to freeze, bit 6 affects backlight&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0006|0006]]&lt;br /&gt;
|03&lt;br /&gt;
|Display refresh&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0007|0007]]&lt;br /&gt;
|B7&lt;br /&gt;
|Latches values written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0008|0008]]&lt;br /&gt;
|7F&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0009|0009]]&lt;br /&gt;
|37&lt;br /&gt;
|Power control system&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000A|000A]]&lt;br /&gt;
|FD&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000B|000B]]&lt;br /&gt;
|F8&lt;br /&gt;
|Charging Status&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000C|000C]]&lt;br /&gt;
|00&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000D|000D]]&lt;br /&gt;
|FF&lt;br /&gt;
|Bit 0: Freeze if reset&amp;lt;br /&amp;gt;Bit 1: Crash if reset&amp;lt;br /&amp;gt;Bit 2: No apparent effect if reset&amp;lt;br /&amp;gt;Bit 3: Reset to disable VRAM? Upon set, VRAM is garbage.&amp;lt;br /&amp;gt;Bits [7:4]Possibly last value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000E|000E]]&lt;br /&gt;
|0A&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000F|000F]]&lt;br /&gt;
|42&lt;br /&gt;
|High nibble may be a status, low 2 bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001C|001C]]&lt;br /&gt;
|80&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0028|0028]]&lt;br /&gt;
|&lt;br /&gt;
|Bit 1 is always 0, other bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0029|0029]]&lt;br /&gt;
|00&lt;br /&gt;
|Bit 0 latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002A|002A]]&lt;br /&gt;
|70&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002B|002B]]&lt;br /&gt;
|FE&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002C|002C]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 002C-0031 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0032|0032]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0033|0033]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0034|0034]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0035|0035]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0036|0036]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 0036-0039 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control</id>
		<title>84PCE:Ports:Control</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control"/>
				<updated>2017-08-06T11:11:54Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Synopsis */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|Control]] [[Category:84PCE:Ports:By_Name|Control]]&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0000-0fff&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Master Control&lt;br /&gt;
&lt;br /&gt;
This port range is used to configure and control important things; possibly the reason why it does not have a memory-mapped address.&lt;br /&gt;
&lt;br /&gt;
If a port is not listed; it indicates that writes have no effect and do not latch, and that reads are 0. Note that this may not be true one hundred percent.&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0000|0000]]&lt;br /&gt;
|03&lt;br /&gt;
|CPU Speed Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0001|0001]]&lt;br /&gt;
|03&lt;br /&gt;
|OS Timer Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0002|0002]]&lt;br /&gt;
|&lt;br /&gt;
|Read only, value can change&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0003|0003]]&lt;br /&gt;
|&lt;br /&gt;
|Hardware ID&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0005|0005]]&lt;br /&gt;
|76&lt;br /&gt;
|Set bit 5 to freeze, bit 6 affects backlight&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0006|0006]]&lt;br /&gt;
|03&lt;br /&gt;
|Display refresh&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0007|0007]]&lt;br /&gt;
|B7&lt;br /&gt;
|Latches values written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0008|0008]]&lt;br /&gt;
|7F&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0009|0009]]&lt;br /&gt;
|37&lt;br /&gt;
|Power control system&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000A|000A]]&lt;br /&gt;
|FD&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000B|000B]]&lt;br /&gt;
|F8&lt;br /&gt;
|Charging Status&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000C|000C]]&lt;br /&gt;
|00&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000D|000D]]&lt;br /&gt;
|FF&lt;br /&gt;
|Bit 0: Freeze if reset&amp;lt;br /&amp;gt;Bit 1: Crash if reset&amp;lt;br /&amp;gt;Bit 2: No apparent effect if reset&amp;lt;br /&amp;gt;Bit 3: Reset to disable VRAM? Upon set, VRAM is garbage.&amp;lt;br /&amp;gt;Bits [7:4]Possibly last value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000E|000E]]&lt;br /&gt;
|0A&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000F|000F]]&lt;br /&gt;
|42&lt;br /&gt;
|High nibble may be a status, low 2 bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001C|001C]]&lt;br /&gt;
|80&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0028|0028]]&lt;br /&gt;
|&lt;br /&gt;
|Bit 1 is always 0, other bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0029|0029]]&lt;br /&gt;
|00&lt;br /&gt;
|Bit 0 latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002A|002A]]&lt;br /&gt;
|70&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002B|002B]]&lt;br /&gt;
|FE&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002C|002C]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 002C-0031 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0032|0032]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0033|0033]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0034|0034]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0035|0035]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0036|0036]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 0036-0039 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:000B</id>
		<title>84PCE:Ports:000B</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:000B"/>
				<updated>2017-08-06T11:10:47Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: Created page with &amp;quot;000B - Charging Status == Synopsis == '''Port Number:''' 000B  '''Function:''' Charging Status  == Details ==  This port is read only.  ===...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|000B - Charging Status]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 000B&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Charging Status&lt;br /&gt;
&lt;br /&gt;
== Details ==&lt;br /&gt;
&lt;br /&gt;
This port is read only.&lt;br /&gt;
&lt;br /&gt;
=== Bit [0] ===&lt;br /&gt;
Writes have no apparent effect, value does not latch.&lt;br /&gt;
&lt;br /&gt;
=== Bit [1] ===&lt;br /&gt;
When connected to a power source and charging, this bit is set.&lt;br /&gt;
&lt;br /&gt;
=== Bits [7:2] ===&lt;br /&gt;
Writes have no apparent effect, value does not latch.&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control</id>
		<title>84PCE:Ports:Control</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control"/>
				<updated>2017-08-06T11:09:14Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* Synopsis */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|Control]] [[Category:84PCE:Ports:By_Name|Control]]&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0000-0fff&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Master Control&lt;br /&gt;
&lt;br /&gt;
This port range is used to configure and control important things; possibly the reason why it does not have a memory-mapped address.&lt;br /&gt;
&lt;br /&gt;
If a port is not listed; it indicates that writes have no effect and do not latch, and that reads are 0. Note that this may not be true one hundred percent.&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0000|0000]]&lt;br /&gt;
|03&lt;br /&gt;
|CPU Speed Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0001|0001]]&lt;br /&gt;
|03&lt;br /&gt;
|OS Timer Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0002|0002]]&lt;br /&gt;
|&lt;br /&gt;
|Read only, value can change&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0005|0005]]&lt;br /&gt;
|76&lt;br /&gt;
|Set bit 5 to freeze, bit 6 affects backlight&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0006|0006]]&lt;br /&gt;
|03&lt;br /&gt;
|Display refresh&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0007|0007]]&lt;br /&gt;
|B7&lt;br /&gt;
|Latches values written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0008|0008]]&lt;br /&gt;
|7F&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0009|0009]]&lt;br /&gt;
|37&lt;br /&gt;
|Power control system&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000A|000A]]&lt;br /&gt;
|FD&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000B|000B]]&lt;br /&gt;
|F8&lt;br /&gt;
|Charging Status&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000C|000C]]&lt;br /&gt;
|00&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000D|000D]]&lt;br /&gt;
|FF&lt;br /&gt;
|Bit 0: Freeze if reset&amp;lt;br /&amp;gt;Bit 1: Crash if reset&amp;lt;br /&amp;gt;Bit 2: No apparent effect if reset&amp;lt;br /&amp;gt;Bit 3: Reset to disable VRAM? Upon set, VRAM is garbage.&amp;lt;br /&amp;gt;Bits [7:4]Possibly last value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000E|000E]]&lt;br /&gt;
|0A&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000F|000F]]&lt;br /&gt;
|42&lt;br /&gt;
|High nibble may be a status, low 2 bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001C|001C]]&lt;br /&gt;
|80&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0028|0028]]&lt;br /&gt;
|&lt;br /&gt;
|Bit 1 is always 0, other bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0029|0029]]&lt;br /&gt;
|00&lt;br /&gt;
|Bit 0 latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002A|002A]]&lt;br /&gt;
|70&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002B|002B]]&lt;br /&gt;
|FE&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002C|002C]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 002C-0031 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0032|0032]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0033|0033]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0034|0034]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0035|0035]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0036|0036]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 0036-0039 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0000_Unknowns</id>
		<title>84PCE:Ports:0000 Unknowns</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0000_Unknowns"/>
				<updated>2017-08-06T11:06:25Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: Blanked the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control</id>
		<title>84PCE:Ports:Control</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control"/>
				<updated>2017-08-06T11:06:05Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|Control]] [[Category:84PCE:Ports:By_Name|Control]]&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0000-0fff&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Master Control&lt;br /&gt;
&lt;br /&gt;
This port range is used to configure and control important things; possibly the reason why it does not have a memory-mapped address.&lt;br /&gt;
&lt;br /&gt;
If a port is not listed; it indicates that writes have no effect and do not latch, and that reads are 0. Note that this may not be true one hundred percent.&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0000|0000]]&lt;br /&gt;
|03&lt;br /&gt;
|CPU Speed Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0001|0001]]&lt;br /&gt;
|03&lt;br /&gt;
|OS Timer Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0002|0002]]&lt;br /&gt;
|&lt;br /&gt;
|Read only, value can change&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0005|0005]]&lt;br /&gt;
|76&lt;br /&gt;
|Set bit 5 to freeze, bit 6 affects backlight&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0006|0006]]&lt;br /&gt;
|03&lt;br /&gt;
|Display refresh&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0007|0007]]&lt;br /&gt;
|B7&lt;br /&gt;
|Latches values written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0008|0008]]&lt;br /&gt;
|7F&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0009|0009]]&lt;br /&gt;
|37&lt;br /&gt;
|Power control system&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000A|000A]]&lt;br /&gt;
|FD&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000C|000C]]&lt;br /&gt;
|00&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000D|000D]]&lt;br /&gt;
|FF&lt;br /&gt;
|Bit 0: Freeze if reset&amp;lt;br /&amp;gt;Bit 1: Crash if reset&amp;lt;br /&amp;gt;Bit 2: No apparent effect if reset&amp;lt;br /&amp;gt;Bit 3: Reset to disable VRAM? Upon set, VRAM is garbage.&amp;lt;br /&amp;gt;Bits [7:4]Possibly last value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000E|000E]]&lt;br /&gt;
|0A&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000F|000F]]&lt;br /&gt;
|42&lt;br /&gt;
|High nibble may be a status, low 2 bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001C|001C]]&lt;br /&gt;
|80&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0028|0028]]&lt;br /&gt;
|&lt;br /&gt;
|Bit 1 is always 0, other bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0029|0029]]&lt;br /&gt;
|00&lt;br /&gt;
|Bit 0 latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002A|002A]]&lt;br /&gt;
|70&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002B|002B]]&lt;br /&gt;
|FE&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002C|002C]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 002C-0031 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0032|0032]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0033|0033]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0034|0034]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0035|0035]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0036|0036]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 0036-0039 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control</id>
		<title>84PCE:Ports:Control</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control"/>
				<updated>2017-08-06T11:05:34Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|Control]] [[Category:84PCE:Ports:By_Name|Control]]&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0000-0fff&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Master Control&lt;br /&gt;
&lt;br /&gt;
This port range is used to configure and control masters.&lt;br /&gt;
&lt;br /&gt;
If a port is not listed; it indicates that writes have no effect and do not latch, and that reads are 0. Note that this may not be true one hundred percent.&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0000|0000]]&lt;br /&gt;
|03&lt;br /&gt;
|CPU Speed Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0001|0001]]&lt;br /&gt;
|03&lt;br /&gt;
|OS Timer Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0002|0002]]&lt;br /&gt;
|&lt;br /&gt;
|Read only, value can change&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0005|0005]]&lt;br /&gt;
|76&lt;br /&gt;
|Set bit 5 to freeze, bit 6 affects backlight&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0006|0006]]&lt;br /&gt;
|03&lt;br /&gt;
|Display refresh&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0007|0007]]&lt;br /&gt;
|B7&lt;br /&gt;
|Latches values written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0008|0008]]&lt;br /&gt;
|7F&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0009|0009]]&lt;br /&gt;
|37&lt;br /&gt;
|Power control system&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000A|000A]]&lt;br /&gt;
|FD&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000C|000C]]&lt;br /&gt;
|00&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000D|000D]]&lt;br /&gt;
|FF&lt;br /&gt;
|Bit 0: Freeze if reset&amp;lt;br /&amp;gt;Bit 1: Crash if reset&amp;lt;br /&amp;gt;Bit 2: No apparent effect if reset&amp;lt;br /&amp;gt;Bit 3: Reset to disable VRAM? Upon set, VRAM is garbage.&amp;lt;br /&amp;gt;Bits [7:4]Possibly last value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000E|000E]]&lt;br /&gt;
|0A&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000F|000F]]&lt;br /&gt;
|42&lt;br /&gt;
|High nibble may be a status, low 2 bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001C|001C]]&lt;br /&gt;
|80&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0028|0028]]&lt;br /&gt;
|&lt;br /&gt;
|Bit 1 is always 0, other bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0029|0029]]&lt;br /&gt;
|00&lt;br /&gt;
|Bit 0 latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002A|002A]]&lt;br /&gt;
|70&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002B|002B]]&lt;br /&gt;
|FE&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002C|002C]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 002C-0031 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0032|0032]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0033|0033]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0034|0034]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0035|0035]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0036|0036]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 0036-0039 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control</id>
		<title>84PCE:Ports:Control</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:Control"/>
				<updated>2017-08-06T11:05:15Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: Created page with &amp;quot;Control Control  == Synopsis == '''Port Number:''' 0000-0fff  '''Function:''' Master Control  This port ra...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|Control]] [[Category:84PCE:Ports:By_Name|Control]]&lt;br /&gt;
&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0000-0fff&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Master Control&lt;br /&gt;
&lt;br /&gt;
This port range is used to configure and control different things.&lt;br /&gt;
&lt;br /&gt;
If a port is not listed; it indicates that writes have no effect and do not latch, and that reads are 0. Note that this may not be true one hundred percent.&lt;br /&gt;
&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0000|0000]]&lt;br /&gt;
|03&lt;br /&gt;
|CPU Speed Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0001|0001]]&lt;br /&gt;
|03&lt;br /&gt;
|OS Timer Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0002|0002]]&lt;br /&gt;
|&lt;br /&gt;
|Read only, value can change&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0005|0005]]&lt;br /&gt;
|76&lt;br /&gt;
|Set bit 5 to freeze, bit 6 affects backlight&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0006|0006]]&lt;br /&gt;
|03&lt;br /&gt;
|Display refresh&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0007|0007]]&lt;br /&gt;
|B7&lt;br /&gt;
|Latches values written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0008|0008]]&lt;br /&gt;
|7F&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0009|0009]]&lt;br /&gt;
|37&lt;br /&gt;
|Power control system&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000A|000A]]&lt;br /&gt;
|FD&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000C|000C]]&lt;br /&gt;
|00&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000D|000D]]&lt;br /&gt;
|FF&lt;br /&gt;
|Bit 0: Freeze if reset&amp;lt;br /&amp;gt;Bit 1: Crash if reset&amp;lt;br /&amp;gt;Bit 2: No apparent effect if reset&amp;lt;br /&amp;gt;Bit 3: Reset to disable VRAM? Upon set, VRAM is garbage.&amp;lt;br /&amp;gt;Bits [7:4]Possibly last value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000E|000E]]&lt;br /&gt;
|0A&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000F|000F]]&lt;br /&gt;
|42&lt;br /&gt;
|High nibble may be a status, low 2 bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001C|001C]]&lt;br /&gt;
|80&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0028|0028]]&lt;br /&gt;
|&lt;br /&gt;
|Bit 1 is always 0, other bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0029|0029]]&lt;br /&gt;
|00&lt;br /&gt;
|Bit 0 latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002A|002A]]&lt;br /&gt;
|70&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002B|002B]]&lt;br /&gt;
|FE&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002C|002C]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 002C-0031 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0032|0032]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0033|0033]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0034|0034]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0035|0035]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0036|0036]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 0036-0039 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0000_Unknowns</id>
		<title>84PCE:Ports:0000 Unknowns</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0000_Unknowns"/>
				<updated>2017-08-06T10:58:06Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* 0000 Range */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|0000 Unknowns]] [[Category:84PCE:Ports:By_Name|0000 Unknowns]] [[Category:84PCE:Ports:Unknown|0000 Unknowns]]&lt;br /&gt;
&lt;br /&gt;
If a port is not listed; it indicates that writes have no effect and do not latch, and that reads are 0. Note that this may not be true one hundred percent.&lt;br /&gt;
&lt;br /&gt;
=== 0000 Range ===&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0000|0000]]&lt;br /&gt;
|03&lt;br /&gt;
|CPU Speed Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0001|0001]]&lt;br /&gt;
|03&lt;br /&gt;
|OS Timer Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0002|0002]]&lt;br /&gt;
|&lt;br /&gt;
|Read only, value can change&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0005|0005]]&lt;br /&gt;
|76&lt;br /&gt;
|Set bit 5 to freeze, bit 6 affects backlight&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0006|0006]]&lt;br /&gt;
|03&lt;br /&gt;
|Display refresh&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0007|0007]]&lt;br /&gt;
|B7&lt;br /&gt;
|Latches values written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0008|0008]]&lt;br /&gt;
|7F&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0009|0009]]&lt;br /&gt;
|37&lt;br /&gt;
|Power control system&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000A|000A]]&lt;br /&gt;
|FD&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000C|000C]]&lt;br /&gt;
|00&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000D|000D]]&lt;br /&gt;
|FF&lt;br /&gt;
|Bit 0: Freeze if reset&amp;lt;br /&amp;gt;Bit 1: Crash if reset&amp;lt;br /&amp;gt;Bit 2: No apparent effect if reset&amp;lt;br /&amp;gt;Bit 3: Reset to disable VRAM? Upon set, VRAM is garbage.&amp;lt;br /&amp;gt;Bits [7:4]Possibly last value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000E|000E]]&lt;br /&gt;
|0A&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000F|000F]]&lt;br /&gt;
|42&lt;br /&gt;
|High nibble may be a status, low 2 bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001C|001C]]&lt;br /&gt;
|80&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0028|0028]]&lt;br /&gt;
|&lt;br /&gt;
|Bit 1 is always 0, other bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0029|0029]]&lt;br /&gt;
|00&lt;br /&gt;
|Bit 0 latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002A|002A]]&lt;br /&gt;
|70&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002B|002B]]&lt;br /&gt;
|FE&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002C|002C]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 002C-0031 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0032|0032]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0033|0033]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0034|0034]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0035|0035]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0036|0036]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 0036-0039 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0000_Unknowns</id>
		<title>84PCE:Ports:0000 Unknowns</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0000_Unknowns"/>
				<updated>2017-08-06T10:57:53Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* 0000 Range */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|0000 Unknowns]] [[Category:84PCE:Ports:By_Name|0000 Unknowns]] [[Category:84PCE:Ports:Unknown|0000 Unknowns]]&lt;br /&gt;
&lt;br /&gt;
If a port is not listed; it indicates that writes have no effect and do not latch, and that reads are 0. Note that this may not be true one hundred percent.&lt;br /&gt;
&lt;br /&gt;
=== 0000 Range ===&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Bits&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0000|0000]]&lt;br /&gt;
|03&lt;br /&gt;
|CPU Speed Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0001|0001]]&lt;br /&gt;
|03&lt;br /&gt;
|OS Timer Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0002|0002]]&lt;br /&gt;
|&lt;br /&gt;
|Read only, value can change&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0005|0005]]&lt;br /&gt;
|76&lt;br /&gt;
|Set bit 5 to freeze, bit 6 affects backlight&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0006|0006]]&lt;br /&gt;
|03&lt;br /&gt;
|Display refresh&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0007|0007]]&lt;br /&gt;
|B7&lt;br /&gt;
|Latches values written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0008|0008]]&lt;br /&gt;
|7F&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0009|0009]]&lt;br /&gt;
|37&lt;br /&gt;
|Power control system&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000A|000A]]&lt;br /&gt;
|FD&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000C|000C]]&lt;br /&gt;
|00&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000D|000D]]&lt;br /&gt;
|FF&lt;br /&gt;
|Bit 0: Freeze if reset&amp;lt;br /&amp;gt;Bit 1: Crash if reset&amp;lt;br /&amp;gt;Bit 2: No apparent effect if reset&amp;lt;br /&amp;gt;Bit 3: Reset to disable VRAM? Upon set, VRAM is garbage.&amp;lt;br /&amp;gt;Bits [7:4]Possibly last value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000E|000E]]&lt;br /&gt;
|0A&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000F|000F]]&lt;br /&gt;
|42&lt;br /&gt;
|High nibble may be a status, low 2 bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001C|001C]]&lt;br /&gt;
|80&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0028|0028]]&lt;br /&gt;
|&lt;br /&gt;
|Bit 1 is always 0, other bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0029|0029]]&lt;br /&gt;
|00&lt;br /&gt;
|Bit 0 latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002A|002A]]&lt;br /&gt;
|70&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002B|002B]]&lt;br /&gt;
|FE&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002C|002C]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 002C-0031 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0032|0032]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0033|0033]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0034|0034]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0035|0035]]&lt;br /&gt;
|&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0036|0036]]&lt;br /&gt;
|&lt;br /&gt;
|Ports 0036-0039 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0000_Unknowns</id>
		<title>84PCE:Ports:0000 Unknowns</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0000_Unknowns"/>
				<updated>2017-08-06T10:56:25Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* 0000 Range */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|0000 Unknowns]] [[Category:84PCE:Ports:By_Name|0000 Unknowns]] [[Category:84PCE:Ports:Unknown|0000 Unknowns]]&lt;br /&gt;
&lt;br /&gt;
If a port is not listed; it indicates that writes have no effect and do not latch, and that reads are 0. Note that this may not be true one hundred percent.&lt;br /&gt;
&lt;br /&gt;
=== 0000 Range ===&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Bits&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0000|0000]]&lt;br /&gt;
|03&lt;br /&gt;
|D3&lt;br /&gt;
|CPU Speed Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0001|0001]]&lt;br /&gt;
|03&lt;br /&gt;
|13&lt;br /&gt;
|OS Timer Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0002|0002]]&lt;br /&gt;
|&lt;br /&gt;
|??&lt;br /&gt;
|Read only, value can change&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0005|0005]]&lt;br /&gt;
|76&lt;br /&gt;
|??&lt;br /&gt;
|Set bit 5 to freeze, bit 6 affects backlight&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0006|0006]]&lt;br /&gt;
|03&lt;br /&gt;
|03?&lt;br /&gt;
|Display refresh&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0007|0007]]&lt;br /&gt;
|B7&lt;br /&gt;
|FF&lt;br /&gt;
|Latches values written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0008|0008]]&lt;br /&gt;
|7F&lt;br /&gt;
|7F&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0009|0009]]&lt;br /&gt;
|37&lt;br /&gt;
|??&lt;br /&gt;
|Power control system&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000A|000A]]&lt;br /&gt;
|FD&lt;br /&gt;
|FF&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000C|000C]]&lt;br /&gt;
|00&lt;br /&gt;
|FF&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000D|000D]]&lt;br /&gt;
|FF&lt;br /&gt;
|FF&lt;br /&gt;
|Bit 0: Freeze if reset&amp;lt;br /&amp;gt;Bit 1: Crash if reset&amp;lt;br /&amp;gt;Bit 2: No apparent effect if reset&amp;lt;br /&amp;gt;Bit 3: Reset to disable VRAM? Upon set, VRAM is garbage.&amp;lt;br /&amp;gt;Bits [7:4]Possibly last value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000E|000E]]&lt;br /&gt;
|0A&lt;br /&gt;
|FF&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000F|000F]]&lt;br /&gt;
|42&lt;br /&gt;
|?3&lt;br /&gt;
|High nibble may be a status, low 2 bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001C|001C]]&lt;br /&gt;
|80&lt;br /&gt;
|??&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0028|0028]]&lt;br /&gt;
|&lt;br /&gt;
|FD&lt;br /&gt;
|Bit 1 is always 0, other bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0029|0029]]&lt;br /&gt;
|00&lt;br /&gt;
|01&lt;br /&gt;
|Bit 0 latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002A|002A]]&lt;br /&gt;
|70&lt;br /&gt;
|73&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002B|002B]]&lt;br /&gt;
|FE&lt;br /&gt;
|FF&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002C|002C]]&lt;br /&gt;
|&lt;br /&gt;
|FF&lt;br /&gt;
|Ports 002C-0031 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0032|0032]]&lt;br /&gt;
|&lt;br /&gt;
|07&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0033|0033]]&lt;br /&gt;
|&lt;br /&gt;
|F1&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0034|0034]]&lt;br /&gt;
|&lt;br /&gt;
|31&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0035|0035]]&lt;br /&gt;
|&lt;br /&gt;
|3F&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0036|0036]]&lt;br /&gt;
|&lt;br /&gt;
|FF&lt;br /&gt;
|Ports 0036-0039 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0009</id>
		<title>84PCE:Ports:0009</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0009"/>
				<updated>2017-08-06T10:53:49Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: Created page with &amp;quot;0002 - Unknown == Synopsis == '''Port Number:''' 0002  '''Function:''' Unknown  == Details ==  This port appears to be the power control....&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|0002 - Unknown]]&lt;br /&gt;
== Synopsis ==&lt;br /&gt;
'''Port Number:''' 0002&lt;br /&gt;
&lt;br /&gt;
'''Function:''' Unknown&lt;br /&gt;
&lt;br /&gt;
== Details ==&lt;br /&gt;
&lt;br /&gt;
This port appears to be the power control.&lt;br /&gt;
&lt;br /&gt;
=== Bits [1:0] ===&lt;br /&gt;
Latches value written, no apparent effect.&lt;br /&gt;
&lt;br /&gt;
=== Bit [2] ===&lt;br /&gt;
Reset to disable screen. Setting after reset has no effect.&lt;br /&gt;
&lt;br /&gt;
=== Bits [7:3] ===&lt;br /&gt;
Latches value written, no apparent effect.&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0000_Unknowns</id>
		<title>84PCE:Ports:0000 Unknowns</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0000_Unknowns"/>
				<updated>2017-08-06T10:49:43Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* 0000 Range */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|0000 Unknowns]] [[Category:84PCE:Ports:By_Name|0000 Unknowns]] [[Category:84PCE:Ports:Unknown|0000 Unknowns]]&lt;br /&gt;
&lt;br /&gt;
If a port is not listed; it indicates that writes have no effect and do not latch, and that reads are 0. Note that this may not be true one hundred percent.&lt;br /&gt;
&lt;br /&gt;
=== 0000 Range ===&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Bits&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0000|0000]]&lt;br /&gt;
|03&lt;br /&gt;
|D3&lt;br /&gt;
|CPU Speed Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0001|0001]]&lt;br /&gt;
|03&lt;br /&gt;
|13&lt;br /&gt;
|OS Timer Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0002|0002]]&lt;br /&gt;
|&lt;br /&gt;
|??&lt;br /&gt;
|Read only, value can change&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0005|0005]]&lt;br /&gt;
|76&lt;br /&gt;
|??&lt;br /&gt;
|Set bit 5 to freeze, bit 6 affects backlight&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0006|0006]]&lt;br /&gt;
|03&lt;br /&gt;
|03?&lt;br /&gt;
|Display refresh&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0007|0007]]&lt;br /&gt;
|B7&lt;br /&gt;
|FF&lt;br /&gt;
|Latches values written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0008|0008]]&lt;br /&gt;
|7F&lt;br /&gt;
|7F&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0009|0009]]&lt;br /&gt;
|37&lt;br /&gt;
|??&lt;br /&gt;
|Power control system&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000A|000A]]&lt;br /&gt;
|05&lt;br /&gt;
|??&lt;br /&gt;
|Latches value written, OS reset to 05&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000B|000B]]&lt;br /&gt;
|FC&lt;br /&gt;
|??&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000C|000C]]&lt;br /&gt;
|00&lt;br /&gt;
|FF&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000D|000D]]&lt;br /&gt;
|FF&lt;br /&gt;
|FF&lt;br /&gt;
|Bit 0: Freeze if reset&amp;lt;br /&amp;gt;Bit 1: Crash if reset&amp;lt;br /&amp;gt;Bit 2: No apparent effect if reset&amp;lt;br /&amp;gt;Bit 3: Reset to disable VRAM? Upon set, VRAM is garbage.&amp;lt;br /&amp;gt;Bits [7:4]Possibly last value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000E|000E]]&lt;br /&gt;
|0A&lt;br /&gt;
|FF&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000F|000F]]&lt;br /&gt;
|42&lt;br /&gt;
|?3&lt;br /&gt;
|High nibble may be a status, low 2 bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001C|001C]]&lt;br /&gt;
|80&lt;br /&gt;
|??&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0028|0028]]&lt;br /&gt;
|&lt;br /&gt;
|FD&lt;br /&gt;
|Bit 1 is always 0, other bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0029|0029]]&lt;br /&gt;
|00&lt;br /&gt;
|01&lt;br /&gt;
|Bit 0 latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002A|002A]]&lt;br /&gt;
|70&lt;br /&gt;
|73&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002B|002B]]&lt;br /&gt;
|FE&lt;br /&gt;
|FF&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002C|002C]]&lt;br /&gt;
|&lt;br /&gt;
|FF&lt;br /&gt;
|Ports 002C-0031 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0032|0032]]&lt;br /&gt;
|&lt;br /&gt;
|07&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0033|0033]]&lt;br /&gt;
|&lt;br /&gt;
|F1&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0034|0034]]&lt;br /&gt;
|&lt;br /&gt;
|31&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0035|0035]]&lt;br /&gt;
|&lt;br /&gt;
|3F&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0036|0036]]&lt;br /&gt;
|&lt;br /&gt;
|FF&lt;br /&gt;
|Ports 0036-0039 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0000_Unknowns</id>
		<title>84PCE:Ports:0000 Unknowns</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0000_Unknowns"/>
				<updated>2017-08-06T10:48:54Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: /* 0000 Range */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|0000 Unknowns]] [[Category:84PCE:Ports:By_Name|0000 Unknowns]] [[Category:84PCE:Ports:Unknown|0000 Unknowns]]&lt;br /&gt;
&lt;br /&gt;
If a port is not listed; it indicates that writes have no effect and do not latch, and that reads are 0. Note that this may not be true one hundred percent.&lt;br /&gt;
&lt;br /&gt;
=== 0000 Range ===&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Bits&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0000|0000]]&lt;br /&gt;
|03&lt;br /&gt;
|D3&lt;br /&gt;
|CPU Speed Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0001|0001]]&lt;br /&gt;
|03&lt;br /&gt;
|13&lt;br /&gt;
|OS Timer Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0002|0002]]&lt;br /&gt;
|&lt;br /&gt;
|??&lt;br /&gt;
|Read only, value can change&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0005|0005]]&lt;br /&gt;
|76&lt;br /&gt;
|??&lt;br /&gt;
|Set bit 5 to freeze, bit 6 affects backlight&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0006|0006]]&lt;br /&gt;
|03&lt;br /&gt;
|03?&lt;br /&gt;
|Display refresh&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0007|0007]]&lt;br /&gt;
|B7&lt;br /&gt;
|FF&lt;br /&gt;
|Latches values written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0008|0008]]&lt;br /&gt;
|7F&lt;br /&gt;
|7F&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0009|0009]]&lt;br /&gt;
|&lt;br /&gt;
|??&lt;br /&gt;
|Appears to be a part of the power control system.&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000A|000A]]&lt;br /&gt;
|05&lt;br /&gt;
|??&lt;br /&gt;
|Latches value written, OS reset to 05&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000B|000B]]&lt;br /&gt;
|FC&lt;br /&gt;
|??&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000C|000C]]&lt;br /&gt;
|00&lt;br /&gt;
|FF&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000D|000D]]&lt;br /&gt;
|FF&lt;br /&gt;
|FF&lt;br /&gt;
|Bit 0: Freeze if reset&amp;lt;br /&amp;gt;Bit 1: Crash if reset&amp;lt;br /&amp;gt;Bit 2: No apparent effect if reset&amp;lt;br /&amp;gt;Bit 3: Reset to disable VRAM? Upon set, VRAM is garbage.&amp;lt;br /&amp;gt;Bits [7:4]Possibly last value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000E|000E]]&lt;br /&gt;
|0A&lt;br /&gt;
|FF&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000F|000F]]&lt;br /&gt;
|42&lt;br /&gt;
|?3&lt;br /&gt;
|High nibble may be a status, low 2 bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001C|001C]]&lt;br /&gt;
|80&lt;br /&gt;
|??&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0028|0028]]&lt;br /&gt;
|&lt;br /&gt;
|FD&lt;br /&gt;
|Bit 1 is always 0, other bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0029|0029]]&lt;br /&gt;
|00&lt;br /&gt;
|01&lt;br /&gt;
|Bit 0 latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002A|002A]]&lt;br /&gt;
|70&lt;br /&gt;
|73&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002B|002B]]&lt;br /&gt;
|FE&lt;br /&gt;
|FF&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002C|002C]]&lt;br /&gt;
|&lt;br /&gt;
|FF&lt;br /&gt;
|Ports 002C-0031 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0032|0032]]&lt;br /&gt;
|&lt;br /&gt;
|07&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0033|0033]]&lt;br /&gt;
|&lt;br /&gt;
|F1&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0034|0034]]&lt;br /&gt;
|&lt;br /&gt;
|31&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0035|0035]]&lt;br /&gt;
|&lt;br /&gt;
|3F&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0036|0036]]&lt;br /&gt;
|&lt;br /&gt;
|FF&lt;br /&gt;
|Ports 0036-0039 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	<entry>
		<id>https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0000_Unknowns</id>
		<title>84PCE:Ports:0000 Unknowns</title>
		<link rel="alternate" type="text/html" href="https://wikiti.brandonw.net/index.php?title=84PCE:Ports:0000_Unknowns"/>
				<updated>2017-08-06T10:47:09Z</updated>
		
		<summary type="html">&lt;p&gt;MateoConLechuga: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:84PCE:Ports:By_Address|0000 Unknowns]] [[Category:84PCE:Ports:By_Name|0000 Unknowns]] [[Category:84PCE:Ports:Unknown|0000 Unknowns]]&lt;br /&gt;
&lt;br /&gt;
If a port is not listed; it indicates that writes have no effect and do not latch, and that reads are 0. Note that this may not be true one hundred percent.&lt;br /&gt;
&lt;br /&gt;
=== 0000 Range ===&lt;br /&gt;
{|-&lt;br /&gt;
|&amp;lt;u&amp;gt;Port&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Default&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Bits&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|&amp;lt;u&amp;gt;Information&amp;lt;/u&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0000|0000]]&lt;br /&gt;
|03&lt;br /&gt;
|D3&lt;br /&gt;
|CPU Speed Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0001|0001]]&lt;br /&gt;
|03&lt;br /&gt;
|13&lt;br /&gt;
|OS Timer Control&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0002|0002]]&lt;br /&gt;
|&lt;br /&gt;
|??&lt;br /&gt;
|Read only, value can change&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0005|0005]]&lt;br /&gt;
|76&lt;br /&gt;
|??&lt;br /&gt;
|Set bit 5 to freeze, bit 6 affects backlight&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0006|0006]]&lt;br /&gt;
|03&lt;br /&gt;
|03?&lt;br /&gt;
|Display refresh&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0007|0007]]&lt;br /&gt;
|B7&lt;br /&gt;
|FF&lt;br /&gt;
|Latches values written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0008|0008]]&lt;br /&gt;
|7F&lt;br /&gt;
|??&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0009|0009]]&lt;br /&gt;
|&lt;br /&gt;
|??&lt;br /&gt;
|Appears to be a part of the power control system.&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000A|000A]]&lt;br /&gt;
|05&lt;br /&gt;
|??&lt;br /&gt;
|Latches value written, OS reset to 05&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000B|000B]]&lt;br /&gt;
|FC&lt;br /&gt;
|??&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000C|000C]]&lt;br /&gt;
|00&lt;br /&gt;
|FF&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000D|000D]]&lt;br /&gt;
|FF&lt;br /&gt;
|FF&lt;br /&gt;
|Bit 0: Freeze if reset&amp;lt;br /&amp;gt;Bit 1: Crash if reset&amp;lt;br /&amp;gt;Bit 2: No apparent effect if reset&amp;lt;br /&amp;gt;Bit 3: Reset to disable VRAM? Upon set, VRAM is garbage.&amp;lt;br /&amp;gt;Bits [7:4]Possibly last value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000E|000E]]&lt;br /&gt;
|0A&lt;br /&gt;
|FF&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:000F|000F]]&lt;br /&gt;
|42&lt;br /&gt;
|?3&lt;br /&gt;
|High nibble may be a status, low 2 bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:001C|001C]]&lt;br /&gt;
|80&lt;br /&gt;
|??&lt;br /&gt;
|Cannot change value&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0028|0028]]&lt;br /&gt;
|&lt;br /&gt;
|FD&lt;br /&gt;
|Bit 1 is always 0, other bits latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0029|0029]]&lt;br /&gt;
|00&lt;br /&gt;
|01&lt;br /&gt;
|Bit 0 latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002A|002A]]&lt;br /&gt;
|70&lt;br /&gt;
|73&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002B|002B]]&lt;br /&gt;
|FE&lt;br /&gt;
|FF&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:002C|002C]]&lt;br /&gt;
|&lt;br /&gt;
|FF&lt;br /&gt;
|Ports 002C-0031 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0032|0032]]&lt;br /&gt;
|&lt;br /&gt;
|07&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0033|0033]]&lt;br /&gt;
|&lt;br /&gt;
|F1&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0034|0034]]&lt;br /&gt;
|&lt;br /&gt;
|31&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0035|0035]]&lt;br /&gt;
|&lt;br /&gt;
|3F&lt;br /&gt;
|Latches value written&lt;br /&gt;
|-&lt;br /&gt;
|[[:84PCE:Ports:0036|0036]]&lt;br /&gt;
|&lt;br /&gt;
|FF&lt;br /&gt;
|Ports 0036-0039 latch value written&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>MateoConLechuga</name></author>	</entry>

	</feed>