forked from MirrorRepos/RomWBW
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2583 lines
31 KiB
2583 lines
31 KiB
begin.asm
|
|
;Copyright (C) 1981,1982,1983 by Manx Software Systems
|
|
; :ts=8
|
|
BDOS equ 5
|
|
extrn Croot_
|
|
extrn _Uorg_, _Uend_
|
|
;
|
|
public lnprm, lntmp, lnsec
|
|
;
|
|
; The 3 "bss" statements below must remain in EXACTLY the same order,
|
|
; with no intervening statements!
|
|
;
|
|
bss lnprm,4
|
|
bss lntmp,4
|
|
bss lnsec,4
|
|
;
|
|
global sbot,2
|
|
global errno_,2
|
|
global _mbot_,2
|
|
dseg
|
|
public Sysvec_
|
|
Sysvec_: dw 0
|
|
dw 0
|
|
dw 0
|
|
dw 0
|
|
public $MEMRY
|
|
$MEMRY: dw 0ffffh
|
|
;
|
|
fcb: db 0,'???????????',0,0,0,0
|
|
ds 16
|
|
cseg
|
|
public .begin
|
|
public _exit_
|
|
.begin:
|
|
lxi h,_Uorg_
|
|
lxi b,_Uend_-_Uorg_
|
|
mvi e,0
|
|
clrbss:
|
|
mov m,e
|
|
inx h
|
|
dcx b
|
|
mov a,c
|
|
ora b
|
|
jnz clrbss
|
|
;
|
|
LHLD BDOS+1
|
|
SPHL
|
|
lxi d,-2048
|
|
dad d ;set heap limit at 2K below stack
|
|
shld sbot
|
|
lhld $MEMRY
|
|
shld _mbot_
|
|
CALL Croot_
|
|
_exit_:
|
|
mvi c,17 ;search for first (used to flush deblock buffer)
|
|
lxi d,fcb
|
|
call BDOS
|
|
lxi b,0
|
|
call BDOS
|
|
JMP _exit_
|
|
;
|
|
end .begin
|
|
mbegin.asm
|
|
;Copyright (C) 1981,1982,1983 by Manx Software Systems
|
|
; :ts=8
|
|
BDOS equ 5
|
|
extrn Croot_
|
|
dseg
|
|
;
|
|
; The 3 "ds 4" statements below must remain in EXACTLY the same order,
|
|
; with no intervening statements!
|
|
;
|
|
public lnprm, lntmp, lnsec
|
|
lnprm: ds 4
|
|
lntmp: ds 4
|
|
lnsec: ds 4
|
|
;
|
|
public Sysvec_
|
|
Sysvec_: dw 0
|
|
dw 0
|
|
dw 0
|
|
dw 0
|
|
public $MEMRY
|
|
$MEMRY: dw -1
|
|
public sbot
|
|
sbot: dw 0
|
|
public errno_
|
|
errno_: dw 0
|
|
;
|
|
fcb: db 0,'???????????',0,0,0,0
|
|
ds 16
|
|
cseg
|
|
public .begin
|
|
public _exit_
|
|
.begin:
|
|
LHLD BDOS+1
|
|
SPHL
|
|
lxi d,-2048
|
|
dad d ;set heap limit at 2K below stack
|
|
shld sbot
|
|
CALL Croot_
|
|
_exit_:
|
|
mvi c,17 ;search for first (used to flush deblock buffer)
|
|
lxi d,fcb
|
|
call BDOS
|
|
lxi b,0
|
|
call BDOS
|
|
JMP _exit_
|
|
end .begin
|
|
rom.asm
|
|
;Copyright (C) 1983 by Manx Software Systems
|
|
; :ts=8
|
|
;
|
|
; stksize should be set according to your program's needs
|
|
;
|
|
stksize equ 1024
|
|
bss stack,stksize
|
|
|
|
extrn main_
|
|
extrn _Corg_, _Cend_
|
|
extrn _Dorg_, _Dend_
|
|
extrn _Uorg_, _Uend_
|
|
;
|
|
; The 3 "bss" statements below must remain in EXACTLY the same order,
|
|
; with no intervening statements!
|
|
;
|
|
public lnprm, lntmp, lnsec
|
|
bss lnprm,4
|
|
bss lntmp,4
|
|
bss lnsec,4
|
|
;
|
|
global errno_,2
|
|
dseg
|
|
public Sysvec_
|
|
Sysvec_: dw 0
|
|
dw 0
|
|
dw 0
|
|
dw 0
|
|
public $MEMRY
|
|
$MEMRY: dw 0ffffh
|
|
cseg
|
|
public .begin
|
|
.begin:
|
|
di
|
|
lxi sp,stack+stksize
|
|
;
|
|
; The loop below moves the initialized data from ROM to RAM.
|
|
; If your program has no initialized data, or the initialized
|
|
; data isn't modified, then delete this loop.
|
|
;
|
|
lxi h,_Cend_
|
|
lxi d,_Dorg_
|
|
lxi b,_Dend_-_Dorg_
|
|
mov a,h
|
|
cmp d
|
|
jnz movedata
|
|
mov a,l
|
|
cmp e
|
|
jz movedone
|
|
movedata:
|
|
; If your processor is a Z80, then remove the comment from the
|
|
; next line and comment out the next 8 lines.
|
|
; db 237,176 ;ldir
|
|
mov a,m
|
|
stax d
|
|
inx h
|
|
inx d
|
|
dcx b
|
|
mov a,c
|
|
ora b
|
|
jnz movedata
|
|
movedone:
|
|
;
|
|
lxi h,_Uorg_
|
|
lxi b,_Uend_-_Uorg_
|
|
mvi e,0
|
|
clrbss:
|
|
mov m,e
|
|
inx h
|
|
dcx b
|
|
mov a,c
|
|
ora b
|
|
jnz clrbss
|
|
;
|
|
ei
|
|
;no argc,argv in ROM system
|
|
jmp main_ ;main shouldn't return in ROM based system
|
|
end .begin
|
|
csave.asm
|
|
;Copyright (C) 1981,1982,1984 by Manx Software Systems
|
|
; :ts=8
|
|
extrn .begin
|
|
public .chl
|
|
.chl: PCHL
|
|
;
|
|
public zsave,zret
|
|
zsave: POP H
|
|
PUSH B
|
|
MOV B,H
|
|
MOV C,L
|
|
LXI H,0
|
|
DAD SP
|
|
XCHG
|
|
DAD SP
|
|
SPHL
|
|
PUSH D
|
|
DB 221,229,253,229 ;push ix ; push iy
|
|
mov h,b
|
|
mov l,c
|
|
call .chl
|
|
;
|
|
zret:
|
|
DB 253,225,221,225 ; pop iy ; pop ix
|
|
cret:
|
|
XCHG
|
|
POP H
|
|
SPHL
|
|
POP B
|
|
XCHG
|
|
MOV A,H
|
|
ORA L
|
|
RET
|
|
;
|
|
public csave,cret
|
|
csave: POP H
|
|
PUSH B
|
|
MOV B,H
|
|
MOV C,L
|
|
LXI H,0
|
|
DAD SP
|
|
XCHG
|
|
DAD SP
|
|
SPHL
|
|
PUSH D
|
|
lxi h,cret
|
|
push h
|
|
mov h,b
|
|
mov l,c
|
|
pchl
|
|
;
|
|
; move - move BC bytes from (HL) to (DE), used for struct assignment
|
|
;
|
|
public .move
|
|
.move:
|
|
mov a,m
|
|
stax d
|
|
inx h
|
|
inx d
|
|
dcx b
|
|
mov a,b
|
|
ora c
|
|
jnz .move
|
|
ret
|
|
;
|
|
public .ARG1,.ARG2,.ARG3,.asave
|
|
;
|
|
.asave: ;support for assembly routines which must save IX and IY
|
|
pop d ;save return address
|
|
lxi h,2 ;compute address of arguments
|
|
dad sp
|
|
xra a
|
|
adi 3
|
|
jpe nopush
|
|
DB 221,229,253,229 ;push ix ; push iy
|
|
nopush:
|
|
PUSH B
|
|
push d ;put return addr back
|
|
lxi d,.ARG1
|
|
mvi b,6
|
|
cpyloop: ;copy args to known place
|
|
mov a,m
|
|
stax d
|
|
inx h
|
|
inx d
|
|
dcr b
|
|
jnz cpyloop
|
|
lxi h,asmret
|
|
xthl
|
|
pchl
|
|
;
|
|
asmret:
|
|
POP B
|
|
xra a
|
|
adi 3
|
|
jpe nopop
|
|
DB 253,225,221,225 ; pop iy ; pop ix
|
|
nopop:
|
|
mov a,h
|
|
ora l
|
|
RET
|
|
;
|
|
dseg
|
|
.ARG1: ds 2
|
|
.ARG2: ds 2
|
|
.ARG3: ds 2
|
|
end
|
|
fmtcvt.asm
|
|
; Copyright (C) 1983 by Manx Software Systems
|
|
; :ts=8
|
|
dseg
|
|
string: ds 2
|
|
size: dw 0
|
|
number: ds 4
|
|
cseg
|
|
public fmtcvt_
|
|
fmtcvt_: ;char *fmtcvt(ptr, base, buffer, size)
|
|
push b
|
|
lxi h,0
|
|
shld number
|
|
shld number+2
|
|
lxi h,10
|
|
dad sp
|
|
mov a,m
|
|
sta size
|
|
mov b,a ;save size for later
|
|
dcx h
|
|
mov d,m
|
|
dcx h
|
|
mov e,m
|
|
dcx h
|
|
xchg
|
|
mvi m,0 ;null terminate string
|
|
shld string
|
|
xchg
|
|
dcx h
|
|
mov c,m ;C = base
|
|
dcx h
|
|
mov d,m
|
|
dcx h
|
|
mov e,m
|
|
lxi h,number
|
|
cpnum:
|
|
ldax d
|
|
mov m,a
|
|
inx d
|
|
inx h
|
|
dcr b
|
|
jnz cpnum
|
|
|
|
mov a,c
|
|
ora a
|
|
jp unsigned ; base < 0, means do signed conversion
|
|
cma
|
|
inr a
|
|
mov c,a ;C = base
|
|
lhld size
|
|
lxi d,number-1
|
|
dad d
|
|
mov a,m
|
|
ora a
|
|
push psw
|
|
jp top
|
|
;number is negative, so make it positive
|
|
;note: carry is already cleared by 'ora' above
|
|
lda size
|
|
mov b,a
|
|
lxi h,number
|
|
ngloop:
|
|
mvi a,0
|
|
sbb m
|
|
mov m,a
|
|
inx h
|
|
dcr b
|
|
jnz ngloop
|
|
jmp top
|
|
unsigned:
|
|
push psw
|
|
top:
|
|
lxi h,number+3
|
|
mvi d,0
|
|
mvi a,4
|
|
outer:
|
|
push psw
|
|
mov e,m
|
|
xchg
|
|
mvi b,8
|
|
inner:
|
|
dad h
|
|
mov a,h
|
|
sub c
|
|
jc zero
|
|
mov h,a
|
|
inr l
|
|
zero:
|
|
dcr b
|
|
jnz inner
|
|
xchg
|
|
mov m,e
|
|
dcx h
|
|
pop psw
|
|
dcr a
|
|
jnz outer
|
|
;
|
|
mov e,d
|
|
mvi d,0
|
|
lxi h,digits
|
|
dad d
|
|
mov a,m
|
|
lhld string
|
|
dcx h
|
|
shld string
|
|
mov m,a
|
|
;
|
|
lxi h,number
|
|
mvi b,4
|
|
xra a
|
|
zcheck:
|
|
cmp m
|
|
jnz top
|
|
inx h
|
|
dcr b
|
|
jnz zcheck
|
|
|
|
lhld string
|
|
pop psw
|
|
jp notneg
|
|
dcx h
|
|
mvi m,'-'
|
|
notneg:
|
|
pop b
|
|
ret
|
|
;
|
|
digits: db '0123456789abcdef'
|
|
end
|
|
blkio.asm
|
|
; Copyright (C) 1982, 1983 by Manx Software Systems
|
|
; :ts=8
|
|
BDOS equ 5
|
|
extrn errno_
|
|
extrn .asave,.ARG1,.ARG2,.ARG3
|
|
public blkrd_
|
|
blkrd_:
|
|
call .asave
|
|
mvi c,33 ;set function to read sequential
|
|
jmp rdwrt
|
|
;
|
|
public blkwr_
|
|
blkwr_:
|
|
call .asave
|
|
mvi c,34 ;set function to write sequential
|
|
rdwrt:
|
|
push b
|
|
ioloop:
|
|
lhld .ARG2
|
|
xchg
|
|
lxi h,128
|
|
dad d ;bump address to next sector
|
|
shld .ARG2
|
|
mvi c,26 ;set DMA address
|
|
call BDOS
|
|
pop b
|
|
push b
|
|
lhld .ARG1
|
|
xchg
|
|
call BDOS ;read or write sector
|
|
ora a
|
|
jnz ioerr
|
|
lhld .ARG1
|
|
lxi d,33
|
|
dad d
|
|
inr m
|
|
jnz nocarry
|
|
inx h
|
|
inr m
|
|
nocarry:
|
|
lhld .ARG3
|
|
dcx h
|
|
shld .ARG3
|
|
mov a,l
|
|
ora h
|
|
jnz ioloop
|
|
pop b ;pull function code from stack
|
|
ret ;all done, return number remaining
|
|
;
|
|
ioerr:
|
|
cpi 1
|
|
jz dontset
|
|
cpi 4
|
|
jz dontset
|
|
mov l,a
|
|
mvi h,0
|
|
shld errno_
|
|
dontset:
|
|
pop b ;pull function code from stack
|
|
lhld .ARG3
|
|
ret ;return number remaining
|
|
end
|
|
bdos.asm
|
|
;Copyright (C) 1981,1982 by Manx Software Systems
|
|
; :ts=8
|
|
BASE equ 0
|
|
BDOS equ 5
|
|
|
|
extrn .ARG1,.ARG2,.ARG3,.asave
|
|
;
|
|
public bdoshl_
|
|
bdoshl_:
|
|
call .asave
|
|
call combdos
|
|
xchg ;get back original hl value
|
|
ret
|
|
;
|
|
public bdos_,CPM_
|
|
bdos_:
|
|
CPM_:
|
|
call .asave
|
|
combdos:
|
|
lhld .ARG1
|
|
mov b,h
|
|
mov c,l
|
|
lhld .ARG2
|
|
xchg
|
|
CALL BDOS
|
|
xchg ;save for bdoshl call
|
|
mov l,a
|
|
xra a ;set zero flag
|
|
mov h,a
|
|
RET
|
|
end
|
|
bios.asm
|
|
;Copyright (C) 1981,1982 by Manx Software Systems
|
|
BASE equ 0
|
|
BDOS equ 5
|
|
|
|
extrn .ARG1,.ARG2,.ARG3,.asave
|
|
;
|
|
public bios_
|
|
bios_:
|
|
call .asave
|
|
call combios
|
|
mov l,a
|
|
mvi h,0
|
|
ret
|
|
;
|
|
public bioshl_
|
|
bioshl_:
|
|
call .asave
|
|
combios:
|
|
lhld .ARG1
|
|
xchg
|
|
lhld BASE+1
|
|
dcx h
|
|
dcx h
|
|
dcx h
|
|
dad d
|
|
dad d
|
|
dad d
|
|
xchg ;bios jump addr in DE
|
|
|
|
lhld .ARG2
|
|
mov b,h
|
|
mov c,l
|
|
lhld .ARG3
|
|
xchg ;now arg3 in DE, and bios jump in HL
|
|
pchl
|
|
end
|
|
fcbinit.asm
|
|
;Copyright (C) 1981,1982 by Manx Software Systems
|
|
; :ts=8
|
|
public fcbinit_
|
|
fcbinit_:
|
|
push b
|
|
lxi h,4
|
|
dad sp
|
|
mov c,m ; BC contains name
|
|
inx h
|
|
mov b,m
|
|
inx h
|
|
mov e,m ; DE contains fcb address
|
|
inx h
|
|
mov d,m
|
|
; clear name to blanks
|
|
mov l,e ;copy fcb address into HL
|
|
mov h,d
|
|
mvi m,0 ;clear drive #
|
|
inx h
|
|
mvi a,11 ;clear name and ext to blanks
|
|
clrlp:
|
|
mvi m,' '
|
|
inx h
|
|
dcr a
|
|
jnz clrlp
|
|
mvi a,4
|
|
zrlp:
|
|
mvi m,0
|
|
inx h
|
|
dcr a
|
|
jnz zrlp
|
|
xchg ; now HL contains fcb addr
|
|
;
|
|
mov a,c
|
|
ora b
|
|
jz badname
|
|
skipbl:
|
|
ldax b
|
|
cpi ' '
|
|
jz skip
|
|
cpi 9
|
|
jnz skipdone
|
|
skip: inx b
|
|
jmp skipbl
|
|
skipdone:
|
|
;
|
|
push b ;save address of name
|
|
mvi d,0 ;init user #
|
|
userloop:
|
|
ldax b
|
|
call isdig
|
|
jc userdone
|
|
sui '0'
|
|
mov e,a
|
|
mov a,d
|
|
add a ;*2
|
|
add a ;*4
|
|
add a ;*8
|
|
add d ;*9
|
|
add d ;*10
|
|
add e ;add in digit
|
|
mov d,a
|
|
inx b
|
|
jmp userloop
|
|
userdone:
|
|
cpi '/'
|
|
jnz nouser
|
|
inx b
|
|
pop psw ;throw away saved address
|
|
jmp setuser
|
|
nouser:
|
|
pop b ;restore original address
|
|
mvi d,255 ;set user # to default
|
|
setuser:
|
|
inx b
|
|
ldax b
|
|
cpi ':'
|
|
dcx b
|
|
mvi a,0
|
|
jnz nodrive
|
|
;
|
|
ldax b
|
|
ani 127
|
|
cpi 'A'
|
|
jc badname
|
|
cpi 'Z'+1
|
|
jnc lowerc
|
|
sui 'A'-1
|
|
jmp setdrive
|
|
;
|
|
lowerc:
|
|
cpi 'a'
|
|
jc badname
|
|
cpi 'z'+1
|
|
jnc badname
|
|
sui 'a'-1
|
|
setdrive:
|
|
mov m,a
|
|
inx b
|
|
inx b
|
|
nodrive:
|
|
inx h
|
|
; move name in mapping to upper case
|
|
mvi e,8
|
|
nameskp:
|
|
inr e
|
|
namelp:
|
|
ldax b
|
|
inx b
|
|
cpi '.'
|
|
jz namedn
|
|
ora a
|
|
jz alldone
|
|
dcr e
|
|
jz nameskp
|
|
call toupper
|
|
mov m,a
|
|
inx h
|
|
jmp namelp
|
|
;
|
|
namedn:
|
|
dcr e
|
|
mov a,e
|
|
add l
|
|
mov l,a
|
|
mov a,h
|
|
aci 0
|
|
mov h,a
|
|
; move extension mapping to upper case
|
|
mvi e,3
|
|
extlp:
|
|
ldax b
|
|
inx b
|
|
ora a
|
|
jz alldone
|
|
call toupper
|
|
mov m,a
|
|
inx h
|
|
dcr e
|
|
jnz extlp
|
|
;
|
|
alldone:
|
|
mvi h,0
|
|
mov l,d ;return user # prefix
|
|
mov a,d
|
|
ora a
|
|
pop b
|
|
ret
|
|
;
|
|
badname:
|
|
lxi h,-1
|
|
mov a,h
|
|
ora a
|
|
pop b
|
|
ret
|
|
;
|
|
toupper:
|
|
cpi '*'
|
|
jnz nostar
|
|
dcx b ;back up so we see star again
|
|
mvi a,'?' ;and map into question
|
|
ret
|
|
nostar:
|
|
cpi 'a'
|
|
rc
|
|
cpi 'z'+1
|
|
rnc
|
|
sui 'a'-'A'
|
|
ret
|
|
;
|
|
isdig:
|
|
cpi '0'
|
|
rc
|
|
cpi '9'+1
|
|
jnc notdig
|
|
ora a
|
|
ret
|
|
notdig:
|
|
stc
|
|
ret
|
|
;
|
|
end
|
|
sbrk.asm
|
|
;Copyright (C) 1981,1982 by Manx Software Systems
|
|
;Copyright (C) 1983,1984 by Manx Software Systems
|
|
; :ts=8
|
|
extrn $MEMRY, sbot
|
|
;
|
|
; sbrk(size): return address of current top & bump by size bytes
|
|
;
|
|
public sbrk_
|
|
sbrk_:
|
|
lxi h,2
|
|
dad sp
|
|
mov e,m ; get size to allocate
|
|
inx h
|
|
mov d,m
|
|
lhld $MEMRY
|
|
dad d
|
|
jc sbrk.ov
|
|
xchg ;save for compare
|
|
lhld sbot
|
|
mov a,l ;check for stack/heap overflow
|
|
sub e
|
|
mov a,h
|
|
sbb d
|
|
jc sbrk.ov
|
|
lhld $MEMRY ;get old value
|
|
xchg
|
|
shld $MEMRY ;new value is good so save it away
|
|
xchg ;return original value
|
|
mov a,h
|
|
ora l
|
|
ret
|
|
; no space left!!
|
|
sbrk.ov:
|
|
lxi h,-1
|
|
xra a
|
|
dcr a
|
|
ret
|
|
;
|
|
;
|
|
; rsvstk(size): reserve size bytes of stack space
|
|
;
|
|
public rsvstk_
|
|
rsvstk_:
|
|
lxi h,2
|
|
dad sp
|
|
mov a,l
|
|
sub m
|
|
mov e,a
|
|
mov a,h
|
|
inx h
|
|
sbb m
|
|
mov d,a
|
|
xchg
|
|
shld sbot
|
|
ret
|
|
end
|
|
loader.asm
|
|
; Copyright (C) 1984 by Manx Software Systems
|
|
; :ts=8
|
|
; The C routine execl() in exec.c knows that this function is
|
|
; less than 70 bytes long. If this code is changed, then execl
|
|
; must be changed also.
|
|
;
|
|
; This routine is copied into an automatic array and invoked
|
|
; there by execl(). The code is self relocating and must
|
|
; remain so.
|
|
;
|
|
bdos equ 5
|
|
defdma equ 80h
|
|
tpa equ 100h
|
|
public ldr__ ; ldr_(&fcb, ouser)
|
|
ldr__:
|
|
pop d ;throw away return
|
|
pop b ;set up fcb address
|
|
lxi d,9
|
|
dad d ;fix hl to point to head of loop
|
|
lxi d,tpa
|
|
;
|
|
; bc = fcb address
|
|
; de = tpa address
|
|
; hl = address of this routine
|
|
; old user # pushed onto stack
|
|
;
|
|
push h ;save loop address
|
|
push d
|
|
push b
|
|
mvi c,26
|
|
call bdos
|
|
pop d
|
|
push d
|
|
mvi c,20
|
|
call bdos
|
|
pop b ;restore fcb address
|
|
pop d ;and loading addr.
|
|
lxi h,80h
|
|
dad d ;bump loading addr
|
|
xchg
|
|
pop h
|
|
push h ;restore loop address
|
|
ora a ;check if eof
|
|
rz ;if not, return to top of loop
|
|
pop h ;throw away return addr
|
|
pop d ;get old user #
|
|
mvi c,32
|
|
call bdos ;restore user #
|
|
lxi d,defdma
|
|
mvi c,26
|
|
call bdos
|
|
lhld bdos+1
|
|
sphl
|
|
lxi h,0
|
|
push h ;set for proper return from program
|
|
jmp tpa
|
|
end
|
|
user.asm
|
|
; Copyright (C) 1983 by Manx Software Systems
|
|
; :ts=8
|
|
BDOS equ 5
|
|
extrn .asave,.ARG1,.ARG2,.ARG3
|
|
dseg
|
|
oldusr: db 0
|
|
cseg
|
|
public getusr_
|
|
getusr_:
|
|
call .asave
|
|
mvi c,32
|
|
mvi e,255
|
|
call BDOS ;get current user #
|
|
mov l,a
|
|
mvi h,0
|
|
ora a
|
|
ret
|
|
;
|
|
public setusr_
|
|
setusr_:
|
|
call .asave
|
|
mvi c,32
|
|
mvi e,255
|
|
call BDOS
|
|
sta oldusr
|
|
lda .ARG1
|
|
cpi 255
|
|
rz
|
|
mvi c,32
|
|
mov e,a
|
|
jmp BDOS ;set new user number
|
|
;
|
|
public rstusr_
|
|
rstusr_:
|
|
call .asave
|
|
mvi c,32
|
|
lda oldusr
|
|
mov e,a
|
|
jmp BDOS ;restore old user number
|
|
end
|
|
setjmp.asm
|
|
; Copyright (C) 1983 by Manx Software Systems
|
|
; :ts=8
|
|
public setjmp_
|
|
setjmp_:
|
|
lxi h,2
|
|
dad sp
|
|
mov e,m ;get address of jump buffer
|
|
inx h
|
|
mov d,m
|
|
dcx h ;get SP value back
|
|
xchg
|
|
mov m,e ;save SP value
|
|
inx h
|
|
mov m,d
|
|
inx h
|
|
pop d
|
|
push d
|
|
mov m,e ;save PC value
|
|
inx h
|
|
mov m,d
|
|
inx h
|
|
mov m,c ;save BC value
|
|
inx h
|
|
mov m,b
|
|
xra a
|
|
adi 3
|
|
jpe setdone
|
|
inx h
|
|
db 221,229 ;push ix
|
|
pop d
|
|
mov m,e ;save IX value
|
|
inx h
|
|
mov m,d
|
|
inx h
|
|
db 253,229 ;push iy
|
|
pop d
|
|
mov m,e ;save IY value
|
|
inx h
|
|
mov m,d
|
|
setdone:
|
|
lxi h,0
|
|
xra a ;set zero flag
|
|
ret
|
|
;
|
|
public longjmp_
|
|
longjmp_:
|
|
lxi h,2
|
|
dad sp
|
|
mov e,m ;get address of jump buffer
|
|
inx h
|
|
mov d,m
|
|
inx h
|
|
mov c,m ;get return value
|
|
inx h
|
|
mov b,m
|
|
xchg
|
|
mov e,m ;get SP value
|
|
inx h
|
|
mov d,m
|
|
inx h
|
|
xchg
|
|
sphl ;switch to original stack
|
|
xchg
|
|
mov e,m ;get PC value
|
|
inx h
|
|
mov d,m
|
|
inx h
|
|
push d ;save for return
|
|
push b ;save return value
|
|
mov c,m ;get BC value
|
|
inx h
|
|
mov b,m
|
|
xra a
|
|
adi 3
|
|
jpe longdone
|
|
inx h
|
|
mov e,m ;get IX value
|
|
inx h
|
|
mov d,m
|
|
inx h
|
|
push d
|
|
db 221,225 ;pop ix
|
|
mov e,m ;get IY value
|
|
inx h
|
|
mov d,m
|
|
push d
|
|
db 253,225 ;pop iy
|
|
longdone:
|
|
pop h
|
|
mov a,l
|
|
ora h
|
|
rnz
|
|
inx h ;force non-zero return
|
|
inr a ;set non-zero flag
|
|
ret
|
|
end
|
|
strcmp.asm
|
|
;Copyright (C) 1981,1982,1983 by Manx Software Systems
|
|
; :ts=8
|
|
public strcmp_
|
|
strcmp_:
|
|
lxi h,5
|
|
dad sp
|
|
push b
|
|
lxi b,32767
|
|
jmp same
|
|
;
|
|
public strncmp_
|
|
strncmp_:
|
|
lxi h,7
|
|
dad sp
|
|
push b
|
|
mov b,m
|
|
dcx h
|
|
mov c,m ;BC = len
|
|
dcx h
|
|
same:
|
|
mov d,m
|
|
dcx h
|
|
mov e,m ;DE = s2
|
|
dcx h
|
|
mov a,m
|
|
dcx h
|
|
mov l,m
|
|
mov h,a ;HL = s1
|
|
xchg ;now DE=s1, HL=s2
|
|
cmploop:
|
|
mov a,b ;while (len) {
|
|
ora c
|
|
jz done
|
|
ldax d ;if (*s1-*s2) break
|
|
sub m
|
|
jnz done
|
|
ldax d ;if (*s1 == 0) break
|
|
ora a
|
|
jz done
|
|
inx d ;++s1
|
|
inx h ;++s2
|
|
dcx b ;--len
|
|
jmp cmploop ;}
|
|
done:
|
|
pop b
|
|
mov l,a
|
|
sbb a
|
|
mov h,a
|
|
ora l
|
|
ret
|
|
end
|
|
strcpy.asm
|
|
;Copyright (C) 1981,1982,1983 by Manx Software Systems
|
|
; :ts=8
|
|
public strcpy_
|
|
strcpy_:
|
|
lxi h,5
|
|
dad sp
|
|
mov d,m
|
|
dcx h
|
|
mov e,m ;DE = s2
|
|
dcx h
|
|
mov a,m
|
|
dcx h
|
|
mov l,m
|
|
mov h,a ;HL = s1
|
|
push h ;save target for return
|
|
cpyloop:
|
|
ldax d ;while (*s1++ = *s2++) ;
|
|
mov m,a
|
|
ora a
|
|
jz done
|
|
inx d
|
|
inx h ;++s2
|
|
jmp cpyloop ;}
|
|
done:
|
|
pop h ;return target address
|
|
mov a,h
|
|
ora l
|
|
ret
|
|
end
|
|
strncpy.asm
|
|
;Copyright (C) 1981,1982,1983 by Manx Software Systems
|
|
; :ts=8
|
|
public strncpy_
|
|
strncpy_:
|
|
lxi h,7
|
|
dad sp
|
|
push b
|
|
mov b,m
|
|
dcx h
|
|
mov c,m ;BC = len
|
|
dcx h
|
|
mov d,m
|
|
dcx h
|
|
mov e,m ;DE = s2
|
|
dcx h
|
|
mov a,m
|
|
dcx h
|
|
mov l,m
|
|
mov h,a ;HL = s1
|
|
push h ;save target for return
|
|
cpyloop:
|
|
mov a,b ;while (len) {
|
|
ora c
|
|
jz done
|
|
ldax d ;if (*s1 = *s2) ++s1
|
|
mov m,a
|
|
ora a
|
|
jz padding
|
|
inx d
|
|
padding:
|
|
inx h ;++s2
|
|
dcx b ;--len
|
|
jmp cpyloop ;}
|
|
done:
|
|
pop h ;return target address
|
|
pop b
|
|
mov a,h
|
|
ora l
|
|
ret
|
|
end
|
|
strcat.asm
|
|
;Copyright (C) 1981,1982,1983 by Manx Software Systems
|
|
; :ts=8
|
|
public strcat_ ;strcat(s1,s2)
|
|
strcat_:
|
|
lxi h,5
|
|
dad sp
|
|
push b
|
|
lxi b,32767
|
|
jmp same
|
|
;
|
|
public strncat_ ;strncat(s1,s2,len)
|
|
strncat_:
|
|
lxi h,7
|
|
dad sp
|
|
push b
|
|
mov b,m
|
|
dcx h
|
|
mov c,m ;BC = len
|
|
dcx h
|
|
same:
|
|
mov d,m
|
|
dcx h
|
|
mov e,m ;DE = s2
|
|
dcx h
|
|
mov a,m
|
|
dcx h
|
|
mov l,m
|
|
mov h,a ;HL = s1
|
|
push h ;save destination for return value
|
|
xra a
|
|
eloop:
|
|
cmp m ;while (*s1) ++s1;
|
|
jz cpyloop
|
|
inx h
|
|
jmp eloop ;}
|
|
cpyloop: ;while (len) {
|
|
mov a,b
|
|
ora c
|
|
jz done
|
|
ldax d ;if ((*s1 = *s2) == 0) break
|
|
mov m,a
|
|
ora a
|
|
jz done
|
|
inx d ;++s1
|
|
inx h ;++s2
|
|
dcx b ;--len
|
|
jmp cpyloop ;}
|
|
done:
|
|
mov m,a ;guarantee null termination
|
|
pop h
|
|
pop b
|
|
mov a,h
|
|
ora l
|
|
ret
|
|
end
|
|
index.asm
|
|
;Copyright (C) 1981,1982,1983 by Manx Software Systems
|
|
; :ts=8
|
|
public index_
|
|
index_:
|
|
lxi h,2
|
|
dad sp
|
|
mov e,m ;DE = destination
|
|
inx h
|
|
mov d,m
|
|
inx h
|
|
mov l,m
|
|
xchg ;e has char to look for
|
|
scan:
|
|
mov a,m
|
|
cmp e
|
|
jz foundit
|
|
ora a
|
|
jz noluck
|
|
inx h
|
|
jmp scan
|
|
;
|
|
noluck:
|
|
lxi h,0
|
|
xra a
|
|
ret
|
|
;
|
|
foundit:
|
|
mov a,h
|
|
ora l
|
|
ret
|
|
end
|
|
rindex.asm
|
|
;Copyright (C) 1981,1982,1983 by Manx Software Systems
|
|
; :ts=8
|
|
public rindex_
|
|
rindex_:
|
|
push b
|
|
lxi h,4
|
|
dad sp
|
|
mov e,m ;DE = destination
|
|
inx h
|
|
mov d,m
|
|
inx h
|
|
mov l,m
|
|
xchg ;e has char to look for
|
|
lxi b,0
|
|
xra a
|
|
toend:
|
|
cmp m ;scan for end of string
|
|
jz scan
|
|
inx h
|
|
inx b
|
|
jmp toend
|
|
|
|
scan:
|
|
mov a,b
|
|
ora c
|
|
jz noluck
|
|
dcx b
|
|
dcx h
|
|
mov a,m
|
|
cmp e
|
|
jnz scan
|
|
mov a,h
|
|
ora l
|
|
pop b
|
|
ret
|
|
noluck:
|
|
lxi h,0
|
|
xra a
|
|
pop b
|
|
ret
|
|
;
|
|
end
|
|
strlen.asm
|
|
;Copyright (C) 1981,1982,1983 by Manx Software Systems
|
|
; :ts=8
|
|
public strlen_
|
|
strlen_: LXI H,2
|
|
DAD SP
|
|
MOV A,M
|
|
INX H
|
|
MOV H,M
|
|
MOV L,A
|
|
LXI D,0
|
|
XRA A
|
|
.stl: CMP M
|
|
JZ .stlx
|
|
INX D
|
|
INX H
|
|
JMP .stl
|
|
.stlx: XCHG
|
|
mov a,l
|
|
ora h
|
|
RET
|
|
end
|
|
setmem.asm
|
|
;Copyright (C) 1983 by Manx Software Systems
|
|
public setmem_
|
|
setmem_: push b
|
|
lxi h,4
|
|
dad sp
|
|
mov e,m
|
|
inx h
|
|
mov d,m
|
|
inx h
|
|
mov c,m
|
|
inx h
|
|
mov b,m
|
|
inx h
|
|
mov l,m
|
|
xchg
|
|
setloop:
|
|
mov a,b
|
|
ora c
|
|
jz done
|
|
mov m,e
|
|
inx h
|
|
dcx b
|
|
jmp setloop
|
|
done: pop b
|
|
ret
|
|
end
|
|
movmem.asm
|
|
;Copyright (C) 1983 by Manx Software Systems
|
|
; :ts=8
|
|
public movmem_ ;movmem(src,dst,len)
|
|
movmem_:
|
|
push b
|
|
lxi h,9
|
|
dad sp
|
|
mov b,m ;BC=len
|
|
dcx h
|
|
mov c,m
|
|
dcx h
|
|
mov d,m ;DE=dst
|
|
dcx h
|
|
mov e,m
|
|
dcx h
|
|
mov a,m
|
|
dcx h
|
|
mov l,m ;HL=src
|
|
mov h,a
|
|
cmp d
|
|
jc movedown
|
|
jnz moveup
|
|
mov a,l
|
|
cmp e
|
|
jc movedown
|
|
jz done
|
|
moveup: ;src > dst
|
|
dad b
|
|
xchg
|
|
dad b
|
|
xra a
|
|
adi 3 ;test if z80
|
|
jpe uploop ;not z80 use loop to move data
|
|
xchg
|
|
dcx d
|
|
dcx h
|
|
db 237,184 ;lddr
|
|
pop b
|
|
ret
|
|
;
|
|
uploop: ;HL=dst, DE=src
|
|
dcx d
|
|
dcx h
|
|
ldax d
|
|
mov m,a
|
|
dcx b
|
|
mov a,b
|
|
ora c
|
|
jnz uploop
|
|
pop b
|
|
ret
|
|
;
|
|
movedown: ;src < dst
|
|
xra a
|
|
adi 3 ;test if z80
|
|
jpe downloop ;not z80 use loop to move data
|
|
db 237,176 ;ldir
|
|
pop b
|
|
ret
|
|
;
|
|
downloop:
|
|
mov a,m
|
|
stax d
|
|
inx d
|
|
inx h
|
|
dcx b
|
|
mov a,b
|
|
ora c
|
|
jnz downloop
|
|
done:
|
|
pop b
|
|
ret
|
|
end
|
|
swapmem.asm
|
|
; Copyright (C) 1983 by Manx Software Systems
|
|
; :ts=8
|
|
public swapmem_ ;swapmem(s1,s2,len)
|
|
swapmem_:
|
|
lxi h,7
|
|
dad sp
|
|
push b
|
|
mov b,m
|
|
dcx h
|
|
mov c,m ;BC = len
|
|
dcx h
|
|
mov d,m
|
|
dcx h
|
|
mov e,m ;DE = s2
|
|
dcx h
|
|
mov a,m
|
|
dcx h
|
|
mov l,m
|
|
mov h,a ;HL = s1
|
|
|
|
mov a,c
|
|
ora a
|
|
jnz bok
|
|
dcr b
|
|
bok:
|
|
push b
|
|
swaploop:
|
|
mov b,m
|
|
ldax d
|
|
mov m,a
|
|
mov a,b
|
|
stax d
|
|
inx h
|
|
inx d
|
|
dcr c
|
|
jnz swaploop
|
|
pop psw
|
|
ora a
|
|
jz done
|
|
dcr a
|
|
push psw
|
|
jmp swaploop
|
|
done:
|
|
pop b
|
|
ret
|
|
end
|
|
toupper.asm
|
|
;Copyright (C) 1981,1982 by Manx Software Systems
|
|
; :ts=8
|
|
public toupper_
|
|
toupper_:
|
|
lxi h,2
|
|
dad sp
|
|
mov a,m
|
|
cpi 'a'
|
|
jc skip
|
|
cpi 'z'+1
|
|
jnc skip
|
|
sui 'a'-'A'
|
|
skip:
|
|
mov l,a
|
|
mvi h,0
|
|
ora a
|
|
ret
|
|
;
|
|
;
|
|
public tolower_
|
|
;
|
|
tolower_:
|
|
lxi h,2
|
|
dad sp
|
|
mov a,m
|
|
cpi 'A'
|
|
jc skip2
|
|
cpi 'Z'+1
|
|
jnc skip2
|
|
adi 'a'-'A'
|
|
skip2:
|
|
mov l,a
|
|
mvi h,0
|
|
ora a
|
|
ret
|
|
end
|
|
lsubs.asm
|
|
; Copyright (C) 1982, 1983, 1984 by Manx Software Systems
|
|
; :ts=8
|
|
extrn lnprm,lntmp,lnsec
|
|
;
|
|
public .llis ;load long immediate secondary
|
|
.llis:
|
|
pop d ;get return addr
|
|
lxi h,4 ;size of long
|
|
dad d
|
|
push h ;put back correct return addr
|
|
xchg
|
|
;fall through into .llds
|
|
;
|
|
public .llds ;load long into secondary accum
|
|
.llds:
|
|
lxi d,lnsec
|
|
jmp lload
|
|
;
|
|
public .llip ;load long immediate primary
|
|
.llip:
|
|
pop d ;get return addr
|
|
lxi h,4 ;size of long
|
|
dad d
|
|
push h ;put back correct return addr
|
|
xchg
|
|
;fall through into .lldp
|
|
;
|
|
public .lldp ;load long into primary accum
|
|
.lldp:
|
|
lxi d,lnprm
|
|
lload:
|
|
mov a,m
|
|
stax d
|
|
inx d
|
|
inx h
|
|
mov a,m
|
|
stax d
|
|
inx d
|
|
inx h
|
|
mov a,m
|
|
stax d
|
|
inx d
|
|
inx h
|
|
mov a,m
|
|
stax d
|
|
ret
|
|
;
|
|
public .lst ;store long at addr in HL
|
|
.lst:
|
|
lxi d,lnprm
|
|
ldax d
|
|
mov m,a
|
|
inx h
|
|
inx d
|
|
ldax d
|
|
mov m,a
|
|
inx h
|
|
inx d
|
|
ldax d
|
|
mov m,a
|
|
inx h
|
|
inx d
|
|
ldax d
|
|
mov m,a
|
|
ret
|
|
;
|
|
public .lpsh ;push long onto the stack
|
|
.lpsh: ;from the primary accumulator
|
|
pop d ;get return address
|
|
lxi h,lnprm+3
|
|
lhld lnprm+2
|
|
push h
|
|
lhld lnprm
|
|
push h
|
|
xchg
|
|
pchl
|
|
;
|
|
public .lpop ;pop long into secondary accum
|
|
.lpop:
|
|
pop d ;get return address
|
|
pop h ;bytes 0 and 1
|
|
shld lnsec
|
|
pop h
|
|
shld lnsec+2
|
|
xchg
|
|
pchl
|
|
;
|
|
public .lswap ;exchange primary and secondary
|
|
.lswap:
|
|
lhld lnsec
|
|
xchg
|
|
lhld lnprm
|
|
shld lnsec
|
|
xchg
|
|
shld lnprm
|
|
lhld lnsec+2
|
|
xchg
|
|
lhld lnprm+2
|
|
shld lnsec+2
|
|
xchg
|
|
shld lnprm+2
|
|
ret
|
|
;
|
|
public .lng ;negate primary
|
|
.lng:
|
|
lxi h,lnprm
|
|
negate:
|
|
xra a
|
|
mvi d,4
|
|
ngloop:
|
|
mvi a,0
|
|
sbb m
|
|
mov m,a
|
|
inx h
|
|
dcr d
|
|
jnz ngloop
|
|
ret
|
|
;
|
|
public .ltst ;test if primary is zero
|
|
.ltst:
|
|
lxi h,lnprm
|
|
mvi d,4
|
|
tstlp:
|
|
mov a,m
|
|
ora a
|
|
jnz true
|
|
inx h
|
|
dcr d
|
|
jnz tstlp
|
|
jmp false
|
|
;
|
|
public .lcmp ;compare primary and secondary
|
|
;
|
|
;return 0 if p == s
|
|
p.lt.s: ;return < 0 if p < s
|
|
xra a
|
|
dcr a
|
|
pop b
|
|
ret
|
|
;
|
|
p.gt.s: ; > 0 if p > s
|
|
xra a
|
|
inr a
|
|
pop b
|
|
ret
|
|
;
|
|
.lcmp:
|
|
push b
|
|
lxi d,lnprm+3
|
|
lxi h,lnsec+3
|
|
mov a,m
|
|
xri 80h
|
|
mov c,a
|
|
ldax d
|
|
xri 80h
|
|
cmp c
|
|
mvi b,4
|
|
jmp pswchk
|
|
|
|
public .ulcmp
|
|
.ulcmp:
|
|
push b
|
|
lxi d,lnprm+3
|
|
lxi h,lnsec+3
|
|
mvi b,4
|
|
cmploop:
|
|
ldax d
|
|
cmp m
|
|
pswchk:
|
|
jc p.lt.s
|
|
jnz p.gt.s
|
|
dcx h
|
|
dcx d
|
|
dcr b
|
|
jnz cmploop
|
|
;return 0 if p == s
|
|
xra a
|
|
pop b
|
|
ret
|
|
;
|
|
public .lad ;add secondary to primary
|
|
.lad:
|
|
;DE is used as primary address
|
|
;and HL is used as secondary address
|
|
push b
|
|
lxi d,lnprm
|
|
lxi h,lnsec
|
|
xra a ;clear carry
|
|
mvi b,4
|
|
adloop:
|
|
ldax d
|
|
adc m
|
|
stax d
|
|
inx h
|
|
inx d
|
|
dcr b
|
|
jnz adloop
|
|
pop b
|
|
ret
|
|
;
|
|
public .lsb ;subtract secondary from primary
|
|
.lsb:
|
|
push b
|
|
lxi d,lnprm
|
|
lxi h,lnsec
|
|
xra a ;clear carry
|
|
mvi b,4
|
|
sbloop:
|
|
ldax d
|
|
sbb m
|
|
stax d
|
|
inx h
|
|
inx d
|
|
dcr b
|
|
jnz sbloop
|
|
pop b
|
|
ret
|
|
;
|
|
public .lan ;and primary with secondary
|
|
.lan:
|
|
push b
|
|
lxi d,lnprm
|
|
lxi h,lnsec
|
|
mvi b,4
|
|
ndloop:
|
|
ldax d
|
|
ana m
|
|
stax d
|
|
inx h
|
|
inx d
|
|
dcr b
|
|
jnz ndloop
|
|
pop b
|
|
ret
|
|
;
|
|
public .lor ;or primary with secondary
|
|
.lor:
|
|
push b
|
|
lxi d,lnprm
|
|
lxi h,lnsec
|
|
mvi b,4
|
|
orloop:
|
|
ldax d
|
|
ora m
|
|
stax d
|
|
inx h
|
|
inx d
|
|
dcr b
|
|
jnz orloop
|
|
pop b
|
|
ret
|
|
;
|
|
public .lxr ;exclusive or primary with secondary
|
|
.lxr:
|
|
push b
|
|
lxi d,lnprm
|
|
lxi h,lnsec
|
|
mvi b,4
|
|
xrloop:
|
|
ldax d
|
|
xra m
|
|
stax d
|
|
inx h
|
|
inx d
|
|
dcr b
|
|
jnz xrloop
|
|
pop b
|
|
ret
|
|
;
|
|
public .lcm ;complement primary
|
|
.lcm:
|
|
lxi h,lnprm
|
|
mvi d,4
|
|
cmloop:
|
|
mov a,m
|
|
cma
|
|
mov m,a
|
|
inx h
|
|
dcr d
|
|
jnz cmloop
|
|
ret
|
|
;
|
|
public .lls ;shift primary left by secondary
|
|
.lls:
|
|
lda lnsec
|
|
ani 03fH ;restrict to 63 bits
|
|
rz
|
|
lhld lnprm
|
|
xchg
|
|
lhld lnprm+2 ;DE has low word, HL has high word
|
|
lsloop:
|
|
dad h ;shift high word
|
|
xchg
|
|
dad h ;shift low word
|
|
xchg
|
|
jnc lsnc
|
|
inr l ;carry into high word
|
|
lsnc:
|
|
dcr a
|
|
jnz lsloop
|
|
shld lnprm+2 ;put back high word
|
|
xchg
|
|
shld lnprm
|
|
ret
|
|
;
|
|
public .lur ;unsigned right shift primary by secondary bits
|
|
.lur:
|
|
clc ;propogate 0 bit
|
|
jmp rs_sub
|
|
;
|
|
public .lrs ;right shift primary by secondary bits
|
|
.lrs:
|
|
lda lnprm+3
|
|
ral ;set carry to MSB
|
|
rs_sub:
|
|
push psw
|
|
lda lnsec
|
|
ani 03fH ;limit to 63 places
|
|
jz rsdone
|
|
mov d,a
|
|
rslp1:
|
|
lxi h,lnprm+3
|
|
mvi e,4
|
|
pop psw ;get correct carry setting
|
|
push psw
|
|
rslp2:
|
|
mov a,m
|
|
rar
|
|
mov m,a
|
|
dcx h
|
|
dcr e
|
|
jnz rslp2
|
|
dcr d
|
|
jnz rslp1
|
|
rsdone:
|
|
pop psw
|
|
ret
|
|
;
|
|
;
|
|
setup:
|
|
lxi h,3
|
|
dad d
|
|
mov c,m
|
|
mov a,c
|
|
ora a
|
|
rp
|
|
xchg
|
|
jmp negate ;force positive
|
|
;
|
|
public .ldv
|
|
.ldv: ;long divide (primary = primary/secondary)
|
|
push b
|
|
lxi d,lnprm
|
|
call setup
|
|
push b
|
|
lxi d,lnsec
|
|
call setup
|
|
mov a,c
|
|
pop b ;get primary sign
|
|
xra c ;merge signs
|
|
push psw ;save for return
|
|
call dodivide
|
|
pop psw
|
|
pop b
|
|
jm .lng
|
|
ret
|
|
;
|
|
public .lrm
|
|
.lrm: ;long remainder (primary = primary%secondary)
|
|
push b
|
|
lxi d,lnprm
|
|
call setup
|
|
mov a,c
|
|
ora a
|
|
push psw
|
|
lxi d,lnsec
|
|
call setup
|
|
call dodivide
|
|
lxi d,lntmp
|
|
lxi h,lnprm
|
|
mvi b,4
|
|
remsave:
|
|
ldax d
|
|
mov m,a
|
|
inx d
|
|
inx h
|
|
dcr b
|
|
jnz remsave
|
|
pop psw
|
|
pop b
|
|
jm .lng
|
|
ret
|
|
;
|
|
public .lud
|
|
.lud: ;unsigned long divide (primary = primary/secondary)
|
|
push b
|
|
call dodivide
|
|
pop b
|
|
ret
|
|
;
|
|
public .lum
|
|
.lum: ;long remainder (primary = primary%secondary)
|
|
push b
|
|
call dodivide
|
|
lxi d,lntmp
|
|
lxi h,lnprm
|
|
mvi b,4
|
|
uremsave:
|
|
ldax d
|
|
mov m,a
|
|
inx d
|
|
inx h
|
|
dcr b
|
|
jnz uremsave
|
|
pop b
|
|
ret
|
|
;
|
|
;
|
|
dodivide:
|
|
mvi b,4
|
|
lxi h,lntmp ;clear quotient buffer
|
|
xra a
|
|
quinit:
|
|
mov m,a
|
|
inx h
|
|
dcr b
|
|
jnz quinit
|
|
|
|
mvi a,32 ;initialize loop counter
|
|
divloop:
|
|
push psw
|
|
lxi h,lnprm
|
|
mvi b,8
|
|
ora a ;clear carry
|
|
shlp:
|
|
mov a,m
|
|
adc a ;shift one bit to the left
|
|
mov m,a
|
|
inx h
|
|
dcr b
|
|
jnz shlp
|
|
sbb a
|
|
ani 1
|
|
mov c,a
|
|
|
|
mvi b,4
|
|
lxi d,lntmp
|
|
lxi h,lnsec
|
|
ora a ;clear carry
|
|
sublp:
|
|
ldax d
|
|
sbb m
|
|
stax d
|
|
inx d
|
|
inx h
|
|
dcr b
|
|
jnz sublp
|
|
mov a,c
|
|
sbi 0
|
|
jnz zerobit
|
|
onebit:
|
|
lxi h,lnprm
|
|
inr m
|
|
pop psw
|
|
dcr a
|
|
jnz divloop
|
|
ret
|
|
;
|
|
zerobit:
|
|
pop psw
|
|
dcr a
|
|
jz restore
|
|
push psw
|
|
lxi h,lnprm
|
|
mvi b,8
|
|
ora a ;clear carry
|
|
zshlp:
|
|
mov a,m
|
|
adc a ;shift one bit to the left
|
|
mov m,a
|
|
inx h
|
|
dcr b
|
|
jnz zshlp
|
|
sbb a
|
|
mov c,a
|
|
|
|
mvi b,4
|
|
lxi d,lntmp
|
|
lxi h,lnsec
|
|
ora a ;clear carry
|
|
daddlp:
|
|
ldax d
|
|
adc m
|
|
stax d
|
|
inx d
|
|
inx h
|
|
dcr b
|
|
jnz daddlp
|
|
mov a,c
|
|
aci 0
|
|
jnz zerobit
|
|
jmp onebit
|
|
;
|
|
restore: ;fix up remainder if still negative
|
|
mvi b,4
|
|
lxi d,lntmp
|
|
lxi h,lnsec
|
|
ora a ;clear carry
|
|
resloop:
|
|
ldax d
|
|
adc m
|
|
stax d
|
|
inx d
|
|
inx h
|
|
dcr b
|
|
jnz resloop
|
|
ret
|
|
;
|
|
;
|
|
public .lml
|
|
.lml: ;long multiply (primary = primary * secondary)
|
|
push b
|
|
;
|
|
lxi h,lnprm
|
|
mvi b,4
|
|
lxi d,lntmp ;copy multiplier into work area
|
|
msav:
|
|
mov a,m
|
|
stax d
|
|
mvi m,0
|
|
inx h
|
|
inx d
|
|
dcr b
|
|
jnz msav
|
|
;
|
|
mvi a,32 ;initialize loop counter
|
|
muloop:
|
|
push psw
|
|
lxi h,lnprm
|
|
mvi b,8
|
|
ora a ;clear carry
|
|
mshlp:
|
|
mov a,m
|
|
adc a ;shift one bit to the left
|
|
mov m,a
|
|
inx h
|
|
dcr b
|
|
jnz mshlp
|
|
jnc mnext
|
|
|
|
mvi b,4
|
|
lxi d,lnprm
|
|
lxi h,lnsec
|
|
ora a ;clear carry
|
|
maddlp:
|
|
ldax d
|
|
adc m
|
|
stax d
|
|
inx d
|
|
inx h
|
|
dcr b
|
|
jnz maddlp
|
|
;
|
|
mnext:
|
|
pop psw
|
|
dcr a
|
|
jnz muloop
|
|
pop b
|
|
ret
|
|
;
|
|
;
|
|
public .leq
|
|
.leq:
|
|
call .lcmp
|
|
jz true
|
|
false:
|
|
lxi h,0
|
|
xra a
|
|
ret
|
|
;
|
|
public .lne
|
|
.lne:
|
|
call .lcmp
|
|
jz false
|
|
true:
|
|
lxi h,1
|
|
xra a
|
|
inr a
|
|
ret
|
|
;
|
|
public .llt
|
|
.llt:
|
|
call .lcmp
|
|
jm true
|
|
jmp false
|
|
;
|
|
public .lle
|
|
.lle:
|
|
call .lcmp
|
|
jm true
|
|
jz true
|
|
jmp false
|
|
;
|
|
public .lge
|
|
.lge:
|
|
call .lcmp
|
|
jm false
|
|
jmp true
|
|
;
|
|
public .lgt
|
|
.lgt:
|
|
call .lcmp
|
|
jm false
|
|
jz false
|
|
jmp true
|
|
;
|
|
public .lul
|
|
.lul:
|
|
call .ulcmp
|
|
jm true
|
|
jmp false
|
|
;
|
|
public .lue
|
|
.lue:
|
|
call .ulcmp
|
|
jm true
|
|
jz true
|
|
jmp false
|
|
;
|
|
public .luf
|
|
.luf:
|
|
call .ulcmp
|
|
jm false
|
|
jmp true
|
|
;
|
|
public .lug
|
|
.lug:
|
|
call .ulcmp
|
|
jm false
|
|
jz false
|
|
jmp true
|
|
;
|
|
public .utox
|
|
.utox:
|
|
shld lnprm
|
|
posconv:
|
|
lxi h,0
|
|
shld lnprm+2
|
|
ret
|
|
;
|
|
public .itox
|
|
.itox:
|
|
shld lnprm
|
|
mov a,h
|
|
ora a
|
|
jp posconv
|
|
lxi h,-1
|
|
shld lnprm+2
|
|
ret
|
|
;
|
|
public .xtoi
|
|
.xtoi:
|
|
lhld lnprm
|
|
ret
|
|
end
|
|
divide.asm
|
|
;Copyright (C) 1981,1982,1983 by Manx Software Systems
|
|
; :ts=8
|
|
extrn .ng
|
|
public .dv,.ud
|
|
.dv: ; DE has dividend, HL has divisor
|
|
mov a,d
|
|
xra h ;check if signs differ
|
|
push psw ;and remember
|
|
call divsub ;use same routine as modulo
|
|
xchg ;and swap results
|
|
pop psw
|
|
jm .ng ;negate result if signs of operands differ
|
|
mov a,l
|
|
ora h
|
|
RET
|
|
;
|
|
.ud:
|
|
CALL .um ;use same routine as modulo
|
|
XCHG ;and swap results
|
|
mov a,l
|
|
ora h
|
|
RET
|
|
;
|
|
public .rm,.um
|
|
.rm:
|
|
mov a,d
|
|
push psw
|
|
call divsub
|
|
pop psw
|
|
ora a
|
|
jm .ng ;negate result if dividend was signed
|
|
mov a,h
|
|
ora l
|
|
ret
|
|
;
|
|
divsub:
|
|
mov a,h
|
|
ora a
|
|
jp hlpos
|
|
cma
|
|
mov h,a
|
|
mov a,l
|
|
cma
|
|
mov l,a
|
|
inx h
|
|
hlpos:
|
|
mov a,d
|
|
ora a
|
|
jp .um
|
|
cma
|
|
mov d,a
|
|
mov a,e
|
|
cma
|
|
mov e,a
|
|
inx d
|
|
; fall through into .um
|
|
;
|
|
.um: push b ;save for C
|
|
mov c,l
|
|
mov b,h
|
|
lxi h,0
|
|
call div16
|
|
pop b
|
|
mov a,l ;set flags for C
|
|
ora h
|
|
ret
|
|
;
|
|
; div16: divides (hl,de) by bc
|
|
; returns remainder in hl, quotient in de
|
|
public div16
|
|
div16:
|
|
mov a,c
|
|
cma
|
|
mov c,a
|
|
mov a,b
|
|
cma
|
|
mov b,a
|
|
inx b
|
|
MVI A,16 ;iteration count
|
|
divloop:
|
|
DAD H ;shift hl left
|
|
XCHG
|
|
DAD H ;shift de left
|
|
XCHG
|
|
JNC nocy
|
|
INR L ;carry into high part
|
|
nocy:
|
|
dad b ;subtract divisor
|
|
jc setbit
|
|
push psw
|
|
mov a,l
|
|
sub c
|
|
mov l,a
|
|
mov a,h
|
|
sbb b
|
|
mov h,a
|
|
pop psw
|
|
DCR A ;count times thru
|
|
JNZ divloop
|
|
ret
|
|
setbit:
|
|
INR E ;set quotient bit
|
|
DCR A ;count times thru
|
|
JNZ divloop
|
|
ret
|
|
end
|
|
shifts.asm
|
|
;Copyright (C) 1981,1982 by Manx Software Systems
|
|
;
|
|
public .ml
|
|
.ml: PUSH B
|
|
MOV B,H
|
|
MOV C,L
|
|
LXI H,0 ;CLEAR RESULT
|
|
MVI A,16 ;ITERATION COUNT
|
|
.mlp: DAD H ;SHIFT LEFT
|
|
XCHG ; NOW SHIFT DE LEFT
|
|
DAD H
|
|
XCHG
|
|
JNC .msk
|
|
DAD B
|
|
.msk: DCR A ;COUNT TIMES THRU
|
|
JNZ .mlp ;go thru 16 times
|
|
POP B
|
|
mov a,l
|
|
ora h
|
|
RET
|
|
;
|
|
public .rs
|
|
.rs: XCHG
|
|
mov a,e
|
|
ani 31
|
|
mov e,a
|
|
jz setcc
|
|
MOV A,H
|
|
ORA H
|
|
JP .arloop
|
|
;
|
|
.sign: MOV A,H
|
|
STC
|
|
RAR
|
|
MOV H,A
|
|
MOV A,L
|
|
RAR
|
|
MOV L,A
|
|
DCR E
|
|
JNZ .sign
|
|
ora h
|
|
ret
|
|
;
|
|
public .ls
|
|
.ls: XCHG
|
|
mov a,e
|
|
ani 31
|
|
mov e,a
|
|
jz setcc
|
|
lslp:
|
|
DAD H
|
|
DCR E
|
|
JNZ lslp
|
|
setcc:
|
|
mov a,l
|
|
ora h
|
|
ret
|
|
;
|
|
public .ur
|
|
.ur: XCHG
|
|
mov a,e
|
|
ani 31
|
|
mov e,a
|
|
jz setcc
|
|
.arloop: MOV A,H
|
|
ORA A
|
|
RAR
|
|
MOV H,A
|
|
MOV A,L
|
|
RAR
|
|
MOV L,A
|
|
DCR E
|
|
JNZ .arloop
|
|
ora h
|
|
ret
|
|
;
|
|
end
|
|
bitopr.asm
|
|
;Copyright (C) 1981,1982 by Manx Software Systems
|
|
public .an
|
|
.an: MOV A,H
|
|
ANA D
|
|
MOV H,A
|
|
MOV A,L
|
|
ANA E
|
|
MOV L,A
|
|
ora h
|
|
RET
|
|
;
|
|
public .cm
|
|
.cm: MOV A,H
|
|
CMA
|
|
MOV H,A
|
|
MOV A,L
|
|
CMA
|
|
MOV L,A
|
|
ora h
|
|
RET
|
|
;
|
|
public .or
|
|
.or: MOV A,H
|
|
ORA D
|
|
MOV H,A
|
|
MOV A,L
|
|
ORA E
|
|
MOV L,A
|
|
ora h
|
|
RET
|
|
;
|
|
public .xr
|
|
.xr: MOV A,H
|
|
XRA D
|
|
MOV H,A
|
|
MOV A,L
|
|
XRA E
|
|
MOV L,A
|
|
ora h
|
|
RET
|
|
end
|
|
support.asm
|
|
;Copyright (C) 1981,1982 by Manx Software Systems
|
|
; Copyright (C) 1981 Thomas Fenwick
|
|
; :ts=8
|
|
public .nt
|
|
.nt: MOV A,H
|
|
ORA L
|
|
jz .true
|
|
jmp .false
|
|
;
|
|
public .eq,.ne
|
|
.eq: mov a,l
|
|
sub e
|
|
jnz .false
|
|
mov a,h
|
|
sub d
|
|
jz .true
|
|
.false: lxi h,0
|
|
xra a
|
|
ret
|
|
;
|
|
.ne: mov a,l
|
|
sub e
|
|
jnz .true
|
|
mov a,h
|
|
sub d
|
|
jz .false
|
|
.true: lxi h,1
|
|
mov a,l
|
|
ora h
|
|
RET
|
|
;
|
|
public .le,.ge
|
|
.ge: ; ge
|
|
XCHG
|
|
.le: mov a,h
|
|
xra d
|
|
jm .lediff ; signs differ
|
|
; signs alike
|
|
mov a,l
|
|
sub e
|
|
mov a,h
|
|
sbb d
|
|
cmc
|
|
mvi a,0
|
|
aci 0
|
|
mov l,a
|
|
mvi h,0
|
|
ret
|
|
.lediff: mov a,d
|
|
rlc
|
|
ani 1
|
|
mov l,a
|
|
mvi h,0
|
|
ret
|
|
;
|
|
public .lt,.gt
|
|
.lt:
|
|
XCHG
|
|
.gt: mov a,h
|
|
xra d
|
|
jm .gtdiff ; signs differ
|
|
; signs alike
|
|
mov a,l
|
|
sub e
|
|
mov a,h
|
|
sbb d
|
|
mvi a,0
|
|
aci 0
|
|
mov l,a
|
|
mvi h,0
|
|
ret
|
|
.gtdiff: mov a,h
|
|
rlc
|
|
ani 1
|
|
mov l,a
|
|
mvi h,0
|
|
ret
|
|
;
|
|
public .ng
|
|
.ng: MOV A,L
|
|
CMA
|
|
MOV L,A
|
|
MOV A,H
|
|
CMA
|
|
MOV H,A
|
|
INX H
|
|
mov a,l
|
|
ora h
|
|
RET
|
|
;
|
|
public .sb
|
|
.sb: XCHG
|
|
mov a,l
|
|
sub e
|
|
mov l,a
|
|
mov a,h
|
|
sbb d
|
|
mov h,a
|
|
ora l
|
|
ret
|
|
;
|
|
public .swt
|
|
.swt: xchg
|
|
pop h
|
|
PUSH B
|
|
MOV B,D
|
|
MOV C,E
|
|
MOV E,M
|
|
INX H
|
|
MOV D,M
|
|
swt.1: DCX D
|
|
MOV A,D
|
|
ORA A
|
|
JM swt.def
|
|
INX H
|
|
MOV A,C
|
|
CMP M
|
|
JZ swt.3
|
|
INX H
|
|
swt.2: INX H
|
|
INX H
|
|
JMP swt.1
|
|
swt.3: INX H
|
|
MOV A,B
|
|
CMP M
|
|
JNZ swt.2
|
|
swt.def: INX H
|
|
MOV A,M
|
|
INX H
|
|
MOV H,M
|
|
MOV L,A
|
|
POP B
|
|
PCHL
|
|
;
|
|
public .ue,.uf
|
|
.uf: ; uge
|
|
XCHG
|
|
.ue: mov a,l ; ule
|
|
sub e
|
|
mov a,h
|
|
sbb d
|
|
mvi a,0
|
|
cmc
|
|
aci 0
|
|
mov l,a
|
|
mvi h,0
|
|
ret
|
|
;
|
|
public .ug,.ul
|
|
.ul: ; ult
|
|
XCHG
|
|
.ug: mov a,l
|
|
sub e
|
|
mov a,h
|
|
sbb d
|
|
mvi a,0
|
|
aci 0
|
|
mov l,a
|
|
mvi h,0
|
|
ret
|
|
;
|
|
end
|
|
port.asm
|
|
;
|
|
; Direct Port I/O Functions for AZTEC C II
|
|
;
|
|
; Copyright (c) 1982 William C. Colley III
|
|
;
|
|
; I grant Manx Software Systems permission to incorporate these functions
|
|
; into the AZTEC C library subject only to the condition that my copyright
|
|
; notice remain in the source code. WCC3.
|
|
;
|
|
; These functions allow AZTEC C II to get to the machine I/O ports. They
|
|
; are more complicated than might be expected as they can't use the Z-80's
|
|
; "IN A,(C)" and "OUT (C),A" instructions and still remain 8080-compatible.
|
|
; Self-modifying code is also out of the question as that kills ROMability.
|
|
; I therefore go through the hassle of setting up temporary subroutines in
|
|
; RAM and calling them.
|
|
;
|
|
; The functions in the package are:
|
|
;
|
|
; char in(p) Returns contents of input port p.
|
|
; char p;
|
|
;
|
|
; out(p,c) Sends character c to output port p.
|
|
; char p, c;
|
|
;
|
|
CSEG
|
|
PUBLIC in_, out_
|
|
|
|
;*****************************************************************************
|
|
|
|
in_: LXI H, 2 ;Get port number from stack.
|
|
DAD SP
|
|
MOV H, M
|
|
|
|
MVI L, 0dbh ;Form input instruction of temporary
|
|
SHLD TMP ; subroutine and set it up in core.
|
|
|
|
LXI H, TMP + 2 ;Add return instruction to temporary
|
|
MVI M, 0c9h ; subroutine in core.
|
|
|
|
CALL TMP ;Call temporary subroutine.
|
|
|
|
MOV L, A ;Return result.
|
|
MVI H, 0
|
|
ORA H
|
|
RET
|
|
|
|
;*****************************************************************************
|
|
|
|
out_: LXI H, 4 ;Get data and port number from stack.
|
|
DAD SP
|
|
MOV A, M
|
|
DCX H
|
|
DCX H
|
|
MOV H, M
|
|
|
|
MVI L, 0d3h ;Form output instruction of temporary
|
|
SHLD TMP ; subroutine and set it up in core.
|
|
|
|
LXI H, TMP + 2 ;Add return instruction to temporary
|
|
MVI M, 0c9h ; subroutine in core.
|
|
|
|
JMP TMP ;Call temporary subroutine and return.
|
|
|
|
;*****************************************************************************
|
|
|
|
DSEG
|
|
|
|
TMP: DS 3 ;Space for temporary subroutine.
|
|
|
|
;*****************************************************************************
|
|
|
|
END
|
|
|