; MODEL I - BOOT SECTOR ; copied from the HACKER'S HANDBOOK FOR NEWDOS/80, page 42 and on. ; modifies and added comments and some symbols SYS0LC EQU 0005H ; Start track & sector SYS0/SYS DSDR0L EQU 37E1H ; Disk select / Drive 0 latch FDCCSR EQU 37ECH ; FDC Command/Status Register FDC_TR EQU 37EDH ; FDC Track Register FDC_SR EQU 37EEH ; FDC Sector Register FDC_DR EQU 37EFH ; FDC Data Register SECBUF EQU 5100H ; Sector Buffer SCBUFE EQU 51FFH ; Sector Buffer end ; Addr. Code Instruction Function 4200H 00 NOP ; No operation 4201H FE 11 CP 11H ; Recognition Code + 17 = Dir Sector 4203H F3 DI ; Disable Interrupts 4204H 21 EC 37 LD HL,FDCCSR ; Command/Status Register 4207H 36 FE LD (HL),FEH ; Code for Request ) Activate (set to Single Density) 4209H 36 D0 LD (HL),D0H ; Terminate Request ) Drive 420BH 23 INC HL ; Move to Track Register 420CH 36 00 LD (HL),00H ; Track 0 420EH 23 INC HL ; Sector Register 420FH 36 00 LD (HL),00H ; Sector 0 4211H 11 05 00 LD DE,SYS0LC ; D=Track=0,E=Sector=5 4214H D9 EXX ; Alternate Registers (for buffer to memory copy) 4215H 31 ED 41 LD SP,41EDH ; Set Stack to Comm. Area 4218H 21 FF 51 LD HL,SCBUFE ; Set HL to Sector Buffer 1 421BH CD 52 42 CALL 4252H ; get 1st Byte 421EH FE 20 CP 20H ; Set or not Carry Flag 4220H 47 LD B,A ; Store for 422CH 4221H 30 29 JR NC,424CH ; Go to Error handling if > 1FH 4223H 57 LD D,A ; If byte >2 & <32 load to ROM 4224H CD 52 42 CALL 4252H ; get 2nd Byte (size of area) 4227H 4F LD C,A ; Store No. of Bytes 4228H CD 52 42 CALL 4252H ; Get 3rd Byte (1st area = 00H 422BH 5F LD E,A ; LSB of Address to load to 422CH 10 12 DJNZ 4240H ; If 1st byte <> 1 goto 4240H ; Sector buffer-to-memory transfer 422EH CD 52 42 CALL 4252H ; Go & read MSB of 4231H 57 LD D,A ; Address to load to 4232H 0D DEC C ; allow for 2 Byte Addr in 4233H 0D DEC C ; count of Bytes to be loaded 4234H 2C INC L ; Move along in Buffer 4235H CC 55 42 CALL Z,4255H ; if end Buffer load another sector 4238H 7E LD A,(HL) ; then load DATA Reg 4239H 12 LD (DE),A ; into Address in DE. 423AH 13 INC DE ; move Address on 423BH 0D DEC C ; 1 Byte less to load 423CH 20 F6 JR NZ,4234H ; if more go back 423EH 18 DB JR 421BH ; or go load another area 1 4240H 10 F9 DJNZ 423BH ; If 1st byte <> 2 load to ROM ; Get transfer address and execute or Error 4242H CD 52 42 CALL 4252H ; else read next byte 4245H 57 LD D,A ; MSB of transfer address (4D00H) 4246H 1A LD A,(DE) ; Check if contents of 4D00H 4247H FE A5 CP A5H ; is A5H 4249H 13 INC DE ; Move on to 4D01H 424AH D5 PUSH DE ; To stack : if OK return to 424BH C8 RET Z ; transfer addr. or error 1 424CH 21 E5 42 LD HL,42E5H ; 'No SYS' ASCII 424FH C3 C3 42 JP 42C3H ; Go to Error routine. ; get next byte from buffer, load new sector if at end of buffer 5 4252H 2C INC L ; Move on 1 Byte in buffer 4253H 7E LD A,(HL) ; Store in A 4254H C0 RET NZ ; Go back if not end of buffer ; load a new sector into the buffer 1 4255H D9 EXX ; Alternate Registers (for fdc to buffer copy) 4256H 06 0A LD B,0AH ; 10 error tries 1 4258H 21 E1 37 LD HL,DSDR0L ; Drive control Reg 425BH 36 01H LD (HL),01H ; select Drive 0 425DH D5 PUSH DE ; Store both Track# & Sector# 425EH C5 PUSH BC ; and error count 425FH 7B LD A,E ; check sector count 4260H D6 0A SUB 0AH ; is it more than 10 ? 4262H 38 03 JR C,4267H ; if not jump 4264H 5F LD E,A ; 4265H 36 09 LD (HL),09H ; select Drive 0, second side. 4267H 21 EC 37 LD HL,FDCCSR ; Command Register 426AH CD CE 42 CALL 42CEH ; Delay - get ready 426DH ED 53 EE 37 LD (FDC_SR),DE ; E in Sect Reg : D=Data Reg 4271H 36 1B LD (HL),1BH ; 27 = SEEK Track 0, 20ms step 4273H CD CE 42 CALL 42CEH ; Delay 4276H 36 88 LD (HL),88H ; 136 = load 1 sector IBM fmt 4278H 11 EF 37 LD DE,FDC_DR ; DATA Register 427BH 01 00 51 LD BC,SECBUF ; Buffer 427EH CD D7 42 CALL 42D7H ; Delay 1 4281H 7E LD A,(HL) ; Status of Drive 4282H E6 83 AND 83H ; leave Bits 0, 1, and 7 4284H E2 81 42 JP PO,4281H ; if Bit 7, Drive not Ready ; Start actual read loop 4287H 1A LD A,(DE) ; Transfer Data to 4288H 02 LD (BC),A ; Sector Buffer 4289H 03 INC BC ; move on in the Buffer 1 428AH CB 4E BIT 0,(HL) ; If not Busy 428CH C2 B7 42 JP NZ,4287H ; move more data ; End actual read loop. If we are to fast, there some extra delayed retries 428FH CB 4E BIT 1,(HL) ; Wait till the 4291H C2 87 42 JP NZ,4287H ; Status Reg 4294H CB 4E BIT 1,(HL) ; has Data read 4296H 20 EF JR NZ,4287H ; request 4298H CB 46 BIT 2,(HL) ; if Drive is not busy 429AH 28 D8 JR Z,42A4H ; go.... 429EH 20 E7 JR NZ,4287H ; data request 42A0H CB 7E BIT 7,(HL) ; Test if Drive is ready 42A2H 28 E6 JR Z,428AH ; if so go try again ; End of read loop delays 1 42A4H 7E LD A,(HL) ; Store status in A 42A5H 36 D0 LD (HL),D0H ; Interrupt Command 42A7H C1 POP BC ; Restore original 42A8H D1 POP DE ; values for next time 42A9H E6 FC AND 0FCH ; all but Bits 0 & 1 42ABH 20 OC JR NZ,42B9H ; if error/not ready Go 42ADH 1C INC E ; move sector # on 42AEH 7B LD A,E ; if < 10 then 42AFH D6 DA SUB DAH ; go through 42B1H 20 03 JR NZ,4286H ; else incr Track 42B3H 14 INC D ; & set Sector 42B4H 1E 00 LD E,00H ; to 0. 42B6H 09 EXX ; Back to other Registers (for buffer to memory copy) 42B7H 7E LD A,(HL) ; contents of buffer into A 42B8H C9 RET ; & go back ; ............. Test if all Errors used 42B9H CD D7 42 CALL 4207H ; Delay 42BCH 36 0B LD (HL),0BH ; Restore to Track 0 42BEH 10 98 DJNZ 4258H ; if B <> 1 start again ; ERROR handling 42C0H 21 DD 42 LD HL,42DDH ; 'ERROR' ASCII ; Error print and lock up routine 3 42C3H 7E LD A,(HL) ; Read the byte 42C4H FE 03 CP 03H ; if it is 3 go into 42C6H 28 FB JR Z,42C3H ; an enless loop. 42C8H 23 INC HL ; else 42C9H CD 33 00 CALL 0033H ; & Print 42CCH 18 F5 JR 42C3H ; more. ; After a delay, test for busy 1 42CEH CD 07 42 CALL 42D7H ; Delay subroutine 1 42D1H CB 46 BIT 0,(HL) ; Test for busy 42D3H 20 FC JR NZ,42D1H ; if so wait 42D5H 7E LD A,(HL) ; Get Status value 42D6H C9 RET ; & Return ; Delay subroutine 3 42D7H 3E 06 LD A,06H ; Delay 1 42D9H 3D DEC A ; just 42DAH 20 FD JR NZ,42D9H ; 50 Microseconds 42DCH C9 RET ; and go back ; ASCII storage 1 42DDH - 42DEH 1C 1F ; ASCII - Home & Clear screen 42DFH - 42E3H 45 52 52 4F 52 ; ASCII - 'ERROR' 42E4H 03 ; ETX - terminator 1 42E5H - 42E6H 1C 1F ; ASCII - Home Cursor & Clear 42E7H - 42ECH 4E 4F 20 53 59 53 ; ASCII - 'NO SYS' 42EDH 03 ; ETX - End of message 42EEH - 42FFH ; Garbage