2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Code for downloading an ELF file onto a Palm Pilot(TM).
9 #include <System/SerialMgr.h>
10 #include <System/StringMgr.h>
13 #define __PILOT_CODE__
14 #include "../registers.h"
16 #include "loaderRsc.h"
29 #define UNPROTECT_MEMORY \
30 csa0 = RREG_L(CSA0); \
31 csa1 = RREG_L(CSA1); \
32 csa2 = RREG_L(CSA2); \
33 csa3 = RREG_L(CSA3); \
34 WREG_L(CSA0)=csa0 &(~8); \
35 WREG_L(CSA1)=csa1 &(~8); \
36 WREG_L(CSA2)=csa2 &(~8); \
37 WREG_L(CSA3)=csa3 &(~8);
39 #define PROTECT_MEMORY \
45 #define BAUDRATE 57600
47 int _strncmp(const char * s1
, const char * s2
, int len
)
60 void _strncpy(char * d
, const char * s
, int len
)
82 #define TYPE_HANDSHAKE 0x01
83 #define TYPE_READ_MEM 0x02
84 #define TYPE_WRITE_MEM 0x03
85 #define TYPE_MEM_CONTENT 0x04
86 #define TYPE_WRITE_MEM_ACK 0x05
87 #define TYPE_GET_SPECIAL_INFO 0x06
88 #define TYPE_START_PROGRAM 0x07
89 #define TYPE_START_PROGRAM_ACK 0x08
90 #define TYPE_QUIT 0x10
94 unsigned short payload_length
;
95 unsigned char payload_type
;
102 GET_FRAME_BEGINNING
= 0x01,
103 GET_PAYLOAD_LENGTH_HI
,
104 GET_PAYLOAD_LENGTH_LO
,
110 void free_packet(struct Packet
* packet
)
113 MemPtrFree(packet
->payload
);
117 struct Packet
* ready_packet
= NULL
;
118 struct Packet
* current_packet
= NULL
;
120 void free_all_packets(void)
122 if (NULL
!= current_packet
) {
123 free_packet(current_packet
);
126 if (NULL
!= ready_packet
)
127 free_packet(ready_packet
);
131 struct Packet
* get_next_packet(UInt refnum
)
133 struct Packet
* p
= NULL
;
137 err
= SerReceiveCheck(refnum
, &len
);
143 buf
= MemPtrNew(len
);
146 len
= SerReceive(refnum
,
156 if (NULL
== current_packet
) {
157 current_packet
= MemPtrNew(sizeof(struct Packet
));
158 current_packet
->state
= GET_FRAME_BEGINNING
;
159 current_packet
->pos
= 0;
162 switch (current_packet
->state
) {
163 case GET_FRAME_BEGINNING
:
165 current_packet
->state
= GET_PAYLOAD_LENGTH_HI
;
169 case GET_PAYLOAD_LENGTH_HI
:
170 current_packet
->payload_length
= ((unsigned short)buf
[i
]) << 8;
171 current_packet
->state
= GET_PAYLOAD_LENGTH_LO
;
175 case GET_PAYLOAD_LENGTH_LO
:
176 current_packet
->payload_length
|= ((unsigned short)buf
[i
]);
177 current_packet
->state
= GET_TYPE
;
178 current_packet
->payload
= MemPtrNew(current_packet
->payload_length
);
183 current_packet
->payload_type
= buf
[i
];
184 current_packet
->state
= GET_PAYLOAD
;
190 current_packet
->pos
< current_packet
->payload_length
) {
192 current_packet
->payload
[current_packet
->pos
++] = buf
[i
];
196 if (current_packet
->pos
== current_packet
->payload_length
)
197 current_packet
->state
= GET_FRAME_END
;
201 if (0x7f == buf
[i
]) {
202 ready_packet
= current_packet
;
204 free_packet(current_packet
);
207 current_packet
= NULL
;
217 * Try to get the first complete packet in the list.
219 p
= (struct Packet
*)ready_packet
;
226 * Reconvert the payload (if necessary)
228 while (i
< p
->payload_length
) {
229 if (0x27 == p
->payload
[i
])
236 * Convert the payload
238 char * pl
= MemPtrNew(p
->payload_length
- c
);
242 while (i
< p
->payload_length
) {
243 if (0x27 == p
->payload
[i
]) {
244 if (0x28 == p
->payload
[i
+1]) {
250 pl
[_i
] = p
->payload
[i
];
255 MemPtrFree(p
->payload
);
257 p
->payload_length
-= c
;
264 void send_packet(UInt refnum
, char * buffer
, unsigned short len
, unsigned char type
)
272 * Count number of characters to escape.
274 if (0x7f == buffer
[i
] || 0x27 == buffer
[i
])
279 packet
= MemPtrNew(1 + /* frame begin */
280 2 + /* length of payload indicator */
282 len
+ c
+ /* payload */
285 if (NULL
!= packet
) {
288 packet
[1] = ((len
+c
) >> 8) & 0xff;
289 packet
[2] = ((len
+c
) ) & 0xff;
294 * convert forbidden bytes.
297 if (0x7f == buffer
[i
]) {
298 packet
[pos
++] = 0x27;
299 packet
[pos
] = 0x29; /* = 0x7f */
300 } else if (0x27 == buffer
[i
]) {
301 packet
[pos
++] = 0x27;
302 packet
[pos
] = 0x28; /* = 0x27 */
304 packet
[pos
] = buffer
[i
];
314 SerSend(refnum
,packet
,pos
+1,&err
);
315 SerSendWait(refnum
,-1);
322 * Do a handshake. I send "AROS?", expect "AROS!" and send back
325 int do_handshake(UInt refnum
)
327 struct Packet
* packet
;
331 send_packet(refnum
, "AROS?", 5, TYPE_HANDSHAKE
);
333 packet
= get_next_packet(refnum
);
334 if (NULL
!= packet
) {
335 if (0 == _strncmp("AROS!", &packet
->payload
[0], 5) &&
336 5 == packet
->payload_length
) {
338 send_packet(refnum
, "greets!", 7, TYPE_HANDSHAKE
);
348 void howdy(UInt refnum
)
350 send_packet(refnum
,"HOWDY!",6,0xff);
353 void read_mem(UInt refnum
, struct Packet
* packet
)
357 * ULong: Start address
358 * unsigned short: Num Bytes
360 if (6 == packet
->payload_length
) {
364 ULong addr
= (((ULong
)packet
->payload
[0]) << 24) |
365 (((ULong
)packet
->payload
[1]) << 16) |
366 (((ULong
)packet
->payload
[2]) << 8) |
367 (((ULong
)packet
->payload
[3]) << 0);
368 ULong numbytes
= (((ULong
)packet
->payload
[4]) << 8) |
369 (((ULong
)packet
->payload
[5]) );
371 buf
= MemPtrNew((ULong
)numbytes
+ sizeof(addr
));
373 _strncpy(buf
, (char *)&addr
, sizeof(addr
));
379 buf
[i
] = RREG_B(addr
);
384 send_packet(refnum
,buf
,numbytes
+sizeof(addr
),TYPE_MEM_CONTENT
);
389 void write_mem(UInt refnum
, struct Packet
* packet
)
393 * ULong: Start address
395 if (packet
->payload_length
>= 4) {
397 ULong csa0
, csa1
, csa2
, csa3
;
398 ULong addr
= (((ULong
)packet
->payload
[0]) << 24) |
399 (((ULong
)packet
->payload
[1]) << 16) |
400 (((ULong
)packet
->payload
[2]) << 8) |
401 (((ULong
)packet
->payload
[3]) << 0);
402 i
= packet
->payload_length
- 4;
406 *(Byte
*)addr
= packet
->payload
[ctr
];
413 * Send back the start address as ack!
415 send_packet(refnum
,packet
->payload
,4,TYPE_WRITE_MEM_ACK
);
419 void execute(void * func())
424 void start_program(UInt refnum
, struct Packet
* packet
)
428 * ULong: Start address
430 if (packet
->payload_length
== 4) {
431 ULong csa0
,csa1
,csa2
,csa3
;
432 ULong addr
= (((ULong
)packet
->payload
[0]) << 24) |
433 (((ULong
)packet
->payload
[1]) << 16) |
434 (((ULong
)packet
->payload
[2]) << 8) |
435 (((ULong
)packet
->payload
[3]) << 0);
437 * Send back the start address as ack!
439 send_packet(refnum
,packet
->payload
,4,TYPE_START_PROGRAM_ACK
);
441 execute((void *)addr
);
453 extern void end_marker();
456 void get_special_info(UInt refnum
)
458 struct special_info si
;
459 si
.start
= (ULong
)start
;
460 si
.end
= (ULong
)end_marker
;
462 send_packet(refnum
,(char *)&si
,sizeof(struct special_info
),TYPE_GET_SPECIAL_INFO
);
465 int download_AROS(void)
472 err
= SysLibFind("Serial Library",&refNum
);
474 err
= SerOpen(refNum
, 0, BAUDRATE
);
476 VoidPtr serbuf
= MemPtrNew(0x400);
478 SerSetReceiveBuffer(refNum
, serbuf
, 0x400);
480 * Serial Port is opened. So let's try a handshake
482 if (0 == do_handshake(refNum
)) {
484 * Let's read all packets and act upon.
487 while (FALSE
== end
) {
488 struct Packet
* packet
;
490 packet
= get_next_packet(refNum
);
491 if (NULL
!= packet
) {
492 switch (packet
->payload_type
) {
494 read_mem(refNum
,packet
);
498 write_mem(refNum
,packet
);
501 case TYPE_GET_SPECIAL_INFO
:
502 get_special_info(refNum
);
505 case TYPE_START_PROGRAM
:
506 start_program(refNum
, packet
);
518 if (NULL
!= serbuf
) {
519 SerSetReceiveBuffer(refNum
, serbuf
, 0);
532 static Boolean
MainFormHandleEvent (EventPtr e
)
534 Boolean handled
= false;
541 frm
= FrmGetActiveForm();
548 MenuEraseStatus(NULL
);
550 switch(e
->data
.menu
.itemID
) {
557 switch(e
->data
.ctlSelect
.controlID
) {
559 rc
= download_AROS();
573 static Boolean
ApplicationHandleEvent(EventPtr e
)
577 Boolean handled
= false;
579 if (e
->eType
== frmLoadEvent
) {
580 formId
= e
->data
.frmLoad
.formID
;
581 frm
= FrmInitForm(formId
);
582 FrmSetActiveForm(frm
);
586 FrmSetEventHandler(frm
, MainFormHandleEvent
);
595 /* Get preferences, open (or create) app database */
596 static Word
StartApplication(void)
598 FrmGotoForm(MainForm
);
602 /* Save preferences, close forms, close app database */
603 static void StopApplication(void)
609 /* The main event loop */
610 static void EventLoop(void)
616 EvtGetEvent(&e
, evtWaitForever
);
617 if (! SysHandleEvent (&e
))
618 if (! MenuHandleEvent (NULL
, &e
, &err
))
619 if (! ApplicationHandleEvent (&e
))
620 FrmDispatchEvent (&e
);
621 } while (e
.eType
!= appStopEvent
);
626 /* Main entry point; it is unlikely you will need to change this except to
627 handle other launch command codes */
628 DWord
PilotMain(Word cmd
, Ptr cmdPBP
, Word launchFlags
)
633 if (cmd
== sysAppLaunchCmdNormalLaunch
) {
635 err
= StartApplication();
642 return sysErrParamErr
;