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
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
|
IF NOT lasm
.printx * CPXTOR.ASM *
ENDIF ;NOT lasm
; KERMIT - (Celtic for "FREE")
;
; This is the CP/M-80 implementation of the Columbia University
; KERMIT file transfer protocol.
;
; Version 4.0
;
; Copyright June 1981,1982,1983,1984,1985
; Columbia University
;
; Originally written by Bill Catchings of the Columbia University Center for
; Computing Activities, 612 W. 115th St., New York, NY 10025.
;
; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
; others.
;
; This file contains the system dependent part for Torch, Superbrains,
; PCI2651 (Loughborough 8" Standard CP/M system) and Cifer computers.
;
; This is the first attempt to break the huge CPXSYS.ASM file
; into smaller system dependent files. To start with I will bunch
; several micros to one class.
;
; Please name system dependent files in the form CPXxxx.ASM where
; xxx is a three letter abbrev. for the system you are adding.
;
; revision history:
;
;edit 5, 10-Jan-1991 by MF. Removed references to assembly switch ker09.
; edit 4, 21 July, 1987 by OBSchou. Removed routines no in CPXCOM.ASM
;
; edit 3, 8 April, 1987 by OBSchou. Moved the VDU declarations for the
; Torch, superbrain and Cifer from CPXVDU.ASM. Also added code to
; see if the MCP/CCCP ROM versions on the Torch is less or grater than
; 1. Less than 1 => poor screen control. Finally adjusted the
; positioning of the filename to cope with a user number and drive
; in the filename field
;
;
; edit 2, 20 March, 1987 by C.J.MILES@UK.AC.UMRCC. Added support for
; NCR Decision Mate V (2651 USART)
;
; edit 1, 22 April, 1986, OBSchou. Start on splitting off individual
; systems from this huge file. It is done using the LINK facility
; LASM. We link to a collection of systems under CPXxxx.ASM.
; I have started with the systems I know, the Torch, Cifer and
; pci2651. These will all be held under CPXTOR.ASM
;
;
; Keep module name, edit number, and last revision date in memory.
family: db 'CPXTOR.ASM (5) 10-Jan-1991 $'
;
; Assembly time message to let me know I'm building the right version.
; LASM generates an 'S' error along with the message, which is messy, but
; better than trying to put everything inside a IF m80 OR mac80 conditional,
; because LASM doesn't like nested IF's, either.
IF ncrdmv
.printx * Assembling KERMIT-80 for the N.C.R. Decision Mate V *
ENDIF
IF brain
.printx * Assembling KERMIT-80 for the Intertec Superbrain *
ENDIF
IF brainm
.printx * With main port selected
ENDIF
IF braina
.printx * With Aux port
ENDIF
IF pci2651 ;
.printx * assembling Kermit-80 for 2651 PCI as comms device *
ENDIF
IF torch
.printx * Assembling Kermit-80 for Torch Unicorn 5 *
ENDIF
; *******This should be in the original CPXSYS.ASM file
;
;=========================================================================
; I/O Byte assignments (2-bit fields for 4 devices at loc 3)
;
;bits 6+7 LIST field
; 0 LIST is Teletype device (TTY:)
; 1 LIST is CRT device (CRT:)
; 2 LIST is Lineprinter (LPT:)
; 3 LIST is user defined (UL1:)
;
;bits 4+5 PUNCH field
; 0 PUNCH is Teletype device (TTY:)
; 1 PUNCH is high speed punch (PUN:)
; 2 PUNCH is user defined #1 (UP1:)
; 3 PUNCH is user defined #2 (UP2:)
;
;bits 2+3 READER field
; 0 READER is Teletype device (TTY:)
; 1 READER is high speed reader (RDR:)
; 2 READER is user defined #1 (UR1:)
; 3 READER is user defined #2 (UR2:)
;
;bits 0+1 CONSOLE field
; 0 CONSOLE is console printer (TTY:)
; 1 CONSOLE is CRT device (CRT:)
; 2 CONSOLE is in Batch-mode (BAT:);READER = Input,
; LIST = Output
; 3 CONSOLE is user defined (UC1:)
;
;=========================================================================
iobyte EQU 03H ;Location of I/O byte
; [13] modifed to use either main or aux port. Should really
; be selected by set port, but this is urgent, so no frills
IF brain
baudst EQU 60H ;
baudrt EQU 0EF00H ;Memory location where baud rates are stored.
output EQU 01H ;Transmitter ready
input EQU 02H ;Input data available
TxEmpty EQU 04h ;Transmitter empty
z80 SET TRUE ;I don't know...
ENDIF;brain
IF brainm ; Superbrain and main ports
mnport EQU 58H ;Modem data port
mnprts EQU 59H ;Modem status port
ENDIF ;brainm
IF braina ; Superbrain and aux port
mnport EQU 40H ;Modem data port
mnprts EQU 41H ;Modem status port
ENDIF ;braina [13]
IF ncrdmv
iobase equ 70h ; base address of PCI device
modrx equ 70h ; Rx data port
mnprts equ 71h ; status port
mnmodr equ 72h ; mode register read
mncmdr equ 73h ; command register read
modtx equ 74h ; Tx data port
mnmodw equ 76h ; mode register write
mncmdw equ 77h ; command register write
txrdy equ 1
output equ txrdy
rxrdy equ 2
input equ rxrdy
baudini equ 0ah ; initial baud to 2400
z80 SET true
cpuspd SET 40
ENDIF
IF pci2651 ;[28]
iobase equ 04h ; base address of PCI device
mnport equ iobase ; rx and tx data ports
mnprts equ iobase+1 ; status port
mnmode equ iobase+2 ; mode port
mncmd equ iobase+3 ; PCI command port
txrdy equ 1 ; tx ready bit set if free
output equ txrdy
rxrdy equ 2 ; RX ready bit
input equ rxrdy
baudini equ 7 ; 7 => 1200 baud by default
z80 SET true ; For Ithica intersystems it is
cpuspd SET 40 ; and running at four megs
ENDIF ;[28]
IF torch ;[13]
z80 SET TRUE
; [32] baudini removed as now read current baud rate
; settings from base processor.
;baudini equ 707h ; Initial Baud rate = 1200 baud
; Entry to be of form x0xh where x is
; the value x in the FX 7,x and FX 8,x
; funtion calls. 4= 1200 baud, 7 = 9600
; 2 = 300 baud.
ENDIF
IF brain OR torch
defesc EQU ']'-100O ;The default escape character.
ENDIF;brain OR torch
; If none of the above, default to VT52-EMULATION ON.
IF NOT crt
vtval EQU 1
ENDIF;NOT crt
sysxin:
IF brainm ;[25]
lda baudrt ; fetch current baud rate
ani 0F0H ; extract left nibble
rrc ; shift right 4 places
rrc
rrc
rrc
sta speed ; store as comm port speed
sta speed+1 ; (16 bits, to match speed table entries)
ENDIF;brainm
IF braina ;[25]
lda baudrt ; fetch current baud rate
ani 00FH ; extract right nibble
sta speed ; store as comm port speed
sta speed+1 ; (16 bits, to match speed table entries)
ENDIF;braina
IF torch ; [13] [32]
push h
mvi a,0f2h ; nick code from BBC initialisation
lxi h,0ff00h
call osbyte ; Read current speed setting
mov a,l
ani 7
xri 7 ; Store as two's complement
inr a
sta speed
sta speed+1
mov e,a
call sysspd ; Make sure they are both the same!
mvi a,15 ; Flush all internal buffers [32]
mvi l,0
; call osbyte
mvi a,3
lxi h,0100h ; *FX 3,0,1 Enable RS423
call osbyte
mvi a,2 ; Select keyboard, Enable RS423 input
mvi l,2
call osbyte
mvi a,5 ; Select serial printer [32]
mvi l,2
call osbyte ; [30]
mvi a,6 ; Must be able to send LF [30]
mvi l,0
call osbyte ; [30]
mvi a,202 ; FX 202,255 set lower case on
mvi l,255
call osbyte
pop h
; Now see what version of MCP CCP roms. Assume >1, else copy a few of the
; older Torch VDU declares over the new ones.
;
; lda 0ffffh ; Address 0ffffh has single byte Version no.
; push psw ; save for a rainy day
; ani 0F0h ; get ms digit of MCP version
; rra ; move right 4 places
; rra
; rra
; rra
; ani 0fh
; adi 30h ; make it a number
; sta mcpver
; pop psw ; its raining...
; push psw ; ... its pouring...
; ani 0fh ; get ls digit
; adi 30h ; make it ascii number
; sta mcpver+2
; pop psw ; restore psw
; cpi 10h ; Version 1.00 or less?
; jp init2 ; yes, so skip next bit
; lxi h,ooutli ; from old string table
; lxi d,ttab ; to new ttab
; lxi b,60 ; 60 bytes to move
; call mover
init2:
IF ncrdmv
mvi a,00 ; clear out command register
out mncmdw
mvi a,4eh ; 1 stop bit, 8 data bits, / by 16 counter
out mnmodw
mvi a,70h+baudini ; baud rate and select internal rate gen.
out mnmodw
mvi a,27h ; enable tx and rx, RTS and DTR low
out mncmdw
ENDIF ; ncrdmv
IF pci2651 ;[28]
in mncmd ; clearw command reg counter
mvi a,4eh ; 1 stop bit, 8 data bits, / by 16 counter
out mnmode
mvi a,30h+baudini ; baud rate and select internal rate gen.
out mnmode
mvi a,27h ; enable tx and rx, RTS and DTR low
out mncmd
ENDIF ; pci2651 [28]
ret ; return from system-dependent routine
;
;
; system-dependent termination processing
; If we've changed anything, this is our last chance to put it back.
sysexit:
ret
;
; system-dependent processing for start of CONNECT command
;
syscon:
ret
conmsg: ; Messages printed when entering transparent (CONNECT) mode:
;
;
; syscls - system-dependent close routine
; called when exiting transparent session.
;
syscls:
ret
;
;
; sysinh - help for system-dependent special functions.
; called in response to <escape>?, after listing all the
; system-independent escape sequences.
;
sysinh:
IF torch OR brain OR pci2651 OR ncrdmv
lxi d,inhlps ; we got options...
call prtstr ; print them.
ENDIF;torch OR brain OR pci2651 OR ncrdmv
ret
;additional, system-dependent help for transparent mode
; (two-character escape sequences)
inhlps:
; [16] [18] have added super brain and Torch to the list of Breaking machines.
IF pci2651 OR brain OR torch OR ncrdmv
db cr,lf,'B Transmit a BREAK'
ENDIF ;pci2651 OR brain OR torch OR ncrdmv
IF torch ; added this simply to debug the escape cokebottle D for the apple
db cr,lf,'D Disconnect the modem (Test purposes only)'
ENDIF;Torch
db '$' ;[hh] table terminator
;
; sysint - system dependent special functions
; called when transparent escape character has been typed;
; the second character of the sequence is in A (and in B).
; returns:
; non-skip: sequence has been processed
; skip: sequence was not recognized
sysint: ani 137O ; convert lower case to upper, for testing...
; [19] have added superbrain and torch to the list
IF brain OR pci2651 OR torch OR ncrdmv
cpi 'B' ; send break?
jz sendbr ; yes, go do it. return nonskip when through.
ENDIF ;brain OR pci2651 OR torch OR ncrdmv
IF Torch; added bit for doing a D...
cpi 'D' ;drop the line...
jz dropln
ENDIF ;torch
jmp rskp ; take skip return - command not recognized.
IF torch
dropln: lxi d,dropm ; tell user line is dropped..
call prtstr
xra a ; destroy A
ret
dropm: db bell,cr,lf,'Testing line dropped ',cr,lf,bell
db '$'
ENDIF ;torch and dropping them there lines..
;
IF brain
sendbr:
;
; Ensure that the transmitter has finished sending buffered chars
sndbr1: in mnprts ; get UART status
ani TxEmpty ; everything sent?
jz sndbr1 ; no, wait a bit more
;
; Begin sending a break by setting bit in UART command register
mvi a,3Fh ; Set TxEna, DTR, RxEna, SBreak, ErrRst, RTS
out mnprts
;
; Wait for 250 milliseconds (using hundredths second delay routine)
mvi a,25
call delay
;
; Resume normal operation by clearing the SendBreak command bit
mvi a,37h ;Set TxEna, DTR, RxEna, ErrRst, RTS
out mnprts
;
ret ;done
ENDIF;brain
IF torch ; [18] [27] [30] [32]
; Send a break.
;
; [30] Dumping of 6502 code not yet used, but may be for later versions of
; the Torch CCCP Rom in the BBC. This works, so I leave it for now.
sendbr:
push h ;save for a monsoon
mvi a,0e8h
lxi h,0 ; turn interrupts off
call osbyte
push h
;
mvi a,9ch ; OSBYTE call 9c is read/write 6850 cntl prt
lxi h,0077h ; H = 6502 Y reg, L = 6502 X reg
call osbyte ; returned new val. = (old value AND Y)XOR X
push h ; save it for return
;
mvi a,30
call delay ; do a delay
;
; now clear rx register
;
mvi a,96h ; do a read sheila address 08h
mvi l,8
mvi h,0
call osbyte ; read sheila 08h = 6850 rx reg
;
; restore 6850 regs...
;
pop h ; restore previous cntl reg
; old x reg in l, so leave it there
; mov l,h
mvi h,0
mvi a,9ch ; write previous value to 6850
call osbyte
;
; and Beebs interrupt mask
;
pop h ; get interrupt mask
; Once again, old X in L so leave it alone
; mov l,h
mvi h,0
mvi a,0e8h
call osbyte ; restore interrupts mask
;
pop h
ret ; its raining again, so exit
ENDIF ; torch [18] [32]
IF ncrdmv
sendbr: in mnprts ; get status
ani 04h ; make sure shift register is empty
jz sendbr
mvi a,2fh ; force a break
out mncmdw
mvi a,100 ; set delay period
call delay
mvi a,27h ; restore command register
out mncmdw
ret
ENDIF ; ncrdmv
IF pci2651 ;[28]
sendbr: in mnprts
ani 04h ; make sure shift reg is clear
jz sendbr
mvi a,2fh ; set foe a break
out mncmd
mvi a,100 ; wait a bit
call delay
mvi a,27h ; restore mode
out mncmd
ret
ENDIF ;pci2651 [28]
;
; sysflt - system-dependent filter
; called with character in E.
; if this character should not be printed, return with A = zero.
; preserves bc, de, hl.
; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
sysflt:
mov a,e ; get character for testing
ret
; mdmflt - modem filter [30]
; called with character to be sent to printer in E
; with parity set as appropriate.
; return with accumulator = 0 do do nothing,
; <> 0 to send char in E.
mdmflt:
mov a,e ;[30] get character to test
IF torch ;[30] map del to bs,space,bs
ani 7fh ; strip parity
cpi 7fh ; is it the delete character
rnz ; no, then a <> 0 so print it
mvi e,bs ; else load a backspace
call outmdm ; little recursion...
mvi e,' ' ; then a space
call outmdm ; backspace, space, now another...
mvi e,bs ; backspace
call outmdm ;
xra a ; clear a => on return do nowt.
ENDIF ;torch [30]
ret
; prtflt - printer filter [30]
; called with character to be sent to printer in E
; returns with a = 0 to do nothing
; a <> 0 to print it.
;
; this routine for those printer that automatically insert
; a lf on cr, or cr for lf. Should this be shifted to
; the system indep. stuff, in say 4.06?
prtflt:
mov a,e ; [30] get character to test
IF torch ; strip out lf from printer stream
ani 7fh ; make sure it is parity less
cpi lf ; is it a line feed?
rnz ; no, print it
; xra a ; yes, don't.
ENDIF ;torch [30]
ret
;
;
; system-dependent processing for BYE command.
; for apmmdm, heath, and lobo, hang up the phone.
sysbye:
ret
;
; This is the system-dependent command to change the baud rate.
; DE contains the two-byte value from the baud rate table; this
; value is also stored in 'speed'.
sysspd:
; Set the speed for the Brain (Main Port)
IF brainm ;[25]
lda baudrt ;Get the present baud rates.
ani 0fH ;turn off the left
mov d,a ;Set it aside.
mov a,e ;Get the new baud rate.
rlc ;Shift left 4 places.
rlc
rlc
rlc
ora d ; combine with the old baud rate
sta baudrt ;Store the new baud rates.
out baudst ;Set the baud rates.
ret
ENDIF;brainm
; Set the speed for the Brain (Aux Port)
IF braina ;[25]
lda baudrt ;Get the present baud rates.
ani 0f0H ;turn off the right
ora e ; combine with the new baud rate
sta baudrt ;Store the new baud rates.
out baudst ;Set the baud rates.
ret
ENDIF;braina
If torch ; Set speed for Torch [14] [32]
mvi a,7 ; Osbyte call to set rx rate
mov l,e
call osbyte ;
mvi a,8 ; set up for tx rate to be set
mov l,e
call osbyte
ret ; and now, all rates should be different
ENDIF ;torch [14] [32]
IF ncrdmv ; Set baud rate for NCR Decision Mate V
mvi a,00 ; clear command register
out mncmdw
mvi a,4eh ; set for 1 stop, 8 data bits
out mnmodw ; save in mode 1 port
mvi a,70h ; set bits for rate etc..
add e ; add baud rate (bits 0 - 3)
out mnmodw ; set mode port 2
mvi a,27h ; set tx/rx ready, RTS CTS active
out mncmdw
ret
ENDIF ; ncrdmv
IF pci2651 ; Set baud for PCI [28]
in mncmd ; Clear register counter
mvi a,4eh ; set for 1 stop, 8 data bits
out mnmode ; save in mode 1 port
mvi a,30h ; set bits for rate etc..
add e ; add baud rate (bits 0 - 3)
out mnmode ; set mode port 2
mvi a,27h ; set tx/rx ready, RTS CTS active
out mncmd
ret
ENDIF ;pci2651 [28]
;
; Speed tables
; (Note that speed tables MUST be in alphabetical order for later
; lookup procedures, and must begin with a value showing the total
; number of entries. The speed help tables are just for us poor
; humans.
; db string length,string,divisor (2 identical bytes or 1 word)
; [Toad Hall]
IF brain OR pci2651 OR ncrdmv
spdtbl: db 10h ;16 entries
db 03h,'110$', 02h,02h
db 04h,'1200$', 07h,07h
db 05h,'134.5$', 03h,03h
db 03h,'150$', 04h,04h
db 04h,'1800$', 08h,08h
db 05h,'19200$', 0fh,0fh
db 04h,'2000$', 09h,09h
db 04h,'2400$', 0ah,0ah
db 03h,'300$', 05h,05h
db 04h,'3600$', 0bh,0bh
db 04h,'4800$', 0ch,0ch
db 02h,'50$', 00h,00h
db 03h,'600$', 06h,06h
db 04h,'7200$', 0dh,0dh
db 02h,'75$', 01h,01h
db 04h,'9600$', 0eh,0eh
sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200'
db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$'
ENDIF;brain OR pci2651 OR ncrdmv
IF torch ;[17]
spdtbl: db 8 ; 8 entries
db 4,'1200$', 4,4
db 3,'150$', 2,2
db 5,'19200$', 8,8
db 4,'2400$', 5,5
db 3,'300$', 3,3
db 4,'4800$', 6,6
db 2,'75$', 1,1
db 4,'9600$', 7,7
sphtbl: db cr,lf,' 75 150 300 1200 2400 4800 9600 19200$'
ENDIF;torch [17]
; The following conditionals were once a huge if not statement. There
; wasn't enough room to add the lobo to the list, so it had to be broken
; into 2, which you can't do with an if not. I redid it as two ifs and
; applied them to those that wouldn't set baud. [Hal Hostetler]
;
; This is the system-dependent SET PORT command.
; HL contains the argument from the command table.
sysprt:
IF iobyt
mov a,m ;Get the I/O byte
sta prtiob ;Save the desired IO byte for this port
inx h ;Point at next entry
mov a,m ;Get the output function
sta prtfun ;Save it
ENDIF;iobyt
ret
;
;
;
; Port tables for GENERIC CPM 2.2
IF gener
; help text
prhtbl: db cr,lf,'CRT device'
db cr,lf,'PTR device'
db cr,lf,'TTY device'
db cr,lf,'UC1 device'
db cr,lf,'UR1 device'
db cr,lf,'UR2 device$'
; command table
prttbl: db 06H ;Six devices to choose from
db 03H,'CRT$'
dw crtptb
db 03H,'PTR$'
dw ptrptb
db 03H,'TTY$'
dw ttyptb
db 03H,'UC1$'
dw uc1ptb
db 03H,'UR1$'
dw ur1ptb
db 03H,'UR2$'
dw ur2ptb
; port entry table
; table entries are:
; db iobyte-value, BDOS output function, reserved
crtptb: db crtio,conout,0
ptrptb: db ptrio,punout,0
ttyptb: db ttyio,conout,0
uc1ptb: db uc1io,conout,0
ur1ptb: db ur1io,punout,0
ur2ptb: db ur2io,punout,0
ENDIF;gener
;
;
IF iobyt
prtfun: db punout ;Function to use for output to comm port
prtiob: db batio ;I/O byte to use for communicating
coniob: db defio ;I/O byte to use for console
ENDIF;iobyt
IF NOT iobyt
prttbl equ 0 ; SET PORT is not supported
prhtbl equ 0
ENDIF;NOT iobyt
;
;
; selmdm - select modem port
; selcon - select console port
; selmdm is called before using inpmdm or outmdm;
; selcon is called before using inpcon or outcon.
; For iobyt systems, diddle the I/O byte to select console or comm port;
; For Decision I, switches Multi I/O board to console or modem serial
; port. [Toad Hall]
; For the rest, does nothing.
; preserves bc, de, hl.
selmdm:
IF iobyt
lda prtiob ;Set up for output to go to the comm port
sta iobyte ;Switch byte directly
ENDIF;iobyt
ret
selcon:
IF iobyt
lda coniob ;Set up for output to go to the console port
sta iobyte ;Switch directly
ENDIF;iobyt
ret
;
; Get character from console, or return zero.
; result is returned in A. destroys bc, de, hl.
;
inpcon:
IF NOT iobyt
mvi c,dconio ;Direct console I/O BDOS call.
mvi e,0FFH ;Input.
call BDOS
ENDIF;NOT iobyt
IF iobyt
call bconst ;Get the status
ora a ;Anything there?
rz ;No, forget it
call bconin ;Yes, get the character
ENDIF;iobyt
ret
;
;
; Output character in E to the console.
; destroys bc, de, hl
;
outcon:
IF NOT iobyt
mvi c,dconio ;Console output bdos call.
call bdos ;Output the char to the console.
ENDIF;NOT iobyt
IF iobyt
mov c,e ;Character
call bcnout ;to Console
ENDIF;iobyt
ret
;
;
; outmdm - output a char from E to the modem.
; the parity bit has been set as necessary.
; returns nonskip; bc, de, hl preserved.
outmdm:
IF inout AND NOT ncrdmv
in mnprts ;Get the output done flag.
ani output ;Is it set?
jz outmdm ;If not, loop until it is.
mov a,e
out mnport ;Output it.
ret
ENDIF;inout AND NOT ncrdmv
IF inout AND ncrdmv
in mnprts ;Get the output done flag
ani output ;Set ?
jz outmdm ;Loop until it is
mov a,e
out modtx ;output char
ret
ENDIF;inout AND ncrdmv
IF iobyt
;**** Note that we enter from outpkt with the I/O byte already set up for
; output to go to the comm port
push h
push b
lda prtfun ;Get the output function
mov c,a ;Into C
call bdos ;And output the character
pop b
pop h
ret
ENDIF;iobyt
IF torch ; [32] [13] Torch stuff. Requires some bit bashing
; via the BBC host computer (io computer)
; see also decription of osbyte later on
outdat:
lda prinuse ; get the printer in use flag
ana a ; if set, then must use traditional osbyte,
jnz outda2 ; else...
push b
push h ; Preserve registers [32]
call tx
db 1 ; MCP send to printer command
mov c,e ; Byte to send is in E [32]
call txbyte
pop h
pop b
ret
outda2: ; Preserve registers [32]
push h
mvi a,138 ; Osbyte insert byte into buffer
mvi l,2
mov h,e ; get the byte to be sent s-l-o-w-l-y
call osbyte
pop h ; Restore registers and exit
ret
ENDIF ;[13]
;
;
; get character from modem; return zero if none available.
; for IOBYT systems, the modem port has already been selected.
; destroys bc, de, hl.
inpmdm:
IF iobyt
call bconst ;Is Char at COMM-Port?
ora a ;something there?
rz ; return if nothing there
call bconin ; data present. read data.
ENDIF;iobyt
IF inout AND NOT ncrdmv
;Note: modem port should already be selected for mdI. [Toad Hall]
in mnprts ;Get the port status into A.
ani input ;See if the input ready bit is on.
rz ;If not then return.
in mnport ;If so, get the char.
ENDIF;inout AND NOT ncrdmv
IF inout AND ncrdmv
in mnprts ;Get input port status
ani input ;Mask input RDY bit
rz ;return if no char
in modrx ;get the char
ENDIF;inout AND ncrdmv
IF torch ; [32] [13] torch input
indat:
push h
mvi a,128
lxi h,0fffeh ; Read buffer status
call osbyte
mov a,h ; HL has number of characters
ora l ; in the buffer
jz indatq ; None, so skip fetch
mvi a,145 ; Get character from input buffer [32]
lxi h,1
call osbyte ; Result returned in 'Y', rather H
mov a,h
indatq:
pop h
ani 7fh
ret ; rx data in A
ENDIF ;torch [13] [32]
ret ; return with character in A
;
; flsmdm - flush comm line.
; Modem is selected.
; Currently, just gets characters until none are available.
flsmdm: call inpmdm ; Try to get a character
ora a ; Got one?
jnz flsmdm ; If so, try for another
ret ; Receiver is drained. Return.
;
;
; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
lptstat:
IF torch
mvi a,80h ; read chars remaining in printer buffer
mvi l,252 ; do osbyte 80H, X=252 (printer buffer)
mvi h,0ffh
call osbyte
mov a,h
cpi 10 ; 10 characters left?
mvi a,0 ; if pos, yes r better
rp
mvi a,0ffh
ret
ENDIF ;torch
IF torch
mvi a,5 ; got to select the real printer (par. port)
mvi l,1 ; ie FX 5,1
call osbyte
ENDIF ;torch
IF iobyte ;[33]
call bprtst ; get status
ENDIF ;iobyte[33]
IF torch
push psw
mvi a,5 ; restore serial line = printer
mvi l,2 ; ie FX 5,2
call osbyte
pop psw ; return with code in a
ENDIF ;torch
IF NOT iobyte ;[33]
xra a ; assume it is ok.. this may not be necessary
ENDIF ;iobyte [33]
ret
;
;
; outlpt - output character in E to printer
; console is selected.
; preserves de.
outlpt:
push d ; save DE in either case
call prtflt ; go through printer filter [30]
ana a ; if A = 0 do nothing,
jz outlp1 ; [30] if a=0 do nothing
IF torch ;[30] Must set printer routed to par port
mvi a,5 ; fx 5,1 (parallel port selected for printer)
mvi l,1 ; Modified for new osbyte form [32]
call osbyte
ENDIF ;torch [30]
IF NOT iobyt
mvi c,lstout
call bdos ;Char to printer
ENDIF;NOT iobyt
IF iobyt
mov c,e
call blsout
ENDIF;iobyt
IF torch ; re-route printer to serial port => faster tx bytes to line [30]
mvi a,5 ; Modified for new Osbyte form [32]
mvi l,2 ;fx 5,2
call osbyte
mvi a,6
mvi l,0 ;fx 6,0
call osbyte
ENDIF ;torch [30]
outlp1: pop d ; restore saved register pair
ret
;
;
; Screen manipulation routines
; csrpos - move to row B, column C
;
; csrpos for terminals that use a leadin sequence followed
; by (row + 31.) and (column + 31.)
;
IF brain
csrpos: push b ; save coordinates
lxi d,curldn ; get cursor leadin sequence
call prtstr ; print it
pop h ; restore coordinates
mov a,h ; get row
adi (' '-1) ; space is row one
mov e,a
push h
call outcon ; output row
pop h
mov a,l ; get column
adi (' '-1) ; space is column one
mov e,a
jmp outcon ; output it and return
ENDIF;brain
;
;
IF torch
csrpos: push b ; save coordinates
lxi d,curldn ; get cursor leadin sequence
call prtstr ; print it
pop h ; restore coordinates
mov a,l ; [obs] get column
adi 0ffh ; NULL is column one
mov e,a
push h
call outcon ; output row
pop h
mov a,h ; [obs] get row
adi 0ffh ; NULL (ie decrement) is row one
mov e,a
jmp outcon ; output it and return
ENDIF;torch
;
;
; delchr - make delete look like a backspace. Unless delete is a printing
; character, we just need to print a backspace. (we'll output clrspc
; afterwards)
; For Kaypro and Vector General, delete puts a blotch on the screen.
; For Apple and Osborne 1, delete moves but doesn't print.
delchr:
IF NOT torch ;[22]
mvi e,bs ;get a backspace
jmp outcon
ENDIF;NOT torch
; erase the character at the current cursor position
clrspc: mvi e,' '
call outcon
mvi e,bs ;get a backspace
jmp outcon
; erase the current line
clrlin: lxi d,eralin
jmp prtstr
; erase the whole screen, and go home. preserves b (but not c)
clrtop: lxi d,erascr
jmp prtstr
IF torch ;[13]
;
; OSBYTE call from Torch to BBC Base Processor.
;
; A register has osbyte type
; H register has equivalent Y register of 6502
; L register has equivalent X register of 6502
;
; Results (X and Y) are returned in HL respectively
;
;
usrimm equ 0ffc0h ; MCP user function [32]
tx equ 0ffc3h ; tx routine to talk to base board proc.
rx equ 0ffc6h ; rx ditto
txbyte equ 0ffc9h ; send C to base processor [32]
osbyte: ; Osbyte rewritten [32]
push b ; Keep these
mov b,a ; Local copy - use in a moment
call usrimm ; MCP osbyte function
db 15
mov c,b ; Osbyte function
call txbyte
mov c,l ; 6502 X register
call txbyte
mov c,h ; 6502 Y register
call txbyte
call rx ; fetch results
mov l,a ; X returned
sta xx ; save just in case...
call rx
mov h,a ; Y returned
sta yy
mov a,b ; return A as called
pop b
ret
xx: db 0
yy: db 0 ; temporary space
prinuse:db 0 ; 0=> fast tx, <>0 => slow tx to serial pt. [30]
ENDIF ;torch [13]
IF pci2651 ; whatever version
sysver: db 'Ithaca Intersystems S100$'
ENDIF ;pci2651
IF ncrdmv ; whatever version
sysver: db 'NCR DecisionMate V$'
ENDIF ;ncrdmv
IF torch ; whatever version
ttytyp:
sysver: db 'Torch Unicorn 5 '
db '$' ; stop here for now, otherwise say..
db ' MCP version '
db '1.00 $' ; or whatever...
ENDIF ;torch
; Assume MCP - CCCP ROMS greater than 1
;mcpver: db 'x.x $'
;outlin: db esc,'*',cr,lf,tab,'$'
;eralin: db cr,esc,'&$' ;Clear to end of line.
;erascr: db esc,'*$' ;Clear screen and go home.
;curldn: db esc,'=$' ;Cursor lead-in
;ttab: ;Table start location.
;ta:
db esc,'!$',0 ;Cursor up.
;tb: db 0ah,'$',0,0 ;Cursor down.
;tc: db esc,'+$',0 ;Cursor right.
;td: db 08h,'$',0,0 ;Cursor left.
;te: db esc,'*$',0 ;Clear screen and home cursor
;tf: db '$',0,0,0 ;(can't) Enter Graphics mode
;tg: db '$',0,0,0 ;(can't) Exit Graphics mode
;th: db esc,'>$',0 ;Cursor home.
;ti: db '$',0,0,0 ;(Can't) reverse linefeed
;tj: db esc,'%$',0 ; Clear to end of screen
;tk: db esc,'&$',0 ; Clear to end of line.
;Older message for MCP - CCCP verstion less than 1
;ooutli: db 0ch,cr,lf,tab,tab,'$';
;oerali: db '$',0,0,0 ;Clear to end of line.
;oerasc: db 0ch,'$',0 ;Clear screen and go home.
;ocurld: db 1fh,'$',0 ;Cursor lead-in
;ottab: ;Table start location.
; db 0bh,'$',0,0 ;Cursor up.
; db 0ah,'$',0,0 ;Cursor down.
; db 09h,'$',0,0 ;Cursor right.
; db 08h,'$',0,0 ;Cursor left.
; db 0ch,'$',0,0 ;Clear screen and home cursor
; db '$',0,0,0 ;(can't) Enter Graphics mode
; db '$',0,0,0 ;(can't) Exit Graphics mode
; db 1eh,'$',0,0 ;Cursor home.
; db 0bh,'$',0,0 ;reverse linfeed
; db '$',0,0,0 ;(Can't) Clear to end of screen
; db '$',0,0,0 ;(Can't) Clear to end of line.
;
;Specials
;spac15: db ' '
; db bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,'$';
;spac80: db cr
; db ' '
; db ' '
; db bs,cr,'$' ;80 spaces, bs and then back to line start
;
IF torch ; Should be IF ker08 AND torch...
db '$' ; to terminate the ID string
outlin: db 0ch,cr,lf,tab,tab,'$'
eralin: db '$',0,0,0 ;Clear to end of line.
erascr: db 0ch,'$',0 ;Clear screen and go home.
curldn: db 1fh,'$',0 ;Cursor lead-in
ttab: ;Table start location.
ta: db 0bh,'$',0,0 ;Cursor up.
tb: db 0ah,'$',0,0 ;Cursor down.
tc: db 09h,'$',0,0 ;Cursor right.
td: db 08h,'$',0,0 ;Cursor left.
te: db 0ch,'$',0,0 ;Clear screen and home cursor
tf: db '$',0,0,0 ;(can't) Enter Graphics mode
tg: db '$',0,0,0 ;(can't) Exit Graphics mode
th: db 1eh,'$',0,0 ;Cursor home.
ti: db 0bh,'$',0,0 ;reverse linfeed
tj: db '$',0,0,0 ;(Can't) Clear to end of screen
tk: db '$',0,0,0 ;(Can't) Clear to end of line.
;Specials
spac15: db ' '
db bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,'$';
spac80: db cr
db ' '
db ' '
db bs,cr,'$' ;80 spaces, bs and then back to line start
ENDIF;ker08 AND torch [13]
IF brain
sysver: db 'Intertec SuperBrain$'
outlin: db ('A'-100O),esc,'~k',cr,lf,tab,tab,'$'
erascr: db ('A'-100O),esc,'~k$' ;Clear screen and go home.
eralin: db cr,esc,'~K$' ;Clear line.
curldn: db esc,'Y$' ; leadin for cursor positioning
ttab: ;Table start location.
ta: db ('K'-100O),'$',0,0 ;Cursor up.
tb: db 12O,'$',0,0 ;Cursor down.
tc: db ('F'-100O),'$',0,0 ;Cursor right.
td: db '$',0,0,0 ;(can't) Cursor left
te: db '$',0,0,0 ;(can't) Clear display
tf: db '$',0,0,0 ;(can't) Enter graphics mode
tg: db '$',0,0,0 ;(can't) Exit graphics mode
th: db ('A'-100O),'$',0,0 ;Cursor home.
ti: db ('K'-100O),'$',0,0 ;Reverse linefeed.
tj: db esc,'~k$',0 ;Clear to end of screen.
tk: db esc,'~K$',0 ;Clear to end of line.
ENDIF;brain
IF lasm and not termin ; we dont want CPXVDU
ovlend equ $ ;Overlay end - start buffer
end
ENDIF ;lasm and not termin
IF lasm; we want a terminal
LINK CPXVDU.ASM
ENDIF ;lasm
|