ack/mach/z80/int/fpp.s
1987-02-03 13:32:24 +00:00

488 lines
6.9 KiB
ArmAsm

.define fpac, fpadd, fpcdf, fpcfd, fpcfi, fpcif, fpcmf, fpcomp
.define fpdiv, fpfef, fpfif, fpmult, fpop, fpsub, fpnorm
.sect .text
.sect .rom
.sect .data
.sect .bss
.sect .text
! floating point pakket voor Z80
! geimplementeerd zoals beschreven in
! Electronica top internationaal.
! September 1979
! Auteur: Hr. R. Beverdam, Zuidbroekweg 9,7642 NW Wierden
xa: .space 1
fpac:
fal: .space 1
fan: .space 1
fam: .space 1
fax: .space 1
xo: .space 1
fpop:
fol: .space 1
fon: .space 1
fom: .space 1
fox: .space 1
fpsub:
call fpcomp ! inverteer fpacc
fpadd:
ld de,(fam) ! d fax,e fam
ld bc,(fom) ! b fox,c fom
ld a,e ! test fpacc
or a ! 0?
jr z,movop ! ja: som=fpop dus verplaats
xor a
add a,c
ret z ! som is dus fpacc, klaar
ld a,b
sub d ! a:=fox-fax
ld l,a ! bewaar verschil exponenten
jp p,skpneg ! maak positief
neg
skpneg:
cp 0x18 ! verschil meer dan 23?
ld a,l
jp m,lineup ! spring indien binnen bereik
and a ! getallen te groot tov elkaar
ret m ! klaar als fpacc het grootst
movop:
ld hl,fol ! verplaats fpop naar fpacc
ld de,fal ! want fpop is het antwoord
ld bc,4
ldir
ret
lineup:
and a ! kijk welke groter is
jp m,shifto ! spring als fpop>fpac
inc a ! bereken sa
ld b,a ! save sa in b register
ld a,1 ! so 1
push af ! bewaar so op stapel
jr shacop ! gr schuiven
shifto:
neg ! bereken fox-fax
eqexp:
inc a ! so 1+(fox-fax)
push af ! bewaar so op stapel
ld b,1 ! sa 1
shacop:
ld hl,(fal) ! l fal,h fan
xor a ! xa 0
moracc:
sra e ! schuif fam
rr h ! fan
rr l ! fal
rra ! xa
inc d ! update voor fax
djnz moracc ! herhaal sa keer
ld (xa),a ! berg alles
ld (fal),hl ! weg in
ld (fam),de ! fpacc en xa
pop af ! haal so terug van stapel
ld b,a ! en zet in b register
xor a ! xo 0
ld hl,(fol) ! l fol,h fon
morop:
sra c ! schuif: fom
rr h ! fon
rr l !
rra ! xo
djnz morop ! herhaal so keer
ld (xo),a
ld (fol),hl
ld (fom),bc ! berg alles weg in fpop en xo
ld de,xa
ld hl,xo
ld b,4
or a ! reset carry
addmor:
ld a,(de) ! haal een byte
adc a,(hl) ! tel er een bij op
ld (de),a ! en berg de som weer op
inc e
inc l
djnz addmor ! herhaal dit 4 keer
jr fpnorm
yyy:
.data2 fom
fpmult:
call setsgn
add a,(hl) ! bereken exponent produkt
ld (hl),a ! fax exponent produkt
ld a,(yyy)
ld l,a
ex de,hl ! gebruik de als wijzer
xor a
ld h,a
ld l,a ! hoogste 16 bits van pp worden nul
exx
ld bc,(fal)
ld de,(fam) ! haal mc in registers
ld d,a ! d:=0 tbv 16-bit add
ld h,a
ld l,a ! middelste 16 bits van pp worden nul
ld ix,0 ! laagste 16 bits ook
exx
ld c,3
mult:
ld a,(de) ! haal een byte van mr
dec e
ld b,8 ! bits in a byte
shift:
rla ! schuif vooste bit in carry
exx
jr nc,noadd ! vooste bit is 0, dan niet optellen
add ix,bc ! pp:=pp+mc
adc hl,de ! continued
noadd:
add ix,ix
adc hl,hl
exx
adc hl,hl ! dit schoof het hele partiele produkt <
djnz shift ! herhaal voor alle 8 bits
dec c
jr nz,mult ! herhaal voor 3 bytes
exx
rl l
rla
add a,h
ld (fal),a
ld a,d
exx
adc a,l
ld (fan),a ! rond getal in pp af en berg resultaat op
ld a,c
adc a,h
ld (fam),a
call fpnorm
exmldv:
ld hl,xa
ld c,(hl)
jp resign ! fix sign
fpdiv:
call setsgn
sub (hl)
ld (hl),a ! berg exponent quotient op
ld hl,(fol)
push hl
pop ix
ld de,(fal)
ld a,(fam)
or a ! fpacc = 0 ?
jr z,fperr ! fout, deling door nul
ld b,a ! b:=fam
ld a,(fom)
ld c,a
exx
ld hl,fam
ld e,3
divide:
ld b,8
mordiv:
exx
and a
sbc hl,de
sbc a,b ! probeer de aftrekking
jp m,nogo ! gaat niet
push hl
pop ix
ld c,a
ex af,af2 ! quotient in tweede accumulator
scf
jr quorot
nogo:
ex af,af2
or a
quorot:
rla ! volgende bit in quotient
ex af,af2
add ix,ix ! schuif eventueel vernieuwde
rl c ! dd naar links
push ix
pop hl
ld a,c ! zet nieuwe dd in rekenregisters
exx
djnz mordiv ! herhaal 8 keer
ex af,af2
ld (hl),a ! zet een byte van het quotient in het geheugen
dec l
ex af,af2
dec e
jr nz,divide ! herhaal 3 keer
ld bc,(fal)
ld hl,(fam) ! haal quotient terug in cpu
bit 7,l
jp z,exmldv ! als niet te groot tekenherstellen
ld a,1 ! wel te groot
add a,c ! eerst getal afronden
ld c,a
ld a,e
adc a,b
ld b,a
ld a,e
adc a,l
ld l,a
shft:
inc h ! nu getal naar rechts schuiven
rr l
rr b
rr c
or a
bit 7,l
jr nz,shft ! door afronding weer te groot
ld (fal),bc
ld (fam),hl
jr exmldv ! inspecteer teken
setsgn:
ld a,(fom) ! ******** setsgn ************
ld c,1 ! teken -1
rlca ! fpop 0 ?
jr nc,tstacc ! nee
rrc c ! ja, dus teken:=teken*(-1)
ld hl,fol ! en inverteer fpop
call complm
tstacc:
ld a,(fam)
rlca ! fpacc 0?
jr nc,init ! nee
rrc c ! ja dus teken:=teken*(-1)
call fpcomp
init:
ld hl,xa ! initialiseer nog een paar registers
ld (hl),c
ld a,(xxx)
ld l,a
ld a,(fox)
ret
xxx:
.data2 fax
fpcif:
ld de,(fpac) ! integer to convert
xor a
sra d
rr e
rr a
ld (fan),de
ld (fal),a
ld a,16
ld (fax),a
jr fpnorm
fpcfi:
ld a,(fax)
dec a
jp m,fpzero ! really integer zero here
sub 15
jp p,fperr ! overflow
ld de,(fan)
inc a
neg
jr z,2f
ld b,a
ld a,(fal)
1:
sra d
rr e
rr a
djnz 1b
2:
bit 7,d
jr z,0f
inc de
0:
ld (fpac),de
ret
fpcdf:
ld de,(fpac)
ld bc,(fpac+2)
ld h,31
3:
ld a,b
and 0300
jr z,1f
cp 0300
jr z,1f
or a
jp p,2f
sra b
rr c
rr d
inc h
2:
ld a,h
ld (fax),a
ld (fan),bc
ld a,d
ld (fal),a
ret
1:
sla e
rl d
rl c
rl b
dec h
jr 3b
fpcfd:
ld a,(fax)
dec a
jp m,fpzero
cp 32
jp p,fperr
sub 31
cpl
ld bc,(fan)
ld de,(fal)
ld d,e
ld e,0
1:
dec a
jp m,2f
sra b
rr c
rr d
rr e
jr 1b
2:
bit 7,b
jr z,3f
sla e
rl d
rl c
rl b
3:
ld (fpac+2),bc
ld (fpac),de
ret
fpfef:
ld a,(fox)
ld (fpac),a
9:
bit 7,a
jr z,1f
ld a,0xFF
jr 2f
1:
xor a
2:
ld (fpac+1),a
xor a
ld (fox),a
ret
fpcmf:
call fpsub
ld a,(fam)
ld (fpac),a
jr 9b
fpfif:
call fpmult
ld a,(fax)
dec a
jp m,intzero
inc a
ld b,a
xor a
ld c,0200
ld d,a
ld e,a
1:
sra c
rr d
rr e
djnz 1b
ld hl,fam
ld b,(hl)
ld a,c
and b
ld (fom),a
ld a,c
xor 0177
and b
ld (hl),a
dec l
ld b,(hl)
ld a,d
and b
ld (fon),a
ld a,d
cpl
and b
ld (hl),a
dec l
ld b,(hl)
ld a,e
and b
ld (fol),a
ld a,e
cpl
and b
ld (hl),a
ld a,(fax)
ld (fox),a
jr fpnorm
intzero:
xor a
ld hl,fol
ld b,4
1: ld (hl),a
inc hl
djnz 1b
ret
fpzero:
xor a
ld h,a
ld l,a
ld (fal),hl
ld (fam),hl
ret
fpnorm:
ld a,(fam)
ld c,a
or a ! fpacc < 0 ?
call m,fpcomp ! ja -- inverteer
ld hl,(fal)
ld de,(fam)
ld a,l
or h
or e
jr z,fpzero ! als hele facc 0 is
ld a,e
mortst:
bit 6,a ! test meest significante bit
jr nz,catch ! stop als bit is 1
add hl,hl ! schuif links zolang bit = 0
adc a,a
dec d ! pas fax ook aan
jr mortst
catch:
ld e,a ! herstel nu fpacc in geheugen
ld (fal),hl
ld (fam),de
resign:
bit 7,c ! test op teken
ret z ! positief, geen actie
fpcomp:
ld hl,fal
complm:
ld b,3 ! inverteer alleen mantisse
xor a
morcom:
sbc a,(hl)
ld (hl),a
inc hl
ld a,0
djnz morcom
or a
ret
fperr:
scf
ret