Преглед изворни кода

* synchronised with trunk till r42256

git-svn-id: branches/debug_eh@42257 -
Jonas Maebe пре 6 година
родитељ
комит
c262c5dbc9
100 измењених фајлова са 6027 додато и 2656 уклоњено
  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/tcpassrcutil.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/tcscanner.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.fpc 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.fpc 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/maxmod7.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/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/input.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/boxtest.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/decompress.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/exceptions.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/linkedlist.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/paddle.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/ndstypes.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/timers.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/trtti19.pp svneol=native#text/pascal
 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/trtti4.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 =
      (fpu_none,
       fpu_soft,
-      fp_libgcc
+      fpu_libgcc
      );
 
    tcontrollertype =

+ 3 - 0
compiler/avr/cpupara.pas

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

+ 20 - 7
compiler/avr/rgcpu.pas

@@ -155,6 +155,13 @@ unit rgcpu;
               A_LDI:
                 for r:=RS_R0 to RS_R15 do
                   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:
                 begin
                   for r:=RS_R0 to RS_R15 do
@@ -162,6 +169,14 @@ unit rgcpu;
                   for r:=RS_R0 to RS_R15 do
                     add_edge(r,GetSupReg(taicpu(p).oper[1]^.reg));
                 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;
@@ -175,8 +190,8 @@ unit rgcpu;
         if not(spilltemp.offset in [0..63]) then
           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
           begin
             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[1]^.reg))<>orgreg) then
                   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;
                   end
                 else if (getregtype(oper[1]^.reg)=regtype) and
@@ -196,7 +209,7 @@ unit rgcpu;
                    (get_alias(getsupreg(oper[0]^.reg))<>orgreg) then
                   begin
                     instr.loadref(1,spilltemp);
-                    opcode:=A_LD;
+                    opcode:=A_LDD;
                     result:=true;
                   end;
               end;

+ 1 - 1
compiler/dbgstabs.pas

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

+ 1 - 1
compiler/dbgstabx.pas

@@ -158,7 +158,7 @@ implementation
           declstabnr:=def_stab_number(def)
         end;
       if (symname='') or
-         not(def.typ in tagtypes) then
+         not(use_tag_prefix(def)) then
         begin
           st:=def_stabstr_evaluate(def,':$1$2=',[stabchar,declstabnr]);
           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;
 
+    {# 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 }
     function is_packed_array(p: tdef) : boolean;
 
@@ -752,6 +755,14 @@ implementation
                  );
       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 }
     function is_ansistring(p : tdef) : boolean;
       begin

+ 5 - 0
compiler/fpcdefs.inc

@@ -34,6 +34,11 @@
 
 {$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
   into utils/ppudump without any CPU specific code PM }
 {$ifdef generic_cpu}

+ 4 - 0
compiler/hlcg2ll.pas

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

+ 5 - 1
compiler/hlcgobj.pas

@@ -823,9 +823,13 @@ implementation
           objectdef,
           procvardef,
           procdef,
-          arraydef,
           formaldef:
             result:=R_ADDRESSREGISTER;
+          arraydef:
+            if tstoreddef(def).is_intregable then
+              result:=R_INTREGISTER
+            else
+              result:=R_ADDRESSREGISTER;
           floatdef:
             if use_vectorfpu(def) then
               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
 % should use for the reference. This warning is only used in Delphi mode where
 % 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
 % 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
 % 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
-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
 % 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

+ 1 - 1
compiler/msgidx.inc

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

Разлика између датотеке није приказан због своје велике величине
+ 270 - 273
compiler/msgtxt.inc


+ 56 - 13
compiler/ncgmem.pas

@@ -855,7 +855,9 @@ implementation
          paraloc2 : tcgpara;
          subsetref : tsubsetreference;
          temp : longint;
+         hreg : tregister;
          indexdef : tdef;
+         i : Integer;
       begin
          paraloc1.init;
          paraloc2.init;
@@ -936,19 +938,29 @@ implementation
            end
          else
            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;
 
          { location must be memory }
@@ -994,6 +1006,37 @@ implementation
                   update_reference_offset(location.reference,extraoffset,bytemulsize);
                   { adjust alignment after this change }
                   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
               else
                 begin

+ 1 - 0
compiler/ncnv.pas

@@ -3255,6 +3255,7 @@ implementation
 
       begin
          first_array_to_pointer:=nil;
+         make_not_regable(left,[ra_addr_regable]);
          expectloc:=LOC_REGISTER;
       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
            can't be a regvar either }
          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
              (tstringdef(left.resultdef).stringtype in [st_shortstring,st_longstring])) then
            make_not_regable(left,[ra_addr_regable]);

+ 279 - 10
compiler/ogomf.pas

@@ -24,6 +24,8 @@ unit ogomf;
 
 {$i fpcdefs.inc}
 
+{$PackSet 1}
+
 interface
 
     uses
@@ -165,6 +167,8 @@ interface
         function ReadPubDef(RawRec: TOmfRawRecord; objdata:TObjData): Boolean;
         function ReadModEnd(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;
 
         property LNames: TOmfOrderedNameCollection read FLNames;
@@ -363,6 +367,115 @@ interface
         netoPharLap286DosExtenderOS2       = $81,
         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)
         constructor create(info: pasminfo; smart:boolean);override;
       end;
@@ -1221,7 +1334,8 @@ implementation
       var
         RawRecord: TOmfRawRecord;
         Header: TOmfRecord_THEADR;
-        DllImport_COMENT: TOmfRecord_COMENT;
+        DllImport_COMENT: TOmfRecord_COMENT=nil;
+        DllImport_COMENT_IMPDEF: TOmfRecord_COMENT_IMPDEF=nil;
         ModEnd: TOmfRecord_MODEND;
       begin
         { write header record }
@@ -1233,20 +1347,26 @@ implementation
         Header.Free;
 
         { 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
           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
         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);
+        FreeAndNil(DllImport_COMENT);
         RawRecord.WriteTo(FWriter);
-        DllImport_COMENT.Free;
 
         { write MODEND record }
         ModEnd:=TOmfRecord_MODEND.Create;
@@ -1730,6 +1850,18 @@ implementation
         Result:=True;
       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;
       var
         reloc: TOmfRelocation;
@@ -2111,7 +2243,17 @@ implementation
                 case FCOMENTRecord.CommentClass of
                   CC_OmfExtension:
                     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;
                   CC_LIBMOD:
                     begin
@@ -3250,6 +3392,133 @@ cleanup:
         inherited destroy;
       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
 ****************************************************************************}

+ 200 - 0
compiler/omfbase.pas

@@ -160,6 +160,12 @@ interface
     CC_DependencyFileBorland    = $E9;
     CC_CommandLineMicrosoft     = $FF;
 
+    { CC_OmfExtension subtypes }
+    CC_OmfExtension_IMPDEF      = $01;
+    CC_OmfExtension_EXPDEF      = $02;
+    CC_OmfExtension_INCDEF      = $03;
+    CC_OmfExtension_LNKDIR      = $05;
+
   type
     TOmfSegmentAlignment = (
       saAbsolute                = 0,
@@ -324,6 +330,58 @@ interface
       property NoList: Boolean read GetNoList write SetNoList;
     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 = class(TOmfParsedRecord)
@@ -1542,6 +1600,148 @@ implementation
       RawRecord.CalculateChecksumByte;
     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 }
 
   constructor TOmfRecord_LNAMES.Create;

