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

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