si_prc.pp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2020 by Free Pascal development team
  4. This file contains startup code for the ZX Spectrum
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit si_prc;
  12. {$SMARTLINK OFF}
  13. interface
  14. implementation
  15. {$GOTO ON}
  16. var
  17. FPC_SAVE_IY: word; external name 'FPC_SAVE_IY';
  18. fpc_stackarea_start: word; external name '__fpc_stackarea_start';
  19. fpc_stackarea_end: word; external name '__fpc_stackarea_end';
  20. procedure PascalMain; external name 'PASCALMAIN';
  21. { this *must* always remain the first procedure with code in this unit }
  22. procedure _start; assembler; nostackframe; public name 'start';
  23. label
  24. bstart,bend,loop,loop2,our_int_handler,key_int;
  25. asm
  26. { init the stack }
  27. ld sp, offset fpc_stackarea_end
  28. { zero the .bss section }
  29. ld bc, offset bstart
  30. ld hl, offset bend
  31. scf
  32. ccf
  33. sbc hl, bc
  34. ld a, 0
  35. loop:
  36. ld (bc), a
  37. inc bc
  38. dec hl
  39. cp a, l
  40. jr NZ, loop
  41. cp a, h
  42. jr NZ, loop
  43. { save IY (must be done after zeroing the .bss section) }
  44. ld (FPC_SAVE_IY), iy
  45. { prepare to run in interrupt mode 2; install our own interrupt handler }
  46. di
  47. ld de, 65024
  48. ld hl, 65021
  49. ld a, d
  50. ld i, a
  51. ld a, l
  52. loop2:
  53. ld (de), a
  54. inc e
  55. jr nz, loop2
  56. inc d
  57. ld (de), a
  58. ld (hl), 195
  59. ld hl, offset our_int_handler
  60. ld (65022), hl
  61. im 2
  62. ei
  63. { ready to run the main program }
  64. jp PASCALMAIN
  65. { replacement for the ROM interrupt handler that preserves IY and that
  66. doesn't break if IY is changed }
  67. our_int_handler:
  68. push af
  69. push hl
  70. push iy
  71. ld iy, (FPC_SAVE_IY)
  72. ld hl, (23672)
  73. inc hl
  74. ld (23672), hl
  75. ld a, h
  76. or a, l
  77. jr nz, key_int
  78. inc (iy+64)
  79. key_int:
  80. push bc
  81. push de
  82. call 703
  83. pop de
  84. pop bc
  85. ld (FPC_SAVE_IY), iy
  86. pop iy
  87. pop hl
  88. pop af
  89. ei
  90. reti
  91. { When using the SDCC-SDLDZ80 linker, the first object module defines the
  92. order of areas (sections). Since this module contains the startup code,
  93. it is loaded first, so we define all the sections we use in the proper
  94. order. }
  95. area '_DATA'
  96. area '_BSS'
  97. bstart:
  98. area '_BSSEND'
  99. bend:
  100. area '_HEAP'
  101. area '_STACK'
  102. area '_CODE'
  103. end;
  104. end.