+ 9 - 7
compiler/pp.lpi

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

+ 15 - 3
compiler/symdef.pas

@@ -2231,11 +2231,23 @@ implementation
             is_intregable:=(is_implicit_pointer_object_type(self)) and not needs_inittable;
           setdef:
             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:
             begin
-{$ifdef llvm}
+{$ifdef cpuhighleveltarget}
               is_intregable:=false;
-{$else llvm}
+{$else cpuhighleveltarget}
               recsize:=size;
               is_intregable:=
                 ispowerof2(recsize,temp) and
@@ -2247,7 +2259,7 @@ implementation
                   (recsize <= sizeof(aint))
                  ) and
                  not needs_inittable;
-{$endif llvm}
+{$endif cpuhighleveltarget}
             end;
           else
            is_intregable:=false;

+ 2 - 1
compiler/systems.inc

@@ -280,7 +280,8 @@
              ld_int_nativent,
              ld_int_netware,
              ld_int_windows,
-             ld_int_msdos
+             ld_int_msdos,
+             ld_int_win16
        );
 
        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})
        );
 
+       { 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
        targetinfos   : array[tsystem] of psysteminfo;
        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('/*         & __end__ to point to end of iwram or    */');
       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('/* This file is released into the public domain		*/');
       add('/* for commercial or non-commercial use with no		*/');
-      add('/* restrictions placed upon it.				*/');
+      add('/* restrictions placed upon it.						*/');
       add('');
       add('/* NOTE!!!: This linker script defines the RAM &  */');
       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_ARCH(arm)');
       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('MEMORY {');
       add('');
@@ -288,10 +279,13 @@ begin
       add('	ewram	: ORIGIN = 0x02000000, LENGTH = 256K');
       add('}');
       add('');
-      add('__text_start	=	ORIGIN(rom);');
+      add('');
+      add('');
+      add('__text_start	=	ORIGIN(ewram);');
       add('__eheap_end	=	ORIGIN(ewram) + LENGTH(ewram);');
       add('__iwram_start	=	ORIGIN(iwram);');
       add('__iwram_top	=	ORIGIN(iwram) + LENGTH(iwram);;');
+      add('');
       add('__sp_irq	=	__iwram_top - 0x060;');
       add('__sp_usr	=	__sp_irq - 0x0a0;');
       add('__irq_flags	=	0x03007ff8;');
@@ -299,19 +293,26 @@ begin
       add('SECTIONS');
       add('{');
       add('	. = __text_start;');
-      add('	.init :');
+      add('	. = __text_start;');
+      add('	.crt0 :');
       add('	{');
-      add('		KEEP (*(.init))');
+      add('		KEEP (*(.crt0))');
       add('		. = ALIGN(4);');
-      add('	} >rom =0xff');
+      add('	} >ewram =0xff');
+      add('');
+      add('	.init :');
+      add('	{');
+      add('		KEEP (*(SORT_NONE(.init)))');
+      add('	} >ewram');
       add('');
       add('	.plt :');
       add('	{');
       add('		*(.plt)');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-      add('	} >rom');
+      add('	} >ewram');
       add('');
-      add('	.text  :   /* ALIGN (4): */');
+      add('');
+      add('	.text  ALIGN (4):');
       add('	{');
       add('		*(EXCLUDE_FILE (*.iwram*) .text)');
       add('		*(.text .stub .text.* .gnu.linkonce.t.*)');
@@ -320,14 +321,14 @@ begin
       add('		*(.gnu.warning)');
       add('		*(.glue_7t) *(.glue_7) *(.vfp11_veneer)');
       add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
-      add('	} >rom = 0xff');
+      add('	} >ewram = 0xff');
       add('');
       add('	__text_end = .;');
       add('	.fini           :');
       add('	{');
       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('	.rodata :');
       add('	{');
@@ -338,12 +339,26 @@ begin
       add('		*(.gnu.linkonce.r*)');
       add('		SORT(CONSTRUCTORS)');
       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('  .ARM.exidx   : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >rom');
+      add('  .ARM.exidx   : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >ewram');
       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('	{');
       add('		/*	gcc uses crtbegin.o to find the start of the constructors, so');
@@ -357,7 +372,7 @@ begin
       add('		KEEP (*(SORT(.ctors.*)))');
       add('		KEEP (*(.ctors))');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-      add('	} >rom = 0');
+      add('	} >ewram = 0');
       add('');
       add('	.dtors :');
       add('	{');
@@ -366,144 +381,121 @@ begin
       add('		KEEP (*(SORT(.dtors.*)))');
       add('		KEEP (*(.dtors))');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-      add('	} >rom = 0');
-      add('');
+      add('	} >ewram = 0');
       add('');
+      add('	.jcr            : { KEEP (*(.jcr)) } >ewram');
       add('	.eh_frame :');
       add('	{');
       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('	.gcc_except_table :');
       add('	{');
       add('		*(.gcc_except_table)');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-      add('	} >rom = 0');
+      add('	} >ewram = 0');
       add('');
       add('	__iwram_lma = .;');
       add('');
       add('	.iwram __iwram_start : AT (__iwram_lma)');
       add('	{');
-      add('		__iwram_start = ABSOLUTE(.) ;');
+      add('		__iwram_start__ = ABSOLUTE(.) ;');
       add('		*(.iwram)');
       add('		*iwram.*(.text)');
       add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-      add('		__iwram_end = ABSOLUTE(.) ;');
+      add('		__iwram_end__ = ABSOLUTE(.) ;');
       add('	} >iwram = 0xff');
       add('');
       add('	__data_lma = __iwram_lma + SIZEOF(.iwram) ;');
       add('');
-      add('	.bss ALIGN(4) (NOLOAD) :');
+      add('	.bss ALIGN(4) (NOLOAD):');
       add('	{');
-      add('		__bss_start = ABSOLUTE(.);');
       add('		__bss_start__ = ABSOLUTE(.);');
       add('		*(.dynbss)');
       add('		*(.gnu.linkonce.b*)');
       add('		*(.bss*)');
       add('		*(COMMON)');
       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('	.data ALIGN(4) : AT (__data_lma)');
       add('	{');
-      add('		__data_start = ABSOLUTE(.);');
+      add('		__data_start__ = ABSOLUTE(.);');
       add('		*(.data)');
       add('		*(.data.*)');
       add('		*(.gnu.linkonce.d*)');
-      add('		*(.fpc*)');
       add('		CONSTRUCTORS');
-      add('		. = ALIGN(4);');
+      add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
+      add('		__data_end__  =  ABSOLUTE(.);');
       add('	} >iwram = 0xff');
       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('	__init_lma = __preinit_lma + SIZEOF(.preinit_array);');
+      add('	PROVIDE (edata = .);');
+      add('	__iwram_overlay_start = . ;');
       add('');
-      add('	PROVIDE (__init_array_start = .);');
-      add('	.init_array     : AT (__init_lma)');
+      add('	OVERLAY ALIGN(4) : NOCROSSREFS AT (__iwram_overlay_lma)');
       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('	.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('	__jcr_lma = __fini_lma + SIZEOF(.fini_array);');
-      add('	.jcr            : AT (__jcr_lma) { KEEP (*(.jcr)) } >iwram');
+      add('	__iwram_overlay_end = __ewram_lma ;');
       add('');
-      add('	__data_end  =  ABSOLUTE(.);');
-      add('	__iwram_overlay_lma = __jcr_lma + SIZEOF(.jcr);');
+      add('	/* v1.3 */');
+      add('	__ewram_start =  __ewram_lma ;');
       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('	{');
       add('		*(.ewram)');
       add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
-      add('	}>ewram = 0xff');
+      add('		__ewram_end = ABSOLUTE(.);');
+      add('	} >ewram = 0xff');
       add('');
-      add('	__pad_lma = __ewram_lma + SIZEOF(.ewram);');
+      add('	__ewram_overlay_lma = __ewram_lma + SIZEOF(.ewram);');
       add('');
       add('	.sbss ALIGN(4)(NOLOAD):');
       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('	/* 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('		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('	/* Stabs debugging sections.  */');
       add('	.stab 0 : { *(.stab) }');
@@ -513,9 +505,9 @@ begin
       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 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) }');
@@ -540,9 +532,6 @@ begin
       add('	.debug_varnames  0 : { *(.debug_varnames) }');
       add('	.stack 0x80000 : { _stack = .; *(.stack) }');
       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('}');
     end;
 

+ 199 - 103
compiler/systems/t_nds.pas

@@ -248,22 +248,24 @@ begin
       if apptype=app_arm9 then //ARM9
       begin
         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('	vectors	: ORIGIN = 0x01000000, LENGTH = 256');
         add('	itcm	: ORIGIN = 0x01000100, LENGTH = 32K - 256');
         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_ARCH(arm)');
         add('ENTRY(_start)');
         add('');
-        add('__vectors_start	=	ORIGIN(vectors);');
-        add('__itcm_start	=	ORIGIN(itcm);');
         add('__ewram_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('__irq_flags	=	__dtcm_top - 0x08;');
         add('__irq_vector	=	__dtcm_top - 0x04;');
@@ -272,52 +274,67 @@ begin
         add('__sp_irq	=	__sp_svc - 0x100;');
         add('__sp_usr	=	__sp_irq - 0x100;');
         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('{');
-        add('	.init	:');
+        add('	/* Secure area crap */');
+        add('	.secure : { *(.secure) } >ewram :main = 0');
+        add('');
+        add('	.crt0	:');
         add('	{');
         add('		__text_start = . ;');
-        add('		KEEP (*(.init))');
+        add('		KEEP (*(.crt0))');
         add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
-        add('	} >ewram = 0xff');
+        add('	} >ewram :main = 0x00');
         add('');
-        add('	.plt : { *(.plt) } >ewram = 0xff');
+        add('	.plt : { *(.plt) } >ewram :main = 0xff');
         add('');
-        add('	.text :   /* ALIGN (4): */');
+        add('	.init :');
         add('	{');
-        add('		*(EXCLUDE_FILE (*.itcm*) .text)');
+        add('		KEEP (*(SORT_NONE(.init)))');
+        add('	} >ewram :main');
         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)');
-        add('		*(.gnu.linkonce.t*)');
+        add('		*(EXCLUDE_FILE(*.twl*) .gnu.warning)');
+        add('		*(EXCLUDE_FILE(*.twl*) .gnu.linkonce.t*)');
         add('		*(.glue_7)');
         add('		*(.glue_7t)');
         add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
-        add('	} >ewram = 0xff');
+        add('	} >ewram :main = 0xff');
         add('');
         add('	.fini           :');
         add('	{');
         add('		KEEP (*(.fini))');
-        add('	} >ewram =0xff');
+        add('	} >ewram :main =0xff');
         add('');
         add('	__text_end = . ;');
         add('');
         add('	.rodata :');
         add('	{');
-        add('		*(.rodata)');
+        add('		*(EXCLUDE_FILE(*.twl*) .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('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-        add('	} >ewram = 0xff');
+        add('	} >ewram :main = 0xff');
         add('');
-        add('	.ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >ewram');
+        add('	.ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >ewram :main');
         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('');
         add('	/*	Ensure the __preinit_array_start label is properly aligned.  We');
@@ -328,21 +345,21 @@ begin
         add('	. = ALIGN(32 / 8);');
         add('');
         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 (__init_array_start = .);');
         add('	.init_array     :');
         add('	{');
         add('		KEEP (*(SORT(.init_array.*)))');
         add('		KEEP (*(.init_array))');
-        add('	} >ewram = 0xff');
+        add('	} >ewram :main = 0xff');
         add('	PROVIDE (__init_array_end = .);');
         add('	PROVIDE (__fini_array_start = .);');
         add('	.fini_array     :');
         add('	{');
         add('		KEEP (*(.fini_array))');
         add('		KEEP (*(SORT(.fini_array.*)))');
-        add('	} >ewram = 0xff');
+        add('	} >ewram :main = 0xff');
         add('');
         add('	PROVIDE (__fini_array_end = .);');
         add('');
@@ -359,7 +376,7 @@ begin
         add('		KEEP (*(SORT(.ctors.*)))');
         add('		KEEP (*(.ctors))');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-        add('	} >ewram = 0xff');
+        add('	} >ewram :main = 0xff');
         add('');
         add('	.dtors :');
         add('	{');
@@ -368,98 +385,122 @@ begin
         add('		KEEP (*(SORT(.dtors.*)))');
         add('		KEEP (*(.dtors))');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-        add('	} >ewram = 0xff');
+        add('	} >ewram :main = 0xff');
         add('');
         add('	.eh_frame :');
         add('	{');
         add('		KEEP (*(.eh_frame))');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-        add('	} >ewram = 0xff');
+        add('	} >ewram :main = 0xff');
         add('');
         add('	.gcc_except_table :');
         add('	{');
         add('		*(.gcc_except_table)');
         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('	.ewram ALIGN(4) : ');
+        add('	.ewram ALIGN(4) :'); 
         add('	{');
         add('		__ewram_start = ABSOLUTE(.) ;');
         add('		*(.ewram)');
         add('		*ewram.*(.text)');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-        add('	} >ewram = 0xff');
+        add('	} >ewram :main = 0xff');
         add('');
         add('');
         add('	.data ALIGN(4) :');
         add('	{');
         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('		. = ALIGN(4);');
         add('		__data_end = ABSOLUTE(.) ;');
-        add('	} >ewram = 0xff');
+        add('	} >ewram :main = 0xff');
         add('');
-        add('');
-        add('	__dtcm_lma = . ;');
         add('	__bss_vma = . ;');
         add('');
-        add('	.dtcm __dtcm_start : AT (__dtcm_lma)');
+        add('	.dtcm :');
         add('	{');
+        add('		__dtcm_lma = LOADADDR(.dtcm);');
+        add('		__dtcm_start = ABSOLUTE(.);');
         add('		*(.dtcm)');
         add('		*(.dtcm.*)');
         add('		. = ALIGN(4);');
         add('		__dtcm_end = ABSOLUTE(.);');
-        add('	} >dtcm  = 0xff');
-        add('');
+        add('	} >dtcm AT>ewram :dtcm = 0xff');
         add('');
-        add('	__itcm_lma = __dtcm_lma + SIZEOF(.dtcm);');
-        add('');
-        add('	.itcm __itcm_start : AT (__itcm_lma)');
+        add('	.itcm :');
         add('	{');
+        add('		__itcm_lma = LOADADDR(.itcm);');
+        add('		__itcm_start = ABSOLUTE(.);');
         add('		*(.itcm)');
-        add('		*itcm.*(.text)');
+        add('		*.itcm*(.text .stub .text.*)');
         add('		. = ALIGN(4);');
         add('		__itcm_end = ABSOLUTE(.);');
-        add('	} >itcm = 0xff');
-        add('	');
-        add('	__vectors_lma = __itcm_lma + SIZEOF(.itcm);');
+        add('	} >itcm AT>ewram :itcm = 0xff');
         add('');
-        add('	.vectors __vectors_start : AT (__vectors_lma)');
+        add('	.vectors :');
         add('	{');
-        add('		*(.vectors)');
-        add('		*vectors.*(.text)');
+        add('		__vectors_lma = LOADADDR(.vectors);');
+        add('		__vectors_start = ABSOLUTE(.);');
+        add('		KEEP(*(.vectors .vectors.*))');
         add('		. = ALIGN(4);');
         add('		__vectors_end = ABSOLUTE(.);');
-        add('	} >vectors = 0xff');
+        add('	} >vectors AT>ewram :vectors = 0xff');
         add('	');
-        add('	.sbss __dtcm_end (NOLOAD): ');
+        add('	.sbss __dtcm_end (NOLOAD):'); 
         add('	{');
         add('		__sbss_start = ABSOLUTE(.);');
         add('		__sbss_start__ = ABSOLUTE(.);');
         add('		*(.sbss)');
         add('		. = ALIGN(4);    /* REQUIRED. LD is flaky without it. */');
         add('		__sbss_end = ABSOLUTE(.);');
-        add('	} >dtcm ');
+        add('	} >dtcm :NONE');
         add('');
-        add('	.bss __bss_vma (NOLOAD): ');
+        add('	.bss __bss_vma (NOLOAD):'); 
         add('	{');
         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('		__bss_end__ = ABSOLUTE(.) ;');
         add('		__end__ = ABSOLUTE(.) ;');
-        add('	} AT>ewram ');
-        add('');
+        add('	} >ewram :NONE');
         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('	/* Stabs debugging sections.  */');
         add('	.stab 0 : { *(.stab) }');
@@ -497,18 +538,33 @@ begin
         add('	.stack 0x80000 : { _stack = .; *(.stack) }');
         add('	/* These must appear regardless of  .  */');
         add('}');
-        add('');
       end;
       if apptype=app_arm7 then
       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_ARCH(arm)');
         add('ENTRY(_start)');
         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('	ewram  : ORIGIN = 0x02380000, LENGTH = 12M - 512K');
+        add('	rom    : ORIGIN = 0x08000000, LENGTH = 32M');
+        add('	iwram  : ORIGIN = 0x037f8000, LENGTH = 96K');
         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('__iwram_start	=	ORIGIN(iwram);');
@@ -524,30 +580,59 @@ begin
         add('');
         add('SECTIONS');
         add('{');
-        add('	.init	:');
+        add('');
+        add('	.twl :');
         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('		} >iwram = 0xff');
-        add('	.plt : { *(.plt) } >iwram = 0xff');
+        add('	} >ewram :crt0');
         add('');
-        add('	.text :   /* ALIGN (4): */');
+        add('	.text :');
         add('	{');
+        add('		__arm7_lma__ = LOADADDR(.text);');
+        add('		__arm7_start__ = .;');
+        add('		KEEP (*(SORT_NONE(.init)))');
+        add('		*(.plt)');
         add('		*(.text .stub .text.* .gnu.linkonce.t.*)');
         add('		KEEP (*(.text.*personality*))');
         add('		/* .gnu.warning sections are handled specially by elf32.em.  */');
         add('		*(.gnu.warning)');
         add('		*(.glue_7t) *(.glue_7) *(.vfp11_veneer)');
         add('		. = ALIGN(4);  /* REQUIRED. LD is flaky without it. */');
-        add('	} >iwram = 0xff');
+        add('	} >iwram AT>ewram :arm7');
         add('');
         add('	.fini           :');
         add('	{');
         add('		KEEP (*(.fini))');
-        add('	} >iwram =0xff');
-        add('');
-        add('	__text_end = . ;');
+        add('	} >iwram AT>ewram');
         add('');
         add('	.rodata :');
         add('	{');
@@ -558,27 +643,38 @@ begin
         add('		*(.gnu.linkonce.r*)');
         add('		SORT(CONSTRUCTORS)');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-        add('	} >iwram = 0xff');
+        add('	} >iwram AT>ewram');
         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('/* 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)) } >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('	.ctors :');
         add('	{');
@@ -593,7 +689,7 @@ begin
         add('		KEEP (*(SORT(.ctors.*)))');
         add('		KEEP (*(.ctors))');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-        add('	} >iwram = 0xff');
+        add('	} >iwram AT>ewram');
         add('');
         add('	.dtors :');
         add('	{');
@@ -602,21 +698,21 @@ begin
         add('		KEEP (*(SORT(.dtors.*)))');
         add('		KEEP (*(.dtors))');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-        add('	} >iwram = 0xff');
+        add('	} >iwram AT>ewram');
         add('');
         add('	.eh_frame :');
         add('	{');
         add('		KEEP (*(.eh_frame))');
         add('		. = ALIGN(4);   /* REQUIRED. LD is flaky without it. */');
-        add('	} >iwram = 0xff');
+        add('	} >iwram AT>ewram');
         add('');
         add('	.gcc_except_table :');
         add('	{');
         add('		*(.gcc_except_table)');
         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('	.data ALIGN(4) : 	{');
         add('		__data_start = ABSOLUTE(.);');
@@ -626,10 +722,11 @@ begin
         add('		CONSTRUCTORS');
         add('		. = ALIGN(4);');
         add('		__data_end = ABSOLUTE(.) ;');
-        add('	} >iwram = 0xff');
+        add('	} >iwram AT>ewram');
         add('');
-        add('	.bss ALIGN(4) :');
+        add('	.bss ALIGN(4) (NOLOAD) :');
         add('	{');
+        add('		__arm7_end__ = .;');
         add('		__bss_start = ABSOLUTE(.);');
         add('		__bss_start__ = ABSOLUTE(.);');
         add('		*(.dynbss)');
@@ -674,7 +771,6 @@ begin
         add('	.debug_funcnames 0 : { *(.debug_funcnames) }');
         add('	.debug_typenames 0 : { *(.debug_typenames) }');
         add('	.debug_varnames  0 : { *(.debug_varnames) }');
-        add('	.stack 0x80000 : { _stack = .; *(.stack) }');
         add('	/* These must appear regardless of  .  */');
         add('}');
       end;

+ 304 - 298
compiler/systems/t_wii.pas

@@ -224,304 +224,310 @@ begin
    end;   
   with linkres do
    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;
    
    

+ 138 - 16
compiler/systems/t_win16.pas

@@ -69,6 +69,25 @@ implementation
          function  MakeExecutable:boolean;override;
       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
 ****************************************************************************}
@@ -144,9 +163,8 @@ var
   i: Integer;
   hp: texported_item;
   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
   if EList.Count=0 then
     exit;
@@ -169,30 +187,30 @@ begin
       hp:=texported_item(EList[i]);
 
       { 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
         case hp.sym.typ of
           staticvarsym:
-            internal_name:=tstaticvarsym(hp.sym).mangledname;
+            DllExport_COMENT_EXPDEF.InternalName:=tstaticvarsym(hp.sym).mangledname;
           procsym:
-            internal_name:=tprocdef(tprocsym(hp.sym).ProcdefList[0]).mangledname;
+            DllExport_COMENT_EXPDEF.InternalName:=tprocdef(tprocsym(hp.sym).ProcdefList[0]).mangledname;
           else
             internalerror(2015092701);
         end
       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
-        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);
+      FreeAndNil(DllExport_COMENT);
       RawRecord.WriteTo(ObjWriter);
-      DllExport_COMENT.Free;
     end;
 
   { write MODEND record }
@@ -312,13 +330,117 @@ begin
 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
 *****************************************************************************}
 
 initialization
+  RegisterLinker(ld_int_win16,TInternalLinkerWin16);
   RegisterLinker(ld_win16,TExternalLinkerWin16WLink);
   RegisterImport(system_i8086_win16,TImportLibWin16);
   RegisterExport(system_i8086_win16,TExportLibWin16);
+  RegisterDLLScanner(system_i8086_win16,TDLLScannerWin16);
   RegisterTarget(system_i8086_win16_info);
 end.

+ 85 - 6
compiler/x86/rax86.pas

@@ -248,7 +248,8 @@ begin
 end;
 
 Function Tx86Operand.CheckOperand: boolean;
-
+var
+  ErrorRefStr: string;
 begin
   result:=true;
   if (opr.typ=OPR_Reference) then
@@ -257,15 +258,93 @@ begin
         begin
           if (getsupreg(opr.ref.base)=RS_EBP) and (opr.ref.offset>0) then
             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
-                message(asmr_w_no_direct_ebp_for_parameter)
+                message1(asmr_w_no_direct_ebp_for_parameter,ErrorRefStr)
               else
-                message(asmr_w_direct_ebp_for_parameter_regcall);
+                message1(asmr_w_direct_ebp_for_parameter_regcall,ErrorRefStr);
             end
           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;
       if (cs_create_pic in current_settings.moduleswitches) 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 
         WriteLn('  ', lines[i]);
       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
         WriteLn('  ', lines[i]);
       lines.Clear();

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

@@ -59,8 +59,8 @@ Type
     function GetPosition: Int64; override;
     procedure InvalidSeek; override;
   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;
     Property BlowFish : TBlowFish Read FBF;
   end;
@@ -74,7 +74,11 @@ Type
   end;
 
   TBlowFishDeCryptStream = Class(TBlowFishStream)
+  private
+    FSourcePos0: Int64;
   public
+    Constructor Create(AKey : TBlowFishKey; AKeySize : Byte; Dest: TStream); override;
+
     function Read(var Buffer; Count: Longint): Longint; override;
     function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
   end;
@@ -652,6 +656,13 @@ end;
     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;
 
@@ -697,7 +708,13 @@ end;
 function TBlowFishDeCryptStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
 
 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;
 end;
 

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

@@ -1190,7 +1190,6 @@ begin
     oSection := FSectionList.SectionByName(Section,CaseSensitive);
     if oSection <> nil then with oSection.KeyList do
       for i := 0 to Count-1 do
-        if not IsComment(Items[i].Ident) then
          begin
            if Items[i].Ident<>'' then
             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 AssertEquals(const AMessage: string; 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(Expected, Actual: UnicodeString); overload;
-    {$ENDIF}
     class procedure AssertEquals(const AMessage: string; Expected, Actual: integer); overload;
     class procedure AssertEquals(Expected, Actual: integer); overload;
     class procedure AssertEquals(const AMessage: string; Expected, Actual: int64); overload;
@@ -334,9 +332,7 @@ type
   end;
 
   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;
 
   // Made public for 3rd party developers extending TTestCase with new AssertXXX methods
@@ -438,16 +434,15 @@ begin
     Result := format(SCompareNotEqual, [aExpected, aActual]);
 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.
 begin
   if aCheckEqual then
-    Result := format(UnicodeString(SCompare), [aExpected, aActual])
+    Result := unicodeformat(SCompare, [aExpected, aActual])
   else {check unequal requires opposite error message}
-    Result := format(UnicodeString(SCompareNotEqual), [aExpected, aActual]);
+    Result := unicodeformat(SCompareNotEqual, [aExpected, aActual]);
 end;
-{$ENDIF}
+
 
 function ComparisonMsg(const aMsg: string; const aExpected: string; const aActual: string; const aCheckEqual: boolean): string;
 begin
@@ -698,18 +693,18 @@ begin
   AssertTrue(ComparisonMsg(Expected, Actual), Expected=Actual,CallerAddr);
 end;
 
-{$IFDEF UNICODE}
-class procedure TAssert.AssertEquals(const AMessage: string; Expected, Actual: UnicodeString);
+class procedure TAssert.AssertEquals(const AMessage: string; Expected, Actual: Unicodestring);
 begin
-  AssertTrue(ComparisonMsg(AMessage,Expected, Actual), (Expected=Actual),CallerAddr);
+  AssertTrue(ComparisonMsg(AMessage ,Expected, Actual), Expected=Actual,CallerAddr);
 end;
 
 
-class procedure TAssert.AssertEquals(Expected, Actual: UnicodeString);
+class procedure TAssert.AssertEquals(Expected, Actual: Unicodestring);
 begin
-  AssertTrue(ComparisonMsg(Expected, Actual), (Expected=Actual),CallerAddr);
+  AssertTrue(ComparisonMsg(Expected, Actual), Expected=Actual,CallerAddr);
 end;
-{$ENDIF}
+
+
 
 class procedure TAssert.AssertNotNull(const AString: string);
 begin

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

@@ -1525,6 +1525,7 @@ type
     procedure FinishClassOfType(El: TPasClassOfType); virtual;
     procedure FinishPointerType(El: TPasPointerType); virtual;
     procedure FinishArrayType(El: TPasArrayType); virtual;
+    procedure FinishGenericTemplateType(El: TPasGenericTemplateType); virtual;
     procedure FinishResourcestring(El: TPasResString); virtual;
     procedure FinishProcedure(aProc: TPasProcedure); virtual;
     procedure FinishProcedureType(El: TPasProcedureType); virtual;
@@ -5397,7 +5398,9 @@ begin
     EmitTypeHints(El,TPasAliasType(El).DestType);
     end
   else if (C=TPasPointerType) then
-    EmitTypeHints(El,TPasPointerType(El).DestType);
+    EmitTypeHints(El,TPasPointerType(El).DestType)
+  else if C=TPasGenericTemplateType then
+    FinishGenericTemplateType(TPasGenericTemplateType(El));
 end;
 
 procedure TPasResolver.FinishEnumType(El: TPasEnumType);
@@ -5801,6 +5804,24 @@ begin
     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);
 var
   ResolvedEl: TPasResolverResult;
@@ -15852,6 +15873,7 @@ begin
       // resolved when finished
     else if AClass=TPasImplCommand then
     else if AClass=TPasAttributes then
+    else if AClass=TPasGenericTemplateType then
     else if AClass=TPasUnresolvedUnitRef then
       RaiseMsg(20171018121900,nCantFindUnitX,sCantFindUnitX,[AName],El)
     else

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

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

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

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

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

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

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

@@ -17,6 +17,7 @@ Type
     Procedure TestRecordGenerics;
     Procedure TestArrayGenerics;
     Procedure TestGenericConstraint;
+    Procedure TestGenericInterfaceConstraint; // ToDo
     Procedure TestDeclarationConstraint;
     Procedure TestSpecializationDelphi;
     Procedure TestDeclarationDelphi;
@@ -26,7 +27,8 @@ Type
     Procedure TestInlineSpecializationInArgument;
     Procedure TestSpecializeNested;
     Procedure TestInlineSpecializeInStatement;
-    Procedure TestGenericFunction; // ToDo
+    Procedure TestInlineSpecializeInStatementDelphi;
+    Procedure TestGenericFunction;
   end;
 
 implementation
@@ -69,6 +71,32 @@ begin
     'Generic TSomeClass<T: TObject> = class',
     '  b : T;',
     '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;
 end;
@@ -80,8 +108,8 @@ begin
   Scanner.CurrentModeSwitches:=[msDelphi]+Scanner.CurrentModeSwitches ;
   Source.Add('Type');
   Source.Add('  TSomeClass<T: T2> = Class(TObject)');
-  Source.Add('  b : T;');
-  Source.Add('end;');
+  Source.Add('    b : T;');
+  Source.Add('  end;');
   ParseDeclarations;
   AssertNotNull('have generic definition',Declarations.Classes);
   AssertEquals('have generic definition',1,Declarations.Classes.Count);
@@ -105,9 +133,9 @@ begin
   Scanner.CurrentModeSwitches:=[msDelphi]+Scanner.CurrentModeSwitches ;
   Source.Add('Type');
   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;
   AssertNotNull('have generic definition',Declarations.Classes);
   AssertEquals('have generic definition',1,Declarations.Classes.Count);
@@ -126,9 +154,9 @@ begin
   Scanner.CurrentModeSwitches:=[msDelphi]+Scanner.CurrentModeSwitches ;
   Source.Add('Type');
   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;
   AssertNotNull('have generic definition',Declarations.Classes);
   AssertEquals('have generic definition',1,Declarations.Classes.Count);
@@ -148,9 +176,9 @@ begin
   Scanner.CurrentModeSwitches:=[msDelphi]+Scanner.CurrentModeSwitches;
   Source.Add('Type');
   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;
   AssertNotNull('have generic definition',Declarations.Classes);
   AssertEquals('have generic definition',1,Declarations.Classes.Count);
@@ -207,12 +235,25 @@ begin
 end;
 
 procedure TTestGenerics.TestInlineSpecializeInStatement;
+begin
+  Add([
+  'begin',
+  '  t:=specialize a<b>;',
+  '  t:=a.specialize b<c>;',
+  '']);
+  ParseModule;
+end;
+
+procedure TTestGenerics.TestInlineSpecializeInStatementDelphi;
 begin
   Add([
   'begin',
   '  vec:=TVector<double>.create;',
   '  b:=a<b;',
   '  t:=a<b.c<d,e.f>>;',
+  '  t:=a.b<c>;',
+  '  t:=a<b>.c;',
+  // forbidden:'  t:=a<b<c>.d>;',
   '']);
   ParseModule;
 end;
@@ -224,7 +265,7 @@ begin
   'begin',
   'end;',
   'begin',
-  //'  specialize IfThen<word>(true,2,3);',
+  '  specialize IfThen<word>(true,2,3);',
   '']);
   ParseModule;
 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_ImplicitCalls;
     Procedure TestProc_Absolute;
