/* * Key Map Editor ver 1.0 * Key Map IO * * by: Tim Friest * on: January 1, 1989 */ #include "KME_Includes.h" #include "KME_Protos.h" #include "KME_Defs.h" #include "KME_Globals.h" #define LongToByteArr(a, l) a[3] = (l & 0x000000FF); a[2] = ((l & 0x0000FF00)>>8); a[1] = ((l & 0x00FF0000)>>16); a[0] = ((l & 0xFF000000)>>24) #define HUNK_HEADER 0x3F3 #define HUNK_CODE 0x3E9 #define HUNK_RELOC32 0x3EC #define HUNK_END 0x3F2 struct RelocNode { struct RelocNode *Next; ULONG Offset; }; struct KeyMap_Hunk { ULONG Hunk; ULONG Length; struct KeyMapNode kh_KeyMapNode; UBYTE kh_LoKeyMapTypes[0x40]; ULONG kh_LoKeyMap[0x40]; UBYTE kh_LoCapsable[0x08]; UBYTE kh_LoRepeatable[0x08]; UBYTE kh_HiKeyMapTypes[0x38]; ULONG kh_HiKeyMap[0x38]; UBYTE kh_HiCapsable[0x07]; UBYTE kh_HiRepeatable[0x07]; }; struct KeyMap_Hunk *CodeSegment; struct RelocNode *RelocList = NULL; extern struct KeyMapNode *ConvertKeyMap(struct KeyMapNode *); extern ULONG MakeCodeSeg(struct KeyMapNode *, char *); extern int InsertRelocList(ULONG); /* * KeyMapIO * * parameters: Filename - String pointer to filename * Option - IO option (Read or Write) */ void KeyMapIO(filename, Option) char *filename; int Option; { if (Option == LOAD) { if ((filename = ProcFileReq("Load")) != NULL) { if (!ReadKeyMap(filename)) KeyMapNode = MakeNewKeyMap(); UpdateDisplay(GadgetList, KeyMapNode, TRUE); } else if (!(CheckResource(RF_KeyMap))) KeyMapNode = MakeNewKeyMap(); } else if (Option == SAVE) { if ((filename = ProcFileReq("Save")) != NULL) WriteKeyMap(filename); } } /* * ReadKeyMap * * parameter: Filename - Filename of KeyMap to read * returns: Result - Success of operation (TRUE or FALSE) */ int ReadKeyMap(filename) char *filename; { if (CheckResource(RF_KeyMap)) { FreeKeyMap(KeyMapNode); ClearResource(RF_KeyMap); } if ((KeyMapSegment = LoadSeg(filename)) == NULL) { Write(Output(), "Error ReadKeyMap: LoadSeg failed\n", 33); return(FALSE); } if ((KeyMapNode = ConvertKeyMap((struct KeyMapNode *)BADDR((KeyMapSegment+1)))) == NULL) { Write(Output(), "Error ReadKeyMap: ConvertKeyMap Failed\n", 39); return(FALSE); } UnLoadSeg(KeyMapSegment); FlagResource(RF_KeyMap); return(TRUE); } /* * Convert Key Map Strings to freememable places * * parameters: KeyMapNode - Key Map Node structure * * returns: Success - TRUE or FALSE */ struct KeyMapNode *ConvertKeyMap(OldKeyMapNode) struct KeyMapNode *OldKeyMapNode; { USHORT KeyCode; struct HalfKeyMap *HalfKeyMap; int length, maphalf; UBYTE len, HeaderLen; struct KeyMapNode *NewKeyMapNode; UBYTE *old, *new; if ((NewKeyMapNode = (struct KeyMapNode *)AllocMem((KeyNodeSize + KeyMapSize), MEMF_CLEAR)) == NULL) { Write(Output(), "Memory Allocation failed, ConvertKeyMap:KeyMap\n", 47); return(NULL); } memcpy((UBYTE *)NewKeyMapNode, (UBYTE *)OldKeyMapNode, KeyNodeSize); new = ((UBYTE *)NewKeyMapNode) + KeyNodeSize; memcpy(new, OldKeyMapNode->kn_KeyMap.km_LoKeyMapTypes, 0x40); NewKeyMapNode->kn_KeyMap.km_LoKeyMapTypes = new; new += 0x40; memcpy(new, (UBYTE *)OldKeyMapNode->kn_KeyMap.km_LoKeyMap, (0x40*4)); NewKeyMapNode->kn_KeyMap.km_LoKeyMap = (long *)new; new += (0x40 * 4); memcpy(new, OldKeyMapNode->kn_KeyMap.km_LoCapsable, 0x08); NewKeyMapNode->kn_KeyMap.km_LoCapsable = new; new += 0x08; memcpy(new, OldKeyMapNode->kn_KeyMap.km_LoRepeatable, 0x08); NewKeyMapNode->kn_KeyMap.km_LoRepeatable = new; new += 0x08; memcpy(new, OldKeyMapNode->kn_KeyMap.km_HiKeyMapTypes, 0x38); NewKeyMapNode->kn_KeyMap.km_HiKeyMapTypes = new; new += 0x38; memcpy(new, (UBYTE *)OldKeyMapNode->kn_KeyMap.km_HiKeyMap, (0x38*4)); NewKeyMapNode->kn_KeyMap.km_HiKeyMap = (long *)new; new += (0x38 * 4); memcpy(new, OldKeyMapNode->kn_KeyMap.km_HiCapsable, 0x07); NewKeyMapNode->kn_KeyMap.km_HiCapsable = new; new += 0x07; memcpy(new, OldKeyMapNode->kn_KeyMap.km_HiRepeatable, 0x07); NewKeyMapNode->kn_KeyMap.km_HiRepeatable = new; HalfKeyMap = (struct HalfKeyMap *)&NewKeyMapNode->kn_KeyMap; maphalf = 0; KeyCode = 0x00; while (maphalf < 2) if (((maphalf == 0) && (KeyCode < 0x40)) || ((maphalf == 1) && (KeyCode < 0x38))) { switch (HalfKeyMap->KeyMapTypes[KeyCode] & (KCF_STRING|KCF_DEAD|KCF_NOP)) { case KCF_STRING: len = StringKeyLength(HalfKeyMap, KeyCode, &HeaderLen); if ((new = (UBYTE *)AllocMem(len, MEMF_CLEAR)) == NULL) { Write(Output(), "Memory allocation failed, ConvertKeyMap:String\n", 47); return(NULL); } CopyStringKey(HalfKeyMap, KeyCode, new, HeaderLen); HalfKeyMap->KeyMap[KeyCode] = (ULONG)new; break; case KCF_DEAD: len = DeadKeyLength(HalfKeyMap, KeyCode, &HeaderLen); if ((new = (UBYTE *)AllocMem(len, MEMF_CLEAR)) == NULL) { Write(Output(), "Memory allocation failed, ConvertKeyMap:Dead\n", 46); return(NULL); } CopyDeadKey(HalfKeyMap, KeyCode, new, HeaderLen); HalfKeyMap->KeyMap[KeyCode] = (ULONG)new; } /* switch */ KeyCode += 1; } else { KeyCode = 0x00; HalfKeyMap = (struct HalfKeyMap *)&NewKeyMapNode->kn_KeyMap.km_HiKeyMapTypes; maphalf += 1; } old = OldKeyMapNode->kn_Node.ln_Name; length = strlen(old) + 1; if ((new = (UBYTE *)AllocMem(length, MEMF_CLEAR)) == NULL) { Write(Output(), "Memory Allocation Failed, ConvertKeyMap:NodeName\n", 49); return(NULL); } strcpy(new, old); NewKeyMapNode->kn_Node.ln_Name = (char *)new; return(NewKeyMapNode); } /* * Free Key Map * * parameter: KeyMapNode - Key Map Node to free */ void FreeKeyMap(FreeKeyMapNode) struct KeyMapNode *FreeKeyMapNode; { UBYTE *buff; UBYTE len, headerlen; struct HalfKeyMap *HalfKeyMap; USHORT KeyCode; int maphalf, length; if ((buff = FreeKeyMapNode->kn_Node.ln_Name) != NULL) { length = strlen(buff) + 1; FreeMem(buff, length); } HalfKeyMap = (struct HalfKeyMap *)&FreeKeyMapNode->kn_KeyMap.km_HiKeyMapTypes; maphalf = 1; KeyCode = 0x37; while (maphalf >= 0) { KeyCode -= 1; switch (HalfKeyMap->KeyMapTypes[KeyCode] & (KCF_STRING|KCF_DEAD|KCF_NOP)) { case KCF_STRING: buff = (UBYTE *)HalfKeyMap->KeyMap[KeyCode]; len = StringKeyLength(HalfKeyMap, KeyCode, &headerlen); FreeMem(buff, len); break; case KCF_DEAD: buff = (UBYTE *)HalfKeyMap->KeyMap[KeyCode]; len = DeadKeyLength(HalfKeyMap, KeyCode, &headerlen); FreeMem(buff, len); } /* switch */ if (KeyCode == 0x00) { KeyCode = 0x3F; HalfKeyMap = (struct HalfKeyMap *)&FreeKeyMapNode->kn_KeyMap; maphalf -= 1; } } /* while */ FreeMem((UBYTE *)FreeKeyMapNode, (KeyNodeSize + KeyMapSize)); ClearFlag(RF_KeyMap); } /* * WriteKeyMap * * parameter: Filename - Filename of KeyMap to read * returns: Result - Success of operation (TRUE or FALSE) */ int WriteKeyMap(filename) char *filename; { BPTR File; ULONG CodeLen, RelocLen; struct RelocNode *temp, *next; UBYTE bytes[4]; int status = TRUE; if ((CodeLen = MakeCodeSeg(KeyMapNode, filename)) == NULL) { Write(Output(), "HUNK_CODE Creation Error\n", 24); goto EndWrite; } if ((File = Open(filename, MODE_NEWFILE)) == NULL) return(FALSE); /* Creating an executable HUNK */ LongToByteArr(bytes, HUNK_HEADER); if (Write(File, bytes, 4) != 4) { Write(Output(), "Write Error, Hunk_Header\n", 25); status = FALSE; goto EndWrite; } /* No libraries used */ LongToByteArr(bytes, 0); if (Write(File, bytes, 4) != 4) { Write(Output(), "Write Error, Hunk_Header libname\n", 34); status = FALSE; goto EndWrite; } /* Hunk table size */ LongToByteArr(bytes, 1); if (Write(File, bytes, 4) != 4) { Write(Output(), "Write Error, Hunk_Header table\n", 31); status = FALSE; goto EndWrite; } /* First hunk */ LongToByteArr(bytes, 0); if (Write(File, bytes, 4) != 4) { Write(Output(), "Write Error, Hunk_Header first hunk\n", 36); status = FALSE; goto EndWrite; } /* Last hunk */ LongToByteArr(bytes, 0); if (Write(File, bytes, 4) != 4) { Write(Output(), "Write Error, Hunk_Header last hunk\n", 35); status = FALSE; goto EndWrite; } /* write Hunk sizes (number of longwords) */ LongToByteArr(bytes, ((CodeLen>>2)-2)); if (Write(File, bytes, 4) != 4) { Write(Output(), "Write Error, Hunk_Header sizes\n", 31); status = FALSE; goto EndWrite; } /* write HUNK_CODE */ if (Write(File, (UBYTE *)CodeSegment, CodeLen) != CodeLen) { Write(Output(), "Write Error, HUNK_CODE\n", 22); status = FALSE; goto EndWrite; } /* write Hunk_Reloc32 */ LongToByteArr(bytes, HUNK_RELOC32); if (Write(File, bytes, 4) != 4) { Write(Output(), "Write Error, Hunk_Reloc32\n", 26); status = FALSE; goto EndWrite; } for (temp = RelocList, RelocLen = 0; temp; (temp = temp->Next), RelocLen++); /* write hunk_reloc32 length (number of longwords) */ if (Write(File, (UBYTE *)&RelocLen, 4) != 4) { Write(Output(), "Write Error, Hunk_Reloc32 Length\n", 33); status = FALSE; goto EndWrite; } /* write hunk_reloc32 hunk number effected */ LongToByteArr(bytes, 0); if (Write(File, bytes, 4) != 4) { Write(Output(), "Write Error, Hunk_Reloc32 hunk number\n", 38); status = FALSE; goto EndWrite; } /* write hunk_reloc32 offsets */ for (temp = RelocList; temp; temp = temp->Next) if (Write(File, (UBYTE *)&temp->Offset, 4) != 4) { Write(Output(), "Write Error, Hunk_Reloc32 offset\n", 33); status = FALSE; goto EndWrite; } /* write end Hunk_Reloc32 */ LongToByteArr(bytes, 0); if (Write(File, bytes, 4) != 4) { Write(Output(), "Write Error, Hunk_Reloc32 end\n", 30); status = FALSE; goto EndWrite; } /* write Hunk_End */ LongToByteArr(bytes, HUNK_END); if (Write(File, bytes, 4) != 4) { Write(Output(), "Write Error, Hunk_End\n", 22); status = FALSE; goto EndWrite; } EndWrite: Close(File); FreeMem((UBYTE *)CodeSegment, CodeLen); for (temp = RelocList; temp; temp = next) { next = temp->Next; FreeMem((UBYTE *)temp, sizeof(struct RelocNode)); } if (status) { SetProtection(filename, 0x02); ClearFlag(SF_Modified); } return(status); } /* * Make Code Segment * * Convert KeyMap to a HUNK_CODE hunk * * parameter: KeyMapNode - Pointer to Key Map Node * returns: LoadSeg - Pointer to LoadSeg */ ULONG MakeCodeSeg(KeyMapNode, filename) struct KeyMapNode *KeyMapNode; char *filename; { UBYTE *Segment; struct KeyMap *KeyMap; ULONG *NewKeyMap; struct HalfKeyMap *HalfKeyMap, *NewHalfKeyMap; USHORT KeyCode; int maphalf; ULONG SegmentLen, len, offset; UBYTE headerlen; len = sizeof(struct KeyMap_Hunk); HalfKeyMap = (struct HalfKeyMap *)&KeyMapNode->kn_KeyMap; maphalf = 0; KeyCode = 0x00; while (maphalf < 2) if (((maphalf == 0) && (KeyCode < 0x40)) || ((maphalf == 1) && (KeyCode < 0x38))) { switch (HalfKeyMap->KeyMapTypes[KeyCode] & (KCF_STRING|KCF_DEAD|KCF_NOP)) { case KCF_STRING: len += StringKeyLength(HalfKeyMap, KeyCode, &headerlen); break; case KCF_DEAD: len += DeadKeyLength(HalfKeyMap, KeyCode, &headerlen); } /* switch */ KeyCode += 1; } else { KeyCode = 0x00; HalfKeyMap = (struct HalfKeyMap *)&KeyMapNode->kn_KeyMap.km_HiKeyMapTypes; maphalf += 1; } len += strlen(filename) + 1; len = (len & 0x03)?((len & ~0x03)+4):len; if ((CodeSegment = (struct KeyMap_Hunk *)AllocMem(len, MEMF_CLEAR)) == NULL) { Write(Output(), "Memory Allocation Failed, MakeCodeSeg:CodeSegment\n", 50); return(NULL); } SegmentLen = (len>>2) - 2; CodeSegment->Hunk = HUNK_CODE; CodeSegment->Length = SegmentLen; Segment = (UBYTE *)&CodeSegment->kh_KeyMapNode; offset = sizeof(struct KeyMap_Hunk) - 8; memcpy(Segment, (UBYTE *)KeyMapNode, offset); KeyMap = &CodeSegment->kh_KeyMapNode.kn_KeyMap; KeyMap->km_LoKeyMapTypes = (UBYTE *)((ULONG)&CodeSegment->kh_LoKeyMapTypes - (ULONG)&CodeSegment->kh_KeyMapNode); if (!InsertRelocList((ULONG)&KeyMap->km_LoKeyMapTypes - (ULONG)&CodeSegment->kh_KeyMapNode)) return(NULL); KeyMap->km_LoKeyMap = (ULONG *)((ULONG)&CodeSegment->kh_LoKeyMap - (ULONG)&CodeSegment->kh_KeyMapNode); if (!InsertRelocList((ULONG)&KeyMap->km_LoKeyMap - (ULONG)&CodeSegment->kh_KeyMapNode)) return(NULL); KeyMap->km_LoCapsable = (UBYTE *)((ULONG)&CodeSegment->kh_LoCapsable - (ULONG)&CodeSegment->kh_KeyMapNode); if (!InsertRelocList((ULONG)&KeyMap->km_LoCapsable - (ULONG)&CodeSegment->kh_KeyMapNode)) return(NULL); KeyMap->km_LoRepeatable = (UBYTE *)((ULONG)&CodeSegment->kh_LoRepeatable - (ULONG)&CodeSegment->kh_KeyMapNode); if (!InsertRelocList((ULONG)&KeyMap->km_LoRepeatable - (ULONG)&CodeSegment->kh_KeyMapNode)) return(NULL); KeyMap->km_HiKeyMapTypes = (UBYTE *)((ULONG)&CodeSegment->kh_HiKeyMapTypes - (ULONG)&CodeSegment->kh_KeyMapNode); if (!InsertRelocList((ULONG)&KeyMap->km_HiKeyMapTypes - (ULONG)&CodeSegment->kh_KeyMapNode)) return(NULL); KeyMap->km_HiKeyMap = (ULONG *)((ULONG)&CodeSegment->kh_HiKeyMap - (ULONG)&CodeSegment->kh_KeyMapNode); if (!InsertRelocList((ULONG)&KeyMap->km_HiKeyMap - (ULONG)&CodeSegment->kh_KeyMapNode)) return(NULL); KeyMap->km_HiCapsable = (UBYTE *)((ULONG)&CodeSegment->kh_HiCapsable - (ULONG)&CodeSegment->kh_KeyMapNode); if (!InsertRelocList((ULONG)&KeyMap->km_HiCapsable - (ULONG)&CodeSegment->kh_KeyMapNode)) return(NULL); KeyMap->km_HiRepeatable = (UBYTE *)((ULONG)&CodeSegment->kh_HiRepeatable - (ULONG)&CodeSegment->kh_KeyMapNode); if (!InsertRelocList((ULONG)&KeyMap->km_HiRepeatable - (ULONG)&CodeSegment->kh_KeyMapNode)) return(NULL); HalfKeyMap = (struct HalfKeyMap *)&KeyMapNode->kn_KeyMap; NewKeyMap = CodeSegment->kh_LoKeyMap; NewHalfKeyMap = (struct HalfKeyMap *)&CodeSegment->kh_KeyMapNode.kn_KeyMap; maphalf = 0; KeyCode = 0x00; while (maphalf < 2) if (((maphalf == 0) && (KeyCode < 0x40)) || ((maphalf == 1) && (KeyCode < 0x38))) { switch (HalfKeyMap->KeyMapTypes[KeyCode] & (KCF_STRING|KCF_DEAD|KCF_NOP)) { case KCF_STRING: len = StringKeyLength(HalfKeyMap, KeyCode, &headerlen); len = CopyStringKey(HalfKeyMap, KeyCode, &Segment[offset], headerlen); NewKeyMap[KeyCode] = offset; if (!InsertRelocList((ULONG)&NewHalfKeyMap->KeyMap[KeyCode])) return(NULL); offset += len; break; case KCF_DEAD: len = DeadKeyLength(HalfKeyMap, KeyCode, &headerlen); len = CopyDeadKey(HalfKeyMap, KeyCode, &Segment[offset], headerlen); NewKeyMap[KeyCode] = offset; if (!InsertRelocList((ULONG)&NewHalfKeyMap->KeyMap[KeyCode])) return(NULL); offset += len; } /* switch */ KeyCode += 1; } else { KeyCode = 0x00; HalfKeyMap = (struct HalfKeyMap *)&KeyMapNode->kn_KeyMap.km_HiKeyMapTypes; NewKeyMap = CodeSegment->kh_HiKeyMap; NewHalfKeyMap = (struct HalfKeyMap *)&CodeSegment->kh_KeyMapNode.kn_KeyMap.km_HiKeyMapTypes; maphalf += 1; } len = strlen(filename) + 1; memcpy(&Segment[offset], filename, len); CodeSegment->kh_KeyMapNode.kn_Node.ln_Name = (UBYTE *)offset; if (!InsertRelocList((ULONG)&CodeSegment->kh_KeyMapNode.kn_Node.ln_Name - (ULONG)Segment)) return(NULL); return((SegmentLen+2)<<2); } /* * Insert Reloc List * * parameter: Offset - offset of pointer * return: Success - TRUE if success */ int InsertRelocList(offset) ULONG offset; { struct RelocNode *new, *temp, *prev; prev = NULL; for (temp = RelocList; (temp != NULL) && (temp->Offset > offset); temp = temp->Next) prev = temp; if ((new = (struct RelocNode *)AllocMem(sizeof(struct RelocNode), MEMF_CLEAR)) == NULL) { Write(Output(), "Memory Allocation Failed, InsertRelocList\n", 42); return(FALSE); } new->Offset = offset; new->Next = temp; if (prev == NULL) RelocList = new; else prev->Next = new; return(TRUE); }