home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD2.bin
/
bbs
/
dev
/
oberon-a-1.4ß.lha
/
Oberon-A
/
source
/
oberonsys
/
DIVMOD.asm
< prev
next >
Wrap
Assembly Source File
|
1994-08-08
|
8KB
|
282 lines
****************************************************************************
*
* $RCSfile: DIVMOD.asm $
* Description: Runtime support for the Oberon-A compiler
*
* Created by: fjc (Frank Copeland)
* $Revision: 1.3 $
* $Author: fjc $
* $Date: 1994/07/24 18:25:16 $
*
* Copyright © 1994, Frank Copeland.
* This file is part of the Oberon-A Library.
* See Oberon-A.doc for conditions of use and distribution.
*
* Log entries are at the end of the file.
*
****************************************************************************
*
* This file contains the MC68000 source code for part of the runtime
* support library of the Oberon-A compiler. It contains the code to
* perform division and modulus operations on 32-bit signed integers
* (LONGINTs).
*
* Other parts of the runtime system may be found in the other files in
* this directory. The object files resulting from assembling these
* files are concatenated to create OberonSys.lib.
*
* This code is by definition *not* re-entrant and is not suitable for
* creating shared-code libraries.
*
* Acknowledgements
* ----------------
*
* The 32-bit multiply and divide procedures are from the runtime
* library of Patrick Quaid's PCQ freeware Pascal compiler, which in
* turn came from the runtime library of Sozobon C.
*
**********************************************************************
;---------------------------------------------------------------------
; Program unit hunk name
TTL OberonSys
;---------------------------------------------------------------------
; Imports
INCLUDE "OberonSys.i"
**********************************************************************
**********
* lmath.s
**********
* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg
*
* Permission is granted to anyone to use this software for any purpose
* on any computer system, and to redistribute it freely, with the
* following restrictions:
* 1) No charge may be made other than reasonable charges for reproduction.
* 2) Modified versions must be clearly marked as such.
* 3) The authors are not responsible for any harmful consequences
* of using this software, even if they result from defects in it.
*
* For PCQ Pascal:
* These are the 32-bit math functions from Sozobon-C,
* as noted above. I changed the names of the routines to
* be more similar to the rest of my library, and handle the
* divide by zero condition differently. Other than that I
* haven't changed the code a bit.
* For Oberon-A:
* I have changed the names (again) and modified the
* routines to accept parameters passed in registers instead of
* on the stack, in keeping with the conventions I use in the
* rest of the compiler.
**********************************************************************
;----------------------------------------------------------------
; PROCEDURE OberonSys_DIV
; l1 {D0} : LONGINT;
; l2 {D1} : LONGINT)
; : LONGINT;
;
; Calculates l1 DIV l2, returning the result in D0.
;----------------------------------------------------------------
SECTION OberonSys,CODE
XDEF OberonSys_DIV
OberonSys_DIV:
movem.l d2-d5,-(a7) ; save registers
tst.l d0
smi d4
bpl ld1
neg.l d0
ld1:
tst.l d1
smi d5
bpl ld2
neg.l d1
ld2:
bsr i_ldiv /* d0 = d0/d1, d1 = d0%d1 */
cmp.b d4,d5
beq ld3
neg.l d0
ld3:
; tst.b d4
; beq ld4
; neg.l d1
;ld4:
movem.l (a7)+,d2-d5
rts
;---------------------------------------------------------------------
;----------------------------------------------------------------
; PROCEDURE OberonSys_MOD
; l1 {D0} : LONGINT;
; l2 {D1} : LONGINT)
; : LONGINT;
;
; Calculates l1 MOD l2, returning the result in D0.
;----------------------------------------------------------------
SECTION OberonSys,CODE
XDEF OberonSys_MOD
OberonSys_MOD:
; movem.l d2-d5,-(a7) ; save registers
movem.l d2-d4,-(a7) ; save registers
tst.l d0
smi d4
bpl lmd1
neg.l d0
lmd1:
; tst.l d1
; smi d5
; bpl lmd2
; neg.l d1
;lmd2:
bsr i_ldiv /* d0 = d0/d1, d1 = d0%d1 */
; cmp.b d4,d5
; beq lmd3
; neg.l d0
;lmd3:
tst.b d4
beq lmd4
neg.l d1
lmd4:
move.l d1,d0
; movem.l (a7)+,d2-d5
movem.l (a7)+,d2-d4
rts
;---------------------------------------------------------------------
SECTION OberonSys,CODE
XREF OberonSys_CLEANUP
*A in d0, B in d1, return A/B in d0, A%B in d1
i_ldiv:
tst.l d1
bne.s nz1
* divide by zero
LEA OberonSys_VAR,A5
move.l #OS_ZeroDiv,OS_returnCode(A5) ; HALT (ZeroDiv)
bra OberonSys_CLEANUP
nz1:
cmp.l d1,d0
bhi norm
beq is1
* A<B, so ret 0, rem A
move.l d0,d1
clr.l d0
rts
* A==B, so ret 1, rem 0
is1:
moveq.l #1,d0
clr.l d1
rts
* A>B and B is not 0
norm:
cmp.l #1,d1
bne.s not1
* B==1, so ret A, rem 0
clr.l d1
rts
* check for A short (implies B short also)
not1:
cmp.l #$ffff,d0
bhi slow
* A short and B short -- use 'divu'
divu d1,d0 /* d0 = REM:ANS */
swap d0 /* d0 = ANS:REM */
clr.l d1
move.w d0,d1 /* d1 = REM */
clr.w d0
swap d0
rts
* check for B short
slow:
cmp.l #$ffff,d1
bhi slower
* A long and B short -- use special stuff from gnu
move.l d0,d2
clr.w d2
swap d2
divu d1,d2 /* d2 = REM:ANS of Ahi/B */
clr.l d3
move.w d2,d3 /* d3 = Ahi/B */
swap d3
move.w d0,d2 /* d2 = REM << 16 + Alo */
divu d1,d2 /* d2 = REM:ANS of stuff/B */
move.l d2,d1
clr.w d1
swap d1 /* d1 = REM */
clr.l d0
move.w d2,d0
add.l d3,d0 /* d0 = ANS */
rts
* A>B, B > 1
slower:
move.l #1,d2
clr.l d3
moreadj:
cmp.l d0,d1
bhi.s adj
add.l d2,d2
add.l d1,d1
bpl moreadj
* we shifted B until its >A or sign bit set
* we shifted #1 (d2) along with it
adj:
cmp.l d0,d1
bhi.s ltuns
or.l d2,d3
sub.l d1,d0
ltuns:
lsr.l #1,d1
lsr.l #1,d2
bne adj
* d3=answer, d0=rem
move.l d0,d1
move.l d3,d0
rts
;---------------------------------------------------------------------
END ; OberonSys
**********************************************************************
*
* $Log: DIVMOD.asm $
* Revision 1.3 1994/07/24 18:25:16 fjc
* - Changed code for calling HALT().
*
* Revision 1.2 1994/05/12 20:31:15 fjc
* - Prepared for release
*
* Revision 1.1 1994/01/15 18:31:52 fjc
* Start of revision control
*
* (12 Jan 1994) Modified to assemble with PhxAss instead of A68K
* ( 9 Jul 1993) Changed return code to OS_ZeroDiv.
* (29 May 1993) Split OberonSys.asm into several files to create
* OberonSys.lib.
*
**********************************************************************