-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathUade19.asm
760 lines (592 loc) · 14.2 KB
/
Uade19.asm
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
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
;.OPT
;UADE19;File > Uade19
;.TTL
;Fileserver file UADE19
.UADE19
;**********
;* GETBYT *
;**********
;Read single byte from file.
;All work done by RNDMAN.
;Entry: BPTR is offset of buffer in RXBUF
;QPTR is offset of control block in RXCBV
.GETBYT
{
JSR STKUSE;Put user info ptr on stack
BNE GTBYTZ
LDX BPTR
LDA RXBUF + 2,X;Get file handle
LDY #ARGD
STA (NEWARG),Y
LDX QPTR;Get seq no. from control block
LDA RXCBV,X
AND #1;Mask out reception flag
INY
STA (NEWARG),Y
LDA #7;RNDMAN.RDCH
JSR SETRTN
JSR RNDMAN;*** Call RNDMAN.RDCH **
BNE GTBYTX;Failed
LDY #ARGB
LDA (NEWARG),Y;Get byte read
STA MIDTX;Put in TX buffer
INY
LDA (NEWARG),Y;Get EOF flag
STA MIDTX + 1;Put in TX buffer
LDA #TXHDR + 2;Message length
;Note that sequence no. is still in control block
JSR REPLYC;Send reply
.GTBYTZ
JMP COMRTS;exit
.GTBYTX
JMP ERROR
}
;**********
;* PUTBYT *
;**********
;Write single byte to file.
;All work done by RNDMAN.
;Entry: BPTR is offset of buffer in RXBUF
;QPTR is offset of control block in RXCBV
.PUTBYT
{
JSR STKUSE;Put user info ptr on stack
BNE PTBYTZ
LDX BPTR
LDA RXBUF + 2,X;Get file handle
LDY #ARGD
STA (NEWARG),Y
LDX QPTR;Get seq no. from control block
LDA RXCBV,X
AND #1;Mask out reception flag
INY
STA (NEWARG),Y
LDX BPTR
LDA RXBUF + 3,X;Get byte to be written
INY
STA (NEWARG),Y;Put on call stack
LDA #8;RNDMAN.WRCH
JSR SETRTN
JSR RNDMAN;*** Call RNDMAN.WRCH **
;Note that sequence no. is still in control block
JSR RCODE;Send return code
.PTBYTZ
JMP COMRTS;exit
}
;* CPRDAR *
;Read specified part of file info
;Most work done in RNDMAN.
.CPRDAR
{
JSR GETUSR;USTPTR := USERTB entry
BNE CPRDAX
JSR SETUSR;Copy user info to NEWARG stack
LDX BPTR;Offset of request buffer
LDA MIDRX,X;Get handle
LDY #ARGD
STA (NEWARG),Y;Put handle on NEWARG stack
LDA #&B;RNDMAN.RDAR
JSR SETRTN
JSR RNDMAN;*** Call RNDMAN.RDAR **
BNE CPRDAB;Not OK, send error code and exit
;Have now got sequential file ptr, file hwm,
;and file size on NEWARG stack.
;The one to be sent back is determined by
;arg in request block.
;Arg is 0,1,2 resp. to get the above.
;Set Y to appropriate offset on NEWARG stack
LDX BPTR;Offset of request buffer
LDA MIDRX + 1,X;Arg from request
BNE CPRDAC;Not 0
LDY #ARGB;Offset of file ptr
BNE CPRDAF;Always jumps
.CPRDAC
CMP #1;Test arg
BNE CPRDAD;Not 0 or 1
LDY #ARGE;Offset of file HWM
BNE CPRDAF;Always jumps
.CPRDAD
CMP #2;Test arg
BNE CPRDAE;Not 0, 2, or 1
LDY #ARGH;Offset of file size
BNE CPRDAF;Always jumps
;Invalid arg in request
.CPRDAE
LDA #ARGERR;"Bad arg to RDAR"
.CPRDAB
JMP ERROR
;Y now contains the offset on NEWARG
;of the required 3 bytes.
.CPRDAF
LDA (NEWARG),Y;LS byte
STA MIDTX;Put in TX buffer
INY
LDA (NEWARG),Y;CS byte
STA MIDTX + 1
INY
LDA (NEWARG),Y;MS byte
STA MIDTX + 2
LDA #TXHDR + 3;Mesage length
JSR REPLYC;Send reply
.*CPRDAX
JMP COMRTS;Exit
}
;* CPSTAR *
;Set sequential file pointer
.CPSTAR
{
JSR GETUSR;USTPTR := ptr to user info
BNE CPSTAX
JSR SETUSR;Copy user info to stack
LDX BPTR;Offset of request buffer
LDA MIDRX,X;Get handle
LDY #ARGD
STA (NEWARG),Y;Put handle on stack
;Put arg saying what to set on stack
LDA MIDRX + 1,X
INY
STA (NEWARG),Y
;Put value to be set on stack
LDA MIDRX + 2,X;value (LS)
INY
STA (NEWARG),Y
LDA MIDRX + 3,X;value (CS)
INY
STA (NEWARG),Y
LDA MIDRX + 4,X;value (MS)
INY
STA (NEWARG),Y
LDA MIDRX + 5,X;Some vals have 4 bytes
INY
STA (NEWARG),Y
LDA #&C;RNDMAN.STAR
JSR SETRTN
JSR RNDMAN;*** Call RNDMAN.STAR **
JSR RCODE;Transmit reply
.CPSTAX
JMP COMRTS;Exit
}
;************
;* PUTBYTES *
;************
;Write several bytes to specified file offset.
;1) Set up pointer to user info
;2) (abolished)
;3) Send first reply, giving data port
;and max. blocksize.
;4) LOOP: receive block into big buffer
;5) LOOP: write to disc (RNDMAN.PUTBYTES)
;unless disc error flag set
;6) LOOP: If disc error, then set flag but
;continue to receive.
;7) LOOP: If more to receive, adjust OFFSET
;and loop to 4).
;8) Send final RC (disc error flag)
;Entry: BPTR is offset of buffer in RXBUF
;QPTR is offset of control block in RXCBV
.PBYTES
{
JSR GETUSR;USTPTR := ptr to user info
BNE PBYTEK;not logged on ** 6/9/84 **
JSR RMSUBO;Prepare for some PUTBYTES calls
BEQ PBYTEJ
.PBYTEC
JSR EXTERR;Not OK, send RC
.PBYTEK
JMP COMRTS
;Send first reply, giving data port and max blocksize
.PBYTEJ
LDA #PSAVD;Use same data port as SAVE
STA MIDTX
LDA #LO(BUFSZ);Big buffer size (2 bytes)
STA MIDTX + 1
LDA #HI(BUFSZ)
STA MIDTX + 2
LDA #0;RTCODE := CCODE := 0
STA RTCODE
STA CCODE
LDA #TXHDR + 3;Message length
JSR REPLY;Send message
BNE PBYTEK
;Ready to receive data, so set up for
;reception loop.
LDA #0;DATAIN := 0 (3 bytes)
STA DATAIN
STA DATAIN + 1
STA DATAIN + 2
STA DSCERR;Clear disc err flag
STA FINFLG;Clear end-of-transfer flag
;Test specially for transfer of zero bytes,
;to prevent 64K net control block being
;set up! Jump straight to final reply.
LDX BPTR
LDA MIDRX + 2,X;Ls byte of size
ORA MIDRX + 3,X;CS
ORA MIDRX + 4,X;MS
BNE PBLOOP;Not zero bytes
JMP PBYTED;Jump straight to final reply
.PBLOOP
;Loop which receives data and writes it to disc
;Set buffer pointers in RX control block
LDY QPTR;Buffer start = BBUF
LDA BBUF
STA CBBUF,Y
LDA BBUF + 1
STA CBBUF + 1,Y
LDA BBEND;Buffer end = BBEND
STA CBBUFE,Y
LDA BBEND + 1
STA CBBUFE + 1,Y
LDA #PSAVD;Set data port
STA CBPORT,Y
;Station already set from first reception
JSR WAIT;Wait for reception
BNE PBYTEK;No contact => abort
;Now subtract buffer limits to see how
;much data was received.
LDY QPTR
SEC ;COWORK := CBBUFE-CBBUF
LDA CBBUFE,Y
SBC CBBUF,Y
STA COWORK;LS byte
LDA CBBUFE + 1,Y
SBC CBBUF + 1,Y
STA COWORK + 1;MS byte
;Add amount received to total number of bytes
;received.
CLC ;DATAIN +:= COWORK
LDA COWORK;LS byte
ADC DATAIN
STA DATAIN
LDA COWORK + 1;CS byte
ADC DATAIN + 1
STA DATAIN + 1
BCC PBLOOA
INC DATAIN + 2
.PBLOOA
;Compare total amount received (in DATAIN)
;with total number of bytes to be written.
;(in original message buffer).
;Set FINFLG if exactly the right amount
;has been received.
;If too much has been received, then send
;a return code.
LDX BPTR
SEC
LDA MIDRX + 2,X;LS byte of size
SBC DATAIN
STA BREGA;Use BREGA as workspace
LDA MIDRX + 3,X;CS byte of size
SBC DATAIN + 1
STA BREGA + 1
LDA MIDRX + 4,X;MS byte
SBC DATAIN + 2
;Carry set if received <= size
ORA BREGA;OR 3 bytes of result
ORA BREGA + 1;for zero test
BEQ PBLOOC;Equal => last block
BCS PBLOOD;Recd < size => carry on
;Client sent too much data.
;Send error code and stop.
LDA #PBERRA;Error code
JMP PBYTEC;Send RC and exit
.PBLOOC
LDA #&FF;Last block; set FINFLG
STA FINFLG
;If disc error flag set, ignore received data,
;and jump round disc write.
.PBLOOD
LDA DSCERR;Disc error flag
BNE PBLOOE;Jump if error
;Set up for call of RNDMAN
LDX BPTR
LDA MIDRX,X;Get file handle
LDY #ARGD
STA (NEWARG),Y;Put on call stack
LDA BBUF;Buffer addr (Big Buffer)
INY
STA (NEWARG),Y
LDA BBUF + 1
INY
STA (NEWARG),Y
LDA COWORK;No. of bytes (calculated above)
INY
STA (NEWARG),Y;LS byte
LDA COWORK + 1
INY
STA (NEWARG),Y;MS byte
LDA #&A;RNDMAN.PUTBYTES
JSR SETUSB;Stack user info
JSR RNDMAN;*** RNDMAN.PUTBYTES **
BEQ PBLOOE;OK, continue
STA DSCERR;Store error code
;If FINFLG is set, then we have just written
;the last block.
;Otherwise, adjust the file offset and carry on.
.PBLOOE
LDA FINFLG;Finished?
BNE PBYTED;Exit from loop if yes
;Send ack to client's ack port
LDY BPTR
LDX CPUFD,Y;Ack port
LDA #1;Message length
JSR REPLYB;Send byte (random contents)
BNE PBYTEZ;Contact lost => abort
JMP PBLOOP;Round loop again
.PBYTED
;Have received all the data.
;Final RC is in DSCERR.
;If RC is zero, send back amount xferred (always amount requested
;if no error). If non-zero, send error.
LDA DSCERR
STA RTCODE
BNE PBYTEX;RC <> 0 => error
STA CCODE;Set command code = 0
STA MIDTX+4;send 32 bit number
LDX BPTR
LDA MIDRX + 2,X
STA MIDTX + 1
LDA MIDRX + 3,X
STA MIDTX + 2
LDA MIDRX + 4,X;Move length of data to MIDTX
STA MIDTX + 3
LDA #TXHDR + 5
JSR REPLYC;Send reply (note MIDTX undefined)
.PBYTEZ
JMP COMRTS;Exit from command
.PBYTEX
JSR RCODE;Send error reply
JMP PBYTEZ
}
;************
;* GETBYTES *
;************
;Read several bytes from specified file offset.
;1) Set up pointer to user info
;2) Save size of transfer.
;SEND first RC to client
;3) LOOP: read chunk into big buffer (RNDMAN.GETBYTES)
;unless disc error flag set
;4) LOOP: If disc error, then set flag but
;continue to send data.
;5) LOOP: send to client
;6) LOOP: If more to send, adjust OFFSET
;and loop to 3).
;7) Send final RC (disc error flag)
;Entry: BPTR is offset of buffer in RXBUF
;QPTR is offset of control block in RXCBV
.GBYTES
{
LDA #0
STA GBBXFD;GBBXFD := 0
STA GBBXFD + 1
STA GBBXFD + 2
STA GBEFLG;GBEFLG := 0
JSR GETUSR;USTPTR := ptr to user info
BNE GBYTEC;OK, continue ** 6/9/84 **
JSR RMSUBO;Set up RNDMAN for GETBYTES calls
BEQ GBYTEF
JSR EXTERR;Not OK, send RC
.GBYTEC
JMP COMRTS
.GBYTEF
JSR RCODE;Send "OK" rc
BNE GBYTEC;lost contect so ABORT
;TOSEND := size of transfer
LDX BPTR
LDA MIDRX + 2,X;Size (LS)
STA TOSEND
LDA MIDRX + 3,X;Size (CS)
STA TOSEND + 1
LDA MIDRX + 4,X;Size (MS)
STA TOSEND + 2
;Use the big buffer.
;Read from disc chunks of size BUFSZ, and transmit
;them to the client.
;Note that, in general, each chunk will be badly
;aligned with respect to disc blocks. RNDMAN tries
;to be efficient about this for each chunk.
;It may be worth adding extra optimization here if
;very large (> BUFSZ) transfers are common.
LDA #0
STA DSCERR;No disc error yet
STA FINFLG;Not finished yet
;Test specially for transfer of zero
;bytes to prevent 64K net control
;block being set up!
LDA TOSEND;Size (LS)
ORA TOSEND + 1;CS
ORA TOSEND + 2;MS
BNE GBLOOP;OK - not zero bytes
JMP GBYTEB;Jump straight to final reply
;Loop, sending data to client in blocks of
;size BUFSZ. TOSEND is the amount left to
;send, OFFSET the current file position.
;If an error occurs, the error code is put
;in DSCERR and the loop continues, padding
;out the transmission until the right
;amount of data has been sent.
;FINFLG gets set on the last time round
;the loop.
.GBLOOP
SEC ;COWORK := TOSEND - BUFSZ
LDA TOSEND
SBC #LO(BUFSZ)
STA COWORK
LDA TOSEND + 1
SBC #HI(BUFSZ)
STA COWORK + 1
LDA TOSEND + 2
SBC #0;BUFSZ only 2 bytes
STA COWORK + 2
ORA COWORK;OR 3 bytes for zero test
ORA COWORK + 1
BEQ GBLOOA;TOSEND = BUFSZ
BCS GBLOOB;TOSEND < BUFSZ
;BUFSZ >= TOSEND: send remaining data
;and set finish flag.
.GBLOOA
LDA TOSEND;OUTBSZ := TOSEND
STA OUTBSZ
LDA TOSEND + 1
STA OUTBSZ + 1
DEC FINFLG;Set loop finish flag to $FF
BNE GBLOOC
.GBLOOB
LDA #LO(BUFSZ);OUTBSZ := BUFSZ
STA OUTBSZ
LDA #HI(BUFSZ)
STA OUTBSZ + 1
.GBLOOC
;The size of the block to send is in OUTBSZ.
;Call RNDMAN.GETBYTES to get the data into
;the big buffer.
LDX BPTR
LDA MIDRX,X;Get file handle
LDY #ARGD
STA (NEWARG),Y;Put handle on stack
LDA BBUF;Put buffer address on stack
INY
STA (NEWARG),Y
LDA BBUF + 1
INY
STA (NEWARG),Y
LDA OUTBSZ;Put no. of bytes on stack
INY
STA (NEWARG),Y
LDA OUTBSZ + 1
INY
STA (NEWARG),Y
LDA #9;RNDMAN.GETBYTES
JSR SETUSB
JSR RNDMAN;*** Call RNDMAN.GETBYTES **
BEQ GBLOOD;OK, continue
STA DSCERR;Otherwise set error code
.GBLOOD
;Add number of bytes actually read to
;GBBXFD, and OR end-of-file flag
;into GBEFLG.
CLC
LDY #ARGB
LDA (NEWARG),Y;Bytes xferred (LS)
ADC GBBXFD
STA GBBXFD;LS total
INY
LDA (NEWARG),Y
ADC GBBXFD + 1
STA GBBXFD + 1;CS total
BCC GBLOOJ
INC GBBXFD + 2;MS total
.GBLOOJ
INY
LDA (NEWARG),Y;EOF flag
ORA GBEFLG;OR with flag so far
STA GBEFLG
LDY BPTR
LDA CPUFD,Y;Get client's data port
JSR SENDBC;Send big block (size in OUTBSZ)
BNE GBYTEZ
;End of loop. Test finish flag, and set
;TOSEND from COWORK.
BIT FINFLG;Test finish flag
BMI GBYTEB;Exit from loop if finished
LDA COWORK;TOSEND := COWORK
STA TOSEND
LDA COWORK + 1
STA TOSEND + 1
LDA COWORK + 2
STA TOSEND + 2
JMP GBLOOP;Loop return
;Exit from GBLOOP: RC in DSCERR
.GBYTEB
LDA DSCERR
BNE GBYTEE;Jump if error
;Send back end-of-file flag and
;count of bytes actually read.
LDA GBEFLG;EOF flag
STA MIDTX;Put in TX buffer
LDA GBBXFD;Bytes xferred (LS)
STA MIDTX + 1
LDA GBBXFD + 1
STA MIDTX + 2;CS
LDA GBBXFD + 2
STA MIDTX + 3;MS
LDA #0
STA MIDTX+4;send 32 bit number ** 26/2/85 **
LDA #TXHDR + 5;Message length
JMP DATOUT;Send reply
.GBYTEE
JSR RCODE;Send return code
.GBYTEZ
JMP COMRTS;Exit from command
}
;*** Call RNDMAN to set up bytes operation
.RMSUBO
{
LDA #&E;**** RNDMAN.SUBO ***
JSR SETUSB
LDX BPTR
LDA MIDRX + 0,X;Get file handle
INY
STA (NEWARG),Y
LDX QPTR;Get seq no from control block
LDA RXCBV,X
AND #1;Get just seq bit
INY
STA (NEWARG),Y
;The flag, no of bytes, and offset
;are in the correct order in rx block
LDX BPTR
.RMSUBA
LDA MIDRX + 1,X
INY
STA (NEWARG),Y
INX
CPY #ARGL
BNE RMSUBA;More to copy
JMP RNDMAN;**** Call RNDMAN.SUBO & return ***
}
.CPWHO
{
;ROUT;** 19/3/85 **
;Yet another interface - this one allows an application
;to determine the userid under which it is logged-on
;This is probably most useful for MAILing type progs
JSR GETUSR
BNE Y20;nb this will deal with the error
LDX #0
LDY #UTUSID
.Y10
LDA (USTPTR),Y;copy the user name
STA MIDTX,X
INY
INX
CMP #CR;copy only upto CR (pw follows - dont want that)
BNE Y10
TXA
JMP DATOT2
.Y20
JMP COMRTS
}
;.LNK
;UADE20