mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-14 04:19:28 +02:00
* Changes to compiler and rtl to make it compatible with devkitARM r24
* First attempt to implement a sort of generic "gate" for adding different file access methods * Optimized heap and stack handling git-svn-id: trunk@12562 -
This commit is contained in:
parent
d2d4aa22db
commit
8506d8fdf1
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -5707,8 +5707,10 @@ rtl/nds/classes.pp -text
|
||||
rtl/nds/cprt07.as svneol=native#text/plain
|
||||
rtl/nds/cprt09.as svneol=native#text/plain
|
||||
rtl/nds/dos.pp -text
|
||||
rtl/nds/nds.inc svneol=native#text/plain
|
||||
rtl/nds/ndsbios.inc -text
|
||||
rtl/nds/ndsbiosh.inc -text
|
||||
rtl/nds/ndsh.inc svneol=native#text/plain
|
||||
rtl/nds/prt07.as svneol=native#text/plain
|
||||
rtl/nds/prt09.as svneol=native#text/plain
|
||||
rtl/nds/sysdir.inc -text
|
||||
|
@ -34,12 +34,13 @@ unit i_nds;
|
||||
system : system_arm_nds;
|
||||
name : 'Nintendo DS';
|
||||
shortname : 'nds';
|
||||
flags : [tf_needs_symbol_size,tf_files_case_sensitive,tf_use_function_relative_addresses
|
||||
,tf_smartlink_sections,tf_requires_proper_alignment];
|
||||
flags : [tf_needs_symbol_size,tf_files_case_sensitive,
|
||||
tf_use_function_relative_addresses,tf_requires_proper_alignment,
|
||||
tf_smartlink_sections];
|
||||
cpu : cpu_arm;
|
||||
unit_env : '';
|
||||
extradefines : '';
|
||||
exeext : '.bin';
|
||||
extradefines : 'CPUARMEL';
|
||||
exeext : '.nef';//'.bin';
|
||||
defext : '.def';
|
||||
scriptext : '.sh';
|
||||
smartext : '.sl';
|
||||
@ -65,7 +66,7 @@ unit i_nds;
|
||||
link : nil;
|
||||
linkextern : nil;
|
||||
ar : ar_gnu_ar;
|
||||
res : res_none;
|
||||
res : res_elf;
|
||||
dbg : dbg_stabs;
|
||||
script : script_unix;
|
||||
endian : endian_little;
|
||||
@ -75,18 +76,18 @@ unit i_nds;
|
||||
loopalign : 4;
|
||||
jumpalign : 0;
|
||||
constalignmin : 0;
|
||||
constalignmax : 4;
|
||||
constalignmax : 8;//4;
|
||||
varalignmin : 0;
|
||||
varalignmax : 4;
|
||||
varalignmax : 8;//4;
|
||||
localalignmin : 4;
|
||||
localalignmax : 8;
|
||||
recordalignmin : 0;
|
||||
recordalignmax : 4;
|
||||
maxCrecordalign : 4
|
||||
recordalignmax : 8;//4;
|
||||
maxCrecordalign : 8//4
|
||||
);
|
||||
first_parm_offset : 8;
|
||||
stacksize : 16384;
|
||||
abi : abi_default
|
||||
stacksize : $3CFF; //15615? or 16384?;
|
||||
abi : abi_eabi
|
||||
);
|
||||
|
||||
implementation
|
||||
|
@ -251,9 +251,11 @@ begin
|
||||
add(' rom : ORIGIN = 0x08000000, LENGTH = 32M');
|
||||
add(' ewram : ORIGIN = 0x02000000, LENGTH = 4M - 4k');
|
||||
add(' dtcm : ORIGIN = 0x0b000000, LENGTH = 16K');
|
||||
add(' itcm : ORIGIN = 0x01000000, LENGTH = 32K');
|
||||
add(' vectors : ORIGIN = 0x00000000, LENGTH = 256');
|
||||
add(' itcm : ORIGIN = 0x01000100, LENGTH = 32K - 256');
|
||||
add('}');
|
||||
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);');
|
||||
@ -410,7 +412,17 @@ begin
|
||||
add(' __itcm_end = ABSOLUTE(.);');
|
||||
add(' } >itcm = 0xff');
|
||||
add('');
|
||||
add(' .sbss __dtcm_end : ');
|
||||
|
||||
add(' __vectors_lma = __itcm_lma + SIZEOF(.itcm);');
|
||||
add(' .vectors __vectors_start : AT (__vectors_lma)');
|
||||
add(' {');
|
||||
add(' *(.vectors)');
|
||||
add(' *vectors.*(.text)');
|
||||
add(' . = ALIGN(4);');
|
||||
add(' __vectors_end = ABSOLUTE(.);');
|
||||
add(' } >vectors = 0xff');
|
||||
add('');
|
||||
add(' .sbss __dtcm_end (NOLOAD):');
|
||||
add(' {');
|
||||
add(' __sbss_start = ABSOLUTE(.);');
|
||||
add(' __sbss_start__ = ABSOLUTE(.);');
|
||||
@ -515,7 +527,7 @@ begin
|
||||
add(' KEEP (*(.text.*personality*))');
|
||||
add(' /* .gnu.warning sections are handled specially by elf32.em. */');
|
||||
add(' *(.gnu.warning)');
|
||||
add(' KEEP (*(.text.*personality*))');
|
||||
add(' *(.glue_7t) *(.glue_7) *(.vfp11_veneer)');
|
||||
add(' . = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
|
||||
add(' } >iwram = 0xff');
|
||||
add('');
|
||||
@ -705,6 +717,10 @@ begin
|
||||
app_arm7: preName:='.nlf';
|
||||
end;
|
||||
|
||||
|
||||
if (cs_link_map in current_settings.globalswitches) then
|
||||
StripStr:='-Map '+maybequoted(ChangeFileExt(current_module.exefilename^,'.map'));
|
||||
|
||||
GCSectionsStr:='--gc-sections';
|
||||
if not(cs_link_nolink in current_settings.globalswitches) then
|
||||
Message1(exec_i_linking,current_module.exefilename^);
|
||||
|
@ -28,17 +28,22 @@ _start:
|
||||
bl ClearMem
|
||||
|
||||
ldr r3, =__libc_init_array @ global constructors
|
||||
bl _call_via_r3
|
||||
bl _blx_r3_stub
|
||||
|
||||
mov r0, #0 @ int argc
|
||||
mov r1, #0 @ char *argv[]
|
||||
ldr r3, =main
|
||||
bl _call_via_r3 @ jump to user code
|
||||
bl _blx_r3_stub
|
||||
|
||||
@ If the user ever returns, return to flash cartridge
|
||||
mov r0, #0x08000000
|
||||
bx r0
|
||||
|
||||
@---------------------------------------------------------------------------------
|
||||
_blx_r3_stub:
|
||||
@---------------------------------------------------------------------------------
|
||||
bx r3
|
||||
|
||||
@---------------------------------------------------------------------------------
|
||||
@ Clear memory to 0x00 if length != 0
|
||||
@ r0 = Start Address
|
||||
|
@ -64,9 +64,9 @@ _start:
|
||||
mcr p15, 0, r0, c6, c1, 0
|
||||
|
||||
@-------------------------------------------------------------------------
|
||||
@ Region 2 - iwram
|
||||
@ Region 2 - alternate vector base
|
||||
@-------------------------------------------------------------------------
|
||||
ldr r0,=( (0b01110 << 1) | 0x037F8000 | 1)
|
||||
ldr r0,=( (0b01011 << 1) | 0x00000000 | 1)
|
||||
mcr p15, 0, r0, c6, c2, 0
|
||||
|
||||
@-------------------------------------------------------------------------
|
||||
@ -86,6 +86,9 @@ _start:
|
||||
@ Region 5 - ITCM
|
||||
@-------------------------------------------------------------------------
|
||||
ldr r0,=__itcm_start
|
||||
@ align to 32k boundary
|
||||
mov r0,r0,lsr #15
|
||||
mov r0,r0,lsl #15
|
||||
orr r0,r0,#((0b01110 << 1) | 1)
|
||||
mcr p15, 0, r0, c6, c5, 0
|
||||
|
||||
@ -110,21 +113,20 @@ _start:
|
||||
@-------------------------------------------------------------------------
|
||||
@ DCache & ICache enable
|
||||
@-------------------------------------------------------------------------
|
||||
ldr r0,=0b01000110
|
||||
ldr r0,=0x42
|
||||
ldr r0,=0b01000010
|
||||
mcr p15, 0, r0, c2, c0, 0
|
||||
mcr p15, 0, r0, c2, c0, 1
|
||||
|
||||
@-------------------------------------------------------------------------
|
||||
@ IAccess
|
||||
@-------------------------------------------------------------------------
|
||||
ldr r0,=0x36636333
|
||||
ldr r0,=0x36636633
|
||||
mcr p15, 0, r0, c5, c0, 3
|
||||
|
||||
@-------------------------------------------------------------------------
|
||||
@ DAccess
|
||||
@-------------------------------------------------------------------------
|
||||
ldr r0,=0x36333333
|
||||
ldr r0,=0x36333633
|
||||
mcr p15, 0, r0, c5, c0, 2
|
||||
|
||||
@-------------------------------------------------------------------------
|
||||
@ -147,12 +149,20 @@ _start:
|
||||
msr cpsr, r0
|
||||
ldr sp, =__sp_usr @ Set user stack
|
||||
|
||||
ldr r1, =__itcm_lma @ Copy instruction tightly coupled memory (itcm section) from LMA to VMA (ROM to RAM)
|
||||
ldr r1, =__itcm_lma @ Copy instruction tightly coupled memory (itcm section) from LMA to VMA
|
||||
ldr r2, =__itcm_start
|
||||
ldr r4, =__itcm_end
|
||||
bl CopyMemCheck
|
||||
|
||||
ldr r1, =__dtcm_lma @ Copy data tightly coupled memory (dtcm section) from LMA to VMA (ROM to RAM)
|
||||
ldr r1, =__vectors_lma @ Copy reserved vectors area (itcm section) from LMA to VMA
|
||||
ldr r2, =__itcm_start @ alternate vectors based accessed via itcm mirror
|
||||
mov r2,r2,lsr #15 @ rounded to 32k boundary
|
||||
mov r2,r2,lsl #15
|
||||
ldr r4, =__vectors_end
|
||||
add r4,r4,r2
|
||||
bl CopyMemCheck
|
||||
|
||||
ldr r1, =__dtcm_lma @ Copy data tightly coupled memory (dtcm section) from LMA to VMA
|
||||
ldr r2, =__dtcm_start
|
||||
ldr r4, =__dtcm_end
|
||||
bl CopyMemCheck
|
||||
@ -173,12 +183,6 @@ _start:
|
||||
ldr r0, =__eheap_end
|
||||
str r0, [r1]
|
||||
|
||||
ldr r3, =__libc_init_array @ global constructors
|
||||
blx r3
|
||||
|
||||
ldr r3, =initSystem
|
||||
blx r3 @ jump to user code
|
||||
|
||||
ldr r0, =_libnds_argv
|
||||
|
||||
@ reset heap base
|
||||
@ -186,9 +190,17 @@ _start:
|
||||
ldr r1,=fake_heap_start
|
||||
str r2,[r1]
|
||||
|
||||
push {r0}
|
||||
ldr r3, =initSystem
|
||||
blx r3 @ system initialisation
|
||||
ldr r3, =__libc_init_array @ global constructors
|
||||
blx r3
|
||||
pop {r0}
|
||||
|
||||
ldr r1, [r0,#16] @ argv
|
||||
ldr r0, [r0,#12] @ argc
|
||||
|
||||
|
||||
ldr r3, =main
|
||||
blx r3 @ jump to user code
|
||||
|
||||
|
38
rtl/nds/nds.inc
Normal file
38
rtl/nds/nds.inc
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
This file is part of the Free Component Library (FCL)
|
||||
Copyright (c) 1999-2002 by the Free Pascal development team
|
||||
|
||||
BIOS functions unit for Nintendo DS
|
||||
Copyright (c) 2006 by Francesco Lombardi
|
||||
|
||||
See the file COPYING.FPC, included in this distribution,
|
||||
for details about the copyright.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
*****************************************************************************}
|
||||
|
||||
{
|
||||
NDS CPU detecting function
|
||||
--------------------------
|
||||
ARM946E-S processor can handle dsp extensions, but ARM7TDMI does not. FPC can
|
||||
detect dsp by catching a SIGILL that fires when ARM7 cpu tries to use a dsp
|
||||
command. Unfortunately, NDS' rtl does not have any error catching mechanism.
|
||||
This function takes care to check if the code is running on an ARM9 or on an
|
||||
ARM7 CPU, by checking the IRQ vector address ($0B003FFC for ARM9, 0380fff8
|
||||
for ARM7), declared in the linker script. This function is cleaner than the
|
||||
older one, because does not raise any memory writing error.
|
||||
It works on Nintendo DS only, I guess :)
|
||||
}
|
||||
function IsARM9(): boolean;
|
||||
begin
|
||||
IsARM9 := integer(@irq_vector) = $0B003FFC;
|
||||
end;
|
||||
|
||||
procedure AssignDevice(const FIOD: TFileIODevice);
|
||||
begin
|
||||
FileIODevice := FIOD;
|
||||
end;
|
||||
|
151
rtl/nds/ndsh.inc
Normal file
151
rtl/nds/ndsh.inc
Normal file
@ -0,0 +1,151 @@
|
||||
{
|
||||
This file is part of the Free Component Library (FCL)
|
||||
Copyright (c) 1999-2002 by the Free Pascal development team
|
||||
|
||||
BIOS functions unit for Nintendo DS
|
||||
Copyright (c) 2006 by Francesco Lombardi
|
||||
|
||||
See the file COPYING.FPC, included in this distribution,
|
||||
for details about the copyright.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
*****************************************************************************}
|
||||
|
||||
type
|
||||
TStat = packed record
|
||||
st_dev: qword;
|
||||
__pad1: word;
|
||||
__align_pad1: word;
|
||||
st_ino: dword;
|
||||
st_mode : dword;
|
||||
st_nlink : dword;
|
||||
st_uid : dword;
|
||||
st_gid : dword;
|
||||
st_rdev : qword;
|
||||
__pad2 : word;
|
||||
__align_pad2 : word;
|
||||
st_size : longint;
|
||||
st_blksize : longint;
|
||||
st_blocks : longint;
|
||||
st_atime : longint;
|
||||
__unused1 : dword;
|
||||
st_mtime : longint;
|
||||
__unused2 : dword;
|
||||
st_ctime : longint;
|
||||
__unused3 : dword;
|
||||
__unused4 : dword;
|
||||
__unused5 : dword;
|
||||
end;
|
||||
PStat = ^TStat;
|
||||
|
||||
(* libc file handling types and routines *)
|
||||
_FILE = record
|
||||
firstCluster: longword;
|
||||
length: longword;
|
||||
curPos: longword;
|
||||
curClus: longword; // Current cluster to read from
|
||||
curSect: integer; // Current sector within cluster
|
||||
curByte: integer; // Current byte within sector
|
||||
readBuffer: array [0..511] of byte; // Buffer used for unaligned reads
|
||||
appClus: longword; // Cluster to append to
|
||||
appSect: integer; // Sector within cluster for appending
|
||||
appByte: integer; // Byte within sector for appending
|
||||
read: boolean; // Can read from file
|
||||
write: boolean; // Can write to file
|
||||
append: boolean; // Can append to file
|
||||
inUse: boolean; // This file is open
|
||||
dirEntSector: longword; // The sector where the directory entry is stored
|
||||
dirEntOffset: integer; // The offset within the directory sector
|
||||
end;
|
||||
P_FILE = ^_FILE;
|
||||
|
||||
type
|
||||
TDoOpen = procedure (var f; p: pchar; flags: longint);
|
||||
TDoClose = procedure (handle: THandle);
|
||||
TDoWrite = function (h: THandle; addr: pointer; len: longint): longint;
|
||||
TDoRead = function (h: THandle; addr: pointer; len: longint): longint;
|
||||
TDoSeek = procedure (handle: THandle; pos: longint);
|
||||
TDoSeekend = function (handle: THandle): longint;
|
||||
TDoErase = procedure (p: pchar);
|
||||
TDoRename = procedure (p1, p2: pchar);
|
||||
TDoFilepos = function (handle: THandle): longint;
|
||||
TDoFilesize = function (handle: THandle): longint;
|
||||
TDoTruncate = procedure (handle: THandle; pos: longint);
|
||||
TDoIsdevice = function (handle: THandle): boolean;
|
||||
|
||||
TFileIO = packed record
|
||||
DoOpen : TDoOpen;
|
||||
DoClose : TDoClose;
|
||||
DoWrite : TDoWrite;
|
||||
DoRead : TDoRead;
|
||||
DoSeek : TDoSeek;
|
||||
DoSeekend : TDoSeekend;
|
||||
DoErase : TDoErase;
|
||||
DoRename : TDoRename;
|
||||
DoFilepos : TDoFilepos;
|
||||
DoFilesize: TDoFilesize;
|
||||
DoTruncate: TDoTruncate;
|
||||
DoIsdevice: TDoIsdevice;
|
||||
end;
|
||||
PFileIO = ^TFileIO;
|
||||
|
||||
|
||||
TDoMkdir = procedure (const s: string);
|
||||
TDoRmdir = procedure (const s: string);
|
||||
TDoChdir = procedure (const s: string);
|
||||
TDoGetdir = procedure (DriveNr: byte; var Dir: ShortString);
|
||||
|
||||
TDirIO = packed record
|
||||
DoMkdir : TDoMkdir;
|
||||
DoRmdir : TDoRmdir;
|
||||
DoChdir : TDoChdir;
|
||||
DoGetdir: TDoGetdir;
|
||||
end;
|
||||
PDirIO = ^TDirIO;
|
||||
|
||||
TFileIODevice = packed record
|
||||
FileIO: TFileIO;
|
||||
DirIO: TDirIO;
|
||||
end;
|
||||
PFileIODevice = ^TFileIODevice;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function IsARM9(): boolean;
|
||||
procedure AssignDevice(const FIOD: TFileIODevice);
|
||||
|
||||
var
|
||||
FileIODevice: TFileIODevice =
|
||||
(
|
||||
FileIO:
|
||||
(
|
||||
DoOpen: nil;
|
||||
DoClose: nil;
|
||||
DoWrite: nil;
|
||||
DoRead: nil;
|
||||
DoSeek: nil;
|
||||
DoSeekend: nil;
|
||||
DoErase: nil;
|
||||
DoRename: nil;
|
||||
DoFilepos: nil;
|
||||
DoFilesize: nil;
|
||||
DoTruncate: nil;
|
||||
DoIsdevice: nil;
|
||||
);
|
||||
DirIO:
|
||||
(
|
||||
DoMkdir: nil;
|
||||
DoRmdir: nil;
|
||||
DoChdir: nil;
|
||||
DoGetdir: nil;
|
||||
);
|
||||
);
|
||||
|
||||
|
@ -64,9 +64,9 @@ _start:
|
||||
mcr p15, 0, r0, c6, c1, 0
|
||||
|
||||
@-------------------------------------------------------------------------
|
||||
@ Region 2 - iwram
|
||||
@ Region 2 - alternate vector base
|
||||
@-------------------------------------------------------------------------
|
||||
ldr r0,=( (0b01110 << 1) | 0x037F8000 | 1)
|
||||
ldr r0,=( (0b01011 << 1) | 0x00000000 | 1)
|
||||
mcr p15, 0, r0, c6, c2, 0
|
||||
|
||||
@-------------------------------------------------------------------------
|
||||
@ -86,6 +86,9 @@ _start:
|
||||
@ Region 5 - ITCM
|
||||
@-------------------------------------------------------------------------
|
||||
ldr r0,=__itcm_start
|
||||
@ align to 32k boundary
|
||||
mov r0,r0,lsr #15
|
||||
mov r0,r0,lsl #15
|
||||
orr r0,r0,#((0b01110 << 1) | 1)
|
||||
mcr p15, 0, r0, c6, c5, 0
|
||||
|
||||
@ -110,21 +113,20 @@ _start:
|
||||
@-------------------------------------------------------------------------
|
||||
@ DCache & ICache enable
|
||||
@-------------------------------------------------------------------------
|
||||
ldr r0,=0b01000110
|
||||
ldr r0,=0x42
|
||||
ldr r0,=0b01000010
|
||||
mcr p15, 0, r0, c2, c0, 0
|
||||
mcr p15, 0, r0, c2, c0, 1
|
||||
|
||||
@-------------------------------------------------------------------------
|
||||
@ IAccess
|
||||
@-------------------------------------------------------------------------
|
||||
ldr r0,=0x36636333
|
||||
ldr r0,=0x36636633
|
||||
mcr p15, 0, r0, c5, c0, 3
|
||||
|
||||
@-------------------------------------------------------------------------
|
||||
@ DAccess
|
||||
@-------------------------------------------------------------------------
|
||||
ldr r0,=0x36333333
|
||||
ldr r0,=0x36333633
|
||||
mcr p15, 0, r0, c5, c0, 2
|
||||
|
||||
@-------------------------------------------------------------------------
|
||||
@ -152,11 +154,19 @@ _start:
|
||||
ldr r4, =__itcm_end
|
||||
bl CopyMemCheck
|
||||
|
||||
ldr r1, =__dtcm_lma @ Copy data tightly coupled memory (dtcm section) from LMA to VMA (ROM to RAM)
|
||||
ldr r1, =__vectors_lma @ Copy reserved vectors area (itcm section) from LMA to VMA
|
||||
ldr r2, =__itcm_start @ alternate vectors based accessed via itcm mirror
|
||||
mov r2,r2,lsr #15 @ rounded to 32k boundary
|
||||
mov r2,r2,lsl #15
|
||||
ldr r4, =__vectors_end
|
||||
add r4,r4,r2
|
||||
bl CopyMemCheck
|
||||
|
||||
ldr r1, =__dtcm_lma @ Copy data tightly coupled memory (dtcm section) from LMA to VMA
|
||||
ldr r2, =__dtcm_start
|
||||
ldr r4, =__dtcm_end
|
||||
bl CopyMemCheck
|
||||
|
||||
|
||||
bl checkARGV @ check and process argv trickery
|
||||
|
||||
ldr r0, =__bss_start @ Clear BSS section
|
||||
@ -172,13 +182,7 @@ _start:
|
||||
ldr r1, =fake_heap_end @ set heap end
|
||||
ldr r0, =__eheap_end
|
||||
str r0, [r1]
|
||||
|
||||
@ ldr r3, =__libc_init_array @ global constructors
|
||||
@ blx r3
|
||||
|
||||
ldr r3, =initSystem
|
||||
blx r3 @ jump to user code
|
||||
|
||||
|
||||
ldr r0, =_libnds_argv
|
||||
|
||||
@ reset heap base
|
||||
@ -186,9 +190,17 @@ _start:
|
||||
ldr r1,=fake_heap_start
|
||||
str r2,[r1]
|
||||
|
||||
push {r0}
|
||||
ldr r3, =initSystem
|
||||
blx r3 @ system initialisation
|
||||
@ ldr r3, =__libc_init_array @ global constructors
|
||||
@ blx r3
|
||||
pop {r0}
|
||||
|
||||
ldr r1, [r0,#16] @ argv
|
||||
ldr r0, [r0,#12] @ argc
|
||||
|
||||
|
||||
ldr r3, =main
|
||||
blx r3 @ jump to user code
|
||||
|
||||
|
@ -19,20 +19,28 @@
|
||||
{*****************************************************************************
|
||||
Directory Handling
|
||||
*****************************************************************************}
|
||||
procedure mkdir(const s : string);[IOCheck];
|
||||
procedure mkdir(const s: string);[IOCheck];
|
||||
begin
|
||||
if FileIODevice.DirIO.DoMkdir <> nil then
|
||||
FileIODevice.DirIO.DoMkdir(s);
|
||||
end;
|
||||
|
||||
procedure rmdir(const s : string);[IOCheck];
|
||||
procedure rmdir(const s: string);[IOCheck];
|
||||
begin
|
||||
if FileIODevice.DirIO.DoRmdir <> nil then
|
||||
FileIODevice.DirIO.DoRmdir(s);
|
||||
end;
|
||||
|
||||
procedure chdir(const s : string);[IOCheck];
|
||||
procedure chdir(const s: string);[IOCheck];
|
||||
begin
|
||||
if FileIODevice.DirIO.DoChdir <> nil then
|
||||
FileIODevice.DirIO.DoChdir(s);
|
||||
end;
|
||||
|
||||
procedure GetDir (DriveNr: byte; var Dir: ShortString);
|
||||
procedure GetDir(DriveNr: byte; var Dir: ShortString);
|
||||
begin
|
||||
if FileIODevice.DirIO.DoGetdir <> nil then
|
||||
FileIODevice.DirIO.DoGetdir(DriveNr, Dir);
|
||||
end;
|
||||
|
||||
|
||||
|
@ -16,65 +16,164 @@
|
||||
**********************************************************************}
|
||||
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
Low level File Routines
|
||||
All these functions can set InOutRes on errors
|
||||
****************************************************************************}
|
||||
|
||||
{ close a file from the handle value }
|
||||
procedure do_close(handle : longint);
|
||||
procedure do_close(handle: THandle);
|
||||
begin
|
||||
|
||||
if FileIODevice.FileIO.DoClose <> nil then
|
||||
FileIODevice.FileIO.DoClose(handle);
|
||||
//_fclose (_PFILE(pointer(handle))^);
|
||||
end;
|
||||
|
||||
procedure do_erase(p : pchar);
|
||||
procedure do_erase(p: pchar);
|
||||
begin
|
||||
if FileIODevice.FileIO.DoErase <> nil then
|
||||
FileIODevice.FileIO.DoErase(p);
|
||||
// _unlink(p);
|
||||
end;
|
||||
|
||||
procedure do_rename(p1,p2 : pchar);
|
||||
procedure do_rename(p1, p2: pchar);
|
||||
begin
|
||||
// _rename(p1, p2);
|
||||
if FileIODevice.FileIO.DoRename <> nil then
|
||||
FileIODevice.FileIO.DoRename(p1, p2);
|
||||
end;
|
||||
|
||||
function do_write(h: longint; addr: pointer; len: longint) : longint;
|
||||
function do_write(h: THandle; addr: pointer; len: longint) : longint;
|
||||
begin
|
||||
result := -1;
|
||||
// result := _fwrite(addr, 1, len, _PFILE(pointer(h))^);
|
||||
if FileIODevice.FileIO.DoWrite <> nil then
|
||||
result := FileIODevice.FileIO.DoWrite(h, addr, len);
|
||||
end;
|
||||
|
||||
function do_read(h: longint; addr: pointer; len: longint) : longint;
|
||||
function do_read(h: THandle; addr: pointer; len: longint) : longint;
|
||||
begin
|
||||
result := -1;
|
||||
// result := _fread(addr, 1, len, _PFILE(pointer(h))^);
|
||||
if FileIODevice.FileIO.DoRead <> nil then
|
||||
result := FileIODevice.FileIO.DoRead(h, addr, len);
|
||||
end;
|
||||
|
||||
function do_filepos(handle: longint) : longint;
|
||||
function do_filepos(handle: THandle): longint;
|
||||
begin
|
||||
result := -1;
|
||||
// result := _ftell(_PFILE(pointer(handle))^);
|
||||
if FileIODevice.FileIO.DoFilePos <> nil then
|
||||
result := FileIODevice.FileIO.DoFilePos(handle);
|
||||
end;
|
||||
|
||||
procedure do_seek(handle, pos: longint);
|
||||
procedure do_seek(handle: THandle; pos: longint);
|
||||
begin
|
||||
//_fseek(_PFILE(pointer(handle))^, pos, SEEK_SET);
|
||||
if FileIODevice.FileIO.DoSeek <> nil then
|
||||
FileIODevice.FileIO.DoSeek(handle, pos);
|
||||
end;
|
||||
|
||||
function do_seekend(handle: longint):longint;
|
||||
function do_seekend(handle: THandle): longint;
|
||||
begin
|
||||
result := -1;
|
||||
// result := _fseek(_PFILE(pointer(handle))^, 0, SEEK_END);
|
||||
if FileIODevice.FileIO.DoSeekend <> nil then
|
||||
result := FileIODevice.FileIO.DoSeekend(handle);
|
||||
end;
|
||||
|
||||
function do_filesize(handle : longint) : longint;
|
||||
function do_filesize(handle: THandle): longint;
|
||||
begin
|
||||
result := -1;
|
||||
// result := -1;
|
||||
if FileIODevice.FileIO.DoFilesize <> nil then
|
||||
result := FileIODevice.FileIO.DoFilesize(handle);
|
||||
end;
|
||||
|
||||
{ truncate at a given position }
|
||||
procedure do_truncate(handle, pos: longint);
|
||||
procedure do_truncate(handle: THandle; pos: longint);
|
||||
begin
|
||||
// _ftruncate(_fileno(_PFILE(pointer(handle))^), pos);
|
||||
if FileIODevice.FileIO.DoTruncate <> nil then
|
||||
FileIODevice.FileIO.DoTruncate(handle, pos);
|
||||
end;
|
||||
|
||||
procedure do_open(var f;p:pchar;flags:longint);
|
||||
procedure do_open(var f; p: pchar; flags: longint);
|
||||
begin
|
||||
(*
|
||||
{ close first if opened }
|
||||
if ((flags and $10000) = 0) then
|
||||
begin
|
||||
case FileRec(f).mode of
|
||||
fminput,fmoutput,fminout : Do_Close(FileRec(f).Handle);
|
||||
fmclosed : ;
|
||||
else
|
||||
begin
|
||||
// inoutres:=102; {not assigned}
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
{ reset file Handle }
|
||||
FileRec(f).Handle:=UnusedHandle;
|
||||
|
||||
{ We do the conversion of filemodes here, concentrated on 1 place }
|
||||
case (flags and 3) of
|
||||
0 : begin
|
||||
oflags := 'rb'#0;
|
||||
filerec(f).mode := fminput;
|
||||
end;
|
||||
1 : begin
|
||||
if (flags and $1000)=$1000 then
|
||||
oflags := 'w+b' else
|
||||
oflags := 'wb';
|
||||
filerec(f).mode := fmoutput;
|
||||
end;
|
||||
2 : begin
|
||||
if (flags and $1000)=$1000 then
|
||||
oflags := 'w+' else
|
||||
oflags := 'r+';
|
||||
filerec(f).mode := fminout;
|
||||
end;
|
||||
end;
|
||||
{if (flags and $1000)=$1000 then
|
||||
oflags:=oflags or (O_CREAT or O_TRUNC)
|
||||
else
|
||||
if (flags and $100)=$100 then
|
||||
oflags:=oflags or (O_APPEND);}
|
||||
|
||||
{ empty name is special }
|
||||
if p[0]=#0 then
|
||||
begin
|
||||
case FileRec(f).mode of
|
||||
fminput: FileRec(f).Handle:=StdInputHandle;
|
||||
fminout, { this is set by rewrite }
|
||||
fmoutput: FileRec(f).Handle:=StdOutputHandle;
|
||||
fmappend:
|
||||
begin
|
||||
FileRec(f).Handle:=StdOutputHandle;
|
||||
FileRec(f).mode:=fmoutput; {fool fmappend}
|
||||
end;
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
|
||||
{ real open call }
|
||||
FileRec(f).Handle := longint(fopen(p, @oflags[1]));//_open(p,oflags,438);
|
||||
// errno does not seem to be set on succsess ??
|
||||
{
|
||||
if FileRec(f).Handle = 0 then
|
||||
Errno2Inoutres
|
||||
else
|
||||
InOutRes := 0;
|
||||
}
|
||||
*)
|
||||
// FileRec(f).Handle := THandle (_fopen(p, @oflags[1]));
|
||||
if FileIODevice.FileIO.DoOpen <> nil then
|
||||
FileIODevice.FileIO.DoOpen(f, p, flags);
|
||||
end;
|
||||
|
||||
function do_isdevice(handle: longint): boolean;
|
||||
function do_isdevice(handle: THandle): boolean;
|
||||
begin
|
||||
result := false;
|
||||
// result := (_isatty(_fileno(_PFILE(pointer(handle))^)) > 0);
|
||||
if FileIODevice.FileIO.DoIsdevice <> nil then
|
||||
result := FileIODevice.FileIO.DoIsdevice(handle);
|
||||
end;
|
||||
|
||||
|
||||
|
@ -20,6 +20,22 @@
|
||||
OS Memory allocation / deallocation
|
||||
****************************************************************************}
|
||||
|
||||
function sbrk2(size: longint): pointer; cdecl; external name 'sbrk';
|
||||
|
||||
function SysOSAlloc(size: ptruint): pointer;
|
||||
begin
|
||||
result := sbrk2(size);
|
||||
if result = pointer(-1) then
|
||||
result := nil
|
||||
end;
|
||||
|
||||
procedure SysOSFree(p: pointer; size: ptruint);
|
||||
begin
|
||||
sbrk2(-size);
|
||||
end;
|
||||
|
||||
|
||||
(*
|
||||
var
|
||||
heap_start: longint; external name '_end';
|
||||
|
||||
@ -34,3 +50,4 @@ procedure SysOSFree(p: pointer; size: ptruint);
|
||||
begin
|
||||
|
||||
end;
|
||||
*)
|
||||
|
@ -25,14 +25,15 @@ interface
|
||||
{$define FPC_HAS_FEATURE_FILEIO}
|
||||
|
||||
|
||||
{$i ndsbiosh.inc}
|
||||
{$i systemh.inc}
|
||||
{$i ndsbiosh.inc}
|
||||
{$i ndsh.inc}
|
||||
|
||||
|
||||
{$define fpc_softfpu_interface}
|
||||
{$i softfpu.pp}
|
||||
{$undef fpc_softfpu_interface}
|
||||
|
||||
function IsARM9(): boolean;
|
||||
|
||||
const
|
||||
LineEnding = #10;
|
||||
@ -58,6 +59,8 @@ const
|
||||
StdErrorHandle = $ffff;
|
||||
|
||||
|
||||
|
||||
|
||||
var
|
||||
argc: LongInt = 0;
|
||||
argv: PPChar;
|
||||
@ -66,7 +69,7 @@ var
|
||||
fake_heap_end: ^byte; cvar; external;
|
||||
irq_vector: integer; external name '__irq_vector';
|
||||
|
||||
|
||||
//procedure AssignDevice(FIOD: Pointer);
|
||||
|
||||
implementation
|
||||
|
||||
@ -88,25 +91,9 @@ implementation
|
||||
|
||||
{$i system.inc}
|
||||
{$i ndsbios.inc}
|
||||
{$i nds.inc}
|
||||
|
||||
|
||||
{
|
||||
NDS CPU detecting function
|
||||
--------------------------
|
||||
ARM946E-S processor can handle dsp extensions, but ARM7TDMI does not. FPC can
|
||||
detect dsp by catching a SIGILL that fires when ARM7 cpu tries to use a dsp
|
||||
command. Unfortunately, NDS' rtl does not have any error catching mechanism.
|
||||
This function takes care to check if the code is running on an ARM9 or on an
|
||||
ARM7 CPU, by checking the IRQ vector address ($0B003FFC for ARM9, 0380fff8
|
||||
for ARM7), declared in the linker script. This function is cleaner than the
|
||||
older one, because does not raise any memory writing error.
|
||||
It works on Nintendo DS only, I guess :)
|
||||
}
|
||||
function IsARM9(): boolean;
|
||||
begin
|
||||
IsARM9 := integer(@irq_vector) = $0B003FFC;
|
||||
end;
|
||||
|
||||
{$ifdef FPC_HAS_FEATURE_PROCESSES}
|
||||
function GetProcessID: SizeUInt;
|
||||
begin
|
||||
|
Loading…
Reference in New Issue
Block a user