;NavNet high-level requests include "ti83plus.inc" include "equates.inc" include "usb8x.inc" include "settings.inc" SEGMENT Main GLOBALS ON PUBLIC NavNetRequestDeviceInfo,NavNetEchoData,NavNetGetFile,NavNetPutFile EXTERN SendNavNetPacket,RequestInputData,IsEventReceived,DispHexB,DispHexHL,DispHexA,IGetKey EXTERN ProcessNavNetEvents,ThrowNavNetError,SendServiceDisconnect,myLoadCIndPaged,DoLog2 NavNetRequestDeviceInfo: ;Requests information about the connected TI-Nspire/CAS. ;Inputs: A: information type: ; 01h: serial number, free memory, and other information ; 02h: device name ; 03h: list of supported file extensions ; HL => buffer to store information ;Outputs: Buffer filled with structure: ; When A=01h: ; S+0: 8 bytes : free Flash ROM memory in bytes ; S+8: 8 bytes : physical Flash ROM memory in bytes ; S+16: 8 bytes : free RAM memory in bytes ; S+24: 8 bytes : physical RAM memory in bytes ; S+32: 1 byte : battery level; FF=unknown, 00=powered, 01=low, 7F=good ; S+33: 2 bytes : 00 if not charging, 01 if charging ; S+35: 1 byte : clock speed in MHz ; S+36: 4 bytes : product version (X.Y.ZZZZ) as XX YY ZZ ZZ ; S+40: 4 bytes : boot1 version (same as above) ; S+44: 4 bytes : boot2 version (same as above) ; S+48: 4 bytes : hardware version (TI-Nspire=00, TI-Nspire CAS=01) ; S+52: 2 bytes : 00 02 if running OS, 00 01 if in boot code (recovery mode) ; S+54: 2 bytes : LCD x ; S+56: 2 bytes : LCD y ; S+58: 2 bytes : LCD width ; S+60: 2 bytes : LCD height ; S+62: 1 byte : 04 (4 bits per pixel) ; S+63: 1 byte : sample model (00 which means packed) ; S+64: 1 byte : device (TI-Nspire=1E, TI-Nspire CAS=0E) ; S+65: 17 bytes: electronic ID as null-terminated string (first two and last 8 digits missing) ; S+82: 27 bytes: full electronic ID as null-terminated string ; When A=02h: ; Null-terminated device name (ex. "TI-Nspire") ; When A=03h: ; List of null-terminated extensions (ex. ".tns", ".tno") ld ix,(NavNetMemPtr) ld (ix+offDataOutAddr),l ld (ix+offDataOutAddr+1),h ;First, send the NavNet request for this ld l,(ix+offServiceID) ld h,(ix+offServiceID+1) ld de,4020h ld b,0 ld ix,OP1 ld (ix+0),a ld c,1 call SendNavNetPacket jr nc,$F ld a,errDeviceInfoRequest jr ThrowNavNetError $$: push af call IncrementSequenceNumber pop af ;A is the sequence ID we're waiting on ld l,a ld h,evDeviceInfoReceived WaitForEventHL: $$: in a,(4) bit 3,a ld a,errBreakWaitEvent jr z,ThrowNavNetError ei halt push hl call ProcessNavNetEvents call IsEventReceived pop hl jr c,$B xor a ret NavNetGetScreenshot: ;Gets a screenshot from the connected TI-Nspire/CAS. ;Inputs: HL => buffer to store information ;Outputs: Event evScreenshotReceived will be raised through callback when data is available ;NOTE: This just plain does not work (at least on OS 1.1). Don't use it. ld ix,(NavNetMemPtr) ld (ix+offDataOutAddr),l ld (ix+offDataOutAddr+1),h ;First, send the NavNet request for this ld l,(ix+offServiceID) ld h,(ix+offServiceID+1) ld de,4024h ld b,0 ld ix,OP1 ld (ix+0),00h ld c,1 call SendNavNetPacket ld a,errGetScreenshotRequest jr c,ThrowNavNetError push af call IncrementSequenceNumber pop af ;A is the sequence ID we're waiting on xor a ret NavNetEchoData: ;Echoes data to the connected TI-Nspire/CAS. ;Inputs: HL => buffer of data to echo ; C: length of data to echo ;Outputs: None ld ix,(NavNetMemPtr) ld (ix+offDataOutAddr),l ld (ix+offDataOutAddr+1),h ;First, send the NavNet request for this push hl ld l,(ix+offServiceID) ld h,(ix+offServiceID+1) ld de,4002h ld b,0 pop ix call SendNavNetPacket ld a,errEchoDataRequest jr c,ThrowNavNetError push af call IncrementSequenceNumber pop af ;A is the sequence ID we're waiting on ld l,a ld h,evEchoReceived jr WaitForEventHL NavNetGetDirectoryListing: ;Gets a directory listing from the connected TI-Nspire/CAS. ;Inputs: HL => zero-terminated string of directory to list ; DE => buffer to fill with data ;Outputs: Buffer filled with following structure: ; wNumEntries : 2 bytes: number of entries in this directory ; asciizEntries: N bytes: list of zero-terminated names ld (iy+navNetRequestFlags),0 ld ix,(NavNetMemPtr) ex de,hl ld (hl),0 inc hl ld (hl),0 inc hl ld (hl),0 dec hl dec hl ex de,hl ld (ix+offDataOutAddr),e ld (ix+offDataOutAddr+1),d push de push hl ld bc,offPacketBuffer+16+1 add ix,bc push ix pop hl ld d,h ld e,l ld (hl),0 inc de ld bc,10-1 ldir pop hl pop de ;First, send the NavNet request for this ld ix,(NavNetMemPtr) ld d,h ld e,l $$: ld a,(hl) or a inc hl jr nz,$B or a sbc hl,de ld bc,9 or a sbc hl,bc push af add hl,bc pop af jr z,nineChars jr nc,$F nineChars: ld hl,9 $$: ld b,h ld c,l ex de,hl ;BC is the size ;HL is the data ld de,offPacketBuffer+16+1 add ix,de ld (ix-1),0Dh push ix pop de $$: ld a,(hl) ld (de),a inc hl inc de or a jr nz,$B ld b,0 inc c push bc pop hl ld ix,(NavNetMemPtr) ld l,(ix+offServiceID) ld h,(ix+offServiceID+1) ld de,offPacketBuffer+16 add ix,de ld de,4060h set receivingDirectory,(iy+navNetRequestFlags) res fileRequestComplete,(iy+navNetRequestFlags) call SendNavNetPacket jr nc,$F ld a,errDirectoryListingRequest jr ThrowNavNetError $$: push af call IncrementSequenceNumber pop af ;A is the sequence ID we're waiting on ld l,a ld h,evFileRequestReceived call WaitForEventHL ld a,errDirectoryListingRequest jr c,ThrowNavNetError directoryEntryLoop: bit fileRequestComplete,(iy+navNetRequestFlags) jr nz,directoryEntryLoopDone ld ix,(NavNetMemPtr) ld l,(ix+offServiceID) ld h,(ix+offServiceID+1) ld de,4060h ld bc,1 ld ix,OP1 ld (ix+0),0Eh call SendNavNetPacket jr nc,$F ld a,errDirectoryEntryRequest jr ThrowNavNetError $$: push af call IncrementSequenceNumber pop af ;A is the sequence ID we're waiting on ld l,a ld h,evFileRequestReceived call WaitForEventHL ld a,errDirectoryEntryRequest jr c,ThrowNavNetError jr directoryEntryLoop directoryEntryLoopDone: ;Send DirEnumDone ld ix,(NavNetMemPtr) ld l,(ix+offServiceID) ld h,(ix+offServiceID+1) ld de,4060h ld bc,1 ld ix,OP1 ld (ix+0),0Fh call SendNavNetPacket jr nc,$F ld a,errDirectoryListingDoneRequest jr ThrowNavNetError $$: push af call IncrementSequenceNumber pop af ;A is the sequence ID we're waiting on ld l,a ld h,evFileRequestReceived call WaitForEventHL ld a,errDirectoryListingDoneRequest jr c,ThrowNavNetError res receivingDirectory,(iy+navNetRequestFlags) res fileRequestComplete,(iy+navNetRequestFlags) xor a ret NavNetGetFileFolderInfo: ;Gets attributes/information about a specified file/directory from the connected TI-Nspire/CAS. ;Inputs: HL => zero-terminated string of full path to file/directory ; DE => buffer to fill with data ;Outputs: Returns Z if file/directory found ; Buffer filled with following structure: ; dSize: 4 bytes: size in bytes (0 for directory) ; dDate: 4 bytes: file date (not exactly sure what this is, might be last modified) ; bType: 1 byte : 0 if file, 1 if directory ; bFlag: 1 byte : unknown, always 0 ld (iy+navNetRequestFlags),0 ld ix,(NavNetMemPtr) ld (ix+offDataOutAddr),e ld (ix+offDataOutAddr+1),d ld (ix+offErrorCode),0 push de push hl ld bc,offPacketBuffer+16+1 add ix,bc push ix pop hl ld d,h ld e,l ld (hl),0 inc de ld bc,10-1 ldir pop hl pop de ;First, send the NavNet request for this ld ix,(NavNetMemPtr) ld d,h ld e,l $$: ld a,(hl) or a inc hl jr nz,$B or a sbc hl,de ld bc,9 or a sbc hl,bc push af add hl,bc pop af jr z,gffiNineChars jr nc,$F gffiNineChars: ld hl,9 $$: ld b,h ld c,l ex de,hl ;BC is the size ;HL is the data ld de,offPacketBuffer+16+2 add ix,de ld (ix-2),20h ld (ix-1),01h push ix pop de $$: ld a,(hl) ld (de),a inc hl inc de or a jr nz,$B ld b,0 inc c inc c push bc pop hl ld ix,(NavNetMemPtr) ld l,(ix+offServiceID) ld h,(ix+offServiceID+1) ld de,offPacketBuffer+16 add ix,de ld de,4060h set receivingAttributes,(iy+navNetRequestFlags) set fileRequestComplete,(iy+navNetRequestFlags) call SendNavNetPacket jr nc,$F ld a,errFileAttributeRequest jr ThrowNavNetError $$: push af call IncrementSequenceNumber pop af ;A is the sequence ID we're waiting on ld l,a ld h,evFileRequestReceived call WaitForEventHL ld a,errDirectoryListingRequest jr c,ThrowNavNetError ld ix,(NavNetMemPtr) ld a,(ix+offErrorCode) or a ret NavNetDeleteFile: ;Deletes the specified file from the connected TI-Nspire/CAS. ;Inputs: HL => zero-terminated string of full path to file ;Outputs: Returns carry flag set if problems ld (iy+navNetRequestFlags),0 ld ix,(NavNetMemPtr) push de push hl ld bc,offPacketBuffer+16+1 add ix,bc push ix pop hl ld d,h ld e,l ld (hl),0 inc de ld bc,10-1 ldir pop hl pop de ;First, send the NavNet request for this ld ix,(NavNetMemPtr) ld d,h ld e,l $$: ld a,(hl) or a inc hl jr nz,$B or a sbc hl,de ld bc,9 or a sbc hl,bc push af add hl,bc pop af jr z,dfNineChars jr nc,$F dfNineChars: ld hl,9 $$: ld b,h ld c,l ex de,hl ;BC is the size ;HL is the data ld de,offPacketBuffer+16+2 add ix,de ld (ix-2),09h ld (ix-1),01h push ix pop de $$: ld a,(hl) ld (de),a inc hl inc de or a jr nz,$B ld b,0 inc c inc c push bc pop hl ld ix,(NavNetMemPtr) ld l,(ix+offServiceID) ld h,(ix+offServiceID+1) ld de,offPacketBuffer+16 add ix,de ld de,4060h set fileRequestComplete,(iy+navNetRequestFlags) call SendNavNetPacket jr nc,$F ld a,errFileAttributeRequest jr ThrowNavNetError $$: push af call IncrementSequenceNumber pop af ;A is the sequence ID we're waiting on ld l,a ld h,evFileRequestReceived call WaitForEventHL ld a,errDeleteFileRequest jr c,ThrowNavNetError xor a ret NavNetDeleteDirectory: ;Deletes the specified directory from the connected TI-Nspire/CAS. ;Inputs: HL => zero-terminated string of full path to directory ;Outputs: Returns carry flag set if problems ld (iy+navNetRequestFlags),0 ld ix,(NavNetMemPtr) push de push hl ld bc,offPacketBuffer+16+1 add ix,bc push ix pop hl ld d,h ld e,l ld (hl),0 inc de ld bc,10-1 ldir pop hl pop de ;First, send the NavNet request for this ld ix,(NavNetMemPtr) ld d,h ld e,l $$: ld a,(hl) or a inc hl jr nz,$B or a sbc hl,de ld bc,9 or a sbc hl,bc push af add hl,bc pop af jr z,ddNineChars jr nc,$F ddNineChars: ld hl,9 $$: ld b,h ld c,l ex de,hl ;BC is the size ;HL is the data ld de,offPacketBuffer+16+2 add ix,de ld (ix-2),0Bh ld (ix-1),03h push ix pop de $$: ld a,(hl) ld (de),a inc hl inc de or a jr nz,$B ld b,0 inc c inc c push bc pop hl ld ix,(NavNetMemPtr) ld l,(ix+offServiceID) ld h,(ix+offServiceID+1) ld de,offPacketBuffer+16 add ix,de ld de,4060h set fileRequestComplete,(iy+navNetRequestFlags) call SendNavNetPacket jr nc,$F ld a,errFileAttributeRequest jr ThrowNavNetError $$: push af call IncrementSequenceNumber pop af ;A is the sequence ID we're waiting on ld l,a ld h,evFileRequestReceived call WaitForEventHL ld a,errDirectoryDeleteRequest jr c,ThrowNavNetError xor a ret NavNetCreateDirectory: ;Creates the specified directory on the connected TI-Nspire/CAS. ;Inputs: HL => zero-terminated string of full path to directory ;Outputs: Returns carry flag set if problems ld (iy+navNetRequestFlags),0 ld ix,(NavNetMemPtr) push de push hl ld bc,offPacketBuffer+16+1 add ix,bc push ix pop hl ld d,h ld e,l ld (hl),0 inc de ld bc,10-1 ldir pop hl pop de ;First, send the NavNet request for this ld ix,(NavNetMemPtr) ld d,h ld e,l $$: ld a,(hl) or a inc hl jr nz,$B or a sbc hl,de ld bc,9 or a sbc hl,bc push af add hl,bc pop af jr z,cdNineChars jr nc,$F cdNineChars: ld hl,9 $$: ld b,h ld c,l ex de,hl ;BC is the size ;HL is the data ld de,offPacketBuffer+16+2 add ix,de ld (ix-2),0Ah ld (ix-1),03h push ix pop de $$: ld a,(hl) ld (de),a inc hl inc de or a jr nz,$B ld b,0 inc c inc c push bc pop hl ld ix,(NavNetMemPtr) ld l,(ix+offServiceID) ld h,(ix+offServiceID+1) ld de,offPacketBuffer+16 add ix,de ld de,4060h set fileRequestComplete,(iy+navNetRequestFlags) call SendNavNetPacket jr nc,$F ld a,errFileAttributeRequest jr ThrowNavNetError $$: push af call IncrementSequenceNumber pop af ;A is the sequence ID we're waiting on ld l,a ld h,evFileRequestReceived call WaitForEventHL ld a,errCreateDirectoryRequest jr c,ThrowNavNetError xor a ret NavNetGetFile: ;Gets the specified file from the connected TI-Nspire/CAS and stores it in RAM/Flash. ;Inputs: HL => zero-terminated string of full path to directory ; DE: size of file's data ; B: 0 to store in RAM, 1 for Flash ROM ; OP1: OS-style name of AppVar to store file in ;Outputs: Returns carry flag set if problems ld (iy+navNetRequestFlags),0 push hl ld a,b or a jr nz,$F ;We're storing in RAM, so just create the AppVar and save the pointers ex de,hl inc hl inc hl B_CALL CreateAppVar pop hl ld a,errOutOfMemory jr c,ThrowNavNetError inc de inc de ex de,hl ld (hl),32h inc hl ld (hl),35h inc hl ld ix,(NavNetMemPtr) ld (ix+offDataOutAddr),l ld (ix+offDataOutAddr+1),h jr nngfStart1 $$: ;We're storing in Flash, so set up Write-to-Flash inc de inc de ld (arcInfo+9),de ld ix,(NavNetMemPtr) ld (ix+offDataOutAddr),0 ld (ix+offDataOutAddr+1),0 ;Create dummy AppVar ld hl,0 B_CALL CreateAppVar pop bc ld a,errOutOfMemory jr c,ThrowNavNetError push bc push hl ;Delete the two size bytes ex de,hl ld de,2 B_CALL DelMem B_CALL OP4ToOP1 pop hl ld a,2 B_CALL WriteToFlash ld hl,arcInfo+9 ld bc,2 ld a,3 B_CALL WriteToFlash ld hl,OP1 ld (hl),32h inc hl ld (hl),35h dec hl ld bc,2 ld a,3 B_CALL WriteToFlash nngfStart: pop hl nngfStart1: ld ix,(NavNetMemPtr) push de push hl ld bc,offPacketBuffer+16+2 add ix,bc push ix pop hl ld d,h ld e,l ld (hl),0 inc de ld bc,10-1 ldir pop hl pop de ;First, send the NavNet request for this ld ix,(NavNetMemPtr) ld d,h ld e,l $$: ld a,(hl) or a inc hl jr nz,$B or a sbc hl,de ld bc,9 or a sbc hl,bc push af add hl,bc pop af jr z,gfNineChars jr nc,$F gfNineChars: ld hl,9 $$: ld b,h ld c,l ex de,hl ;BC is the size ;HL is the data ld de,offPacketBuffer+16+2 add ix,de ld (ix-2),07h ld (ix-1),01h push ix pop de $$: ld a,(hl) ld (de),a inc hl inc de or a jr nz,$B ld b,0 inc c inc c ld ix,(NavNetMemPtr) ld l,(ix+offServiceID) ld h,(ix+offServiceID+1) ld de,offPacketBuffer+16 add ix,de ld de,4060h set receivingFile,(iy+navNetRequestFlags) call SendNavNetPacket jr nc,$F ld a,errGetFileRequest jr ThrowNavNetError $$: push af call IncrementSequenceNumber pop af ;A is the sequence ID we're waiting on ld l,a ld h,evFileRequestReceived call WaitForEventHL ld a,errGetFileRequest jr c,ThrowNavNetError ;Send continue ld ix,(NavNetMemPtr) ld l,(ix+offServiceID) ld h,(ix+offServiceID+1) ld de,4060h ld bc,1 ld ix,OP1 ld (ix+0),04h call SendNavNetPacket ld a,errGetFileOKRequest jr c,ThrowNavNetError call IncrementSequenceNumber ;Wait on file to finish receiving $$: bit fileRequestComplete,(iy+navNetRequestFlags) jr nz,$F ei halt call ProcessNavNetEvents jr $B $$: ;Send FF 00 acknowledgement call IncrementSequenceNumber ld ix,(NavNetMemPtr) ld l,(ix+offServiceID) ld h,(ix+offServiceID+1) ld de,4060h ld bc,2 ld ix,OP1 ld (ix+0),0FFh ld (ix+1),00h call SendNavNetPacket jr nc,$F ld a,errGetFileDoneRequest jr ThrowNavNetError $$: call IncrementSequenceNumber call SendServiceDisconnect call IncrementSequenceNumber ld ix,(NavNetMemPtr) ld l,(ix+offDataOutAddr) ld a,(ix+offDataOutAddr+1) or l jr z,$F ;We were writing to RAM, so there's nothing left to do xor a ret $$: ;We were writing to Flash, so flush our write cache and move on ld a,4 B_CALL WriteToFlash ld a,5 ld hl,OP1 B_CALL WriteToFlash xor a ret NavNetPutFile: ;Writes the specified file to the connected TI-Nspire/CAS. ;Inputs: DE => zero-terminated string of full path to file name ; B: 0 if data in RAM, otherwise Flash ROM page ; HL => pointer to file data ; IX: size bytes ;Outputs: Writes new file and data to device ; Returns carry flag set if problems push ix ld (iy+navNetRequestFlags),0 res sendServiceDisconnect,(iy+nspire8xFlags) ;Save the data pointers ld ix,(NavNetMemPtr) ld (ix+offDataOutPage),b ld (ix+offDataOutAddr),l ld (ix+offDataOutAddr+1),h ;Zero out our name buffer in case it's less than 9 bytes push de ld bc,offPacketBuffer+16+2 add ix,bc push ix pop hl ld d,h ld e,l ld (hl),0 inc de ld bc,10-1 ldir pop hl ;First, send the NavNet request for this ld ix,(NavNetMemPtr) ld d,h ld e,l $$: ld a,(hl) or a inc hl jr nz,$B or a sbc hl,de ld bc,9 or a sbc hl,bc push af add hl,bc pop af jr z,pfNineChars jr nc,$F pfNineChars: ld hl,9 $$: ld b,h ld c,l ex de,hl ;BC is the size ;HL is the data ld de,offPacketBuffer+16+2 add ix,de ld (ix-2),03h ld (ix-1),01h push ix pop de $$: ld a,(hl) ld (de),a inc hl inc de or a jr nz,$B ld b,0 inc c inc c ;File size bytes inc c inc c inc c inc c ;Write the file size bytes ex de,hl pop de ld (hl),0 inc hl ld (hl),0 inc hl ld (hl),d inc hl ld (hl),e ld ix,(NavNetMemPtr) ld (ix+offFileBytesRemaining),e ld (ix+offFileBytesRemaining+1),d ld l,(ix+offServiceID) ld h,(ix+offServiceID+1) ld de,offPacketBuffer+16 add ix,de ld de,4060h set sendingFile,(iy+navNetRequestFlags) call SendNavNetPacket jr nc,$F ld a,errSendFileRequest jr ThrowNavNetError $$: push af call IncrementSequenceNumber pop af ;A is the sequence ID we're waiting on ld l,a ld h,evFileRequestReceived call WaitForEventHL ld a,errSendFileRequest jr c,ThrowNavNetError ;Check to see if the device refused the file, and if so, abort ld ix,(NavNetMemPtr) ld a,(ix+offErrorCode) or a jr nz,pfThrowNavNetError ;Send the file contents, if there are any ld l,(ix+offFileBytesRemaining) ld h,(ix+offFileBytesRemaining+1) pfSendDataLoop: ld a,h or l jr z,pfSendDataLoopDone ;Determine how much to send ld bc,253 or a sbc hl,bc jr nc,$F add hl,bc ld b,h ld c,l ld hl,0 $$: ;BC is the number of bytes to send push hl push bc ld hl,(NavNetMemPtr) ld de,offPacketBuffer+16 add hl,de push hl ld (hl),05h inc hl ex de,hl ;Get BC bytes of file data to DE ld ix,(NavNetMemPtr) ld l,(ix+offDataOutAddr) ld h,(ix+offDataOutAddr+1) ld a,(ix+offDataOutPage) or a jr nz,$F ;This is RAM data, just copy it ldir ld (ix+offDataOutAddr),l ld (ix+offDataOutAddr+1),h jr pfSendData $$: ;This is Flash data ld b,a pfGetDataLoop: push bc push ix call myLoadCIndPaged pop ix ld a,c ld (de),a inc de ld a,b pop bc ld b,a dec c jr nz,pfGetDataLoop ld (ix+offDataOutAddr),l ld (ix+offDataOutAddr+1),h ld (ix+offDataOutPage),b pfSendData: ;Send a data packet of BC data bytes ld ix,(NavNetMemPtr) ld l,(ix+offServiceID) ld h,(ix+offServiceID+1) ld de,4060h pop ix pop bc inc bc call SendNavNetPacket jr nc,$F ld a,errSendFileData jr ThrowNavNetError $$: call IncrementSequenceNumber ei halt call ProcessNavNetEvents pop hl jr pfSendDataLoop pfSendDataLoopDone: set fileRequestComplete,(iy+navNetRequestFlags) res sendServiceDisconnect,(iy+nspire8xFlags) ;Receive acknowledgement ld h,evFileRequestReceived call WaitForEventHL xor a jr $F pfThrowNavNetError: scf $$: push af ;Disconnect from file management service ; call SendServiceDisconnect ; call IncrementSequenceNumber pop af ret NavNetCopyFile: ;Copies a file from one directory to another on the connected TI-Nspire/CAS device. ;Inputs: HL => path to source file ; DE => path to destination file (can have a different file name) ;Outputs: File copied from source to destination path ; Returns carry flag set if problems call PrepareCopyRenamePacket ;Build the packet and send it off ld ix,(NavNetMemPtr) ld l,(ix+offServiceID) ld h,(ix+offServiceID+1) ld ix,(NavNetMemPtr) ld de,offPacketBuffer+16 add ix,de ld (ix+0),0Ch ld (ix+1),01h ld de,4060h set fileRequestComplete,(iy+navNetRequestFlags) res sendServiceDisconnect,(iy+nspire8xFlags) call SendNavNetPacket jr nc,$F ld a,errCopyFile jr ThrowNavNetError $$: push af call IncrementSequenceNumber pop af ;A is the sequence ID we're waiting on ld l,a ld h,evFileRequestReceived call WaitForEventHL ld a,errCopyFileRequest jr c,ThrowNavNetError ; call SendServiceDisconnect ; call IncrementSequenceNumber xor a ret NavNetRenameFile: ;Renames a file on the connected TI-Nspire/CAS device. ;Inputs: HL => old file name ; DE => new file name ;Outputs: File renamed ; Returns carry flag set if problems call PrepareCopyRenamePacket ;Build the packet and send it off ld ix,(NavNetMemPtr) ld l,(ix+offServiceID) ld h,(ix+offServiceID+1) ld ix,(NavNetMemPtr) ld de,offPacketBuffer+16 add ix,de ld (ix+0),21h ld (ix+1),01h ld de,4060h set fileRequestComplete,(iy+navNetRequestFlags) res sendServiceDisconnect,(iy+nspire8xFlags) call SendNavNetPacket jr nc,$F ld a,errCopyFile jr ThrowNavNetError $$: push af call IncrementSequenceNumber pop af ;A is the sequence ID we're waiting on ld l,a ld h,evFileRequestReceived call WaitForEventHL ld a,errRenameFileRequest jr c,ThrowNavNetError ; call SendServiceDisconnect ; call IncrementSequenceNumber xor a ret PrepareCopyRenamePacket: ;Clear packet buffer push de push hl ld hl,(NavNetMemPtr) ld de,offPacketBuffer+16+2 add hl,de push hl ld d,h ld e,l inc de ld (hl),0 ld bc,270-1-16-2 ldir pop de pop hl ;Copy HL path to DE call CopyHLPathToDE pop hl ;Copy HL path to DE call CopyHLPathToDE ;Figure out the length of this packet ld hl,(NavNetMemPtr) ld bc,offPacketBuffer+16 add hl,bc ex de,hl or a sbc hl,de ld b,h ld c,l ret CopyHLPathToDE: ;Copies the path pointed to by HL to DE (taking into account minimum length of 9 bytes) ;Make sure memory is zeroed out beforehand ;Get the minimum address for the end of this path to BC push hl ld h,d ld l,e ld bc,9 add hl,bc ld b,h ld c,l pop hl ;Copy the string $$: ld a,(hl) ld (de),a inc hl inc de or a jr nz,$B ;If we're not at BC, put DE there instead ld h,d ld l,e or a sbc hl,bc ret nc ld d,b ld e,c ret NavNetInstallOS: ;Installs an OS on the connected TI-Nspire/CAS device. ;Inputs: DEHL: size of OS ; BC => callback routine for caching OS data to send ;Outputs: Returns carry flag set if problems ;Notes: The callback routine passes destination in HL, and number of bytes in BC. ; It's up to you to keep track of where you are in the OS data, and to fill ; the buffer at HL with BC bytes, and advance your own pointer to the OS data ; by that much. ; Return Z to continue OS transfer, or NZ to abort. ld (iy+navNetRequestFlags),0 ld ix,(NavNetMemPtr) ld (ix+offFileBytesRemaining),l ld (ix+offFileBytesRemaining+1),h ld (ix+offFileBytesRemaining+2),e ld (ix+offFileBytesRemaining+3),d ld (ix+offDataOutAddr),c ld (ix+offDataOutAddr+1),b ld b,h ld c,l ld l,(ix+offServiceID) ld h,(ix+offServiceID+1) push hl ld ix,(NavNetMemPtr) push de ld de,offPacketBuffer+16 add ix,de pop de ld (ix+0),03h ld (ix+1),d ld (ix+2),e ld (ix+3),b ld (ix+4),c ld de,4080h pop hl ld bc,5 set installingOS,(iy+navNetRequestFlags) call SendNavNetPacket jr nc,$F ld a,errCopyFile jr ThrowNavNetError $$: push af call IncrementSequenceNumber pop af ;A is the sequence ID we're waiting on ld l,a ld h,evOSRequestReceived call WaitForEventHL ld a,errInstallOSRequest jr c,ThrowNavNetError ;Keep sending OS data in 253-byte chunks until we're done sendOSLoop: ld ix,(NavNetMemPtr) ld l,(ix+offFileBytesRemaining) ld h,(ix+offFileBytesRemaining+1) ld e,(ix+offFileBytesRemaining+2) ld d,(ix+offFileBytesRemaining+3) ld a,l or h or e or d jr z,sendOSLoopDone ;Decrease our remaining count by 253 (or less) and store it ld bc,253 ld a,e or d jr nz,$F ;more than 65535 bytes, we definitely have 253 bytes left to send push hl or a sbc hl,bc pop hl jr nc,$F ;didn't carry when subtracting 253 bytes, so send that ;Otherwise we just need to send what's in HL ld b,h ld c,l $$: ;BC is now what we need to send ;Subtract it from our count and store it or a sbc hl,bc jr nc,$F dec de $$: ld (ix+offFileBytesRemaining),l ld (ix+offFileBytesRemaining+1),h ld (ix+offFileBytesRemaining+2),e ld (ix+offFileBytesRemaining+3),d ;Call the callback routine to get our data ld de,offPacketBuffer+16 add ix,de push ix pop hl ld (hl),05h inc hl ld ix,(NavNetMemPtr) ld e,(ix+offDataOutAddr) ld d,(ix+offDataOutAddr+1) push de pop ix push bc ld de,$F push de jp (ix) $$: ;Send the NavNet packet of OS data pop bc ret nz ld ix,(NavNetMemPtr) ld l,(ix+offServiceID) ld h,(ix+offServiceID+1) ld ix,(NavNetMemPtr) ld de,offPacketBuffer+16 add ix,de ld de,4080h ld b,0 inc c call SendNavNetPacket jr nc,$F ld a,errSendOSPacket jr ThrowNavNetError $$: push af call IncrementSequenceNumber pop af ;A is the sequence ID we're waiting on ld l,a ld h,evOSRequestReceived call WaitForEventHL ld a,errInstallOSRequest jr c,ThrowNavNetError ei halt call ProcessNavNetEvents jr sendOSLoop sendOSLoopDone: ld de,4080h call SendServiceDisconnect call IncrementSequenceNumber xor a ret IncrementSequenceNumber: ld ix,(NavNetMemPtr) ld a,(ix+offSequenceNumber) inc a or a jr nz,$F inc a ;Don't allow sequence ID 0 $$: ld (ix+offSequenceNumber),a ret