home *** CD-ROM | disk | FTP | other *** search
- 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