+    Procedure TestProc_LocalInit;
 
     // anonymous procs
     Procedure TestAnonymousProc_Assign;
@@ -7456,6 +7457,25 @@ begin
   'begin',
   'end;',
   '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;
 
 procedure TTestResolver.TestAnonymousProc_Assign;

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

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

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

@@ -34,4 +34,4 @@ nortl=y
 [rules]
 .NOTPARALLEL:
 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_LSQR2   = $0200;
   DMGSNDCTRL_LTRI    = $0400;
-  DMGSNTCTRL_LNOISE  = $0800;
+  DMGSNDCTRL_LNOISE  = $0800;
   DMGSNDCTRL_RSQR1   = $1000;
   DMGSNDCTRL_RSQR2   = $2000;
   DMGSNDCTRL_RTRI    = $4000;
@@ -219,7 +219,7 @@ const
 function DSOUNDCTRL_ATIMER(x: integer): integer; inline; 
   
 const
-  DSOUNDCTRL_ARESET    = $0400;
+  DSOUNDCTRL_ARESET    = $0800;
   DSOUNDCTRL_BR        = $1000;
   DSOUNDCTRL_BL        = $2000;
   

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

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

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

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

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

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

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

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

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

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

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

@@ -55,7 +55,7 @@ procedure play();
 begin
 	soundMicOff();
 	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);
 end;
 
