home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
vol_100
/
104_01
/
runtime.asm
< prev
next >
Wrap
Assembly Source File
|
1979-12-31
|
12KB
|
886 lines
title runtime package for small "C"
ram equ 0 ;start of ram in system
extrn main
;********************************************************
; *
; run time libray for small c compiler *
; *
; by Ron Cain *
; *
;********************************************************
;
; fetch a single byte from stack pointer plus
; offset of byte following call and sign extend
; into hl
;
@gcharss:csect
pop b
ldax b
mov l,a
inx b
mvi h,0
dad sp
push b
mov a,m
jmp @sxt
;
; fetch a single byte from stack plus a 2 byte offset
; and sign extend byte into hl
;
@gcharsl:csect
pop b
ldax b
mov l,a
inx b
ldax b
mov h,a
inx h
dad sp
push b
mov a,m
jmp @sxt
;
; fetch a single byte from address in hl and
; sign extend into hl
;
@gchar: csect
mov a,m
jmp @sxt
;
; put the accum into hl and sign extend through h
;
@sxt: csect
mov l,a
rlc
sbb a
mov h,a
ret
;
; fetch a full 16-bit integer from offset plus stack pointer
; into hl
;
@gintss:csect
pop b
ldax b
mov l,a
mvi h,0
inx b
dad sp
push b
mov a,m
inx h
mov h,m
mov l,a
ret
;
; fetch a 16-bit integer from stack pointer plus
; a 16 bit offset and put value in hl
;
@gintsl:csect
pop b
ldax b
mov l,a
inx b
ldax b
mov h,a
inx b
dad sp
push b
mov a,m
inx h
mov h,m
mov l,a
ret
;
; fetch a full 16-bit integer from the address in hl
; into hl
;
@gint: csect
mov a,m
inx h
mov h,m
mov l,a
ret
;
; store a byte stack plus 8 byte offset
;
@pcharss:csect
xchg
pop b
ldax b
mov l,a
mvi h,0
inx b
dad sp
mov m,e
xchg
push b
ret
;
; store a byte at stack plus offset
;
@pcharsl:csect
xchg
pop b
ldax b
mov l,a
inx b
ldax b
mov h,a
inx b
dad sp
mov m,e
xchg
push b
ret
;
; store 16-bit integer at offset plus stack
;
@pintss:csect
xchg
pop b
ldax b
mov l,a
mvi h,0
inx b
dad sp
mov m,e
inx h
mov m,d
xchg
push b
ret
;
; store a 16 bit integer in hl at stack plus offset
;
@pintsl:csect
xchg
pop b
ldax b
mov l,a
inx b
ldax b
mov h,a
inx b
dad sp
mov m,e
inx h
mov m,d
push b
xchg
ret
;
; store a 16-bit integer in hl at the address in de
;
@pint: csect
mov a,l
stax d
inx d
mov a,h
stax d
ret
page
@incdec:csect
;
; take the address in hl and add value that follow and save back
; address in hl
;
@preinc:
call @incdecl
call @inc
nop
ret
;
; take the address in hl and sub value that follow and
; save it back in place
;
@predec:
call @incdecl
call @dec
nop
ret
;
; take the address in hl and sub value that follow and save
; back in address in hl and restore value to pre inc
;
@postinc:
call @incdecl
push d
call @inc
pop h
nop
ret
;
; take the address in hl and add value that follow and
; save back in address in hl restore value pre dec
;
@postdec:
call @incdecl
push d
call @dec
pop h
nop
ret
;
; load needed valut for inc and dec
;
@incdecl:
pop d
pop b
ldax b
inx b
push b
push d
dcx b
ora a
jp @incdec1
mov e,m
inx h
mov d,m
ret
@incdec1:
mov e,m
mov a,e
rlc
sbb a
mov d,a
ret
;
; add value in a to de and save at address in hl
;
@inc:
ani 07fh
add e
mov e,a
mov a,d
aci 0
mov d,a
jmp @incdecs
;
; subtract value in a to de and save at address in hl
;
@dec:
ani 07fh
cma
inr a
add e
mov e,a
mov a,d
aci 0ffh
mov d,a
jmp @incdecs
;
; store value in de at address in hl
;
@incdecs:
ldax b
ora a
jp @incdec2
mov m,d
dcx h
mov m,e
xchg
mov a,h
ora l
ret
@incdec2:
mov m,e
xchg
mov a,h
ora l
ret
page
;
; inclusive "or" hl and de into hl
;
@or: csect
pop b
pop d
push b
mov a,l
ora e
mov l,a
mov a,h
ora d
mov h,a
ora l
ret
;
; excluseive "or" hl and de into hl
;
@xor: csect
pop b
pop d
push b
mov a,l
xra e
mov l,a
mov a,h
xra d
mov h,a
ora l
ret
;
; "and" hl and de into hl
;
@and: csect
pop b
pop d
push b
mov a,l
ana e
mov l,a
mov a,h
ana d
mov h,a
ora l
ret
;
; in all the following compare routines hl is set to 1
; if the condition is true, otherwise it is set to 0
;
; not current condition
;
@nlog: csect
mov a,h
ora l
jnz @nlog1
lxi h,1
mov a,h
ora l
ret
@nlog1:
lxi h,0
mov a,h
ora l
ret
page
@comp: csect
;
; test if hl equal to de
;
@eq:
pop b
pop d
push b
lxi b,@compret
push b
call @cmp
rz
dcx h
ret
;
; test if de to hl for not equal
;
@ne:
pop b
pop d
push b
lxi b,@compret
push b
call @cmp
rnz
dcx h
ret
;
; test if de greater then hl (signed)
;
@gt:
pop b
pop d
push b
lxi b,@compret
push b
xchg
call @cmp
rc
dcx h
ret
;
; test if de less then hl (signed)
;
@lt:
pop b
pop d
push b
lxi b,@compret
push b
call @cmp
rc
dcx h
ret
;
; test if de greater then or equal to hl (signed)
;
@ge:
pop b
pop d
push b
lxi b,@compret
push b
call @cmp
rz
rnc
dcx h
ret
;
; test if de less than or equal to hl (signed)
;
@le:
pop b
pop d
push b
lxi b,@compret
push b
call @cmp
rz
rc
dcx h
ret
page
;
; test if de greater than hl (unsigned)
;
@ugt:
pop b
pop d
push b
lxi b,@compret
push b
xchg
call @ucmp
rc
dcx h
ret
;
; test if de less than hl(unsigned)
;
@ult:
pop b
pop d
push b
lxi b,@compret
push b
call @ucmp
rc
dcx h
ret
;
; test if de greater than or equal to hl (unsigned)
;
@uge:
pop b
pop d
push b
lxi b,@compret
push b
call @ucmp
rnc
dcx h
ret
;
; test if de less than or equal to hl (unsigned)
;
@ule:
pop b
pop d
push b
lxi b,@compret
push b
call @ucmp
rz
rc
dcx h
ret
;
; common routine to preform a signed compare of
; de and hl
;
; de-hl and sets the conditions:
; carry set means de < hl
; zero/non-zero set according to equality
;
@cmp:
mov a,e
sub l
mov e,a
mov a,d
sbb h
lxi h,1
jm @cmp1
ora e
ret
@cmp1:
ora e
stc
ret
;
; common routine to perform unsinged compare
;
; carry set if de less than hl
; zero/non-zero set accordingly hl=de
;
@ucmp:
mov a,d
cmp h
jnz @ucmp1
mov a,e
cmp l
@ucmp1:
lxi h,1
ret
;
; set machine status for all comditional operators
;
@compret:
mov a,h
ora l
ret
page
;
; shift de arithmetically right by hl return in hl
;
@asr: csect
pop b
pop d
push b
@asr1:
xchg
mov a,h
ral
mov a,h
rar
mov h,a
mov a,l
rar
mov l,a
dcr e
jnz @asr1
ret
;
; shift de arithmetically left by hl and return in hl
;
@asl: csect
pop b
pop d
push b
@asl1:
xchg
dad h
dcr e
jnz @asl1
ret
;
; subtract hl from de and return in hl
;
@sub: csect
pop b
pop d
push b
mov a,e
sub l
mov l,a
mov a,d
sbb h
mov h,a
ret
;
; from the two's complement of hl
;
@neg: csect
call @com
inx h
ret
;
; from the one's complement of hl
;
@com: csect
mov a,h
cma
mov h,a
mov a,l
cma
mov l,a
ret
;
; mutiply de by hl and return in hl (signed)
;
@mult: csect
pop b
pop d
push b
mov b,h
mov c,l
lxi h,0
@mult1:
mov a,c
rrc
jnc @mult2
dad d
@mult2:
xra a
mov a,b
rar
mov b,a
mov a,c
rar
mov c,a
ora b
rz
xra a
mov a,e
ral
mov e,a
mov a,d
ral
mov d,a
ora e
rz
jmp @mult1
;
; divide de by hl and return quotient in hl
; return remainder in de (signed)
;
@div: csect
pop b
pop d
push b
mov b,h
mov c,l
mov a,d
xra b
push psw
mov a,d
ora a
cm @deneg
mov a,b
ora a
cm @bcneg
mvi a,16
push psw
xchg
lxi d,0
@div1:
dad h
call @rdel
jz @div2
call @cmpbcde
jm @div2
mov a,l
ori 1
mov l,a
mov a,e
sub c
mov e,a
mov a,d
sbb b
mov d,a
@div2:
pop psw
dcr a
jz @div3
push psw
jmp @div1
@div3:
pop psw
rp
call @deneg
xchg
call @deneg
xchg
ret
;
; negate the integer in bc (used by divide only)
;
@deneg:
mov a,d
cma
mov d,a
mov a,e
cma
mov e,a
inx d
ret
;
; negate then integer in bc (used by divide only)
;
@bcneg:
mov a,b
cma
mov b,a
mov a,c
cma
mov c,a
inx b
ret
;
; roate de left one bit (used by divide only)
;
@rdel:
mov a,e
ral
mov e,a
mov a,d
ral
mov d,a
ora e
ret
;
; compare bc to de (used by divide only)
;
@cmpbcde:
mov a,e
sub c
mov a,d
sbb b
ret
;
; used by switch to search table
; calling format form compiler
; d-pointer to table
; h-where to go if value not in table
; b- number of entry in table
;
@switch:csect
xthl ;get value of expresstion to check
xchg ;put value in de
@switch1:
mov a,e
cmp m ;check to see if low byte match
inx h ;move pointer to next byte of data
jnz @switch2 ;no nov to next entry
mov a,d ;move high byte of data
cmp m ;check to see if match
jnz @switch2 ;yes jump to address
inx h
mov e,m ;get low byte of address
inx h
mov d,m ;get high byte of address
xchg ;put address in hl
pop b ;remove entry from stack
pchl ;jump to needed case statement
@switch2:
inx h ;move pointer to next entry
inx h
inx h
dcr b ;check to see if done with scan
jnz @switch1
xthl ;get address of where to go when done
pop b ;remove entry from stack
pchl ;go there
;
; call a bios routine with be loaded
;
bios: csect
pop h
pop b
pop d
push d
push b
push h
lhld 1
dcx h
dcx h
dcx h
mvi d,0
dad d
dad d
dad d
call bios1
mov l,a
mvi h,0
ret
bios1: pchl
;
; call bods to do a cpm function bods(c,de)
;
bdos: csect
pop h
pop d
pop b
push b
push d
push h
jmp 5
;
; exit back to system
;
exit: csect
mvi c,0
call 5
;
; take command buffer and build pointer list
@init: csect
lhld 6+ram ;get pointer to high memory
dcx h ;move to just below bdos
sphl ;make it current stack
lxi h,80h+ram ;pointer to start of command buffer
mov e,m ;number of bytes in command line
mvi d,0 ;make it 16 bit value
dad d ;point to end of text
inx h ;move past end of buffer
mvi m,0 ;make end of text
lxi d,cpointer ;place where pointer should place
lxi h,80h+ram ;address of text string
lxi b,1 ;number of arg
@init2:
inx h ;move pointer to next byte
mov a,m ;check for end of buffer
ora a ;set machine status
jz @init10 ;yes call main line
cpi ' ' ;is there a leading space
jz @init2 ;yes
mov a,l ;save pointer value
stax d
mov a,h
inx d
stax d
inx d
inr c ;add 1 to arg count
@init3:
inx h ;move to next byte
mov a,m ;get byte into a
ora a ;see if end of buffer
jz @init10 ;yes...
cpi ' ' ;check for space
jnz @init3 ;no keep looking
mvi m,0 ;mark as end of parm
jmp @init2 ;loop for next command
@init10:
lxi h,cpointer-2 ;get address of pointers
push b ;push argc on stack
push h ;push argv on stack
call main ;execute main line
jmp 0 ;it just return from main exit to cpm
dw @ccnull
cpointer:
dw @ccnull,@ccnull,@ccnull,@ccnull,@ccnull
dw @ccnull,@ccnull,@ccnull,@ccnull,@ccnull
dw @ccnull,@ccnull,@ccnull,@ccnull,@ccnull
dw @ccnull,@ccnull,@ccnull,@ccnull,@ccnull
dw @ccnull,@ccnull,@ccnull,@ccnull,@ccnull
@ccnull:
db 'noname',0
page
@oeq equ @eq-@comp
@one equ @ne-@comp
@ogt equ @gt-@comp
@olt equ @lt-@comp
@oge equ @ge-@comp
@ole equ @le-@comp
@ougt equ @ugt-@comp
@oult equ @ult-@comp
@ouge equ @uge-@comp
@oule equ @ule-@comp
@oprei equ @preinc-@incdec
@opred equ @predec-@incdec
@oposi equ @postinc-@incdec
@oposd equ @postdec-@incdec
end