exp_farg.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /* exp_farg.c: Routines to export to a Fargo file
  2. Copyright (C) 2002-2003 Sebastian Reichelt
  3. Copyright (C) 2003 Kevin Kofler
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software Foundation,
  14. Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  15. #include "exp_farg.h"
  16. #ifdef FARGO_SUPPORT
  17. #include "../manip.h"
  18. // Fargo TI-BASIC fork
  19. static const I1 FARGO_TIBASIC_FORK[] = {
  20. 0xE9, // ENDSTACK_TAG
  21. 0x12, 0xE4, // 'EndPrgm'
  22. 0x00, 0xE8, // Newline
  23. 0x19, 0xE4, // 'Prgm'
  24. 0xE5, // No arguments, END_TAG only
  25. 0x00, 0x00, 0x40 // Flags
  26. };
  27. // Get the file size needed to export the program into a Fargo file.
  28. // Returns 0 on failure.
  29. // Call this function once to receive necessary error messages.
  30. SIZE GetFargoFileSize (const PROGRAM *Program)
  31. {
  32. // Get a pointer to the main section.
  33. SECTION *MainSection = Program->MainSection;
  34. // There must be exactly one section.
  35. if (!MainSection)
  36. {
  37. Error (NULL, "No main section.");
  38. return 0;
  39. }
  40. // The program consists of a TI-Basic fork and the section.
  41. return (MainSection->Size + sizeof (FARGO_TIBASIC_FORK));
  42. }
  43. // Export the internal data structures into a Fargo file.
  44. BOOLEAN ExportFargoFile (const PROGRAM *Program, EXP_FILE *File, SIZE FileSize ATTRIBUTE_UNUSED, ProgramCalcs DestCalc ATTRIBUTE_UNUSED)
  45. {
  46. // A simple macro to make the code more readable.
  47. #define FailWithError(Err...) ({ Error (Err); return FALSE; })
  48. const char *SectionFileName = NULL;
  49. OFFSET DataStart = 0;
  50. // Get a pointer to the first section.
  51. SECTION *MainSection = Program->MainSection;
  52. if (!MainSection)
  53. FailWithError (NULL, "No main section.");
  54. // Get the section file name for error messages.
  55. SectionFileName = MainSection->FileName;
  56. // Startup code should always be marked as such. When merging
  57. // sections, the destination startup number is kept, so in the
  58. // end, the complete code is marked as a startup section (which
  59. // makes sense; it is startable).
  60. if (!(MainSection->StartupNumber))
  61. FailWithError (SectionFileName, "No startup section(s) defined.");
  62. if (!(MainSection->Data))
  63. FailWithError (SectionFileName, "No section contents.");
  64. // Write out the section contents first.
  65. DataStart = ExportTell (File);
  66. ExportWrite (File, MainSection->Data, MainSection->Size, 1);
  67. // Write out the TI-BASIC fork.
  68. ExportWrite (File, FARGO_TIBASIC_FORK, sizeof (FARGO_TIBASIC_FORK), 1);
  69. if (!(IsEmpty (MainSection->Relocs)))
  70. {
  71. RELOC *Reloc;
  72. for_each (Reloc, MainSection->Relocs)
  73. {
  74. // If this can be resolved to a calculator-dependent value, write the
  75. // value into the section data.
  76. if (!(EmitCalcBuiltinValue (Reloc, DestCalc, File, FileSize, DataStart)))
  77. FailWithError (SectionFileName, "Fargo does not support AMS relocs.");
  78. }
  79. }
  80. if ((!(IsEmpty (MainSection->ROMCalls))) && (!(MainSection->ROMCalls.Handled)))
  81. FailWithError (SectionFileName, "Fargo does not support ROM calls. Use `tios__0000' and so on.");
  82. if ((!(IsEmpty (MainSection->RAMCalls))) && (!(MainSection->RAMCalls.Handled)))
  83. FailWithError (SectionFileName, "Fargo does not support RAM calls. Use `kernel__0000' and so on.");
  84. if ((!(IsEmpty (MainSection->LibCalls))) && (!(MainSection->LibCalls.Handled)))
  85. FailWithError (SectionFileName, "Library calls are not supported in this mode.");
  86. return TRUE;
  87. #undef FailWithError
  88. }
  89. #endif /* FARGO_SUPPORT */