-
Notifications
You must be signed in to change notification settings - Fork 0
/
k11edi.mac
722 lines (600 loc) · 16 KB
/
k11edi.mac
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
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
.title k11edi Command line editing
.ident /3.52/
; 18-Jul-86 12:00:29 Brian Nelson
;
; This code is used (currently) for the RSTS/E Command Line
; Editor (CLE.RTS) written by the above author, and for 5.1
; of MINITAB. The encryption calls are for the RSTS/E CLE.
.iif ndf, $MINITAB, $MINITAB = 0
.if eq ,$Minitab
.if ndf, K11INC
.ift
.include /IN:K11MAC.MAC/
.endc
.endc
.enabl gbl
.psect rwdata ,rw,d,lcl,rel,con
.psect CLECTX ,rw,d,gbl,rel,con
curpos: .word edipos
curlen: .word edilen
curcmd: .word edicmd
maxsiz: .word edisiz
clests: .word edists
enckey: .word $enckey
deckey: .word $deckey
.if ne ,$Minitab
.ift
.macro dump v
mov v ,-(sp)
call o$dump
.globl o$dump
.endm dump
CR = 15
LF = 12
LN$MAX = 80.
LN$CNT = 3
ER$EOF == -1
$lastl: .blkb <<LN$MAX+2>*LN$CNT>+2
lastli: .word $lastl ,$lastl+<1*<LN$MAX+2>>,$lastl+<2*<LN$MAX+2>>,0
lastcn: .word LN$CNT
edipos: .word 0
edilen: .word 0
edicmd: .word -1
edists: .word 0
edikey: .word 0
edisiz: .word LN$MAX
$enckey:
$deckey:
TTY = 0
.endc ; If NE, $Minitab
.psect $pdata ,ro,d,lcl,rel,con
.psect $code ,i,ro,i,lcl,rel
FALSE = 0
TRUE = 1
IN$MODE = 1
SET$VT1 = 2
$DEBUG = 0
.iif ndf, $DEBUG, $DEBUG = 0
.sbttl Define macros
.if ne ,$MINITAB
.ift
.MACRO ENCRYPT txt,key
.ENDM ENCRYPT
.MACRO DECRYPT txt,key
.ENDM DECRYPT
.MACRO DEBUG a,b,c
.ENDM DEBUG
.MACRO STRCPY dst,src
mov src ,-(sp)
mov dst ,-(sp)
jsr pc ,strcpy
.ENDM STRCPY
.MACRO STRLEN src
mov src ,-(sp)
call strlen
.ENDM STRLEN
.MACRO SCAN ch,str
mov str ,-(sp)
clr -(sp)
bisb ch ,@sp
call scanch
.ENDM SCAN
.MACRO SAVE list
.if b , <list>
.ift
SAVE <r0,r1,r2,r3,r4,r5>
.iff
.irp x,<list>
mov x,-(sp)
.endr
.endc
.ENDM SAVE
.MACRO UNSAVE list
.if b , <list>
.ift
UNSAVE <r5,r4,r3,r2,r1,r0>
.iff
.irp x,<list>
mov (sp)+,x
.endr
.endc
.ENDM UNSAVE
.MACRO GLOBAL LIST
.GLOBL LIST
.ENDM GLOBAL
.iff ; Kermit or CLE
.MACRO ENCRYPT txt,key
mov key ,-(sp)
mov txt ,-(sp)
call ENCRYPT
.endm ENCRYPT
.MACRO DECRYPT txt,key
mov key ,-(sp)
mov txt ,-(sp)
call DECRYPT
.endm DECRYPT
.MACRO DEBUG txt,sts=1,docr=1
.if ne ,$DEBUG
.if ne ,sts
.save
.psect $pdata
$$ = .
.if b ,<txt>
.ift
.byte 15,12,0
.iff
.asciz @txt@
.endc
.even
.restore
mov #$$ ,-(sp) ; dump the text next please
CALL mout ; to the terminal
.globl mout ; perhaps
.if nb ,<txt>
.ift
.iif nb,docr, message
.endc
.endc
.endc
.endm DEBUG
.endc ; if NE, $Minitab
.macro WRTALL arg ; IO.WAL for an .asciz string
mov arg ,-(sp) ; Pass the address
call wrtall ; Do it
GLOBAL <wrtall> ; Insure globalized
.endm WRTALL ; Done
.enabl lsb
Kbredi::.iif ne, $MINITAB, mov r1,-(sp);
.iif ne, $MINITAB, mov r5,-(sp);
SAVE <r2,r3,r4> ; Save
cmpb vttype ,#TTY ; Not a VT100 or VT2xx?
bne 10$ ; No, try editing
.if ne ,$MINITAB ; Minitab today?
.ift ; Yes
sec ; Just set carry and exit
.iff ; Kermit or CLE
WRTALL @r5 ; Prompt
CALLS kbread ,<2(r5)> ; Hardcopy, use vanilla reads
.endc ; All done
br 100$ ; Exit
10$: WRTALL #$cr ;
WRTALL @r5 ;
bit #SET$VT1,@clests ; Insure terminal in VT100 mode
bne 15$ ; Already did it
WRTALL #$setvt1 ; Not done, do so
bis #SET$VT1,@clests ; Flag as having been done
15$: clr @curpos ; Assume at start of the line.
clr @curlen ; No length
mov 2(r5) ,r4 ; Buffer address
clrb @r4 ; Insure starting with .ASCIZ
20$: CALL read1ch ; Read one character now
mov r0 ,r3 ; Any data persent?
beq 90$ ; Yes, treat as a control Z
SCAN r3 ,#scanlst ; Look for a match
asl r0 ; And dispatch
jsr pc ,@scandsp(r0) ; Do it
bcs 20$ ; Not done
.iif ne, $MINITAB, mov r1,r0 ;
br 100$ ; Done
;
90$: mov #ER$EOF ,r0 ; Error, return END_OF_FILE
clr r1 ; And no data
100$: UNSAVE <r4,r3,r2> ; Exit
.iif ne, $MINITAB, mov (sp)+,r5;
.iif ne, $MINITAB, mov (sp)+,r1;
return
.dsabl lsb
.save
.psect $pdata
scanlst:.byte 'H&37 ,'E&37 ,'B&37 ,'U&37 ,'Z&37 ,CR ,LF
.byte 'I&37 ,177 ,33 ,233 ,'R&37 ,'X&37 ,'C&37
.byte 'A&37
.byte 0
.even
scandsp:.word INSCH
.word SOL ,EOL ,PREV ,CTRLU ,EOF ,NOOP ,DONE
.word NOOP ,DORUB ,DOESC ,DO220 ,RETYPE ,CANTYP ,CTRLC
.word TOGGLE
esclst: .byte 'A&137 ,'B&137 ,'C&137 ,'D&137 ,0
.even
escdsp: .word NOOP
.word PREV ,NEXT ,RIGHT ,LEFT
$cc: .asciz /^C/
$cz: .asciz /^Z/
$bs: .byte 'H&37,0
$cr: .byte 15,0
$right: .asciz <33>/[C/
$left: .asciz <33>/[D/
$save: .asciz <33>/7/
$resto: .asciz <33>/8/
$ceol: .asciz <33>/[K/
$crlf: .byte CR,LF,0
$rrub: .byte 10,40,10,0
$setvt: .byte 33,'<
.even
.restore
Doesc: DEBUG <Doesc> ; ...
CALL read1ch ; Get next in esc seq
Do220: DEBUG <Do220> ; You know
CALL read1ch ; Ditto
mov r0 ,r3 ; Get the data
beq 90$ ; Error Exit
SCAN r3 ,#esclst ; Process the character
asl r0 ; Convert to word offset
jsr pc ,@escdsp(r0) ; Do it
br 100$ ; Ok
90$: sec ; Failure on the READ
100$: return ; And Exit
Noop: DEBUG <Noop> ; ...
sec ; Ignore
return ; And Exit
Insch: DEBUG <Insch>,FALSE ; ...
sub #200 ,sp ; A temp buffer
mov sp ,r2 ; A pointer to it
tst r3 ; Null?
beq 100$ ; Ignore
cmp @curlen ,@maxsiz ; Too many chars?
blo 10$ ; No
CALL done ; Yes, exit
br 100$ ; Bye
10$: inc @curlen ; Save this
mov @curpos ,r1 ; Get the offset into line
add r4 ,r1 ; Where to stuff the data
tstb @r1 ; Already at end of line?
beq 20$ ; Yes, we have the stop to stuff it
bit #IN$MODE,@clests ; Insert or overstrike?
bne 15$ ; Insert
movb r3 ,(r1)+ ; Overstrike
br 30$ ; Exit
15$: STRCPY r2 ,r1 ; No, so save the data now
movb r3 ,(r1)+ ; And insert the new character
STRCPY r1 ,r2 ; And put the trailing data back in.
br 30$ ; Now for the echoing
20$: movb r3 ,(r1)+ ; Already at eol, insert
clrb @r1 ; And insure .ASCIZ
dec r1 ; ...
WRTALL r1 ; Echo
br 90$ ; Exit
30$: WRTALL #$save ; Save cursor pos
dec r1 ; Back to to the new character
WRTALL r1 ; Dump the data
WRTALL #$restore ; Put the cursor back now
WRTALL #$right ; Move over on the display
90$: inc @curpos ; Move over one
100$: add #200 ,sp ; Pop buffer
sec ; Not done
return ; Exit
.sbttl More line editing routines
; SOL Move to start of line (Control H)
Sol: DEBUG <Sol> ; ...
tst @curpos ; Stop when at position 0
ble 100$ ; Done
WRTALL #$bs ; Move
dec @curpos ; Fix position
br sol ; Next please
100$: clr @curpos ; Insure correct
sec ; Not done
return ; Exit
; EOL Move to End of Line, Control E
Eol: DEBUG <Eol> ; ...
STRLEN r4 ; Find string length
10$: cmp @curpos ,r0 ; End yet?
bhis 100$ ; Yes
WRTALL #$right ; No
inc @curpos ; Fix this
br 10$ ; Next
100$: sec ; Not done
return ; Exit
Gotoeol:STRLEN r4 ; Find string length
10$: cmp @curpos ,r0 ; End yet?
bhis 100$ ; Yes
inc @curpos ; Fix this
br 10$ ; Next
100$: return ; Exit
; EOF Control Z on input
.enabl lsb ; Temp
Ctrlc: DEBUG <Control C> ; ...
WRTALL #$cc ; Echo a control C
br 100$ ; Common exit now
Eof: DEBUG <Eof> ; ...
WRTALL #$cz ; Echo a control Z
.if ne ,$MINITAB ;
WRTALL #$crlf ;
.endc ;
100$: mov #ER$EOF ,r0 ; Control Z
clr r1 ; And return byte count of zero
clc ; All done
return ; Exit
.dsabl lsb ; Done
.enabl lsb
.sbttl Carriage return (actually LF) processing
; Done. CR on input, store new line and bubble previous ones back
Done: mov r5 ,-(sp) ; A scratch register we need
DEBUG <Done> ; ...
WRTALL #$crlf ;
STRLEN r4 ; Get byte count (we have CR or LF)
mov r0 ,r1 ; Return it
beq 90$ ; Nothing there, don't copy it.
clr r2 ; The index
mov lastcnt ,r3 ; Number of lines to do
10$: mov lastli(r2),r0 ; Look to find a free spot.
tstb @r0 ; Empty?
beq 60$ ; Yes
add #2 ,r2 ; No, keep looking
sob r3 ,10$ ; ....
; No room for command line.
clr r2 ; The index
mov r4 ,-(sp) ; Save it
mov lastcnt ,r3 ; Number of lines to do
dec r3 ; ...
asl r3 ; See if this is same as last
mov lastli(r3),r5 ; Current address
inc r5 ; Skip the length
mov r5 ,-(sp) ; Save
DECRYPT r5,deckey ; Undo the old line
STRLEN r4 ; Length
cmpb -1(r5) ,r0 ; Same length
bne 20$ ; No
15$: cmpb (r4)+ ,(r5)+ ; Check for string equality
bne 20$ ; Not the same
sob r0 ,15$ ; Same, check next
20$: mov (sp)+ ,r5 ; Restore old text pointer
mov (sp)+ ,r4 ; Restore the current pointer
ENCRYPT r5,enckey ; Restore the data
asr r3 ; Restore r3
tst r0 ; Same ?
bne 30$ ; No
mov r3 ,@curcmd ; Yes, save index
br 100$ ; Exit
30$:
40$: mov lastli(r2),r0 ; Counted string format
mov lastli+2(r2),r1 ; Again
movb (r1) ,(r0)+ ; Copy the string length
beq 55$ ; Can't happen, but may as well check
clr r5 ; Counter for the copy operation
bisb (r1)+ ,r5 ; Copy the byte count
50$: movb (r1)+ ,(r0)+ ; Copy the string now
sob r5 ,50$ ; Next
55$: add #2 ,r2 ; Move up
sob r3 ,40$ ; Next please
;
60$: mov lastli(r2),r1 ; Copy the line at last
STRLEN r4 ; Get the line length
mov @maxsiz ,r3 ; For padding with spaces
movb r0 ,(r1)+ ; Copy the length
beq 80$ ; Nothing
mov r4 ,r5 ; Source string
mov r1 ,-(sp) ; Save text address
70$: movb (r5)+ ,(r1)+ ; Copy the data now
dec r3 ; Keep track of remaining space
beq 75$ ; No room left
sob r0 ,70$ ; Next please
74$: movb #40 ,(r1)+ ; Now space fill the line
sob r3 ,74$ ; Next please
75$: mov (sp)+ ,r1 ; Restore text address
ENCRYPT r1,enckey ; Encode it
80$: asr r2 ; Set 'Current' Command index
mov r2 ,@curcmd ; And save it
br 100$ ; Exit
90$: movb #CR ,@r4 ; Return only a carriage return
clrb 1(r4) ; .ASCIZ
100$: STRLEN r4 ; Get line length
mov r0 ,r1 ; Where to return it.
clr r0 ; No errors
mov (sp)+ ,r5 ; Restore r5
clc ; All done
return ; Exit
.dsabl lsb
; PREV: Recall previous command line, UP-Arrow Key.
Prev: DEBUG <Prev> ; ...
mov r5 ,-(sp) ; Save it
10$: mov @curcmd ,r2 ; Current command number
blt 100$ ; Never been here.
CALL sol ; Back up
WRTALL #$cr ; Start of line
WRTALL #$ceol ; Clear
WRTALL @r5 ; Prompt
asl r2 ; We want addresses today
mov lastli(r2),r2 ; At last
tstb @r2 ; Anything to copy?
bne 20$ ; Yes
dec @curcmd ; No, back up again
bge 10$ ; Ok
clr @curcmd ; Reached the end
br 100$ ; And exit
20$: clrb @r4 ; TO be safe
clr r3 ; Get length next
bisb (r2)+ ,r3 ; Do it
beq 50$ ; Nothing?
mov @maxsiz ,r0 ; Copy all for DES types
mov r4 ,r5 ; A copy of the destination
30$: movb (r2)+ ,(r5)+ ; Copy it
sob r0 ,30$ ; Next please
DECRYPT r4,deckey ; Decode the data
add r4 ,r3 ; Point to the real end of data
clrb @r3 ; Insure .asciz
WRTALL r4 ; Echo it
50$: CALL gotoeol ; Move to end of the line
STRLEN r4 ; Get length
mov r0 ,@curlen ; And save it
tst @curcmd ; Check for underflow
ble 100$ ; Yes, exit
dec @curcmd ; No, backup now.
br 100$ ; Exit
90$: clrb @r4 ; Nothing, kill the buffer
100$: sec ; Not done yet
mov (sp)+ ,r5 ; Restore this
return ; Exit
; Control U: Erase entire line
Ctrlu: DEBUG <Ctrlu> ; ...
CALL sol ; Move to start of the line
WRTALL #$ceol ; Erase to the end of the line
clrb @r4 ; No data left over
clr @curlen ; No length
sec ; Not done
return ; Exit
Right: DEBUG <Right> ; ...
STRLEN r4 ; Get current length of the line
cmp @curpos ,r0 ; Already at EOL?
bhis 100$ ; Yes
inc @curpos ; No, move over
WRTALL #$right ; Simple to do.
100$: sec ; Not done
return ; Exit
.sbttl Rubouts and move left
; DORUB: Erase character
Dorub: DEBUG <Dorub>,FALSE ; ...
sub #200 ,sp ; Allocate a buffer again
mov sp ,r3 ; And a pointer to such.
tstb @r4 ; Is there ANYTHING in the line?
beq 100$ ; No, it's a NO-OP
tst @curpos ; Already at SOL (start of line)?
bgt 10$ ; No
clr @curpos ; Insure correct position
clr @curlen ; Save this
br 20$ ; Off to common code
10$: mov r4 ,r2 ; See if at eoln
add @curpos ,r2 ; Compute address
dec @curpos ; Correct offset now
dec @curlen ; Fix this up
movb @r2 ,-(sp) ; Get current
beq 20$ ; Nothing to do
WRTALL #$LEFT ; Go back one please
20$: mov r4 ,r2 ; And move down
add @curpos ,r2 ; Point to CURRENT character
mov r2 ,r1 ; Again
inc r1 ; Next position please
STRCPY r3 ,r1 ; Make a temporary copy of the data
STRCPY r2 ,r3 ; Move it down
tstb (sp)+ ; Were we already at EOL?
bne 30$ ; No
WRTALL #$rrub ; Use simple style BS SP BS if EOL
br 100$ ; Exit
30$: WRTALL #$save ; Save cursor position
WRTALL #$ceol ; Erase to EOL
WRTALL r2 ; Dump buffer
WRTALL #$restore ; And go back
100$: add #200 ,sp ; Pop local buffer and Exit
sec ; Not done
return ; Exit
; Left: Move left one character
Left: DEBUG <Left> ; ...
tst @curpos ; Can we back up ?
ble 100$ ; No
dec @curpos ; Yes, backup a bit
WRTALL #$left ; And do so.
100$: sec ; Not done
return ; Exit
.sbttl Command recall and control R processing
Next: DEBUG <Next> ; ...
mov r5 ,-(sp) ; Save
mov curcmd ,r2 ; Point to CURCMD
tst @r2 ; Current command number
blt 100$ ; Never been here.
mov lastcnt ,-(sp) ; Get the recall buffer count
dec (sp) ; ...
cmp @r2 ,(sp)+ ; Can we move up?
bge 100$ ; No
inc @r2 ; Yes, move up.
CALL sol ; Back up
WRTALL #$cr ; Start of line
WRTALL #$ceol ; Clear
WRTALL @r5 ; Prompt
mov @r2 ,r2 ; Copy it.
asl r2 ; We want addresses today
mov lastli(r2),r2 ; At last
tstb @r2 ; Anything to copy?
beq 90$ ; No
;
clrb @r4 ; TO be safe
clr r3 ; Get length next
bisb (r2)+ ,r3 ; Do it
mov @maxsiz ,r0 ; Copy ALL for DES type routines
mov r4 ,r5 ; A copy of the destination
30$: movb (r2)+ ,(r5)+ ; Copy it
sob r0 ,30$ ; Next please
DECRYPT r4,deckey ; Decode the data
add r4 ,r3 ; Point to the real end of data
clrb @r3 ; And force to .ASCIZ
WRTALL r4 ; Dump the data
call gotoeol ; Fix internal pointers
STRLEN r4 ; Get last line length
mov r0 ,@curlen ; And save it
mov lastcnt ,-(sp) ; Get the recall buffer count
dec (sp) ; ...
cmp @curcmd ,(sp)+ ; Poised at the last command?
bne 100$ ; No
dec @curcmd ; Fix so PREV works correctly.
br 100$ ; Exit
90$: clrb @r4 ; Nothing, kill the buffer
100$: sec ; Not done yet
mov (sp)+ ,r5 ; Restore
return ; Exit
Retype: DEBUG <Retype> ; ...
WRTALL #$cr ; Start of line
WRTALL #$ceol ; Clear
WRTALL @r5 ; Prompt
WRTALL r4 ; Dump the buffer
WRTALL #$cr ; Back up again
STRLEN @r5 ; Get a new poistion now
add @curpos ,r0 ; Get to correct position
beq 100$ ; Nothing (?)
10$: WRTALL #$right ; Move over
sob r0 ,10$ ; Simple
100$: sec ; Not yet done
return ; Exit
Cantyp: call clrcns ; Eat up console data
sec ; Not done
return ; Exit
Toggle: mov #IN$MODE,r0 ; Toggle modes
xor r0 ,@clests ; Do it
sec ; Not done
return ; Exit
.sbttl Utilities
.if ne ,$MINITAB
.ift
Strlen: mov 2(sp) ,r0 ; Get string length
10$: tstb (r0)+ ; Look for end
bne 10$ ; Not yet
sub 2(sp) ,r0 ; Compute length
dec r0 ; Fix
mov (sp)+ ,(sp) ; Pop stack
return ; Exit
; Strcpy
;
; input:
; 0(sp) return address
; 2(sp) dst address
; 4(sp) src address
; output: r0 dest address
Strcpy: save <r1> ; save temp registers please
mov 2+2(sp) ,r0 ; destination address
mov 2+4(sp) ,r1 ; source .asciz address
10$: movb (r1)+ ,(r0)+ ; copy until a null
bne 10$ ; not done
mov 2+2(sp) ,r0 ; return the dst address
unsave <r1> ; pop r1 and exit
mov (sp) ,4(sp) ; move return address up now
cmp (sp)+ ,(sp)+ ; pop junk and exit
return
; S C A N C H
;
; input: 4(sp) the string address
; 2(sp) the character to look for
; output: r0 position of ch in string
Scanch: save <r2> ; save temps
mov 6(sp) ,r2 ; get address of the string
clr r0 ; initial found position
10$: tstb @r2 ; end of the string yet ?
beq 90$ ; yes
inc r0 ; no, pos := succ(pos)
cmpb 4(sp) ,(r2)+ ; does the ch match the next one?
bne 10$ ; no, try again
br 100$ ; yes, exit loop
90$: clr r0 ; failure, return postion = 0
100$: unsave <r2> ; pop r2
mov @sp ,4(sp) ; move return address up
cmp (sp)+ ,(sp)+ ; pop stack
return ; and exit
.endc ; If NE, $Minitab
.end