aboutsummaryrefslogtreecommitdiff
path: root/ROMTransfer
diff options
context:
space:
mode:
Diffstat (limited to 'ROMTransfer')
-rw-r--r--ROMTransfer/Resources/ROM_Transfer.rcp43
-rw-r--r--ROMTransfer/Resources/ROM_Transfer.rsrc0
-rw-r--r--ROMTransfer/Resources/ROM_Transfer.rsrc.c22
-rw-r--r--ROMTransfer/Resources/ROM_Transfer.rsrc.h50
-rw-r--r--ROMTransfer/Resources/ROM_Transfer_icon.pbitm32
-rw-r--r--ROMTransfer/Source/Makefile27
-rwxr-xr-xROMTransfer/Source/ROM_Transferbin0 -> 137999 bytes
-rw-r--r--ROMTransfer/Source/ROM_Transfer.c768
-rw-r--r--ROMTransfer/Source/ROM_Transfer.h55
-rw-r--r--ROMTransfer/Source/ROM_Transfer.prcbin0 -> 4958 bytes
-rw-r--r--ROMTransfer/Source/SerialPortTools.c388
-rw-r--r--ROMTransfer/Source/SerialPortTools.h52
12 files changed, 1437 insertions, 0 deletions
diff --git a/ROMTransfer/Resources/ROM_Transfer.rcp b/ROMTransfer/Resources/ROM_Transfer.rcp
new file mode 100644
index 0000000..2b7e2a4
--- /dev/null
+++ b/ROMTransfer/Resources/ROM_Transfer.rcp
@@ -0,0 +1,43 @@
+/* ===================================================================== *\
+ Copyright (c) 2000-2001 Palm, Inc. or its subsidiaries.
+ All rights reserved.
+
+ This file is part of the Palm OS Emulator.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+\* ===================================================================== */
+
+#include "ROM_Transfer.rsrc.h"
+
+/* pbitm is a fairly brutal image format! But it's good enough for icons,
+ and you can be sure that everyone will have software capable of editing
+ it. PilRC does support other image formats too. */
+
+icon "ROM_Transfer_icon.pbitm"
+
+applicationiconname id 1000 "ROM Transfer"
+
+version id 1 "2.0"
+
+/* Unfortunately, pilrc doesn't allow you to write a very long label as a
+ multiple line string. */
+
+form id MainForm at (0 0 160 160)
+begin
+ title "ROM Transfer"
+ button "Begin Transfer" id MainBeginTransferButton at (79 138 74 16)
+ label "ROM Transfer is provided as a\rcompanion utility to the Palm OS\rEmulator. To use this utility, select\r\"Download ROM...\" from the File\rmenu in the emulator and follow the\rinstructions provided."
+ autoid at (7 21)
+ label "Transfer Speed:" autoid at (7 98) font 1
+ popuptrigger "" id MainSpeedPopTrigger at (90 97 0 13) leftanchor
+ list
+ "115,200 bps" "57,600 bps" "38,400 bps" "28,800 bps"
+ "19,200 bps" "14,400 bps" "9,600 bps"
+ id MainSpeedList at (94 98 65 auto) visibleitems 7 nonusable disabled
+ popuplist MainSpeedPopTrigger MainSpeedList
+ label "Status:" autoid at (49 114) font 1
+ label "Idle " MainStatusTextLabel at (93 114)
+end
diff --git a/ROMTransfer/Resources/ROM_Transfer.rsrc b/ROMTransfer/Resources/ROM_Transfer.rsrc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ROMTransfer/Resources/ROM_Transfer.rsrc
diff --git a/ROMTransfer/Resources/ROM_Transfer.rsrc.c b/ROMTransfer/Resources/ROM_Transfer.rsrc.c
new file mode 100644
index 0000000..207ccf5
--- /dev/null
+++ b/ROMTransfer/Resources/ROM_Transfer.rsrc.c
@@ -0,0 +1,22 @@
+/* -*- mode: C++; tab-width: 4 -*- */
+/* ===================================================================== *\
+ Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries.
+ All rights reserved.
+
+ This file is part of the Palm OS Emulator.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+\* ===================================================================== */
+
+#include <BuildRules.h>
+
+
+char* AppResourceList[] =
+{
+ ":Resources:Rom Transfer.rsrc",
+ ""
+};
+
diff --git a/ROMTransfer/Resources/ROM_Transfer.rsrc.h b/ROMTransfer/Resources/ROM_Transfer.rsrc.h
new file mode 100644
index 0000000..f88371f
--- /dev/null
+++ b/ROMTransfer/Resources/ROM_Transfer.rsrc.h
@@ -0,0 +1,50 @@
+// Header generated by Constructor for Pilot 1.0.2
+
+//
+
+// Generated at 2:42:07 PM on Wednesday, November 4, 1998
+
+//
+
+// Generated for file: Phantom:Projects:Emulator:main:ROM_Transfer:Resources:ROM Transfer.rsrc
+
+//
+
+// THIS IS AN AUTOMATICALLY GENERATED HEADER FILE FROM CONSTRUCTOR FOR PALMPILOT;
+
+// - DO NOT EDIT - CHANGES MADE TO THIS FILE WILL BE LOST
+
+//
+
+// Pilot App Name: "ROM Transfer"
+
+//
+
+// Pilot App Version: "2.0"
+
+
+
+
+
+
+
+// Resource: tFRM 1000
+
+#define MainForm 1000 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 160, Usable = 1, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0)
+
+#define MainBeginTransferButton 1000 //(Left Origin = 79, Top Origin = 138, Width = 74, Height = 16, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard)
+
+#define MainInstructionsLabel 1001 //(Left Origin = 7, Top Origin = 21, Usable = 1, Font = Standard)
+
+#define MainSpeedLabel 1002 //(Left Origin = 7, Top Origin = 98, Usable = 1, Font = Bold)
+
+#define MainStatusLabel 1005 //(Left Origin = 49, Top Origin = 114, Usable = 1, Font = Bold)
+
+#define MainStatusTextLabel 1006 //(Left Origin = 93, Top Origin = 114, Usable = 1, Font = Standard)
+
+#define MainSpeedList 1004 //(Left Origin = 94, Top Origin = 98, Width = 65, Usable = 0, Font = Standard, Visible Items = 0)
+
+#define MainSpeedPopTrigger 1003 //(Left Origin = 90, Top Origin = 97, Width = 0, Height = 13, Usable = 1, Anchor Left = 1, Font = Standard, List ID = 1004)
+
+
+
diff --git a/ROMTransfer/Resources/ROM_Transfer_icon.pbitm b/ROMTransfer/Resources/ROM_Transfer_icon.pbitm
new file mode 100644
index 0000000..3fca0bf
--- /dev/null
+++ b/ROMTransfer/Resources/ROM_Transfer_icon.pbitm
@@ -0,0 +1,32 @@
+------------#######-------------
+----------###########-----------
+---------######-######----------
+--------######-#-######---------
+-------######-###-######--------
+------######-#####-######-------
+------#####-######--#####-------
+-----#####-######--#######------
+-----####-######--#-######------
+-----###-######--#########------
+-----##-######--#-########------
+-----###-####--###########------
+-----####-##--#-##-##-####------
+-----#####---####---#-####------
+------#####-#-####----###-------
+------#############---###-------
+-------##########-----##--------
+--------###############---------
+---------#############----------
+----------###########-----------
+------------#######-------------
+--------------------------------
+--------------------------------
+--------------------------------
+--------------------------------
+--------------------------------
+--------------------------------
+--------------------------------
+--------------------------------
+--------------------------------
+--------------------------------
+--------------------------------
diff --git a/ROMTransfer/Source/Makefile b/ROMTransfer/Source/Makefile
new file mode 100644
index 0000000..efb76d1
--- /dev/null
+++ b/ROMTransfer/Source/Makefile
@@ -0,0 +1,27 @@
+## -*- mode: Makefile; tab-width: 4; -*-
+## ======================================================================================
+## Copyright (c) 2000 Palm Computing, Inc. or its subsidiaries. All rights reserved.
+## ======================================================================================
+
+R = ../Resources
+
+CC = m68k-palmos-gcc
+CFLAGS = -O2 -Wall -I$(R) -g -Wno-unknown-pragmas
+
+ROM_Transfer.prc: ROM_Transfer tver0001.bin
+ build-prc ROM_Transfer.prc "ROM Transfer" ROMX ROM_Transfer *.bin
+
+ROM_Transfer: ROM_Transfer.o SerialPortTools.o
+ $(CC) -v -g -o ROM_Transfer ROM_Transfer.o SerialPortTools.o
+
+ROM_Transfer.o: ROM_Transfer.c ROM_Transfer.h SerialPortTools.h $(R)/ROM_Transfer.rsrc.h
+ $(CC) $(CFLAGS) -c ROM_Transfer.c
+
+SerialPortTools.o: SerialPortTools.c SerialPortTools.h $(R)/ROM_Transfer.rsrc.h
+ $(CC) $(CFLAGS) -c SerialPortTools.c
+
+tver0001.bin: $(R)/ROM_Transfer.rcp $(R)/ROM_Transfer_icon.pbitm $(R)/ROM_Transfer.rsrc.h
+ pilrc -I $(R) $(R)/ROM_Transfer.rcp
+
+clean:
+ -rm -f ROM_Transfer *.o *.bin
diff --git a/ROMTransfer/Source/ROM_Transfer b/ROMTransfer/Source/ROM_Transfer
new file mode 100755
index 0000000..8e9d15c
--- /dev/null
+++ b/ROMTransfer/Source/ROM_Transfer
Binary files differ
diff --git a/ROMTransfer/Source/ROM_Transfer.c b/ROMTransfer/Source/ROM_Transfer.c
new file mode 100644
index 0000000..2126ce9
--- /dev/null
+++ b/ROMTransfer/Source/ROM_Transfer.c
@@ -0,0 +1,768 @@
+/* -*- mode: C++; tab-width: 4 -*- */
+/* ===================================================================== *\
+ Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries.
+ All rights reserved.
+
+ This file is part of the Palm OS Emulator.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+\* ===================================================================== */
+
+#define PILOT_PRECOMPILED_HEADERS_OFF
+
+#include <PalmOS.h>
+
+#include "ROM_Transfer.h"
+#include "ROM_Transfer.rsrc.h"
+
+UInt32 HwrMemReadable(void *addr)
+ HAL_CALL(sysTrapHwrMemReadable);
+
+static void SendXModem (FormType* form, UInt8* romStart, Int32 romSize);
+static void SendRaw (FormType* form, UInt8* romStart, Int32 romSize);
+static void UpdatePercentComplete (FormType* form, Int32 offset, Int32 romSize);
+static void GetROMStartSize (UInt8** romStart, Int32* romSize);
+static void PrvUpdateStatus (FormType* form, const char*);
+static void PrvStrPrintF (char* dest, const char* fmt, Int32 num);
+static void PrvStrIToX (char* dest, UInt32 val);
+
+static UInt32 gROMVersion;
+
+const char* kSerialErrors[] =
+{
+ "Bad Param",
+ "Bad Port",
+ "No Memory",
+ "Bad ConnID",
+ "Timeout",
+ "Line Error",
+ "Already Open",
+ "Still Open",
+ "Not Open",
+ "Not Supported",
+ "No Devices"
+};
+
+
+// ---------------------------------------------------------------------------
+// ¥ PilotMain
+// ---------------------------------------------------------------------------
+// The main entry point for ROM Transfer.
+
+UInt32 PilotMain ( UInt16 iCommand,
+ void* iCommandParams,
+ UInt16 iLaunchFlags)
+{
+ if (iCommand != sysAppLaunchCmdNormalLaunch)
+ return 0;
+
+ ErrTry
+ {
+ InitializeApplication ();
+ ExecuteApplication ();
+ }
+
+ // Catch any unhandled exceptions.
+
+ ErrCatch (iError)
+ {
+ }
+ ErrEndCatch
+
+ // Clean up.
+
+ DisposeApplication ();
+
+ return 0;
+}
+
+
+#pragma mark -
+
+
+// ---------------------------------------------------------------------------
+// ¥ InitializeApplication
+// ---------------------------------------------------------------------------
+// Initializes the application globals and prepares to execute the event loop.
+
+void InitializeApplication (void)
+{
+ Char* aLabel;
+ ListPtr aList;
+ UInt16 aListItem;
+ ControlPtr aControl;
+ FormPtr aMainForm;
+
+ FtrGet (sysFtrCreator, sysFtrNumROMVersion, &gROMVersion);
+
+ // Initialize and draw the main form.
+
+ aMainForm = FrmInitForm (MainForm);
+ Throw_IfNil (aMainForm, 0);
+
+ FrmSetActiveForm (aMainForm);
+ FrmDrawForm (aMainForm);
+
+ // Set up the speed popup.
+
+ aListItem = kItem_115200;
+ aList = FrmGetObjectPtr (aMainForm, FrmGetObjectIndex (aMainForm, MainSpeedList));
+ aLabel = LstGetSelectionText (aList, aListItem);
+ aControl = FrmGetObjectPtr (aMainForm, FrmGetObjectIndex (aMainForm, MainSpeedPopTrigger));
+ CtlSetLabel (aControl, aLabel);
+ LstSetSelection (aList, aListItem);
+
+#if 0
+{
+ #define sysFtrNewSerialVersion 2
+ int fred;
+
+#define gSerialManagerVersion fred
+
+ Err err;
+ char buffer[20];
+ UInt32 systemVersion;
+ UInt32 ftrValue;
+
+ // Determine what version Serial Manager we have:
+ //
+ // 0 = undetermined
+ // 1 = Original driver in Pilot 1000/5000
+ // 2 = Updated driver in PalmPilot (new Send/Receive calls)
+ // 3 = New Serial Manager (Srm calls)
+ // 4 = Updated Serial Manager (includes SrmExtOpen call)
+
+ err = FtrGet (sysFileCSystem, sysFtrNumROMVersion, &systemVersion);
+
+ ErrFatalDisplayIf (err, "Unable to determine System version");
+
+ if (sysGetROMVerMajor(systemVersion) < 2)
+ {
+ gSerialManagerVersion = 1;
+ }
+ else
+ {
+ err = FtrGet (sysFileCSerialMgr, sysFtrNewSerialPresent, &ftrValue);
+
+ if (err || ftrValue == 0)
+ {
+ gSerialManagerVersion = 2;
+ }
+ else
+ {
+ err = FtrGet (sysFileCSerialMgr, sysFtrNewSerialVersion, &ftrValue);
+
+ if (err)
+ {
+ gSerialManagerVersion = 3;
+ }
+ else if (ftrValue <= 2)
+ {
+ gSerialManagerVersion = 3;
+
+ // Palm OS 3.5.2 for Handspring implements
+ // sysFtrNewSerialVersion and returns a feature value of 2.
+ // Palm OS 4.0 also implements sysFtrNewSerialVersion and
+ // returns a value of 2. However, the two serial managers
+ // are different: the latter implements SrmExtOpen. In
+ // order to differentiate between the two, we have to check
+ // the OS version.
+
+ if (ftrValue == 2 &&
+ sysGetROMVerMajor (systemVersion) == 4 &&
+ sysGetROMVerMinor (systemVersion) == 0)
+ {
+ gSerialManagerVersion = 4;
+ }
+ }
+ else
+ {
+ // ftrValue should be at least 3 for versions of the
+ // Serial Manager that implement SrmExtOpen.
+
+ gSerialManagerVersion = ftrValue + 1;
+ }
+ }
+ }
+
+ StrPrintF (buffer, "%d %d", (int) err, (int) gSerialManagerVersion);
+
+ PrvUpdateStatus (aMainForm, buffer);
+}
+#endif
+
+#if 0
+{
+ char buffer1[20];
+ char buffer2[20];
+ char buffer3[20];
+ UInt8* romStart;
+ Int32 romSize;
+
+ GetROMStartSize (&romStart, &romSize);
+
+ PrvStrIToX (buffer1, (UInt32) romStart);
+ PrvStrIToX (buffer2, (UInt32) romSize);
+
+ StrCopy (buffer3, buffer1);
+ StrCat (buffer3, " ");
+ StrCat (buffer3, buffer2);
+
+ PrvUpdateStatus (aMainForm, buffer3);
+}
+#endif
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ DisposeApplication
+// ---------------------------------------------------------------------------
+// Disposes the application globals and prepares to exit.
+
+void DisposeApplication (void)
+{
+ FrmCloseAllForms ();
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ ExecuteApplication
+// ---------------------------------------------------------------------------
+// Executes an event loop until the application quits.
+
+void ExecuteApplication (void)
+{
+ EventType aEvent;
+
+ aEvent.eType = nilEvent;
+
+ // Repeat until the application quits.
+
+ while (aEvent.eType != appStopEvent)
+ {
+ // Get the next available event.
+
+ EvtGetEvent (&aEvent, evtWaitForever);
+
+ // Give the system a chance to handle the event.
+
+ if (!SysHandleEvent (&aEvent))
+
+ // Try to handle the event ourselves.
+
+ if (!ProcessEvent (&aEvent))
+
+ // Let the form provide default handling of the event.
+
+ FrmHandleEvent (FrmGetActiveForm (), &aEvent);
+ }
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ ProcessEvent
+// ---------------------------------------------------------------------------
+// Attempts to process the specified event.
+
+Boolean ProcessEvent (EventPtr iEvent)
+{
+ Boolean aWasHandled = false;
+
+ if (iEvent->eType == ctlSelectEvent)
+ {
+ switch (iEvent->data.ctlEnter.controlID)
+ {
+ case MainBeginTransferButton:
+ {
+ TransferROM ();
+
+ aWasHandled = true;
+ break;
+ }
+ }
+ }
+
+ return aWasHandled;
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ TransferROM
+// ---------------------------------------------------------------------------
+// Downloads the ROM via the serial connection.
+
+static UInt32 MySysTicksPerSecond ()
+{
+ if (sysGetROMVerMajor(gROMVersion) < 2)
+ return sysTicksPerSecond;
+
+ return SysTicksPerSecond ();
+}
+
+void TransferROM (void)
+{
+ Int16 err;
+ UInt8* romStart;
+ Int32 romSize;
+
+ Int16 speedChoice;
+ UInt32 speed;
+ FormPtr form;
+
+ form = FrmGetActiveForm ();
+
+ ErrTry
+ {
+ ErrFatalDisplayIf (!form, "Unable to get form");
+
+ speedChoice = LstGetSelection (FrmGetObjectPtr (form, FrmGetObjectIndex (form, MainSpeedList)));
+ switch (speedChoice)
+ {
+ case kItem_1200: speed = kBaud_1200; break;
+ case kItem_2400: speed = kBaud_2400; break;
+ case kItem_4800: speed = kBaud_4800; break;
+ case kItem_9600: speed = kBaud_9600; break;
+ case kItem_14400: speed = kBaud_14400; break;
+ case kItem_19200: speed = kBaud_19200; break;
+ case kItem_28800: speed = kBaud_28800; break;
+ case kItem_38400: speed = kBaud_38400; break;
+ case kItem_57600: speed = kBaud_57600; break;
+ case kItem_115200: speed = kBaud_115200; break;
+ default: speed = kBaud_14400; break;
+ }
+
+ err = Comm_Initialize (speed);
+ Throw_IfError (err, err);
+
+ // Get the size and location of the ROM.
+
+ GetROMStartSize (&romStart, &romSize);
+
+ // Send the data using a protocol appropriate for the connection.
+
+#if 0
+ if (using_USB)
+ {
+ SendRaw (form, romStart, romSize);
+ }
+ else
+#endif
+ {
+ SendXModem (form, romStart, romSize);
+ }
+
+ // Change the status text.
+
+ PrvUpdateStatus (form, "Finished");
+ }
+
+ // Catch any exceptions.
+
+ ErrCatch (iError)
+ {
+ // Change the status text.
+
+ if (form != NULL)
+ {
+ char buffer[20];
+
+ if (iError >= serErrBadParam &&
+ iError <= serErrNoDevicesAvail)
+ {
+ StrCopy (buffer, kSerialErrors[iError - serErrBadParam]);
+ }
+ else
+ {
+ PrvStrPrintF (buffer, "Error #%d", iError);
+ }
+
+ PrvUpdateStatus (form, buffer);
+ }
+ }
+ ErrEndCatch
+
+ Comm_Dispose ();
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ PrvSendChar
+// ---------------------------------------------------------------------------
+
+static void PrvSendChar (UInt8 ch)
+{
+ Err err = Comm_Send (&ch, 1);
+ Throw_IfError (err, err);
+
+ EvtResetAutoOffTimer ();
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ PrvReceiveChar
+// ---------------------------------------------------------------------------
+
+static void PrvReceiveChar (UInt8* ch)
+{
+ Err err = Comm_Receive (ch, 1, 30 * MySysTicksPerSecond ());
+ Throw_IfError (err, err);
+
+ EvtResetAutoOffTimer ();
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ SendXModem
+// ---------------------------------------------------------------------------
+
+void SendXModem (FormType* form, UInt8* romStart, Int32 romSize)
+{
+ const int kXModemBodySize = 1024; // 1k-XModem variant
+ const int kXModemSohOffset = 0;
+ const int kXModemBlkOffset = kXModemSohOffset + 1;
+ const int kXModemNBlkOffset = kXModemBlkOffset + 1;
+ const int kXModemBodyOffset = kXModemNBlkOffset + 1;
+ const int kXModemChk1Offset = kXModemBodyOffset + kXModemBodySize;
+ const int kXModemChk2Offset = kXModemChk1Offset + 1;
+ const int kXModemBlockSize = kXModemChk2Offset + 1;
+
+ const char kXModemSoh = 1; // start of block header
+ const char kXModemEof = 4; // end of file signal
+ const char kXModemAck = 6; // acknowledge
+ const char kXModemNak = 21; // negative acknowledge (resend packet)
+ const char kXModemCan = 24; // cancel
+ const char kXModemNakCrc = 'C'; // used instead of NAK for initial block
+
+ Err err;
+ UInt8 c;
+ UInt8 blockNum;
+ UInt32 i;
+ Boolean bXModemCrc;
+ char block[kXModemBlockSize];
+ Boolean bXModemHeaderBlock;
+ Int32 offset;
+ UInt16 crc;
+ char* body = &block[kXModemBodyOffset];
+
+ // Change the status text.
+
+ PrvUpdateStatus (form, "Waiting...");
+
+ // First, wait for the receiver to send us a nak. If it's
+ // a real nak, then we'll send in checksum mode. If it's
+ // a 'C', we'll send in CRC mode.
+
+ Comm_ClearError ();
+
+ while (true)
+ {
+ PrvReceiveChar (&c);
+
+ if (c == kXModemNakCrc)
+ {
+ bXModemCrc = true;
+ break;
+ }
+ else if (c == kXModemNak)
+ {
+ bXModemCrc = false;
+ break;
+ }
+ else if (c == kXModemCan)
+ {
+ ErrThrow (c);
+ }
+ }
+
+ // Send the ROM one block at a time until it's done.
+
+ offset = 0;
+ blockNum = 0;
+ bXModemHeaderBlock = true;
+
+ while (offset < romSize)
+ {
+ // Change the status text.
+
+ UpdatePercentComplete (form, offset, romSize);
+
+ // Build up the block.
+
+ block[kXModemSohOffset] = kXModemSoh;
+ block[kXModemBlkOffset] = blockNum;
+ block[kXModemNBlkOffset] = ~blockNum;
+
+ if (bXModemHeaderBlock)
+ {
+ // The very first block sends over a "file name"
+ // and "file size".
+
+ MemSet (body, kXModemBodySize, 0);
+ StrCopy (body, "PalmOS.ROM"); // What's in a name?
+ StrIToA (&body[StrLen (body) + 1], romSize);
+ }
+ else
+ {
+ // All subseqent blocks contain 1K of the ROM.
+
+ MemMove (body, romStart + offset, kXModemBodySize);
+ }
+
+ // Figure out and add the checksum.
+
+ if (bXModemCrc)
+ {
+ // Calculate the checksum of the body data, as
+ // well as the two empty spots that will get filled
+ // in with the checksum bytes in a moment.
+
+ block[kXModemChk1Offset] = 0;
+ block[kXModemChk2Offset] = 0;
+
+ crc = Crc16CalcBlock (body, kXModemBodySize + 2, 0);
+
+ block[kXModemChk1Offset] = crc >> 8;
+ block[kXModemChk2Offset] = crc;
+
+ err = Comm_Send (block, kXModemBlockSize);
+ }
+ else
+ {
+ c = 0;
+
+ for (i = 0; i < kXModemBodySize; i++)
+ {
+ c += (romStart + offset)[i];
+ }
+
+ body[kXModemChk1Offset] = c;
+
+ err = Comm_Send (block, kXModemBlockSize - 1);
+ }
+
+ Throw_IfError (err, err);
+
+ EvtResetAutoOffTimer ();
+
+ // Wait for the other end to ack or nak us. Leave
+ // plenty of timeout so the receiver has time to
+ // decide whether it got a partial block.
+
+ do
+ {
+ PrvReceiveChar (&c);
+ } while (c != kXModemAck && c != kXModemNak && c != kXModemNakCrc);
+
+ if (c == kXModemAck)
+ {
+ if (!bXModemHeaderBlock)
+ {
+ // Only do this if we're into sending the file
+ // (don't increment on the file header block).
+
+ offset += kXModemBodySize;
+ }
+
+ blockNum++;
+ bXModemHeaderBlock = false;
+ }
+ }
+
+ // Send an EOF and wait for an acknowledgement.
+
+ do
+ {
+ PrvSendChar (kXModemEof);
+ PrvReceiveChar (&c);
+ } while (c != kXModemAck);
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ SendRaw
+// ---------------------------------------------------------------------------
+
+void SendRaw (FormType* form, UInt8* romStart, Int32 romSize)
+{
+#define kRawBlockSize 1024
+
+ Err err;
+ Int32 offset = 0;
+
+ // Start by sending the size.
+
+ err = Comm_Send (&romSize, sizeof (romSize));
+ Throw_IfError (err, err);
+
+ // Now send the ROM.
+
+ while (offset < romSize)
+ {
+ // Change the status text.
+
+ UpdatePercentComplete (form, offset, romSize);
+
+ err = Comm_Send (romStart + offset, kRawBlockSize);
+ Throw_IfError (err, err);
+
+ offset += kRawBlockSize;
+ }
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ UpdatePercentComplete
+// ---------------------------------------------------------------------------
+
+void UpdatePercentComplete (FormType* form, Int32 offset, Int32 romSize)
+{
+ Int32 percentComplete = (offset * 100) / romSize;
+ char buffer[20];
+
+ PrvStrPrintF (buffer, "Sending...%d%%", percentComplete);
+
+ PrvUpdateStatus (form, buffer);
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ GetROMStartSize
+// ---------------------------------------------------------------------------
+
+void * MemHeapPtr(UInt16 heapID)
+ SYS_TRAP(sysTrapMemHeapPtr);
+
+#define memHeapFlagReadOnly 0x0001 // heap is read-only (ROM based)
+
+void GetROMStartSize (UInt8** romStartP, Int32* romSizeP)
+{
+#if 0
+ void* romStart = (void*) HwrMemReadable ((void*) 0xFFFFFFFF);
+ UInt32 romSize = HwrMemReadable (romStart);
+
+ *romStartP = romStart;
+ *romSizeP = romSize;
+#else
+ UInt16 numHeaps = MemNumHeaps (0);
+ UInt16 heapID;
+ UInt16 heapFlags;
+ UInt8* heapBegin;
+ UInt8* heapEnd;
+ UInt32 heapSize;
+
+ UInt8* romLow = (UInt8*) 0xFFFFFFFF;
+ UInt8* romHigh = (UInt8*) NULL;
+
+ for (heapID = 0; heapID < numHeaps; ++heapID)
+ {
+ heapFlags = MemHeapFlags (heapID);
+
+ if (heapFlags & memHeapFlagReadOnly)
+ {
+ heapBegin = (UInt8*) MemHeapPtr (heapID);
+ heapSize = MemHeapSize (heapID);
+ heapEnd = heapBegin + heapSize;
+
+ if (romLow > heapBegin)
+ {
+ romLow = heapBegin;
+ }
+
+ if (romHigh < heapEnd)
+ {
+ romHigh = heapEnd;
+ }
+ }
+ }
+
+ // Round up/down to 512K boundaries. (512K is the size
+ // of the Pilot 1000/5000 ROM).
+
+ #define MASK (512L * 1024 - 1)
+
+ romLow = (UInt8*) ((UInt32) romLow & ~MASK);
+ romHigh = (UInt8*) (((UInt32) romHigh + MASK) & ~MASK);
+
+ *romStartP = romLow;
+ *romSizeP = romHigh - romLow;
+#endif
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ PrvUpdateStatus
+// ---------------------------------------------------------------------------
+
+void PrvUpdateStatus (FormType* form, const char* txt)
+{
+ char buffer[100];
+ StrCopy (buffer, txt);
+ StrCat (buffer, " ");
+
+ FrmCopyLabel (form, MainStatusTextLabel, buffer);
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ PrvStrPrintF
+// ---------------------------------------------------------------------------
+// Roll our own StrPrintF, since it doesn't exist in 1.0.
+
+void PrvStrPrintF (char* dest, const char* fmt, Int32 num)
+{
+ char ch;
+ const char* s = fmt;
+ char* d = dest;
+ char numBuff[12]; // -2 xxx xxx xxx \0 = 12 bytes
+
+ while ((ch = *s++) != 0)
+ {
+ if (ch != '%')
+ {
+ *d++ = ch;
+ }
+ else
+ {
+ ch = *s++;
+
+ if (ch == 'd')
+ {
+ StrIToA (numBuff, num);
+ StrCopy (d, numBuff);
+ d += StrLen (numBuff);
+ }
+ else if (ch == 'c')
+ {
+ *d++ = (char) num;
+ }
+ else if (ch == '%')
+ {
+ *d++ = '%';
+ }
+ }
+ }
+
+ *d = 0;
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ PrvStrIToX
+// ---------------------------------------------------------------------------
+
+void PrvStrIToX (char* dest, UInt32 val)
+{
+ const char* kDigits = "0123456789ABCDEF";
+ int ii;
+
+ for (ii = 0; ii < 8; ++ii)
+ {
+ unsigned nybble = (val >> (28 - ii * 4)) & 0x0F;
+ dest[ii] = kDigits[nybble];
+ }
+
+ dest[8] = 0;
+}
diff --git a/ROMTransfer/Source/ROM_Transfer.h b/ROMTransfer/Source/ROM_Transfer.h
new file mode 100644
index 0000000..3bc9b2a
--- /dev/null
+++ b/ROMTransfer/Source/ROM_Transfer.h
@@ -0,0 +1,55 @@
+/* -*- mode: C++; tab-width: 4 -*- */
+/* ===================================================================== *\
+ Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries.
+ All rights reserved.
+
+ This file is part of the Palm OS Emulator.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+\* ===================================================================== */
+
+#ifndef ROM_TRANSFER_H
+#define ROM_TRANSFER_H
+
+
+#include "SerialPortTools.h"
+
+
+// Constants.
+
+#define kItem_1200 9
+#define kItem_2400 8
+#define kItem_4800 7
+#define kItem_9600 6
+#define kItem_14400 5
+#define kItem_19200 4
+#define kItem_28800 3
+#define kItem_38400 2
+#define kItem_57600 1
+#define kItem_115200 0
+
+// Error macros.
+
+#define Throw_IfNil(iHandle,iError) { if ((iHandle) == NULL) ErrThrow (iError); }
+#define Throw_IfError(iCode,iError) { if ((iCode) != 0) ErrThrow (iError); }
+
+// Function prototypes.
+
+UInt32 PilotMain (UInt16 iCommand,
+ void* iCommandParams,
+ UInt16 iLaunchFlags);
+
+void InitializeApplication (void);
+
+void DisposeApplication (void);
+
+void ExecuteApplication (void);
+
+Boolean ProcessEvent (EventPtr iEvent);
+
+void TransferROM (void);
+
+#endif
diff --git a/ROMTransfer/Source/ROM_Transfer.prc b/ROMTransfer/Source/ROM_Transfer.prc
new file mode 100644
index 0000000..1227cdb
--- /dev/null
+++ b/ROMTransfer/Source/ROM_Transfer.prc
Binary files differ
diff --git a/ROMTransfer/Source/SerialPortTools.c b/ROMTransfer/Source/SerialPortTools.c
new file mode 100644
index 0000000..0428a43
--- /dev/null
+++ b/ROMTransfer/Source/SerialPortTools.c
@@ -0,0 +1,388 @@
+/* -*- mode: C++; tab-width: 4 -*- */
+/* ===================================================================== *\
+ Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries.
+ All rights reserved.
+
+ This file is part of the Palm OS Emulator.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+\* ===================================================================== */
+
+#define PILOT_PRECOMPILED_HEADERS_OFF
+
+#include <PalmOS.h>
+#include <SerialMgrOld.h> // SerSettingsType
+
+#include "SerialPortTools.h"
+
+// for Handspring API access
+#define sysTrapHsSelector sysTrapOEMDispatch
+#define hsSelExtKeyboardEnable 5
+#define SYS_SEL_TRAP(trapNum, selector) \
+ _SYSTEM_API(_CALL_WITH_16BIT_SELECTOR)(_SYSTEM_TABLE, trapNum, selector)
+
+Err HsExtKeyboardEnable (Boolean enable)
+ SYS_SEL_TRAP (sysTrapHsSelector, hsSelExtKeyboardEnable);
+
+#ifndef serMgrVersion
+
+ // Bits of the Palm OS 4.0 Serial Manager we need until
+ // the SDK is available
+
+ #define sysFtrNewSerialVersion 2
+
+ #define sysSerialOpenV4 24
+ #define sysSerialOpenBkgndV4 25
+ #define sysSerialCustomControl 26
+
+ //
+ // Open Configuration Structure
+ //
+ typedef struct SrmOpenConfigType {
+ UInt32 baud; // Baud rate that the connection is to be opened at.
+ // Applications that use drivers that do not require
+ // baud rates can set this to zero or any other value.
+ // Drivers that do not require a baud rate should
+ // ignore this field
+ UInt32 function; // Designates the function of the connection. A value
+ // of zero indictates default behavior for the protocol.
+ // Drivers that do not support multiple functions should
+ // ignore this field.
+ MemPtr drvrDataP; // Pointer to driver specific data.
+ UInt16 drvrDataSize; // Size of the driver specific data block.
+ UInt32 sysReserved1; // System Reserved
+ UInt32 sysReserved2; // System Reserved
+ } SrmOpenConfigType;
+
+ typedef SrmOpenConfigType* SrmOpenConfigPtr;
+
+ Err SrmExtOpen(UInt32 port, SrmOpenConfigType* configP, UInt16 configSize, UInt16 *newPortIdP)
+ SERIAL_TRAP(sysSerialOpenV4);
+
+#endif
+
+
+// Globals.
+
+UInt16 gPortID;
+int gSerialManagerVersion;
+
+
+// ---------------------------------------------------------------------------
+// ¥ Comm_Initialize
+// ---------------------------------------------------------------------------
+// Opens the communications port.
+
+Int16 Comm_Initialize (UInt32 iBaud)
+{
+ Err err = errNone;
+ SrmOpenConfigType config;
+ SerSettingsType serSettings;
+ UInt32 srmSettings;
+ UInt16 srmSettingsSize;
+ UInt32 systemVersion;
+ UInt32 ftrValue;
+
+ // Exit if communications have already been established.
+
+ if (gPortID)
+ return (serErrAlreadyOpen);
+
+ // Clear the globals.
+
+ gPortID = 0;
+ gSerialManagerVersion = 0;
+
+ // Determine what version Serial Manager we have:
+ //
+ // 0 = undetermined
+ // 1 = Original driver in Pilot 1000/5000
+ // 2 = Updated driver in PalmPilot (new Send/Receive calls)
+ // 3 = New Serial Manager (Srm calls)
+ // 4 = Updated Serial Manager (includes SrmExtOpen call)
+
+ err = FtrGet (sysFileCSystem, sysFtrNumROMVersion, &systemVersion);
+
+ ErrFatalDisplayIf (err, "Unable to determine System version");
+
+ if (sysGetROMVerMajor(systemVersion) < 2)
+ {
+ gSerialManagerVersion = 1;
+ }
+ else
+ {
+ err = FtrGet (sysFileCSerialMgr, sysFtrNewSerialPresent, &ftrValue);
+
+ if (err || ftrValue == 0)
+ {
+ gSerialManagerVersion = 2;
+ }
+ else
+ {
+ err = FtrGet (sysFileCSerialMgr, sysFtrNewSerialVersion, &ftrValue);
+
+ if (err)
+ {
+ gSerialManagerVersion = 3;
+ }
+ else if (ftrValue <= 2)
+ {
+ gSerialManagerVersion = 3;
+
+ // Palm OS 3.5.2 for Handspring implements
+ // sysFtrNewSerialVersion and returns a feature value of 2.
+ // Palm OS 4.0 also implements sysFtrNewSerialVersion and
+ // returns a value of 2. However, the two serial managers
+ // are different: the latter implements SrmExtOpen. In
+ // order to differentiate between the two, we have to check
+ // the OS version.
+
+ if (ftrValue == 2 && sysGetROMVerMajor (systemVersion) >= 4)
+ {
+ gSerialManagerVersion = 4;
+ }
+ }
+ else
+ {
+ // ftrValue should be at least 3 for versions of the
+ // Serial Manager that implement SrmExtOpen.
+
+ gSerialManagerVersion = ftrValue + 1;
+ }
+ }
+ }
+
+ // <chg 02-01-2000 BP> If on Handspring device, disable the keyboard
+ // thread before opening the serial library.
+
+ if (FtrGet ('hsEx', 0, &ftrValue) == errNone)
+ {
+ HsExtKeyboardEnable (false);
+ }
+
+ // Open the serial port in a manner appropriate for this platform.
+
+ if (gSerialManagerVersion <= 2)
+ {
+ // Find the serial library.
+
+ err = SysLibFind ("Serial Library", &gPortID);
+ if (err != errNone)
+ return (err);
+
+ // Open the serial port.
+
+ err = SerOpen (gPortID, kPort_Pilot, iBaud);
+ if (err != errNone)
+ goto Exit;
+
+ // Set the serial attributes.
+
+ serSettings.baudRate = iBaud;
+ serSettings.flags = serSettingsFlagBitsPerChar8 | serSettingsFlagStopBits1;
+ serSettings.ctsTimeout = serDefaultCTSTimeout;
+
+ err = SerSetSettings (gPortID, &serSettings);
+ if (err != errNone)
+ goto Exit;
+ }
+ else // if (gSerialManagerVersion >= 3)
+ {
+ // Open the serial port.
+
+ if (gSerialManagerVersion == 3)
+ {
+ err = SrmOpen (serPortLocalHotSync, iBaud, &gPortID);
+ }
+ else
+ {
+ MemSet (&config, sizeof (config), 0);
+
+ config.baud = iBaud;
+ config.function = 'ROMX';
+
+ err = SrmExtOpen ( serPortLocalHotSync,
+ &config, sizeof (config),
+ &gPortID);
+ }
+
+ if (err != errNone)
+ goto Exit;
+
+ // Set the serial attributes.
+
+ srmSettings = srmSettingsFlagBitsPerChar8 | srmSettingsFlagStopBits1;
+ srmSettingsSize = sizeof (srmSettings);
+ err = SrmControl (gPortID, srmCtlSetFlags,
+ &srmSettings, &srmSettingsSize);
+ if (err != errNone)
+ goto Exit;
+ }
+
+Exit:
+ if (err != errNone)
+ {
+ if (gPortID)
+ {
+ SrmClose (gPortID);
+ gPortID = 0;
+ }
+ }
+
+ return err;
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ Comm_Receive
+// ---------------------------------------------------------------------------
+
+Err Comm_Receive (void* bufP, UInt32 count, UInt32 timeout)
+{
+ Err err;
+
+ if (gSerialManagerVersion == 1)
+ {
+ err = SerReceive10 (gPortID, bufP, count, timeout);
+ }
+ else if (gSerialManagerVersion == 2)
+ {
+ (void) SerReceive (gPortID, bufP, count, timeout, &err);
+ }
+ else // if (gSerialManagerVersion >= 3)
+ {
+ (void) SrmReceive (gPortID, bufP, count, timeout, &err);
+ }
+
+ return err;
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ Comm_Send
+// ---------------------------------------------------------------------------
+
+#define CORRUPT_SENDS 0
+
+#if CORRUPT_SENDS
+static UInt32 PrvRange (UInt32 maxValue)
+{
+ static int initialized;
+ if (!initialized)
+ {
+ initialized = true;
+ SysRandom (1);
+ }
+
+ return (SysRandom (0) * maxValue) / (1UL + sysRandomMax);
+}
+#endif
+
+
+Err Comm_Send (void* bufP, UInt32 count)
+{
+ Err err;
+
+#if CORRUPT_SENDS
+ void* buf2 = MemPtrNew (count);
+
+ MemMove (buf2, bufP, count);
+
+ bufP = buf2;
+
+ if (PrvRange (100) <= (count / 100))
+ {
+ // Corrupt a character
+
+ ((char*) bufP)[PrvRange (count)]++;
+ }
+ else if (PrvRange (100) <= (count / 100))
+ {
+ // Drop a character
+
+ UInt32 index = PrvRange (count);
+
+ if (count - index - 1 > 0)
+ {
+ MemMove ((char*) bufP + index,
+ (char*) bufP + index + 1,
+ count - index - 1);
+ }
+ count--;
+ }
+#endif
+
+ if (gSerialManagerVersion == 1)
+ {
+ err = SerSend10 (gPortID, bufP, count);
+ }
+ else if (gSerialManagerVersion == 2)
+ {
+ (void) SerSend (gPortID, bufP, count, &err);
+ }
+ else // if (gSerialManagerVersion >= 3)
+ {
+ (void) SrmSend (gPortID, bufP, count, &err);
+ }
+
+#if CORRUPT_SENDS
+ MemPtrFree (bufP);
+#endif
+
+ return err;
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ Comm_Dispose
+// ---------------------------------------------------------------------------
+// Closes the communications port.
+
+void Comm_Dispose (void)
+{
+ // Exit if communications have not been established.
+
+ if (!gPortID)
+ return;
+
+ // Close the serial port.
+
+ if (gSerialManagerVersion <= 2)
+ {
+ SerClose (gPortID);
+ }
+ else // if (gSerialManagerVersion >= 3)
+ {
+ SrmClose (gPortID);
+ }
+
+ // Clear the globals.
+
+ gPortID = 0;
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ Comm_ClearError
+// ---------------------------------------------------------------------------
+// Clears the current serial errors.
+
+void Comm_ClearError (void)
+{
+ // Exit if communications have not been established.
+
+ if (!gPortID)
+ return;
+
+ if (gSerialManagerVersion <= 2)
+ {
+ SerClearErr (gPortID);
+ }
+ else // if (gSerialManagerVersion >= 3)
+ {
+ SrmClearErr (gPortID);
+ }
+}
diff --git a/ROMTransfer/Source/SerialPortTools.h b/ROMTransfer/Source/SerialPortTools.h
new file mode 100644
index 0000000..bf25cde
--- /dev/null
+++ b/ROMTransfer/Source/SerialPortTools.h
@@ -0,0 +1,52 @@
+/* -*- mode: C++; tab-width: 4 -*- */
+/* ===================================================================== *\
+ Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries.
+ All rights reserved.
+
+ This file is part of the Palm OS Emulator.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+\* ===================================================================== */
+
+#ifndef SERIAL_PORT_TOOLS_H
+#define SERIAL_PORT_TOOLS_H
+
+// Globals.
+
+#define kPort_Pilot 0
+
+#define kBaud_1200 1200
+#define kBaud_2400 2400
+#define kBaud_4800 4800
+#define kBaud_9600 9600
+#define kBaud_14400 14400
+#define kBaud_19200 19200
+#define kBaud_28800 28800
+#define kBaud_38400 38400
+#define kBaud_57600 57600
+#define kBaud_57600 57600
+#define kBaud_115200 115200
+
+
+// Prototypes.
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+Int16 Comm_Initialize (UInt32 iBaud);
+Err Comm_Receive (void* bufP, UInt32 count, UInt32 timeout);
+Err Comm_Send (void* bufP, UInt32 count);
+void Comm_Dispose (void);
+void Comm_ClearError (void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif