home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
mbug
/
mbug103.arc
/
CALL.MAC
< prev
next >
Wrap
Text File
|
1979-12-31
|
9KB
|
459 lines
;
;----- CALL: Small-C arithmetic and logical library
;
CCDCAL::
PCHL
;
CCDDGC::
DAD D
JMP CCGCHAR
;
CCDSGC::
INX H
INX H
DAD SP
;
;FETCH A SINGLE BYTE FROM THE ADDRESS IN HL AND SIGN INTO HL
CCGCHAR::
MOV A,M
;
;PUT THE ACCUM INTO HL AND SIGN EXTEND THROUGH H.
CCARGC::
CCSXT::
MOV L,A
RLC
SBB A
MOV H,A
RET
;
CCDDGI::
DAD D
JMP CCGINT
;
CCDSGI::
INX H
INX H
DAD SP
;
;FETCH A FULL 16-BIT INTEGER FROM THE ADDRESS IN HL INTO HL
CCGINT::
MOV A,M
INX H
MOV H,M
MOV L,A
RET
;
CCDECC::
INX H
INX H
DAD SP
MOV D,H
MOV E,L
CALL CCGCHAR
DCX H
MOV A,L
STAX D
RET
;
CCINCC::
INX H
INX H
DAD SP
MOV D,H
MOV E,L
CALL CCGCHAR
INX H
MOV A,L
STAX D
RET
;
CDPDPC::
DAD D
CCPDPC::
POP B ;RET ADDR
POP D
PUSH B
;
;STORE A SINGLE BYTE FROM HL AT THE ADDRESS IN DE
CCPCHAR::
PCHAR: MOV A,L
STAX D
RET
;
CCDECI::
INX H
INX H
DAD SP
MOV D,H
MOV E,L
CALL CCGINT
DCX H
JMP CCPINT
;
CCINCI::
INX H
INX H
DAD SP
MOV D,H
MOV E,L
CALL CCGINT
INX H
JMP CCPINT
;
CDPDPI::
DAD D
CCPDPI::
POP B ;RET ADDR
POP D
PUSH B
;
;STORE A 16-BIT INTEGER IN HL AT THE ADDRESS IN DE
CCPINT::
PINT: MOV A,L
STAX D
INX D
MOV A,H
STAX D
RET
;
;INCLUSIVE "OR" HL AND DE INTO HL
CCOR::
MOV A,L
ORA E
MOV L,A
MOV A,H
ORA D
MOV H,A
RET
;
;EXCLUSIVE "OR" HL AND DE INTO HL
CCXOR::
MOV A,L
XRA E
MOV L,A
MOV A,H
XRA D
MOV H,A
RET
;
;"AND" HL AND DE INTO HL
CCAND::
MOV A,L
ANA E
MOV L,A
MOV A,H
ANA D
MOV H,A
RET
;
;IN ALL THE FOLLOWING COMPARE ROUTINES, HL IS SET TO 1 IF THE
; CONDITION IS TRUE, OTHERWISE IT IS SET TO 0 (ZERO).
;
;TEST IF HL = DE
;
CCEQ::
CALL CCCMP
RZ
DCX H
RET
;
;TEST IF DE != HL
CCNE::
CALL CCCMP
RNZ
DCX H
RET
;
;TEST IF DE > HL (SIGNED)
CCGT::
XCHG
CALL CCCMP
RC
DCX H
RET
;
;TEST IF DE <= HL (SIGNED)
CCLE::
CALL CCCMP
RZ
RC
DCX H
RET
;
;TEST IF DE >= HL (SIGNED)
CCGE::
CALL CCCMP
RNC
DCX H
RET
;
;TEST IF DE < HL (SIGNED)
CCLT::
CALL CCCMP
RC
DCX H
RET
;
;COMMON ROUTINE TO PERFORM A SIGNED COMPARE OF DE AND HL
; THIS ROUTINE PERFORMS DE - HL AND SETS THE CONDITIONS:
; CARRY REFLECTS SIGN OF DIFFERENCE (SET MEANS DE < HL)
; ZERO/NON-ZERO SET ACCORDING TO EQUALITY.
CCCMP::
MOV A,H ;INVERT SIGN OF HL
XRI 80H
MOV H,A
MOV A,D ;INVERT SIGN OF DE
XRI 80H
CMP H ;COMPARE MSBS
JNZ CCCMP1 ;DONE IF NEQ
MOV A,E ;COMPARE LSBS
CMP L
CCCMP1: LXI H,1 ;PRESET TRUE COND
RET
;
;TEST IF DE >= HL (UNSIGNED)
CCUGE::
CALL CCUCMP
RNC
DCX H
RET
;
;TEST IF DE < HL (UNSIGNED)
CCULT::
CALL CCUCMP
RC
DCX H
RET
;
;TEST IF DE > HL (UNSIGNED)
CCUGT::
XCHG
CALL CCUCMP
RC
DCX H
RET
;
;TEST IF DE <= HL (UNSIGNED)
CCULE::
CALL CCUCMP
RZ
RC
DCX H
RET
;
;COMMON ROUTINE TO PERFORM UNSIGNED COMPARE
; CARRY SET IF DE < HL
; ZERO/NONZERO SET ACCORDINGLY
CCUCMP::
MOV A,D
CMP H
JNZ UCMP1
MOV A,E
CMP L
UCMP1: LXI H,1
RET
;
;SHIFT DE ARITHMETICALLY RIGHT BY HL AND RETURN IN HL
CCASR::
XCHG
DCR E
RM
MOV A,H
RAL
MOV A,H
RAR
MOV H,A
MOV A,L
RAR
MOV L,A
JMP CCASR+1
;
;SHIFT DE ARITHMETICALLY LEFT BY HL AND RETURN IN HL
CCASL::
XCHG
DCR E
RM
DAD H
JMP CCASL+1
;
;SUBTRACT HL FROM DE AND RETURN IN HL
CCSUB::
MOV A,E
SUB L
MOV L,A
MOV A,D
SBB H
MOV H,A
RET
;
;FORM THE TWO'S COMPLEMENT OF HL
CCNEG::
CALL CCCOM
INX H
RET
;
;FORM THE ONE'S COMPLEMENT OF HL
CCCOM::
MOV A,H
CMA
MOV H,A
MOV A,L
CMA
MOV L,A
RET
;
;MULTIPLY DE BY HL AND RETURN IN HL (SIGNED MULTIPLY)
CCMULT::
MULT: 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, REMAINDER IN DE (SIGNED DIVIDE)
CCDIV::
DIV: MOV B,H
MOV C,L
MOV A,D
XRA B
PUSH PSW
MOV A,D
ORA A
CM CCDENEG
MOV A,B
ORA A
CM CCBCNEG
MVI A,16
PUSH PSW
XCHG
LXI D,0
CCDIV1: DAD H
CALL CCRDEL
JZ CCDIV2
CALL CCCMPBCDE
JM CCDIV2
MOV A,L
ORI 1
MOV L,A
MOV A,E
SUB C
MOV E,A
MOV A,D
SBB B
MOV D,A
CCDIV2: POP PSW
DCR A
JZ CCDIV3
PUSH PSW
JMP CCDIV1
CCDIV3: POP PSW
RP
CALL CCDENEG
XCHG
CALL CCDENEG
XCHG
RET
;
;NEGATE THE INTEGER IN DE (INTERNAL ROUTINE)
CCDENEG: MOV A,D
CMA
MOV D,A
MOV A,E
CMA
MOV E,A
INX D
RET
;
;NEGATE THE INTEGER IN BC (INTERNAL ROUTINE)
CCBCNEG: MOV A,B
CMA
MOV B,A
MOV A,C
CMA
MOV C,A
INX B
RET
;
;ROTATE DE LEFT ONE BIT (INTERNAL ROUTINE)
CCRDEL: MOV A,E
RAL
MOV E,A
MOV A,D
RAL
MOV D,A
ORA E
RET
;
;COMPARE BC TO DE (INTERNAL ROUTINE)
CCCMPBCDE: MOV A,E
SUB C
MOV A,D
SBB B
RET
;
;LOGICAL NEGATION
CCLNEG::
MOV A,H
ORA L
JNZ $+6
MVI L,1
RET
LXI H,0
RET
;
; EXECUTE "SWITCH" STATEMENT
;
; HL = SWITCH VALUE
; (SP) -> SWITCH TABLE
; DW ADDR1, VALUE1
; DW ADDR2, VALUE2
; ...
; DW 0
; [JMP default]
; continuation
;
CCSWITCH::
XCHG ;DE = SWITCH VALUE
POP H ;HL -> SWITCH TABLE
SWLOOP: MOV C,M
INX H
MOV B,M ;BC -> CASE ADDR, ELSE 0
INX H
MOV A,B
ORA C
JZ SWEND ;DEFAULT OR CONTINUATION CODE
MOV A,M
INX H
CMP E
MOV A,M
INX H
JNZ SWLOOP
CMP D
JNZ SWLOOP
MOV H,B ;CASE MATCHED
MOV L,C
SWEND: PCHL
;
END