home *** CD-ROM | disk | FTP | other *** search
- ;* COMMONIO.ASM
- ;************************************************************************
- ;* *
- ;* PC Scheme/Geneva 4.00 Borland TASM code *
- ;* *
- ;* (c) 1985-1988 by Texas Instruments, Inc. See COPYRIGHT.TXT *
- ;* (c) 1992 by L. Bartholdi & M. Vuilleumier, University of Geneva *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Integer & float printing interfaces *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Created by: John Jensen Date: 1985 *
- ;* Revision history: *
- ;* - 18 Jun 92: Renaissance (Borland Compilers, ...) *
- ;* *
- ;* ``In nomine omnipotentii dei'' *
- ;************************************************************************
- IDEAL
- %PAGESIZE 60, 132
- MODEL medium
- LOCALS @@
-
- INCLUDE "scheme.ash"
-
- CODESEG
- ;************************************************************************
- ;* Find approximate space left on stack (assume Bot of Stack at DS:FFFF)*
- ;* Caling sequence: stkspc() *
- ;************************************************************************
- PROC C stkspc
- DATASEG
- EXTRN C _stklen:WORD ; total length of runtime stack
- CODESEG
- mov ax, [_stklen]
- add ax, sp
- ret
- ENDP stkspc
-
- ;************************************************************************
- ;* Parse input integer *
- ;* Calling sequence: buildint(work,buf,base) *
- ;* Where work: pointer to some workspace *
- ;* buf: pointer to integer characters *
- ;* base: numeric base *
- ;************************************************************************
- PROC C buildint USES si di, @@bignum:WORD, @@charbuf:WORD, $$base:WORD
- push ds ; Assume es = ds
- pop es
- cld
- mov si, [@@charbuf]
- lodsb ; Fetch first character
- cmp al, '-'
- pushf
- je @@negative
- cmp al, '+'
- je @@negative
- dec si ; Point si back to first char
- @@negative:
- mov cx, 1 ; At first, bignum is one word
- add [@@bignum], 3 ; Point BIGPTR to bignum proper
- @@skipbase:
- lodsb ; Get first number char
- cmp al, '#' ; we know the base - skip all #x's
- jne @@skipped
- inc si
- jmp @@skipbase
- @@readloop:
- lodsb ; Get next int character
- @@skipped:
- mov di, [@@bignum]
- sub al, '0'
- js @@numberdone
- cmp al, 9
- jbe @@plaindigit
- and al, 7 ;Otherwise, parse extra hex digit
- add al, 9
- @@plaindigit:
- xor ah, ah
- call bigx10 ;Multiply bignum by 10, adding digit
- jmp @@readloop
-
- @@numberdone:
- sub di, 3 ; Point di back to start of buffer
- mov ax, cx ; Save integer size
- stosw
- xor al, al
- popf ; Get number's sign
- jne @@storesign
- inc al
- @@storesign:
- mov [di], al
- ret
- ENDP buildint
-
- ;************************************************************************
- ;* BIGX10: Multiply bignum at es:[di], size=cx words, by BASE and add ax*
- ;************************************************************************
- PROC bigx10 NEAR
- push cx
- mov dx, ax ; Transfer digit to add
- cld
- @@loop:
- mov ax, [di] ; Get word to multiply
- call wordx10 ; Multiply word by 10
- stosw
- loop @@loop
- pop cx
- or dx, dx ; Does a carry remain?
- jz @@samelength
- mov [es:di], dx ; enlarge bignum
- inc cx
- @@samelength:
- ret
- ENDP bigx10
-
- ;************************************************************************
- ;* WORDX10: Multiply ax by BASE and add dx *
- ;* product in ax, carry in dx *
- ;************************************************************************
- PROC wordx10 NEAR
- push cx dx ; Save value of cx, carry in
- mul [$$base]
- pop cx ; Restore carry to cx
- add ax, cx ; Add carry
- adc dx, 0
- pop cx ; Restore cx
- ret
- ENDP wordx10
-
- ;************************************************************************
- ;* Copy bignum data to a math buffer *
- ;* Calling sequence: copybig(pg,ds,buf) *
- ;* Where: pg,ds ---- page & displacement of bignum *
- ;* buf ------ pointer to math buffer *
- ;************************************************************************
- PROC C copybig USES ds si di, @@page:WORD, @@disp:WORD, @@buffer:WORD
- push ds ; Assume es = ds
- pop es
- mov si, [@@page]
- sal si, 1
- ldpage ds, si
- mov si, [@@disp]
- mov ax, [si+1] ; Get size of bignum proper (words)
- sub ax, 4
- shr ax, 1
- add si, 3 ; Point ds:si to sign byte
- mov di, [@@buffer]
- cld ; Direction forward
- stosw ; Store bignum size in math buffer
- movsb ; Copy sign byte
- mov cx, ax
- rep movsw
- ret
- ENDP copybig
-
- ;************************************************************************
- ;* Convert buffered bignum to ASCII *
- ;* Calling sequence: big2asc(mathbuf,charbuf) *
- ;* Where: mathbuf --- pointer to buffered bignum *
- ;* charbuf --- pointer to ASCII charcater array *
- ;************************************************************************
- PROC C big2asc USES si di, @@math:WORD, @@chars:WORD
- push ds ; Assume es = ds
- pop es
- mov si, [@@math]
- mov di, [@@chars]
- cld
- lodsw ; Fetch bignum size
- mov cx, ax
- lodsb ; Fetch sign
- test al, 1
- jz @@positive
- mov al, '-' ; first character: minus
- stosb
- @@positive:
- mov bx, 10
- and ax, 1 ; Push 0 or 1 (1 if start with -)
- @@loop:
- push ax
- call divbig
- mov al, dl
- add al, '0'
- stosb
- pop ax ; Increment character counter
- inc ax
- or cx, cx ; Loop until bignum is zeroed
- jnz @@loop
- mov cx, ax
- push ax
- sub di, cx ; Point di to beginning of string
- call reverse
- pop ax ; Restore character count
- ret
- ENDP big2asc
-
- ;************************************************************************
- ;* Divide bignum at ds:si, length cx words, by bx (es=ds) *
- ;************************************************************************
- PROC divbig NEAR
- push cx di
- add si, cx ; Point si to last word (most signif.)
- add si, cx
- sub si, 2
- cmp [si], bx ; Will working length be reduced?
- pushf
- mov di, si ; es:di = ds:si
- std ;Direction backward
- xor dx, dx ; Clear carry in
- @@loop:
- lodsw
- div bx
- stosw
- loop @@loop
- add si, 2 ; Point si again to first word
- popf
- pop di cx
- jae @@nounderflow
- dec cx
- @@nounderflow:
- ret ; Remainder left in dx
- ENDP divbig
-
- ;************************************************************************
- ;* Reverse the string containing cx characters at es:di (es=ds) *
- ;************************************************************************
- PROC reverse NEAR
- cmp [BYTE di], '-'
- jne @@positive
- inc di ; Otherwise, don't include minus in reverse
- dec cx
- @@positive:
- mov si, di ; Point si to last string char
- add si, cx
- dec si
- shr cx, 1 ; Number of switches
- jcxz @@done
- @@loop:
- mov al, [di] ;Exchange outside bytes
- xchg al, [si]
- stosb
- dec si ;Move pointers inward
- loop @@loop
- @@done:
- ret
- ENDP reverse
-
- ;************************************************************************
- ;* Is character a whitespace? *
- ;* Calling sequence: iswhitespace(ch) *
- ;* Where ch = character to check *
- ;* Returns zero iff not a whitespace *
- ;************************************************************************
- PROC C iswhitespace, @@char:WORD
- mov ax, [@@char]
- cmp al, ' '
- je @@isspace
- cmp al, 9
- jb @@isnotspace
- cmp al, 13
- jbe @@isspace
- @@isnotspace:
- xor ax, ax ; Set to zero
- @@isspace:
- ret
- ENDP iswhitespace
-
- END
-
-