.TITLE "< GSR COMPUTERS CPM BOOT PROGRAM >" .SBTTL 'VERSION III.2 10-1-82' ; ***************************************** ; * THE GSR CPM BOOT PROGRAM VER III.2 * ; * REQUIRES SBC-880 CPU BOARD * ; * AND UFDC-1 FLOPPY DISK CONTROLLER * ; * REQUIRES 2.2 CPM * ; * CONFIGURED FOR 20K MEMORY SIZE * ; * 2.2 CPM BIOS CONTAINED IN ROM AND * ; * DISK PARAMETERS ARE SET FOR * ; * 8" OR 5 1/4" SINGLE DENSITY DISK * ; * PRINT DRIVER FOR CENTRONIX PARALLEL * ; * INTERFACE AND CONSOLE DRIVER FOR * ; * 9600 BAUD TERMINAL ARE IN BIOS * ; * WRITTEN BY R. D. CATILLER * ; * COPYRIGHT 1982 (C) COMPUTIME & GSR * ; ***************************************** ; ; .PHEX .XLINK .PABS ; ; MEMORY USED BY PROGRAM ; BASE = 0D400H ;PROGRAM BASE ADDRESS. STACK = 00FFH ;PROGRAM STACK ; ; CONSTANTS FOR PROGRAM ; CR = 0DH ;ASCII CARRIAGE RET LF = 0AH ;ASCII LINE FEED ; ; I/O PORTS ON CPU BOARD ; T0 = 028H T1 = T0+1 T2 = T0+2 TCTL = T0+3 INOUT = T0+4 CONDTA = T0+6 CONCTL = T0+7 CONSTS = CONCTL ; ; ; I/O PORTS ON CT256K RAM BOARD ; MEMSTS = 88H ;MEMORY STATUS PORT ; ; ; DISK DEFINES ; VERS = 22 ;CP/M VERSION NUMBER MSIZE = 20 ;CP/M MEMORY SIZE BIAS = (MSIZE-20)*1024 CCP = 3400H+BIAS ;BASE OF CCP BDOS = CCP+806H ;BASE OF BDOS BIOS = CCP+1600H ;BASE OF BIOS WRALL = 0 ;WRT TO ALOC BLK WRDIR = 1 ;WRT TO DIRECTORY WRUAL = 2 ;WRT TO UNALOC BLK WBOOTE = BIOS+3 ;WARM BOOT ENTRY ; ; ;DISK I/O PORTS ; DSTAT = 9CH ;DISK STATUS PORT DCMMD = DSTAT ;DISK COMMAND PORT DTRCK = DSTAT+1 ;DISK TRACK PORT DSCTR = DSTAT+2 ;DISK SECTOR PORT DDATA = DSTAT+3 ;DISK DATA PORT DFLAG = 9BH ;STATUS REGISTER 1 DCNTL = DFLAG ;CONTROL REGISTER 1 ; ; ;MEMORY USED BY CPM ; CURDSK = 4 ;CURRENT DISK DRIVE TBUF = 80H ;DEFAULT CPM BUFFER ; ; ; PROGRAM CODE BEGINS: ; .LOC BASE ; ;LET US BEGIN ; JMP BEGIN ; ; PROGRAM SIGN-ON MESSAGE ; MSG: .BYTE CR,LF .ASCII 'GSR COMPUTERS CPM BOOT PROGRAM' .BYTE CR,LF,CR,LF,CR,LF .ASCII 'REMOVE THE SYSTEM DISK FROM DRIVE A.' .BYTE CR,LF,CR,LF .ASCII 'INSERT A DISK IN DRIVE A THAT CONTAINS A 2.2 CPM IMAGE' .BYTE CR,LF .ASCII 'THAT IS CONFIGURED FOR 20K OF MEMORY.' .BYTE CR,LF,CR,LF .ASCII 'PRESS CARRIAGE RETURN KEY WHEN READY.' .BYTE CR,LF,CR,LF,CR,LF,CR,LF MSGL = .-MSG ; ; MEMORY PARITY ERROR MESSAGE ; MSG1: .BYTE CR,LF .ASCII 'PAR ERR' MSG1L = .-MSG1 ; ; CPM SIZE ERROR MESSAGE ; MSGW: .BYTE CR,LF .ASCII 'THE CPM IMAGE IS THE WRONG SIZE.' .BYTE CR,LF .ASCII 'USE MOVCPM AND SYSGEN TO GENERATE ONE OF' .BYTE CR,LF .ASCII 'THE PROPER SIZE' .BYTE CR,LF,CR,LF MSGWL = .-MSGW ; BEGIN: LXI SP,STACK ;SET UP STACK HELLO: MVI B,MSGL ;SAY HELLO CALL MESG START: LXI SP,STACK ;RESTORE STACK CALL MAININ ;GET INPUT CPI CR JNZ BEGIN JMP BOOT ; ;MESSAGE OUTPUT ROUTINE. ; MESG: LXI H,MSG MESG1: MOV C,M ;GET A CHARACTER INX H ;MOVE POINTER CALL CO ;OUTPUT IT DJNZ MESG1 ;KEEP GOING TILL B=0 RET ; ; ;CRLF BEFORE HLBLK ROUTINE ; CRLFHL: CALL CRLF ; ;PRINT THE CURRENT VALUE OF H&L, ;AND A SPACE. ; HLBLK: CALL DISPHL ; ;PRINT A SPACE ON THE CONSOLE ; SPACE: MVI C,' ' ; ;THIS IS THE MAIN CONSOLE ;OUTPUT ROUTINE. ; CO: IN CONCTL ANI 01H JRZ CO MOV A,C OUT CONDTA RET ; ; CONVERT HEX TO ASCII ; HTA: ANI 0FH ;LOW NIBBLE ONLY ADI 90H DAA ACI 40H DAA MOV C,A RET ; ; ; CONSOLE CARRIAGE RETURN & ; LINE FEED ROUTINE. ; CRLF: PUSH H ;SAVE HL MVI B,2 ;CRLF LENGTH CALL MESG ;SEND CRLF POP H RET ; ;CONSOLE STATUS TEST ROUTINE. ; CSTS: IN MEMSTS ;TEST FOR PAR ERR ANI 0C0H CPI 80H JRNZ CSTS1 ;NO PAR ERR LDA PARFLG ;1ST PAR ERR? CPI 0 JRNZ CSTS1 ;NOT 1ST INR A ;SET PAR FLG STA PARFLG PUSH H PUSH B LXI H,MSG1 ;DISPLAY PAR ERR MVI B,MSG1L CALL MESG1 POP B POP H CSTS1: IN CONCTL ANI 02H MVI A,0FFH RNZ CMA RET ; ; ;PRINT H&L ON CONSOLE ; DISPHL: MOV A,H CALL DISPB MOV A,L DISPB: PUSH PSW RRC RRC RRC RRC CALL HTA2 POP PSW HTA2: CALL HTA JMPR CO ; ;MAIN KEYBOARD ROUTINE ; MAININ: CALL CI ;GET INPUT MOV C,A ;ECHO IT JMPR CO ; ;MAIN CONSOLE INPUT ROUTINE ; CI: CALL CSTS ;TEST FOR INPUT ORA A JRZ CI IN CONDTA ANI 7FH RET ; ; ;PRINTER OUTPUT ROUTINE ; PRINT: IN INOUT ANI 1 JRNZ PRINT MOV A,C ORI 80H OUT INOUT ANI 7FH OUT INOUT ORI 80H OUT INOUT RET ; ; PRINTER STATUS ROUTINE ; PSTS: IN INOUT ANI 1 MVI A,0FFH RZ CMA RET ; ; ;BOOT CPM AND RUN ; BOOT: LXI H,TPLT ;MOVE DOWN JMP VECTORS LXI D,0 LXI B,8 LDIR WBOOT: LXI SP,STACK ;RESTORE STACK LXI H,BEGDAT ;CLEAR SCRATCH RAM LXI D,BEGDAT+1 LXI B,DATSIZ MVI M,0 LDIR LXI H,EPBASE ;SET UP CPM TABLES LXI D,DPBASE LXI B,EPLGTH LDIR LXI H,CCP ;SET DMA ADR SHLD DMAAD MVI A,2 ;SECTOR = 2 STA SECTOR STA LUNIT XRA A CALL LOGDS2 ;LOG ON DRIVE A JNZ START ;LOG ON ERROR LIXD CTBLP ;GET TBL POINTER MVI A,49 ;NO OF SECS STA BTSEC MVI D,25 ;8" SECS ON TRK 0 IN DFLAG ANI 4 ;8" OR 5 1/4" ? JRZ WBOOT8 ;8" MVI D,17 WBOOT8: LDA BTSEC ;SUBTRACT SECTORS SUB D STA BTSEC MVI B,10 BRWAGN: PUSH B LDA SECTOR OUT DSCTR CALL SETUP PUSH D ;SAVE FOR RETRY LHLD DMAAD ;GET DMA ADR BOOTRD: LDA SECTOR ;TEST FOR SIDE 1 ANI 80H MVI A,98H ;READ COMMAND JRZ BTRW3 ;SIDE 0 MVI A,9AH ;SELECT SIDE 1 BTRW3: STA CMND OUT DCMMD BTRW1: LXI B,(128*256)+DDATA INIR DCR D ;LOOP CONTROL JRNZ BTRW1 MVI B,50 BWTDLY: DJNZ BWTDLY MVI A,0D0H ;FORCE INT COMMAND OUT DCMMD ;EXECUTE IT MVI B,10 ;DELAY FRC1: DJNZ FRC1 IN DSTAT ;READ STATUS POP D ;RESTORE LENGTH CALL EOJ ANI 9CH POP B JRZ WBOOTA ;DONE, NO ERRORS DJNZ BRWAGN ;RETRY DERROR: CALL DERR1 ;DISPLAY ERROR JMP START WBOOTA: SHLD DMAAD ;UPDATE DMAAD LDA BTSEC ;ALL SECS DONE? ORA A JZ GOCPM ;DONE MOV A,18(X) ;TEST FOR DOUBLE SIDE ANI 2 MVI A,81H ;SIDE 1 SELECT JRNZ WBOOT9 ;DOUBLE SIDE MVI B,58H ;STEP IN 1 TRACK CALL EOJA LXI H,TRACK ;TRK + 1 INR M MVI A,1 ;SECTOR = 1 WBOOT9: STA SECTOR LDA BTSEC ;BTSEC > SEC/TRK? CMP 0(X) MOV D,A ;REMAINING SECS JC WBOOT8 ;DO THE REST MOV D,0(X) ;SECS PER TRK JMP WBOOT8 ;DO NEXT TRK GOCPM: LDA CCP+2 ;SEE IF RIGHT SIZE ANI 0FCH CPI 34H JNZ WSIZE ;WRONG SIZE LXI H,BIOSCD ;MOVE BIOS VECTORS LXI D,BIOS LXI B,BCDL LDIR LXI H,TBUF ;DEFAULT CPM BUFFER SHLD SEKDMA ;SET DMA ADDRESS LDA CURDSK ;LOG-ON DSK MOV C,A ;SEND TO CPM JMP CCP ;GO TO CP/M WSIZE: MVI B,MSGWL ;SEND ERROR MESG LXI H,MSGW CALL MESG1 JMP BEGIN ; ; ;PROGRAM BIOS JUMP VECTORS ; BIOSCD: JMP BOOT ;COLD BOOT JMP WBOOT ;WARM BOOT JMP CSTS ;CONSOLE STATUS JMP CI ;CONSOLE INPUT JMP CO ;CONSOLE OUTPUT JMP PRINT ;LIST DEVICE JMP CO ;PUNCH DEVICE JMP CI ;READER DEVICE JMP HOME ;MOVE HEAD TO TRK 0 JMP SELDSK ;SELECT DISK JMP SETTRK ;SET TRACK NUMBER JMP SETSEC ;SET SECTOR NUMBER JMP SETDMA ;SET DMA ADDRESS JMP HREAD ;READ DISK JMP HWRITE ;WRITE DISK JMP PSTS ;LIST STATUS JMP SECTRN ;SECTOR TRANSLATE BCDL = .-BIOSCD ; ;JUMPS AT START OF MEMORY AND IOBYTE ; TPLT: JMP WBOOTE IOBYT: .BYTE 0BDH .BYTE 0 JMP BDOS ; ; DERRM: .ASCII 'DSKTRKSCTSTSCMDDMA' ; ; ;DISPLAYS ALL DISK PARAMETERS ; DERR1: PUSH B ;SAVE REGISTERS PUSH D PUSH H LXI H,DERRM ;POINT TO NAMES LXI D,DISKNO ;POINT TO PARAMETERS CALL CRLF ;DISPLAY CRLF MVI C,5 ;SET TALLY DERR2: MVI B,3 PUSH B ;SAVE BC CALL MESG1 ;DISPLAY NAME CALL SPACE ;DISPLAY SPACE PUSH H ;SAVE HL LDAX D ;GET DATA INX D ;STEP TO NEXT CALL DISPB ;DISPLAY DATA CALL SPACE ;DISPLAY SPACE POP H ;GET HL POP B ;GET BC DCR C ;TALLY - 1 JRNZ DERR2 ;CONTINUE MVI B,3 ;DISPLAY NAME CALL MESG1 CALL SPACE ;DISPLAY SPACE LHLD DMAAD ;LAST PARAMETER CALL DISPHL ;DISPLAY IT POP H ;RESTORE REGISTERS POP D POP B LDA STATUS ORA A RET ; ; ; ;SELECT DISK GIVEN BY REGISTER C ; SELDSK: LXI H,0 ;ERROR RETURN CODE MOV A,C STA SEKDSK ;STORE DSK NO. CPI 4 ;MUST BE 0,1,2,OR 3 RNC ;INVALID DSK NO. PUSH X ;LOG ON DISK PUSH H CALL LOGDS2 POP H RNZ ;ERROR RETURN POP X LDA SEKDSK ;GET DISK NO. MOV L,A MOV H,B DAD H ;*2 DAD H ;*4 DAD H ;*8 DAD H ;*16 XCHG LXI H,DPBASE DAD D ;HL=DPBASE+(DISKNO*16) RET ; LOGDSK: LDA DISKNO LOGDS2: MOV C,A ;SAVE DSK NO IN C INR A LXI X,DP0 ;BUILD TBL ADR IN X LXI D,128 DABLD1: DCR A JRZ DABLD2 DADX D JMPR DABLD1 DABLD2: SIXD CTBLP MVI A,0C0H ORA C STA HSELCD ;STORE SELECT CODE LXI H,DSKSEL ;SEE IF NEW DISK MVI B,0 DAD B MOV A,M ORA A JRNZ DBPARM ;NOT NEW DISK CMA MOV M,A ;MARK AS USED LDA HSELCD ;GET SEL CODE OUT DCNTL ;SEL DRIVE CALL EOJB ;RESTORE DRIVE ANI 80H ;TEST FOR NOT READY JNZ DERR1 ;NOT RDY ERROR MVI B,10 ;RETRY COUNT NTAGN: PUSH B MVI A,1 ;SELECT SEC 1 OUT DSCTR MOV D,A ;SEC SIZE=128 LHLD CTBLP LDA HSELCD ;GET SELECT CODE OUT DCNTL MVI A,8CH ;READ OP CALL RDAT ;READ TABLES POP B ;RETRY COUNT ORA A ;TEST FOR ERRORS JRZ DBPARM ;DONE, NO ERRORS DJNZ NTAGN ;RETRY JMP DERR1 ;DISP PARAMETERS DBPARM: MOV L,15(X) ;GET BYTES/SEC MOV H,16(X) DAD H MOV A,H STA HSTBLK ;CPM SEC/PHY SEC DCR A STA SECMSK ;SECTOR MASK MOV B,2(X) ;GET BLK SHIFT FACTOR MVI A,1 ;CPM ALOC SIZE/128 BLKCAL: RLC DJNZ BLKCAL STA BLKCNT XRA A ;RETURN, NO ERRORS RET ; ; ;SET TRACK GIVEN BY REGISTER C ; SETTRK: MOV A,C STA SEKTRK RET ; ; ;SET SECTOR GIVEN BY REGISTER C ; SETSEC: MOV A,C STA SEKSEC RET ; ; ;TRANSLATE THE SECTOR GIVEN BY BC USING THE ;TRANSLATE TABLE GIVEN BY DE ; SECTRN: PUSH X ;SAVE X LXI H,0FFECH ;TBL POINTER-20 DAD D PUSH H ;POINTER TO X POP X MOV A,18(X) ;TEST FOR DBL SIDE ANI 2 JRZ SECTR1 ;SINGLE SIDE XRA A ;DOUBLE SIDE MOV L,0(X) ;GET CPM SEC/TRK MOV H,A SRLR L ;DIVIDE BY 2 DCR L ;SUBTRACT 1 DSBC B ;SEC ON SD 0 OR 1? JRNC SECTR1 ;SECTOR ON SIDE 0 MOV A,L ;BUILD ADR FOR SD 1 CMA MOV C,A MVI A,80H ;SIDE SELECT = SD 1 SECTR1: XCHG ;HL=TRANS TBL DAD B ;ADD SEC INDEX ORA M ;OR SIDE SELECT MOV L,A ;HL = TRANS(SECTOR) MVI H,0 POP X ;RESTORE X RET ; ; ;SET DMA ADDRESS GIVEN BY REGISTERS B AND C ; SETDMA: SBCD SEKDMA ;SAVE THE ADDRESS RET ; ; ;MOVE TO THE TRACK 00 POSITION OF CURRENT DRIVE ; HOME: LDA HSTWRT ;TEST FOR WRITE PEND ORA A RNZ STA HSTACT ;CLEAR HSTACT FLAG RET ; ; ;DEBLOCKING ROUTINES ; HREAD: MVI A,1 ;SET READOP=READ STA READOP INR A STA WRTYPE ;TREAT AS UNALOC JMP ALLOC HWRITE: XRA A ;SET READOP=WRITE STA READOP MOV A,C ;SAVE WRITE TYPE STA WRTYPE CPI WRUAL ;UNALOC WRITE? JRNZ CHKUNA ;NOT UNALOC WRT LHLD SEKDSK ;UNADSK=SEKDSK SHLD UNADSK ;UNATRK=SEKTRK LDA BLKCNT ;RECORDS/CPM BLOCK STA UNACNT LDA SEKSEC ;UNASEC=SEKSEC STA UNASEC LHLD CTBLP ;SAVE TBL ADR SHLD UTBLP CHKUNA: LDA UNACNT ;ANY UNALOC REMAIN? ORA A JRZ ALLOC ;NONE REMAIN DCR A ;UNACNT-1 STA UNACNT LHLD UNADSK ;SEK = UNA? LDA SEKSEC MOV C,A LDA UNASEC CALL CMP3 JRNZ ALLOC ;NOT EQUAL LHLD UTBLP ;GET TBL ADR MOV C,M ;CPM SEC/TRK MVI B,0 LXI D,20 ;SEC TRANSL TBL DAD D LDA UNASEC ;SEARCH FOR UNASEC CCIR ;END OF TRK? JO NOOVF ;NOT END LXI H,UNATRK ;UNATRK + 1 INR M MVI A,1 ;UNASEC = 1 JMPR OVF NOOVF: MOV A,M ;GET NEXT SECTOR OVF: STA UNASEC ;STORE NEXT UNASEC XRA A ;RESET RSFLAG JMPR ALLOC2 ALLOC: XRA A ;SET UNACNT=0 STA UNACNT INR A ;SET RSFLAG ALLOC2: STA RSFLAG ;NEED PREREAD LXI H,DBUF ;SET DMA ADR SHLD DMAAD RWOPER: PUSH X LDA SEKDSK ;LOG ON SEKDSK CALL LOGDS2 LDA SEKSEC ;COMPUTE PHY SEC ADR MOV C,A ANI 80H ;GET SIDE SELECT STA SIDSEL ;SAVE IT MOV A,C ;MASK OFF SIDE SEL ANI 7FH MOV C,A LDA HSTBLK DCR C PSEC1: RAR JRC SECDN SRLR C JMPR PSEC1 SECDN: INR C LDA SIDSEL ;GET SIDE SELECT ORA C ;OR IT WITH SECTOR STA SEKHST ;SAVE IT LXI H,HSTACT ;TEST & SET HSTACT FLG MOV A,M MVI M,1 ;SET FLAG ORA A ;TEST FLAG JRZ FILHST ;NOT SET LHLD DISKNO ;SEEK=HOST? LDA SEKHST MOV C,A LDA SECTOR CALL CMP3 JRZ MATCH ;SAME LDA HSTWRT ;HOST WRITTEN? ORA A CNZ DWRITE ;WRITE HOST BUF FILHST: LHLD SEKDSK ;GET SET TO FILL BUF SHLD DISKNO LDA SEKHST ;PHYSICAL SEC ADR STA SECTOR LDA RSFLAG ;RSFLAG SET? ORA A CNZ DREAD ;YES DO READ XRA A STA HSTWRT ;NO PENDING WRT MATCH: LDA SEKSEC ;MASK BUF SEL BITS DCR A MOV L,A LDA SECMSK ANA L MOV H,A ;BUF SEL BITS X 128 MVI L,0 SRLR H RARR L LXI D,DBUF ;ADD BUFFER INDEX DAD D LDED SEKDMA ;GET SEEK DMA ADR LXI B,128 ;SIZE OF MOVE LDA READOP ;READOP=1? ORA A JRNZ RWMOVE ;YES MOVE READ DATA MVI A,1 STA HSTWRT ;SET HOST WRITTEN XCHG ;MOVE WRITE DATA RWMOVE: LDIR ;MOVE THE DATA LDA WRTYPE ;WRITE TO DIRECTORY? CPI WRDIR LDA ERFLAG ;GET ERROR FLAG JRNZ RWD ;NOT DIR WRT ORA A ;ERRORS? JRNZ RWD ;DONE IF ERRORS XRA A STA HSTWRT ;RESET HSTWRT FLAG CALL DWRITE ;WRITE TO DIRECTORY LDA ERFLAG ;GET ERROR FLAG RWD: POP X RET ;DONE CMP3: LDED SEKDSK ;GET SEKDSK & SEKTRK ORA A DSBC D ;COMPARE HL & DE RNZ ;RETURN NOT EQUAL CMP C ;COMPARE A & C RET ;DONE ; ; ;DISK READ AND WRITE ROUTINES ; DREAD: MVI A,1 ;SET READ FLAG JMPR STRFLG DWRITE: XRA A ;SET WRITE FLAG STRFLG: STA RWFLG ;SAVE IT FOR LATER USE DORDWT: MVI B,10 ;NUMBER OF RETRIES AGN: PUSH B ;SAVE BC CALL SEEK ;SEEK THE TRACK CZ RDWR ;NO ERROR STA ERFLAG ;STORE ERROR FLAG READ3: POP B ;GET ERROR RETRY COUNT RZ ;RETURN IF NO ERRORS DJNZ AGN ;DO A RETRY JMP DERR1 ;DISP PARAMETERS ; RDWR: MOV E,A ;SAVE COMMAND LDA RWFLG ORA A MOV A,E ;REGET THE COMMAND JRZ WRDAT ;WRITE IF ZERO RDAT: OUT DCMMD ;DISK COMMAND PORT STA CMND READ1: LXI B,(128*256)+DDATA READ2: INIR DCR D ;LOOP CONTROL JRNZ READ1 CALL EOJ ANI 9CH ;ISOLATE READ ERROR BITS RET ; WRDAT: ORI 20H ;ADD WRITE COMMAND OUT DCMMD ;DISK COMMAND PORT STA CMND WRT1: LXI B,(128*256)+DDATA OUTIR DCR D ;LOOP CONTROL JRNZ WRT1 JMPR EOJ EOJB: MVI B,8 ;BASIS OF RESTORE COMMAND EOJA: IN DFLAG ;STEP RATE BITS ANI 3 ORA B ;ADD ON THE COMMAND STA CMND OUT DCMMD ;DO THE COMMAND MVI B,128 ;DELAY SKDLY: DJNZ SKDLY EOJ: IN DSTAT ;TEST FOR INTRQ ANI 1 JRNZ EOJ ;WAIT FOR INTRQ CALL DWAIT ;DISABLE WAITS EOJ1: IN DSTAT ;GET THE DISK STATUS STA STATUS ANI 0FCH RET ; SEEK: LDA DISKNO ;GET DISK NO LXI H,LUNIT ;POINT TO LAST UNIT CMP M ;SEE IF SAME MOV M,A ;SAVE THIS UNIT JZ SEEK1 ;ALREADY LOGGED IN CALL SETUP LXI H,IDSV MVI D,1 MVI A,0C4H ;READ ADR COMMAND OUT DCMMD STA CMND LXI B,(6*256)+DDATA CALL READ2 IDRD1: LDA IDSV OUT DTRCK ;SET THE TRACK SEEK1: CALL LOGDSK ;LOG ON DISKNO RNZ ;ERROR RETURN LDA SECTOR ;SET THE SECTOR OUT DSCTR ;DISK SECTOR PORT SEEK2: IN DTRCK ;DISK TRACK PORT MOV C,A ;SAVE IT LDA TRACK ;GET DESIRED TRACK CMP C JRZ RDWRT ;NO SEEK NEEDED OUT DDATA ;SET THE TRACK MVI B,18H ;SEEK COMMAND CALL EOJA ;DO THE SEEK ANI 80H ;ERROR MASK RNZ ;SEEK ERROR RDWRT: CALL SETUP ;GET READY IN DFLAG ANI 10H ;HEAD LOADED? MVI A,4 JRZ RDWRT1 ;JUMP IF NOT XRA A ;RESET HEAD LD FLAG RDWRT1: ADI 88H ;READ COMMAND MOV C,A ;SAVE IT LDA TRACK ;TEST FOR TRK 0 ORA A MVI D,1 JRZ RDWRT2 ;TRK 0 = SD MOV L,15(X) ;GET SECTOR SIZE MOV H,16(X) DAD H MOV D,H RDWRT2: LHLD DMAAD ;GET DMA ADDRESS RDWRT3: LDA SECTOR ;TEST FOR SIDE 1 ANI 80H MOV A,C ;REGET COMMAND RZ ;SIDE 0 ORI 2 ;SELECT SIDE 1 CMP A ;CLEAR THE FLAGS RET ; ; ;SELECTS DRIVE ; SETUP: PUSH B LDA HSELCD ;GET SEL CODE MOV C,A IN DFLAG ANI 40H ;TEST FOR TRK 0 JRNZ SETUP2 ;NOT TRK 0 LDA SECTOR ;TEST FOR SIDE 1 ANI 80H JZ SETUP3 ;TRK 0, SIDE 0 IS SD SETUP2: MOV A,18(X) ;TEST FOR SD/DD ANI 80H JRZ SETUP4 ;THIS DSK IS SD MVI A,0BFH ;SET DD ANA C MOV C,A SETUP4: LDA SECTOR ;TEST FOR SIDE 1 ANI 80H JRZ SETUP3 ;SIDE 0 MVI A,20H ;SELECT SIDE 1 ORA C MOV C,A SETUP3: MOV A,C OUT DCNTL POP B RET ; ; ;DISABLE WAIT STATES ; DWAIT: LDA HSELCD ;RESET AUTO-WAIT ANI 7FH OUT DCNTL RET ; ; EPBASE: ;DISK PARAMETER HEADER FOR DISK 00 .WORD TD0,0 .WORD 0,0 .WORD DIRBF,DP0 .WORD CHK00,ALL00 ;DISK PARAMETER HEADER FOR DISK 01 .WORD TD1,0 .WORD 0,0 .WORD DIRBF,DP1 .WORD CHK01,ALL01 ;DISK PARAMETER HEADER FOR DISK 02 .WORD TD2,0 .WORD 0,0 .WORD DIRBF,DP2 .WORD CHK02,ALL02 ;DISK PARAMETER HEADER FOR DISK 03 .WORD TD3,0 .WORD 0,0 .WORD DIRBF,DP3 .WORD CHK03,ALL03 EPLGTH = .-EPBASE ; ; ;SCRATCH RAM AREA FOR BDOS USE ; BEGDAT = BIOS+BCDL ;BEGINNING OF DATA AREA .LOC BEGDAT DBUF: .BLKB 1024 ;DEBLOCK BUFFER DP0: .BLKB 20 TD0: .BLKB 108 DP1: .BLKB 20 TD1: .BLKB 108 DP2: .BLKB 20 TD2: .BLKB 108 DP3: .BLKB 20 TD3: .BLKB 108 DIRBF: .BLKB 128 ;SCRATCH DIRECTORY AREA ALL00: .BLKB 128 ;ALLOCATION VECTOR 0 ALL01: .BLKB 128 ;ALLOCATION VECTOR 1 ALL02: .BLKB 128 ;ALLOCATION VECTOR 2 ALL03: .BLKB 128 ;ALLOCATION VECTOR 3 CHK00: .BLKB 64 ;CHECK VECTOR 0 CHK01: .BLKB 64 ;CHECK VECTOR 1 CHK02: .BLKB 64 ;CHECK VECTOR 2 CHK03: .BLKB 64 ;CHECK VECTOR 3 DSKSEL: .BLKB 4 ;DISK ACCESS TABLE DISKNO: .BLKB 1 ;DISK PARAMATERS TRACK: .BLKB 1 SECTOR: .BLKB 1 STATUS: .BLKB 1 CMND: .BLKB 1 RWFLG: .BLKB 1 DMAAD: .BLKB 2 PARFLG: .BLKB 1 ;PAR ERROR FLAG HSELCD: .BLKB 1 ;HOST SELECT CODE HSTBLK: .BLKB 1 ;CPM SEC/PHY SEC BLKCNT: .BLKB 1 ;REC/CPMBLK SECMSK: .BLKB 1 ;SECTOR MASK WRTYPE: .BLKB 1 ;WRITE TYPE UNACNT: .BLKB 1 ;UNALOC REC COUNT UNADSK: .BLKB 1 ;LAST UNALOC DISK UNATRK: .BLKB 1 ;LAST UNALOC TRACK UNASEC: .BLKB 1 ;LAST UNALOC SECTOR SEKDSK: .BLKB 1 ;SEEK DISK SEKTRK: .BLKB 1 ;SEEK TRACK SEKSEC: .BLKB 1 ;SEEK SECTOR SEKHST: .BLKB 1 ;PHYSICAL SEC ADR SIDSEL: .BLKB 1 ;SIDE SELECT STORAGE HSTWRT: .BLKB 1 ;HOST WRITTEN FLAG HSTACT: .BLKB 1 ;HOST ACTIVE FLAG RSFLAG: .BLKB 1 ;READ SECTOR FLAG READOP: .BLKB 1 ;1=READ, 0=WRITE LUNIT: .BLKB 1 ;LAST SELECTED DRIVE ERFLAG: .BLKB 1 ;ERROR FLAG RFLAG: .BLKB 1 ;CPM READ FLAG BTSEC: .BLKB 1 ;NO OF BOOT SECS SEKDMA: .BLKB 2 ;SEEK DMA ADDRESS CTBLP: .BLKB 2 ;CURRENT TBL ADR UTBLP: .BLKB 2 ;UNALOC TBL ADR HLSTR: .BLKB 2 DPBASE: .BLKB EPLGTH ;CPM DISK PARAMETER HEADERS IDSV: .BLKB 6 ; DATSIZ = .-BEGDAT ;SIZE OF SCRATCH RAM ; ; ;END OF PROGRAM ; ; ; .END  .BLKB 2 ;SEEK DMA ADDRESS CTBLP: .BLKB 2 ;CURRENT TBL ADR UTBLP: .BLKB 2 ;UNALOC TBL A