]> wirehaze git hosting - MS-DOS.git/blob - v2.0/source/SKELIO.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v2.0 / source / SKELIO.ASM
1 TITLE IO.SYS for the ALTOS ACS-86C.
2
3 ; I/O system for Version 2.x of MSDOS.
4
5 ;This BIOS designed to be linked with the SYSINIT module provided by
6 ;Microsoft
7
8 BIOSIZ EQU 4096 ;Size of BIOS in bytes.
9 BIOSIZS EQU 100H ;Size of BIOS in Paragraphs.
10 ANSI EQU 0 ;Ansi switch.
11
12 ;Additional Information for the ALTOS machine.
13
14 QSIZE EQU 100 ;Input queue size.
15 BIOSSEG EQU 0C0H ;I/O system segment.
16 MAX_MEM EQU 4000H ;Memory size in paragraphs.
17
18 ; Constants for commands in Altos ROM.
19
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.
26
27 ;Things needed to communicate with SYSINIT
28
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.
37
38 CODE SEGMENT
39 ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE
40
41 ORG 0 ;Starts at an offset of zero.
42
43 INIT: JMP HWINIT
44
45 PAGE
46
47 SUBTTL Device driver tables.
48
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. ;
56 ; ;
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. ;
62 ; ;
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 ;
74 ; field. ;
75 ; Block devices contain # of units in ;
76 ; the first byte. ;
77 ;-----------------------------------------------+
78
79 DEVSTART LABEL WORD
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
86
87 AUXDEV: ;Header for device AUX
88 DW PRNDEV,BIOSSEG
89 DW 8000H
90 DW STRATEGY
91 DW AUX_INT
92 DB "AUX "
93
94 PRNDEV: ;Header for device PRN
95 DW TIMDEV,BIOSSEG
96 DW 8000H
97 DW STRATEGY
98 DW PRN_INT
99 DB "PRN "
100
101 TIMDEV: ;Header for device CLOCK
102 DW DSKDEV,BIOSSEG
103 DW 8008H
104 DW STRATEGY
105 DW TIM_INT
106 DB "CLOCK "
107
108 DSKDEV: ;Header for disk devices
109 DW -1,-1 ;Last device
110 DW 2000H ;Is a block device
111 DW STRATEGY
112 DW DSK_INT
113 DRVMAX DB 1 ;Number of Units
114 DB 7 DUP (?)
115
116 PAGE
117 SUBTTL Dispatch tables for each device.
118
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.
132
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.
146
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.
160
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.
174
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.
188
189 PAGE
190 SUBTTL Strategy and Software Interrupt routines.
191
192 ;Define offsets for io data packet
193
194 IODAT STRUC
195 CMDLEN DB ? ;LENGTH OF THIS COMMAND
196 UNIT DB ? ;SUB UNIT SPECIFIER
197 CMD DB ? ;COMMAND CODE
198 STATUS DW ? ;STATUS
199 DB 8 DUP (?)
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
204 IODAT ENDS
205
206 PTRSAV DD 0 ;Strategy pointer save.
207
208 ;
209 ; Simplistic Strategy routine for non-multi-Tasking system.
210 ;
211 ; Currently just saves I/O packet pointers in PTRSAV for
212 ; later processing by the individual interrupt routines.
213 ;
214
215 STRATP PROC FAR
216
217 STRATEGY:
218 MOV WORD PTR CS:[PTRSAV],BX
219 MOV WORD PTR CS:[PTRSAV+2],ES
220 RET
221
222 STRATP ENDP
223
224 ;
225 ; Console interrupt routine for processing I/O packets.
226 ;
227
228 CON_INT:
229 PUSH SI
230 MOV SI,OFFSET CONTBL
231 JMP SHORT ENTRY
232
233 ;
234 ; Auxilary interrupt routine for processing I/O packets.
235 ;
236
237 AUX_INT:
238 PUSH SI
239 MOV SI,OFFSET AUXTBL
240 JMP SHORT ENTRY
241
242 ;
243 ; Printer interrupt routine for processing I/O packets.
244 ;
245
246 PRN_INT:
247 PUSH SI
248 MOV SI,OFFSET PRNTBL
249 JMP SHORT ENTRY
250
251 ;
252 ; Clock interrupt routine for processing I/O packets.
253 ;
254
255 TIM_INT:
256 PUSH SI
257 MOV SI,OFFSET TIMTBL
258 JMP SHORT ENTRY
259
260 ;
261 ; Disk interrupt routine for processing I/O packets.
262 ;
263
264 DSK_INT:
265 PUSH SI
266 MOV SI,OFFSET DSKTBL
267
268 ;
269 ; Common program for handling the simplistic I/O packet
270 ; processing scheme in MSDOS 2.0
271 ;
272
273 ENTRY: PUSH AX ;Save all nessacary registers.
274 PUSH CX
275 PUSH DX
276 PUSH DI
277 PUSH BP
278 PUSH DS
279 PUSH ES
280 PUSH BX
281
282 LDS BX,CS:[PTRSAV] ;Retrieve pointer to I/O Packet.
283
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.
288
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.
293 ADD SI,AX
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.
299 PUSH CS
300 POP DS ;Data segment same as Code segment.
301 JMP [SI] ;Perform I/O packet command.
302
303 PAGE
304 SUBTTL Common error and exit points.
305
306 BUS_EXIT: ;Device busy exit.
307 MOV AH,00000011B ;Set busy and done bits.
308 JMP SHORT EXIT1
309
310 CMDERR: MOV AL,3 ;Set unknown command error #.
311
312 ;
313 ; Common error processing routine.
314 ; AL contains actual error code.
315 ;
316 ; Error # 0 = Write Protect violation.
317 ; 1 = Unkown unit.
318 ; 2 = Drive not ready.
319 ; 3 = Unknown command in I/O packet.
320 ; 4 = CRC error.
321 ; 5 = Bad drive request structure length.
322 ; 6 = Seek error.
323 ; 7 = Unknown media discovered.
324 ; 8 = Sector not found.
325 ; 9 = Printer out of paper.
326 ; 10 = Write fault.
327 ; 11 = Read fault.
328 ; 12 = General failure.
329 ;
330
331 ERR_EXIT:
332 MOV AH,10000001B ;Set error and done bits.
333 STC ;Set carry bit also.
334 JMP SHORT EXIT1 ;Quick way out.
335
336 EXITP PROC FAR ;Normal exit for device drivers.
337
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.
341
342 POP BX ;Restore registers.
343 POP ES
344 POP DS
345 POP BP
346 POP DI
347 POP DX
348 POP CX
349 POP AX
350 POP SI
351 RET ;RESTORE REGS AND RETURN
352 EXITP ENDP
353
354 PAGE
355 SUBTTL Main console I/O section.
356
357 MCON DW 0001H
358 PCON DW 0002H
359 ACON DW 0003H
360
361 CHAR DB ? ;Small typeahead buffer for now.
362
363 ;
364 ; Console keyboard handler.
365 ;
366
367 CISTAT: PUSH CX ;Save CX pair.
368 MOV AL,[CHAR]
369 OR AL,AL
370 JNZ CISTA9 ;Character still in buffer.
371 CISTA1: MOV BX,ROM_CONSTA
372 MOV CX,[MCON]
373 CALL ROM_CALL ;See if character waiting.
374 TEST AL,AL
375 JZ CISTA9
376 MOV BX,ROM_CONIN
377 MOV CX,[MCON]
378 CALL ROM_CALL ;Get character from Rom.
379 OR AL,AL
380 JZ CISTA1 ;Got a null character.
381 MOV [CHAR],AL
382 CISTA9: POP CX ;Can't lose CX pair.
383 RET
384
385 ;
386 ; Get a character from the buffer queue.
387 ;
388
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.
392 RET
393
394 ;
395 ; Console read non-destructive.
396 ;
397
398 CON_RDND:
399 CALL CISTAT ;See if character ready.
400 JZ CON_RDN2 ;No, return busy signal.
401 CON_RDN1:
402 LDS BX,CS:[PTRSAV]
403 MOV [BX.MEDIA],AL
404 JMP EXIT
405 CON_RDN2:
406 JMP BUS_EXIT
407
408 ;
409 ; Console destructive read.
410 ;
411
412 CON_READ:
413 CALL CINP ;Get character.
414 STOSB ;Save it in users buffer.
415 LOOP CON_READ ;Loop until CX is exhausted.
416 JMP EXIT
417
418 ;
419 ; Console flush routine. (ctrl-c, ctrl-f, or ctrl-s inspired)
420 ;
421
422 CON_FLSH:
423 MOV [CHAR],0 ;Clear small type a head buffer.
424 JMP EXIT
425
426 ;
427 ; Console output status routine.
428 ;
429
430 CON_WRST:
431 JMP EXIT ;Yes, normal exit.
432
433 ;
434 ; Console output routine.
435 ;
436
437 CON_WRIT:
438 MOV SI,DI ;Get destination to source.
439 CON_WRI1:
440 LODS BYTE PTR ES:[SI]
441 PUSH CX
442 IF ANSI
443 CALL CONOUT ;Call ansi driver.
444 ENDIF
445 IFE ANSI
446 CALL OUTCHR
447 ENDIF
448 POP CX
449 LOOP CON_WRI1 ;Keep going until user buffer through.
450 JMP EXIT
451
452 ;
453 ; Console character output routine.
454 ;
455
456 OUTCHR: MOV BX,ROM_CONOUT
457 MOV CX,[MCON] ;Get current console port.
458 MOV DL,AL
459 CALL ROM_CALL
460 RET
461
462 PAGE
463
464 IF ANSI
465
466 SUBTTL ANSI interface section.
467
468 ;
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.
474 ;
475
476 ESC EQU 1BH ;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.
481
482 CMDTABL DB 'A' ;Cursor up. "esc","[",#,"A"
483 DW CUU
484 DB 'B' ;Cursor down. "esc","[",#,"B"
485 DW CUD
486 DB 'C' ;Cursor forward. "esc","[",#,"C"
487 DW CUF
488 DB 'D' ;Cursor back. "esc","[",#,"D"
489 DW CUB
490 DB 'H' ;Direct cursor posit. "esc","[",x,y,"H"
491 DW CUP
492 DB 'J' ;Erase. "esc","[",code,"J"
493 DW ED
494 DB 'K' ;Erase in line. "esc","[",code,"K"
495 DW EL
496 DB 'f' ;Direct cursor posit. "esc","[",x,y,"f"
497 DW CUP
498 DB 'm' ;Special video mode. "esc","[",code,"m"
499 DW SGR
500 DB 's' ;Save cursor posit. "esc","[","s"
501 DW PSCP
502 DB 'u' ;Move cursor to saved. "esc","[","u"
503 DW PRCP
504 DB 00 ;End of table.
505
506 ;
507 ; ANSI console output driver.
508 ;
509
510 CONOUT: MOV DI,OFFSET STATE ;Retrieve current ansi state.
511 JMP [DI] ;Jump to it.
512
513 ;
514 ; State one (1).
515 ; Looks for an Escape character.
516 ;
517
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.
521 RET
522
523 ;
524 ; State two (2).
525 ; Looks for the "[" character.
526 ;
527
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.
534 RET
535
536 ;
537 ; State three (3).
538 ; Entered one or more times for parameter passing.
539 ;
540
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.
545 CMP [PRMPNT],AX
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.
550 RET
551
552 ;
553 ; State three A (3A).
554 ; Check for a ascii digit.
555 ;
556
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.
565 MUL AH
566 ADD [DI],AL ;Add to new digit.
567 RET
568
569 ;
570 ; State three B (3B).
571 ; Wasn't a ascii digit, so check for secondary command.
572 ;
573
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.
578
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.
586
587 ;
588 ; Get binary parameter from storage and return a one if = 0
589 ;
590
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.
597 RET
598
599 GETPARM:INC WORD PTR [PRMPNT] ;Increment parameter pointer.
600 GOTPARM:MOV DI,[PRMPNT] ;Get parameter pointer.
601 MOV AL,[DI] ;Get parameter value.
602 RET
603
604 ;
605 ; Send escape, character sequence.
606 ;
607
608 OUTESC: MOV AL,ESC ;Send escape character.
609 CALL OUTCHR
610 MOV AL,BL ;Send follow character.
611 JMP OUTCHR
612
613 ;
614 ; Cursor Positioning routines.
615 ;
616
617 CUU: MOV BL,'A' ;Cursor up.
618 JMP SHORT CURPOS
619 CUD: MOV BL,'B' ;Cursor down.
620 JMP SHORT CURPOS
621 CUF: MOV BL,'C' ;Cursor forward.
622 JMP SHORT CURPOS
623 CUB: MOV BL,'D' ;Cursor back.
624
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.
628 RET
629
630 ;
631 ; Direct cursor positioning routine.
632 ;
633
634 CUP: CALL GETONE ;Get X position.
635 MOV DX,AX ;Save in DX.
636 CALL GETONE ;Get Y position.
637 MOV BL,'Y'
638 CALL OUTESC ;Send escape, "Y" sequence.
639 MOV AL,DL
640 ADD AL,' '-1 ;Convert binary to Character.
641 CALL OUTCHR ;Send X posit.
642 MOV AL,CL
643 ADD AL,' '-1 ;Convert binary to Character.
644 JMP OUTCHR ;Send Y posit.
645
646 ;
647 ; Erase all/part of screen.
648 ;
649
650 ED: CALL GETPARM ;Get trinary command type.
651 MOV BL,'b'
652 DEC AL ;See if erase from begining of screen.
653 JZ ED1 ;Yes, perform ZDS function.
654 MOV BL,'E'
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.
658 ED1: JMP OUTESC
659
660 ;
661 ; Erase all/part of a line.
662 ;
663
664 EL: CALL GETPARM ;Get trinary command type.
665 MOV BL,'o'
666 DEC AL ;See if erase from begining of line.
667 JZ EL1 ;Yes, perform ZDS function.
668 MOV BL,'l'
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.
672 EL1: JMP OUTESC
673
674 ;
675 ; Special video modes.
676 ;
677
678 SGR: CALL GETPARM ;Get trinary command type.
679 MOV BL,'p'
680 CMP AL,7 ;See if enter reverse video mode.
681 JZ SGR2 ;Yes, perform ZDS function.
682 MOV BL,'q'
683 OR AL,AL ;See if exit reverse video mode.
684 JNZ SGR3 ;No, ignore.
685 SGR2: CALL OUTESC
686 SGR3: RET
687
688 ;
689 ; Save / restore cursor position.
690 ;
691
692 PSCP: MOV BL,'j' ;Set save cursor posit. mode.
693 JMP OUTESC
694
695 PRCP: MOV BL,'k' ;Restore last cursor save.
696 JMP OUTESC
697
698 ENDIF
699
700
701 PAGE
702 SUBTTL Printer buffer handler.
703
704 ;
705 ; Printer status routine.
706 ;
707
708 PRN_STA:
709 JMP EXIT
710
711 ;
712 ; Printer write routine.
713 ;
714
715 PRN_WRT:MOV SI,DI ;Set source = destination index.
716
717 PRN_WR1:LODS BYTE PTR ES:[SI];Get a data byte.
718 PUSH CX
719 MOV CX,[PCON]
720 MOV BX,ROM_CONOUT
721 MOV DL,AL
722 CALL ROM_CALL
723 POP CX
724 LOOP PRN_WR1
725 RET
726
727 PAGE
728 SUBTTL Auxilary I/O routines.
729
730 AUXCHAR DB 0 ;Temporary AUX ahead storage.
731
732 ;
733 ; Status routine for Auxilary port.
734 ;
735
736 AISTAT: MOV AL,[AUXCHAR]
737 TEST AL,AL
738 JNZ AISTA9 ;Character already waiting.
739 MOV CX,[ACON]
740 MOV BX,ROM_CONSTA
741 CALL ROM_CALL
742 TEST AL,AL
743 JZ AISTA9 ;Still none waiting.
744 MOV CX,[ACON]
745 MOV BX,ROM_CONIN
746 CALL ROM_CALL
747 AISTA9: MOV [AUXCHAR],AL
748 RET
749
750 ;
751 ; Auxilary port read.
752 ;
753
754 AIN: CALL AISTAT ;Get status and/or char.
755 JZ AIN ;Cycle until one is ready.
756 MOV [AUXCHAR],0
757 RET
758
759 ;
760 ; Write routine for Auxilary port.
761 ;
762
763 AOUT: MOV CX,[ACON]
764 MOV BX,ROM_CONOUT
765 MOV DL,AL
766 CALL ROM_CALL
767 RET
768
769 ;
770 ; Non-Destructive Auxilary read routine.
771 ;
772
773 AUX_RDND:
774 CALL AISTAT ;Get status and copy of char. waiting if any.
775 JZ AUX_RDN2 ;No character waiting, exit.
776 JMP CON_RDN1
777 AUX_RDN2:
778 JMP BUS_EXIT
779
780 ;
781 ; Destructive Auxilary read routine.
782 ;
783
784 AUX_READ:
785 CALL AIN ;Get data character.
786 STOSB ;Save it through DI.
787 LOOP AUX_READ ;Cycle until user buffer full.
788 JMP EXIT
789
790 ;
791 ; Auxilary clear type a head.
792 ;
793
794 AUX_CLR:
795 MOV [AUXCHAR],0
796 JMP EXIT
797
798 ;
799 ; Auxilary write port status.
800 ;
801
802 AUX_WRST:
803 JMP EXIT
804
805 ;
806 ; Auxilary write.
807 ;
808
809 AUX_WRIT:
810 MOV SI,DI
811 AUX_WRI1:
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.
815 JMP EXIT
816
817 PAGE
818 SUBTTL Date/Time Routines.
819
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.
825
826 ;
827 ; Time write routine.
828 ;
829
830 TIM_WRT:
831 MOV SI,OFFSET TIM_DAYS
832 XCHG SI,DI
833 PUSH ES
834 MOV AX,DS
835 POP DS
836 MOV ES,AX
837 MOV CX,6
838 REP MOVSB
839 MOV AL,0
840 JMP EXIT
841
842 ;
843 ; Time read routine.
844 ;
845
846 TIM_RED:
847 MOV SI,OFFSET TIM_DAYS
848 MOV CX,6
849 REP MOVSB
850 MOV AL,0
851 JMP EXIT
852
853 PAGE
854 SUBTTL 8089 Monitor structure.
855
856 ;
857 ; Structure to reference 8089 and ROM command table.
858 ;
859
860 SIOPB STRUC
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.
875 SIOPB ENDS
876
877 IOPB SIOPB <,00H,0,0,0,0,0,0,000H,0,0,0,0,>
878
879 PAGE
880 SUBTTL Drive Tables.
881
882
883 ;
884 ; MSDOS drive initialization tables and other what not.
885 ;
886 ; Drive 0 is:
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).
890 ; or
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).
894 ; or
895 ; Single sided, Double Density, 75 track with 12
896 ; 512 byte sectors per track.
897 ; (460,800 bytes)
898 ; Two hidden single density tracks.
899 ;
900
901 DBP STRUC
902
903 JMPNEAR DB 3 DUP (?) ;Jmp Near xxxx for boot.
904 NAMEVER DB 8 DUP (?) ;Name / Version of OS.
905
906 ;------- Start of Drive Parameter Block.
907
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)
916
917 ;------- End of Drive Parameter Block.
918
919 SECTRK DW ? ;Number of Sectors per track.
920
921 DBP ENDS
922
923 LSDRIV1 DBP <,,128,4,1,2,68,2002,0FEH,6,26>
924
925 LSDRIV2 DBP <,,128,4,4,2,68,2002,0FDH,6,26>
926
927 LDDRIV1 DBP <,,512,1,24,2,128,924,0F8H,3,12>
928
929 LDDRIV2 DBP <,,1024,1,16,2,128,616,0F9H,1,8>
930
931 DSK_INIT:
932 MOV AX,1
933 MOV SI,OFFSET INITTAB
934 JMP GET_BP5
935
936 INITTAB:
937 DW LDDRIV2.SECSIZE
938
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.
943
944 DDENS EQU 55H ;Density select port.
945 DDBIT EQU 04H ;Density select bit.
946 DSELECT EQU 53H ;Drive select port.
947
948 CURDRV DB 0
949 DRVTAB DB 0EH,0DH,0BH,07H
950 TRKPT DB 0,1,2,3
951 TRKTAB DB -1,-1,-1,-1
952 PREDENS DB 0,0,0,0
953
954 PAGE
955 SUBTTL Media check routine
956
957 ;
958 ; Media check routine.
959 ; On entry:
960 ; AL = disk unit number.
961 ; AH = media byte
962 ; On exit:
963 ;
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.
967 ;
968 ; [MEDIA] = 0FEH for Standard single density.
969 ; [MEDIA] = 0FDH for Altos single density.
970 ; [MEDIA] = 0F4H for Altos double density.
971 ;
972
973 MEDIAS STRUC
974 DB 13 DUP(?) ;Static request header.
975 MEDIAS1 DB ? ;Media byte.
976 MEDIAS2 DB ? ;Media status byte flag.
977 MEDIAS ENDS
978
979 MEDIAC:
980 AND AL,03H ;Clear any extraneous bits.
981 PUSH AX ;Save drive number requested.
982 MOV AL,0D0H ;Terminate with no interrupt.
983 CALL DCOM
984 AND AL,20H ;See if head load bit set.
985 POP AX
986 JZ MEDIA2 ;Head not loaded, so see if media changed.
987 MOV AH,1 ; AH = 1, disk not changed.
988 JMP SHORT MEDIA1
989
990 MEDIA1A:MOV [PREDENS],DL ;Save last density used for read.
991
992 MEDIA1: LDS BX,[PTRSAV] ;Udate media section of data block.
993 MOV [BX.MEDIAS2],AH
994 MOV AL,0
995 JMP EXIT
996
997 MEDIA2: CALL MEDIA4 ;Unload head if selecting new drive.
998 MOV CX,2 ;Try each density once.
999 MOV BX,OFFSET DRVTAB
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.
1005 MEDIA3: IN AL,DDENS
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
1010 CALL DCOM
1011 AND AL,98H
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.
1016 LOOP MEDIA3
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 -
1019
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.
1024 ;
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.
1027 ;
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
1031 CALL DCOM
1032 MOV AL,AH ;Restore current drive number
1033 MEDIA5: RET
1034
1035 ;
1036 ; Short routine to send a command to 1793 diskette controller chip and
1037 ; wait for 1793 to complete the command.
1038 ;
1039
1040 DCOM: OUT 41H,AL ;Send command to 1793.
1041 MOV CX,10H
1042 DCOM1: LOOP DCOM1 ;Wait a short time for 1793 to digest it.
1043
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
1048 RET
1049
1050 PAGE
1051 SUBTTL Build and return Bios Parameter Block for a diskette.
1052
1053 ;
1054 ; Build Bios Parameter Blocks.
1055 ;
1056 ; On entry: ES:DI contains the address of a scratch sector buffer.
1057 ; AL = Unit number.
1058 ; AH = Current media byte.
1059 ;
1060 ; On exit: Return a DWORD pointer to the associated BPB
1061 ; in the Request packet.
1062 ;
1063
1064 BPBS STRUC
1065 DB 13 DUP(?) ;Static request header.
1066 BPB1 DB ? ;Media byte.
1067 BPB2 DW ? ;DWORD transfer address.
1068 DW ?
1069 BPB3 DW ? ;DWORD pointer to BPB
1070 DW ?
1071 BPBS ENDS
1072
1073 GET_BPB:
1074 PUSH ES
1075 PUSH DI
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
1083 MOV [IOPB.TRACK],0
1084 MOV BYTE PTR[IOPB.HEAD],1
1085 MOV BYTE PTR[IOPB.RETMASK],0DCH
1086 MOV [IOPB.SECLENG],128
1087 MOV BX,ROM_DISKIO
1088 MOV CX,OFFSET IOPB
1089 PUSH CS
1090 POP ES
1091 CALL ROM_CALL ;Read sector zero for information.
1092 PUSH CS
1093 POP DS
1094 POP DI
1095 POP ES
1096 MOV AH,[IOPB.RETCODE]
1097 OR AH,AH
1098 JNZ GET_BP3 ;Disk error, assume old single density.
1099
1100 GET_BP1:MOV AL,ES:[DI.MEDIAID] ;Get diskettes media ID.
1101 MOV SI,OFFSET LSDRIV2
1102 CMP AL,[SI.MEDIAID]
1103 JZ GET_BP4
1104 MOV SI,OFFSET LDDRIV1
1105 CMP AL,[SI.MEDIAID]
1106 JZ GET_BP4
1107 MOV SI,OFFSET LDDRIV2
1108 CMP AL,[SI.MEDIAID]
1109 JZ GET_BP4
1110
1111 GET_BP3:MOV SI,OFFSET LSDRIV1 ;No compares, assume old style for now.
1112
1113 GET_BP4:MOV AL,[SI.MEDIAID]
1114 ADD SI,11 ;Convert to DPB pointer
1115
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.
1120 OR AH,AH
1121 JNZ GET_BP6
1122 MOV AL,0
1123 JMP EXIT
1124 GET_BP6:MOV AX,7
1125 JMP ERR_EXIT
1126
1127 PAGE
1128
1129 SUBTTL Disk I/O equates.
1130
1131 ; Floppy drives
1132
1133 ; --------------------------
1134 ; Hardware command def.
1135 ; --------------------------
1136 ;
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.
1143 ;
1144 ; --------------------------
1145 ; Status bits:
1146 ; --------------------------
1147 ;
1148 ; Busy = 01 hex.
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.
1158 ;
1159 ; --------------------------
1160
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.
1167
1168 PAGE
1169 SUBTTL MSDOS 2.x Disk I/O drivers.
1170
1171 ;
1172 ; Disk READ/WRITE functions.
1173 ;
1174 ; On entry:
1175 ; AL = Disk I/O driver number
1176 ; AH = Media byte.
1177 ; ES = Disk transfer segment.
1178 ; DI = Disk transfer offset in ES.
1179 ; CX = Number of sectors to transfer
1180 ; DX = Logical starting sector.
1181 ;
1182 ; On exit:
1183 ; Normal exit through common exit routine.
1184 ;
1185 ; Abnormal exit through common error routine.
1186 ;
1187
1188 DSK_RED:
1189 MOV BX,0DC88H ;Set read mode and Error mask.
1190 JMP SHORT DSK_COM
1191 DSK_WRV:
1192 DSK_WRT:MOV BX,0FCA8H ;Set write mode and Error mask.
1193
1194 DSK_COM:MOV SI,OFFSET LSDRIV1
1195 CMP AH,[SI.MEDIAID]
1196 JE DSK_CO3
1197 MOV SI,OFFSET LSDRIV2
1198 CMP AH,[SI.MEDIAID]
1199 JE DSK_CO3
1200 MOV SI,OFFSET LDDRIV1
1201 CMP AH,[SI.MEDIAID]
1202 JE DSK_CO2
1203 MOV SI,OFFSET LDDRIV2
1204 CMP AH,[SI.MEDIAID]
1205 JE DSK_CO2
1206 MOV AL,7
1207 JMP ERR_EXIT
1208
1209 DSK_CO2:OR AL,F_DD ;Set double density mode.
1210
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.
1222 MOV AX,DX
1223 MOV DX,0 ;32 bit divide coming up.
1224 MOV CX,[SI.SECTRK]
1225 DIV CX ;Get track+head and start sector.
1226 INC DL
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.
1233 MOV AH,0
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.
1239 JMP SHORT DSK_CO6
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.
1244 MOV BX,ROM_DISKIO
1245 MOV CX,OFFSET IOPB
1246 PUSH CS
1247 POP ES
1248 CALL ROM_CALL ;Do disk operation.
1249 MOV AL,[IOPB.RETCODE] ;Get error code.
1250 OR AL,AL
1251 JNZ DERROR
1252 MOV AX,DI ;Retrieve number of sectors read.
1253 MOV CX,[SI.SECSIZE] ;Number of bytes per sector.
1254 PUSH DX
1255 MUL CX
1256 POP DX
1257 TEST AL,0FH ;Make sure no strange sizes.
1258 JNZ DSK_CO7 ;Illegal sector size found.
1259 MOV CL,4
1260 SHR AX,CL ;Convert number of bytes to para.
1261 ADD AX,[IOPB.DMASEG]
1262 MOV [IOPB.DMASEG],AX
1263 OR BP,BP
1264 JNZ DSK_CO4 ;Still more to do.
1265 MOV AL,0
1266 JMP EXIT ;All done.
1267 DSK_CO7:MOV AL,12
1268 JMP ERR_EXIT
1269
1270 PAGE
1271 SUBTTL Disk Error processing.
1272
1273 ;
1274 ; Disk error routine.
1275 ;
1276
1277 DERROR: LDS BX,CS:[PTRSAV]
1278 MOV [BX.COUNT],0
1279 PUSH CS
1280 POP DS
1281
1282 MOV BL,-1
1283 MOV AH,AL
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.
1290 DEC BH
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.
1294 RET
1295
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.
1309
1310 PAGE
1311 SUBTTL Common ROM call routine.
1312
1313 ;
1314 ; Save all registers except CX, BX and AX.
1315
1316 ROMRTN DD 0FE000000H ;Main ROM entry point.
1317
1318 ROM_CALL:
1319 PUSH DI
1320 PUSH SI
1321 PUSH BP
1322 PUSH DX
1323 PUSH ES
1324 CALL CS:DWORD PTR [ROMRTN]
1325 POP ES
1326 POP DX
1327 POP BP
1328 POP SI
1329 POP DI
1330 RET
1331
1332 PAGE
1333 SUBTTL Initalization code and temporary work areas.
1334
1335 ;
1336 ; Overlayed by MSDOS by SYSINIT.
1337 ;
1338
1339 WRKSTK LABEL WORD
1340 DB 100 DUP (?)
1341
1342
1343 HWINIT: XOR BP,BP
1344 MOV SS,BP
1345 MOV SP,OFFSET WRKSTK+98 ;Some nice area for stack.
1346
1347 PUSH CS
1348 POP ES
1349
1350 MOV BX,ROM_INIT
1351 CALL ROM_CALL
1352 MOV AH,0
1353 MOV MCON,AX
1354
1355 MOV AX,SEG SYSINIT
1356 MOV DS,AX
1357
1358 ASSUME DS:SEG SYSINIT
1359
1360 MOV AX,CS
1361 ADD AX,BIOSIZS
1362 MOV DS:[CURRENT_DOS_LOCATION],AX
1363 MOV DS:[MEMORY_SIZE],MAX_MEM
1364 MOV AX,CS
1365 MOV WORD PTR DS:[DEVICE_LIST+2],AX
1366 MOV WORD PTR DS:[DEVICE_LIST],OFFSET DEVSTART
1367 MOV AX,CS
1368 ADD AX,((OFFSET WRKSTK - OFFSET INIT)+50) /16
1369 MOV DS:[FINAL_DOS_LOCATION],AX
1370 JMP SYSINIT
1371
1372 DOSSPOT LABEL WORD
1373
1374 CODE ENDS
1375
1376 END
1377 \1a