.nolist #include "ti83plus.inc" .list .org userMem-2 .db 0BBh,6Dh res 1,(iy+asm_Flag1) ;Verify we're running on Nspire hardware call IsNspire ret c set 1,(iy+asm_Flag1) ;we're an Nspire! call UnlockFlash ;Verify we're on OS 2.54MP bcall(_getBaseVer) sub 02h ret nz ld a,b sub 54 ret nz ;Apply the patch ld a,78h ld de,6B5Bh ld b,06h call WriteAByte ld hl,appData ld (hl),0CDh inc hl ld (hl),0D0h inc hl ld (hl),7Fh ld a,78h ld hl,appData ld de,6C85h ld bc,3 call WriteFlash ld a,0D6h ld (appData+1),a ld de,5C00h call WriteBlock ld de,5CA7h call WriteBlock ld de,607Dh call WriteBlock ld de,695Ah call WriteBlock ld de,6BFBh call WriteBlock ld a,78h ld hl,patchBlock ld de,7FD0h ld bc,patchBlockEnd-patchBlock call WriteFlash ;All done! ret patchBlock: .db 21h,01h,00h,22h,61h,96h,0FDh,0CBh,07h,0C6h,0C9h patchBlockEnd: WriteBlock: ld a,78h ld hl,appData ld bc,3 WriteFlash: ;Writes BC bytes from HL to ADE ;Inputs: A is page ; HL is source ; DE is destination ; BC is number of bytes to write ;Outputs: ADE is next destination location ; HL is next source location ; BC=0 ;Notes: This must run from RAM. ; Requires Flash unlocked. bit 1,(iy+asm_Flag1) jr nz,WriteFlashNspire push ix bcall(_WriteFlash) pop ix ret WriteFlashNspire: push af WriteFlashLoop: pop af push af push bc ld b,(hl) call WriteAByte pop bc bit 7,d jr z,noOverflow res 7,d set 6,d pop af inc a push af noOverflow: inc hl dec bc ld a,b or c jr nz,WriteFlashLoop pop af ret FindPattern: ;Pattern in IX, Flash page in A, starting address in DE ;Returns NZ if pattern not found ;(appBackUpScreen) contains the address of match found ;Search pattern: terminated by 00h ; 0FFh is ? (one-character wildcard) ld (iMathPtr4),a in a,(6) push af ld hl,findPatternRet push hl ld a,(iMathPtr4) out (6),a dec de searchLoopRestart: inc de ld (appBackUpScreen),de push ix pop hl searchLoop: ld b,(hl) ld a,b or a ret z inc de inc a jr z,matchSoFar dec de ld a,(de) inc de bit 7,d ret nz cp b jr z,matchSoFar ld de,(appBackUpScreen) jr searchLoopRestart matchSoFar: inc hl jr searchLoop findPatternRet: pop bc ld a,b out (6),a ret IsNspire: ;Determines if calculator is an Nspire. ;Inputs: None ;Outputs: Carry set if NOT Nspire ;Notes: This must run from RAM. ; Destroys all in a,(6) push af ld a,7Fh call translatePage out (6),a ld hl,4000h ld bc,4000h isNspireLoop: ld e,(hl) inc hl dec bc ld a,b or c scf jr z,exitIsNspire ld a,e cp 0EDh jr nz,isNspireLoop ld e,(hl) inc hl dec bc ld a,b or c scf jr z,exitIsNspire ld a,e cp 0EFh jr nz,isNspireLoop exitIsNspire: pop bc ld a,b out (6),a ret WriteAByte: ;Writes byte B to A:DE ;Inputs: A is page ; DE is address ; B is byte to write ;Outputs: DE=DE+1 ; All preserved ;Notes: This must run from RAM. ; Requires Flash unlocked. bit 1,(iy+asm_Flag1) jr nz,WriteAByteNspire bcall(_WriteAByte) ret WriteAByteNspire: push af push bc push hl or a jr nz,notPageZero set 6,d notPageZero: ld c,a in a,(6) push af ld a,c ld hl,(OP1) push hl push af ld a,8 out (6),a ld hl,OP1 ld (hl),b .db 0EDh,0EFh pop af out (6),a ldi pop hl ld (OP1),hl pop af out (6),a pop hl pop bc pop af ret UnlockFlash: ;Unlocks Flash protection. ;Destroys: appBackUpScreen ; pagedCount ; pagedGetPtr ; arcInfo ; iMathPtr5 ; pagedBuf ; ramCode in a,(6) push af ld a,7Bh call translatePage out (6),a ld hl,5092h ld e,(hl) inc hl ld d,(hl) inc hl ld a,(hl) call translatePage out (6),a ex de,hl ld a,0CCh ld bc,0FFFFh cpir ld e,(hl) inc hl ld d,(hl) push de pop ix ld hl,9898h ld (hl),0C3h inc hl ld (hl),returnPoint & 11111111b inc hl ld (hl),returnPoint >> 8 ld hl,pagedBuf ld (hl),98h ld de,pagedBuf+1 ld bc,49 ldir ld (iMathPtr5),sp ld hl,(iMathPtr5) ld de,9A00h ld bc,50 ldir ld de,(iMathPtr5) ld hl,-12 add hl,de ld (iMathPtr5),hl ld iy,0056h-25h ld a,50 ld (pagedCount),a ld a,8 ld (arcInfo),a jp (ix) translatePage: ld b,a in a,(2) and 80h jr z,_is83P in a,(21h) and 3 ld a,b ret nz and 3Fh ret _is83P: ld a,b and 1Fh ret returnPoint: ld iy,flags ld hl,(iMathPtr5) ld de,12 add hl,de ld sp,hl ex de,hl ld hl,9A00h ld bc,50 ldir pop af out (6),a ret .end end