.z80 ;use z80 mode ; ;********************************************* ;* Small Example using STRU * ;* by Rolf-Dieter Klein 821229 1.0 * ;********************************************* ; a small pocket calculator ; ; jp start ;start main program ; bdos equ 5 ;cp/m entry point ; procedures for the calculator ; ci: ;get byte from console to akku push hl ;save all registers push de push bc ld c,1 ;ci function call bdos pop bc pop de pop hl ret ;result in akku co: ;put byte to console push hl ;value in c register push de push bc ld e,c ld c,2 call bdos pop bc pop de pop hl ret ; ; print: ;print a string till 0 ;start adress at -> HL ;1 while (hl)<>0 .L1: LD A,(hl) OR A JP Z,.L2 ld c,(hl) call co inc hl ;1 endwhile JP .L1 .L2: ret ; ; getnum: ;get dezimal or hex number ;$FF or 12333 are valid numbers ;hl is result ;carry means no value is valid ld a,0 ld (flag),a ;no sign ld hl,0 ;initial value call ci ;get first value ;1 if a = '-' ;negative sign CP '-' JP NZ,.L3 ld a,1 ld (flag),a call ci ;get next ;1 endif .L3: ;1 if a = '$' ;is it a hex value ? CP '$' JP NZ,.L4 call ci ;2 if not a in ['0'..'9','A'..'F','a'..'f'] CP '9'+1 JR NC,.L6 CP '0'+0 JP NC,.L5 .L6: CP 'F'+1 JR NC,.L7 CP 'A'+0 JP NC,.L5 .L7: CP 'f'+1 JR NC,.L8 CP 'a'+0 JP NC,.L5 .L8: scf ;error exit no hex number ;3 exit RET ;2 endif .L5: ;2 while a in ['0'..'9','A'..'F','a'..'f'] .L9: CP '9'+1 JR NC,.L12 CP '0'+0 JP NC,.L11 .L12: CP 'F'+1 JR NC,.L13 CP 'A'+0 JP NC,.L11 .L13: CP 'f'+1 JR NC,.L14 CP 'a'+0 JP NC,.L11 .L14: JP .L10 .L11: add hl,hl ;hl * 16 add hl,hl add hl,hl add hl,hl ;3 if a in ['A'..'F'] CP 'F'+1 JR NC,.L17 CP 'A'+0 JP NC,.L16 .L17: JP .L15 .L16: sub 'A' add a,10 ;3 else JP .L18 .L15: ;4 if a in ['a'..'f'] CP 'f'+1 JR NC,.L21 CP 'a'+0 JP NC,.L20 .L21: JP .L19 .L20: sub 'a' add a,10 ;4 else JP .L22 .L19: sub '0' ;4 endif .L22: ;3 endif .L18: and 0fh ld e,a ld d,0 add hl,de ;result + new digit call ci ;2 endwhile JP .L9 .L10: ;1 else JP .L23 .L4: ;2 if not a in ['0'..'9'] CP '9'+1 JR NC,.L25 CP '0'+0 JP NC,.L24 .L25: scf ;error was no digit ;3 exit ;leave procedure RET ;2 endif .L24: ;2 while a in ['0'..'9'] .L26: CP '9'+1 JR NC,.L29 CP '0'+0 JP NC,.L28 .L29: JP .L27 .L28: ld d,h ld e,l ;multiply hl with 10 add hl,hl add hl,hl add hl,de ;*5 add hl,hl ;*10 and 0fh ;digit ld e,a ld d,0 add hl,de ;result value call ci ;2 endwhile JP .L26 .L27: ;1 endif .L23: push af ;save terminator ld a,(flag) ;1 if a>0 CP 0 JP Z,.L30 JP C,.L30 ld de,0 ex de,hl xor a sbc hl,de ;complement ;1 endif .L30: pop af scf ccf ;hl = value ret ;no carry akku=terminator hexout: ;prints hl in hex ld a,h call nibble ld a,l nibble: push af rrca rrca rrca rrca and 0fh call hexdigit pop af and 0fh hexdigit: ;1 if a in [10..15] CP 15+1 JR NC,.L33 CP 10+0 JP NC,.L32 .L33: JP .L31 .L32: sub 10 add a,'A' ;1 else JP .L34 .L31: add a,'0' ;1 endif .L34: ld c,a call co ret ; ; dezout: ;prints hl in dez ld c,0 push bc ;save flag on stack bit 7,h ;1 if nz JP Z,.L35 ld c,'-' call co ld de,0 ex de,hl xor a sbc hl,de ;complement if negative ;1 endif .L35: ; ;1 repeat .L36: ; hl := hl div 10 ; a := hl mod 10 ld a,0 ;overflow ;2 do b,16 ;for each bit LD b,16 .L37: sla l rl h rl a cp 10 ;div 10 ;3 if nc JP C,.L38 sub 10 set 0,l ;3 endif .L38: ;2 enddo DEC B JP NZ,.L37 add a,'0' ld c,a push bc ;save it ;1 until h=0 and l=0 LD A,h OR A JP NZ,.L36 LD A,l OR A JP NZ,.L36 pop bc ;1 while c<>0 .L39: LD A,c OR A JP Z,.L40 call co pop bc ;1 endwhile JP .L39 .L40: ret txt1: defm 'Pocket-Hex Calculator' defb 0dh,0ah defm 'Written in STRU by Rolf-D.Klein ' defb 0dh,0ah,0 txt2: defb 0dh,0ah defm 'Enter Formula ->' defb 0 ; start start: ld hl,txt1 call print ;1 loop PUSH HL LD HL,.L41 EX (SP),HL .L42: ld hl,txt2 call print call getnum ;2 exitif a = 3 ;CTRL-C stops CP 3 RET Z ;2 while a in ['+','-'] .L43: CP '+' JP Z,.L45 CP '-' JP Z,.L45 JP .L44 .L45: ;3 if a = '+' CP '+' JP NZ,.L46 push hl call getnum ;4 exitif a = 3 CP 3 RET Z pop de add hl,de ;3 else JP .L47 .L46: push hl call getnum ;4 exitif a = 3 CP 3 RET Z pop de push af xor a ex de,hl sbc hl,de pop af ;3 endif .L47: ;2 endwhile JP .L43 .L44: ld c,' ' call co call hexout ld c,' ' call co call dezout ;1 endloop JP .L42 .L41: call 0 ;warm boot ; flag: defb 0 ;ram zell end start