@@ -89,7 +89,11 @@ begin
 			end;
       recording := not recording;
 		end;
-
+		//-----------------------------------------------------
+		// START: exit
+		//-----------------------------------------------------
+		if (keys and KEY_START) <> 0 then break;
+      
 		swiWaitForVBlank();
 
 	end;

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

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

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

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

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

@@ -5,43 +5,67 @@ program apSearch;
 uses
   ctypes, nds9, dswifi9;
 
-procedure findAP(ap: pWifi_AccessPoint); 
 var
-	selected, i, count: integer;
+  ap: pWifi_AccessPoint;
+
+function findAP(): pWifi_AccessPoint; 
+var
+	selected, i, count, displaytop: integer;
 	ap2: Wifi_AccessPoint;
+  pressed: cint;
+  displayend: integer;
+  s1, s2: string;
 begin
   selected := 0;  
   count := 0;
-
+  displaytop := 0;
+  
   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
     scanKeys();
     
+    pressed := keysDown();
+    
+    if (pressed and KEY_START) <> 0 then exit;
+    
     //find out how many APs there are in the area
     count := Wifi_GetNumAP();
+    
     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
-    for i := 0 to count - 1 do
+    for i := displaytop to displayend - 1 do
     begin
-      Wifi_GetAPData(i, @ap2);
+      Wifi_GetAPData(i, ap);
       // display the name of the AP
       if i = selected then
