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
|
1: ;*=*=*
2: ; xtrshard/dct
3: ; Emulate hard disk in a Unix file under xtrs
4: ;
5: ; Copyright (c) 1998, Timothy Mann
6: ;
7: ; This software may be copied, modified, and used for any
8: ; purpose without fee, provided that (1) the above copyright
9: ; notice is retained, and (2) modified versions are clearly
10: ; marked as having been modified, with the modifier's name and
11: ; the date included.
12: ;
13: ; Created 1-10-98
14: ; Last modified on Wed May 17 00:08:52 PDT 2000 by mann
15: ;*=*=*
16:
17:
18: ; Number of drives to allow
19: 0008 ndrive equ 8
20:
21:
22: ; ASCII chars
23: 000A LF equ 10
24: 000D CR equ 13
25: 0003 ETX equ 3
26:
27: ; Model 4 SVC numbers
28: 0064 @high equ 100
29: 000A @dsply equ 10
30: 0065 @flags equ 101
31: 000C @logot equ 12
32: 0052 @gtdcb equ 82
33: 0053 @gtmod equ 83
34: 005D @div8 equ 93
35: 005B @mul16 equ 91
36: 0009 @keyin equ 9
37:
38: ; Model I/III hard addresses
39: 0125 m3flag$ equ 0125h ; 'I' in ROM on Model III
40: 447B @logot1 equ 447bh
41: 428A @logot3 equ 428ah
42: 4467 @dsply1 equ 4467h
43: 4467 @dsply3 equ 4467h
44: 4049 high$1 equ 4049h
45: 4411 high$3 equ 4411h
46: 4758 cflag$1 equ 4758h
47: 4758 cflag$3 equ 4758h
48: 4303 @icnfg1 equ 4303h
49: 421D @icnfg3 equ 421dh
50: 4B8F @mult1 equ 4b8fh
51: 444E @mult3 equ 444eh
52: 4B7B @divea1 equ 4b7bh
53: 4B7A @divea3 equ 4b7ah
54: 0040 @keyin1 equ 0040h
55: 0040 @keyin3 equ 0040h
56:
57: ; Emulator trap instructions in byte-reversed form
58: 32ED emt_read equ 32EDH
59: 33ED emt_write equ 33EDH
60: 34ED emt_lseek equ 34EDH
61: 35ED emt_strerror equ 35EDH
62: 3DED emt_ftruncate equ 3DEDH
63: 3EED emt_opendisk equ 3EEDH
64: 3FED emt_closedisk equ 3FEDH
65:
66: ; Constants for emt_opendisk
67: 0000 EO_RDONLY equ 00o
68: 0001 EO_WRONLY equ 01o
69: 0002 EO_RDWR equ 02o
70: 0040 EO_CREAT equ 0100o
71: 0080 EO_EXCL equ 0200o
72: 0200 EO_TRUNC equ 01000o
73: 0400 EO_APPEND equ 02000o
74:
75: ;*=*=*
76: ; Set origin to be safe on both LDOS 5 and 6
77: ;*=*=*
78: 6000 org 6000h
79:
80: ;*=*=*
81: ; Relocator for disk driver
82: ;*=*=*
83: 6000 ED537363 instal: ld (dct),de ;Save DCT address
84: 6004 3A0A00 ld a,(000ah) ;Determine TRS-80 model
85: 6007 FE40 cp 40h
86: 6009 C23661 jp nz,lsdos6 ;Model 4 (or other LS-DOS, I hope)
87: 600C 3A2501 ld a,(m3flag$)
88: 600F FE49 cp 'I'
89: 6011 CAA560 jp z,model3 ;Go if Model III
90: ;*=*=*
91: ; LDOS 5 Model I - See LS-DOS 6 version for comments
92: ;*=*=*
93: 6014 3ECD ld a,0cdh ;Insert Model I @LOGOT
94: 6016 324262 ld (logot),a
95: 6019 217B44 ld hl,@logot1
96: 601C 224362 ld (logot+1),hl
97: 601F 327B65 ld (domul),a ;Insert Model I MULT
98: 6022 218F4B ld hl,@mult1
99: 6025 227C65 ld (domul+1),hl
100: 6028 32FA65 ld (dodiv),a ;Insert Model I DIVEA
101: 602B 217B4B ld hl,@divea1
102: 602E 22FB65 ld (dodiv+1),hl
103: 6031 3E31 ld a,'1' ;Modify filename
104: 6033 325366 ld (hmod),a
105: 6036 219D62 ld hl,hello_
106: 6039 CD6744 call @dsply1
107: 603C 3A5847 ld a,(cflag$1)
108: 603F CB5F bit 3,a ;System request?
109: 6041 CA3762 jp z,viaset
110: 6044 ED5B7363 ld de,(dct)
111: 6048 7A ld a,d ;DRIVE= must be specified
112: 6049 B3 or e
113: 604A CA3362 jp z,needdr
114: 604D 214A63 asku1: ld hl,unit_ ;Ask which unit number
115: 6050 CD6744 call @dsply1
116: 6053 217563 ld hl,unit
117: 6056 010001 ld bc,100h
118: 6059 CD4000 call @keyin1
119: 605C DA3F62 jp c,hitbrk
120: 605F C23F62 jp nz,hitbrk
121: 6062 3A7563 ld a,(unit)
122: 6065 FE30 cp '0'
123: 6067 38E4 jr c,asku1
124: 6069 FE38 cp '0'+ndrive
125: 606B 30E0 jr nc,asku1
126: 606D 2A4940 ld hl,(high$1)
127: 6070 CD7062 call xgtmod ;Module already loaded?
128: 6073 CAEF61 jp z,setdct
129: 6076 2A4940 ld hl,(high$1)
130: 6079 227163 ld (newend),hl
131: 607C 11E001 ld de,length
132: 607F 97 sub a
133: 6080 ED52 sbc hl,de
134: 6082 224940 ld (high$1),hl
135: 6085 CD4166 call dvrini
136: 6088 CD4962 call relo
137: 608B 3A0343 ld a,(@icnfg1)
138: 608E 323E66 ld (link),a
139: 6091 2A0443 ld hl,(@icnfg1+1)
140: 6094 223F66 ld (link+1),hl
141: 6097 213666 ld hl,dvrcfg
142: 6098 rx16 equ $-2
143: 609A 220443 ld (@icnfg1+1),hl
144: 609D 3EC3 ld a,0c3h
145: 609F 320343 ld (@icnfg1),a
146: 60A2 C3E161 jp move
147: ;*=*=*
148: ; LDOS 5 Model III
149: ;*=*=*
150: 60A5 model3:
151: 60A5 3ECD ld a,0cdh ;Insert Model III @LOGOT
152: 60A7 324262 ld (logot),a
153: 60AA 218A42 ld hl,@logot3
154: 60AD 224362 ld (logot+1),hl
155: 60B0 327B65 ld (domul),a ;Insert Model III MULT
156: 60B3 214E44 ld hl,@mult3
157: 60B6 227C65 ld (domul+1),hl
158: 60B9 32FA65 ld (dodiv),a ;Insert Model III DIVEA
159: 60BC 217A4B ld hl,@divea3
160: 60BF 22FB65 ld (dodiv+1),hl
161: 60C2 3E33 ld a,'3' ;Modify filename
162: 60C4 325366 ld (hmod),a
163: 60C7 219D62 ld hl,hello_
164: 60CA CD6744 call @dsply3
165: 60CD 3A5847 ld a,(cflag$3)
166: 60D0 CB5F bit 3,a ;System request?
167: 60D2 CA3762 jp z,viaset
168: 60D5 ED5B7363 ld de,(dct)
169: 60D9 7A ld a,d ;DRIVE= must be specified
170: 60DA B3 or e
171: 60DB CA3362 jp z,needdr
172: 60DE 214A63 asku3: ld hl,unit_ ;Ask which unit number
173: 60E1 CD6744 call @dsply3
174: 60E4 217563 ld hl,unit
175: 60E7 010001 ld bc,100h
176: 60EA CD4000 call @keyin3
177: 60ED DA3F62 jp c,hitbrk
178: 60F0 C23F62 jp nz,hitbrk
179: 60F3 3A7563 ld a,(unit)
180: 60F6 FE30 cp '0'
181: 60F8 38E4 jr c,asku3
182: 60FA FE38 cp '0'+ndrive
183: 60FC 30E0 jr nc,asku3
184: 60FE 2A1144 ld hl,(high$3)
185: 6101 CD7062 call xgtmod ;Module already loaded?
186: 6104 CAEF61 jp z,setdct
187: 6107 2A1144 ld hl,(high$3)
188: 610A 227163 ld (newend),hl
189: 610D 11E001 ld de,length
190: 6110 97 sub a
191: 6111 ED52 sbc hl,de
192: 6113 221144 ld (high$3),hl
193: 6116 CD4166 call dvrini
194: 6119 CD4962 call relo
195: 611C 3A1D42 ld a,(@icnfg3)
196: 611F 323E66 ld (link),a
197: 6122 2A1E42 ld hl,(@icnfg3+1)
198: 6125 223F66 ld (link+1),hl
199: 6128 213666 ld hl,dvrcfg
200: 6129 rx17 equ $-2
201: 612B 221E42 ld (@icnfg3+1),hl
202: 612E 3EC3 ld a,0c3h
203: 6130 321D42 ld (@icnfg3),a
204: 6133 C3E161 jp move
205:
206: ;*=*=*
207: ; LS-DOS 6
208: ;*=*=*
209: 6136 3E34 lsdos6: ld a,'4' ;Modify filename
210: 6138 325366 ld (hmod),a
211: 613B 219D62 ld hl,hello_
212: 613E 3E0A ld a,@dsply ;Display hello
213: 6140 EF rst 40
214: ;*=*=*
215: ; Check if entry from SYSTEM command.
216: ;*=*=*
217: 6141 3E65 ld a,@flags ;Get flags pointer into IY
218: 6143 EF rst 40
219: 6144 FD7E02 ld a,(iy+'C'-'A') ;Get CFLAG$
220: 6147 CB5F bit 3,a ;System request?
221: 6149 CA3762 jp z,viaset
222: 614C ED5B7363 ld de,(dct)
223: 6150 7A ld a,d ;DRIVE= must be specified
224: 6151 B3 or e
225: 6152 CA3362 jp z,needdr
226: ;*=*=*
227: ; Ask which unit number
228: ;*=*=*
229: 6155 214A63 asku4: ld hl,unit_ ;Ask which unit number
230: 6158 3E0A ld a,@dsply
231: 615A EF rst 40
232: 615B 217563 ld hl,unit
233: 615E 010001 ld bc,100h
234: 6161 3E09 ld a,@keyin
235: 6163 EF rst 40
236: 6164 DA3F62 jp c,hitbrk
237: 6167 C23F62 jp nz,hitbrk
238: 616A 3A7563 ld a,(unit)
239: 616D FE30 cp '0'
240: 616F 38E4 jr c,asku4
241: 6171 FE38 cp '0'+ndrive
242: 6173 30E0 jr nc,asku4
243: ;*=*=*
244: ; Check if driver already loaded
245: ;*=*=*
246: 6175 117C64 ld de,modnam
247: 6178 3E53 ld a,@gtmod
248: 617A EF rst 40
249: 617B CAEF61 jp z,setdct ;Already loaded, skip loading
250: ;*=*=*
251: ; Obtain low memory driver pointer. Bizarre API here!
252: ;*=*=*
253: 617E 1E4B ld e,'K' ;Locate pointer to *KI DCB
254: 6180 1649 ld d,'I' ; via @GTDCB SVC
255: 6182 3E52 ld a,@gtdcb
256: 6184 EF rst 40
257: 6185 C22F62 jp nz,curdl ;No error unless KI clobbered!
258: 6188 2B dec hl ;Decrement to driver pointer
259: 6189 56 ld d,(hl) ;P/u hi-order of pointer,
260: 618A 2B dec hl ; decrement to and p/u
261: 618B 5E ld e,(hl) ; lo-order of pointer
262: ;*=*=*
263: ; Check if driver will fit into [(LCPTR), X'12FF']
264: ;*=*=*
265: 618C E5 push hl ;Save address of pointer
266: 618D 21E001 ld hl,length ;New pointer will be
267: 6190 19 add hl,de ; pointer + LENGTH
268: 6191 54 ld d,h ;Save a copy in DE
269: 6192 5D ld e,l
270: 6193 010113 ld bc,1301h ;If > 1300H, driver won't fit
271: 6196 97 sub a ;Reset carry flag
272: 6197 ED42 sbc hl,bc
273: 6199 E1 pop hl ;Get back address of pointer
274: 619A 300A jr nc,usehi ;Go if driver won't fit
275: 619C 73 ld (hl),e ;Store new value of pointer
276: 619D 23 inc hl
277: 619E 72 ld (hl),d
278: 619F 1B dec de ;Last byte of driver goes here
279: 61A0 ED537163 ld (newend),de
280: 61A4 1816 jr dorelo
281: ;*=*=*
282: ; Put in high memory instead.
283: ;*=*=*
284: 61A6 210000 usehi: ld hl,0 ;Get current HIGH$
285: 61A9 45 ld b,l
286: 61AA 3E64 ld a,@high
287: 61AC EF rst 40
288: 61AD C23B62 jp nz,nomem
289: 61B0 227163 ld (newend),hl ;Last byte of driver goes here
290: 61B3 11E001 ld de,length
291: 61B6 97 sub a ;Reset carry flag
292: 61B7 ED52 sbc hl,de ;Compute new HIGH$
293: 61B9 3E64 ld a,@high ;Set new HIGH$ into the system
294: 61BB EF rst 40
295: ;*=*=*
296: ; Relocate internal references in driver.
297: ; HL = address for last byte of driver.
298: ;*=*=*
299: 61BC CD4166 dorelo: call dvrini ;Final driver init before move
300: 61BF CD4962 call relo
301: ;*=*=*
302: ; Link to @ICNFG (must follow address relocation and precede movement)
303: ;*=*=*
304: 61C2 3E65 ld a,@flags ;Get flags pointer into IY
305: 61C4 EF rst 40
306: 61C5 FD7E1C ld a,(iy+28) ;Copy current @ICNFG into LINK
307: 61C8 FD6E1D ld l,(iy+29)
308: 61CB FD661E ld h,(iy+30)
309: 61CE 323E66 ld (link),a
310: 61D1 223F66 ld (link+1),hl
311: 61D4 213666 ld hl,dvrcfg ;Get relocated init address
312: 61D5 rx10 equ $-2
313: 61D7 FD751D ld (iy+29),l ;Save in @ICNFG vector
314: 61DA FD741E ld (iy+30),h
315: 61DD FD361CC3 ld (iy+28),0c3h ;Insert JP opcode
316: ;*=*=*
317: ; Move driver into low or high memory.
318: ;*=*=*
319: 61E1 move:
320: 61E1 ED5B7163 ld de,(newend) ;Destination address
321: 61E5 215666 ld hl,dvrend ;Last byte of module
322: 61E8 01E001 ld bc,length ;Length of filter
323: 61EB EDB8 lddr
324: 61ED EB ex de,hl
325: 61EE 23 inc hl ;Bump to driver entry
326: ;*=*=*
327: ; Setup DCT (iy+5 to iy+9 are reset by ckopen if successful)
328: ;*=*=*
329: 61EF setdct:
330: 61EF FD2A7363 ld iy,(dct)
331: 61F3 FD3600C3 ld (iy),0c3h ;JP instruction (enable driver)
332: 61F7 FD7501 ld (iy+1),l ;Driver address
333: 61FA FD7402 ld (iy+2),h
334: 61FD FD36030C ld (iy+3),00001100b ;Flags: rigid, fixed, step rate 0
335: 6201 3A7563 ld a,(unit)
336: 6204 E60F and 0fh
337: 6206 F610 or 00010000b ;Flags: alien (=no index pulses), unit#
338: 6208 FD7704 ld (iy+4),a
339: 620B FD360500 ld (iy+5),0 ;LDOS undefined; we use as sec/cyl (0=256).
340: 620F FD3606C9 ld (iy+6),201 ;high cylinder number
341: 6213 FD3607FF ld (iy+7),11111111b ;high head # (111), high sec/trak (11111)
342: 6217 FD3608FF ld (iy+8),11111111b ;high gran # (111), high sec/gran (11111)
343: 621B FD3609FF ld (iy+9),0ffh ;Directory cylinder
344: ;*=*=*
345: ; Open file now so user can get error if any, and so geometry
346: ; is established as early as possible.
347: ;*=*=*
348: 621F CD9965 call ckopen
349: 6222 210000 ld hl,0 ;Successful completion
350: 6225 C8 ret z ;Fall thru if error
351: ;*=*=*
352: 6226 217763 uerror: ld hl,errbuf ;Unix error
353: 6229 010001 ld bc,256
354: 622C ED35 defw emt_strerror
355: 622E DD defb 0ddh
356: 622F 21D562 curdl: ld hl,curdl_ ;Other error
357: 6232 DD defb 0ddh
358: 6233 213063 needdr: ld hl,needdr_
359: 6236 DD defb 0ddh
360: 6237 210663 viaset: ld hl,viaset_
361: 623A DD defb 0ddh
362: 623B 21E862 nomem: ld hl,nomem_
363: 623E DD defb 0ddh
364: 623F 216663 hitbrk: ld hl,hitbrk_
365: 6242 3E0C logot: ld a,@logot
366: 6244 EF rst 40
367: 6245 21FFFF ld hl,-1 ;Unuccessful completion
368: 6248 C9 ret
369:
370: ;*=*=*
371: ; Relocate internal references in driver.
372: ; HL = address for last byte of driver.
373: ;*=*=*
374: 6249 2A7163 relo: ld hl,(newend)
375: 624C FD215766 ld iy,reltab ;Point to relocation tbl
376: 6250 115666 ld de,dvrend
377: 6253 97 sub a ;Clear carry flag
378: 6254 ED52 sbc hl,de
379: 6256 44 ld b,h ;Move to BC
380: 6257 4D ld c,l
381: 6258 FD6E00 rloop: ld l,(iy) ;Get address to change
382: 625B FD6601 ld h,(iy+1)
383: 625E 7C ld a,h
384: 625F B5 or l
385: 6260 C8 ret z
386: 6261 5E ld e,(hl) ;P/U address
387: 6262 23 inc hl
388: 6263 56 ld d,(hl)
389: 6264 EB ex de,hl ;Offset it
390: 6265 09 add hl,bc
391: 6266 EB ex de,hl
392: 6267 72 ld (hl),d ;And put back
393: 6268 2B dec hl
394: 6269 73 ld (hl),e
395: 626A FD23 inc iy
396: 626C FD23 inc iy
397: 626E 18E8 jr rloop ;Loop till done
398:
399: ;*=*=*
400: ; Search for existing copy of driver.
401: ; Rough Model I/III emulation of Model 4 @GTMOD,
402: ; hardcoded with driver address.
403: ; Entry: HL holds HIGH$
404: ; Exit Z: HL holds driver address
405: ; NZ: driver not found
406: ;*=*=*
407: 6270 23 xgtmod: inc hl
408: 6271 7C ld a,h
409: 6272 B5 or l
410: 6273 2002 jr nz,xgtm1
411: 6275 3D dec a ;not found
412: 6276 C9 ret
413: 6277 7E xgtm1: ld a,(hl)
414: 6278 FE18 cp 18h ;unconditional jr?
415: 627A C0 ret nz ;not a module header
416: 627B E5 push hl ;save start address
417: 627C 23 inc hl ;skip jr
418: 627D 23 inc hl ;skip offset
419: 627E 23 inc hl ;skip start address
420: 627F 23 inc hl
421: 6280 7E ld a,(hl) ;compare name length
422: 6281 FE08 cp modptr-modnam
423: 6283 200F jr nz,nextmd ;different - skip
424: 6285 47 ld b,a ;compare name
425: 6286 117C64 ld de,modnam
426: 6289 23 inc hl
427: 628A 1A xgtm2: ld a,(de)
428: 628B BE cp (hl)
429: 628C 2006 jr nz,nextmd ;different - skip
430: 628E 13 inc de
431: 628F 23 inc hl
432: 6290 10F8 djnz xgtm2
433: 6292 E1 pop hl ;same - found
434: 6293 C9 ret
435: 6294 E1 nextmd: pop hl ;get back start of module
436: 6295 23 inc hl
437: 6296 23 inc hl
438: 6297 5E ld e,(hl) ;pointer to last byte
439: 6298 23 inc hl
440: 6299 56 ld d,(hl)
441: 629A EB ex de,hl
442: 629B 18D3 jr xgtmod
443:
444: ;*=*=*
445: ; Messages and globals
446: ;*=*=*
447: 629D 58545253 hello_: defb 'XTRSHARD - Emulated hard disk driver for xtrs - 5/17/00',CR
48415244
202D2045
6D756C61
74656420
68617264
20646973
6B206472
69766572
20666F72
20787472
73202D20
352F3137
2F30300D
448: 62D5 4C532D44 curdl_: defb 'LS-DOS is curdled!',CR
4F532069
73206375
72646C65
64210D
449: 62E8 48696768 nomem_: defb 'High memory is not available!',CR
206D656D
6F727920
6973206E
6F742061
7661696C
61626C65
210D
450: 6306 4D757374 viaset_:defb 'Must install via SYSTEM (DRIVE=,DRIVER=)!',CR
20696E73
74616C6C
20766961
20535953
54454D20
28445249
56453D2C
44524956
45523D29
210D
451: 6330 44524956 needdr_:defb 'DRIVE= must be specified!',CR
453D206D
75737420
62652073
70656369
66696564
210D
452: 634A 456E7465 unit_: defb 'Enter unit number ([0]-','0'+ndrive-1,'): ',ETX
7220756E
6974206E
756D6265
7220285B
305D2D37
293A2003
453: 6366 41626F72 hitbrk_:defb 'Aborted!',CR
74656421
0D
454: 636F 0000 lcptr: defw 0
455: 6371 0000 newend: defw 0
456: 6373 0000 dct: defw 0
457: 6375 unit: defs 2
458: 6377 errbuf: defs 256
459:
460: ;
461: ; Driver - Based on skeletal driver from the Guide
462: ;
463:
464: 6477 1827 entry: jr begin ;The driver starts with the
465: 6479 5666 defw dvrend ; DOS standard header
466: 6479 rx00 equ $-2
467: 647B 08 defb modptr-modnam ;Length of name
468: 647C 78747273 modnam: defb 'xtrshard' ;Name for @GTMOD requests
68617264
469: 6484 0000 modptr: defw 0 ;These pointers are unused
470: 6486 0000 defw 0
471: 6488 fd: defs ndrive*2 ;Unix file descriptors
472: 6498 00000000 offset: defw 0,0,0,0 ;lseek offset buffer
00000000
473: 64A0 begin:
474: ;*=*=*
475: ; First make sure the file is open and correct the geometry
476: ; in the DCT if needed.
477: ;*=*=*
478: 64A0 DDE5 push ix
479: 64A2 CD9965 call ckopen
480: 64A3 rx03 equ $-2
481: 64A5 CDAB64 call body
482: 64A6 rx06 equ $-2
483: 64A8 DDE1 pop ix
484: 64AA C9 ret
485: 64AB 3E20 body: ld a,32 ;"Illegal drive number"
486: 64AD C0 ret nz
487: 64AE 78 ld a,b ;The first test will return
488: 64AF A7 and a ; to the caller on @DCSTAT
489: 64B0 C8 ret z ; and set the Z-flag with A=0
490: 64B1 FE07 notdcs: cp 7
491: 64B3 2804 jr z,rslct ;Transfer on @RSLCT
492: 64B5 3004 jr nc,diskio ;Transfer on physical I/O request
493: ;*=*=*
494: ; @SLCT, @DCINIT, @DCRES, @RSTOR, @STEPI or @SEEK: no-op
495: ;*=*=*
496: 64B7 97 retzer: sub a
497: 64B8 C9 ret
498: ;*=*=*
499: ; The RSLCT function should return with the hardware
500: ; write protection status. Set bit 6 of the accumulator
501: ; to indicate the drive is write-protected
502: ;*=*=*
503: 64B9 97 rslct: sub a ;No emulated hardware WP for now
504: 64BA C9 ret
505: ;*=*=*
506: 64BB CB50 diskio: bit 2,b ;Test if read or write commands
507: 64BD 2058 jr nz,wrcmd ;Transfer if functions <12-15>
508: 64BF FE0A cp 10
509: 64C1 2847 jr z,vrsec
510: 64C3 304E jr nc,rdtrk
511: 64C5 FE09 cp 9
512: 64C7 2804 jr z,rdsec
513: 64C9 3E20 rdhdr: ld a,32 ;Not supported ("Illegal drive number")
514: 64CB A7 and a
515: 64CC C9 ret
516: ;*=*=*
517: 64CD rdsec: ;Read a sector of data
518: 64CD FD7E06 ld a,(iy+6) ;Get high cyl #
519: 64D0 BA cp d ;At or below it?
520: 64D1 3003 jr nc,rdok
521: 64D3 3E02 ld a,2 ;"Seek error during read"
522: 64D5 C9 ret ;NZ already set
523: 64D6 D5 rdok: push de
524: 64D7 E5 push hl
525: 64D8 CD6F65 call doseek ;Setup and do lseek
526: 64D9 rx01 equ $-2
527: 64DB E1 pop hl
528: 64DC 3E05 ld a,5 ;"Data record not found during read"
529: 64DE 2007 jr nz,rddun
530: 64E0 010001 ld bc,256
531: 64E3 ED32 defw emt_read
532: 64E5 3E04 ld a,4 ;"Parity error during read"
533: 64E7 D1 rddun: pop de
534: 64E8 C0 ret nz
535: 64E9 78 ld a,b ;Check for end of file
536: 64EA B1 or c
537: 64EB 2012 jr nz,rddun2
538: 64ED D5 push de
539: 64EE E5 push hl ;Return a block full of 0E5H
540: 64EF C5 push bc
541: 64F0 36E5 ld (hl),0e5h
542: 64F2 54 ld d,h
543: 64F3 5D ld e,l
544: 64F4 13 inc de
545: 64F5 01FF00 ld bc,0ffh
546: 64F8 EDB0 ldir
547: 64FA C1 pop bc
548: 64FB E1 pop hl
549: 64FC D1 pop de
550: 64FD 97 sub a
551: 64FE C9 ret
552: 64FF 7A rddun2: ld a,d
553: 6500 FD9609 sub (iy+9)
554: 6503 2003 jr nz,rddun1
555: 6505 C606 add a,6 ;"Attempted to read system data record"
556: 6507 C9 ret
557: 6508 97 rddun1: sub a
558: 6509 C9 ret
559: ;*=*=*
560: 650A vrsec: ;Read/verify -- we don't bother reading
561: 650A FD7E06 ld a,(iy+6) ;Get high cyl #
562: 650D BA cp d ;At or below it?
563: 650E 30EF jr nc,rddun2 ;Go if so
564: 6510 3E02 ld a,2 ;"Seek error during read"
565: 6512 C9 ret ;NZ already set
566: ;*=*=*
567: ; On RDSEC and VRSEC, if the read referenced the
568: ; directory cylinder and was successful,
569: ; then you need to return an error code 6. A floppy
570: ; disk controller will provide the indicated status.
571: ; Hard disk users may have to compare the requested
572: ; cylinder to DIRCYL in the DCT.
573: ;*=*=*
574: 6513 3E20 rdtrk: ld a,32 ;Not supported ("Illegal drive number")
575: 6515 A7 and a
576: 6516 C9 ret
577: ;*=*=*
578: 6517 FDCB037E wrcmd: bit 7,(iy+3) ;Check for software write protect
579: 651B 2803 jr z,wrcmd1 ;Transfer if no soft WP
580: 651D 3E0F ld a,15 ;Set "Write protected disk" error
581: 651F C9 ret
582: 6520 FE0E wrcmd1: cp 14 ;Now parse functions 12-15
583: 6522 2829 jr z,wrssc
584: 6524 3045 jr nc,wrtrk
585: 6526 FE0D cp 13
586: 6528 281E jr z,wrsec
587: ;*=*=*
588: 652A hdfmt: ;Low-level format (=erase)
589: 652A FD3609FF ld (iy+9),0ffh ;Invalidate directory cylinder
590: 652E D5 push de
591: 652F E5 push hl
592: 6530 DD5E00 ld e,(ix) ;Get fd
593: 6533 DD5601 ld d,(ix+1)
594: 6536 210001 exists: ld hl,256 ;Truncate file to just the header
595: 6539 229964 ld (offset+1),hl
596: 653A rx07 equ $-2
597: 653C 219864 ld hl,offset
598: 653D rx08 equ $-2
599: 653F ED3D defw emt_ftruncate
600: 6541 E1 creatd: pop hl
601: 6542 D1 pop de
602: 6543 3E0E ld a,14 ;"Write fault on disk drive"
603: 6545 C0 ret nz
604: 6546 97 sub a
605: 6547 C9 ret
606: ;*=*=*
607: 6548 wrsec: ;Write with X'FB' data address mark
608: 6548 7A ld a,d ;Check if writing track 0, sector 0
609: 6549 B3 or e
610: 654A CC1566 call z,setdir ;Set directory cyl in Reed header
611: 654B rx20 equ $-2
612: ;*=*=*
613: 654D wrssc: ;Write with X'F8' data address mark
614: 654D FD7E06 ld a,(iy+6) ;Get high cyl #
615: 6550 BA cp d ;Beyond it?
616: 6551 3003 jr nc,wrok1
617: 6553 3E0A ld a,10 ;"Seek error during write"
618: 6555 C9 ret ;NZ already set
619: ;*=*=*
620: 6556 D5 wrok1: push de
621: 6557 E5 push hl
622: 6558 CD6F65 call doseek
623: 6559 rx04 equ $-2
624: 655B E1 pop hl
625: 655C 3E0D ld a,13 ;"Data record not found during write"
626: 655E 2007 jr nz,wrdun
627: 6560 010001 ld bc,256
628: 6563 ED33 defw emt_write
629: 6565 3E0C ld a,12 ;"Parity error during write"
630: 6567 D1 wrdun: pop de
631: 6568 C0 ret nz
632: 6569 97 sub a
633: 656A C9 ret
634: ;*=*=*
635: 656B 3E20 wrtrk: ld a,32 ;Write track
636: 656D A7 and a ;Not supported ("Illegal drive number")
637: 656E C9 ret
638: ;*=*=*
639: ; Perform lseek before r/w
640: ;*=*=*
641: 656F 97 doseek: sub a ;sec/cyl to hl, xlate 0 to 256
642: 6570 67 ld h,a
643: 6571 FD8605 add a,(iy+5)
644: 6574 6F ld l,a
645: 6575 2001 jr nz,noinc
646: 6577 24 inc h
647: 6578 4A noinc: ld c,d ;cyl# to c
648: 6579 43 ld b,e ;sec# to b
649: 657A 79 ld a,c ;model I/III call uses a, not c
650: 657B 3E5B domul: ld a,@mul16 ;hla = hl * c, smash de
651: 657D EF rst 40
652: 657E 54 ld d,h ;sec# to de (h is 0)
653: 657F 58 ld e,b
654: 6580 65 ld h,l ;product to hl
655: 6581 6F ld l,a
656: 6582 23 inc hl ;add 1 extra for header
657: 6583 19 add hl,de
658: 6584 EB ex de,hl ;offset to de
659: 6585 219A64 ld hl,offset+2
660: 6586 rx15 equ $-2
661: 6588 72 ld (hl),d
662: 6589 2B dec hl
663: 658A 73 ld (hl),e
664: 658B 2B dec hl
665: 658C 010000 ld bc,0
666: 658F 71 ld (hl),c
667: 6590 DD5E00 ld e,(ix) ;Get fd
668: 6593 DD5601 ld d,(ix+1)
669: 6596 ED34 defw emt_lseek
670: 6598 C9 ret
671:
672: ;*=*=*
673: ; Open file and read geometry if needed, and
674: ; get address of correct fd to ix.
675: ;*=*=*
676: 6599 DD218864 ckopen: ld ix,fd ;Compute fd address
677: 659B rx02 equ $-2
678: 659D D5 push de
679: 659E 1600 ld d,0
680: 65A0 FD7E04 ld a,(iy+4)
681: 65A3 E60F and 0fh
682: 65A5 07 rlca
683: 65A6 5F ld e,a
684: 65A7 DD19 add ix,de
685: 65A9 D1 pop de
686: 65AA DD7E00 ld a,(ix) ;fd == -1?
687: 65AD DDA601 and (ix+1)
688: 65B0 3C inc a
689: 65B1 2802 jr z,doopen
690: 65B3 97 sub a
691: 65B4 C9 ret
692: 65B5 D5 doopen: push de
693: 65B6 C5 push bc
694: 65B7 E5 push hl
695: 65B8 010200 ld bc,EO_RDWR ;Prepare to open
696: 65BB 11B601 ld de,0666o ;mode
697: 65BE 214F66 ld hl,hard_ ;name
698: 65BF rx05 equ $-2
699: 65C1 FD7E04 ld a,(iy+4)
700: 65C4 E60F and 0fh
701: 65C6 C630 add a,'0'
702: 65C8 325566 ld (hadr),a
703: 65C9 rx09 equ $-2
704: 65CB ED3E defw emt_opendisk
705: 65CD DD7300 ld (ix),e
706: 65D0 DD7201 ld (ix+1),d
707: 65D3 203C jr nz,opnerr
708: 65D5 219864 ld hl,offset ;Prepare to read geometry
709: 65D6 rx13 equ $-2
710: 65D8 361C ld (hl),28 ;offset to cyl/sec/gran params
711: 65DA 010000 ld bc,0
712: 65DD ED439964 ld (offset+1),bc
713: 65DF rx14 equ $-2
714: 65E1 ED34 defw emt_lseek
715: 65E3 202C jr nz,opnerr
716: 65E5 010300 ld bc,3 ;length
717: 65E8 ED32 defw emt_read ;use offset buffer
718: 65EA 2025 jr nz,opnerr
719: 65EC 7E ld a,(hl) ;cyl
720: 65ED 3D dec a
721: 65EE FD7706 ld (iy+6),a ;max cylinder
722: 65F1 23 inc hl
723: 65F2 46 ld b,(hl) ;sec
724: 65F3 FD7005 ld (iy+5),b
725: 65F6 23 inc hl
726: 65F7 4E ld c,(hl) ;gran
727: 65F8 58 ld e,b ;compute sec/gran
728: 65F9 79 ld a,c ;model I/III call uses a, not c
729: 65FA 3E5D dodiv: ld a,@div8 ;a = e / c, e = e % c
730: 65FC EF rst 40 ;remainder mbz, but we don't check here
731: 65FD 3D dec a
732: 65FE 0D dec c
733: 65FF CB09 rrc c
734: 6601 CB09 rrc c
735: 6603 CB09 rrc c
736: 6605 B1 or c
737: 6606 FD7707 ld (iy+7),a ;heads, secs per track
738: 6609 FD7708 ld (iy+8),a ;grans, secs per gran
739: 660C FD3609FF ld (iy+9),0ffh ;dircyl unknown
740: 6610 97 sub a ;no error
741: 6611 E1 opnerr: pop hl
742: 6612 C1 pop bc
743: 6613 D1 pop de
744: 6614 C9 ret
745: ;*=*=*
746: ; Sleazy trick to update dir cyl in Reed header: do
747: ; it whenever track 0, sector 0 is written.
748: ; Only important if sharing images with Reed emulator.
749: ;*=*=*
750: 6615 E5 setdir: push hl
751: 6616 C5 push bc
752: 6617 D5 push de
753: 6618 219864 ld hl,offset
754: 6619 rx18 equ $-2
755: 661B 42 ld b,d ;de is known to be 0 here
756: 661C 4B ld c,e
757: 661D DD5E00 ld e,(ix) ;Get fd
758: 6620 DD5601 ld d,(ix+1)
759: 6623 361F ld (hl),31 ;offset to dir cyl param
760: 6625 ED439964 ld (offset+1),bc
761: 6627 rx19 equ $-2
762: 6629 ED34 defw emt_lseek
763: 662B FD7E09 ld a,(iy+9) ;dir cyl value to write
764: 662E 77 ld (hl),a
765: 662F 03 inc bc
766: 6630 ED33 defw emt_write
767: 6632 D1 pop de ;cheat, ignore errors
768: 6633 C1 pop bc
769: 6634 E1 pop hl
770: 6635 C9 ret
771: ;*=*=*
772: ; Boot-time initialization
773: ;*=*=*
774: 6636 11FFFF dvrcfg: ld de,-1 ;@ICNFG chains in here
775: 6639 ED3F defw emt_closedisk ;close any files left from before reboot
776: 663B CD4166 call dvrini
777: 663C rx11 equ $-2
778: 663E 54696D link: defb 'Tim' ;Replaced by next link in @ICNFG chain
779: 6641 218864 dvrini: ld hl,fd
780: 6642 rx12 equ $-2
781: 6644 54 ld d,h
782: 6645 5D ld e,l
783: 6646 13 inc de
784: 6647 36FF ld (hl),0ffh
785: 6649 010F00 ld bc,ndrive*2-1
786: 664C EDB0 ldir
787: 664E C9 ret
788: ;*=*=*
789: ; Disk name: hardM-N for model M (1,3,4), number N (0-7)
790: ;*=*=*
791: 664F 68617264 hard_: defb 'hard'
792: 6653 312D hmod: defb '1-'
793: 6655 3000 hadr: defb '0',0
794:
795: 6656 dvrend equ $-1
796: 01E0 length equ $-entry
797: 6657 7964D964 reltab: defw rx00,rx01,rx02,rx03,rx04,rx05,rx06,rx07,rx08,rx09
9B65A364
5965BF65
A6643A65
3D65C965
798: 666B D5613C66 defw rx10,rx11,rx12,rx13,rx14,rx15,rx16,rx17,rx18,rx19
4266D665
DF658665
98602961
19662766
799: 667F 4B650000 defw rx20,0
800: 6000 end instal
Statistics:
146 symbols
1393 bytes
Symbol Table:
@div8 = 5d emt_write =33ed rdok 64d6
@divea1 =4b7b entry 6477 rdsec 64cd
@divea3 =4b7a eo_append = 400+ rdtrk 6513
@dsply = a eo_creat = 40+ relo 6249
@dsply1 =4467 eo_excl = 80+ reltab 6657
@dsply3 =4467 eo_rdonly = 0+ retzer 64b7+
@flags = 65 eo_rdwr = 2 rloop 6258
@gtdcb = 52 eo_trunc = 200+ rslct 64b9
@gtmod = 53 eo_wronly = 1+ rx00 =6479
@high = 64 errbuf 6377 rx01 =64d9
@icnfg1 =4303 etx = 3 rx02 =659b
@icnfg3 =421d exists 6536+ rx03 =64a3
@keyin = 9 fd 6488 rx04 =6559
@keyin1 = 40 hadr 6655 rx05 =65bf
@keyin3 = 40 hard_ 664f rx06 =64a6
@logot = c hdfmt 652a+ rx07 =653a
@logot1 =447b hello_ 629d rx08 =653d
@logot3 =428a high1 =4049 rx09 =65c9
@mul16 = 5b high3 =4411 rx10 =61d5
@mult1 =4b8f hitbrk 623f rx11 =663c
@mult3 =444e hitbrk_ 6366 rx12 =6642
asku1 604d hmod 6653 rx13 =65d6
asku3 60de instal 6000 rx14 =65df
asku4 6155 lcptr 636f+ rx15 =6586
begin 64a0 length = 1e0 rx16 =6098
body 64ab lf = a+ rx17 =6129
cflag1 =4758 link 663e rx18 =6619
cflag3 =4758 logot 6242 rx19 =6627
ckopen 6599 lsdos6 6136 rx20 =654b
cr = d m3flag = 125 setdct 61ef
creatd 6541+ model3 60a5 setdir 6615
curdl 622f modnam 647c uerror 6226+
curdl_ 62d5 modptr 6484 unit 6375
dct 6373 move 61e1 unit_ 634a
diskio 64bb ndrive = 8 usehi 61a6
dodiv 65fa needdr 6233 viaset 6237
domul 657b needdr_ 6330 viaset_ 6306
doopen 65b5 newend 6371 vrsec 650a
dorelo 61bc nextmd 6294 wrcmd 6517
doseek 656f noinc 6578 wrcmd1 6520
dvrcfg 6636 nomem 623b wrdun 6567
dvrend =6656 nomem_ 62e8 wrok1 6556
dvrini 6641 notdcs 64b1+ wrsec 6548
emt_closedisk =3fed offset 6498 wrssc 654d
emt_ftruncate =3ded opnerr 6611 wrtrk 656b
emt_lseek =34ed rddun 64e7 xgtm1 6277
emt_opendisk =3eed rddun1 6508 xgtm2 628a
emt_read =32ed rddun2 64ff xgtmod 6270
emt_strerror =35ed rdhdr 64c9+
|