Files
RomWBW/Source/Images/d_aztecc/u0/LIBASRC.ARC
2023-06-14 12:45:41 -04:00

2583 lines
31 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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