-
Notifications
You must be signed in to change notification settings - Fork 1
/
srdisk.inc
executable file
·1799 lines (1506 loc) · 56.2 KB
/
srdisk.inc
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
;
; ReSizeable RAMDisk device driver
;
; Copyright (C) 1992-1996, 2005 Marko Kohtala
; Released under GNU GPL, read the file 'COPYING' for more information
;
; To compile with TASM, find the appropriate srd???.asm file and:
; tasm /m2 srd???.asm
; tlink /t srd???.obj,srd???.sys
include dosstruc.inc
DR_ATTRIBUTES = DHATTR_NOFAT or DHATTR_OPENCLOSE
if CAPABLE and C_32BITSEC
DR_ATTRIBUTES = DR_ATTRIBUTES or DHATTR_32BIT
endif
if CAPABLE and C_GIOCTL
DR_ATTRIBUTES = DR_ATTRIBUTES or DHATTR_GIOCTL
endif
;**************************************************************************
;
; Device driver start and the structures
;
;**************************************************************************
d_seg segment page public
assume ds:d_seg, cs:d_seg
org 0
; The following is to be considered as both a device driver header and
; as a starting point for the configuration table. This driver will be
; identified by its segment address and this structure must be at offset
; 0.
; Device driver header
drhdr_next dd -1 ; Pointer to next device (now last)
drhdr_attr dw DR_ATTRIBUTES
drhdr_strategy dw offset strategy ; Offset to strategy function
drhdr_commands dw offset commands ; Offset to commands function
drhdr_units db 1 ; Number of units
; The rest has four functions to be considered
; 1) usable as device driver name if this driver is changed
; into character device on init.
; 2) usable as a label to be returned in media check call
; 3) identifies this device driver as SRDISK driver by always having
; the letters SRD at offset dr_ID
; 4) identifies the memory used by the 4 char string at offset dr_memory
dr_volume label byte
dr_ID db 'SRD' ; SRDISK signature (3 char)
dr_memory db MEMSTR ; Memory type identifier (4 char)
dr_version db SRD_VERSION ; Device driver version (4 char)
db 0 ; null to end volume label
dr_v_format db V_FORMAT ; Configuration format version
dr_conf dw offset conf ; Pointer to drive configuration
disk_IO proc far
mac_disk_IO ; Disk access function
disk_IO endp
ife CAPABLE and C_NOALLOC
malloc proc far
mac_malloc ; Memory allocation function
malloc endp
freemem proc far
mac_freemem
freemem endp
else ; ife CAPABLE and C_NOALLOC
freemem equ 0
endif ; ife CAPABLE and C_NOALLOC
ret_far proc far ; Null function to replace
ret ; strategy and command when appended
ret_far endp ; to another SRDISK drive
if HOOKINT19
int_19_entry proc far
mac_int_19 ; INT 19 boot function
int_19_entry endp
old_int19 label dword ; Address of old INT 19
old_int19_off dw -1
old_int19_seg dw -1
endif ; HOOKINT19
mac_resident_data ; Memory specific resident data
;**************************************************************************
;
; Debugging code
;
; This code prints out a character and a word in hex. This code can be
; used using "debug char,word" macro in the code to give some output of
; the actions device driver is doing.
;
; A color display is assumed with 80 characters on a row and 25 rows.
;
;**************************************************************************
if DEBUGGING
assume ds:nothing
debug_c proc near
push es
push di
mov ah,d_attr ; Load color attribute
mov di,0B800h ; Load screen segment (assumes color)
mov es,di
mov di,d_loc ; Load line
cmp di,26*160 ; Below screen?
jb debug_c1
mov di,2*160 ; Yes, move to third line (for scroll off)
mov d_loc,di
add ah,10h ; Change color
cmp ah,70h
jb debug_c2
sub ah,60h
debug_c2: mov d_attr,ah
push es ; Wait if shift down
push ax
mov ax,40h
mov es,ax
debug_c3: test byte ptr es:[17h],3
jnz debug_c3
pop ax
pop es
debug_c1:
add di,d_col ; Advance to right column
mov es:[di],ax ; Print error letter
call debug_x ; Print high byte
mov dh,dl
call debug_x ; Print low byte
add d_loc,160 ; Next line
pop di
pop es
ret
debug_c endp
debug_x proc near ; Print a byte in hex
mov al,dh
shr al,1
shr al,1
shr al,1
shr al,1
call debug_x1
mov al,dh
debug_x1: and al,0Fh ; Print a hex digit
cmp al,10
jae debug_x2
add al,'0'
jmp debug_x3
debug_x2: add al,'A'-10
debug_x3:
inc di
inc di
mov es:[di],ax
ret
debug_x endp
d_loc dw 2*160
d_col dw 150
d_attr db 40h
assume ds:d_seg
endif ; DEBUGGING
;**************************************************************************
;
; Configuration tables
;
; This structure holds all the formatting data used by the formatter.
; The formatter is passed a pointer to this data and it modifies it
; directly. For this arrangement to work THE BELOW TABLE MAY NOT BE
; MODIFIED WITHOUT PROPER CHANGES IN SRDISK.EXE. dr_v_format contains
; version number which is to be changed when a change is made to this
; structure.
;
; Only the first fields up to label appended_eor is resident and used in
; in every case. The rest is used only in the main driver in a chain of
; RAM disk drivers.
;
; !!! The formatter may use any initial values in this structure as
; default values i.e. set all needed values here !!!
; !!! A DR-DOS bug must be avoided by defining c_BPB_sectors and
; c_BPB_FATsectors so that they could be real !!!
;**************************************************************************
READ_ACCESS equ 1 ; Bit masks for the RW_access
WRITE_ACCESS equ 2
config_s struc
c_drive db ? ; Drive letter
c_flags db CAPABLE ; Misc capability flags
c_disk_IO dw offset disk_IO ; disk_IO entry
c_disk_IO_seg dw 0 ; disk_IO entry segment
c_malloc dw malloc ; malloc entry offset (in DS/CS)
c_freemem dw freemem ; free mem query entry offset (in DS/CS)
c_next dw 0 ; Next driver in chain (segment)
c_maxK dd MAX_SIZE ; Maximum allowed size
c_size dd 0 ; Current allocated size in Kbytes
c_allocblock dw ALLOCBLOCK ; Memory allocation block size
c_sectorsl dw 0 ; Sectors in this driver (low word)
c_sectorsh dw 0 ; Sectors in this driver (high word)
c_bps_shift db 7 ; 2^c_bps_shift == c_BPB_bps
c_BPB_bps dw 512 ; Sector size
c_BPB_spc db 1 ; Cluster size in sectors
c_BPB_reserved dw 1 ; The boot sector is reserved
c_BPB_FATs db 1 ; One FAT copy
c_BPB_dir dw 64 ; 64 entries in root directory
c_BPB_sectors dw 100 ; number of sectors on 16-bit disk
c_BPB_media db 0FAh ; Media is RAM DISK
c_BPB_FATsectors dw 1 ; Sectors per one FAT
c_BPB_spt dw 8 ; Sectors per track
c_BPB_heads dw 1 ; Number of heads
c_BPB_hiddenl dw 0 ; # of hidden sectors (low word)
c_BPB_hiddenh dw 0 ; # of hidden sectors (high word)
c_BPB_tsectorsl dw 0 ; # of sectors on 32-bit disk (low word)
c_BPB_tsectorsh dw 0 ; # of sectors on 32-bit disk (high)
c_tsize dd 0 ; Total size in Kbytes (all drivers)
c_RW_access db 000b ; B0 = read, B1 = write, B2 = fixed
c_media_change db 1 ; -1 if media changed, 1 if not
c_device_type db 0 ; Device type for Generic IOCTL
c_open_files dw 0 ; Files currently open on drive
c_next_drive dw 0 ; Segment of next SRDISK drive
c_transfer dw batch_xfer ; Batch xfer function address
config_s ends
;conf config_s <>
; TASM 3.0 bugs force this approach:
conf config_s <?,CAPABLE,offset disk_IO,0,malloc,freemem,0,MAX_SIZE,0,ALLOCBLOCK,0,0,9,512,1,1,1,64,100,0FAh,1,8,1,0,0,0,0,0,0,1,0,0,0,batch_xfer>
appended_eor equ offset conf.c_BPB_spc ; End of resident for appended driver
;**************************************************************************
;
; Other internal and resident data
;
; The order of this data is not significant as it will not be used outside
;
;**************************************************************************
BPB equ byte ptr conf.c_BPB_bps
pBPB dw offset BPB ; Pointer to BPB (for cmd_init)
old_multiplex dd ? ; Multiplex hook
req_ptr dd ? ; Request structure pointer
ifdef STACKSIZE
caller_sp dw ? ; To store pointer to callers stack
caller_ss dw ? ; if we use our own stack
endif
; Pointers to commands
command_tbl dw cmd_init ; 0 Init
dw cmd_media ; 1 Media
dw cmd_BPB ; 2 Build BPB
dw cmd_unknown ; 3 IOCTL input
dw cmd_input ; 4 Input
dw cmd_unknown ; 5 nondest input (char)
dw cmd_unknown ; 6 input status (char)
dw cmd_unknown ; 7 input flush (char)
dw cmd_output ; 8 Output
dw cmd_output ; 9 Output with verify
dw cmd_unknown ; 10 output status (char)
dw cmd_unknown ; 11 output flush (char)
dw cmd_unknown ; 12 IOCTL output
dw cmd_open ; 13 Open device
dw cmd_close ; 14 Close device
dw cmd_removable ; 15 Removable media check
if CAPABLE and C_GIOCTL
dw cmd_unknown ; 16 Output untill busy (char)
dw cmd_unknown ; 17
dw cmd_unknown ; 18
dw cmd_GIOCTL ; 19 Generic IOCTL
dw cmd_unknown ; 20
dw cmd_unknown ; 21
dw cmd_unknown ; 22
dw cmd_getLogical ; 23
dw cmd_setLogical ; 24
endif
high_cmd db ($-offset command_tbl)/2 ; Number of supported commands
;**************************************************************************
;
; Batch transfer of sectors
;
; This transfers sectors according to the parameters passed on stack
; even if the sectors are on different drivers chained to this one.
;
; Returns how many sectors were NOT moved; ax = 0 means all OK.
;
; !!! This function destroys the contents of DS !!!
;
;**************************************************************************
batch_xfer proc C far
arg buffer:far ptr, sector:dword, count:word, RW:word
local byteoffset:dword, bytes:word
debug 'o',<word ptr buffer>
debug 's',<word ptr buffer+2>
if CAPABLE and C_GIOCTL
test RW,-1 ; Writing boot sector?
jz batch_notboot
mov ax,word ptr sector
or ax,word ptr sector+2
jnz batch_notboot
mov ds,word ptr buffer+2
assume ds:nothing
mov si,word ptr buffer
add si,bsBytesPerSec
mov ax,[si]
cmp ax,conf.c_BPB_bps
jnz batch_notboot
push cs ; Copy new BPS to conf
pop es
mov di,offset conf.c_BPB_bps
mov cx,25
rep movsb
mov conf.c_media_change,0 ; Tell do not know if changed
batch_notboot:
endif
push cs
pop ds
mov si,offset conf
; DS:SI - conf of current driver (main here)
assume ds:nothing
batch_next_driver:
; Transfer sector to byte offset to disk and count the
; number of bytes to xfer.
mov ax,word ptr sector
mov dx,word ptr sector+2
mov cx,count
debug 'a',ax
debug 'd',dx
debug 'c',cx
cmp ax,[si].c_sectorsl ; Starting sector on disk?
sbb dx,[si].c_sectorsh
mov dx,word ptr sector+2
jae batch_to_next ; No
add ax,cx ; Count ending sector
adc dx,0
cmp dx,[si].c_sectorsh ; Ending sector on disk?
jb batch_IO1 ; Jump if is
sub ax,[si].c_sectorsl
jbe batch_IO1 ; Jump if is
sub cx,ax ; Count how many we CAN transfer
debug 'T',cx
batch_IO1:
push cx
mov ax,cx ; Count number of bytes to move
;mul [si].c_BPB_bps
mov cl,[si].c_bps_shift
sal ax,cl
mov word ptr bytes,ax ; Number of bytes to move
mov ax,word ptr sector+2 ; Count starting byte
;mul [si].c_BPB_bps
sal ax,cl
mov cx,ax
mov ax,word ptr sector
mul [si].c_BPB_bps
add dx,cx ; dx:ax is starting byte
mov word ptr byteoffset,ax
mov word ptr byteoffset+2,dx
call dword ptr [si].c_disk_IO
pop ax ; Pop number of sectors
jc batch_IOx ; I/O error
sub count,ax ; All transferred?
jbe batch_done ; yes, so exit
if CAPABLE and C_APPENDED
debug 'N',ax
push ax
;mul [si].c_BPB_bps ; Increment transfer offset
mov cl,[si].c_bps_shift
sal ax,cl
add word ptr buffer,ax ; which can not exceed 0FFFFh
pop ax
xor dx,dx
add ax,word ptr sector ; Count new starting sector
adc dx,word ptr sector+2
batch_to_next:
sub ax,[si].c_sectorsl ; Subtract passed sectors
sbb dx,[si].c_sectorsh
mov word ptr sector,ax ; And store the result
mov word ptr sector+2,dx
mov si,[si].c_next ; Find next driver
or si,si
mov ds,si
mov si,ds:dr_conf
jz batch_err
jmp batch_next_driver
else ;if CAPABLE and C_APPENDED
batch_to_next:
endif ;if CAPABLE and C_APPENDED
batch_err:
; there is no next driver - sectors not found!
debug 'E',count
stc
jmp batch_IOx
batch_done:
clc
batch_IOx:
mov ax,count
ret
assume ds:d_seg
batch_xfer endp
;**************************************************************************
;
; Set request header address
;
; Called by DOS to set the request structure pointer
;
;**************************************************************************
strategy proc far
mov word ptr cs:req_ptr,bx
mov word ptr cs:req_ptr+2,es
ret
strategy endp
;**************************************************************************
;
; Commands
;
; Called by DOS. Requested action defined in structure pointed by req_ptr.
;
;**************************************************************************
commands proc far
assume ds:nothing
pushf
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
ifdef STACKSIZE
; Switch into our own stack
mov caller_ss,ss
mov caller_sp,sp
push cs
pop ss
mov sp,end_of_resident
endif
if DEBUGGING
push bp
mov bp,sp
endif
cld
lds si,req_ptr
assume ds:nothing
; We trust Microsoft that the unit is right at [si].rhUnit
mov cx,[si].rwrBytesSec ; Sectors/Cmd line/BPB pointer
mov dx,[si].rwrStartSec ; Start sector/Device number
mov bl,[si].rhFunction
xor bh,bh ; Count index to command_tbl
debug 'F',bx
cmp bl,high_cmd ; Is command supported?
jae cmd_unknown ; Jump if not
shl bx,1
les di,[si].rwrBuffer ; ES:DI = transfer address
push cs
pop ds ; DS to local data segment
assume ds:d_seg
jmp command_tbl[bx] ; Do command
cmd_unknown:
assume ds:nothing
mov ax,ERROR or UNKNOWN_COMMAND
jmp cmd_ret
cmd_IOerr:
lds bx,req_ptr
mov [bx].rwrBytesSec,0 ; Sector count zero
cmd_error:
mov ah,HIGH (ERROR OR DONE) ; ERROR and DONE (err #, in al)
jmp cmd_ret
cmd_ok:
mov ax,DONE
cmd_ret:
debug 'Q',ax
lds bx,req_ptr
mov [bx].rhStatus,ax
if DEBUGGING
cmp bp,sp
je dbstack1
debug '/',sp
debug '/',bp
dbstack1:
mov sp,bp
pop bp
endif
ifdef STACKSIZE
; Switch back into callers stack
mov ss,caller_ss
mov sp,caller_sp
; cmp stack_check,STACK_CHECK_ID
; je cmd_stack_ok
;report error
;cmd_stack_ok:
endif
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
retf ; Return far
assume ds:d_seg
commands endp
;**************************************************************************
;
; Media Check command
;
;**************************************************************************
cmd_media proc near
les bx,req_ptr
mov al,conf.c_media_change ; Read the change return
debug 'C',ax
test conf.c_RW_access,READ_ACCESS
jz dev_not_ready
mov es:[bx].mrReturn,al
mov word ptr es:[bx].mrVolumeID,offset dr_volume
mov word ptr es:[bx].mrVolumeID+2,cs
jmp cmd_ok
dev_not_ready:
mov al,DRIVE_NOT_READY
jmp cmd_error
cmd_media endp
;**************************************************************************
;
; Build BPB command
;
;**************************************************************************
cmd_BPB proc near
debug 'B',<conf.c_RW_access>
test conf.c_RW_access,READ_ACCESS
jz dev_not_ready
les bx,req_ptr
mov word ptr es:[bx].bbrBPBAddress,offset BPB
mov word ptr es:[bx].bbrBPBAddress+2,cs
mov conf.c_open_files,0 ; Reset open files to 0
mov conf.c_media_change,1 ; Media no longer changed
jmp cmd_ok
cmd_BPB endp
;**************************************************************************
;
; Device Open command
;
;**************************************************************************
cmd_open proc near
debug 'O',-1
inc conf.c_open_files
jmp cmd_ok
cmd_open endp
;**************************************************************************
;
; Device Close command
;
;**************************************************************************
cmd_close proc near
cmp conf.c_open_files,0
jz cmd_close1
dec conf.c_open_files
cmd_close1:
jmp cmd_ok
cmd_close endp
;**************************************************************************
;
; Removable media query
;
;**************************************************************************
cmd_removable proc near
mov ax,DONE
test conf.c_RW_access,4
jz cmd_removable_x
or ax,BUSY
cmd_removable_x:
jmp cmd_ret
cmd_removable endp
;**************************************************************************
;
; INPUT command
;
;**************************************************************************
cmd_input proc near
debug 'R',0
test conf.c_RW_access,READ_ACCESS
jz cmd_input1
xor bl,bl
push bx ; Last parameter to batch_xfer
jmp cmd_io
cmd_input1:
mov al,DRIVE_NOT_READY
jmp cmd_IOerr
cmd_input endp
;**************************************************************************
;
; OUTPUT command
;
;**************************************************************************
cmd_output proc near
debug 'W',0
mov al,WRITE_PROTECT
mov bl,1
test conf.c_RW_access,WRITE_ACCESS
jnz to_cmd_io
jmp cmd_outerr
to_cmd_io: push bx ; Last parameter to batch_xfer
cmd_io:
; CX - sectors
; ES:DI - transfer address
; DS = CS
mov ax,cx ; Count number of bytes to move
mul conf.c_BPB_bps
jc cmd_output4 ; Is it too much? (dx != 0)
; check transfer address and count that they do not
; exceed segment limit
add ax,di ; (dx = 0 after the mul)
jnc cmd_output5
cmd_output4:
mov ax,di ; How many bytes CAN we move?
xor ax,-1
;xor dx,dx ; How many sectors?
;div conf.c_BPB_bps
mov cl,conf.c_bps_shift
shr ax,cl
mov cx,ax
cmd_output5:
push cx ; count parameter to batch_xfer
; mov cx,es
; les si,req_ptr
; mov es:[si].rwrBytesSec,dx ; Xferred 0 sectors so far
; cmp es:[si].rwrLength,1Ah ; Do we use 32-bit sec. address?
; jbe cmd_output3
; debug '3',0
; push word ptr es:[si].rwrHugeStartSec+2
; push word ptr es:[si].rwrHugeStartSec
; jmp cmd_output8
;cmd_output3:
; xor dx,dx ; 16 bit sector parameter
; push dx ; to batch_xfer
; push es:[si].rwrStartSec
mov cx,es
les si,req_ptr
mov ax,es:[si].rwrStartSec
cmp ax,-1
jne cmd_output3
debug '3',0
push word ptr es:[si].rwrHugeStartSec+2
push word ptr es:[si].rwrHugeStartSec
jmp cmd_output8
cmd_output3:
xor dx,dx ; 16 bit sector parameter
push dx ; to batch_xfer
push ax
cmd_output8:
push cx ; buffer parameter to batch_xfer
push di
call batch_xfer
assume ds:nothing
jc cmd_output1
add sp,12
les si,cs:req_ptr
sub es:[si].rwrBytesSec,ax ; actually transferred
cmd_output6:
jmp cmd_ok
cmd_output1:
add sp,12
debug 'S',ax
mov al,SECTOR_NOT_FOUND
cmd_outerr:
jmp cmd_IOerr
assume ds:d_seg
cmd_output endp
if 0
;**************************************************************************
;
; IOCTL write
;
; This function is used to switch to "inside DOS" and avoid some
; multitaskin memory manager problems. We hope that the multitasker does
; not free the memory if it is allocated here.
;
; The actual service routine is located in the caller at the address
; where the data location is. Data size must be IOCTL_ID.
;
;**************************************************************************
cmd_IOCTL_write proc near
debug 'i',cx
cmp cx,IOCTL_ID ; cx is the count
je cmd_iow1
jmp cmd_unknown
cmd_iow1:
lds si,req_ptr
assume ds:nothing
call [si].irwrBuffer
jmp cmd_ok
assume ds:d_seg
cmd_IOCTL_write endp
endif
;**************************************************************************
;
; MULTIPLEX server
;
;**************************************************************************
multiplex proc far
cmp ah,MULTIPLEXAH
jne mplex_old
cmp al,0
jz mplex_installed
push cs ; Tell our segment
pop es
mplex_installed:
mov al,-1 ; Tell we are installed
iret
mplex_old:
jmp cs:old_multiplex
multiplex endp
;**************************************************************************
;
; GENERIC IOCTL
;
;**************************************************************************
if CAPABLE and C_GIOCTL
ifdef STACKSIZE
noGIOCTL_eor equ offset $ + STACKSIZE ; End of resident when no GIOCTL
; but when we have stack!
else
noGIOCTL_eor equ offset $ ; End of resident when GIOCTL not supported
endif
GIOCTL_MEDIA equ FALSE ; If true, MID info is handled
if GIOCTL_MEDIA
media_ID MID <0, 12345678h, "SRDISK ", "FAT12 ">
endif
gioctl_func_s struc
gioctl_fcode db ?
gioctl_faddr dw ?
gioctl_func_s ends
gioctl_func gioctl_func_s <41h, offset gioctl_write>
gioctl_func_s <60h, offset gioctl_getparam>
gioctl_func_s <61h, offset gioctl_read>
gioctl_func_s <42h, offset cmd_ok> ; Format
gioctl_func_s <62h, offset cmd_ok> ; Verify
; gioctl_func_s <40h, offset gioctl_setparam>
if GIOCTL_MEDIA
gioctl_func_s <46h, offset gioctl_setmedia>
gioctl_func_s <66h, offset gioctl_getmedia>
endif
gioctl_func_end label byte
cmd_GIOCTL proc near
les si,req_ptr
cmp es:[si].giCategory,8
jnz cmd_gioerr1
mov al,es:[si].giMinorCode
debug 'G',ax
les si,es:[si].giIOCTLData ; Parameter block
mov bx,offset gioctl_func
cmd_gionfunc:
cmp [bx].gioctl_fcode,al
je cmd_giodofunc
add bx,type gioctl_func_s
cmp bx,offset gioctl_func_end
jb cmd_gionfunc
cmd_gioerr1:
jmp cmd_unknown
cmd_giodofunc:
jmp [bx].gioctl_faddr ; Call with ES:SI -> param block
gioctl_dev_not_ready:
mov al,DRIVE_NOT_READY
jmp cmd_error
cmd_GIOCTL endp
;******** GIOCTL write (41h)
gioctl_write proc near
test conf.c_RW_access,WRITE_ACCESS
jz gioctl_write_prot
mov al,1
push ax ; RW parameter to batch_xfer
jmp track_xfer
gioctl_write_prot:
mov al,WRITE_PROTECT
jmp cmd_error
gioctl_write endp
;******** GIOCTL read (61h)
gioctl_read proc near
test conf.c_RW_access,READ_ACCESS
jz gioctl_dev_not_ready
mov al,0
push ax ; RW parameter to batch_xfer
track_xfer:
; !!!! Expects c_BPB_heads * cylinders
; and c_BPB_heads * c_BPB_spt less than 65536
push es:[si].rwSectors
mov ax,es:[si].rwCylinder
mul conf.c_BPB_heads
mul conf.c_BPB_spt
mov bx,ax
mov cx,dx
mov ax,es:[si].rwHead
mul conf.c_BPB_spt
add ax,es:[si].rwFirstSector
add ax,bx
adc dx,cx
push dx ; absolute sector
push ax
push word ptr es:[si].rwBuffer+2 ; transfer address
push word ptr es:[si].rwBuffer
call batch_xfer ; Destroys DS
add sp,12
jc track_xfer_IOerr
jmp cmd_ok
track_xfer_IOerr:
mov al,SECTOR_NOT_FOUND
jmp cmd_error
gioctl_read endp
;******** GIOCTL set parameters (40h)
if 0
gioctl_setparam proc near
; test conf.c_RW_access,READ_ACCESS ; !!!! Is this needed?
; jz gioctl_dev_not_ready
debug '0',<word ptr es:[si]>
debug '2',<word ptr es:[si+2]>
debug '4',<word ptr es:[si+4]>
debug '6',<word ptr es:[si+6]>
debug 'R',<word ptr es:[si].dpRootDirEnts>
debug 'S',<word ptr es:[si].dpSectors> ; Sectors
debug 'M',<word ptr es:[si].dpMedia> ; Media
; test byte ptr es:[si].dpSpecFunc,3 ; Change format?
; jnz gioctl_bad_media
; jmp cmd_ok
gioctl_bad_media:
mov al,UNKNOWN_MEDIA
jmp cmd_error
gioctl_setparam endp
endif
;******** GIOCTL get parameters (60h)
gioctl_getparam proc near
; test conf.c_RW_access,READ_ACCESS ; !!!! Is this needed?
; jz gioctl_dev_not_ready
push ds
push es
pop ds
assume ds:nothing
; Tell that we return info about current medium
; mov [si].dpSpecFunc,GETDPSF_CURRENT
mov al,conf.c_device_type
mov [si].dpDevType,al
mov [si].dpDevAttr,0 ; bit 0 Removable, bit 1 no change line
mov ax,conf.c_BPB_heads
mul conf.c_BPB_spt ; Implicit dx = 0
mov cx,ax
mov ax,conf.c_BPB_sectors
or ax,ax
jnz gioctl_gp16bit
mov ax,conf.c_BPB_tsectorsl ; 32-bit disk
mov dx,conf.c_BPB_tsectorsh
gioctl_gp16bit:
div cx
mov [si].dpCylinders,ax
mov [si].dpMediaType,0 ; Normal media
pop ds
assume ds:d_seg
mov di,si
mov si,offset conf.c_BPB_bps ; ds:si -> current BPB
add di,7 ; es:di -> Device Params BPB
mov cx,25
rep movsb ; Copy BPB
jmp cmd_ok