-        iprintf('%s %s'#10, '*', pcchar(ap2.ssid))
+        s1 := '*' 
       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;
-
+    
 		//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);
 
-		if ((keysDown() and KEY_DOWN) <> 0) and (selected < (count-1)) then 
+		if ((pressed and KEY_DOWN) <> 0) and (selected < (count-1)) then 
       inc(selected);
 
 		swiWaitForVBlank();
@@ -49,7 +73,7 @@ begin
 
 	//user has made a choice so grab the ap and return it
 	Wifi_GetAPData(selected, ap);
-
+  result := ap;
 end;
 
 //---------------------------------------------------------------------------------
@@ -66,58 +90,105 @@ var
   oldStatus: integer;
 	url: array [0..255] of char;
   host: phostent;
-
+  wepkey = array [0..63] of char;
+  wepmode: cint;
+  len: integer;
+  ip: cuint32;
+  quit: integer;
+  pressed: cint;
 begin
-  status := integer(ASSOCSTATUS_DISCONNECTED);
-  
+  Wifi_InitDefault(false);
   consoleDemoInit(); 
-
   new(kb);
   kb := keyboardDemoInit();
   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
-    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.

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

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

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

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

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

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

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

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

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

@@ -9,9 +9,9 @@ uses
 function startTimer(timer: integer): cuint16;
 begin
   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;
 
 
@@ -74,7 +74,7 @@ begin
 end;
 
 var
-	touchXY: touchPosition;
+  touchXY: touchPosition;
 
   rotX: cfloat = 0;
   rotY: cfloat = 0;
@@ -92,7 +92,7 @@ var
   oldx: integer = 0;
   oldy: integer = 0;
 
-	held, pressed: integer;
+  held, pressed: integer;
   hit: integer;
   
   i: integer;
@@ -121,114 +121,114 @@ begin
   // Set our view port to be the same size as the screen
   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
     scanKeys();
     
     touchRead(touchXY);
 
-		
+    
     held := keysHeld();
     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
       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 
-		  printf(#10#10'Ram usage: Culling none')
+      printf(#10#10'Ram usage: Culling none')
     else 
     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.

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

@@ -78,7 +78,8 @@ begin
     scanKeys();
     
     keys := keysHeld();
-
+    if (keys and KEY_START) <> 0 then break;
+    
     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;

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

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

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

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

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

@@ -47,6 +47,9 @@ begin
 	glEnd();										// Done Drawing The Quad
 end;
 
+var
+  keys: integer;
+
 begin
 	// initialize the geometry engine
 	glInit();	
@@ -98,6 +101,10 @@ begin
  
 		// wait for the screen to refresh
 		swiWaitForVBlank();
+   
+    scanKeys();
+		keys := keysDown();
+		if (keys and KEY_START) <> 0 then break;
 
 		printf(#$1b'[15;5H rtri  = %f     '#10, rtri);
 		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;
 end;
 
+var
+  held: integer;
+
 begin
   // Setup the Main screen for 3D
   videoSetMode(MODE_0_3D);
@@ -132,13 +135,14 @@ begin
   while true do
   begin
     scanKeys();
+    held := keysHeld();
 
     //reset the projection matrix
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
 
     // 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)
     else
       glOrtho(-3, 3,-2, 2, 0.1, 100);
@@ -147,7 +151,7 @@ begin
     glMatrixMode(GL_MODELVIEW);
 
     //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)
     else
       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
     glFlush(0);
+    
+    if (held and KEY_START) <> 0 then break;
   end;
 end.

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

@@ -308,7 +308,7 @@ begin
         nTexture := 10;
     end;
 
-    glBindTexture(nTexture, textureIDS[nTexture]);
+    glBindTexture(0, textureIDS[nTexture]);
 
     //draw the obj
     glBegin(GL_QUAD);
@@ -320,6 +320,8 @@ begin
 
     glFlush(0);
     swiWaitForVBlank();
+    
+    if (keysPressed and KEY_START) <> 0 then break;
   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
 procedure startCheck();
 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;
 
 // run afer drawing an object while picking
 procedure endCheck(obj: TClickable);
 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;
 
 
 var
-	rotateX: cuint32 = 0;
-	rotateY: cuint32 = 0;
+  rotateX: cuint32 = 0;
+  rotateY: cuint32 = 0;
   touchXY: touchPosition;
   viewport: array [0..3] of cint32 = (0,0,255,191); // used later for gluPickMatrix()
-	keys: u16;
+  keys: u16;
 
 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
 
 
-				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.

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

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

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

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

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

@@ -206,10 +206,10 @@ begin
 
     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
     begin
@@ -220,21 +220,23 @@ begin
         DisplayEnableNormal();
     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.
-    REG_DISPCAPCNT^ := REG_DISPCAPCNT^ or DCAP_ENABLE;		
+    REG_DISPCAPCNT^ := REG_DISPCAPCNT^ or DCAP_ENABLE;    
   end;
 end.

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

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

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

@@ -11,115 +11,117 @@ uses
 {$include inc/statue.bin.inc}
 
 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);
 var
-	keys: cuint32;
+  keys: cuint32;
   touchXY: touchPosition;
 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;
-		dx := 0;
-		dy := 0;
-	end;
+    dx := 0;
+    dy := 0;
+  end;
 end;
 
 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
-	//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.

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

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

+ 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;
@@ -12,28 +12,29 @@ uses
 
 function DrawGLScene(): boolean;
 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;
 
-
+var
+  keys: integer;
 begin
   // Setup the Main screen for 3D 
   videoSetMode(MODE_0_3D);
@@ -43,38 +44,40 @@ begin
   // 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
+  // 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);
   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.

+ 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;
@@ -17,75 +17,79 @@ var
 
 function DrawGLScene(): boolean;
 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;
 
-
+var
+  keys: integer;
 
 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);
   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);
-	
+  //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);	
-	
+  glMatrixMode(GL_MODELVIEW); 
+  
   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.

+ 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;
@@ -17,119 +17,124 @@ var
 
 function DrawGLScene(): boolean;
 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;
 
-
-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);
-  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
-	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.

