avrsim.pp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. {******************************************************************************
  2. Startup code for an avr simulator
  3. ******************************************************************************}
  4. unit avrsim;
  5. interface
  6. var
  7. OUTPUTREG : byte absolute $20;
  8. EXITCODEREG : byte absolute $21;
  9. HALTREQUEST : byte absolute $22;
  10. EXCEPTIONJMPZERO : boolean absolute 52;
  11. implementation
  12. uses
  13. consoleio,heapmgr;
  14. procedure PASCALMAIN; external name 'PASCALMAIN';
  15. procedure _FPC_haltproc; public name '_haltproc'; noreturn;
  16. begin
  17. EXITCODEREG:=exitcode;
  18. HALTREQUEST:=1;
  19. { really stop }
  20. while true do
  21. ;
  22. end;
  23. var
  24. _data: record end; external name '__data_start';
  25. _edata: record end; external name '__data_end';
  26. _etext: record end; external name '_etext';
  27. _bss_start: record end; external name '__bss_start';
  28. _bss_end: record end; external name '__bss_end';
  29. _stack_top: record end; external name '_stack_top';
  30. __dtors_end: record end; external name '__dtors_end';
  31. procedure _FPC_start; assembler; nostackframe; noreturn; public name '_START'; section '.init';
  32. asm
  33. jmp __dtors_end // Jump to last linker symbol before .init0
  34. // Interrupt vectors to be added here
  35. end;
  36. procedure _FPC_init_zeroreg_SP; assembler; nostackframe; noreturn; public name '_init_zeroreg_SP'; section '.init2';
  37. asm
  38. {$ifdef CPUAVR_16_REGS}
  39. clr r17
  40. {$else CPUAVR_16_REGS}
  41. clr r1
  42. {$endif CPUAVR_16_REGS}
  43. {$ifndef CPUAVR1}
  44. // load stack pointer
  45. ldi r30,lo8(_stack_top)
  46. out 0x3d,r30
  47. ldi r30,hi8(_stack_top)
  48. out 0x3e,r30
  49. {$endif CPUAVR1}
  50. end;
  51. procedure _FPC_copy_data; assembler; nostackframe; noreturn; section '.init4';
  52. asm
  53. // Initialize .data section
  54. ldi XL,lo8(_data)
  55. ldi XH,hi8(_data)
  56. ldi YH,hi8(_edata)
  57. ldi ZL,lo8(_etext)
  58. {$ifdef CPUAVR_16_REGS}
  59. ldi ZH,hi8(_etext)+(0x40) // program memory mapped to $4000 in data space
  60. {$else CPUAVR_16_REGS}
  61. ldi ZH,hi8(_etext)
  62. {$endif CPUAVR_16_REGS}
  63. rjmp .LCopyDataLoopEntry
  64. .LCopyDataLoop:
  65. {$ifdef CPUAVR_16_REGS}
  66. ld r16, Z+
  67. {$else CPUAVR_16_REGS}
  68. lpm r16, Z+
  69. {$endif CPUAVR_16_REGS}
  70. st X+, r16
  71. .LCopyDataLoopEntry:
  72. cpi XL, lo8(_edata)
  73. cpc XH, YH
  74. brne .LCopyDataLoop
  75. // Zero .bss section
  76. ldi XL,lo8(_bss_start)
  77. ldi XH,hi8(_bss_start)
  78. ldi YH,hi8(_bss_end)
  79. {$ifdef RELBRANCHES}
  80. rjmp .LZeroBssLoopEntry
  81. {$else RELBRANCHES}
  82. jmp .LZeroBssLoopEntry
  83. {$endif RELBRANCHES}
  84. .LZeroBssLoop:
  85. {$ifdef CPUAVR_16_REGS}
  86. st X+, r17
  87. {$else CPUAVR_16_REGS}
  88. st X+, r1
  89. {$endif CPUAVR_16_REGS}
  90. .LZeroBssLoopEntry:
  91. cpi XL, lo8(_bss_end)
  92. cpc XH, YH
  93. brne .LZeroBssLoop
  94. end;
  95. procedure _FPC_jmp_main; noreturn; assembler; nostackframe; section '.init9';
  96. asm
  97. {$ifdef RELBRANCHES}
  98. rjmp PASCALMAIN
  99. {$else RELBRANCHES}
  100. jmp PASCALMAIN
  101. {$endif RELBRANCHES}
  102. end;
  103. function WriteChar(ACh: AnsiChar; AUserData: pointer): boolean;
  104. begin
  105. WriteChar:=true;
  106. OUTPUTREG:=ord(ACh);
  107. end;
  108. function ReadChar(var ACh: AnsiChar; AUserData: pointer): boolean;
  109. begin
  110. ReadChar:=true;
  111. ACh:=#0;
  112. end;
  113. begin
  114. EXCEPTIONJMPZERO:=true;
  115. OpenIO(Input, @WriteChar, @ReadChar, fmInput, nil);
  116. OpenIO(Output, @WriteChar, @ReadChar, fmOutput, nil);
  117. OpenIO(ErrOutput, @WriteChar, @ReadChar, fmOutput, nil);
  118. OpenIO(StdOut, @WriteChar, @ReadChar, fmOutput, nil);
  119. OpenIO(StdErr, @WriteChar, @ReadChar, fmOutput, nil);
  120. end.