Well, its been a few days and I didnt want my loyal readers to think I was sleeping on the job

So here's the actual code used to transmit the Cmd07 packets. I've commented a good bit of it.
Code: Select all
seg000:0000D56E ; ??????????????? S U B R O U T I N E ???????????????????????????????????????
seg000:0000D56E
seg000:0000D56E ; Upon entry D specifies the packet sequence number.
seg000:0000D56E ; the sequence number also determines the size of the
seg000:0000D56E ; packet as packets 0 and 1 are 0x08 bytes long while
seg000:0000D56E ; all other packets are 0x20 bytes long (plus the
seg000:0000D56E ; 2 bytes for the seq num and subCmd)
seg000:0000D56E
seg000:0000D56E OSMO_SendCmd07: ; CODE XREF: sub_D1A1+221p
seg000:0000D56E ; sub_D1A1+290p
seg000:0000D56E leas -$A,sp
seg000:0000D570 pshd ; save original packet sequence number at call time to var0
seg000:0000D571 jsr OSMO_DetermineCmd07PktLength
seg000:0000D574 std $A,sp ; set varA to packet length for data segment of Cmd07
seg000:0000D576 addd #2 ; add space for sequence number and subcommand ID
seg000:0000D579 std iPacketLength ; save full data field length to variable
seg000:0000D57C ldd ,sp ; store Cmd 07 sequence number to var2
seg000:0000D57E std 2,sp
seg000:0000D580 ldab 3,sp ; get LSB of seq num
seg000:0000D582 stab arrayPacketDataBuffer ; put the value in the first position of the packet's data field
seg000:0000D585 ldd 2,sp
seg000:0000D587 jsr OSMO_Cmd07DetermineSubcommand ; Sets byte 1 of the Cmd 07 data field equal to the following
seg000:0000D587 ; 0 - if seq num = 0x0000
seg000:0000D587 ; 1 - if seq num = 0x0001
seg000:0000D587 ; 2 - if seq num greater than 0x0001
seg000:0000D58A std 2,sp ; var2 set to subcommand ID
seg000:0000D58C ldab 3,sp
seg000:0000D58E stab arrayPacketDataBuffer+1 ; store in packet's data buffer at second position
seg000:0000D591 ldd ,sp
seg000:0000D593 jsr OSMO_CalcFlashImageMemOffset ; Calculates memory displacement for Firmware image
seg000:0000D593 ; based on sequence number
seg000:0000D596 std iFlashImageMemOffset ; store output in RAM variable
seg000:0000D599 ldd ,sp
seg000:0000D59B jsr OSMO_CalcFlashImageParagraph ; Calculates the paragraph number for the current
seg000:0000D59B ; seq num. Paragraphs are 256bytes. Calculation is:
seg000:0000D59B ;
seg000:0000D59B ; paragraph = (seqNum - 2)/256
seg000:0000D59E std iFlashImageParagraph ; store output in RAM variable
seg000:0000D5A1 clrb
seg000:0000D5A2 clra
seg000:0000D5A3 std 2,sp ; clear var2
seg000:0000D5A5
seg000:0000D5A5 loc_D5A5: ; CODE XREF: OSMO_SendCmd07+94j
seg000:0000D5A5 ldd $A,sp
seg000:0000D5A7 ldx #2
seg000:0000D5AA idivs
seg000:0000D5AC ldy 2,sp
seg000:0000D5AE dex
seg000:0000D5AF pshx
seg000:0000D5B0 cpy 2,sp+
seg000:0000D5B2 bhi loc_D604
seg000:0000D5B4 ldd iCmd07FlashAddrAdjustIndex
seg000:0000D5B7 pshd
seg000:0000D5B8 ldd iFlashImageParagraph
seg000:0000D5BB pshd
seg000:0000D5BC ldd iFlashImageMemOffset
seg000:0000D5BF jsr OSMO_GetFirmwareWordFromFlash
seg000:0000D5C2 leas 4,sp ; clean up stack
seg000:0000D5C4 tfr d, y
seg000:0000D5C6 exg a, d
seg000:0000D5C8 std 8,sp
seg000:0000D5CA bsr sub_D60D
seg000:0000D5CC ldab #2
seg000:0000D5CE clra
seg000:0000D5CF addd 4,sp
seg000:0000D5D1 std 6,sp
seg000:0000D5D3 ldab 7,sp
seg000:0000D5D5 ldaa 9,sp
seg000:0000D5D7 ldx #arrayPacketDataBuffer
seg000:0000D5DA staa b,x
seg000:0000D5DC sty 8,sp
seg000:0000D5DE bsr sub_D60D
seg000:0000D5E0 ldab #2
seg000:0000D5E2 clra
seg000:0000D5E3 addd 4,sp
seg000:0000D5E5 addd #1
seg000:0000D5E8 std 6,sp
seg000:0000D5EA ldab 7,sp
seg000:0000D5EC ldaa 9,sp
seg000:0000D5EE staa b,x
seg000:0000D5F0 ldd #iFlashImageMemOffset
seg000:0000D5F3 pshd
seg000:0000D5F4 ldab #2 ; D = 0x0002
seg000:0000D5F6 clra
seg000:0000D5F7 sex a, x ; X = 0x0000
seg000:0000D5F9 jsr sub_C3B8
seg000:0000D5FC pulx
seg000:0000D5FD ldx 2,sp
seg000:0000D5FF inx
seg000:0000D600 stx 2,sp
seg000:0000D602 bra loc_D5A5
seg000:0000D604 ; ---------------------------------------------------------------------------
seg000:0000D604
seg000:0000D604 loc_D604: ; CODE XREF: OSMO_SendCmd07+44j
seg000:0000D604 ldab #7
seg000:0000D606 clra
seg000:0000D607 jsr OSMO_SendCmdPacketToRoomba ; D = PacketID a.k.a Command Number
seg000:0000D607 ; (NOT sequence number)
seg000:0000D60A leas $C,sp
seg000:0000D60C rts
seg000:0000D60C ; End of function OSMO_SendCmd07
seg000:0000D60C
seg000:0000D60D
seg000:0000D60D ; ??????????????? S U B R O U T I N E ???????????????????????????????????????
seg000:0000D60D
seg000:0000D60D
seg000:0000D60D sub_D60D: ; CODE XREF: OSMO_SendCmd07+5Cp
seg000:0000D60D ; OSMO_SendCmd07+70p
seg000:0000D60D ldd 4,sp
seg000:0000D60F std 6,sp
seg000:0000D611 lsl 7,sp
seg000:0000D613 rol 6,sp
seg000:0000D615 rts
seg000:0000D615 ; End of function sub_D60D
seg000:0000D615
seg000:0000C3B8 sub_C3B8: ; CODE XREF: OSMO_SendCmd07+8Bp
seg000:0000C3B8 leas -8,sp
seg000:0000C3BA pshd
seg000:0000C3BB pshx ; STACK:
seg000:0000C3BB ; F iFlashMemoryOffset Addr- MSB
seg000:0000C3BB ; E iFlashMemoryOffset Addr- LSB
seg000:0000C3BB ; D -- return PC (RTS)
seg000:0000C3BB ; C -- return PC (RTS)
seg000:0000C3BB ; B varA - MSB
seg000:0000C3BB ; A varA - LSB
seg000:0000C3BB ; 9 var8 - MSB
seg000:0000C3BB ; 8 var8 - LSB
seg000:0000C3BB ; 7 var6 - MSB
seg000:0000C3BB ; 6 var6 - LSB
seg000:0000C3BB ; 5 var4 - MSB
seg000:0000C3BB ; 4 var4 - LSB
seg000:0000C3BB ; 3 o_D - MSB
seg000:0000C3BB ; 2 o_D - LSB
seg000:0000C3BB ; 1 o_X - MSB
seg000:0000C3BB ; 0 o_X - LSB
seg000:0000C3BC ldx $E,sp ; X = iFlashMemoryOffset
seg000:0000C3BE ldd ,x ; D = iFlashMemoryOffset[0]
seg000:0000C3C0 std 6,sp ; var6 = iFlashMemoryOffset[0]
seg000:0000C3C2 clrb
seg000:0000C3C3 clra ; D = 0
seg000:0000C3C4 std 4,sp ; var4 = 0
seg000:0000C3C6 ldd 2,x ; D = iFlashMemoryOffset[2]
seg000:0000C3C8 jsr OSMO_IsMSbOfASet ; IsMSBofASet: returns 0xFFFF is bit7 of A is set, else
seg000:0000C3C8 ; returns 0x0000 if bit 7 of A is cleared
seg000:0000C3CB ldy #0 ; y = 0
seg000:0000C3CE xgdy ; Y <==> D
seg000:0000C3D0 addd 6,sp ; CF = 0
seg000:0000C3D2 std 6,sp ; var6 = Y = var6
seg000:0000C3D4 xgdy ; ***D back to D, Y back to Y
seg000:0000C3D6 adcb 5,sp
seg000:0000C3D8 adca 4,sp ; D = var4 + iFlashMemoryOffset[2]
seg000:0000C3DA std 4,sp ; var4 = D = var4 + iFlashMemoryOffset[2]
seg000:0000C3DC xgdy ; Y <==> D
seg000:0000C3DE addd 2,sp ; Y = var6 + o_D
seg000:0000C3E0 std $A,sp ; varA = var6 + o_d
seg000:0000C3E0 ; --- CF = 1 IF (MSb(var6) & MSb(o_d)) or
seg000:0000C3E0 ; (MSb(var6) or MSb(o_d)) & !(MSb(result))
seg000:0000C3E2 xgdy ; ***D back to D, Y back to Y
seg000:0000C3E4 adcb 1,sp ; D = D + o_X + CF
seg000:0000C3E6 adca ,sp
seg000:0000C3E8 std 8,sp ; var8 = D = var4 + o_X + CF
seg000:0000C3EA ldx $E,sp ; X = iFlashMemoryOffset
seg000:0000C3EC sty ,x ; iFlashMemoryOffset[0] = varA
seg000:0000C3EE ldd 8,sp ; D = var8
seg000:0000C3F0 std 2,x ; iFlashMemoryOffset[2] = D = var8
seg000:0000C3F2 ldd 8,sp ; D = var8
seg000:0000C3F4 cpd 4,sp ; compare (var8, var4)
seg000:0000C3F6 bcs loc_C402
seg000:0000C3F8 bne loc_C400
seg000:0000C3FA ldd $A,sp
seg000:0000C3FC cpd 6,sp
seg000:0000C3FE bcs loc_C402
seg000:0000C400
seg000:0000C400 loc_C400: ; CODE XREF: sub_C3B8+40j
seg000:0000C400 clrb
seg000:0000C401 skip2
seg000:0000C402
seg000:0000C402 loc_C402: ; CODE XREF: sub_C3B8+3Ej
seg000:0000C402 ; sub_C3B8+46j
seg000:0000C402 ldab #1
seg000:0000C404 clra
seg000:0000C405 leas $C,sp
seg000:0000C407 rts
seg000:0000C407 ; End of function sub_C3B8
As of right now, here is the C code I've produced to figure out what was going on:
Code: Select all
#define MSB(x) (unsigned char)((x >> 8) & 0x00FF)
void OSMO_SendCmd07(unsigned int seqNum)
{
/* translations:
dataLength = varA
seqNum = var0
indexer = var2
*/
unsigned int dataLength, var8, var6, var4, indexer;
// determine the packet length based on subCmd type
dataLength = OSMO_DetermineCmd07PktLength(seqNum)
iPacketLength = dataLength + 2; // add space for additional fields
arrayPacketDataBuffer[0] = iPacketLength;
subCommand = OSMO_Cmd07DetermineSubcommand(seqNum);
iFlashImageMemOffset = OSMO_CalcFlashImageMemOffset(seqNum);
iFlashImageParagraph = OSMO_CalcFlashImageParagraph(seqNum);
indexer = 0;
while (indexer < (dataLength/2) - 1)
{
value = OSMO_GetFirmwareWordFromFlash(iFlashImageMemOffset,
iFlashImageParagraph,
iCmd07FlashAddrAdjustIndex);
// store value into packetBuffer... offset of +2 is used to skip over
// the subCmd and sequence number
pktbuffer[LSB((indexer * 2) + 2)] = MSB(value)
pktbuffer[LSB((indexer * 2) + 3)] = LSB(value)
call sub_c3b8(D=0x0002, X=0x0000, iFlashImageMemOffset)
indexer ++;
}
OSMO_SendCmdPacketToRoomba(0x07);
}
The first part of this looks pretty straightforward.. you figure out how big your packet is going to be... put the pktlength and subcommand fields in place and then you get into the loop where you fill the pktBuffer up. Once you have the packet buffer properly filled, you send the command to the Roomba. Like I said, pretty straight forward stuff.
HOWEVER... the C3B3 function is odd. I can't figure out what exactly it's doing. I've decoded it about 4 times now and somehow I keep mixing up variables or something. This is what is taking me so long get you a proper analysis. Actually, while putting this all together in a post it just dawned on me that they aren't passing the value of iFlashImageMemOffset, but are passing the address of the variable. duh, Greg!
At this point however, we can determine the following about Cmd 07 packets..
* the packets are based on the standard template pattern I described earlier
* the data field of the standard packet model is broken into three subfields: sequence number, subcommand, flash data (in that order)
Anyway, I'm still working on this. Feel free to comment on the code if you like. I would appreciate any help and feedback that you are willing to give.
greg.
PS. I'll post the code for the subroutine that retrieves the byte from memory later. It's messy.. looks pretty in a flowchart, but not pretty in pseudo C. If you want to see the assembly code, here it is...
Code: Select all
seg000:0000C240 OSMO_GetFirmwareWordFromFlash: ; CODE XREF: OSMO_SendCmd07+51p
seg000:0000C240 std 6,-sp ; Pulls a word of the firmware from flash memory and
seg000:0000C240 ; return in D
seg000:0000C242 ldy 8,sp
seg000:0000C244 ldx #0
seg000:0000C247 tfr x, d
seg000:0000C249 pshd
seg000:0000C24A ldd 2,sp
seg000:0000C24C orab 1,sp
seg000:0000C24E oraa ,sp
seg000:0000C250 std 6,sp
seg000:0000C252 sty 4,sp
seg000:0000C254 ldd $C,sp
seg000:0000C256 lsld
seg000:0000C257 lsld
seg000:0000C258 tfr d, y
seg000:0000C25A ldd 6,sp
seg000:0000C25C addd (arrayCmd07CoefficientTable+2),y
seg000:0000C260 std 6,sp
seg000:0000C262 ldd 4,sp
seg000:0000C264 adcb (arrayCmd07CoefficientTable+1),y
seg000:0000C268 adca arrayCmd07CoefficientTable,y
seg000:0000C26C std 4,sp
seg000:0000C26E ldx 6,sp
seg000:0000C270 lsrd
seg000:0000C271 xgdx
seg000:0000C273 rora
seg000:0000C274 rorb
seg000:0000C275 std 6,sp
seg000:0000C277 stx 4,sp
seg000:0000C279 leas 2,sp
seg000:0000C27B bne loc_C28C
seg000:0000C27D cpd #$2000
seg000:0000C280 bcc loc_C28C
seg000:0000C282 lsld
seg000:0000C283 addd #$8000
seg000:0000C286 tfr d, y
seg000:0000C288 ldab #$38
seg000:0000C28A bra loc_C2B2
seg000:0000C28C ; ---------------------------------------------------------------------------
seg000:0000C28C
seg000:0000C28C loc_C28C: ; CODE XREF: OSMO_GetFirmwareWordFromFlash+3Bj
seg000:0000C28C ; OSMO_GetFirmwareWordFromFlash+40j
seg000:0000C28C tbne x, loc_C2A0
seg000:0000C28F ldd 4,sp
seg000:0000C291 cpd #$4000
seg000:0000C294 bcc loc_C2A0
seg000:0000C296 lsld
seg000:0000C297 addd #$4000
seg000:0000C29A tfr d, y
seg000:0000C29C ldab #$39
seg000:0000C29E bra loc_C30D
seg000:0000C2A0 ; ---------------------------------------------------------------------------
seg000:0000C2A0
seg000:0000C2A0 loc_C2A0: ; CODE XREF: OSMO_GetFirmwareWordFromFlash:loc_C28Cj
seg000:0000C2A0 ; OSMO_GetFirmwareWordFromFlash+54j
seg000:0000C2A0 tbne x, loc_C2B4
seg000:0000C2A3 ldd 4,sp
seg000:0000C2A5 cpd #$6000
seg000:0000C2A8 bcc loc_C2B4
seg000:0000C2AA lsld
seg000:0000C2AB addd #0
seg000:0000C2AE tfr d, y
seg000:0000C2B0 ldab #$3A
seg000:0000C2B2
seg000:0000C2B2 loc_C2B2: ; CODE XREF: OSMO_GetFirmwareWordFromFlash+4Aj
seg000:0000C2B2 bra loc_C30D
seg000:0000C2B4 ; ---------------------------------------------------------------------------
seg000:0000C2B4
seg000:0000C2B4 loc_C2B4: ; CODE XREF: OSMO_GetFirmwareWordFromFlash:loc_C2A0j
seg000:0000C2B4 ; OSMO_GetFirmwareWordFromFlash+68j
seg000:0000C2B4 tbne x, loc_C2C7
seg000:0000C2B7 brset 4,sp, #$80, loc_C2C7
seg000:0000C2BB ldd 4,sp
seg000:0000C2BD lsld
seg000:0000C2BE addd #$C000
seg000:0000C2C1 tfr d, y
seg000:0000C2C3 ldab #$3B
seg000:0000C2C5 bra loc_C30D
seg000:0000C2C7 ; ---------------------------------------------------------------------------
seg000:0000C2C7
seg000:0000C2C7 loc_C2C7: ; CODE XREF: OSMO_GetFirmwareWordFromFlash:loc_C2B4j
seg000:0000C2C7 ; OSMO_GetFirmwareWordFromFlash+77j
seg000:0000C2C7 tbne x, loc_C2DB
seg000:0000C2CA ldd 4,sp
seg000:0000C2CC cpd #$A000
seg000:0000C2CF bcc loc_C2DB
seg000:0000C2D1 lsld
seg000:0000C2D2 addd #$8000
seg000:0000C2D5 tfr d, y
seg000:0000C2D7 ldab #$3C
seg000:0000C2D9 bra loc_C30D
seg000:0000C2DB ; ---------------------------------------------------------------------------
seg000:0000C2DB
seg000:0000C2DB loc_C2DB: ; CODE XREF: OSMO_GetFirmwareWordFromFlash:loc_C2C7j
seg000:0000C2DB ; OSMO_GetFirmwareWordFromFlash+8Fj
seg000:0000C2DB tbne x, loc_C2EF
seg000:0000C2DE ldd 4,sp
seg000:0000C2E0 cpd #$C000
seg000:0000C2E3 bcc loc_C2EF
seg000:0000C2E5 lsld
seg000:0000C2E6 addd #$4000
seg000:0000C2E9 tfr d, y
seg000:0000C2EB ldab #$3D
seg000:0000C2ED bra loc_C30D
seg000:0000C2EF ; ---------------------------------------------------------------------------
seg000:0000C2EF
seg000:0000C2EF loc_C2EF: ; CODE XREF: OSMO_GetFirmwareWordFromFlash:loc_C2DBj
seg000:0000C2EF ; OSMO_GetFirmwareWordFromFlash+A3j
seg000:0000C2EF tbne x, loc_C303
seg000:0000C2F2 ldd 4,sp
seg000:0000C2F4 cpd #$E000
seg000:0000C2F7 bcc loc_C303
seg000:0000C2F9 lsld
seg000:0000C2FA addd #0
seg000:0000C2FD tfr d, y
seg000:0000C2FF ldab #$3E
seg000:0000C301 bra loc_C30D
seg000:0000C303 ; ---------------------------------------------------------------------------
seg000:0000C303
seg000:0000C303 loc_C303: ; CODE XREF: OSMO_GetFirmwareWordFromFlash:loc_C2EFj
seg000:0000C303 ; OSMO_GetFirmwareWordFromFlash+B7j
seg000:0000C303 ldd 4,sp
seg000:0000C305 lsld
seg000:0000C306 addd #$1B5B
seg000:0000C309 tfr d, y
seg000:0000C30B ldab #0
seg000:0000C30D
seg000:0000C30D loc_C30D: ; CODE XREF: OSMO_GetFirmwareWordFromFlash+5Ej
seg000:0000C30D ; OSMO_GetFirmwareWordFromFlash:loc_C2B2j ...
seg000:0000C30D jsr OSMO_ReadWordFromFlashPage ; Reads the word located at address Y on PPAGE B
seg000:0000C310 tfr y, d ; return read word in D
seg000:0000C312 leas 6,sp
seg000:0000C314 rts
seg000:0000C314 ; End of function OSMO_GetFirmwareWordFromFlash