+ 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;
 {$L build/drunkenlogo.pcx.o}
@@ -13,141 +13,147 @@ uses
 {$include inc/drunkenlogo.pcx.inc}
 
 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
-	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;
 
 
-function LoadGLTextures(): boolean;									// Load PCX files And Convert To Textures
+function LoadGLTextures(): boolean;                 // Load PCX files And Convert To Textures
 var
-	pcx: sImage;                //////////////(NEW) and different from nehe.
+  pcx: sImage;                //////////////(NEW) and different from nehe.
 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;
 
-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.

+ 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;
@@ -14,182 +14,182 @@ uses
 {$include inc/drunkenlogo.pcx.inc}
 
 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
-  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
-	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;
 
 
-function LoadGLTextures(): boolean;									// Load PCX files And Convert To Textures
+function LoadGLTextures(): boolean;                 // Load PCX files And Convert To Textures
 var
-	pcx: sImage;                //////////////(NEW) and different from nehe.
+  pcx: sImage;                //////////////(NEW) and different from nehe.
 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;
 
+var
+  pressed: integer;
+  held: 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 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.

+ 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;
@@ -14,183 +14,183 @@ uses
 {$include inc/drunkenlogo.pcx.inc}
 
 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
-  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
-	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;
 
 
-function LoadGLTextures(): boolean;									// Load PCX files And Convert To Textures
+function LoadGLTextures(): boolean;                 // Load PCX files And Convert To Textures
 var
