-
Notifications
You must be signed in to change notification settings - Fork 0
/
DISC_MONITOR_V421.L99
1845 lines (1799 loc) · 89.6 KB
/
DISC_MONITOR_V421.L99
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
;
;-----------------------------------------------------------------------
; MONITOR AND FDC INTERFACE ROUTINES for the TI99000 SBC
;
; Written by Alex Cameron
;
; The monitor routines are called from a DOS or other
; programme to perform Console I/O and Disc I/O similar
; to a BIOS.
;
; Version 2.1 14th May 2020 - The year of the Corona Virus
; Version 2.2 3rd February, 2024 -
; Combined partial set of TIBUG commands into Monitor
; and targeted for the SBC ROM.
; RAM ADDRESS: EC00H-EFFFH;
; ROM ADDRESS: F000H-FFFFH
; VERSION 3.0 9th June, 2024
; Support added to allows for a IDE/SATA interface using LBA sectors.
; VERSION 4.1 29th July, 2024
; Support segmented memory model and removal of Floppy Disc Code
; VERSION 4.21 7th September, 2024
; Support segmented memory model extension of a PSEL SET AND CLEAR
;
;---------------------------------------------------------------------
;
0000 R0 EQU 0
0001 R1 EQU 1
0002 R2 EQU 2
0003 R3 EQU 3
0004 R4 EQU 4
0005 R5 EQU 5
0006 R6 EQU 6
0007 R7 EQU 7
0008 R8 EQU 8
0009 R9 EQU 9 ;Use to index workspace pointer not stack overflow
;SL EQU R9 ;STACK LIMIT
000A R10 EQU 10
000A SP EQU R10 ;STACK POINTER
000B R11 EQU 11
000C R12 EQU 12
000C PORT EQU R12 ;IO BASE
000D R13 EQU 13
000E R14 EQU 14
000F R15 EQU 15
000F ST EQU 15
;
;***************************************************
;
; DEFINE SOME XOP'S.
; ALL PROGRAMMES USE THESE XOPS
;
;****************************************************
;
DXOP PSEL,0
DXOP RETF,1
DXOP NEWPAGE,2
DXOP SWBANK,3
DXOP PUSHREG,4 ;PUSH RANGE OF REGISTERS TO STACH
DXOP POPREG,5
DXOP CALL,6
DXOP RET,7
DXOP PUSH,8 ;PUSH SINGLE REGISTER
DXOP POP,9
DXOP WHEX,10 ;WRITE OUT A 16 BIT HEX VALUE
DXOP RHEX,11 ;READ IN A 16 BIT HEX VALUE
DXOP WRITE,12 ;WRITE CHAR IN MSB
DXOP READ,13 ;READ CHAR IN MSB
DXOP MESG,14 ;OUTPUT NULL TERMINATED MESSAGE
DXOP DEBUG,15 ;DEBUG CURRENT LOCATION & STORE INTO DEBUG_BUFFER
;
; SOME EQUATES. NOTE WORKSP MUST BE IN COMMON MEMORY
;
F000 MONORG: EQU 0F000H ;ORIGIN FOR THIS MONITOR
0000 INTVEC: EQU 0000H ;START AT THE TOP
0040 XOPVEC: EQU 0040H
00B0 INTWP: EQU 00B0H ;;7 INT AND 16 XOPS WORKSPACES OF 16 BYTES EACH
0130 XOPWP: EQU 0130H ;XOP WORKSPACE ALLOCATION FOR ALL XOPS
0230 WORKSP: EQU 0230H ;USE AREA BELOW XOP WORKSPACES - 32 BYTES
0500 STACKP: EQU 0500H ;COMMON STACK USED BY ALL PROGRAMMES
0088 MON_PTR: EQU 0088H ;MONITOR VECTOR. PROGRAMMES CAN USE THIS
0500 TPA: EQU 0500H ;PROGRAME LOAD AREA
;
; THIS IS WHERE THE LBA (TWO WORDS) ARE STORED SO IT CAN BE LOADED
;
00A8 LBA: EQU 0A8H ;TWO WORDS (4 BYTES)
;
; DECLARE VARIABLES THAT NEED RAM
;
ED00 BUFFER: EQU MONORG-0300H ;THIS IS A TEMPORARY BUFFER USED BY BOOT
EF00 LOCAL_RAM: EQU MONORG-0100H
EF00 AORG LOCAL_RAM
EF00 BSS 32
;
; NOTE THIS IS USED BY DEBUG TO STORE MULTIPLE DEBUG POINTERS TO
; PROGRAMMES CALLING DEBUG
;
EF20 DEBUG_NAME: BSS 10 ;;NAME OF MODULE 8 CHARS LONG NULL TERMINATED
EF2A DEBUG_BUFFER: BSS 20 ;DEBUG TRACE LIST
;
;-- RAM BASED IO PARAMETER BLOCK - NOT USED WITH IDE
;
EF3E EVEN
EF3E DISC_PARAM: EQU $ + 0
EF3E 0000 FDCSTATUS: WORD 0 ;OPERATION STATUS
EF40 0001 TIMEOUT: WORD 1 ;N * 16MS DURATION
EF42 0000 DISC_INUSE: WORD 0
0006 RAM_SIZE: EQU $ - DISC_PARAM
; AORG 0400H
; SETO R9 ;CLEAR SEGEMENT AND SELECT PAGE 0
; LI PORT,MEMBASE
; LDCR R9,BYTEWIDE ;GET PAGE VALUE FROM STEP ABOVE
; BLWP @INIT_MONITOR
;
;;-----TESTING CODE
; AORG 0500H
; BLWP @TEMP
;TEMP: WORD WORKSP
; WORD INITIAL
;----- END TESTING CODE
;
; LOCATE THE MONITOR IN MEMORY
;
F000 AORG MONORG
;
; INITIALISATION
;
;
;************************************************************************************
;
; USE BLWP @MONITOR TO INITIALISE MONITOR VECTORS AND INTERRUPTS
;
; NOTE ALL PROGRAMMES OR MODULES MUST SET THEIR WORSPACE
; POINTERS AND STACKS BEFORE CALLING, e.g.
;
; AORG 0100H
; LWPI WORKSP
; BLWP @INIT_MONITOR
; <INITIALISED MONITOR WILL RETURN HERE>
;
;
;*************************************************************************************
;
INIT_MONITOR:
F000 0230 WORD WORKSP ;THIS IS MONITOR WORKSAPCE
F002 F81A WORD INITIAL ;INITIALISE ALL XOP, INTERRUPT AND ENTRY VECTORS
F004 0460 F204 BOOT_ADDR: B @BOOT ;PERFORM A COLD BOOT - POS IN TABLE HELPS DEBUGGING
F008 0460 F26C B @CIN ;CHAR IN
F00C 0460 F270 B @COUT ;CHAR OUT
F010 0460 F278 B @SELDSK ;SELECT A DISK DRIVE
F014 0460 F27C B @RECAL ;RECALIBRATE DRIVES
F018 0460 F3F2 B @SEEK ;SEEK THE TRACK IN R3
F01C 0460 F280 B @RDREC ;READ SELECTED SECTOR
F020 0460 F288 B @WRREC ;WRITE SELECTED SECTOR
F024 0460 F27E B @RDID ;READ TRACK ID ADDRESS
F028 0460 F202 B @WBOOT ;PERFORM A WARM BOOT
F02C 0460 F284 B @RDTRK ;READ A TRACK OF DATA
F030 0460 F286 B @WRTRK ;WRITE A TRACK OF DATA
;
;**********************************************************
;
; DMA PARAMETER BLOCK DEFINITIONS
; INDEXED DEPENDING ON READ(0), OR WRITE(1) COMMAND
;
;************************************************************
;
F034 34B8 CMDTBL: STCR *R8+,BYTEWIDE ;BYTE WIDE FDC DATA READ
F036 30B8 LDCR *R8+,BYTEWIDE ;BYTE WIDE FDC DATA WRITE
;
;--REGISTERS IN INTERRUPT 3 WORKSPACE
;
00E2 DMACMD SET 2*R9+INTWP2 ;CURRENT COMMAND
00E0 DMAADDR SET 2*R8+INTWP2 ;REGISTER HOLDING SOURCE ADDRESS
00E8 DMAPORT SET 2*R12+INTWP2 ;IO BASE REG I.E. DATAREG
F038 0D0A 00 CRLF BYTE 0DH,0AH,0
F03B 00 EVEN
;
;FDC 1797 COMMANDS
;
;RDCMD: EQU 10001000B ;READ CMD
;RIDCMD: EQU 11000000B ;READ ID
;WRCMD: EQU 10101000B ;WRITE CMD
;WTCMD: EQU 11110000B ;WRITE TRACK
;RTCMD: EQU 11100000B ;READ TRACK
;SEKCMD: EQU 00011100B ;SEEK CMD
;RSTCMD: EQU 00001100B ;RESTORE COMMAND
;FINTCMD: EQU 11010000B ;FORCE INTERRUPT COMMAND
;SICMD: EQU 01011100B ;STEP IN COMMAND
;SOCMD: EQU 01111100B ;STEP OUT COMMAND
;
;--FDC 1797 IO REG LOCATIONS. SET BY ADDRESS BITS A13,A14 HENCE 2, 4 6
;
8000 FDC1797: EQU 8000H ;IO BASE REGISTER- BYTE TRANSFER WITH MSB SET
8000 STSREG: EQU FDC1797+0 ;MAIN STATUS REG
;CMDREG: EQU FDC1797+0 ;COMMAND REGISTER
;TRKREG: EQU FDC1797+2 ;TRACK REGISTER
;SECREG: EQU FDC1797+4 ;SECTOR REGISTER
;DATREG: EQU FDC1797+6 ;DATA REGISTER
;
; BANK SWITCHING PORT
;
80C0 MEMBASE: EQU 80C0H ;BASE MEMORY BANK SWITCH PORT
;
;
;--PORTS ETC.
;
0000 SELMUX: EQU 0 ;SELECT CONTROL PORT (R12 CRU PORT)
;TYPMUX: EQU SELMUX + 2*5 ;START AT BIT 5
0002 BYTEWIDE: EQU 2 ;PARALLEL I/O DONE IN BYTES (UNIQUE TO 99105)
;
;
; THESE ARE THE TIBUG BASIC COMMANDS, SUCH AS:
; QBOOT, ADDR G(O), ADDR O(UTPUT), W(ORKSPACE), R(EGISTERS), ADDRESS O(PEN).
;
; TIBUG WILL BE THE DEFAULT ENTRY POINT.
; BOOTING IS EFFECTED BY ISSUING THE Q(QBOOT) COMMAND
;
;TIBUG_ENTRY: AND WE CAN NOW ENABLE INTERRUPTS
;
F03C 0300 0007 BANNER LIMI 7 ;ENABLE INTERRUPTS
F040 2FA0 F0F2 MESG @MESS00 ;_PRINT ">> TMS9900 TIBUG <<"
F044 2FA0 F110 PROMPT MESG @MESS01 ;PRINT PROMPTER
F048 06A0 F124 BL @HEXIN ;OBTAIN ADDRESS IN R2 AND INSTRUCTION IN R1
F04C 0204 0014 LI R4,20 ;20 POSSIBLE INSTRUCTIONS
F050 9064 F09A MON01 CB @INTAB(R4),R1 ;SEARCH INTAB
F054 1305 JEQ MON03
F056 0604 DEC R4
F058 18FB JOC MON01
F05A 2FA0 F114 MON02 MESG @MESS02 ;PRINT " ??"
F05E 10F2 JMP PROMPT
F060 0A14 MON03 SLA R4,1 ;BRANCH TO APPROPRIATEE ROUTINE
F062 C124 F0B0 MOV @SUBTAB(R4),R4 ;
F066 C0C3 MOV R3,R3 ;TEST HEXIN FLAG
F068 0454 B *R4
;
; TIBUG INSTRUCTION TABLE
;
F06A 3031 3233 HEXTAB TEXT '0123456789ABCDEF'
F06E 3435 3637
F072 3839 4142
F076 4344 4546
F07A 3020 3120 NUMTAB TEXT '0 1 2 3 4 5 6 7 8 9 101112131415'
F07E 3220 3320
F082 3420 3520
F086 3620 3720
F08A 3820 3920
F08E 3130 3131
F092 3132 3133
F096 3134 3135
F09A 1A INTAB BYTE 1AH ;CONTROL Z(CLEARS SCREEN) AND VERSION
F09B 2F2F 5155 TEXT '//QUVGMZOWRPXLHST/. '
F09F 5647 4D5A
F0A3 4F57 5250
F0A7 584C 4853
F0AB 542F 2E20
F0AF 00 EVEN
F0B0 F03C 0000 SUBTAB WORD BANNER,0,0,QBOOT,HEXLOAD,HEXLOAD2,GO,MOVE,FIND,OUTPUT,WP,PRINT_REGS,PRINT
F0B4 0000 F670
F0B8 F758 F79C
F0BC F674 F0E6
F0C0 F0E8 F700
F0C4 F740 F678
F0C8 F0F0
F0CA F0EA F0EC WORD XCUTE,LOWW,SETBP,SSTEP,TRACE,CHAR,INSTANT,OPEN
F0CE F0E0 F0DE
F0D2 F0E2 F0E4
F0D6 F0EE F6C2
;
; COMMANDS IMPLEMENTED IN DISC_MONITOR
; REGIST, OPEN, GO AND QBOOT.
;
;MASK32 WORD 001FH
F0DA 000F MASK15 WORD 000FH
;MASK8 WORD 0007H
F0DC 0003 MASK3 WORD 0003H
;
; DUMMY LIST
;
F0DE 10B2 SSTEP: JMP PROMPT; NULL COMMAND
F0E0 10B1 SETBP: JMP PROMPT; NULL COMMAND
F0E2 10B0 TRACE: JMP PROMPT; NULL COMMAND
F0E4 10AF CHAR: JMP PROMPT; NULL COMMAND
F0E6 10AE MOVE: JMP PROMPT; NULL COMMAND
F0E8 10AD FIND: JMP PROMPT; NULL COMMAND
F0EA 10AC XCUTE: JMP PROMPT; NULL COMMAND
F0EC 10AB LOWW: JMP PROMPT; NULL COMMAND
F0EE 10AA INSTANT: JMP PROMPT; NULL COMMAND
F0F0 10A9 PRINT: JMP PROMPT; NULL COMMAND
;
;ONLY THESE ONES HAVE BEEN IMPLEMENT WITHIN THE DISC_MONITOR ROM. AS
;THE ADDRESS SPACE HAS BEEN TAKEN UP WITH THE DISC-IO AND THE OTHER FUNCTIONS
;CAN BE EASILY IMPLEMENTED WITH DISC BASED PROGRAMMES.
;
;QBOOT: JMP PROMPT; NULL COMMAND
;GO: JMP PROMPT; NULL COMMAND
;OUTPUT: JMP PROMPT; NULL COMMAND
;WP: JMP PROMPT; NULL COMMAND
;PRINT_REGS: JMP PROMPT; NULL COMMAND
;OPEN: JMP PROMPT; NULL COMMAND
;
; MESSGES AND OTHER EQUATES
;
F0F2 0D0A MESS00 BYTE CR,LF
F0F4 3C54 4D53 TEXT '<TMS9900 DISC MONITOR V4.21>'
F0F8 3939 3030
F0FC 2044 4953
F100 4320 4D4F
F104 4E49 544F
F108 5220 5634
F10C 2E32 313E
; BYTE 0
F110 0D0A MESS01 BYTE CR,LF
F112 3E TEXT '>'
F113 00 BYTE 0
F114 3F3F MESS02 TEXT '??'
F116 00 BYTE 0
F117 0A0D 0A MESS03 BYTE LF,CR,LF
F11A 2020 2020 TEXT ' '
F11E 00 BYTE 0
F11F 203D 20 MESS04 TEXT ' = '
F122 00 BYTE 0
;
000D CR: EQU 0DH ;CARRIAGE RETURN
000A LF: EQU 0AH ;LINE FEED
F123 00 EVEN
;
;*********************************
; SUPPORT ROUTINES FOR INPUT AND OUTPUT
;**********************************
;
;
; SUBROUTINE HEXIN
; INPUTS A HEX NO. INTO R2
; AND INSTRUCTION INTO R1
; (INSTRUCTION ' ' INSERT AND MOVE TO NEXT ADDRESS
; (INSTRUCTION '-' INSERT AND MOVE TO PREVIOUS ADDRESS
; THE HEX INDEX USES THE TRANSLATE TABLE HEXTAB TO IDENTIFY THE HEX DIGIT.
; THE LAST CHARACTER, EITHER SPACE OR - BREAKS THE CYCLE AS THEY ARE NOT IN THE HEXTABLE
;
; USES R1,R2,R3,R4
;
F124 04C1 HEXIN: CLR R1
F126 04C2 CLR R2
F128 0703 SETO R3 ;SET FLAG
F12A 2F41 HEXIN0 READ R1 ;GET CHARACTER
F12C 2F01 WRITE R1 ;PRINT CHARACTER
F12E 0204 000F LI R4,15
F132 9064 F06A HEXIN1 CB @HEXTAB(R4),R1
F136 1604 JNE HEXIN2
F138 04C3 CLR R3 ;CLEARS FLAG
F13A 0A42 SLA R2,4 ;SHIFTS HEX DIGIT INTO R2
F13C E084 SOC R4,R2
F13E 10F5 JMP HEXIN0
F140 0604 HEXIN2 DEC R4
F142 18F7 JOC HEXIN1 ;SUBTRACTING 1 FROM 0 DOES NOT RESULT IN CARRY
F144 C0C3 MOV R3,R3 ;TEST HEXIN FLAG
F146 045B RT ;RETURN FROM BL
;
; SUBROUTINE HEXOUT ;OUTPUT CONTENTS OF R2
; USES R0,R1,R2,R3
;
;HEXOUT WRITE @MESS03+7 ;PRINTS " "
;HEXOUT0 PUSHREG R3 ;SAVE R0-R3
;HEXOUTX CLR R0
; LI R3,4
;HEXOUT1 SRC R2,12
; MOV R2,R1
; ANDI R1,000FH
; MOVB @HEXTAB(R1),R0
; WRITE R0
; DEC R3
; JNE HEXOUT1
; POPREG R3 ;RESTORE R3-R0
; RT
;
F148 2E00 DOT: BYTE '.',0
F14A 2B00 PLUS BYTE '+',0
F14C 4C4F 4144 LOADERR: TEXT 'LOAD ERROR'
F150 2045 5252
F154 4F52
F156 00 BYTE 0
F157 00 EVEN
;
;**********************************************
; XOP WP ENTRY POINTS
;**********************************************
;
F158 0130 F452 XOPTAB: WORD XOPWP0,XOP0,XOPWP1,XOP1,XOPWP2,XOP2,XOPWP3,XOP3
F15C 0140 F454
F160 0150 F480
F164 0160 F48E
F168 0170 F4C0 WORD XOPWP4,XOP4,XOPWP5,XOP5,XOPWP6,XOP6,XOPWP7,XOP7,XOPWP8,XOP8
F16C 0180 F4D4
F170 0190 F4E6
F174 01A0 F4F6
F178 01B0 F502
F17C 01C0 F510 WORD XOPWP9,XOP9,XOPWP10,XOP10,XOPWP11,XOP11
F180 01D0 F51C
F184 01E0 F540
F188 01F0 F570 WORD XOPWP12,XOP12,XOPWP13,XOP13,XOPWP14,XOP14,XOPWP15,XOP15
F18C 0200 F580
F190 0210 F590
F194 0220 F59A
;
F198 0230 F81A INTTAB: WORD WORKSP,INITIAL,INTWP1,INT1,INTWP2,FDC_RWINT, INTWP3,FDC_DRQ ;FDC1797 INTERUPT VECTORS
F19C 00C0 F1B8
F1A0 00D0 F400
F1A4 00E0 F3F8
F1A8 00F0 F402 WORD INTWP4,INTTIMER,INTWP5,IDE_IRQ, INTWP6, IDE_DMARQ, INTWP7,INT7 ;TIMER INTERRUPT
F1AC 0100 F2B0
F1B0 0110 F2B8
F1B4 0120 F1BA
;
INT1: ;LI R0,1
;WHEX R0
F1B8 0380 RTWP
INT7: ;LI R0,7
;WHEX R0
F1BA 0380 RTWP
;
; NOTE. APPLICATIONS MUST CALL WITH THEIR WP POINTERS SET
; THIS CALL IS USED TO SET UP MONITOR AND IS CALLED USING BL
; CALLED USING BLWP @MONITOR
;
F1BC 0360 INIT_VECTORS: RSET ;CLEAR INTERRUPT MASK
; LWPI WORKSP ;USE MONITOR LOCAL WORKSPACE
; LI SP,STACKP ;STACK FOR LOCAL MONITOR USE
;
; LI R0,MON_PTR ;SET UP THE MONITOR POINTER
; LI R1,MONORG
; MOV *R1+,*R0+ ;MOVE WORKSPACE POINTER
; MOV *R1+,*R0+ ;MOVE MONITOR INITIALISATION ADDRESS
;
;************************************************************
;
; SWTICH TO MONITOR XOP VECTORS RATHER THAN TIMON ROM
; THIS MEANS THAT ALL PROGRAMMES THAT USE XOP WILL USE THE
; THE XOP IMPLEMENTATIONS DEFINED IN MONITOR THAT IS HERE!
;
;************************************************************
F1BE 0200 0000 LI R0,INTVEC ;SET UP INTERRUPT VECTORS
F1C2 0201 F198 LI R1,INTTAB ;ONLY INT 0 TO 7
F1C6 CC31 INIT1: MOV *R1+,*R0+
F1C8 CC31 MOV *R1+,*R0+
F1CA 0280 0020 CI R0,INTVEC+8*4 ;8 INTERRUPT VECTORS
F1CE 16FB JNE INIT1
;
;ZERO UNUSED INTERRUPT WORDS AND OTHER INITIALISATION AREAS UP TO TPA
;
F1D0 0200 00B0 LI R0,INTWP0
F1D4 0201 0500 LI R1,TPA
INIT2: ;CLR *R0+
;C R0,R1
;JNE INIT2
;
;INITIALISE XOP-START AT XOP0, INTO MEMORY LOCATION AT 40H
;
F1D8 0200 0040 LI R0,XOPVEC
F1DC 0201 F158 LI R1,XOPTAB
F1E0 CC31 INIT3: MOV *R1+,*R0+
F1E2 CC31 MOV *R1+,*R0+
F1E4 0280 0080 CI R0,80H ;FINISHED?
F1E8 16FB JNE INIT3 ;NO
;
;Now initialise DISC and OTHER RAM. FIRST ZERO THEN COMPY PRESETS
;
F1EA 0200 0006 LI R0,RAM_SIZE
F1EE 0201 EF3E LI R1,DISC_PARAM
F1F2 04C2 CLR R2
F1F4 DC42 INIT_RAM MOVB R2,*R1+
F1F6 0600 DEC R0
F1F8 16FD JNE INIT_RAM
;
; NOW MOVE PRESETS
;
F1FA 0700 SETO R0
F1FC 05A0 EF40 INC @TIMEOUT ;THIS JUST SETS TIMEOUT TO 1 AS IT IS ALREAY 0
F200 045B RT
;
;************************************************************
;
; WARM BOOT ASSUMES A COLD BOOT HAS ALREADY OCCURED
; AND DISC IS JUST BEING CALIBRATED TO A KNOWN STATE
;
;************************************************************
;
F202 1000 WBOOT: JMP BOOT
;
;*********************************************************
;
; BOOT ASSUMES MONITOR HAS BEEN INITIALISED AND SO
; THE FDC AND INTERRUPT VECTORS ARE IN VALID
;
;***********************************************************
;
F204 2FA0 F254 BOOT: MESG @BMSG2
F208 04C2 CLR R2
F20A 2DA0 F28C CALL @IDE_READY
;
;BOOT SECTOR IS LBA = 0
;
F20E 04C3 CLR R3 ;BOOT LBA SECTOR
F210 0204 ED00 LI R4,BUFFER ;USE THIS AREA TO BOOT
F214 2DA0 F300 CALL @READ_SECTOR
F218 160F JNE BOOT2
;
; GET THE LOAD ADDRESS WHICH IS LOCATED AT THE LAST 2 BYTES OF THE LOADER BUFFER
;
F21A C120 EEFE MOV @BUFFER+510,R4
F21E C004 MOV R4,R0
F220 0201 ED00 LI R1,BUFFER
F224 0202 0200 LI R2,512
F228 CD31 BOOT1 MOV *R1+,*R4+
F22A 0642 DECT R2
F22C 16FD JNE BOOT1
F22E 02E0 0230 LWPI WORKSP ;RESET USE MONITOR LOCAL WORKSPACE
F232 020A 0500 LI SP,STACKP
F236 0450 B *R0 ;LET THERE BE LIFE - LOAD THE SYSTEM
;
; --BOOT ERROR
;
F238 C801 EF3E BOOT2 MOV R1,@FDCSTATUS
F23C 2FA0 F244 MESG @BMSG1
F240 0460 F044 B @PROMPT
;
F244 2D2D 426F BMSG1 TEXT '--Boot error'
F248 6F74 2065
F24C 7272 6F72
F250 0D0A 00 BYTE 0DH,0AH,0
F253 00 EVEN
F254 2D2D 426F BMSG2 TEXT '--Booting....'
F258 6F74 696E
F25C 672E 2E2E
F260 2E
F261 0D0A 00 BYTE 0DH,0AH,0
F264 5041 4745 PAGE TEXT "PAGE: "
F268 3A20
F26A 00 BYTE 0
F26B 00 EVEN
;
;****************************
;
; CHAR IN (MSB OF R1)
;
;*****************************
F26C 2F41 CIN READ R1 ;GET CHAR
F26E 2DC0 RET
;*******************************
;
; CHAR OUT (MSB OF R2)
;
;********************************
;
F270 04C1 COUT CLR R1
F272 D042 MOVB R2,R1 ;COPY CHAR TO R1
F274 2F01 WRITE R1 ;OUTPUT IT
F276 2DC0 RET
;
;************************************************
;
; SELECT THE DRIVE IN R2
;
;************************************************
;
F278 0460 F28C SELDSK: B @IDE_READY
;
;*****************************
;
;--RECAL IS JUST SEEK TO TRK ZERO (RECAL IS HANDLED THERE)
;
;*****************************
;
F27C 2DC0 RECAL: RET
;*******************************
;
;READ ID FIELDS
;
;******************************
;
F27E 2DC0 RDID RET
;****************************
;
;READ A RECORD
; R3 HOLDS SECTOR
; R4 HOLDS BUFFER POINTER
;
;*****************************
;
F280 0460 F300 RDREC: B @READ_SECTOR
;****************************
;
;READ A TRACK
; R3 NOT REQUIRED
; R4 HOLDS BUFFER POINTER
;
;*****************************
;
F284 2DC0 RDTRK RET
;
;
;****************************
;
;WRITE A TRACK
; R3 NOT REQUIRED
; R4 HOLDS BUFFER POINTER
;
;*****************************
;
F286 2DC0 WRTRK RET
;******************************
;
;WRITE A RECORD
; R3 HOLDS SECTOR/LBA
; R4 HOLDS BUFFER POINTER
;
;*****************************
;
F288 0460 F320 WRREC B @WRITE_SECTOR
;
;=========START OF IDE INTERFACE ROUTINES====================
;
;
; IDE REGISTERS - REFERENCE SEE THE SEAGATE REFERENCE MANUAL
;
; IDE I/O ports
8040 IDE_BASE_PORT: EQU 8040H ;PARALLEL OUTPUT ADDRESS WITH MSB SET THIS IS CS0
804E IDE_COMMAND: EQU IDE_BASE_PORT+7*2
804E IDE_STATUS: EQU IDE_BASE_PORT+7*2
804C IDE_CONTROL: EQU IDE_BASE_PORT+6*2
8040 IDE_DATA: EQU IDE_BASE_PORT
804C IDE_HEAD: EQU IDE_BASE_PORT + 6*2
8048 IDE_CYL_LSB: EQU IDE_BASE_PORT + 4*2
804A IDE_CYL_MSB: EQU IDE_BASE_PORT + 5*2
8046 IDE_SECTOR: EQU IDE_BASE_PORT + 3*2
8044 IDE_SEC_CNT: EQU IDE_BASE_PORT + 2*2
8042 IDE_ERROR: EQU IDE_BASE_PORT + 1*2
;
; IDE STATUS REGISTER AND BIT DEFINTIONS
;
0080 IDE_BSY: EQU 10000000B ;80H
0040 IDE_DRDY: EQU 01000000B ;40H
0001 IDE_ERR: EQU 00000001B ;01H
0020 IDE_DWF: EQU 00100000B ;20H DRIVE WRITE FAULT
0010 IDE_DSC: EQU 00010000B ;01H DRIVE SEEK COMPLETE
0010 IDE_DRQ: EQU 000010000B ;01H DATA REQUEST BIT
;
; IDE COMMANDS - NOTE COMMAND IS IN THE MOST SIGNIFICANT BYTE
;
2000 IDE_CMD_READ: EQU 02000H
3000 IDE_CMD_WRITE: EQU 03000H ;R = 0 FOR NO RETRY
1000 IDE_CMD_RECAL: EQU 01000H ;R = 0 FOR NO RETRY
9100 IDE_CMD_INIT: EQU 09100H
EC00 IDE_CMD_ID: EQU 0EC00H ;GET THE DRIVE PROPERTIES
E000 IDE_CMD_SDOWN: EQU 0E000H ;R = 0 FOR NO RETRY
E100 IDE_CMD_SUP: EQU 0E100H ;R = 0 FOR NO RETRY
0200 BYTSEC: EQU 512
;
; CHECK THE IDE READY BIT.
;
F28C 020C 804C IDE_READY: LI PORT, IDE_HEAD ;DEVICE HEAD REGISTER
F290 0201 A000 LI R1, 10100000B*256 ;SPECIFY LBA MODE
F294 3081 LDCR R1,BYTEWIDE ;WRITE THE COMMAND
F296 020C 804E LI PORT,IDE_STATUS ;STATUS
F29A 3481 BSY1: STCR R1,BYTEWIDE ;GET STATUS REGISTER
F29C 0241 8000 ANDI R1,10000000B * 256 ;IF BUSY, THEN WAIT
F2A0 16FC JNE BSY1
F2A2 020C 804E LI PORT,IDE_STATUS ;STATUS
F2A6 3481 RDY1: STCR R1,BYTEWIDE ;GET STATUS REGISTER
F2A8 0241 4000 ANDI R1,01000000B * 256 ;WAIT FOR RDY TO BE SET
F2AC 13FC JEQ RDY1
F2AE 2DC0 RET
;
; TEMPORARY INTERRUPT HANDLERS
;
IDE_IRQ: ;LI R0,5
;WHEX R0
F2B0 020C 804E LI PORT,IDE_STATUS ;STATUS
F2B4 3480 STCR R0,BYTEWIDE
F2B6 0380 RTWP
;
; TEMPORARY INTERRUPT HANDLERS
;
IDE_DMARQ: ;LI R0,6
;WHEX R0
F2B8 020C 804E LI PORT,IDE_STATUS ;STATUS
F2BC 3480 STCR R0,BYTEWIDE
F2BE 0380 RTWP
;
; CALL THE DRIVE ID. THIS IS NOT OF MUCH PRACTICAL USE, BUT A GOOD TEST.
;
F2C0 2DA0 F28C DRIVE_ID: CALL @IDE_READY
F2C4 020C 804E LI PORT, IDE_COMMAND ;COMMAND REGISTER6
F2C8 0201 EC00 LI R1, IDE_CMD_ID ; READ BUFFER
F2CC 3081 LDCR R1,BYTEWIDE
F2CE 2DA0 F34C CALL @IDE_WAIT_DRQ
F2D2 1303 JEQ IDE_GET_ERROR
F2D4 2DA0 F362 CALL @IDE_READ_DATA
F2D8 2DC0 RET
;
;when an error occurs, we get acc.0 set from a call to ide_drq
;or ide_wait_not_busy (which read the drive's status register). If
;that error bit is set, we should jump here to read the drive's
;explaination of the error, to be returned to the user. If for
;some reason the error code is zero (shouldn't happen), we'll
;return 255, so that the main program can always depend on a
;return of zero to indicate success.
;
F2DA 020C 8042 IDE_GET_ERROR: LI PORT, IDE_ERROR
F2DE 04C1 CLR R1
F2E0 3481 STCR R1,BYTEWIDE
F2E2 D041 MOVB R1,R1
F2E4 1303 JEQ IGE_X ;RETURN ERROR IN MSB OF R1
F2E6 2FA0 F2EE MESG @IDE_MSG1
F2EA 2E81 WHEX R1
F2EC 2DC0 IGE_X RET
F2EE 4944 4520 IDE_MSG1: TEXT "IDE ERROR: "
F2F2 4552 524F
F2F6 523A 20
F2F9 000D 000A WORD 0DH,0AH,0
F2FD 0000
F2FF 00 EVEN
;
; READ_SECTOR
; R3 HOLDS THE LSB OF THE LBA VALUE FOR THE SECTOR WE WANT TO READ
; R4 HOLDS THE BUFFER ADDRESS
;
F300 C143 READ_SECTOR: MOV R3,R5 ;SAVE THE LBA
F302 2DA0 F33E CALL @IDE_NOT_BUSY
F306 2DA0 F38A CALL @IDE_WR_LBA
F30A 020C 804E LI PORT, IDE_COMMAND ;COMMAND REGISTER6
F30E 0201 2000 LI R1, IDE_CMD_READ ; READ BUFFER
F312 3081 LDCR R1,BYTEWIDE
;
F314 2DA0 F34C CALL @IDE_WAIT_DRQ
F318 13E0 JEQ IDE_GET_ERROR
F31A 2DA0 F362 CALL @IDE_READ_DATA
F31E 2DC0 RET
;
; WRITE SECTOR
; R3 HOLDS THE LSB OF THE LBA VALUE FOR THE SECTOR WE WANT TO READ
; R4 HOLDS THE BUFFER ADDRESS
;
;
F320 C143 WRITE_SECTOR: MOV R3,R5
F322 2DA0 F33E CALL @IDE_NOT_BUSY
F326 2DA0 F38A CALL @IDE_WR_LBA
F32A 020C 804E LI PORT, IDE_COMMAND ;COMMAND REGISTER6
F32E 0201 3000 LI R1, IDE_CMD_WRITE ; WRITE BUFFER
F332 3081 LDCR R1,BYTEWIDE
;
F334 2DA0 F34C CALL @IDE_WAIT_DRQ
F338 2DA0 F376 CALL @IDE_WRITE_DATA
F33C 2DC0 RET
;
; WAIT FOR THE IDE DRIVE TO NOT BE BUSY
;
F33E 020C 804E IDE_NOT_BUSY: LI PORT,IDE_COMMAND ;STATUS
F342 3481 BSY2 STCR R1,BYTEWIDE ;GET STATUS REGISTER
F344 0241 8000 ANDI R1,10000000B * 256 ;IF BUSY, THEN WAIT
F348 16FC JNE BSY2
F34A 2DC0 RET
;
; WAIT FOR DRQ BEFORE READ DATA. 0 STATUS, ERROR
;
F34C 0700 IDE_WAIT_DRQ: SETO R0 ;VERY CRUDE TIMEOUT
F34E 020C 804E LI PORT,IDE_COMMAND
F352 04C1 CLR R1
F354 0600 DRQ1 DEC R0
F356 1304 JEQ DRQ_X
F358 3481 STCR R1,BYTEWIDE
F35A 0241 0800 ANDI R1,00001000B * 256 ;WAUT FOR DRQ READT, THEN WAIT
F35E 13FA JEQ DRQ1
F360 2DC0 DRQ_X RET
;
; IDE Status Register:
; bit 7: Busy 1=busy, 0=not busy
; bit 6: Ready 1=ready for command, 0=not ready yet
; bit 5: DF 1=fault occured inside drive
; bit 4: DSC 1=seek complete
; bit 3: DRQ 1=data request ready, 0=not ready to xfer yet
; bit 2: CORR 1=correctable error occured
; bit 1: IDX vendor specific
; bit 0: ERR 1=error occured
;;------------------------------------------------------------------
;
; BECAUSE IDE TRANSFERS ARE IN 16 BIT WORDS AND WE ONLY HAVE ACCESS TO 8 BIT
; TRANSFERS, 256 BYTES REPRESENTS AN LBA AND TWO LBA A SECTOR. SO TWO LBAS ARE READ
;
; WE ENTER WITH R4 -> BUFFER
;
F362 0200 0200 IDE_READ_DATA: LI R0,BYTSEC
F366 020C 8040 LI PORT,IDE_DATA ;DATA REG
F36A 3481 RL11: STCR R1,BYTEWIDE ;
F36C DD01 MOVB R1,*R4+
F36E 0600 DEC R0
F370 16FC JNE RL11
F372 C040 MOV R0,R1
F374 2DC0 RET
;
; BECAUSE IDE TRANSFERS ARE IN 16 BIT WORDS AND WE ONLY HAVE ACCESS TO 8 BIT
; TRANSFERS, 256 BYTES REPRESENTS AN LBA AND TWO LBA A SECTOR.
;
; WE ENTER WITH R4 -> BUFFER
F376 0200 0200 IDE_WRITE_DATA: LI R0,BYTSEC
F37A 020C 8040 LI PORT,IDE_DATA ;DATA REG
F37E D074 WL11: MOVB *R4+,R1
F380 3081 LDCR R1,BYTEWIDE ;
F382 0600 DEC R0
F384 16FC JNE WL11
F386 C040 MOV R0,R1
F388 2DC0 RET
;
; WRITE THE LOGICAL BLOCK ADDRESS TO THE DRIVE'S REGISTERS
; ORGANISED AS:
; LBA WORD 0,0
;
; LBA + 3 = HEAD (MSB)
; LBA + 2 = CYL MSB
; LBA + 1 = CYL LSB
; LBA + 0 = SECTOR (LSB )
;
; R5 HOLDS THE LSB OF THE LBA, MSB WILL BE ZEROED FOR TIME BEING
;
F38A 04E0 00A8 IDE_WR_LBA: CLR @LBA
F38E C805 00AA MOV R5,@LBA + 2
F392 D060 00A8 MOVB @LBA+0,R1 ;GET THE FIRST MSB BYTE
F396 0241 0F00 ANDI R1,0FH*256
F39A 0261 E000 ORI R1,0E0H*256 ; 0EH IS JUST THE 1110 CODE FOR HEAD REGISTER
F39E 020C 804C LI PORT,IDE_HEAD ; IDE HEAD
F3A2 3081 LDCR R1,BYTEWIDE
;
F3A4 D060 00A9 MOVB @LBA+1,R1
F3A8 020C 804A LI PORT,IDE_CYL_MSB ;CYLINDER MSB
F3AC 3081 LDCR R1,BYTEWIDE
F3AE D060 00AA MOVB @LBA+2,R1
F3B2 020C 8048 LI PORT,IDE_CYL_LSB ;CYLINDER LSB
F3B6 3081 LDCR R1,BYTEWIDE
F3B8 D060 00AB MOVB @LBA+3,R1
F3BC 020C 8046 LI PORT,IDE_SECTOR ;CYLINDER LSB
F3C0 3081 LDCR R1,BYTEWIDE
;
; WE NEED TO READ TWO SECTORS TO GET 512 BYTES DUE TO THE FACT THAT WE CAN'T DO 16 BIT READS/WRITES
; SO TWO LBAS REPRESENT A VIRTUAL SECTOR OF 512
;
F3C2 0201 0200 LI R1,2*256 ;
F3C6 020C 8044 LI PORT,IDE_SEC_CNT ;CYLINDER LSB
F3CA 3081 LDCR R1,BYTEWIDE
F3CC 2DC0 RET
;======================= END IDE INTERFACE ROUTINES ==============
;
;
;********************************
;
;INTIALISE INT.VECTORS ETC
;
;*******************************
;
F3CE 2DC0 INTSYS RET
;
;********************************
;
;RESET FDC
;
;********************************
;
F3D0 2DC0 RSET RET
;
;
;*******************************************
;
; SET THE TIME OUT TIMER
;
F3D2 00F0 F3D6 SETTIMER: WORD INTWP4,SETTIMER+4
F3D6 020C 0080 LI PORT,0080H
F3DA 1E14 SBZ 20 ;RESET INTERRUPT
F3DC 0208 00C8 LI R8,200 ; 200 X 16MS = 7.0SEC
F3E0 C808 EF40 MOV R8,@TIMEOUT
F3E4 1E0E SBZ 14
F3E6 1D0D SBO 13 ;LOAD INTERVAL TIMER ONLY
F3E8 3220 F3F0 LDCR @INTLV2,8
F3EC 1D14 SBO 20 ;ENABLE INTERRUPT
F3EE 0380 RTWP
;
F3F0 FF INTLV2: BYTE 255 ;16.0 MILLISECONDS
F3F1 00 EVEN
;
;;*******************************************
;
; SEEK TO THE TRACK NUMBER HELD IN R3
;
; DRIVE # IS IN DRIVE
;
;********************************************
;
F3F2 2DA0 F28C SEEK: CALL @IDE_READY
F3F6 2DC0 RET
;
;******************************
;
; MAIN INTERRUPT ROUTINES
;
;********************************
;
FDC_DRQ ;LI R0,3 ;SHOW WHERE THE INTERRUPT CAME FROM
;WHEX R0
F3F8 020C 8000 LI PORT,STSREG
F3FC 3408 STCR R8 ;READ THE PORT AND CLEAR THE INTERRUPT
F3FE 0380 RTWP
;
;***********************************
;
; THIS INTERRUPT SIMULATES DMA CONTROL
; ORGANISED AS FOLLOWS:
;
; R9 HOLDS CURRENT COMMAND I.E. STCR OR LDCR
; R8 HOLDS THE CURRENT DMA ADDRESS.
; R12 HOLDS THE CURRENT IO PORT - GENERALLY DATREG
;
FDC_RWINT ;LI R0,2 ;SHOW WHERE THE INTERRUPT CAME FROM
;WHEX R0
;X R9 ;EXECUTE THE COMMAND SPECIFIED BY RDWRT
F400 0380 RTWP
;
;*********************************************************************
;
; THIS INTERRUPT IS CONTROLED BY THE TIMER ON THE TMS9902
;
;**********************************************************************
;
F402 020C 0080 INTTIMER: LI PORT,CRUBASE
F406 1F19 TB 25
F408 160B JNE TIME2
F40A 1D14 SBO 20 ;RESET INTERRUPT
F40C 0620 EF40 DEC @TIMEOUT
F410 1607 JNE TIME2
F412 05A0 EF40 INC @TIMEOUT
F416 1E14 SBZ 20 ;DISABLE TIMER
F418 020C 0000 LI PORT,SELMUX
F41C 04C8 CLR R8
F41E 3148 LDCR R8,5 ;CLEAR DISKS
F420 0380 TIME2 RTWP
;
;***********************************************************************
;
; MESSAGES
;
;************************************************************************
;
F422 0D0A 20 ERRMSG BYTE 0DH,0AH,20H
F425 4644 4320 TEXT 'FDC error type: '
F429 6572 726F
F42D 7220 7479
F431 7065 3A20
F435 00 BYTE 0
;STKMSG BYTE 0DH,0AH,20H
; TEXT 'Stack overflow at: '
; BYTE 0
F436 2044 7269 DRVMSG TEXT ' Drive: '
F43A 7665 3A20
F43E 00 BYTE 0
F43F 2054 7261 TRKMSG TEXT ' Track: '
F443 636B 3A20
F447 00 BYTE 0
F448 2053 6563 SECTMSG TEXT ' Sector: '
F44C 746F 723A
F450 20
F451 00 BYTE 0