; THIS IS THE CP/M BOOTSTRAP FOR THE SINGLE USER SYSTEM. ; I HAVE WRITTEN IT IN SUCH A WAY THAT IT IS INDEPENDENT ; OF THE PROM CODE, EVEN THOUGH THIS MEANS MORE PROGRAMMING ; OF THE DMA. OTHERWISE, WE WOULD BE FORCED TO MODIFY THE ; PROM CODE EVERY TIME WE WANTED TO MOVE CP/M AROUND IN ; RAM. THE BOOTSTRAP IS OTHERWISE STRAIGHTFORWARD AND ; REQUIRES NO SPECIAL EXPLANATION. IT IS DESIGNED TO BE ; LOADED AND EXECUTED AT 0C100H. ; ; JAN 14, 1983 EDITED BY CHUNG MIN CHOI TITLE TS3BOOT.MAC--TELEVIDEO SYSTEM TS-803 BOOTSTRAP--JAN 14, 1983 .Z80 CSEG .PHASE 0C100H BOOT: DI ; DISABLE SYSTEM INTERRUPT LD (WBFLAG),A OR A LD A,1 OUT (BANKSP),A ; CHANGE MEMORY BANK TO 1 LD SP,BOOT ; INITIALIZE THE STACK POINTER JR NZ,BOOT10 ; IF FROM FLOPPY THEN SKIP ; ; ELSE LOAD CP/M FROM WINCHESTER. ; ; PRESET RECNO = 1 ; LD (RECNO),A LD DE,CPMBAS ; LOOP: EX DE,HL LD A,(H$TRK) OUT (WSDH),A XOR A OUT (WHICYL),A OUT (WLOCYL),A INC A OUT (WCOUNT),A LD A,(H$SEC) OUT (WSECT),A LD A,WREAD OUT (WCMD),A ; ; SET B = TRANSFER COUNT; C = INPUT DATA PORT ADDRESS ; LD BC,WDATA GETIO: IN A,(WSTAT) AND WDRQ JR Z,GETIO ; ; TRANSFER DATA FROM CONTROLLER TO MEMORY ; INIR WAITH: IN A,(WSTAT) AND WBUSY JR NZ,WAITH DEC H ; SET HL = LAST DMA ADDRESS EX DE,HL IN A,(WSTAT) ; CHECK FOR ERROR AND WFAULT+WERROR ; JR NZ,LOOP ; IF ERROR THEN RETRY TRANS. DATAT BLOCK INC D ; ELSE HL = NEXT DMA ADDRESS. LD HL,RECNO LD A,(HL) SUB CPMSEC ; JP Z,CCP ; INC (HL) DEC HL INC (HL) LD A,(HL) CP 32 JR NZ,LOOP XOR A LD (HL),A DEC HL DEC HL INC (HL) JR LOOP ; ; HOME THE HEAD TO TRACK 0 ; BOOT10: LD A,RESCMD ; RESTORE COMMAND OUT (FDCCMD),A CALL WAIT ; WAIT FOR COMPLETION AND SEEMSK JR NZ,BOOT10 ; SEEK ERROR, TRY AGAIN ; ; INITIAL VALUES FOR TRACK, SECTOR, AND SECTOR COUNT ; LD HL,TRKNO LD (HL),0 INC HL LD (HL),2 INC HL LD (HL),CPMSEC LD DE,CPMBAS ; BOOT20: LD HL,SECNO LD A,(HL) CP SPCYL+1 ; TIME TO MOVE TO NEXT TRACK JR C,BOOT30 ; NO. ; ; MOVE TO NEXT TRACK AND SEEK. ; LD (HL),1 DEC HL ; BUMP TRACK NO. INC (HL) LD A,(HL) OUT (FDCDAT),A ; WRITE TRACK TO DATA REGISTER INC HL LD A,SEECMD OUT (FDCCMD),A ; SEEK. CALL WAIT ; WAIT FOR COMPLETION AND SEEMSK ; STRIP OFF NON-SIGNIFICANT BITS JR NZ,BOOT10 ; BOOT ERROR, TRY AGAIN ; BOOT30: LD A,(HL) ; UPDATE SECTOR REGISTER EX DE,HL CP (SPCYL/2)+1 ; WHICH SIDE? LD C,11100101B ; MOTOR-ON(B1),SIDE-0(B2),DRIVE-0(B4) JR C,BOOT40 ; (PRIMARY) LD C,11100001B ; MOTOR-ON,SIDE-1,DRIVE-0 (SECONDARY) SUB (SPCYL/2) ; BOOT40: OUT (FDCSEC),A LD A,C ; CHOOSE SIDE OUT (FDD),A ; WRITE TO FLOPPY SELECT LATCH LD BC,FDCDAT ; SET 256 BYTES COUNTER LD DE,0FFFFH ; SET TIMER LD A,RDSCMD ; READ SECTOR COMMAND OUT (FDCCMD),A ; LD A,15 ; DELAY 60 US WAIT0: DEC A JR NZ,WAIT0 ; DEVRDY: IN A,(FDCCMD) BIT 1,A ; DRQ BIT SET? JR NZ,READIN ; YES DEC DE ; COUNT DOWN TIMER LD A,D OR E JR Z,BOOT10 ; TIME OUT IN A,(FDCCMD) BIT 1,A ; DRQ BIT SET? JR NZ,READIN ; YES RRCA JR C,DEVRDY JR BOOT10 ; ERROR, RETRY ; DRQRDY: IN A,(FDCCMD) AND 02H ; DRQ BIT SET? JR Z,DRQRDY ; NO, WAIT ; READIN: INI ; INPUT AN ASSEMBLED BYTE JR NZ,DRQRDY ; ALL BYTE READ-IN? ; CALL WAIT ; AND 0CH ; ANY ERROR: CRC, LOST DATA? JR NZ,BOOT10 ; YES, RETRY ; EX DE,HL LD HL,SECNO INC (HL) INC HL DEC (HL) JR NZ,BOOT20 ; LOOP ON NEXT SECTOR IF MORE TO READ CCP: EI ; ENABLE SYSTEM INTERRUPT LD A,(WBFLAG) JP CPMBOO ; JUMP TO CBIOS BOOT ADDRESS ; THIS ROUTINE LOOPS UNTIL THE FDC IS ; IN A NON-BUSY STATE, OR UNTIL A NOT- ; READY CONDITION IS DETECTED. WAIT: LD A,15 ; WE MUST DELAY ABOUT WAIT10: DEC A ; 60 USECS BEFORE READING JR NZ,WAIT10 ; THE STATUS. WAIT20: IN A,(FDCCMD) ; READ THE FDC STATUS BIT FDCBSY,A ; ARE WE PROCESSING A COMMAND? JR NZ,WAIT20 ; YES, LOOP UNTIL NOT BUSY AND ERRMSK ; MASK OFF NON-ERROR BITS RET ; H$TRK: DEFW 0 H$SEC: DEFB 1 RECNO: DEFS 1 TRKNO: DEFS 1 ; STORAGE FOR TRACK NUMBER SECNO: DEFS 1 ; STORAGE FOR SECTOR NUMBER SECCNT: DEFS 1 ; STORAGE FOR CPM SECTOR COUNTER WBFLAG: DEFS 1 ; INDICATOR OF HARD OR FLOPPY DISK BOOT. .DEPHASE ; DRIVE STATUS ; WFAULT EQU 020H ; WRITE FAULT ON DRIVE ; ; CONTROLLER COMMAND ; WREAD EQU 020H ; READ SECTOR ; ; CONTROLLER STATUS ; WBUSY EQU 080H ; CONTROLLER BUSY WDRQ EQU 008H ; DATA REQUEST WERROR EQU 001H ; ERROR STATUS REPORT ; ; DRIVE/CONTROLLER I/O ; CBASE EQU 0B0H ; BASE ADDRESS OF THE CONTROLLER WDATA EQU CBASE ; DATA PORT (I/O) WPCYL EQU CBASE+1 ; WRITE PRECOMP CYLINDER NUMBER (O) WERRS EQU CBASE+1 ; ERROR DEFINITION (I) WCOUNT EQU CBASE+2 ; SECTOR COUNT (I/O) WSECT EQU CBASE+3 ; SECTOR NUMBER (I/O) WLOCYL EQU CBASE+4 ; CYLINDER NUMBER, LOW ORDER BITS(I-O) WHICYL EQU CBASE+5 ; CYLINDER NUMBER, HIGH ORDER BITS(I-O) WSDH EQU CBASE+6 ; SECTOR SIZE, DRIVE SELECT, HEAD SELECT (I/O) WCMD EQU CBASE+7 ; COMMAND PORT (O) WSTAT EQU CBASE+7 ; STATUS PORT (I) ; ; FDC EQUATES FDCCMD EQU 80H ; FDC STATUS AND COMMAND PORT FDCTRK EQU 81H ; FDC TRACK PORT FDCSEC EQU 82H ; FDC SECTOR PORT FDCDAT EQU 83H ; FDC DATA PORT FDD EQU 90H ; FLOPPY SELECT LATCH BANKSP EQU 13H ; MEMORY SELECTION PORT ; FDC STATUS BITS FDCBSY EQU 0 ; FDC BUSY IS BIT 0 FDCIND EQU 1 ; FDC INDEX HOLE DETECTED FDCTR0 EQU 2 ; FDC TRACK 0 DETECTED FDCCRC EQU 3 ; FDC CRC ERROR ENCOUNTERED FDCSEE EQU 4 ; FDC SEEK ERROR ENCOUNTERED FDCHLD EQU 5 ; FDC HEAD LOAD ACK. FDCPRT EQU 6 ; FDC DISK IS WRITE PROTECTED FDCRDY EQU 7 ; FDC DISK NOT READY BIT ; FDC STATUS BYTE MASKS ERRMSK EQU 01011100B ; MASK OFF INSIGNIFICANT BITS SEEMSK EQU 00011000B ; CHECK THE NOT READY BIT DNRMSK EQU 00000000B ; DRIVE NOT READY MASK ; FDC COMMAND BYTES RESCMD EQU 00000111B ; HOME HEAD COMMAND SEECMD EQU 00010111B ; SEEK TRACK COMMAND HDSCMD EQU 00110111B ; HEAD STEP, PREVIOUS DIRECTION HSICMD EQU 01010111B ; HEAD STEP IN, TOWARD HUB. HSOCMD EQU 01110111B ; HEAD STEP OUT, TOWARD EDGE. RDSCMD EQU 10000000B ; READ SECTOR WTSCMD EQU 10100000B ; WRITE SECTOR RDACMD EQU 11000000B ; READ SECTOR ADDRESS RDTCMD EQU 11100000B ; READ TRACK WTTCMD EQU 11110000B ; WRITE TRACK FRCCMD EQU 11010000B ; FORCE TERMINATION ; DISK CONFIGURATION EQUATES NUMTRK EQU 40 ; NUMBER OF TRACKS ON DISKETTES MAXTRK EQU NUMTRK-1 ; NUMBER STARTS AT 0 MINTRK EQU 0 ; WHERE TO BEGIN SEEK TEST SPT EQU 18 ; SECTORS PER TRACK SPCYL EQU SPT*2 ; SECTORS PER CYLINDER BPSEC EQU 100H ; BYTE PER SECTOR ; ********************************************* ; * FOLLOWING CPMBAS(CCP ENTRY POINT ADDRESS) * ; * HAS TO BE CONSULTED WITH 802FBIOS.MAC FOR * ; * FUTURE MOVCPM GENERATION. * ; ********************************************* CPMBAS EQU 0D400H ; CCP ADDRESS FOR 59K SYSTEM CPMLN EQU 1600H ; CP/M SIZE = CCP + BDOS = 1600H CPMSEC EQU (0FFFFH-CPMBAS)/256+1 ; NUMBER OF SECTORS FOR TVI CP/M CPMBOO EQU CPMBAS+CPMLN ; CBIOS COLD START ENTRY POINT END