-
Notifications
You must be signed in to change notification settings - Fork 85
/
Copy pathoperand.src
576 lines (449 loc) · 10.6 KB
/
operand.src
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
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
.page
.subttl operand
; operand processing *****
; processes normal operands & determines if they are valid.
h201 ldy #0
sty joptyp ;operand type
sty joplen ;bytes to generate
sty jnopv ;operand value flag
; check for implied operand
lda joptem ;opcode template
cmp #20 ;implied operand?
bne h17 ;...no, skip to next section
; generate opcode for implied and accumulator modes
h459 ldy #0 ;insert in op posit
lda jopbas ;op is base opcode
jsr objout ;put in memory map
ldx #0 ;get error col
ldy #1 ;num of bytes
txa
jmp lts1
; need operand - check branch first
h17 cmp #21 ;branch template
bne 4$ ;...no
lda #14
sta joptem
lda #7 ;error code
sta ierr
4$ ldx icse ;point to character after opcode
inx
stx icolp
jsr nfndnb ;find start of operand
bcs 6$ ;...found it
5$ lda #7 ;EOL or missing operand
sta ierr
ldx icse ;point at space after opcode
inx
jmp h9933 ;error- missing operand
; process operand field
6$ cmp #';' ;check first character of operand
beq 5$ ;...comment (error)
cmp #'A' ;accumulator mode?
bne 9$ ;...no
ldy icrd+1,x ;...maybe: 'A' must stand alone
beq 7$ ;...yes (EOL)
cpy #space
beq 7$ ;...yes <space> or <comment>
cpy #';'
bne 9$ ;...not accumulator mode
7$ ldy joptem ;.A mode - process
lda kltbl-1,y
bmi 8$ ;.A mode not valid
clc
adc jopbas ;compute real opcode
sta jopbas
jmp h459 ;done with this opcode
8$ ldx icsb ;error column
ldy #3 ;number of bytes to save
lda #5 ;error code
jmp lts1
9$ cmp #'#' ;check for immediate mode
beq 11$ ;...yes!
cmp #'(' ;check for indirect mode
bne 12$ ;not indirect
lda #5 ;opcode type: indirect
.byte $2c
11$ lda #10 ;opcode type: immediate
sta joptyp
inx
inc icsb ;point to symbol following '#' or '('
; done parsing addressing modes. now evaluate operand.
12$ jsr eval ;evaluate the operand
stx jercol ;error column from eval (if any)
lda #19 ;error type SYNTAX ERROR (if any)
sta ierr
dec return ;status from eval
bmi 20$ ;...good return (0)
beq 19$ ;...undefined symbol (1)
;...uninterp expr (2)
lda joptyp ;might be #<ascii string>
cmp #10
beq 14$ ;...maybe- immediate mode set
jmp h995 ;...no- could not evaluate, report syntax error
; check immediate ascii operation
14$ lda icrd,x
jsr is_quote ;check for apostrophe or quote
bne 17$ ;...no- error
15$ txa
tay ;save pointer to start in .Y
inx
lda icrd,x
bne 16$ ;...found a character
dex
lda #space ;...found EOL: pass a space character
16$ sta iexp+1 ;val of char
inx
lda icrd,x
beq 20$ ;...ok
cmp #space
beq 20$ ;...ok
jsr is_quote
beq 18$ ;...ok
tya ;ascii string invalid
tax ;error column
17$ ldy #2 ;number of bytes
lda ierr ;error code
jmp lts1
18$ inx ;ascii char expression
jsr d71 ;eval next
dec return
bmi 20$ ;evaluate ok
beq 19$ ;undefd symbol
jmp h995 ;bad expression
.page
; 1 - operand has no value
19$ inc jnopv ;no operand val
lda #2 ;assumed length
sta joplen ;operand length
; 0 - good return. index register check.
20$ jsr nfncmp ;comma or paren
bcc 25$ ;no indexing
lda icrd,x ;get character
cmp #')'
bne 21$ ;no
inc joptyp ;right paren - add to optype
inc joptyp
lda jopbas ;jump instr. test
cmp #$4c ;jump instr
beq 26$ ;yes
; done with paren - next char
inx ;point to next
21$ lda icrd,x ;check for comma - indexing
beq 29$ ;...EOL
cmp #comma
bne 22$ ;no - could be y
; has a comma. check for jump again.
lda jopbas ;base opcode
cmp #$4c ;a jump
beq 27$ ;...yes- error-not allowed
; done with comma - look for index.
inx ;point to next character
22$ lda icrd,x ;check for index register x
beq 29$ ;...EOL
cmp #'X'
bne 23$ ;no
inc joptyp ;an x-add 1 to optype
jmp 32$
29$ jmp h99 ;EOL: error
23$ cmp #'Y' ;check for index reg y
beq 24$ ;yes
ldy #3 ;invalid index reg - flag
lda #$12 ;error code
jmp lts1
24$ inc joptyp ;index reg y-add 2 to optype
inc joptyp
bne 32$
25$ lda jopbas ;if a jump instruction check
cmp #$4c
bne 32$ ;not a jump
; a jump-see if optype is valid
; only 2 type operands allowed: type 0 is abs, 7 is ind
26$ lda joptyp
beq 30$ ;type 0...o.k.
cmp #7
beq 28$ ;type 7...o.k.
; invalid oper for jmp - flag
27$ lda #$18 ;error code
sta ierr
jmp h980 ;put in length tab
28$ inx ;good optype- make sure no more
lda icrd,x
beq 30$
cmp #space
bne 27$ ;no-bad jump
30$ lda joptyp ;good jump-incr to base opcode
beq 31$ ;finish jump
lda #32 ;type 7-add to base
; end of jump processing
31$ ldy #2 ;length of operand
sty joplen
jmp h46 ;finish line process
; operand processed. see if operand valid for opcode.
32$ lda jnopv ;operand value?
beq 33$
jmp h41 ;no-assume extended
; have operand value - check rel
33$ lda joptem ;opcode template
cmp #14 ;relative address
bne 38$ ;not relative
clc ;relative adr- chk validity. adjust expr to get rel adr
lda ipc
adc #2
sta temp+1
lda ipc+1
adc #0
sta temp
lda iexp+1 ;low byte of expr
sec
sbc temp+1
sta iexp+1
tay ;for later
lda iexp ;high byte of expr
sbc temp
sta iexp
; test expr for branch too far
; if sign bits same then o.k.
; low byte iexp tested.
; branch attempted to go too far
bpl 34$ ;high byte +
tya ;high byte neg check lo byt
bmi 36$ ;both neg-expr ok
bpl 35$ ;differ signs-bad
34$ tya ;hi byte pos-check lo
bpl 36$ ;both pos-expr ok
; bad rel-flag as error
35$ lda #$17 ;branch error
sta ierr ;save in ierr
36$ lda iexp ;good relative-oplength at 2
beq 41$
cmp #255
beq 37$
lda #$17
sta ierr
37$ lda #0
sta iexp
beq 41$ ;bra
; check indirect address error
; error indicated by expr over 254
; or optype >= 6 and <= 9
38$ lda joptyp
cmp #6
bcc 41$ ;no
cmp #9
beq 39$ ;yes
bcs 41$ ;not indirect
39$ lda iexp ;check val of expr
bne 40$ ;error-over 255
lda iexp+1
cmp #255
bne 41$ ;no-ok
; error on indirect
40$ lda #$19 ;error code
sta ierr
lda #0
sta iexp
41$ lda #2 ;one or two byte operand
sta joplen
lda joptyp ;immediate mode?
cmp #10
beq 42$ ;1 byte operand
lda iexp
bne h41 ;we need 2 bytes
; 1 byte operand - check if valid
42$ lda #1
sta joplen
lda joptyp
clc
adc #2
sta joptyp
h50 cmp #13 ;max addr mode
bcc h45 ;yes...oper valid opcode
lda #$15 ;bad operand-flag
sta ierr ;page zero invalid
jmp h900
h41 lda joptyp ;process 2 byte operands
clc
adc #13
sta joptyp
h47 cmp #15 ;over 15 could be bad
beq h45 ;good extended operand
bcs h49 ;bad-might be a page 0
; see if operand is valid for opcode.
h45 tay ;first subscript
dey
lda kludg,y
clc
adc joptem ;second subscript
tay ;opcode base increment
lda kltbl,y
bpl h46 ;pos operand type valid
; operand not valid first try. try 2 byte operand.
h49 lda jnopv ;an operand value
beq h48 ;yes
lda joplen ;no operand val-try 1 byte instr
cmp #2
beq h206 ;was 2 - try as 1
lda #$18 ;1 byte novalue operand-flg error
sta ierr ;invalid operand
jmp h900
h206 lda #1 ;abs mode as page zero mode
sta joplen
lda joptyp
sec
sbc #11
sta joptyp ;new op type
jmp h50
h48 lda joplen ;had an operand value
cmp #1 ;1 byte long
beq h207 ;yes...try 2 bytes
lda #$18 ;operand 2 bytes - flag as error
sta ierr ;invalid operand
jmp h900
; page 0 mode as abs
h207 inc joplen ;op length to 2
lda joptyp
clc
adc #11
sta joptyp
jmp h47
; valid operand - compute opcode and put in memory map
h46 clc
adc jopbas ;kludge+base opcode
ldy #0
jsr objout
; operand value - enter into memory map
lda jnopv ;operand value flag
bne h313 ;no value
ldy #1 ;an operand value
lda iexp+1 ;low byte of expr
jsr objout
ldy #2
lda joplen
cmp #1 ;if 1 byte then done
beq h9931 ;yes...done
lda iexp ;2byt=hi-byte to memory
jsr objout
; any operand errors
h9931 lda ierr ;error code
cmp #$17 ;rel address error?
beq h900r
cmp #$19 ;ind address error?
beq h980 ;yes
; overflow or negative expr
;
; lda #9 ;mask overflow and sign
; and overflow
; bne h960 ;error exists
; lda joplen
; cmp #1
; bne ;2 bytes ok
; lda iexp ;see if over 1 byt
; bne h960 ;yes...error
;
;end of processing
ldx #0 ;error column
ldy joplen
iny ;count opcode
txa ;error code
jmp lts1
h313 ldy joplen ;forward references found
lda joptem ;operand template
cmp #14 ;branch--3 bytes
bne 10$ ;not branch
ldy #1 ;branch operand length
10$ ldx icsb ;error column from eval
iny ;adjust byte count for opcode
lda #1 ;error code
jmp lts1
; common length table entries
;
; relative branch error #$17
h900r ldx icsb ;column of target
ldy #2 ;two byte length
jmp lts1
h99 lda #7 ;ran off end of card error
sta ierr
h900 ldx icsb ;error at start of field
jmp h9933
h980 ldx icolp ;error at current column
jmp h9933
h995 ldx jercol ;err at col returned by eval
; enter in length table
h9933 ldy #3 ;save 3 bytes
lda ierr ;error code
jmp lts1
;h960 ldx icsb ;invalid address err - start of field
; ldy joplen
; iny ;count opcode
; lda #4 ;get error message
; jmp lts1
; no error - comment or blank card
h990 ldx #0 ;no error column
txa ;no error code
tay ;no bytes generated
lts1 jsr ltins
endln ldx stack_ptr ;so much for structure!
txs
jmp snewln
.page
; find next non-blank. carry set if non-blank found, else carry clear.
;
; sets <icolp> = <icsb> = first character of string
nfndnb1 inc icolp ;increment column pointer
nfndnb ldx icolp ;column pointer
lda icrd,x ;next character
beq 10$ ;...EOL
cmp #space
beq nfndnb1 ;...loop while space
stx icsb ;got non-blank: point to it
sec
rts
10$ clc ;none found
rts
; find end of current string starting at .X
;
; sets <icse> = pointer to last character in string
; sets <icsl> = length of string (from <icolp> at time of call)
nfnden lda #$ff
sta icsl ;reset length
dex
10$ inx ;pointer to next character
inc icsl ;count it
lda icrd,x ;get next character
beq 20$ ;...string end: EOL
cmp #space
beq 20$ ;...string end: space
cmp #'='
beq 20$ ;...string end: equal sign
cmp #';'
bne 10$ ;...end of quoted string
20$ dex ;found end of string (EOL, space, '=', ';')
stx icse ;set pointer to end of string
rts
.page
; find <comma> or <closing paren>. carry set if found.
;
; ignores items between quotes.
; sets <icolp> = pointer to <comma>, <paren>, or terminator: <space>, EOL
nfncmp1 inc icolp ;next character
nfncmp ldx icolp ;column pointer
lda icrd,x ;next character
beq 20$ ;...EOL: return false
cmp #space
beq 20$ ;...space: return false
cmp #')'
beq 30$ ;...paren: return true (.c=1)
cmp #comma
beq 30$ ;...comma: return true (.c=1)
jsr is_quote
bne nfncmp1 ;...loop until a find or a terminator
10$ inc icolp ;skip over quoted string
ldx icolp ;advance pointers
lda icrd,x ;get next character
beq 20$ ;...EOL: return false
jsr is_quote
bne 10$ ;...loop until closing quote or EOL
beq nfncmp1 ;...found closing quote- resume comma hunt
20$ clc
30$ rts
; .end