home *** CD-ROM | disk | FTP | other *** search
- ; CALCRCP.Z80 Version 1.0
- ; October 31, 1986 by Carson Wilson.
- ;
- ; Please leave any problems, comments, or suggestions at
- ; Lillipute Z-Node, Chicago, 312-649-1730 or 312-664-1730.
- ;
- ; This is a combination of elements from Paul Pomerleau's
- ; SLTRAP.LBR and Eric Meyer's HP.COM. When assembled into a
- ; Resident Command Package (RCP) for ZCPR3, it becomes a "pop-up"
- ; calculator modelled on the principles of Eric Meyer's HP+.COM
- ; for CP/M Plus.
- ;
- ; To use, first put this file and Z3BASE.LIB for your system on
- ; the current drive and assemble and load to CALC.RCP. Then load
- ; CALC.RCP with LDR.COM. Use the "H" command to display help on
- ; usage. The calculator won't become active until activated by
- ; the command "CALC" from your system's operating system prompt.
- ; Thereafter, whenever a CONTROL-] is detected, the calculator
- ; will become active. The calculator can thus be activated from
- ; the middle of any program which tests for console input, which
- ; means any interactive program.
-
- ; WARNING: BECAUSE THIS RCP LINKS UP WITH YOUR SYSTEM'S BIOS, IT
- ; IS NECESSARY TO TURN IT OFF BY USING THE "CALC" COMMAND AGAIN
- ; BEFORE LOADING ANOTHER RCP.
-
- ; To make the CALC.RCP even more versatile, create an alias named
- ; RCP.COM which will respond to commands to automatically go to
- ; the proper directories, get the proper RCP and load it.
-
- ; For example, my CALC.COM contains the following:
-
- ; IF EX LOAD:$1.RCP
- ; ROOT:LDR LOAD:$1.RCP
- ; FI
- ; H
-
- ; This enables me to type "RCP CALC," thereby commanding my
- ; system to get CALC.RCP from the proper directory, load it, and
- ; display its built-in help. When I'm through with CALC, I first type
- ; CALC to turn it off, then "RCP SYS" to reload my normal RCP.
-
- ; Like HP+.COM, this calculator may not work with a very few
- ; programs such as WordStar, which interact directly with the
- ; BIOS. See HP+.DOC for more on this. For information on how the
- ; calculator works, see HP.DOC by Eric Meyer. Both of these files
- ; are found in HP.LBR.
-
- vers equ 10
- BDOS equ 5
-
- maclib Z3Base.lib ; use base addresses
-
- ;
- ; System entry point
- ;
- org RCP ; Passed from Z3Base
- db 'Z3RCP' ; Flag for package loader
- db 04 ; How long each name is
- ctab:
- db 'H ' ; Help for RCP
- dw CList
- db 'CALC' ; Enable/Disable trigger key
- dw TrigOn
- ctab1:
- db 0
- ;
- ; Banner name of RCP:
- ; Command list routine
- ;
- CList:
- ld de,RCP$name
- jp string
- ;
- ; Routines for trapping I/O.
- ;
- Trigger equ ']'-'@' ; control-] is current trigger key
- ;
- TrigOn: ld a,(IsOn)
- cp 1 ; key detection on?
- jp z,TrigOff ; yes, turn off
- ld a,1 ; no, flip flag to ON
- ld (IsOn),a ; & fall through
- ;
- ; ENABLE Trigger Key Detection
- ;
- ; First, replace BIOS jump to its "console in" routine with jump
- ; to RCP routine, and save the addresses of the BIOS jump and the
- ; routine.
- ;
- ld hl,(1) ; Get boot location
- ld de,07h ; Offset for location of "JP CONIN" in BIOS
- add hl,de ; hl now holds BIOS "jump" location
- ld (JConIn),hl ; Save location for BIOS jp to console in
- ld e,(hl)
- inc hl
- ld d,(hl) ; Move to de
- ld (ConIn),de ; Save BIOS ConIn routine address
- ld de,NewIn
- ld (hl),d ; Replace BIOS "jump" with ours
- dec hl
- ld (hl),e ; Fill our NewIn location in
- ;
- ; Now save the address of the BIOS conout routine.
- ;
- ld hl,(1) ; Get boot location
- ld de,0ah ; Offset for location of "JP CONOUT" in BIOS
- add hl,de ; hl now holds BIOS "jump" location
- ld e,(hl)
- inc hl
- ld d,(hl) ; Move to de
- ld (con),de ; Save BIOS ConOut routine address
- ;
- ld a,(on) ; Is the calculator running?
- or a
- ret nz ; Yes, don't print "Trigger Key Enabled" msg.
- ld de,OnMsg ; Else tell user trigger key activated
- jp string
- ret
- ;
- NewIn: call OrigIn ; Bring key in
- cp Trigger ; Is it the trigger key?
- ret nz ; No - business as usual
- ;
- ld (SavStk),sp ; Yes, run calculator
- ld sp,newstk
- ;
- push ix
- push iy
- push af
- push bc
- push de
- push hl
- ;
- ld a,(on)
- cpl
- ld (on),a ; Flip calculator running flag
- ;
- call TrigOff ; Turn off trigger key detection
- ; and fall through to calculator
-
- ;
- ; ********** Begin Calculator *********
- ;
- ; This is a modified disassembly of HP.COM by Eric Meyer. In place
- ; of the HP prompt, I have substituted a more informative one.
- ; Relative jumps are substituted for absolute ones where possible.
- ; The exit and entry routines have been replaced by my own routines
- ; which appear immediately before and after the calculator routine.
- ; The exit key has been changed from ^C to ^] to maintain
- ; consistency with the trigger key. Finally, direct BIOS calls
- ; replace BDOS calls to conin and conout, and a routine which
- ; replaces echoed characters from BDOS conin is no longer
- ; necessary (commented out).
- ;
- jr start
- signon: db 0dh,'CALC-RCP (^] = Off) '
- db ' ',0
- ld a,(de)
- start: xor a
- ld (r17),a
- s9: ld hl,signon
- call StrOut
- call s2
- ld hl,(r4)
- call s3
- ld hl,r5
- ld b,8 ; Print 8 spaces
- prompt: ld (hl),' '
- inc hl
- dec b
- jr nz,prompt
- ld hl,r5 ; Print prompt "H>"
- call StrOut
- xor a
- ld (r3),a
- getin: call s4 ; Get input from BIOS
- cp Trigger ; RCP trigger key
- jp z,quit ; End program
- cp 1bh
- jp z,esc
- cp '+'
- jp z,plus
- cp '-'
- jp z,minus
- cp '*'
- jp z,times
- cp '^'
- jp z,exp
- cp '/'
- jp z,div
- cp '%'
- jp z,remain
- cp '&'
- jp z,bitand
- cp '|'
- jp z,bitor
- cp '~'
- jp z,negate
- cp 0dh
- jp z,run
- cp 8
- jr z,backsp
- cp '='
- jp z,equals
- cp 18h ; ^X
- jr z,clear
- cp 'S'
- jp z,save
- cp 's'
- jp z,save
- cp 'R'
- jp z,recall
- cp 'r'
- jp z,recall
- cp '!' ; Space or control char?
- jp c,illegal ; Yes - error
- s23: ld hl,r7
- ld de,r5
- ld bc,7
- ldir
- ld (r8),a
- ld a,0ffh
- ld (r3),a
- s8: ld hl,signon ; Reprint prompt
- call StrOut
- call s2
- ld hl,r5
- call StrOut
- jp getin ; Get input
- backsp: ld a,(r3)
- or a
- jr z,s7
- ld hl,r9
- ld de,r8
- ld bc,7
- lddr
- ld a,' '
- ld (r5),a
- jr s8
- s7: ld hl,0
- ld (r4),hl
- ld a,0ffh
- ld (r17),a
- jp s9
- clear: ld hl,r4 ; Clear registers
- ld b,10h ; (16 bytes)
- s10: ld (hl),0
- inc hl
- dec b
- jr nz,s10
- jp s9
- run: call s11
- call s12
- ld a,0ffh
- ld (r17),a
- jp s9
- equals: call s11
- ld hl,(r4)
- ex de,hl
- ld hl,(r10)
- ex de,hl
- ld (r10),hl
- ex de,hl
- ld (r4),hl
- jp start
- negate: call s11
- ld hl,(r4)
- ld a,h
- cpl
- ld h,a
- ld a,l
- cpl
- ld l,a
- inc hl
- ld (r4),hl
- jp start
- bitor: call s11
- call s14
- ld a,h
- or d
- ld h,a
- ld a,l
- or e
- ld l,a
- s16: ld (r10),hl
- call s15
- jp start
- bitand: call s11 ; bitwise and
- call s14
- ld a,h
- and d
- ld h,a
- ld a,l
- and e
- ld l,a
- jr s16
- remain: call s11 ; remainder
- call s14
- call s17
- jp c,s18
- ex de,hl
- jr s16
- div: call s11
- call s14
- call s17
- jp c,s18
- jr s16
- times: call s11
- call s14
- call s19
- jp c,s18
- jr s16
- exp: call s11
- call s14
- ld a,d
- or e
- jr nz,s20
- ld hl,1
- jr s16
- s20: ld b,d
- ld c,e
- ld d,h
- ld e,l
- s21: dec bc
- ld a,b
- or c
- jr z,s16
- push bc
- push de
- call s19
- pop de
- pop bc
- jp c,s18
- jr s21
- minus: call s11
- call s14
- sbc hl,de
- jr s16
- plus: call s11
- call s14
- add hl,de
- jp s16
- save: call s11
- call s4
- cp '4' ; Legal register?
- jp nc,s18
- sub '1' ; Legal register?
- jp c,s18
- add a,a
- ld e,a
- ld d,0
- ld hl,r11
- add hl,de
- ld a,(r4)
- ld (hl),a
- inc hl
- ld a,(r12)
- ld (hl),a
- jp start
- recall: call s11
- call s4
- cp '4'
- jp nc,s18
- sub '1'
- jp c,s18
- add a,a
- ld e,a
- ld d,0
- ld hl,r11
- add hl,de
- ld a,(r17)
- or a
- jr nz,s22
- push hl
- call s12
- pop hl
- s22: ld a,(hl)
- ld (r4),a
- inc hl
- ld a,(hl)
- ld (r12),a
- jp start
- chars: db '+-*^/%&~=|SsRr' ; Legal commands
- esc: call s4
- ld hl,chars
- ld b,0eh
- s24: cp (hl)
- jp z,s23
- inc hl
- dec b
- jr nz,s24
- and 5fh
- push af
- call s11
- pop af
- cp 'H' ; Switch to hex
- jr z,hex
- cp 'D' ; Switch to decimal
- jr z,dec
- cp 'B' ; Switch to binary
- jr z,bin
- cp 'C' ; Switch to character
- jr z,char
- jr s18
- hex: ld hl,s25
- ld de,s26
- jr s27
- dec: ld hl,s28
- ld de,s29
- jr s27
- bin: ld hl,s30
- ld de,s31
- jr s27
- char: ld hl,s32
- ld de,s33
- s27: ld (r13),a
- ld (scale),hl ; Store current scale = hex, dec, etc.
- ex de,hl
- ld (r14),hl
- jp start
- s14: ld hl,(r4)
- ex de,hl
- ld hl,(r10)
- ret
- s11: ld a,(r3)
- or a
- ret z
- ld hl,r5
- call s35
- jr c,s36 ; Illegal - ring bell
- ld a,(r17)
- or a
- jr nz,s37
- push hl
- call s12
- pop hl
- s37: ld (r4),hl
- xor a
- ld (r17),a
- ret
- s36: pop hl
- illegal:ld a,7 ; Ring bell
- call CharOut
- jp s8
- s18: ld a,7
- call CharOut
- jp start
- s15: ld hl,r10
- ld de,r4
- ld bc,0eh
- ldir
- ret
- s12: ld hl,r15
- ld de,r16
- ld bc,0eh
- lddr
- ret
- s2: ld a,(r13)
- call CharOut
- ld a,'>' ; Prompt
- call CharOut
- ld a,' ' ; Prompt: "H> "
- call CharOut
- ret
- s19: ld c,l
- ld b,h
- ld hl,0
- ld a,0fh
- s40: push af
- or d
- jp p,s38
- add hl,bc
- jp c,s39
- s38: add hl,hl
- jp c,s39
- ex de,hl
- add hl,hl
- ex de,hl
- pop af
- dec a
- jr nz,s40
- or d
- ret p
- add hl,bc
- ret
- s17: ld a,e
- or d
- jp z,s41
- ld c,l
- ld b,h
- ld hl,0
- ld a,10h
- or a
- s43: ld (r20),a
- rl c
- rl b
- rl l
- rl h
- ld (r21),hl
- sbc hl,de
- ccf
- jr c,s42
- ld hl,(r21)
- s42: ld a,(r20)
- dec a
- jr nz,s43
- ex de,hl
- rl c
- ld l,c
- rl b
- ld h,b
- or a
- ret
- s35: push hl
- s45: ld a,(hl)
- or a
- jr z,s44
- cp ' '
- jr nz,s44
- ld (hl),'0'
- inc hl
- jr s45
- s44: pop hl
- db 0c3h ; jp
- scale: dw s25 ; Current scale (hex default)
- s25: ld b,04h
- call s46
- call s47
- ret c
- ld d,a
- inc hl
- call s47
- ret c
- ld e,a
- ex de,hl
- or a
- ret
- s47: call s48
- ret c
- rlca
- rlca
- rlca
- rlca
- inc hl
- ld e,a
- call s48
- ret c
- add a,e
- or a
- ret
- s48: ld a,(hl)
- and 7fh
- cp 'A'
- jr c,s49
- and 5fh
- sub 7
- s49: sub '0'
- jp m,s41
- cp 10h
- jr nc,s41
- or a
- ret
- s39: pop bc
- s41: scf
- ret
- s46: ld a,(hl)
- cp '0'
- jr nz,s39
- inc hl
- dec b
- jr nz,s46
- or a
- ret
- s28: ld b,3
- call s46
- ld de,0
- ld bc,2710h ; constant
- call s50
- ld bc,03e8h
- call s50
- ld bc,64h
- call s50
- ld bc,0ah
- call s50
- ld bc,1
- call s50
- ex de,hl
- or a
- ret
- s50: ld a,(hl)
- cp ':'
- jr nc,s39
- sub '0'
- jp m,s39
- ex de,hl
- or a
- s52: jr z,s51
- add hl,bc
- jr c,s39
- dec a
- jr s52
- s51: ex de,hl
- inc hl
- ret
- s30: ld b,0
- ld c,80h
- s56: ld a,(hl)
- inc hl
- cp '0'
- jr z,s53
- cp '1'
- jr z,s54
- jr s41
- s54: ld a,b
- or c
- ld b,a
- s53: ld a,c
- cp 1
- jr z,s55
- rrca
- ld c,a
- jr s56
- s55: ld l,b
- ld h,0
- or a
- ret
- s32: ld b,7
- call s46
- ld a,(hl)
- and 7fh
- ld l,a
- ld h,0
- or a
- ret
- s3: db 0c3h ; jp
- r14: dw s26
- s26: ld b,4
- call s57
- ld a,h
- call s58
- ld a,l
- call s58
- ret
- s58: push af
- and 0f0h
- rra
- rra
- rra
- rra
- call hexout
- pop af
- and 0fh
- call hexout
- ret
- hexout: add a,'0'
- cp ':' ; Arabic number output?
- jp c,CharOut ; Yes
- add a,7 ; No - get char. A-F for hex output
- jp CharOut
- s57: ld a,' '
- call CharOut
- dec b
- jr nz,s57
- ret
- s29: ld b,3
- call s57
- ld c,0
- s74: ld a,h
- cp ''''
- jr c,s60
- jr nz,s61
- ld a,l
- cp 10h
- jr c,s60
- s61: inc c
- ld de,0d8f0h ; Constant
- add hl,de
- jr s74
- s60: ld a,'0'
- add a,c
- call CharOut
- ld c,0
- s63: ld a,h
- cp 3
- jr c,s62
- jr nz,s75
- ld a,l
- cp 0e8h
- jr c,s62
- s75: inc c
- ld de,0fc18h ; Constant
- add hl,de
- jr s63
- s62: ld a,'0'
- add a,c
- call CharOut
- ld c,0
- s66: ld a,h
- or a
- jr nz,s64
- ld a,l
- cp 64h
- jr c,s65
- s64: inc c
- ld de,0ff9ch ;Constant
- add hl,de
- jr s66
- s65: push af
- ld a,'0' ;30h
- add a,c
- call CharOut
- pop af
- ld c,0
- s68: cp 0ah
- jr c,s67
- inc c
- sub 0ah
- jr s68
- s67: push af
- ld a,'0'
- add a,c
- call CharOut
- pop af
- add a,'0'
- call CharOut
- ret
- s31: ld c,80h
- ld b,l
- s70: call s69
- ld a,c
- cp 1
- ret z
- rrca
- ld c,a
- jr s70
- s69: ld a,b
- and c
- ld a,'0'
- jr z,s71
- ld a,'1'
- s71: call CharOut
- ret
- s33: ld b,7
- call s57
- ld a,l
- and 7fh
- cp 7fh
- jr z,s72
- cp ' '
- jr nc,CharOut
- or '@'
- jr s73
- s72: ld a,'?'
- s73: push af
- ld a,8 ; Backspace
- call CharOut
- ld a,5eh
- call CharOut
- pop af
- jr CharOut
- CharOut:
- push bc
- push de
- push hl
- ld c,a ; Put char. in C, and
- call OrigOut ; BIOS console out
- pop hl
- pop de
- pop bc
- ret
- StrOut: xor a ; Print string
- add a,(hl)
- ret z
- push hl
- call CharOut
- pop hl
- inc hl
- jr StrOut
- s4: call OrigIn
- and 7fh ; Strip high bit
- ;
- ; Since we are calling BIOS directly, characters are
- ; no longer echoed to the screen, so they needn't be erased
- ;
- ; cp '!' ; printable character?
- ; ret c ; yes
- ; push af ; no- delete present character
- ; ld a,8 ; backspace
- ; call CharOut
- ; ld a,' ' ; space
- ; call CharOut
- ; pop af
- ;
- ret
- r4: db 0 ; Registers cleared by "^X"
- r12: db 0
- r10: ds 11
- r15: dw 0
- r16: db 0
- ;
- r11: ds 6
- r13: db 'H' ; Hex scale is default
- r5: db 0
- r7: db 0,0,0,0,0
- r9: db 0
- r8: dw 0
- r3: db 0
- r17: db 0
- r20: db 0
- r18: db 0
- r21: dw 0
- ;
- ; ********* End Calculator *********
- ;
-
- quit: ; Turn off calculator
-
- ld a,0dh
- call CharOut ; Print carriage return to indicate
- ; Return to normal
- call TrigOn ; Enable trigger key checking,
- ; now that calculator no longer active.
- ; ; "On" flag tells TrigOn to enable checking
- ld a,(on)
- cpl
- ld (on),a ; Flip calc. running flag to off
- ;
- pop hl ; Restore registers
- pop de
- pop bc
- pop af
- pop iy
- pop ix
- ;
- ld sp,(SavStk) ; Restore stack pointer
- ;
- jp OrigIn ; = Call BIOS ConIn, ret to transient program
- ;
- ;
- TrigOff: ; DISABLE trigger key detection
-
- ld a,(IsOn) ; Is key detection off?
- cp 0
- jp z,TrigOn ; Yes, turn on
- ld a,0 ; No, flip flag and turn it off
- ld (IsOn),a
- ld hl,(JConIn) ; Get place in BIOS to restore jump
- ld de,(ConIn) ; Get location of BIOS routine
- ld (hl),e
- inc hl
- ld (hl),d ; Put in a jp and the location
- ;
- ld a,(on) ; Is calculator running?
- or a
- ret nz ; Yes, just resume key detection,
- ; don't tell user
- ld de,OffMsg ; Tell user trigger key de-activated
- call string
- ret
-
- string: ld c,9
- jp BDOS
- OnMsg:
- db 'Trigger Key Enabled - Disable Before Re-loading RCP.$'
- OffMsg:
- db 'Trigger Key Disabled.$'
- RCP$name:
- db 'CALC-RCP ',(vers/10)+'0'
- db '.0',13,10 ;
- db 'H',13,10
- db 'CALC - Enable/Disable Trigger Key',13,10
- db 'Control-] - Calculator On/Off.$'
- OrigOut:
- db 0c3h ; Jp
- con: dw 0 ; Store BIOS console out routine address
- ;
- IsOn: db 0 ; Trigger-key detection on flag
- ;
- OrigIn:
- db 0c3h ; jp
- ConIn: dw 0 ; Store BIOS console in routine address
- JConIn: dw 0 ; Store BIOS jump to console in address
- ;
- on: db 0 ; Calculator running flag
- ;
- SavStk: ds 2 ; Save incoming stack pointer
- ;
- ds 32
- NewStk equ $ ; Our own stack
-
- ;
- ; Size error test
- ;
- if ($ gt (RCP+RCPs*128-1))
- SizErr equ novalue ; RCP is too large for buffer
- endif
- ;
- end
-
-
- ;
- ; Size error test
- ;
- if ($ gt (RCP+RCPs*128-1))
- SizErr equ noval