123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- {
- This file is part of the Free Pascal run time library.
- Copyright (c) 1999-2000 by Carl-Eric Codere,
- member of the Free Pascal development team.
- 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.
- **********************************************************************}
- {****************************************************************************
- m68k.inc : Processor dependent implementation of system unit
- For Motorola 680x0 Processor.
- *****************************************************************************}
- {****************************************************************************}
- { Credit where credit is due: }
- { -Some of the copy routines taken from the Atari dlib source code: }
- { Dale Schumacher (alias: Dalnefre') [email protected] }
- { 399 Beacon Ave. St. Paul, MN 55104,USA }
- { -Some of the routines taken from the freeware ATARI Sozobon C compiler }
- { 1988 by Sozobon, Limited. Author: Johann Ruegg (freeware) }
- { Thanks to all these people wherever they maybe today! }
- {****************************************************************************}
- procedure fpc_cpuinit;
- begin
- end;
- {$define FPC_SYSTEM_HAS_GET_FRAME}
- function get_frame : pointer; assembler;
- asm
- move.l a6,d0
- end;
- {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
- function get_caller_addr(framebp : pointer) : pointer;
- begin
- asm
- move.l FRAMEBP,a0
- cmp.l #0,a0
- beq @Lnul_address
- move.l 4(a0),a0
- @Lnul_address:
- move.l a0,@RESULT
- end ['a0'];
- end;
- {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
- function get_caller_frame(framebp : pointer) : pointer;
- begin
- asm
- move.l FRAMEBP,a0
- cmp.l #0,a0
- beq @Lnul_frame
- move.l (a0),a0
- @Lnul_frame:
- move.l a0,@RESULT
- end ['a0'];
- end;
- {$define FPC_SYSTEM_HAS_SPTR}
- function Sptr : Longint;
- begin
- asm
- move.l sp,d0
- add.l #8,d0
- move.l d0,@RESULT
- end ['d0'];
- end;
- {$define FPC_SYSTEM_HAS_FILLCHAR}
- procedure FillChar(var x;count:longint;value:byte);[public,alias: 'FPC_FILL_OBJECT'];
- begin
- asm
- move.l 8(a6), a0 { destination }
- move.l 12(a6), d1 { number of bytes to fill }
- move.b 16(a6),d0 { fill data }
- cmpi.l #65535, d1 { check, if this is a word move }
- ble @LMEMSET3 { use fast dbra mode }
- bra @LMEMSET2
- @LMEMSET1:
- move.b d0,(a0)+
- @LMEMSET2:
- subq.l #1,d1
- cmp.l #-1,d1
- bne @LMEMSET1
- bra @LMEMSET5 { finished slow mode , exit }
- @LMEMSET4: { fast loop mode section 68010+ }
- move.b d0,(a0)+
- @LMEMSET3:
- dbra d1,@LMEMSET4
- @LMEMSET5:
- end ['d0','d1','a0'];
- end;
- {$ifdef dummy}
- { procedure strcopy(dstr,sstr : pointer;len : longint);[public,alias: 'STRCOPY'];}
- procedure strcopy; assembler;[public,alias: 'FPC_STRCOPY'];
- {---------------------------------------------------}
- { Low-level routine to copy a string to another }
- { string with maximum length. Never call directly! }
- { On Entry: }
- { a1.l = string to copy to }
- { a0.l = source string }
- { d0.l = maximum length of copy }
- { registers destroyed: a0,a1,d0,d1 }
- {---------------------------------------------------}
- asm
- { move.l 12(a6),a0
- move.l 16(a6),a1
- move.l 8(a6),d1 }
- move.l d0,d1
- move.b (a0)+,d0 { Get source length }
- and.w #$ff,d0
- cmp.w d1,d0 { This is a signed comparison! }
- ble @LM4
- move.b d1,d0 { If longer than maximum size of target, cut
- source length }
- @LM4:
- andi.l #$ff,d0 { zero extend d0-byte }
- move.l d0,d1 { save length to copy }
- move.b d0,(a1)+ { save new length }
- { Check if copying length is zero - if so then }
- { exit without copying anything. }
- tst.b d1
- beq @Lend
- bra @LMSTRCOPY55
- @LMSTRCOPY56: { 68010 Fast loop mode }
- move.b (a0)+,(a1)+
- @LMSTRCOPY55:
- dbra d1,@LMSTRCOPY56
- @Lend:
- end;
- { Concatenate Strings }
- { PARAMETERS ARE REVERSED COMPARED TO NORMAL! }
- { therefore online assembler may not parse the params as normal }
- procedure strconcat(s1,s2 : pointer);[public,alias: 'STRCONCAT'];
- begin
- asm
- move.b #255,d0
- move.l s1,a0 { a0 = destination }
- move.l s2,a1 { a1 = source }
- sub.b (a0),d0 { copyl:= 255 -length(s1) }
- move.b (a1),d6
- and.w #$ff,d0 { Sign flags are checked! }
- and.w #$ff,d6
- cmp.w d6,d0 { if copyl > length(s2) then }
- ble @Lcontinue
- move.b (a1),d0 { copyl:=length(s2) }
- @Lcontinue:
- move.b (a0),d6
- and.l #$ff,d6
- lea 1(a0,d6),a0 { s1[length(s1)+1] }
- add.l #1,a1 { s2[1] }
- move.b d0,d6
- { Check if copying length is zero - if so then }
- { exit without copying anything. }
- tst.b d6
- beq @Lend
- bra @ALoop
- @Loop:
- move.b (a1)+,(a0)+ { s1[i] := s2[i]; }
- @ALoop:
- dbra d6,@Loop
- move.l s1,a0
- add.b d0,(a0) { change to new string length }
- @Lend:
- end ['d0','d1','a0','a1','d6'];
- end;
- { Compares strings }
- { DO NOT CALL directly. }
- { a0 = pointer to first string to compare }
- { a1 = pointer to second string to compare }
- { ALL FLAGS are set appropriately. }
- { ZF = strings are equal }
- { REGISTERS DESTROYED: a0, a1, d0, d1, d6 }
- procedure strcmp; assembler;[public,alias:'FPC_STRCMP'];
- asm
- move.b (a0)+,d0 { Get length of first string }
- move.b (a1)+,d6 { Get length of 2nd string }
- move.b d6,d1 { Save length of string for final compare }
- cmp.b d0,d6 { Get shortest string length }
- ble @LSTRCONCAT1
- move.b d0,d6 { Set length to shortest string }
- @LSTRCONCAT1:
- tst.b d6 { Both strings have a length of zero, exit }
- beq @LSTRCONCAT2
- andi.l #$ff,d6
- subq.l #1,d6 { subtract first attempt }
- { if value is -1 then don't loop and just compare lengths of }
- { both strings before exiting. }
- bmi @LSTRCONCAT2
- or.l d0,d0 { Make sure to set Zerfo flag to 0 }
- @LSTRCONCAT5:
- { Workaroung for GAS v.134 bug }
- { old: cmp.b (a1)+,(a0)+ }
- cmpm.b (a1)+,(a0)+
- @LSTRCONCAT4:
- dbne d6,@LSTRCONCAT5 { Repeat until not equal }
- bne @LSTRCONCAT3
- @LSTRCONCAT2:
- { If length of both string are equal }
- { Then set zero flag }
- cmp.b d1,d0 { Compare length - set flag if equal length strings }
- @LSTRCONCAT3:
- end;
- {$endif dummy}
- {$define FPC_SYSTEM_HAS_MOVE}
- procedure move(var source;var dest;count : longint);
- { base pointer+8 = source }
- { base pointer+12 = destination }
- { base pointer+16 = number of bytes to move}
- begin
- asm
- clr.l d0
- move.l 16(a6),d0 { number of bytes }
- @LMOVE0:
- move.l 12(a6),a1 { destination }
- move.l 8(a6),a0 { source }
- cmpi.l #65535, d0 { check, if this is a word move }
- ble @LMEMSET00 { use fast dbra mode 68010+ }
- cmp.l a0,a1 { check copy direction }
- bls @LMOVE4
- add.l d0,a0 { move pointers to end }
- add.l d0,a1
- bra @LMOVE2
- @LMOVE1:
- move.b -(a0),-(a1) { (s < d) copy loop }
- @LMOVE2:
- subq.l #1,d0
- cmpi.l #-1,d0
- bne @LMOVE1
- bra @LMOVE5
- @LMOVE3:
- move.b (a0)+,(a1)+ { (s >= d) copy loop }
- @LMOVE4:
- subq.l #1,d0
- cmpi.l #-1,d0
- bne @LMOVE3
- bra @LMOVE5
- @LMEMSET00: { use fast loop mode 68010+ }
- cmp.l a0,a1 { check copy direction }
- bls @LMOVE04
- add.l d0,a0 { move pointers to end }
- add.l d0,a1
- bra @LMOVE02
- @LMOVE01:
- move.b -(a0),-(a1) { (s < d) copy loop }
- @LMOVE02:
- dbra d0,@LMOVE01
- bra @LMOVE5
- @LMOVE03:
- move.b (a0)+,(a1)+ { (s >= d) copy loop }
- @LMOVE04:
- dbra d0,@LMOVE03
- { end fast loop mode }
- @LMOVE5:
- end ['d0','a0','a1'];
- end;
- {$define FPC_SYSTEM_HAS_FILLWORD}
- procedure fillword(var x;count : longint;value : word);
- begin
- asm
- move.l 8(a6), a0 { destination }
- move.l 12(a6), d1 { number of bytes to fill }
- move.w 16(a6),d0 { fill data }
- bra @LMEMSET21
- @LMEMSET11:
- move.w d0,(a0)+
- @LMEMSET21:
- subq.l #1,d1
- cmp.b #-1,d1
- bne @LMEMSET11
- end ['d0','d1','a0'];
- end;
- {$define FPC_SYSTEM_HAS_ABS_LONGINT}
- function abs(l : longint) : longint;
- begin
- asm
- move.l 8(a6),d0
- tst.l d0
- bpl @LMABS1
- neg.l d0
- @LMABS1:
- move.l d0,@RESULT
- end ['d0'];
- end;
|