Browse Source

* synchronised with trunk till r42256

git-svn-id: branches/debug_eh@42257 -
Jonas Maebe 6 years ago
parent
commit
c262c5dbc9
100 changed files with 6027 additions and 2656 deletions
  1. 15 0
      .gitattributes
  2. 1 1
      compiler/avr/cpuinfo.pas
  3. 3 0
      compiler/avr/cpupara.pas
  4. 20 7
      compiler/avr/rgcpu.pas
  5. 1 1
      compiler/dbgstabs.pas
  6. 1 1
      compiler/dbgstabx.pas
  7. 11 0
      compiler/defutil.pas
  8. 5 0
      compiler/fpcdefs.inc
  9. 4 0
      compiler/hlcg2ll.pas
  10. 5 1
      compiler/hlcgobj.pas
  11. 4 4
      compiler/msg/errore.msg
  12. 1 1
      compiler/msgidx.inc
  13. 270 273
      compiler/msgtxt.inc
  14. 56 13
      compiler/ncgmem.pas
  15. 1 0
      compiler/ncnv.pas
  16. 3 1
      compiler/nmem.pas
  17. 279 10
      compiler/ogomf.pas
  18. 200 0
      compiler/omfbase.pas
  19. 9 7
      compiler/pp.lpi
  20. 15 3
      compiler/symdef.pas
  21. 2 1
      compiler/systems.inc
  22. 21 0
      compiler/systems.pas
  23. 109 120
      compiler/systems/t_gba.pas
  24. 199 103
      compiler/systems/t_nds.pas
  25. 304 298
      compiler/systems/t_wii.pas
  26. 138 16
      compiler/systems/t_win16.pas
  27. 85 6
      compiler/x86/rax86.pas
  28. 7 2
      packages/fcl-base/examples/testini.pp
  29. 20 3
      packages/fcl-base/src/blowfish.pp
  30. 0 1
      packages/fcl-base/src/inifiles.pp
  31. 11 16
      packages/fcl-fpcunit/src/fpcunit.pp
  32. 23 1
      packages/fcl-passrc/src/pasresolver.pp
  33. 116 22
      packages/fcl-passrc/src/pastree.pp
  34. 90 38
      packages/fcl-passrc/src/pparser.pp
  35. 6 0
      packages/fcl-passrc/src/pscanner.pp
  36. 54 13
      packages/fcl-passrc/tests/tcgenerics.pp
  37. 43 0
      packages/fcl-passrc/tests/tcresolvegenerics.pas
  38. 20 0
      packages/fcl-passrc/tests/tcresolver.pas
  39. 1 1
      packages/fcl-passrc/tests/testpassrc.lpr
  40. 1 1
      packages/libgbafpc/Makefile.fpc.fpcmake
  41. 2 2
      packages/libgbafpc/src/gba/gba_sound.inc
  42. 7 0
      packages/libndsfpc/examples/audio/maxmod/audio_modes/audio_modes.pp
  43. 7 0
      packages/libndsfpc/examples/audio/maxmod/reverb/reverb.pp
  44. 12 1
      packages/libndsfpc/examples/audio/maxmod/song_events_example/song_events_example.pp
  45. 12 0
      packages/libndsfpc/examples/audio/maxmod/song_events_example2/song_events_example2.pp
  46. 13 0
      packages/libndsfpc/examples/audio/maxmod/streaming/streaming.pp
  47. 6 2
      packages/libndsfpc/examples/audio/micrecord/micrecord.pp
  48. 12 7
      packages/libndsfpc/examples/card/eeprom/eeprom.pp
  49. 6 3
      packages/libndsfpc/examples/ds_motion/dsMotion.pp
  50. 126 55
      packages/libndsfpc/examples/dswifi/ap_search/apSearch.pp
  51. 5 1
      packages/libndsfpc/examples/dswifi/autoconnect/autoconnect.pp
  52. 8 1
      packages/libndsfpc/examples/dswifi/httpget/httpget.pp
  53. 5 2
      packages/libndsfpc/examples/filesystem/libfat/libfatdir/libfatdir.pp
  54. 5 0
      packages/libndsfpc/examples/graphics/3D/3D_Both_Screens/3DBothScreens.pp
  55. 96 96
      packages/libndsfpc/examples/graphics/3D/BoxTest/BoxTest.pp
  56. 2 1
      packages/libndsfpc/examples/graphics/3D/Display_List/DisplayList.pp
  57. 1 0
      packages/libndsfpc/examples/graphics/3D/Display_List_2/DisplayList2.pp
  58. 1 0
      packages/libndsfpc/examples/graphics/3D/Env_Mapping/EnvMapping.pp
  59. 7 0
      packages/libndsfpc/examples/graphics/3D/Mixed_Text_3D/MixedText3D.pp
  60. 8 2
      packages/libndsfpc/examples/graphics/3D/Ortho/Ortho.pp
  61. 4 2
      packages/libndsfpc/examples/graphics/3D/Paletted_Cube/PalettedCube.pp
  62. 134 132
      packages/libndsfpc/examples/graphics/3D/Picking/Picking.pp
  63. 2 0
      packages/libndsfpc/examples/graphics/3D/Simple_Quad/SimpleQuad.pp
  64. 2 0
      packages/libndsfpc/examples/graphics/3D/Simple_Tri/SimpleTri.pp
  65. 16 14
      packages/libndsfpc/examples/graphics/3D/Textured_Cube/TexturedCube.pp
  66. 7 5
      packages/libndsfpc/examples/graphics/3D/Textured_Quad/TexturedQuad.pp
  67. 101 99
      packages/libndsfpc/examples/graphics/3D/Toon_Shading/ToonShading.pp
  68. 7 1
      packages/libndsfpc/examples/graphics/3D/nehe/lesson01/lesson01.pp
  69. 65 59
      packages/libndsfpc/examples/graphics/3D/nehe/lesson02/lesson02.pp
  70. 51 48
      packages/libndsfpc/examples/graphics/3D/nehe/lesson03/lesson03.pp
  71. 62 58
      packages/libndsfpc/examples/graphics/3D/nehe/lesson04/lesson04.pp
  72. 112 107
      packages/libndsfpc/examples/graphics/3D/nehe/lesson05/lesson05.pp
  73. 130 124
      packages/libndsfpc/examples/graphics/3D/nehe/lesson06/lesson06.pp
  74. 161 161
      packages/libndsfpc/examples/graphics/3D/nehe/lesson07/lesson07.pp
  75. 162 162
      packages/libndsfpc/examples/graphics/3D/nehe/lesson08/lesson08.pp
  76. 134 130
      packages/libndsfpc/examples/graphics/3D/nehe/lesson09/lesson09.pp
  77. 11 7
      packages/libndsfpc/examples/graphics/3D/nehe/lesson10/lesson10.pp
  78. 2 0
      packages/libndsfpc/examples/graphics/3D/nehe/lesson10b/lesson10b.pp
  79. 145 139
      packages/libndsfpc/examples/graphics/3D/nehe/lesson11/lesson11.pp
  80. 55 53
      packages/libndsfpc/examples/graphics/Backgrounds/all_in_one/BackgroundAllInOne.pp
  81. 1 1
      packages/libndsfpc/examples/graphics/Makefile.fpc
  82. 8 2
      packages/libndsfpc/examples/graphics/Printing/ansi_console/AnsiConsole.pp
  83. 1 1
      packages/libndsfpc/examples/graphics/Printing/console_windows/ConsoleWindows.pp
  84. 29 24
      packages/libndsfpc/examples/graphics/Printing/custom_font/CustomFont.pp
  85. 25 21
      packages/libndsfpc/examples/graphics/Printing/print_both_screens/printBothScreens.pp
  86. 43 42
      packages/libndsfpc/examples/graphics/Printing/rotscale_text/RotscaleText.pp
  87. 7 4
      packages/libndsfpc/examples/graphics/Sprites/allocation_test/AllocationTest.pp
  88. 5 0
      packages/libndsfpc/examples/graphics/Sprites/bitmap_sprites/BitmapSprites.pp
  89. 149 117
      packages/libndsfpc/examples/graphics/Sprites/fire_and_sprites/FireAndSprites.pp
  90. BIN
      packages/libndsfpc/examples/graphics/Sprites/fire_and_sprites/data/ball.pcx
  91. 1679 0
      packages/libndsfpc/examples/graphics/grit/256colorTilemap/Makefile
  92. 124 0
      packages/libndsfpc/examples/graphics/grit/256colorTilemap/Makefile.fpc
  93. 21 0
      packages/libndsfpc/examples/graphics/grit/256colorTilemap/gfx/tilemap.grit
  94. BIN
      packages/libndsfpc/examples/graphics/grit/256colorTilemap/gfx/tilemap.png
  95. 39 0
      packages/libndsfpc/examples/graphics/grit/256colorTilemap/tilemap_256_color.pp
  96. 18 0
      packages/libndsfpc/examples/graphics/grit/Makefile.fpc
  97. 15 1
      packages/libndsfpc/examples/hello_world/helloWorld.pp
  98. 1 1
      packages/libndsfpc/examples/time/RealTimeClock/Makefile.fpc
  99. 2 2
      packages/libndsfpc/src/dswifi/inc/dswifi9.inc
  100. 2 1
      packages/libndsfpc/src/fat/fat.inc

+ 15 - 0
.gitattributes

@@ -2654,6 +2654,7 @@ packages/fcl-passrc/tests/tcmoduleparser.pas svneol=native#text/plain
 packages/fcl-passrc/tests/tconstparser.pas svneol=native#text/plain
 packages/fcl-passrc/tests/tconstparser.pas svneol=native#text/plain
 packages/fcl-passrc/tests/tcpassrcutil.pas svneol=native#text/plain
 packages/fcl-passrc/tests/tcpassrcutil.pas svneol=native#text/plain
 packages/fcl-passrc/tests/tcprocfunc.pas svneol=native#text/plain
 packages/fcl-passrc/tests/tcprocfunc.pas svneol=native#text/plain
+packages/fcl-passrc/tests/tcresolvegenerics.pas svneol=native#text/plain
 packages/fcl-passrc/tests/tcresolver.pas svneol=native#text/plain
 packages/fcl-passrc/tests/tcresolver.pas svneol=native#text/plain
 packages/fcl-passrc/tests/tcscanner.pas svneol=native#text/plain
 packages/fcl-passrc/tests/tcscanner.pas svneol=native#text/plain
 packages/fcl-passrc/tests/tcstatements.pas svneol=native#text/plain
 packages/fcl-passrc/tests/tcstatements.pas svneol=native#text/plain
@@ -5905,6 +5906,12 @@ packages/libndsfpc/examples/graphics/Sprites/sprite_extended_palettes/SpriteExte
 packages/libndsfpc/examples/graphics/Sprites/sprite_rotate/Makefile svneol=native#text/plain
 packages/libndsfpc/examples/graphics/Sprites/sprite_rotate/Makefile svneol=native#text/plain
 packages/libndsfpc/examples/graphics/Sprites/sprite_rotate/Makefile.fpc svneol=native#text/plain
 packages/libndsfpc/examples/graphics/Sprites/sprite_rotate/Makefile.fpc svneol=native#text/plain
 packages/libndsfpc/examples/graphics/Sprites/sprite_rotate/SpriteRotate.pp svneol=native#text/plain
 packages/libndsfpc/examples/graphics/Sprites/sprite_rotate/SpriteRotate.pp svneol=native#text/plain
+packages/libndsfpc/examples/graphics/grit/256colorTilemap/Makefile svneol=native#text/plain
+packages/libndsfpc/examples/graphics/grit/256colorTilemap/Makefile.fpc svneol=native#text/plain
+packages/libndsfpc/examples/graphics/grit/256colorTilemap/gfx/tilemap.grit svneol=native#text/plain
+packages/libndsfpc/examples/graphics/grit/256colorTilemap/gfx/tilemap.png -text
+packages/libndsfpc/examples/graphics/grit/256colorTilemap/tilemap_256_color.pp svneol=native#text/plain
+packages/libndsfpc/examples/graphics/grit/Makefile.fpc svneol=native#text/plain
 packages/libndsfpc/examples/hello_world/Makefile svneol=native#text/plain
 packages/libndsfpc/examples/hello_world/Makefile svneol=native#text/plain
 packages/libndsfpc/examples/hello_world/Makefile.fpc svneol=native#text/plain
 packages/libndsfpc/examples/hello_world/Makefile.fpc svneol=native#text/plain
 packages/libndsfpc/examples/hello_world/helloWorld.pp svneol=native#text/plain
 packages/libndsfpc/examples/hello_world/helloWorld.pp svneol=native#text/plain
@@ -5970,8 +5977,10 @@ packages/libndsfpc/src/maxmod/inc/mm_msl.inc svneol=native#text/plain
 packages/libndsfpc/src/maxmod/inc/mm_types.inc svneol=native#text/plain
 packages/libndsfpc/src/maxmod/inc/mm_types.inc svneol=native#text/plain
 packages/libndsfpc/src/maxmod/maxmod7.pp svneol=native#text/plain
 packages/libndsfpc/src/maxmod/maxmod7.pp svneol=native#text/plain
 packages/libndsfpc/src/maxmod/maxmod9.pp svneol=native#text/plain
 packages/libndsfpc/src/maxmod/maxmod9.pp svneol=native#text/plain
+packages/libndsfpc/src/nds/arm7/aes.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm7/audio.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm7/audio.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm7/clock.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm7/clock.inc svneol=native#text/plain
+packages/libndsfpc/src/nds/arm7/codec.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm7/i2c.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm7/i2c.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm7/input.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm7/input.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm7/sdmmc.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm7/sdmmc.inc svneol=native#text/plain
@@ -5980,9 +5989,11 @@ packages/libndsfpc/src/nds/arm7/touch.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/background.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/background.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/boxtest.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/boxtest.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/cache.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/cache.inc svneol=native#text/plain
+packages/libndsfpc/src/nds/arm9/cache_asm.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/console.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/console.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/decompress.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/decompress.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/dldi.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/dldi.inc svneol=native#text/plain
+packages/libndsfpc/src/nds/arm9/dldi_asm.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/dynamicArray.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/dynamicArray.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/exceptions.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/exceptions.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/guitarGrip.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/guitarGrip.inc svneol=native#text/plain
@@ -5991,6 +6002,7 @@ packages/libndsfpc/src/nds/arm9/input.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/keyboard.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/keyboard.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/linkedlist.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/linkedlist.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/math.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/math.inc svneol=native#text/plain
+packages/libndsfpc/src/nds/arm9/nand.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/ndsmotion.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/ndsmotion.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/paddle.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/paddle.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/pcx.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/pcx.inc svneol=native#text/plain
@@ -6022,6 +6034,8 @@ packages/libndsfpc/src/nds/nds.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/ndsinclude.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/ndsinclude.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/ndstypes.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/ndstypes.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/registers_alt.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/registers_alt.inc svneol=native#text/plain
+packages/libndsfpc/src/nds/rsa.inc svneol=native#text/plain
+packages/libndsfpc/src/nds/sha1.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/system.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/system.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/timers.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/timers.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/touch.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/touch.inc svneol=native#text/plain
@@ -14028,6 +14042,7 @@ tests/test/trtti18a.pp svneol=native#text/pascal
 tests/test/trtti18b.pp svneol=native#text/pascal
 tests/test/trtti18b.pp svneol=native#text/pascal
 tests/test/trtti19.pp svneol=native#text/pascal
 tests/test/trtti19.pp svneol=native#text/pascal
 tests/test/trtti2.pp svneol=native#text/plain
 tests/test/trtti2.pp svneol=native#text/plain
+tests/test/trtti20.pp svneol=native#text/pascal
 tests/test/trtti3.pp svneol=native#text/plain
 tests/test/trtti3.pp svneol=native#text/plain
 tests/test/trtti4.pp svneol=native#text/plain
 tests/test/trtti4.pp svneol=native#text/plain
 tests/test/trtti5.pp svneol=native#text/plain
 tests/test/trtti5.pp svneol=native#text/plain

+ 1 - 1
compiler/avr/cpuinfo.pas

@@ -50,7 +50,7 @@ Type
    tfputype =
    tfputype =
      (fpu_none,
      (fpu_none,
       fpu_soft,
       fpu_soft,
-      fp_libgcc
+      fpu_libgcc
      );
      );
 
 
    tcontrollertype =
    tcontrollertype =

+ 3 - 0
compiler/avr/cpupara.pas

@@ -220,7 +220,10 @@ unit cpupara;
                paraloc^.loc:=LOC_REFERENCE;
                paraloc^.loc:=LOC_REFERENCE;
                paraloc^.reference.index:=NR_STACK_POINTER_REG;
                paraloc^.reference.index:=NR_STACK_POINTER_REG;
                paraloc^.reference.offset:=stack_offset;
                paraloc^.reference.offset:=stack_offset;
+{$push}
+{$R-}
                dec(stack_offset,2);
                dec(stack_offset,2);
+{$pop}
             end;
             end;
         end;
         end;
 
 

+ 20 - 7
compiler/avr/rgcpu.pas

@@ -155,6 +155,13 @@ unit rgcpu;
               A_LDI:
               A_LDI:
                 for r:=RS_R0 to RS_R15 do
                 for r:=RS_R0 to RS_R15 do
                   add_edge(r,GetSupReg(taicpu(p).oper[0]^.reg));
                   add_edge(r,GetSupReg(taicpu(p).oper[0]^.reg));
+              A_STS:
+                for r:=RS_R0 to RS_R15 do
+                  add_edge(r,GetSupReg(taicpu(p).oper[1]^.reg));
+              A_ADIW:
+                for r:=RS_R0 to RS_R31 do
+                  if not (r in [RS_R24,RS_R26,RS_R28,RS_R30]) then
+                    add_edge(r,GetSupReg(taicpu(p).oper[0]^.reg));
               A_MULS:
               A_MULS:
                 begin
                 begin
                   for r:=RS_R0 to RS_R15 do
                   for r:=RS_R0 to RS_R15 do
@@ -162,6 +169,14 @@ unit rgcpu;
                   for r:=RS_R0 to RS_R15 do
                   for r:=RS_R0 to RS_R15 do
                     add_edge(r,GetSupReg(taicpu(p).oper[1]^.reg));
                     add_edge(r,GetSupReg(taicpu(p).oper[1]^.reg));
                 end;
                 end;
+              A_LDD:
+                for r:=RS_R0 to RS_R31 do
+                  if not (r in [RS_R28,RS_R30]) then
+                    add_edge(r,GetSupReg(taicpu(p).oper[1]^.ref^.base));
+              A_STD:
+                for r:=RS_R0 to RS_R31 do
+                  if not (r in [RS_R28,RS_R30]) then
+                    add_edge(r,GetSupReg(taicpu(p).oper[0]^.ref^.base));
             end;
             end;
           end;
           end;
       end;
       end;
@@ -175,8 +190,8 @@ unit rgcpu;
         if not(spilltemp.offset in [0..63]) then
         if not(spilltemp.offset in [0..63]) then
           exit;
           exit;
 
 
-        { Replace 'mov  dst,orgreg' with 'ld  dst,spilltemp'
-          and     'mov  orgreg,src' with 'st  dst,spilltemp' }
+        { Replace 'mov  dst,orgreg' with 'ldd  dst,spilltemp'
+          and     'mov  orgreg,src' with 'std  spilltemp,src' }
         with instr do
         with instr do
           begin
           begin
             if (opcode=A_MOV) and (ops=2) and (oper[1]^.typ=top_reg) and (oper[0]^.typ=top_reg) then
             if (opcode=A_MOV) and (ops=2) and (oper[1]^.typ=top_reg) and (oper[0]^.typ=top_reg) then
@@ -185,10 +200,8 @@ unit rgcpu;
                    (get_alias(getsupreg(oper[0]^.reg))=orgreg) and
                    (get_alias(getsupreg(oper[0]^.reg))=orgreg) and
                    (get_alias(getsupreg(oper[1]^.reg))<>orgreg) then
                    (get_alias(getsupreg(oper[1]^.reg))<>orgreg) then
                   begin
                   begin
-                    { str expects the register in oper[0] }
-                    instr.loadreg(0,oper[1]^.reg);
-                    instr.loadref(1,spilltemp);
-                    opcode:=A_ST;
+                    instr.loadref(0,spilltemp);
+                    opcode:=A_STD;
                     result:=true;
                     result:=true;
                   end
                   end
                 else if (getregtype(oper[1]^.reg)=regtype) and
                 else if (getregtype(oper[1]^.reg)=regtype) and
@@ -196,7 +209,7 @@ unit rgcpu;
                    (get_alias(getsupreg(oper[0]^.reg))<>orgreg) then
                    (get_alias(getsupreg(oper[0]^.reg))<>orgreg) then
                   begin
                   begin
                     instr.loadref(1,spilltemp);
                     instr.loadref(1,spilltemp);
-                    opcode:=A_LD;
+                    opcode:=A_LDD;
                     result:=true;
                     result:=true;
                   end;
                   end;
               end;
               end;

+ 1 - 1
compiler/dbgstabs.pas

@@ -1642,7 +1642,7 @@ implementation
         ss:='';
         ss:='';
         if not assigned(sym.typedef) then
         if not assigned(sym.typedef) then
           internalerror(200509262);
           internalerror(200509262);
-        if sym.typedef.typ in tagtypes then
+        if use_tag_prefix(sym.typedef) then
           stabchar:=tagtypeprefix
           stabchar:=tagtypeprefix
         else
         else
           stabchar:='t';
           stabchar:='t';

+ 1 - 1
compiler/dbgstabx.pas

@@ -158,7 +158,7 @@ implementation
           declstabnr:=def_stab_number(def)
           declstabnr:=def_stab_number(def)
         end;
         end;
       if (symname='') or
       if (symname='') or
-         not(def.typ in tagtypes) then
+         not(use_tag_prefix(def)) then
         begin
         begin
           st:=def_stabstr_evaluate(def,':$1$2=',[stabchar,declstabnr]);
           st:=def_stabstr_evaluate(def,':$1$2=',[stabchar,declstabnr]);
           st:='"'+def_stabstr_evaluate(def,symname,[])+st+ss;
           st:='"'+def_stabstr_evaluate(def,symname,[])+st+ss;

+ 11 - 0
compiler/defutil.pas

@@ -156,6 +156,9 @@ interface
     }
     }
     function is_special_array(p : tdef) : boolean;
     function is_special_array(p : tdef) : boolean;
 
 
+    {# Returns true, if p points to a normal array, bitpacked arrays are included }
+    function is_normal_array(p : tdef) : boolean;
+
     {# Returns true if p is a bitpacked array }
     {# Returns true if p is a bitpacked array }
     function is_packed_array(p: tdef) : boolean;
     function is_packed_array(p: tdef) : boolean;
 
 
@@ -752,6 +755,14 @@ implementation
                  );
                  );
       end;
       end;
 
 
+    { true, if p points to a normal array, bitpacked arrays are included }
+    function is_normal_array(p : tdef) : boolean;
+      begin
+         result:=(p.typ=arraydef) and
+                 ((tarraydef(p).arrayoptions * [ado_IsVariant,ado_IsArrayOfConst,ado_IsConstructor,ado_IsDynamicArray])=[]) and
+                 not(is_open_array(p));
+      end;
+
     { true if p is an ansi string def }
     { true if p is an ansi string def }
     function is_ansistring(p : tdef) : boolean;
     function is_ansistring(p : tdef) : boolean;
       begin
       begin

+ 5 - 0
compiler/fpcdefs.inc

@@ -34,6 +34,11 @@
 
 
 {$define USEEXCEPT}
 {$define USEEXCEPT}
 
 
+{$ifdef VER3_0}
+  { fix bootstrapping dfa gives warnings on 3.2+ code due to changed case behaviour }
+  {$OPTIMIZATION NODFA}
+{$endif VER3_0}
+
 { This fake CPU is used to allow incorporation of globtype unit
 { This fake CPU is used to allow incorporation of globtype unit
   into utils/ppudump without any CPU specific code PM }
   into utils/ppudump without any CPU specific code PM }
 {$ifdef generic_cpu}
 {$ifdef generic_cpu}

+ 4 - 0
compiler/hlcg2ll.pas

@@ -1319,6 +1319,10 @@ implementation
       ncgutil.maketojumpboollabels(list,p,truelabel,falselabel);
       ncgutil.maketojumpboollabels(list,p,truelabel,falselabel);
     end;
     end;
 
 
+{$if first_mm_imreg = 0}
+  {$WARN 4044 OFF} { Comparison might be always false ... }
+{$endif}
+
   procedure thlcg2ll.gen_load_para_value(list: TAsmList);
   procedure thlcg2ll.gen_load_para_value(list: TAsmList);
 
 
     procedure get_para(const paraloc:TCGParaLocation);
     procedure get_para(const paraloc:TCGParaLocation);

+ 5 - 1
compiler/hlcgobj.pas

@@ -823,9 +823,13 @@ implementation
           objectdef,
           objectdef,
           procvardef,
           procvardef,
           procdef,
           procdef,
-          arraydef,
           formaldef:
           formaldef:
             result:=R_ADDRESSREGISTER;
             result:=R_ADDRESSREGISTER;
+          arraydef:
+            if tstoreddef(def).is_intregable then
+              result:=R_INTREGISTER
+            else
+              result:=R_ADDRESSREGISTER;
           floatdef:
           floatdef:
             if use_vectorfpu(def) then
             if use_vectorfpu(def) then
               result:=R_MMREGISTER
               result:=R_MMREGISTER

+ 4 - 4
compiler/msg/errore.msg

@@ -2758,15 +2758,15 @@ asmr_w_unable_to_determine_reference_size_using_byte=07101_W_No size specified a
 % the compiler is unable to determine what size (byte,word,dword,etc.) it
 % the compiler is unable to determine what size (byte,word,dword,etc.) it
 % should use for the reference. This warning is only used in Delphi mode where
 % should use for the reference. This warning is only used in Delphi mode where
 % it falls back to use BYTE as default.
 % it falls back to use BYTE as default.
-asmr_w_no_direct_ebp_for_parameter=07102_W_Use of +offset(%ebp) for parameters invalid here
+asmr_w_no_direct_ebp_for_parameter=07102_W_Use of $1 for parameters invalid here
 % Using direct 8(%ebp) reference for function/procedure parameters is invalid
 % Using direct 8(%ebp) reference for function/procedure parameters is invalid
 % if parameters are in registers.
 % if parameters are in registers.
-asmr_w_direct_ebp_for_parameter_regcall=07103_W_Use of +offset(%ebp) is not compatible with regcall convention
+asmr_w_direct_ebp_for_parameter_regcall=07103_W_Use of $1 is not compatible with regcall convention
 % Using direct 8(%ebp) reference for function/procedure parameters is invalid
 % Using direct 8(%ebp) reference for function/procedure parameters is invalid
 % if parameters are in registers.
 % if parameters are in registers.
-asmr_w_direct_ebp_neg_offset=07104_W_Use of -offset(%ebp) is not recommended for local variable access
+asmr_w_direct_ebp_neg_offset=07104_W_Use of $1 is not recommended for local variable access
 % Using -8(%ebp) to access a local variable is not recommended
 % Using -8(%ebp) to access a local variable is not recommended
-asmr_w_direct_esp_neg_offset=07105_W_Use of -offset(%esp), access may cause a crash or value may be lost
+asmr_w_direct_esp_neg_offset=07105_W_Use of $1, access may cause a crash or value may be lost
 % Using -8(%esp) to access a local stack is not recommended, as
 % Using -8(%esp) to access a local stack is not recommended, as
 % this stack portion can be overwritten by any function calls or interrupts.
 % this stack portion can be overwritten by any function calls or interrupts.
 asmr_e_no_vmtoffset_possible=07106_E_VMTOffset must be used in combination with a virtual method, and "$1" is not virtual
 asmr_e_no_vmtoffset_possible=07106_E_VMTOffset must be used in combination with a virtual method, and "$1" is not virtual

+ 1 - 1
compiler/msgidx.inc

@@ -1111,7 +1111,7 @@ const
   option_info=11024;
   option_info=11024;
   option_help_pages=11025;
   option_help_pages=11025;
 
 
-  MsgTxtSize = 83468;
+  MsgTxtSize = 83424;
 
 
   MsgIdxMax : array[1..20] of longint=(
   MsgIdxMax : array[1..20] of longint=(
     28,106,351,126,99,61,142,34,221,68,
     28,106,351,126,99,61,142,34,221,68,

File diff suppressed because it is too large
+ 270 - 273
compiler/msgtxt.inc


+ 56 - 13
compiler/ncgmem.pas

@@ -855,7 +855,9 @@ implementation
          paraloc2 : tcgpara;
          paraloc2 : tcgpara;
          subsetref : tsubsetreference;
          subsetref : tsubsetreference;
          temp : longint;
          temp : longint;
+         hreg : tregister;
          indexdef : tdef;
          indexdef : tdef;
+         i : Integer;
       begin
       begin
          paraloc1.init;
          paraloc1.init;
          paraloc2.init;
          paraloc2.init;
@@ -936,19 +938,29 @@ implementation
            end
            end
          else
          else
            begin
            begin
-              { may happen in case of function results }
-              case left.location.loc of
-                LOC_CSUBSETREG,
-                LOC_CREGISTER,
-                LOC_CMMREGISTER,
-                LOC_SUBSETREG,
-                LOC_REGISTER,
-                LOC_MMREGISTER:
-                  hlcg.location_force_mem(current_asmdata.CurrAsmList,left.location,left.resultdef);
-                else
-                  ;
-              end;
-             location_copy(location,left.location);
+             { may happen in case of function results }
+             case left.location.loc of
+               LOC_CREGISTER,
+               LOC_REGISTER:
+                 begin
+                   if not(is_constnode(right)) or (tarraydef(left.resultdef).elementdef.size<>alusinttype.size) then
+                     hlcg.location_force_mem(current_asmdata.CurrAsmList,left.location,left.resultdef);
+                   { we use location here only to get the right offset }
+                   location_reset_ref(location,LOC_REFERENCE,OS_NO,1,[]);
+                 end;
+               LOC_CSUBSETREG,
+               LOC_CMMREGISTER,
+               LOC_SUBSETREG,
+               LOC_MMREGISTER:
+                 begin
+                   hlcg.location_force_mem(current_asmdata.CurrAsmList,left.location,left.resultdef);
+                   location_copy(location,left.location);
+                 end;
+               LOC_INVALID:
+                 Internalerror(2019061101);
+               else
+                 location_copy(location,left.location);
+             end;
            end;
            end;
 
 
          { location must be memory }
          { location must be memory }
@@ -994,6 +1006,37 @@ implementation
                   update_reference_offset(location.reference,extraoffset,bytemulsize);
                   update_reference_offset(location.reference,extraoffset,bytemulsize);
                   { adjust alignment after this change }
                   { adjust alignment after this change }
                   location.reference.alignment:=newalignment(location.reference.alignment,extraoffset*bytemulsize);
                   location.reference.alignment:=newalignment(location.reference.alignment,extraoffset*bytemulsize);
+
+                  { actually an array in a register? }
+                  if (left.location.loc in [LOC_CREGISTER,LOC_REGISTER]) and
+                    is_normal_array(left.resultdef) then
+                    begin
+{$if defined(cpu64bitalu)}
+                      hreg:=left.location.register;
+{$else defined(cpu64bitalu)}
+                      if target_info.endian=endian_little then
+                        begin
+                          if location.reference.offset>3 then
+                            hreg:=left.location.register64.reghi
+                          else
+                            hreg:=left.location.register64.reglo;
+                        end
+                      else
+                        begin
+                          if location.reference.offset>3 then
+                            hreg:=left.location.register64.reglo
+                          else
+                            hreg:=left.location.register64.reghi;
+                        end;
+{$endif defined(cpu64bitalu)}
+{$if defined(cpu8bitalu) or defined(cpu16bitalu)}
+                      { we support only the case that one element fills at least one register }
+                      for i:=1 to location.reference.offset mod 4 do
+                        hreg:=cg.GetNextReg(hreg);
+{$endif defined(cpu8bitalu) or defined(cpu16bitalu)}
+                      location_reset(location,left.location.loc,def_cgsize(tarraydef(left.resultdef).elementdef));
+                      location.register:=hreg;
+                    end;
                 end
                 end
               else
               else
                 begin
                 begin

+ 1 - 0
compiler/ncnv.pas

@@ -3255,6 +3255,7 @@ implementation
 
 
       begin
       begin
          first_array_to_pointer:=nil;
          first_array_to_pointer:=nil;
+         make_not_regable(left,[ra_addr_regable]);
          expectloc:=LOC_REGISTER;
          expectloc:=LOC_REGISTER;
       end;
       end;
 
 

+ 3 - 1
compiler/nmem.pas

@@ -1054,7 +1054,9 @@ implementation
            that has a field of one of these types -> in that case the record
            that has a field of one of these types -> in that case the record
            can't be a regvar either }
            can't be a regvar either }
          if ((left.resultdef.typ=arraydef) and
          if ((left.resultdef.typ=arraydef) and
-             not is_special_array(left.resultdef)) or
+             not is_special_array(left.resultdef) and
+             { arrays with elements equal to the alu size and with a constant index can be kept in register }
+             not(is_constnode(right) and (tarraydef(left.resultdef).elementdef.size=alusinttype.size))) or
             ((left.resultdef.typ=stringdef) and
             ((left.resultdef.typ=stringdef) and
              (tstringdef(left.resultdef).stringtype in [st_shortstring,st_longstring])) then
              (tstringdef(left.resultdef).stringtype in [st_shortstring,st_longstring])) then
            make_not_regable(left,[ra_addr_regable]);
            make_not_regable(left,[ra_addr_regable]);

+ 279 - 10
compiler/ogomf.pas

@@ -24,6 +24,8 @@ unit ogomf;
 
 
 {$i fpcdefs.inc}
 {$i fpcdefs.inc}
 
 
+{$PackSet 1}
+
 interface
 interface
 
 
     uses
     uses
@@ -165,6 +167,8 @@ interface
         function ReadPubDef(RawRec: TOmfRawRecord; objdata:TObjData): Boolean;
         function ReadPubDef(RawRec: TOmfRawRecord; objdata:TObjData): Boolean;
         function ReadModEnd(RawRec: TOmfRawRecord; objdata:TObjData): Boolean;
         function ReadModEnd(RawRec: TOmfRawRecord; objdata:TObjData): Boolean;
         function ReadLeOrLiDataAndFixups(RawRec: TOmfRawRecord; objdata:TObjData): Boolean;
         function ReadLeOrLiDataAndFixups(RawRec: TOmfRawRecord; objdata:TObjData): Boolean;
+        function ReadImpDef(Rec: TOmfRecord_COMENT): Boolean;
+        function ReadExpDef(Rec: TOmfRecord_COMENT): Boolean;
         function ImportOmfFixup(objdata: TObjData; objsec: TOmfObjSection; Fixup: TOmfSubRecord_FIXUP): Boolean;
         function ImportOmfFixup(objdata: TObjData; objsec: TOmfObjSection; Fixup: TOmfSubRecord_FIXUP): Boolean;
 
 
         property LNames: TOmfOrderedNameCollection read FLNames;
         property LNames: TOmfOrderedNameCollection read FLNames;
@@ -363,6 +367,115 @@ interface
         netoPharLap286DosExtenderOS2       = $81,
         netoPharLap286DosExtenderOS2       = $81,
         netoPharLap286DosExtenderWindows   = $82);
         netoPharLap286DosExtenderWindows   = $82);
 
 
+      TNewExeSegmentFlag = (
+        nesfData,                                                     { bit  0 }
+        nesfLoaderAllocatedMemory,                                    { bit  1 }
+        nesfLoaded,                                                   { bit  2 }
+        nesfReserved3,                                                { bit  3 }
+        nesfMovable,                                                  { bit  4 }
+        nesfShareable,                                                { bit  5 }
+        nesfPreload,                                                  { bit  6 }
+        nesfExecuteOnlyCodeOrReadOnlyData,                            { bit  7 }
+        nesfHasRelocationData,                                        { bit  8 }
+        nesfReserved9,                                                { bit  9 }
+        nesfReserved10,                                               { bit 10 }
+        nesfReserved11,                                               { bit 11 }
+        nesfDiscardable,                                              { bit 12 }
+        nesfReserved13,                                               { bit 13 }
+        nesfReserved14,                                               { bit 14 }
+        nesfReserved15);                                              { bit 15 }
+      TNewExeSegmentFlags = set of TNewExeSegmentFlag;
+
+      TNewExeMsDosStub = array of byte;
+
+      { TNewExeHeader }
+
+      TNewExeHeader = class
+      private
+        FMsDosStub: TNewExeMsDosStub;
+        FLinkerVersion: Byte;
+        FLinkerRevision: Byte;
+        FEntryTableOffset: Word;
+        FEntryTableLength: Word;
+        FReserved: LongWord;
+        FFlags: TNewExeHeaderFlags;
+        FAutoDataSegmentNumber: Word;
+        FInitialLocalHeapSize: Word;
+        FInitialStackSize: Word;
+        FInitialIP: Word;
+        FInitialCS: Word;
+        FInitialSP: Word;
+        FInitialSS: Word;
+        FSegmentTableEntriesCount: Word;
+        FModuleReferenceTableEntriesCount: Word;
+        FNonresidentNameTableLength: Word;
+        FSegmentTableStart: Word;
+        FResourceTableStart: Word;
+        FResidentNameTableStart: Word;
+        FModuleReferenceTableStart: Word;
+        FImportedNameTableStart: Word;
+        FNonresidentNameTableStart: LongWord;
+        FMovableEntryPointsCount: Word;
+        FLogicalSectorAlignmentShiftCount: Word;
+        FResourceSegmentsCount: Word;
+        FTargetOS: TNewExeTargetOS;
+        FAdditionalFlags: TNewExeAdditionalHeaderFlags;
+        FGangLoadAreaStart: Word;
+        FGangLoadAreaLength: Word;
+        FReserved2: Word;
+        FExpectedWindowsVersion: Word;
+      public
+        constructor Create;
+        procedure WriteTo(aWriter: TObjectWriter);
+
+        property MsDosStub: TNewExeMsDosStub read FMsDosStub write FMsDosStub;
+        property LinkerVersion: Byte read FLinkerVersion write FLinkerVersion;
+        property LinkerRevision: Byte read FLinkerRevision write FLinkerRevision;
+        property EntryTableOffset: Word read FEntryTableOffset write FEntryTableOffset;
+        property EntryTableLength: Word read FEntryTableLength write FEntryTableLength;
+        property Reserved: LongWord read FReserved write FReserved;
+        property Flags: TNewExeHeaderFlags read FFlags write FFlags;
+        property AutoDataSegmentNumber: Word read FAutoDataSegmentNumber write FAutoDataSegmentNumber;
+        property InitialLocalHeapSize: Word read FInitialLocalHeapSize write FInitialLocalHeapSize;
+        property InitialStackSize: Word read FInitialStackSize write FInitialStackSize;
+        property InitialIP: Word read FInitialIP write FInitialIP;
+        property InitialCS: Word read FInitialCS write FInitialCS;
+        property InitialSP: Word read FInitialSP write FInitialSP;
+        property InitialSS: Word read FInitialSS write FInitialSS;
+        property SegmentTableEntriesCount: Word read FSegmentTableEntriesCount write FSegmentTableEntriesCount;
+        property ModuleReferenceTableEntriesCount: Word read FModuleReferenceTableEntriesCount write FModuleReferenceTableEntriesCount;
+        property NonresidentNameTableLength: Word read FNonresidentNameTableLength write FNonresidentNameTableLength;
+        property SegmentTableStart: Word read FSegmentTableStart write FSegmentTableStart;
+        property ResourceTableStart: Word read FResourceTableStart write FResourceTableStart;
+        property ResidentNameTableStart: Word read FResidentNameTableStart write FResidentNameTableStart;
+        property ModuleReferenceTableStart: Word read FModuleReferenceTableStart write FModuleReferenceTableStart;
+        property ImportedNameTableStart: Word read FImportedNameTableStart write FImportedNameTableStart;
+        property NonresidentNameTableStart: LongWord read FNonresidentNameTableStart write FNonresidentNameTableStart;
+        property MovableEntryPointsCount: Word read FMovableEntryPointsCount write FMovableEntryPointsCount;
+        property LogicalSectorAlignmentShiftCount: Word read FLogicalSectorAlignmentShiftCount write FLogicalSectorAlignmentShiftCount;
+        property ResourceSegmentsCount: Word read FResourceSegmentsCount write FResourceSegmentsCount;
+        property TargetOS: TNewExeTargetOS read FTargetOS write FTargetOS;
+        property AdditionalFlags: TNewExeAdditionalHeaderFlags read FAdditionalFlags write FAdditionalFlags;
+        property GangLoadAreaStart: Word read FGangLoadAreaStart write FGangLoadAreaStart;
+        property GangLoadAreaLength: Word read FGangLoadAreaLength write FGangLoadAreaLength;
+        property Reserved2: Word read FReserved2 write FReserved2;
+        property ExpectedWindowsVersion: Word read FExpectedWindowsVersion write FExpectedWindowsVersion;
+      end;
+
+      { TNewExeOutput }
+
+      TNewExeOutput = class(TExeOutput)
+      private
+        FHeader: TNewExeHeader;
+      protected
+        procedure DoRelocationFixup(objsec:TObjSection);override;
+      public
+        constructor create;override;
+        destructor destroy;override;
+
+        function writeData:boolean;override;
+      end;
+
       TOmfAssembler = class(tinternalassembler)
       TOmfAssembler = class(tinternalassembler)
         constructor create(info: pasminfo; smart:boolean);override;
         constructor create(info: pasminfo; smart:boolean);override;
       end;
       end;
@@ -1221,7 +1334,8 @@ implementation
       var
       var
         RawRecord: TOmfRawRecord;
         RawRecord: TOmfRawRecord;
         Header: TOmfRecord_THEADR;
         Header: TOmfRecord_THEADR;
-        DllImport_COMENT: TOmfRecord_COMENT;
+        DllImport_COMENT: TOmfRecord_COMENT=nil;
+        DllImport_COMENT_IMPDEF: TOmfRecord_COMENT_IMPDEF=nil;
         ModEnd: TOmfRecord_MODEND;
         ModEnd: TOmfRecord_MODEND;
       begin
       begin
         { write header record }
         { write header record }
@@ -1233,20 +1347,26 @@ implementation
         Header.Free;
         Header.Free;
 
 
         { write IMPDEF record }
         { write IMPDEF record }
-        DllImport_COMENT:=TOmfRecord_COMENT.Create;
-        DllImport_COMENT.CommentClass:=CC_OmfExtension;
+        DllImport_COMENT_IMPDEF:=TOmfRecord_COMENT_IMPDEF.Create;
+        DllImport_COMENT_IMPDEF.InternalName:=mangledname;
+        DllImport_COMENT_IMPDEF.ModuleName:=dllname;
         if ordnr <= 0 then
         if ordnr <= 0 then
           begin
           begin
-            if afuncname=mangledname then
-              DllImport_COMENT.CommentString:=#1#0+Chr(Length(mangledname))+mangledname+Chr(Length(dllname))+dllname+#0
-            else
-              DllImport_COMENT.CommentString:=#1#0+Chr(Length(mangledname))+mangledname+Chr(Length(dllname))+dllname+Chr(Length(afuncname))+afuncname;
+            DllImport_COMENT_IMPDEF.ImportByOrdinal:=False;
+            DllImport_COMENT_IMPDEF.Name:=afuncname;
           end
           end
         else
         else
-          DllImport_COMENT.CommentString:=#1#1+Chr(Length(mangledname))+mangledname+Chr(Length(dllname))+dllname+Chr(ordnr and $ff)+Chr((ordnr shr 8) and $ff);
+          begin
+            DllImport_COMENT_IMPDEF.ImportByOrdinal:=True;
+            DllImport_COMENT_IMPDEF.Ordinal:=ordnr;
+          end;
+
+        DllImport_COMENT:=TOmfRecord_COMENT.Create;
+        DllImport_COMENT_IMPDEF.EncodeTo(DllImport_COMENT);
+        FreeAndNil(DllImport_COMENT_IMPDEF);
         DllImport_COMENT.EncodeTo(RawRecord);
         DllImport_COMENT.EncodeTo(RawRecord);
+        FreeAndNil(DllImport_COMENT);
         RawRecord.WriteTo(FWriter);
         RawRecord.WriteTo(FWriter);
-        DllImport_COMENT.Free;
 
 
         { write MODEND record }
         { write MODEND record }
         ModEnd:=TOmfRecord_MODEND.Create;
         ModEnd:=TOmfRecord_MODEND.Create;
@@ -1730,6 +1850,18 @@ implementation
         Result:=True;
         Result:=True;
       end;
       end;
 
 
+    function TOmfObjInput.ReadImpDef(Rec: TOmfRecord_COMENT): Boolean;
+      begin
+        {todo: implement}
+        Result:=True;
+      end;
+
+    function TOmfObjInput.ReadExpDef(Rec: TOmfRecord_COMENT): Boolean;
+      begin
+        {todo: implement}
+        Result:=True;
+      end;
+
     function TOmfObjInput.ImportOmfFixup(objdata: TObjData; objsec: TOmfObjSection; Fixup: TOmfSubRecord_FIXUP): Boolean;
     function TOmfObjInput.ImportOmfFixup(objdata: TObjData; objsec: TOmfObjSection; Fixup: TOmfSubRecord_FIXUP): Boolean;
       var
       var
         reloc: TOmfRelocation;
         reloc: TOmfRelocation;
@@ -2111,7 +2243,17 @@ implementation
                 case FCOMENTRecord.CommentClass of
                 case FCOMENTRecord.CommentClass of
                   CC_OmfExtension:
                   CC_OmfExtension:
                     begin
                     begin
-                      {todo: handle these as well...}
+                      if Length(FCOMENTRecord.CommentString)>=1 then
+                        begin
+                          case Ord(FCOMENTRecord.CommentString[1]) of
+                            CC_OmfExtension_IMPDEF:
+                              if not ReadImpDef(FCOMENTRecord) then
+                                exit;
+                            CC_OmfExtension_EXPDEF:
+                              if not ReadExpDef(FCOMENTRecord) then
+                                exit;
+                          end;
+                        end;
                     end;
                     end;
                   CC_LIBMOD:
                   CC_LIBMOD:
                     begin
                     begin
@@ -3250,6 +3392,133 @@ cleanup:
         inherited destroy;
         inherited destroy;
       end;
       end;
 
 
+
+{****************************************************************************
+                               TNewExeHeader
+****************************************************************************}
+
+    constructor TNewExeHeader.Create;
+      begin
+        SetLength(FMsDosStub,High(win16stub)-Low(win16stub)+1);
+        Move(win16stub[Low(win16stub)],FMsDosStub[0],High(win16stub)-Low(win16stub)+1);
+
+        { BP7 identifies itself as linker version 6.1 in the Win16 .exe files it produces }
+        LinkerVersion:=6;
+        LinkerRevision:=1;
+        LogicalSectorAlignmentShiftCount:=8;  { 256-byte logical sectors }
+        TargetOS:=netoWindows;
+        ExpectedWindowsVersion:=$0300;
+        Flags:=[nehfNotWindowAPICompatible,nehfWindowAPICompatible,nehfMultipleData,nehfProtectedModeOnly];
+        AdditionalFlags:=[];
+        GangLoadAreaStart:=0;
+        GangLoadAreaLength:=0;
+        Reserved:=0;
+        Reserved2:=0;
+      end;
+
+    procedure TNewExeHeader.WriteTo(aWriter: TObjectWriter);
+      var
+        HeaderBytes: array [0..$3F] of Byte;
+      begin
+        aWriter.write(MsDosStub[0],Length(MsDosStub));
+
+        HeaderBytes[$00]:=$4E;  { 'N' }
+        HeaderBytes[$01]:=$45;  { 'E' }
+        HeaderBytes[$02]:=Byte(LinkerVersion);
+        HeaderBytes[$03]:=Byte(LinkerRevision);
+        HeaderBytes[$04]:=Byte(EntryTableOffset);
+        HeaderBytes[$05]:=Byte(EntryTableOffset shr 8);
+        HeaderBytes[$06]:=Byte(EntryTableLength);
+        HeaderBytes[$07]:=Byte(EntryTableLength shr 8);
+        HeaderBytes[$08]:=Byte(Reserved);
+        HeaderBytes[$09]:=Byte(Reserved shr 8);
+        HeaderBytes[$0A]:=Byte(Reserved shr 16);
+        HeaderBytes[$0B]:=Byte(Reserved shr 24);
+        HeaderBytes[$0C]:=Byte(Word(Flags));
+        HeaderBytes[$0D]:=Byte(Word(Flags) shr 8);
+        HeaderBytes[$0E]:=Byte(AutoDataSegmentNumber);
+        HeaderBytes[$0F]:=Byte(AutoDataSegmentNumber shr 8);
+        HeaderBytes[$10]:=Byte(InitialLocalHeapSize);
+        HeaderBytes[$11]:=Byte(InitialLocalHeapSize shr 8);
+        HeaderBytes[$12]:=Byte(InitialStackSize);
+        HeaderBytes[$13]:=Byte(InitialStackSize shr 8);
+        HeaderBytes[$14]:=Byte(InitialIP);
+        HeaderBytes[$15]:=Byte(InitialIP shr 8);
+        HeaderBytes[$16]:=Byte(InitialCS);
+        HeaderBytes[$17]:=Byte(InitialCS shr 8);
+        HeaderBytes[$18]:=Byte(InitialSP);
+        HeaderBytes[$19]:=Byte(InitialSP shr 8);
+        HeaderBytes[$1A]:=Byte(InitialSS);
+        HeaderBytes[$1B]:=Byte(InitialSS shr 8);
+        HeaderBytes[$1C]:=Byte(SegmentTableEntriesCount);
+        HeaderBytes[$1D]:=Byte(SegmentTableEntriesCount shr 8);
+        HeaderBytes[$1E]:=Byte(ModuleReferenceTableEntriesCount);
+        HeaderBytes[$1F]:=Byte(ModuleReferenceTableEntriesCount shr 8);
+        HeaderBytes[$20]:=Byte(NonresidentNameTableLength);
+        HeaderBytes[$21]:=Byte(NonresidentNameTableLength shr 8);
+        HeaderBytes[$22]:=Byte(SegmentTableStart);
+        HeaderBytes[$23]:=Byte(SegmentTableStart shr 8);
+        HeaderBytes[$24]:=Byte(ResourceTableStart);
+        HeaderBytes[$25]:=Byte(ResourceTableStart shr 8);
+        HeaderBytes[$26]:=Byte(ResidentNameTableStart);
+        HeaderBytes[$27]:=Byte(ResidentNameTableStart shr 8);
+        HeaderBytes[$28]:=Byte(ModuleReferenceTableStart);
+        HeaderBytes[$29]:=Byte(ModuleReferenceTableStart shr 8);
+        HeaderBytes[$2A]:=Byte(ImportedNameTableStart);
+        HeaderBytes[$2B]:=Byte(ImportedNameTableStart shr 8);
+        HeaderBytes[$2C]:=Byte(NonresidentNameTableStart);
+        HeaderBytes[$2D]:=Byte(NonresidentNameTableStart shr 8);
+        HeaderBytes[$2E]:=Byte(NonresidentNameTableStart shr 16);
+        HeaderBytes[$2F]:=Byte(NonresidentNameTableStart shr 24);
+        HeaderBytes[$30]:=Byte(MovableEntryPointsCount);
+        HeaderBytes[$31]:=Byte(MovableEntryPointsCount shr 8);
+        HeaderBytes[$32]:=Byte(LogicalSectorAlignmentShiftCount);
+        HeaderBytes[$33]:=Byte(LogicalSectorAlignmentShiftCount shr 8);
+        HeaderBytes[$34]:=Byte(ResourceSegmentsCount);
+        HeaderBytes[$35]:=Byte(ResourceSegmentsCount shr 8);
+        HeaderBytes[$36]:=Byte(Ord(TargetOS));
+        HeaderBytes[$37]:=Byte(AdditionalFlags);
+        HeaderBytes[$38]:=Byte(GangLoadAreaStart);
+        HeaderBytes[$39]:=Byte(GangLoadAreaStart shr 8);
+        HeaderBytes[$3A]:=Byte(GangLoadAreaLength);
+        HeaderBytes[$3B]:=Byte(GangLoadAreaLength shr 8);
+        HeaderBytes[$3C]:=Byte(Reserved2);
+        HeaderBytes[$3D]:=Byte(Reserved2 shr 8);
+        HeaderBytes[$3E]:=Byte(ExpectedWindowsVersion);
+        HeaderBytes[$3F]:=Byte(ExpectedWindowsVersion shr 8);
+
+        aWriter.write(HeaderBytes[0],$40);
+      end;
+
+{****************************************************************************
+                               TNewExeOutput
+****************************************************************************}
+
+    procedure TNewExeOutput.DoRelocationFixup(objsec: TObjSection);
+      begin
+        {todo}
+      end;
+
+    constructor TNewExeOutput.create;
+      begin
+        inherited create;
+        CObjData:=TOmfObjData;
+        CObjSymbol:=TOmfObjSymbol;
+        FHeader:=TNewExeHeader.Create;
+      end;
+
+    destructor TNewExeOutput.destroy;
+      begin
+        FHeader.Free;
+        inherited destroy;
+      end;
+
+    function TNewExeOutput.writeData: boolean;
+      begin
+        {todo}
+        Result:=False;
+      end;
+
 {****************************************************************************
 {****************************************************************************
                                TOmfAssembler
                                TOmfAssembler
 ****************************************************************************}
 ****************************************************************************}

+ 200 - 0
compiler/omfbase.pas

@@ -160,6 +160,12 @@ interface
     CC_DependencyFileBorland    = $E9;
     CC_DependencyFileBorland    = $E9;
     CC_CommandLineMicrosoft     = $FF;
     CC_CommandLineMicrosoft     = $FF;
 
 
+    { CC_OmfExtension subtypes }
+    CC_OmfExtension_IMPDEF      = $01;
+    CC_OmfExtension_EXPDEF      = $02;
+    CC_OmfExtension_INCDEF      = $03;
+    CC_OmfExtension_LNKDIR      = $05;
+
   type
   type
     TOmfSegmentAlignment = (
     TOmfSegmentAlignment = (
       saAbsolute                = 0,
       saAbsolute                = 0,
@@ -324,6 +330,58 @@ interface
       property NoList: Boolean read GetNoList write SetNoList;
       property NoList: Boolean read GetNoList write SetNoList;
     end;
     end;
 
 
+    { TOmfRecord_COMENT_Subtype }
+
+    TOmfRecord_COMENT_Subtype = class
+    public
+      procedure DecodeFrom(ComentRecord: TOmfRecord_COMENT);virtual;abstract;
+      procedure EncodeTo(ComentRecord: TOmfRecord_COMENT);virtual;abstract;
+    end;
+
+    { TOmfRecord_COMENT_IMPDEF }
+
+    TOmfRecord_COMENT_IMPDEF = class(TOmfRecord_COMENT_Subtype)
+    private
+      FImportByOrdinal: Boolean;
+      FInternalName: string;
+      FModuleName: string;
+      FOrdinal: Word;
+      FName: string;
+    public
+      procedure DecodeFrom(ComentRecord: TOmfRecord_COMENT);override;
+      procedure EncodeTo(ComentRecord: TOmfRecord_COMENT);override;
+
+      property ImportByOrdinal: Boolean read FImportByOrdinal write FImportByOrdinal;
+      property InternalName: string read FInternalName write FInternalName;
+      property ModuleName: string read FModuleName write FModuleName;
+      property Ordinal: Word read FOrdinal write FOrdinal;
+      property Name: string read FName write FName;
+    end;
+
+    { TOmfRecord_COMENT_EXPDEF }
+
+    TOmfRecord_COMENT_EXPDEF = class(TOmfRecord_COMENT_Subtype)
+    private
+      FExportByOrdinal: Boolean;
+      FResidentName: Boolean;
+      FNoData: Boolean;
+      FParmCount: Integer;
+      FExportedName: string;
+      FInternalName: string;
+      FExportOrdinal: Word;
+    public
+      procedure DecodeFrom(ComentRecord: TOmfRecord_COMENT);override;
+      procedure EncodeTo(ComentRecord: TOmfRecord_COMENT);override;
+
+      property ExportByOrdinal: Boolean read FExportByOrdinal write FExportByOrdinal;
+      property ResidentName: Boolean read FResidentName write FResidentName;
+      property NoData: Boolean read FNoData write FNoData;
+      property ParmCount: Integer read FParmCount write FParmCount;
+      property ExportedName: string read FExportedName write FExportedName;
+      property InternalName: string read FInternalName write FInternalName;
+      property ExportOrdinal: Word read FExportOrdinal write FExportOrdinal;
+    end;
+
     { TOmfRecord_LNAMES }
     { TOmfRecord_LNAMES }
 
 
     TOmfRecord_LNAMES = class(TOmfParsedRecord)
     TOmfRecord_LNAMES = class(TOmfParsedRecord)
@@ -1542,6 +1600,148 @@ implementation
       RawRecord.CalculateChecksumByte;
       RawRecord.CalculateChecksumByte;
     end;
     end;
 
 
+  { TOmfRecord_COMENT_IMPDEF }
+
+  procedure TOmfRecord_COMENT_IMPDEF.DecodeFrom(ComentRecord: TOmfRecord_COMENT);
+    var
+      InternalNameLen, ModuleNameLenIdx, ModuleNameLen, NameLenIdx,
+        NameLen, OrdinalIdx: Integer;
+    begin
+      if ComentRecord.CommentClass<>CC_OmfExtension then
+        internalerror(2019061621);
+      if Length(ComentRecord.CommentString)<5 then
+        internalerror(2019061622);
+      if ComentRecord.CommentString[1]<>Chr(CC_OmfExtension_IMPDEF) then
+        internalerror(2019061623);
+      ImportByOrdinal:=Ord(ComentRecord.CommentString[2])<>0;
+      InternalNameLen:=Ord(ComentRecord.CommentString[3]);
+      InternalName:=Copy(ComentRecord.CommentString,4,InternalNameLen);
+      ModuleNameLenIdx:=4+InternalNameLen;
+      if ModuleNameLenIdx>Length(ComentRecord.CommentString) then
+        internalerror(2019061624);
+      ModuleNameLen:=Ord(ComentRecord.CommentString[ModuleNameLenIdx]);
+      ModuleName:=Copy(ComentRecord.CommentString,ModuleNameLenIdx+1,ModuleNameLen);
+      if ImportByOrdinal then
+        begin
+          Name:='';
+          OrdinalIdx:=ModuleNameLenIdx+1+ModuleNameLen;
+          if (OrdinalIdx+1)>Length(ComentRecord.CommentString) then
+            internalerror(2019061625);
+          Ordinal:=Ord(ComentRecord.CommentString[OrdinalIdx]) or
+                   (Word(Ord(ComentRecord.CommentString[OrdinalIdx+1])) shl 8);
+        end
+      else
+        begin
+          Ordinal:=0;
+          NameLenIdx:=ModuleNameLenIdx+1+ModuleNameLen;
+          if NameLenIdx>Length(ComentRecord.CommentString) then
+            internalerror(2019061626);
+          NameLen:=Ord(ComentRecord.CommentString[NameLenIdx]);
+          if (NameLenIdx+NameLen)>Length(ComentRecord.CommentString) then
+            internalerror(2019061627);
+          Name:=Copy(ComentRecord.CommentString,NameLenIdx+1,NameLen);
+          if Name='' then
+            Name:=InternalName;
+        end;
+    end;
+
+  procedure TOmfRecord_COMENT_IMPDEF.EncodeTo(ComentRecord: TOmfRecord_COMENT);
+    begin
+      ComentRecord.CommentClass:=CC_OmfExtension;
+      if ImportByOrdinal then
+        ComentRecord.CommentString:=Chr(CC_OmfExtension_IMPDEF)+#1+
+                                    Chr(Length(InternalName))+InternalName+
+                                    Chr(Length(ModuleName))+ModuleName+
+                                    Chr(Ordinal and $ff)+Chr((Ordinal shr 8) and $ff)
+      else if InternalName=Name then
+        ComentRecord.CommentString:=Chr(CC_OmfExtension_IMPDEF)+#0+
+                                    Chr(Length(InternalName))+InternalName+
+                                    Chr(Length(ModuleName))+ModuleName+#0
+      else
+        ComentRecord.CommentString:=Chr(CC_OmfExtension_IMPDEF)+#0+
+                                    Chr(Length(InternalName))+InternalName+
+                                    Chr(Length(ModuleName))+ModuleName+
+                                    Chr(Length(Name))+Name;
+    end;
+
+  { TOmfRecord_COMENT_EXPDEF }
+
+  procedure TOmfRecord_COMENT_EXPDEF.DecodeFrom(ComentRecord: TOmfRecord_COMENT);
+    var
+      expflag: Byte;
+      ExportedNameLen, InternalNameLenIdx, InternalNameLen,
+        ExportOrdinalIdx: Integer;
+    begin
+      if ComentRecord.CommentClass<>CC_OmfExtension then
+        internalerror(2019061601);
+      if Length(ComentRecord.CommentString)<4 then
+        internalerror(2019061602);
+      if ComentRecord.CommentString[1]<>Chr(CC_OmfExtension_EXPDEF) then
+        internalerror(2019061603);
+      expflag:=Ord(ComentRecord.CommentString[2]);
+      ExportByOrdinal:=(expflag and $80)<>0;
+      ResidentName:=(expflag and $40)<>0;
+      NoData:=(expflag and $20)<>0;
+      ParmCount:=expflag and $1F;
+      ExportedNameLen:=Ord(ComentRecord.CommentString[3]);
+      ExportedName:=Copy(ComentRecord.CommentString,4,ExportedNameLen);
+      InternalNameLenIdx:=4+ExportedNameLen;
+      if InternalNameLenIdx>Length(ComentRecord.CommentString) then
+        internalerror(2019061604);
+      InternalNameLen:=Ord(ComentRecord.CommentString[InternalNameLenIdx]);
+      if (InternalNameLenIdx+InternalNameLen)>Length(ComentRecord.CommentString) then
+        internalerror(2019061605);
+      InternalName:=Copy(ComentRecord.CommentString,InternalNameLenIdx+1,InternalNameLen);
+      if ExportByOrdinal then
+        begin
+          ExportOrdinalIdx:=InternalNameLenIdx+1+InternalNameLen;
+          if (ExportOrdinalIdx+1)>Length(ComentRecord.CommentString) then
+            internalerror(2019061606);
+          ExportOrdinal:=Ord(ComentRecord.CommentString[ExportOrdinalIdx]) or
+                         (Word(Ord(ComentRecord.CommentString[ExportOrdinalIdx+1])) shl 8);
+        end
+      else
+        ExportOrdinal:=0;
+      if InternalName='' then
+        InternalName:=ExportedName;
+    end;
+
+  procedure TOmfRecord_COMENT_EXPDEF.EncodeTo(ComentRecord: TOmfRecord_COMENT);
+    var
+      expflag: Byte;
+    begin
+      ComentRecord.CommentClass:=CC_OmfExtension;
+
+      if (ParmCount<0) or (ParmCount>31) then
+        internalerror(2019061504);
+      expflag:=ParmCount;
+      if ExportByOrdinal then
+        expflag:=expflag or $80;
+      if ResidentName then
+        expflag:=expflag or $40;
+      if NoData then
+        expflag:=expflag or $20;
+
+      if ExportByOrdinal then
+        if InternalName=ExportedName then
+          ComentRecord.CommentString:=Chr(CC_OmfExtension_EXPDEF)+Chr(expflag)+
+                                      Chr(Length(ExportedName))+ExportedName+#0+
+                                      Chr(Byte(ExportOrdinal))+Chr(Byte(ExportOrdinal shr 8))
+        else
+          ComentRecord.CommentString:=Chr(CC_OmfExtension_EXPDEF)+Chr(expflag)+
+                                      Chr(Length(ExportedName))+ExportedName+
+                                      Chr(Length(InternalName))+InternalName+
+                                      Chr(Byte(ExportOrdinal))+Chr(Byte(ExportOrdinal shr 8))
+      else
+        if InternalName=ExportedName then
+          ComentRecord.CommentString:=Chr(CC_OmfExtension_EXPDEF)+Chr(expflag)+
+                                      Chr(Length(ExportedName))+ExportedName+#0
+        else
+          ComentRecord.CommentString:=Chr(CC_OmfExtension_EXPDEF)+Chr(expflag)+
+                                      Chr(Length(ExportedName))+ExportedName+
+                                      Chr(Length(InternalName))+InternalName;
+    end;
+
   { TOmfRecord_LNAMES }
   { TOmfRecord_LNAMES }
 
 
   constructor TOmfRecord_LNAMES.Create;
   constructor TOmfRecord_LNAMES.Create;

+ 9 - 7
compiler/pp.lpi

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?xml version="1.0" encoding="UTF-8"?>
 <CONFIG>
 <CONFIG>
   <ProjectOptions>
   <ProjectOptions>
-    <Version Value="9"/>
+    <Version Value="11"/>
     <PathDelim Value="\"/>
     <PathDelim Value="\"/>
     <General>
     <General>
       <Flags>
       <Flags>
@@ -19,13 +19,12 @@
     </BuildModes>
     </BuildModes>
     <PublishOptions>
     <PublishOptions>
       <Version Value="2"/>
       <Version Value="2"/>
-      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
-      <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
     </PublishOptions>
     </PublishOptions>
     <RunParams>
     <RunParams>
-      <local>
-        <FormatVersion Value="1"/>
-      </local>
+      <FormatVersion Value="2"/>
+      <Modes Count="1">
+        <Mode0 Name="default"/>
+      </Modes>
     </RunParams>
     </RunParams>
     <Units Count="2">
     <Units Count="2">
       <Unit0>
       <Unit0>
@@ -66,7 +65,10 @@
       <ConfigFile>
       <ConfigFile>
         <StopAfterErrCount Value="50"/>
         <StopAfterErrCount Value="50"/>
       </ConfigFile>
       </ConfigFile>
-      <CustomOptions Value="-di386 -dEXTDEBUG"/>
+      <CustomOptions Value="-di386
+-dEXTDEBUG
+-Sew
+-Oodfa"/>
     </Other>
     </Other>
   </CompilerOptions>
   </CompilerOptions>
 </CONFIG>
 </CONFIG>

+ 15 - 3
compiler/symdef.pas

@@ -2231,11 +2231,23 @@ implementation
             is_intregable:=(is_implicit_pointer_object_type(self)) and not needs_inittable;
             is_intregable:=(is_implicit_pointer_object_type(self)) and not needs_inittable;
           setdef:
           setdef:
             is_intregable:=is_smallset(self);
             is_intregable:=is_smallset(self);
+          arraydef:
+{$ifdef cpuhighleveltarget}
+            is_intregable:=false
+{$else cpuhighleveltarget}
+            is_intregable:=not(is_special_array(self)) and
+              (tarraydef(self).size in [1,2,4,8]) and tstoreddef(tarraydef(self).elementdef).is_intregable
+{$ifdef SUPPORT_MMX}
+              and not((cs_mmx in current_settings.localswitches) and
+                 is_mmx_able_array(self))
+{$endif SUPPORT_MMX}
+{$endif cpuhighleveltarget}
+              ;
           recorddef:
           recorddef:
             begin
             begin
-{$ifdef llvm}
+{$ifdef cpuhighleveltarget}
               is_intregable:=false;
               is_intregable:=false;
-{$else llvm}
+{$else cpuhighleveltarget}
               recsize:=size;
               recsize:=size;
               is_intregable:=
               is_intregable:=
                 ispowerof2(recsize,temp) and
                 ispowerof2(recsize,temp) and
@@ -2247,7 +2259,7 @@ implementation
                   (recsize <= sizeof(aint))
                   (recsize <= sizeof(aint))
                  ) and
                  ) and
                  not needs_inittable;
                  not needs_inittable;
-{$endif llvm}
+{$endif cpuhighleveltarget}
             end;
             end;
           else
           else
            is_intregable:=false;
            is_intregable:=false;

+ 2 - 1
compiler/systems.inc

@@ -280,7 +280,8 @@
              ld_int_nativent,
              ld_int_nativent,
              ld_int_netware,
              ld_int_netware,
              ld_int_windows,
              ld_int_windows,
-             ld_int_msdos
+             ld_int_msdos,
+             ld_int_win16
        );
        );
 
 
        tar = (ar_none
        tar = (ar_none

+ 21 - 0
compiler/systems.pas

@@ -434,6 +434,27 @@ interface
          (name: 'RISCVHF'; supported:{$if defined(riscv32) or defined(riscv64)}true{$else}false{$endif})
          (name: 'RISCVHF'; supported:{$if defined(riscv32) or defined(riscv64)}true{$else}false{$endif})
        );
        );
 
 
+       { x86 asm modes with an Intel-style syntax }
+       asmmodes_x86_intel = [
+{$ifdef i8086}
+         asmmode_standard,
+{$endif i8086}
+         asmmode_i8086_intel,
+         asmmode_i386_intel,
+         asmmode_x86_64_intel
+       ];
+
+       { x86 asm modes with an AT&T-style syntax }
+       asmmodes_x86_att = [
+{$if defined(i386) or defined(x86_64)}
+         asmmode_standard,
+{$endif}
+         asmmode_i8086_att,
+         asmmode_i386_att,
+         asmmode_x86_64_att,
+         asmmode_x86_64_gas
+       ];
+
     var
     var
        targetinfos   : array[tsystem] of psysteminfo;
        targetinfos   : array[tsystem] of psysteminfo;
        arinfos       : array[tar] of parinfo;
        arinfos       : array[tar] of parinfo;

+ 109 - 120
compiler/systems/t_gba.pas

@@ -244,15 +244,16 @@ begin
       add('/*         support added to allow labels end, _end, */');
       add('/*         support added to allow labels end, _end, */');
       add('/*         & __end__ to point to end of iwram or    */');
       add('/*         & __end__ to point to end of iwram or    */');
       add('/*         the end of ewram.                        */');
       add('/*         the end of ewram.                        */');
-      add('/*	Additions by WinterMute				*/');
-      add('/* v1.4 -	.sbss section added for unitialised	*/');
-      add('/*		    data in ewram 			*/');
-      add('/* v1.5 -	padding section added to stop EZF 	*/');
-      add('/*		    stripping important data		*/');
+      add('/*	Additions by WinterMute	               	*/');
+      add('/* v1.4 -	.sbss section added for unitialised		*/');
+      add('/*		    data in ewram 							*/');
+      add('/* v1.5 -	padding section added to stop EZF 		*/');
+      add('/*		    stripping important data				*/');
+      add('/* v1.6 -	added memory sections			 		*/');
       add('');
       add('');
       add('/* This file is released into the public domain		*/');
       add('/* This file is released into the public domain		*/');
       add('/* for commercial or non-commercial use with no		*/');
       add('/* for commercial or non-commercial use with no		*/');
-      add('/* restrictions placed upon it.				*/');
+      add('/* restrictions placed upon it.						*/');
       add('');
       add('');
       add('/* NOTE!!!: This linker script defines the RAM &  */');
       add('/* NOTE!!!: This linker script defines the RAM &  */');
       add('/*   ROM start addresses. In order for it to work */');
       add('/*   ROM start addresses. In order for it to work */');
@@ -270,16 +271,6 @@ begin
       add('OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")');
       add('OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")');
       add('OUTPUT_ARCH(arm)');
       add('OUTPUT_ARCH(arm)');
       add('ENTRY(_start)');
       add('ENTRY(_start)');
-      add('/* SEARCH_DIR(/bin/arm); */');
-      add('');
-      add('/* The linker script function "var1 += var2;" sometimes    */');
-      add('/* reports incorrect values in the *.map file but the      */');
-      add('/* actual value it calculates is usually, if not always,   */');
-      add('/* correct. If you leave out the ". = ALIGN(4);" at the    */');
-      add('/* end of each section then the return value of SIZEOF()   */');
-      add('/* is sometimes incorrect and "var1 += var2;" appears to   */');
-      add('/* not work as well. "var1 += var2" style functions are    */');
-      add('/* avoided below as a result.                              */');
       add('');
       add('');
       add('MEMORY {');
       add('MEMORY {');
       add('');
       add('');
@@ -288,10 +279,13 @@ begin
       add('	ewram	: ORIGIN = 0x02000000, LENGTH = 256K');
       add('	ewram	: ORIGIN = 0x02000000, LENGTH = 256K');
       add('}');
       add('}');
       add('');
       add('');
-      add('__text_start	=	ORIGIN(rom);');
+      add('');
+      add('');
+      add('__text_start	=	ORIGIN(ewram);');
       add('__eheap_end	=	ORIGIN(ewram) + LENGTH(ewram);');
       add('__eheap_end	=	ORIGIN(ewram) + LENGTH(ewram);');
       add('__iwram_start	=	ORIGIN(iwram);');
       add('__iwram_start	=	ORIGIN(iwram);');
       add('__iwram_top	=	ORIGIN(iwram) + LENGTH(iwram);;');
       add('__iwram_top	=	ORIGIN(iwram) + LENGTH(iwram);;');
+      add('');
       add('__sp_irq	=	__iwram_top - 0x060;');
       add('__sp_irq	=	__iwram_top - 0x060;');
       add('__sp_usr	=	__sp_irq - 0x0a0;');
       add('__sp_usr	=	__sp_irq - 0x0a0;');
       add('__irq_flags	=	0x03007ff8;');
       add('__irq_flags	=	0x03007ff8;');
@@ -299,19 +293,26 @@ begin
       add('SECTIONS');
       add('SECTIONS');
       add('{');
       add('{');
       add('	. = __text_start;');
       add('	. = __text_start;');
-      add('	.init :');
+      add('	. = __text_start;');
+      add('	.crt0 :');
       add('	{');
       add('	{');
-      add('		KEEP (*(.init))');
+      add('		KEEP (*(.crt0))');
       add('		. = ALIGN(4);');
       add('		. = ALIGN(4);');
-      add('	} >rom =0xff');
+      add('	} >ewram =0xff');
+      add('');
+      add('	.init :');
+      add('	{');
+      add('		KEEP (*(SORT_NONE(.init)))');
+      add('	} >ewram');
       add('');
       add('');
       add('	.plt :');
       add('	.plt :');
       add('	{');
       add('	{');
       add('		*(.plt)');
       add('		*(.plt)');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-      add('	} >rom');
+      add('	} >ewram');
       add('');
       add('');
-      add('	.text  :   /* ALIGN (4): */');
+      add('');
+      add('	.text  ALIGN (4):');
       add('	{');
       add('	{');
       add('		*(EXCLUDE_FILE (*.iwram*) .text)');
       add('		*(EXCLUDE_FILE (*.iwram*) .text)');
       add('		*(.text .stub .text.* .gnu.linkonce.t.*)');
       add('		*(.text .stub .text.* .gnu.linkonce.t.*)');
@@ -320,14 +321,14 @@ begin
       add('		*(.gnu.warning)');
       add('		*(.gnu.warning)');
       add('		*(.glue_7t) *(.glue_7) *(.vfp11_veneer)');
       add('		*(.glue_7t) *(.glue_7) *(.vfp11_veneer)');
       add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
       add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
-      add('	} >rom = 0xff');
+      add('	} >ewram = 0xff');
       add('');
       add('');
       add('	__text_end = .;');
       add('	__text_end = .;');
       add('	.fini           :');
       add('	.fini           :');
       add('	{');
       add('	{');
       add('		KEEP (*(.fini))');
       add('		KEEP (*(.fini))');
-      add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
-      add('	} >rom =0');
+      add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
+      add('	} >ewram =0');
       add('');
       add('');
       add('	.rodata :');
       add('	.rodata :');
       add('	{');
       add('	{');
@@ -338,12 +339,26 @@ begin
       add('		*(.gnu.linkonce.r*)');
       add('		*(.gnu.linkonce.r*)');
       add('		SORT(CONSTRUCTORS)');
       add('		SORT(CONSTRUCTORS)');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-      add('	} >rom = 0xff');
-      add('  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >rom');
+      add('	} >ewram = 0xff');
+      add('');
+      add('  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >ewram');
       add('   __exidx_start = .;');
       add('   __exidx_start = .;');
-      add('  .ARM.exidx   : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >rom');
+      add('  .ARM.exidx   : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >ewram');
       add('   __exidx_end = .;');
       add('   __exidx_end = .;');
-      add('');
+      add('  /* Ensure the __preinit_array_start label is properly aligned.  We');
+      add('     could instead move the label definition inside the section, but');
+      add('     the linker would then create the section even if it turns out to');
+      add('     be empty, which isn''t pretty.  */');
+      add('  . = ALIGN(32 / 8);');
+      add('  PROVIDE (__preinit_array_start = .);');
+      add('  .preinit_array     : { KEEP (*(.preinit_array)) } >ewram = 0xff');
+      add('  PROVIDE (__preinit_array_end = .);');
+      add('  PROVIDE (__init_array_start = .);');
+      add('  .init_array     : { KEEP (*(.init_array)) } >ewram = 0xff');
+      add('  PROVIDE (__init_array_end = .);');
+      add('  PROVIDE (__fini_array_start = .);');
+      add('  .fini_array     : { KEEP (*(.fini_array)) } >ewram = 0xff');
+      add('  PROVIDE (__fini_array_end = .);');
       add('	.ctors :');
       add('	.ctors :');
       add('	{');
       add('	{');
       add('		/*	gcc uses crtbegin.o to find the start of the constructors, so');
       add('		/*	gcc uses crtbegin.o to find the start of the constructors, so');
@@ -357,7 +372,7 @@ begin
       add('		KEEP (*(SORT(.ctors.*)))');
       add('		KEEP (*(SORT(.ctors.*)))');
       add('		KEEP (*(.ctors))');
       add('		KEEP (*(.ctors))');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-      add('	} >rom = 0');
+      add('	} >ewram = 0');
       add('');
       add('');
       add('	.dtors :');
       add('	.dtors :');
       add('	{');
       add('	{');
@@ -366,144 +381,121 @@ begin
       add('		KEEP (*(SORT(.dtors.*)))');
       add('		KEEP (*(SORT(.dtors.*)))');
       add('		KEEP (*(.dtors))');
       add('		KEEP (*(.dtors))');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-      add('	} >rom = 0');
-      add('');
+      add('	} >ewram = 0');
       add('');
       add('');
+      add('	.jcr            : { KEEP (*(.jcr)) } >ewram');
       add('	.eh_frame :');
       add('	.eh_frame :');
       add('	{');
       add('	{');
       add('		KEEP (*(.eh_frame))');
       add('		KEEP (*(.eh_frame))');
-      add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-      add('	} >rom = 0');
+      add('	. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
+      add('	} >ewram = 0');
       add('');
       add('');
       add('	.gcc_except_table :');
       add('	.gcc_except_table :');
       add('	{');
       add('	{');
       add('		*(.gcc_except_table)');
       add('		*(.gcc_except_table)');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-      add('	} >rom = 0');
+      add('	} >ewram = 0');
       add('');
       add('');
       add('	__iwram_lma = .;');
       add('	__iwram_lma = .;');
       add('');
       add('');
       add('	.iwram __iwram_start : AT (__iwram_lma)');
       add('	.iwram __iwram_start : AT (__iwram_lma)');
       add('	{');
       add('	{');
-      add('		__iwram_start = ABSOLUTE(.) ;');
+      add('		__iwram_start__ = ABSOLUTE(.) ;');
       add('		*(.iwram)');
       add('		*(.iwram)');
       add('		*iwram.*(.text)');
       add('		*iwram.*(.text)');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-      add('		__iwram_end = ABSOLUTE(.) ;');
+      add('		__iwram_end__ = ABSOLUTE(.) ;');
       add('	} >iwram = 0xff');
       add('	} >iwram = 0xff');
       add('');
       add('');
       add('	__data_lma = __iwram_lma + SIZEOF(.iwram) ;');
       add('	__data_lma = __iwram_lma + SIZEOF(.iwram) ;');
       add('');
       add('');
-      add('	.bss ALIGN(4) (NOLOAD) :');
+      add('	.bss ALIGN(4) (NOLOAD):');
       add('	{');
       add('	{');
-      add('		__bss_start = ABSOLUTE(.);');
       add('		__bss_start__ = ABSOLUTE(.);');
       add('		__bss_start__ = ABSOLUTE(.);');
       add('		*(.dynbss)');
       add('		*(.dynbss)');
       add('		*(.gnu.linkonce.b*)');
       add('		*(.gnu.linkonce.b*)');
       add('		*(.bss*)');
       add('		*(.bss*)');
       add('		*(COMMON)');
       add('		*(COMMON)');
       add('		. = ALIGN(4);    /* REQUIRED. LD is flaky without it. */');
       add('		. = ALIGN(4);    /* REQUIRED. LD is flaky without it. */');
-      add('		__bss_end = ABSOLUTE(.) ;');
-      add('');
-      add('	} AT>iwram');
-      add('');
-      add('	__bss_end__ = __bss_end ;');
+      add('		__bss_end__ = ABSOLUTE(.) ;');
+      add('	}');
       add('');
       add('');
       add('	.data ALIGN(4) : AT (__data_lma)');
       add('	.data ALIGN(4) : AT (__data_lma)');
       add('	{');
       add('	{');
-      add('		__data_start = ABSOLUTE(.);');
+      add('		__data_start__ = ABSOLUTE(.);');
       add('		*(.data)');
       add('		*(.data)');
       add('		*(.data.*)');
       add('		*(.data.*)');
       add('		*(.gnu.linkonce.d*)');
       add('		*(.gnu.linkonce.d*)');
-      add('		*(.fpc*)');
       add('		CONSTRUCTORS');
       add('		CONSTRUCTORS');
-      add('		. = ALIGN(4);');
+      add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
+      add('		__data_end__  =  ABSOLUTE(.);');
       add('	} >iwram = 0xff');
       add('	} >iwram = 0xff');
       add('');
       add('');
-      add('	__preinit_lma = __data_lma + SIZEOF(.data);');
-      add('');
-      add('	PROVIDE (__preinit_array_start = .);');
-      add('	.preinit_array     : AT (__preinit_lma) { KEEP (*(.preinit_array)) } >iwram');
-      add('	PROVIDE (__preinit_array_end = .);');
+      add('	__iwram_overlay_lma = __data_lma + SIZEOF(.data);');
       add('');
       add('');
-      add('	__init_lma = __preinit_lma + SIZEOF(.preinit_array);');
+      add('	PROVIDE (edata = .);');
+      add('	__iwram_overlay_start = . ;');
       add('');
       add('');
-      add('	PROVIDE (__init_array_start = .);');
-      add('	.init_array     : AT (__init_lma)');
+      add('	OVERLAY ALIGN(4) : NOCROSSREFS AT (__iwram_overlay_lma)');
       add('	{');
       add('	{');
-      add('		KEEP (*(SORT(.init_array.*)))');
-      add('		KEEP (*(.init_array))');
-      add('	} >iwram');
-      add('	PROVIDE (__init_array_end = .);');
-      add('	PROVIDE (__fini_array_start = .);');
-      add('');
-      add('	__fini_lma = __init_lma + SIZEOF(.init_array);');
+      add('	   .iwram0 { *(.iwram0) . = ALIGN(4);}');
+      add('	   .iwram1 { *(.iwram1) . = ALIGN(4);}');
+      add('	   .iwram2 { *(.iwram2) . = ALIGN(4);}');
+      add('	   .iwram3 { *(.iwram3) . = ALIGN(4);}');
+      add('	   .iwram4 { *(.iwram4) . = ALIGN(4);}');
+      add('	   .iwram5 { *(.iwram5) . = ALIGN(4);}');
+      add('	   .iwram6 { *(.iwram6) . = ALIGN(4);}');
+      add('	   .iwram7 { *(.iwram7) . = ALIGN(4);}');
+      add('	   .iwram8 { *(.iwram8) . = ALIGN(4);}');
+      add('	   .iwram9 { *(.iwram9) . = ALIGN(4);}');
+      add('	} >iwram = 0xff');
       add('');
       add('');
-      add('	.fini_array     : AT (__fini_lma)');
-      add('	{');
-      add('		KEEP (*(SORT(.fini_array.*)))');
-      add('		KEEP (*(.fini_array))');
-      add('	} >iwram');
-      add('  	PROVIDE (__fini_array_end = .);');
+      add('	__ewram_lma = LOADADDR(.iwram0) + SIZEOF(.iwram0)+SIZEOF(.iwram1)+SIZEOF(.iwram2)+SIZEOF(.iwram3)+SIZEOF(.iwram4)+SIZEOF(.iwram5)+SIZEOF(.iwram6)+SIZEOF(.iwram7)+SIZEOF(.iwram8)+SIZEOF(.iwram9);');
       add('');
       add('');
-      add('	__jcr_lma = __fini_lma + SIZEOF(.fini_array);');
-      add('	.jcr            : AT (__jcr_lma) { KEEP (*(.jcr)) } >iwram');
+      add('	__iwram_overlay_end = __ewram_lma ;');
       add('');
       add('');
-      add('	__data_end  =  ABSOLUTE(.);');
-      add('	__iwram_overlay_lma = __jcr_lma + SIZEOF(.jcr);');
+      add('	/* v1.3 */');
+      add('	__ewram_start =  __ewram_lma ;');
       add('');
       add('');
-      add('	__iwram_overlay_start = . ;');
-      add('');
-      add('	OVERLAY ALIGN(4) : NOCROSSREFS AT (__iwram_overlay_lma)');
-      add('	{');
-      add('		.iwram0 { *(.iwram0) . = ALIGN(4);}');
-      add('		.iwram1 { *(.iwram1) . = ALIGN(4);}');
-      add('		.iwram2 { *(.iwram2) . = ALIGN(4);}');
-      add('		.iwram3 { *(.iwram3) . = ALIGN(4);}');
-      add('		.iwram4 { *(.iwram4) . = ALIGN(4);}');
-      add('		.iwram5 { *(.iwram5) . = ALIGN(4);}');
-      add('		.iwram6 { *(.iwram6) . = ALIGN(4);}');
-      add('		.iwram7 { *(.iwram7) . = ALIGN(4);}');
-      add('		.iwram8 { *(.iwram8) . = ALIGN(4);}');
-      add('		.iwram9 { *(.iwram9) . = ALIGN(4);}');
-      add('	}>iwram = 0xff');
-      add('');
-      add('	__iwram_overlay_end = . ;');
-      add('  __ewram_lma = __iwram_overlay_lma + (__iwram_overlay_end - __iwram_overlay_start) ;');
-      add('');
-      add('	__iheap_start = . ;');
-      add('');
-      add('	__ewram_start = ORIGIN(ewram);');
       add('	.ewram __ewram_start : AT (__ewram_lma)');
       add('	.ewram __ewram_start : AT (__ewram_lma)');
       add('	{');
       add('	{');
       add('		*(.ewram)');
       add('		*(.ewram)');
       add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
       add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
-      add('	}>ewram = 0xff');
+      add('		__ewram_end = ABSOLUTE(.);');
+      add('	} >ewram = 0xff');
       add('');
       add('');
-      add('	__pad_lma = __ewram_lma + SIZEOF(.ewram);');
+      add('	__ewram_overlay_lma = __ewram_lma + SIZEOF(.ewram);');
       add('');
       add('');
       add('	.sbss ALIGN(4)(NOLOAD):');
       add('	.sbss ALIGN(4)(NOLOAD):');
       add(' 	{');
       add(' 	{');
-      add('		__sbss_start = ABSOLUTE(.);');
-      add(' 		*(.sbss)');
-      add(' 		. = ALIGN(4);');
-      add('		__sbss_end  = ABSOLUTE(.);');
-      add(' 	} AT>ewram');
-      add('');
-      add('');
-      add('	__ewram_end = __sbss_end ;');
-      add('	__eheap_start = __sbss_end;');
-      add('	__end__ = __sbss_end;');
+      add('		__sbss_start__ = ABSOLUTE(.);');
+      add('		*(.sbss)');
+      add('		. = ALIGN(4);');
+      add('		__sbss_end__  = ABSOLUTE(.);');
+      add('		__end__ = ABSOLUTE(.);');
+      add('		__eheap_start = ABSOLUTE(.);');
+      add('	}');
       add('');
       add('');
-      add('	/* EZF Advance strips trailing 0xff bytes, add a pad section so nothing important is removed */');
-      add('	.pad ALIGN(4) : AT (__pad_lma)');
+      add('	OVERLAY ALIGN(4): NOCROSSREFS AT (__ewram_overlay_lma)');
       add('	{');
       add('	{');
-      add('		LONG(0x52416b64)');
-      add('		LONG(0x4d)');
-      add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
-      add('	} = 0xff');
-      add('	__rom_end__ = __pad_lma + SIZEOF(.pad);');
-      add('');
+      add('		.ewram0 { *(.ewram0) . = ALIGN(4);}');
+      add('		.ewram1 { *(.ewram1) . = ALIGN(4);}');
+      add('		.ewram2 { *(.ewram2) . = ALIGN(4);}');
+      add('		.ewram3 { *(.ewram3) . = ALIGN(4);}');
+      add('		.ewram4 { *(.ewram4) . = ALIGN(4);}');
+      add('		.ewram5 { *(.ewram5) . = ALIGN(4);}');
+      add('		.ewram6 { *(.ewram6) . = ALIGN(4);}');
+      add('		.ewram7 { *(.ewram7) . = ALIGN(4);}');
+      add('		.ewram8 { *(.ewram8) . = ALIGN(4);}');
+      add('		.ewram9 { *(.ewram9) . = ALIGN(4);}');
+      add('	} >ewram = 0xff');
+      add('	__ewram_overlay_end  = ABSOLUTE(.);');
+      add('');
+      add('	__eheap_start = __ewram_overlay_end ;');
+      add('');
+      add('	_end = __ewram_overlay_end;');
+      add('	__end__ = __ewram_overlay_end;');
+      add('	__rom_end__ = __ewram_overlay_end;');
       add('');
       add('');
       add('	/* Stabs debugging sections.  */');
       add('	/* Stabs debugging sections.  */');
       add('	.stab 0 : { *(.stab) }');
       add('	.stab 0 : { *(.stab) }');
@@ -513,9 +505,9 @@ begin
       add('	.stab.index 0 : { *(.stab.index) }');
       add('	.stab.index 0 : { *(.stab.index) }');
       add('	.stab.indexstr 0 : { *(.stab.indexstr) }');
       add('	.stab.indexstr 0 : { *(.stab.indexstr) }');
       add('	.comment 0 : { *(.comment) }');
       add('	.comment 0 : { *(.comment) }');
-      add('	/*	DWARF debug sections.');
-      add('		Symbols in the DWARF debugging sections are relative to the beginning');
-      add('		of the section so we begin them at 0.  */');
+      add('	/* DWARF debug sections.');
+      add('	   Symbols in the DWARF debugging sections are relative to the beginning');
+      add('	   of the section so we begin them at 0.  */');
       add('	/* DWARF 1 */');
       add('	/* DWARF 1 */');
       add('	.debug          0 : { *(.debug) }');
       add('	.debug          0 : { *(.debug) }');
       add('	.line           0 : { *(.line) }');
       add('	.line           0 : { *(.line) }');
@@ -540,9 +532,6 @@ begin
       add('	.debug_varnames  0 : { *(.debug_varnames) }');
       add('	.debug_varnames  0 : { *(.debug_varnames) }');
       add('	.stack 0x80000 : { _stack = .; *(.stack) }');
       add('	.stack 0x80000 : { _stack = .; *(.stack) }');
       add('	/* These must appear regardless of  .  */');
       add('	/* These must appear regardless of  .  */');
-      add('  .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }');
-      add('  .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }');
-      add('  /DISCARD/ : { *(.note.GNU-stack) }');
       add('}');
       add('}');
     end;
     end;
 
 

+ 199 - 103
compiler/systems/t_nds.pas

@@ -248,22 +248,24 @@ begin
       if apptype=app_arm9 then //ARM9
       if apptype=app_arm9 then //ARM9
       begin
       begin
         add('MEMORY {');
         add('MEMORY {');
-        add('	rom	: ORIGIN = 0x08000000, LENGTH = 32M');
-        add('	ewram	: ORIGIN = 0x02000000, LENGTH = 4M - 4k');
+        add('	ewram	: ORIGIN = 0x02000000, LENGTH = 4M - 512k');
         add('	dtcm	: ORIGIN = 0x0b000000, LENGTH = 16K');
         add('	dtcm	: ORIGIN = 0x0b000000, LENGTH = 16K');
         add('	vectors	: ORIGIN = 0x01000000, LENGTH = 256');
         add('	vectors	: ORIGIN = 0x01000000, LENGTH = 256');
         add('	itcm	: ORIGIN = 0x01000100, LENGTH = 32K - 256');
         add('	itcm	: ORIGIN = 0x01000100, LENGTH = 32K - 256');
         add('}');
         add('}');
-        add('');
-        add('OUTPUT_ARCH(arm)');
+
+        add('/*--------------------------------------------------------------------------------');
+        add('	This Source Code Form is subject to the terms of the Mozilla Public License,');
+        add('	v. 2.0. If a copy of the MPL was not distributed with this file, You can');
+        add('	obtain one at https://mozilla.org/MPL/2.0/.');
+        add('--------------------------------------------------------------------------------*/');
         add('OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")');
         add('OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")');
+        add('OUTPUT_ARCH(arm)');
         add('ENTRY(_start)');
         add('ENTRY(_start)');
         add('');
         add('');
-        add('__vectors_start	=	ORIGIN(vectors);');
-        add('__itcm_start	=	ORIGIN(itcm);');
         add('__ewram_end	=	ORIGIN(ewram) + LENGTH(ewram);');
         add('__ewram_end	=	ORIGIN(ewram) + LENGTH(ewram);');
         add('__eheap_end	=	ORIGIN(ewram) + LENGTH(ewram);');
         add('__eheap_end	=	ORIGIN(ewram) + LENGTH(ewram);');
-        add('__dtcm_start	=	ORIGIN(dtcm);');
+        add('');
         add('__dtcm_top	=	ORIGIN(dtcm) + LENGTH(dtcm);');
         add('__dtcm_top	=	ORIGIN(dtcm) + LENGTH(dtcm);');
         add('__irq_flags	=	__dtcm_top - 0x08;');
         add('__irq_flags	=	__dtcm_top - 0x08;');
         add('__irq_vector	=	__dtcm_top - 0x04;');
         add('__irq_vector	=	__dtcm_top - 0x04;');
@@ -272,52 +274,67 @@ begin
         add('__sp_irq	=	__sp_svc - 0x100;');
         add('__sp_irq	=	__sp_svc - 0x100;');
         add('__sp_usr	=	__sp_irq - 0x100;');
         add('__sp_usr	=	__sp_irq - 0x100;');
         add('');
         add('');
+        add('PHDRS {');
+        add('	main    PT_LOAD FLAGS(7);');
+        add('	dtcm    PT_LOAD FLAGS(7);');
+        add('	itcm    PT_LOAD FLAGS(7);');
+        add('	vectors PT_LOAD FLAGS(7);');
+        add('	twl     PT_LOAD FLAGS(0x100007);');
+        add('}');
+        add('');
         add('SECTIONS');
         add('SECTIONS');
         add('{');
         add('{');
-        add('	.init	:');
+        add('	/* Secure area crap */');
+        add('	.secure : { *(.secure) } >ewram :main = 0');
+        add('');
+        add('	.crt0	:');
         add('	{');
         add('	{');
         add('		__text_start = . ;');
         add('		__text_start = . ;');
-        add('		KEEP (*(.init))');
+        add('		KEEP (*(.crt0))');
         add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
         add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
-        add('	} >ewram = 0xff');
+        add('	} >ewram :main = 0x00');
         add('');
         add('');
-        add('	.plt : { *(.plt) } >ewram = 0xff');
+        add('	.plt : { *(.plt) } >ewram :main = 0xff');
         add('');
         add('');
-        add('	.text :   /* ALIGN (4): */');
+        add('	.init :');
         add('	{');
         add('	{');
-        add('		*(EXCLUDE_FILE (*.itcm*) .text)');
+        add('		KEEP (*(SORT_NONE(.init)))');
+        add('	} >ewram :main');
         add('');
         add('');
-        add('		*(.text.*)');
-        add('		*(.stub)');
+        add('	.text :   /* ALIGN (4): */');
+        add('	{');
+        add('		*(EXCLUDE_FILE(*.itcm* *.vectors* *.twl*) .text)');
+        add('		*(EXCLUDE_FILE(*.itcm* *.vectors* *.twl*) .stub)');
+        add('		*(EXCLUDE_FILE(*.itcm* *.vectors* *.twl*) .text.*)');
         add('		/* .gnu.warning sections are handled specially by elf32.em.  */');
         add('		/* .gnu.warning sections are handled specially by elf32.em.  */');
-        add('		*(.gnu.warning)');
-        add('		*(.gnu.linkonce.t*)');
+        add('		*(EXCLUDE_FILE(*.twl*) .gnu.warning)');
+        add('		*(EXCLUDE_FILE(*.twl*) .gnu.linkonce.t*)');
         add('		*(.glue_7)');
         add('		*(.glue_7)');
         add('		*(.glue_7t)');
         add('		*(.glue_7t)');
         add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
         add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
-        add('	} >ewram = 0xff');
+        add('	} >ewram :main = 0xff');
         add('');
         add('');
         add('	.fini           :');
         add('	.fini           :');
         add('	{');
         add('	{');
         add('		KEEP (*(.fini))');
         add('		KEEP (*(.fini))');
-        add('	} >ewram =0xff');
+        add('	} >ewram :main =0xff');
         add('');
         add('');
         add('	__text_end = . ;');
         add('	__text_end = . ;');
         add('');
         add('');
         add('	.rodata :');
         add('	.rodata :');
         add('	{');
         add('	{');
-        add('		*(.rodata)');
+        add('		*(EXCLUDE_FILE(*.twl*) .rodata)');
         add('		*all.rodata*(*)');
         add('		*all.rodata*(*)');
-        add('		*(.roda)');
-        add('		*(.rodata.*)');
-        add('		*(.gnu.linkonce.r*)');
+        add('		*(EXCLUDE_FILE(*.twl*) .roda)');
+        add('		*(EXCLUDE_FILE(*.twl*) .rodata.*)');
+        add('		*(EXCLUDE_FILE(*.twl*) .gnu.linkonce.r*)');
         add('		SORT(CONSTRUCTORS)');
         add('		SORT(CONSTRUCTORS)');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-        add('	} >ewram = 0xff');
+        add('	} >ewram :main = 0xff');
         add('');
         add('');
-        add('	.ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >ewram');
+        add('	.ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >ewram :main');
         add(' 	__exidx_start = .;');
         add(' 	__exidx_start = .;');
-        add('	ARM.exidx   : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >ewram');
+        add('	ARM.exidx   : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >ewram :main');
         add(' 	__exidx_end = .;');
         add(' 	__exidx_end = .;');
         add('');
         add('');
         add('	/*	Ensure the __preinit_array_start label is properly aligned.  We');
         add('	/*	Ensure the __preinit_array_start label is properly aligned.  We');
@@ -328,21 +345,21 @@ begin
         add('	. = ALIGN(32 / 8);');
         add('	. = ALIGN(32 / 8);');
         add('');
         add('');
         add('	PROVIDE (__preinit_array_start = .);');
         add('	PROVIDE (__preinit_array_start = .);');
-        add('	.preinit_array     : { KEEP (*(.preinit_array)) } >ewram = 0xff');
+        add('	.preinit_array     : { KEEP (*(.preinit_array)) } >ewram :main = 0xff');
         add('	PROVIDE (__preinit_array_end = .);');
         add('	PROVIDE (__preinit_array_end = .);');
         add('	PROVIDE (__init_array_start = .);');
         add('	PROVIDE (__init_array_start = .);');
         add('	.init_array     :');
         add('	.init_array     :');
         add('	{');
         add('	{');
         add('		KEEP (*(SORT(.init_array.*)))');
         add('		KEEP (*(SORT(.init_array.*)))');
         add('		KEEP (*(.init_array))');
         add('		KEEP (*(.init_array))');
-        add('	} >ewram = 0xff');
+        add('	} >ewram :main = 0xff');
         add('	PROVIDE (__init_array_end = .);');
         add('	PROVIDE (__init_array_end = .);');
         add('	PROVIDE (__fini_array_start = .);');
         add('	PROVIDE (__fini_array_start = .);');
         add('	.fini_array     :');
         add('	.fini_array     :');
         add('	{');
         add('	{');
         add('		KEEP (*(.fini_array))');
         add('		KEEP (*(.fini_array))');
         add('		KEEP (*(SORT(.fini_array.*)))');
         add('		KEEP (*(SORT(.fini_array.*)))');
-        add('	} >ewram = 0xff');
+        add('	} >ewram :main = 0xff');
         add('');
         add('');
         add('	PROVIDE (__fini_array_end = .);');
         add('	PROVIDE (__fini_array_end = .);');
         add('');
         add('');
@@ -359,7 +376,7 @@ begin
         add('		KEEP (*(SORT(.ctors.*)))');
         add('		KEEP (*(SORT(.ctors.*)))');
         add('		KEEP (*(.ctors))');
         add('		KEEP (*(.ctors))');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-        add('	} >ewram = 0xff');
+        add('	} >ewram :main = 0xff');
         add('');
         add('');
         add('	.dtors :');
         add('	.dtors :');
         add('	{');
         add('	{');
@@ -368,98 +385,122 @@ begin
         add('		KEEP (*(SORT(.dtors.*)))');
         add('		KEEP (*(SORT(.dtors.*)))');
         add('		KEEP (*(.dtors))');
         add('		KEEP (*(.dtors))');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-        add('	} >ewram = 0xff');
+        add('	} >ewram :main = 0xff');
         add('');
         add('');
         add('	.eh_frame :');
         add('	.eh_frame :');
         add('	{');
         add('	{');
         add('		KEEP (*(.eh_frame))');
         add('		KEEP (*(.eh_frame))');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-        add('	} >ewram = 0xff');
+        add('	} >ewram :main = 0xff');
         add('');
         add('');
         add('	.gcc_except_table :');
         add('	.gcc_except_table :');
         add('	{');
         add('	{');
         add('		*(.gcc_except_table)');
         add('		*(.gcc_except_table)');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-        add('	} >ewram = 0xff');
-        add('	.jcr            : { KEEP (*(.jcr)) } >ewram = 0');
-        add('	.got            : { *(.got.plt) *(.got) *(.rel.got) } >ewram = 0');
+        add('	} >ewram :main = 0xff');
+        add('	.jcr            : { KEEP (*(.jcr)) } >ewram :main = 0');
+        add('	.got            : { *(.got.plt) *(.got) *(.rel.got) } >ewram :main = 0');
         add('');
         add('');
-        add('	.ewram ALIGN(4) : ');
+        add('	.ewram ALIGN(4) :'); 
         add('	{');
         add('	{');
         add('		__ewram_start = ABSOLUTE(.) ;');
         add('		__ewram_start = ABSOLUTE(.) ;');
         add('		*(.ewram)');
         add('		*(.ewram)');
         add('		*ewram.*(.text)');
         add('		*ewram.*(.text)');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-        add('	} >ewram = 0xff');
+        add('	} >ewram :main = 0xff');
         add('');
         add('');
         add('');
         add('');
         add('	.data ALIGN(4) :');
         add('	.data ALIGN(4) :');
         add('	{');
         add('	{');
         add('		__data_start = ABSOLUTE(.);');
         add('		__data_start = ABSOLUTE(.);');
-        add('		*(.data)');
-        add('		*(.data.*)');
-        add('		*(.gnu.linkonce.d*)');
+        add('		*(EXCLUDE_FILE(*.twl*) .data)');
+        add('		*(EXCLUDE_FILE(*.twl*) .data.*)');
+        add('		*(EXCLUDE_FILE(*.twl*) .gnu.linkonce.d*)');
         add('		CONSTRUCTORS');
         add('		CONSTRUCTORS');
         add('		. = ALIGN(4);');
         add('		. = ALIGN(4);');
         add('		__data_end = ABSOLUTE(.) ;');
         add('		__data_end = ABSOLUTE(.) ;');
-        add('	} >ewram = 0xff');
+        add('	} >ewram :main = 0xff');
         add('');
         add('');
-        add('');
-        add('	__dtcm_lma = . ;');
         add('	__bss_vma = . ;');
         add('	__bss_vma = . ;');
         add('');
         add('');
-        add('	.dtcm __dtcm_start : AT (__dtcm_lma)');
+        add('	.dtcm :');
         add('	{');
         add('	{');
+        add('		__dtcm_lma = LOADADDR(.dtcm);');
+        add('		__dtcm_start = ABSOLUTE(.);');
         add('		*(.dtcm)');
         add('		*(.dtcm)');
         add('		*(.dtcm.*)');
         add('		*(.dtcm.*)');
         add('		. = ALIGN(4);');
         add('		. = ALIGN(4);');
         add('		__dtcm_end = ABSOLUTE(.);');
         add('		__dtcm_end = ABSOLUTE(.);');
-        add('	} >dtcm  = 0xff');
-        add('');
+        add('	} >dtcm AT>ewram :dtcm = 0xff');
         add('');
         add('');
-        add('	__itcm_lma = __dtcm_lma + SIZEOF(.dtcm);');
-        add('');
-        add('	.itcm __itcm_start : AT (__itcm_lma)');
+        add('	.itcm :');
         add('	{');
         add('	{');
+        add('		__itcm_lma = LOADADDR(.itcm);');
+        add('		__itcm_start = ABSOLUTE(.);');
         add('		*(.itcm)');
         add('		*(.itcm)');
-        add('		*itcm.*(.text)');
+        add('		*.itcm*(.text .stub .text.*)');
         add('		. = ALIGN(4);');
         add('		. = ALIGN(4);');
         add('		__itcm_end = ABSOLUTE(.);');
         add('		__itcm_end = ABSOLUTE(.);');
-        add('	} >itcm = 0xff');
-        add('	');
-        add('	__vectors_lma = __itcm_lma + SIZEOF(.itcm);');
+        add('	} >itcm AT>ewram :itcm = 0xff');
         add('');
         add('');
-        add('	.vectors __vectors_start : AT (__vectors_lma)');
+        add('	.vectors :');
         add('	{');
         add('	{');
-        add('		*(.vectors)');
-        add('		*vectors.*(.text)');
+        add('		__vectors_lma = LOADADDR(.vectors);');
+        add('		__vectors_start = ABSOLUTE(.);');
+        add('		KEEP(*(.vectors .vectors.*))');
         add('		. = ALIGN(4);');
         add('		. = ALIGN(4);');
         add('		__vectors_end = ABSOLUTE(.);');
         add('		__vectors_end = ABSOLUTE(.);');
-        add('	} >vectors = 0xff');
+        add('	} >vectors AT>ewram :vectors = 0xff');
         add('	');
         add('	');
-        add('	.sbss __dtcm_end (NOLOAD): ');
+        add('	.sbss __dtcm_end (NOLOAD):'); 
         add('	{');
         add('	{');
         add('		__sbss_start = ABSOLUTE(.);');
         add('		__sbss_start = ABSOLUTE(.);');
         add('		__sbss_start__ = ABSOLUTE(.);');
         add('		__sbss_start__ = ABSOLUTE(.);');
         add('		*(.sbss)');
         add('		*(.sbss)');
         add('		. = ALIGN(4);    /* REQUIRED. LD is flaky without it. */');
         add('		. = ALIGN(4);    /* REQUIRED. LD is flaky without it. */');
         add('		__sbss_end = ABSOLUTE(.);');
         add('		__sbss_end = ABSOLUTE(.);');
-        add('	} >dtcm ');
+        add('	} >dtcm :NONE');
         add('');
         add('');
-        add('	.bss __bss_vma (NOLOAD): ');
+        add('	.bss __bss_vma (NOLOAD):'); 
         add('	{');
         add('	{');
         add('		__bss_start = ABSOLUTE(.);');
         add('		__bss_start = ABSOLUTE(.);');
         add('		__bss_start__ = ABSOLUTE(.);');
         add('		__bss_start__ = ABSOLUTE(.);');
-        add('		*(.dynbss)');
-        add('		*(.gnu.linkonce.b*)');
-        add('		*(.bss*)');
-        add('		*(COMMON)');
+        add('		*(EXCLUDE_FILE(*.twl*) .dynbss)');
+        add('		*(EXCLUDE_FILE(*.twl*) .gnu.linkonce.b*)');
+        add('		*(EXCLUDE_FILE(*.twl*) .bss*)');
+        add('		*(EXCLUDE_FILE(*.twl*) COMMON)');
         add('		. = ALIGN(4);    /* REQUIRED. LD is flaky without it. */');
         add('		. = ALIGN(4);    /* REQUIRED. LD is flaky without it. */');
         add('		__bss_end__ = ABSOLUTE(.) ;');
         add('		__bss_end__ = ABSOLUTE(.) ;');
         add('		__end__ = ABSOLUTE(.) ;');
         add('		__end__ = ABSOLUTE(.) ;');
-        add('	} AT>ewram ');
-        add('');
+        add('	} >ewram :NONE');
         add('');
         add('');
+        add('	.twl __end__ : AT(MAX(0x2400000,MAX(__end__,LOADADDR(.vectors)+SIZEOF(.vectors))))');
+        add('	{');
+        add('		__arm9i_lma__ = LOADADDR(.twl);');
+        add('		__arm9i_start__ = ABSOLUTE(.);');
+        add('		*(.twl)');
+        add('		*.twl*(.text .stub .text.* .gnu.linkonce.t.*)');
+        add('		*.twl*(.rodata)');
+        add('		*.twl*(.roda)');
+        add('		*.twl*(.rodata.*)');
+        add('		*.twl*(.data)');
+        add('		*.twl*(.data.*)');
+        add('		*.twl*(.gnu.linkonce.d*)');
+        add('		__arm9i_end__ = ABSOLUTE(.);');
+        add('	} :twl');
+        add('');
+        add('	.twl_bss __arm9i_end__ (NOLOAD):');
+        add('	{');
+        add('		__twl_bss_start__ = ABSOLUTE(.);');
+        add('		*(.twl_bss)');
+        add('		*.twl*(.dynbss)');
+        add('		*.twl*(.gnu.linkonce.b*)');
+        add('		*.twl*(.bss*)');
+        add('		*.twl*(COMMON)');
+        add('		. = ALIGN(4);    /* REQUIRED. LD is flaky without it. */');
+        add('		__twl_bss_end__ = ABSOLUTE(.);');
+        add('		__twl_end__ = ABSOLUTE(.);');
+        add('	} :NONE');
         add('');
         add('');
         add('	/* Stabs debugging sections.  */');
         add('	/* Stabs debugging sections.  */');
         add('	.stab 0 : { *(.stab) }');
         add('	.stab 0 : { *(.stab) }');
@@ -497,18 +538,33 @@ begin
         add('	.stack 0x80000 : { _stack = .; *(.stack) }');
         add('	.stack 0x80000 : { _stack = .; *(.stack) }');
         add('	/* These must appear regardless of  .  */');
         add('	/* These must appear regardless of  .  */');
         add('}');
         add('}');
-        add('');
       end;
       end;
       if apptype=app_arm7 then
       if apptype=app_arm7 then
       begin
       begin
+        add('/*--------------------------------------------------------------------------------');
+        add('	This Source Code Form is subject to the terms of the Mozilla Public License,');
+        add('	v. 2.0. If a copy of the MPL was not distributed with this file, You can');
+        add('	obtain one at https://mozilla.org/MPL/2.0/.');
+        add('--------------------------------------------------------------------------------*/');
         add('OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")');
         add('OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")');
         add('OUTPUT_ARCH(arm)');
         add('OUTPUT_ARCH(arm)');
         add('ENTRY(_start)');
         add('ENTRY(_start)');
         add('');
         add('');
+        add('');
+        add('PHDRS {');
+        add('	crt0  PT_LOAD FLAGS(7);');
+        add('	arm7  PT_LOAD FLAGS(7);');
+        add('	arm7i PT_LOAD FLAGS(0x100007);');
+        add('}');
+        add('');
+        add('');
         add('MEMORY {');
         add('MEMORY {');
+        add('	ewram  : ORIGIN = 0x02380000, LENGTH = 12M - 512K');
+        add('	rom    : ORIGIN = 0x08000000, LENGTH = 32M');
+        add('	iwram  : ORIGIN = 0x037f8000, LENGTH = 96K');
         add('');
         add('');
-        add('	rom	: ORIGIN = 0x08000000, LENGTH = 32M');
-        add('	iwram	: ORIGIN = 0x037f8000, LENGTH = 96K	');
+        add('	twl_ewram : ORIGIN = 0x02e80000, LENGTH = 512K - 64K');
+        add('	twl_iwram : ORIGIN = 0x03000000, LENGTH = 256K');
         add('}');
         add('}');
         add('');
         add('');
         add('__iwram_start	=	ORIGIN(iwram);');
         add('__iwram_start	=	ORIGIN(iwram);');
@@ -524,30 +580,59 @@ begin
         add('');
         add('');
         add('SECTIONS');
         add('SECTIONS');
         add('{');
         add('{');
-        add('	.init	:');
+        add('');
+        add('	.twl :');
         add('	{');
         add('	{');
-        add('		__text_start = . ;');
-        add('		KEEP (*(.init))');
+        add('		__arm7i_lma__ = LOADADDR(.twl);');
+        add('		__arm7i_start__ = .;');
+        add('		*(.twl)');
+        add('		*.twl*(.text .stub .text.* .gnu.linkonce.t.*)');
+        add('		*.twl*(.rodata)');
+        add('		*.twl*(.roda)');
+        add('		*.twl*(.rodata.*)');
+        add('		*.twl*(.data)');
+        add('		*.twl*(.data.*)');
+        add('		*.twl*(.gnu.linkonce.d*)');
+        add('		. = ALIGN(4);');
+        add('		__arm7i_end__ = .;');
+        add('	} >twl_iwram AT>twl_ewram :arm7i');
+        add('');
+        add('	.twl_bss ALIGN(4) (NOLOAD) :');
+        add('	{');
+        add('		__twl_bss_start__ = .;');
+        add('		*(.twl_bss)');
+        add('		*.twl.*(.dynbss)');
+        add('		*.twl.*(.gnu.linkonce.b*)');
+        add('		*.twl.*(.bss*)');
+        add('		*.twl.*(COMMON)');
+        add('		. = ALIGN(4);');
+        add('		__twl_bss_end__ = .;');
+        add('	} >twl_iwram :NONE');
+        add('');
+        add('	.crt0	:');
+        add('	{');
+        add('		KEEP (*(.crt0))');
         add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
         add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
-        add('		} >iwram = 0xff');
-        add('	.plt : { *(.plt) } >iwram = 0xff');
+        add('	} >ewram :crt0');
         add('');
         add('');
-        add('	.text :   /* ALIGN (4): */');
+        add('	.text :');
         add('	{');
         add('	{');
+        add('		__arm7_lma__ = LOADADDR(.text);');
+        add('		__arm7_start__ = .;');
+        add('		KEEP (*(SORT_NONE(.init)))');
+        add('		*(.plt)');
         add('		*(.text .stub .text.* .gnu.linkonce.t.*)');
         add('		*(.text .stub .text.* .gnu.linkonce.t.*)');
         add('		KEEP (*(.text.*personality*))');
         add('		KEEP (*(.text.*personality*))');
         add('		/* .gnu.warning sections are handled specially by elf32.em.  */');
         add('		/* .gnu.warning sections are handled specially by elf32.em.  */');
         add('		*(.gnu.warning)');
         add('		*(.gnu.warning)');
         add('		*(.glue_7t) *(.glue_7) *(.vfp11_veneer)');
         add('		*(.glue_7t) *(.glue_7) *(.vfp11_veneer)');
         add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
         add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
-        add('	} >iwram = 0xff');
+        add('	} >iwram AT>ewram :arm7');
         add('');
         add('');
         add('	.fini           :');
         add('	.fini           :');
         add('	{');
         add('	{');
         add('		KEEP (*(.fini))');
         add('		KEEP (*(.fini))');
-        add('	} >iwram =0xff');
-        add('');
-        add('	__text_end = . ;');
+        add('	} >iwram AT>ewram');
         add('');
         add('');
         add('	.rodata :');
         add('	.rodata :');
         add('	{');
         add('	{');
@@ -558,27 +643,38 @@ begin
         add('		*(.gnu.linkonce.r*)');
         add('		*(.gnu.linkonce.r*)');
         add('		SORT(CONSTRUCTORS)');
         add('		SORT(CONSTRUCTORS)');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-        add('	} >iwram = 0xff');
+        add('	} >iwram AT>ewram');
         add('');
         add('');
-        add('	.ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >iwram');
-        add('	__exidx_start = .;');
-        add('	.ARM.exidx   : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >iwram');
-        add('	__exidx_end = .;');
+        add('	.ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >iwram AT>ewram');
+        add('');
+        add('	.ARM.exidx   : {');
+        add('		__exidx_start = .;');
+        add('		*(.ARM.exidx* .gnu.linkonce.armexidx.*)');
+        add('		__exidx_end = .;');
+        add('	 } >iwram AT>ewram');
         add('');
         add('');
         add('/* Ensure the __preinit_array_start label is properly aligned.  We');
         add('/* Ensure the __preinit_array_start label is properly aligned.  We');
         add('   could instead move the label definition inside the section, but');
         add('   could instead move the label definition inside the section, but');
         add('   the linker would then create the section even if it turns out to');
         add('   the linker would then create the section even if it turns out to');
         add('   be empty, which isn''t pretty.  */');
         add('   be empty, which isn''t pretty.  */');
-        add('	. = ALIGN(32 / 8);');
-        add('	PROVIDE (__preinit_array_start = .);');
-        add('	.preinit_array     : { KEEP (*(.preinit_array)) } >iwram = 0xff');
-        add('	PROVIDE (__preinit_array_end = .);');
-        add('	PROVIDE (__init_array_start = .);');
-        add('	.init_array     : { KEEP (*(.init_array)) } >iwram = 0xff');
-        add('	PROVIDE (__init_array_end = .);');
-        add('	PROVIDE (__fini_array_start = .);');
-        add('	.fini_array     : { KEEP (*(.fini_array)) } >iwram = 0xff');
-        add('	PROVIDE (__fini_array_end = .);');
+        add('	.preinit_array     : {');
+        add('		. = ALIGN(32 / 8);');
+        add('		PROVIDE (__preinit_array_start = .);');
+        add('		KEEP (*(.preinit_array))');
+        add('		PROVIDE (__preinit_array_end = .);');
+        add('	} >iwram AT>ewram');
+        add('');
+        add('	.init_array     : {');
+        add('		PROVIDE (__init_array_start = .);');
+        add('		KEEP (*(.init_array))');
+        add('		PROVIDE (__init_array_end = .);');
+        add('	} >iwram AT>ewram');
+        add('');
+        add('	.fini_array     : {');
+        add('		PROVIDE (__fini_array_start = .);');
+        add('		KEEP (*(.fini_array))');
+        add('		PROVIDE (__fini_array_end = .);');
+        add('	} >iwram AT>ewram');
         add('');
         add('');
         add('	.ctors :');
         add('	.ctors :');
         add('	{');
         add('	{');
@@ -593,7 +689,7 @@ begin
         add('		KEEP (*(SORT(.ctors.*)))');
         add('		KEEP (*(SORT(.ctors.*)))');
         add('		KEEP (*(.ctors))');
         add('		KEEP (*(.ctors))');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-        add('	} >iwram = 0xff');
+        add('	} >iwram AT>ewram');
         add('');
         add('');
         add('	.dtors :');
         add('	.dtors :');
         add('	{');
         add('	{');
@@ -602,21 +698,21 @@ begin
         add('		KEEP (*(SORT(.dtors.*)))');
         add('		KEEP (*(SORT(.dtors.*)))');
         add('		KEEP (*(.dtors))');
         add('		KEEP (*(.dtors))');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-        add('	} >iwram = 0xff');
+        add('	} >iwram AT>ewram');
         add('');
         add('');
         add('	.eh_frame :');
         add('	.eh_frame :');
         add('	{');
         add('	{');
         add('		KEEP (*(.eh_frame))');
         add('		KEEP (*(.eh_frame))');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-        add('	} >iwram = 0xff');
+        add('	} >iwram AT>ewram');
         add('');
         add('');
         add('	.gcc_except_table :');
         add('	.gcc_except_table :');
         add('	{');
         add('	{');
         add('		*(.gcc_except_table)');
         add('		*(.gcc_except_table)');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-        add('	} >iwram = 0xff');
-        add('	.jcr            : { KEEP (*(.jcr)) } >iwram = 0');
-        add('	.got            : { *(.got.plt) *(.got) } >iwram = 0');
+        add('	} >iwram AT>ewram');
+        add('	.jcr            : { KEEP (*(.jcr)) } >iwram AT>ewram');
+        add('	.got            : { *(.got.plt) *(.got) } >iwram AT>ewram');
         add('');
         add('');
         add('	.data ALIGN(4) : 	{');
         add('	.data ALIGN(4) : 	{');
         add('		__data_start = ABSOLUTE(.);');
         add('		__data_start = ABSOLUTE(.);');
@@ -626,10 +722,11 @@ begin
         add('		CONSTRUCTORS');
         add('		CONSTRUCTORS');
         add('		. = ALIGN(4);');
         add('		. = ALIGN(4);');
         add('		__data_end = ABSOLUTE(.) ;');
         add('		__data_end = ABSOLUTE(.) ;');
-        add('	} >iwram = 0xff');
+        add('	} >iwram AT>ewram');
         add('');
         add('');
-        add('	.bss ALIGN(4) :');
+        add('	.bss ALIGN(4) (NOLOAD) :');
         add('	{');
         add('	{');
+        add('		__arm7_end__ = .;');
         add('		__bss_start = ABSOLUTE(.);');
         add('		__bss_start = ABSOLUTE(.);');
         add('		__bss_start__ = ABSOLUTE(.);');
         add('		__bss_start__ = ABSOLUTE(.);');
         add('		*(.dynbss)');
         add('		*(.dynbss)');
@@ -674,7 +771,6 @@ begin
         add('	.debug_funcnames 0 : { *(.debug_funcnames) }');
         add('	.debug_funcnames 0 : { *(.debug_funcnames) }');
         add('	.debug_typenames 0 : { *(.debug_typenames) }');
         add('	.debug_typenames 0 : { *(.debug_typenames) }');
         add('	.debug_varnames  0 : { *(.debug_varnames) }');
         add('	.debug_varnames  0 : { *(.debug_varnames) }');
-        add('	.stack 0x80000 : { _stack = .; *(.stack) }');
         add('	/* These must appear regardless of  .  */');
         add('	/* These must appear regardless of  .  */');
         add('}');
         add('}');
       end;
       end;

+ 304 - 298
compiler/systems/t_wii.pas

@@ -224,304 +224,310 @@ begin
    end;   
    end;   
   with linkres do
   with linkres do
    begin
    begin
-    Add('/*');
-    Add(' * Linkscript for Wii');
-    Add(' */');
-    Add('');
-    Add('OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc");');
-    Add('OUTPUT_ARCH(powerpc:common);');
-    Add('EXTERN(_start);');
-    Add('ENTRY(_start);');
-    Add('');
-    Add('PHDRS');
-    Add('{');
-    Add('  stub PT_LOAD FLAGS(5);');
-    Add('  text PT_LOAD FLAGS(5);');
-    Add('  data PT_LOAD FLAGS(6);');
-    Add('  bss1 PT_LOAD;');
-    Add('  bss2 PT_LOAD;');
-    Add('');
-    Add('}');
-    Add('');
-    Add('SECTIONS');
-    Add('{');
-    Add('	/* stub is loaded at physical address 0x00003400 (though both 0x80003400 and 0x00003400 are equivalent for IOS) */');
-    Add('	/* This can also be used to load an arbitrary standalone stub at an arbitrary address in memory, for any purpose */');
-    Add('	/* Use -Wl,--section-start,.stub=0xADDRESS to change */');
-    Add('	. = 0x00003400;');
-    Add('');
-    Add('	.stub :');
-    Add('	{');
-    Add('		KEEP(*(.stub))');
-    Add('	} :stub = 0');
-    Add('');
-    Add('	/* default base address */');
-    Add('	/* use -Wl,--section-start,.init=0xADDRESS to change */');
-    Add('	. = 0x80004000;');
-    Add('');
-    Add('	/* Program */');
-    Add('	.init          :');
-    Add('	{');
-    Add('		KEEP (*crt0.o(*.init))');
-    Add('		KEEP (*(.init))');
-    Add('	} :text = 0');
-    Add('	.plt      : { *(.plt)	}');
-    Add('	.interp			: { *(.interp) 	}');
-    Add('	.hash			: { *(.hash) }');
-    Add('	.dynsym			: { *(.dynsym) }');
-    Add('	.dynstr			: { *(.dynstr) }');
-    Add('	.gnu.version	: { *(.gnu.version) }');
-    Add('	.gnu.version_d	: { *(.gnu.version_d) }');
-    Add('	.gnu.version_r	: { *(.gnu.version_r) }');
-    Add('	.rel.init		: { *(.rel.init) }');
-    Add('	.rela.init		: { *(.rela.init) }');
-    Add('	.rel.text		: { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }');
-    Add('	.rela.text		: { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }');
-    Add('	.rel.fini		: { *(.rel.fini) }');
-    Add('	.rela.fini		: { *(.rela.fini) }');
-    Add('	.rel.rodata		: { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }');
-    Add('	.rela.rodata	: { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }');
-    Add('	.rel.data		: { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }');
-    Add('	.rela.data		: { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }');
-    Add('	.rel.tdata		: { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }');
-    Add('	.rela.tdata		: { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }');
-    Add('	.rel.tbss		: { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }');
-    Add('	.rela.tbss		: { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }');
-    Add('	.rel.ctors		: { *(.rel.ctors) }');
-    Add('	.rela.ctors		: { *(.rela.ctors) }');
-    Add('	.rel.dtors		: { *(.rel.dtors) }');
-    Add('	.rela.dtors		: { *(.rela.dtors) }');
-    Add('	.rel.got		: { *(.rel.got)	}');
-    Add('	.rela.got		: { *(.rela.got) }');
-    Add('	.rela.got1		: { *(.rela.got1) }');
-    Add('	.rela.got2		: { *(.rela.got2) }');
-    Add('	.rel.sdata		: { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) }');
-    Add('	.rela.sdata		: { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) }');
-    Add('	.rel.sbss		: { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) }');
-    Add('	.rela.sbss		: { *(.rela.sbss .rela.sbss.* .rel.gnu.linkonce.sb.*) }');
-    Add('	.rel.sdata2		: { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) }');
-    Add('	.rela.sdata2	: { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) }');
-    Add('	.rel.sbss2		: { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) }');
-    Add('	.rela.sbss2		: { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }');
-    Add('	.rel.bss		: { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }');
-    Add('	.rela.bss		: { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }');
-    Add('	.rel.plt		: { *(.rel.plt) }');
-    Add('	.rela.plt		: { *(.rela.plt) }');
-    Add('');
-    Add('	.text      :');
-    Add('	{');
-    Add('		*(.text)');
-    Add('		*(.text.*)');
-    Add('		/* .gnu.warning sections are handled specially by elf32.em.  */');
-    Add('		*(.gnu.warning)');
-    Add('		*(.gnu.linkonce.t.*)');
-    Add('		. = ALIGN(32);   /* REQUIRED. LD is flaky without it. */');
-    Add('	} = 0');
-    Add('');
-    Add('	.fini      :');
-    Add('	{');
-    Add('		KEEP (*(.fini))');
-    Add('		. = ALIGN(32);   /* REQUIRED. LD is flaky without it. */');
-    Add('	} = 0');
-    Add('	');
-    Add('	PROVIDE (__etext = .);');
-    Add('	PROVIDE (_etext = .);');
-    Add('	PROVIDE (etext = .);');
-    Add('');
-    Add('	.rodata   : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) } :data');
-    Add('	.rodata1   : { *(.rodata1) }');
-    Add('	.sdata2   : { *(.sdata2) *(.sdata2.*) *(.gnu.linkonce.s2.*) }');
-    Add('	.sbss2   : { *(.sbss2) *(.sbss2.*) *(.gnu.linkonce.sb2.*) }');
-    Add('  /* Adjust the address for the data segment.  We want to adjust up to');
-    Add('     the same address within the page on the next page up.  */');
-    Add('  /* Ensure the __preinit_array_start label is properly aligned.  We');
-    Add('     could instead move the label definition inside the section, but');
-    Add('     the linker would then create the section even if it turns out to');
-    Add('     be empty, which isn''t pretty.  */');
-    Add('	. = ALIGN(32 / 8);');
-    Add('	PROVIDE (__preinit_array_start = .);');
-    Add('	.preinit_array     : { *(.preinit_array) }');
-    Add('	PROVIDE (__preinit_array_end = .);');
-    Add('	PROVIDE (__init_array_start = .);');
-    Add('	.init_array     : { *(.init_array) }');
-    Add('	PROVIDE (__init_array_end = .);');
-    Add('	PROVIDE (__fini_array_start = .);');
-    Add('	.fini_array     : { *(.fini_array) }');
-    Add('	PROVIDE (__fini_array_end = .);');
-    Add('	.data    :');
-    Add('	{');
-    Add('		*(.data)');
-    Add('		*(.data.*)');
-    Add('		*(.gnu.linkonce.d.*)');
-    Add('		SORT(CONSTRUCTORS)');
-    Add('		. = ALIGN(32);   /* REQUIRED. LD is flaky without it. */');
-    Add('	}');
-    Add('');
-    Add('	.data1   : { *(.data1) }');
-    Add('	.tdata	  : { *(.tdata .tdata.* .gnu.linkonce.td.*) }');
-    Add('	.tbss		  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }');
-    Add('	.eh_frame : { KEEP (*(.eh_frame)) }');
-    Add('	.gcc_except_table : { *(.gcc_except_table) }');
-    Add('	.fixup          : { *(.fixup) }');
-    Add('	.got1           : { *(.got1) }');
-    Add('	.got2           : { *(.got2) }');
-    Add('	.dynamic       : { *(.dynamic) }');
-    Add('');
-    Add('	.ctors   :');
-    Add('	{');
-    Add('	/*	gcc uses crtbegin.o to find the start of');
-    Add('		the constructors, so we make sure it is');
-    Add('		first.  Because this is a wildcard, it');
-    Add('		doesn''t matter if the user does not');
-    Add('		actually link against crtbegin.o; the');
-    Add('		linker won''t look for a file to match a');
-    Add('		wildcard.  The wildcard also means that it');
-    Add('		doesn''t matter which directory crtbegin.o');
-    Add('		is in.  */');
-    Add('');
-    Add('		KEEP (*crtbegin.o(.ctors))');
-    Add('');
-    Add('    /*	We don''t want to include the .ctor section from');
-    Add('		from the crtend.o file until after the sorted ctors.');
-    Add('		The .ctor section from the crtend file contains the');
-    Add('		end of ctors marker and it must be last */');
-    Add('');
-    Add('		KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))');
-    Add('		KEEP (*(SORT(.ctors.*)))');
-    Add('		KEEP (*(.ctors))');
-    Add('		. = ALIGN(32);   /* REQUIRED. LD is flaky without it. */');
-    Add('	}');
-    Add('');
-    Add('	.dtors         :');
-    Add('	{');
-    Add('		KEEP (*crtbegin.o(.dtors))');
-    Add('		KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))');
-    Add('		KEEP (*(SORT(.dtors.*)))');
-    Add('		KEEP (*(.dtors))');
-    Add('		. = ALIGN(32);   /* REQUIRED. LD is flaky without it. */');
-    Add('	}');
-    Add('');
-    Add('	.jcr            : { KEEP (*(.jcr)) }');
-    Add('	.got		  : { *(.got.plt) *(.got) }');
-    Add('');
-    Add('');
-    Add('	/*	We want the small data sections together, so single-instruction offsets');
-    Add('		can access them all, and initialized data all before uninitialized, so');
-    Add('		we can shorten the on-disk segment size.  */');
-    Add('');
-    Add('	.sdata     :');
-    Add('	{');
-    Add('		*(.sdata)');
-    Add('		*(.sdata.*)');
-    Add('		*(.gnu.linkonce.s.*)');
-    Add('		. = ALIGN(32);   /* REQUIRED. LD is flaky without it. */');
-    Add('	}');
-    Add('');
-    Add('	_edata = .;');
-    Add('	PROVIDE (edata = .);');
-    Add('	');
-    Add('	.sbss      :');
-    Add('	{');
-    Add('		__sbss_start = .;');
-    Add('		PROVIDE (__sbss_start = .);');
-    Add('		PROVIDE (___sbss_start = .);');
-    Add('		*(.dynsbss)');
-    Add('		*(.sbss)');
-    Add('		*(.sbss.*)');
-    Add('		*(.gnu.linkonce.sb.*)');
-    Add('		*(.scommon)');
-    Add('		PROVIDE (__sbss_end = .);');
-    Add('		PROVIDE (___sbss_end = .);');
-    Add('		. = ALIGN(32);   /* REQUIRED. LD is flaky without it. */');
-    Add('		__sbss_end = .;');
-    Add('	} :bss1');
-    Add('');
-    Add('	.bss       :');
-    Add('	{');
-    Add('		__bss_start = .;');
-    Add('		PROVIDE (__bss_start = .);');
-    Add('		*(.dynbss)');
-    Add('		*(.bss)');
-    Add('		*(.bss.*)');
-    Add('		*(.gnu.linkonce.b.*)');
-    Add('		*(COMMON)');
-    Add('	/*	Align here to ensure that the .bss section occupies space up to');
-    Add('		_end.  Align after .bss to ensure correct alignment even if the');
-    Add('		.bss section disappears because there are no input sections.  */');
-    Add('');
-    Add('		. = ALIGN(32);');
-    Add('');
-    Add('		PROVIDE (__bss_end = .);');
-    Add('		__bss_end = .;');
-    Add('	} :bss2');
-    Add('');
-    Add('	_end = .;');
-    Add('	PROVIDE(end = .);');
-    Add('	/* Stabs debugging sections.  */');
-    Add('	.stab 0 : { *(.stab) }');
-    Add('	.stabstr 0 : { *(.stabstr) }');
-    Add('	.stab.excl 0 : { *(.stab.excl) }');
-    Add('	.stab.exclstr 0 : { *(.stab.exclstr) }');
-    Add('	.stab.index 0 : { *(.stab.index) }');
-    Add('	.stab.indexstr 0 : { *(.stab.indexstr) }');
-    Add('	.comment 0 : { *(.comment) }');
-    Add('	/*	DWARF debug sections.');
-    Add('		Symbols in the DWARF debugging sections are relative to the beginning');
-    Add('		of the section so we begin them at 0.  */');
-    Add('	/* DWARF 1 */');
-    Add('	.debug          0 : { *(.debug) }');
-    Add('	.line           0 : { *(.line) }');
-    Add('	/* GNU DWARF 1 extensions */');
-    Add('	.debug_srcinfo  0 : { *(.debug_srcinfo) }');
-    Add('	.debug_sfnames  0 : { *(.debug_sfnames) }');
-    Add('	/* DWARF 1.1 and DWARF 2 */');
-    Add('	.debug_aranges  0 : { *(.debug_aranges) }');
-    Add('	.debug_pubnames 0 : { *(.debug_pubnames) }');
-    Add('	/* DWARF 2 */');
-    Add('	.debug_info     0 : { *(.debug_info) }');
-    Add('	.debug_abbrev   0 : { *(.debug_abbrev) }');
-    Add('	.debug_line     0 : { *(.debug_line) }');
-    Add('	.debug_frame    0 : { *(.debug_frame) }');
-    Add('	.debug_str      0 : { *(.debug_str) }');
-    Add('	.debug_loc      0 : { *(.debug_loc) }');
-    Add('	.debug_macinfo  0 : { *(.debug_macinfo) }');
-    Add('	/* SGI/MIPS DWARF 2 extensions */');
-    Add('	.debug_weaknames 0 : { *(.debug_weaknames) }');
-    Add('	.debug_funcnames 0 : { *(.debug_funcnames) }');
-    Add('	.debug_typenames 0 : { *(.debug_typenames) }');
-    Add('	.debug_varnames  0 : { *(.debug_varnames) }');
-    Add('	/* These must appear regardless of  .  */');
-    Add('}');
-    Add('');
-    Add('__isIPL = 0;');
-    Add('__stack_addr = (__bss_start + SIZEOF(.bss) + 0x20000 + 7) & (-8);');
-    Add('__stack_end = (__bss_start + SIZEOF(.bss));');
-    Add('__intrstack_addr = (__stack_addr + 0x4000);');
-    Add('__intrstack_end = (__stack_addr);');
-    Add('__Arena1Lo = (__intrstack_addr + 31) & (-32);');
-    Add('__Arena1Hi = (0x817FEFF0);');
-    Add('__Arena2Lo = (0x90002000);');
-    Add('__Arena2Hi = (0x933E0000);');
-    Add('');
-    Add('__gxregs = (__Arena1Hi + 31) & (-32);');
-    Add('__ipcbufferLo = (0x933e0000);');
-    Add('__ipcbufferHi = (0x93400000);');
-    Add('');
-    Add('/* for backward compatibility with old crt0 */');
-    Add('PROVIDE (__stack = (0x817FEFF0));');
-    Add('');
-    Add('PROVIDE(__isIPL = __isIPL);');
-    Add('PROVIDE(__stack_addr = __stack_addr);');
-    Add('PROVIDE(__stack_end = __stack_end);');
-    Add('PROVIDE(__intrstack_addr = __intrstack_addr);');
-    Add('PROVIDE(__intrstack_end = __intrstack_end);');
-    Add('PROVIDE(__Arena1Lo = __Arena1Lo);');
-    Add('PROVIDE(__Arena1Hi = __Arena1Hi);');
-    Add('PROVIDE(__Arena2Lo = __Arena2Lo);');
-    Add('PROVIDE(__Arena2Hi = __Arena2Hi);');
-    Add('PROVIDE(__ipcbufferLo = __ipcbufferLo);');
-    Add('PROVIDE(__ipcbufferHi = __ipcbufferHi);');
-    Add('PROVIDE(__gxregs = __gxregs);');
+    add('/*');
+    add(' * Linkscript for Wii');
+    add(' */');
+    add('');
+    add('OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc");');
+    add('OUTPUT_ARCH(powerpc:common);');
+    add('EXTERN(_start);');
+    add('ENTRY(_start);');
+    add('');
+    add('PHDRS');
+    add('{');
+    add('  stub PT_LOAD FLAGS(5);');
+    add('  text PT_LOAD FLAGS(5);');
+    add('  data PT_LOAD FLAGS(6);');
+    add('  bss1 PT_LOAD;');
+    add('  bss2 PT_LOAD;');
+    add('');
+    add('}');
+    add('');
+    add('SECTIONS');
+    add('{');
+    add('	/* stub is loaded at physical address 0x00003400 (though both 0x80003400 and 0x00003400 are equivalent for IOS) */');
+    add('	/* This can also be used to load an arbitrary standalone stub at an arbitrary address in memory, for any purpose */');
+    add('	/* Use -Wl,--section-start,.stub=0xADDRESS to change */');
+    add('	. = 0x00003400;');
+    add('');
+    add('	.stub :');
+    add('	{');
+    add('		KEEP(*(.stub))');
+    add('	} :stub = 0');
+    add('');
+    add('	/* default base address */');
+    add('	/* use -Wl,--section-start,.init=0xADDRESS to change */');
+    add('	. = 0x80004000;');
+    add('');
+    add('	/* Program */');
+    add('	.init          :');
+    add('	{');
+    add('		KEEP (*crt0.o(*.init))');
+    add('		KEEP (*(.init))');
+    add('	} :text = 0');
+    add('	.plt      : { *(.plt)	}');
+    add('	.interp			: { *(.interp) 	}');
+    add('	.hash			: { *(.hash) }');
+    add('	.dynsym			: { *(.dynsym) }');
+    add('	.dynstr			: { *(.dynstr) }');
+    add('	.gnu.version	: { *(.gnu.version) }');
+    add('	.gnu.version_d	: { *(.gnu.version_d) }');
+    add('	.gnu.version_r	: { *(.gnu.version_r) }');
+    add('	.rel.init		: { *(.rel.init) }');
+    add('	.rela.init		: { *(.rela.init) }');
+    add('	.rel.text		: { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }');
+    add('	.rela.text		: { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }');
+    add('	.rel.fini		: { *(.rel.fini) }');
+    add('	.rela.fini		: { *(.rela.fini) }');
+    add('	.rel.rodata		: { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }');
+    add('	.rela.rodata	: { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }');
+    add('	.rel.data		: { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }');
+    add('	.rela.data		: { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }');
+    add('	.rel.tdata		: { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }');
+    add('	.rela.tdata		: { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }');
+    add('	.rel.tbss		: { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }');
+    add('	.rela.tbss		: { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }');
+    add('	.rel.ctors		: { *(.rel.ctors) }');
+    add('	.rela.ctors		: { *(.rela.ctors) }');
+    add('	.rel.dtors		: { *(.rel.dtors) }');
+    add('	.rela.dtors		: { *(.rela.dtors) }');
+    add('	.rel.got		: { *(.rel.got)	}');
+    add('	.rela.got		: { *(.rela.got) }');
+    add('	.rela.got1		: { *(.rela.got1) }');
+    add('	.rela.got2		: { *(.rela.got2) }');
+    add('	.rel.sdata		: { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) }');
+    add('	.rela.sdata		: { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) }');
+    add('	.rel.sbss		: { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) }');
+    add('	.rela.sbss		: { *(.rela.sbss .rela.sbss.* .rel.gnu.linkonce.sb.*) }');
+    add('	.rel.sdata2		: { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) }');
+    add('	.rela.sdata2	: { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) }');
+    add('	.rel.sbss2		: { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) }');
+    add('	.rela.sbss2		: { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }');
+    add('	.rel.bss		: { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }');
+    add('	.rela.bss		: { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }');
+    add('	.rel.plt		: { *(.rel.plt) }');
+    add('	.rela.plt		: { *(.rela.plt) }');
+    add('');
+    add('	.text      :');
+    add('	{');
+    add('		*(.text)');
+    add('		*(.text.*)');
+    add('		/* .gnu.warning sections are handled specially by elf32.em.  */');
+    add('		*(.gnu.warning)');
+    add('		*(.gnu.linkonce.t.*)');
+    add('		. = ALIGN(32);   /* REQUIRED. LD is flaky without it. */');
+    add('	} = 0');
+    add('');
+    add('	.fini      :');
+    add('	{');
+    add('		KEEP (*(.fini))');
+    add('		. = ALIGN(32);   /* REQUIRED. LD is flaky without it. */');
+    add('	} = 0');
+    add('	');
+    add('	PROVIDE (__etext = .);');
+    add('	PROVIDE (_etext = .);');
+    add('	PROVIDE (etext = .);');
+    add('');
+    add('	.rodata   : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) } :data');
+    add('	.rodata1   : { *(.rodata1) }');
+    add('	.sdata2   : {');
+    add('		PROVIDE(_SDA2_BASE_ = .);');
+    add('		*(.sdata2)');
+    add('		*(.sdata2.*)');
+    add('		*(.gnu.linkonce.s2.*)');
+    add('	}');
+    add('	.sbss2   : { *(.sbss2) *(.sbss2.*) *(.gnu.linkonce.sb2.*) }');
+    add('  /* Adjust the address for the data segment.  We want to adjust up to');
+    add('     the same address within the page on the next page up.  */');
+    add('  /* Ensure the __preinit_array_start label is properly aligned.  We');
+    add('     could instead move the label definition inside the section, but');
+    add('     the linker would then create the section even if it turns out to');
+    add('     be empty, which isn''t pretty.  */');
+    add('	. = ALIGN(32 / 8);');
+    add('	PROVIDE (__preinit_array_start = .);');
+    add('	.preinit_array     : { *(.preinit_array) }');
+    add('	PROVIDE (__preinit_array_end = .);');
+    add('	PROVIDE (__init_array_start = .);');
+    add('	.init_array     : { *(.init_array) }');
+    add('	PROVIDE (__init_array_end = .);');
+    add('	PROVIDE (__fini_array_start = .);');
+    add('	.fini_array     : { *(.fini_array) }');
+    add('	PROVIDE (__fini_array_end = .);');
+    add('	.data    :');
+    add('	{');
+    add('		*(.data)');
+    add('		*(.data.*)');
+    add('		*(.gnu.linkonce.d.*)');
+    add('		SORT(CONSTRUCTORS)');
+    add('		. = ALIGN(32);   /* REQUIRED. LD is flaky without it. */');
+    add('	}');
+    add('');
+    add('	.data1   : { *(.data1) }');
+    add('	.tdata	  : { *(.tdata .tdata.* .gnu.linkonce.td.*) }');
+    add('	.tbss		  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }');
+    add('	.eh_frame : { KEEP (*(.eh_frame)) }');
+    add('	.gcc_except_table : { *(.gcc_except_table) }');
+    add('	.fixup          : { *(.fixup) }');
+    add('	.got1           : { *(.got1) }');
+    add('	.got2           : { *(.got2) }');
+    add('	.dynamic       : { *(.dynamic) }');
+    add('');
+    add('	.ctors   :');
+    add('	{');
+    add('	/*	gcc uses crtbegin.o to find the start of');
+    add('		the constructors, so we make sure it is');
+    add('		first.  Because this is a wildcard, it');
+    add('		doesn''t matter if the user does not');
+    add('		actually link against crtbegin.o; the');
+    add('		linker won''t look for a file to match a');
+    add('		wildcard.  The wildcard also means that it');
+    add('		doesn''t matter which directory crtbegin.o');
+    add('		is in.  */');
+    add('');
+    add('		KEEP (*crtbegin.o(.ctors))');
+    add('');
+    add('    /*	We don''t want to include the .ctor section from');
+    add('		from the crtend.o file until after the sorted ctors.');
+    add('		The .ctor section from the crtend file contains the');
+    add('		end of ctors marker and it must be last */');
+    add('');
+    add('		KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))');
+    add('		KEEP (*(SORT(.ctors.*)))');
+    add('		KEEP (*(.ctors))');
+    add('		. = ALIGN(32);   /* REQUIRED. LD is flaky without it. */');
+    add('	}');
+    add('');
+    add('	.dtors         :');
+    add('	{');
+    add('		KEEP (*crtbegin.o(.dtors))');
+    add('		KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))');
+    add('		KEEP (*(SORT(.dtors.*)))');
+    add('		KEEP (*(.dtors))');
+    add('		. = ALIGN(32);   /* REQUIRED. LD is flaky without it. */');
+    add('	}');
+    add('');
+    add('	.jcr            : { KEEP (*(.jcr)) }');
+    add('	.got		  : { *(.got.plt) *(.got) }');
+    add('');
+    add('');
+    add('	/*	We want the small data sections together, so single-instruction offsets');
+    add('		can access them all, and initialized data all before uninitialized, so');
+    add('		we can shorten the on-disk segment size.  */');
+    add('');
+    add('	.sdata     :');
+    add('	{');
+    add('		PROVIDE(_SDA_BASE_ = .);');
+    add('		*(.sdata)');
+    add('		*(.sdata.*)');
+    add('		*(.gnu.linkonce.s.*)');
+    add('		. = ALIGN(32);   /* REQUIRED. LD is flaky without it. */');
+    add('	}');
+    add('');
+    add('	_edata = .;');
+    add('	PROVIDE (edata = .);');
+    add('	');
+    add('	.sbss      :');
+    add('	{');
+    add('		__sbss_start = .;');
+    add('		PROVIDE (__sbss_start = .);');
+    add('		PROVIDE (___sbss_start = .);');
+    add('		*(.dynsbss)');
+    add('		*(.sbss)');
+    add('		*(.sbss.*)');
+    add('		*(.gnu.linkonce.sb.*)');
+    add('		*(.scommon)');
+    add('		PROVIDE (__sbss_end = .);');
+    add('		PROVIDE (___sbss_end = .);');
+    add('		. = ALIGN(32);   /* REQUIRED. LD is flaky without it. */');
+    add('		__sbss_end = .;');
+    add('	} :bss1');
+    add('');
+    add('	.bss       :');
+    add('	{');
+    add('		__bss_start = .;');
+    add('		PROVIDE (__bss_start = .);');
+    add('		*(.dynbss)');
+    add('		*(.bss)');
+    add('		*(.bss.*)');
+    add('		*(.gnu.linkonce.b.*)');
+    add('		*(COMMON)');
+    add('	/*	Align here to ensure that the .bss section occupies space up to');
+    add('		_end.  Align after .bss to ensure correct alignment even if the');
+    add('		.bss section disappears because there are no input sections.  */');
+    add('');
+    add('		. = ALIGN(32);');
+    add('');
+    add('		PROVIDE (__bss_end = .);');
+    add('		__bss_end = .;');
+    add('	} :bss2');
+    add('');
+    add('	_end = .;');
+    add('	PROVIDE(end = .);');
+    add('	/* Stabs debugging sections.  */');
+    add('	.stab 0 : { *(.stab) }');
+    add('	.stabstr 0 : { *(.stabstr) }');
+    add('	.stab.excl 0 : { *(.stab.excl) }');
+    add('	.stab.exclstr 0 : { *(.stab.exclstr) }');
+    add('	.stab.index 0 : { *(.stab.index) }');
+    add('	.stab.indexstr 0 : { *(.stab.indexstr) }');
+    add('	.comment 0 : { *(.comment) }');
+    add('	/*	DWARF debug sections.');
+    add('		Symbols in the DWARF debugging sections are relative to the beginning');
+    add('		of the section so we begin them at 0.  */');
+    add('	/* DWARF 1 */');
+    add('	.debug          0 : { *(.debug) }');
+    add('	.line           0 : { *(.line) }');
+    add('	/* GNU DWARF 1 extensions */');
+    add('	.debug_srcinfo  0 : { *(.debug_srcinfo) }');
+    add('	.debug_sfnames  0 : { *(.debug_sfnames) }');
+    add('	/* DWARF 1.1 and DWARF 2 */');
+    add('	.debug_aranges  0 : { *(.debug_aranges) }');
+    add('	.debug_pubnames 0 : { *(.debug_pubnames) }');
+    add('	/* DWARF 2 */');
+    add('	.debug_info     0 : { *(.debug_info) }');
+    add('	.debug_abbrev   0 : { *(.debug_abbrev) }');
+    add('	.debug_line     0 : { *(.debug_line) }');
+    add('	.debug_frame    0 : { *(.debug_frame) }');
+    add('	.debug_str      0 : { *(.debug_str) }');
+    add('	.debug_loc      0 : { *(.debug_loc) }');
+    add('	.debug_macinfo  0 : { *(.debug_macinfo) }');
+    add('	/* SGI/MIPS DWARF 2 extensions */');
+    add('	.debug_weaknames 0 : { *(.debug_weaknames) }');
+    add('	.debug_funcnames 0 : { *(.debug_funcnames) }');
+    add('	.debug_typenames 0 : { *(.debug_typenames) }');
+    add('	.debug_varnames  0 : { *(.debug_varnames) }');
+    add('	/* These must appear regardless of  .  */');
+    add('}');
+    add('');
+    add('__isIPL = 0;');
+    add('__stack_addr = (__bss_start + SIZEOF(.bss) + 0x20000 + 7) & (-8);');
+    add('__stack_end = (__bss_start + SIZEOF(.bss));');
+    add('__intrstack_addr = (__stack_addr + 0x4000);');
+    add('__intrstack_end = (__stack_addr);');
+    add('__Arena1Lo = (__intrstack_addr + 31) & (-32);');
+    add('__Arena1Hi = (0x817FEFF0);');
+    add('__Arena2Lo = (0x90002000);');
+    add('__Arena2Hi = (0x933E0000);');
+    add('');
+    add('__gxregs = (__Arena1Hi + 31) & (-32);');
+    add('__ipcbufferLo = (0x933e0000);');
+    add('__ipcbufferHi = (0x93400000);');
+    add('');
+    add('/* for backward compatibility with old crt0 */');
+    add('PROVIDE (__stack = (0x817FEFF0));');
+    add('');
+    add('PROVIDE(__isIPL = __isIPL);');
+    add('PROVIDE(__stack_addr = __stack_addr);');
+    add('PROVIDE(__stack_end = __stack_end);');
+    add('PROVIDE(__intrstack_addr = __intrstack_addr);');
+    add('PROVIDE(__intrstack_end = __intrstack_end);');
+    add('PROVIDE(__Arena1Lo = __Arena1Lo);');
+    add('PROVIDE(__Arena1Hi = __Arena1Hi);');
+    add('PROVIDE(__Arena2Lo = __Arena2Lo);');
+    add('PROVIDE(__Arena2Hi = __Arena2Hi);');
+    add('PROVIDE(__ipcbufferLo = __ipcbufferLo);');
+    add('PROVIDE(__ipcbufferHi = __ipcbufferHi);');
+    add('PROVIDE(__gxregs = __gxregs);');
    end;
    end;
    
    
    
    

+ 138 - 16
compiler/systems/t_win16.pas

@@ -69,6 +69,25 @@ implementation
          function  MakeExecutable:boolean;override;
          function  MakeExecutable:boolean;override;
       end;
       end;
 
 
+      { TInternalLinkerWin16 }
+
+      TInternalLinkerWin16=class(tinternallinker)
+      protected
+        procedure DefaultLinkScript;override;
+      public
+        constructor create;override;
+      end;
+
+      { TDLLScannerWin16 }
+
+      TDLLScannerWin16=class(tDLLScanner)
+      private
+        importfound : boolean;
+{        procedure CheckDLLFunc(const dllname,funcname:string);}
+      public
+        function Scan(const binname:string):boolean;override;
+      end;
+
 {****************************************************************************
 {****************************************************************************
                                TImportLibWin16
                                TImportLibWin16
 ****************************************************************************}
 ****************************************************************************}
@@ -144,9 +163,8 @@ var
   i: Integer;
   i: Integer;
   hp: texported_item;
   hp: texported_item;
   ModEnd: TOmfRecord_MODEND;
   ModEnd: TOmfRecord_MODEND;
-  DllExport_COMENT: TOmfRecord_COMENT;
-  expflag: Byte;
-  internal_name: TSymStr;
+  DllExport_COMENT: TOmfRecord_COMENT=nil;
+  DllExport_COMENT_EXPDEF: TOmfRecord_COMENT_EXPDEF=nil;
 begin
 begin
   if EList.Count=0 then
   if EList.Count=0 then
     exit;
     exit;
@@ -169,30 +187,30 @@ begin
       hp:=texported_item(EList[i]);
       hp:=texported_item(EList[i]);
 
 
       { write EXPDEF record }
       { write EXPDEF record }
-      DllExport_COMENT:=TOmfRecord_COMENT.Create;
-      DllExport_COMENT.CommentClass:=CC_OmfExtension;
-      expflag:=0;
-      if eo_index in hp.options then
-        expflag:=expflag or $80;
-      if eo_resident in hp.options then
-        expflag:=expflag or $40;
+      DllExport_COMENT_EXPDEF:=TOmfRecord_COMENT_EXPDEF.Create;
+      DllExport_COMENT_EXPDEF.ExportByOrdinal:=eo_index in hp.options;
+      DllExport_COMENT_EXPDEF.ResidentName:=eo_resident in hp.options;
+      DllExport_COMENT_EXPDEF.ExportedName:=hp.name^;
       if assigned(hp.sym) then
       if assigned(hp.sym) then
         case hp.sym.typ of
         case hp.sym.typ of
           staticvarsym:
           staticvarsym:
-            internal_name:=tstaticvarsym(hp.sym).mangledname;
+            DllExport_COMENT_EXPDEF.InternalName:=tstaticvarsym(hp.sym).mangledname;
           procsym:
           procsym:
-            internal_name:=tprocdef(tprocsym(hp.sym).ProcdefList[0]).mangledname;
+            DllExport_COMENT_EXPDEF.InternalName:=tprocdef(tprocsym(hp.sym).ProcdefList[0]).mangledname;
           else
           else
             internalerror(2015092701);
             internalerror(2015092701);
         end
         end
       else
       else
-        internal_name:=hp.name^;
-      DllExport_COMENT.CommentString:=#2+Chr(expflag)+Chr(Length(hp.name^))+hp.name^+Chr(Length(internal_name))+internal_name;
+        DllExport_COMENT_EXPDEF.InternalName:=hp.name^;
       if eo_index in hp.options then
       if eo_index in hp.options then
-        DllExport_COMENT.CommentString:=DllExport_COMENT.CommentString+Chr(Byte(hp.index))+Chr(Byte(hp.index shr 8));
+        DllExport_COMENT_EXPDEF.ExportOrdinal:=hp.index;
+
+      DllExport_COMENT:=TOmfRecord_COMENT.Create;
+      DllExport_COMENT_EXPDEF.EncodeTo(DllExport_COMENT);
+      FreeAndNil(DllExport_COMENT_EXPDEF);
       DllExport_COMENT.EncodeTo(RawRecord);
       DllExport_COMENT.EncodeTo(RawRecord);
+      FreeAndNil(DllExport_COMENT);
       RawRecord.WriteTo(ObjWriter);
       RawRecord.WriteTo(ObjWriter);
-      DllExport_COMENT.Free;
     end;
     end;
 
 
   { write MODEND record }
   { write MODEND record }
@@ -312,13 +330,117 @@ begin
 end;
 end;
 
 
 
 
+{****************************************************************************
+                               TInternalLinkerWin16
+****************************************************************************}
+
+procedure TInternalLinkerWin16.DefaultLinkScript;
+var
+  s: TCmdStr;
+begin
+  { add objectfiles, start with prt0 always }
+  case current_settings.x86memorymodel of
+    mm_small:   LinkScript.Concat('READOBJECT ' + maybequoted(FindObjectFile('prt0s','',false)));
+    mm_medium:  LinkScript.Concat('READOBJECT ' + maybequoted(FindObjectFile('prt0m','',false)));
+    mm_compact: LinkScript.Concat('READOBJECT ' + maybequoted(FindObjectFile('prt0c','',false)));
+    mm_large:   LinkScript.Concat('READOBJECT ' + maybequoted(FindObjectFile('prt0l','',false)));
+    mm_huge:    LinkScript.Concat('READOBJECT ' + maybequoted(FindObjectFile('prt0h','',false)));
+    else
+      internalerror(2019061501);
+  end;
+  while not ObjectFiles.Empty do
+  begin
+    s:=ObjectFiles.GetFirst;
+    if s<>'' then
+      LinkScript.Concat('READOBJECT ' + maybequoted(s));
+  end;
+  LinkScript.Concat('GROUP');
+  while not StaticLibFiles.Empty do
+  begin
+    s:=StaticLibFiles.GetFirst;
+    if s<>'' then
+      LinkScript.Concat('READSTATICLIBRARY '+MaybeQuoted(s));
+  end;
+  LinkScript.Concat('ENDGROUP');
+
+  LinkScript.Concat('EXESECTION .MZ_flat_content');
+  LinkScript.Concat('  OBJSECTION _TEXT||CODE');
+  LinkScript.Concat('  OBJSECTION *||CODE');
+  LinkScript.Concat('  OBJSECTION *||FAR_DATA');
+  LinkScript.Concat('  OBJSECTION _NULL||BEGDATA');
+  LinkScript.Concat('  OBJSECTION _AFTERNULL||BEGDATA');
+  LinkScript.Concat('  OBJSECTION *||BEGDATA');
+  LinkScript.Concat('  OBJSECTION *||DATA');
+  LinkScript.Concat('  SYMBOL _edata');
+  LinkScript.Concat('  OBJSECTION *||BSS');
+  LinkScript.Concat('  SYMBOL _end');
+  LinkScript.Concat('  OBJSECTION *||STACK');
+  LinkScript.Concat('  OBJSECTION *||HEAP');
+  LinkScript.Concat('ENDEXESECTION');
+
+  if (cs_debuginfo in current_settings.moduleswitches) and
+     (target_dbg.id in [dbg_dwarf2,dbg_dwarf3,dbg_dwarf4]) then
+    begin
+      LinkScript.Concat('EXESECTION .debug_info');
+      LinkScript.Concat('  OBJSECTION .DEBUG_INFO||DWARF');
+      LinkScript.Concat('ENDEXESECTION');
+      LinkScript.Concat('EXESECTION .debug_abbrev');
+      LinkScript.Concat('  OBJSECTION .DEBUG_ABBREV||DWARF');
+      LinkScript.Concat('ENDEXESECTION');
+      LinkScript.Concat('EXESECTION .debug_line');
+      LinkScript.Concat('  OBJSECTION .DEBUG_LINE||DWARF');
+      LinkScript.Concat('ENDEXESECTION');
+      LinkScript.Concat('EXESECTION .debug_aranges');
+      LinkScript.Concat('  OBJSECTION .DEBUG_ARANGES||DWARF');
+      LinkScript.Concat('ENDEXESECTION');
+    end;
+
+  LinkScript.Concat('ENTRYNAME ..start');
+end;
+
+constructor TInternalLinkerWin16.create;
+begin
+  inherited create;
+  CArObjectReader:=TOmfLibObjectReader;
+  CExeOutput:=TNewExeOutput;
+  CObjInput:=TOmfObjInput;
+end;
+
+{****************************************************************************
+                               TDLLScannerWin16
+****************************************************************************}
+
+function TDLLScannerWin16.Scan(const binname: string): boolean;
+var
+  hs,
+  dllname : TCmdStr;
+begin
+  result:=false;
+  { is there already an import library the we will use that one }
+  if FindLibraryFile(binname,target_info.staticClibprefix,target_info.staticClibext,hs) then
+    exit;
+  { check if we can find the dll }
+  hs:=binname;
+  if ExtractFileExt(hs)='' then
+    hs:=ChangeFileExt(hs,target_info.sharedlibext);
+  if not FindDll(hs,dllname) then
+    exit;
+  importfound:=false;
+  {todo: ReadDLLImports(dllname,@CheckDLLFunc);}
+  if importfound then
+    current_module.dllscannerinputlist.Pack;
+  result:=importfound;
+end;
+
 {*****************************************************************************
 {*****************************************************************************
                                      Initialize
                                      Initialize
 *****************************************************************************}
 *****************************************************************************}
 
 
 initialization
 initialization
+  RegisterLinker(ld_int_win16,TInternalLinkerWin16);
   RegisterLinker(ld_win16,TExternalLinkerWin16WLink);
   RegisterLinker(ld_win16,TExternalLinkerWin16WLink);
   RegisterImport(system_i8086_win16,TImportLibWin16);
   RegisterImport(system_i8086_win16,TImportLibWin16);
   RegisterExport(system_i8086_win16,TExportLibWin16);
   RegisterExport(system_i8086_win16,TExportLibWin16);
+  RegisterDLLScanner(system_i8086_win16,TDLLScannerWin16);
   RegisterTarget(system_i8086_win16_info);
   RegisterTarget(system_i8086_win16_info);
 end.
 end.

+ 85 - 6
compiler/x86/rax86.pas

@@ -248,7 +248,8 @@ begin
 end;
 end;
 
 
 Function Tx86Operand.CheckOperand: boolean;
 Function Tx86Operand.CheckOperand: boolean;
-
+var
+  ErrorRefStr: string;
 begin
 begin
   result:=true;
   result:=true;
   if (opr.typ=OPR_Reference) then
   if (opr.typ=OPR_Reference) then
@@ -257,15 +258,93 @@ begin
         begin
         begin
           if (getsupreg(opr.ref.base)=RS_EBP) and (opr.ref.offset>0) then
           if (getsupreg(opr.ref.base)=RS_EBP) and (opr.ref.offset>0) then
             begin
             begin
+              if current_settings.asmmode in asmmodes_x86_intel then
+                begin
+                  case getsubreg(opr.ref.base) of
+                    R_SUBW:
+                      ErrorRefStr:='[BP+offset]';
+                    R_SUBD:
+                      ErrorRefStr:='[EBP+offset]';
+                    R_SUBQ:
+                      ErrorRefStr:='[RBP+offset]';
+                    else
+                      internalerror(2019061001);
+                  end;
+                end
+              else
+                begin
+                  case getsubreg(opr.ref.base) of
+                    R_SUBW:
+                      ErrorRefStr:='+offset(%bp)';
+                    R_SUBD:
+                      ErrorRefStr:='+offset(%ebp)';
+                    R_SUBQ:
+                      ErrorRefStr:='+offset(%rbp)';
+                    else
+                      internalerror(2019061002);
+                  end;
+                end;
               if current_procinfo.procdef.proccalloption=pocall_register then
               if current_procinfo.procdef.proccalloption=pocall_register then
-                message(asmr_w_no_direct_ebp_for_parameter)
+                message1(asmr_w_no_direct_ebp_for_parameter,ErrorRefStr)
               else
               else
-                message(asmr_w_direct_ebp_for_parameter_regcall);
+                message1(asmr_w_direct_ebp_for_parameter_regcall,ErrorRefStr);
             end
             end
           else if (getsupreg(opr.ref.base)=RS_EBP) and (opr.ref.offset<0) then
           else if (getsupreg(opr.ref.base)=RS_EBP) and (opr.ref.offset<0) then
-            message(asmr_w_direct_ebp_neg_offset)
-          else if (getsupreg(opr.ref.base)=RS_ESP) and (opr.ref.offset<0) then
-            message(asmr_w_direct_esp_neg_offset);
+            begin
+              if current_settings.asmmode in asmmodes_x86_intel then
+                begin
+                  case getsubreg(opr.ref.base) of
+                    R_SUBW:
+                      ErrorRefStr:='[BP-offset]';
+                    R_SUBD:
+                      ErrorRefStr:='[EBP-offset]';
+                    R_SUBQ:
+                      ErrorRefStr:='[RBP-offset]';
+                    else
+                      internalerror(2019061003);
+                  end;
+                end
+              else
+                begin
+                  case getsubreg(opr.ref.base) of
+                    R_SUBW:
+                      ErrorRefStr:='-offset(%bp)';
+                    R_SUBD:
+                      ErrorRefStr:='-offset(%ebp)';
+                    R_SUBQ:
+                      ErrorRefStr:='-offset(%rbp)';
+                    else
+                      internalerror(2019061004);
+                  end;
+                end;
+              message1(asmr_w_direct_ebp_neg_offset,ErrorRefStr);
+            end
+          else if (getsupreg(opr.ref.base)=RS_ESP) and (getsubreg(opr.ref.base)<>R_SUBW) and (opr.ref.offset<0) then
+            begin
+              if current_settings.asmmode in asmmodes_x86_intel then
+                begin
+                  case getsubreg(opr.ref.base) of
+                    R_SUBD:
+                      ErrorRefStr:='[ESP-offset]';
+                    R_SUBQ:
+                      ErrorRefStr:='[RSP-offset]';
+                    else
+                      internalerror(2019061005);
+                  end;
+                end
+              else
+                begin
+                  case getsubreg(opr.ref.base) of
+                    R_SUBD:
+                      ErrorRefStr:='-offset(%esp)';
+                    R_SUBQ:
+                      ErrorRefStr:='-offset(%rsp)';
+                    else
+                      internalerror(2019061006);
+                  end;
+                end;
+              message1(asmr_w_direct_esp_neg_offset,ErrorRefStr);
+            end;
         end;
         end;
       if (cs_create_pic in current_settings.moduleswitches) and
       if (cs_create_pic in current_settings.moduleswitches) and
          assigned(opr.ref.symbol) and
          assigned(opr.ref.symbol) and

+ 7 - 2
packages/fcl-base/examples/testini.pp

@@ -33,8 +33,13 @@ begin
       for i:=0 to lines.Count-1 do 
       for i:=0 to lines.Count-1 do 
         WriteLn('  ', lines[i]);
         WriteLn('  ', lines[i]);
       lines.Clear();
       lines.Clear();
-      ini.ReadSectionValues('main', lines,[svoIncludeComments]);
-      WriteLn('ReadSectionValues (with comments, no invalid):');
+      ini.ReadSectionValues('main', lines,[]);
+      WriteLn('ReadSectionValues (no options):');
+      for i:=0 to lines.Count-1 do
+        WriteLn('  ', lines[i]);
+      lines.Clear();
+      ini.ReadSectionRaw('main', lines);
+      WriteLn('ReadSectionRaw (with comments, no invalid):');
       for i:=0 to lines.Count-1 do
       for i:=0 to lines.Count-1 do
         WriteLn('  ', lines[i]);
         WriteLn('  ', lines[i]);
       lines.Clear();
       lines.Clear();

+ 20 - 3
packages/fcl-base/src/blowfish.pp

@@ -59,8 +59,8 @@ Type
     function GetPosition: Int64; override;
     function GetPosition: Int64; override;
     procedure InvalidSeek; override;
     procedure InvalidSeek; override;
   Public
   Public
-    Constructor Create(AKey : TBlowFishKey; AKeySize : Byte; Dest: TStream);
-    Constructor Create(Const KeyPhrase : String; Dest: TStream);
+    Constructor Create(AKey : TBlowFishKey; AKeySize : Byte; Dest: TStream); overload; virtual;
+    Constructor Create(Const KeyPhrase : String; Dest: TStream); overload;
     Destructor Destroy; override;
     Destructor Destroy; override;
     Property BlowFish : TBlowFish Read FBF;
     Property BlowFish : TBlowFish Read FBF;
   end;
   end;
@@ -74,7 +74,11 @@ Type
   end;
   end;
 
 
   TBlowFishDeCryptStream = Class(TBlowFishStream)
   TBlowFishDeCryptStream = Class(TBlowFishStream)
+  private
+    FSourcePos0: Int64;
   public
   public
+    Constructor Create(AKey : TBlowFishKey; AKeySize : Byte; Dest: TStream); override;
+
     function Read(var Buffer; Count: Longint): Longint; override;
     function Read(var Buffer; Count: Longint): Longint; override;
     function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
     function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
   end;
   end;
@@ -652,6 +656,13 @@ end;
     TBlowFishDecryptStream
     TBlowFishDecryptStream
   ---------------------------------------------------------------------}
   ---------------------------------------------------------------------}
 
 
+constructor TBlowFishDeCryptStream.Create(AKey: TBlowFishKey; AKeySize: Byte;
+  Dest: TStream);
+begin
+  inherited Create(AKey, AKeySize, Dest);
+
+  FSourcePos0 := Source.Position;
+end;
 
 
 function TBlowFishDeCryptStream.Read(var Buffer; Count: Longint): Longint;
 function TBlowFishDeCryptStream.Read(var Buffer; Count: Longint): Longint;
 
 
@@ -697,7 +708,13 @@ end;
 function TBlowFishDeCryptStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
 function TBlowFishDeCryptStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
 
 
 begin
 begin
-  FakeSeekForward(Offset,TSeekOrigin(Origin),FPos);
+  if (Offset=0) and (Origin=soBeginning) then
+  begin // support seek to beginning
+    FBufPos:=0;
+    FPos:=0;
+    Source.Position := FSourcePos0;
+  end else
+    FakeSeekForward(Offset,TSeekOrigin(Origin),FPos);
   Result:=FPos;
   Result:=FPos;
 end;
 end;
 
 

+ 0 - 1
packages/fcl-base/src/inifiles.pp

@@ -1190,7 +1190,6 @@ begin
     oSection := FSectionList.SectionByName(Section,CaseSensitive);
     oSection := FSectionList.SectionByName(Section,CaseSensitive);
     if oSection <> nil then with oSection.KeyList do
     if oSection <> nil then with oSection.KeyList do
       for i := 0 to Count-1 do
       for i := 0 to Count-1 do
-        if not IsComment(Items[i].Ident) then
          begin
          begin
            if Items[i].Ident<>'' then
            if Items[i].Ident<>'' then
             Strings.Add(Items[i].Ident + Separator +Items[i].Value)
             Strings.Add(Items[i].Ident + Separator +Items[i].Value)

+ 11 - 16
packages/fcl-fpcunit/src/fpcunit.pp

@@ -100,10 +100,8 @@ type
     class procedure AssertFalse(ACondition: boolean); overload;
     class procedure AssertFalse(ACondition: boolean); overload;
     class procedure AssertEquals(const AMessage: string; Expected, Actual: string); overload;
     class procedure AssertEquals(const AMessage: string; Expected, Actual: string); overload;
     class procedure AssertEquals(Expected, Actual: string); overload;
     class procedure AssertEquals(Expected, Actual: string); overload;
-    {$IFDEF UNICODE}
     class procedure AssertEquals(const AMessage: string; Expected, Actual: UnicodeString); overload;
     class procedure AssertEquals(const AMessage: string; Expected, Actual: UnicodeString); overload;
     class procedure AssertEquals(Expected, Actual: UnicodeString); overload;
     class procedure AssertEquals(Expected, Actual: UnicodeString); overload;
-    {$ENDIF}
     class procedure AssertEquals(const AMessage: string; Expected, Actual: integer); overload;
     class procedure AssertEquals(const AMessage: string; Expected, Actual: integer); overload;
     class procedure AssertEquals(Expected, Actual: integer); overload;
     class procedure AssertEquals(Expected, Actual: integer); overload;
     class procedure AssertEquals(const AMessage: string; Expected, Actual: int64); overload;
     class procedure AssertEquals(const AMessage: string; Expected, Actual: int64); overload;
@@ -334,9 +332,7 @@ type
   end;
   end;
 
 
   function ComparisonMsg(const aExpected: string; const aActual: string; const aCheckEqual: boolean=true): string; overload;
   function ComparisonMsg(const aExpected: string; const aActual: string; const aCheckEqual: boolean=true): string; overload;
-  {$IFDEF UNICODE}
-  function ComparisonMsg(const aExpected: UnicodeString; const aActual: UnicodeString; const aCheckEqual: boolean=true): string; overload;
-  {$ENDIF}
+  function ComparisonMsg(const aExpected: UnicodeString; const aActual: UnicodeString; const aCheckEqual: boolean=true): Unicodestring; overload;
   function ComparisonMsg(const aMsg: string; const aExpected: string; const aActual: string; const aCheckEqual: boolean=true): string; overload;
   function ComparisonMsg(const aMsg: string; const aExpected: string; const aActual: string; const aCheckEqual: boolean=true): string; overload;
 
 
   // Made public for 3rd party developers extending TTestCase with new AssertXXX methods
   // Made public for 3rd party developers extending TTestCase with new AssertXXX methods
@@ -438,16 +434,15 @@ begin
     Result := format(SCompareNotEqual, [aExpected, aActual]);
     Result := format(SCompareNotEqual, [aExpected, aActual]);
 end;
 end;
 
 
-{$IFDEF UNICODE}
-function ComparisonMsg(const aExpected: UnicodeString; const aActual: UnicodeString; const aCheckEqual: boolean=true): string;
+function ComparisonMsg(const aExpected: Unicodestring; const aActual: Unicodestring; const aCheckEqual: boolean=true): Unicodestring;
 // aCheckEqual=false gives the error message if the test does *not* expect the results to be the same.
 // aCheckEqual=false gives the error message if the test does *not* expect the results to be the same.
 begin
 begin
   if aCheckEqual then
   if aCheckEqual then
-    Result := format(UnicodeString(SCompare), [aExpected, aActual])
+    Result := unicodeformat(SCompare, [aExpected, aActual])
   else {check unequal requires opposite error message}
   else {check unequal requires opposite error message}
-    Result := format(UnicodeString(SCompareNotEqual), [aExpected, aActual]);
+    Result := unicodeformat(SCompareNotEqual, [aExpected, aActual]);
 end;
 end;
-{$ENDIF}
+
 
 
 function ComparisonMsg(const aMsg: string; const aExpected: string; const aActual: string; const aCheckEqual: boolean): string;
 function ComparisonMsg(const aMsg: string; const aExpected: string; const aActual: string; const aCheckEqual: boolean): string;
 begin
 begin
@@ -698,18 +693,18 @@ begin
   AssertTrue(ComparisonMsg(Expected, Actual), Expected=Actual,CallerAddr);
   AssertTrue(ComparisonMsg(Expected, Actual), Expected=Actual,CallerAddr);
 end;
 end;
 
 
-{$IFDEF UNICODE}
-class procedure TAssert.AssertEquals(const AMessage: string; Expected, Actual: UnicodeString);
+class procedure TAssert.AssertEquals(const AMessage: string; Expected, Actual: Unicodestring);
 begin
 begin
-  AssertTrue(ComparisonMsg(AMessage,Expected, Actual), (Expected=Actual),CallerAddr);
+  AssertTrue(ComparisonMsg(AMessage ,Expected, Actual), Expected=Actual,CallerAddr);
 end;
 end;
 
 
 
 
-class procedure TAssert.AssertEquals(Expected, Actual: UnicodeString);
+class procedure TAssert.AssertEquals(Expected, Actual: Unicodestring);
 begin
 begin
-  AssertTrue(ComparisonMsg(Expected, Actual), (Expected=Actual),CallerAddr);
+  AssertTrue(ComparisonMsg(Expected, Actual), Expected=Actual,CallerAddr);
 end;
 end;
-{$ENDIF}
+
+
 
 
 class procedure TAssert.AssertNotNull(const AString: string);
 class procedure TAssert.AssertNotNull(const AString: string);
 begin
 begin

+ 23 - 1
packages/fcl-passrc/src/pasresolver.pp

@@ -1525,6 +1525,7 @@ type
     procedure FinishClassOfType(El: TPasClassOfType); virtual;
     procedure FinishClassOfType(El: TPasClassOfType); virtual;
     procedure FinishPointerType(El: TPasPointerType); virtual;
     procedure FinishPointerType(El: TPasPointerType); virtual;
     procedure FinishArrayType(El: TPasArrayType); virtual;
     procedure FinishArrayType(El: TPasArrayType); virtual;
+    procedure FinishGenericTemplateType(El: TPasGenericTemplateType); virtual;
     procedure FinishResourcestring(El: TPasResString); virtual;
     procedure FinishResourcestring(El: TPasResString); virtual;
     procedure FinishProcedure(aProc: TPasProcedure); virtual;
     procedure FinishProcedure(aProc: TPasProcedure); virtual;
     procedure FinishProcedureType(El: TPasProcedureType); virtual;
     procedure FinishProcedureType(El: TPasProcedureType); virtual;
@@ -5397,7 +5398,9 @@ begin
     EmitTypeHints(El,TPasAliasType(El).DestType);
     EmitTypeHints(El,TPasAliasType(El).DestType);
     end
     end
   else if (C=TPasPointerType) then
   else if (C=TPasPointerType) then
-    EmitTypeHints(El,TPasPointerType(El).DestType);
+    EmitTypeHints(El,TPasPointerType(El).DestType)
+  else if C=TPasGenericTemplateType then
+    FinishGenericTemplateType(TPasGenericTemplateType(El));
 end;
 end;
 
 
 procedure TPasResolver.FinishEnumType(El: TPasEnumType);
 procedure TPasResolver.FinishEnumType(El: TPasEnumType);
@@ -5801,6 +5804,24 @@ begin
     end;
     end;
 end;
 end;
 
 
+procedure TPasResolver.FinishGenericTemplateType(El: TPasGenericTemplateType);
+var
+  i: Integer;
+  Expr: TPasExpr;
+  Value: String;
+begin
+  for i:=0 to length(El.Constraints)-1 do
+    begin
+    Expr:=El.Constraints[i];
+    if (Expr.ClassType=TPrimitiveExpr) and (TPrimitiveExpr(Expr).Kind=pekIdent) then
+      begin
+      Value:=TPrimitiveExpr(Expr).Value;
+      if SameText(Value,'class') then
+        ; // ToDo
+      end;
+    end;
+end;
+
 procedure TPasResolver.FinishResourcestring(El: TPasResString);
 procedure TPasResolver.FinishResourcestring(El: TPasResString);
 var
 var
   ResolvedEl: TPasResolverResult;
   ResolvedEl: TPasResolverResult;
@@ -15852,6 +15873,7 @@ begin
       // resolved when finished
       // resolved when finished
     else if AClass=TPasImplCommand then
     else if AClass=TPasImplCommand then
     else if AClass=TPasAttributes then
     else if AClass=TPasAttributes then
+    else if AClass=TPasGenericTemplateType then
     else if AClass=TPasUnresolvedUnitRef then
     else if AClass=TPasUnresolvedUnitRef then
       RaiseMsg(20171018121900,nCantFindUnitX,sCantFindUnitX,[AName],El)
       RaiseMsg(20171018121900,nCantFindUnitX,sCantFindUnitX,[AName],El)
     else
     else

+ 116 - 22
packages/fcl-passrc/src/pastree.pp

@@ -58,6 +58,7 @@ resourcestring
   SPasTreeClassType = 'class';
   SPasTreeClassType = 'class';
   SPasTreeInterfaceType = 'interface';
   SPasTreeInterfaceType = 'interface';
   SPasTreeSpecializedType = 'specialized class type';
   SPasTreeSpecializedType = 'specialized class type';
+  SPasTreeSpecializedExpr = 'specialize expr';
   SPasClassHelperType = 'class helper type';
   SPasClassHelperType = 'class helper type';
   SPasRecordHelperType = 'record helper type';
   SPasRecordHelperType = 'record helper type';
   SPasTypeHelperType = 'type helper type';
   SPasTypeHelperType = 'type helper type';
@@ -564,28 +565,27 @@ type
     destructor Destroy; override;
     destructor Destroy; override;
     function ElementTypeName: string; override;
     function ElementTypeName: string; override;
     function GetDeclaration(full: boolean) : string; override;
     function GetDeclaration(full: boolean) : string; override;
+    procedure ForEachCall(const aMethodCall: TOnForEachPasElement;
+      const Arg: Pointer); override;
     procedure AddParam(El: TPasElement);
     procedure AddParam(El: TPasElement);
   public
   public
     Params: TFPList; // list of TPasType or TPasExpr
     Params: TFPList; // list of TPasType or TPasExpr
   end;
   end;
 
 
-  { TInlineTypeExpr - base class TInlineSpecializeExpr }
+  { TInlineSpecializeExpr - A<B,C> }
 
 
-  TInlineTypeExpr = class(TPasExpr)
+  TInlineSpecializeExpr = class(TPasExpr)
   public
   public
+    constructor Create(const AName: string; AParent: TPasElement); override;
     destructor Destroy; override;
     destructor Destroy; override;
     function ElementTypeName: string; override;
     function ElementTypeName: string; override;
     function GetDeclaration(full : Boolean): string; override;
     function GetDeclaration(full : Boolean): string; override;
     procedure ForEachCall(const aMethodCall: TOnForEachPasElement;
     procedure ForEachCall(const aMethodCall: TOnForEachPasElement;
       const Arg: Pointer); override;
       const Arg: Pointer); override;
-    procedure ClearTypeReferences(aType: TPasElement); override;
+    procedure AddParam(El: TPasElement);
   public
   public
-    DestType: TPasType; // TPasSpecializeType
-  end;
-
-  { TInlineSpecializeExpr - A<B,C> }
-
-  TInlineSpecializeExpr = class(TInlineTypeExpr)
+    NameExpr: TPasExpr; // TPrimitiveExpr
+    Params: TFPList; // list of TPasType or TPasExpr
   end;
   end;
 
 
   { TPasRangeType }
   { TPasRangeType }
@@ -731,9 +731,18 @@ type
     Function IsAdvancedRecord : Boolean;
     Function IsAdvancedRecord : Boolean;
   end;
   end;
 
 
+  { TPasGenericTemplateType }
+
   TPasGenericTemplateType = Class(TPasType)
   TPasGenericTemplateType = Class(TPasType)
+  public
+    destructor Destroy; override;
+    function GetDeclaration(full : boolean) : string; override;
+    procedure ForEachCall(const aMethodCall: TOnForEachPasElement;
+      const Arg: Pointer); override;
+    procedure AddConstraint(Expr: TPasExpr);
   Public
   Public
-    TypeConstraint : String;
+    TypeConstraint: String deprecated; // deprecated in fpc 3.3.1
+    Constraints: TPasExprArray;
   end;
   end;
 
 
   TPasObjKind = (
   TPasObjKind = (
@@ -1753,6 +1762,54 @@ begin
     end;
     end;
 end;
 end;
 
 
+{ TPasGenericTemplateType }
+
+destructor TPasGenericTemplateType.Destroy;
+var
+  i: Integer;
+begin
+  for i:=0 to length(Constraints)-1 do
+    Constraints[i].Release;
+  Constraints:=nil;
+  inherited Destroy;
+end;
+
+function TPasGenericTemplateType.GetDeclaration(full: boolean): string;
+var
+  i: Integer;
+begin
+  Result:=inherited GetDeclaration(full);
+  if length(Constraints)>0 then
+    begin
+    Result:=Result+': ';
+    for i:=0 to length(Constraints)-1 do
+      begin
+      if i>0 then
+        Result:=Result+',';
+      Result:=Result+Constraints[i].GetDeclaration(false);
+      end;
+    end;
+end;
+
+procedure TPasGenericTemplateType.ForEachCall(
+  const aMethodCall: TOnForEachPasElement; const Arg: Pointer);
+var
+  i: Integer;
+begin
+  inherited ForEachCall(aMethodCall, Arg);
+  for i:=0 to length(Constraints)-1 do
+    ForEachChildCall(aMethodCall,Arg,Constraints[i],false);
+end;
+
+procedure TPasGenericTemplateType.AddConstraint(Expr: TPasExpr);
+var
+  l: Integer;
+begin
+  l:=Length(Constraints);
+  SetLength(Constraints,l+1);
+  Constraints[l]:=Expr;
+end;
+
 {$IFDEF HasPTDumpStack}
 {$IFDEF HasPTDumpStack}
 procedure PTDumpStack;
 procedure PTDumpStack;
 begin
 begin
@@ -1831,34 +1888,61 @@ begin
   SemicolonAtEOL := true;
   SemicolonAtEOL := true;
 end;
 end;
 
 
-{ TInlineTypeExpr }
+{ TInlineSpecializeExpr }
 
 
-destructor TInlineTypeExpr.Destroy;
+constructor TInlineSpecializeExpr.Create(const AName: string;
+  AParent: TPasElement);
 begin
 begin
-  ReleaseAndNil(TPasElement(DestType){$IFDEF CheckPasTreeRefCount},'TInlineTypeExpr.DestType'{$ENDIF});
+  if AName='' then ;
+  inherited Create(AParent, pekSpecialize, eopNone);
+  Params:=TFPList.Create;
+end;
+
+destructor TInlineSpecializeExpr.Destroy;
+var
+  i: Integer;
+begin
+  ReleaseAndNil(TPasElement(NameExpr));
+  for i:=0 to Params.Count-1 do
+    TPasElement(Params[i]).Release{$IFDEF CheckPasTreeRefCount}('TInlineSpecializeExpr.Params'){$ENDIF};
+  FreeAndNil(Params);
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 
-function TInlineTypeExpr.ElementTypeName: string;
+function TInlineSpecializeExpr.ElementTypeName: string;
 begin
 begin
-  Result := DestType.ElementTypeName;
+  Result:=SPasTreeSpecializedExpr;
 end;
 end;
 
 
-function TInlineTypeExpr.GetDeclaration(full: Boolean): string;
+function TInlineSpecializeExpr.GetDeclaration(full: Boolean): string;
+var
+  i: Integer;
 begin
 begin
-  Result:=DestType.GetDeclaration(full);
+  Result:='specialize ';
+  Result:=Result+NameExpr.GetDeclaration(full);
+  Result:=Result+'<';
+  for i:=0 to Params.Count-1 do
+    begin
+    if i>0 then
+      Result:=Result+',';
+    Result:=Result+TPasElement(Params[i]).GetDeclaration(false);
+    end;
 end;
 end;
 
 
-procedure TInlineTypeExpr.ForEachCall(
+procedure TInlineSpecializeExpr.ForEachCall(
   const aMethodCall: TOnForEachPasElement; const Arg: Pointer);
   const aMethodCall: TOnForEachPasElement; const Arg: Pointer);
+var
+  i: Integer;
 begin
 begin
-  DestType.ForEachChildCall(aMethodCall,Arg,DestType,true);
+  inherited ForEachCall(aMethodCall, Arg);
+  ForEachChildCall(aMethodCall,Arg,NameExpr,false);
+  for i:=0 to Params.Count-1 do
+    ForEachChildCall(aMethodCall,Arg,TPasElement(Params[i]),true);
 end;
 end;
 
 
-procedure TInlineTypeExpr.ClearTypeReferences(aType: TPasElement);
+procedure TInlineSpecializeExpr.AddParam(El: TPasElement);
 begin
 begin
-  if DestType=aType then
-    ReleaseAndNil(TPasElement(DestType){$IFDEF CheckPasTreeRefCount},'TInlineTypeExpr.DestType'{$ENDIF});
+  Params.Add(El);
 end;
 end;
 
 
 { TPasSpecializeType }
 { TPasSpecializeType }
@@ -1903,6 +1987,16 @@ begin
     end;
     end;
 end;
 end;
 
 
+procedure TPasSpecializeType.ForEachCall(
+  const aMethodCall: TOnForEachPasElement; const Arg: Pointer);
+var
+  i: Integer;
+begin
+  inherited ForEachCall(aMethodCall, Arg);
+  for i:=0 to Params.Count-1 do
+    ForEachChildCall(aMethodCall,Arg,TPasElement(Params[i]),true);
+end;
+
 procedure TPasSpecializeType.AddParam(El: TPasElement);
 procedure TPasSpecializeType.AddParam(El: TPasElement);
 begin
 begin
   Params.Add(El);
   Params.Add(El);

+ 90 - 38
packages/fcl-passrc/src/pparser.pp

@@ -72,7 +72,7 @@ const
   nParserNotAProcToken = 2026;
   nParserNotAProcToken = 2026;
   nRangeExpressionExpected = 2027;
   nRangeExpressionExpected = 2027;
   nParserExpectCase = 2028;
   nParserExpectCase = 2028;
-  // free 2029;
+  nParserGenericFunctionNeedsGenericKeyword = 2029;
   nLogStartImplementation = 2030;
   nLogStartImplementation = 2030;
   nLogStartInterface = 2031;
   nLogStartInterface = 2031;
   nParserNoConstructorAllowed = 2032;
   nParserNoConstructorAllowed = 2032;
@@ -132,7 +132,7 @@ resourcestring
   SParserNotAProcToken = 'Not a procedure or function token';
   SParserNotAProcToken = 'Not a procedure or function token';
   SRangeExpressionExpected = 'Range expression expected';
   SRangeExpressionExpected = 'Range expression expected';
   SParserExpectCase = 'Case label expression expected';
   SParserExpectCase = 'Case label expression expected';
-  // free for 2029
+  SParserGenericFunctionNeedsGenericKeyword = 'Generic function needs keyword generic';
   SLogStartImplementation = 'Start parsing implementation section.';
   SLogStartImplementation = 'Start parsing implementation section.';
   SLogStartInterface = 'Start parsing interface section';
   SLogStartInterface = 'Start parsing interface section';
   SParserNoConstructorAllowed = 'Constructors or Destructors are not allowed in Interfaces or Records';
   SParserNoConstructorAllowed = 'Constructors or Destructors are not allowed in Interfaces or Records';
@@ -319,7 +319,7 @@ type
     procedure ParseClassMembers(AType: TPasClassType);
     procedure ParseClassMembers(AType: TPasClassType);
     procedure ProcessMethod(AType: TPasClassType; IsClass : Boolean; AVisibility : TPasMemberVisibility);
     procedure ProcessMethod(AType: TPasClassType; IsClass : Boolean; AVisibility : TPasMemberVisibility);
     procedure ReadGenericArguments(List : TFPList;Parent : TPasElement);
     procedure ReadGenericArguments(List : TFPList;Parent : TPasElement);
-    procedure ReadSpecializeArguments(Spec: TPasSpecializeType);
+    procedure ReadSpecializeArguments(Spec: TPasElement);
     function ReadDottedIdentifier(Parent: TPasElement; out Expr: TPasExpr; NeedAsString: boolean): String;
     function ReadDottedIdentifier(Parent: TPasElement; out Expr: TPasExpr; NeedAsString: boolean): String;
     function CheckProcedureArgs(Parent: TPasElement;
     function CheckProcedureArgs(Parent: TPasElement;
       Args: TFPList; // list of TPasArgument
       Args: TFPList; // list of TPasArgument
@@ -1587,7 +1587,7 @@ begin
   Expr:=nil;
   Expr:=nil;
   ST:=nil;
   ST:=nil;
   try
   try
-    if not (msDelphi in CurrentModeswitches) and (CurToken=tkspecialize) then
+    if CurToken=tkspecialize then
       begin
       begin
       IsSpecialize:=true;
       IsSpecialize:=true;
       NextToken;
       NextToken;
@@ -1739,7 +1739,8 @@ begin
         Result := ParseClassDecl(Parent, NamePos, TypeName, okDispInterface);
         Result := ParseClassDecl(Parent, NamePos, TypeName, okDispInterface);
       tkInterface:
       tkInterface:
         Result := ParseClassDecl(Parent, NamePos, TypeName, okInterface);
         Result := ParseClassDecl(Parent, NamePos, TypeName, okInterface);
-      tkSpecialize: Result:=ParseSpecializeType(Parent,TypeName);
+      tkSpecialize:
+        Result:=ParseSpecializeType(Parent,TypeName);
       tkClass:
       tkClass:
         begin
         begin
         isHelper:=false;
         isHelper:=false;
@@ -2165,6 +2166,8 @@ begin
 end;
 end;
 
 
 function TPasParser.ParseExprOperand(AParent: TPasElement): TPasExpr;
 function TPasParser.ParseExprOperand(AParent: TPasElement): TPasExpr;
+type
+  TAllow = (aCannot, aCan, aMust);
 
 
   Function IsWriteOrStr(P : TPasExpr) : boolean;
   Function IsWriteOrStr(P : TPasExpr) : boolean;
 
 
@@ -2235,17 +2238,17 @@ var
   Last, Func, Expr: TPasExpr;
   Last, Func, Expr: TPasExpr;
   Params: TParamsExpr;
   Params: TParamsExpr;
   Bin: TBinaryExpr;
   Bin: TBinaryExpr;
-  ok, CanSpecialize: Boolean;
+  ok: Boolean;
+  CanSpecialize: TAllow;
   aName: String;
   aName: String;
   ISE: TInlineSpecializeExpr;
   ISE: TInlineSpecializeExpr;
-  ST: TPasSpecializeType;
   SrcPos, ScrPos: TPasSourcePos;
   SrcPos, ScrPos: TPasSourcePos;
   ProcType: TProcType;
   ProcType: TProcType;
   ProcExpr: TProcedureExpr;
   ProcExpr: TProcedureExpr;
 
 
 begin
 begin
   Result:=nil;
   Result:=nil;
-  CanSpecialize:=false;
+  CanSpecialize:=aCannot;
   aName:='';
   aName:='';
   case CurToken of
   case CurToken of
     tkString: Last:=CreatePrimitiveExpr(AParent,pekString,CurTokenString);
     tkString: Last:=CreatePrimitiveExpr(AParent,pekString,CurTokenString);
@@ -2253,13 +2256,20 @@ begin
     tkNumber: Last:=CreatePrimitiveExpr(AParent,pekNumber,CurTokenString);
     tkNumber: Last:=CreatePrimitiveExpr(AParent,pekNumber,CurTokenString);
     tkIdentifier:
     tkIdentifier:
       begin
       begin
-      CanSpecialize:=true;
+      CanSpecialize:=aCan;
       aName:=CurTokenText;
       aName:=CurTokenText;
       if (CompareText(aName,'self')=0) and not (tkself in Scanner.NonTokens) then
       if (CompareText(aName,'self')=0) and not (tkself in Scanner.NonTokens) then
         Last:=CreateSelfExpr(AParent)
         Last:=CreateSelfExpr(AParent)
       else
       else
         Last:=CreatePrimitiveExpr(AParent,pekIdent,aName);
         Last:=CreatePrimitiveExpr(AParent,pekIdent,aName);
       end;
       end;
+    tkspecialize:
+      begin
+      CanSpecialize:=aMust;
+      ExpectToken(tkIdentifier);
+      aName:=CurTokenText;
+      Last:=CreatePrimitiveExpr(AParent,pekIdent,aName);
+      end;
     tkfalse, tktrue:    Last:=CreateBoolConstExpr(AParent,pekBoolConst, CurToken=tktrue);
     tkfalse, tktrue:    Last:=CreateBoolConstExpr(AParent,pekBoolConst, CurToken=tktrue);
     tknil:              Last:=CreateNilExpr(AParent);
     tknil:              Last:=CreateNilExpr(AParent);
     tkSquaredBraceOpen:
     tkSquaredBraceOpen:
@@ -2288,7 +2298,7 @@ begin
       end;
       end;
     tkself:
     tkself:
       begin
       begin
-      CanSpecialize:=true;
+      CanSpecialize:=aCan;
       aName:=CurTokenText;
       aName:=CurTokenText;
       Last:=CreateSelfExpr(AParent);
       Last:=CreateSelfExpr(AParent);
       end;
       end;
@@ -2350,6 +2360,13 @@ begin
         begin
         begin
         ScrPos:=CurTokenPos;
         ScrPos:=CurTokenPos;
         NextToken;
         NextToken;
+        if CurToken=tkspecialize then
+          begin
+          if CanSpecialize=aMust then
+            CheckToken(tkLessThan);
+          CanSpecialize:=aMust;
+          NextToken;
+          end;
         if CurToken in [tkIdentifier,tktrue,tkfalse,tkself] then // true and false are sub identifiers as well
         if CurToken in [tkIdentifier,tktrue,tkfalse,tkself] then // true and false are sub identifiers as well
           begin
           begin
           aName:=aName+'.'+CurTokenString;
           aName:=aName+'.'+CurTokenString;
@@ -2374,34 +2391,32 @@ begin
         Params.Value:=Result;
         Params.Value:=Result;
         Result.Parent:=Params;
         Result.Parent:=Params;
         Result:=Params;
         Result:=Params;
-        CanSpecialize:=false;
+        CanSpecialize:=aCannot;
         Func:=nil;
         Func:=nil;
         end;
         end;
       tkCaret:
       tkCaret:
         begin
         begin
         Result:=CreateUnaryExpr(AParent,Result,TokenToExprOp(CurToken));
         Result:=CreateUnaryExpr(AParent,Result,TokenToExprOp(CurToken));
         NextToken;
         NextToken;
-        CanSpecialize:=false;
+        CanSpecialize:=aCannot;
         Func:=nil;
         Func:=nil;
         end;
         end;
       tkLessThan:
       tkLessThan:
         begin
         begin
         SrcPos:=CurTokenPos;
         SrcPos:=CurTokenPos;
-        if (not CanSpecialize) or not IsSpecialize then
+        if CanSpecialize=aCannot then
+          break
+        else if (CanSpecialize=aCan) and not IsSpecialize then
           break
           break
         else
         else
           begin
           begin
           // an inline specialization (e.g. A<B,C>)
           // an inline specialization (e.g. A<B,C>)
           ISE:=TInlineSpecializeExpr(CreateElement(TInlineSpecializeExpr,'',AParent,SrcPos));
           ISE:=TInlineSpecializeExpr(CreateElement(TInlineSpecializeExpr,'',AParent,SrcPos));
-          ISE.Kind:=pekSpecialize;
-          ST:=TPasSpecializeType(CreateElement(TPasSpecializeType,'',ISE,SrcPos));
-          ISE.DestType:=ST;
-          ReadSpecializeArguments(ST);
-          ST.DestType:=ResolveTypeReference(aName,ST);
-          ST.Expr:=Result;
+          ReadSpecializeArguments(ISE);
+          ISE.NameExpr:=Result;
           Result:=ISE;
           Result:=ISE;
           ISE:=nil;
           ISE:=nil;
-          CanSpecialize:=false;
+          CanSpecialize:=aCannot;
           NextToken;
           NextToken;
           end;
           end;
         Func:=nil;
         Func:=nil;
@@ -3585,6 +3600,9 @@ begin
              Declarations.Declarations.Add(ArrEl);
              Declarations.Declarations.Add(ArrEl);
              Declarations.Types.Add(ArrEl);
              Declarations.Types.Add(ArrEl);
              CheckHint(ArrEl,True);
              CheckHint(ArrEl,True);
+             {$IFDEF VerbosePasResolver}
+             ParseExcTokenError('20190619145000');
+             {$ENDIF}
              ArrEl.ElType.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
              ArrEl.ElType.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
              ArrEl.ElType:=TPasGenericTemplateType(List[0]);
              ArrEl.ElType:=TPasGenericTemplateType(List[0]);
              List.Clear;
              List.Clear;
@@ -4008,12 +4026,12 @@ begin
   end;
   end;
 end;
 end;
 
 
+{$warn 5043 off}
 procedure TPasParser.ReadGenericArguments(List: TFPList; Parent: TPasElement);
 procedure TPasParser.ReadGenericArguments(List: TFPList; Parent: TPasElement);
-
 Var
 Var
   N : String;
   N : String;
   T : TPasGenericTemplateType;
   T : TPasGenericTemplateType;
-
+  Expr: TPasExpr;
 begin
 begin
   ExpectToken(tkLessThan);
   ExpectToken(tkLessThan);
   repeat
   repeat
@@ -4022,17 +4040,46 @@ begin
     List.Add(T);
     List.Add(T);
     NextToken;
     NextToken;
     if Curtoken = tkColon then
     if Curtoken = tkColon then
-      begin
-      T.TypeConstraint:=ExpectIdentifier;
-      NextToken;
-      end;
-    if not (CurToken in [tkComma,tkSemicolon,tkGreaterThan]) then
-      ParseExc(nParserExpectToken2Error,SParserExpectToken2Error,
-        [TokenInfos[tkComma], TokenInfos[tkGreaterThan]]);
-  until CurToken = tkGreaterThan;
+      repeat
+        NextToken;
+        // comma separated list: identifier, class, record, constructor
+        if CurToken in [tkclass,tkrecord,tkconstructor] then
+          begin
+          if T.TypeConstraint='' then
+            T.TypeConstraint:=CurTokenString;
+          Expr:=CreatePrimitiveExpr(T,pekIdent,CurTokenText);
+          NextToken;
+          end
+        else if CurToken=tkIdentifier then
+          begin
+          if T.TypeConstraint='' then
+            T.TypeConstraint:=ReadDottedIdentifier(T,Expr,true)
+          else
+            ReadDottedIdentifier(T,Expr,false);
+          end
+        else
+          CheckToken(tkIdentifier);
+        T.AddConstraint(Expr);
+      until CurToken<>tkComma;
+    Engine.FinishScope(stTypeDef,T);
+  until not (CurToken in [tkSemicolon,tkComma]);
+  if CurToken<>tkGreaterThan then
+    ParseExc(nParserExpectToken2Error,SParserExpectToken2Error,
+      [TokenInfos[tkComma], TokenInfos[tkGreaterThan]]);
 end;
 end;
+{$warn 5043 on}
+
+procedure TPasParser.ReadSpecializeArguments(Spec: TPasElement);
 
 
-procedure TPasParser.ReadSpecializeArguments(Spec: TPasSpecializeType);
+  procedure AddParam(El: TPasElement);
+  begin
+    if Spec is TPasSpecializeType then
+      TPasSpecializeType(Spec).AddParam(El)
+    else if Spec is TInlineSpecializeExpr then
+      TInlineSpecializeExpr(Spec).AddParam(El)
+    else
+      ParseExcTokenError('[20190619112611] '+Spec.ClassName);
+  end;
 
 
 Var
 Var
   Name : String;
   Name : String;
@@ -4042,6 +4089,7 @@ Var
   Expr: TPasExpr;
   Expr: TPasExpr;
 
 
 begin
 begin
+  //writeln('START TPasParser.ReadSpecializeArguments ',CurTokenText,' ',CurTokenString);
   CheckToken(tkLessThan);
   CheckToken(tkLessThan);
   NextToken;
   NextToken;
   Expr:=nil;
   Expr:=nil;
@@ -4049,7 +4097,8 @@ begin
   NestedSpec:=nil;
   NestedSpec:=nil;
   try
   try
     repeat
     repeat
-      if not (msDelphi in CurrentModeswitches) and (CurToken=tkspecialize) then
+      //writeln('ARG TPasParser.ReadSpecializeArguments ',CurTokenText,' ',CurTokenString);
+      if CurToken=tkspecialize then
         begin
         begin
         IsNested:=true;
         IsNested:=true;
         NextToken;
         NextToken;
@@ -4060,6 +4109,7 @@ begin
       CheckToken(tkIdentifier);
       CheckToken(tkIdentifier);
       Expr:=nil;
       Expr:=nil;
       Name:=ReadDottedIdentifier(Spec,Expr,true);
       Name:=ReadDottedIdentifier(Spec,Expr,true);
+      //writeln('AFTER NAME TPasParser.ReadSpecializeArguments ',CurTokenText,' ',CurTokenString);
 
 
       if CurToken=tkLessThan then
       if CurToken=tkLessThan then
         begin
         begin
@@ -4075,18 +4125,19 @@ begin
         // read nested specialize arguments
         // read nested specialize arguments
         ReadSpecializeArguments(NestedSpec);
         ReadSpecializeArguments(NestedSpec);
         // add nested specialize
         // add nested specialize
-        Spec.AddParam(NestedSpec);
+        AddParam(NestedSpec);
         NestedSpec:=nil;
         NestedSpec:=nil;
         NextToken;
         NextToken;
         end
         end
       else if IsNested then
       else if IsNested then
-        CheckToken(tkLessThan)
+        CheckToken(tkLessThan)   // specialize keyword without <
       else
       else
         begin
         begin
         // simple type reference
         // simple type reference
-        Spec.AddParam(Expr);
+        AddParam(Expr);
         Expr:=nil;
         Expr:=nil;
         end;
         end;
+      //writeln('AFTER PARAMS TPasParser.ReadSpecializeArguments ',CurTokenText,' ',CurTokenString);
 
 
       if CurToken=tkComma then
       if CurToken=tkComma then
         begin
         begin
@@ -6043,7 +6094,8 @@ begin
       tkEOF:
       tkEOF:
         CheckToken(tkend);
         CheckToken(tkend);
       tkAt,tkAtAt,
       tkAt,tkAtAt,
-      tkIdentifier,tkNumber,tkString,tkfalse,tktrue,tkChar,
+      tkIdentifier,tkspecialize,
+      tkNumber,tkString,tkfalse,tktrue,tkChar,
       tkBraceOpen,tkSquaredBraceOpen,
       tkBraceOpen,tkSquaredBraceOpen,
       tkMinus,tkPlus,tkinherited:
       tkMinus,tkPlus,tkinherited:
         begin
         begin
@@ -6207,9 +6259,9 @@ function TPasParser.ParseProcedureOrFunctionDecl(Parent: TPasElement;
         if CurToken=tkDot then
         if CurToken=tkDot then
           Result:=Result+'.'+ExpectIdentifier
           Result:=Result+'.'+ExpectIdentifier
         else if CurToken=tkLessThan then
         else if CurToken=tkLessThan then
-          begin // <> can be ignored, we read the list but discard its content
+          begin
           if (not MustBeGeneric) and not (msDelphi in CurrentModeswitches) then
           if (not MustBeGeneric) and not (msDelphi in CurrentModeswitches) then
-            ParseExcTokenError('('); // e.g. "generic" is missing in mode objfpc
+            ParseExc(nParserGenericFunctionNeedsGenericKeyword,SParserGenericFunctionNeedsGenericKeyword);
           UnGetToken;
           UnGetToken;
           L:=TFPList.Create;
           L:=TFPList.Create;
           Try
           Try

+ 6 - 0
packages/fcl-passrc/src/pscanner.pp

@@ -3432,16 +3432,22 @@ begin
   'FPC','DEFAULT':
   'FPC','DEFAULT':
     SetMode(msFpc,FPCModeSwitches,false,bsFPCMode);
     SetMode(msFpc,FPCModeSwitches,false,bsFPCMode);
   'OBJFPC':
   'OBJFPC':
+    begin
     SetMode(msObjfpc,OBJFPCModeSwitches,true,bsObjFPCMode);
     SetMode(msObjfpc,OBJFPCModeSwitches,true,bsObjFPCMode);
+    UnsetNonToken(tkgeneric);
+    UnsetNonToken(tkspecialize);
+    end;
   'DELPHI':
   'DELPHI':
     begin
     begin
     SetMode(msDelphi,DelphiModeSwitches,true,bsDelphiMode,[bsPointerMath]);
     SetMode(msDelphi,DelphiModeSwitches,true,bsDelphiMode,[bsPointerMath]);
     SetNonToken(tkgeneric);
     SetNonToken(tkgeneric);
+    SetNonToken(tkspecialize);
     end;
     end;
   'DELPHIUNICODE':
   'DELPHIUNICODE':
     begin
     begin
     SetMode(msDelphiUnicode,DelphiUnicodeModeSwitches,true,bsDelphiUnicodeMode,[bsPointerMath]);
     SetMode(msDelphiUnicode,DelphiUnicodeModeSwitches,true,bsDelphiUnicodeMode,[bsPointerMath]);
     SetNonToken(tkgeneric);
     SetNonToken(tkgeneric);
+    SetNonToken(tkspecialize);
     end;
     end;
   'TP':
   'TP':
     SetMode(msTP7,TPModeSwitches,false);
     SetMode(msTP7,TPModeSwitches,false);

+ 54 - 13
packages/fcl-passrc/tests/tcgenerics.pp

@@ -17,6 +17,7 @@ Type
     Procedure TestRecordGenerics;
     Procedure TestRecordGenerics;
     Procedure TestArrayGenerics;
     Procedure TestArrayGenerics;
     Procedure TestGenericConstraint;
     Procedure TestGenericConstraint;
+    Procedure TestGenericInterfaceConstraint; // ToDo
     Procedure TestDeclarationConstraint;
     Procedure TestDeclarationConstraint;
     Procedure TestSpecializationDelphi;
     Procedure TestSpecializationDelphi;
     Procedure TestDeclarationDelphi;
     Procedure TestDeclarationDelphi;
@@ -26,7 +27,8 @@ Type
     Procedure TestInlineSpecializationInArgument;
     Procedure TestInlineSpecializationInArgument;
     Procedure TestSpecializeNested;
     Procedure TestSpecializeNested;
     Procedure TestInlineSpecializeInStatement;
     Procedure TestInlineSpecializeInStatement;
-    Procedure TestGenericFunction; // ToDo
+    Procedure TestInlineSpecializeInStatementDelphi;
+    Procedure TestGenericFunction;
   end;
   end;
 
 
 implementation
 implementation
@@ -69,6 +71,32 @@ begin
     'Generic TSomeClass<T: TObject> = class',
     'Generic TSomeClass<T: TObject> = class',
     '  b : T;',
     '  b : T;',
     'end;',
     'end;',
+    'Generic TBird<T: class> = class',
+    '  c : TBird<T>;',
+    'end;',
+    'Generic TEagle<T: record> = class',
+    'end;',
+    'Generic TEagle<T: constructor> = class',
+    'end;',
+    '']);
+  ParseDeclarations;
+end;
+
+procedure TTestGenerics.TestGenericInterfaceConstraint;
+begin
+  Add([
+    'Type',
+    'TIntfA = interface end;',
+    'TIntfB = interface end;',
+    'TBird = class(TInterfacedObject,TIntfA,TIntfB) end;',
+    'Generic TAnt<T: TIntfA, TIntfB> = class',
+    '  b: T;',
+    '  c: TAnt<T>;',
+    'end;',
+    'Generic TFly<T: TIntfA, TIntfB; S> = class',
+    '  b: S;',
+    '  c: TFly<T>;',
+    'end;',
     '']);
     '']);
   ParseDeclarations;
   ParseDeclarations;
 end;
 end;
@@ -80,8 +108,8 @@ begin
   Scanner.CurrentModeSwitches:=[msDelphi]+Scanner.CurrentModeSwitches ;
   Scanner.CurrentModeSwitches:=[msDelphi]+Scanner.CurrentModeSwitches ;
   Source.Add('Type');
   Source.Add('Type');
   Source.Add('  TSomeClass<T: T2> = Class(TObject)');
   Source.Add('  TSomeClass<T: T2> = Class(TObject)');
-  Source.Add('  b : T;');
-  Source.Add('end;');
+  Source.Add('    b : T;');
+  Source.Add('  end;');
   ParseDeclarations;
   ParseDeclarations;
   AssertNotNull('have generic definition',Declarations.Classes);
   AssertNotNull('have generic definition',Declarations.Classes);
   AssertEquals('have generic definition',1,Declarations.Classes.Count);
   AssertEquals('have generic definition',1,Declarations.Classes.Count);
@@ -105,9 +133,9 @@ begin
   Scanner.CurrentModeSwitches:=[msDelphi]+Scanner.CurrentModeSwitches ;
   Scanner.CurrentModeSwitches:=[msDelphi]+Scanner.CurrentModeSwitches ;
   Source.Add('Type');
   Source.Add('Type');
   Source.Add('  TSomeClass<T,T2> = Class(TObject)');
   Source.Add('  TSomeClass<T,T2> = Class(TObject)');
-  Source.Add('  b : T;');
-  Source.Add('  b2 : T2;');
-  Source.Add('end;');
+  Source.Add('    b : T;');
+  Source.Add('    b2 : T2;');
+  Source.Add('  end;');
   ParseDeclarations;
   ParseDeclarations;
   AssertNotNull('have generic definition',Declarations.Classes);
   AssertNotNull('have generic definition',Declarations.Classes);
   AssertEquals('have generic definition',1,Declarations.Classes.Count);
   AssertEquals('have generic definition',1,Declarations.Classes.Count);
@@ -126,9 +154,9 @@ begin
   Scanner.CurrentModeSwitches:=[msDelphi]+Scanner.CurrentModeSwitches ;
   Scanner.CurrentModeSwitches:=[msDelphi]+Scanner.CurrentModeSwitches ;
   Source.Add('Type');
   Source.Add('Type');
   Source.Add('  TSomeClass<T,T2> = Class(TSomeGeneric<Integer,Integer>)');
   Source.Add('  TSomeClass<T,T2> = Class(TSomeGeneric<Integer,Integer>)');
-  Source.Add('  b : T;');
-  Source.Add('  b2 : T2;');
-  Source.Add('end;');
+  Source.Add('    b : T;');
+  Source.Add('    b2 : T2;');
+  Source.Add('  end;');
   ParseDeclarations;
   ParseDeclarations;
   AssertNotNull('have generic definition',Declarations.Classes);
   AssertNotNull('have generic definition',Declarations.Classes);
   AssertEquals('have generic definition',1,Declarations.Classes.Count);
   AssertEquals('have generic definition',1,Declarations.Classes.Count);
@@ -148,9 +176,9 @@ begin
   Scanner.CurrentModeSwitches:=[msDelphi]+Scanner.CurrentModeSwitches;
   Scanner.CurrentModeSwitches:=[msDelphi]+Scanner.CurrentModeSwitches;
   Source.Add('Type');
   Source.Add('Type');
   Source.Add('  TSomeClass<T;T2> = Class(TObject)');
   Source.Add('  TSomeClass<T;T2> = Class(TObject)');
-  Source.Add('  b : T;');
-  Source.Add('  b2 : T2;');
-  Source.Add('end;');
+  Source.Add('    b : T;');
+  Source.Add('    b2 : T2;');
+  Source.Add('  end;');
   ParseDeclarations;
   ParseDeclarations;
   AssertNotNull('have generic definition',Declarations.Classes);
   AssertNotNull('have generic definition',Declarations.Classes);
   AssertEquals('have generic definition',1,Declarations.Classes.Count);
   AssertEquals('have generic definition',1,Declarations.Classes.Count);
@@ -207,12 +235,25 @@ begin
 end;
 end;
 
 
 procedure TTestGenerics.TestInlineSpecializeInStatement;
 procedure TTestGenerics.TestInlineSpecializeInStatement;
+begin
+  Add([
+  'begin',
+  '  t:=specialize a<b>;',
+  '  t:=a.specialize b<c>;',
+  '']);
+  ParseModule;
+end;
+
+procedure TTestGenerics.TestInlineSpecializeInStatementDelphi;
 begin
 begin
   Add([
   Add([
   'begin',
   'begin',
   '  vec:=TVector<double>.create;',
   '  vec:=TVector<double>.create;',
   '  b:=a<b;',
   '  b:=a<b;',
   '  t:=a<b.c<d,e.f>>;',
   '  t:=a<b.c<d,e.f>>;',
+  '  t:=a.b<c>;',
+  '  t:=a<b>.c;',
+  // forbidden:'  t:=a<b<c>.d>;',
   '']);
   '']);
   ParseModule;
   ParseModule;
 end;
 end;
@@ -224,7 +265,7 @@ begin
   'begin',
   'begin',
   'end;',
   'end;',
   'begin',
   'begin',
-  //'  specialize IfThen<word>(true,2,3);',
+  '  specialize IfThen<word>(true,2,3);',
   '']);
   '']);
   ParseModule;
   ParseModule;
 end;
 end;

+ 43 - 0
packages/fcl-passrc/tests/tcresolvegenerics.pas

@@ -0,0 +1,43 @@
+unit tcresolvegenerics;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, testregistry, tcresolver;
+
+type
+
+  { TTestResolveGenerics }
+
+  TTestResolveGenerics = Class(TCustomTestResolver)
+  Published
+    procedure TestGen_GenericFunction; // ToDo
+  end;
+
+implementation
+
+{ TTestResolveGenerics }
+
+procedure TTestResolveGenerics.TestGen_GenericFunction;
+begin
+  exit;
+  StartProgram(false);
+  Add([
+  'generic function DoIt<T>(a: T): T;',
+  'begin',
+  '  Result:=a;',
+  'end;',
+  'var w: word;',
+  'begin',
+  '  w:=DoIt<word>(3);',
+  '']);
+  ParseProgram;
+end;
+
+initialization
+  RegisterTests([TTestResolveGenerics]);
+
+end.
+

+ 20 - 0
packages/fcl-passrc/tests/tcresolver.pas

@@ -451,6 +451,7 @@ type
     Procedure TestProc_TypeCastFunctionResult;
     Procedure TestProc_TypeCastFunctionResult;
     Procedure TestProc_ImplicitCalls;
     Procedure TestProc_ImplicitCalls;
     Procedure TestProc_Absolute;
     Procedure TestProc_Absolute;
+    Procedure TestProc_LocalInit;
 
 
     // anonymous procs
     // anonymous procs
     Procedure TestAnonymousProc_Assign;
     Procedure TestAnonymousProc_Assign;
@@ -7456,6 +7457,25 @@ begin
   'begin',
   'begin',
   'end;',
   'end;',
   'begin']);
   'begin']);
+  ParseProgram;
+end;
+
+procedure TTestResolver.TestProc_LocalInit;
+begin
+  StartProgram(false);
+  Add([
+  'type TBytes = array of byte;',
+  'procedure DoIt;',
+  'const c = 4;',
+  'var',
+  '  w: word = c;',
+  '  b: byte = 1+c;',
+  '  p: pointer = nil;',
+  '  buf: TBytes = nil;',
+  'begin',
+  'end;',
+  'begin']);
+  ParseProgram;
 end;
 end;
 
 
 procedure TTestResolver.TestAnonymousProc_Assign;
 procedure TTestResolver.TestAnonymousProc_Assign;

+ 1 - 1
packages/fcl-passrc/tests/testpassrc.lpr

@@ -7,7 +7,7 @@ uses
   Classes, consoletestrunner, tcscanner, tctypeparser, tcstatements,
   Classes, consoletestrunner, tcscanner, tctypeparser, tcstatements,
   tcbaseparser, tcmoduleparser, tconstparser, tcvarparser, tcclasstype,
   tcbaseparser, tcmoduleparser, tconstparser, tcvarparser, tcclasstype,
   tcexprparser, tcprocfunc, tcpassrcutil, tcresolver, tcgenerics,
   tcexprparser, tcprocfunc, tcpassrcutil, tcresolver, tcgenerics,
-  tcuseanalyzer, pasresolveeval;
+  tcuseanalyzer, pasresolveeval, tcresolvegenerics;
 
 
 type
 type
 
 

+ 1 - 1
packages/libgbafpc/Makefile.fpc.fpcmake

@@ -34,4 +34,4 @@ nortl=y
 [rules]
 [rules]
 .NOTPARALLEL:
 .NOTPARALLEL:
 core_asm$(OEXT):src/gba/core_asm.as
 core_asm$(OEXT):src/gba/core_asm.as
-        $(AS) -o $(UNITTARGETDIRPREFIX)core_asm$(OEXT) src/gba/core_asm.as
+        $(AS) src/gba/core_asm.as -o $(UNITTARGETDIRPREFIX)core_asm$(OEXT) 

+ 2 - 2
packages/libgbafpc/src/gba/gba_sound.inc

@@ -180,7 +180,7 @@ const
   DMGSNDCTRL_LSQR1   = $0100;
   DMGSNDCTRL_LSQR1   = $0100;
   DMGSNDCTRL_LSQR2   = $0200;
   DMGSNDCTRL_LSQR2   = $0200;
   DMGSNDCTRL_LTRI    = $0400;
   DMGSNDCTRL_LTRI    = $0400;
-  DMGSNTCTRL_LNOISE  = $0800;
+  DMGSNDCTRL_LNOISE  = $0800;
   DMGSNDCTRL_RSQR1   = $1000;
   DMGSNDCTRL_RSQR1   = $1000;
   DMGSNDCTRL_RSQR2   = $2000;
   DMGSNDCTRL_RSQR2   = $2000;
   DMGSNDCTRL_RTRI    = $4000;
   DMGSNDCTRL_RTRI    = $4000;
@@ -219,7 +219,7 @@ const
 function DSOUNDCTRL_ATIMER(x: integer): integer; inline; 
 function DSOUNDCTRL_ATIMER(x: integer): integer; inline; 
   
   
 const
 const
-  DSOUNDCTRL_ARESET    = $0400;
+  DSOUNDCTRL_ARESET    = $0800;
   DSOUNDCTRL_BR        = $1000;
   DSOUNDCTRL_BR        = $1000;
   DSOUNDCTRL_BL        = $2000;
   DSOUNDCTRL_BL        = $2000;
   
   

+ 7 - 0
packages/libndsfpc/examples/audio/maxmod/audio_modes/audio_modes.pp

@@ -201,6 +201,13 @@ begin
 			// switch audio mode
 			// switch audio mode
 			mmSelectMode( mode );
 			mmSelectMode( mode );
 		end;
 		end;
+
+		//-----------------------------------------------------
+		// START: exit
+		//-----------------------------------------------------
+		if( keys and KEY_START ) <> 0 then 
+      break;
+		//-----------------------------------------------------
 		
 		
 		//-----------------------------------------------------
 		//-----------------------------------------------------
 		// wait until next frame
 		// wait until next frame

+ 7 - 0
packages/libndsfpc/examples/audio/maxmod/reverb/reverb.pp

@@ -151,6 +151,13 @@ begin
 				reverb_is_started := 0;
 				reverb_is_started := 0;
 			end;
 			end;
 		end;
 		end;
+
+		//-----------------------------------------------------
+		// START: exit
+		//-----------------------------------------------------
+		if( keys and KEY_START ) <> 0 then 
+      break;
+		//-----------------------------------------------------
 		
 		
 		//-----------------------------------------------------
 		//-----------------------------------------------------
 		// wait until next frame
 		// wait until next frame

+ 12 - 1
packages/libndsfpc/examples/audio/maxmod/song_events_example/song_events_example.pp

@@ -48,7 +48,7 @@ end;
 
 
 var
 var
   gfx: pcuint16;
   gfx: pcuint16;
-
+  keys: cint;
 begin	
 begin	
 	videoSetMode(MODE_0_2D);
 	videoSetMode(MODE_0_2D);
 	
 	
@@ -114,6 +114,17 @@ begin
 		
 		
 		//send the updates to the hardware
 		//send the updates to the hardware
 		oamUpdate(oamMain);
 		oamUpdate(oamMain);
+   
+ 		//-----------------------------------------------------
+		// get new keypad input
+		//-----------------------------------------------------
+		scanKeys();
+		keys := keysDown();
+
+		//-----------------------------------------------------
+		// START: exit
+		//-----------------------------------------------------
+		if (keys and KEY_START) <> 0 then break;
 	end;
 	end;
 
 
 end.
 end.

+ 12 - 0
packages/libndsfpc/examples/audio/maxmod/song_events_example2/song_events_example2.pp

@@ -58,6 +58,7 @@ end;
 var
 var
   j: integer;
   j: integer;
 	i: integer;
 	i: integer;
+  keys: cint;
 
 
 begin
 begin
   for j := 0 to 4 do
   for j := 0 to 4 do
@@ -148,6 +149,17 @@ begin
 		
 		
 		//send the updates to the hardware
 		//send the updates to the hardware
 		oamUpdate(oamMain);
 		oamUpdate(oamMain);
+   
+ 		//-----------------------------------------------------
+		// get new keypad input
+		//-----------------------------------------------------
+		scanKeys();
+		keys := keysDown();
+
+		//-----------------------------------------------------
+		// START: exit
+		//-----------------------------------------------------
+		if (keys and KEY_START) <> 0 then break;   
 	end;
 	end;
 
 
 end.
 end.

+ 13 - 0
packages/libndsfpc/examples/audio/maxmod/streaming/streaming.pp

@@ -64,6 +64,7 @@ end;
 var
 var
   sys: mm_ds_system;
   sys: mm_ds_system;
   mystream: mm_stream;
   mystream: mm_stream;
+  keys: cint;
 begin	
 begin	
 
 
 	//----------------------------------------------------------------
 	//----------------------------------------------------------------
@@ -122,6 +123,18 @@ begin
 		
 		
 		// wait until next frame
 		// wait until next frame
 		swiWaitForVBlank();
 		swiWaitForVBlank();
+
+   
+ 		//-----------------------------------------------------
+		// get new keypad input
+		//-----------------------------------------------------
+		scanKeys();
+		keys := keysDown();
+
+		//-----------------------------------------------------
+		// START: exit
+		//-----------------------------------------------------
+		if (keys and KEY_START) <> 0 then break;  
 		
 		
 		// set backdrop to show cpu usage
 		// set backdrop to show cpu usage
 		BG_PALETTE_SUB[0] := cpu_colour;
 		BG_PALETTE_SUB[0] := cpu_colour;

+ 6 - 2
packages/libndsfpc/examples/audio/micrecord/micrecord.pp

@@ -55,7 +55,7 @@ procedure play();
 begin
 begin
 	soundMicOff();
 	soundMicOff();
 	soundEnable();
 	soundEnable();
-	iprintf('data length: %i'#10, data_length);
+	iprintf('data length: %li'#10, data_length);
 	soundPlaySample(sound_buffer, SoundFormat_16Bit, data_length, sample_rate, 127, 64, false, 0);
 	soundPlaySample(sound_buffer, SoundFormat_16Bit, data_length, sample_rate, 127, 64, false, 0);
 end;
 end;
 
 
@@ -89,7 +89,11 @@ begin
 			end;
 			end;
       recording := not recording;
       recording := not recording;
 		end;
 		end;
-
+		//-----------------------------------------------------
+		// START: exit
+		//-----------------------------------------------------
+		if (keys and KEY_START) <> 0 then break;
+      
 		swiWaitForVBlank();
 		swiWaitForVBlank();
 
 
 	end;
 	end;

+ 12 - 7
packages/libndsfpc/examples/card/eeprom/eeprom.pp

@@ -11,14 +11,19 @@ var
   vtype, vsize: integer;
   vtype, vsize: integer;
   data: array [0..511] of cchar;
   data: array [0..511] of cchar;
 
 
-procedure pause();
+procedure ButtonWait();
+var
+  buttons: cint;
 begin
 begin
-	iprintf('Press start...'#10);
+	iprintf('Press a key, start to exit...'#10);
 	while true do
 	while true do
 	begin
 	begin
 		scanKeys();
 		scanKeys();
-		if (keysDown() and KEY_START)<>0 then
-			exit;
+   buttons := keysDown();
+		if (buttons and KEY_START)<>0 then
+			exit;  
+    if buttons <> 0 then
+      break;
 		swiWaitForVBlank();
 		swiWaitForVBlank();
 	end;
 	end;
 	scanKeys();
 	scanKeys();
@@ -47,7 +52,7 @@ begin
     begin
     begin
       // If not, the card needs ejected and reinserted into the DS
       // If not, the card needs ejected and reinserted into the DS
       iprintf('Please eject & reinsert DS card.'#10);
       iprintf('Please eject & reinsert DS card.'#10);
-      pause();
+      ButtonWait();
       cardReadHeader(@header1);
       cardReadHeader(@header1);
       cardReadHeader(@header2);
       cardReadHeader(@header2);
     end;
     end;
@@ -63,7 +68,7 @@ begin
     iprintf('EEPROM:'#10);
     iprintf('EEPROM:'#10);
     iprintf(' Type: %d'#10, vtype);
     iprintf(' Type: %d'#10, vtype);
     iprintf(' Size: %d'#10, vsize);
     iprintf(' Size: %d'#10, vsize);
-    pause();
+    ButtonWait();
 
 
     // Read the first 512 bytes of EEPROM
     // Read the first 512 bytes of EEPROM
     cardReadEeprom(0, @data, 512, vtype);
     cardReadEeprom(0, @data, 512, vtype);
@@ -91,6 +96,6 @@ begin
     end;
     end;
   
   
     iprintf('Insert a new card to read again'#10);
     iprintf('Insert a new card to read again'#10);
-    pause();
+    ButtonWait();
   end;
   end;
 end.
 end.

+ 6 - 3
packages/libndsfpc/examples/ds_motion/dsMotion.pp

@@ -29,6 +29,8 @@ begin
   
   
 end;
 end;
 
 
+var
+  keys: cint;
 
 
 begin	
 begin	
   consoleDemoInit();
   consoleDemoInit();
@@ -38,10 +40,11 @@ begin
   while true do
   while true do
   begin	
   begin	
     scanKeys();
     scanKeys();
-    
-    if (keysDown() and KEY_A) <> 0 then 
+    keys := keysDown();
+    if (keys and KEY_A) <> 0 then 
       Calibrate();
       Calibrate();
-  
+    if (keys and KEY_START) <> 0 then 
+      break;
     consoleClear();
     consoleClear();
     if motion_init() <> 0 then
     if motion_init() <> 0 then
       iprintf('Nds is inserted'#10)
       iprintf('Nds is inserted'#10)

+ 126 - 55
packages/libndsfpc/examples/dswifi/ap_search/apSearch.pp

@@ -5,43 +5,67 @@ program apSearch;
 uses
 uses
   ctypes, nds9, dswifi9;
   ctypes, nds9, dswifi9;
 
 
-procedure findAP(ap: pWifi_AccessPoint); 
 var
 var
-	selected, i, count: integer;
+  ap: pWifi_AccessPoint;
+
+function findAP(): pWifi_AccessPoint; 
+var
+	selected, i, count, displaytop: integer;
 	ap2: Wifi_AccessPoint;
 	ap2: Wifi_AccessPoint;
+  pressed: cint;
+  displayend: integer;
+  s1, s2: string;
 begin
 begin
   selected := 0;  
   selected := 0;  
   count := 0;
   count := 0;
-
+  displaytop := 0;
+  
   Wifi_ScanMode(); //this allows us to search for APs
   Wifi_ScanMode(); //this allows us to search for APs
   
   
-  while ((keysDown() and KEY_A) = 0) do
+  pressed := 0;
+  
+  while ((pressed and KEY_A) = 0) do
   begin
   begin
     scanKeys();
     scanKeys();
     
     
+    pressed := keysDown();
+    
+    if (pressed and KEY_START) <> 0 then exit;
+    
     //find out how many APs there are in the area
     //find out how many APs there are in the area
     count := Wifi_GetNumAP();
     count := Wifi_GetNumAP();
+    
     consoleClear();
     consoleClear();
     
     
-    iprintf('Number of APs found: %d'#10, count);
+    iprintf('%d APs detected'#10, count);
+
+		displayend := displaytop + 10;
+		if (displayend > count) then displayend := count;
     
     
     //display the APs to the user
     //display the APs to the user
-    for i := 0 to count - 1 do
+    for i := displaytop to displayend - 1 do
     begin
     begin
-      Wifi_GetAPData(i, @ap2);
+      Wifi_GetAPData(i, ap);
       // display the name of the AP
       // display the name of the AP
       if i = selected then
       if i = selected then
-        iprintf('%s %s'#10, '*', pcchar(ap2.ssid))
+        s1 := '*' 
       else
       else
-        iprintf('%s %s'#10, ' ', pcchar(ap2.ssid));
+        s1 := ' ';
+      
+      if (ap.flags and WFLAG_APDATA_WEP) <> 0 then
+        s2 := 'Yes ' 
+      else
+        s2 :=  'No ';
+      
+      iprintf('%s %.29s'#10'  Wep:%s Sig:%i'#10, s1, pcchar(ap^.ssid), s2, ap.rssi * 100 div $D0);
       
       
     end;
     end;
-
+    
 		//move the selection asterick
 		//move the selection asterick
-		if ((keysDown() and KEY_UP) <> 0) and (selected > 0) then 
+		if ((pressed and KEY_UP) <> 0) and (selected > 0) then 
       dec(selected);
       dec(selected);
 
 
-		if ((keysDown() and KEY_DOWN) <> 0) and (selected < (count-1)) then 
+		if ((pressed and KEY_DOWN) <> 0) and (selected < (count-1)) then 
       inc(selected);
       inc(selected);
 
 
 		swiWaitForVBlank();
 		swiWaitForVBlank();
@@ -49,7 +73,7 @@ begin
 
 
 	//user has made a choice so grab the ap and return it
 	//user has made a choice so grab the ap and return it
 	Wifi_GetAPData(selected, ap);
 	Wifi_GetAPData(selected, ap);
-
+  result := ap;
 end;
 end;
 
 
 //---------------------------------------------------------------------------------
 //---------------------------------------------------------------------------------
@@ -66,58 +90,105 @@ var
   oldStatus: integer;
   oldStatus: integer;
 	url: array [0..255] of char;
 	url: array [0..255] of char;
   host: phostent;
   host: phostent;
-
+  wepkey = array [0..63] of char;
+  wepmode: cint;
+  len: integer;
+  ip: cuint32;
+  quit: integer;
+  pressed: cint;
 begin
 begin
-  status := integer(ASSOCSTATUS_DISCONNECTED);
-  
+  Wifi_InitDefault(false);
   consoleDemoInit(); 
   consoleDemoInit(); 
-
   new(kb);
   new(kb);
   kb := keyboardDemoInit();
   kb := keyboardDemoInit();
   kb^.OnKeyPressed := @keyPressed;
   kb^.OnKeyPressed := @keyPressed;
-  
-  Wifi_InitDefault(false);
-  
-  findAP(ap3);
-  	
-  iprintf('Connecting to %s'#10, pcchar(ap3^.ssid));
-  
-  //this tells the wifi lib to use dhcp for everything
-  Wifi_SetIP(0,0,0,0,0);	
-  
-  Wifi_ConnectAP(ap3, integer(WEPMODE_NONE), 0, nil);
 
 
-  while (status <> integer(ASSOCSTATUS_ASSOCIATED)) and (status <> integer(ASSOCSTATUS_CANNOTCONNECT)) do
+  while true do
   begin
   begin
-    oldStatus := status;
-    
-    status := Wifi_AssocStatus();
-    if oldStatus <> status then
-      iprintf('%s', pchar(@ASSOCSTATUS_STRINGS[status]))
-    else 
-      iprintf('%s', '.');
-    
-    swiWaitForVBlank();
-  end;
+    status := integer(ASSOCSTATUS_DISCONNECTED);
+    consoleClear();
+    consoleSetWindow(nil, 0,0,32,24);   
 
 
-	consoleClear();
-	consoleSetWindow(nil, 0,0,32,10);
+    ap3 := findAp();
 
 
+    consoleClear();
+    consoleSetWindow(nil, 0,0,32,10);
 
 
-  while true do
-  begin
-    iprintf('Url? ');
-    
-    scanf('%s', url);
-    
-    host := gethostbyname(url);
-    
-    if (host) <> nil then
-    	iprintf('IP (%s) : %s'#10,  url, inet_ntoa(in_addr(host^.h_addr_list^)))
-    else
-    	iprintf('Could not resolve'#10);
-    
-    swiWaitForVBlank();
+    iprintf('Connecting to %s'#10, pcchar(ap3^.ssid));
+
+    //this tells the wifi lib to use dhcp for everything
+    Wifi_SetIP(0,0,0,0,0);
+    wepmode := WEPMODE_NONE;
+
+    if (ap3^.flags and WFLAG_APDATA_WEP) <> 0 then
+    begin
+      iprintf('Enter Wep Key'#10);
+      while (wepmode = WEPMODE_NONE) do
+      begin
+        scanf('%s', wepkey);
+        if (strlen(wepkey) = 13) then
+          wepmode := WEPMODE_128BIT;
+        else if (strlen(wepkey) = 5) then
+          wepmode := WEPMODE_40BIT;
+        else 
+          iprintf('Invalid key!'#10);
+      end;
+      Wifi_ConnectAP(ap3, wepmode, 0, pcuint8(wepkey));
+    end else 
+      Wifi_ConnectAP(ap3, integer(WEPMODE_NONE), 0, nil);
+
+    consoleClear();
+    while (status <> ASSOCSTATUS_ASSOCIATED) and (status <> ASSOCSTATUS_CANNOTCONNECT) do
+    begin
+      status := Wifi_AssocStatus();
+      len := strlen(ASSOCSTATUS_STRINGS[status]);
+      iprintf(#27'[0;0H\x1b[K');
+      iprintf(#27'[0;%dH%s', (32-len) div 2, ASSOCSTATUS_STRINGS[status]);
+      
+      scanKeys();
+      
+      if (keysDown() and KEY_B) <> 0 then break;
+      
+      swiWaitForVBlank();
+    end;
+   
+
+    if (status = ASSOCSTATUS_ASSOCIATED) then
+    begin
+      ip := Wifi_GetIP();
+
+      iprintf(#10'ip: [%li.%li.%li.%li]'#10, (ip ) and $FF, (ip shr 8) and $FF, (ip shr 16) and $FF, (ip shr 24) and $FF);
+			while true do 
+      begin
+
+				scanf('%s', url);
+
+				if (strcmp(url, 'quit') = 0) then break;
+
+				host := gethostbyname(url);
+
+				if(host <> nil) then
+					iprintf('IP (%s) : %s'#10,  url, inet_ntoa(pin_addr(host)^.h_addr_list[0]))
+				else
+					iprintf('Could not resolve'#10);
+
+				swiWaitForVBlank();
+			end;
+		end else 
+			iprintf(#10'Connection failed!'#10);
+
+		quit := 0;
+		iprintf('Press A to try again, B to quit.');
+		while true do
+   begin
+			swiWaitForVBlank();
+			scanKeys();
+			pressed := keysDown();
+			if(pressed and KEY_B) <> 0 then quit := 1;
+			if(pressed and (KEY_A or KEY_B)) <> 0 then break;
+		end;
+		if (quit) <> 0 then break;
+   
   end;
   end;
 
 
 end.
 end.

+ 5 - 1
packages/libndsfpc/examples/dswifi/autoconnect/autoconnect.pp

@@ -7,7 +7,7 @@ uses
 
 
 var
 var
 	ip, gateway, mask, dns1, dns2: in_addr;
 	ip, gateway, mask, dns1, dns2: in_addr;
-
+    keys: integer;
 begin
 begin
 
 
 	consoleDemoInit();  //setup the sub screen for printing
 	consoleDemoInit();  //setup the sub screen for printing
@@ -31,6 +31,10 @@ begin
 	end;
 	end;
 
 
 	while true do
 	while true do
+  begin
 		swiWaitForVBlank();
 		swiWaitForVBlank();
+		if( keys and KEY_START ) <> 0 then 
+      break;
+  end;
 end.
 end.
 
 

+ 8 - 1
packages/libndsfpc/examples/dswifi/httpget/httpget.pp

@@ -54,6 +54,9 @@ begin
   closesocket(my_socket); // remove the socket.
   closesocket(my_socket); // remove the socket.
 end;
 end;
 
 
+var
+    keys: integer;
+
 begin
 begin
 	consoleDemoInit();  //setup the sub screen for printing
 	consoleDemoInit();  //setup the sub screen for printing
 
 
@@ -68,6 +71,10 @@ begin
 		getHttp('www.akkit.org');
 		getHttp('www.akkit.org');
 	end;
 	end;
 
 
-	while true do
+  while true do
+  begin
 		swiWaitForVBlank();
 		swiWaitForVBlank();
+		if( keys and KEY_START ) <> 0 then 
+      break;
+  end;
 end.
 end.

+ 5 - 2
packages/libndsfpc/examples/filesystem/libfat/libfatdir/libfatdir.pp

@@ -42,7 +42,10 @@ begin
 		iprintf('fatInitDefault failure: terminating'#10);
 		iprintf('fatInitDefault failure: terminating'#10);
 	end;
 	end;
 
 
-	while true do
+  while true do
+  begin
 		swiWaitForVBlank();
 		swiWaitForVBlank();
-
+    scanKeys();
+    if (keysDown() and KEY_START) <> 0 then break;
+  end;
 end.
 end.

+ 5 - 0
packages/libndsfpc/examples/graphics/3D/3D_Both_Screens/3DBothScreens.pp

@@ -132,6 +132,7 @@ end;
 
 
 var
 var
 	top: boolean = true;
 	top: boolean = true;
+  keys: integer;
 
 
 begin 
 begin 
   videoSetMode(MODE_0_3D);
   videoSetMode(MODE_0_3D);
@@ -171,6 +172,10 @@ begin
     // wait for capture unit to be ready
     // wait for capture unit to be ready
     while (REG_DISPCAPCNT^ and DCAP_ENABLE) <> 0 do;
     while (REG_DISPCAPCNT^ and DCAP_ENABLE) <> 0 do;
     
     
+    scanKeys();
+		keys := keysDown();
+		if (keys and KEY_START) <> 0 then break;
+    
     //-------------------------------------------------------
     //-------------------------------------------------------
     //	 Switch render targets
     //	 Switch render targets
     //-------------------------------------------------------
     //-------------------------------------------------------

+ 96 - 96
packages/libndsfpc/examples/graphics/3D/BoxTest/BoxTest.pp

@@ -9,9 +9,9 @@ uses
 function startTimer(timer: integer): cuint16;
 function startTimer(timer: integer): cuint16;
 begin
 begin
   TIMER_CR(timer)^ := 0;
   TIMER_CR(timer)^ := 0;
-	TIMER_DATA(0)^ := 0;
-	TIMER_CR(timer)^ := TIMER_DIV_1 or TIMER_ENABLE;
-	startTimer := TIMER_DATA(0)^;
+  TIMER_DATA(0)^ := 0;
+  TIMER_CR(timer)^ := TIMER_DIV_1 or TIMER_ENABLE;
+  startTimer := TIMER_DATA(0)^;
 end;
 end;
 
 
 
 
@@ -74,7 +74,7 @@ begin
 end;
 end;
 
 
 var
 var
-	touchXY: touchPosition;
+  touchXY: touchPosition;
 
 
   rotX: cfloat = 0;
   rotX: cfloat = 0;
   rotY: cfloat = 0;
   rotY: cfloat = 0;
@@ -92,7 +92,7 @@ var
   oldx: integer = 0;
   oldx: integer = 0;
   oldy: integer = 0;
   oldy: integer = 0;
 
 
-	held, pressed: integer;
+  held, pressed: integer;
   hit: integer;
   hit: integer;
   
   
   i: integer;
   i: integer;
@@ -121,114 +121,114 @@ begin
   // Set our view port to be the same size as the screen
   // Set our view port to be the same size as the screen
   glViewport(0,0,255,191);
   glViewport(0,0,255,191);
   
   
-	printf(#$1b'[10;0HPress A to change culling');
-	printf(#10#10'Press B to change Ortho vs Persp');
-	printf(#10'Left/Right/Up/Down to rotate');
-	printf(#10'Press L and R to zoom');
-	printf(#10'Touch screen to rotate cube');
+  printf(#$1b'[10;0HPress A to change culling');
+  printf(#10#10'Press B to change Ortho vs Persp');
+  printf(#10'Left/Right/Up/Down to rotate');
+  printf(#10'Press L and R to zoom');
+  printf(#10'Touch screen to rotate cube');
 
 
-	//main loop
-	while true do
-	begin
+  //main loop
+  while true do
+  begin
     
     
     //process input
     //process input
     scanKeys();
     scanKeys();
     
     
     touchRead(touchXY);
     touchRead(touchXY);
 
 
-		
+    
     held := keysHeld();
     held := keysHeld();
     pressed := keysDown();
     pressed := keysDown();
-		
-		if( held and KEY_LEFT) <> 0 then rotY := rotY + 1;
-		if( held and KEY_RIGHT) <> 0 then rotY := rotY - 1;
-		if( held and KEY_UP) <> 0 then rotX := rotX + 1;
-		if( held and KEY_DOWN) <> 0 then rotX := rotX - 1;
-		if( held and KEY_L) <> 0 then translate := translate + 0.1;
-		if( held and KEY_R) <> 0 then translate := translate - 0.1;
-
-		//reset x and y when user touches screen
-		if (pressed and KEY_TOUCH) <> 0 then
-		begin
-			oldx := touchXY.px;
-			oldy := touchXY.py;
-		end;
-
-		//if user drags then grab the delta
-		if (held and KEY_TOUCH) <> 0 then
-		begin
-			rx := rx + (touchXY.px - oldx); 
-			ry := ry + (touchXY.py - oldy);
-			oldx := touchXY.px;
-			oldy := touchXY.py;
-		end;
-
-		
-		//change ortho vs perspective
-		glMatrixMode(GL_PROJECTION);
-		glLoadIdentity();
-		if (keysHeld() and KEY_B) <> 0 then
-			glOrtho(-4,4,-3,3,0.1,10)	
-		else 
-			gluPerspective(70, 256.0 / 192.0, 0.1, 10);
-	
-		//change cull mode
-		if (held and KEY_A) <> 0 then
-			glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE )
-		else
-			glPolyFmt(POLY_ALPHA(31) or POLY_CULL_FRONT );
-
-		// Set the current matrix to be the model matrix
-		glMatrixMode(GL_MODELVIEW);
-		glLoadIdentity();
-
-		//handle camera
-		glRotateY(rotY);
-		glRotateX(rotX);
-		glTranslatef(0,0,translate);
-
-		//move the cube
-		glRotateX(ry);
-		glRotateY(rx);
-
-		DrawBox(-1,-1,-1,2,2,2);
-
-		swiWaitForVBlank();
-		printf(#$1b'[0;0HBox test cycle count');
-
-		time := startTimer(0);
-		hit := BoxTestf(-1,-1,-1,2,2,2);
-		printf(#10'Single test (float): %i', 2*(getTimer(0) - time));
-
-		time := startTimer(0);
-		BoxTest(inttov16(-1),inttov16(-1),inttov16(-1),inttov16(2),inttov16(2),inttov16(2));
-		printf(#10'Single test (fixed): %i', 2*(getTimer(0) - time));
-
-		time := startTimer(0);
-		for i := 0 to 63 do
-			BoxTest(inttov16(-1),inttov16(-1),inttov16(-1),inttov16(2),inttov16(2),inttov16(2));
-
-		printf(#10'64 tests avg. (fixed): %i', (getTimer(0) - time) / 32);
-		if hit <> 0 then
-		  printf(#10'Box Test result: hit') 
+    
+    if( held and KEY_LEFT) <> 0 then rotY := rotY + 1;
+    if( held and KEY_RIGHT) <> 0 then rotY := rotY - 1;
+    if( held and KEY_UP) <> 0 then rotX := rotX + 1;
+    if( held and KEY_DOWN) <> 0 then rotX := rotX - 1;
+    if( held and KEY_L) <> 0 then translate := translate + 0.1;
+    if( held and KEY_R) <> 0 then translate := translate - 0.1;
+
+    //reset x and y when user touches screen
+    if (pressed and KEY_TOUCH) <> 0 then
+    begin
+      oldx := touchXY.px;
+      oldy := touchXY.py;
+    end;
+
+    //if user drags then grab the delta
+    if (held and KEY_TOUCH) <> 0 then
+    begin
+      rx := rx + (touchXY.px - oldx); 
+      ry := ry + (touchXY.py - oldy);
+      oldx := touchXY.px;
+      oldy := touchXY.py;
+    end;
+
+    
+    //change ortho vs perspective
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    if (keysHeld() and KEY_B) <> 0 then
+      glOrtho(-4,4,-3,3,0.1,10) 
+    else 
+      gluPerspective(70, 256.0 / 192.0, 0.1, 10);
+  
+    //change cull mode
+    if (held and KEY_A) <> 0 then
+      glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE )
+    else
+      glPolyFmt(POLY_ALPHA(31) or POLY_CULL_FRONT );
+
+    // Set the current matrix to be the model matrix
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+
+    //handle camera
+    glRotateY(rotY);
+    glRotateX(rotX);
+    glTranslatef(0,0,translate);
+
+    //move the cube
+    glRotateX(ry);
+    glRotateY(rx);
+
+    DrawBox(-1,-1,-1,2,2,2);
+
+    swiWaitForVBlank();
+    printf(#$1b'[0;0HBox test cycle count');
+
+    time := startTimer(0);
+    hit := BoxTestf(-1,-1,-1,2,2,2);
+    printf(#10'Single test (float): %i', 2*(getTimer(0) - time));
+
+    time := startTimer(0);
+    BoxTest(inttov16(-1),inttov16(-1),inttov16(-1),inttov16(2),inttov16(2),inttov16(2));
+    printf(#10'Single test (fixed): %i', 2*(getTimer(0) - time));
+
+    time := startTimer(0);
+    for i := 0 to 63 do
+      BoxTest(inttov16(-1),inttov16(-1),inttov16(-1),inttov16(2),inttov16(2),inttov16(2));
+
+    printf(#10'64 tests avg. (fixed): %i', (getTimer(0) - time) / 32);
+    if hit <> 0 then
+      printf(#10'Box Test result: hit') 
     else
     else
       printf(#10'Box Test result: miss');
       printf(#10'Box Test result: miss');
 
 
-		while (GFX_STATUS^ and (1 shl 27)) <> 0 do; // wait until the geometry engine is not busy
+    while (GFX_STATUS^ and (1 shl 27)) <> 0 do; // wait until the geometry engine is not busy
 
 
-		glGetInt(GL_GET_VERTEX_RAM_COUNT, vertex_count);
-		glGetInt(GL_GET_POLYGON_RAM_COUNT, polygon_count);
+    glGetInt(GL_GET_VERTEX_RAM_COUNT, vertex_count);
+    glGetInt(GL_GET_POLYGON_RAM_COUNT, polygon_count);
 
 
     if (held and KEY_A)<> 0 then 
     if (held and KEY_A)<> 0 then 
-		  printf(#10#10'Ram usage: Culling none')
+      printf(#10#10'Ram usage: Culling none')
     else 
     else 
     printf(#10#10'Ram usage: Culling back faces');
     printf(#10#10'Ram usage: Culling back faces');
     
     
-		printf(#10'Vertex ram: %i', vertex_count);
-		printf(#10'Polygon ram: %i', polygon_count);
-
-		// flush to the screen
-		glFlush(0);
+    printf(#10'Vertex ram: %i', vertex_count);
+    printf(#10'Polygon ram: %i', polygon_count);
 
 
-	end;
+    // flush to the screen
+    glFlush(0);
+    if (pressed and KEY_START) <> 0 then break;
+  end;
 end.
 end.

+ 2 - 1
packages/libndsfpc/examples/graphics/3D/Display_List/DisplayList.pp

@@ -78,7 +78,8 @@ begin
     scanKeys();
     scanKeys();
     
     
     keys := keysHeld();
     keys := keysHeld();
-
+    if (keys and KEY_START) <> 0 then break;
+    
     if ((keys and KEY_UP)) <> 0 then rotateX := rotateX + 3;
     if ((keys and KEY_UP)) <> 0 then rotateX := rotateX + 3;
     if ((keys and KEY_DOWN)) <> 0 then rotateX := rotateX - 3;
     if ((keys and KEY_DOWN)) <> 0 then rotateX := rotateX - 3;
     if ((keys and KEY_LEFT)) <> 0 then rotateY := rotateY + 3;
     if ((keys and KEY_LEFT)) <> 0 then rotateY := rotateY + 3;

+ 1 - 0
packages/libndsfpc/examples/graphics/3D/Display_List_2/DisplayList2.pp

@@ -70,6 +70,7 @@ begin
 		glPopMatrix(1);
 		glPopMatrix(1);
 			
 			
 		glFlush(0);
 		glFlush(0);
+   if (keys and KEY_START) <> 0 then break;
 	end;
 	end;
 
 
 end.
 end.

+ 1 - 0
packages/libndsfpc/examples/graphics/3D/Env_Mapping/EnvMapping.pp

@@ -124,5 +124,6 @@ begin
 		glCallList(@teapot_bin);
 		glCallList(@teapot_bin);
 
 
 		glFlush(0);
 		glFlush(0);
+    if (keys and KEY_START) <> 0 then break;
   end;
   end;
 end.
 end.

+ 7 - 0
packages/libndsfpc/examples/graphics/3D/Mixed_Text_3D/MixedText3D.pp

@@ -47,6 +47,9 @@ begin
 	glEnd();										// Done Drawing The Quad
 	glEnd();										// Done Drawing The Quad
 end;
 end;
 
 
+var
+  keys: integer;
+
 begin
 begin
 	// initialize the geometry engine
 	// initialize the geometry engine
 	glInit();	
 	glInit();	
@@ -98,6 +101,10 @@ begin
  
  
 		// wait for the screen to refresh
 		// wait for the screen to refresh
 		swiWaitForVBlank();
 		swiWaitForVBlank();
+   
+    scanKeys();
+		keys := keysDown();
+		if (keys and KEY_START) <> 0 then break;
 
 
 		printf(#$1b'[15;5H rtri  = %f     '#10, rtri);
 		printf(#$1b'[15;5H rtri  = %f     '#10, rtri);
 		printf(#$1b'[16;5H rquad = %f     '#10, rquad);
 		printf(#$1b'[16;5H rquad = %f     '#10, rquad);

+ 8 - 2
packages/libndsfpc/examples/graphics/3D/Ortho/Ortho.pp

@@ -84,6 +84,9 @@ begin
   result := true;
   result := true;
 end;
 end;
 
 
+var
+  held: integer;
+
 begin
 begin
   // Setup the Main screen for 3D
   // Setup the Main screen for 3D
   videoSetMode(MODE_0_3D);
   videoSetMode(MODE_0_3D);
@@ -132,13 +135,14 @@ begin
   while true do
   while true do
   begin
   begin
     scanKeys();
     scanKeys();
+    held := keysHeld();
 
 
     //reset the projection matrix
     //reset the projection matrix
     glMatrixMode(GL_PROJECTION);
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
     glLoadIdentity();
 
 
     // set the projection matrix as either ortho or perspective
     // set the projection matrix as either ortho or perspective
-    if (keysHeld() and KEY_R) = 0 then
+    if (held and KEY_R) = 0 then
       gluPerspective(70, 256.0 / 192.0, 0.1, 100)
       gluPerspective(70, 256.0 / 192.0, 0.1, 100)
     else
     else
       glOrtho(-3, 3,-2, 2, 0.1, 100);
       glOrtho(-3, 3,-2, 2, 0.1, 100);
@@ -147,7 +151,7 @@ begin
     glMatrixMode(GL_MODELVIEW);
     glMatrixMode(GL_MODELVIEW);
 
 
     //ds specific, several attributes can be set here
     //ds specific, several attributes can be set here
-    if (keysHeld() and KEY_L) <> 0 then
+    if (held and KEY_L) <> 0 then
       glPolyFmt(POLY_ALPHA(0) or POLY_CULL_NONE or POLY_FORMAT_LIGHT0 or POLY_FORMAT_LIGHT1 or POLY_FORMAT_LIGHT2)
       glPolyFmt(POLY_ALPHA(0) or POLY_CULL_NONE or POLY_FORMAT_LIGHT0 or POLY_FORMAT_LIGHT1 or POLY_FORMAT_LIGHT2)
     else
     else
       glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE or POLY_FORMAT_LIGHT0 or POLY_FORMAT_LIGHT1 or POLY_FORMAT_LIGHT2);
       glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE or POLY_FORMAT_LIGHT0 or POLY_FORMAT_LIGHT1 or POLY_FORMAT_LIGHT2);
@@ -163,5 +167,7 @@ begin
 
 
     // flush to screen
     // flush to screen
     glFlush(0);
     glFlush(0);
+    
+    if (held and KEY_START) <> 0 then break;
   end;
   end;
 end.
 end.

+ 4 - 2
packages/libndsfpc/examples/graphics/3D/Paletted_Cube/PalettedCube.pp

@@ -308,7 +308,7 @@ begin
         nTexture := 10;
         nTexture := 10;
     end;
     end;
 
 
-    glBindTexture(nTexture, textureIDS[nTexture]);
+    glBindTexture(0, textureIDS[nTexture]);
 
 
     //draw the obj
     //draw the obj
     glBegin(GL_QUAD);
     glBegin(GL_QUAD);
@@ -320,6 +320,8 @@ begin
 
 
     glFlush(0);
     glFlush(0);
     swiWaitForVBlank();
     swiWaitForVBlank();
+    
+    if (keysPressed and KEY_START) <> 0 then break;
   end;
   end;
 
 
-end.
+end.

+ 134 - 132
packages/libndsfpc/examples/graphics/3D/Picking/Picking.pp

@@ -23,154 +23,156 @@ var
 // run before starting to draw an object while picking
 // run before starting to draw an object while picking
 procedure startCheck();
 procedure startCheck();
 begin
 begin
-	while PosTestBusy() do; // wait for the position test to finish
-	while GFX_BUSY do; // wait for all the polygons from the last object to be drawn
-	PosTest_Asynch(0,0,0); // start a position test at the current translated position
-	polyCount := GFX_POLYGON_RAM_USAGE^; // save the polygon count
+  while PosTestBusy() do; // wait for the position test to finish
+  while GFX_BUSY do; // wait for all the polygons from the last object to be drawn
+  PosTest_Asynch(0,0,0); // start a position test at the current translated position
+  polyCount := GFX_POLYGON_RAM_USAGE^; // save the polygon count
 end;
 end;
 
 
 // run afer drawing an object while picking
 // run afer drawing an object while picking
 procedure endCheck(obj: TClickable);
 procedure endCheck(obj: TClickable);
 begin
 begin
-	while GFX_BUSY do; // wait for all the polygons to get drawn
-	while PosTestBusy() do; // wait for the position test to finish
-	if (GFX_POLYGON_RAM_USAGE^ > polyCount) then // if a polygon was drawn
-	begin
-		if PosTestWresult() <= closeW then
-		begin
-			// this is currently the closest object under the cursor!
-			closeW := PosTestWresult();
-			clicked := obj;
-		end;
-	end;
+  while GFX_BUSY do; // wait for all the polygons to get drawn
+  while PosTestBusy() do; // wait for the position test to finish
+  if (GFX_POLYGON_RAM_USAGE^ > polyCount) then // if a polygon was drawn
+  begin
+    if PosTestWresult() <= closeW then
+    begin
+      // this is currently the closest object under the cursor!
+      closeW := PosTestWresult();
+      clicked := obj;
+    end;
+  end;
 end;
 end;
 
 
 
 
 var
 var
-	rotateX: cuint32 = 0;
-	rotateY: cuint32 = 0;
+  rotateX: cuint32 = 0;
+  rotateY: cuint32 = 0;
   touchXY: touchPosition;
   touchXY: touchPosition;
   viewport: array [0..3] of cint32 = (0,0,255,191); // used later for gluPickMatrix()
   viewport: array [0..3] of cint32 = (0,0,255,191); // used later for gluPickMatrix()
-	keys: u16;
+  keys: u16;
 
 
 begin
 begin
-	// initialize gl
-	glInit();
-
-	//set mode 0, enable BG0 and set it to 3D
-	videoSetMode(MODE_0_3D);
-	
-	lcdMainOnBottom(); // we are going to be touching the 3D display
-	
-	// enable edge outlining, this will be used to show which object is selected
-	glEnable(GL_OUTLINE);
-	
-	//set the first outline color to white
-	glSetOutlineColor(0,RGB15(31,31,31));
-
-	// setup the rear plane
-	glClearColor(0,0,0,0); // set BG to black and clear
-	glClearPolyID(0); // the BG and polygons will have the same ID unless a polygon is highlighted
-	glClearDepth($7FFF);
-	
-	// setup the camera
-	gluLookAt( 0.0, 0.0, 1.0,		//camera possition
-				     0.0, 0.0, 0.0,		//look at
-				     0.0, 1.0, 0.0);	//up
-	
-	glLight(0, RGB15(31,31,31) , 0, floattov10(-1.0), 0); // setup the light
-	
-	while true do
-	begin
-		// handle key input
-		scanKeys();
-		keys := keysHeld();
-		if ((keys and KEY_UP)) = 0 then rotateX := rotateX +3;
-		if((keys and KEY_DOWN)) = 0 then rotateX := rotateX -3;
-		if((keys and KEY_LEFT)) = 0 then rotateY := rotateY +3;
-		if((keys and KEY_RIGHT)) = 0 then rotateY := rotateY -3;
-
-		// get touchscreen position
-		touchXY := touchReadXY();
-
-		glViewPort(0,0,255,191); // set the viewport to fullscreen
-
-		// setup the projection matrix for regular drawing
-		glMatrixMode(GL_PROJECTION);
-		glLoadIdentity();
-		gluPerspective(60, 256.0 / 192.0, 0.1, 20); 
-		
-		glMatrixMode(GL_MODELVIEW); // use the modelview matrix while drawing
-		
-		glPushMatrix(); // save the state of the current matrix(the modelview matrix)
-			glTranslate3f32(0,0,floattof32(-6));
-			glRotateXi(rotateX); // add X rotation to the modelview matrix
-			glRotateYi(rotateY); // add Y rotation to the modelview matrix
-			
-			glPushMatrix(); // save the state of the modelview matrix while making the first pass
-				// draw the scene for displaying
-				
-				glTranslatef32(floattof32(2.9),floattof32(0),floattof32(0)); // translate the modelview matrix to the drawing location
-				if (clicked = clCone) then
-					glPolyFmt(POLY_ALPHA(31) or POLY_CULL_BACK or POLY_FORMAT_LIGHT0 or POLY_ID(1)) // set a poly ID for outlining
-				else
-					glPolyFmt(POLY_ALPHA(31) or POLY_CULL_BACK or POLY_FORMAT_LIGHT0 or POLY_ID(0)); // set a poly ID for no outlining (same as BG)
-
-				glCallList((@cone_bin)); // draw a green cone from a predefined packed command list
-
-				
-				glTranslatef32(floattof32(-3),floattof32(1.8),floattof32(2)); // translate the modelview matrix to the drawing location
-				if (clicked = clCylinder) then
-					glPolyFmt(POLY_ALPHA(31) or POLY_CULL_BACK or POLY_FORMAT_LIGHT0 or POLY_ID(1)) // set a poly ID for outlining
-				else
-					glPolyFmt(POLY_ALPHA(31) or POLY_CULL_BACK or POLY_FORMAT_LIGHT0 or POLY_ID(0)); // set a poly ID for no outlining (same as BG)
+  // initialize gl
+  glInit();
+
+  //set mode 0, enable BG0 and set it to 3D
+  videoSetMode(MODE_0_3D);
+  
+  lcdMainOnBottom(); // we are going to be touching the 3D display
+  
+  // enable edge outlining, this will be used to show which object is selected
+  glEnable(GL_OUTLINE);
+  
+  //set the first outline color to white
+  glSetOutlineColor(0,RGB15(31,31,31));
+
+  // setup the rear plane
+  glClearColor(0,0,0,0); // set BG to black and clear
+  glClearPolyID(0); // the BG and polygons will have the same ID unless a polygon is highlighted
+  glClearDepth($7FFF);
+  
+  // setup the camera
+  gluLookAt( 0.0, 0.0, 1.0,   //camera possition
+             0.0, 0.0, 0.0,   //look at
+             0.0, 1.0, 0.0);  //up
+  
+  glLight(0, RGB15(31,31,31) , 0, floattov10(-1.0), 0); // setup the light
+  
+  while true do
+  begin
+    // handle key input
+    scanKeys();
+    keys := keysHeld();
+    if ((keys and KEY_UP)) = 0 then rotateX := rotateX +3;
+    if((keys and KEY_DOWN)) = 0 then rotateX := rotateX -3;
+    if((keys and KEY_LEFT)) = 0 then rotateY := rotateY +3;
+    if((keys and KEY_RIGHT)) = 0 then rotateY := rotateY -3;
+
+    // get touchscreen position
+    touchXY := touchReadXY();
+
+    glViewPort(0,0,255,191); // set the viewport to fullscreen
+
+    // setup the projection matrix for regular drawing
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluPerspective(60, 256.0 / 192.0, 0.1, 20); 
+    
+    glMatrixMode(GL_MODELVIEW); // use the modelview matrix while drawing
+    
+    glPushMatrix(); // save the state of the current matrix(the modelview matrix)
+      glTranslate3f32(0,0,floattof32(-6));
+      glRotateXi(rotateX); // add X rotation to the modelview matrix
+      glRotateYi(rotateY); // add Y rotation to the modelview matrix
+      
+      glPushMatrix(); // save the state of the modelview matrix while making the first pass
+        // draw the scene for displaying
+        
+        glTranslatef32(floattof32(2.9),floattof32(0),floattof32(0)); // translate the modelview matrix to the drawing location
+        if (clicked = clCone) then
+          glPolyFmt(POLY_ALPHA(31) or POLY_CULL_BACK or POLY_FORMAT_LIGHT0 or POLY_ID(1)) // set a poly ID for outlining
+        else
+          glPolyFmt(POLY_ALPHA(31) or POLY_CULL_BACK or POLY_FORMAT_LIGHT0 or POLY_ID(0)); // set a poly ID for no outlining (same as BG)
+
+        glCallList((@cone_bin)); // draw a green cone from a predefined packed command list
+
+        
+        glTranslatef32(floattof32(-3),floattof32(1.8),floattof32(2)); // translate the modelview matrix to the drawing location
+        if (clicked = clCylinder) then
+          glPolyFmt(POLY_ALPHA(31) or POLY_CULL_BACK or POLY_FORMAT_LIGHT0 or POLY_ID(1)) // set a poly ID for outlining
+        else
+          glPolyFmt(POLY_ALPHA(31) or POLY_CULL_BACK or POLY_FORMAT_LIGHT0 or POLY_ID(0)); // set a poly ID for no outlining (same as BG)
 
 
         glCallList((@cylinder_bin)); // draw a blue cylinder from a predefined packed command list
         glCallList((@cylinder_bin)); // draw a blue cylinder from a predefined packed command list
 
 
 
 
-				glTranslatef32(floattof32(0.5),floattof32(-2.6),floattof32(-4)); // translate the modelview matrix to the drawing location
-				if(clicked = clSphere) then
-					glPolyFmt(POLY_ALPHA(31) or POLY_CULL_BACK or POLY_FORMAT_LIGHT0 or POLY_ID(1)) // set a poly ID for outlining
-				else
-					glPolyFmt(POLY_ALPHA(31) or POLY_CULL_BACK or POLY_FORMAT_LIGHT0 or POLY_ID(0)); // set a poly ID for no outlining (same as BG)
-
-				glCallList((@sphere_bin)); // draw a red sphere from a predefined packed command list
-
-			glPopMatrix(1); // restores the modelview matrix to where it was just rotated
-			
-			// draw the scene again for picking
-				clicked := clNothing; //reset what was clicked on
-				closeW := $7FFFFFFF; //reset the distance
-
-				//set the viewport to just off-screen, this hides all rendering that will be done during picking
-				glViewport(0,192,0,192);
-				
-				// setup the projection matrix for picking
-				glMatrixMode(GL_PROJECTION);
-				glLoadIdentity();
-				gluPickMatrix((touchXY.px),(191-touchXY.py),4,4,viewport); // render only what is below the cursor
-				gluPerspective(60, 256.0 / 192.0, 0.1, 20); // this must be the same as the original perspective matrix
-				
-				glMatrixMode(GL_MODELVIEW); // switch back to modifying the modelview matrix for drawing
-				
-				glTranslatef32(floattof32(2.9),floattof32(0),floattof32(0)); // translate the modelview matrix to the drawing location
-				startCheck();
-				glCallList((@cone_bin)); // draw a cone from a predefined packed command list
-				endCheck(clCone);
-
-				glTranslatef32(floattof32(-3),floattof32(1.8),floattof32(2)); // translate the modelview matrix to the drawing location
-				startCheck();
-				glCallList((@cylinder_bin)); // draw a cylinder from a predefined packed command list
-				endCheck(clCylinder);
-
-				glTranslatef32(floattof32(0.5),floattof32(-2.6),floattof32(-4)); // translate the modelview matrix to the drawing location
-				startCheck();
-				glCallList((@sphere_bin)); // draw a sphere from a predefined packed command list
-				endCheck(clSphere);
-
-		glPopMatrix(1); // restores the modelview matrix to its original state
-
-		glFlush(0); // wait for everything to be drawn before starting on the next frame
-	end;
+        glTranslatef32(floattof32(0.5),floattof32(-2.6),floattof32(-4)); // translate the modelview matrix to the drawing location
+        if(clicked = clSphere) then
+          glPolyFmt(POLY_ALPHA(31) or POLY_CULL_BACK or POLY_FORMAT_LIGHT0 or POLY_ID(1)) // set a poly ID for outlining
+        else
+          glPolyFmt(POLY_ALPHA(31) or POLY_CULL_BACK or POLY_FORMAT_LIGHT0 or POLY_ID(0)); // set a poly ID for no outlining (same as BG)
+
+        glCallList((@sphere_bin)); // draw a red sphere from a predefined packed command list
+
+      glPopMatrix(1); // restores the modelview matrix to where it was just rotated
+      
+      // draw the scene again for picking
+        clicked := clNothing; //reset what was clicked on
+        closeW := $7FFFFFFF; //reset the distance
+
+        //set the viewport to just off-screen, this hides all rendering that will be done during picking
+        glViewport(0,192,0,192);
+        
+        // setup the projection matrix for picking
+        glMatrixMode(GL_PROJECTION);
+        glLoadIdentity();
+        gluPickMatrix((touchXY.px),(191-touchXY.py),4,4,viewport); // render only what is below the cursor
+        gluPerspective(60, 256.0 / 192.0, 0.1, 20); // this must be the same as the original perspective matrix
+        
+        glMatrixMode(GL_MODELVIEW); // switch back to modifying the modelview matrix for drawing
+        
+        glTranslatef32(floattof32(2.9),floattof32(0),floattof32(0)); // translate the modelview matrix to the drawing location
+        startCheck();
+        glCallList((@cone_bin)); // draw a cone from a predefined packed command list
+        endCheck(clCone);
+
+        glTranslatef32(floattof32(-3),floattof32(1.8),floattof32(2)); // translate the modelview matrix to the drawing location
+        startCheck();
+        glCallList((@cylinder_bin)); // draw a cylinder from a predefined packed command list
+        endCheck(clCylinder);
+
+        glTranslatef32(floattof32(0.5),floattof32(-2.6),floattof32(-4)); // translate the modelview matrix to the drawing location
+        startCheck();
+        glCallList((@sphere_bin)); // draw a sphere from a predefined packed command list
+        endCheck(clSphere);
+
+    glPopMatrix(1); // restores the modelview matrix to its original state
+
+    glFlush(0); // wait for everything to be drawn before starting on the next frame
+   
+    if (keys and KEY_START) <> 0 then break;
+  end;
 
 
 end.
 end.

+ 2 - 0
packages/libndsfpc/examples/graphics/3D/Simple_Quad/SimpleQuad.pp

@@ -86,6 +86,8 @@ begin
     glFlush(0);
     glFlush(0);
 
 
     swiWaitForVBlank();
     swiWaitForVBlank();
+    
+    if (keys and KEY_START) <> 0 then break;
   end;
   end;
 
 
 end.
 end.

+ 2 - 0
packages/libndsfpc/examples/graphics/3D/Simple_Tri/SimpleTri.pp

@@ -85,6 +85,8 @@ begin
     glFlush(0);
     glFlush(0);
 
 
     swiWaitForVBlank();
     swiWaitForVBlank();
+    
+    if (keys and KEY_START) <> 0 then break;
   end;
   end;
 
 
 end.
 end.

+ 16 - 14
packages/libndsfpc/examples/graphics/3D/Textured_Cube/TexturedCube.pp

@@ -206,10 +206,10 @@ begin
 
 
     keys := keysHeld();
     keys := keysHeld();
 
 
-		if((keys and KEY_UP)) <> 0 then rotateX := rotateX +3;
-		if((keys and KEY_DOWN)) <> 0 then rotateX := rotateX -3;
-		if((keys and KEY_LEFT)) <> 0 then rotateY := rotateY +3;
-		if((keys and KEY_RIGHT)) <> 0 then rotateY := rotateY -3;
+    if((keys and KEY_UP)) <> 0 then rotateX := rotateX +3;
+    if((keys and KEY_DOWN)) <> 0 then rotateX := rotateX -3;
+    if((keys and KEY_LEFT)) <> 0 then rotateY := rotateY +3;
+    if((keys and KEY_RIGHT)) <> 0 then rotateY := rotateY -3;
 
 
     if (keysDown() and KEY_A) <> 0 then
     if (keysDown() and KEY_A) <> 0 then
     begin
     begin
@@ -220,21 +220,23 @@ begin
         DisplayEnableNormal();
         DisplayEnableNormal();
     end;
     end;
 
 
-		glBindTexture(0, textureID);
+    glBindTexture(0, textureID);
 
 
-		//draw the obj
-		glBegin(GL_QUAD);
-			for i := 0 to 5 do
-				drawQuad(i);
-		glEnd();
+    //draw the obj
+    glBegin(GL_QUAD);
+      for i := 0 to 5 do
+        drawQuad(i);
+    glEnd();
 
 
-		glPopMatrix(1);
+    glPopMatrix(1);
 
 
-		glFlush(0);
+    glFlush(0);
 
 
-		swiWaitForVBlank();
+    swiWaitForVBlank();
+    
+    if (keys and KEY_START) <> 0 then break;
     
     
     //the display capture enable bit must be set again each frame if you want to continue capturing.
     //the display capture enable bit must be set again each frame if you want to continue capturing.
-    REG_DISPCAPCNT^ := REG_DISPCAPCNT^ or DCAP_ENABLE;		
+    REG_DISPCAPCNT^ := REG_DISPCAPCNT^ or DCAP_ENABLE;    
   end;
   end;
 end.
 end.

+ 7 - 5
packages/libndsfpc/examples/graphics/3D/Textured_Quad/TexturedQuad.pp

@@ -10,7 +10,7 @@ uses
 {$include inc/texture.bin.inc}
 {$include inc/texture.bin.inc}
 
 
 var
 var
-	textureID: integer;
+  textureID: integer;
   rotateX: cfloat = 0.0;
   rotateX: cfloat = 0.0;
   rotateY: cfloat = 0.0;
   rotateY: cfloat = 0.0;
   keys: cuint16;
   keys: cuint16;
@@ -80,10 +80,10 @@ begin
 
 
     keys := keysHeld();
     keys := keysHeld();
 
 
-		if((keys and KEY_UP)) <> 0 then rotateX := rotateX +3;
-		if((keys and KEY_DOWN)) <> 0 then rotateX := rotateX -3;
-		if((keys and KEY_LEFT)) <> 0 then rotateY := rotateY +3;
-		if((keys and KEY_RIGHT)) <> 0 then rotateY := rotateY -3;
+    if((keys and KEY_UP)) <> 0 then rotateX := rotateX +3;
+    if((keys and KEY_DOWN)) <> 0 then rotateX := rotateX -3;
+    if((keys and KEY_LEFT)) <> 0 then rotateY := rotateY +3;
+    if((keys and KEY_RIGHT)) <> 0 then rotateY := rotateY -3;
 
 
     glBindTexture(0, textureID);
     glBindTexture(0, textureID);
 
 
@@ -110,6 +110,8 @@ begin
     glFlush(0);
     glFlush(0);
 
 
     swiWaitForVBlank();
     swiWaitForVBlank();
+    
+    if (keys and KEY_START) <> 0 then break;
   end;
   end;
 
 
 end.
 end.

+ 101 - 99
packages/libndsfpc/examples/graphics/3D/Toon_Shading/ToonShading.pp

@@ -11,115 +11,117 @@ uses
 {$include inc/statue.bin.inc}
 {$include inc/statue.bin.inc}
 
 
 var
 var
-	prev_pen: array [0..1] of cint = ( $7FFFFFFF, $7FFFFFFF );
+  prev_pen: array [0..1] of cint = ( $7FFFFFFF, $7FFFFFFF );
 
 
 
 
 procedure get_pen_delta(var dx, dy: cint);
 procedure get_pen_delta(var dx, dy: cint);
 var
 var
-	keys: cuint32;
+  keys: cuint32;
   touchXY: touchPosition;
   touchXY: touchPosition;
 begin
 begin
-	keys := keysHeld();
-
-	if( keys and KEY_TOUCH ) <> 0 then
-	begin
-		touchXY := touchReadXY();
-
-		if ( prev_pen[0] <> $7FFFFFFF ) then
-		begin
-			dx := (prev_pen[0] - touchXY.rawx);
-			dy := (prev_pen[1] - touchXY.rawy);
-		end;
-
-		prev_pen[0] := touchXY.rawx;
-		prev_pen[1] := touchXY.rawy;
-	end else
-	begin
-		prev_pen[0] := $7FFFFFFF;
+  keys := keysHeld();
+
+  if( keys and KEY_TOUCH ) <> 0 then
+  begin
+    touchXY := touchReadXY();
+
+    if ( prev_pen[0] <> $7FFFFFFF ) then
+    begin
+      dx := (prev_pen[0] - touchXY.rawx);
+      dy := (prev_pen[1] - touchXY.rawy);
+    end;
+
+    prev_pen[0] := touchXY.rawx;
+    prev_pen[1] := touchXY.rawy;
+  end else
+  begin
+    prev_pen[0] := $7FFFFFFF;
     prev_pen[1] := $7FFFFFFF;
     prev_pen[1] := $7FFFFFFF;
-		dx := 0;
-		dy := 0;
-	end;
+    dx := 0;
+    dy := 0;
+  end;
 end;
 end;
 
 
 var
 var
-	rotateX: integer = 0;
-	rotateY: integer = 0;
-	keys: cuint32;
-	pen_delta: array [0..1] of cint;
+  rotateX: integer = 0;
+  rotateY: integer = 0;
+  keys: cuint32;
+  pen_delta: array [0..1] of cint;
 
 
 begin
 begin
-	//set mode 0, enable BG0 and set it to 3D
-	videoSetMode(MODE_0_3D);
-
-	// initialize gl
-	glInit();
-	
-	// enable antialiasing
-	glEnable(GL_ANTIALIAS);
-	
-	// setup the rear plane
-	glClearColor(0,0,0,31); // BG must be opaque for AA to work
-	glClearPolyID(63); // BG must have a unique polygon ID for AA to work
-	glClearDepth($7FFF);
-
-	//this should work the same as the normal gl call
-	glViewport(0,0,255,191);
-
-	//toon-table entry 0 is for completely unlit pixels, going up to entry 31 for completely lit
-	//We block-fill it in two halves, we get cartoony 2-tone lighting
-	glSetToonTableRange( 0, 15, RGB15(8,8,8) );
-	glSetToonTableRange( 16, 31, RGB15(24,24,24) );
-	
-	//any floating point gl call is being converted to fixed prior to being implemented
-	glMatrixMode(GL_PROJECTION);
-	glLoadIdentity();
-	gluPerspective(70, 256.0 / 192.0, 0.1, 40);
-	
-	//NB: When toon-shading, the hw ignores lights 2 and 3
-	//Also note that the hw uses the RED component of the lit vertex to index the toon-table
-	glLight(0, RGB15(16,16,16) , 0,		floattov10(-1.0),		0);
-	glLight(1, RGB15(16,16,16),   floattov10(-1.0),	0,		0);
-	
-	gluLookAt(	0.0, 0.0, -3.0,		//camera possition 
-				0.0, 0.0, 0.0,		//look at
-				0.0, 1.0, 0.0);		//up
-	
-	while true do
-	begin
-
-		glMatrixMode(GL_MODELVIEW);
-		glPushMatrix();
-			glRotateXi(rotateX);
-			glRotateYi(rotateY);
-
-
-			glMaterialf(GL_AMBIENT, RGB15(8,8,8));
-			glMaterialf(GL_DIFFUSE, RGB15(24,24,24));
-			glMaterialf(GL_SPECULAR, RGB15(0,0,0));
-			glMaterialf(GL_EMISSION, RGB15(0,0,0));
-
-			glPolyFmt(POLY_ALPHA(31) or POLY_CULL_BACK or POLY_FORMAT_LIGHT0 or POLY_FORMAT_LIGHT1 or POLY_TOON_HIGHLIGHT);
-
-
-			scanKeys();
-			keys := keysHeld();
-
-			if( keys and KEY_UP ) <> 0 then rotateX := rotateX +1;
-			if( keys and KEY_DOWN ) <> 0 then rotateX := rotateX -1;
-			if( keys and KEY_LEFT ) <> 0 then rotateY := rotateY +1;
-			if( keys and KEY_RIGHT ) <> 0 then rotateY := rotateY -1;
-
-			get_pen_delta( pen_delta[0], pen_delta[1] );
-			rotateY := rotateY - pen_delta[0];
-			rotateX := rotateY - pen_delta[1];
-
-
-			glCallList(@statue_bin);
-			glPopMatrix(1);
-
-		glFlush(0);
-
-		swiWaitForVBlank();
-	end;
+  //set mode 0, enable BG0 and set it to 3D
+  videoSetMode(MODE_0_3D);
+
+  // initialize gl
+  glInit();
+  
+  // enable antialiasing
+  glEnable(GL_ANTIALIAS);
+  
+  // setup the rear plane
+  glClearColor(0,0,0,31); // BG must be opaque for AA to work
+  glClearPolyID(63); // BG must have a unique polygon ID for AA to work
+  glClearDepth($7FFF);
+
+  //this should work the same as the normal gl call
+  glViewport(0,0,255,191);
+
+  //toon-table entry 0 is for completely unlit pixels, going up to entry 31 for completely lit
+  //We block-fill it in two halves, we get cartoony 2-tone lighting
+  glSetToonTableRange( 0, 15, RGB15(8,8,8) );
+  glSetToonTableRange( 16, 31, RGB15(24,24,24) );
+  
+  //any floating point gl call is being converted to fixed prior to being implemented
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  gluPerspective(70, 256.0 / 192.0, 0.1, 40);
+  
+  //NB: When toon-shading, the hw ignores lights 2 and 3
+  //Also note that the hw uses the RED component of the lit vertex to index the toon-table
+  glLight(0, RGB15(16,16,16) , 0,   floattov10(-1.0),   0);
+  glLight(1, RGB15(16,16,16),   floattov10(-1.0), 0,    0);
+  
+  gluLookAt(  0.0, 0.0, -3.0,   //camera possition 
+        0.0, 0.0, 0.0,    //look at
+        0.0, 1.0, 0.0);   //up
+  
+  while true do
+  begin
+
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+      glRotateXi(rotateX);
+      glRotateYi(rotateY);
+
+
+      glMaterialf(GL_AMBIENT, RGB15(8,8,8));
+      glMaterialf(GL_DIFFUSE, RGB15(24,24,24));
+      glMaterialf(GL_SPECULAR, RGB15(0,0,0));
+      glMaterialf(GL_EMISSION, RGB15(0,0,0));
+
+      glPolyFmt(POLY_ALPHA(31) or POLY_CULL_BACK or POLY_FORMAT_LIGHT0 or POLY_FORMAT_LIGHT1 or POLY_TOON_HIGHLIGHT);
+
+
+      scanKeys();
+      keys := keysHeld();
+
+      if( keys and KEY_UP ) <> 0 then rotateX := rotateX +1;
+      if( keys and KEY_DOWN ) <> 0 then rotateX := rotateX -1;
+      if( keys and KEY_LEFT ) <> 0 then rotateY := rotateY +1;
+      if( keys and KEY_RIGHT ) <> 0 then rotateY := rotateY -1;
+
+      get_pen_delta( pen_delta[0], pen_delta[1] );
+      rotateY := rotateY - pen_delta[0];
+      rotateX := rotateY - pen_delta[1];
+
+
+      glCallList(@statue_bin);
+      glPopMatrix(1);
+
+    glFlush(0);
+
+    swiWaitForVBlank();
+   
+    if (keys and KEY_START) <> 0 then break;
+  end;
 end.
 end.

+ 7 - 1
packages/libndsfpc/examples/graphics/3D/nehe/lesson01/lesson01.pp

@@ -19,6 +19,9 @@ begin
 	result := true;
 	result := true;
 end;
 end;
 
 
+var
+  keys: integer;
+
 begin	
 begin	
 	// Setup the Main screen for 3D 
 	// Setup the Main screen for 3D 
 	videoSetMode(MODE_0_3D);
 	videoSetMode(MODE_0_3D);
@@ -65,7 +68,10 @@ begin
 		swiWaitForVBlank();
 		swiWaitForVBlank();
 
 
 		// flush to screen	
 		// flush to screen	
-		glFlush(0);	
+		glFlush(0);
+    scanKeys();
+		keys := keysDown();
+		if (keys and KEY_START) <> 0 then break;
 	end;
 	end;
 	
 	
 end.
 end.

+ 65 - 59
packages/libndsfpc/examples/graphics/3D/nehe/lesson02/lesson02.pp

@@ -1,6 +1,6 @@
 (****************************************
 (****************************************
- * 		NDS NeHe Lesson 02    			*
- * 		Author: Dovoto					*
+ *    NDS NeHe Lesson 02          *
+ *    Author: Dovoto          *
  ****************************************)
  ****************************************)
 
 
 program Lesson02;
 program Lesson02;
@@ -12,72 +12,78 @@ uses
 
 
 function DrawGLScene(): boolean;
 function DrawGLScene(): boolean;
 begin
 begin
-	glLoadIdentity();									// Reset The Current Modelview Matrix
+  glLoadIdentity();                 // Reset The Current Modelview Matrix
 
 
-	glTranslatef(-1.5,0.0,-6.0);						// Move Left 1.5 Units And Into The Screen 6.0
-	glBegin(GL_TRIANGLES);								// Drawing Using Triangles
-		glVertex3f( 0.0, 1.0, 0.0);					// Top
-		glVertex3f(-1.0,-1.0, 0.0);					// Bottom Left
-		glVertex3f( 1.0,-1.0, 0.0);					// Bottom Right
-	glEnd();											// Finished Drawing The Triangle
+  glTranslatef(-1.5,0.0,-6.0);            // Move Left 1.5 Units And Into The Screen 6.0
+  glBegin(GL_TRIANGLES);                // Drawing Using Triangles
+    glVertex3f( 0.0, 1.0, 0.0);         // Top
+    glVertex3f(-1.0,-1.0, 0.0);         // Bottom Left
+    glVertex3f( 1.0,-1.0, 0.0);         // Bottom Right
+  glEnd();                      // Finished Drawing The Triangle
 
 
-	glTranslatef(3.0,0.0,0.0);						// Move Right 3 Units
-	glBegin(GL_QUADS);									// Draw A Quad
-		glVertex3f(-1.0, 1.0, 0.0);					// Top Left
-		glVertex3f( 1.0, 1.0, 0.0);					// Top Right
-		glVertex3f( 1.0,-1.0, 0.0);					// Bottom Right
-		glVertex3f(-1.0,-1.0, 0.0);					// Bottom Left
-	glEnd();											// Done Drawing The Quad
+  glTranslatef(3.0,0.0,0.0);            // Move Right 3 Units
+  glBegin(GL_QUADS);                  // Draw A Quad
+    glVertex3f(-1.0, 1.0, 0.0);         // Top Left
+    glVertex3f( 1.0, 1.0, 0.0);         // Top Right
+    glVertex3f( 1.0,-1.0, 0.0);         // Bottom Right
+    glVertex3f(-1.0,-1.0, 0.0);         // Bottom Left
+  glEnd();                      // Done Drawing The Quad
 
 
-	result := true;										// Keep Going
+  result := true;                   // Keep Going
 end;
 end;
 
 
-begin	
+var
+  keys: integer;
 
 
-	// Setup the Main screen for 3D 
-	videoSetMode(MODE_0_3D);
+begin 
 
 
-	// initialize the geometry engine
-	glInit();
-	
-	// enable antialiasing
-	glEnable(GL_ANTIALIAS);
+  // Setup the Main screen for 3D 
+  videoSetMode(MODE_0_3D);
 
 
-	// setup the rear plane
-	glClearColor(0,0,0,31); // BG must be opaque for AA to work
-	glClearPolyID(63); // BG must have a unique polygon ID for AA to work
-	glClearDepth($7FFF);
-	
-	// Set our viewport to be the same size as the screen
-	glViewPort(0,0,255,191);
-	
-	glMatrixMode(GL_PROJECTION);
-	glLoadIdentity();
-	gluPerspective(70, 256.0 / 192.0, 0.1, 100);
-	// Set the color of the vertices
-	glColor3f(1, 1, 1);
-	
+  // initialize the geometry engine
+  glInit();
+  
+  // enable antialiasing
+  glEnable(GL_ANTIALIAS);
+
+  // setup the rear plane
+  glClearColor(0,0,0,31); // BG must be opaque for AA to work
+  glClearPolyID(63); // BG must have a unique polygon ID for AA to work
+  glClearDepth($7FFF);
+  
+  // Set our viewport to be the same size as the screen
+  glViewPort(0,0,255,191);
+  
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  gluPerspective(70, 256.0 / 192.0, 0.1, 100);
+  // Set the color of the vertices
+  glColor3f(1, 1, 1);
+  
   while true do
   while true do
-	begin
-		//ds specific, several attributes can be set here	
-		glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE);
-		
-		// Set the current matrix to be the model matrix
-		glMatrixMode(GL_MODELVIEW);
-		
-		//Push our original Matrix onto the stack (save state)
-		glPushMatrix();	
+  begin
+    //ds specific, several attributes can be set here 
+    glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE);
+    
+    // Set the current matrix to be the model matrix
+    glMatrixMode(GL_MODELVIEW);
+    
+    //Push our original Matrix onto the stack (save state)
+    glPushMatrix(); 
  
  
-		DrawGLScene();
-		
-		// Pop our Matrix from the stack (restore state)
-		glPopMatrix(1);
+    DrawGLScene();
+    
+    // Pop our Matrix from the stack (restore state)
+    glPopMatrix(1);
 
 
-		//a handy little built in function to wait for a screen refresh
-		swiWaitForVBlank();
-		
-		// flush to screen	
-		glFlush(0);
-	end;
-	
+    //a handy little built in function to wait for a screen refresh
+    swiWaitForVBlank();
+    
+    // flush to screen  
+    glFlush(0);
+    scanKeys();
+    keys := keysDown();
+    if (keys and KEY_START) <> 0 then break;
+  end;
+  
 end.
 end.

+ 51 - 48
packages/libndsfpc/examples/graphics/3D/nehe/lesson03/lesson03.pp

@@ -1,6 +1,6 @@
 (****************************************
 (****************************************
- * 		NDS NeHe Lesson 03    			*
- * 		Author: Dovoto					*
+ *    NDS NeHe Lesson 03          *
+ *    Author: Dovoto          *
  ****************************************)
  ****************************************)
 
 
 program Lesson03;
 program Lesson03;
@@ -12,28 +12,29 @@ uses
 
 
 function DrawGLScene(): boolean;
 function DrawGLScene(): boolean;
 begin
 begin
-	glLoadIdentity();									// Reset The Current Modelview Matrix
-	glTranslatef(-1.5,0.0,-6.0);						// Move Left 1.5 Units And Into The Screen 6.0
-	glBegin(GL_TRIANGLES);								// Drawing Using Triangles
-		glColor3f(1.0,0.0,0.0);						// Set The Color To Red
-		glVertex3f( 0.0, 1.0, 0.0);					// Top
-		glColor3f(0.0,1.0,0.0);						// Set The Color To Green
-		glVertex3f(-1.0,-1.0, 0.0);					// Bottom Left
-		glColor3f(0.0,0.0,1.0);						// Set The Color To Blue
-		glVertex3f( 1.0,-1.0, 0.0);					// Bottom Right
-	glEnd();											// Finished Drawing The Triangle
-	glTranslatef(3.0,0.0,0.0);						// Move Right 3 Units
-	glColor3f(0.5,0.5,1.0);							// Set The Color To Blue One Time Only
-	glBegin(GL_QUADS);									// Draw A Quad
-		glVertex3f(-1.0, 1.0, 0.0);					// Top Left
-		glVertex3f( 1.0, 1.0, 0.0);					// Top Right
-		glVertex3f( 1.0,-1.0, 0.0);					// Bottom Right
-		glVertex3f(-1.0,-1.0, 0.0);					// Bottom Left
-	glEnd();											// Done Drawing The Quad
-	result := true;										// Keep Going
+  glLoadIdentity();                 // Reset The Current Modelview Matrix
+  glTranslatef(-1.5,0.0,-6.0);            // Move Left 1.5 Units And Into The Screen 6.0
+  glBegin(GL_TRIANGLES);                // Drawing Using Triangles
+    glColor3f(1.0,0.0,0.0);           // Set The Color To Red
+    glVertex3f( 0.0, 1.0, 0.0);         // Top
+    glColor3f(0.0,1.0,0.0);           // Set The Color To Green
+    glVertex3f(-1.0,-1.0, 0.0);         // Bottom Left
+    glColor3f(0.0,0.0,1.0);           // Set The Color To Blue
+    glVertex3f( 1.0,-1.0, 0.0);         // Bottom Right
+  glEnd();                      // Finished Drawing The Triangle
+  glTranslatef(3.0,0.0,0.0);            // Move Right 3 Units
+  glColor3f(0.5,0.5,1.0);             // Set The Color To Blue One Time Only
+  glBegin(GL_QUADS);                  // Draw A Quad
+    glVertex3f(-1.0, 1.0, 0.0);         // Top Left
+    glVertex3f( 1.0, 1.0, 0.0);         // Top Right
+    glVertex3f( 1.0,-1.0, 0.0);         // Bottom Right
+    glVertex3f(-1.0,-1.0, 0.0);         // Bottom Left
+  glEnd();                      // Done Drawing The Quad
+  result := true;                   // Keep Going
 end;
 end;
 
 
-
+var
+  keys: integer;
 begin
 begin
   // Setup the Main screen for 3D 
   // Setup the Main screen for 3D 
   videoSetMode(MODE_0_3D);
   videoSetMode(MODE_0_3D);
@@ -43,38 +44,40 @@ begin
   // enable antialiasing
   // enable antialiasing
   glEnable(GL_ANTIALIAS);
   glEnable(GL_ANTIALIAS);
   
   
-	// setup the rear plane
-	glClearColor(0,0,0,31); // BG must be opaque for AA to work
-	glClearPolyID(63); // BG must have a unique polygon ID for AA to work
+  // setup the rear plane
+  glClearColor(0,0,0,31); // BG must be opaque for AA to work
+  glClearPolyID(63); // BG must have a unique polygon ID for AA to work
   glClearDepth($7FFF);
   glClearDepth($7FFF);
    
    
-	// Set our viewport to be the same size as the screen
-	glViewPort(0,0,255,191);
-	
+  // Set our viewport to be the same size as the screen
+  glViewPort(0,0,255,191);
+  
 
 
   glMatrixMode(GL_PROJECTION);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glLoadIdentity();
-	gluPerspective(70, 256.0 / 192.0, 0.1, 100);
+  gluPerspective(70, 256.0 / 192.0, 0.1, 100);
 
 
-	//ds specific, several attributes can be set here	
-	glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE);
-		
-	// Set the current matrix to be the model matrix
-	glMatrixMode(GL_MODELVIEW);
-	
-  glColor3f(1, 1, 1);									// Set the color..not in nehe source...ds gl default will be black
-	
-	while true do 
-	begin
+  //ds specific, several attributes can be set here 
+  glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE);
+    
+  // Set the current matrix to be the model matrix
+  glMatrixMode(GL_MODELVIEW);
+  
+  glColor3f(1, 1, 1);                 // Set the color..not in nehe source...ds gl default will be black
+  
+  while true do 
+  begin
 
 
-		DrawGLScene();
-		
-		// flush to screen	
-		glFlush(0);
+    DrawGLScene();
+    
+    // flush to screen  
+    glFlush(0);
 
 
-		//a handy little built in function to wait for a screen refresh
-		swiWaitForVBlank();
-		
-	end;
-	
+    //a handy little built in function to wait for a screen refresh
+    swiWaitForVBlank();
+    scanKeys();
+    keys := keysDown();
+    if (keys and KEY_START) <> 0 then break;    
+  end;
+  
 end.
 end.

+ 62 - 58
packages/libndsfpc/examples/graphics/3D/nehe/lesson04/lesson04.pp

@@ -1,6 +1,6 @@
 (****************************************
 (****************************************
- * 		NDS NeHe Lesson 04    			*
- * 		Author: Dovoto					*
+ *    NDS NeHe Lesson 04          *
+ *    Author: Dovoto          *
  ****************************************)
  ****************************************)
 
 
 program Lesson04;
 program Lesson04;
@@ -17,75 +17,79 @@ var
 
 
 function DrawGLScene(): boolean;
 function DrawGLScene(): boolean;
 begin
 begin
-	glLoadIdentity();									// Reset The Current Modelview Matrix
-	glTranslatef(-1.5,0.0,-6.0);						// Move Left 1.5 Units And Into The Screen 6.0
-	glRotatef(rtri,0.0,1.0,0.0);						// Rotate The Triangle On The Y axis ( NEW )
-	glColor3f(1, 1, 1);									// set the vertex color
-	glBegin(GL_TRIANGLES);								// Drawing Using Triangles
-		glColor3f(1.0,0.0,0.0);						// Set The Color To Red
-		glVertex3f( 0.0, 1.0, 0.0);					// Top
-		glColor3f(0.0,1.0,0.0);						// Set The Color To Green
-		glVertex3f(-1.0,-1.0, 0.0);					// Bottom Left
-		glColor3f(0.0,0.0,1.0);						// Set The Color To Blue
-		glVertex3f( 1.0,-1.0, 0.0);					// Bottom Right
-	glEnd();											// Finished Drawing The Triangle
-	glLoadIdentity();									// Reset The Current Modelview Matrix
-	glTranslatef(1.5,0.0,-6.0);						// Move Right 3 Units
-	glRotatef(rquad,1.0,0.0,0.0);					// Rotate The Quad On The X axis ( NEW )
-	glColor3f(0.5,0.5,1.0);							// Set The Color To Blue One Time Only
-	glBegin(GL_QUADS);									// Draw A Quad
-		glVertex3f(-1.0, 1.0, 0.0);					// Top Left
-		glVertex3f( 1.0, 1.0, 0.0);					// Top Right
-		glVertex3f( 1.0,-1.0, 0.0);					// Bottom Right
-		glVertex3f(-1.0,-1.0, 0.0);					// Bottom Left
-	glEnd();											// Done Drawing The Quad
-	rtri := rtri + 0.9;											// Increase The Rotation Variable For The Triangle ( NEW )
-	rquad := rquad - 0.75;										// Decrease The Rotation Variable For The Quad ( NEW )
-  result := true;										// Keep Going
+  glLoadIdentity();                 // Reset The Current Modelview Matrix
+  glTranslatef(-1.5,0.0,-6.0);            // Move Left 1.5 Units And Into The Screen 6.0
+  glRotatef(rtri,0.0,1.0,0.0);            // Rotate The Triangle On The Y axis ( NEW )
+  glColor3f(1, 1, 1);                 // set the vertex color
+  glBegin(GL_TRIANGLES);                // Drawing Using Triangles
+    glColor3f(1.0,0.0,0.0);           // Set The Color To Red
+    glVertex3f( 0.0, 1.0, 0.0);         // Top
+    glColor3f(0.0,1.0,0.0);           // Set The Color To Green
+    glVertex3f(-1.0,-1.0, 0.0);         // Bottom Left
+    glColor3f(0.0,0.0,1.0);           // Set The Color To Blue
+    glVertex3f( 1.0,-1.0, 0.0);         // Bottom Right
+  glEnd();                      // Finished Drawing The Triangle
+  glLoadIdentity();                 // Reset The Current Modelview Matrix
+  glTranslatef(1.5,0.0,-6.0);           // Move Right 3 Units
+  glRotatef(rquad,1.0,0.0,0.0);         // Rotate The Quad On The X axis ( NEW )
+  glColor3f(0.5,0.5,1.0);             // Set The Color To Blue One Time Only
+  glBegin(GL_QUADS);                  // Draw A Quad
+    glVertex3f(-1.0, 1.0, 0.0);         // Top Left
+    glVertex3f( 1.0, 1.0, 0.0);         // Top Right
+    glVertex3f( 1.0,-1.0, 0.0);         // Bottom Right
+    glVertex3f(-1.0,-1.0, 0.0);         // Bottom Left
+  glEnd();                      // Done Drawing The Quad
+  rtri := rtri + 0.9;                     // Increase The Rotation Variable For The Triangle ( NEW )
+  rquad := rquad - 0.75;                    // Decrease The Rotation Variable For The Quad ( NEW )
+  result := true;                   // Keep Going
 end;
 end;
 
 
-
+var
+  keys: integer;
 
 
 begin
 begin
-	// Setup the Main screen for 3D 
-	videoSetMode(MODE_0_3D);
-	
-	// initialize the geometry engine
-	glInit();
-	
-	// enable antialiasing
-	glEnable(GL_ANTIALIAS);
+  // Setup the Main screen for 3D 
+  videoSetMode(MODE_0_3D);
+  
+  // initialize the geometry engine
+  glInit();
+  
+  // enable antialiasing
+  glEnable(GL_ANTIALIAS);
 
 
-	// setup the rear plane
-	glClearColor(0,0,0,31); // BG must be opaque for AA to work
-	glClearPolyID(63); // BG must have a unique polygon ID for AA to work
-	glClearDepth($7FFF);
+  // setup the rear plane
+  glClearColor(0,0,0,31); // BG must be opaque for AA to work
+  glClearPolyID(63); // BG must have a unique polygon ID for AA to work
+  glClearDepth($7FFF);
 
 
-	// Set our viewport to be the same size as the screen
-	glViewPort(0,0,255,191);
+  // Set our viewport to be the same size as the screen
+  glViewPort(0,0,255,191);
 
 
-	
+  
 
 
   glMatrixMode(GL_PROJECTION);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glLoadIdentity();
   gluPerspective(70, 256.0 / 192.0, 0.1, 100);
   gluPerspective(70, 256.0 / 192.0, 0.1, 100);
 
 
 
 
-	//ds specific, several attributes can be set here	
-	glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE);
-	
+  //ds specific, several attributes can be set here 
+  glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE);
+  
   // Set the current matrix to be the model matrix
   // Set the current matrix to be the model matrix
-	glMatrixMode(GL_MODELVIEW);	
-	
+  glMatrixMode(GL_MODELVIEW); 
+  
   while true do
   while true do
-	begin
-		// draw the scene
-		DrawGLScene();
-		
-		// flush to screen	
-		glFlush(0);
-		
-		// wait for the screen to refresh
-		swiWaitForVBlank();
-	end;
+  begin
+    // draw the scene
+    DrawGLScene();
+    
+    // flush to screen  
+    glFlush(0);
+    
+    // wait for the screen to refresh
+    swiWaitForVBlank();
+    scanKeys();
+    keys := keysDown();
+    if (keys and KEY_START) <> 0 then break;
+  end;
 end.
 end.

+ 112 - 107
packages/libndsfpc/examples/graphics/3D/nehe/lesson05/lesson05.pp

@@ -1,6 +1,6 @@
 (****************************************
 (****************************************
- * 		NDS NeHe Lesson 05    			*
- * 		Author: Dovoto					*
+ *    NDS NeHe Lesson 05          *
+ *    Author: Dovoto          *
  ****************************************)
  ****************************************)
 
 
 program Lesson05;
 program Lesson05;
@@ -17,119 +17,124 @@ var
 
 
 function DrawGLScene(): boolean;
 function DrawGLScene(): boolean;
 begin
 begin
-	glLoadIdentity();									// Reset The Current Modelview Matrix
-	glTranslatef(-1.5,0.0,-6.0);						// Move Left 1.5 Units And Into The Screen 6.0
-	glRotatef(rtri,0.0,1.0,0.0);						// Rotate The Triangle On The Y axis ( NEW )
-	glBegin(GL_TRIANGLES);								// Start Drawing A Triangle
-		glColor3f(1.0,0.0,0.0);						// Red
-		glVertex3f( 0.0, 1.0, 0.0);					// Top Of Triangle (Front)
-		glColor3f(0.0,1.0,0.0);						// Green
-		glVertex3f(-1.0,-1.0, 1.0);					// Left Of Triangle (Front)
-		glColor3f(0.0,0.0,1.0);						// Blue
-		glVertex3f( 1.0,-1.0, 1.0);					// Right Of Triangle (Front)
-		glColor3f(1.0,0.0,0.0);						// Red
-		glVertex3f( 0.0, 1.0, 0.0);					// Top Of Triangle (Right)
-		glColor3f(0.0,0.0,1.0);						// Blue
-		glVertex3f( 1.0,-1.0, 1.0);					// Left Of Triangle (Right)
-		glColor3f(0.0,1.0,0.0);						// Green
-		glVertex3f( 1.0,-1.0, -1.0);					// Right Of Triangle (Right)
-		glColor3f(1.0,0.0,0.0);						// Red
-		glVertex3f( 0.0, 1.0, 0.0);					// Top Of Triangle (Back)
-		glColor3f(0.0,1.0,0.0);						// Green
-		glVertex3f( 1.0,-1.0, -1.0);					// Left Of Triangle (Back)
-		glColor3f(0.0,0.0,1.0);						// Blue
-		glVertex3f(-1.0,-1.0, -1.0);					// Right Of Triangle (Back)
-		glColor3f(1.0,0.0,0.0);						// Red
-		glVertex3f( 0.0, 1.0, 0.0);					// Top Of Triangle (Left)
-		glColor3f(0.0,0.0,1.0);						// Blue
-		glVertex3f(-1.0,-1.0,-1.0);					// Left Of Triangle (Left)
-		glColor3f(0.0,1.0,0.0);						// Green
-		glVertex3f(-1.0,-1.0, 1.0);					// Right Of Triangle (Left)
-	glEnd();											// Done Drawing The Pyramid
+  glLoadIdentity();                 // Reset The Current Modelview Matrix
+  glTranslatef(-1.5,0.0,-6.0);            // Move Left 1.5 Units And Into The Screen 6.0
+  glRotatef(rtri,0.0,1.0,0.0);            // Rotate The Triangle On The Y axis ( NEW )
+  glBegin(GL_TRIANGLES);                // Start Drawing A Triangle
+    glColor3f(1.0,0.0,0.0);           // Red
+    glVertex3f( 0.0, 1.0, 0.0);         // Top Of Triangle (Front)
+    glColor3f(0.0,1.0,0.0);           // Green
+    glVertex3f(-1.0,-1.0, 1.0);         // Left Of Triangle (Front)
+    glColor3f(0.0,0.0,1.0);           // Blue
+    glVertex3f( 1.0,-1.0, 1.0);         // Right Of Triangle (Front)
+    glColor3f(1.0,0.0,0.0);           // Red
+    glVertex3f( 0.0, 1.0, 0.0);         // Top Of Triangle (Right)
+    glColor3f(0.0,0.0,1.0);           // Blue
+    glVertex3f( 1.0,-1.0, 1.0);         // Left Of Triangle (Right)
+    glColor3f(0.0,1.0,0.0);           // Green
+    glVertex3f( 1.0,-1.0, -1.0);          // Right Of Triangle (Right)
+    glColor3f(1.0,0.0,0.0);           // Red
+    glVertex3f( 0.0, 1.0, 0.0);         // Top Of Triangle (Back)
+    glColor3f(0.0,1.0,0.0);           // Green
+    glVertex3f( 1.0,-1.0, -1.0);          // Left Of Triangle (Back)
+    glColor3f(0.0,0.0,1.0);           // Blue
+    glVertex3f(-1.0,-1.0, -1.0);          // Right Of Triangle (Back)
+    glColor3f(1.0,0.0,0.0);           // Red
+    glVertex3f( 0.0, 1.0, 0.0);         // Top Of Triangle (Left)
+    glColor3f(0.0,0.0,1.0);           // Blue
+    glVertex3f(-1.0,-1.0,-1.0);         // Left Of Triangle (Left)
+    glColor3f(0.0,1.0,0.0);           // Green
+    glVertex3f(-1.0,-1.0, 1.0);         // Right Of Triangle (Left)
+  glEnd();                      // Done Drawing The Pyramid
 
 
-	glLoadIdentity();									// Reset The Current Modelview Matrix
-	glTranslatef(1.5,0.0,-7.0);						// Move Right 1.5 Units And Into The Screen 7.0
-	glRotatef(rquad,1.0,1.0,1.0);					// Rotate The Quad On The X axis ( NEW )
-	glBegin(GL_QUADS);									// Draw A Quad
-		glColor3f(0.0,1.0,0.0);						// Set The Color To Green
-		glVertex3f( 1.0, 1.0,-1.0);					// Top Right Of The Quad (Top)
-		glVertex3f(-1.0, 1.0,-1.0);					// Top Left Of The Quad (Top)
-		glVertex3f(-1.0, 1.0, 1.0);					// Bottom Left Of The Quad (Top)
-		glVertex3f( 1.0, 1.0, 1.0);					// Bottom Right Of The Quad (Top)
-		glColor3f(1.0,0.5,0.0); 					// Set The Color To Orange
-		glVertex3f( 1.0,-1.0, 1.0);					// Top Right Of The Quad (Bottom)
-		glVertex3f(-1.0,-1.0, 1.0);					// Top Left Of The Quad (Bottom)
-		glVertex3f(-1.0,-1.0,-1.0);					// Bottom Left Of The Quad (Bottom)
-		glVertex3f( 1.0,-1.0,-1.0);					// Bottom Right Of The Quad (Bottom)
-		glColor3f(1.0,0.0,0.0);						// Set The Color To Red
-		glVertex3f( 1.0, 1.0, 1.0);					// Top Right Of The Quad (Front)
-		glVertex3f(-1.0, 1.0, 1.0);					// Top Left Of The Quad (Front)
-		glVertex3f(-1.0,-1.0, 1.0);					// Bottom Left Of The Quad (Front)
-		glVertex3f( 1.0,-1.0, 1.0);					// Bottom Right Of The Quad (Front)
-		glColor3f(1.0,1.0,0.0);						// Set The Color To Yellow
-		glVertex3f( 1.0,-1.0,-1.0);					// Top Right Of The Quad (Back)
-		glVertex3f(-1.0,-1.0,-1.0);					// Top Left Of The Quad (Back)
-		glVertex3f(-1.0, 1.0,-1.0);					// Bottom Left Of The Quad (Back)
-		glVertex3f( 1.0, 1.0,-1.0);					// Bottom Right Of The Quad (Back)
-		glColor3f(0.0,0.0,1.0);						// Set The Color To Blue
-		glVertex3f(-1.0, 1.0, 1.0);					// Top Right Of The Quad (Left)
-		glVertex3f(-1.0, 1.0,-1.0);					// Top Left Of The Quad (Left)
-		glVertex3f(-1.0,-1.0,-1.0);					// Bottom Left Of The Quad (Left)
-		glVertex3f(-1.0,-1.0, 1.0);					// Bottom Right Of The Quad (Left)
-		glColor3f(1.0,0.0,1.0);						// Set The Color To Violet
-		glVertex3f( 1.0, 1.0,-1.0);					// Top Right Of The Quad (Right)
-		glVertex3f( 1.0, 1.0, 1.0);					// Top Left Of The Quad (Right)
-		glVertex3f( 1.0,-1.0, 1.0);					// Bottom Left Of The Quad (Right)
-		glVertex3f( 1.0,-1.0,-1.0);					// Bottom Right Of The Quad (Right)
-	glEnd();											// Done Drawing The Quad
+  glLoadIdentity();                 // Reset The Current Modelview Matrix
+  glTranslatef(1.5,0.0,-7.0);           // Move Right 1.5 Units And Into The Screen 7.0
+  glRotatef(rquad,1.0,1.0,1.0);         // Rotate The Quad On The X axis ( NEW )
+  glBegin(GL_QUADS);                  // Draw A Quad
+    glColor3f(0.0,1.0,0.0);           // Set The Color To Green
+    glVertex3f( 1.0, 1.0,-1.0);         // Top Right Of The Quad (Top)
+    glVertex3f(-1.0, 1.0,-1.0);         // Top Left Of The Quad (Top)
+    glVertex3f(-1.0, 1.0, 1.0);         // Bottom Left Of The Quad (Top)
+    glVertex3f( 1.0, 1.0, 1.0);         // Bottom Right Of The Quad (Top)
+    glColor3f(1.0,0.5,0.0);           // Set The Color To Orange
+    glVertex3f( 1.0,-1.0, 1.0);         // Top Right Of The Quad (Bottom)
+    glVertex3f(-1.0,-1.0, 1.0);         // Top Left Of The Quad (Bottom)
+    glVertex3f(-1.0,-1.0,-1.0);         // Bottom Left Of The Quad (Bottom)
+    glVertex3f( 1.0,-1.0,-1.0);         // Bottom Right Of The Quad (Bottom)
+    glColor3f(1.0,0.0,0.0);           // Set The Color To Red
+    glVertex3f( 1.0, 1.0, 1.0);         // Top Right Of The Quad (Front)
+    glVertex3f(-1.0, 1.0, 1.0);         // Top Left Of The Quad (Front)
+    glVertex3f(-1.0,-1.0, 1.0);         // Bottom Left Of The Quad (Front)
+    glVertex3f( 1.0,-1.0, 1.0);         // Bottom Right Of The Quad (Front)
+    glColor3f(1.0,1.0,0.0);           // Set The Color To Yellow
+    glVertex3f( 1.0,-1.0,-1.0);         // Top Right Of The Quad (Back)
+    glVertex3f(-1.0,-1.0,-1.0);         // Top Left Of The Quad (Back)
+    glVertex3f(-1.0, 1.0,-1.0);         // Bottom Left Of The Quad (Back)
+    glVertex3f( 1.0, 1.0,-1.0);         // Bottom Right Of The Quad (Back)
+    glColor3f(0.0,0.0,1.0);           // Set The Color To Blue
+    glVertex3f(-1.0, 1.0, 1.0);         // Top Right Of The Quad (Left)
+    glVertex3f(-1.0, 1.0,-1.0);         // Top Left Of The Quad (Left)
+    glVertex3f(-1.0,-1.0,-1.0);         // Bottom Left Of The Quad (Left)
+    glVertex3f(-1.0,-1.0, 1.0);         // Bottom Right Of The Quad (Left)
+    glColor3f(1.0,0.0,1.0);           // Set The Color To Violet
+    glVertex3f( 1.0, 1.0,-1.0);         // Top Right Of The Quad (Right)
+    glVertex3f( 1.0, 1.0, 1.0);         // Top Left Of The Quad (Right)
+    glVertex3f( 1.0,-1.0, 1.0);         // Bottom Left Of The Quad (Right)
+    glVertex3f( 1.0,-1.0,-1.0);         // Bottom Right Of The Quad (Right)
+  glEnd();                      // Done Drawing The Quad
 
 
-	rtri:=rtri+0.2;											// Increase The Rotation Variable For The Triangle ( NEW )
-	rquad:=rquad-0.15;										// Decrease The Rotation Variable For The Quad ( NEW )
-	result := true;										// Keep Going
+  rtri:=rtri+0.2;                     // Increase The Rotation Variable For The Triangle ( NEW )
+  rquad:=rquad-0.15;                    // Decrease The Rotation Variable For The Quad ( NEW )
+  result := true;                   // Keep Going
 end;
 end;
 
 
-
-begin	
-	// Setup the Main screen for 3D 
-	videoSetMode(MODE_0_3D);
-	
-	// initialize the geometry engine
-	glInit();
-	
-	// enable antialiasing
-	glEnable(GL_ANTIALIAS);
-	
-	// Specify the Clear Color and Depth 
-	glClearColor(0,0,0,31);
-	glClearPolyID(63); // BG must have a unique polygon ID for AA to work
-	glClearDepth($7FFF);
-	
-		// Set our viewport to be the same size as the screen
-	glViewPort(0,0,255,191);
+var
+  keys: integer;
+begin 
+  // Setup the Main screen for 3D 
+  videoSetMode(MODE_0_3D);
+  
+  // initialize the geometry engine
+  glInit();
+  
+  // enable antialiasing
+  glEnable(GL_ANTIALIAS);
+  
+  // Specify the Clear Color and Depth 
+  glClearColor(0,0,0,31);
+  glClearPolyID(63); // BG must have a unique polygon ID for AA to work
+  glClearDepth($7FFF);
+  
+    // Set our viewport to be the same size as the screen
+  glViewPort(0,0,255,191);
 
 
   glMatrixMode(GL_PROJECTION);
   glMatrixMode(GL_PROJECTION);
-  glLoadIdentity();	
-	gluPerspective(70, 256.0 / 192.0, 0.1, 100);
-	
-	//ds specific, several attributes can be set here	
-	glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE);
-		
+  glLoadIdentity(); 
+  gluPerspective(70, 256.0 / 192.0, 0.1, 100);
+  
+  //ds specific, several attributes can be set here 
+  glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE);
+    
   while true do
   while true do
-	begin
-		// Set the current matrix to be the model matrix
-		glMatrixMode(GL_MODELVIEW);
-		
-		//Push our original Matrix onto the stack (save state)
-		glPushMatrix();	
+  begin
+    // Set the current matrix to be the model matrix
+    glMatrixMode(GL_MODELVIEW);
+    
+    //Push our original Matrix onto the stack (save state)
+    glPushMatrix(); 
 
 
-		DrawGLScene();
-		
-		// Pop our Matrix from the stack (restore state)
-		glPopMatrix(1);
+    DrawGLScene();
+    
+    // Pop our Matrix from the stack (restore state)
+    glPopMatrix(1);
 
 
-		// flush to screen	
-		glFlush(0);
+    // flush to screen  
+    glFlush(0);
+    
+    swiWaitForVBlank();
     
     
-    swiWaitForVBlank();	
-	end;
+    scanKeys();
+    keys := keysDown();
+    if (keys and KEY_START) <> 0 then break;  
+  end;
 end.
 end.

+ 130 - 124
packages/libndsfpc/examples/graphics/3D/nehe/lesson06/lesson06.pp

@@ -1,6 +1,6 @@
 (****************************************
 (****************************************
- * 		NDS NeHe Lesson 06    			*
- * 		Author: Dovoto					*
+ *    NDS NeHe Lesson 06          *
+ *    Author: Dovoto          *
  ****************************************)
  ****************************************)
 program Lesson06;
 program Lesson06;
 {$L build/drunkenlogo.pcx.o}
 {$L build/drunkenlogo.pcx.o}
@@ -13,141 +13,147 @@ uses
 {$include inc/drunkenlogo.pcx.inc}
 {$include inc/drunkenlogo.pcx.inc}
 
 
 var
 var
-  xrot: cfloat;				// X Rotation ( NEW )
-  yrot: cfloat;				// Y Rotation ( NEW )
-  zrot: cfloat;				// Z Rotation ( NEW )
+  xrot: cfloat;       // X Rotation ( NEW )
+  yrot: cfloat;       // Y Rotation ( NEW )
+  zrot: cfloat;       // Z Rotation ( NEW )
   
   
-  texture: array [0..0] of integer;			// Storage For One Texture ( NEW )
+  texture: array [0..0] of integer;     // Storage For One Texture ( NEW )
 
 
 
 
 
 
-function DrawGLScene(): boolean;											// Here's Where We Do All The Drawing
+function DrawGLScene(): boolean;                      // Here's Where We Do All The Drawing
 begin
 begin
-	glLoadIdentity();									// Reset The View
-	glTranslatef(0.0,0.0,-5.0);
-
-	glRotatef(xrot,1.0,0.0,0.0);
-	glRotatef(yrot,0.0,1.0,0.0);
-	glRotatef(zrot,0.0,0.0,1.0);
-
-	glBindTexture(GL_TEXTURE_2D, texture[0]);
-
-	glBegin(GL_QUADS);
-		// Front Face
-		glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);
-		glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
-		glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
-		glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
-		// Back Face
-		glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
-		glTexCoord2f(1.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
-		glTexCoord2f(0.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
-		glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
-		// Top Face
-		glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
-		glTexCoord2f(0.0, 0.0); glVertex3f(-1.0,  1.0,  1.0);
-		glTexCoord2f(1.0, 0.0); glVertex3f( 1.0,  1.0,  1.0);
-		glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
-		// Bottom Face
-		glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0);
-		glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0, -1.0);
-		glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
-		glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);
-		// Right face
-		glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
-		glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
-		glTexCoord2f(0.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
-		glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
-		// Left Face
-		glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
-		glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);
-		glTexCoord2f(1.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
-		glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
-	glEnd();
-
-	xrot:=xrot+0.3;
-	yrot:=yrot+0.2;
-	zrot:=zrot+0.4;
-	result := true;			
+  glLoadIdentity();                 // Reset The View
+  glTranslatef(0.0,0.0,-5.0);
+
+  glRotatef(xrot,1.0,0.0,0.0);
+  glRotatef(yrot,0.0,1.0,0.0);
+  glRotatef(zrot,0.0,0.0,1.0);
+
+  glBindTexture(GL_TEXTURE_2D, texture[0]);
+
+  glBegin(GL_QUADS);
+    // Front Face
+    glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);
+    glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
+    glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
+    glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
+    // Back Face
+    glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
+    glTexCoord2f(1.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
+    glTexCoord2f(0.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
+    glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
+    // Top Face
+    glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
+    glTexCoord2f(0.0, 0.0); glVertex3f(-1.0,  1.0,  1.0);
+    glTexCoord2f(1.0, 0.0); glVertex3f( 1.0,  1.0,  1.0);
+    glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
+    // Bottom Face
+    glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0);
+    glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0, -1.0);
+    glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
+    glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);
+    // Right face
+    glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
+    glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
+    glTexCoord2f(0.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
+    glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
+    // Left Face
+    glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
+    glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);
+    glTexCoord2f(1.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
+    glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
+  glEnd();
+
+  xrot:=xrot+0.3;
+  yrot:=yrot+0.2;
+  zrot:=zrot+0.4;
+  result := true;     
 end;
 end;
 
 
 
 
-function LoadGLTextures(): boolean;									// Load PCX files And Convert To Textures
+function LoadGLTextures(): boolean;                 // Load PCX files And Convert To Textures
 var
 var
-	pcx: sImage;                //////////////(NEW) and different from nehe.
+  pcx: sImage;                //////////////(NEW) and different from nehe.
 begin
 begin
-	//load our texture
-	loadPCX(pcuint8(drunkenlogo_pcx), @pcx);
-	
-	image8to16(@pcx);
+  //load our texture
+  loadPCX(pcuint8(drunkenlogo_pcx), @pcx);
+  
+  image8to16(@pcx);
 
 
-	glGenTextures(1, @texture[0]);
-	glBindTexture(0, texture[0]);
-	glTexImage2D(0, 0, GL_RGB, TEXTURE_SIZE_128 , TEXTURE_SIZE_128, 0, TEXGEN_TEXCOORD, pcx.image.data8);
+  glGenTextures(1, @texture[0]);
+  glBindTexture(0, texture[0]);
+  glTexImage2D(0, 0, GL_RGB, TEXTURE_SIZE_128 , TEXTURE_SIZE_128, 0, TEXGEN_TEXCOORD, pcx.image.data8);
 
 
-	imageDestroy(@pcx);
+  imageDestroy(@pcx);
 
 
-	result := true;
+  result := true;
 end;
 end;
 
 
-begin	
-
-	// Setup the Main screen for 3D 
-	videoSetMode(MODE_0_3D);
-	vramSetBankA(VRAM_A_TEXTURE);                        //NEW  must set up some memory for textures
-
-	// initialize the geometry engine
-	glInit();
-	
-	// enable textures
-	glEnable(GL_TEXTURE_2D);
-	
-	// enable antialiasing
-	glEnable(GL_ANTIALIAS);
-	
-	// setup the rear plane
-	glClearColor(0,0,0,31); // BG must be opaque for AA to work
-	glClearPolyID(63); // BG must have a unique polygon ID for AA to work
-	glClearDepth($7FFF);
-	
-	// Set our viewport to be the same size as the screen
-	glViewport(0,0,255,191);
-	
-	LoadGLTextures();
-	
-	glMatrixMode(GL_PROJECTION);
-	glLoadIdentity();
-	gluPerspective(70, 256.0 / 192.0, 0.1, 100);
-	
-	// Set the current matrix to be the model matrix
-	glMatrixMode(GL_MODELVIEW);
-	
-	//need to set up some material properties since DS does not have them set by default
-	glMaterialf(GL_AMBIENT, RGB15(16,16,16));
-	glMaterialf(GL_DIFFUSE, RGB15(16,16,16));
-	glMaterialf(GL_SPECULAR, BIT(15) or RGB15(8,8,8));
-	glMaterialf(GL_EMISSION, RGB15(16,16,16));
-	
-	//ds uses a table for shinyness..this generates a half-ass one
-	glMaterialShinyness();
-	
-	//ds specific, several attributes can be set here	
-	glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE  or POLY_FORMAT_LIGHT0 or POLY_FORMAT_LIGHT1 or POLY_FORMAT_LIGHT2);
-	
-	glLight(0, RGB15(31,31,31) , 0,				  floattov10(-1.0),		 0);
-	glLight(1, RGB15(31,31,31) , 0,				  0,	floattov10(-1.0));
-	glLight(2, RGB15(31,31,31) , 0,				  0,	floattov10(1.0));
-
-	while true do
-	begin
-
-		glColor3f(1,1,1);
-
-		DrawGLScene();
-		
-		// flush to screen	
-		glFlush(0);
-
-    swiWaitForVBlank();	
-	end;
+var
+  keys: integer;
+begin 
+
+  // Setup the Main screen for 3D 
+  videoSetMode(MODE_0_3D);
+  vramSetBankA(VRAM_A_TEXTURE);                        //NEW  must set up some memory for textures
+
+  // initialize the geometry engine
+  glInit();
+  
+  // enable textures
+  glEnable(GL_TEXTURE_2D);
+  
+  // enable antialiasing
+  glEnable(GL_ANTIALIAS);
+  
+  // setup the rear plane
+  glClearColor(0,0,0,31); // BG must be opaque for AA to work
+  glClearPolyID(63); // BG must have a unique polygon ID for AA to work
+  glClearDepth($7FFF);
+  
+  // Set our viewport to be the same size as the screen
+  glViewport(0,0,255,191);
+  
+  LoadGLTextures();
+  
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  gluPerspective(70, 256.0 / 192.0, 0.1, 100);
+  
+  // Set the current matrix to be the model matrix
+  glMatrixMode(GL_MODELVIEW);
+  
+  //need to set up some material properties since DS does not have them set by default
+  glMaterialf(GL_AMBIENT, RGB15(16,16,16));
+  glMaterialf(GL_DIFFUSE, RGB15(16,16,16));
+  glMaterialf(GL_SPECULAR, BIT(15) or RGB15(8,8,8));
+  glMaterialf(GL_EMISSION, RGB15(16,16,16));
+  
+  //ds uses a table for shinyness..this generates a half-ass one
+  glMaterialShinyness();
+  
+  //ds specific, several attributes can be set here 
+  glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE  or POLY_FORMAT_LIGHT0 or POLY_FORMAT_LIGHT1 or POLY_FORMAT_LIGHT2);
+  
+  glLight(0, RGB15(31,31,31) , 0,         floattov10(-1.0),    0);
+  glLight(1, RGB15(31,31,31) , 0,         0,  floattov10(-1.0));
+  glLight(2, RGB15(31,31,31) , 0,         0,  floattov10(1.0));
+
+  while true do
+  begin
+
+    glColor3f(1,1,1);
+
+    DrawGLScene();
+    
+    // flush to screen  
+    glFlush(0);
+
+    swiWaitForVBlank(); 
+
+    scanKeys();
+    keys := keysDown();
+    if (keys and KEY_START) <> 0 then break;
+  end;
 end.
 end.

+ 161 - 161
packages/libndsfpc/examples/graphics/3D/nehe/lesson07/lesson07.pp

@@ -1,6 +1,6 @@
 (****************************************
 (****************************************
- * 		NDS NeHe Lesson 07    			*
- * 		Author: Ethos					*
+ *    NDS NeHe Lesson 07          *
+ *    Author: Ethos         *
  ****************************************)
  ****************************************)
 
 
 program Lesson07;
 program Lesson07;
@@ -14,182 +14,182 @@ uses
 {$include inc/drunkenlogo.pcx.inc}
 {$include inc/drunkenlogo.pcx.inc}
 
 
 var
 var
-  light: boolean;				// Lighting ON/OFF ( NEW )
-  lp: boolean;					// L Pressed? ( NEW )
+  light: boolean;       // Lighting ON/OFF ( NEW )
+  lp: boolean;          // L Pressed? ( NEW )
 
 
-  xrot: cfloat;				// X Rotation
-  yrot: cfloat;				// Y Rotation
-  xspeed: cfloat;				// X Rotation Speed
-  yspeed: cfloat;				// Y Rotation Speed
-  z: cfloat = -5.0;			// Depth Into The Screen
+  xrot: cfloat;       // X Rotation
+  yrot: cfloat;       // Y Rotation
+  xspeed: cfloat;       // X Rotation Speed
+  yspeed: cfloat;       // Y Rotation Speed
+  z: cfloat = -5.0;     // Depth Into The Screen
 
 
-  texture: array [0..2] of integer;			// Storage For 3 Textures (only going to use 1 on the DS for this demo)
+  texture: array [0..2] of integer;     // Storage For 3 Textures (only going to use 1 on the DS for this demo)
 
 
 const
 const
-  LightAmbient: array [0..3] of cfloat =		( 0.5, 0.5, 0.5, 1.0 );
-  LightDiffuse: array [0..3] of cfloat =		( 1.0, 1.0, 1.0, 1.0 );
-  LightPosition: array [0..3] of cfloat =	  ( 0.0, 0.0, 2.0, 1.0 );
+  LightAmbient: array [0..3] of cfloat =    ( 0.5, 0.5, 0.5, 1.0 );
+  LightDiffuse: array [0..3] of cfloat =    ( 1.0, 1.0, 1.0, 1.0 );
+  LightPosition: array [0..3] of cfloat =   ( 0.0, 0.0, 2.0, 1.0 );
 
 
   
   
 
 
-function DrawGLScene(): boolean;											// Here's Where We Do All The Drawing
+function DrawGLScene(): boolean;                      // Here's Where We Do All The Drawing
 begin
 begin
-	glLoadIdentity();									// Reset The View
-	glTranslatef(0.0,0.0,z);
-
-	glRotatef(xrot,1.0,0.0,0.0);
-	glRotatef(yrot,0.0,1.0,0.0);
-
-	glBindTexture(GL_TEXTURE_2D, texture[0]);  //no filters to swtich between
-
-	glBegin(GL_QUADS);
-		// Front Face
-		glNormal3f( 0.0, 0.0, 1.0);
-		glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);
-		glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
-		glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
-		glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
-		// Back Face
-		glNormal3f( 0.0, 0.0,-1.0);
-		glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
-		glTexCoord2f(1.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
-		glTexCoord2f(0.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
-		glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
-		// Top Face
-		glNormal3f( 0.0, 1.0, 0.0);
-		glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
-		glTexCoord2f(0.0, 0.0); glVertex3f(-1.0,  1.0,  1.0);
-		glTexCoord2f(1.0, 0.0); glVertex3f( 1.0,  1.0,  1.0);
-		glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
-		// Bottom Face
-		glNormal3f( 0.0,-1.0, 0.0);
-		glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0);
-		glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0, -1.0);
-		glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
-		glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);
-		// Right face
-		glNormal3f( 1.0, 0.0, 0.0);
-		glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
-		glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
-		glTexCoord2f(0.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
-		glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
-		// Left Face
-		glNormal3f(-1.0, 0.0, 0.0);
-		glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
-		glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);
-		glTexCoord2f(1.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
-		glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
-	glEnd();
-
-	xrot:=xrot+xspeed;
-	yrot:=yrot+yspeed;
-
-
-	result := true;			
+  glLoadIdentity();                 // Reset The View
+  glTranslatef(0.0,0.0,z);
+
+  glRotatef(xrot,1.0,0.0,0.0);
+  glRotatef(yrot,0.0,1.0,0.0);
+
+  glBindTexture(GL_TEXTURE_2D, texture[0]);  //no filters to swtich between
+
+  glBegin(GL_QUADS);
+    // Front Face
+    glNormal3f( 0.0, 0.0, 1.0);
+    glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);
+    glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
+    glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
+    glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
+    // Back Face
+    glNormal3f( 0.0, 0.0,-1.0);
+    glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
+    glTexCoord2f(1.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
+    glTexCoord2f(0.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
+    glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
+    // Top Face
+    glNormal3f( 0.0, 1.0, 0.0);
+    glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
+    glTexCoord2f(0.0, 0.0); glVertex3f(-1.0,  1.0,  1.0);
+    glTexCoord2f(1.0, 0.0); glVertex3f( 1.0,  1.0,  1.0);
+    glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
+    // Bottom Face
+    glNormal3f( 0.0,-1.0, 0.0);
+    glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0);
+    glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0, -1.0);
+    glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
+    glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);
+    // Right face
+    glNormal3f( 1.0, 0.0, 0.0);
+    glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
+    glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
+    glTexCoord2f(0.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
+    glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
+    // Left Face
+    glNormal3f(-1.0, 0.0, 0.0);
+    glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
+    glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);
+    glTexCoord2f(1.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
+    glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
+  glEnd();
+
+  xrot:=xrot+xspeed;
+  yrot:=yrot+yspeed;
+
+
+  result := true;     
 end;
 end;
 
 
 
 
-function LoadGLTextures(): boolean;									// Load PCX files And Convert To Textures
+function LoadGLTextures(): boolean;                 // Load PCX files And Convert To Textures
 var
 var
-	pcx: sImage;                //////////////(NEW) and different from nehe.
+  pcx: sImage;                //////////////(NEW) and different from nehe.
 begin
 begin
-	//load our texture
-	loadPCX(pcuint8(drunkenlogo_pcx), @pcx);
-	
-	image8to16(@pcx);
+  //load our texture
+  loadPCX(pcuint8(drunkenlogo_pcx), @pcx);
+  
+  image8to16(@pcx);
 
 
-	glGenTextures(1, @texture[0]);
-	glBindTexture(0, texture[0]);
-	glTexImage2D(0, 0, GL_RGB, TEXTURE_SIZE_128 , TEXTURE_SIZE_128, 0, TEXGEN_TEXCOORD, pcx.image.data8);
+  glGenTextures(1, @texture[0]);
+  glBindTexture(0, texture[0]);
+  glTexImage2D(0, 0, GL_RGB, TEXTURE_SIZE_128 , TEXTURE_SIZE_128, 0, TEXGEN_TEXCOORD, pcx.image.data8);
 
 
-	imageDestroy(@pcx);
+  imageDestroy(@pcx);
 
 
-	result := true;
+  result := true;
 end;
 end;
 
 
+var
+  pressed: integer;
+  held: integer;
 begin
 begin
-	// Setup the Main screen for 3D 
-	videoSetMode(MODE_0_3D);
-	vramSetBankA(VRAM_A_TEXTURE);                        //NEW  must set up some memory for textures
-
-	// initialize the geometry engine
-	glInit();
-	
-	// enable textures
-	glEnable(GL_TEXTURE_2D);
-	
-	// enable antialiasing
-	glEnable(GL_ANTIALIAS);
-	
-	// setup the rear plane
-	glClearColor(0,0,0,31); // BG must be opaque for AA to work
-	glClearPolyID(63); // BG must have a unique polygon ID for AA to work
-	glClearDepth($7FFF);
-
-	// Set our viewport to be the same size as the screen
-	glViewPort(0,0,255,191);
-	
-	LoadGLTextures();
-	
-	glMatrixMode(GL_PROJECTION);
-	glLoadIdentity();
-	gluPerspective(70, 256.0 / 192.0, 0.1, 100);
-	
-	//set up a directional light arguments are light number (0-3), light color, 
-	//and an x,y,z vector that points in the direction of the light, the direction must be normalized
-	glLight(0, RGB15(31,31,31) , 0, floattov10(-1.0), 0);
-	
-	//need to set up some material properties since DS does not have them set by default
-	glMaterialf(GL_AMBIENT, RGB15(8,8,8));
-	glMaterialf(GL_DIFFUSE, RGB15(8,8,8));
-	glMaterialf(GL_SPECULAR, BIT(15) or RGB15(8,8,8));
-	glMaterialf(GL_EMISSION, RGB15(16,16,16));
-	
-	//ds uses a table for shinyness..this generates a half-ass one
-	glMaterialShinyness();
-	
-	// Set the current matrix to be the model matrix
-	glMatrixMode(GL_MODELVIEW);
-	
-	while true do 
-	begin
-		//these little button functions are pretty handy
-		scanKeys();
-
-	
-		if ((keysDown() and KEY_A)) <> 0 then
-			light := not light;
-
-		if (keysHeld() and KEY_R) <> 0 then
-			z := z -0.02;
-		if (keysHeld() and KEY_L) <> 0 then
-			z := z+0.02;
-		if (keysHeld() and KEY_LEFT) <> 0 then
-			xspeed := xspeed-0.01;
-		if (keysHeld() and KEY_RIGHT) <> 0 then
-			xspeed := xspeed+0.01;
-		if (keysHeld() and KEY_UP) <> 0 then
-			yspeed := yspeed+0.01;
-		if (keysHeld() and KEY_DOWN) <> 0 then
-			yspeed := yspeed-0.01;
-		
-		
-		glColor3f(1,1,1);
-		
-		if (not light) then
-			//ds specific, several attributes can be set here including turning on our light	
-			glPolyFmt(POLY_ALPHA(31) or POLY_CULL_BACK)
-		else
-			//ds specific, several attributes can be set here including turning on our light	
-			glPolyFmt(POLY_ALPHA(31) or POLY_CULL_BACK  or POLY_FORMAT_LIGHT0);
-
-		DrawGLScene();
-
-		// flush to screen	
-		glFlush(0);
-		
-		// wait for the screen to refresh
-		swiWaitForVBlank();
-	end;
-		
+  // Setup the Main screen for 3D 
+  videoSetMode(MODE_0_3D);
+  vramSetBankA(VRAM_A_TEXTURE);                        //NEW  must set up some memory for textures
+
+  // initialize the geometry engine
+  glInit();
+  
+  // enable textures
+  glEnable(GL_TEXTURE_2D);
+  
+  // enable antialiasing
+  glEnable(GL_ANTIALIAS);
+  
+  // setup the rear plane
+  glClearColor(0,0,0,31); // BG must be opaque for AA to work
+  glClearPolyID(63); // BG must have a unique polygon ID for AA to work
+  glClearDepth($7FFF);
+
+  // Set our viewport to be the same size as the screen
+  glViewPort(0,0,255,191);
+  
+  LoadGLTextures();
+  
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  gluPerspective(70, 256.0 / 192.0, 0.1, 100);
+  
+  //set up a directional light arguments are light number (0-3), light color, 
+  //and an x,y,z vector that points in the direction of the light, the direction must be normalized
+  glLight(0, RGB15(31,31,31) , 0, floattov10(-1.0), 0);
+  
+  //need to set up some material properties since DS does not have them set by default
+  glMaterialf(GL_AMBIENT, RGB15(8,8,8));
+  glMaterialf(GL_DIFFUSE, RGB15(8,8,8));
+  glMaterialf(GL_SPECULAR, BIT(15) or RGB15(8,8,8));
+  glMaterialf(GL_EMISSION, RGB15(16,16,16));
+  
+  //ds uses a table for shinyness..this generates a half-ass one
+  glMaterialShinyness();
+  
+  // Set the current matrix to be the model matrix
+  glMatrixMode(GL_MODELVIEW);
+  
+  while true do 
+  begin
+    //these little button functions are pretty handy
+    scanKeys();
+    pressed := keysDown();
+  
+    if ((pressed and KEY_A)) <> 0 then light := not light;
+
+    held := keysHeld();  
+
+    if (held and KEY_R)     <> 0 then z := z - 0.02;
+    if (held and KEY_L)     <> 0 then z := z + 0.02;
+    if (held and KEY_LEFT)  <> 0 then xspeed := xspeed - 0.01;
+    if (held and KEY_RIGHT) <> 0 then xspeed := xspeed + 0.01;
+    if (held and KEY_UP)    <> 0 then yspeed := yspeed + 0.01;
+    if (held and KEY_DOWN)  <> 0 then yspeed := yspeed - 0.01;
+    
+    
+    glColor3f(1,1,1);
+    
+    if (not light) then
+      //ds specific, several attributes can be set here including turning on our light  
+      glPolyFmt(POLY_ALPHA(31) or POLY_CULL_BACK)
+    else
+      //ds specific, several attributes can be set here including turning on our light  
+      glPolyFmt(POLY_ALPHA(31) or POLY_CULL_BACK  or POLY_FORMAT_LIGHT0);
+
+    DrawGLScene();
+
+    // flush to screen  
+    glFlush(0);
+    
+    // wait for the screen to refresh
+    swiWaitForVBlank();
+    
+    if (pressed and KEY_START) <> 0 then break;
+  end;
+    
 end.
 end.

+ 162 - 162
packages/libndsfpc/examples/graphics/3D/nehe/lesson08/lesson08.pp

@@ -1,6 +1,6 @@
 (****************************************
 (****************************************
- * 		NDS NeHe Lesson 08    			*
- * 		Author: Ethos					*
+ *    NDS NeHe Lesson 08          *
+ *    Author: Ethos         *
  ****************************************)
  ****************************************)
 
 
 program Lesson08;
 program Lesson08;
@@ -14,183 +14,183 @@ uses
 {$include inc/drunkenlogo.pcx.inc}
 {$include inc/drunkenlogo.pcx.inc}
 
 
 var
 var
-  light: boolean;				// Lighting ON/OFF ( NEW )
-  lp: boolean;					// L Pressed? ( NEW )
+  light: boolean;       // Lighting ON/OFF ( NEW )
+  lp: boolean;          // L Pressed? ( NEW )
 
 
-  xrot: cfloat;				// X Rotation
-  yrot: cfloat;				// Y Rotation
-  xspeed: cfloat;				// X Rotation Speed
-  yspeed: cfloat;				// Y Rotation Speed
-  z: cfloat = -5.0;			// Depth Into The Screen
+  xrot: cfloat;       // X Rotation
+  yrot: cfloat;       // Y Rotation
+  xspeed: cfloat;       // X Rotation Speed
+  yspeed: cfloat;       // Y Rotation Speed
+  z: cfloat = -5.0;     // Depth Into The Screen
 
 
-  texture: array [0..2] of integer;			// Storage For 3 Textures (only going to use 1 on the DS for this demo)
+  texture: array [0..2] of integer;     // Storage For 3 Textures (only going to use 1 on the DS for this demo)
 
 
 const
 const
-  LightAmbient: array [0..3] of cfloat =		( 0.5, 0.5, 0.5, 1.0 );
-  LightDiffuse: array [0..3] of cfloat =		( 1.0, 1.0, 1.0, 1.0 );
-  LightPosition: array [0..3] of cfloat = 	( 0.0, 0.0, 2.0, 1.0 );
+  LightAmbient: array [0..3] of cfloat =    ( 0.5, 0.5, 0.5, 1.0 );
+  LightDiffuse: array [0..3] of cfloat =    ( 1.0, 1.0, 1.0, 1.0 );
+  LightPosition: array [0..3] of cfloat =   ( 0.0, 0.0, 2.0, 1.0 );
 
 
-function DrawGLScene(): boolean;											// Here's Where We Do All The Drawing
+function DrawGLScene(): boolean;                      // Here's Where We Do All The Drawing
 begin
 begin
-	glLoadIdentity();									// Reset The View
-	glTranslatef(0.0,0.0,z);
-
-	glRotatef(xrot,1.0,0.0,0.0);
-	glRotatef(yrot,0.0,1.0,0.0);
-	
-	glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE  or POLY_FORMAT_LIGHT0);
-
-	glBindTexture(GL_TEXTURE_2D, texture[0]);  //no filters to swtich between
-	
-	glBegin(GL_QUADS);
-		// Front Face
-		glNormal3f( 0.0, 0.0, 1.0);
-		glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);
-		glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
-		glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
-		glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
-		// Back Face
-		glNormal3f( 0.0, 0.0,-1.0);
-		glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
-		glTexCoord2f(1.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
-		glTexCoord2f(0.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
-		glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
-		// Top Face
-		glNormal3f( 0.0, 1.0, 0.0);
-		glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
-		glTexCoord2f(0.0, 0.0); glVertex3f(-1.0,  1.0,  1.0);
-		glTexCoord2f(1.0, 0.0); glVertex3f( 1.0,  1.0,  1.0);
-		glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
-	// Bottom Face
-		glNormal3f( 0.0,-1.0, 0.0);
-		glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0);
-		glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0, -1.0);
-		glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
-		glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);
-		// Right face
-		glNormal3f( 1.0, 0.0, 0.0);
-		glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
-		glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
-		glTexCoord2f(0.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
-		glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
-	glEnd();
-
-	glPolyFmt(POLY_ALPHA(15) or POLY_CULL_BACK  or POLY_FORMAT_LIGHT0);
-	
-	glBegin(GL_QUADS);
-	
-	// Left Face
-		glNormal3f(-1.0, 0.0, 0.0);
-		glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
-		glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);
-		glTexCoord2f(1.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
-		glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
-	glEnd();
-
-	xrot := xrot+xspeed;
-	yrot := yrot+yspeed;
-
-	result := true;			
+  glLoadIdentity();                 // Reset The View
+  glTranslatef(0.0,0.0,z);
+
+  glRotatef(xrot,1.0,0.0,0.0);
+  glRotatef(yrot,0.0,1.0,0.0);
+  
+  glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE  or POLY_FORMAT_LIGHT0);
+
+  glBindTexture(GL_TEXTURE_2D, texture[0]);  //no filters to swtich between
+  
+  glBegin(GL_QUADS);
+    // Front Face
+    glNormal3f( 0.0, 0.0, 1.0);
+    glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);
+    glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
+    glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
+    glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
+    // Back Face
+    glNormal3f( 0.0, 0.0,-1.0);
+    glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
+    glTexCoord2f(1.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
+    glTexCoord2f(0.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
+    glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
+    // Top Face
+    glNormal3f( 0.0, 1.0, 0.0);
+    glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
+    glTexCoord2f(0.0, 0.0); glVertex3f(-1.0,  1.0,  1.0);
+    glTexCoord2f(1.0, 0.0); glVertex3f( 1.0,  1.0,  1.0);
+    glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
+  // Bottom Face
+    glNormal3f( 0.0,-1.0, 0.0);
+    glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0);
+    glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0, -1.0);
+    glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
+    glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);
+    // Right face
+    glNormal3f( 1.0, 0.0, 0.0);
+    glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
+    glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
+    glTexCoord2f(0.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
+    glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
+  glEnd();
+
+  glPolyFmt(POLY_ALPHA(15) or POLY_CULL_BACK  or POLY_FORMAT_LIGHT0);
+  
+  glBegin(GL_QUADS);
+  
+  // Left Face
+    glNormal3f(-1.0, 0.0, 0.0);
+    glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
+    glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);
+    glTexCoord2f(1.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
+    glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
+  glEnd();
+
+  xrot := xrot+xspeed;
+  yrot := yrot+yspeed;
+
+  result := true;     
 end;
 end;
 
 
 
 
-function LoadGLTextures(): boolean;									// Load PCX files And Convert To Textures
+function LoadGLTextures(): boolean;                 // Load PCX files And Convert To Textures
 var
 var
-	pcx: sImage;                //////////////(NEW) and different from nehe.
+  pcx: sImage;                //////////////(NEW) and different from nehe.
 begin
 begin
-	//load our texture
-	loadPCX(pcuint8(drunkenlogo_pcx), @pcx);
-	
-	image8to16(@pcx);
+  //load our texture
+  loadPCX(pcuint8(drunkenlogo_pcx), @pcx);
+  
+  image8to16(@pcx);
 
 
-	glGenTextures(1, @texture[0]);
-	glBindTexture(0, texture[0]);
-	glTexImage2D(0, 0, GL_RGB, TEXTURE_SIZE_128 , TEXTURE_SIZE_128, 0, TEXGEN_TEXCOORD, pcx.image.data8);
+  glGenTextures(1, @texture[0]);
+  glBindTexture(0, texture[0]);
+  glTexImage2D(0, 0, GL_RGB, TEXTURE_SIZE_128 , TEXTURE_SIZE_128, 0, TEXGEN_TEXCOORD, pcx.image.data8);
 
 
-	imageDestroy(@pcx);
+  imageDestroy(@pcx);
 
 
-	result := true;
+  result := true;
 end;
 end;
 
 
+var
+  pressed: integer;
+  held: integer;
 
 
 begin
 begin
-	
-	// Setup the Main screen for 3D 
-	videoSetMode(MODE_0_3D);
-	vramSetBankA(VRAM_A_TEXTURE);                        //NEW  must set up some memory for textures
-
-	// initialize the geometry engine
-	glInit();
-	
-	// enable textures
-	glEnable(GL_TEXTURE_2D);
-	
-	glEnable(GL_BLEND);
-	
-	// enable antialiasing
-	glEnable(GL_ANTIALIAS);
-	
-	// setup the rear plane
-	glClearColor(0,0,0,31); // BG must be opaque for AA to work
-	glClearPolyID(63); // BG must have a unique polygon ID for AA to work
-	glClearDepth($7FFF);
-	
-	// Set our viewport to be the same size as the screen
-	glViewPort(0,0,255,191);
-	
-	LoadGLTextures();
-	
-	glMatrixMode(GL_PROJECTION);
-	glLoadIdentity();
-	gluPerspective(70, 256.0 / 192.0, 0.1, 100);
-	
-	//set up a directional ligth arguments are light number (0-3), light color, 
-	//and an x,y,z vector that points in the direction of the light
-	glLight(0, RGB15(31,31,31) , 0, floattov10(-1.0), 0);
-	
-	
-	glColor3f(1,1,1);
-	
-	glMatrixMode(GL_MODELVIEW);
-	
-	//need to set up some material properties since DS does not have them set by default
-	
-	glMaterialf(GL_AMBIENT, RGB15(16,16,16));
-	glMaterialf(GL_DIFFUSE, RGB15(16,16,16));
-	glMaterialf(GL_SPECULAR, BIT(15) or RGB15(8,8,8));
-	glMaterialf(GL_EMISSION, RGB15(16,16,16));
-	
-	//ds uses a table for shinyness..this generates a half-ass one
-	glMaterialShinyness();
-	
-	// Set the current matrix to be the model matrix
-	glMatrixMode(GL_MODELVIEW);
+  
+  // Setup the Main screen for 3D 
+  videoSetMode(MODE_0_3D);
+  vramSetBankA(VRAM_A_TEXTURE);                        //NEW  must set up some memory for textures
+
+  // initialize the geometry engine
+  glInit();
+  
+  // enable textures
+  glEnable(GL_TEXTURE_2D);
+  
+  glEnable(GL_BLEND);
+  
+  // enable antialiasing
+  glEnable(GL_ANTIALIAS);
+  
+  // setup the rear plane
+  glClearColor(0,0,0,31); // BG must be opaque for AA to work
+  glClearPolyID(63); // BG must have a unique polygon ID for AA to work
+  glClearDepth($7FFF);
+  
+  // Set our viewport to be the same size as the screen
+  glViewPort(0,0,255,191);
+  
+  LoadGLTextures();
+  
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  gluPerspective(70, 256.0 / 192.0, 0.1, 100);
+  
+  //set up a directional ligth arguments are light number (0-3), light color, 
+  //and an x,y,z vector that points in the direction of the light
+  glLight(0, RGB15(31,31,31) , 0, floattov10(-1.0), 0);
+  
+  
+  glColor3f(1,1,1);
+  
+  glMatrixMode(GL_MODELVIEW);
+  
+  //need to set up some material properties since DS does not have them set by default
+  
+  glMaterialf(GL_AMBIENT, RGB15(16,16,16));
+  glMaterialf(GL_DIFFUSE, RGB15(16,16,16));
+  glMaterialf(GL_SPECULAR, BIT(15) or RGB15(8,8,8));
+  glMaterialf(GL_EMISSION, RGB15(16,16,16));
+  
+  //ds uses a table for shinyness..this generates a half-ass one
+  glMaterialShinyness();
+  
+  // Set the current matrix to be the model matrix
+  glMatrixMode(GL_MODELVIEW);
   while true do
   while true do
-	begin
-		//these little button functions are pretty handy
-		scanKeys();
-				
-		if (keysHeld() and KEY_R) <> 0 then
-			z := z -0.02;
-		if (keysHeld() and KEY_L) <> 0 then
-			z := z+0.02;
-		if (keysHeld() and KEY_LEFT) <> 0 then
-			xspeed := xspeed-0.01;
-		if (keysHeld() and KEY_RIGHT) <> 0 then
-			xspeed := xspeed+0.01;
-		if (keysHeld() and KEY_UP) <> 0 then
-			yspeed := yspeed+0.01;
-		if (keysHeld() and KEY_DOWN) <> 0 then
-			yspeed := yspeed-0.01;
-
-		DrawGLScene();
-
-		// flush to screen	
-		glFlush(0);
-		
-		// wait for the screen to refresh
-		swiWaitForVBlank();
-	
-	end;
-	
+  begin
+    //these little button functions are pretty handy
+    scanKeys();
+    held := keysHeld();
+    pressed := keysDown();
+        
+    if (held and KEY_R)     <> 0 then z := z - 0.02;
+    if (held and KEY_L)     <> 0 then z := z + 0.02;
+    if (held and KEY_LEFT)  <> 0 then xspeed := xspeed - 0.01;
+    if (held and KEY_RIGHT) <> 0 then xspeed := xspeed + 0.01;
+    if (held and KEY_UP)    <> 0 then yspeed := yspeed + 0.01;
+    if (held and KEY_DOWN)  <> 0 then yspeed := yspeed - 0.01;
+
+    DrawGLScene();
+
+    // flush to screen  
+    glFlush(0);
+    
+    // wait for the screen to refresh
+    swiWaitForVBlank();
+  
+    if (pressed and KEY_START) then break;
+  end;
+  
 end.
 end.

+ 134 - 130
packages/libndsfpc/examples/graphics/3D/nehe/lesson09/lesson09.pp

@@ -1,8 +1,8 @@
 (****************************************
 (****************************************
- * 		NDS NeHe Lesson 09    			*
- * 		Author: dovoto
- *		DS does not appear to support 
-		the features needed for this demo
+ *    NDS NeHe Lesson 09          *
+ *    Author: dovoto
+ *    DS does not appear to support 
+    the features needed for this demo
  ****************************************)
  ****************************************)
 
 
 program Lesson09;
 program Lesson09;
@@ -25,154 +25,158 @@ type
 
 
 
 
 var
 var
-  twinkle: boolean;		// Twinkling Stars
-  tp: boolean;				// 'T' Key Pressed?
+  twinkle: boolean;   // Twinkling Stars
+  tp: boolean;        // 'T' Key Pressed?
 
 
-const	
-  num = 50;		// Number Of Stars To Draw
+const 
+  num = 50;   // Number Of Stars To Draw
 
 
 
 
 var
 var
-  star: array [0..num-1] of TStars;		// Need To Keep Track Of 'num' Stars
-  zoom: cfloat = -15.0;	// Distance Away From Stars
-  tilt: cfloat = 90.0;		// Tilt The View
-  spin: cfloat;			// Spin Stars
+  star: array [0..num-1] of TStars;   // Need To Keep Track Of 'num' Stars
+  zoom: cfloat = -15.0; // Distance Away From Stars
+  tilt: cfloat = 90.0;    // Tilt The View
+  spin: cfloat;     // Spin Stars
 
 
-  loop: integer;			// General Loop Variable
-  texture: array [0..0] of integer;			// Storage For One textures
+  loop: integer;      // General Loop Variable
+  texture: array [0..0] of integer;     // Storage For One textures
 
 
 
 
 
 
 // Load PCX files And Convert To Textures
 // Load PCX files And Convert To Textures
-function LoadGLTextures(): boolean;									// Load PCX files And Convert To Textures
+function LoadGLTextures(): boolean;                 // Load PCX files And Convert To Textures
 var
 var
-	pcx: sImage;                //////////////(NEW) and different from nehe.
+  pcx: sImage;                //////////////(NEW) and different from nehe.
 begin
 begin
-	//load our texture
-	loadPCX(pcuint8(Star_pcx), @pcx);
-	
-	image8to16(@pcx);
+  //load our texture
+  loadPCX(pcuint8(Star_pcx), @pcx);
+  
+  image8to16(@pcx);
 
 
-	glGenTextures(1, @texture[0]);
-	glBindTexture(0, texture[0]);
-	glTexImage2D(0, 0, GL_RGBA, TEXTURE_SIZE_128 , TEXTURE_SIZE_128, 0, TEXGEN_TEXCOORD, pcx.image.data8);
+  glGenTextures(1, @texture[0]);
+  glBindTexture(0, texture[0]);
+  glTexImage2D(0, 0, GL_RGBA, TEXTURE_SIZE_128 , TEXTURE_SIZE_128, 0, TEXGEN_TEXCOORD, pcx.image.data8);
 
 
-	imageDestroy(@pcx);
+  imageDestroy(@pcx);
 
 
-	result := true;
+  result := true;
 end;
 end;
 
 
-function DrawGLScene(): boolean;											// Here's Where We Do All The Drawing
+function DrawGLScene(): boolean;                      // Here's Where We Do All The Drawing
 var
 var
   loop: integer;
   loop: integer;
 begin
 begin
-	glBindTexture(GL_TEXTURE_2D, texture[0]);			// Select Our Texture
-
-	for loop := 0 to num - 1 do						// Loop Through All The Stars
-	begin
-		glLoadIdentity();								// Reset The View Before We Draw Each Star
-		glTranslatef(0.0, 0.0, zoom);					// Zoom Into The Screen (Using The Value In 'zoom')
-		glRotatef(tilt, 1.0, 0.0, 0.0);					// Tilt The View (Using The Value In 'tilt')
-		glRotatef(star[loop].angle, 0.0, 1.0, 0.0);		// Rotate To The Current Stars Angle
-		glTranslatef(star[loop].dist, 0.0, 0.0);		// Move Forward On The X Plane
-		glRotatef(-star[loop].angle, 0.0, 1.0, 0.0);	// Cancel The Current Stars Angle
-		glRotatef(-tilt, 1.0, 0.0, 0.0);				// Cancel The Screen Tilt
-		
-		if (twinkle) then
-		begin
-			glColor3b(star[(num-loop)-1].r,star[(num-loop)-1].g,star[(num-loop)-1].b);  ///different
-			glBegin(GL_QUADS);
-				glTexCoord2f(0.0, 0.0); glVertex3f(-1.0,-1.0, 0.0);
-				glTexCoord2f(1.0, 0.0); glVertex3f( 1.0,-1.0, 0.0);
-				glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 0.0);
-				glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 0.0);
-			glEnd();
-		end;
-
-		glRotatef(spin, 0.0, 0.0, 1.0);
-		glColor3b(star[loop].r,star[loop].g,star[loop].b);                            //different
-		glBegin(GL_QUADS);
-			glTexCoord2f(0.0, 0.0); glVertex3f(-1.0,-1.0, 0.0);
-			glTexCoord2f(1.0, 0.0); glVertex3f( 1.0,-1.0, 0.0);
-			glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 0.0);
-			glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 0.0);
-		glEnd();
-
-		spin := spin + 0.01;
-		star[loop].angle := star[loop].angle + cfloat(loop) / num;
-		star[loop].dist := star[loop].dist - 0.01;
-		if (star[loop].dist < 0.0) then
-		begin
-			star[loop].dist := star[loop].dist + 5.0;
-			star[loop].r := random(256);
-			star[loop].g := random(256);
-			star[loop].b := random(256);
-		end;
-	end;
-	result := true;															// Keep Going
+  glBindTexture(GL_TEXTURE_2D, texture[0]);     // Select Our Texture
+
+  for loop := 0 to num - 1 do           // Loop Through All The Stars
+  begin
+    glLoadIdentity();               // Reset The View Before We Draw Each Star
+    glTranslatef(0.0, 0.0, zoom);         // Zoom Into The Screen (Using The Value In 'zoom')
+    glRotatef(tilt, 1.0, 0.0, 0.0);         // Tilt The View (Using The Value In 'tilt')
+    glRotatef(star[loop].angle, 0.0, 1.0, 0.0);   // Rotate To The Current Stars Angle
+    glTranslatef(star[loop].dist, 0.0, 0.0);    // Move Forward On The X Plane
+    glRotatef(-star[loop].angle, 0.0, 1.0, 0.0);  // Cancel The Current Stars Angle
+    glRotatef(-tilt, 1.0, 0.0, 0.0);        // Cancel The Screen Tilt
+    
+    if (twinkle) then
+    begin
+      glColor3b(star[(num-loop)-1].r,star[(num-loop)-1].g,star[(num-loop)-1].b);  ///different
+      glBegin(GL_QUADS);
+        glTexCoord2f(0.0, 0.0); glVertex3f(-1.0,-1.0, 0.0);
+        glTexCoord2f(1.0, 0.0); glVertex3f( 1.0,-1.0, 0.0);
+        glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 0.0);
+        glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 0.0);
+      glEnd();
+    end;
+
+    glRotatef(spin, 0.0, 0.0, 1.0);
+    glColor3b(star[loop].r,star[loop].g,star[loop].b);                            //different
+    glBegin(GL_QUADS);
+      glTexCoord2f(0.0, 0.0); glVertex3f(-1.0,-1.0, 0.0);
+      glTexCoord2f(1.0, 0.0); glVertex3f( 1.0,-1.0, 0.0);
+      glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 0.0);
+      glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 0.0);
+    glEnd();
+
+    spin := spin + 0.01;
+    star[loop].angle := star[loop].angle + cfloat(loop) / num;
+    star[loop].dist := star[loop].dist - 0.01;
+    if (star[loop].dist < 0.0) then
+    begin
+      star[loop].dist := star[loop].dist + 5.0;
+      star[loop].r := random(256);
+      star[loop].g := random(256);
+      star[loop].b := random(256);
+    end;
+  end;
+  result := true;                             // Keep Going
 
 
 end;
 end;
 
 
-
+var
+  pressed: integer;
 begin
 begin
   Randomize;
   Randomize;
-	// Setup the Main screen for 3D 
-	videoSetMode(MODE_0_3D);
-	vramSetBankA(VRAM_A_TEXTURE);                        //NEW  must set up some memory for textures
-
-	// initialize the geometry engine
-	glInit();
-	
-	// enable antialiasing
-	glEnable(GL_ANTIALIAS);
-	
-	// setup the rear plane
-	glClearColor(0,0,0,31); // BG must be opaque for AA to work
-	glClearPolyID(63); // BG must have a unique polygon ID for AA to work
-	glClearDepth($7FFF);
-	
-	// enable textures
-	glEnable(GL_TEXTURE_2D);
-	
-	// enable alpha blending
-	glEnable(GL_BLEND);
-
-	// Set our viewport to be the same size as the screen
-	glViewport(0,0,255,191);
-	
-	LoadGLTextures();
-	
-	glMatrixMode(GL_PROJECTION);
-	glLoadIdentity();
-	gluPerspective(70, 256.0 / 192.0, 0.1, 100);
-	glColor3f(1,1,1);
-	
-	//set up a directional ligth arguments are light number (0-3), light color, 
-	//and an x,y,z vector that points in the direction of the light
-	glLight(0, RGB15(31,31,31), 0, 0, floattov10(-1.0));
-	
-	//need to set up some material properties since DS does not have them set by default
-	glMaterialf(GL_AMBIENT, RGB15(16,16,16));
-	glMaterialf(GL_DIFFUSE, RGB15(16,16,16));
-	glMaterialf(GL_SPECULAR, BIT(15) or RGB15(8,8,8));
-	glMaterialf(GL_EMISSION, RGB15(16,16,16));
-	
-	//ds uses a table for shinyness..this generates a half-ass one
-	glMaterialShinyness();
-	
-	glPolyFmt(POLY_ALPHA(15) or POLY_CULL_BACK or POLY_FORMAT_LIGHT0);
-
-	glMatrixMode(GL_MODELVIEW);
-	
-	while true do
-	begin
-		DrawGLScene();
-		
-		// flush to screen	
-		glFlush(0);
-		
-		// wait for the screen to refresh
-		swiWaitForVBlank();
-	end;
-	
+  // Setup the Main screen for 3D 
+  videoSetMode(MODE_0_3D);
+  vramSetBankA(VRAM_A_TEXTURE);                        //NEW  must set up some memory for textures
+
+  // initialize the geometry engine
+  glInit();
+  
+  // enable antialiasing
+  glEnable(GL_ANTIALIAS);
+  
+  // setup the rear plane
+  glClearColor(0,0,0,31); // BG must be opaque for AA to work
+  glClearPolyID(63); // BG must have a unique polygon ID for AA to work
+  glClearDepth($7FFF);
+  
+  // enable textures
+  glEnable(GL_TEXTURE_2D);
+  
+  // enable alpha blending
+  glEnable(GL_BLEND);
+
+  // Set our viewport to be the same size as the screen
+  glViewport(0,0,255,191);
+  
+  LoadGLTextures();
+  
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  gluPerspective(70, 256.0 / 192.0, 0.1, 100);
+  glColor3f(1,1,1);
+  
+  //set up a directional ligth arguments are light number (0-3), light color, 
+  //and an x,y,z vector that points in the direction of the light
+  glLight(0, RGB15(31,31,31), 0, 0, floattov10(-1.0));
+  
+  //need to set up some material properties since DS does not have them set by default
+  glMaterialf(GL_AMBIENT, RGB15(16,16,16));
+  glMaterialf(GL_DIFFUSE, RGB15(16,16,16));
+  glMaterialf(GL_SPECULAR, BIT(15) or RGB15(8,8,8));
+  glMaterialf(GL_EMISSION, RGB15(16,16,16));
+  
+  //ds uses a table for shinyness..this generates a half-ass one
+  glMaterialShinyness();
+  
+  glPolyFmt(POLY_ALPHA(15) or POLY_CULL_BACK or POLY_FORMAT_LIGHT0);
+
+  glMatrixMode(GL_MODELVIEW);
+  
+  while true do
+  begin
+    DrawGLScene();
+    
+    // flush to screen  
+    glFlush(0);
+    
+    // wait for the screen to refresh
+    swiWaitForVBlank();
+    scanKeys();
+    pressed := keysDown();
+    if (pressed and KEY_START) <> 0 then break;
+  end;
+  
 end.
 end.

+ 11 - 7
packages/libndsfpc/examples/graphics/3D/nehe/lesson10/lesson10.pp

@@ -226,7 +226,7 @@ end;
 procedure EmitCube();
 procedure EmitCube();
 begin
 begin
   glPushMatrix();
   glPushMatrix();
-  glScalef(0.03, 0.03, 0.03);	
+  glScalef(0.03, 0.03, 0.03); 
   
   
   glRotatef(cubeRot.x, 1.0, 0.0, 0.0);
   glRotatef(cubeRot.x, 1.0, 0.0, 0.0);
   glRotatef(cubeRot.y, 0.0, 1.0, 0.0);
   glRotatef(cubeRot.y, 0.0, 1.0, 0.0);
@@ -313,6 +313,7 @@ var
   lastXY: touchPosition;
   lastXY: touchPosition;
   dx, dy: cint16;
   dx, dy: cint16;
   i: integer;
   i: integer;
+  held: integer;
 begin
 begin
   MyFile := pchar(@World_txt);
   MyFile := pchar(@World_txt);
   // Setup the Main screen for 3D
   // Setup the Main screen for 3D
@@ -383,24 +384,25 @@ begin
   begin
   begin
     //these little button functions are pretty handy
     //these little button functions are pretty handy
     scanKeys();
     scanKeys();
+    held := keysHeld();
 
 
-    if (keysHeld() and KEY_A) <> 0 then lookupdown := lookupdown - 1.0;
+    if (held and KEY_A) <> 0 then lookupdown := lookupdown - 1.0;
 
 
-    if (keysHeld() and KEY_B) <> 0 then lookupdown := lookupdown + 1.0;
+    if (held and KEY_B) <> 0 then lookupdown := lookupdown + 1.0;
 
 
-    if (keysHeld() and KEY_LEFT) <> 0 then
+    if (held and KEY_LEFT) <> 0 then
     begin
     begin
       heading := heading + 1.0;
       heading := heading + 1.0;
       yrot := heading;
       yrot := heading;
     end;
     end;
 
 
-    if (keysHeld() and KEY_RIGHT) <> 0 then
+    if (held and KEY_RIGHT) <> 0 then
     begin
     begin
       heading := heading - 1.0;
       heading := heading - 1.0;
       yrot := heading;
       yrot := heading;
     end;
     end;
 
 
-    if (keysHeld() and KEY_DOWN) <> 0 then
+    if (held and KEY_DOWN) <> 0 then
     begin
     begin
       xpos := xpos + (tsin(heading)) * 0.05;
       xpos := xpos + (tsin(heading)) * 0.05;
       zpos := zpos + (tcos(heading)) * 0.05;
       zpos := zpos + (tcos(heading)) * 0.05;
@@ -412,7 +414,7 @@ begin
       walkbias := tsin(walkbiasangle) / 20.0;
       walkbias := tsin(walkbiasangle) / 20.0;
     end;
     end;
 
 
-    if (keysHeld() and KEY_UP) <> 0 then
+    if (held and KEY_UP) <> 0 then
     begin
     begin
       xpos := xpos - (tsin(heading)) * 0.05;
       xpos := xpos - (tsin(heading)) * 0.05;
       zpos := zpos - (tcos(heading)) * 0.05;
       zpos := zpos - (tcos(heading)) * 0.05;
@@ -434,6 +436,8 @@ begin
 
 
     // wait for the screen to refresh
     // wait for the screen to refresh
     swiWaitForVBlank();
     swiWaitForVBlank();
+    
+    if (held and KEY_START) <> 0 then break;
   end;
   end;
 
 
 end.
 end.

+ 2 - 0
packages/libndsfpc/examples/graphics/3D/nehe/lesson10b/lesson10b.pp

@@ -285,6 +285,8 @@ begin
 
 
     // wait for the screen to refresh
     // wait for the screen to refresh
     swiWaitForVBlank();
     swiWaitForVBlank();
+    
+    if (held and KEY_START) <> 0 then break;
   end;
   end;
 
 
 end.
 end.

+ 145 - 139
packages/libndsfpc/examples/graphics/3D/nehe/lesson11/lesson11.pp

@@ -10,14 +10,14 @@ uses
 
 
 var
 var
   points: array [0..63, 0..31, 0..2] of v16;    // The Array For The Points On The Grid Of Our "Wave"
   points: array [0..63, 0..31, 0..2] of v16;    // The Array For The Points On The Grid Of Our "Wave"
-  wiggle_count: integer = 0;		// Counter Used To Control How Fast Flag Waves
+  wiggle_count: integer = 0;    // Counter Used To Control How Fast Flag Waves
 
 
-  xrot: cfloat;				// X Rotation ( NEW )
-  yrot: cfloat;				// Y Rotation ( NEW )
-  zrot: cfloat;				// Z Rotation ( NEW )
-  hold: v16;				  // Temporarily Holds A Floating Point Value
+  xrot: cfloat;       // X Rotation ( NEW )
+  yrot: cfloat;       // Y Rotation ( NEW )
+  zrot: cfloat;       // Z Rotation ( NEW )
+  hold: v16;          // Temporarily Holds A Floating Point Value
 
 
-  texture: array [0..0] of integer;			// Storage For 3 Textures (only going to use 1 on the DS for this demo)
+  texture: array [0..0] of integer;     // Storage For 3 Textures (only going to use 1 on the DS for this demo)
 
 
 function sin(angle: cfloat): cfloat;
 function sin(angle: cfloat): cfloat;
 var
 var
@@ -35,160 +35,166 @@ begin
   result := f32tofloat(c);
   result := f32tofloat(c);
 end;
 end;
 
 
-function DrawGLScene(): boolean;											// Here's Where We Do All The Drawing
+function DrawGLScene(): boolean;                      // Here's Where We Do All The Drawing
 var
 var
   x, y: integer;
   x, y: integer;
   float_x, float_y, float_xb, float_yb: t16;
   float_x, float_y, float_xb, float_yb: t16;
 begin
 begin
 
 
-	glColor3b(255,255,255);    // set the vertex color
-	
-	glLoadIdentity();									// Reset The View
-
-	glTranslatef(0.0,0.0,-12.0);
-	  
-	glRotatef(xrot,1.0,0.0,0.0);
-	glRotatef(yrot,0.0,1.0,0.0);  
-	glRotatef(zrot,0.0,0.0,1.0);
-
-	glBindTexture(GL_TEXTURE_2D, texture[0]);
-
-	glBegin(GL_QUADS);
-	for x := 0 to 30 do
-	begin
-		for  y := 0 to 30 do
-		begin
-			float_x := inttot16(x) shl 2;
-			float_y := inttot16(y) shl 2;
-			float_xb := inttot16(x+1) shl 2;
-			float_yb := inttot16(y+1) shl 2;
-
-			glTexCoord2t16( float_x, float_y);
-			glVertex3v16( points[x][y][0], points[x][y][1], points[x][y][2] );
-
-			glTexCoord2t16( float_x, float_yb );
-			glVertex3v16( points[x][y+1][0], points[x][y+1][1], points[x][y+1][2] );
-
-			glTexCoord2t16( float_xb, float_yb );
-			glVertex3v16( points[x+1][y+1][0], points[x+1][y+1][1], points[x+1][y+1][2] );
-
-			glTexCoord2t16( float_xb, float_y );
-			glVertex3v16( points[x+1][y][0], points[x+1][y][1], points[x+1][y][2] );
-		end;
-	end;
-	glEnd();
-
-	if ( wiggle_count = 2 ) then
-	begin
-		for y := 0 to 31 do
-		begin
-			hold := points[0][y][2];
-			for x := 0 to 31 do
-			begin
-				points[x][y][2] := points[x+1][y][2];
-			end;
-			points[31][y][2]:=hold;
-		end;
-		wiggle_count := 0;
-	end;
-
-	inc(wiggle_count);
-
-	xrot:=xrot+0.3;
-	yrot:=yrot+0.2;
-	zrot:=zrot+0.4;
-
-	result := true;											// Everything Went OK
+  glColor3b(255,255,255);    // set the vertex color
+  
+  glLoadIdentity();                 // Reset The View
+
+  glTranslatef(0.0,0.0,-12.0);
+    
+  glRotatef(xrot,1.0,0.0,0.0);
+  glRotatef(yrot,0.0,1.0,0.0);  
+  glRotatef(zrot,0.0,0.0,1.0);
+
+  glBindTexture(GL_TEXTURE_2D, texture[0]);
+
+  glBegin(GL_QUADS);
+  for x := 0 to 30 do
+  begin
+    for  y := 0 to 30 do
+    begin
+      float_x := inttot16(x) shl 2;
+      float_y := inttot16(y) shl 2;
+      float_xb := inttot16(x+1) shl 2;
+      float_yb := inttot16(y+1) shl 2;
+
+      glTexCoord2t16( float_x, float_y);
+      glVertex3v16( points[x][y][0], points[x][y][1], points[x][y][2] );
+
+      glTexCoord2t16( float_x, float_yb );
+      glVertex3v16( points[x][y+1][0], points[x][y+1][1], points[x][y+1][2] );
+
+      glTexCoord2t16( float_xb, float_yb );
+      glVertex3v16( points[x+1][y+1][0], points[x+1][y+1][1], points[x+1][y+1][2] );
+
+      glTexCoord2t16( float_xb, float_y );
+      glVertex3v16( points[x+1][y][0], points[x+1][y][1], points[x+1][y][2] );
+    end;
+  end;
+  glEnd();
+
+  if ( wiggle_count = 2 ) then
+  begin
+    for y := 0 to 31 do
+    begin
+      hold := points[0][y][2];
+      for x := 0 to 31 do
+      begin
+        points[x][y][2] := points[x+1][y][2];
+      end;
+      points[31][y][2]:=hold;
+    end;
+    wiggle_count := 0;
+  end;
+
+  inc(wiggle_count);
+
+  xrot:=xrot+0.3;
+  yrot:=yrot+0.2;
+  zrot:=zrot+0.4;
+
+  result := true;                     // Everything Went OK
 
 
 end;
 end;
 
 
 
 
  
  
-function LoadGLTextures(): boolean;									// Load PCX files And Convert To Textures
+function LoadGLTextures(): boolean;                 // Load PCX files And Convert To Textures
 var
 var
-	pcx: sImage;                //////////////(NEW) and different from nehe.
+  pcx: sImage;                //////////////(NEW) and different from nehe.
 begin
 begin
-	//load our texture
-	loadPCX(pcuint8(drunkenlogo_pcx), @pcx);
+  //load our texture
+  loadPCX(pcuint8(drunkenlogo_pcx), @pcx);
 
 
-	image8to16(@pcx);
+  image8to16(@pcx);
 
 
-	glGenTextures(1, @texture[0]);
-	glBindTexture(0, texture[0]);
-	glTexImage2D(0, 0, GL_RGB, TEXTURE_SIZE_128 , TEXTURE_SIZE_128, 0, TEXGEN_TEXCOORD, pcx.image.data8);
+  glGenTextures(1, @texture[0]);
+  glBindTexture(0, texture[0]);
+  glTexImage2D(0, 0, GL_RGB, TEXTURE_SIZE_128 , TEXTURE_SIZE_128, 0, TEXGEN_TEXCOORD, pcx.image.data8);
 
 
-	result := true;
+  result := true;
 end;
 end;
 
 
 procedure InitGL();
 procedure InitGL();
 var
 var
   x, y:integer;
   x, y:integer;
 begin
 begin
-	// Setup the Main screen for 3D 
-	videoSetMode(MODE_0_3D);
-	vramSetBankA(VRAM_A_TEXTURE);                        //NEW  must set up some memory for textures
-	
-	// initialize the geometry engine
-	glInit();
-	
-	// enable textures
-	glEnable(GL_TEXTURE_2D);
-	
-	// Set our viewport to be the same size as the screen
-	glViewPort(0,0,255,191);
-	
-	// enable antialiasing
-	glEnable(GL_ANTIALIAS);
-	
-	// setup the rear plane
-	glClearColor(0,0,0,31); // BG must be opaque for AA to work
-	glClearPolyID(63); // BG must have a unique polygon ID for AA to work
-	glClearDepth($7FFF);
-	
-	LoadGLTextures();
-	
-	glMatrixMode(GL_PROJECTION);
-	glLoadIdentity();
-	gluPerspective(70, 256.0 / 192.0, 0.1, 100);
-	
-	//need to set up some material properties since DS does not have them set by default
-	glMaterialf(GL_AMBIENT, RGB15(31,31,31));
-	glMaterialf(GL_DIFFUSE, RGB15(31,31,31));
-	glMaterialf(GL_SPECULAR, BIT(15) or RGB15(16,16,16));
-	glMaterialf(GL_EMISSION, RGB15(31,31,31));
-	
-	//ds uses a table for shinyness..this generates a half-ass one
-	glMaterialShinyness();
-	
-	//ds specific, several attributes can be set here	
-	glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE );
-	
-
-	for x:=0 to 31 do
-	begin
-		for y:=0 to 31 do
-		begin
-			points[x][y][0] := (inttov16(x) div 4);
-			points[x][y][1] := (inttov16(y) div 4);
-			points[x][y][2] := sinLerp(x * (DEGREES_IN_CIRCLE div 32));
-		end;
-	end;
+  // Setup the Main screen for 3D 
+  videoSetMode(MODE_0_3D);
+  vramSetBankA(VRAM_A_TEXTURE);                        //NEW  must set up some memory for textures
+  
+  // initialize the geometry engine
+  glInit();
+  
+  // enable textures
+  glEnable(GL_TEXTURE_2D);
+  
+  // Set our viewport to be the same size as the screen
+  glViewPort(0,0,255,191);
+  
+  // enable antialiasing
+  glEnable(GL_ANTIALIAS);
+  
+  // setup the rear plane
+  glClearColor(0,0,0,31); // BG must be opaque for AA to work
+  glClearPolyID(63); // BG must have a unique polygon ID for AA to work
+  glClearDepth($7FFF);
+  
+  LoadGLTextures();
+  
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  gluPerspective(70, 256.0 / 192.0, 0.1, 100);
+  
+  //need to set up some material properties since DS does not have them set by default
+  glMaterialf(GL_AMBIENT, RGB15(31,31,31));
+  glMaterialf(GL_DIFFUSE, RGB15(31,31,31));
+  glMaterialf(GL_SPECULAR, BIT(15) or RGB15(16,16,16));
+  glMaterialf(GL_EMISSION, RGB15(31,31,31));
+  
+  //ds uses a table for shinyness..this generates a half-ass one
+  glMaterialShinyness();
+  
+  //ds specific, several attributes can be set here 
+  glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE );
+  
+
+  for x:=0 to 31 do
+  begin
+    for y:=0 to 31 do
+    begin
+      points[x][y][0] := (inttov16(x) div 4);
+      points[x][y][1] := (inttov16(y) div 4);
+      points[x][y][2] := sinLerp(x * (DEGREES_IN_CIRCLE div 32));
+    end;
+  end;
 end;
 end;
 
 
-
-begin	
-	InitGL();
-	
-	glMatrixMode(GL_MODELVIEW);
-
-	while true do
-	begin	
-		DrawGLScene();
-		
-		// flush to screen	
-		glFlush(0);
-		
-		// wait for the screen to refresh
-		swiWaitForVBlank();
-	end;
+var
+  pressed: integer;
+
+begin 
+  InitGL();
+  
+  glMatrixMode(GL_MODELVIEW);
+
+  while true do
+  begin 
+    DrawGLScene();
+    
+    // flush to screen  
+    glFlush(0);
+    
+    // wait for the screen to refresh
+    swiWaitForVBlank();
+
+    scanKeys();
+    pressed := keysDown();
+    if (pressed and KEY_START) <> 0 then break;
+  end;
 end.
 end.

+ 55 - 53
packages/libndsfpc/examples/graphics/Backgrounds/all_in_one/BackgroundAllInOne.pp

@@ -76,7 +76,8 @@ var
     (name: 'Basic';     demos: @basicExamples;      count: sizeof(basicExamples) div sizeof(Demo);),
     (name: 'Basic';     demos: @basicExamples;      count: sizeof(basicExamples) div sizeof(Demo);),
     (name: 'Bitmap';    demos: @bitmapExamples;     count: sizeof(bitmapExamples) div sizeof(Demo);),
     (name: 'Bitmap';    demos: @bitmapExamples;     count: sizeof(bitmapExamples) div sizeof(Demo);),
     (name: 'Scrolling'; demos: @scrollingExamples;  count: sizeof(scrollingExamples) div sizeof(Demo);),
     (name: 'Scrolling'; demos: @scrollingExamples;  count: sizeof(scrollingExamples) div sizeof(Demo);),
-    (name: 'Advanced';  demos: @advancedExamples;   count: sizeof(advancedExamples) div sizeof(Demo);)
+    (name: 'Advanced';  demos: @advancedExamples;   count: sizeof(advancedExamples) div sizeof(Demo);),
+    (name: 'Exit';      demos: nil;                 count: 0;)
   );
   );
 
 
 
 
@@ -85,82 +86,83 @@ var
   selectedCategory: integer = 0;
   selectedCategory: integer = 0;
   selectedDemo: integer = 0;
   selectedDemo: integer = 0;
   selected: boolean = false;
   selected: boolean = false;
-	catCount: integer;
+  catCount: integer;
   demoCount: integer = 0;
   demoCount: integer = 0;
   ci: integer;
   ci: integer;
   di: integer;
   di: integer;
 
 
 begin
 begin
 
 
-	while true do
-	begin
-		catCount := sizeof(categories) div sizeof(Category);
-		demoCount := 0;
+  while true do
+  begin
+    catCount := sizeof(categories) div sizeof(Category);
+    demoCount := 0;
 
 
-		videoSetModeSub(MODE_0_2D);
-		consoleDemoInit();
+    videoSetModeSub(MODE_0_2D);
+    consoleDemoInit();
 
 
-		while not selected do
-		begin
-			scanKeys();
+    while not selected do
+    begin
+      scanKeys();
 
 
-			keys := keysDown();
+      keys := keysDown();
 
 
-			if (keys and KEY_UP) <> 0 then dec(selectedCategory);
-			if (keys and KEY_DOWN) <> 0 then inc(selectedCategory);
-			if (keys and KEY_A) <> 0 then selected := true;
+      if (keys and KEY_UP) <> 0 then dec(selectedCategory);
+      if (keys and KEY_DOWN) <> 0 then inc(selectedCategory);
+      if (keys and KEY_A) <> 0 then selected := true;
 
 
-			if (selectedCategory < 0) then selectedCategory := catCount - 1;
-			if (selectedCategory >= catCount) then selectedCategory := 0;
+      if (selectedCategory < 0) then selectedCategory := catCount - 1;
+      if (selectedCategory >= catCount) then selectedCategory := 0;
 
 
-			swiWaitForVBlank();
-			consoleClear();
-			for ci := 0 to catCount - 1 do
-			begin
+      swiWaitForVBlank();
+      consoleClear();
+      for ci := 0 to catCount - 1 do
+      begin
         if ci = selectedCategory then
         if ci = selectedCategory then
-				  iprintf('%c%d: %s'#10, '*', ci + 1, categories[ci].name)
+          iprintf('%c%d: %s'#10, '*', ci + 1, categories[ci].name)
         else
         else
-				  iprintf('%c%d: %s'#10, ' ', ci + 1, categories[ci].name);
-			end;
-		end;
+          iprintf('%c%d: %s'#10, ' ', ci + 1, categories[ci].name);
+      end;
+    end;
 
 
-		selected := false;
+    selected := false;
 
 
-		demoCount := categories[selectedCategory].count;
+    demoCount := categories[selectedCategory].count;
+    if demoCount = o then exit;
+    
+    while not (selected) do
+    begin
+      scanKeys();
 
 
-		while not (selected) do
-		begin
-			scanKeys();
+      keys := keysDown();
 
 
-			keys := keysDown();
+      if (keys and KEY_UP) <> 0 then dec(selectedDemo);
+      if (keys and KEY_DOWN) <> 0 then inc(selectedDemo);
+      if (keys and KEY_A) <> 0 then selected := true;
+      if (keys and KEY_B) <> 0 then break;
 
 
-			if (keys and KEY_UP) <> 0 then dec(selectedDemo);
-			if (keys and KEY_DOWN) <> 0 then inc(selectedDemo);
-			if (keys and KEY_A) <> 0 then selected := true;
-			if (keys and KEY_B) <> 0 then break;
+      if (selectedDemo < 0) then selectedDemo := demoCount - 1;
+      if (selectedDemo >= demoCount) then selectedDemo := 0;
 
 
-			if (selectedDemo < 0) then selectedDemo := demoCount - 1;
-			if (selectedDemo >= demoCount) then selectedDemo := 0;
+      swiWaitForVBlank();
+      consoleClear();
 
 
-			swiWaitForVBlank();
-			consoleClear();
-
-			for di := 0 to demoCount - 1 do
-			begin
+      for di := 0 to demoCount - 1 do
+      begin
         if di = selectedDemo then
         if di = selectedDemo then
-				  iprintf('%c%d: %s'#10, '*', di + 1, categories[selectedCategory].demos[di].name)
+          iprintf('%c%d: %s'#10, '*', di + 1, categories[selectedCategory].demos[di].name)
         else
         else
           iprintf('%c%d: %s'#10, ' ', di + 1, categories[selectedCategory].demos[di].name);
           iprintf('%c%d: %s'#10, ' ', di + 1, categories[selectedCategory].demos[di].name);
-			end;
-		end;
-
-		if (selected) then
-		begin
-			consoleClear();
-			iprintf('Use arrow keys to scroll'#10'Press ''B'' to exit');
-			categories[selectedCategory].demos[selectedDemo].go();
-		end;
-	end;
+      end;
+    end;
+
+    if (selected) then
+    begin
+      consoleClear();
+      iprintf('Use arrow keys to scroll'#10'Press ''B'' to exit');
+      categories[selectedCategory].demos[selectedDemo].go();
+    end;
+  end;
 
 
 end.
 end.
 
 

+ 1 - 1
packages/libndsfpc/examples/graphics/Makefile.fpc

@@ -3,7 +3,7 @@
 #
 #
 
 
 [target]
 [target]
-dirs=3D Backgrounds Effects Ext_Palettes Printing Sprites
+dirs=3D Backgrounds Effects Ext_Palettes grit Printing Sprites
 
 
 [require]
 [require]
 packages=libndsfpc
 packages=libndsfpc

+ 8 - 2
packages/libndsfpc/examples/graphics/Printing/ansi_console/AnsiConsole.pp

@@ -4,7 +4,9 @@ program AnsiConsole;
 
 
 uses
 uses
   ctypes, nds9;
   ctypes, nds9;
-
+var
+  keys: integer;
+  
 begin
 begin
 
 
   consoleDemoInit();
   consoleDemoInit();
@@ -34,6 +36,10 @@ begin
   iprintf(#27 + '[5C' + 'Column 20');
   iprintf(#27 + '[5C' + 'Column 20');
 
 
   while true do
   while true do
+  begin
     swiWaitForVBlank();
     swiWaitForVBlank();
-
+    scanKeys();
+		keys := keysDown();
+		if (keys and KEY_START) <> 0 then break;
+  end;
 end.
 end.

+ 1 - 1
packages/libndsfpc/examples/graphics/Printing/console_windows/ConsoleWindows.pp

@@ -47,7 +47,7 @@ begin
 	begin
 	begin
 		scanKeys();
 		scanKeys();
 		keys := keysHeld();
 		keys := keysHeld();
-
+    if (keys and KEY_START) <> 0 then break;
 		if (keys and KEY_TOUCH) <> 0 then
 		if (keys and KEY_TOUCH) <> 0 then
 		begin
 		begin
 			touchRead(touch);
 			touchRead(touch);

+ 29 - 24
packages/libndsfpc/examples/graphics/Printing/custom_font/CustomFont.pp

@@ -17,30 +17,35 @@ var
   fontPal: array [0..255] of cushort; cvar; external;
   fontPal: array [0..255] of cushort; cvar; external;
 
 
   console: pPrintConsole;
   console: pPrintConsole;
-	font: ConsoleFont;
-
+  font: ConsoleFont;
+  keys: integer;
 
 
 begin
 begin
-	videoSetModeSub(MODE_0_2D);
-	vramSetBankC(VRAM_C_SUB_BG);
-
-	console := consoleInit(nil, 0, BgType_Text4bpp, BgSize_T_256x256, map_base, tile_base, false, false);
-
-	font.gfx := pcuint16(fontTiles);
-	font.pal := pcuint16(fontPal);
-	font.numChars := 95;
-	font.numColors :=  fontPalLen div 2;
-	font.bpp := 4;
-	font.asciiOffset := 32;
-	font.convertSingleColor := false;
-
-	consoleSetFont(console, @font);
-
-	printf('Custom Font Demo'#10);
-	printf('   by Poffy'#10);
-	printf('modified by WinterMute'#10);
-	printf('for libnds examples'#10);
-
-	while true do
-		swiWaitForVBlank();
+  videoSetModeSub(MODE_0_2D);
+  vramSetBankC(VRAM_C_SUB_BG);
+
+  console := consoleInit(nil, 0, BgType_Text4bpp, BgSize_T_256x256, map_base, tile_base, false, false);
+
+  font.gfx := pcuint16(fontTiles);
+  font.pal := pcuint16(fontPal);
+  font.numChars := 95;
+  font.numColors :=  fontPalLen div 2;
+  font.bpp := 4;
+  font.asciiOffset := 32;
+  font.convertSingleColor := false;
+
+  consoleSetFont(console, @font);
+
+  printf('Custom Font Demo'#10);
+  printf('   by Poffy'#10);
+  printf('modified by WinterMute'#10);
+  printf('for libnds examples'#10);
+
+  while true do
+  begin
+    swiWaitForVBlank();
+    scanKeys();
+		keys := keysDown();
+		if (keys and KEY_START) <> 0 then break;
+  end;
 end.
 end.

+ 25 - 21
packages/libndsfpc/examples/graphics/Printing/print_both_screens/printBothScreens.pp

@@ -6,35 +6,39 @@ uses
   ctypes, nds9;
   ctypes, nds9;
 
 
 var
 var
-	touch: touchPosition;
-	topScreen, bottomScreen: PrintConsole;
+  keys: integer;
+  touch: touchPosition;
+  topScreen, bottomScreen: PrintConsole;
 
 
 begin
 begin
-	videoSetMode(MODE_0_2D);
-	videoSetModeSub(MODE_0_2D);
+  videoSetMode(MODE_0_2D);
+  videoSetModeSub(MODE_0_2D);
 
 
-	vramSetBankA(VRAM_A_MAIN_BG);
-	vramSetBankC(VRAM_C_SUB_BG);
+  vramSetBankA(VRAM_A_MAIN_BG);
+  vramSetBankC(VRAM_C_SUB_BG);
 
 
-	consoleInit(@topScreen, 3,BgType_Text4bpp, BgSize_T_256x256, 31, 0, true, true);
-	consoleInit(@bottomScreen, 3,BgType_Text4bpp, BgSize_T_256x256, 31, 0, false, true);
+  consoleInit(@topScreen, 3,BgType_Text4bpp, BgSize_T_256x256, 31, 0, true, true);
+  consoleInit(@bottomScreen, 3,BgType_Text4bpp, BgSize_T_256x256, 31, 0, false, true);
 
 
-	consoleSelect(@topScreen);
-	
-	iprintf(#10#10#9'Hello DS dev''rs'#10);
-	iprintf(#9'www.drunkencoders.com'#10);
-	iprintf(#9'www.devkitpro.org');
+  consoleSelect(@topScreen);
+  
+  iprintf(#10#10#9'Hello DS dev''rs'#10);
+  iprintf(#9'www.drunkencoders.com'#10);
+  iprintf(#9'www.devkitpro.org');
 
 
   consoleSelect(@bottomScreen);
   consoleSelect(@bottomScreen);
 
 
-	while true do
-	begin
-		touchRead(touch);
-		iprintf(#27'[10;0H' + 'Touch x = %04i, %04i'#10, touch.rawx, touch.px);
-		iprintf('Touch y = %04i, %04i'#10, touch.rawy, touch.py);
-
-		swiWaitForVBlank();
-	end;
+  while true do
+  begin
+    touchRead(touch);
+    iprintf(#27'[10;0H' + 'Touch x = %04i, %04i'#10, touch.rawx, touch.px);
+    iprintf('Touch y = %04i, %04i'#10, touch.rawy, touch.py);
+
+    swiWaitForVBlank();
+    scanKeys();
+    keys := keysDown();
+    if (keys and KEY_START) <> 0 then break;
+  end;
 
 
 end.
 end.
 
 

+ 43 - 42
packages/libndsfpc/examples/graphics/Printing/rotscale_text/RotscaleText.pp

@@ -10,7 +10,7 @@ const
   fontPalLen = 32;
   fontPalLen = 32;
   fontTilesLen = 3072;
   fontTilesLen = 3072;
   tile_base = 0;
   tile_base = 0;
-	map_base = 20;
+  map_base = 20;
 
 
 var
 var
   fontTiles: array [0..767] of cushort; cvar; external;
   fontTiles: array [0..767] of cushort; cvar; external;
@@ -22,66 +22,67 @@ var
   keys: cuint32;
   keys: cuint32;
 
 
   console: pPrintConsole;
   console: pPrintConsole;
-	font: ConsoleFont;
-	bg3: cint;
+  font: ConsoleFont;
+  bg3: cint;
 
 
 begin
 begin
-	videoSetMode(0);	
+  videoSetMode(0);  
 
 
-	videoSetModeSub(MODE_5_2D);	
-	vramSetBankC(VRAM_C_SUB_BG); 
+  videoSetModeSub(MODE_5_2D); 
+  vramSetBankC(VRAM_C_SUB_BG); 
 
 
-	console := consoleInit(nil, 3, BgType_ExRotation, BgSize_ER_256x256, map_base, tile_base, false, false);
+  console := consoleInit(nil, 3, BgType_ExRotation, BgSize_ER_256x256, map_base, tile_base, false, false);
 
 
-	font.gfx := pcuint16(fontTiles);
-	font.pal := pcuint16(fontPal);
-	font.numChars := 95;
-	font.numColors :=  fontPalLen div 2;
-	font.bpp := 8;
-	font.asciiOffset := 32;
-	font.convertSingleColor := false;
+  font.gfx := pcuint16(fontTiles);
+  font.pal := pcuint16(fontPal);
+  font.numChars := 95;
+  font.numColors :=  fontPalLen div 2;
+  font.bpp := 8;
+  font.asciiOffset := 32;
+  font.convertSingleColor := false;
 
 
-	consoleSetFont(console, @font);
+  consoleSetFont(console, @font);
 
 
-	bg3 := console^.bgId;
+  bg3 := console^.bgId;
 
 
-	printf('Custom Font Demo'#10);
-	printf('   by Poffy'#10);
-	printf('modified by WinterMute and Dovoto'#10);
-	printf('for libnds examples'#10);
+  printf('Custom Font Demo'#10);
+  printf('   by Poffy'#10);
+  printf('modified by WinterMute and Dovoto'#10);
+  printf('for libnds examples'#10);
 
 
-	
-	angle := 0;
+  
+  angle := 0;
   scrollX := 0;
   scrollX := 0;
   scrollY := 0;
   scrollY := 0;
   scaleX := intToFixed(1,8);
   scaleX := intToFixed(1,8);
   scaleY := intToFixed(1,8);
   scaleY := intToFixed(1,8);
 
 
-	while true do
-	begin
-		scanKeys();
-		keys := keysHeld();
+  while true do
+  begin
+    scanKeys();
+    keys := keysHeld();
+    if (keys and KEY_START) <> 0 then break;
+    
+    if ( keys and KEY_L ) <> 0 then angle := angle + 64;
+    if ( keys and KEY_R )  <> 0 then angle := angle - 64;
 
 
-		if ( keys and KEY_L ) <> 0 then angle := angle + 64;
-		if ( keys and KEY_R )  <> 0 then angle := angle - 64;
+    if ( keys and KEY_LEFT )  <> 0 then scrollX := scrollX + 1;
+    if ( keys and KEY_RIGHT )  <> 0 then scrollX := scrollX - 1;
+    if ( keys and KEY_UP )  <> 0 then scrollY := scrollY + 1;
+    if ( keys and KEY_DOWN )  <> 0 then scrollY := scrollY - 1;
 
 
-		if ( keys and KEY_LEFT )  <> 0 then scrollX := scrollX + 1;
-		if ( keys and KEY_RIGHT )  <> 0 then scrollX := scrollX - 1;
-		if ( keys and KEY_UP )  <> 0 then scrollY := scrollY + 1;
-		if ( keys and KEY_DOWN )  <> 0 then scrollY := scrollY - 1;
+    if ( keys and KEY_A )  <> 0 then scaleX := scaleX + 1;
+    if ( keys and KEY_B )  <> 0 then scaleX := scaleX - 1;
 
 
-		if ( keys and KEY_A )  <> 0 then scaleX := scaleX + 1;
-		if ( keys and KEY_B )  <> 0 then scaleX := scaleX - 1;
+    if( keys and KEY_X )  <> 0 then scaleY := scaleY + 1;
+    if( keys and KEY_Y )  <> 0 then scaleY := scaleY - 1;
 
 
-		if( keys and KEY_X )  <> 0 then scaleY := scaleY + 1;
-		if( keys and KEY_Y )  <> 0 then scaleY := scaleY - 1;
+    swiWaitForVBlank();
 
 
-		swiWaitForVBlank();
 
 
-
-		bgSetRotateScale(bg3, angle, scaleX, scaleY);
-		bgSetScroll(bg3, scrollX, scrollY);
-		bgUpdate();
-	end;
+    bgSetRotateScale(bg3, angle, scaleX, scaleY);
+    bgSetScroll(bg3, scrollX, scrollY);
+    bgUpdate();
+  end;
 
 
 end.
 end.

+ 7 - 4
packages/libndsfpc/examples/graphics/Sprites/allocation_test/AllocationTest.pp

@@ -180,6 +180,7 @@ end;
 
 
 var
 var
   memUsageTemp: longint;// = $FFFFFFFF;
   memUsageTemp: longint;// = $FFFFFFFF;
+  keys: integer;
 
 
 begin
 begin
   randomize;
   randomize;
@@ -226,7 +227,9 @@ begin
 		updateSprites();
 		updateSprites();
 
 
 		swiWaitForVBlank();
 		swiWaitForVBlank();
-		
+    scanKeys();
+		keys := keysDown();
+		if (keys and KEY_START) <> 0 then break;
 		//api: updates real oam memory 
 		//api: updates real oam memory 
 		oamUpdate(oam^);
 		oamUpdate(oam^);
 
 
@@ -236,9 +239,9 @@ begin
 
 
 		consoleClear();
 		consoleClear();
 
 
-    printf('Memory usage: %i %i%% '#10,  spriteMemoryUsage, 100 * spriteMemoryUsage div (spriteMemSize));
-    printf('Percentage fail: %i%% '#10, oomCount * 100 div allocationCount);
-    printf('Lowest Usage at fail %i %i%% '#10, memUsageTemp, 100 * memUsageTemp div (spriteMemSize));
+    printf('Memory usage: %li %li%% '#10,  spriteMemoryUsage, 100 * spriteMemoryUsage div (spriteMemSize));
+    printf('Percentage fail: %li%% '#10, oomCount * 100 div allocationCount);
+    printf('Lowest Usage at fail %li %li%% '#10, memUsageTemp, 100 * memUsageTemp div (spriteMemSize));
   end;
   end;
 end.
 end.
 		
 		

+ 5 - 0
packages/libndsfpc/examples/graphics/Sprites/bitmap_sprites/BitmapSprites.pp

@@ -21,6 +21,7 @@ type
   end;
   end;
 
 
 var
 var
+  keys: integer;
   sprites: array [0..2] of TMySprite;
   sprites: array [0..2] of TMySprite;
   i, angle: integer;
   i, angle: integer;
 
 
@@ -119,6 +120,10 @@ begin
 
 
     swiWaitForVBlank();
     swiWaitForVBlank();
 
 
+   
+    scanKeys();
+    keys := keysDown();
+    if (keys and KEY_START) <> 0 then break;
     //send the updates to the hardware
     //send the updates to the hardware
     oamUpdate(oamSub);
     oamUpdate(oamSub);
   end;
   end;

+ 149 - 117
packages/libndsfpc/examples/graphics/Sprites/fire_and_sprites/FireAndSprites.pp

@@ -16,10 +16,10 @@ var
 
 
 type
 type
   TSprite = record
   TSprite = record
-    x, y: cint;				//location
-    dx, dy: cint;			//speed
+    x, y: cint;       //location
+    dx, dy: cint;     //speed
     oam: PSpriteEntry;
     oam: PSpriteEntry;
-    gfxID: integer; 				//graphics location
+    gfxID: integer;         //graphics location
   end;
   end;
   PSprite = ^TSprite;
   PSprite = ^TSprite;
 
 
@@ -30,7 +30,7 @@ var
 begin
 begin
   x := sp.x shr 8;
   x := sp.x shr 8;
   y := sp.y shr 8;
   y := sp.y shr 8;
-	sp.oam^.y := y;
+  sp.oam^.y := y;
   sp.oam^.x := x;
   sp.oam^.x := x;
 end;
 end;
 
 
@@ -48,42 +48,86 @@ begin
   //dmaCopy(@OAMCopySub, OAM_SUB, 128 * sizeof(SpriteEntry));
   //dmaCopy(@OAMCopySub, OAM_SUB, 128 * sizeof(SpriteEntry));
 end;
 end;
 
 
+// HSV to RGB conversion function with only integer math
+function hsl2rgb(hue, sat, lum: cuint8): cuint16;
+var
+  v: cint;
+  m: cint;
+  sextant: cint;
+  fract, vsf, mid1, mid2: cint;
+begin
+  if lum < 128 then
+    v := lum * (256 + sat) shr 8
+  else
+    v := (((lum + sat) shl 8) - lum * sat) shr 8;
+  
+  if (v <= 0) then
+    hsl2rgb := RGB8(0,0,0)
+  else 
+ begin
+
+    m := lum + lum - v;
+    hue := hue * 6;
+    sextant := hue shr 8;
+    fract := hue - (sextant shl 8);
+    vsf := v * fract * (v - m) div v shr 8;
+    mid1 := m + vsf;
+    mid2 := v - vsf;
+    case sextant of
+      0: hsl2rgb := RGB8(v,mid1,m); 
+      1: hsl2rgb := RGB8(mid2,v,m);
+      2: hsl2rgb := RGB8(m,v,mid1); 
+      3: hsl2rgb := RGB8(m,mid2,v); 
+      4: hsl2rgb := RGB8(mid1,m,v); 
+    else hsl2rgb := RGB8(v,m,mid2);
+    end; 
+  end;
+end;
+
+const
+  WIDTH = 256;   
+  HEIGHT = 196;
 
 
 var
 var
-	back, front: pcuint16;
+  fire: array [0..HEIGHT, 0..WIDTH - 1] of cuint8;
+
+  x, y: integer;
+  w: integer = WIDTH; 
+  h: integer = HEIGHT;
   sprites: array [0..NUM_SPRITES - 1] of TSprite;
   sprites: array [0..NUM_SPRITES - 1] of TSprite;
   i, delta: integer;
   i, delta: integer;
   ix, iy: integer;
   ix, iy: integer;
-  screen: integer;
+  
+  temp: cint;
+  pressed: integer;
+  
   map0, map1: pcuint16;
   map0, map1: pcuint16;
   red: cuint16;
   red: cuint16;
   ball: sImage;
   ball: sImage;
 
 
 begin
 begin
   randomize;
   randomize;
-	back := VRAM_A;
-	front := VRAM_B;
 
 
-	i := 0;
+  i := 0;
   delta := 0;
   delta := 0;
-	ix := 0;
-	iy := 0;
-	screen := 1;
-	map0 := pcuint16(SCREEN_BASE_BLOCK_SUB(1));
-	map1 := pcuint16(SCREEN_BASE_BLOCK_SUB(2));
+  ix := 0;
+  iy := 0;
 
 
-	//set main display to render directly from the frame buffer
-	videoSetMode(MODE_FB1);
+  map0 := pcuint16(SCREEN_BASE_BLOCK_SUB(1));
+  map1 := pcuint16(SCREEN_BASE_BLOCK_SUB(2));
 
 
-	//set up the sub display
-	videoSetModeSub(MODE_0_2D or
+  //set main display to render 256 color bitmap
+  videoSetMode(MODE_5_2D or DISPLAY_BG3_ACTIVE);
+
+  //set up the sub display
+  videoSetModeSub(MODE_0_2D or
           DISPLAY_SPR_1D_LAYOUT or
           DISPLAY_SPR_1D_LAYOUT or
           DISPLAY_SPR_ACTIVE or
           DISPLAY_SPR_ACTIVE or
           DISPLAY_BG0_ACTIVE or
           DISPLAY_BG0_ACTIVE or
           DISPLAY_BG1_ACTIVE );
           DISPLAY_BG1_ACTIVE );
 
 
-	//vram banks are somewhat complex
-	vramSetPrimaryBanks(VRAM_A_LCD, VRAM_B_LCD, VRAM_C_SUB_BG, VRAM_D_SUB_SPRITE);
+  //vram banks are somewhat complex
+  vramSetPrimaryBanks(VRAM_A_MAIN_BG_0x06000000, VRAM_B_MAIN_SPRITE, VRAM_C_SUB_BG, VRAM_D_SUB_SPRITE);
 
 
   //load our ball pcx file into an image
   //load our ball pcx file into an image
   loadPCX(pcuint8(ball_pcx), @ball);
   loadPCX(pcuint8(ball_pcx), @ball);
@@ -98,7 +142,7 @@ begin
   for i := 0 to 32*16 - 1 do
   for i := 0 to 32*16 - 1 do
     SPRITE_GFX_SUB[i] := cuint32(ball.image.data16[i]);
     SPRITE_GFX_SUB[i] := cuint32(ball.image.data16[i]);
 
 
-	//turn off sprites
+  //turn off sprites
   initOAM();
   initOAM();
 
 
   for i := 0 to NUM_SPRITES - 1 do
   for i := 0 to NUM_SPRITES - 1 do
@@ -123,113 +167,101 @@ begin
     sprites[i].oam^.attribute[2] := sprites[i].gfxID;
     sprites[i].oam^.attribute[2] := sprites[i].gfxID;
   end;
   end;
 
 
-	//set up two backgrounds to scroll around
-	REG_BG0CNT_SUB^ := BG_COLOR_256 or (1 shl MAP_BASE_SHIFT);
-	REG_BG1CNT_SUB^ := BG_COLOR_256 or (2 shl MAP_BASE_SHIFT);
-
-	BG_PALETTE_SUB[0] := RGB15(10,10,10);
-	BG_PALETTE_SUB[1] := RGB15(0,16,0);
-	BG_PALETTE_SUB[2] := RGB15(0,0,31);
-
-	//load the maps with alternating tiles (0,1 for bg0 and 0,2 for bg1)
-	for iy := 0 to 31 do
-		for ix := 0 to 31 do
-		begin
-			map0[iy * 32 + ix] := (ix xor iy) and 1;
-			map1[iy * 32 + ix] := ((ix xor iy) and 1) shl 1;
-		end;
+  //set up two backgrounds to scroll around
+  REG_BG0CNT_SUB^ := BG_COLOR_256 or (1 shl MAP_BASE_SHIFT);
+  REG_BG1CNT_SUB^ := BG_COLOR_256 or (2 shl MAP_BASE_SHIFT);
 
 
-	//fill 2 tiles with different colors
-	for i := 0 to (64 div 2) - 1 do
-	begin
-		BG_GFX_SUB[i+32] := $0101;
-		BG_GFX_SUB[i+32+32] := $0202;
-	end;
+  BG_PALETTE_SUB[0] := RGB15(10,10,10);
+  BG_PALETTE_SUB[1] := RGB15(0,16,0);
+  BG_PALETTE_SUB[2] := RGB15(0,0,31);
 
 
-	while (true) do
-	begin
-		//scroll the background
-		REG_BG0HOFS^ := delta;
-		inc(delta);
-		REG_BG0VOFS^ := delta;
+  //load the maps with alternating tiles (0,1 for bg0 and 0,2 for bg1)
+  for iy := 0 to 31 do
+    for ix := 0 to 31 do
+    begin
+      map0[iy * 32 + ix] := (ix xor iy) and 1;
+      map1[iy * 32 + ix] := ((ix xor iy) and 1) shl 1;
+    end;
 
 
-		//move the sprites
-		for i := 0 to NUM_SPRITES - 1 do
-		begin
-			sprites[i].x := sprites[i].x + sprites[i].dx;
-			sprites[i].y := sprites[i].y + sprites[i].dy;
-
-			//check for collision with the screen boundries
-			if (sprites[i].x < (1 shl 8)) or (sprites[i].x > (247 shl 8)) then
-				sprites[i].dx := -sprites[i].dx;
-
-			if (sprites[i].y < (1 shl 8)) or (sprites[i].y > (182 shl 8)) then
-				sprites[i].dy := -sprites[i].dy;
-
-			//reposition the sprites
-			MoveSprite(sprites[i]);
-		end;
-
-
-
-		//do the plasma/fire
-		for ix := 0 to SCREEN_WIDTH - 1 do
-		begin
-			back[ix + SCREEN_WIDTH * (SCREEN_HEIGHT - 1)] := random($FFFF);
-			back[ix + SCREEN_WIDTH * (SCREEN_HEIGHT - 2)] := random($FFFF);
-		end;
+  //fill 2 tiles with different colors
+  for i := 0 to (64 div 2) - 1 do
+  begin
+    BG_GFX_SUB[i+32] := $0101;
+    BG_GFX_SUB[i+32+32] := $0202;
+  end;
 
 
-		back := back + 1;
+	FillChar(fire, 256*192, 0);
 
 
-		for iy := 1 to SCREEN_HEIGHT - 3 do
-		begin
-			for ix := 1 to SCREEN_WIDTH - 2 do
-			begin
-				red := 0;
+	// Set up palette for fire effect
+	for x := 0 to 256 do
+  begin 
+    if x * 2 > 255 then
+      BG_PALETTE[x] := hsl2rgb(x div 3,255, 255)
+    else
+      BG_PALETTE[x] := hsl2rgb(x div 3, 255, x * 2);
+  end;
 
 
-				red := red + front[0];
-				red := red + front[2];
+	// Set up background for 8bit bitmap
+	REG_BG3CNT^ := BG_BMP8_256x256;
 
 
-				front := front + SCREEN_WIDTH;
+	// and 1:1 scaling
+	REG_BG3PA^ := 1 shl 8;
+	REG_BG3PB^ := 0; // BG SCALING X
+	REG_BG3PC^ := 0; // BG SCALING Y
+	REG_BG3PD^ := 1 shl 8;
+	REG_BG3X^ := 0;
+	REG_BG3Y^ := 0;
 
 
-				red := red + front[0];
-				red := red + front[1];
-				red := red + front[2];
+  while (true) do
+  begin
+    //scroll the background
+    REG_BG0HOFS_SUB^ := delta;
+    inc(delta);
+    REG_BG0VOFS_SUB^ := delta;
+
+    //move the sprites
+    for i := 0 to NUM_SPRITES - 1 do
+    begin
+      sprites[i].x := sprites[i].x + sprites[i].dx;
+      sprites[i].y := sprites[i].y + sprites[i].dy;
+
+      //check for collision with the screen boundries
+      if (sprites[i].x < (1 shl 8)) or (sprites[i].x > (247 shl 8)) then
+        sprites[i].dx := -sprites[i].dx;
+
+      if (sprites[i].y < (1 shl 8)) or (sprites[i].y > (182 shl 8)) then
+        sprites[i].dy := -sprites[i].dy;
+
+      //reposition the sprites
+      MoveSprite(sprites[i]);
+    end;
+
+ 
+
+    //do the plasma/fire
+		//randomize the bottom row of the fire buffer
+		for x := 0 to w - 1 do
+      //fire[h-1, x] := abs(32768 + random(high(cint))) mod 256;
+      fire[h-1, x] := abs(32768 + random(32767)) mod 256;
+    
+		//do the fire calculations for every pixel, from top to bottom
+		for y := 0 to h - 2 do
+			for x := 0 to w - 1 do
+      begin
+        temp := fire[y + 1, (x - 1) mod w] + fire[y + 2, (x) mod w] + fire[y + 1, (x + 1) mod w] + fire[y + 3, (x) mod w];
+			end;
 
 
-				front := front + SCREEN_WIDTH;
+		dmaCopy(@fire, pointer($06000000), 256 * 192);
+  
+    swiWaitForVBlank();
 
 
-				red := red + front[0];
-				red := red + front[1];
-				red := red + front[2];
+   
+    scanKeys();
+		pressed := keysDown();
+		if (pressed and KEY_START) <> 0 then break;
 
 
-				front := front - ((2 * SCREEN_WIDTH) - 1);
+    updateOAM();
 
 
-				back[0] :=  (red shr 3);
-		    back := back + 1;
-			end;
-		  back := back + 2;
-			front := front + 2;
-
-		end;
-
-		swiWaitForVBlank();
-
-		updateOAM();
-
-		//flip screens
-		if (screen) <> 0 then
-		begin
-			videoSetMode(MODE_FB1);
-			front := VRAM_B;
-			back := VRAM_A;
-			screen := 0;
-		end else
-		begin
-			videoSetMode(MODE_FB0);
-			front := VRAM_A;
-			back := VRAM_B;
-			screen := 1;
-		end;
-	end;
+  end;
 end.
 end.
 
 

BIN
packages/libndsfpc/examples/graphics/Sprites/fire_and_sprites/data/ball.pcx


+ 1679 - 0
packages/libndsfpc/examples/graphics/grit/256colorTilemap/Makefile

@@ -0,0 +1,1679 @@
+#
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2017-02-13 rev 35434]
+#
+default: all
+MAKEFILETARGETS=arm-nds
+BSDs = freebsd netbsd openbsd darwin dragonfly
+UNIXs = linux $(BSDs) solaris qnx haiku aix
+LIMIT83fs = go32v2 os2 emx watcom msdos
+OSNeedsComspecToRunBatch = go32v2 watcom
+FORCE:
+.PHONY: FORCE
+override PATH:=$(patsubst %/,%,$(subst \,/,$(PATH)))
+ifneq ($(findstring darwin,$(OSTYPE)),)
+inUnix=1 #darwin
+SEARCHPATH:=$(filter-out .,$(subst :, ,$(PATH)))
+else
+ifeq ($(findstring ;,$(PATH)),)
+inUnix=1
+SEARCHPATH:=$(filter-out .,$(subst :, ,$(PATH)))
+else
+SEARCHPATH:=$(subst ;, ,$(PATH))
+endif
+endif
+SEARCHPATH+=$(patsubst %/,%,$(subst \,/,$(dir $(MAKE))))
+PWD:=$(strip $(wildcard $(addsuffix /pwd.exe,$(SEARCHPATH))))
+ifeq ($(PWD),)
+PWD:=$(strip $(wildcard $(addsuffix /pwd,$(SEARCHPATH))))
+ifeq ($(PWD),)
+$(error You need the GNU utils package to use this Makefile)
+else
+PWD:=$(firstword $(PWD))
+SRCEXEEXT=
+endif
+else
+PWD:=$(firstword $(PWD))
+SRCEXEEXT=.exe
+endif
+ifndef inUnix
+ifeq ($(OS),Windows_NT)
+inWinNT=1
+else
+ifdef OS2_SHELL
+inOS2=1
+endif
+endif
+else
+ifneq ($(findstring cygdrive,$(PATH)),)
+inCygWin=1
+endif
+endif
+ifdef inUnix
+SRCBATCHEXT=.sh
+else
+ifdef inOS2
+SRCBATCHEXT=.cmd
+else
+SRCBATCHEXT=.bat
+endif
+endif
+ifdef COMSPEC
+ifneq ($(findstring $(OS_SOURCE),$(OSNeedsComspecToRunBatch)),)
+ifndef RUNBATCH
+RUNBATCH=$(COMSPEC) /C
+endif
+endif
+endif
+ifdef inUnix
+PATHSEP=/
+else
+PATHSEP:=$(subst /,\,/)
+ifdef inCygWin
+PATHSEP=/
+endif
+endif
+ifdef PWD
+BASEDIR:=$(subst \,/,$(shell $(PWD)))
+ifdef inCygWin
+ifneq ($(findstring /cygdrive/,$(BASEDIR)),)
+BASENODIR:=$(patsubst /cygdrive%,%,$(BASEDIR))
+BASEDRIVE:=$(firstword $(subst /, ,$(BASENODIR)))
+BASEDIR:=$(subst /cygdrive/$(BASEDRIVE)/,$(BASEDRIVE):/,$(BASEDIR))
+endif
+endif
+else
+BASEDIR=.
+endif
+ifdef inOS2
+ifndef ECHO
+ECHO:=$(strip $(wildcard $(addsuffix /gecho$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO:=$(strip $(wildcard $(addsuffix /echo$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO=echo
+else
+ECHO:=$(firstword $(ECHO))
+endif
+else
+ECHO:=$(firstword $(ECHO))
+endif
+endif
+export ECHO
+endif
+override OS_TARGET_DEFAULT=nds
+override CPU_TARGET_DEFAULT=arm
+override DEFAULT_FPCDIR=../../../../../..
+ifndef FPC
+ifdef PP
+FPC=$(PP)
+endif
+endif
+ifndef FPC
+FPCPROG:=$(strip $(wildcard $(addsuffix /fpc$(SRCEXEEXT),$(SEARCHPATH))))
+ifneq ($(FPCPROG),)
+FPCPROG:=$(firstword $(FPCPROG))
+ifneq ($(CPU_TARGET),)
+FPC:=$(shell $(FPCPROG) -P$(CPU_TARGET) -PB)
+else
+FPC:=$(shell $(FPCPROG) -PB)
+endif
+ifneq ($(findstring Error,$(FPC)),)
+override FPC=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
+else
+ifeq ($(strip $(wildcard $(FPC))),)
+FPC:=$(firstword $(FPCPROG))
+endif
+endif
+else
+override FPC=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
+endif
+endif
+override FPC:=$(subst $(SRCEXEEXT),,$(FPC))
+override FPC:=$(subst \,/,$(FPC))$(SRCEXEEXT)
+FOUNDFPC:=$(strip $(wildcard $(FPC)))
+ifeq ($(FOUNDFPC),)
+FOUNDFPC=$(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH))))
+ifeq ($(FOUNDFPC),)
+$(error Compiler $(FPC) not found)
+endif
+endif
+ifndef FPC_COMPILERINFO
+FPC_COMPILERINFO:=$(shell $(FPC) -iVSPTPSOTO)
+endif
+ifndef FPC_VERSION
+FPC_VERSION:=$(word 1,$(FPC_COMPILERINFO))
+endif
+export FPC FPC_VERSION FPC_COMPILERINFO
+unexport CHECKDEPEND ALLDEPENDENCIES
+ifndef CPU_TARGET
+ifdef CPU_TARGET_DEFAULT
+CPU_TARGET=$(CPU_TARGET_DEFAULT)
+endif
+endif
+ifndef OS_TARGET
+ifdef OS_TARGET_DEFAULT
+OS_TARGET=$(OS_TARGET_DEFAULT)
+endif
+endif
+ifndef CPU_SOURCE
+CPU_SOURCE:=$(word 2,$(FPC_COMPILERINFO))
+endif
+ifndef CPU_TARGET
+CPU_TARGET:=$(word 3,$(FPC_COMPILERINFO))
+endif
+ifndef OS_SOURCE
+OS_SOURCE:=$(word 4,$(FPC_COMPILERINFO))
+endif
+ifndef OS_TARGET
+OS_TARGET:=$(word 5,$(FPC_COMPILERINFO))
+endif
+FULL_TARGET=$(CPU_TARGET)-$(OS_TARGET)
+FULL_SOURCE=$(CPU_SOURCE)-$(OS_SOURCE)
+ifeq ($(CPU_TARGET),armeb)
+ARCH=arm
+override FPCOPT+=-Cb
+else
+ifeq ($(CPU_TARGET),armel)
+ARCH=arm
+override FPCOPT+=-CaEABI
+else
+ARCH=$(CPU_TARGET)
+endif
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+ifeq ($(SUBARCH),)
+$(error When compiling for arm-embedded, a sub-architecture (e.g. SUBARCH=armv4t or SUBARCH=armv7m) must be defined)
+endif
+override FPCOPT+=-Cp$(SUBARCH)
+endif
+ifeq ($(FULL_TARGET),mipsel-embedded)
+ifeq ($(SUBARCH),)
+$(error When compiling for mipsel-embedded, a sub-architecture (e.g. SUBARCH=pic32mx) must be defined)
+endif
+override FPCOPT+=-Cp$(SUBARCH)
+endif
+ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
+TARGETSUFFIX=$(OS_TARGET)
+SOURCESUFFIX=$(OS_SOURCE)
+else
+ifneq ($(findstring $(OS_TARGET),$(LIMIT83fs)),)
+TARGETSUFFIX=$(OS_TARGET)
+else
+TARGETSUFFIX=$(FULL_TARGET)
+endif
+SOURCESUFFIX=$(FULL_SOURCE)
+endif
+ifneq ($(FULL_TARGET),$(FULL_SOURCE))
+CROSSCOMPILE=1
+endif
+ifeq ($(findstring makefile,$(MAKECMDGOALS)),)
+ifeq ($(findstring $(FULL_TARGET),$(MAKEFILETARGETS)),)
+$(error The Makefile doesn't support target $(FULL_TARGET), please run fpcmake first)
+endif
+endif
+ifneq ($(findstring $(OS_TARGET),$(BSDs)),)
+BSDhier=1
+endif
+ifeq ($(OS_TARGET),linux)
+linuxHier=1
+endif
+ifndef CROSSCOMPILE
+BUILDFULLNATIVE=1
+export BUILDFULLNATIVE
+endif
+ifdef BUILDFULLNATIVE
+BUILDNATIVE=1
+export BUILDNATIVE
+endif
+export OS_TARGET OS_SOURCE ARCH CPU_TARGET CPU_SOURCE FULL_TARGET FULL_SOURCE TARGETSUFFIX SOURCESUFFIX CROSSCOMPILE
+ifdef FPCDIR
+override FPCDIR:=$(subst \,/,$(FPCDIR))
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=wrong
+endif
+else
+override FPCDIR=wrong
+endif
+ifdef DEFAULT_FPCDIR
+ifeq ($(FPCDIR),wrong)
+override FPCDIR:=$(subst \,/,$(DEFAULT_FPCDIR))
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=wrong
+endif
+endif
+endif
+ifeq ($(FPCDIR),wrong)
+ifdef inUnix
+override FPCDIR=/usr/local/lib/fpc/$(FPC_VERSION)
+ifeq ($(wildcard $(FPCDIR)/units),)
+override FPCDIR=/usr/lib/fpc/$(FPC_VERSION)
+endif
+else
+override FPCDIR:=$(subst /$(FPC),,$(firstword $(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH))))))
+override FPCDIR:=$(FPCDIR)/..
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR:=$(FPCDIR)/..
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR:=$(BASEDIR)
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=c:/pp
+endif
+endif
+endif
+endif
+endif
+ifndef CROSSBINDIR
+CROSSBINDIR:=$(wildcard $(FPCDIR)/bin/$(TARGETSUFFIX))
+endif
+ifneq ($(findstring $(OS_TARGET),darwin iphonesim),)
+ifeq ($(OS_SOURCE),darwin)
+DARWIN2DARWIN=1
+endif
+endif
+ifndef BINUTILSPREFIX
+ifndef CROSSBINDIR
+ifdef CROSSCOMPILE
+ifneq ($(OS_TARGET),msdos)
+ifndef DARWIN2DARWIN
+ifneq ($(CPU_TARGET),jvm)
+BINUTILSPREFIX=$(CPU_TARGET)-$(OS_TARGET)-
+ifeq ($(OS_TARGET),android)
+ifeq ($(CPU_TARGET),arm)
+BINUTILSPREFIX=arm-linux-androideabi-
+else
+ifeq ($(CPU_TARGET),i386)
+BINUTILSPREFIX=i686-linux-android-
+else
+ifeq ($(CPU_TARGET),mipsel)
+BINUTILSPREFIX=mipsel-linux-android-
+endif
+endif
+endif
+endif
+endif
+endif
+else
+BINUTILSPREFIX=$(OS_TARGET)-
+endif
+endif
+endif
+endif
+UNITSDIR:=$(wildcard $(FPCDIR)/units/$(TARGETSUFFIX))
+ifeq ($(UNITSDIR),)
+UNITSDIR:=$(wildcard $(FPCDIR)/units/$(OS_TARGET))
+endif
+PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages $(FPCDIR)/packages/base $(FPCDIR)/packages/extra)
+ifndef FPCFPMAKE
+ifdef CROSSCOMPILE
+ifeq ($(strip $(wildcard $(addsuffix /compiler/ppc$(SRCEXEEXT),$(FPCDIR)))),)
+FPCPROG:=$(strip $(wildcard $(addsuffix /fpc$(SRCEXEEXT),$(SEARCHPATH))))
+ifneq ($(FPCPROG),)
+FPCPROG:=$(firstword $(FPCPROG))
+FPCFPMAKE:=$(shell $(FPCPROG) -PB)
+ifeq ($(strip $(wildcard $(FPCFPMAKE))),)
+FPCFPMAKE:=$(firstword $(FPCPROG))
+endif
+else
+override FPCFPMAKE=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
+endif
+else
+FPCFPMAKE=$(strip $(wildcard $(addsuffix /compiler/ppc$(SRCEXEEXT),$(FPCDIR))))
+FPMAKE_SKIP_CONFIG=-n
+export FPCFPMAKE
+export FPMAKE_SKIP_CONFIG
+endif
+else
+FPMAKE_SKIP_CONFIG=-n
+FPCFPMAKE=$(FPC)
+endif
+endif
+BIN = bin
+BUILD = build
+DATA = data
+FILESYSTEM = filesystem
+GFX = gfx
+INC = inc
+AUDIO_FILES = $(foreach dir, $(notdir $(wildcard audio/*.*)), $(CURDIR)/audio/$(dir))
+GFX_FILES   = $(foreach dir, $(GFX), $(notdir $(wildcard $(dir)/*.bmp $(dir)/*.png)))
+BIN_FILES   = $(foreach dir, $(DATA), $(notdir $(wildcard $(dir)/*)))
+GBFS_FILES  = $(foreach dir, GBFS, $(notdir $(wildcard $(dir)/*)))
+ifeq ($(FULL_TARGET),arm-nds)
+override TARGET_PROGRAMS+=tilemap_256_color
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override CLEAN_UNITS+=*
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override CLEAN_FILES+=*.elf *.o *.s *.nds *.nef *.h *.bin *.map $(BUILD)/* $(INC)/* $(BIN)/*
+endif
+override INSTALL_FPCPACKAGE=y
+ifeq ($(FULL_TARGET),arm-nds)
+override COMPILER_OPTIONS+=-Xm
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override COMPILER_TARGETDIR+=$(BIN)
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override COMPILER_UNITTARGETDIR+=$(BUILD)
+endif
+ifdef REQUIRE_UNITSDIR
+override UNITSDIR+=$(REQUIRE_UNITSDIR)
+endif
+ifdef REQUIRE_PACKAGESDIR
+override PACKAGESDIR+=$(REQUIRE_PACKAGESDIR)
+endif
+ifdef ZIPINSTALL
+ifneq ($(findstring $(OS_TARGET),$(UNIXs)),)
+UNIXHier=1
+endif
+else
+ifneq ($(findstring $(OS_SOURCE),$(UNIXs)),)
+UNIXHier=1
+endif
+endif
+ifndef INSTALL_PREFIX
+ifdef PREFIX
+INSTALL_PREFIX=$(PREFIX)
+endif
+endif
+ifndef INSTALL_PREFIX
+ifdef UNIXHier
+INSTALL_PREFIX=/usr/local
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_BASEDIR:=/pp
+else
+INSTALL_BASEDIR:=/$(PACKAGE_NAME)
+endif
+endif
+endif
+export INSTALL_PREFIX
+ifdef INSTALL_FPCSUBDIR
+export INSTALL_FPCSUBDIR
+endif
+ifndef DIST_DESTDIR
+DIST_DESTDIR:=$(BASEDIR)
+endif
+export DIST_DESTDIR
+ifndef COMPILER_UNITTARGETDIR
+ifdef PACKAGEDIR_MAIN
+COMPILER_UNITTARGETDIR=$(PACKAGEDIR_MAIN)/units/$(TARGETSUFFIX)
+else
+COMPILER_UNITTARGETDIR=units/$(TARGETSUFFIX)
+endif
+endif
+ifndef COMPILER_TARGETDIR
+COMPILER_TARGETDIR=.
+endif
+ifndef INSTALL_BASEDIR
+ifdef UNIXHier
+ifdef INSTALL_FPCPACKAGE
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)/lib/fpc/$(FPC_VERSION)
+else
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)/lib/$(PACKAGE_NAME)
+endif
+else
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)
+endif
+endif
+ifndef INSTALL_BINDIR
+ifdef UNIXHier
+INSTALL_BINDIR:=$(INSTALL_PREFIX)/bin
+else
+INSTALL_BINDIR:=$(INSTALL_BASEDIR)/bin
+ifdef INSTALL_FPCPACKAGE
+ifdef CROSSCOMPILE
+ifdef CROSSINSTALL
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(SOURCESUFFIX)
+else
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(TARGETSUFFIX)
+endif
+else
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(TARGETSUFFIX)
+endif
+endif
+endif
+endif
+ifndef INSTALL_UNITDIR
+INSTALL_UNITDIR:=$(INSTALL_BASEDIR)/units/$(TARGETSUFFIX)
+ifdef INSTALL_FPCPACKAGE
+ifdef PACKAGE_NAME
+INSTALL_UNITDIR:=$(INSTALL_UNITDIR)/$(PACKAGE_NAME)
+endif
+endif
+endif
+ifndef INSTALL_LIBDIR
+ifdef UNIXHier
+INSTALL_LIBDIR:=$(INSTALL_PREFIX)/lib
+else
+INSTALL_LIBDIR:=$(INSTALL_UNITDIR)
+endif
+endif
+ifndef INSTALL_SOURCEDIR
+ifdef UNIXHier
+ifdef BSDhier
+SRCPREFIXDIR=share/src
+else
+ifdef linuxHier
+SRCPREFIXDIR=share/src
+else
+SRCPREFIXDIR=src
+endif
+endif
+ifdef INSTALL_FPCPACKAGE
+ifdef INSTALL_FPCSUBDIR
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/fpc-$(FPC_VERSION)/$(INSTALL_FPCSUBDIR)/$(PACKAGE_NAME)
+else
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+endif
+else
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+ifdef INSTALL_FPCSUBDIR
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source/$(INSTALL_FPCSUBDIR)/$(PACKAGE_NAME)
+else
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source/$(PACKAGE_NAME)
+endif
+else
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source
+endif
+endif
+endif
+ifndef INSTALL_DOCDIR
+ifdef UNIXHier
+ifdef BSDhier
+DOCPREFIXDIR=share/doc
+else
+ifdef linuxHier
+DOCPREFIXDIR=share/doc
+else
+DOCPREFIXDIR=doc
+endif
+endif
+ifdef INSTALL_FPCPACKAGE
+INSTALL_DOCDIR:=$(INSTALL_PREFIX)/$(DOCPREFIXDIR)/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+else
+INSTALL_DOCDIR:=$(INSTALL_PREFIX)/$(DOCPREFIXDIR)/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_DOCDIR:=$(INSTALL_BASEDIR)/doc/$(PACKAGE_NAME)
+else
+INSTALL_DOCDIR:=$(INSTALL_BASEDIR)/doc
+endif
+endif
+endif
+ifndef INSTALL_EXAMPLEDIR
+ifdef UNIXHier
+ifdef INSTALL_FPCPACKAGE
+ifdef BSDhier
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/share/examples/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+else
+ifdef linuxHier
+INSTALL_EXAMPLEDIR:=$(INSTALL_DOCDIR)/examples
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/doc/fpc-$(FPC_VERSION)/examples/$(PACKAGE_NAME)
+endif
+endif
+else
+ifdef BSDhier
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/share/examples/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+else
+ifdef linuxHier
+INSTALL_EXAMPLEDIR:=$(INSTALL_DOCDIR)/examples/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/doc/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+endif
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_EXAMPLEDIR:=$(INSTALL_BASEDIR)/examples/$(PACKAGE_NAME)
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_BASEDIR)/examples
+endif
+endif
+endif
+ifndef INSTALL_DATADIR
+INSTALL_DATADIR=$(INSTALL_BASEDIR)
+endif
+ifndef INSTALL_SHAREDDIR
+INSTALL_SHAREDDIR=$(INSTALL_PREFIX)/lib
+endif
+ifdef CROSSCOMPILE
+ifndef CROSSBINDIR
+CROSSBINDIR:=$(wildcard $(CROSSTARGETDIR)/bin/$(SOURCESUFFIX))
+ifeq ($(CROSSBINDIR),)
+CROSSBINDIR:=$(wildcard $(INSTALL_BASEDIR)/cross/$(TARGETSUFFIX)/bin/$(FULL_SOURCE))
+endif
+endif
+else
+CROSSBINDIR=
+endif
+BATCHEXT=.bat
+LOADEREXT=.as
+EXEEXT=.exe
+PPLEXT=.ppl
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.so
+SHAREDLIBPREFIX=libfp
+STATICLIBPREFIX=libp
+IMPORTLIBPREFIX=libimp
+RSTEXT=.rst
+EXEDBGEXT=.dbg
+ifeq ($(OS_TARGET),go32v1)
+STATICLIBPREFIX=
+SHORTSUFFIX=v1
+endif
+ifeq ($(OS_TARGET),go32v2)
+STATICLIBPREFIX=
+SHORTSUFFIX=dos
+IMPORTLIBPREFIX=
+endif
+ifeq ($(OS_TARGET),watcom)
+STATICLIBPREFIX=
+OEXT=.obj
+ASMEXT=.asm
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=wat
+IMPORTLIBPREFIX=
+endif
+ifneq ($(CPU_TARGET),jvm)
+ifeq ($(OS_TARGET),android)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=lnx
+endif
+endif
+ifeq ($(OS_TARGET),linux)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=lnx
+endif
+ifeq ($(OS_TARGET),dragonfly)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=df
+endif
+ifeq ($(OS_TARGET),freebsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=fbs
+endif
+ifeq ($(OS_TARGET),netbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=nbs
+endif
+ifeq ($(OS_TARGET),openbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=obs
+endif
+ifeq ($(OS_TARGET),win32)
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=w32
+endif
+ifeq ($(OS_TARGET),os2)
+BATCHEXT=.cmd
+AOUTEXT=.out
+STATICLIBPREFIX=
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=os2
+ECHO=echo
+IMPORTLIBPREFIX=
+endif
+ifeq ($(OS_TARGET),emx)
+BATCHEXT=.cmd
+AOUTEXT=.out
+STATICLIBPREFIX=
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=emx
+ECHO=echo
+IMPORTLIBPREFIX=
+endif
+ifeq ($(OS_TARGET),amiga)
+EXEEXT=
+SHAREDLIBEXT=.library
+SHORTSUFFIX=amg
+endif
+ifeq ($(OS_TARGET),aros)
+EXEEXT=
+SHAREDLIBEXT=.library
+SHORTSUFFIX=aros
+endif
+ifeq ($(OS_TARGET),morphos)
+EXEEXT=
+SHAREDLIBEXT=.library
+SHORTSUFFIX=mos
+endif
+ifeq ($(OS_TARGET),atari)
+EXEEXT=.ttp
+SHORTSUFFIX=ata
+endif
+ifeq ($(OS_TARGET),beos)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=be
+endif
+ifeq ($(OS_TARGET),haiku)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=hai
+endif
+ifeq ($(OS_TARGET),solaris)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=sun
+endif
+ifeq ($(OS_TARGET),qnx)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=qnx
+endif
+ifeq ($(OS_TARGET),netware)
+EXEEXT=.nlm
+STATICLIBPREFIX=
+SHORTSUFFIX=nw
+IMPORTLIBPREFIX=imp
+endif
+ifeq ($(OS_TARGET),netwlibc)
+EXEEXT=.nlm
+STATICLIBPREFIX=
+SHORTSUFFIX=nwl
+IMPORTLIBPREFIX=imp
+endif
+ifeq ($(OS_TARGET),macos)
+BATCHEXT=
+EXEEXT=
+DEBUGSYMEXT=.xcoff
+SHORTSUFFIX=mac
+IMPORTLIBPREFIX=imp
+endif
+ifneq ($(findstring $(OS_TARGET),darwin iphonesim),)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=dwn
+EXEDBGEXT=.dSYM
+endif
+ifeq ($(OS_TARGET),gba)
+EXEEXT=.gba
+SHAREDLIBEXT=.so
+SHORTSUFFIX=gba
+endif
+ifeq ($(OS_TARGET),symbian)
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=symbian
+endif
+ifeq ($(OS_TARGET),NativeNT)
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=nativent
+endif
+ifeq ($(OS_TARGET),wii)
+EXEEXT=.dol
+SHAREDLIBEXT=.so
+SHORTSUFFIX=wii
+endif
+ifeq ($(OS_TARGET),aix)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=aix
+endif
+ifeq ($(OS_TARGET),java)
+OEXT=.class
+ASMEXT=.j
+SHAREDLIBEXT=.jar
+SHORTSUFFIX=java
+endif
+ifeq ($(CPU_TARGET),jvm)
+ifeq ($(OS_TARGET),android)
+OEXT=.class
+ASMEXT=.j
+SHAREDLIBEXT=.jar
+SHORTSUFFIX=android
+endif
+endif
+ifeq ($(OS_TARGET),msdos)
+STATICLIBPREFIX=
+STATICLIBEXT=.a
+SHORTSUFFIX=d16
+endif
+ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
+FPCMADE=fpcmade.$(SHORTSUFFIX)
+ZIPSUFFIX=$(SHORTSUFFIX)
+ZIPCROSSPREFIX=
+ZIPSOURCESUFFIX=src
+ZIPEXAMPLESUFFIX=exm
+else
+FPCMADE=fpcmade.$(TARGETSUFFIX)
+ZIPSOURCESUFFIX=.source
+ZIPEXAMPLESUFFIX=.examples
+ifdef CROSSCOMPILE
+ZIPSUFFIX=.$(SOURCESUFFIX)
+ZIPCROSSPREFIX=$(TARGETSUFFIX)-
+else
+ZIPSUFFIX=.$(TARGETSUFFIX)
+ZIPCROSSPREFIX=
+endif
+endif
+ifndef ECHO
+ECHO:=$(strip $(wildcard $(addsuffix /gecho$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO:=$(strip $(wildcard $(addsuffix /echo$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO= __missing_command_ECHO
+else
+ECHO:=$(firstword $(ECHO))
+endif
+else
+ECHO:=$(firstword $(ECHO))
+endif
+endif
+export ECHO
+ifndef DATE
+DATE:=$(strip $(wildcard $(addsuffix /gdate$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(DATE),)
+DATE:=$(strip $(wildcard $(addsuffix /date$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(DATE),)
+DATE= __missing_command_DATE
+else
+DATE:=$(firstword $(DATE))
+endif
+else
+DATE:=$(firstword $(DATE))
+endif
+endif
+export DATE
+ifndef GINSTALL
+GINSTALL:=$(strip $(wildcard $(addsuffix /ginstall$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(GINSTALL),)
+GINSTALL:=$(strip $(wildcard $(addsuffix /install$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(GINSTALL),)
+GINSTALL= __missing_command_GINSTALL
+else
+GINSTALL:=$(firstword $(GINSTALL))
+endif
+else
+GINSTALL:=$(firstword $(GINSTALL))
+endif
+endif
+export GINSTALL
+ifndef CPPROG
+CPPROG:=$(strip $(wildcard $(addsuffix /cp$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(CPPROG),)
+CPPROG= __missing_command_CPPROG
+else
+CPPROG:=$(firstword $(CPPROG))
+endif
+endif
+export CPPROG
+ifndef RMPROG
+RMPROG:=$(strip $(wildcard $(addsuffix /rm$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(RMPROG),)
+RMPROG= __missing_command_RMPROG
+else
+RMPROG:=$(firstword $(RMPROG))
+endif
+endif
+export RMPROG
+ifndef MVPROG
+MVPROG:=$(strip $(wildcard $(addsuffix /mv$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MVPROG),)
+MVPROG= __missing_command_MVPROG
+else
+MVPROG:=$(firstword $(MVPROG))
+endif
+endif
+export MVPROG
+ifndef MKDIRPROG
+MKDIRPROG:=$(strip $(wildcard $(addsuffix /gmkdir$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MKDIRPROG),)
+MKDIRPROG:=$(strip $(wildcard $(addsuffix /mkdir$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MKDIRPROG),)
+MKDIRPROG= __missing_command_MKDIRPROG
+else
+MKDIRPROG:=$(firstword $(MKDIRPROG))
+endif
+else
+MKDIRPROG:=$(firstword $(MKDIRPROG))
+endif
+endif
+export MKDIRPROG
+ifndef ECHOREDIR
+ifndef inUnix
+ECHOREDIR=echo
+else
+ECHOREDIR=$(ECHO)
+endif
+endif
+ifndef COPY
+COPY:=$(CPPROG) -fp
+endif
+ifndef COPYTREE
+COPYTREE:=$(CPPROG) -Rfp
+endif
+ifndef MKDIRTREE
+MKDIRTREE:=$(MKDIRPROG) -p
+endif
+ifndef MOVE
+MOVE:=$(MVPROG) -f
+endif
+ifndef DEL
+DEL:=$(RMPROG) -f
+endif
+ifndef DELTREE
+DELTREE:=$(RMPROG) -rf
+endif
+ifndef INSTALL
+ifdef inUnix
+INSTALL:=$(GINSTALL) -c -m 644
+else
+INSTALL:=$(COPY)
+endif
+endif
+ifndef INSTALLEXE
+ifdef inUnix
+INSTALLEXE:=$(GINSTALL) -c -m 755
+else
+INSTALLEXE:=$(COPY)
+endif
+endif
+ifndef MKDIR
+MKDIR:=$(GINSTALL) -m 755 -d
+endif
+export ECHOREDIR COPY COPYTREE MOVE DEL DELTREE INSTALL INSTALLEXE MKDIR
+ifndef PPUMOVE
+PPUMOVE:=$(strip $(wildcard $(addsuffix /ppumove$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(PPUMOVE),)
+PPUMOVE= __missing_command_PPUMOVE
+else
+PPUMOVE:=$(firstword $(PPUMOVE))
+endif
+endif
+export PPUMOVE
+ifndef FPCMAKE
+FPCMAKE:=$(strip $(wildcard $(addsuffix /fpcmake$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(FPCMAKE),)
+FPCMAKE= __missing_command_FPCMAKE
+else
+FPCMAKE:=$(firstword $(FPCMAKE))
+endif
+endif
+export FPCMAKE
+ifndef ZIPPROG
+ZIPPROG:=$(strip $(wildcard $(addsuffix /zip$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ZIPPROG),)
+ZIPPROG= __missing_command_ZIPPROG
+else
+ZIPPROG:=$(firstword $(ZIPPROG))
+endif
+endif
+export ZIPPROG
+ifndef TARPROG
+TARPROG:=$(strip $(wildcard $(addsuffix /gtar$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(TARPROG),)
+TARPROG:=$(strip $(wildcard $(addsuffix /tar$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(TARPROG),)
+TARPROG= __missing_command_TARPROG
+else
+TARPROG:=$(firstword $(TARPROG))
+endif
+else
+TARPROG:=$(firstword $(TARPROG))
+endif
+endif
+export TARPROG
+ASNAME=$(BINUTILSPREFIX)as
+LDNAME=$(BINUTILSPREFIX)ld
+ARNAME=$(BINUTILSPREFIX)ar
+RCNAME=$(BINUTILSPREFIX)rc
+NASMNAME=$(BINUTILSPREFIX)nasm
+ifndef ASPROG
+ifdef CROSSBINDIR
+ASPROG=$(CROSSBINDIR)/$(ASNAME)$(SRCEXEEXT)
+else
+ASPROG=$(ASNAME)
+endif
+endif
+ifndef LDPROG
+ifdef CROSSBINDIR
+LDPROG=$(CROSSBINDIR)/$(LDNAME)$(SRCEXEEXT)
+else
+LDPROG=$(LDNAME)
+endif
+endif
+ifndef RCPROG
+ifdef CROSSBINDIR
+RCPROG=$(CROSSBINDIR)/$(RCNAME)$(SRCEXEEXT)
+else
+RCPROG=$(RCNAME)
+endif
+endif
+ifndef ARPROG
+ifdef CROSSBINDIR
+ARPROG=$(CROSSBINDIR)/$(ARNAME)$(SRCEXEEXT)
+else
+ARPROG=$(ARNAME)
+endif
+endif
+ifndef NASMPROG
+ifdef CROSSBINDIR
+NASMPROG=$(CROSSBINDIR)/$(NASMNAME)$(SRCEXEEXT)
+else
+NASMPROG=$(NASMNAME)
+endif
+endif
+AS=$(ASPROG)
+LD=$(LDPROG)
+RC=$(RCPROG)
+AR=$(ARPROG)
+NASM=$(NASMPROG)
+ifdef inUnix
+PPAS=./ppas$(SRCBATCHEXT)
+else
+PPAS=ppas$(SRCBATCHEXT)
+endif
+ifdef inUnix
+LDCONFIG=ldconfig
+else
+LDCONFIG=
+endif
+ifdef DATE
+DATESTR:=$(shell $(DATE) +%Y%m%d)
+else
+DATESTR=
+endif
+ZIPOPT=-9
+ZIPEXT=.zip
+ifeq ($(USETAR),bz2)
+TAROPT=vj
+TAREXT=.tar.bz2
+else
+TAROPT=vz
+TAREXT=.tar.gz
+endif
+override REQUIRE_PACKAGES=libndsfpc
+ifeq ($(FULL_TARGET),arm-nds)
+REQUIRE_PACKAGES_LIBNDSFPC=1
+endif
+ifdef REQUIRE_PACKAGES_LIBNDSFPC
+PACKAGEDIR_LIBNDSFPC:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /libndsfpc/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_LIBNDSFPC),)
+ifneq ($(wildcard $(PACKAGEDIR_LIBNDSFPC)/units/$(TARGETSUFFIX)),)
+UNITDIR_LIBNDSFPC=$(PACKAGEDIR_LIBNDSFPC)/units/$(TARGETSUFFIX)
+else
+UNITDIR_LIBNDSFPC=$(PACKAGEDIR_LIBNDSFPC)
+endif
+ifneq ($(wildcard $(PACKAGEDIR_LIBNDSFPC)/units/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_LIBNDSFPC=$(PACKAGEDIR_LIBNDSFPC)/units/$(SOURCESUFFIX)
+else
+ifneq ($(wildcard $(PACKAGEDIR_LIBNDSFPC)/units_bs/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_LIBNDSFPC=$(PACKAGEDIR_LIBNDSFPC)/units_bs/$(SOURCESUFFIX)
+else
+UNITDIR_FPMAKE_LIBNDSFPC=$(PACKAGEDIR_LIBNDSFPC)
+endif
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_LIBNDSFPC)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_LIBNDSFPC) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_LIBNDSFPC)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_LIBNDSFPC=
+UNITDIR_LIBNDSFPC:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /libndsfpc/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_LIBNDSFPC),)
+UNITDIR_LIBNDSFPC:=$(firstword $(UNITDIR_LIBNDSFPC))
+else
+UNITDIR_LIBNDSFPC=
+endif
+endif
+ifdef UNITDIR_LIBNDSFPC
+override COMPILER_UNITDIR+=$(UNITDIR_LIBNDSFPC)
+endif
+ifdef UNITDIR_FPMAKE_LIBNDSFPC
+override COMPILER_FPMAKE_UNITDIR+=$(UNITDIR_FPMAKE_LIBNDSFPC)
+endif
+endif
+ifndef NOCPUDEF
+override FPCOPTDEF=$(ARCH)
+endif
+ifneq ($(OS_TARGET),$(OS_SOURCE))
+override FPCOPT+=-T$(OS_TARGET)
+endif
+ifneq ($(CPU_TARGET),$(CPU_SOURCE))
+override FPCOPT+=-P$(ARCH)
+endif
+ifeq ($(OS_SOURCE),openbsd)
+override FPCOPT+=-FD$(NEW_BINUTILS_PATH)
+override FPCMAKEOPT+=-FD$(NEW_BINUTILS_PATH)
+endif
+ifndef CROSSBOOTSTRAP
+ifneq ($(BINUTILSPREFIX),)
+override FPCOPT+=-XP$(BINUTILSPREFIX)
+endif
+ifneq ($(BINUTILSPREFIX),)
+override FPCOPT+=-Xr$(RLINKPATH)
+endif
+endif
+ifndef CROSSCOMPILE
+ifneq ($(BINUTILSPREFIX),)
+override FPCMAKEOPT+=-XP$(BINUTILSPREFIX)
+endif
+endif
+ifdef UNITDIR
+override FPCOPT+=$(addprefix -Fu,$(UNITDIR))
+endif
+ifdef LIBDIR
+override FPCOPT+=$(addprefix -Fl,$(LIBDIR))
+endif
+ifdef OBJDIR
+override FPCOPT+=$(addprefix -Fo,$(OBJDIR))
+endif
+ifdef INCDIR
+override FPCOPT+=$(addprefix -Fi,$(INCDIR))
+endif
+ifdef LINKSMART
+override FPCOPT+=-XX
+endif
+ifdef CREATESMART
+override FPCOPT+=-CX
+endif
+ifdef DEBUG
+override FPCOPT+=-gl
+override FPCOPTDEF+=DEBUG
+endif
+ifdef RELEASE
+ifneq ($(findstring 2.0.,$(FPC_VERSION)),)
+ifeq ($(CPU_TARGET),i386)
+FPCCPUOPT:=-OG2p3
+endif
+ifeq ($(CPU_TARGET),powerpc)
+FPCCPUOPT:=-O1r
+endif
+else
+FPCCPUOPT:=-O2
+endif
+override FPCOPT+=-Ur -Xs $(FPCCPUOPT) -n
+override FPCOPTDEF+=RELEASE
+endif
+ifdef STRIP
+override FPCOPT+=-Xs
+endif
+ifdef OPTIMIZE
+override FPCOPT+=-O2
+endif
+ifdef VERBOSE
+override FPCOPT+=-vwni
+endif
+ifdef COMPILER_OPTIONS
+override FPCOPT+=$(COMPILER_OPTIONS)
+endif
+ifdef COMPILER_UNITDIR
+override FPCOPT+=$(addprefix -Fu,$(COMPILER_UNITDIR))
+endif
+ifdef COMPILER_LIBRARYDIR
+override FPCOPT+=$(addprefix -Fl,$(COMPILER_LIBRARYDIR))
+endif
+ifdef COMPILER_OBJECTDIR
+override FPCOPT+=$(addprefix -Fo,$(COMPILER_OBJECTDIR))
+endif
+ifdef COMPILER_INCLUDEDIR
+override FPCOPT+=$(addprefix -Fi,$(COMPILER_INCLUDEDIR))
+endif
+ifdef CROSSBINDIR
+override FPCOPT+=-FD$(CROSSBINDIR)
+endif
+ifdef COMPILER_TARGETDIR
+override FPCOPT+=-FE$(COMPILER_TARGETDIR)
+ifeq ($(COMPILER_TARGETDIR),.)
+override TARGETDIRPREFIX=
+else
+override TARGETDIRPREFIX=$(COMPILER_TARGETDIR)/
+endif
+endif
+ifdef COMPILER_UNITTARGETDIR
+override FPCOPT+=-FU$(COMPILER_UNITTARGETDIR)
+ifeq ($(COMPILER_UNITTARGETDIR),.)
+override UNITTARGETDIRPREFIX=
+else
+override UNITTARGETDIRPREFIX=$(COMPILER_UNITTARGETDIR)/
+endif
+else
+ifdef COMPILER_TARGETDIR
+override COMPILER_UNITTARGETDIR=$(COMPILER_TARGETDIR)
+override UNITTARGETDIRPREFIX=$(TARGETDIRPREFIX)
+endif
+endif
+ifdef CREATESHARED
+override FPCOPT+=-Cg
+endif
+ifneq ($(findstring $(OS_TARGET),dragonfly freebsd openbsd netbsd linux solaris),)
+ifneq ($(findstring $(CPU_TARGET),x86_64 mips mipsel),)
+override FPCOPT+=-Cg
+endif
+endif
+ifdef LINKSHARED
+endif
+ifdef OPT
+override FPCOPT+=$(OPT)
+endif
+ifdef FPCOPTDEF
+override FPCOPT+=$(addprefix -d,$(FPCOPTDEF))
+endif
+ifdef CFGFILE
+override FPCOPT+=@$(CFGFILE)
+endif
+ifdef USEENV
+override FPCEXTCMD:=$(FPCOPT)
+override FPCOPT:=!FPCEXTCMD
+export FPCEXTCMD
+endif
+override AFULL_TARGET=$(CPU_TARGET)-$(OS_TARGET)
+override AFULL_SOURCE=$(CPU_SOURCE)-$(OS_SOURCE)
+ifneq ($(AFULL_TARGET),$(AFULL_SOURCE))
+override ACROSSCOMPILE=1
+endif
+ifdef ACROSSCOMPILE
+override FPCOPT+=$(CROSSOPT)
+endif
+override COMPILER:=$(strip $(FPC) $(FPCOPT))
+ifneq (,$(findstring -sh ,$(COMPILER)))
+UseEXECPPAS=1
+endif
+ifneq (,$(findstring -s ,$(COMPILER)))
+ifeq ($(FULL_SOURCE),$(FULL_TARGET))
+UseEXECPPAS=1
+endif
+endif
+ifneq ($(UseEXECPPAS),1)
+EXECPPAS=
+else
+ifdef RUNBATCH
+EXECPPAS:=@$(RUNBATCH) $(PPAS)
+else
+EXECPPAS:=@$(PPAS)
+endif
+endif
+.PHONY: fpc_exes
+ifndef CROSSINSTALL
+ifneq ($(TARGET_PROGRAMS),)
+override EXEFILES=$(addsuffix $(EXEEXT),$(TARGET_PROGRAMS))
+override EXEOFILES:=$(addsuffix $(OEXT),$(TARGET_PROGRAMS)) $(addprefix $(STATICLIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TARGET_PROGRAMS))) $(addprefix $(IMPORTLIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TARGET_PROGRAMS)))
+override EXEDBGFILES:=$(addsuffix $(EXEDBGEXT),$(TARGET_PROGRAMS))
+override ALLTARGET+=fpc_exes
+override INSTALLEXEFILES+=$(EXEFILES)
+override CLEANEXEFILES+=$(EXEFILES) $(EXEOFILES)
+override CLEANEXEDBGFILES+=$(EXEDBGFILES)
+ifeq ($(OS_TARGET),os2)
+override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_PROGRAMS))
+endif
+ifeq ($(OS_TARGET),emx)
+override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_PROGRAMS))
+endif
+endif
+endif
+fpc_exes: $(COMPILER_TARGETDIR) $(COMPILER_UNITTARGETDIR) $(EXEFILES)
+ifdef TARGET_RSTS
+override RSTFILES=$(addsuffix $(RSTEXT),$(TARGET_RSTS))
+override CLEANRSTFILES+=$(RSTFILES)
+endif
+.PHONY: fpc_all fpc_smart fpc_debug fpc_release fpc_shared
+$(FPCMADE): $(ALLDEPENDENCIES) $(ALLTARGET)
+	@$(ECHOREDIR) Compiled > $(FPCMADE)
+fpc_all: $(FPCMADE)
+fpc_smart:
+	$(MAKE) all LINKSMART=1 CREATESMART=1
+fpc_debug:
+	$(MAKE) all DEBUG=1
+fpc_release:
+	$(MAKE) all RELEASE=1
+.SUFFIXES: $(EXEEXT) $(PPUEXT) $(OEXT) .pas .lpr .dpr .pp .rc .res
+$(COMPILER_UNITTARGETDIR):
+	$(MKDIRTREE) $(COMPILER_UNITTARGETDIR)
+$(COMPILER_TARGETDIR):
+	$(MKDIRTREE) $(COMPILER_TARGETDIR)
+%$(PPUEXT): %.pp
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(PPUEXT): %.pas
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(EXEEXT): %.pp
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(EXEEXT): %.pas
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(EXEEXT): %.lpr
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(EXEEXT): %.dpr
+	$(COMPILER) $<
+	$(EXECPPAS)
+%.res: %.rc
+	windres -i $< -o $@
+vpath %.pp $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.pas $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.lpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.dpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.inc $(COMPILER_INCLUDEDIR)
+vpath %$(OEXT) $(COMPILER_UNITTARGETDIR)
+vpath %$(PPUEXT) $(COMPILER_UNITTARGETDIR)
+.PHONY: fpc_shared
+override INSTALLTARGET+=fpc_shared_install
+ifndef SHARED_LIBVERSION
+SHARED_LIBVERSION=$(FPC_VERSION)
+endif
+ifndef SHARED_LIBNAME
+SHARED_LIBNAME=$(PACKAGE_NAME)
+endif
+ifndef SHARED_FULLNAME
+SHARED_FULLNAME=$(SHAREDLIBPREFIX)$(SHARED_LIBNAME)-$(SHARED_LIBVERSION)$(SHAREDLIBEXT)
+endif
+ifndef SHARED_LIBUNITS
+SHARED_LIBUNITS:=$(TARGET_UNITS) $(TARGET_IMPLICITUNITS)
+override SHARED_LIBUNITS:=$(filter-out $(INSTALL_BUILDUNIT),$(SHARED_LIBUNITS))
+endif
+fpc_shared:
+ifdef HASSHAREDLIB
+	$(MAKE) all CREATESHARED=1 LINKSHARED=1 CREATESMART=1
+ifneq ($(SHARED_BUILD),n)
+	$(PPUMOVE) -q $(SHARED_LIBUNITS) -i$(COMPILER_UNITTARGETDIR) -o$(SHARED_FULLNAME) -d$(COMPILER_UNITTARGETDIR)
+endif
+else
+	@$(ECHO) Shared Libraries not supported
+endif
+fpc_shared_install:
+ifneq ($(SHARED_BUILD),n)
+ifneq ($(SHARED_LIBUNITS),)
+ifneq ($(wildcard $(COMPILER_UNITTARGETDIR)/$(SHARED_FULLNAME)),)
+	$(INSTALL) $(COMPILER_UNITTARGETDIR)/$(SHARED_FULLNAME) $(INSTALL_SHAREDDIR)
+endif
+endif
+endif
+.PHONY: fpc_install fpc_sourceinstall fpc_exampleinstall
+ifdef INSTALL_UNITS
+override INSTALLPPUFILES+=$(addsuffix $(PPUEXT),$(INSTALL_UNITS))
+endif
+ifdef INSTALL_BUILDUNIT
+override INSTALLPPUFILES:=$(filter-out $(INSTALL_BUILDUNIT)$(PPUEXT),$(INSTALLPPUFILES))
+endif
+ifdef INSTALLPPUFILES
+override INSTALLPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(INSTALLPPUFILES)) $(addprefix $(STATICLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(INSTALLPPUFILES))) $(addprefix $(IMPORTLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(INSTALLPPUFILES)))
+ifneq ($(UNITTARGETDIRPREFIX),)
+override INSTALLPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(notdir $(INSTALLPPUFILES)))
+override INSTALLPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPREFIX),$(notdir $(INSTALLPPULINKFILES))))
+endif
+override INSTALL_CREATEPACKAGEFPC=1
+endif
+ifdef INSTALLEXEFILES
+ifneq ($(TARGETDIRPREFIX),)
+override INSTALLEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(notdir $(INSTALLEXEFILES)))
+endif
+endif
+fpc_install: all $(INSTALLTARGET)
+ifdef INSTALLEXEFILES
+	$(MKDIR) $(INSTALL_BINDIR)
+	$(INSTALLEXE) $(INSTALLEXEFILES) $(INSTALL_BINDIR)
+endif
+ifdef INSTALL_CREATEPACKAGEFPC
+ifdef FPCMAKE
+ifdef PACKAGE_VERSION
+ifneq ($(wildcard Makefile.fpc),)
+	$(FPCMAKE) -p -T$(CPU_TARGET)-$(OS_TARGET) Makefile.fpc
+	$(MKDIR) $(INSTALL_UNITDIR)
+	$(INSTALL) Package.fpc $(INSTALL_UNITDIR)
+endif
+endif
+endif
+endif
+ifdef INSTALLPPUFILES
+	$(MKDIR) $(INSTALL_UNITDIR)
+	$(INSTALL) $(INSTALLPPUFILES) $(INSTALL_UNITDIR)
+ifneq ($(INSTALLPPULINKFILES),)
+	$(INSTALL) $(INSTALLPPULINKFILES) $(INSTALL_UNITDIR)
+endif
+ifneq ($(wildcard $(LIB_FULLNAME)),)
+	$(MKDIR) $(INSTALL_LIBDIR)
+	$(INSTALL) $(LIB_FULLNAME) $(INSTALL_LIBDIR)
+ifdef inUnix
+	ln -sf $(LIB_FULLNAME) $(INSTALL_LIBDIR)/$(LIB_NAME)
+endif
+endif
+endif
+ifdef INSTALL_FILES
+	$(MKDIR) $(INSTALL_DATADIR)
+	$(INSTALL) $(INSTALL_FILES) $(INSTALL_DATADIR)
+endif
+fpc_sourceinstall: distclean
+	$(MKDIR) $(INSTALL_SOURCEDIR)
+	$(COPYTREE) $(BASEDIR)/* $(INSTALL_SOURCEDIR)
+fpc_exampleinstall: $(addsuffix _distclean,$(TARGET_EXAMPLEDIRS))
+ifdef HASEXAMPLES
+	$(MKDIR) $(INSTALL_EXAMPLEDIR)
+endif
+ifdef EXAMPLESOURCEFILES
+	$(COPY) $(EXAMPLESOURCEFILES) $(INSTALL_EXAMPLEDIR)
+endif
+ifdef TARGET_EXAMPLEDIRS
+	$(COPYTREE) $(addsuffix /*,$(TARGET_EXAMPLEDIRS)) $(INSTALL_EXAMPLEDIR)
+endif
+.PHONY: fpc_clean fpc_cleanall fpc_distclean
+ifdef EXEFILES
+override CLEANEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(CLEANEXEFILES))
+override CLEANEXEDBGFILES:=$(addprefix $(TARGETDIRPREFIX),$(CLEANEXEDBGFILES))
+endif
+ifdef CLEAN_PROGRAMS
+override CLEANEXEFILES+=$(addprefix $(TARGETDIRPREFIX),$(addsuffix $(EXEEXT), $(CLEAN_PROGRAMS)))
+override CLEANEXEDBGFILES+=$(addprefix $(TARGETDIRPREFIX),$(addsuffix $(EXEDBGEXT), $(CLEAN_PROGRAMS)))
+endif
+ifdef CLEAN_UNITS
+override CLEANPPUFILES+=$(addsuffix $(PPUEXT),$(CLEAN_UNITS))
+endif
+ifdef CLEANPPUFILES
+override CLEANPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(CLEANPPUFILES)) $(addprefix $(STATICLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(CLEANPPUFILES))) $(addprefix $(IMPORTLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(CLEANPPUFILES)))
+ifdef DEBUGSYMEXT
+override CLEANPPULINKFILES+=$(subst $(PPUEXT),$(DEBUGSYMEXT),$(CLEANPPUFILES))
+endif
+override CLEANPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(CLEANPPUFILES))
+override CLEANPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANPPULINKFILES)))
+endif
+fpc_clean: $(CLEANTARGET)
+ifdef CLEANEXEFILES
+	-$(DEL) $(CLEANEXEFILES)
+endif
+ifdef CLEANEXEDBGFILES
+	-$(DELTREE) $(CLEANEXEDBGFILES)
+endif
+ifdef CLEANPPUFILES
+	-$(DEL) $(CLEANPPUFILES)
+endif
+ifneq ($(CLEANPPULINKFILES),)
+	-$(DEL) $(CLEANPPULINKFILES)
+endif
+ifdef CLEANRSTFILES
+	-$(DEL) $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANRSTFILES))
+endif
+ifdef CLEAN_FILES
+	-$(DEL) $(CLEAN_FILES)
+endif
+ifdef LIB_NAME
+	-$(DEL) $(LIB_NAME) $(LIB_FULLNAME)
+endif
+	-$(DEL) $(FPCMADE) Package.fpc $(PPAS) script.res link.res $(FPCEXTFILE) $(REDIRFILE)
+	-$(DEL) *$(ASMEXT) *_ppas$(BATCHEXT)
+fpc_cleanall: $(CLEANTARGET)
+ifdef CLEANEXEFILES
+	-$(DEL) $(CLEANEXEFILES)
+endif
+ifdef COMPILER_UNITTARGETDIR
+ifdef CLEANPPUFILES
+	-$(DEL) $(CLEANPPUFILES)
+endif
+ifneq ($(CLEANPPULINKFILES),)
+	-$(DEL) $(CLEANPPULINKFILES)
+endif
+ifdef CLEANRSTFILES
+	-$(DEL) $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANRSTFILES))
+endif
+endif
+ifdef CLEAN_FILES
+	-$(DEL) $(CLEAN_FILES)
+endif
+	-$(DELTREE) units
+	-$(DEL) *$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIBEXT) *$(SHAREDLIBEXT) *$(PPLEXT)
+ifneq ($(PPUEXT),.ppu)
+	-$(DEL) *.o *.ppu *.a
+endif
+	-$(DELTREE) *$(SMARTEXT)
+	-$(DEL) fpcmade.* Package.fpc $(PPAS) script.res link.res $(FPCEXTFILE) $(REDIRFILE)
+	-$(DEL) *_ppas$(BATCHEXT)
+ifdef AOUTEXT
+	-$(DEL) *$(AOUTEXT)
+endif
+ifdef DEBUGSYMEXT
+	-$(DEL) *$(DEBUGSYMEXT)
+endif
+fpc_distclean: cleanall
+.PHONY: fpc_baseinfo
+override INFORULES+=fpc_baseinfo
+fpc_baseinfo:
+	@$(ECHO)
+	@$(ECHO)  == Package info ==
+	@$(ECHO)  Package Name..... $(PACKAGE_NAME)
+	@$(ECHO)  Package Version.. $(PACKAGE_VERSION)
+	@$(ECHO)
+	@$(ECHO)  == Configuration info ==
+	@$(ECHO)
+	@$(ECHO)  FPC.......... $(FPC)
+	@$(ECHO)  FPC Version.. $(FPC_VERSION)
+	@$(ECHO)  Source CPU... $(CPU_SOURCE)
+	@$(ECHO)  Target CPU... $(CPU_TARGET)
+	@$(ECHO)  Source OS.... $(OS_SOURCE)
+	@$(ECHO)  Target OS.... $(OS_TARGET)
+	@$(ECHO)  Full Source.. $(FULL_SOURCE)
+	@$(ECHO)  Full Target.. $(FULL_TARGET)
+	@$(ECHO)  SourceSuffix. $(SOURCESUFFIX)
+	@$(ECHO)  TargetSuffix. $(TARGETSUFFIX)
+	@$(ECHO)  FPC fpmake... $(FPCFPMAKE)
+	@$(ECHO)
+	@$(ECHO)  == Directory info ==
+	@$(ECHO)
+	@$(ECHO)  Required pkgs... $(REQUIRE_PACKAGES)
+	@$(ECHO)
+	@$(ECHO)  Basedir......... $(BASEDIR)
+	@$(ECHO)  FPCDir.......... $(FPCDIR)
+	@$(ECHO)  CrossBinDir..... $(CROSSBINDIR)
+	@$(ECHO)  UnitsDir........ $(UNITSDIR)
+	@$(ECHO)  PackagesDir..... $(PACKAGESDIR)
+	@$(ECHO)
+	@$(ECHO)  GCC library..... $(GCCLIBDIR)
+	@$(ECHO)  Other library... $(OTHERLIBDIR)
+	@$(ECHO)
+	@$(ECHO)  == Tools info ==
+	@$(ECHO)
+	@$(ECHO)  As........ $(AS)
+	@$(ECHO)  Ld........ $(LD)
+	@$(ECHO)  Ar........ $(AR)
+	@$(ECHO)  Rc........ $(RC)
+	@$(ECHO)
+	@$(ECHO)  Mv........ $(MVPROG)
+	@$(ECHO)  Cp........ $(CPPROG)
+	@$(ECHO)  Rm........ $(RMPROG)
+	@$(ECHO)  GInstall.. $(GINSTALL)
+	@$(ECHO)  Echo...... $(ECHO)
+	@$(ECHO)  Shell..... $(SHELL)
+	@$(ECHO)  Date...... $(DATE)
+	@$(ECHO)  FPCMake... $(FPCMAKE)
+	@$(ECHO)  PPUMove... $(PPUMOVE)
+	@$(ECHO)  Zip....... $(ZIPPROG)
+	@$(ECHO)
+	@$(ECHO)  == Object info ==
+	@$(ECHO)
+	@$(ECHO)  Target Loaders........ $(TARGET_LOADERS)
+	@$(ECHO)  Target Units.......... $(TARGET_UNITS)
+	@$(ECHO)  Target Implicit Units. $(TARGET_IMPLICITUNITS)
+	@$(ECHO)  Target Programs....... $(TARGET_PROGRAMS)
+	@$(ECHO)  Target Dirs........... $(TARGET_DIRS)
+	@$(ECHO)  Target Examples....... $(TARGET_EXAMPLES)
+	@$(ECHO)  Target ExampleDirs.... $(TARGET_EXAMPLEDIRS)
+	@$(ECHO)
+	@$(ECHO)  Clean Units......... $(CLEAN_UNITS)
+	@$(ECHO)  Clean Files......... $(CLEAN_FILES)
+	@$(ECHO)
+	@$(ECHO)  Install Units....... $(INSTALL_UNITS)
+	@$(ECHO)  Install Files....... $(INSTALL_FILES)
+	@$(ECHO)
+	@$(ECHO)  == Install info ==
+	@$(ECHO)
+	@$(ECHO)  DateStr.............. $(DATESTR)
+	@$(ECHO)  ZipName.............. $(ZIPNAME)
+	@$(ECHO)  ZipPrefix............ $(ZIPPREFIX)
+	@$(ECHO)  ZipCrossPrefix....... $(ZIPCROSSPREFIX)
+	@$(ECHO)  ZipSuffix............ $(ZIPSUFFIX)
+	@$(ECHO)  FullZipName.......... $(FULLZIPNAME)
+	@$(ECHO)  Install FPC Package.. $(INSTALL_FPCPACKAGE)
+	@$(ECHO)
+	@$(ECHO)  Install base dir..... $(INSTALL_BASEDIR)
+	@$(ECHO)  Install binary dir... $(INSTALL_BINDIR)
+	@$(ECHO)  Install library dir.. $(INSTALL_LIBDIR)
+	@$(ECHO)  Install units dir.... $(INSTALL_UNITDIR)
+	@$(ECHO)  Install source dir... $(INSTALL_SOURCEDIR)
+	@$(ECHO)  Install doc dir...... $(INSTALL_DOCDIR)
+	@$(ECHO)  Install example dir.. $(INSTALL_EXAMPLEDIR)
+	@$(ECHO)  Install data dir..... $(INSTALL_DATADIR)
+	@$(ECHO)
+	@$(ECHO)  Dist destination dir. $(DIST_DESTDIR)
+	@$(ECHO)  Dist zip name........ $(DIST_ZIPNAME)
+	@$(ECHO)
+.PHONY: fpc_info
+fpc_info: $(INFORULES)
+.PHONY: fpc_makefile fpc_makefiles fpc_makefile_sub1 fpc_makefile_sub2 \
+	fpc_makefile_dirs
+fpc_makefile:
+	$(FPCMAKE) -w -T$(OS_TARGET) Makefile.fpc
+fpc_makefile_sub1:
+ifdef TARGET_DIRS
+	$(FPCMAKE) -w -T$(OS_TARGET) $(addsuffix /Makefile.fpc,$(TARGET_DIRS))
+endif
+ifdef TARGET_EXAMPLEDIRS
+	$(FPCMAKE) -w -T$(OS_TARGET) $(addsuffix /Makefile.fpc,$(TARGET_EXAMPLEDIRS))
+endif
+fpc_makefile_sub2: $(addsuffix _makefile_dirs,$(TARGET_DIRS) $(TARGET_EXAMPLEDIRS))
+fpc_makefile_dirs: fpc_makefile_sub1 fpc_makefile_sub2
+fpc_makefiles: fpc_makefile fpc_makefile_dirs
+ifndef BIN2S
+BIN2S:=$(strip $(wildcard $(addsuffix /bin2s$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(BIN2S),)
+BIN2S= __missing_command_BIN2S
+else
+BIN2S:=$(firstword $(BIN2S))
+endif
+endif
+export BIN2S
+ifndef MMUTIL
+MMUTIL:=$(strip $(wildcard $(addsuffix /mmutil$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MMUTIL),)
+MMUTIL= __missing_command_MMUTIL
+else
+MMUTIL:=$(firstword $(MMUTIL))
+endif
+endif
+export MMUTIL
+ifndef GRIT_FPC
+GRIT_FPC:=$(strip $(wildcard $(addsuffix /grit_fpc$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(GRIT_FPC),)
+GRIT_FPC= __missing_command_GRIT_FPC
+else
+GRIT_FPC:=$(firstword $(GRIT_FPC))
+endif
+endif
+export GRIT_FPC
+ifndef RMDIR
+RMDIR:=$(strip $(wildcard $(addsuffix /rmdir$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(RMDIR),)
+RMDIR= __missing_command_RMDIR
+else
+RMDIR:=$(firstword $(RMDIR))
+endif
+endif
+export RMDIR
+ifndef MV
+MV:=$(strip $(wildcard $(addsuffix /mv$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MV),)
+MV= __missing_command_MV
+else
+MV:=$(firstword $(MV))
+endif
+endif
+export MV
+ifndef NDSTOOL
+NDSTOOL:=$(strip $(wildcard $(addsuffix /ndstool$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(NDSTOOL),)
+NDSTOOL= __missing_command_NDSTOOL
+else
+NDSTOOL:=$(firstword $(NDSTOOL))
+endif
+endif
+export NDSTOOL
+debug: fpc_debug
+smart: fpc_smart
+release: fpc_release
+units: fpc_units
+examples:
+shared: fpc_shared
+install: fpc_install
+sourceinstall: fpc_sourceinstall
+exampleinstall: fpc_exampleinstall
+distinstall:
+zipinstall:
+zipsourceinstall:
+zipexampleinstall:
+zipdistinstall:
+distclean: fpc_distclean
+cleanall: fpc_cleanall
+info: fpc_info
+makefiles: fpc_makefiles
+.PHONY: debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall distclean cleanall info makefiles
+ifneq ($(wildcard fpcmake.loc),)
+include fpcmake.loc
+endif
+.NOTPARALLEL:
+clean: dir_delete fpc_clean fpc_cleanall
+all: dir_make $(BIN_FILES) $(GFX_FILES) fpc_all 
+filesystem: all make_filesystem
+dir_delete:
+	@$(DELTREE) $(CURDIR)/$(BUILD) 
+	@$(DELTREE) $(CURDIR)/$(INC) 
+	@$(DELTREE) $(CURDIR)/$(BIN) 
+dir_make:
+ifneq ($(BUILD), $(CURDIR))
+	@$(MKDIR) $(BUILD)
+endif
+ifneq ($(INC), $(CURDIR))
+	@$(MKDIR) $(INC)
+endif
+ifneq ($(BIN), $(CURDIR))
+	@$(MKDIR) $(BIN)
+endif
+soundbank.bin.o : $(AUDIO_FILES)
+	@$(MMUTIL) $^ -d -o$(BUILD)/soundbank.bin -h$(BUILD)/soundbank.h
+	$(BIN2S) $(BUILD)/soundbank.bin > $(BUILD)/soundbank.bin.s
+	$(AS) -o $(BUILD)/soundbank.bin.o $(BUILD)/soundbank.bin.s
+$(GFX_FILES): $(wildcard %.bmp %.png)
+	@echo 'Converting $(@) file to asm...'
+	$(GRIT_FPC) $(GFX)/$(@) -fp -fts -ff $(GFX)/$(basename $(@)).grit -o$(BUILD)/$(@)
+	@echo 'Assembling $(@).s file...'
+	$(AS) -o $(BUILD)/$(basename $(@)).o $(BUILD)/$(basename $(@)).s
+	$(MV) -f $(BUILD)/$(basename $(@)).inc $(INC)/$(basename $(@)).inc           
+	@echo 'Done!'
+$(BIN_FILES): $(wildcard %.*)
+	@echo 'Converting $(@) file to asm...'
+	@$(BIN2S) $(DATA)/$(@) > $(BUILD)/$(@).s
+	@echo 'Creating $(@).inc include file...'
+	@echo "var" > `(echo "$(INC)/"$(@F) | tr . .)`.inc
+	@echo " " `(echo $(@F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end: array [0..0] of cuint8; cvar; external;" >> `(echo "$(INC)/"$(@F) | tr . .)`.inc
+	@echo " " `(echo $(@F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`": array [0..0] of cuint8; cvar; external;" >> `(echo "$(INC)/"$(@F) | tr . .)`.inc
+	@echo " " `(echo $(@F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size": cuint32; cvar; external;" >> `(echo "$(INC)/"$(@F) | tr . .)`.inc
+	@echo 'Assembling $(@).s file...'
+	@$(AS) -o $(BUILD)/$(@).o $(BUILD)/$(@).s
+	@echo 'Done!'
+data.gbfs.o:
+	@cd GBFS && gbfs ../$(BUILD)/data.gbfs $(GBFS_FILES)
+	$(BIN2S) $(BUILD)/data.gbfs > $(BUILD)/data.gbfs.s
+	$(AS) -o $(BUILD)/data.gbfs.o $(BUILD)/data.gbfs.s
+make_filesystem:
+	@$(NDSTOOL) -c $(BIN)/$(TARGET_PROGRAMS).fs.nds -9 $(BIN)/$(TARGET_PROGRAMS).nef.bin -d $(CURDIR)/$(FILESYSTEM)

+ 124 - 0
packages/libndsfpc/examples/graphics/grit/256colorTilemap/Makefile.fpc

@@ -0,0 +1,124 @@
+#
+#   Makefile.fpc for Free Pascal libndsfpc 2.x.y Examples
+#
+
+[target]
+loaders= 
+programs=tilemap_256_color
+
+[require]
+packages=libndsfpc
+tools=bin2s mmutil grit_fpc rmdir mv ndstool
+nortl=y
+
+[install]
+fpcpackage=y
+
+[default]
+cpu=arm
+target=nds
+fpcdir=../../../../../..
+
+[compiler]
+options=-Xm
+targetdir=$(BIN)  
+unittargetdir=$(BUILD)
+
+[clean]
+files=*.elf *.o *.s *.nds *.nef *.h *.bin *.map \
+       $(BUILD)/* \
+       $(INC)/* \
+       $(BIN)/*
+units=*
+
+
+[prerules]
+BIN = bin
+BUILD = build
+DATA = data
+FILESYSTEM = filesystem
+GFX = gfx
+INC = inc
+AUDIO_FILES = $(foreach dir, $(notdir $(wildcard audio/*.*)), $(CURDIR)/audio/$(dir))
+GFX_FILES   = $(foreach dir, $(GFX), $(notdir $(wildcard $(dir)/*.bmp $(dir)/*.png)))
+BIN_FILES   = $(foreach dir, $(DATA), $(notdir $(wildcard $(dir)/*)))
+GBFS_FILES  = $(foreach dir, GBFS, $(notdir $(wildcard $(dir)/*)))
+
+[rules]
+.NOTPARALLEL:
+clean: dir_delete fpc_clean fpc_cleanall
+all: dir_make $(BIN_FILES) $(GFX_FILES) fpc_all 
+filesystem: all make_filesystem
+
+
+
+#
+# Delete temp directories
+#
+dir_delete:
+        @$(DELTREE) $(CURDIR)/$(BUILD) 
+        @$(DELTREE) $(CURDIR)/$(INC) 
+        @$(DELTREE) $(CURDIR)/$(BIN) 
+                
+#
+# Create temp directories
+#
+dir_make:
+ifneq ($(BUILD), $(CURDIR))
+        @$(MKDIR) $(BUILD)
+endif
+ifneq ($(INC), $(CURDIR))
+        @$(MKDIR) $(INC)
+endif
+ifneq ($(BIN), $(CURDIR))
+        @$(MKDIR) $(BIN)
+endif
+
+#
+# Audio files processing rule
+#
+soundbank.bin.o : $(AUDIO_FILES)
+        @$(MMUTIL) $^ -d -o$(BUILD)/soundbank.bin -h$(BUILD)/soundbank.h
+        $(BIN2S) $(BUILD)/soundbank.bin > $(BUILD)/soundbank.bin.s
+        $(AS) -o $(BUILD)/soundbank.bin.o $(BUILD)/soundbank.bin.s
+
+#
+# Png files processing rule
+#
+$(GFX_FILES): $(wildcard %.bmp %.png)
+        @echo 'Converting $(@) file to asm...'
+        $(GRIT_FPC) $(GFX)/$(@) -fp -fts -ff $(GFX)/$(basename $(@)).grit -o$(BUILD)/$(@)
+        @echo 'Assembling $(@).s file...'
+        $(AS) -o $(BUILD)/$(basename $(@)).o $(BUILD)/$(basename $(@)).s
+        $(MV) -f $(BUILD)/$(basename $(@)).inc $(INC)/$(basename $(@)).inc           
+        @echo 'Done!'
+
+#
+# Binary files processing rule
+# 
+$(BIN_FILES): $(wildcard %.*)
+        @echo 'Converting $(@) file to asm...'
+        @$(BIN2S) $(DATA)/$(@) > $(BUILD)/$(@).s
+        @echo 'Creating $(@).inc include file...'
+        @echo "var" > `(echo "$(INC)/"$(@F) | tr . .)`.inc
+        @echo " " `(echo $(@F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end: array [0..0] of cuint8; cvar; external;" >> `(echo "$(INC)/"$(@F) | tr . .)`.inc
+        @echo " " `(echo $(@F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`": array [0..0] of cuint8; cvar; external;" >> `(echo "$(INC)/"$(@F) | tr . .)`.inc
+        @echo " " `(echo $(@F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size": cuint32; cvar; external;" >> `(echo "$(INC)/"$(@F) | tr . .)`.inc
+        @echo 'Assembling $(@).s file...'
+        @$(AS) -o $(BUILD)/$(@).o $(BUILD)/$(@).s
+        @echo 'Done!'
+
+
+#
+# GBFS files processing rule
+#
+data.gbfs.o:
+        @cd GBFS && gbfs ../$(BUILD)/data.gbfs $(GBFS_FILES)
+        $(BIN2S) $(BUILD)/data.gbfs > $(BUILD)/data.gbfs.s
+        $(AS) -o $(BUILD)/data.gbfs.o $(BUILD)/data.gbfs.s
+
+#
+# Nitro Filesystem processing rule
+# 
+make_filesystem:
+	@$(NDSTOOL) -c $(BIN)/$(TARGET_PROGRAMS).fs.nds -9 $(BIN)/$(TARGET_PROGRAMS).nef.bin -d $(CURDIR)/$(FILESYSTEM)

+ 21 - 0
packages/libndsfpc/examples/graphics/grit/256colorTilemap/gfx/tilemap.grit

@@ -0,0 +1,21 @@
+#-------------------------------------------------------
+# graphics in tile format
+#-------------------------------------------------------
+-gt
+
+#-------------------------------------------------------
+# tile reduction by tiles, palette and hflip/vflip
+#-------------------------------------------------------
+-mRtf
+
+#-------------------------------------------------------
+# graphics bit depth is 8 (256 color)
+#-------------------------------------------------------
+-gB8
+
+-p
+
+#-------------------------------------------------------
+# map layout standard bg format
+#-------------------------------------------------------
+-mLs

BIN
packages/libndsfpc/examples/graphics/grit/256colorTilemap/gfx/tilemap.png


+ 39 - 0
packages/libndsfpc/examples/graphics/grit/256colorTilemap/tilemap_256_color.pp

@@ -0,0 +1,39 @@
+program tilemap;
+
+{$L build/tilemap.o}
+
+{$mode objfpc}
+
+uses
+  ctypes, nds9;
+
+{$include inc/tilemap.inc}
+
+
+begin
+
+	// enable the main screen with background 0 active
+	videoSetMode(MODE_0_2D or DISPLAY_BG0_ACTIVE);
+
+	// map bank A for use with the background
+	vramSetBankA(VRAM_A_MAIN_BG);
+
+	// enable background 0 in 256 color mode with a 256x256 map
+	// BG_TILE_BASE changes the offset where tile data is stored
+	// BG_MAP_BASE gives the offset to the map data
+	BGCTRL[0] := BG_TILE_BASE(1) or BG_MAP_BASE(0) or BG_COLOR_256 or BG_32x32;
+
+	// use dma to copy the tile, map and palette data to VRAM
+	// CHAR_BASE_BLOCK gives us the actual address of the tile data
+	// SCREEN_BASE_BLOCK does the same thing for maps
+	// these should match the BG_TILE_BASE and BG_MAP base numbers above
+	dmaCopy(@tilemapTiles, CHAR_BASE_BLOCK(1), tilemapTilesLen);
+	dmaCopy(@tilemapMap, SCREEN_BASE_BLOCK(0), tilemapMapLen);
+	dmaCopy(@tilemapPal, BG_PALETTE, tilemapPalLen);
+ 
+	// finally, hang around in an infinite loop
+	// using swiWaitForVBlank here puts the DS into a low power loop
+	while true do
+		swiWaitForVBlank();
+
+end.

+ 18 - 0
packages/libndsfpc/examples/graphics/grit/Makefile.fpc

@@ -0,0 +1,18 @@
+#
+#   Makefile.fpc for Free Pascal libndsfpc 2.x.y Examples
+#
+
+[target]
+dirs=256colorTilemap
+
+[require]
+packages=libndsfpc
+
+[install]
+fpcpackage=y
+
+[default]
+fpcdir=../../../../..
+
+[rules]
+.NOTPARALLEL:

+ 15 - 1
packages/libndsfpc/examples/hello_world/helloWorld.pp

@@ -9,6 +9,12 @@ var
   frame: integer;
   frame: integer;
 	touchXY: touchPosition;
 	touchXY: touchPosition;
 
 
+  REG_DIVPCNT       : pcuint8 = pointer($4000280);
+  DIV_NUMER   : pcuint32 = pointer($4000290);
+  DIV_DENOM : pcuint32 = pointer($4000298);
+  DIV_RESULT : pcuint32 = pointer($40002A0);
+  DIVREM_RESULT : pcuint32 = pointer($40002A8);
+
 procedure Vblank();
 procedure Vblank();
 begin
 begin
   inc(frame);
   inc(frame);
@@ -19,7 +25,15 @@ begin
   irqSet(IRQ_VBLANK, @Vblank);
   irqSet(IRQ_VBLANK, @Vblank);
 
 
 	consoleDemoInit();
 	consoleDemoInit();
-
+  iprintf('%i div %i'#10, DIV_NUMER^, DIV_DENOM^ );
+  iprintf('%i, %i'#10, DIV_RESULT^, DIVREM_RESULT^);
+  
+  DIV_NUMER^ := 5;
+  DIV_DENOM^ := 0;  
+  iprintf('%i div %i'#10, DIV_NUMER^, DIV_DENOM^ );
+
+  iprintf('%i'#10,DIV_RESULT^ );
+  iprintf('%i'#10,DIVREM_RESULT^ );
 	iprintf('      Hello DS dev''rs'#10);
 	iprintf('      Hello DS dev''rs'#10);
 	iprintf(#27'[32m' + 'www.devkitpro.org'#10);
 	iprintf(#27'[32m' + 'www.devkitpro.org'#10);
 	iprintf(#27'[32;1m' + 'www.drunkencoders.com'#27'[39m');
 	iprintf(#27'[32;1m' + 'www.drunkencoders.com'#27'[39m');

+ 1 - 1
packages/libndsfpc/examples/time/RealTimeClock/Makefile.fpc

@@ -4,7 +4,7 @@
 
 
 [target]
 [target]
 loaders=
 loaders=
-programs=RealTimeClock
+programs=realtimeclock
 
 
 [require]
 [require]
 packages=libndsfpc
 packages=libndsfpc

+ 2 - 2
packages/libndsfpc/src/dswifi/inc/dswifi9.inc

@@ -51,8 +51,8 @@
 const
 const
   WIFIINIT_OPTION_USELED          = $0002;
   WIFIINIT_OPTION_USELED          = $0002;
 
 
-  WIFIINIT_OPTION_USEHEAP_128     = $0000;
-  WIFIINIT_OPTION_USEHEAP_64      = $1000;
+  WIFIINIT_OPTION_USEHEAP_64      = $0000;
+  WIFIINIT_OPTION_USEHEAP_128     = $1000;
   WIFIINIT_OPTION_USEHEAP_256     = $2000;
   WIFIINIT_OPTION_USEHEAP_256     = $2000;
   WIFIINIT_OPTION_USEHEAP_512     = $3000;
   WIFIINIT_OPTION_USEHEAP_512     = $3000;
   WIFIINIT_OPTION_USECUSTOMALLOC  = $4000;
   WIFIINIT_OPTION_USECUSTOMALLOC  = $4000;

+ 2 - 1
packages/libndsfpc/src/fat/fat.inc

@@ -60,7 +60,8 @@ const
 // Methods to modify DOS File Attributes
 // Methods to modify DOS File Attributes
 
 
 function FAT_getAttr(const _file: pcchar): cint; cdecl; external;
 function FAT_getAttr(const _file: pcchar): cint; cdecl; external;
-function FAT_setAttr(const _file: pcchar; attr: cint): cint; cdecl; external;
+function FAT_setAttr(const _file: pcchar; attr: cuint8): cint; cdecl; external;
+
 
 
 {$define LIBFAT_FEOS_MULTICWD}
 {$define LIBFAT_FEOS_MULTICWD}
 
 

Some files were not shown because too many files changed in this diff