fpc/rtl/z80/z80.inc

381 lines
6.8 KiB
PHP

{
This file is part of the Free Pascal run time library.
Copyright (c) 2017 by the Free Pascal development team.
Processor dependent implementation for the system unit for
Z80
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.
**********************************************************************}
var
z80_save_hl: Word; public name 'FPC_Z80_SAVE_HL';
{$define FPC_SYSTEM_HAS_FPC_CPUINIT}
procedure fpc_cpuinit;{$ifdef SYSTEMINLINE}inline;{$endif}
begin
end;
{$define FPC_SYSTEM_HAS_MOVE}
procedure Move(const source;var dest;count:SizeInt);assembler;[public, alias: 'FPC_MOVE'];
label
skip, forward_move;
asm
ld c, (count)
ld b, (count+1)
bit 7, b
jp NZ, skip
ld a, b
or a, c
jp Z, skip
ld l, (source)
ld h, (source+1)
ld e, (dest)
ld d, (dest+1)
ld a, d
cp a, h
jp C, forward_move
ld a, e
cp a, l
jp C, forward_move
{ backward move }
add hl, bc
dec hl
ex de, hl
add hl, bc
dec hl
ex de, hl
lddr
jp skip
forward_move:
ldir
skip:
end;
{$define FPC_SYSTEM_HAS_FILLCHAR}
Procedure FillChar(var x;count:SizeInt;value:byte);assembler;
label
skip, loop;
asm
ld c, (count)
ld b, (count+1)
bit 7, b
jp NZ, skip
ld a, b
or a, c
jp Z, skip
ld e, (value)
ld a, 0
ld l, (x)
ld h, (x+1)
loop:
ld (hl), e
inc hl
dec bc
cp a, c
jp NZ, loop
cp a, b
jp NZ, loop
skip:
end;
{$IFNDEF INTERNAL_BACKTRACE}
{$define FPC_SYSTEM_HAS_GET_FRAME}
function get_frame:pointer;assembler;nostackframe;
asm
push ix
pop hl
end;
{$ENDIF not INTERNAL_BACKTRACE}
{$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler;
label
framebp_null;
asm
ld l, (framebp)
ld h, (framebp+1)
ld a, l
or a, h
jp Z, framebp_null
inc hl
inc hl
ld e, (hl)
inc hl
ld d, (hl)
ex de, hl
framebp_null:
end;
{$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;assembler;
label
framebp_null;
asm
ld l, (framebp)
ld h, (framebp+1)
ld a, l
or a, h
jp Z, framebp_null
ld e, (hl)
inc hl
ld d, (hl)
ex de, hl
framebp_null:
end;
{$define FPC_SYSTEM_HAS_SPTR}
Function Sptr : pointer;assembler;nostackframe;
asm
ld hl, 0
add hl, sp
end;
{$ifdef VER3_2}
function InterLockedDecrement (var Target: longint) : longint;
{$else VER3_2}
{$define FPC_SYSTEM_HAS_ATOMIC_DEC_32}
function fpc_atomic_dec_32 (var Target: longint): longint;
{$endif VER3_2}
begin
{ block interrupts }
asm
di
end;
dec(Target);
Result:=Target;
{ release interrupts }
asm
ei
end;
end;
{$ifdef VER3_2}
function InterLockedIncrement (var Target: longint) : longint;
{$else VER3_2}
{$define FPC_SYSTEM_HAS_ATOMIC_INC_32}
function fpc_atomic_inc_32 (var Target: longint): longint;
{$endif VER3_2}
begin
{ block interrupts }
asm
di
end;
inc(Target);
Result:=Target;
{ release interrupts }
asm
ei
end;
end;
{$ifdef VER3_2}
function InterLockedExchange (var Target: longint;Source : longint) : longint;
{$else VER3_2}
{$define FPC_SYSTEM_HAS_ATOMIC_XCHG_32}
function fpc_atomic_xchg_32 (var Target: longint;Source : longint): longint;
{$endif VER3_2}
begin
{ block interrupts }
asm
di
end;
Result:=Target;
Target:=Source;
{ release interrupts }
asm
ei
end;
end;
{$ifdef VER3_2}
function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint;
{$else VER3_2}
{$define FPC_SYSTEM_HAS_ATOMIC_CMP_XCHG_32}
function fpc_atomic_cmp_xchg_32 (var Target: longint; NewValue: longint; Comparand: longint): longint;
{$endif VER3_2}
begin
{ block interrupts }
asm
di
end;
Result:=Target;
if Target={$ifdef VER3_2}Comperand{$else}Comparand{$endif} then
Target:=NewValue;
{ release interrupts }
asm
ei
end;
end;
{$ifdef VER3_2}
function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint;
{$else VER3_2}
{$define FPC_SYSTEM_HAS_ATOMIC_ADD_32}
function fpc_atomic_add_32 (var Target: longint;Value : longint): longint;
{$endif VER3_2}
begin
{ block interrupts }
asm
di
end;
Result:=Target;
inc(Target,{$ifdef VER3_2}Source{$else}Value{$endif});
{ release interrupts }
asm
ei
end;
end;
{$ifdef VER3_2}
function InterLockedDecrement (var Target: smallint) : smallint;
{$else VER3_2}
{$define FPC_SYSTEM_HAS_ATOMIC_DEC_16}
function fpc_atomic_dec_16 (var Target: smallint): smallint;
{$endif VER3_2}
begin
{ block interrupts }
asm
di
end;
dec(Target);
Result:=Target;
{ release interrupts }
asm
ei
end;
end;
{$ifdef VER3_2}
function InterLockedIncrement (var Target: smallint) : smallint;
{$else VER3_2}
{$define FPC_SYSTEM_HAS_ATOMIC_INC_16}
function fpc_atomic_inc_16 (var Target: smallint): smallint;
{$endif VER3_2}
begin
{ block interrupts }
asm
di
end;
inc(Target);
Result:=Target;
{ release interrupts }
asm
ei
end;
end;
{$ifdef VER3_2}
function InterLockedExchange (var Target: smallint;Source : smallint) : smallint;
{$else VER3_2}
{$define FPC_SYSTEM_HAS_ATOMIC_XCHG_16}
function fpc_atomic_xchg_16 (var Target: smallint;Source : smallint): smallint;
{$endif VER3_2}
begin
{ block interrupts }
asm
di
end;
Result:=Target;
Target:=Source;
{ release interrupts }
asm
ei
end;
end;
{$ifdef VER3_2}
function InterlockedCompareExchange(var Target: smallint; NewValue: smallint; Comperand: smallint): smallint;
{$else VER3_2}
{$define FPC_SYSTEM_HAS_ATOMIC_CMP_XCHG_16}
function fpc_atomic_cmp_xchg_16 (var Target: smallint; NewValue: smallint; Comparand: smallint): smallint; [public,alias:'FPC_ATOMIC_CMP_XCHG_16'];
{$endif VER3_2}
begin
{ block interrupts }
asm
di
end;
Result:=Target;
if Target={$ifdef VER3_2}Comperand{$else}Comparand{$endif} then
Target:=NewValue;
{ release interrupts }
asm
ei
end;
end;
{$ifdef VER3_2}
function InterLockedExchangeAdd (var Target: smallint;Source : smallint) : smallint;
{$else VER3_2}
{$define FPC_SYSTEM_HAS_ATOMIC_ADD_16}
function fpc_atomic_add_16 (var Target: smallint;Value : smallint): smallint;
{$endif VER3_2}
begin
{ block interrupts }
asm
di
end;
Result:=Target;
inc(Target,{$ifdef VER3_2}Source{$else}Value{$endif});
{ release interrupts }
asm
ei
end;
end;