;RAMHooks v0.1 ; (C) 2007 by Brandon Wilson. All rights reserved. ;RAMHooks is a TI-83/84 Plus Flash application which lets you embed dozens or hundreds of hooks of any size into a single ; Flash application (itself), so that RAM programs can call included entry points and install safe, reusable, protected hooks of any type. include "settings.inc" NOLIST include "ti83plus.inc" LIST include "equates.inc" include "header.asm" SEGMENT MAIN GLOBALS ON EXTERN unlockFlash,PutSApp Var swapSectorPage,1 Var myPage,1 Var swapPage,1 Var myPageSwap,1 Var destAddr,2 StartApp: ;See if one-time setup is required ld hl,OneTimeSettings bit 0,(hl) jr z,ExitApp ;Display waiting message B_CALL ClrLCDFull B_CALL HomeUp ld hl,sOneTimeSetup call PutSApp ;Mark one-time setup done call unlockFlash ld de,OneTimeSettings ld a,(de) and 0FEh ld b,a in a,(6) ld (myPage),a B_CALL WriteAByte call garbageCollectMyself ExitApp: B_JUMP JForceCmdNoChar garbageCollectMyself: ;Find and erase swap sector B_CALL FindSwapSector push af ld hl,4000h B_CALL GetBytePaged ld a,b cp 0FFh jr z,$F pop af push af B_CALL EraseFlashPage $$: pop af ld (swapSectorPage),a ;Copy all of this sector to the swap sector ld a,(swapSectorPage) ld b,a ld a,(myPage) and 0FCh ld c,4 $$: push af push bc B_CALL CopyFlashPage pop bc pop af inc a inc b dec c jr nz,$B ;From RAM code, selectively copy from the swap sector back to this sector ld hl,sRAMCode ld de,tempSwapArea ld bc,sRAMCodeEnd-sRAMCode ldir call tempSwapArea ;Now you can modify the end of yourself however you like ;Old data is at (myPageSwap):(iMathPtr5) ld hl,(iMathPtr5) ld (destAddr),hl garbageCollectLoop: ld a,(myPageSwap) ld b,a ld hl,(iMathPtr5) B_CALL LoadCIndPaged ld (iMathPtr5),hl ld a,c ld (appData),a inc a jr z,garbageCollectDone ld b,a ld hl,sHookFlagTable-2 $$: inc hl inc hl djnz $B ld c,(hl) inc hl ld a,(hl) ld hl,flags add hl,bc ld b,a and (hl) jr nz,saveHook ;TODO: checking the hook flag is not enough ld hl,(iMathPtr5) ld a,(myPageSwap) ld b,a B_CALL LoadDEIndPaged add hl,de ld (iMathPtr5),hl jr garbageCollectLoop saveHook: ld (appData+1),bc in a,(6) ld hl,appData ld de,(destAddr) ld bc,3 B_CALL WriteFlash ld hl,(destAddr) inc hl inc hl inc hl ld (destAddr),hl ;TODO: write old hook to myself jr garbageCollectLoop sHookFlagTable: DB 36h,00000100b ;00; app change hook DB 36h,00001000b ;01; catalog 1 hook DB 34h,01000000b ;02; catalog 2 hook DB 34h,10000000b ;03; cursor hook DB 36h,00100000b ;04; cxRedisp hook DB 35h,00100000b ;05; font hook DB 34h,00000001b ;06; GetCSC hook DB 35h,00001000b ;07; graph hook DB 35h,10000000b ;08; graphics hook DB 36h,00010000b ;09; help hook DB 34h,00010000b ;10; homescreen hook DB 34h,00000010b ;11; library hook DB 33h,00010000b ;12; link activity hook DB 35h,00000010b ;13; localize hook DB 36h,01000000b ;14; menu hook DB 36h,00000010b ;15; parser hook DB 34h,00100000b ;16; RawKey hook DB 35h,01000000b ;17; regraph hook DB 36h,10000000b ;18; silent link hook DB 35h,00000001b ;19; token hook DB 36h,00000001b ;20; trace hook DB 3Ah,00000001b ;21; USB activity hook DB 35h,00000100b ;22; window hook DB 35h,00010000b ;23; Y= hook garbageCollectDone: ;Erase swap sector when done ld a,(swapSectorPage) B_CALL EraseFlashPage ld a,(swapSectorPage) ld hl,4000h ld b,0FEh B_CALL WriteAByte ret sRAMCode: ;Copy swap sector to my sector ;Create a loop of 4 increments that copies one page directly to another...but if it's the application's page, do this instead: ; Look up size of myself from the app header and copy that many bytes instead. ld a,(myPage) and 0FCh B_CALL EraseFlashPage ld a,(myPage) and 3 ld b,a ld a,(swapSectorPage) add a,b ld (myPageSwap),a ld a,(myPage) and 0FCh ld b,a ld a,(swapSectorPage) ld c,4 backupSectorLoop: push af push bc ld hl,myPageSwap cp (hl) jp nz,copySector-sRAMCode+tempSwapArea ld a,(myPageSwap) ld b,a ld hl,4004h B_CALL LoadDEIndPaged ld a,d ld d,e ld e,a ld hl,6 add hl,de ld b,h ld c,l ld hl,4000h ld (iMathPtr5),hl ld (iMathPtr4),bc copyMyselfLoop: ld bc,768 ld hl,(iMathPtr4) or a sbc hl,bc jr nc,$F ld bc,(iMathPtr4) $$: ld a,(myPageSwap) ld hl,(iMathPtr5) ld de,appBackUpScreen push bc B_CALL FlashToRam pop bc push bc ld a,(myPage) ld hl,appBackUpScreen ld de,(iMathPtr5) B_CALL WriteFlash pop bc ld hl,(iMathPtr5) add hl,bc ld (iMathPtr5),hl ld hl,(iMathPtr4) sbc hl,bc ld (iMathPtr4),hl ld a,h or l jp nz,copyMyselfLoop-sRAMCode+tempSwapArea ld a,(myPageSwap) ld hl,(iMathPtr5) ld bc,64+3 ;magic because field search routines are wonky add hl,bc ld de,(iMathPtr5) or a sbc hl,de inc hl inc hl ld a,(myPageSwap) ld b,h ld c,l ld hl,(iMathPtr5) ld de,appBackUpScreen push bc B_CALL FlashToRam pop bc ld de,(iMathPtr5) ld hl,(iMathPtr5) add hl,bc ld (iMathPtr5),hl ld a,(myPage) ld hl,appBackUpScreen B_CALL WriteFlash jr $F copySector: B_CALL CopyFlashPage $$: pop bc pop af inc a inc b dec c jp nz,backupSectorLoop-sRAMCode+tempSwapArea ret sRAMCodeEnd: sOneTimeSetup: DB "Setting up " DB "the RAMHooks " DB "application for " DB "the first time",0CEh," " DB " " DB " " DB "Please wait",0CEh,0 sGarbageCollecting: DB "Garbage " DB "collecting " DB "the RAMHooks " DB "application... " DB " " DB " " DB "Please wait",0CEh,0