DEFINE PAGE1C, SPACE=ROM SEGMENT PAGE1C include "includes\os2.inc" include "includes\internal.inc" PUBLIC keyscnlnk EXTERN JErrorNo,NZIf83Plus,CheckLinkLines,EnableLinkAssist,DisableLinkAssist,ContinueGetByte,Get3Bytes EXTERN DispHexA,LdHLInd,SendAcknowledge,ReceiveHeaderPacket,SendSkipExitPacket,Get4BytesNC,SendCommandA EXTERN Send4Bytes,SendCAndAddToChecksum,LCDDelay,_LCD_COMMAND,SendAByte,SetXAutoIncrementMode,EraseRAMPage EXTERN SetYAutoIncrementMode,SendContinue,ReceiveDataPacket,DispHexHL,PutC,receiveRestOfDataPacket EXTERN CopyToRAMPage,CopyRAMToFlashPage,EraseEOL,PowerOff,SendHCommand,IPutSB,IPutC,CheckForBootLoader EXTERN SetupPagedPtr,PagedGet,SendChecksumGetAcknowledge,RecAByteIO,cphlde,NZIf84PlusSeries keyscnlnk: di res enableHW2Timer,(iy+interruptFlags) call NZIf83Plus jr nz,$F $$: call CheckLinkLines jr nz,eiRet ld a,(ioErrState) push af ld a,(sndRecState) push af ld a,(ioFlag) push af ;I haven't decided on what to do with this stuff yet. ld hl,ioFlag res 1,(hl) ld a,7 ld (sndRecState),a ld a,(iy+curFlags) push af res 2,(iy+curFlags) ;call EnableLinkAssist ld hl,keyscnlnkHandler call APP_PUSH_ERRORH set indicOnly,(iy+indicFlags) ld a,(ioData) call ContinueGetByte bit 5,(iy+3Dh) jr nz,keyscnlnkEnd call Get3Bytes HandleLinkPacket: ld hl,cmdTable ld b,(hl) inc hl $$: cp (hl) inc hl jr z,$F inc hl inc hl djnz $B ;This is a command we don't recognize ;TODO: for now, freak out ld a,5 call PutC ld a,(header+1) call DispHexA di halt jp JErrorNo $$: call LdHLInd jp (hl) disableLAEnd: call DisableLinkAssist jr keyscnlnkEnd sendAcknowledgeEnd: call SendAcknowledge keyscnlnkEnd: call APP_POP_ERRORH keyscnlnkHandler: di call DisableLinkAssist pop af bit 2,a jr z,$F set curAble,(iy+curFlags) $$: pop af ld (ioFlag),a pop af ld (sndRecState),a pop af ld (ioErrState),a set apdRunning,(iy+apdFlags) di res indicOnly,(iy+indicFlags) ld a,lcdXAutoIncrementMode call _LCD_COMMAND eiRet: ei ret cmdTable: DB (cmdTableEnd-cmdTableStart)/3 cmdTableStart: DB 68h DW sendAcknowledgeEnd DB 2Dh DW sendInfoPacket DB 06h DW receivedVariableHeader DB 0C9h DW receivedVariableRequest DB 0A2h DW receivedRequestToSend DB 6Fh DW memoryDumpPacket DB 87h DW remoteControlPacket DB 6Dh DW screenshotPacket DB 15h ;this is garbage DW keyscnlnkEnd cmdTableEnd: receivedVariableRequest: ld hl,ioData ld (iMathPtr5),hl call receiveRestOfDataPacket ld de,1 ld a,0Ch call SendSkipExitPacket jr keyscnlnkEnd memoryDumpPacket: ld hl,ioData ld (iMathPtr5),hl call receiveRestOfDataPacket ld bc,(ioData) ld b,c ld de,(ioOP1) ld a,b ld hl,0 ld (curRow),hl call DispHexA ex de,hl call DispHexHL ex de,hl call SetupPagedPtr ld de,(ioOP1+2) ld (header+2),de push de ld hl,1573h ld (header),hl call Send4Bytes ld hl,0 ld (header+4),hl pop de $$: push de call PagedGet ld c,a call SendCAndAddToChecksum pop de dec de ld a,d or e jr nz,$B jr SendChecksumGetAcknowledge receivedRequestToSend: ld hl,ioData ld (iMathPtr5),hl call receiveRestOfDataPacket ld a,(ioOP1) cp 19h jr z,sendDirectoryContentsResponse ld a,6 call PutC ld a,0A2h call DispHexA ld hl,ioOP1 ld b,11 call IPutSB ld a,6 call PutC jr keyscnlnkEnd sendDirectoryContentsResponse: ;TODO: actually implement the directory contents response ld hl,22000 ld (ioData),hl ld a,15h ld hl,2 call SendCommandA ld h,92h call SendHCommand jr keyscnlnkEnd screenshotPacket: call SendScreenshotResponse jr keyscnlnkEnd SendScreenshotResponse: call SendAcknowledge ld de,768 ld (header+2),de ld hl,1573h ld (header),hl call Send4Bytes di call SetYAutoIncrementMode ld a,7Fh ld b,40h SendScreenshotResponseLoop: push bc inc a ld (curXRow),a call SetYAutoIncrementMode call _LCD_COMMAND ld a,20h call _LCD_COMMAND call LCDDelay in a,(LCDdataPort) ld b,12 $$: push bc call LCDDelay in a,(LCDdataPort) ld c,a call SendCAndAddToChecksum pop bc djnz $B pop bc ld a,(curXRow) djnz SendScreenshotResponseLoop call SetXAutoIncrementMode ei SendChecksumAcknowledge: ld hl,(header+4) ld a,l push hl call SendAByte pop af call SendAByte ReceiveAcknowledgement: call Get4BytesNC ld a,(header+1) cp 56h ret z jp JErrorNo remoteControlPacket: call SendAcknowledge jr keyscnlnkEnd receivedVariableHeader: call ReceiveHeaderPacket ld a,(ioOP1) cp 23h jr z,receivingOS ;Not accepting anything else for now call DispHexA ld de,1 ld a,0Ch call SendSkipExitPacket jr keyscnlnkEnd receivingOS: bit receiveTIOS,(iy+linkFlags2) jr z,ReceiveNewOS xor a ld (ramCodeEnd),a B_CALL UnlockFlash ;Wipe sector 70h ld a,70h B_CALL EraseFlashPage ;Wipe the extra RAM pages ld a,84h call EraseRAMPage ld a,85h call EraseRAMPage ld a,86h call EraseRAMPage ld a,87h call EraseRAMPage ;Receive a copy of the TI-OS to the spare Flash sectors ld a,0FFh ld (appSearchPage),a ;Back up pages 68h and 69h to RAM pages 04h and 05h in a,(modelPort) and 3 ld a,68h jr nz,$F ld a,38h $$: ld b,04h push af push bc call CopyToRAMPage pop bc pop af push af inc a inc b call CopyToRAMPage pop af push af ;Erase sector 68h B_CALL EraseFlashPage pop bc ;Copy from RAM pages 04h and 05h back to pages 68h and 69h ld a,04h push af push bc call CopyRAMToFlashPage pop bc pop af inc a inc b call CopyRAMToFlashPage ld hl,receiveTIOSHandler call APP_PUSH_ERRORH ReceiveOSPage: ld hl,(curRow) push hl ld hl,7 ld (curRow),hl ld a,(ioData+8) ; call DispHexA ld hl,(ioData+6) ; call DispHexHL ; call EraseEOL pop hl ld (curRow),hl ld a,(ioData+8) ld hl,(ioData+6) ld b,a cp 08h jr c,$F in a,(statusPort) and STATUS_NON_83P_MASK ld a,b jr z,$F in a,(modelPort) and 3 ld a,b jr z,is84P or 60h jr $F is84P: or 30h $$: ;Maybe erase this sector (only if it's 04h, 74h, 78h) push af push hl ; call DispHexHL ;*** TESTING ld b,a ld a,(appSearchPage) cp b jr z,noSectorErase ld a,b ld (appSearchPage),a cp 04h jr z,$F cp 34h jr z,$F cp 74h jr z,$F cp 18h jr z,$F cp 38h jr z,$F cp 78h jr z,$F jr noSectorErase $$: B_CALL EraseFlashPage noSectorErase: call SendContinue ld bc,(ioData) ld de,appData push bc push de call ReceiveDataPacket pop de pop bc pop de pop af ld h,a ld a,(ioData+5) and 80h jr nz,skipWrite ld a,(ramCodeEnd) or a jr z,skipWrite ld a,h ;Write BC bytes from appData to ADE push bc cp 04h jr nc,$F ;This is part of sector 0, translate it to the extra RAM pages and write it ld hl,6 ld (curRow),hl push af ld a,5 ; call IPutC ex de,hl ; call DispHexHL ex de,hl ld a,d or 40h ld d,a ex de,hl ; call DispHexHL ex de,hl pop af pop bc ld hl,8000h add hl,de ex de,hl ld hl,appData di add a,4 out (5),a ldir xor a out (5),a jr dataWritten $$: ;Is this page 7Ch or 7Dh? If so, change it to 6Ah or 6Bh cp 7Ch ld b,6Ah jr z,translatePage cp 3Ch ld b,3Ah jr z,translatePage cp 7Dh ld b,6Bh jr z,translatePage cp 3Dh ld b,3Bh jr z,translatePage cp 3Ah jr z,checkAddress cp 7Ah jr z,checkAddress $$: ;Just write it ld hl,6 ld (curRow),hl ; call DispHexA ex de,hl ; call DispHexHL ex de,hl pop bc push bc pop hl ; call DispHexHL ld hl,appData B_CALL UnlockFlash B_CALL WriteFlash jr dataWritten translatePage: ld a,b jr $B checkAddress: push de ld hl,4200h or a sbc hl,de pop de jr c,$B jr z,$B ;Skip writes to 7A:4000h and 7A:4100h skipWrite: dataWritten: ld a,0FFh ld (ramCodeEnd),a call Get4BytesNC ld a,(header+1) cp 92h jr z,$F call ReceiveHeaderPacket jr ReceiveOSPage $$: ;TODO: Patch the received TI-OS to not erase sector 70h (where we will be backed up) call PatchSector70hCode ;TODO: Put the [X,T,theta,N] boot loader in page 0 (currently in the extra RAM pages) ;Get the address at 0054h on page 0 and save it to 3FFEh di ld a,84h out (memPageBPort),a ld hl,(0054h+8000h) ld (3FFEh+8000h),hl ;Find the jump to the boot code and modify it to be appropriate for the model ld hl,8000h push hl pop ix findBootCodeJumpLoop: ld l,(ix+0) ld h,(ix+1) ld de,80D5h call cphlde jr z,$F ld de,812Ch jr z,$F inc ix push ix pop bc bit 6,b jr z,findBootCodeJumpLoop jr skipBootCodeJump $$: ld de,812Ch call NZIf84PlusSeries jr nz,$F ld de,80D5h $$: ld (ix+0),e ld (ix+1),d skipBootCodeJump: ;Find the page 0 routine for this OS ld a,7Bh out (memPageBPort),a ld hl,(44F2h+4000h) ;Add six bytes to 3FF8h: ; call [Page 0 routine] ; DW CheckForBootLoader+4000h ; DB 70h ld a,84h out (memPageBPort),a ld a,0CDh ld (3FF8h+8000h),a ld a,l ld (3FF9h+8000h),a ld a,h ld (3FFAh+8000h),a ld hl,CheckForBootLoader+4000h ld a,l ld (3FFBh+8000h),a ld a,h ld (3FFCh+8000h),a ld a,70h ld (3FFDh+8000h),a ;Modify 0053h to contain: ; call 3FF8h ld a,0CDh ld (0053h+8000h),a ld a,0F8h ld (0054h+8000h),a ld a,3Fh ld (0055h+8000h),a ld a,81h out (memPageBPort),a ;Copy the extra RAM pages to sector 70h B_CALL UnlockFlash ld a,04h ld b,70h ld c,4 $$: push af push bc call CopyRAMToFlashPage pop bc pop af inc a inc b dec c jr nz,$B ;Mark the OS as valid ld a,70h ld b,5Ah ld de,4056h B_CALL WriteAByte ld hl,0 ld (curRow),hl ld a,70h out (7),a ld hl,(8000h) ld a,81h out (7),a ; call DispHexHL ; ld a,'Y' ; call PutC res indicOnly,(iy+indicFlags) ; B_CALL GetKey call SendAcknowledge ;Couldn't hurt to try to send another acknowledge, because TI Connect sucks ld hl,tryAckAgainHandler call APP_PUSH_ERRORH call SendAcknowledge call APP_POP_ERRORH tryAckAgainHandler: call APP_POP_ERRORH ;Seems like the most sensible thing to do after receiving the TI-OS is just shut off receiveTIOSHandler: jr keyscnlnkEnd ReceiveNewOS: ;Start the process of receiving the OS to replace this one call EnableLinkAssist ld a,0FFh ld (appSearchPage),a xor a ld (ramCodeEnd),a ld (83A4h),a ;I'm not entirely sure what this is yet, but let's zero it out to be safe. B_CALL MD5Init B_CALL ReceiveOS ;We never return from this PatchSector70hCode: B_CALL UnlockFlash ld hl,findPatternStart ld de,appBackUpScreen ld bc,findPatternEnd-findPatternStart ldir $$: ld a,6Bh ld de,4000h call DoTranslatePage ld ix,searchPattern1-findPatternStart+appBackUpScreen call appBackUpScreen jr nz,$F ld hl,appData push hl ld bc,5 B_CALL MemClear pop hl ld a,(iMathPtr4) ld de,(saveSScreen) ld bc,5 B_CALL WriteFlash jr $B $$: ld a,6Bh call DoTranslatePage ld ix,searchPattern2-findPatternStart+appBackUpScreen ld de,4000h call appBackUpScreen ret nz ld hl,appData push hl ld bc,9 B_CALL MemClear pop hl ld a,(iMathPtr4) ld de,(saveSScreen) ld bc,9 B_CALL WriteFlash jr $B findPatternStart: ;Find pattern in IX, Flash page in A, starting address in DE ;Returns NZ if pattern not found ;(savesscreen) 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-findPatternStart+appBackUpScreen push hl ld a,(iMathPtr4) out (6),a dec de searchLoopRestart: inc de ld (saveSScreen),de push ix pop hl searchLoop: ld b,(hl) ld a,b or a ret z inc de inc a jr z,$F dec de ld a,(de) inc de bit 7,d ret nz cp b jr z,$F ld de,(saveSScreen) jr searchLoopRestart $$: inc hl jr searchLoop findPatternRet: pop bc ld a,b out (6),a ret searchPattern1: DB 3Eh,70h,0EFh,84h,80h,0 searchPattern2: ld c,70h ld b,4 DB 0CDh,0 findPatternEnd: DoTranslatePage: push bc ld b,a in a,(2) and 80h jr z,$F in a,(21h) and 3 ld a,b pop bc ret nz and 3Fh ret $$: ld a,b and 1Fh pop bc ret sendInfoPacket: call SendAcknowledge call Get4BytesNC cp 09h jr nz,JErrorNo call SendAcknowledge ld hl,ioData ld (hl),2 ;OS2_VERSION_MAJOR inc hl ld (hl),22h ;OS2_VERSION_MINOR inc hl B_CALL GetBootVer ld (hl),a inc hl ld (hl),b inc hl ;Always return good battery status for now. ld (hl),2 inc hl B_CALL GetHWVer ld (hl),a inc hl ld de,(localLanguage) ld (hl),e inc hl ld (hl),d inc hl ld (hl),0 inc hl ld (hl),0 inc hl ld (hl),0 ld a,15h ld hl,11 call SendCommandA jr keyscnlnkEnd