A86: Re: GFM Source (fwd)


[Prev][Next][Index][Thread]

A86: Re: GFM Source (fwd)




In answer to TGaArdvark's request (which he mailed me twice in 5 minutes),
here's the GFM source code.  I have ported it to the 86 myself. The I/O
isn't as nice as it was on the 85, but I will enhance it in the future.

Letters:     [ALPHA]<letter> and [2nd][ALPHA]<letter>
Subscripts:  <number>
Parentheses: [(] or [)]
Calculate:   [ENTER]
Quit:        [EXIT]

The answer is displayed without a decimal point, so the GFM for sulfuric
acid (H2S04) displays as 9808, not 98.08.

The limit on GFM is 655.35.  If a molecule is too big, the program will
display "TooBig".

In the future, I will change it so it uses floating-point math and
displays nicely.  I also hope to make use of built-in input routines to
make the program smaller.  Until then, live with this.

--------
Dan Eble (mailto:eble@cis.ohio-state.edu)
         (http://www.cis.ohio-state.edu/~eble)

---------- Forwarded message ----------
Date: Thu, 11 Sep 1997 22:55:22 -0400 (EDT)
From: TGaArdvark@aol.com
To: eble@ticalc.org
Subject: Re: Source

Could you send me the source for GFM. I need it proted to the 86 fast (like
yesterday), and are willing to do it. I'll send a copy when I'm done, but
will not distribute it without prior permission. Thanks.
#INCLUDE "ti86asm.inc"



;-------------------------------------------------------------------------

; Program Data 

;-------------------------------------------------------------------------



NameLength      .equ PROGEND+00h

InputStr        .equ PROGEND+01h

StringPlace     .equ PROGEND+11h

CursorType      .equ PROGEND+18h

ElemStr         .equ PROGEND+19h

Parenthesis     .equ PROGEND+2Bh

TotalGFM        .equ PROGEND+2Ch

PrevGFM         .equ PROGEND+2Eh

Overflow        .equ PROGEND+30h

; .equ PROGEND+31h





;-------------------------------------------------------------------------

; PROGRAM BEGINS HERE

;-------------------------------------------------------------------------



.org _asm_exec_ram



        call _clrLCD



	res 1,(IY+$D)	; don't alter text memory



PreGetSym:

	set 3,(IY+5)	; display white on black

	ld hl, $0000

        ld (_curRow), hl

	ld (TotalGFM), hl

	ld (PrevGFM), hl

        ld hl, TitleStr         ; title

        call _puts

	res 3,(IY+5)	; display black on white



	ld a, 7		; set cursor for input loop

        ld (_curRow), a

	sub a

	ld (NameLength), a

	ld (Overflow), a



	ld a, '('

	ld (Parenthesis), a



        ld a, 223       ; block cursor

	ld (CursorType), a

        call _putc



GetSymLoop:

        call _getkey

        cp kExit        ; EXIT : program done

	ret z

        cp kEnter       ; Enter : input done

        jp z,K_Enter

        cp kLeft        ; Left : backspace

        jp z,K_Left

        cp kLParen      ; if key < '(', don't bother with it

	jr c, GetSymLoop

        cp kz+1         ; if key > 'z', don't bother with it

        jr nc, GetSymLoop

        ld hl, AlphaTable-kLParen

        add a,l         ; look up char in table

        ld l,a

        adc a,h

        sub l

        ld h,a

        ld a, (hl)      ; a = char or 0

        or a            ; save one byte over "cp 0"

	jr z, GetSymLoop

	push af	

	ld a, (NameLength)

        ld (_curCol), a

        ld d,0          ; de = namelength

        ld e,a

	inc a

        cp 15           ; MaxNameLength

	jr nc, NameTooLong

	ld (NameLength), a

	ld hl, InputStr

	add hl, de

	pop af

	push af

	cp '('

	jr nz, NotParenth

	pop af

	ld a, (Parenthesis)

	xor 1

	ld (Parenthesis), a

	xor 1

	push af

NotParenth:

        ld a, 223       ; block cursor

	ld (CursorType), a

	pop af



	ld (hl),a

        call _putc

        ld a, (_curCol)

	push af

	ld a, (CursorType)

        call _putc

	pop af

        ld (_curCol), a

        jp GetSymLoop

NameTooLong:

	pop af

        jp GetSymLoop



K_Left:

	ld a, (NameLength)

        or a            ; save one byte over "cp 0"

        jp z,GetSymLoop

	dec a

	ld (NameLength), a

	ld e, a

	ld d, 0

	push de

        ld (_curCol), a

	ld a, (CursorType)

        call _putc

        ld a, ' '

        call _putc

	pop de

	ld hl, InputStr

	add hl, de

	ld a, (hl)

	and 11111110b

	cp '('

	jr nz, LeftDone

	ld a, (hl)

	ld (Parenthesis), a

LeftDone:

        jp GetSymLoop



K_Enter:

	ld a, (NameLength)

        or a            ; save one byte over "cp 0"

        jp z,GetSymLoop

	push af

        ld (_curCol), a

	ld a, ' '

        call _putc

	pop af

	ld hl, InputStr

	push hl

	ld d, 0

	ld e, a

	add hl, de

	ld (hl), ')'

	inc hl

	ld (hl), ')'

	pop hl		; hl -> InputStr

        call CalcGFM

        ld a, 16

        ld (_curCol), a

	ld a, (Overflow)

        or a            ; save one byte over "cp 0"

	jr z, NoOverflow

        ld a,15

        ld (_curCol),a

        ld hl, TooBig

        call _puts

        jp PreGetSym

NoOverflow:

	ld hl, (TotalGFM)

        sub a

        call $4A33      ; display AHL as decimal number

        jp PreGetSym



;-------------------------------------------------------------------------

; String Data

;-------------------------------------------------------------------------



TooBig: .db "TooBig", 0



;-------------------------------------------------------------------------

; Calculate GFM of ')'-terminated string

;-------------------------------------------------------------------------



CalcGFM:

	push hl

	ld hl, $2020	; two spaces

	ld (ElemStr), hl

	pop hl

	ld a, (hl)

	inc hl

	cp ')'

	ret z

	cp '('

	jr z, RecurseCalc

	cp 128

	jr nc, Subscript

	cp 'A'			; proceed if A...Z

	jr c, CalcGFM

	cp 'Z'+1

	jr nc, CalcGFM

	ld (ElemStr), a

	ld a, (hl)

	cp 'a'			; if not a...z, start calculation

	jr c, StartCalc

	cp 'z'+1

	jr nc, StartCalc

	ld (ElemStr+1), a

	inc hl

StartCalc:

	push hl



; -- get atomic mass in DE



        ld hl, Elements

	ld b, 92	; number of elements

CmpSymLoop:

	ld a, (ElemStr)

	cp (hl)

	inc hl

	jr nz, ThisNoMatch

FirstMatch:

	ld a, (ElemStr+1)

	cp (hl)

	jr z, BothMatch

ThisNoMatch:

	inc hl

	inc hl

	inc hl

	djnz CmpSymLoop

	ld de, 0	; no match

	jr FindDone



BothMatch:

	inc hl		; hl -> atomic weight

	ld e, (hl)	; de = atomic weight

	inc hl

	ld d, (hl)



FindDone:



; -- end of get atomic mass



	ld (PrevGFM), de

StorePrevGFM:

	ld hl, (TotalGFM)

StoreTotalGFM:

	add hl, de

        jp nc,NoOverflow1

	ld a, 1

	ld (Overflow), a

NoOverflow1:

	ld (TotalGFM), hl

	pop hl

	jr CalcGFM



RecurseCalc:

	ld de, (TotalGFM)

	push de

	ld de, 0

	ld (TotalGFM), de

        call CalcGFM

        pop de          ; de = old total

	push hl

	ld hl, (TotalGFM)	; hl = parenthetical total

	ld (PrevGFM), hl

	jr StoreTotalGFM



Subscript:

	sub 128

Subsub:

	ld b, a

	ld a, (hl)

	sub 128

	jr c, EndofSub

	inc hl

	push af

	sla b

	ld a, b

	rlca

	rlca

	add a, b

	pop bc

	add a, b

	jr Subsub

EndofSub:

	ld a, 1

	cp b

        jp nc,CalcGFM   ; if subscript <= 1, go back

	dec b

	ld de, (PrevGFM)

	push hl

	ld hl, 0

MultiplyLoop:

	add hl, de

        jp nc,NoOverflow2

	ld a, 1

	ld (Overflow), a

NoOverflow2:

	djnz MultiplyLoop

	ex de, hl

	jr StorePrevGFM



;-------------------------------------------------------------------------

; Strings

;-------------------------------------------------------------------------



TitleStr: .db " GFM Calculator v1.3 "

          .db " Copr. 1997 Dan Eble ", 0



;-------------------------------------------------------------------------

; Scancode to ASCII translation table

;-------------------------------------------------------------------------



AlphaTable:

; ASCII         ; Scancode : Keysym

.db "("         ; 11h      : kLParen

.db "("         ; 12h      : kRParen

.db 0

.db 0

.db 0

.db 0

.db 0

.db 0

.db 0

.db 0

.db 0

.db 128         ; 1Ch      : k0         ; subscripts

.db 129         ; 1Dh      : k1

.db 130         ; 1Eh      : k2

.db 131         ; 1Fh      : k3

.db 132         ; 20h      : k4

.db 133         ; 21h      : k5

.db 134         ; 22h      : k6

.db 135         ; 23h      : k7

.db 136         ; 24h      : k8

.db 137         ; 25h      : k9

.db 0

.db 0

.db "A"         ; 28h      : kCapA

.db "B"         ; 29h      : kCapB

.db "C"         ; 2Ah      : kCapC

.db "D"         ; 2Bh      : kCapD

.db "E"         ; 2Ch      : kCapE

.db "F"         ; 2Dh      : kCapF

.db "G"         ; 2Eh      : kCapG

.db "H"         ; 2Fh      : kCapH

.db "I"         ; 30h      : kCapI

.db "J"         ; 31h      : kCapJ

.db "K"         ; 32h      : kCapK

.db "L"         ; 33h      : kCapL

.db "M"         ; 34h      : kCapM

.db "N"         ; 35h      : kCapN

.db "O"         ; 36h      : kCapO

.db "P"         ; 37h      : kCapP

.db "Q"         ; 38h      : kCapQ

.db "R"         ; 39h      : kCapR

.db "S"         ; 3Ah      : kCapS

.db "T"         ; 3Bh      : kCapT

.db "U"         ; 3Ch      : kCapU

.db "V"         ; 3Dh      : kCapV

.db "W"         ; 3Eh      : kCapW

.db "X"         ; 3Fh      : kCapX

.db "Y"         ; 40h      : kCapY

.db "Z"         ; 41h      : kCapZ

.db "a"         ; 42h      : ka

.db "b"         ; 43h      : kb

.db "c"         ; 44h      : kc

.db "d"         ; 45h      : kd

.db "e"         ; 46h      : ke

.db "f"         ; 47h      : kf

.db "g"         ; 48h      : kg

.db "h"         ; 49h      : kh

.db "i"         ; 4Ah      : ki

.db "j"         ; 4Bh      : kj

.db "k"         ; 4Ch      : kk

.db "l"         ; 4Dh      : kl

.db "m"         ; 4Eh      : km

.db "n"         ; 4Fh      : kn

.db "o"         ; 50h      : ko

.db "p"         ; 51h      : kp

.db "q"         ; 52h      : kq

.db "r"         ; 53h      : kr

.db "s"         ; 54h      : ks

.db "t"         ; 55h      : kt

.db "u"         ; 56h      : ku

.db "v"         ; 57h      : kv

.db "w"         ; 58h      : kw

.db "x"         ; 59h      : kx

.db "y"         ; 5Ah      : ky

.db "z"         ; 5Bh      : kz



;-------------------------------------------------------------------------

; Element Strings

;-------------------------------------------------------------------------



Elements:

.db "H "

.dw 101

.db "He"

.dw 400

.db "Li"

.dw 694

.db "Be"

.dw 901

.db "B "

.dw 1081

.db "C "

.dw 1201

.db "N "

.dw 1401

.db "O "

.dw 1600

.db "F "

.dw 1900

.db "Ne"

.dw 2018

.db "Na"

.dw 2299

.db "Mg"

.dw 2431

.db "Al"

.dw 2698

.db "Si"

.dw 2809

.db "P "

.dw 3097

.db "S "

.dw 3206

.db "Cl"

.dw 3545

.db "Ar"

.dw 3995

.db "K "

.dw 3910

.db "Ca"

.dw 4008

.db "Sc"

.dw 4496

.db "Ti"

.dw 4790

.db "V "

.dw 5094

.db "Cr"

.dw 5200

.db "Mn"

.dw 5494

.db "Fe"

.dw 5584

.db "Co"

.dw 5893

.db "Ni"

.dw 5871

.db "Cu"

.dw 6354

.db "Zn"

.dw 6537

.db "Ga"

.dw 6972

.db "Ge"

.dw 7259

.db "As"

.dw 7492

.db "Se"

.dw 7896

.db "Br"

.dw 7991

.db "Kr"

.dw 8380

.db "Rb"

.dw 8547

.db "Sr"

.dw 8762

.db "Y "

.dw 8891

.db "Zr"

.dw 9122

.db "Nb"

.dw 9291

.db "Mo"

.dw 9594

.db "Tc"

.dw 9800

.db "Ru"

.dw 10107

.db "Rh"

.dw 10291

.db "Pd"

.dw 10645

.db "Ag"

.dw 10787

.db "Cd"

.dw 11240

.db "In"

.dw 11482

.db "Sn"

.dw 11869

.db "Sb"

.dw 12175

.db "Te"

.dw 12760

.db "I "

.dw 12690

.db "Xe"

.dw 13130

.db "Cs"

.dw 13291

.db "Ba"

.dw 13734

.db "La"

.dw 13891

.db "Ce"

.dw 14012

.db "Pr"

.dw 14091

.db "Nd"

.dw 14424

.db "Pm"

.dw 14700

.db "Sm"

.dw 15035

.db "Eu"

.dw 15196

.db "Gd"

.dw 15725

.db "Tb"

.dw 15892

.db "Dy"

.dw 16250

.db "Ho"

.dw 16493

.db "Er"

.dw 16726

.db "Tm"

.dw 16893

.db "Yb"

.dw 17304

.db "Lu"

.dw 17497

.db "Hf"

.dw 17849

.db "Ta"

.dw 18095

.db "W "

.dw 18385

.db "Re"

.dw 18625

.db "Os"

.dw 19025

.db "Ir"

.dw 19225

.db "Pt"

.dw 19509

.db "Au"

.dw 19697

.db "Hg"

.dw 20059

.db "Tl"

.dw 20437

.db "Pb"

.dw 20719

.db "Bi"

.dw 20898

.db "Po"

.dw 21000

.db "At"

.dw 21000

.db "Rn"

.dw 22200

.db "Fr"

.dw 22300

.db "Ra"

.dw 22600

.db "Ac"

.dw 22700

.db "Th"

.dw 23204

.db "Pa"

.dw 23100

.db "U "

.dw 23803



PROGEND: ; There should be nothing after this label



.end