home *** CD-ROM | disk | FTP | other *** search
Text File | 1987-09-02 | 14.3 KB | 1,156 lines |
-
- LIST C,P ; For Z1 assembler, generates .COM file
- ; directly in a single pass.
- ;
- ; revised 9-2-87: IEEE revised format notes 24 Oct 1986
- ;
- ; by Neil R. Koozer
- ; Kellogg Star Rt. Box 125
- ; Oakland, OR 97462
- ;
- ; This code is hereby released to the public domain for unrestricted
- ; usage. The only thing you may not do is to copyright it as your own
- ; or restrict its unlimited usage in any way.
- ;
- ; This file assembles under Z1.COM (public domain assembler). To assem-
- ; ble, type:
- ; B>Z1 ZMATH
- ;
- ; The 2-character symbols starting with $ are psuedo-labels used in the
- ; single-pass assembler Z1.COM. The psuedo-labels $A thru $Z are re-
- ; usable local labels for forward references only. $_ is similar but
- ; with a nesting behavior. The rest of the psuedo-labels ($1, $@, etc)
- ; are for backward references only.
- ;
- ; The three principal routines, MULT, DIV, and SQRT, illustrate fast Z80
- ; code for double precision floating point operations. These routines
- ; use more memory than is customary in order to achieve high speed. The
- ; example drivers at the end of this file illustrate how to call the
- ; floating point routines.
- ;
- ; revised IEEE double precision format (8 bytes):
- ;
- ; byte 0 low exponent (bias 03FFh)
- ; byte 1, bits 0 to 2 high exponent (bias 03FFfh), 11 bit exponent
- ; bits 3 to 7 least significant mantissa
- ; byte 2 lleast significant+1 mantissa
- ; ... increasingly significant mantissi
- ; byte 7, bits 0 to 6 most significant mantissa, implicit (base 2) 0.1
- ; assumed
- ; bit 7 sign bit
- ;
- ; 15 or 16 decimal digits precision
- ; range: 4.19 * 10^-307 <= n <= 1.67 * 10^+308
- ;
- ;examples:
- ; 0 all 64 bits 0
- ; 1 00 04 00 00 00 00 00 00
- ; -1 00 04 00 00 00 00 00 80
- ; +2 01 04 00 ...
- ; -2 01 04 00 00 00 00 00 80
- ; +3 01 04 00 00 00 00 00 40
- ; -3 01 04 00 00 00 00 00 c0
- ; 4 02 04 00 ...
- ; 5 02 04 00 00 00 00 00 20
- ; 6 02 04 00 00 00 00 00 40
- ; 7 02 04 00 00 00 00 00 60
- ; 8 03 04 00 ...
- ; 9 03 04 00 00 00 00 00 10
- ; 10 03 04 00 00 00 00 00 20
- ;
- ;
- ORG 100H
- ;
- OPER1 DW 0 ; Force the following DS's to be stored
- DS 6 ; in the .COM file
- OPER2 DS 8
- RESULT DS 8
- SIGN DS 1
- NORM DS 1
- SAVESP DS 2
-
- ; The routines MUL8, MUL16, MUL32, DIV8, DIV16, DIV32, and DIV56 are for
- ; multiplying and dividing binary fractions (as opposed to binary
- ; integers).
- ;
- MUL8 XOR A ; H = H * D
- LD B,8
- ;
- $1 RR H
- JR NC,$A
- ADD A,D
- ;
- $A RRA
- DJNZ $1
- LD H,A
- RET NC
- INC H ; Round
- RET
- ;
- MUL16 LD C,H ; HL = HL * DE
- LD A,L
- LD HL,0
- CALL $+4
- LD A,C
- ;
- M1 LD B,8
- ;
- $1 RRA
- JR NC,$+3
- ADD HL,DE
- RR H
- RR L
- DJNZ $1
- RET NC
- INC HL ; Round
- RET
- ;
- MUL32 LD C,H ; HL,HL' = HL,HL' * DE,DE'
- LD A,L
- EX AF,AF'
- LD HL,0
- EXX
- LD C,H
- LD A,L
- LD HL,0
- EXX
- CALL M1
- EXX
- LD A,C
- EXX
- CALL $_
- EX AF,AF'
- CALL $_
- LD A,C
- ;
- $_ LD B,8
- ;
- $2 RRA
- JR NC,$A
- EXX
- ADD HL,DE
- EXX
- ADC HL,DE
- ;
- $A RR H
- RR L
- EXX
- RR H
- RR L
- EXX
- DJNZ $2
- RET NC
- EXX
- INC L
- JR NZ,$A
- INC H
- ;
- $A EXX
- RET NZ
- INC HL
- RET
- ;
- $1 SUB D
- ;
- $2 SCF
- DEC B
- RET Z
- ;
- D1 RL C
- ADD A,A
- JR C,$1
- SUB D
- JR NC,$2
- ADD A,D
- OR A
- DJNZ D1
- RET
- ;
- DIV8 LD A,H ; H = H / D
- LD B,9
- CALL D1
- LD H,C
- RET NC
- INC H ; Rounding
- RET
- ;
- $1 OR A
- SBC HL,DE
- ;
- $2 SCF
- DEC B
- RET Z
- ;
- D2 RLA
- ADD HL,HL
- JR C,$1
- SBC HL,DE
- JR NC,$2
- ADD HL,DE
- OR A
- DJNZ D2
- RET
- ;
- DIV16 LD B,9 ; HL = HL / DE
- CALL D2
- LD C,A
- LD B,3
- CALL D2
- LD L,C
- LD C,A
- LD A,H
- LD H,L
- LD B,5
- CALL D1
- LD L,C
- RET NC
- INC HL ; Rounding
- RET
- ;
- $1 OR A
- ;
- $2 EXX
- SBC HL,DE
- ;
- $3 EXX
- SBC HL,DE
- SCF
- DEC B
- RET Z
- ;
- D4 RL C
- EXX
- ADD HL,HL
- EXX
- ADC HL,HL
- JR C,$1
- LD A,H
- CP D
- JR C,$_
- JP NZ,$2
- LD A,L
- CP E
- JR C,$_
- JR NZ,$2
- EXX
- SBC HL,DE
- JR NC,$3
- ADD HL,DE
- EXX
- ;
- $_ OR A
- DJNZ D4
- RET
-
- DIV32 LD B,9 ; HL,HL' = HL,HL' / DE,DE'
- CALL D4
- DB 0FDH
- LD H,C
- LD B,8
- CALL D4
- DB 0FDH
- LD B,H
- PUSH BC
- LD B,3
- CALL D4
- LD A,C
- LD B,5
- CALL D2
- EXX
- LD H,A
- EXX
- LD B,3
- CALL D2
- LD C,A
- LD A,H
- LD B,5
- CALL D1
- POP HL
- LD A,C
- EXX
- LD L,A
- JR C,$A
- ;
- $1 EXX
- RET
- ;
- $A INC L ; Rounding
- JR NZ,$1
- INC H
- EXX
- RET NZ
- INC HL
- RET
- ;
- $1 EXX
- ;
- $2 LD A,B
- DB 0FDH
- SUB H
- ;
- $3 LD B,A
- SBC HL,DE
- EXX
- SBC HL,DE
- SCF
- DEC B
- RET Z
- ;
- D5 RL C
- EXX
- SLA B
- ADC HL,HL
- EXX
- ADC HL,HL
- JR C,$1
- LD A,H ; Do a compare to see if we should subtract
- CP D
- JR C,$_
- JP NZ,$1
- LD A,L
- CP E
- JR C,$_
- JR NZ,$1
- EXX
- LD A,H
- CP D
- JR C,$_
- JR NZ,$2
- LD A,L
- CP E
- JR C,$_
- JR NZ,$2
- LD A,B
- DB 0FDH
- SUB H
- JR NC,$3
- ;
- $_ EXX
- ;
- $_ OR A
- DJNZ D5
- RET
- ;
- $1 EXX
- ;
- $2 LD A,C
- DB 0FDH
- SUB L
- ;
- $3 LD C,A
- LD A,B
- DB 0FDH
- SBC A,H
- LD B,A
- SBC HL,DE
- EXX
- SBC HL,DE
- SCF
- DEC B
- RET Z
- ;
- D6 RL C ; Do a left shift
- EXX
- SLA C
- RL B
- ADC HL,HL
- EXX
- ADC HL,HL
- JR C,$1
- LD A,H ; Do a compare to see if we should subtract
- CP D
- JR C,$_
- JP NZ,$1
- LD A,L
- CP E
- JR C,$_
- JR NZ,$1
- EXX
- LD A,H
- CP D
- JR C,$_
- JR NZ,$2
- LD A,L
- CP E
- JR C,$_
- JR NZ,$2
- LD A,B
- DB 0FDH
- CP H
- JR C,$_
- JR NZ,$2
- LD A,C
- DB 0FDH
- SUB L
- JR NC,$3
- ;
- $_
- $_
- $_ EXX
- ;
- $_
- $_ OR A
- DJNZ D6
- RET
- ;
- $2 EXX
- ;
- $1 LD A,C
- SUB B
- ;
- $3 LD C,A
- EXX
- LD A,C
- DB 0FDH
- SBC A,L
- LD C,A
- LD A,B
- DB 0FDH
- SBC A,H
- LD B,A
- SBC HL,DE
- EXX
- SBC HL,DE
- EX AF,AF'
- SCF
- RET
- ;
- D7_8 CALL $+3
- CALL $+3
- CALL $+3
- ;
- D7_1 RLA
- EX AF,AF'
- SLA C
- EXX
- RL C
- RL B
- ADC HL,HL
- EXX
- ADC HL,HL
- JR C,$1
- ;
- COMP LD A,H ; Do a compare to see if we should subtract
- CP D
- JR C,$_
- JP NZ,$1
- LD A,L
- CP E
- JR C,$_
- JR NZ,$1
- EXX
- LD A,H
- CP D
- JR C,$_
- JR NZ,$2
- LD A,L
- CP E
- JR C,$_
- JR NZ,$2
- LD A,B
- DB 0FDH
- CP H
- JR C,$_
- JR NZ,$2
- LD A,C
- DB 0FDH
- CP L
- JR C,$_
- JR NZ,$2
- EXX
- LD A,C
- SUB B
- JR NC,$3
- EXX
- ;
- $_
- $_
- $_
- $_ EXX
- ;
- $_
- $_ EX AF,AF'
- OR A
- RET
- ;
- RSHIFT SRL H
- RR L
- EXX
- RR H
- RR L
- RR B
- RR C
- EXX
- RR C
- RET
- ;
- DIV56 EQU $ ; HL,HL',BC',C = HL,HL',BC',C / DE,DE',IY,B
- ;
- CALL D7_1 ; Divisor is preserved
- ;
- DIV55 PUSH BC ; Save divisor lsbyte
- CALL D7_8
- DB 0DDH
- LD H,A
- LD B,8
- CALL D6
- DB 0DDH
- LD L,C
- PUSH IX
- LD B,8
- CALL D5
- DB 0DDH
- LD H,C
- LD B,8
- CALL D4
- DB 0DDH
- LD L,C
- PUSH IX
- LD B,8
- CALL D4
- DB 0DDH
- LD H,C
- LD B,8
- CALL D2
- DB 0DDH
- LD L,A
- LD A,H
- LD B,8
- CALL D1
- EXX
- DB 0DDH
- LD C,L
- DB 0DDH
- LD B,H
- POP HL
- EXX
- POP HL
- LD A,C
- POP BC ; Restore divisor lsbyte
- LD C,A
- RET NC
- INC C ; Rounding
- RET NZ
- ;
- RIPPLE EXX
- INC C
- JR Z,$A
- ;
- $1 EXX
- RET
- ;
- $A INC B
- JR NZ,$1
- INC L
- JR NZ,$1
- INC H
- EXX
- RET NZ
- INC L
- RET NZ
- INC H
- RET
- ;
- DOVER LD A,7FH
- DB 0FEH
- ;
- DUNDER XOR A
- LD B,A
- LD A,(SIGN)
- OR B
- LD (IX+7),A
- RLA
- SRA A
- PUSH IX
- POP HL
- LD B,7
- ;
- $1 LD (HL),A
- INC HL
- DJNZ $1
- RET
- ;
- ; Floating point divide, 53-bit mantissa, 11-bit exponent
- ;
- DIV LD A,(DE) ; Dividend exponent lo
- INC DE
- SUB (HL) ; Divisor exponent lo
- INC HL
- DB 0FDH
- LD L,A
- EX AF,AF' ;save carry flag
- LD A,(HL) ; Divisor exponent hi
- AND 7
- LD B,A
- LD A,(DE) ; Dividend exponent hi
- AND 7
- LD C,A
- EX AF,AF' ;retrieve carry flag
- LD A,C
- SBC A,B
- DB 0FDH
- LD H,A
- PUSH IY ; Save exponent
- LD A,(DE) ; ;dividend mantissa ls 5 bits
- INC DE
- AND 0F8H
- LD C,A
- LD A,(HL) ; ;divisor mantissa ls 5 bits
- INC HL
- AND 0F8H
- LD B,A
- LD (SAVESP),SP
- LD SP,HL
- EX DE,HL
- POP IY ; Now get rest of divisor mantissa
- EXX
- POP DE
- EXX
- POP DE
- LD SP,HL
- EXX ; Now get rest of dividend mantissa
- POP BC
- POP HL
- EXX
- POP HL
- LD SP,(SAVESP)
- LD A,D ; Sign of divisor
- XOR H ; Sign of dividend
- AND 80H ; Clean the sign bit
- LD (SIGN),A ; Sign of result
- SET 7,D ; Make the implicit 1 explicit
- SET 7,H ; Ditto
- ;
- ; Begin the divide
- ;
- CALL COMP
- RLA
- LD (NORM),A ; Save normalization flag
- RRA
- JR C,$A
- CALL D7_1
- ;
- $A PUSH IX
- CALL DIV55
- POP IX
- LD A,C
- ADD A,4 ; Rounding bit
- LD C,A
- LD DE,400H ; Exponent correction
- JR NC,$A
- CALL RIPPLE ; Do ripple carry because of rounding
- JR NZ,$B ; Norm flag (no right shift needed
- INC DE ; because it's all 0's)
- ;
- $A
- $B RES 7,H ; Remove msbit
- LD A,(SIGN)
- OR H ; Append sign bit
- LD (IX+7),A
- LD (IX+6),L
- POP HL ; Exponent
- ADD HL,DE
- LD A,(NORM)
- RRA
- JR C,$A
- DEC HL
- ;
- $A BIT 7,H
- JP NZ,DUNDER ; Negative means underflow
- BIT 3,H ; See if overflow
- JP NZ,DOVER
- LD A,C ; Get lsbyte
- AND 0F8H
- OR H ; Append 3 hi bits of exponent
- LD (IX+1),A
- LD (IX+0),L
- EXX
- LD (IX+2),C
- LD (IX+3),B
- LD (IX+4),L
- LD (IX+5),H
- EXX
- RET
- ;
- MAXDE LD DE,0FFFFH
- EXX
- LD DE,0FFFFH
- EXX
- RET
- ;
- MAXHL LD HL,0FFFFH
- EXX
- LD HL,0FFFFH
- LD B,H
- LD C,L
- EXX
- LD C,H
- RET
- ;
- SQRT LD (SAVESP),SP ; Floating point square root, 53-bit
- LD SP,HL ; mantissa, 11-bit exponential
- POP BC
- EXX
- POP BC
- POP HL
- EXX
- POP HL
- LD SP,(SAVESP)
- PUSH DE ; Dest. addr.
- LD D,B ; Save mantissa lo byte
- LD A,B ; Get exponent hi byte
- AND 7 ; Clean exponent
- ADD A,4 ; Fix offset
- RRA ; Divide by 2
- RR C ; Carry = 'odd exp.'
- LD B,A
- PUSH BC ; Save exponent
- EX AF,AF' ;save 'EXP ODD' flag
- LD A,D ; Get mantissa lsb
- AND 0F8H
- LD C,A
- SET 7,H ; Make the implicit 1 explicit
- CALL RSHIFT ; HalfX
- EX AF,AF'
- LD D,0D7H ; Y seed = 1.68...
- JR C,$A
- CALL RSHIFT
- LD D,98H ; Y seed = 1.189...
- ;
- $A PUSH BC
- PUSH HL
- CALL DIV8 ; H = halfX / Y
- SRL D ; D = Y / 2
- LD A,H
- ADD A,D
- LD D,A ; D = new Y
- CALL C,MAXDE
- POP HL
- PUSH HL ; HL = halfX
- CALL DIV16 ; HL = halfX / Y
- SRL D
- RR E ; DE = Y/2
- ADD HL,DE
- EX DE,HL ; DE = new Y
- CALL C,MAXDE
- POP HL
- PUSH HL
- EXX
- PUSH HL
- EXX
- CALL DIV32 ; HL,HL' = halfX / Y
- SRL D
- RR E
- EXX
- RR D
- RR E ; DE,DE' = Y/2
- ADD HL,DE
- EX DE,HL
- POP HL
- EXX
- ADC HL,DE
- EX DE,HL ; DE,DE' = new Y
- CALL C,MAXDE
- POP HL
- POP BC
- CALL DIV56
- SRL D
- RR E
- EXX
- RR D
- RR E
- DB 0FDH
- LD A,H
- RRA
- DB 0FDH
- LD H,A
- DB 0FDH
- LD A,L
- RRA
- DB 0FDH
- LD L,A
- EXX
- LD A,B
- RRA
- ADD A,C
- LD C,A
- EXX
- LD A,C
- DB 0FDH
- ADC A,L
- LD C,A
- LD A,B
- DB 0FDH
- ADC A,H
- LD B,A
- ADC HL,DE
- EXX
- ADC HL,DE
- CALL C,MAXHL
- LD A,C
- ADD A,4 ; Rounding
- LD C,A
- CALL C,RIPPLE
- CALL Z,MAXHL
- RES 7,H
- LD A,C
- POP BC ; Exponent
- AND 0F8H
- OR B
- LD B,A
- EX DE,HL
- POP HL ; Dest. addr.
- LD SP,HL
- PUSH DE
- EXX
- PUSH HL
- PUSH BC
- EXX
- PUSH BC
- LD SP,(SAVESP)
- RET
- ;
- M7_8 CALL $A
- ;
- M7_7 CALL $B
- CALL $+6
- CALL $+3
- CALL $+3
- ;
- $B
- $A RRA
- JR NC,$A
- ;
- M7_0 EX AF,AF'
- LD A,C
- ADD A,B
- LD C,A
- EXX
- LD A,C
- DEFB 0FDH
- ADC A,L
- LD C,A
- LD A,B
- DEFB 0FDH
- ADC A,H
- LD B,A
- ADC HL,DE
- EXX
- ADC HL,DE
- ;
- M72 RR H
- RR L
- EXX
- RR H
- RR L
- RR B
- RR C
- EXX
- RR C
- EX AF,AF'
- RET
- ;
- $A SRL H
- RR L
- EXX
- RR H
- RR L
- RR B
- RR C
- EXX
- RR C
- RET
- ;
- M4 LD B,8
- ;
- $1 RRA
- JR NC,$A
- EXX
- ADD HL,DE
- EXX
- ADC HL,DE
- ;
- $A RR H
- RR L
- EXX
- RR H
- RR L
- EXX
- DJNZ $1
- RET
- ;
- UNDER LD A,D
- AND 80H
- JR $A
- ;
- OVER LD A,D
- OR 7FH
- ;
- $A POP HL ; Destination address
- DEC HL
- LD (HL),A
- RLA
- SRA A
- LD B,7
- ;
- $1 DEC HL
- LD (HL),A
- DJNZ $1
- RET
- ;
- MULT PUSH DE ; Floating point multiply, 53-bit
- LD (SAVESP),SP ; mantissa, 11-bit exponential
- LD SP,HL
- LD L,(IX+0)
- LD A,(IX+1)
- AND 7
- LD H,A
- POP BC
- LD E,C
- LD A,B
- AND 7
- LD D,A
- ADD HL,DE ; New exponent
- EXX
- POP IY
- POP DE
- EXX
- POP DE
- LD SP,(SAVESP)
- PUSH HL
- LD A,B
- AND 0F8H
- LD B,A
- LD A,(IX+7)
- XOR D
- AND 80H
- LD (SIGN),A
- SET 7,D ; Make implicit 1 explicit
- ;
- ; Zero the accumulator
- ;
- XOR A
- LD C,A
- EXX
- LD C,A
- LD B,A
- LD L,A
- LD H,A
- EXX
- LD L,A
- PUSH BC
- LD A,(IX+1)
- RRA
- RRA
- RRA
- LD H,A
- XOR A
- LD B,5
- ;
- $1 RR H
- JR NC,$+3
- ADD A,D
- RRA
- DJNZ $1
- LD H,A
- LD A,(IX+2)
- LD B,8
- ;
- $1 RRA
- JR NC,$+3
- ADD HL,DE
- RR H
- RR L
- DJNZ $1
- LD A,(IX+3)
- CALL M4
- LD A,(IX+4)
- CALL M4
- LD C,(IX+5)
- LD B,8
- ;
- $1 RR C
- JR NC,$A
- EXX
- LD A,B
- DEFB 0FDH
- ADD A,H
- LD B,A
- ADC HL,DE
- EXX
- ADC HL,DE
- ;
- $A RR H
- RR L
- EXX
- RR H
- RR L
- RR B
- EXX
- DJNZ $1
- LD C,(IX+6)
- LD B,8
- ;
- $1 RR C
- JR NC,$A
- EXX
- LD A,C
- DEFB 0FDH
- ADD A,L
- LD C,A
- LD A,B
- DEFB 0FDH
- ADC A,H
- LD B,A
- ADC HL,DE
- EXX
- ADC HL,DE
- ;
- $A RR H
- RR L
- EXX
- RR H
- RR L
- RR B
- RR C
- EXX
- DJNZ $1
- POP BC
- LD A,(IX+7)
- CALL M7_7
- CALL M7_0 ; Skip the test because ms bit is always 1
- LD B,1 ; Normalization counter
- BIT 7,H
- JR NZ,$A
- DEC B
- ;
- ; Shift left to normalize
- ;
- SLA C
- EXX
- RL C
- RL B
- ADC HL,HL
- EXX
- ADC HL,HL
- ;
- $A LD A,4 ; Round it to 53-bit precision instead
- ADD A,C ; of truncating
- LD C,A
- JR NC,$_
- CALL RIPPLE
- JR NZ,$_
- INC B ; Right shift not needed because it's all 0's
- ;
- $_
- $_ EX DE,HL
- LD HL,SIGN
- LD A,D
- AND 7FH
- OR (HL)
- LD D,A
- LD A,C
- AND 0F8H
- LD H,A
- LD A,B ; Norm flag
- POP BC ; Get exponent
- ADD A,C ; Correct for norm.
- LD C,A
- LD A,0FCH ; Fix offset
- ADC A,B
- JP NC,UNDER
- BIT 3,A
- JP NZ,OVER
- OR H
- LD B,A
- POP HL ; Dest. addr.
- LD (SAVESP),SP
- LD SP,HL
- PUSH DE
- EXX
- PUSH HL
- PUSH BC
- EXX
- PUSH BC
- LD SP,(SAVESP)
- RET
- ;
- ; A driver to do 1000 multiplies for timing purposes
- ;
- MULTEST LD BC,1000
- ;
- $1 PUSH BC
- ;
- ; Here is a segment which represents compiled code for a high level
- ;
- ; Statement like a = b * c
- ;
- LD IX,OPER1 ; Address of one operand
- LD HL,OPER2 ; Address of other operand
- LD DE,RESULT+8
- CALL MULT
- POP BC
- DEC BC
- LD A,B
- OR C
- JR NZ,$1
- RET
- ;
- ;Here is a driver to do 1000 divides for timing purposes
- ;
- DIVTEST LD BC,1000
- ;
- $1 PUSH BC
- ;
- ; Here is a segment which represents compiled code for a high level
- ;
- ; Statement like a = b / c
- ;
- LD DE,OPER1 ; Addr of dividend
- LD HL,OPER2 ; Addr of divisor
- LD IX,RESULT
- CALL DIV
- POP BC
- DEC BC
- LD A,B
- OR C
- JR NZ,$1
- RET
- ;
- ; Here is an empty loop for comparison. It loops 65536 times.
- ;
- EMPTY LD BC,0
- ;
- $1 PUSH BC
- POP BC
- DEC BC
- LD A,B
- OR C
- JR NZ,$1
- RET
- ;
- ; Here is a driver to do 1000 square roots for timing purposes
- ;
- SQRTTEST EQU $
- ;
- LD BC,1000
- ;
- $1 PUSH BC
- ;
- ; Here is a segment which represents compiled code for a high level
- ;
- ; Statement like a = sqrt(b)
- ;
- LD HL,OPER2 ; Address of operand
- LD DE,RESULT+8
- CALL SQRT
- POP BC
- DEC BC
- LD A,B
- OR C
- JR NZ,$1
- RET
- ;
- ;
- END