-	pcx: sImage;                //////////////(NEW) and different from nehe.
+  pcx: sImage;                //////////////(NEW) and different from nehe.
 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;
 
+var
+  pressed: integer;
+  held: 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);
-	
-	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
-	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.

+ 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;
@@ -25,154 +25,158 @@ type
 
 
 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
-  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
-function LoadGLTextures(): boolean;									// Load PCX files And Convert To Textures
+function LoadGLTextures(): boolean;                 // Load PCX files And Convert To Textures
 var
-	pcx: sImage;                //////////////(NEW) and different from nehe.
+  pcx: sImage;                //////////////(NEW) and different from nehe.
 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;
 
-function DrawGLScene(): boolean;											// Here's Where We Do All The Drawing
+function DrawGLScene(): boolean;                      // Here's Where We Do All The Drawing
 var
   loop: integer;
 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;
 
-
+var
+  pressed: integer;
 begin
   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.

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

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

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

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

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

@@ -10,14 +10,14 @@ uses
 
 var
   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;
 var
@@ -35,160 +35,166 @@ begin
   result := f32tofloat(c);
 end;
 
-function DrawGLScene(): boolean;											// Here's Where We Do All The Drawing
+function DrawGLScene(): boolean;                      // Here's Where We Do All The Drawing
 var
   x, y: integer;
   float_x, float_y, float_xb, float_yb: t16;
 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;
 
 
  
