📄 util.asm
字号:
; On Exit:
; Acc Has Entry Value Converted To BCD
;
; Affected:
; PSW.CY, PSW.Z, PSW.P, Acc
;
; Stack:
; 1 Bytes, Not Including Space Used By Called Routines
;
; Comments:
; Values Greater Than 99 Will Not Work Properly.
;
UTIL_BINTOBCD proc
push b ; Save B
mov b,#10 ; Divide By 10
div ab ; Do Divide
swap a ; Move Result To High Of A
orl a,b ; OR In Remainder
pop b ; Recover B
ret ; Return To Caller
endproc
;
;****************************************************************************
;
; Description:
; Convert Value In Acc From Hex To BCD.
;
; Entry Requirements:
; Acc Has Value To Convert To BCD
;
; On Exit:
; DPTR Has Value Of Acc In BCD
;
; Affected:
; PSW.CY, PSW.Z, PSW.P, Acc, DPTR
;
; Stack:
; 2 Bytes, Not Including Space Used By Called Routines
;
; Comments:
; Values Greater Than 255 Will Not Work Properly. If Acc == 12, DPTR
; == 0012. If Acc = 255, DPTR = 0255.
;
UTIL_BINTOBCD12 proc
push b ; Save B
push acc ; Save Acc
mov b,#100 ; Divide By 100
div ab ; Do Divide
mov dph,a ; Store In DPH
pop acc ; Recover Acc
mov b,#10 ; Divide By 10
div ab ; Do Divide
swap a ; Move Result To High Of A
orl a,b ; OR In Remainder
mov dpl,a ; Move To DPL
pop b ; Recover B
ret ; Return To Caller
endproc
;
;****************************************************************************
;
; Description:
; Convert 16 Bit Binary Value In DPTR To A Signed Decimal Number String.
;
; Entry Requirements:
; DPTR Has Value To Print As A Signed Decimal Number In External Memory
;
; On Exit:
; DPTR Points To Start Of Printable String
;
; Affected:
; PSW.Z, PSW.P, Acc
;
; Stack:
; 11 Bytes, Not Including Space Used By Called Routines
;
; Comments:
; Buffer Is In External Memory, And Needs 7 Bytes (Sign, Plus 5 Digits
; Plus ETX Terminator). Buffer Is Defined At The End Of The File.
; The Return String Is ETX Terminated. Since Result Is Returned In
; Buffer, It Will Need To Be Copied Or Saved If Additional Calls Are
; Made, Since The Buffer Will Be Overwritten.
;
UTIL_BINTODEC proc
push psw ; Save PSW
push 0 ; Save R0
push 1 ; Save R1
push 2 ; Save R2
push 3 ; Save R3
push 4 ; Save R4
push 5 ; Save R5
push 6 ; Save R6
push 7 ; Save R7
;
mov r6,dph ; Store High In R6
mov r7,dpl ; Store Low In R7
mov dptr,#X_BUFFER ; Point To Buffer
;
mov a,r6 ; Get High Of Value
jnb acc.7,l?p1 ; If <= 32767, Skip
clr c ; Clear For SUBB
clr a ; Clear For SUBB
subb a,r7 ; Subtract Low
mov r7,a ; Move Back
clr a ; Clear For SUBB
subb a,r6 ; Subtract High
mov r6,a ; Move Back
mov a,#'-' ; Number Is Negative
movx @dptr,a ; Store Sign
inc dptr ; Next Location
;
; DPTR Contains Value From 0..32767.
;
l?p1 mov r0,#high 10000 ; 10^5
mov r1,#low 10000 ; 10^5
clr f0 ; Haven't Stored Non-0 Value
;
; R0/R1 Now Has Factor
;
l?p2 mov r2,6 ; Get Value To R2
mov r3,7 ; Get Value To R3
mov r4,0 ; Get Factor
mov r5,1 ; Get Factor
call UTIL_UDIV ; Divide Value By Factor
mov r6,4 ; Store Remainder High
mov r7,5 ; Store Remainder Low
;
; Quotient In R4/R5 Should Be In 0..9 Range. If 0, Don't Store Unless We've
; Stored A Previous Non-Zero Value
;
mov a,r3 ; Get Low Of Quotient
jnz l?p3 ; If Not 0, Store It
jnb f0,l?p4 ; If No Non-0 Before, Don't Store
l?p3 setb f0 ; Non-0 Value
call UTIL_BINTOASC ; Make Printable
movx @dptr,a ; Store Character
inc dptr ; Next Location
;
; Now Divide Factor By 10 For Next Time
;
l?p4 mov r2,0 ; Get Factor
mov r3,1 ; Get Factor
mov r4,#high 10 ; 10
mov r5,#low 10 ; 10
call UTIL_UDIV ; Factor = Factor / 10
mov r0,2 ; Update Factor High
mov r1,3 ; Update Factor Low
;
mov a,r0 ; Get Factor High
orl a,r1 ; OR In Factor Low
jnz l?p2 ; If Not 0, Repeat
;
; Store The End Of String Marker And Print
;
jb f0,l?p5 ; If We've Stored A Number, Skip
mov a,#'0' ; Put At Least 1 Zero
movx @dptr,a ; Store It
inc dptr ; Next Location
l?p5 mov a,#ETX ; End Of String Marker
movx @dptr,a ; Store It
;
; Now Return Pointer To Buffer
;
mov dptr,#X_BUFFER ; Point To Print Buffer
;
; Recover Registers And Exit
;
pop 7 ; Recover R7
pop 6 ; Recover R6
pop 5 ; Recover R5
pop 4 ; Recover R4
pop 3 ; Recover R3
pop 2 ; Recover R2
pop 1 ; Recover R1
pop 0 ; Recover R0
pop psw ; Recover PSW
ret ; Return To Caller
endproc
;
;****************************************************************************
;
; Description:
; Convert Hexadecimal Value In DPTR As A Unsigned Decimal Number.
; Convert 16 Bit Binary Value In DPTR To An Unsigned Decimal Number
; String.
;
; Entry Requirements:
; DPTR Has Value To Print As An UnsSigned Decimal Number In External
; Memory
;
; On Exit:
; DPTR Points To Start Of Printable String
;
; Affected:
; PSW.Z, PSW.P, Acc
;
; Stack:
; 11 Bytes, Not Including Space Used By Called Routines
;
; Comments:
; Buffer Is In External Memory, And Needs 7 Bytes (Sign, Plus 5 Digits
; Plus ETX Terminator). Buffer Is Defined At The End Of The File.
; The Return String Is ETX Terminated. Since Result Is Returned In
; Buffer, It Will Need To Be Copied Or Saved If Additional Calls Are
; Made, Since The Buffer Will Be Overwritten.
;
UTIL_BINTOUDEC proc
push psw ; Save PSW
push 0 ; Save R0
push 1 ; Save R1
push 2 ; Save R2
push 3 ; Save R3
push 4 ; Save R4
push 5 ; Save R5
push 6 ; Save R6
push 7 ; Save R7
;
mov r6,dph ; Store High In R6
mov r7,dpl ; Store Low In R7
mov dptr,#X_BUFFER ; Point To Buffer
;
l?p1 mov r0,#high 10000 ; 10^5
mov r1,#low 10000 ; 10^5
clr f0 ; Haven't Stored Non-0 Value
;
; R0/R1 Now Has Factor
;
l?p2 mov r2,6 ; Get Value To R2
mov r3,7 ; Get Value To R3
mov r4,0 ; Get Factor
mov r5,1 ; Get Factor
call UTIL_UDIV ; Divide Value By Factor
mov r6,4 ; Store Remainder High
mov r7,5 ; Store Remainder Low
;
; Quotient In R4/R5 Should Be In 0..9 Range. If 0, Don't Store Unless We've
; Stored A Previous Non-Zero Value
;
mov a,r3 ; Get Low Of Quotient
jnz l?p3 ; If Not 0, Store It
jnb f0,l?p4 ; If No Non-0 Before, Don't Store
l?p3 setb f0 ; Non-0 Value
call UTIL_BINTOASC ; Make Printable
movx @dptr,a ; Store Character
inc dptr ; Next Location
;
; Now Divide Factor By 10 For Next Time
;
l?p4 mov r2,0 ; Get Factor
mov r3,1 ; Get Factor
mov r4,#high 10 ; 10
mov r5,#low 10 ; 10
call UTIL_UDIV ; Factor = Factor / 10
mov r0,2 ; Update Factor High
mov r1,3 ; Update Factor Low
;
mov a,r0 ; Get Factor High
orl a,r1 ; OR In Factor Low
jnz l?p2 ; If Not 0, Repeat
;
; Store The End Of String Marker And Print
;
jb f0,l?p5 ; If We've Stored A Number, Skip
mov a,#'0' ; Put At Least 1 Zero
movx @dptr,a ; Store It
inc dptr ; Next Location
l?p5 mov a,#ETX ; End Of String Marker
movx @dptr,a ; Store It
;
; Now Return Pointer To Buffer
;
mov dptr,#X_BUFFER ; Point To Print Buffer
;
; Recover Registers And Exit
;
pop 7 ; Recover R7
pop 6 ; Recover R6
pop 5 ; Recover R5
pop 4 ; Recover R4
pop 3 ; Recover R3
pop 2 ; Recover R2
pop 1 ; Recover R1
pop 0 ; Recover R0
pop psw ; Recover PSW
ret ; Return To Caller
endproc
;
;****************************************************************************
;
; Description:
; Acc Contains An ASCII Value. Determine If Valid Decimal DigitOr Not.
; If Not, Return Acc Trashed, And CY == 1. If Digit Is Valid, Return
; CY == 0.
;
; Entry Requirements:
; Acc Has ASCII Decimal Value To Validate
;
; On Exit:
; CY == 0 If Acc = '0'..'9', CY == 1 If Not
;
; Affected:
; PSW.CY
;
; Stack:
; 2 Bytes, Not Including Space Used By Called Routines
;
; Comments:
; None
;
UTIL_VALDCDG proc
call UTIL_TOUPPER ; Make Upper Case
cjlt a,#'0',l?p1 ; If < '0', Return CY == 1
cjgt a,#'9',l?p1 ; If > '9', Return CY == 1
clr c ; CY == 0 Means Good Digit
ret ; Return To Caller
;
l?p1 setb c ; CY == 1 Means Bad Digit
ret ; Return To Caller
endproc
;
;****************************************************************************
;
; Description:
; Acc Contains An ASCII Value. Determine If Valid Hex Digit Or Not.
; If Not, Return Acc Trashed, And CY == 1. If Digit Is Valid, Return
; CY == 0.
;
; Entry Requirements:
; Acc Has ASCII Hex Value To Validate
;
; On Exit:
; CY == 0 If Acc = '0'..'9', 'a'..'f', 'A'..'F', CY == 1 If Not
;
; Affected:
; PSW.CY
;
; Stack:
; 2 Bytes, Not Including Space Used By Called Routines
;
; Comments:
; None
;
UTIL_VALHXDG proc
call UTIL_TOUPPER ; Make Upper Case
cjlt a,#'0',l?p2 ; If < '0', Return CY == 1
cjle a,#'9',l?p1 ; If <= '9', Return CY == 0
cjlt a,#'A',l?p2 ; If < 'A', Return CY == 1
cjgt a,#'F',l?p2 ; If > 'F', Return CY == 1
;
l?p1 clr c ; CY == 0 Means Good Digit
ret ; Return To Caller
;
l?p2 setb c ; CY == 1 Means Bad Digit
ret ; Return To Caller
endproc
;
;****************************************************************************
;
; Description:
; Acc Has Character To Be Validate For A..Z, a..z, 0..9 Range.
;
; Entry Requirements:
; Acc Has Character To Validate As A..Z, a..z, 0..9 Range
;
; On Exit:
; Return CY == 0 If Character In Range, Else Return CY == 1.
;
; Affected:
; PSW.CY
;
; Stack:
; 2 Bytes, Not Including Space Used By Called Routines
;
; Comments:
; None
;
UTIL_VALALPHA proc
call UTIL_TOUPPER ; Make Upper Case
cjlt a,#'0',l?p2 ; If < '0', Return CY == 1
cjle a,#'9',l?p1 ; If <= '9', Return CY == 0
cjlt a,#'A',l?p2 ; If < 'A', Return CY == 1
cjgt a,#'Z',l?p2 ; If > 'Z', Return CY == 1
;
l?p1 clr c ; CY == 0 Means Good Character
ret ; Return To Caller
;
l?p2 setb c ; CY == 1 Means Bad Character
ret ; Return To Caller
endproc
;
;****************************************************************************
;
; Description:
; DPTR Points To An ETX Terminated String In External Memory. Verify
; That Characters In String Are A..Z, a..z, 0..9.
;
; Entry Requirements:
; DPTR Points To An ETX Terminated String To Search
;
; On Exit:
; CY == 0 If No Other Characters, DPTR Points To ETX
; CY == 1 If Non A..Z, a..z, 0..9 Characters, DPTR Points To Bad Character
;
; Affected:
; PSW.CY, DPTR
;
; Stack:
; 3 Bytes, Not Including Space Used By Called Routines
;
; Comments:
; None
;
UTIL_VALALPHAZ proc
push acc ; Save Acc
l?p1 movx a,@dptr ; Get Character
cjeq a,#ETX,l?p2 ; Exit Of End Of String (CY=0)
call UTIL_VALALPHA ; Validate Character
jc l?p2 ; If Error, Exit
inc dptr ; Next Character
jmp l?p1 ; Continue
l?p2 pop acc ; Recover Acc
ret ; Return To Caller
endproc
;
;****************************************************************************
;
; Description:
; DPTR Points To An ETX Terminated String In External Memory. Count
; The Number Of ASCII Digits In The String. If The Number Of Digits
; Exceeds 255, Return CY == 1, Else Return Digit Count In Acc And
; CY == 0. DPTR Is Modified.
;
; Entry Requirements:
; DPTR Points To ETX Terminated String In External Memory
;
; On Exit:
; CY == 0, Acc Has Number Of Digits ('0'..'9') Found
; CY == 1, Number Of Digits Found Exceeds 255
; DPTR Points To ETX
;
; Affected:
; PSW.CY, PSW.Z, PSW.P, Acc, DPTR
;
; Stack:
; 1 Bytes, Not Including Space Used By Called Routines
;
; Comments:
; None
;
UTIL_CNTDG proc
push 0 ; Save R0
mov r0,#0 ; Clear Counter
l?p1 movx a,@dptr ; Get Character
cjeq a,#ETX,l?p2 ; Exit If End Of String
inc dptr ; Next Character
cjlt a,#'0',l?p1 ; Skip If < '0'
cjgt a,#'9',l?p1 ; Skip If > '9'
inc r0 ; Increment Counter
mov a,r0 ; Get Counter
jnz l?p1 ; Repeat Count
setb c ; Too Many Digits
pop 0 ; Recover R0
ret ; Return To Caller
;
l?p2 mov a,r0 ; Get Count To Acc
clr c ; Clear For No Error
pop 0 ; Recover R0
ret ; Return To Caller
endproc
;
;****************************************************************************
;
; Description:
; Unsigned Divide Of R2/3 By R4/5
;
; Entry Requirements:
; Divisor In R4/5
; Dividend In R2/3
;
; On Exit:
; Quotient In R2/3
; Remainder In R4/5
;
; Affected:
; PSW.CY, PSW.Z, PSW.P, Acc, B, R2, R3, R4, R5
;
; Stack:
; 4 Bytes, Not Including Space Used By Called Routines
;
; Comments:
; None
;
UTIL_UDIV proc
push 0 ; Save R0
push 1 ; Save R1
call DIVIDE ; Divide
pop 1 ; Recover R1
pop 0 ; Recover R0
ret ; Return To Caller
endproc
;
;****************************************************************************
;
; Description:
; Unsigned Modulus Of R2/3 By R4/5
;
; Entry Requirements:
; Divisor In R4/5
; Dividend In R2/3
;
; On Exit:
; Remainder In R4/5, R2/3
;
; Affected:
; PSW.CY, PSW.Z, PSW.P, Acc, B, R2, R3, R4, R5
;
; Stack:
; 4 Bytes, Not Including Space Used By Called Routines
;
; Comments:
; None
;
UTIL_UMOD proc
push 0 ; Save R0
push 1 ; Save R1
call DIVIDE ; Divide
pop 1 ; Recover R1
pop 0 ; Recover R0
mov 2,r4 ; Get Remainder High To R2
mov 3,r5 ; Get Remainder Low To R2
ret ; Return To Caller
endproc
;
;****************************************************************************
;
; Description:
; Signed Modulus Of R2/3 By R4/5
;
; Entry Requirements:
; Divisor In R4/5
; Dividend In R2/3
;
; On Exit:
; Remainder In R2/3
;
; Affected:
; PSW.CY, PSW.Z, PSW.P, Acc, B, R2, R3, R4, R5
;
; Stack:
; 4 Bytes, Not Including Space Used By Called Routines
;
; Comments:
; Swiped From A Now Defunct 'C' Compiler
;
UTIL_MOD proc
push 0
push 1
mov a,r4
xrl a,r2
push acc
call NEGEM
call DIVIDE
mov 2,r4
mov 3,r5
pop acc
jnb acc.7,l?p1
clr a
clr c
subb a,r3
mov r3,a
clr a
subb a,r2
mov r2,a
l?p1 pop 1
pop 0
ret
endproc
;
;****************************************************************************
;
; Description:
; Signed Divide Of R2/3 By R4/5
;
; Entry Requirements:
; Divisor In R4/5
; Dividend In R2/3
;
; On Exit:
; Quotient In R2/3
; Remainder In R4/5
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -