*** empty log message ***
This commit is contained in:
parent
693830b09a
commit
1879c8e724
45 changed files with 1888 additions and 0 deletions
42
mach/z80/libem/LIST
Normal file
42
mach/z80/libem/LIST
Normal file
|
@ -0,0 +1,42 @@
|
|||
tail_em.a
|
||||
aaru.s
|
||||
aar.s
|
||||
aar2.s
|
||||
and.s
|
||||
cii.s
|
||||
cms.s
|
||||
cmu.s
|
||||
cmu4.s
|
||||
csa.s
|
||||
csb.s
|
||||
dvi2.s
|
||||
dvi4.s
|
||||
dvu2.s
|
||||
dvu4.s
|
||||
exg.s
|
||||
gto.s
|
||||
hulp.s
|
||||
ior.s
|
||||
laru.s
|
||||
lar.s
|
||||
lar2.s
|
||||
los.s
|
||||
mli2.s
|
||||
mli4.s
|
||||
rck.s
|
||||
rmi2.s
|
||||
saru.s
|
||||
sar.s
|
||||
sar2.s
|
||||
sdf.s
|
||||
sdl.s
|
||||
set.s
|
||||
str.s
|
||||
sts.s
|
||||
unim.s
|
||||
trp.s
|
||||
inn.s
|
||||
xor.s
|
||||
nop.s
|
||||
outdec.s
|
||||
pstrng.s
|
17
mach/z80/libem/Makefile
Normal file
17
mach/z80/libem/Makefile
Normal file
|
@ -0,0 +1,17 @@
|
|||
# $Header$
|
||||
install:
|
||||
../../install tail_em.a tail_em
|
||||
../../install tail.s end_em
|
||||
|
||||
cmp:
|
||||
-../../compare tail_em.a tail_em
|
||||
-../../compare tail.s end_em
|
||||
|
||||
clean :
|
||||
|
||||
opr :
|
||||
make pr | opr
|
||||
|
||||
pr:
|
||||
@arch pv tail_em.a | pr -h `pwd`/tail_em.a
|
||||
@pr `pwd`/tail.s
|
35
mach/z80/libem/aar.s
Normal file
35
mach/z80/libem/aar.s
Normal file
|
@ -0,0 +1,35 @@
|
|||
.define .aar
|
||||
! use .mli2
|
||||
|
||||
! 2-byte descriptor elements
|
||||
! any size array elements
|
||||
! no range checking
|
||||
! parameters:
|
||||
! stack: pointer to descriptor
|
||||
! index
|
||||
! base address of array
|
||||
! stack: result (out)
|
||||
! uses .mli2 routine
|
||||
! side-effect: size of array elements in bc
|
||||
|
||||
|
||||
|
||||
.aar:
|
||||
pop hl ! return address
|
||||
pop ix ! pointer to descr.
|
||||
ex (sp),hl ! save ret. addr.
|
||||
! hl := index
|
||||
ld c,(ix+0) ! bc := lower bound
|
||||
ld b,(ix+1)
|
||||
xor a
|
||||
sbc hl,bc ! hl := index-lwb
|
||||
ld c,(ix+4) ! bc := size
|
||||
ld b,(ix+5)
|
||||
ex de,hl ! de := index-lwb
|
||||
call .mli2 ! hl := bc*de =
|
||||
! size*(index-lwb)
|
||||
pop ix ! return address
|
||||
pop de ! base
|
||||
add hl,de ! addr. of element
|
||||
push hl
|
||||
jp (ix) ! return
|
23
mach/z80/libem/aar2.s
Normal file
23
mach/z80/libem/aar2.s
Normal file
|
@ -0,0 +1,23 @@
|
|||
.define .aar2
|
||||
|
||||
! special case aar: element size = 2 (statically known)
|
||||
! parameters:
|
||||
! on stack
|
||||
! execution time: 124 states
|
||||
|
||||
|
||||
|
||||
.aar2:
|
||||
pop ix ! save return address
|
||||
pop hl ! pointer to descriptor
|
||||
ld c,(hl) ! bc := lower bound
|
||||
inc hl
|
||||
ld b,(hl)
|
||||
pop hl ! index
|
||||
xor a
|
||||
sbc hl,bc ! index - lwb
|
||||
add hl,hl ! size*(index-lwb)
|
||||
pop de ! base address of array
|
||||
add hl,de
|
||||
push hl
|
||||
jp (ix)
|
19
mach/z80/libem/aaru.s
Normal file
19
mach/z80/libem/aaru.s
Normal file
|
@ -0,0 +1,19 @@
|
|||
.define .aaru
|
||||
|
||||
! AAR NOT DEFINED
|
||||
|
||||
.aaru:
|
||||
pop ix
|
||||
pop hl
|
||||
xor a
|
||||
xor h
|
||||
jp nz,1f
|
||||
ld a,2
|
||||
xor l
|
||||
jp z,2f
|
||||
1:
|
||||
ld hl,EARRAY
|
||||
call .trp.z
|
||||
2:
|
||||
push ix
|
||||
jp .aar
|
35
mach/z80/libem/and.s
Normal file
35
mach/z80/libem/and.s
Normal file
|
@ -0,0 +1,35 @@
|
|||
.define .and
|
||||
|
||||
! auxiliary size 'and'
|
||||
! parameters:
|
||||
! de: size
|
||||
! stack: operands
|
||||
! stack: result (out)
|
||||
|
||||
|
||||
|
||||
.and:
|
||||
pop ix ! save return address
|
||||
ld h,d
|
||||
ld l,e
|
||||
add hl,sp
|
||||
ex de,hl
|
||||
add hl,de ! now hl is the base of second
|
||||
ld b,d ! operand. bc and de are base
|
||||
ld c,e ! of the first operand
|
||||
1:
|
||||
dec hl
|
||||
dec de
|
||||
ld a,(de)
|
||||
and (hl)
|
||||
ld (hl),a
|
||||
xor a
|
||||
sbc hl,bc
|
||||
jr z,2f
|
||||
add hl,bc
|
||||
jr 1b
|
||||
2:
|
||||
ld h,b
|
||||
ld l,c
|
||||
ld sp,hl
|
||||
jp (ix)
|
139
mach/z80/libem/cii.s
Normal file
139
mach/z80/libem/cii.s
Normal file
|
@ -0,0 +1,139 @@
|
|||
.define .cii
|
||||
|
||||
! cii: convert integer to integer
|
||||
! parameters:
|
||||
! stack: destination size
|
||||
! source size
|
||||
! source
|
||||
! stack: result (out)
|
||||
! This code is also used by cuu.
|
||||
! The contents of the a-register determines
|
||||
! if we're doing a cii (a=0) or a cuu (a=1),
|
||||
! so be very careful with this register!
|
||||
|
||||
|
||||
|
||||
.cii:
|
||||
pop ix ! return address
|
||||
pop hl ! destination size
|
||||
pop de ! source size
|
||||
ld b,h ! bc := destination size
|
||||
ld c,l
|
||||
xor a ! watch it, this is dirty!
|
||||
! Besides clearing the carry
|
||||
! this instruction sets a-reg.
|
||||
! to 0, to indicate this is
|
||||
! a cii and not a cuu.
|
||||
sbc hl,de ! hl := destination size
|
||||
! - source size
|
||||
jr z,1f ! equal, return
|
||||
jp p,2f ! larger, expand
|
||||
! smaller, shrink
|
||||
! The most significant part of the source
|
||||
! is removed. As the least sign. part is
|
||||
! on top of the stack, we have to move an
|
||||
! entire data block.
|
||||
9:
|
||||
add hl,sp ! note that hl < 0
|
||||
! (also come here via cuu)
|
||||
add hl,de
|
||||
dec hl ! now hl points to most
|
||||
! significant byte of what
|
||||
! will be left over of source
|
||||
ex de,hl
|
||||
add hl,sp
|
||||
ex de,hl
|
||||
dec de ! now de points to highest
|
||||
! byte of source
|
||||
lddr ! move 'destination size'
|
||||
! bytes upwards (i.e. away
|
||||
! from top of stack)
|
||||
inc de
|
||||
ex de,hl
|
||||
ld sp,hl ! adjust stackpointer
|
||||
1:
|
||||
jp (ix) ! return
|
||||
|
||||
2:
|
||||
! larger, expand
|
||||
! A number of bytes (containing the signbits
|
||||
! of the source) is inserted before the most
|
||||
! significant byte of the source.
|
||||
! As this byte is somewhere in the middle of
|
||||
! the stack, the entire source must first be
|
||||
! moved downwards (in the direction of the
|
||||
! top)
|
||||
8:
|
||||
ld b,d ! bc := source size
|
||||
! (also come here via cuu)
|
||||
ld c,e
|
||||
ex de,hl ! de := difference (> 0)
|
||||
ld hl,0
|
||||
add hl,sp ! hl := sp
|
||||
push hl
|
||||
or a
|
||||
sbc hl,de
|
||||
ex de,hl ! de := sp - difference
|
||||
pop hl ! hl := sp
|
||||
ex de,hl ! adjust sp
|
||||
ld sp,hl
|
||||
ex de,hl
|
||||
ldir ! move source upwards,
|
||||
! creating a 'hole'
|
||||
! inside the stack
|
||||
! now we will fill the hole with bytes
|
||||
! containing either 0 or -1, depending
|
||||
! on the signbit of the source.
|
||||
or a
|
||||
sbc hl,de
|
||||
ex de,hl ! de := difference
|
||||
dec hl ! now hl points to
|
||||
! most significant byte
|
||||
! of the source
|
||||
or a ! see if we're doing
|
||||
! a 'cii' or a 'cuu'
|
||||
jr nz,3f ! cuu, expand with zeroes
|
||||
bit 7,(hl) ! test signbit
|
||||
jr z,3f
|
||||
dec b ! b := -1 (was 0 after ldir)
|
||||
3:
|
||||
inc hl
|
||||
ld (hl),b ! either 0 or -1
|
||||
dec de
|
||||
ld a,d
|
||||
or e
|
||||
jr nz,3b
|
||||
jp (ix) ! return
|
||||
|
||||
|
||||
|
||||
.define .cuu
|
||||
|
||||
! cuu: convert unsigned to unsigned
|
||||
! parameters:
|
||||
! stack: destination size
|
||||
! source size
|
||||
! source
|
||||
! stack: result (out)
|
||||
! The only difference between a cuu and a cii is:
|
||||
! if the destination is larger than the source,
|
||||
! the former extends with zeroes and the latter
|
||||
! extends with sign bits
|
||||
! cuu uses the code of cii. In this case it puts
|
||||
! a '1' in the accumulator to indicate this is
|
||||
! a cuu.
|
||||
|
||||
|
||||
|
||||
.cuu:
|
||||
pop ix
|
||||
pop hl
|
||||
pop de
|
||||
ld b,h
|
||||
ld c,l
|
||||
xor a ! clear carry
|
||||
sbc hl,de
|
||||
jr z,1b ! equal, return
|
||||
jp m,9b ! smaller, shrink
|
||||
inc a ! a := 1
|
||||
jr 8b ! larger, expand
|
33
mach/z80/libem/cms.s
Normal file
33
mach/z80/libem/cms.s
Normal file
|
@ -0,0 +1,33 @@
|
|||
.define .cms
|
||||
|
||||
! any size sets
|
||||
! parameters:
|
||||
! hl: size
|
||||
! stack: second operand
|
||||
! first operand
|
||||
! stack: result (out)
|
||||
|
||||
|
||||
|
||||
.cms:
|
||||
pop ix
|
||||
ld b,h
|
||||
ld c,l
|
||||
add hl,sp
|
||||
0:
|
||||
dec sp
|
||||
pop af
|
||||
cpi
|
||||
jr nz,1f
|
||||
ld a,b
|
||||
or c
|
||||
jr nz,0b
|
||||
ld de,0
|
||||
jr 2f
|
||||
1:
|
||||
add hl,bc
|
||||
ld de,1
|
||||
2:
|
||||
ld sp,hl
|
||||
push de
|
||||
jp (ix)
|
71
mach/z80/libem/cmu.s
Normal file
71
mach/z80/libem/cmu.s
Normal file
|
@ -0,0 +1,71 @@
|
|||
.define .cmu
|
||||
|
||||
! parameters:
|
||||
! hl : size (#bytes)
|
||||
! stack: second operand
|
||||
! first operand
|
||||
! stack: result (out)
|
||||
|
||||
|
||||
|
||||
.cmu:
|
||||
! The two operands are compared byte by byte,
|
||||
! starting at the highest byte, until
|
||||
! they differ.
|
||||
pop ix ! return address
|
||||
pop hl ! #bytes
|
||||
ld b,h ! bc := hl
|
||||
ld c,l
|
||||
add hl,sp
|
||||
dec hl ! pointer to highest byte
|
||||
! of second operand
|
||||
ld d,h ! de := hl
|
||||
ld e,l
|
||||
add hl,bc ! pointer to highest byte
|
||||
! of first operand
|
||||
ld sp,hl ! points to where the
|
||||
! result will be stored
|
||||
ex de,hl
|
||||
! now, de points to highest byte of 1st operand
|
||||
! sp ,, ,, ,,
|
||||
! hl ,, ,, 2nd ,,
|
||||
! bc contains #bytes
|
||||
|
||||
0:
|
||||
! loop, compare the two operands
|
||||
! byte by byte.
|
||||
ld a,(de)
|
||||
xor (hl) ! Avoid overflow during
|
||||
! subtraction. If the
|
||||
! signbits differ, then
|
||||
! the operands differ.
|
||||
jp m,2f ! signbits differ
|
||||
ld a,(de) ! signbits are equal,
|
||||
! so we can savely
|
||||
! compare the bytes.
|
||||
sub (hl)
|
||||
jr nz,1f ! operands are different
|
||||
dec de ! the two bytes are the
|
||||
! same, try next bytes,
|
||||
! if any.
|
||||
dec hl ! bump pointers
|
||||
dec bc
|
||||
ld a,b ! bc = 0 ?
|
||||
or c
|
||||
jr nz,0b ! no, try next bytes
|
||||
! yes, then the two operands are equal.
|
||||
! Note that a=0 now.
|
||||
1:
|
||||
ld h,a ! hl := result
|
||||
ld l,a
|
||||
jr 3f
|
||||
2:
|
||||
! the signbits differ
|
||||
ld h,(hl) ! hl := positive if
|
||||
! signbit of current
|
||||
! byte of 2nd operand
|
||||
! is "0", else negative
|
||||
ld l,1 ! just in case (hl)=0
|
||||
3:
|
||||
ex (sp),hl ! sp was set above
|
||||
jp (ix) ! return
|
60
mach/z80/libem/cmu4.s
Normal file
60
mach/z80/libem/cmu4.s
Normal file
|
@ -0,0 +1,60 @@
|
|||
.define .cmu4
|
||||
|
||||
! 4 byte cmu and cmi routine
|
||||
! parameters:
|
||||
! a: 0 for cmu, 1 for cmi
|
||||
! stack: operands
|
||||
! de: result (out)
|
||||
|
||||
|
||||
|
||||
.cmu4:
|
||||
pop ix
|
||||
ld de,4
|
||||
ld b,d
|
||||
ld c,e
|
||||
ld hl,0
|
||||
add hl,sp
|
||||
add hl,bc
|
||||
dec hl
|
||||
ld d,h
|
||||
ld e,l
|
||||
add hl,bc
|
||||
ld (savesp),hl ! save new sp-1
|
||||
or a
|
||||
jr z,1f
|
||||
ld a,(de)
|
||||
cp (hl)
|
||||
dec hl
|
||||
dec de
|
||||
dec bc
|
||||
jr z,1f
|
||||
jp p,4f
|
||||
jr 6f
|
||||
1:
|
||||
ld a,(de)
|
||||
cp (hl)
|
||||
dec de
|
||||
dec hl
|
||||
dec bc
|
||||
jr nz,2f
|
||||
ld a,b
|
||||
or c
|
||||
jr nz,1b
|
||||
ld d,a
|
||||
ld e,a
|
||||
jr 3f
|
||||
2:
|
||||
jr nc,4f
|
||||
6:
|
||||
ld de,1
|
||||
jr 3f
|
||||
4:
|
||||
ld de,-1
|
||||
3:
|
||||
ld hl,(savesp)
|
||||
inc hl
|
||||
ld sp,hl
|
||||
jp (ix)
|
||||
.data
|
||||
savesp: .word 0
|
44
mach/z80/libem/csa.s
Normal file
44
mach/z80/libem/csa.s
Normal file
|
@ -0,0 +1,44 @@
|
|||
.define .csa
|
||||
|
||||
! this is not a subroutine, but just a
|
||||
! piece of code that computes the jump-
|
||||
! address and jumps to it.
|
||||
! traps if resulting address is zero
|
||||
|
||||
|
||||
|
||||
.csa:
|
||||
pop ix
|
||||
pop hl
|
||||
push bc
|
||||
ld c,(ix)
|
||||
ld b,(ix+1)
|
||||
ld e,(ix+2)
|
||||
ld d,(ix+3)
|
||||
xor a
|
||||
sbc hl,de
|
||||
jp m,1f
|
||||
ex de,hl
|
||||
ld l,(ix+4)
|
||||
ld h,(ix+5)
|
||||
xor a
|
||||
sbc hl,de
|
||||
jp m,1f
|
||||
ex de,hl
|
||||
add hl,hl
|
||||
ld de,6
|
||||
add hl,de
|
||||
ex de,hl
|
||||
add ix,de
|
||||
ld l,(ix)
|
||||
ld h,(ix+1)
|
||||
ld a,h
|
||||
or l
|
||||
jr nz,2f
|
||||
1: ld a,b
|
||||
or c
|
||||
jr z,.trp.z
|
||||
ld l,c
|
||||
ld h,b
|
||||
2: pop bc
|
||||
jp (hl)
|
55
mach/z80/libem/csb.s
Normal file
55
mach/z80/libem/csb.s
Normal file
|
@ -0,0 +1,55 @@
|
|||
.define .csb
|
||||
|
||||
! this is not a subroutine, but just a
|
||||
! piece of code that computes the jump-
|
||||
! address and jumps to it.
|
||||
! traps if resulting address is zero
|
||||
|
||||
|
||||
|
||||
.csb:
|
||||
pop hl ! pointer to descriptor
|
||||
pop de ! case index
|
||||
ld c,(hl) ! bc := default offset
|
||||
inc hl
|
||||
ld b,(hl)
|
||||
inc hl
|
||||
push bc ! save default on stack
|
||||
ld c,(hl) ! bc := #entries
|
||||
inc hl
|
||||
ld b,(hl)
|
||||
inc hl
|
||||
1:
|
||||
! loop, try to find the case index
|
||||
! in the descriptor
|
||||
ld a,b
|
||||
or c
|
||||
jr z,noteq ! done, index not found
|
||||
ld a,(hl) ! is de=(hl) ?
|
||||
inc hl
|
||||
cp e
|
||||
jr nz,2f ! no
|
||||
ld a,(hl)
|
||||
inc hl
|
||||
cp d
|
||||
jr nz,3f ! no
|
||||
ld a,(hl) ! yes, get jump address
|
||||
inc hl
|
||||
ld h,(hl)
|
||||
ld l,a
|
||||
pop af ! remove default
|
||||
jr 4f
|
||||
2:
|
||||
inc hl ! skip high byte of index
|
||||
3:
|
||||
inc hl ! skip jump address
|
||||
inc hl
|
||||
dec bc
|
||||
jr 1b
|
||||
noteq:
|
||||
pop hl ! take default exit
|
||||
4:
|
||||
ld a,l ! jump address is zero?
|
||||
or h
|
||||
jr z,.trp.z ! yes, trap
|
||||
jp (hl)
|
56
mach/z80/libem/dvi2.s
Normal file
56
mach/z80/libem/dvi2.s
Normal file
|
@ -0,0 +1,56 @@
|
|||
.define .dvi2
|
||||
|
||||
! 16-bit signed division
|
||||
! parameters:
|
||||
! bc: divisor
|
||||
! de: dividend
|
||||
! de: result (out)
|
||||
! no check on overflow
|
||||
|
||||
|
||||
|
||||
.dvi2:
|
||||
xor a
|
||||
ld h,a
|
||||
ld l,a
|
||||
sbc hl,bc
|
||||
jp m,1f
|
||||
ld b,h
|
||||
ld c,l
|
||||
cpl
|
||||
1:
|
||||
or a
|
||||
ld hl,0
|
||||
sbc hl,de
|
||||
jp m,1f
|
||||
ex de,hl
|
||||
cpl
|
||||
1:
|
||||
push af
|
||||
ld hl,0
|
||||
ld a,16
|
||||
0:
|
||||
add hl,hl
|
||||
ex de,hl
|
||||
add hl,hl
|
||||
ex de,hl
|
||||
jr nc,1f
|
||||
inc hl
|
||||
or a
|
||||
1:
|
||||
sbc hl,bc
|
||||
inc de
|
||||
jp p,2f
|
||||
add hl,bc
|
||||
dec de
|
||||
2:
|
||||
dec a
|
||||
jr nz,0b
|
||||
pop af
|
||||
or a
|
||||
jr z,1f
|
||||
ld hl,0
|
||||
sbc hl,de
|
||||
ex de,hl
|
||||
1:
|
||||
ret
|
85
mach/z80/libem/dvi4.s
Normal file
85
mach/z80/libem/dvi4.s
Normal file
|
@ -0,0 +1,85 @@
|
|||
.define .dvi4
|
||||
|
||||
! 4-byte divide routine for z80
|
||||
! parameters:
|
||||
! stack: divisor
|
||||
! dividend
|
||||
! stack: quotient (out)
|
||||
! bc de: remainder (out) (high part in bc)
|
||||
|
||||
|
||||
|
||||
.dvi4:
|
||||
pop hl
|
||||
ld (retaddr),hl
|
||||
xor a
|
||||
ld (.flag1),a
|
||||
ld (.flag2),a
|
||||
ld ix,0
|
||||
add ix,sp
|
||||
ld b,(ix+7) ! dividend
|
||||
bit 7,b
|
||||
jr z,1f
|
||||
ld c,(ix+6)
|
||||
ld d,(ix+5)
|
||||
ld e,(ix+4)
|
||||
call .negbd
|
||||
ld (ix+7),b
|
||||
ld (ix+6),c
|
||||
ld (ix+5),d
|
||||
ld (ix+4),e
|
||||
ld a,1
|
||||
ld (.flag1),a
|
||||
1:
|
||||
ld b,(ix+3)
|
||||
bit 7,b
|
||||
jr z,2f
|
||||
call .negst
|
||||
ld a,1
|
||||
ld (.flag2),a
|
||||
2:
|
||||
call .dvu4
|
||||
ld a,(.flag1)
|
||||
or a
|
||||
jr z,3f
|
||||
call .negbd
|
||||
3:
|
||||
ld (.savebc),bc
|
||||
ld (.savede),de
|
||||
ld a,(.flag2)
|
||||
ld b,a
|
||||
ld a,(.flag1)
|
||||
xor b
|
||||
jr z,4f
|
||||
call .negst
|
||||
4:
|
||||
ld bc,(.savebc)
|
||||
ld de,(.savede)
|
||||
ld hl,(retaddr)
|
||||
jp (hl)
|
||||
.negbd:
|
||||
xor a
|
||||
ld h,a
|
||||
ld l,a
|
||||
sbc hl,de
|
||||
ex de,hl
|
||||
ld h,a
|
||||
ld l,a
|
||||
sbc hl,bc
|
||||
ld b,h
|
||||
ld c,l
|
||||
ret
|
||||
.negst:
|
||||
pop ix
|
||||
pop de
|
||||
pop bc
|
||||
call .negbd
|
||||
push bc
|
||||
push de
|
||||
jp (ix)
|
||||
.data
|
||||
.flag1: .byte 0
|
||||
.flag2: .byte 0
|
||||
retaddr:.word 0
|
||||
.savebc: .word 0
|
||||
.savede: .word 0
|
43
mach/z80/libem/dvu2.s
Normal file
43
mach/z80/libem/dvu2.s
Normal file
|
@ -0,0 +1,43 @@
|
|||
.define .dvu2
|
||||
|
||||
! 16-bit divide
|
||||
! parameters:
|
||||
! bc: divisor
|
||||
! de: dividend
|
||||
! de: quotient (out)
|
||||
! hl: remainder (out)
|
||||
! no overflow detection
|
||||
|
||||
|
||||
|
||||
.dvu2:
|
||||
or a
|
||||
ld h,d
|
||||
ld l,e
|
||||
sbc hl,bc
|
||||
jp m,3f
|
||||
jp c,3f ! bc > de?
|
||||
ld hl,0
|
||||
ld a,16
|
||||
0:
|
||||
add hl,hl
|
||||
ex de,hl
|
||||
add hl,hl
|
||||
ex de,hl
|
||||
jr nc,1f
|
||||
inc hl
|
||||
or a
|
||||
1:
|
||||
sbc hl,bc
|
||||
inc de
|
||||
jp p,2f
|
||||
add hl,bc
|
||||
dec de
|
||||
2:
|
||||
dec a
|
||||
jr nz,0b
|
||||
ret
|
||||
3:
|
||||
ld hl,0
|
||||
ex de,hl
|
||||
ret
|
137
mach/z80/libem/dvu4.s
Normal file
137
mach/z80/libem/dvu4.s
Normal file
|
@ -0,0 +1,137 @@
|
|||
.define .dvu4
|
||||
|
||||
! 4-byte divide routine for z80
|
||||
! parameters:
|
||||
! stack: divisor
|
||||
! dividend
|
||||
! stack: quotient (out)
|
||||
! bc de: remainder (out) (high part in bc)
|
||||
|
||||
|
||||
|
||||
! a n-byte divide may be implemented
|
||||
! using 2 (virtual) registers:
|
||||
! - a n-byte register containing
|
||||
! the divisor
|
||||
! - a 2n-byte shiftregister (VSR)
|
||||
!
|
||||
! Initially, the VSR contains the dividend
|
||||
! in its low (right) n bytes and zeroes in its
|
||||
! high n bytes. The dividend is shifted
|
||||
! left into a "window" bit by bit. After
|
||||
! each shift, the contents of the window
|
||||
! is compared with the divisor. If it is
|
||||
! higher or equal, the divisor is subtracted from
|
||||
! it and a "1" bit is inserted in the
|
||||
! VSR from the right side! else a "0" bit
|
||||
! is inserted. These bits are shifted left
|
||||
! too during subsequent iterations.
|
||||
! At the end, the rightmost part of VSR
|
||||
! contains the quotient.
|
||||
! For n=4, we need 2*4+4 = 12 bytes of
|
||||
! registers. Unfortunately we only have
|
||||
! 5 2-byte registers on the z80
|
||||
! (bc,de,hl,ix and iy). Therefore we use
|
||||
! an overlay technique for the rightmost
|
||||
! 4 bytes of the VSR. The 32 iterations
|
||||
! are split up into two groups: during
|
||||
! the first 16 iterations we use the high
|
||||
! order 16 bits of the dividend! during
|
||||
! the last 16 iterations we use the
|
||||
! low order 16 bits.
|
||||
! register allocation:
|
||||
! VSR iy hl ix
|
||||
! divisor -de bc
|
||||
.dvu4:
|
||||
! initialization
|
||||
pop hl ! save return address
|
||||
ld (.retaddr),hl
|
||||
pop bc ! low part (2 bytes)
|
||||
! of divisor in bc
|
||||
xor a ! clear carry, a := 0
|
||||
ld h,a ! hl := 0
|
||||
ld l,a
|
||||
ld (.flag),a ! first pass main loop
|
||||
pop de ! high part divisor
|
||||
sbc hl,de ! inverse of high part
|
||||
ex de,hl ! of divisor in de
|
||||
pop hl ! save low part of
|
||||
! dividend in memory
|
||||
ld (.low),hl ! used during second
|
||||
! iteration over main loop
|
||||
pop ix ! high part of dividend
|
||||
push iy ! save LB
|
||||
ld h,a ! hl := 0
|
||||
ld l,a
|
||||
ld iy,0 ! now the VSR is initialized
|
||||
|
||||
! main loop, done twice
|
||||
1:
|
||||
ld a,16
|
||||
! sub-loop, done 16 times
|
||||
2:
|
||||
add iy,iy ! shift VSR left
|
||||
add ix,ix
|
||||
adc hl,hl
|
||||
jp nc,3f
|
||||
inc iy
|
||||
3:
|
||||
or a ! subtract divisor from
|
||||
! window (iy hl)
|
||||
ld (.iysave),iy
|
||||
sbc hl,bc
|
||||
jr nc,4f ! decrement iy if there
|
||||
! was no borrow
|
||||
dec iy
|
||||
4:
|
||||
add iy,de ! there is no "sbc iy,ss"
|
||||
! on the z80, so de was
|
||||
! inverted during init.
|
||||
inc ix
|
||||
! see if the result is non-negative,
|
||||
! otherwise undo the subtract.
|
||||
! note that this uncooperating machine
|
||||
! does not set its S -or Z flag after
|
||||
! a 16-bit add.
|
||||
ex (sp),iy ! does anyone see a better
|
||||
ex (sp),hl ! solution ???
|
||||
bit 7,h
|
||||
ex (sp),hl
|
||||
ex (sp),iy
|
||||
jp z,5f
|
||||
! undo the subtract
|
||||
add hl,bc
|
||||
ld iy,(.iysave)
|
||||
dec ix
|
||||
5:
|
||||
dec a
|
||||
jr nz,2b
|
||||
ld a,(.flag) ! see if this was first or
|
||||
! second iteration of main loop
|
||||
or a ! 0=first, 1=second
|
||||
jr nz,6f
|
||||
inc a ! a := 1
|
||||
ld (.flag),a ! flag := 1
|
||||
ld (.result),ix ! save high part of result
|
||||
ld ix,(.low) ! initialize second
|
||||
! iteration, ix := low
|
||||
! part of dividend
|
||||
jr 1b
|
||||
6:
|
||||
! clean up
|
||||
push iy ! transfer remainder
|
||||
pop bc ! from iy-hl to bc-de
|
||||
ex de,hl
|
||||
pop iy ! restore LB
|
||||
ld hl,(.result) ! high part of result
|
||||
push hl
|
||||
push ix ! low part of result
|
||||
ld hl,(.retaddr)
|
||||
jp (hl) ! return
|
||||
|
||||
.data
|
||||
.flag: .byte 0
|
||||
.low: .word 0
|
||||
.iysave: .word 0
|
||||
.retaddr: .word 0
|
||||
.result: .word 0
|
15
mach/z80/libem/end.s
Normal file
15
mach/z80/libem/end.s
Normal file
|
@ -0,0 +1,15 @@
|
|||
.define endtext,enddata,endbss
|
||||
.define _end,_etext,_edata
|
||||
|
||||
.text
|
||||
endtext:
|
||||
_etext:
|
||||
.align 2
|
||||
.data
|
||||
enddata:
|
||||
_edata:
|
||||
.align 2
|
||||
.bss
|
||||
_end:
|
||||
endbss:
|
||||
.align 2
|
25
mach/z80/libem/exg.s
Normal file
25
mach/z80/libem/exg.s
Normal file
|
@ -0,0 +1,25 @@
|
|||
.define .exg
|
||||
.exg:
|
||||
pop ix
|
||||
pop de
|
||||
ld hl,0
|
||||
add hl,sp
|
||||
ld b,h
|
||||
ld c,l
|
||||
add hl,de
|
||||
1:
|
||||
ld a,(bc)
|
||||
ex af,af2
|
||||
ld a,(hl)
|
||||
ld (bc),a
|
||||
ex af,af2
|
||||
ld (hl),a
|
||||
inc bc
|
||||
inc hl
|
||||
dec de
|
||||
ld a,d
|
||||
or e
|
||||
jr nz,1b
|
||||
jp (ix)
|
||||
|
||||
|
22
mach/z80/libem/gto.s
Normal file
22
mach/z80/libem/gto.s
Normal file
|
@ -0,0 +1,22 @@
|
|||
.define .gto
|
||||
|
||||
.gto:
|
||||
ld e,(hl)
|
||||
inc hl
|
||||
ld d,(hl)
|
||||
push de
|
||||
pop ix ! new pc
|
||||
inc hl
|
||||
ld e,(hl)
|
||||
inc hl
|
||||
ld d,(hl) ! new sp
|
||||
inc hl
|
||||
ld c,(hl)
|
||||
inc hl
|
||||
ld b,(hl) ! new lb
|
||||
push bc
|
||||
pop iy
|
||||
push de
|
||||
pop hl
|
||||
ld sp,hl
|
||||
jp (ix)
|
62
mach/z80/libem/hulp.s
Normal file
62
mach/z80/libem/hulp.s
Normal file
|
@ -0,0 +1,62 @@
|
|||
loop = 100
|
||||
dvi4:
|
||||
xor a
|
||||
ld (.flag1),a
|
||||
ld (.flag2),a
|
||||
ld ix,0
|
||||
add ix,sp
|
||||
ld b,(ix+7) ! dividend
|
||||
bit 7,b
|
||||
jr z,1f
|
||||
ld c,(ix+6)
|
||||
ld d,(ix+5)
|
||||
ld e,(ix+4)
|
||||
call .negbd
|
||||
ld (ix+7),d
|
||||
ld (ix+6),e
|
||||
ld (ix+5),h
|
||||
ld (ix+4),l
|
||||
ld a,1
|
||||
ld (.flag1),a
|
||||
1:
|
||||
ld b,(ix+3)
|
||||
bit 7,b
|
||||
jr z,2f
|
||||
call .negst
|
||||
ld a,1
|
||||
ld (.flag2),a
|
||||
2:
|
||||
call .dvu4
|
||||
ld a,(.flag1)
|
||||
jr z,3f
|
||||
call .negbd
|
||||
3:
|
||||
ld a,(.flag2)
|
||||
ld b,a
|
||||
ld a,(.flag1)
|
||||
xor b
|
||||
jr z,4f
|
||||
call .negst
|
||||
4:
|
||||
jr loop
|
||||
.negbd:
|
||||
xor a
|
||||
ld h,a
|
||||
ld l,a
|
||||
sbc hl,de
|
||||
ex de,hl
|
||||
ld h,a
|
||||
ld l,a
|
||||
sbc hl,bc
|
||||
ret
|
||||
.negst:
|
||||
pop iy
|
||||
pop de
|
||||
pop bc
|
||||
call .negbd
|
||||
push hl
|
||||
push de
|
||||
jp (iy)
|
||||
.data
|
||||
.flag1: .byte 0
|
||||
.flag2: .byte 0
|
50
mach/z80/libem/inn.s
Normal file
50
mach/z80/libem/inn.s
Normal file
|
@ -0,0 +1,50 @@
|
|||
.define .inn
|
||||
! use .unimpld
|
||||
|
||||
! any size sets
|
||||
! parameters:
|
||||
! hl: size
|
||||
! stack: bit number
|
||||
! stack: result (out)
|
||||
|
||||
|
||||
|
||||
.inn:
|
||||
pop ix
|
||||
pop de
|
||||
add hl,sp
|
||||
ld b,h
|
||||
ld c,l
|
||||
ex de,hl
|
||||
ld a,l
|
||||
sra h
|
||||
jp m,0f
|
||||
rr l
|
||||
sra h
|
||||
rr l
|
||||
sra h
|
||||
rr l
|
||||
add hl,sp
|
||||
push hl
|
||||
or a ! clear carry
|
||||
sbc hl,de
|
||||
pop hl
|
||||
jp m,1f
|
||||
0: xor a
|
||||
jr 4f
|
||||
1: ld e,(hl)
|
||||
and 7
|
||||
jr 2f
|
||||
3: rrc e
|
||||
dec a
|
||||
2: jr nz,3b
|
||||
ld a,e
|
||||
and 1
|
||||
4:
|
||||
ld e,a
|
||||
ld d,0
|
||||
ld h,b
|
||||
ld l,c
|
||||
ld sp,hl
|
||||
push de
|
||||
jp (ix)
|
33
mach/z80/libem/ior.s
Normal file
33
mach/z80/libem/ior.s
Normal file
|
@ -0,0 +1,33 @@
|
|||
.define .ior
|
||||
|
||||
! auxiliary size 'ior'
|
||||
! parameters:
|
||||
! de: size
|
||||
! stack: operands
|
||||
! stack: result (out)
|
||||
|
||||
|
||||
|
||||
.ior:
|
||||
pop ix
|
||||
ld h,d
|
||||
ld l,e
|
||||
add hl,sp
|
||||
ld b,h
|
||||
ld c,l
|
||||
ex de,hl
|
||||
add hl,de
|
||||
1: dec hl
|
||||
dec de
|
||||
ld a,(de)
|
||||
or (hl)
|
||||
ld (hl),a
|
||||
xor a
|
||||
sbc hl,bc
|
||||
jr z,2f
|
||||
add hl,bc
|
||||
jr 1b
|
||||
2: ld h,b
|
||||
ld l,c
|
||||
ld sp,hl
|
||||
jp (ix)
|
49
mach/z80/libem/lar.s
Normal file
49
mach/z80/libem/lar.s
Normal file
|
@ -0,0 +1,49 @@
|
|||
.define .lar
|
||||
! use .mli2
|
||||
|
||||
! 2-byte descriptor elements
|
||||
! any size array elements
|
||||
! parameters:
|
||||
! on stack
|
||||
! uses .mli2
|
||||
! no range checking
|
||||
! adapted from .aar and .los
|
||||
|
||||
|
||||
|
||||
.lar:
|
||||
pop hl
|
||||
pop ix
|
||||
ex (sp),hl
|
||||
ld c,(ix+0)
|
||||
ld b,(ix+1)
|
||||
xor a
|
||||
sbc hl,bc
|
||||
ld c,(ix+4)
|
||||
ld b,(ix+5)
|
||||
ex de,hl
|
||||
call .mli2
|
||||
pop ix
|
||||
pop de
|
||||
add hl,de ! address of array element
|
||||
add hl,bc
|
||||
dec hl ! pointer to highest byte of element
|
||||
srl b
|
||||
rr c
|
||||
jr nc,1f
|
||||
ld a,c ! skip check to save runtime
|
||||
or b
|
||||
jr nz,.trp.z ! size was odd but <> 1
|
||||
ld c,(hl)
|
||||
push bc
|
||||
jp (ix)
|
||||
1: ld d,(hl)
|
||||
dec hl
|
||||
ld e,(hl)
|
||||
dec hl
|
||||
push de
|
||||
dec bc
|
||||
ld a,b
|
||||
or c
|
||||
jr nz,1b
|
||||
jp (ix)
|
27
mach/z80/libem/lar2.s
Normal file
27
mach/z80/libem/lar2.s
Normal file
|
@ -0,0 +1,27 @@
|
|||
.define .lar2
|
||||
|
||||
! special case lar: element size = 2 (statically known)
|
||||
! parameters:
|
||||
! on stack
|
||||
! adapted from .aar2
|
||||
! execution time: 144 states
|
||||
|
||||
|
||||
|
||||
.lar2:
|
||||
pop ix
|
||||
pop hl
|
||||
ld c,(hl)
|
||||
inc hl
|
||||
ld b,(hl)
|
||||
pop hl
|
||||
xor a
|
||||
sbc hl,bc
|
||||
add hl,hl ! size*(index-lwb)
|
||||
pop de
|
||||
add hl,de ! + base
|
||||
ld e,(hl)
|
||||
inc hl
|
||||
ld d,(hl)
|
||||
push de
|
||||
jp (ix)
|
19
mach/z80/libem/laru.s
Normal file
19
mach/z80/libem/laru.s
Normal file
|
@ -0,0 +1,19 @@
|
|||
.define .laru
|
||||
|
||||
! LAR NOT DEFINED
|
||||
|
||||
.laru:
|
||||
pop ix
|
||||
pop hl
|
||||
xor a
|
||||
xor h
|
||||
jp nz,1f
|
||||
ld a,2
|
||||
xor l
|
||||
jp z,2f
|
||||
1:
|
||||
ld hl,EARRAY
|
||||
call .trp.z
|
||||
2:
|
||||
push ix
|
||||
jp .lar
|
31
mach/z80/libem/los.s
Normal file
31
mach/z80/libem/los.s
Normal file
|
@ -0,0 +1,31 @@
|
|||
.define .los
|
||||
|
||||
|
||||
|
||||
.los:
|
||||
pop ix ! save return address
|
||||
pop de ! number of bytes to transfer
|
||||
pop hl ! address of lowest byte
|
||||
add hl,de
|
||||
dec hl ! address of highest byte
|
||||
srl d ! divide de by 2
|
||||
rr e
|
||||
jr nc,1f ! see if de was odd
|
||||
ld a,e ! yes, then it must be 1
|
||||
or d
|
||||
jr nz,.trp.z ! no, error
|
||||
ld e,(hl) ! pack 1 byte into integer
|
||||
push de
|
||||
jp (ix) ! return
|
||||
1:
|
||||
ld b,(hl) ! get 2 bytes
|
||||
dec hl
|
||||
ld c,(hl)
|
||||
dec hl
|
||||
push bc ! put them on stack, most
|
||||
! significant byte first
|
||||
dec de
|
||||
ld a,d
|
||||
or e
|
||||
jr nz,1b ! done ?
|
||||
jp (ix) ! yes, return
|
29
mach/z80/libem/mli2.s
Normal file
29
mach/z80/libem/mli2.s
Normal file
|
@ -0,0 +1,29 @@
|
|||
.define .mli2
|
||||
|
||||
! 16 bit multiply
|
||||
! parameters:
|
||||
! bc: multiplicand
|
||||
! de: multiplier
|
||||
! hl: result (out)
|
||||
! multiplier (bc) is left unchanged
|
||||
! no detection of overflow
|
||||
|
||||
|
||||
|
||||
.mli2:
|
||||
ld hl,0
|
||||
ld a,16
|
||||
0:
|
||||
bit 7,d
|
||||
jr z,1f
|
||||
add hl,bc
|
||||
1:
|
||||
dec a
|
||||
jr z,2f
|
||||
ex de,hl
|
||||
add hl,hl
|
||||
ex de,hl
|
||||
add hl,hl
|
||||
jr 0b
|
||||
2:
|
||||
ret
|
75
mach/z80/libem/mli4.s
Normal file
75
mach/z80/libem/mli4.s
Normal file
|
@ -0,0 +1,75 @@
|
|||
.define .mli4
|
||||
|
||||
! 32-bit multiply routine for z80
|
||||
! parameters:
|
||||
! on stack
|
||||
|
||||
|
||||
|
||||
! register utilization:
|
||||
! ix: least significant 2 bytes of result
|
||||
! hl: most significant 2 bytes of result
|
||||
! bc: least significant 2 bytes of multiplicand
|
||||
! de: most significant 2 bytes of multiplicand
|
||||
! iy: 2 bytes of multiplier (first most significant,
|
||||
! later least significant)
|
||||
! a: bit count
|
||||
.mli4:
|
||||
!initialization
|
||||
pop hl ! return address
|
||||
pop de
|
||||
ld (.mplier+2),de! least significant bytes of
|
||||
! multiplier
|
||||
pop de
|
||||
ld (.mplier),de ! most sign. bytes
|
||||
pop de ! least significant bytes of
|
||||
! multiplicand
|
||||
pop bc ! most sign. bytes
|
||||
push hl ! return address
|
||||
push iy ! LB
|
||||
ld ix,0
|
||||
xor a
|
||||
ld h,a ! clear result
|
||||
ld l,a
|
||||
ld (.flag),a ! indicate that this is
|
||||
! first pass of main loop
|
||||
ld iy,(.mplier)
|
||||
! main loop, done twice, once for each part (2 bytes)
|
||||
! of multiplier
|
||||
1:
|
||||
ld a,16
|
||||
! sub-loop, done 16 times
|
||||
2:
|
||||
add iy,iy ! shift left multiplier
|
||||
jr nc,3f ! skip if most sign. bit is 0
|
||||
add ix,de ! 32-bit add
|
||||
adc hl,bc
|
||||
3:
|
||||
dec a
|
||||
jr z,4f ! done with this part of multiplier
|
||||
add ix,ix ! 32-bit shift left
|
||||
adc hl,hl
|
||||
jr 2b
|
||||
4:
|
||||
! see if we have just processed the first part
|
||||
! of the multiplier (flag = 0) or the second
|
||||
! part (flag = 1)
|
||||
ld a,(.flag)
|
||||
or a
|
||||
jr nz,5f
|
||||
inc a ! a := 1
|
||||
ld (.flag),a ! set flag
|
||||
ld iy,(.mplier+2)! least significant 2 bytes now in iy
|
||||
add ix,ix ! 32-bit shift left
|
||||
adc hl,hl
|
||||
jr 1b
|
||||
5:
|
||||
! clean up
|
||||
pop iy ! restore LB
|
||||
ex (sp),hl ! put most sign. 2 bytes of result
|
||||
! on stack! put return address in hl
|
||||
push ix ! least sign. 2 bytes of result
|
||||
jp (hl) ! return
|
||||
.data
|
||||
.flag: .byte 0
|
||||
.mplier: .space 4
|
40
mach/z80/libem/nop.s
Normal file
40
mach/z80/libem/nop.s
Normal file
|
@ -0,0 +1,40 @@
|
|||
|
||||
|
||||
.define .nop
|
||||
|
||||
! NOP
|
||||
! changed into output routine to print linenumber
|
||||
! in octal (6 digits)
|
||||
|
||||
.nop:
|
||||
push iy
|
||||
ld iy,1f+5
|
||||
ld hl,(hol0)
|
||||
call outdec
|
||||
ld iy,1f+18
|
||||
ld hl,0
|
||||
add hl,sp
|
||||
call octnr
|
||||
ld de,1f
|
||||
call pstrng
|
||||
pop iy
|
||||
ret
|
||||
1: .asciz 'test xxxxx 0xxxxxx\r\n'
|
||||
|
||||
octnr:
|
||||
ld b,6
|
||||
1: ld a,7
|
||||
and l
|
||||
add a,'0'
|
||||
dec iy
|
||||
ld (iy+0),a
|
||||
srl h
|
||||
rr l
|
||||
srl h
|
||||
rr l
|
||||
srl h
|
||||
rr l
|
||||
djnz 1b
|
||||
ret
|
||||
|
||||
|
53
mach/z80/libem/outdec.s
Normal file
53
mach/z80/libem/outdec.s
Normal file
|
@ -0,0 +1,53 @@
|
|||
.define outdec
|
||||
! output contents of HL as a sequence
|
||||
! of decimal digits
|
||||
outdec:
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
push af
|
||||
ld de,table
|
||||
ld b,4
|
||||
1: call convert
|
||||
or 0x30
|
||||
ld (iy+0),a
|
||||
inc iy
|
||||
djnz 1b
|
||||
ld a,l
|
||||
or 0x30
|
||||
ld (iy+0),a
|
||||
pop af
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
! convert returns in a a count
|
||||
! hl is decremented count times by (de)
|
||||
! as a usefull side effect de is incremented
|
||||
! by 2
|
||||
convert:
|
||||
push bc
|
||||
ld b,h
|
||||
ld c,l
|
||||
ex de,hl
|
||||
ld e,(hl)
|
||||
inc hl
|
||||
ld d,(hl)
|
||||
inc hl
|
||||
push hl ! save pointer to new value
|
||||
ld h,b
|
||||
ld l,c
|
||||
xor a
|
||||
1: inc a
|
||||
sbc hl,de
|
||||
jr nc,1b
|
||||
add hl,de
|
||||
dec a
|
||||
pop de
|
||||
pop bc
|
||||
ret
|
||||
table:
|
||||
.short 10000
|
||||
.short 1000
|
||||
.short 100
|
||||
.short 10
|
14
mach/z80/libem/pstrng.s
Normal file
14
mach/z80/libem/pstrng.s
Normal file
|
@ -0,0 +1,14 @@
|
|||
.define pstrng
|
||||
! print a string of characters to the console
|
||||
! entry: DE points to string
|
||||
! string terminator is 0x00
|
||||
! exit: DE points to string terminator
|
||||
pstrng: push af
|
||||
1: ld a,(de)
|
||||
or a
|
||||
jr z,2f
|
||||
call putchr
|
||||
inc de
|
||||
jr 1b
|
||||
2: pop af
|
||||
ret
|
31
mach/z80/libem/rck.s
Normal file
31
mach/z80/libem/rck.s
Normal file
|
@ -0,0 +1,31 @@
|
|||
.define .rck
|
||||
.rck:
|
||||
pop bc
|
||||
pop ix
|
||||
3: pop hl
|
||||
push hl
|
||||
ld e,(ix)
|
||||
ld d,(ix+1)
|
||||
ld a,h
|
||||
xor d ! check sign bit to catch overflow with subtract
|
||||
jp m,1f
|
||||
sbc hl,de
|
||||
jr 2f
|
||||
1: xor d ! now a equals (original) h again
|
||||
2: call m,e.rck
|
||||
pop de
|
||||
push de
|
||||
ld l,(ix+2)
|
||||
ld h,(ix+3)
|
||||
ld a,h
|
||||
xor d ! check sign bit to catch overflow with subtract
|
||||
jp m,1f
|
||||
sbc hl,de
|
||||
jr 2f
|
||||
1: xor d ! now a equals (original) h again
|
||||
2: call m,e.rck
|
||||
push bc
|
||||
pop ix
|
||||
jp (ix)
|
||||
|
||||
|
56
mach/z80/libem/rmi2.s
Normal file
56
mach/z80/libem/rmi2.s
Normal file
|
@ -0,0 +1,56 @@
|
|||
.define .rmi2
|
||||
|
||||
! 16-bit signed remainder
|
||||
! parameters:
|
||||
! bc: divisor
|
||||
! de: dividend
|
||||
! de: result (out)
|
||||
! no check on overflow
|
||||
|
||||
|
||||
|
||||
.rmi2:
|
||||
xor a
|
||||
ld h,a
|
||||
ld l,a
|
||||
sbc hl,bc
|
||||
jp m,1f
|
||||
ld b,h
|
||||
ld c,l
|
||||
1:
|
||||
or a
|
||||
ld hl,0
|
||||
sbc hl,de
|
||||
jp m,1f
|
||||
ex de,hl
|
||||
cpl
|
||||
1:
|
||||
push af
|
||||
ld hl,0
|
||||
ld a,16
|
||||
0:
|
||||
add hl,hl
|
||||
ex de,hl
|
||||
add hl,hl
|
||||
ex de,hl
|
||||
jr nc,1f
|
||||
inc hl
|
||||
or a
|
||||
1:
|
||||
sbc hl,bc
|
||||
inc de
|
||||
jp p,2f
|
||||
add hl,bc
|
||||
dec de
|
||||
2:
|
||||
dec a
|
||||
jr nz,0b
|
||||
ex de,hl
|
||||
pop af
|
||||
or a
|
||||
jr z,1f
|
||||
ld hl,0
|
||||
sbc hl,de
|
||||
ex de,hl
|
||||
1:
|
||||
ret
|
48
mach/z80/libem/sar.s
Normal file
48
mach/z80/libem/sar.s
Normal file
|
@ -0,0 +1,48 @@
|
|||
.define .sar
|
||||
! use .mli2
|
||||
! use .trp.z
|
||||
|
||||
! 2-byte descriptors
|
||||
! any size array elements
|
||||
! parameters:
|
||||
! on stack
|
||||
! uses .mli2
|
||||
! adapted from .aar and .sts
|
||||
|
||||
|
||||
|
||||
.sar:
|
||||
pop hl
|
||||
pop ix
|
||||
ex (sp),hl
|
||||
ld c,(ix+0)
|
||||
ld b,(ix+1)
|
||||
xor a
|
||||
sbc hl,bc
|
||||
ld c,(ix+4)
|
||||
ld b,(ix+5)
|
||||
ex de,hl
|
||||
call .mli2
|
||||
pop ix
|
||||
pop de
|
||||
add hl,de
|
||||
srl b ! bc contains #bytes to transfer
|
||||
rr c ! divide bc by 2
|
||||
jr nc,1f
|
||||
ld a,c
|
||||
or b
|
||||
jr nz,.trp.z
|
||||
pop bc
|
||||
ld (hl),c
|
||||
jp (ix)
|
||||
1:
|
||||
pop de
|
||||
ld (hl),e
|
||||
inc hl
|
||||
ld (hl),d
|
||||
inc hl
|
||||
dec bc
|
||||
ld a,b
|
||||
or c
|
||||
jr nz,1b
|
||||
jp (ix)
|
27
mach/z80/libem/sar2.s
Normal file
27
mach/z80/libem/sar2.s
Normal file
|
@ -0,0 +1,27 @@
|
|||
.define .sar2
|
||||
|
||||
! special case sar: element size = 2 (statically known)
|
||||
! parameters:
|
||||
! on stack
|
||||
! adapted from .aar2
|
||||
! execution time: 143 states
|
||||
|
||||
|
||||
|
||||
.sar2:
|
||||
pop ix
|
||||
pop hl
|
||||
ld c,(hl)
|
||||
inc hl
|
||||
ld b,(hl)
|
||||
pop hl
|
||||
xor a
|
||||
sbc hl,bc
|
||||
add hl,hl
|
||||
pop de
|
||||
add hl,de
|
||||
pop de
|
||||
ld (hl),e
|
||||
inc hl
|
||||
ld (hl),d
|
||||
jp (ix)
|
19
mach/z80/libem/saru.s
Normal file
19
mach/z80/libem/saru.s
Normal file
|
@ -0,0 +1,19 @@
|
|||
.define .saru
|
||||
|
||||
! SAR NOT DEFINED
|
||||
|
||||
.saru:
|
||||
pop ix
|
||||
pop hl
|
||||
xor a
|
||||
xor h
|
||||
jp nz,1f
|
||||
ld a,2
|
||||
xor l
|
||||
jp z,2f
|
||||
1:
|
||||
ld hl,EARRAY
|
||||
call .trp.z
|
||||
2:
|
||||
push ix
|
||||
jp .sar
|
20
mach/z80/libem/sdf.s
Normal file
20
mach/z80/libem/sdf.s
Normal file
|
@ -0,0 +1,20 @@
|
|||
.define .sdf
|
||||
|
||||
! store double offsetted
|
||||
|
||||
.sdf:
|
||||
pop bc
|
||||
push bc !test
|
||||
pop ix ! return address
|
||||
pop hl ! address
|
||||
add hl,de
|
||||
pop bc
|
||||
ld (hl),c
|
||||
inc hl
|
||||
ld (hl),b
|
||||
inc hl
|
||||
pop bc
|
||||
ld (hl),c
|
||||
inc hl
|
||||
ld (hl),b
|
||||
jp (ix) ! return
|
26
mach/z80/libem/sdl.s
Normal file
26
mach/z80/libem/sdl.s
Normal file
|
@ -0,0 +1,26 @@
|
|||
.define .sdl
|
||||
|
||||
! store double local at any offset
|
||||
! parameters:
|
||||
! hl: offset
|
||||
! stack: operand (4 bytes)
|
||||
|
||||
|
||||
|
||||
.sdl:
|
||||
pop ix ! return address
|
||||
push iy ! bc := LB
|
||||
pop bc
|
||||
add hl,bc ! pointer to lowest byte
|
||||
! of local
|
||||
pop bc ! low 2 bytes of source
|
||||
ld (hl),c
|
||||
inc hl
|
||||
ld (hl),b
|
||||
inc hl
|
||||
pop bc ! high 2 bytes of source
|
||||
ld (hl),c
|
||||
inc hl
|
||||
ld (hl),b
|
||||
jp (ix) ! return
|
||||
|
45
mach/z80/libem/set.s
Normal file
45
mach/z80/libem/set.s
Normal file
|
@ -0,0 +1,45 @@
|
|||
.define .set
|
||||
! use .unimpld
|
||||
|
||||
! any size sets
|
||||
! parameters:
|
||||
! hl: size
|
||||
! stack: bitnumber
|
||||
! stack: result (out)
|
||||
|
||||
|
||||
|
||||
.set:
|
||||
pop ix ! return address
|
||||
pop de ! bit number
|
||||
ld b,h
|
||||
ld c,l
|
||||
xor a
|
||||
0: push af
|
||||
inc sp
|
||||
dec c
|
||||
jr nz,0b
|
||||
dec b
|
||||
jp p,0b
|
||||
ex de,hl
|
||||
ld a,l
|
||||
sra h
|
||||
jp m,.unimpld
|
||||
rr l
|
||||
srl h
|
||||
rr l
|
||||
srl h
|
||||
rr l
|
||||
push hl
|
||||
or a
|
||||
sbc hl,de
|
||||
pop hl
|
||||
jp p,.unimpld
|
||||
add hl,sp
|
||||
ld (hl),1
|
||||
and 7
|
||||
jr 1f
|
||||
0: sla (hl)
|
||||
dec a
|
||||
1: jr nz,0b
|
||||
jp (ix)
|
22
mach/z80/libem/str.s
Normal file
22
mach/z80/libem/str.s
Normal file
|
@ -0,0 +1,22 @@
|
|||
.define .strhp
|
||||
|
||||
.strhp:
|
||||
pop ix
|
||||
pop hl
|
||||
push hl
|
||||
or a
|
||||
sbc hl,sp
|
||||
jp m,1f
|
||||
pop hl
|
||||
push hl
|
||||
ld a,l
|
||||
rra
|
||||
jp c,1f
|
||||
pop hl
|
||||
ld (.reghp),hl
|
||||
jp (ix)
|
||||
1:
|
||||
pop hl
|
||||
ld hl,EHEAP
|
||||
call .trp.z
|
||||
jp (ix)
|
37
mach/z80/libem/sts.s
Normal file
37
mach/z80/libem/sts.s
Normal file
|
@ -0,0 +1,37 @@
|
|||
.define .sts
|
||||
! use trp.z
|
||||
|
||||
! object size given by 2-byte integer on
|
||||
! top of stack.
|
||||
! parameters:
|
||||
! on stack
|
||||
! checks if #bytes is even or 1,
|
||||
! else traps
|
||||
|
||||
|
||||
|
||||
.sts:
|
||||
pop ix ! save return address
|
||||
pop de ! # bytes to transfer
|
||||
pop hl ! destination address
|
||||
srl d ! divide de by 2
|
||||
rr e
|
||||
jr nc,1f ! see if it was odd
|
||||
ld a,e ! yes, must be 1
|
||||
or d
|
||||
jr nz,.trp.z ! no, error
|
||||
pop de ! transfer 1 byte,
|
||||
! padded with zeroes
|
||||
ld (hl),e
|
||||
jp (ix)
|
||||
1:
|
||||
pop bc
|
||||
ld (hl), c
|
||||
inc hl
|
||||
ld (hl),b
|
||||
inc hl
|
||||
dec de
|
||||
ld a,e
|
||||
or d
|
||||
jr nz,1b
|
||||
jp (ix)
|
15
mach/z80/libem/tail.s
Normal file
15
mach/z80/libem/tail.s
Normal file
|
@ -0,0 +1,15 @@
|
|||
.define endtext,enddata,endbss
|
||||
.define _end,_etext,_edata
|
||||
|
||||
.text
|
||||
endtext:
|
||||
_etext:
|
||||
.align 2
|
||||
.data
|
||||
enddata:
|
||||
_edata:
|
||||
.align 2
|
||||
.bss
|
||||
_end:
|
||||
endbss:
|
||||
.align 2
|
46
mach/z80/libem/trp.s
Normal file
46
mach/z80/libem/trp.s
Normal file
|
@ -0,0 +1,46 @@
|
|||
.define .trp.z
|
||||
|
||||
! changed into output routine to print errornumber
|
||||
|
||||
.trp.z:
|
||||
! exx
|
||||
pop bc
|
||||
pop hl !error number
|
||||
push hl
|
||||
ld de,15
|
||||
sbc hl,de
|
||||
jp p,1f ! error no >= 16?
|
||||
pop hl
|
||||
push hl ! save error no on stack
|
||||
push bc
|
||||
push ix
|
||||
push hl ! test bit "error no" of ignmask
|
||||
ld hl,(ignmask)
|
||||
ex (sp),hl
|
||||
push hl
|
||||
ld hl,2
|
||||
call .inn
|
||||
pop hl
|
||||
pop ix
|
||||
pop bc
|
||||
ld a,h
|
||||
or l
|
||||
jr z,2f ! if bit <> 0 error
|
||||
1:
|
||||
pop hl
|
||||
push iy
|
||||
push de
|
||||
ld iy,1f+6
|
||||
call outdec
|
||||
ld de,1f
|
||||
call pstrng
|
||||
pop de
|
||||
pop iy
|
||||
jp 0x20
|
||||
2:
|
||||
pop hl
|
||||
push bc
|
||||
! exx
|
||||
ret
|
||||
1: .asciz 'error xxxxx\r\n'
|
||||
|
25
mach/z80/libem/unim.s
Normal file
25
mach/z80/libem/unim.s
Normal file
|
@ -0,0 +1,25 @@
|
|||
.define unimpld, e.mon, e.rck, .trp.z, .unimpld
|
||||
|
||||
.unimpld:
|
||||
unimpld: ! used in dispatch table to
|
||||
! catch unimplemented instructions
|
||||
ld hl,EILLINS
|
||||
9: push hl
|
||||
call .trp.z
|
||||
jp 20
|
||||
|
||||
e.mon:
|
||||
ld hl,EMON
|
||||
jr 9b
|
||||
e.rck:
|
||||
push af
|
||||
ld a,(ignmask)
|
||||
bit 1,a
|
||||
jr nz,8f
|
||||
ld hl,ERANGE
|
||||
jr 9b
|
||||
8:
|
||||
pop af
|
||||
ret
|
||||
|
||||
|
33
mach/z80/libem/xor.s
Normal file
33
mach/z80/libem/xor.s
Normal file
|
@ -0,0 +1,33 @@
|
|||
.define .xor
|
||||
|
||||
! auxiliary size 'xor'
|
||||
! parameters:
|
||||
! de: size
|
||||
! stack: operands
|
||||
! stack: result (out)
|
||||
|
||||
|
||||
|
||||
.xor:
|
||||
pop ix
|
||||
ld h,d
|
||||
ld l,e
|
||||
add hl,sp
|
||||
ld b,h
|
||||
ld c,l
|
||||
ex de,hl
|
||||
add hl,de
|
||||
1: dec hl
|
||||
dec de
|
||||
ld a,(de)
|
||||
xor (hl)
|
||||
ld (hl),a
|
||||
xor a
|
||||
sbc hl,bc
|
||||
jr z,2f
|
||||
add hl,bc
|
||||
jr 1b
|
||||
2: ld h,b
|
||||
ld l,c
|
||||
ld sp,hl
|
||||
jp (ix)
|
Loading…
Reference in a new issue