-function LoadGLTextures(): boolean;									// Load PCX files And Convert To Textures
+function LoadGLTextures(): boolean;                 // Load PCX files And Convert To Textures
 var
-	pcx: sImage;                //////////////(NEW) and different from nehe.
+  pcx: sImage;                //////////////(NEW) and different from nehe.
 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;
 
 procedure InitGL();
 var
   x, y: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);
-	
-	// 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;
 
-
-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.

+ 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: 'Bitmap';    demos: @bitmapExamples;     count: sizeof(bitmapExamples) 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;
   selectedDemo: integer = 0;
   selected: boolean = false;
-	catCount: integer;
+  catCount: integer;
   demoCount: integer = 0;
   ci: integer;
   di: integer;
 
 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
-				  iprintf('%c%d: %s'#10, '*', ci + 1, categories[ci].name)
+          iprintf('%c%d: %s'#10, '*', ci + 1, categories[ci].name)
         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
-				  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
           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.
 

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

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

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

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

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

@@ -47,7 +47,7 @@ begin
 	begin
 		scanKeys();
 		keys := keysHeld();
-
+    if (keys and KEY_START) <> 0 then break;
 		if (keys and KEY_TOUCH) <> 0 then
 		begin
 			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;
 
   console: pPrintConsole;
-	font: ConsoleFont;
-
+  font: ConsoleFont;
+  keys: integer;
 
 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.

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

@@ -6,35 +6,39 @@ uses
   ctypes, nds9;
 
 var
-	touch: touchPosition;
-	topScreen, bottomScreen: PrintConsole;
+  keys: integer;
+  touch: touchPosition;
+  topScreen, bottomScreen: PrintConsole;
 
 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);
 
-	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.
 

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

@@ -10,7 +10,7 @@ const
   fontPalLen = 32;
   fontTilesLen = 3072;
   tile_base = 0;
-	map_base = 20;
+  map_base = 20;
 
 var
   fontTiles: array [0..767] of cushort; cvar; external;
@@ -22,66 +22,67 @@ var
   keys: cuint32;
 
   console: pPrintConsole;
-	font: ConsoleFont;
-	bg3: cint;
+  font: ConsoleFont;
+  bg3: cint;
 
 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;
   scrollY := 0;
   scaleX := 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.

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

@@ -180,6 +180,7 @@ end;
 
 var
   memUsageTemp: longint;// = $FFFFFFFF;
+  keys: integer;
 
 begin
   randomize;
@@ -226,7 +227,9 @@ begin
 		updateSprites();
 
 		swiWaitForVBlank();
-		
+    scanKeys();
+		keys := keysDown();
+		if (keys and KEY_START) <> 0 then break;
 		//api: updates real oam memory 
 		oamUpdate(oam^);
 
@@ -236,9 +239,9 @@ begin
 
 		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.
 		

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

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

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

@@ -16,10 +16,10 @@ var
 
 type
   TSprite = record
-    x, y: cint;				//location
-    dx, dy: cint;			//speed
+    x, y: cint;       //location
+    dx, dy: cint;     //speed
     oam: PSpriteEntry;
-    gfxID: integer; 				//graphics location
+    gfxID: integer;         //graphics location
   end;
   PSprite = ^TSprite;
 
@@ -30,7 +30,7 @@ var
 begin
   x := sp.x shr 8;
   y := sp.y shr 8;
-	sp.oam^.y := y;
+  sp.oam^.y := y;
   sp.oam^.x := x;
 end;
 
@@ -48,42 +48,86 @@ begin
   //dmaCopy(@OAMCopySub, OAM_SUB, 128 * sizeof(SpriteEntry));
 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
-	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;
   i, delta: integer;
   ix, iy: integer;
-  screen: integer;
+  
+  temp: cint;
+  pressed: integer;
+  
   map0, map1: pcuint16;
   red: cuint16;
   ball: sImage;
 
 begin
   randomize;
-	back := VRAM_A;
-	front := VRAM_B;
 
-	i := 0;
+  i := 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_ACTIVE or
           DISPLAY_BG0_ACTIVE or
           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
   loadPCX(pcuint8(ball_pcx), @ball);
@@ -98,7 +142,7 @@ begin
   for i := 0 to 32*16 - 1 do
     SPRITE_GFX_SUB[i] := cuint32(ball.image.data16[i]);
 
-	//turn off sprites
+  //turn off sprites
   initOAM();
 
   for i := 0 to NUM_SPRITES - 1 do
@@ -123,113 +167,101 @@ begin
     sprites[i].oam^.attribute[2] := sprites[i].gfxID;
   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.
 

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;
 	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();
 begin
   inc(frame);
@@ -19,7 +25,15 @@ begin
   irqSet(IRQ_VBLANK, @Vblank);
 
 	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(#27'[32m' + 'www.devkitpro.org'#10);
 	iprintf(#27'[32;1m' + 'www.drunkencoders.com'#27'[39m');

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

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

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

@@ -51,8 +51,8 @@
 const
   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_512     = $3000;
   WIFIINIT_OPTION_USECUSTOMALLOC  = $4000;

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

@@ -60,7 +60,8 @@ const
 // Methods to modify DOS File Attributes
 
 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}
 

Неке датотеке нису приказане због велике количине промена