APPENDIX 3 - DEVLOAD FLOWCHART.

1. Initialisation.

1.1. Set up segment registers.

1.2. Get PSP segment.

1.3 . Print initial message.

1.4. Check DOS version.

2. Check command line.

2.1 If no parameters given, print error and exit.

2.2. Deal with switches.

2.3. Search for file using PATH if no path specified.

2.4. If file not found, print error and exit.

2.5. Expand filename to full pathname using func. 60h.

3. Relocate.

3.1. Get allocation strategy.

3.2. Reduce main allocation to minimum.

3.3. Set allocation strategy to highest fit.

3.4. Request chunk at top of memory for PSP, program and stack.

3.5. Reset allocation strategy to old value.

3.6. Move PSP to top of memory.

3.7. Move program to top of memory.

3.8. Give ownership of top of memory segment to itself.

3.9. Change stack to top of memory.

3.10. Make top PSP current.

3.11. Transfer execution to top of memory.

4. Allocate lower segment of memory.

4.1. Change stored PSPSeg.

4.2. Release old PSPSeg.

4.3. Release old environment.

4.4. Grab all free memory.

4.5. Store DvcSeg.

5. Load driver.

5.1. Disable break.

5.2. Copy all INT vectors.

5.3. Parse command line.

5.4. Print filename.

5.5. Load driver using func. 4Bh

5.6. Print load address.

5.7. Get invar pointer.

5.8. Get max sector size.

5.9. Get LASTDRIVE, LastDrUsed.

6. Execute driver.

6.1. Set DS:SI --> DvcSeg:0000.

6.2. Set ES:BX --> device after NUL.

6.3. InstallDevice until no more left.

6.4. Print LASTDRIVE error if necessary.

7. Clear up.

7.1 . Calculate size of driver to keep.

7.2. Offer abort if nothing installed.

7.3. Print LASTDRIVE and LastDrUsed.

7.4. Print number of devices installed.

7.5. Insert new LastDrUsed into invar.

7.6. Print driver keep size.

7.7. If keep size is zero, exit.

7.8. Allocate driver memory required.

7.9. Print INT vectors changed.

7.10. Link from NUL device.

7.11. Put ownership and device name into driver's arena header.

7.12. Exit program.

INSTALLDEVICE ROUTINE.

1. Store driver addresses.

2. Print CrLf.

3. Make request header.

3.1. Insert next block number.

3.2. Insert 'INIT' command.

3.3. Insert default break address = DvcSeg:0000.

3.4. Insert default no blocks in device.

3.5. Insert ptr to command line tail.

4. Call device routines.

5. If character device, increase count of said.

6. Check driver length.

6.1. Get driver length.

6.2. If grown and blocks already installed, error.

6.3. Else if grown and blocks not installed, store new value.

7. Install blocks.

7.1. Check number of units in driver.

7.2. If none, goto 8.

7.3. Zero block number count in this device.

7.4. ES:BP --> new block header.

7.5. DS:BX --> BPB pointer array.

7.6. DS:SI --> next BPB from pointer array.

7.7. Check sector size.

7.8. Check LASTDRIVE.

7.9. Store abs. block number, block number in device.

7.10. Make last block header in chain point to the new one.

7.11. Change pointer to ChainEnd.

7.12. Print new block header address.

7.13. Fill in LASTDRIVE array.

7.14. Finish filling in block header.

7.15. Expand BPB to block header using func. 53h.

7.16. Increase ES:BP by size of block header.

7.17. Increase BlocksDone.

7.18. If blocks left in this device, loop to 7.6.

7.19. Print INIT return status.

8. Link driver.

8.1. Push address of next in file.

8.2. Point new driver to old driver.

8.3. Pop address of next in file.

8.4. Convert segment if necessary.

8.5. Set ZERO flag on whether last in file.

8.6. RETURN.