-
Notifications
You must be signed in to change notification settings - Fork 84
/
fndrel
195 lines (195 loc) · 3.15 KB
/
fndrel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
.PAGE 'FNDREL'
;********************************
;*
;* FIND RELATIVE FILE
;*
;* VERSION 2.5
;*
;*
;* INPUTS
;* RECL - 1BYTE=LO RECORD #
;* RECH - 1BYTE=HI RECORD #
;* RS - 1BYTE=RECORD SIZE
;* RECPTR - 1BYTE=FIRST BYTE
;* WANTED FROM RECORD
;*
;* OUTPUTS
;* SSNUM - 1BYTE=SIDE SECTOR #
;* SSIND - 1BYTE=INDEX INTO SS
;* RELPTR - 1BYTE=PTR TO FIRST
;* BYTE WANTED
;*
;********************************
;
;
;
;
;
;
FNDREL JSR MULPLY ;RESULT=RN*RS+RP
JSR DIV254 ;DIVIDE BY 254
LDA ACCUM+1 ;SAVE REMAINDER
STA RELPTR
JSR DIV120 ;DIVIDE BY 120
INC RELPTR
INC RELPTR
LDA RESULT ;SAVE QUOTIENT
STA SSNUM
LDA ACCUM+1 ;SAVE REMAINDER
ASL A ;CALC INDEX INTO SS
CLC
ADC #16 ;SKIP LINK TABLE
STA SSIND
RTS
;
;
;
; MULTIPLY
;
; RESULT=RECNUM*RS+RECPTR
;
; DESTROYS A,X
;
MULPLY JSR ZERRES ;RESULT=0
STA ACCUM+3 ;A=0
LDX LINDX ;GET INDEX
LDA RECL,X
STA ACCUM+1
LDA RECH,X
STA ACCUM+2
BNE MUL25 ;ADJUST FOR REC #1 &...
LDA ACCUM+1 ;...#0 = 1ST REC
BEQ MUL50
MUL25 LDA ACCUM+1
SEC
SBC #1
STA ACCUM+1
BCS MUL50
DEC ACCUM+2
MUL50
LDA RS,X ;COPY RECSIZ
STA TEMP
MUL100 LSR TEMP ;DO AN ADD ?
BCC MUL200 ;NO
JSR ADDRES ;RESULT=RESULT+ACCUM+1,2,3
MUL200 JSR ACCX2 ;2*(ACCUM+1,2,3)
LDA TEMP ;DONE ?
BNE MUL100 ;NO
LDA RECPTR ;ADD IN LAST BIT
CLC
ADC RESULT
STA RESULT
BCC MUL400 ;SKIP NO CARRY
INC RESULT+1
BNE MUL400
INC RESULT+2
MUL400 RTS
;
;
;
; DIVIDE
;
; RESULT=QUOTIENT ,ACCUM+1=REMAINDER
;
; DESTROYS A,X
;
DIV254 LDA #254 ;DIVIDE BY 254
.BYTE $2C ;SKIP TWO BYTES
DIV120 LDA #120 ;DIVIDE BY 120
STA TEMP ;SAVE DIVISOR
LDX #3 ;SWAP ACCUM+1,2,3 WITH
DIV100 LDA ACCUM,X ; RESULT,1,2
PHA
LDA RESULT-1,X
STA ACCUM,X
PLA
STA RESULT-1,X
DEX
BNE DIV100
JSR ZERRES ;RESULT=0
DIV150 LDX #0
DIV200 LDA ACCUM+1,X ;DIVIDE BY 256
STA ACCUM,X
INX
CPX #4 ;DONE ?
BCC DIV200 ;NO
LDA #0 ;ZERO HI BYTE
STA ACCUM+3
BIT TEMP ;A DIV120 ?
BMI DIV300 ;NO
ASL ACCUM ;ONLY DIVIDE BY 128
PHP ;SAVE CARRY
LSR ACCUM ;NORMALIZE
PLP ;RESTORE CARRY
JSR ACC200 ;2*(X/256)=X/128
DIV300 JSR ADDRES ;TOTAL A QUOTIENT
JSR ACCX2 ;A=2*A
BIT TEMP ;A DIV120 ?
BMI DIV400 ;NO
JSR ACCX4 ;A=4*(2*A)=8*A
DIV400 LDA ACCUM ;ADD IN REMAINDER
CLC
ADC ACCUM+1
STA ACCUM+1
BCC DIV500
INC ACCUM+2
BNE DIV500
INC ACCUM+3
DIV500 LDA ACCUM+3 ;TEST < 256
ORA ACCUM+2
BNE DIV150 ;CRUNCH SOME MORE
LDA ACCUM+1 ;IS REMAINDER < DIVISOR
SEC
SBC TEMP
BCC DIV700 ;YES
INC RESULT ;NO - FIX RESULT
BNE DIV600
INC RESULT+1
BNE DIV600
INC RESULT+2
DIV600 STA ACCUM+1 ;NEW REMAINDER
DIV700 RTS
;
;
;
; ZERO RESULT
;
ZERRES LDA #0
STA RESULT
STA RESULT+1
STA RESULT+2
RTS
;
;
;
; MULTIPLY ACCUM BY 4
;
ACCX4 JSR ACCX2
;
; MULTIPLY ACCUM BY 2
;
ACCX2 CLC
ACC200 ROL ACCUM+1
ROL ACCUM+2
ROL ACCUM+3
RTS
;
;
;
; ADD ACCUM TO RESULT
;
; RESULT=RESULT+ACCUM+1,2,3
;
ADDRES CLC
LDX #$FD
ADD100 LDA RESULT+3,X
ADC ACCUM+4,X
STA RESULT+3,X
INX
BNE ADD100
RTS
;
;
;
;
.END