1 TITLE IO
.SYS for the ALTOS ACS
-86C
.
3 ; I/O system for Version 2.x of MSDOS.
5 ;This BIOS designed to be linked with the SYSINIT module provided by
8 BIOSIZ EQU
4096 ;Size of BIOS in bytes.
9 BIOSIZS EQU 100H
;Size of BIOS in Paragraphs.
10 ANSI EQU
0 ;Ansi switch.
12 ;Additional Information for the ALTOS machine.
14 QSIZE EQU
100 ;Input queue size.
15 BIOSSEG EQU
0C0H ;I/O system segment.
16 MAX_MEM EQU 4000H
;Memory size in paragraphs.
18 ; Constants for commands in Altos ROM.
20 ROM_CONSTA EQU
01 ;Return status AL of console selected in CX.
21 ROM_CONIN EQU
02 ;Get char. from console in CX to AL
22 ROM_CONOUT EQU
03 ;Write char. in DL to console in CX.
23 ROM_PMSG EQU
07 ;Write string ES:DX to console in CX.
24 ROM_DISKIO EQU
08 ;Perform disk I/O from IOPB in ES:CX.
25 ROM_INIT EQU
10 ;Returns boot console and top memory ES:DX.
27 ;Things needed to communicate with SYSINIT
29 EXTRN SYSINIT
:FAR ;The entry point of SYSINIT
30 EXTRN CURRENT_DOS_LOCATION
:WORD ;Where the DOS is when SYSINIT called
31 EXTRN FINAL_DOS_LOCATION
:WORD ;Where I want SYSINIT to put the DOS
32 EXTRN DEVICE_LIST
:DWORD ;Pointer to the DEVICE list.
33 EXTRN MEMORY_SIZE
:WORD ;Size in paragraphs of Physical memory.
34 EXTRN DEFAULT_DRIVE
:BYTE ;Default Drive to use when system booted
35 EXTRN BUFFERS
:BYTE ;Number of default buffers.
36 ; Leave as is and SYSINIT uses only 2.
39 ASSUME
CS:CODE,DS:CODE,ES:CODE,SS:CODE
41 ORG 0 ;Starts at an offset of zero.
47 SUBTTL Device driver tables
.
49 ;-----------------------------------------------+
50 ; DWORD pointer to next device | 1 word offset.
51 ; (-1,-1 if last device) | 1 word segement.
52 ;-----------------------------------------------+
53 ; Device attribute WORD ; 1 word.
54 ; Bit 15 = 1 for chacter devices. ;
55 ; 0 for Block devices. ;
57 ; Charcter devices. (Bit 15=1) ;
58 ; Bit 0 = 1 current sti device. ;
59 ; Bit 1 = 1 current sto device. ;
60 ; Bit 2 = 1 current NUL device. ;
61 ; Bit 3 = 1 current Clock device. ;
63 ; Bit 13 = 1 for non IBM machines. ;
64 ; 0 for IBM machines only. ;
65 ; Bit 14 = 1 IOCTL control bit. ;
66 ;-----------------------------------------------+
67 ; Device strategy pointer. ; 1 word offset.
68 ;-----------------------------------------------+
69 ; Device interrupt pointer. ; 1 word offset.
70 ;-----------------------------------------------+
71 ; Device name field. ; 8 bytes.
72 ; Character devices are any valid name ;
73 ; left justified, in a space filled ;
75 ; Block devices contain # of units in ;
77 ;-----------------------------------------------+
80 CONDEV: ;Header for device CON
81 DW AUXDEV
,BIOSSEG
;Link to next device
82 DW 8003H
;Attributes - console input, output device
83 DW STRATEGY
;Srategy entry point
84 DW CON_INT
;Interrupt entry point
85 DB "CON " ;Device name
87 AUXDEV: ;Header for device AUX
94 PRNDEV: ;Header for device PRN
101 TIMDEV: ;Header for device CLOCK
108 DSKDEV: ;Header for disk devices
109 DW -1,-1 ;Last device
110 DW 2000H
;Is a block device
113 DRVMAX
DB 1 ;Number of Units
117 SUBTTL Dispatch tables for each device
.
119 DSKTBL: DW DSK_INIT
;0 - Initialize Driver.
120 DW MEDIAC
;1 - Return current media code.
121 DW GET_BPB
;2 - Get Bios Parameter Block.
122 DW CMDERR
;3 - Reserved. (currently returns error)
123 DW DSK_RED
;4 - Block read.
124 DW BUS_EXIT
;5 - (Not used, return busy flag)
125 DW EXIT
;6 - Return status. (Not used)
126 DW EXIT
;7 - Flush input buffer. (Not used.)
127 DW DSK_WRT
;8 - Block write.
128 DW DSK_WRV
;9 - Block write with verify.
129 DW EXIT
;10 - Return output status.
130 DW EXIT
;11 - Flush output buffer. (Not used.)
131 DW EXIT
;12 - IO Control.
133 CONTBL: DW EXIT
;0 - Init. (Not used)
134 DW EXIT
;1 - Media check (Not used)
135 DW EXIT
;2 - Get Bios Parameter Block (Not used)
136 DW CMDERR
;3 - Reserved. (Currently returns error)
137 DW CON_READ
;4 - Character read. (Destructive)
138 DW CON_RDND
;5 - Character read. (Non-destructive)
139 DW EXIT
;6 - Return status. (Not used)
140 DW CON_FLSH
;7 - Flush Input buffer.
141 DW CON_WRIT
;8 - Character write.
142 DW CON_WRIT
;9 - Character write with Verify.
143 DW CON_WRST
;10 - Character write status.
144 DW EXIT
;11 - Flush output buffer. (Not used.)
145 DW EXIT
;12 - IO Control.
147 AUXTBL: DW EXIT
;0 - Init. (Not used)
148 DW EXIT
;1 - Media check (Not used)
149 DW EXIT
;2 - Get Bios Parameter Block (Not used)
150 DW CMDERR
;3 - Reserved. (Returns an error)
151 DW AUX_READ
;4 - Character read. (Destructive)
152 DW AUX_RDND
;5 - Character read. (Non-destructive)
153 DW EXIT
;6 - Return status. (Not used)
154 DW AUX_CLR
;7 - Flush Input buffer.
155 DW AUX_WRIT
;8 - Character write.
156 DW AUX_WRIT
;9 - Character write with verify.
157 DW AUX_WRST
;10 - Character write status.
158 DW EXIT
;11 - Flush output buffer. (Not used.)
159 DW EXIT
;12 - IO Control.
161 TIMTBL: DW EXIT
;0 - Init. (Not used)
162 DW EXIT
;1 - Media check (Not used)
163 DW EXIT
;2 - Get Bios Parameter Block (Not used)
164 DW CMDERR
;3 - Reserved. (Currently returns an error)
165 DW TIM_RED
;4 - Character read. (Destructive)
166 DW BUS_EXIT
;5 - (Not used, returns busy flag.)
167 DW EXIT
;6 - Return status. (Not used)
168 DW EXIT
;7 - Flush Input buffer. (Not used)
169 DW TIM_WRT
;8 - Character write.
170 DW TIM_WRT
;9 - Character write with verify.
171 DW EXIT
;10 - Character write status. (Not used)
172 DW EXIT
;11 - Flush output buffer. (Not used)
173 DW EXIT
;12 - IO Control.
175 PRNTBL: DW EXIT
;0 - (Not used)
176 DW EXIT
;1 - (Not used)
177 DW EXIT
;2 - Block (Not used)
178 DW CMDERR
;3 - Reserved. (currently returns error)
179 DW EXIT
;4 - (Not used)
180 DW BUS_EXIT
;5 - (Not used, returns busy flag.)
181 DW EXIT
;6 - (Not used)
182 DW EXIT
;7 - (Not used)
183 DW PRN_WRT
;8 - Character write.
184 DW PRN_WRT
;9 - Character write with verify.
185 DW PRN_STA
;10 - Character write status.
186 DW EXIT
;11 - (Not used.)
187 DW EXIT
;12 - IO Control.
190 SUBTTL Strategy
and Software Interrupt routines
.
192 ;Define offsets for io data packet
195 CMDLEN
DB ?
;LENGTH OF THIS COMMAND
196 UNIT
DB ?
;SUB UNIT SPECIFIER
197 CMD
DB ?
;COMMAND CODE
200 MEDIA
DB ?
;MEDIA DESCRIPTOR
201 TRANS
DD ?
;TRANSFER ADDRESS
202 COUNT
DW ?
;COUNT OF BLOCKS OR CHARACTERS
203 START
DW ?
;FIRST BLOCK TO TRANSFER
206 PTRSAV
DD 0 ;Strategy pointer save.
209 ; Simplistic Strategy routine for non-multi-Tasking system.
211 ; Currently just saves I/O packet pointers in PTRSAV for
212 ; later processing by the individual interrupt routines.
218 MOV WORD PTR CS:[PTRSAV
],BX
219 MOV WORD PTR CS:[PTRSAV
+2],ES
225 ; Console interrupt routine for processing I/O packets.
234 ; Auxilary interrupt routine for processing I/O packets.
243 ; Printer interrupt routine for processing I/O packets.
252 ; Clock interrupt routine for processing I/O packets.
261 ; Disk interrupt routine for processing I/O packets.
269 ; Common program for handling the simplistic I/O packet
270 ; processing scheme in MSDOS 2.0
273 ENTRY: PUSH AX ;Save all nessacary registers.
282 LDS BX,CS:[PTRSAV
] ;Retrieve pointer to I/O Packet.
284 MOV AL,[BX.UNIT
] ;AL = Unit code.
285 MOV AH,[BX.MEDIA
] ;AH = Media descriptor.
286 MOV CX,[BX.COUNT
] ;CX = Contains byte/sector count.
287 MOV DX,[BX.START
] ;DX = Starting Logical sector.
289 XCHG DI,AX ;Move Unit & Media into DI temporarily.
290 MOV AL,[BX.CMD
] ;Retrieve Command type. (1 => 11)
291 XOR AH,AH ;Clear upper half of AX for calculation.
292 ADD SI,AX ;Compute entry pointer in dispatch table.
294 CMP AL,11 ;Verify that not more than 11 commands.
295 JA CMDERR
;Ah, well, error out.
296 XCHG AX,DI ;Move Unit & Media back where they belong.
297 LES DI,[BX.TRANS
] ;DI contains addess of Transfer address.
298 ;ES contains segment.
300 POP DS ;Data segment same as Code segment.
301 JMP [SI] ;Perform I/O packet command.
304 SUBTTL
Common error
and exit points
.
306 BUS_EXIT: ;Device busy exit.
307 MOV AH,00000011B ;Set busy and done bits.
310 CMDERR: MOV AL,3 ;Set unknown command error #.
313 ; Common error processing routine.
314 ; AL contains actual error code.
316 ; Error # 0 = Write Protect violation.
318 ; 2 = Drive not ready.
319 ; 3 = Unknown command in I/O packet.
321 ; 5 = Bad drive request structure length.
323 ; 7 = Unknown media discovered.
324 ; 8 = Sector not found.
325 ; 9 = Printer out of paper.
328 ; 12 = General failure.
332 MOV AH,10000001B ;Set error and done bits.
333 STC ;Set carry bit also.
334 JMP SHORT EXIT1
;Quick way out.
336 EXITP PROC
FAR ;Normal exit for device drivers.
338 EXIT: MOV AH,00000001B ;Set done bit for MSDOS.
339 EXIT1: LDS BX,CS:[PTRSAV
]
340 MOV [BX.STATUS
],AX ;Save operation compete and status.
342 POP BX ;Restore registers.
351 RET ;RESTORE REGS AND RETURN
355 SUBTTL Main
console I
/O
section.
361 CHAR
DB ?
;Small typeahead buffer for now.
364 ; Console keyboard handler.
367 CISTAT: PUSH CX ;Save CX pair.
370 JNZ CISTA9
;Character still in buffer.
371 CISTA1: MOV BX,ROM_CONSTA
373 CALL ROM_CALL
;See if character waiting.
378 CALL ROM_CALL
;Get character from Rom.
380 JZ CISTA1
;Got a null character.
382 CISTA9: POP CX ;Can't lose CX pair.
386 ; Get a character from the buffer queue.
389 CINP: CALL CISTAT
;Check for character ready in queue.
390 JZ CINP
;Cycle until one ready.
391 MOV [CHAR
],0 ;We have character in AL, clear type a head.
395 ; Console read non-destructive.
399 CALL CISTAT
;See if character ready.
400 JZ CON_RDN2
;No, return busy signal.
409 ; Console destructive read.
413 CALL CINP
;Get character.
414 STOSB ;Save it in users buffer.
415 LOOP CON_READ
;Loop until CX is exhausted.
419 ; Console flush routine. (ctrl-c, ctrl-f, or ctrl-s inspired)
423 MOV [CHAR
],0 ;Clear small type a head buffer.
427 ; Console output status routine.
431 JMP EXIT
;Yes, normal exit.
434 ; Console output routine.
438 MOV SI,DI ;Get destination to source.
440 LODS BYTE PTR ES:[SI]
443 CALL CONOUT
;Call ansi driver.
449 LOOP CON_WRI1
;Keep going until user buffer through.
453 ; Console character output routine.
456 OUTCHR: MOV BX,ROM_CONOUT
457 MOV CX,[MCON
] ;Get current console port.
466 SUBTTL ANSI interface
section.
469 ;ANSI Info and routines. ANSI driver implemented as a finite state automata
470 ;This ANSI driver translates the ANSI standard escape sequences into the
471 ; Zenith Escape sequences used on the Zenith(Heath) Z(H)-19 terminal.
472 ;This is not a full implementation of ANSI, but rather a minimal implementation
473 ; which implements all of the necessary ANSI functions.
476 ESC EQU 1
BH ;Escape character used in this implementation.
477 STATE
DW ST1 ;Current ANSI character state.
478 PRMPNT
DW PARMS
;Current parameter pointer.
479 PARMS
DB 0,0,0,0,0,0,0 ;Allow for up to eight parameters.
480 LASTPRM
DB 0 ;With this being the eight one.
482 CMDTABL
DB 'A' ;Cursor up. "esc","[",#,"A"
484 DB 'B' ;Cursor down. "esc","[",#,"B"
486 DB 'C' ;Cursor forward. "esc","[",#,"C"
488 DB 'D' ;Cursor back. "esc","[",#,"D"
490 DB 'H' ;Direct cursor posit. "esc","[",x,y,"H"
492 DB 'J' ;Erase. "esc","[",code,"J"
494 DB 'K' ;Erase in line. "esc","[",code,"K"
496 DB 'f' ;Direct cursor posit. "esc","[",x,y,"f"
498 DB 'm' ;Special video mode. "esc","[",code,"m"
500 DB 's' ;Save cursor posit. "esc","[","s"
502 DB 'u' ;Move cursor to saved. "esc","[","u"
507 ; ANSI console output driver.
510 CONOUT: MOV DI,OFFSET STATE
;Retrieve current ansi state.
511 JMP [DI] ;Jump to it.
515 ; Looks for an Escape character.
518 ST1: CMP AL,ESC
;See if this the first character is ESC.
519 JNZ OUTCHR
;No, treat as regular character output.
520 MOV WORD PTR [DI],OFFSET
ST2 ;Yes, setup state two.
525 ; Looks for the "[" character.
528 ST2: CMP AL,'[' ;See if a valide state two.
529 JNZ OUTCHR
;No, treat as regular charcter
530 MOV BX,OFFSET PARMS
;Yes, get parameter pointer.
531 MOV WORD PTR [PRMPNT
],BX ;Setup in pointer index.
532 MOV WORD PTR [BX],0 ;Clear first entry.
533 MOV WORD PTR [DI],OFFSET
ST3;Setup for state three.
538 ; Entered one or more times for parameter passing.
541 ST3: CMP AL,';' ;Look for decimal # seperator.
542 JNZ ST3A
;No check phase A.
543 INC WORD PTR [PRMPNT
] ;Yes, incr. pointer to next param.
544 MOV AX,OFFSET LASTPRM
;Check for outside parameter list.
546 JBE RETST3
;Yes, proceed with next parameter.
547 MOV [PRMPNT
],AX ;No, treat as extentsion to old.
548 RETST3: MOV DI,[PRMPNT
] ;Setup for next parameter.
549 MOV BYTE PTR [DI],0 ;Pre-Initialize it to zero.
553 ; State three A (3A).
554 ; Check for a ascii digit.
557 ST3A: CMP AL,'0' ;Check for ASCII digit.
558 JB ST3B
;No, check for seconday command character.
559 CMP AL,'9' ;Still checking for ASCII digit.
560 JA ST3B
;No, it must be a secondary.
561 SUB AL,'0' ;Convert to binary.
562 MOV DI,[PRMPNT
] ;Get the current parameter pointer.
563 XCHG [DI],AL ;Get existing #.
564 MOV AH,10 ;Scale by 10.
566 ADD [DI],AL ;Add to new digit.
570 ; State three B (3B).
571 ; Wasn't a ascii digit, so check for secondary command.
574 ST3B: MOV [DI],OFFSET
ST1 ;Preset STATE to state 1 just in case.
575 MOV DI,OFFSET PARMS
-1 ;Get pointer to start of parameters.
576 MOV [PRMPNT
],DI ;Save it in Parameter pointer.
577 MOV DI,OFFSET CMDTABL
-3 ;Get start of Secondary command table.
579 ST3B1: ADD DI,3 ;Update Command table pointer.
580 CMP BYTE PTR [DI],0 ;Check for end of table.
581 JNZ ST3B2
;No, continue processing.
582 JMP OUTCHR
;Yes, treat as regular character.
583 ST3B2: CMP AL,[DI] ;Check for valid. command.
584 JNZ ST3B1
;No, keep checking.
585 JMP [DI+1] ;Yes, transfer to that secondary command.
588 ; Get binary parameter from storage and return a one if = 0
591 GETONE: CALL GETPARM
;Get parameter form list.
592 OR AL,AL ;Verify for non-zero.
593 JNZ GETRET
;Good, then return to caller.
594 INC AL ;Bad, make it at least a one.
595 GETRET: CBW ;Sign extend AL.
596 MOV CX,AX ;Copy of it to CX.
599 GETPARM:INC WORD PTR [PRMPNT
] ;Increment parameter pointer.
600 GOTPARM:MOV DI,[PRMPNT
] ;Get parameter pointer.
601 MOV AL,[DI] ;Get parameter value.
605 ; Send escape, character sequence.
608 OUTESC: MOV AL,ESC
;Send escape character.
610 MOV AL,BL ;Send follow character.
614 ; Cursor Positioning routines.
617 CUU: MOV BL,'A' ;Cursor up.
619 CUD: MOV BL,'B' ;Cursor down.
621 CUF: MOV BL,'C' ;Cursor forward.
623 CUB: MOV BL,'D' ;Cursor back.
625 CURPOS: CALL GETONE
;Get number of positions to move into CX.
626 MOVCUR: CALL OUTESC
;Send escape, command characters.
627 LOOP MOVCUR
;Keep moving until done.
631 ; Direct cursor positioning routine.
634 CUP: CALL GETONE
;Get X position.
635 MOV DX,AX ;Save in DX.
636 CALL GETONE
;Get Y position.
638 CALL OUTESC
;Send escape, "Y" sequence.
640 ADD AL,' '-1 ;Convert binary to Character.
641 CALL OUTCHR
;Send X posit.
643 ADD AL,' '-1 ;Convert binary to Character.
644 JMP OUTCHR
;Send Y posit.
647 ; Erase all/part of screen.
650 ED: CALL GETPARM
;Get trinary command type.
652 DEC AL ;See if erase from begining of screen.
653 JZ ED1
;Yes, perform ZDS function.
655 DEC AL ;See if erase from end of screen.
656 JZ ED1
;Yes, perform ZDS function.
657 MOV BL,'J' ;Now we assume erase whole screen.
661 ; Erase all/part of a line.
664 EL: CALL GETPARM
;Get trinary command type.
666 DEC AL ;See if erase from begining of line.
667 JZ EL1
;Yes, perform ZDS function.
669 DEC AL ;See if erase whole line.
670 JZ EL1
;Yes, perform ZDS function.
671 MOV BL,'K' ;Now we assume erase to end of line.
675 ; Special video modes.
678 SGR: CALL GETPARM
;Get trinary command type.
680 CMP AL,7 ;See if enter reverse video mode.
681 JZ SGR2
;Yes, perform ZDS function.
683 OR AL,AL ;See if exit reverse video mode.
684 JNZ SGR3
;No, ignore.
689 ; Save / restore cursor position.
692 PSCP: MOV BL,'j' ;Set save cursor posit. mode.
695 PRCP: MOV BL,'k' ;Restore last cursor save.
702 SUBTTL Printer buffer handler
.
705 ; Printer status routine.
712 ; Printer write routine.
715 PRN_WRT:MOV SI,DI ;Set source = destination index.
717 PRN_WR1:LODS BYTE PTR ES:[SI];Get a data byte.
728 SUBTTL Auxilary I
/O routines
.
730 AUXCHAR
DB 0 ;Temporary AUX ahead storage.
733 ; Status routine for Auxilary port.
736 AISTAT: MOV AL,[AUXCHAR
]
738 JNZ AISTA9
;Character already waiting.
743 JZ AISTA9
;Still none waiting.
747 AISTA9: MOV [AUXCHAR
],AL
751 ; Auxilary port read.
754 AIN: CALL AISTAT
;Get status and/or char.
755 JZ AIN
;Cycle until one is ready.
760 ; Write routine for Auxilary port.
770 ; Non-Destructive Auxilary read routine.
774 CALL AISTAT
;Get status and copy of char. waiting if any.
775 JZ AUX_RDN2
;No character waiting, exit.
781 ; Destructive Auxilary read routine.
785 CALL AIN
;Get data character.
786 STOSB ;Save it through DI.
787 LOOP AUX_READ
;Cycle until user buffer full.
791 ; Auxilary clear type a head.
799 ; Auxilary write port status.
812 LODS BYTE PTR ES:[SI] ;Get char. from users buffer.
813 CALL AOUT
;Send it to device.
814 LOOP AUX_WRI1
;Cycle until all done.
818 SUBTTL Date
/Time Routines
.
820 TIM_DAYS: DB 2 DUP (?
) ;Number of days since 1-1-80.
821 TIM_MINS: DB ?
;Minutes.
822 TIM_HRS: DB ?
;Hours.
823 TIM_HSEC: DB ?
;Hundreths of a second.
824 TIM_SECS: DB ?
;Seconds.
827 ; Time write routine.
831 MOV SI,OFFSET TIM_DAYS
847 MOV SI,OFFSET TIM_DAYS
854 SUBTTL
8089 Monitor structure
.
857 ; Structure to reference 8089 and ROM command table.
861 DB 4 DUP (?
) ;Monitor Use Only
862 OPCODE
DB ?
;I/O operation code.
863 DRIVE
DB ?
;Logical drive spec.
864 TRACK
DW ?
;Logical track number.
865 HEAD
DB ?
;Logical head number.
866 SECTOR
DB ?
;Logical sector to start with.
867 SCOUNT
DB ?
;Number of logical sectors in buffer.
868 RETCODE
DB ?
;Error code after masking.
869 RETMASK
DB ?
;Error mask.
870 RETRIES
DB ?
;Number of retries before error exit.
871 DMAOFF
DW ?
;Buffer offset address.
872 DMASEG
DW ?
;Buffer segment.
873 SECLENG
DW ?
;Sector Length.
874 DB 6 DUP (?
) ;8089 use only.
877 IOPB SIOPB
<,00H,0,0,0,0,0,0,000H,0,0,0,0,>
884 ; MSDOS drive initialization tables and other what not.
887 ; Single sided, Single density, 77 track with 26
888 ; 128 byte sectors per track. One sector for
889 ; boot and header. (256,128 bytes free, old style).
891 ; Single sided, Single density, 77 track with 26
892 ; 128 byte sectors per track. Four sectors for
893 ; boot and header. (255,744 bytes free).
895 ; Single sided, Double Density, 75 track with 12
896 ; 512 byte sectors per track.
898 ; Two hidden single density tracks.
903 JMPNEAR
DB 3 DUP (?
) ;Jmp Near xxxx for boot.
904 NAMEVER
DB 8 DUP (?
) ;Name / Version of OS.
906 ;------- Start of Drive Parameter Block.
908 SECSIZE
DW ?
;Sector size in bytes. (dpb)
909 ALLOC
DB ?
;Number of sectors per alloc. block. (dpb)
910 RESSEC
DW ?
;Reserved sectors. (dpb)
911 FATS
DB ?
;Number of FAT's. (dpb)
912 MAXDIR
DW ?
;Number of root directory entries. (dpb)
913 SECTORS
DW ?
;Number of sectors per diskette. (dpb)
914 MEDIAID
DB ?
;Media byte ID. (dpb)
915 FATSEC
DW ?
;Number of FAT Sectors. (dpb)
917 ;------- End of Drive Parameter Block.
919 SECTRK
DW ?
;Number of Sectors per track.
923 LSDRIV1 DBP
<,,128,4,1,2,68,2002,0FEH,6,26>
925 LSDRIV2 DBP
<,,128,4,4,2,68,2002,0FDH,6,26>
927 LDDRIV1 DBP
<,,512,1,24,2,128,924,0F8H,3,12>
929 LDDRIV2 DBP
<,,1024,1,16,2,128,616,0F9H,1,8>
933 MOV SI,OFFSET INITTAB
939 DSTAT EQU 41H
;1793 status port.
940 DTRACK EQU 43H
;1793 track port.
941 DSECTOR EQU 45H
;1793 sector port.
942 DDATA EQU 47H
;1793 data I/O port.
944 DDENS EQU 55H
;Density select port.
945 DDBIT EQU
04H ;Density select bit.
946 DSELECT EQU 53H
;Drive select port.
949 DRVTAB
DB 0EH,0DH,0BH,07H
951 TRKTAB
DB -1,-1,-1,-1
955 SUBTTL Media check routine
958 ; Media check routine.
960 ; AL = disk unit number.
964 ; [MEDIA FLAG] = -1 (FF hex) if disk is changed.
965 ; [MEDIA FLAG] = 0 if don't know.
966 ; [MEDIA FLAG] = 1 if not changed.
968 ; [MEDIA] = 0FEH for Standard single density.
969 ; [MEDIA] = 0FDH for Altos single density.
970 ; [MEDIA] = 0F4H for Altos double density.
974 DB 13 DUP(?
) ;Static request header.
975 MEDIAS1
DB ?
;Media byte.
976 MEDIAS2
DB ?
;Media status byte flag.
980 AND AL,03H ;Clear any extraneous bits.
981 PUSH AX ;Save drive number requested.
982 MOV AL,0D0H ;Terminate with no interrupt.
984 AND AL,20H
;See if head load bit set.
986 JZ MEDIA2
;Head not loaded, so see if media changed.
987 MOV AH,1 ; AH = 1, disk not changed.
990 MEDIA1A:MOV [PREDENS
],DL ;Save last density used for read.
992 MEDIA1: LDS BX,[PTRSAV
] ;Udate media section of data block.
997 MEDIA2: CALL MEDIA4
;Unload head if selecting new drive.
998 MOV CX,2 ;Try each density once.
1000 XLAT ;Convert from drive # to select code.
1001 OUT DSELECT
,AL ;Select disk
1002 MOV AH,0 ;Assume that we don't know.
1003 MOV DL,[PREDENS
] ;Get last density.
1004 AND DL,DDBIT
;Be sure only Density bit set/clr.
1006 AND AL,0FBH ;Clear density bit.
1007 OR AL,DL ;Set/clear density bit.
1008 OUT DDENS
,AL ;Select density.
1009 MOV AL,0C4H ;READ ADDRESS command
1012 IN AL,DDATA
;Eat last byte to reset DRQ
1013 JZ MEDIA1A
;Jump if no error in reading address.
1014 MOV AH,0FFH ; AH = -1 (disk changed) if new density works.
1015 XOR DL,DDBIT
;Flip density bit.
1017 MOV AX,2 ;Couldn't read disk at all, AH = 0 for don't
1018 JMP ERR_EXIT
; know if disk changed, AL = error code 2 -
1020 MEDIA4: MOV AH,AL ;Save disk drive number in AH.
1021 XCHG AL,[CURDRV
] ;make new drive current, AL = previous
1022 CMP AL,AH ;Changing drives?
1023 JZ MEDIA5
;No, return to caller.
1025 ; If changing drives, unload head so the head load delay one-shot
1026 ; will fire again. Do it by seeking to same track with the H bit reset.
1028 IN AL,DTRACK
;Get current track number
1029 OUT DDATA
,AL ;Make it the track to seek to
1030 MOV AL,10H
;Seek and unload head
1032 MOV AL,AH ;Restore current drive number
1036 ; Short routine to send a command to 1793 diskette controller chip and
1037 ; wait for 1793 to complete the command.
1040 DCOM: OUT 41H
,AL ;Send command to 1793.
1042 DCOM1: LOOP DCOM1
;Wait a short time for 1793 to digest it.
1044 DCOM2: IN AL,41H
;Get 1793's status.
1045 AND AL,1 ;See if busy.
1046 JNZ DCOM2
;Yes, keep checking.
1047 IN AL,41H
;Get 1793's status for return
1051 SUBTTL Build
and return Bios Parameter Block for a diskette
.
1054 ; Build Bios Parameter Blocks.
1056 ; On entry: ES:DI contains the address of a scratch sector buffer.
1058 ; AH = Current media byte.
1060 ; On exit: Return a DWORD pointer to the associated BPB
1061 ; in the Request packet.
1065 DB 13 DUP(?
) ;Static request header.
1066 BPB1
DB ?
;Media byte.
1067 BPB2
DW ?
;DWORD transfer address.
1069 BPB3
DW ?
;DWORD pointer to BPB
1076 MOV [IOPB
.DMASEG
],ES
1077 MOV [IOPB
.DMAOFF
],DI
1078 MOV BYTE PTR[IOPB
.SECTOR
],1
1079 MOV BYTE PTR[IOPB
.SCOUNT
],1
1080 MOV BYTE PTR[IOPB
.OPCODE
],088H
1081 MOV BYTE PTR[IOPB
.RETRIES
],1
1082 MOV BYTE PTR[IOPB
.DRIVE
],0
1084 MOV BYTE PTR[IOPB
.HEAD
],1
1085 MOV BYTE PTR[IOPB
.RETMASK
],0DCH
1086 MOV [IOPB
.SECLENG
],128
1091 CALL ROM_CALL
;Read sector zero for information.
1096 MOV AH,[IOPB
.RETCODE
]
1098 JNZ GET_BP3
;Disk error, assume old single density.
1100 GET_BP1:MOV AL,ES:[DI.MEDIAID
] ;Get diskettes media ID.
1101 MOV SI,OFFSET LSDRIV2
1104 MOV SI,OFFSET LDDRIV1
1107 MOV SI,OFFSET LDDRIV2
1111 GET_BP3:MOV SI,OFFSET LSDRIV1
;No compares, assume old style for now.
1113 GET_BP4:MOV AL,[SI.MEDIAID
]
1114 ADD SI,11 ;Convert to DPB pointer
1116 GET_BP5:LDS BX,[PTRSAV
] ;Update I/O data packet.
1117 MOV [BX.BPB1
],AL ;Media byte.
1118 MOV [BX.BPB3
],SI ;DPB pointer.
1119 MOV [BX.BPB3
+2],CS ;Code segment.
1129 SUBTTL Disk I
/O equates
.
1133 ; --------------------------
1134 ; Hardware command def.
1135 ; --------------------------
1137 ; Read command = 88 hex.
1138 ; Write command = A8 hex.
1139 ; Format command = F0 hex.
1140 ; Seek command = 1E hex.
1141 ; Recal command = 0A hex.
1142 ; Set DD mode = 80 hex.
1144 ; --------------------------
1146 ; --------------------------
1149 ; (not used) = 02 hex.
1150 ; TK0(seek) = 04 hex.
1151 ; Lost Data = 04 hex.
1152 ; CRC error = 08 hex.
1153 ; Seek error = 10 hex.
1154 ; Not found = 10 hex.
1155 ; Write fault = 20 hex.
1156 ; Write protect = 40 hex.
1157 ; Not ready = 80 hex.
1159 ; --------------------------
1161 F_READ EQU
088H ;Floppy read command.
1162 F_WRIT EQU
0A8H ;Floppy write command.
1163 F_FMT EQU
0F0H ;Floppy format command.
1164 F_SEEK EQU
01EH ;Floppy seek command.
1165 F_RECAL EQU
00AH ;Floppy recal. command.
1166 F_DD EQU
080H ;Set Drive double density bit.
1169 SUBTTL MSDOS
2.x Disk I
/O drivers
.
1172 ; Disk READ/WRITE functions.
1175 ; AL = Disk I/O driver number
1177 ; ES = Disk transfer segment.
1178 ; DI = Disk transfer offset in ES.
1179 ; CX = Number of sectors to transfer
1180 ; DX = Logical starting sector.
1183 ; Normal exit through common exit routine.
1185 ; Abnormal exit through common error routine.
1189 MOV BX,0DC88H ;Set read mode and Error mask.
1192 DSK_WRT:MOV BX,0FCA8H ;Set write mode and Error mask.
1194 DSK_COM:MOV SI,OFFSET LSDRIV1
1197 MOV SI,OFFSET LSDRIV2
1200 MOV SI,OFFSET LDDRIV1
1203 MOV SI,OFFSET LDDRIV2
1209 DSK_CO2:OR AL,F_DD
;Set double density mode.
1211 DSK_CO3:MOV [IOPB
.DMASEG
],ES ;Setup Buffer segment.
1212 MOV [IOPB
.DMAOFF
],DI ;Setup buffer offset.
1213 MOV DI,[SI.SECSIZE
] ;Get sector size.
1214 MOV [IOPB
.SECLENG
],DI
1215 MOV [IOPB
.RETRIES
],1 ;Setup number of retries.
1216 MOV [IOPB
.RETMASK
],BH ;Operation error mask.
1217 MOV [IOPB
.OPCODE
],BL ;R/W opcode.
1218 MOV [IOPB
.DRIVE
],AL ;Drive with density select.
1219 MOV [IOPB
.HEAD
],1 ;Only one head on floppy drive.
1220 MOV BP,CX ;Save number of sectors to R/W
1221 DSK_CO4:PUSH DX ;Save starting sector.
1223 MOV DX,0 ;32 bit divide coming up.
1225 DIV CX ;Get track+head and start sector.
1227 MOV [IOPB
.SECTOR
],DL ;Starting sector.
1228 MOV BL,DL ;Save starting sector for later.
1229 MOV [IOPB
.TRACK
],AX ;Track to read/write.
1230 MOV AX,[SI.SECTRK
] ;Now see how many sectors
1231 INC AL ; we can burst read.
1232 SUB AL,BL ;BL is the starting sector.
1234 POP DX ;Retrieve logical sector start.
1235 CMP AX,BP ;See if on last partial track+head.
1236 JG DSK_CO5
;Yes, on last track+head.
1237 SUB BP,AX ;No, update number of sectors left.
1238 ADD DX,AX ;Update next starting sector.
1240 DSK_CO5:MOV AX,BP ;Only read enough of sector
1241 MOV BP,0 ;to finish buffer and clear # left.
1242 DSK_CO6:MOV [IOPB
.SCOUNT
],AL
1243 MOV DI,AX ;Save number sectors for later.
1248 CALL ROM_CALL
;Do disk operation.
1249 MOV AL,[IOPB
.RETCODE
] ;Get error code.
1252 MOV AX,DI ;Retrieve number of sectors read.
1253 MOV CX,[SI.SECSIZE
] ;Number of bytes per sector.
1257 TEST AL,0FH ;Make sure no strange sizes.
1258 JNZ DSK_CO7
;Illegal sector size found.
1260 SHR AX,CL ;Convert number of bytes to para.
1261 ADD AX,[IOPB
.DMASEG
]
1262 MOV [IOPB
.DMASEG
],AX
1264 JNZ DSK_CO4
;Still more to do.
1271 SUBTTL Disk Error processing
.
1274 ; Disk error routine.
1277 DERROR: LDS BX,CS:[PTRSAV
]
1284 MOV BH,14 ;Lenght of table.
1285 MOV SI,OFFSET DERRTAB
1286 DERROR2:INC BL ;Increment to next error code.
1287 LODS BYTE PTR CS:[SI]
1288 CMP AH,AL ;See if error code matches disk status.
1289 JZ DERROR3
;Got the right error, exit.
1291 JNZ DERROR2
;Keep checking table.
1292 MOV BL,12 ;Set general type of error.
1293 DERROR3:MOV AL,BL ;Now we've got the code.
1296 DERRTAB
DB 40H
; 0. Write protect error
1297 DB 00H ; 1. Unknown unit.
1298 DB 80H
; 2. Not ready error.
1299 DB 0FFH ; 3. Unknown command.
1300 DB 08H ; 4. CRC error
1301 DB 00H ; 5. Bad drive request.
1302 DB 02H ; 6. Seek error
1303 DB 00H ; 7. Unknown media.
1304 DB 10H
; 8. Sector not found
1305 DB 00H ; 9. (Not used.)
1306 DB 20H
;10. Write fault.
1307 DB 04H ;11. Read fault.
1308 DB 07H ;12. General type of failure.
1311 SUBTTL
Common ROM
call routine
.
1314 ; Save all registers except CX, BX and AX.
1316 ROMRTN
DD 0FE000000H ;Main ROM entry point.
1324 CALL CS:DWORD PTR [ROMRTN
]
1333 SUBTTL Initalization
code and temporary work areas
.
1336 ; Overlayed by MSDOS by SYSINIT.
1345 MOV SP,OFFSET WRKSTK
+98 ;Some nice area for stack.
1358 ASSUME
DS:SEG SYSINIT
1362 MOV DS:[CURRENT_DOS_LOCATION
],AX
1363 MOV DS:[MEMORY_SIZE
],MAX_MEM
1365 MOV WORD PTR DS:[DEVICE_LIST
+2],AX
1366 MOV WORD PTR DS:[DEVICE_LIST
],OFFSET DEVSTART
1368 ADD AX,((OFFSET WRKSTK
- OFFSET INIT
)+50) /16
1369 MOV DS:[FINAL_DOS_LOCATION
],AX