b ;*****************************************************************************; ; THE "WAVE-MATE" CACHE BIOS FOR THE "BULLET" SINGLE BOARD COMPUTER. .; ; FIRST VERSION BY ARCY FOR ARCHIVE COMPUTER SERVICES -- 24 MAY 82. REVLEV EQU 'C7' ;*****************************************************************************; • MODIFICATION HISTORY ... (FIRST RUNABLE VERSION : 02/JUNE/82) 01:DEC:82 - ; 16:OCT:82 25:SEP:82 - ; 18:SEP:82 15:AUG:82 - ; 11:AUG'82 25:JUL:82 - ; 12:JUN:82 ; 10:JUN:82 - ; 07:JUN:82 - ; 02:JUN:82 - ; DAYS EQU UNCONDITIONAL RELATIVE JUMP MNUMONIC CHANGED AND "HOOK5" ADDED. - "MORROW" 2 SIDED DISC FORMAT CORRECTED. UNDEFINED LABLE FIXED. MEMORY DRIVE (DRIVE "M:") ADDED - 48K MAXIMUM. - WARMBOOT FROM RAM. "NOT READY" ERROR TRAF'. "SELECT" BUG FIXED. REAL TIME CLOCK ADDED, HRS:MIN:SEC AT 42H;41H;40H. - CTS HARDWARE HANDSHAKE ADDED ON SERIAL CHANNEL "B" ERROR IN PARALLEL PRINTER STATUS CORRECTED. - FULL I/O BYTE DECODE, REMOTE CONSOLE, AND COLD-BOOT AUTO COMMAND CALCULATION OF SKEW FACTORS IMPLEMENTED. AUTO DISC FORMAT SELECT AND PARAM BLOCK REVISION. COLD BOOT CODE MOVED INTO UNINITIALISED DATA AREA. 335 ;DAYS SINCE Ist Jan 1982 TO LAST CODE UPDATE. i**************e*************************************************************** MACLI B Z80 ;FOR USE WITH D.R'S "MAC" ASSEMBLER. MACLI B MINICODE;FOR O.E.M. QUAD DISC SYSTEMS. TITLE `ARCHIVE COMPUTER SERVICE S' ;****************************************************************************** LOCATE THE BIOS EXECUTION ADDRESS DEPENDANT ON THE CP/M SIZE. SIZE EQU 64 ;SIZE OF CP/M IN "K" BYTES CCP EQU (SIZE*1024)-2400H;CPM LOAD ADDRESS (9K TOTAL OVERHEAD) = 7i)c00 BDOS EQU CCP+0800H ;SYSTEM LOAD ADDRESS (2K FOR CCP) 11-:.4r» BIOS BDOS+0E0OH ;BIOS LOAD ADDRESS (3.75K FOR BDOS) = F200 SYSIZE EQU BIOS-CCP ;*******************Y********************************************************** ; GENERAL SYSTEM EQUATES AND EXTERNAL ADDRESSES. 00000H ;LOCATION OF TRACK CACHE IN 2ND BANK. CACH+(8*1024) ;CCP+BDOS IN BANK 2 (ALLOW 8K FOR TRACK BUFFER) 128 64 02.T.0 SECONDS SECS+1 ; " MINUTES MINS+1 " HOURS. ;DAYS SINCE 1ST JAN 1982. 05 03 04 CACH EQU WBHOLD EQU DEFBUF EQU SECS EQU MINS EQU HRS EQU DATE EQU BDOSVEC EQU IOBYTE EQU CDISK EQU ESC EQU EOF DC3 EQU 19 DC1 EQU 17 ACR EQU 13 CDISK EQU 04 ESC EOU 27 EOF EQU 24 DC3 EQU 19 DC1 EQU 17 ACR EQU 13 ALF EQU 10 BEL EQU ; ****************************************************************************** ; HARDWARE PORT EQUATES. DARTAD EQU 0 ;DART 'A' DATA DARTAC EQU 1 CONTROL DARTBD EQU 2 ; " 'B' DATA DARTBC EQU 3 ; " CONTROL PIOAD EQU 4 ;PIO 'A' DATA PIOBD EQU 5 ; " 7E7 H PIOAC EQU 6 ; 4 'A' CONTROL PIOBC EQU 7; H 3B, h CTC0 EQU 8 ;COUNTER TIMER 0 CTC1 EQU 9 ; " " 1 CTC2 EQU OAH ; II Pi 7 CTC3 EQU 0BH ; . FE 3 FCOM EQU 10H ;FLOPPY DISC COMMAND/STATUS FTRK EQU 11H ; . " TRACK REGISTER FSEC EQU 12H i II " SECTOR REGISTER FDATA EQU 13H ; H U DATA FORT ZDMA EQU 14H ;DMA CONTROLLER DISCM EQU 16H ;DISC HARDWARE CONTROL MUXM EQU 17H ; MEMORY MULTIPLEXER CONTROL DSEP EQU 18H ;DISC DATA SEFERATOR CONTROL HWSTAT EQU 19H ;PORT FOR HEADS-LOADED ETC.. BANK EQU IAH ;MEMORY BANK SELECT FORT ; *************M************************************************************** ; CONTROL BOOLEANS FOR DISC DRIVES SUPPORTED IN THIS COMPILE. (MAXIMUM 4). FALSE EQU 00 TRUE EQU NOT FALSE DOAUTO EQU TRUE ;TRUE FOR "OBEY COLD-START COMMAND" MAXI EnU FALSE ;TRUE FOR 8" DRIVES MINI EQU TRUE ;TRUE FOR 5" DRIVES BOTH EQU MAXI AND MINI ;A: & B: ARE MAXI, C: & D: ARE MINI. DRIVES EQU 4 i****************************************************************************** ; DRIVE STEP RATE EQUATES: VALUE MAXI MINI 0 3Ms 6Ms 1 6Ms 12Ms ; 2 10Ms 20Ms ; 3 15Ms 30Ms MAXIRATEEQU 0 ;FOR "YE DATA" MAXI DRIVES MINIRATEEQU 0 ;FOR "MPI" MINI DRIVES ;****************************************************************************** ; I/O BYTE CONTROL, DEVICES IMPLEMENTED ARE: CON: CRT: -- VIDEO CONSOLE VIA DART CHANNEL "A' CON: UC1: -- REMOTE DIAGNOSTICCONSOLE, DART CHANNELS "A" u n B LST: TTY: -- SERIAL PRINTER, READY/BUSY HANDSHAKE, PART CHANNEL "B" LST: LPT: -- PARALLEL "CENTRONIX" LIKE PRINTER. PIO. '7? 1 ; CCM: =CPT ST: PT: + LJ1. III. ZGRIML— rMINICM, MCMIJI/ZUT rIMNIJMMINC5 MMM1 —1J- LST: LPT: -- PARALLEL "CENTRONIX" LIKE PRINTER, PIO. ; INITIO EQU ;****************************************************************************** ; THE FOLLOWING IS THE CP/M JUMP VECTOR TABLE. lT MUST NOT BE ALTERED. ORG BIOS JP BOOT ;COLD BOOT JP WBOOT ;WARM BOOT JP CONSTAT ;GET CONSOLE STATUS JP CONIN ;GET CONSOLE INPUT JP CONOUT ;WRITE TO CONSOLE JP LIST ;OUTPUT TO PRINTER DEVICE JP PUNCH ;PUNCH OUTPUT JP READER ;READER INPUT JP HOME ;HOME DISC DRIVE JP SETDSK ;SELECT DISC DRIVE JP SETTRK ;SET DISC TRACK JP SETSEC ;SET DISC SECTOR JP SETDMA ;SET TRANSFER ADDREDD JP READ ;READ DISC JP WRITE ;WRITE TO DISC JP LISTST ;TEST LIST STATUS JP SECTRAN ;LOGICAL TO PHYSICAL SECTOR CONVERT ;****************************************************************************** ; POINTERS TO VALUES WHICH CERTAIN EXTERNAL UTILITIES WILL NEED TO ACCESS. ; DEFW 'RC' ;AUTHORS INITIALS ARE A VERSION CHECK WORD. IOVALU: DEFB INITIO ;USED AT COLD—START TO INITIALIZE ASSIGNMENTS DEFW BPSA ;ADDRESS OF BAUD RATE "A" DEFW BPSB • ,, " BAUD RATE "B" DEFW HOOK5 " 5" TABLE (ZERO IF ABSENT). DEFW DR0 9 DISC DRIVE CHARACTERISTICS DEFW MINIVAL ; " MOTOR OFF TIMEOUT COUNT ; ;*************************k**************************************************** ; ; THESE ARE THE VECTORED INTERRUPT DISPATCH ADDRESSES. MOST POINT TO A ; SIMPLE IDLE ROUTINE THAT ENABLES INTERRUPTS AND RETURNS. ; VIR1: DEFW IDARTA ;CONSOLE INPUT SERVICER DEFW IDLE ;DO NOTHING DEFW IDLE ; 0 /I DEFW IDLE ; „ u DEFW IDLE a IP e u DEFW IDLE • II ) PI DEFW IDLE s I; 9 „ DEFW IDLE ° " e H DEFW IDLE • IP 5 „ DEFW IDLE . ,, 9 », DEFW IDLE r Ii A eI DEFW IDLE ; „ n DEFW IDLE ; 16 11 DEFW IDLE • 16 9 u DEFW IDLE . ,, 9 9e DEFW IDLE • ii 5 H VIR2: DEFW IDLE ;CTC CHANNEL 0 DEFW IDLE • u ; i. I DEFW IDLE ; „ . 2 DEFW IRTC ; „ „ 3 DEFW IDLE ;DO NOTHING DEFW IDLE /I ; 10000001B ; CON:=CRT: LST:=LPT: • ;W***4-****************44.444-4-4444-444-444444444444444-444444 DEFW IDLE ;DO NOTHING DEFT IDLE ;****************************************************************************** CONSOLE INPUT VECTORS CONIN: LD B,1 CALL DISPAT DEFW 0 ;TTY: DEFW CRTIN ;CRT: DEFW RDRIN ;BAT: DEFW REMIN ;UC1: ;****************************************************************************** ; CONSOLE STATUS VECTORS CONSTAT: LDB,1 CALL DISPAT DEFW 0 ;TTY: DEFW CRTSTAT ;CRT: DEFW RDRST ;BAT: DEFW REMSTAT ;UC1: ;***********************e44-**************************************************** CONSOLE OUTPUT VECTORS CONOUT: LD B,1 CALL DISPAT DEFW 0 ;TTY! DEFW CRTOUT ;CRT: DEFW LIST ;BAT: DEFW REMOUT ;UC1: ************************4-44************************************************** ; READER DEVICE INPUT VECTORS READER: LD B,3 CALL DISPAT DEFW RDRIN ;TTY: DEFW 0 ;PTR: DEFW 0 ;URI: DEFW 0 ;UR2: ;**************************************************************************** ; PUNCH DEVICE OUTPUT VECTORS PUNCH: LD B,5 CALL DISPAT DEFW SLIST ;TTY: DEFW 0 ;PTP: DEFW 0 ;UP1: DEFW 0 ;UP2: *****i(************************************************************************ ; LIST DEVICE OUTPUT VECTORS LIST: LD B,7 CALL DISPAT Lle1 MeVIUt Vt.LIUKb LIST: LD B,7 CALL DISPAT DEFW SLIST ;TTY: DEFW CRTOUT ;CRT: DEFW PLIST ;LPT: DEFW 0 ;ULI: ;****************************************************************************** ; LIST DEVICE STATUS VECTORS LISTST: LD B,7 CALL DISPAT DEFW SLISST ;TTY: DEFW CRTSTAT ;CRT: DEFW PLISST ;LPT: DEFW 0 ;ULI: ;****************************************************************************** ; I/O BYTE DISPATCHER. ON ENTRY, THE TOP OF STACK POINTS TO A 4 WORD TABLE ; OF SERVICE ROUTINES. HAS A ROTATE COUNT TO USE FOR MASKING. DISPAT: LD A,(IOBYTE) RLCA ;GET AND PRE-CONDITION THE I/O BYTE DISPAL: RRCA DJNZ DISPAL AND 3 ;USE THE I/O VALUE AS AN OFFSET ADD A LD E,A LD D,0 POP HL ;ADD TO THE TABLE BASE ADD HL,DE LD E,(HL) ;LOAD THE SERVICE ROUTINE ADDRESS INC HL LD D,(HL) ;THEN GO THERE EX DE, HL JP (HL) ;****************************************************************************** ; REMOTE CONSOLE INPUT. BOTH SERIAL CHANNELS ARE TESTED IN ROTATION UNTIL ; ONE OF THE USERS HAS SOMETHING TO SAY. REMIN: CALL RDRST JRNZ RDRIN CALL, CRTSTAT JRZ REMIN ;****************************************************************************** GET THE NEXT CHARACTER FROM THE CONSOLE FIFO QUEUE BUFFER. WAIT IF NEED BE. CALL CRTSTAT ;WAIT UNTIL THERE IS JRZ CRTIN ; DATA IN THE QUEUE LD A, (BC) AND 7FH ;GET THE DATA AND STRIP PARITY LD HI ,CBUrTnr ;SEE IF THE CHAR CAME FROM THE DSBC B ; LAST BYTE OF THE QUEUE JRZ RES@ INC BC ;IF NOT, POINT TO THE NEXT POSY JR SET! ; INTHE QUEUE t n BC,FIFnBUP ;LOAD THE BEGINNING OF THE QUEUE '7.7,77 717-4.7 !,-zr7T tnrATT,-^m c-ne C'•'T (rnicii= c.=An RESQ: SETQ: JRZ RES INC BC ;IF NOT, POINT TO THE NEXT POS'(' JR SET0: ; INTHE QUEUE LD Bfl,FIFnBU ;LOAD THE BEGINNING OF THE QUEUE SBCD rJTAIL ;SET LOCATION FOR NEXT QUEUE READ RET ;*************************************J(**************************************** ; INPUT STATUS FOR DART CHANNEL "B" RDRST: IN A,DARTBC RRA ;SEE IF DATA IS AVAILABLE SEC A RET ;****************************************************************************** ; GET DATA FROM DART CHANNEL "B" CALL RDRST JRZ RDRIN IN A,DARTBD AND 0177FH RET ;****************************************************************************** ; REMOTE CONSOLE OUTPUT. ALL CHARACTERS ARE SENT TO BOTH DART SERIAL CHANNELS. REMOUT: CALL SLIST ;DO "B" THEN FALL THRU TO "A" ;****************************************************************************** ; CONSOLE OUTPUT ROUTINE. CHARACTER TO PRINT IS IN REGISTER . CRTOUT: IN A,DARTAC AND 4 JRZ CRTOUT ;WAIT UNTIL THE LAST CHAR IS GONE LD A,C ; THEN OUTPUT THIS ONE. OUT DARTAD,A RET ;****************************************************************************** ; REMOTE CONSOLE STATUS. BOTH DART CHANNEL INPUTS ARE SAMPLED FOR DATA READY. ; CHANNEL "B" IS ASSUMED CONNECTED TO A MODEM AND IS TESTED FIRST. REMSTAT: CALL RDRST ;TEST DART CH "B", IF NOT READY, RET NZ ; FALL THROUGH TO CH "A". ;**************.*******v-******************************************************** ; SEE IF ANY DATA IS IN THE CONSOLE FIFO QUEUE. ON EXIT 00 = NO, FF = YES. CRTSTAT: XOR LD HL,(QHEAD) ;GET WHERE INPUT PUTS THEM LBCD QTAIL ; AND WHERE OUTPUT TAKES 'EM. DSBC RET Z ;IF EQUAL THE OUEUE'S EMPTY LD A,0FFH IF NOT EMPTY RETURN AN FF. RET ;************-*****************************e************************************ LD A,OFFH ; IF NOT EMPTY RETURN AN FF. RET ;************>***************************************************************** ; ANY INPUT CHARACTERS WILL VECTOR TO HERE WHEN HIGHER PRIORITY DEVICES ALLOW THE INTERRUPY DAISY CHAIN. THIS ROUTINE MAY BE INTERRUPTED TOO. IDARTA: SSPD SPHOLD1 ;SAVE PROGRAMS STACK POINTER LD SP,REGSAVE ; AND SET OUR OWN PUSH AF ; THEN SAVE ALL REGISTERS PUSH BC PUSH DE PUSH HL IN A,DARTAD ;GET AND SAVE THE DATA PUSH AF LBCD QHEAD ;GET THE LOCATION OF THE LAST LD D,B ; CHAR TO ENTER THE FIFO QUEUE LD E,C LD HL,CBUFTOP ;SEE IF lT IS AT THE TOP LIMIT XOR A DSBC B ;IF SO THIS CHAR MUST GO JRZ @RES ; TO THE START OF THE QUEUE INC BC ;ELSE JUST POINT TO THE NEXT HOLE JR QSET QRES: LD BC,FIFOBUF ;START OF FIFO ADDRESS QSET: LD HL,(QTAIL) POP AF ;GET THE CHAR BACK OR A ;WE DON'T STORE NULLS DSBC B ; NOR DO WE ALLOW OVEP-RUNS JRZ NULCHR LD (DE),A ;PUT lT IN THE QUEUE SBCD QEAD ; AND UPDATE THE POINTER NULCHR: POP HL POP DE POP PC POP AF LSPD SPHOLD1 ;RESTORE ALL REGS FOR EXIT ;****************************************************************************** THIS IS THE GENERAL "DO NOTHING" INTERRUPT SERVICE CODE. IDLE: EI RETI ;****************************************************************************** ; PARALLEL STATUS ROUTINE. THE RETURNED VALUE REFLECTS THE CENTRONIX LINE "I/O BUSY". ON EXIT, REGISTER. VALUES 0.. "DRIVES" ARE ACCEPTED AND THE RELEVENT DISC PARAMETER ENTRY ADDRESS RETURNED IN SETDSK: LD A,C LD HL,0 ;00 IS AN ERROR RETURN CP 'M'-'A' JRNZ SETRST ;REQUEST FOR DRIVE M: LD HL,DPEM LD (SEKDSK),A RET SETRST: CP DRIVES ;IS THE UNIT LEGAL RET NC )D A,E ;SEE IF CP/M HAS LOOKED AT THIS AND A ; DISC RECIENTLY. LD L,C ADD HL,HL ; (*16) ADD HL,HL ADD HL,HL ADD HL,HL ;MAKE IT A 16 BYTE OFFSET LD DE,DPE0 ; TO THE PARAM ENTRY TABLES ADD HL,DE ;RETURN THE PARAM ENTRY LD A,C ;EXIT IF WE KNOW ABOUT THIS DISC LD (SEKDSK),A ;SAVE SELECTED UNIT RET NZ PUSHI X ;SAVE INDEX REGISTER <%< PUSH HL ;AND DPH POINTER CALL DRPARAM ;SET : A,5 ;IN THE CONFIG. BLOCK LD (PRECOMP),A ; AND THE SAVE AREA LD E,1 ;SET A LOW RETRY COUNT JP RDID1 ;READ A SECTOR HEADER ;************************-X***************************************************** ; SAVE THE SECTOR PASSED IN REG eC> FOR A FUTURE ACCESS. SETSEC: LD A,C LD (SEKSEC),A RET ;****************************************************************************** ; SAVE THE ADDRESS PASSED IN AS THE SOURCE/DESTINATION FOR A DISC ACCESS. SETDMA: SBCD SEKDMA RET ;****************************************************************************** ; THIS ROUTINE IS USED TO CONVERT THE LOGICAL SECTOR NUMBER PASSED INTO A ; PHYSICAL SECTOR NUMEER. SINCE THE "CACHE" BIOS PERFORMS WHOLE TRACK TRANSFERS ; ANY SKEW IS UNIMPORTANT. HOWEVER, IN EMULATING ALIEN DISC SYSTEMS WE MUST ; DUPLICATE THE SKEW. IF A TRANSLATE TABLE EXISTS, IT IS PASSED IN . SECTRAN: LD A,D OR E ;TEST FOR NO XLAT TABLE. JRNZ XLAT LD H,P ;GET THE SECTOR VALUE IN ‚HL\ LD L,C INC HL ;ADJUST FOR A FIRST SECTOR OF RET ; ONE, AND EXIT ;****************************************************************************** INC HL ;ADJUST FOR A FIRST SECTOR OF- RET ; ONE, AND EXIT ;****************************************************************************** ; THIS ROUTINE PERFORMS SEQUENTIAL TO SKEWED SECTOR TRANSLATIONS BASED ON A ; 4 BYTE TABLE POINTED TO BY := DIV := (SECTOR NO.) MOD (SIZE FACTOR) OR L ;COMBINE THIS WITH THE BASE SECTOR AND ADJUST INC A ; FOR A FIRST SECTOR NUMBER OF ONE. LD L,A RET ;****************************************************************************** ; TRANSFER THE REQUESTED BLOCK FROM CACHE MEMORY IF POSSIBLE. IF NOT, READ ; THE DESIRED TRACK THEN DO IT. READCACH: CALL CHKMAP LD A, 2ACHFUL1 READCACH: CALL CHKMAP LD A,(CACHFUL) AND A ;IS ANYTHING IN THE CACHE ? JRZ DOREAD CALL CACHADR JRZ DOREAD LD A,(TRACK) ;SEE IF THE TRACKS MATCH LD HL,SEKTRK CP (HL) JRNZ DOREAD LD A,(DISK) ;AND IF SO, ARE THE DISC UNITS LD HL,SEKDSK ; THE SAME ? CP (HL) JRZ INCORE ;IF SO, NO READS ARE NECCESSARY DOREAD: LD A,(SEKDSK) LD (DISK),A ;SET THE PARAMS FOR THE TRANSFER LD A,(SEKTRK) ; FIRST THE TRACK, THEN THE SECTOR LD (TRACK),A CALL READTRK ;NOW FILL THE CACHE XFRIN: CALL CACHADR LD C,1 JRZ BDMA1 LDED SEKDMA ;GET THE DESTINATION MEMORY ADDRESS PUSH DE LD A,18H ;SET MODE CACHE TO MAIN MEMORY CALL M2MXFER ; AND DO IT. POP HL LD BC,128 ;ADD THE BLOCK SIZE ADD HL,BC LD C,0 BDMAl: LD A,20 LD (PNTR2),A ;0F349H LD A,0FFH LD (CACHFUL),A ;0F7DBH LD A,C RET ;****************************************************************************** ; WHEN WE ARRIVE HERE, THE REQUIRED TRACK IS IN THE CACHE, SO DO THE TRANSFER. INCORE: CALL XFRIN ;DO THE TRANSFER AND A ; AND TEST THE RESULT CALL NZ,DOREAD ;RE-TRY IF NECCESSARY. RET ;****************************************************************************** ; THE MEMORY DRIVE (M:) IS IMPLEMENTED IN THE SECOND BANK AS A 48K "DISC" ; WITH 192 TRACKS HAVING TWO 128 BYTE SECTORS EACH. THIS GEOGRAPHY ENABLES US ; TO USE THE TRAK VALUE AS THE PAGE NUMBER AND THE SECTOR AS THE OFFSET ; WITHIN THE PAGE. A FLAG SET ON ENTRY DECIDES WETHER THE TRANSFER IS TO OR ; FROM THE PGUEDO-DISC. MREAD: DEEB 02EH MWRITE: XOR A AND A PUSH AF LD A,(SEKTRK) LD D,A LD A,(SEKSEC) DEC A JRZ MEMF1 LD A,128 MEMF1: LD E,A LD HL,(SEF.DMA) BECOMES "MVI A,0AFH" ;SAVE THE DRIECTION FLAG ;PAGE NUMBER ;SECTOR 1 IS AT TRACK + 80H JRZ MEMF1 ;5ECTUR 1 15 Af /KALK + bOM LD A,128 MEMF1: LD E,A LD HL,(SEKDMA) POP AF ;RE-GET DIRECTION INDICATOR LD A,10H JRZ MEMF2 LD A,18H ;SET THE MEMORY MANAGER VALUE EX DE,HL MEMF2: CALL M2MXFER XOR A ;ALWAYS RETURN A SUCCESS RET ;****************************************************************************** ; THIS IS THE OUTER LEVEL CACHE READ ROUTINE, UNIT, TRACK, SECTOR AND ; DMA ADDRESS HAVING BEEN SET UP PREVIOUSLY. READ: LD A,(SEKDSK) CP 'M'-'A' ;THE MEMORY DRIVE ? JRZ MREAD SSPD SPHOLD2 ;SAVE USERS STACK POINTER LD SP,FIFOBUF ; AND USE OUR OWN CALL READCACH ;DO THE READ LSPD SPHOLD2 ; THEN RESTORE AND EXIT. RET ;****************************************************************************** ; OUTERMOST WRITE DISC DATA ROUTINE. ACTUAL WRITE NOT DONE HERE. ON FIRST ; WRITE TO THE CACHE, THE MAP IS RESET TO ALL "FF". BLOCKS THAT ARE CHANGED ; HAVE THEIR MAP BYTE SET TO ZERO, AND ARE CHANGED IN THE CACHE BUFFER. ; FINALLY "FLAG1" IS SET SO THAT THE REAL TIME CLOCK WILL CAUSE THE ACTUAL ; WRITE TO OCCUR. WRITE: LD A,(SEKDSK) CP JRZ MWRITE SSPD SPHOLD2 ;SAVE USERS STACK LD SP,FIFOBUF ; AND SUBSTITUTE OUR OWN. XOR A LD (FLAG1),A LD (CACHFUL),A LD A,(MAPMT) ;IF DISC NOT YET UPDATED, SKIP THE AND A ; NEXT BIT. JRNZ WRITEC CALL FILLMAP ;FLAG THE MAP "ALL NEED WRITING" JR XFROUT WRITEC: LD A,(SEKDSK) ;ARE THE UNITS THE SAME LD HL,DISK CP (HL) JRNZ MTCACH LD A,(SEKTRK) ;ARE THE TRACKS THE SAME '2 LD HL,TRACK C (HL) JRZ XFROUT MTCACH: CALL CHKMAP ;CLEAR OUT THE MAP XFROUT: LD A,0FFH LD (MAPMT),A ;FLAG MAP TO "NEEDS WRITING" LD A,(SEKDSK) LD (DISK),A ;SET THE TRANSFER DISC LD A,(SEKTRK) ; AND THE TRANSFER TRACK LD (TRACK),A CALL CACHADR ;CALCULATE BLOCK# IN CACHE REQUESTED XOR A LD (DE),A ;SET MAP TO SHOW "UPDATED" EX DE,HL LD HL,(EKDMA) THE USER DMA ADDRESS XOR A LD 1DE),A ;SET MAP TO SHOW "UPDATED" EX DE,HL LD HLOSEKDMA) ;GET THE USER DMA ADDRESS PUSH HL LD A,10H ;MODE IS MEMORY TO CACHE CALL M2MXFER ; MOVE IT IN POP HL LD BC,128 ;UP THE TRANSFER ADDRESS ADD HL,BC ;RETURN UPDATED DMA TO CP/M LD A,..; ;SET "FLAG1" SO THAT INTERRUPT SERVICER LD (FLAG1),A ; CAN WRITE DISC ON NEXT SERVICE. XOR A ;ENSURE CP/M SEES SUCCESS LSPD SPHOLD2 ;RESTORE STACK RET ;****************************************************************************** ; HERE, AT LAST, IS THE ACTUAL WRITE MECnINISM. "MAPMT" IS CHECKED FOR BEING ; NON-ZERO. IF IT IS, THEN ANY SECTORS CONTAINING BLOCKS WHICH HAVE BEEN ; CHANGED (I.E. BYTE=00), ARE WRITTEN OUT. FINALLY THE WHOLE MAP IS RESET TO ; "FE". THIS ROUTINE WILL PROBABLY BE CALLED FROM THE REAL TIME CLOCK ROUTINE. CHKMAP: XOR A LD (FLAG1),A ;FLAG THE MAP AS CHECKED LD HL,MAPMT ;IF THE MAP IS ALREADY LD A,(HL) INITIALISED, THEN WE CAN AND A ; EXIT NOW. RET XOR A LD (HL),A ;FLAG IT AS INITIALISED CALL DOFN ;WRITE ANY UPDATED SECTORS JP FILLMAP ;RESET ALL BYTES TO "FF" ;****************************************************************************** ; THIS ROUTINE READS A WHOLE TRACK INTO THE CACHE BUFFER. MAP BYTES ARE ZEROED ; EOR EACH SECTOR THAT IS READ SUCCESSFULLY. READTRK: PUSHI X PUSHI Y CALL FILLMAP ;"FF" THE MAP CALL SEEK ; AND MOVE THE HEADS JRNZ READT6 ;JUMP ON A SEEK ERROR CALL RDID ;GET THE NEXT AVAILABLE SECTOR HEADER JRNZ READT6 ; AND EXIT IF DISC UNREADABLE LD A,(SECMAX) ;SET THE TOTAL 128 BYTE BLOCKS ON TRACK LD (BLKCNT),A ; AND SAVE AS A BLOCK COUNT READT1: LD C,1 ;SET A RETRY COUNT OF 1. LD A,(SEKSEC) ;GET THE REC4UESTED SECTOR LD HL,PRVHLD SUB (HL) JRC READT2 LD HL,SECSIZE CP (HL) JRNC READT2 LD C,12 ;SET NORMAL RETRY COUNT READT2: LD A,C ;STORE RETRY COUNT LD (RWRTRY),A CALL CACHA3 ;GET AND SAVE THE MAP POINTER PUSH DE CALL READS ;READ "NXTSEC" READT3: POP HL LD A,(SECSIZE) ;GET THE SECTOR SIZE VALUE LD C,A ; FOR FUTURE USE LD B,A JRNZ READT5 ;JF THE READ FAILED, DO NEXT SECTOR READT4: )D LD C,A ; FOR FUTURE USE LD 1,A JRNZ READT5 ;IF THE READ FAILED, DO NEXT SECTOR READT4: LD (HL),0 INC HL ;ZERO OUT THE APPROPRIATE NUMBER DJNZ READT4 ; OF MAP BLOCK BYTES READT5: CALL SECWARP ;SET UP THE NEXT SECTOR TO READ JRNZ READT1 ; AND LOOP TIL ALL DONE. READT6: LD A,100 LD (MINIVAL),A ;SET MINI MOTRO DELAY POPIY ;ALL DONE, RESTORE AND EXIT. POPIX RET ;****************************************************************************** ; CHECK THE CACHE BYTE-MAP FOR SECTORS CONTAINING ALTERED BLOCKS AND RE-WRITE ; THESE SECTORS. DOFN: PUSHI X PUSHI Y XOR A LD (OPEAIL),A ;SET OPERATION OK CALL SEEK ;POSITION HEADS JRNZ DERROR ; INFORM USER ABOUT FAILS LD A,12 LD (RWRTRY),A ;SET READ/WRITE RETRY COUNT LD A,12 LD (FLAG5),A ; AND READ AFTER WRITE RETRYS LD A,(SECMAX) ;SET BLOCKCOUNT LD (BLKCNT),A LD A11 LD (PRVHLD),A ;AND FIRST SECTOR DOFN1: CALL DEBLOCK ;ARE ALL MAP BYTES OF "PRVHLD" JRNZ DOFN2 ; EQUAL ? (JUMP IF NOT SO) CALL SECWARP ;GET NEXT SECTOR/BLOCK VALUE JRNZ POPN1 ;JUMP "BLKCNT" NOT YET ZERO JR DOFN5 DOFN2: CALL RDID ;FIND OUT WHAT HAS JUST GONE JRNZ DERROR ; RAST THE HEADS LD A,(SECMAX) LD (BLKCNT),A ;RESET THE BLOCKCOUNT DOFN3: CALL DEBLOCK ;ALL MAP BYTES OF "PRVHLD" EQUAL ? JRZ DOEN4 ; (JUMP IF SO) LD HL,CACH-400H ;SET UP TRANSFER BASE 1K BELOW CACHE CALL READS ; AND READ THE SECTOR CALL NZ,RWFAIL ;SERVICE ANY ERRORS CALL MEMOVE ;MOVE THE BLOCK DOFN4: CALL SECWARP ;GET NEXT SECTOR/BLOCK VALUES JRNZ DOFN3 ;LOOP IF ANY LEFT IN "BLKCNT" DOFN5: CALL RDID ;GET AN I.D. JRNZ DERROR LD A,(SECMAX) ;RESET TOTAL BLOCK COUNT LD (BLKCNT),A DOFN6: CALL CACHA3 ;SEE IF MAP VALUE = "FF" JRZ DOFN7 ; JUMP IF SO. PUSH DE ;SAVE MAP POINTER CALL WRITES ;WRITE THE SECTOR POP HL JRZ DOFN7 ;IF AN ERROR OCCURRED, LD (HL),OFFH ; FLAG SECTOR "NEEDS RE-WRITING" DOFN7: CALL SECWARP ;GET NEXT SECTOR/BLOCK VALUES JRNZ DOFN6 ;LOOP IF ANY BLOCKD STILL TO GO LD A,(SECMAX) ;RESET TOTAL BLOCKS LD (BLKCNT),A DOEN8: CALL CACHA3 ;SEE IF MAP VALUE = "FF" CALL NZ,RAWS ;IF NOT DO READ AFTER WRITE CALL SECWARP ;LOOP WHILE MORE BLOCKS LEFT JRNZ DOFN3 DOFN8: CALL CACHA3 ;SEE IF MAP VALUE = "FF" CALL -NZ,RAWS ;IF NOT DO READ AFTER WRITE CALL SECWARP ;LOOP WHILE MORE BLOCKS LEFT JRNZ DOFN8 DERROR: POPIY POPIX LD A,100 ;START THE MINI MOTORS SHUTDOWN LD (NINIVAL),A ; SEQUENCE. LD A,(OPFAIL) ;EXIT IF NOT AN ERROR AND A RET LD A,(DISK) PUSH AF ;NON-ZERO = "WRITE ERROR" JP DERR2 ;****************************************************************************** ; REPORT A DISC OPERATION FAILURE AND WAIT FOR USER RESPONSE. DERR1: SEC A PUSH AF 'ZERO = "NOT READY" LDX A,0 AND 3 DERR2: ADD 'A' ; THE MESSAGE LD (RAWDSK),A CALL PRINTO ;TELL OPERATOR DEFB BEL,ACR,ALF DEFB 'CBIOS Error on ' RAWDSK: DEFB 0 ;SPACE FOR UNIT IN ERROR DEFB ',0 POP AF JRNZ DERR3 ;DO WE NEED TO WAIT NOW ? CALL PRINTO DEFB 'NOT READY ',0 DERR3: CALL CONIN ;WAIT FOR CONSOLE DATA CP 3 JP Z,WBOOT ;RESET ALL ON A CONTROL + "C" CP ESC RET Z ; OR TRY AGAIN ON AN "ESCAPE" JR DERR3 ;****************************************************************************** ; ADJUST THE "NXTSEC" AND ITS BLOCK # (IN "PRVHLD") TO THE NEXT IN LINE. WRAP ; AROUND TO SECTOR 1 WHEN TRACK LIMIT EXCEEDED. REMOVE ONE SECTORS WORTH OF ; BLOCKS FROM "BLKCN1". RETURN A ZERO FLAG WHEN "BLKCNT" IS EXPIRED, SECWARP: LD HL,NXTSEC LD DE,PRVHLD LD A,(DE) ;GOT BLOCK # ADDX 03H ADD BLOCKS/SECOER CMPX 02H COMPARE WITH BLOCKS/TRACK JRC SWARP1 ;SEE IF WE'VE REACHED THE LAST JRZ SWARP1 SECTOR YET. LD A,1 LD B,1 ;IF SO, WRAP AROUND TO SECTOR 1 AGAIN JR SWARP2 SWARP1: LD B,(HL) ;GET NEXT SECTOR INC SWARP2: LD (DE,A ;STORE CALCULATED FIRST BLOCK # OF LD (HL),B ; THE NEXT SECTOR, AND THE SECTOR # LD HL,ELKONT LD A,(HL) ;REMOVE 1 SECTOR OF BLOCKS FROM THE SUBX 03H ; RUNNING TOTAL LD (HL),A RET ;****************************************************************************** • SUBX 03H ; RUNNING TOTAL LD (HL),A RET ;*******-********4=************************************************************** ; RETURN ZERO IF ALL THE MAP BYTES REFERENCED BY THE SECTOR IN "PRVHLD" ; ARE OE THE SAME VALUE. DEBLOCK: LD A,(SECSIZE) ;NO ACTION IF 128 BYTE SECTORS DEC A RET Z PUSH AF CALL CACHA3 ;GET BLOCK # AND MAP VALUE OF FIRST. POP BC ;GOT BLOCKS/SECTOR — 1. (IN eslr, NOW). EX DE,HL DEBLK1: INC HL ;SEE IF NEXT MAP ENTRY IS THE CP (HL) ; SAME AS THE LAST RET NZ DJNZ DEBLK1 ;LOOP ON IT AND RET ;****************************************************************************** ; ROUTINE TO TRANSFER BLOCKS (128 BYTES) OF MEMORY INTO AND OUTOF THE CACHE. MEMOVE: CALL CACHA3 ;SAVE SECTOR IN CACHE ADDRESS LD (MSRCE).HL ; FOR TRANSFER LD HL,CACH-400H LD (MDEST).HL ;AND WHERE IT>S TO GO LD A.(SECSIZE) ;GET BLOCKS/SECTOR LD B,A PUSH BC MEMOV1: LD A,(DE) ;GET MAP BYTE AND A JRZ MEMOV2 ;HAS IT BEEN READ '2 PUSH DE LD HL.(MDEST) ;REGET THE MEMORY POINTERS LDED MSRCE LD A.8 ;SET THE MEMORY CONTROL MODE CALL M2MXFER ; AND SHIFT THE BLOCK POP DE XOR A ;FLAG IT IN THE MAP LD (DE),A MEMOV2: POP BC DEC B ;BLOCKS/SECTOR — 1 RET Z ; DONE IF 128 BYTES/SEC PUSH BC LD BC,128 ;LOAD BLOCK SIZE LD HL,(MSRCE) ADD HL,BC ;FORM OFFSET INTO CACHE LD (MSRCE),HL ; SAVE IT LD HL,(MDEST) ;UP DESTINATION TOO ADD HL.BC LD (MDEST).HL ; AND SAVE THAT INC DE ;BUMP MAP POINTER JR. MEMOV1 ;AND LOOP ;***********3(****************************************************************** ; READ A SECTOR I.D. FROM THE CURRENT DISC. RDID: LD B.12 ;SET RETRY COUNT RDID1: LD A,0COH ;READ I.D. COMMAND LD HL,IDSAVE ;BUFFER TO RECEIVE IT P' BC LD ilL,IDSAVE ;BUFFER TO RECEIVE IT PUSH BC CALL RDWRT ;DO THE READ. POP BC AND 9DH ;MASK ERROR BITS JRZ SECPERV ;DO NEXT STEP IF THE READ WAS OK. DJNZ RDID1 ;LOOP 11 MORE TIMES LD A,OFFH LD (OPFAIL),A BEFORE FLAGGING A BIG FAIL. AND A RET ;****************************************************************************** ; SET "NXTSEC" TO THE SECTOR WHICH WILL APPEAR NEXT. SET "PRVHLD" TO THE FIRST ; BLOCK # OF THIS SECTOR. REDUCE "BLKCNT" BY A SECTOR OF BLOCKS. SECPERV: LD A,(ID3EC) LD (NXTSEC),A ;STORE THE SECTOR # JUST PASSED LD C,A DEC LESS ONE... LD HL,SECSIZE ;GET THE SPECIFIED # nF, PLOCv.9 LD B,(HL) ; IN A SECTOR XOR A SECPV1: ADD C ;PL=K # = ((SFC-1,*7="1-2)+1 DJNZ SECPV1 INC LD (7Rvuun),A 7s4v7 17 CALL CHECK FOR '4RAP—AROUND OF TRACK XOR RET ;***,e*****›,v--,44h-,4********Y********************************************** ; READ "NXTSEC". REPEAT UP TO "RWRTRY" TIMES. RETURN ZERO IF SUCCESSFUL. READS: LD A,(NXTSEC) ;SEND SECTOR VALUE TO CONTROLLER OUT FSEC,A LD A,(RWRTRY) ;LOAD UP THE RETRY LIMIT LD B,A READS1: LD A,80H ;BASIS OF SECTOR READ COMMAND PUSH BC CALL RDWRT ;DO THE READ POP BC AND 9DH ;MASK ERROR BITS RET Z ; EXIT IF OK DJNZ READS1 LD A,1 ;FLAG AN ERROR EXIT AND A RET ;****************************************************************************** ; WRITE "NXTSEC" TO DISC. REPEAT UP TO "RWRTRY" TIMES. RETURN ZERO IF WRITE OK. WRITES: LD A.(NXTSEC) ;SET UP SECTOR FOR CONTROLLER OUT FSEC,A LD A,(PWRTRY) ;LOAD RETRY LIMIT LD B,A WRITE1: LD A,OAOH ;BASIS OF A WRITE COMMAND PUSH BC CALL RDWRT ;DO THE WRITE POP BC AND 0FDH ;MASK ERROR BITS RET DJNZ WRITEI AND gFDH ;MASK ERROR BITS RET DJNZ WRITE1 JP PWFAIL ;****************************************************************************** ; PERFORM A "READ-AFTER-WRITE" CHECK. RAWS: LD A,(NXTSEC) ;SET THE SECTOR OUT FSEC,A LD A,(FLAG5) ; AND THE RETRY COUNT LD B,A RAWS1: LD A,0FFH ;THIS WILL BECOME A SPECIAL PUSH BC ; READ COMMAND CALL RDWRT ;SO DO IT. POP BC AND 9DH ;MASK ERRORS RET 7 EXIT SUCCESSFUL DEC JRZ RWFAIL ;TOO MANY ERRORS PUSH BC CALL WRITES ;WRITE IT AGAIN POP BC JRZ RAWS1 ;NOW TRY TO READ IT AGAIN RET ;****************************************************************************** ; FLAG FAILED READ/WRITE OPERATIONS RWFAIL: LD A,2 LD (OPFAIL),A ;SET OPFAIL = 2 LD (RWRTRY),A ;AND BOTH RETRY COUNTS = 1 DEC A LD (FLAG5),A RET ;****************************************************************************** ; MOVE THE HEADS OF THE SELECTED DISC TO THE TRACK STORED IN "REALTRK". ; SAVE THE VALUE OF THE PARAM BLOCK EOR THE DRIVE FOR EASY ACCESS. IF A SEEK ; ERROR OCCURS, DO A RETURN ZERO SEEK AND RETRY UP TO 5 TIMES BEFOR FAILING. SEEK: LD A,(DISK) ;USE THE SELECTED UNIT TO CALL DRPARAM ; GET THE UNIT CHARACTERISTICS XOR A ;INHIBIT MINI MOTOR SHUT-OFF LD (MINIVAL),A LD C,A LD A,(TRACK) ;GET THE TRACK REQUIRED BITX 0,01H ;TEST THE TWO-SIDE FLAG JRZ SEEK1 SRLR A ;IF TWO-SIDED, HALF THE TRACK NO JRNC SEEK1 ; AND SET SIDE 2 ON ODD TRACKS LD C,10H SEEK1: LD (REALTRK),A ;HAVE THE ACTUAL TRACK HERE CMPX 04H JRC SEEK2 ;LOOK AT THE WRITE PRE-COMP TRACK #. SETB 7,C SEEK2: LDX A,00H ;GET THE SELECT UNIT BITS OR C ; AND MERGE THE OPTIONS LD (UNITSEL),A ;SET THE UNIT PRECOMP VALUE OUT DISCM,A LDX A,06H ;GET THE LAST USED TRACK # OUT FTRK,A ; TO RECHARGE THE TRACK REGISTER AND A 7PM7 ;Ir IT WAS A :Epn, 3Luz7 FIRE OFF VO•d• V111^111..... •—^ I I. VI• .1 .+`^~~.. V •-•••-•—•^.-. • OUT DISCM,A LDX A,06H ;GET THE LAST USED TRACK # OUT FTRK,A ; TO RECHARGE THE TRACK REGISTER AND A JRNZ SEKRTRY ;IF IT WAS A ZERO, JUST FIRE OFF CAL DSELO ; A FORCE INTERRUPT TO READ STATUS BIT 2,A ;NOW CHECK TRACK ZERO STATUS BIT JRNZ SEKRTRY ; TO BE SURE WE ARE REALLY THERE. LDX A,7 ;ISSUE A RESET DRIVE AT FULL SPEED CALL DOCMND BIT 2,A ;LOOK AT SEEK ERROR AGAIN JRZ SEEKERP SEKRTRY: LD B,5 ;SET RETRY LIMIT SEEK3: LD A,(REALTRh) ;PUT THE TRACK REQUIRED OUT FDATA,A ; OUT TO THE DATA PORT LD C.A PUSH BC ;SAVE IT TO XOR A CALL RDWRT ;SET THE UNIT DENSITY PRE-COMP POP BC LD A,1CH ;FORM A SEEK COMMAND ORX 07H ; MERGE THE SEEK RATE CALL DOCMND ;NOW DO IT AND 99H ;MASK READY/DONE IN A,FTRK ;LOAD THE FOUND TRACK STX A,6 ;SAVE IT IN THE PARAM BLOCK JRNZ SEEK4 ;JUMP ON ERRORS CP C ;SEE IF IT'S WHERE WE SHOULD BE RET Z SEEK4: IN A.ECOM ;IF THE DRIVE IS NOT READY, AND 80H JRNZ SEEK3 LD A,3 ;RESET, SLOW SEEK. CALL DOCMND DJNZ SEEK3 ;RE-TRY 5 TIMES SEEKERR: LD A,0FFH ;CAN'T GET ON TRACK, SO LD (OPFAIL),A ; FLAG AN ERROR AND A RET ;****************************************************************************** ; THIS CODE PERFORMS READS, WRITE AND READ-AFTER-WRITES. TRANSFER PARAMS HAVE ; BEEN SET, AND HAS SOURCE AND HAS ; THE DESTINATION. eA%, HAS THE MEMORY MODE SO .. 00H = BANK TO BANK. 03H = CACHE TO CACHE. 10H = BANK TO CACHE. 18H = CACHE TO BANK. M2MXFER: OUT MUel,A ;SET MEMORY MODE LD (M2MDST),HL ;SET DESTINATION SDED M2MSRC ; AND SOURCE LD HL,M2MDMA ;POINT TO DMA DEVICE PARAMS CALL ZINIT ; AND KICK IT OFF M2MXF1: LD A,OBFH OUT ZDMA.A ;TEST DMA DEVICE STATUS IN A,ZDMA ; AND LOOP TILE COMPLETE AND 20H JRNZ M2MXF1 LD A,88H ;DISABLE DMA DEVICE OUT ZDMA,A RET ;****************************************************************************** ; DMA INITIALIZATION VALUES FOR A DMA MEMORY TO MEMORY TRANSFER. M2MDMA: DEFB 16 ;16 COMMANDS TO THE DEFB ZDMA ;DMA CONTROLLER DEFB 83H ;DISABLE DMA DEFB 7DH ;XFER ONLY, ADDR LENGTH FOLLOW M2MDST: DEEW 00 ;PORT "A" ADDRESS DEFW SYSIZE ;BLOCK LENGTH - 1 DEFB 14H ;INCREMENT "A" AS MEMORY DEFB 10H "B" AS MEMORY DEFB OCDH ;"B" ADDR FOLLOWS, I'RUPT EACH BYTE M2MSRC: DEFW 00 ;PORT "B" ADDRESS DEFB 82H ;RDY IS ACTIVE LOW DEFB OCFH ;RESET AND LOAD REGISTERS DEFB 8BH ;RESET STATUS DEFB 0B3H ;DISABLE DMA XFER DEFB 87H ;ENABLE DMA NOW DEFB 0 ;****************************************************************************** INITIALIZE A 64 BYTE BLOCK TO ALL FF. USED TO FLAG USED BLOCKS IN ; THE CACHE BUFEER BEGINNING AT OCOO0H IN THE SECOND BANK. FILLMAP: LD HL,BLOKMAP LD E,64 FILM1: LD (HL),OFFH INC HL 1,72NZ FILM1 FILM1: LD (HL),OFFH INC HL UNZ FILMI PET ;****************************************************************************** CACHADR: LD CACHA2: LD LD LD ADD LD LD SRLR RARR LD ADD LD CP RET CACHA3: LD JR A,.(SEKSEC) HL,BLOKMAP-1 C,A B4O HL , BC DE,HL F,A C,0 r HL,CACH-128 HL,BC A, (DE) OFFH A,(PRVHLD) CACHA2 ;USE THE REQUIRED LOGICAL SECTOR ; AS AN OFFSET INTO THE TRACK MAP ;NOW MULTIPLY SECTOR BY 128 TO ; FORM AN OFFSET INTO THE CACHE ;FORM THE CACHE ADDRESS POINTER ;SET THE ZERO FLAG FRON THE MAP ; AND EXIT ;GET THE REGJUIRED PHYSICAL SECTOR ;****************************************************************************** LISE THE UNIT I.D. IN TO SET THE s'N' INDEX POINTER TO THE DRIVE CHAPACTERISTICS TAFLE. COPY THIS TAFLE TO A BUFFER AREA. DRPARAM: LD INC ;ADJUST THE UNIT NUMBER TO 1..8 LD ; AND LOAD THE TAFLE ENTRY LENGTH PRPRMI: ADD DEC JPNZ PRPRM2: PUSH POPIX LD LDIR RET ;****************************************************************************** ; WARM BOOT CODE REREADS THE CCP AND BDOS FROM THE SECOND PAGE OF RAM, THEN ; ENTERS THE CCP WITH THE CURRENT DISC NUMBER IN REGISTER + THIS MEANS THAT ; WARM—START DISCS NEED NEITHER HAVE A SYSTEM ON THEM, NOR BE DOUBLE DENSITY. WBOOT: HL,DR0-8 A BC,8 HL,BC A PRPRM1 HL DE,PRMSAVE ;FORM THE OFFSET FROM THE BASE ;AND LOAD IT INTO THE INDEX REGISTER ;BLOCK MOVE THE ENTRY INTO ; A FIXED SAVE AREA LD LD LD LD LD LD CALL LD LD SP,DEFBUF HL,SYSIZE (M2MDST+2),HL ;PERVERT THE BLOCK LENGTH FOR A HL,WBHOLD ; MEMORY TO MEMORY BLOCK MOVE. DE, CCP A,18H ;A PAGE 2 TO PAGE 1 TRANSFER M2MXFER HL,127 ;RESTORE CP/M'S LOGICAL BLOCK SIZE (M2MDST+2),HL HL,CCP+3 ; CCP ENTRY FOR NO AUTO FUNCTION ; ;****************************************************************************** ; THIS CODE IS USED BY BOTH COLD AND WARM BOOTS TO RESET LOW MEMORY VECTORS ; AND ENTER THE CCP. NOTE THAT CURRENT DRIVE/USER IS NOT CHANGED. FINALLY, EtolRY IE MADE ,Ir-/-4 A r ADDPg '!+ ) in1J %,UMIC. 1Z UZGL Ml MUln LULL MINIL WMMVI MUU)Z IU MMZC) LUW )'ICVIUM) VGLIUMZ ; AND ENTER THE CCP. NOTE THAT CURRENT DRIVE/USER IS NOT CHANGED. FINALLY, ENTRY IS MADE TO CP/'M AT ADDRESS . SETLOW: LD A,JMP ;STORE A "JMP" INSTRUCTION ; TO "WARMBOOT" AT 0000. LD (0),A ;AND A JUMP TO THE "BDOS" ; AT 0005. LD DE,BIOS+3 ;LOAD UP THE CURRENT DISC/USER ; AND ENTER THE CCP SDED 1 LD (BDOSVEC),A LD DE.BDOS+6 SDED BDOSVEC+1 1D A,(CDISK) LD C,A JP (HL) ;****************************************************************************** THIS ROUTINE INITIALISES ZILOG DEVICES FROM A TABLE ENDING WITH ZERO. ; THE FIRST VALUE IS THE NUMBER OF PARAMS, THE SECOND THE PORT #. ZINIT: LD A,(HL) OR A ;EXIT ON A ZERO RET LD B,A ;LOAD THE COUNT INC HL ID C,(HL) ;AND THE PORT NUMBER INC HL ; THEN POINT TO THE DATA ZSET: OUTIR JR ZINIT ****************************************************************************** ; INTERRUPT SERVICE FROM CHANNEL 3 OF THE ZILOG CTC. IRTC: SSPD SPHOLD3 LD SP,SPHOLD1 ;USER STACK NOT USED. PUSH AF PUSH HL LD HL,RTCVAL ;INCREMENT THE RTC TIMER VALUE INC (HL) LD A,(HL) ;GET IT AND SAVE FOR LATER PUSH AF CP 61 ;SEE IF ONE SECOND HAS PASSED JRNZ IRTC1 LD (HL),0 ;RESET THE RTC TICKER LD A,60 ;FOR SECONDS/MINUTS COMPARISON LD HL,SECS ;LOW MEMORY LOCATION OF REAL TIME CLOCK INC (HL) ;UP THE SECONDS COUNT CP (HL) ; AND TEST FOR A MINUTE PASSED JRNZ IRTC1 LD (HL),0 ;RESET AT 60 (NATURALLY) INC HL ;NOW Dis MINUTES INC (HL) CP (HL) ;AN HOUR PASSED ? JRNZ IRTC1 LD (HL),0 ;RESET THE MINUTES AND UP THE HOURS INC HL INC (HL) LD A,(HL) ;A DAY GONE CP 24 ;WE USE A 24 HOUR CLOCK HERE. JRNZ IRTC1 LD (HL),0 ;A NEW DAY HAS DAWNED LD HL,(DATE) INC HL ;ADD ONE TO THE DATE VALUE LD (DATE),HL IRTC1: AE) ;CHECK THE REST EVERY 8TH TICK 7PN- TETc-'T LD HL,(DATE) INC HL ;ADD ONE TO THE DATE VALUE LD (DATE),HL A‹ü 7/ ;CHECK THE REST EVERY 8TH TICK JRNZ IDISXT / fp5s / LD HL,MINIVAL ;GET THE MINI-DISC MOTOR DELAY LD A,(HL) OR A ;IF IT HAS TIMED OUT, SKIP ON JRZ IDIS1 DEC (HL) ;IF NOT, COUNT IT DOWN TO TURN OFF JRNZ IDIS1 ; THE 5" MOTORS. LD A,(UNITSEL) OR 20H ;KEEP THE CURRENT UNIT SELECTED, OUT DISCM,A ; BUT MOTORS OFF. IDIS1: LD HL,PNTR2 LD A,(HL) ;ANOTHER PROTECTION MECHINISM. OR A ;THIS COUNTER IS SET TO 20 JRZ IDIS2 AT THE END OF EACH BLOCK READ. DEC (HL) JRNZ IDIS2 XOR A LD (CACHFUL),A IDIS2: LD HL,FLAG1 ;SEE IF DISC NEEDS WRITING LD A,(HL) ;THIS VALUE IS ZERO WHEN NO WRITES OR A ; ARE PENDING. JRZ IDISXT ;EACH WRITE RESETS IT TO 5, SO DEC (HL) ; WE CAN BE SURE THAT NO WRITES ARE JRNZ IDISXT ; IN PROGRESS WHEN IT REACHES ZERO. POP HL POP AF LD SP,SPHOLD2 ;SET A DEEPER LEVEL OF STACK PUSH AF PUSH HL LD HL,(SPHOLD3) ;WITH THE OLD PC AT THE TOP PUSH HL CALL IDISEN ;THIS MAKES THE ROUTINE RE-ENTRANT PUSH DE PUSH BC CALL CHKMAP ;UPDATE ANY NEEDED SECTORS IDIS4: POP BC POP DE DI ;SAFEGUARD THE STACK POINTER RELOAD POP HL LD (SPHOLD3),HL ;REPLACE THE SP FOR THE EXIT ROUTINE IDISXT: POP HL POP AF LSPD SPHOLD3 ;RESTORE REGS. AND EXIT IDISEN: EI RETI ;****************************************************************************** SKEW TABLES FOR USE IN 8" SYSTEMS. IF MAXI ; SKEW TABLE FOR SINGLE DENSITY IBM CAMPATABLE CP/M DISCS. X8TI28: DEFB 0,24,13,6 SKEW TABLE FOR DOUBLE DENSITY LIFEBOAT/MORROW FORMAT DISCS. X8T296: DEFB 1,26,26,9 ; SKEW TABLE FOR DOUBLE DENSITY CCS 1024 BYTE/SECTOR DISCS. >!.8T1024: bKLW MUM IMUISLL MtNbIlY LLS 1024; bYlt/bLLIUM 1.11bLb. ; X8T1024: DEFB 2,8,8,3 ENDIF ;****************************************************************************** ; SKEW TABLES FOR USE IN 5" SYSTEMS IF MINI MINIS KW ENDIF 1****************************************************************************** ; DISC PARAMETER ENTRIES FOR USE BY THE SYSTEM. CONDITIONAL ASSEMBLY WILL RESULT IN A FOUR DRIVE SYSTEM WHICH, IF MIXED, MAPS AS :- ; DRIVES LOGICAL PHYSICAL SIZE A: A: 8 B: B: 8 C: A: 5 D: B: 5 M: BANK 2 OF MEMORY - 48K DPEM: DEFW 0 DEFW 0 DEFW 0 DEFW 0 DEFW DIRBUF ;COMMON DIRECTORY BUFFER DEFW MEMDSK ;POINTER TO DISC PARAM BLOCK DEFW CSVM ;CHECKSUM VECTOR ADDRESS DEFW ALVM ;ALLOCATION VECTOR ADDRESS ACTUAL DISC DRIVE PARAMETER HEADERS DPEO: MAXI DEFW 0 DEFW 0 DEFW 0 DEFW 0 DEFW DIRBUF ;COMMON DIRECTORY BUFFER DEFW 0 ;POINTER TO DISC PARAM BLOCK DEFW CSV0 ;CHECKSUM VECTOR ADDRESS DEFW ALV0 ;ALLOCATION VECTOR ADDRESS DPE1: DEFW 0 DEFW 0 DEFW 0 DEFW 0 DEFW DIRBUF ;COMMON DIRECTORY BUFFER DEFW 0 ;POINTER TO DISC PARAM BLOCK DEFW CSV1 ;CHECKSUM VECTOR ADDRESS DEFW ALV1 ;ALLOCATION VECTOR ADDRESS 1 ENDIF IF MAXI AND NOT BOTH DPE2: DEFW 0 DEFW 0 DEFW 0 DEFW 0 DFW DIRBUF ;COMMON DIRECTORY BUFFER DEFW 0 ;POINTER TO DISC PARAM BLOCK DEFW CSV2 ;CHECKSUM VECTOR ADDRESS TIRgU u7 flinr•-77nm 1Arrrn ADDmcc:c DEFW 0 DFW DIRBUF ;COMMON DIRECTORY BUFFER DEFW 0 ;POINTER TO DISC PARAM BLOCK DEFW CSV2 ;CHECKSUM VECTOR ADDRESS DEFW ALV2 ;ALLOCATION VECTOR ADDRESS DPE3: DEFW 0 DEFW 0 DEFW 0 DEFW 0 DEFW DIRBUF ;COMMON DIRECTORY BUFFER DEFW 0 ;POINTER TO DISC PARAM BLOCK DEFW CSV3 ;CHECKSUM VECTOR ADDRESS DEFW ALV3 ;ALLOCATION VECTOR ADDRESS ENDIF IF MINI DPE4: DEFW 0 rEFW DEr 0 DEr0 77EFW DIRBUF ;COMMON DIRECTORY BUFFER DEFW 0 ;POINTER TO DISC PARAM BLOCK DEFW CczV2 ;CHECKSUM VECTOR ADDRESS DEFW ALV2 ;ALLOCATION VECTOR ADDRESS DPE5: DEFW 0 DEFW 0 nEulJ DEFU 0 DEE DIRBUF ;COMMON DIRECTORY BUFFER 7.)Fw ;POINTER TO DISC PARAM BLOCK £JEFW ; CHECKSUM VECTOR ADDRESS DEFW ALV3 ;ALLOCATION VECTOR ADDRESS ENDIF IF MINI AND NOT BOTH DPEC p--7Fw ;77 0 7T 0 nFW DIRBUF ;COMMON DIRECTORY BUFFER DEFW rr ;POINTER TO DISC PARAM BLOCK DEFW CSV0 ;CHECKSUM VECTOR ADDRESS DEFW ALV 0 ;ALLOCATION VECTOR ADDRESS DPE7: DEFW 0 DEFW D77W 0 DEF EFW DIRBUF ;COMMON DIRECTORY BUFFER DEFW ;POINTER TO DISC PARAM BLOCK DEFW ;CHECKSUM VECTOR ADDRESS DEFW ALV' ;ALLOCATION VECTOR ADDRESS ENDIF ;****************************************************************************** ; THESE TABLES MAP THE VALID SECTOR SIZES AND DENSITIES TO DISC PARAM BLOCKS. ; EACH TABLE ENTRY BEGINS WITH A VALUE E9UAL TO THE NUMBER OF 128 BYTE BLOCKS ; IN THE SECTOR AND IS 5 BYTES LONG. THE TABLES ARE REPEATED 4 TIMES FOR EACH ; DISC SECTOR SIZE. UNSUPPORTED FORMATS HAVE ZERO SECTORS PER TRACK. ; THE ENTRIES ARE SEOUENCED: I =1DF 1D 1 AIDE, 2D ; 2 SIDE 1D EIDE 2D ; 1 ="IDE, I ;i 2D ; 2 SIDE 1D ; 2 EIDE 2D ; AND HAVE THE FORM: ; POINTER ; PARAM BLOCK POINTER ; SECTORS/TRACK ; SKEW TABLE ; ; EM8TBL: IF MAXI ; DEFB 1 ;128 BYTE SECTORS DEFB DEFW 26 X8T128,SDSS0 ; A.A. , SINGLE SIDED , 1D DEFB 0 ; A.A 5 A.A , 2D DEFW 0,0 DEFB DEFW 0 ; A.A. , DOUBLE SIDED , 1D 0,0 DEFB 0 ° A.A n A.A. . 2D DEFW 0,0 ; DEFB 2 z. ;256 BYTE SECTORS DEFB DEFW 0 ; A.A. , SINGLE SIDED , 1D 0,0 DEFB 52 ; A.A 4 A.A , 2D DEFW X8T256,DDSS1 DEFB DEFW 0 ; A.A. , DOUBLE SIDED , 1D 0,0 DEFB 52 ; A.A 4 A.A. . 2D DEFW X8T256,DDDS1 ; DEFB 4 ;512 BYTE SECTORS DEFB DEFW 0 ; A.A. , SINGLE SIDED , 1D 0,0 DEFB 60 ; A.A n A.A . 2D DEFW 0,DDSS2 DEFB DEFW 0 ; A.A. , DOUBLE SIDED , 1D 0,0 DEFB 60 ; A.A 4 A.A. , 2D DEFW 0,DDDS2 ; DEFB 8 ;1024 BYTE SECTORS DEFB DEFW 0 ; A.A , SINGLE SIDED , 1D 0,0 DEFB DEFW 64 ; A.A 5 A.A , 2D X8T1024,DDSS3 DEFB DEFW 0 ; A.A. , DOUBLE SIDED , 1D 0,0 DEFB 64 ; A.A 4 A.A. , 2D DEFW X8T1024,DDDS3 ; ENDIF ;****************************************************************************** SIMILAR TABLE FOR USE WITH 5" DRIVES. IF NOT MINI HOOK5 EQU 0 ELSE HOOK5 EGU MINIT BL ENDIF ;****************************************************************************** ; DISC PARAMETER BLOCKS DESCRIBING DISC CHARACTERISTICS OF EACH FORMAT. IF MAXI ; DISC PARAMETER BLOCKS DESCRIBING DISC CHARACTERISTICS OF EACH FORMAT. :)-- TAFLE FOR 1024 IF MAXI DEFW 64 DEFB 4,15,0 DEFW 299 , DEFW 127 DEFB 000H,0 DEFW 32 DEFW 2 .r. TABLE FOR 1024 DEFW 64 DEFB 6,63,7 DEFW 149 DEFW 127 DEFB 80H,0 DEFW 32 DEFW 4 TAFLE FOR 512 BYTE/SEC ONE SIDED DOUBLE DENSITY , ;SECTORS PER TRACK ;LOGICAL BLOCK SIZE IS 4K BYTES. ;NUMBER OF BLOCKS (GROUPS) ON DISC - ;128 DIRECTORY ENTRIES ;DIRECTORY BLOCK MASK ;128 CHECKED DIRECTORY ENTRIES ;2 RESERVED TRACKS BYTE/SEC TWO SIDED DOUBLE DENSITY (C(7`-; ;SECTORS PER TRACK ;LOGICAL BLOCK SIZE IS 8K BYTES. ;NUMBER OF BLOCKS (GROUPS) ON DISC ;128 DIRECTORY ENTRIES ;DIRECTORY BLOCK MASK ;128 CHECKED DIRECTORY ENTRIES ;4 RESERVED TRACKS BYTE/SEC ONE SIDED DOUBLE DENSITY 7 . ;SECTORS PER TRACK ;LOGICAL BLOCK SIZE IS 4K BYTES. ;NUMBER OF BLOCKS (GROUPS) ON DISC ;128 DIRECTORY ENTRIES ;DIRECTORY BLOCK MASK ;128 CHECKED DIRECTORY ENTRIES ;2 RESERVED TRACKS DDSS2: .-(373 DEFW 60 DEFB 5,31,1 DEFW 143 DEFW 127 DEFB 20H,0 DEFW 32 DEFW 2 ; ;,. , i.,, ; THIS TÄBLE FOR 512 BYTE/SEC DDD92:: '--";“ ; THIS DDS53 ; THIS DDDS2;) ; THIS TWO SIDED DOUBLE DENSITY ( ,,,-, ''') ',.• --- ^~l /1 i, iL J \ ; THIS DDSS1: DEFW 60 DEFB 5,31,1 DEFW 284 DEFW 177 DEFB 80H,0 '2: DEFW 2 TABLE FOR 256 DEFW 52 DEFB 4,15,0 DEFW 242 DEFW 127 DEFB 000H,0 DEFW 32 DEFW 2 ;SECTORS PER TRACK ;LOGICAL BLOCK SIZE IS 4K BYTES. ;NUMBER OF BLOCKS (GROUPS) ON DISC ;129 DIRECTORY ENTRIES ;DIRECTORY BLOCK MASK CHECKED DIRECTORY ENTRIES ;2 RESERVED TRACKS DEFW 32 ;128 ;SECTORS PER TRACK ;LOGICAL BLOCK SIZE IS 2K BYTES. ;NUMBER OF BLOCKS (GROUPS) ON DISC ;128 DIRECTORY ENTRIES ;DIRECTORY BLOCK MASK ;128' CHECKED DIRECTORY ENTRIES ;2 RESERVED TRACKS BYTE/SEC ONE SIDED DOUBLE DENSITY ("MORROW" FORMAT) {- ; THIS TAFLE FOR 256 BYTE/SEC DDD E 1 : DEFW 52 DEFB 4,19,0 DEFW 486 ;NUMEER DEFW 255 DEFB 0F0H,0 rIpr-,) &1,,4 _ PvEW 4 TWO SIDED DOUBLE DENSITY (''MORROW" FORMAT) ;SECTORS PER TRACK ;LOGICAL BLOCK SIZE IS 2K BYTES. OF BLOCKS (GROUPS) ON DISC ;256 DIRECTORY ENTRIES ;DIRECTORY BLOCK MASK ;256 CHECKED DIRECTORY ENTRIES ;4- RESERVED TRACKS (2 ACTHAO UI') DEFW DEFB DEFW DEFW —255 0F0H,0 .c94 ;256 DIRECTORY ENTRIES 4 ;DIRECTORY BLOCK MASK ;256 CHECKED DIRECTORY ENTRIES ;4 RESERVED TRACKS (2 ACTUALLY) 5 THIS': TAFLE FOR 128 BYTE/SEC SINGLE SIDED SINGLE DENSITY ("IBM" FORMAT") ; SDSSO: DEFW 26 ;SECTORS PER TRACK t; DEFB 3,7,0 ;LOGICAL BLOCK SIZE IS 1K BYTES. DEFW 242 ;NUMBER OF BLOCKS (GROUPS) ON DISC DEFW 63 ;64 DIRECTORY ENTRIES DEFB 000H,0 ;DIRECTORY BLOCK MASK DEFW 16 ;64 CHECKED DIRECTORY ENTRIES DEFW 2 ;2 RESERVED TRACKS ENDIF ;*******X********************************************************************** ; THIS TAFLE FOR THE PSUEDO—DISC DRIVE "M:" MEMDSK: DEFW 2 ;SECTORS PER TRACK DEFB 3,7,0 ;LOGICAL BLOCK SIZE IS 1K BYTES. DEFW 47 ;NUMBER OF BLOCKS (GROUPS) ON DISC DEFW 31 ;31 DIRECTORY ENTRIES DEFB 080H,0 ;DIRECTORY BLOCK MASK DEFW 0 ;NO CHECKED DIRECTORY ENTRIES DEFW 0 ;NO RESERVED TRACKS ;*******************************************************.********************** ; MINI DISC PARAMETER BLOCKS. IF MINI MINID ;MACRO WILL SUPPLY MINI DISC PARAMETER BLOCKS. ENDIF ; ;****************************************************************************** ; THE FOLLOWING 8—BYTE TABLES ARE USED TO SET THE INDIVIDUAL DRIVE FORMATS. ; THE BYTE USAGE IS : BYTE 0 UNIT SELECT BITS, DRIVE SIZE (5/84). 1 -- 00 = SINGLE SIDED, FF = DOUBLE SIDED. 2 -- NUMBER OF 128 BYTE BLOCKS PER TRACK. ; SECTOP SIZE / 128. 4 -- TRACK AT WHICH TO TURN ON WRITE PRE—COMP (FOR "FMAT") 5 -- DENSITY/PRE—COMPENSATION 6 -- LAST ACCESSED TRACK STORAGE 7 -- STEP RATE ; WHEN BOTH 5" AND 8" DRIVES ARE CONFIGURED IN, DRIVES "A:" AND "B:" WILL ; BE 8", WHILE DRIVES "C:" AND "D:" WILL BE 5". DRO: IF MAXI ;8" CONFIG TABLES DEFB 0CH,0FFH,60,4,64,10H,0,MAXIRATE DEFB 0DH,0FFH;60,4;64;10H,0,MAXIRATE ENDIF IF MAXI AND NOT BOTH DEFB 0EH,0FFH,60,4,64,10H,0,MAXIRATE DEFB 0FH,0FFH,60;4,64,10H,0,MAXIRATE ENDIF IF MINI ;5" CONFIG TABLES MINIA B ENDIF 9 IF -MINI ;5" CONFIG TABLES MINIA B ENDIF IF MINI AND NOT BOTH MINIC D ENDIF ;****************************************************************************** ; HERE ARE SOME PRE-INITIALISED DATA VARIABLE STORAGE LOCATIONS. QHEAD: DEFW FIFOBUF OTAIL: DEFW FIFOBUF PNTR9: DEFB 00 RTCVAL: DEFB 0 FLAG1: DEFB 00 PNTP2: DEFB 00 MINIVAL: DEFB 100 ;MINI-DISC MOTOR OFF DELAY COUNT ;*****************************************************************************; ;* *; ;* ALL RAM FROM HERE ON IS UNINITIALISED. THE "BOOT" CODE IS ONLY NEEDED AT *; ;* COLD BOOT TIME AND SO IS LATER OVERWRITTEN AS REQUIRED FOR COMPACTNESS. *; ;* *; ;*****************************************************************************; ; THE DISC BOOTSTRAP ARRIVES HERE WHEN ALL CP/M IS LOADED. WE NOW SET THE = INTERRUPT MODE, PRINT A SIGN-ON MESSAGE, INITIALIZE LOW MEMORY AND ENTER CCP. BOOT: DI ;NO INTERRUPTS YET IM2 ;SET INTERRUPT MODE 2 LD A,BIOS SHR 8 STAI ;SET INTERRUPT BASE REGISTER LD HL,INITBL ;POINTER TO INITAL VALUES CALL ZINIT ; SEND TO PORTS IN A,DARTAD ;SUCK UP ANY JUNK IN A,DARTAD (DART IS TRIPLE BUFFERED) IN A,DARTAD CALL RESET ;SET ALL DRIVES TO TRACK ZERO, THEN LD HL,CCP ;SAVE THE CCP+BDOS IN THE SECOND BANK LD DE,WBHOLD ; FOR LATER WARM BOOT OPERATIONS LD A,10H ;SET TO MOVE FROM PAGE 1 TO PAGE 2. CALL M2MXFER LD HL,122 ;RESTORE THE CP/M BLOCK LENGTH LD (M2MDST+2),HL EI ; ALLOW RTC AND CONSOLE INTERRUPTS CALL PRINTO ;PRINT THE SIGN-ON. DEFB EOF ; CLEAR SCREEN DEFB ACR,ALF ONE LINE DOWN DEFB 'ARCHIVE Computer Services' DEFB ACR,ALF DEFB (SIZE / 10) '0'; CP/M SIZE (TENS) DEFF (SIZE MOD 10) + '0'; CP/M SIZE (UNITS) DEFB 'K CP/M Ver 2.2 - Mod ' DEFW REVLEV DEFB ACR,ALF DEFB 'Drives Supported ' IF NOT BOTH IF MAXI DEFB '3" Only,' IF NOT BOTH IF MAXI DEFB '8" Only,' ENDIF IF MINI DEFB '5" Only.' ENDIF ENDIF IF BOTH DEFB `8" 5 ENDIF DEFB ACR,ALF,ALF DEFB '** With "Enhanced CCP" **1 DEFB ACR,ALF,ALF,0 XOR A LD (CDISK),A ;FORCE TO DEFAULT DRIVE LD (SECS),A ;ZERO THE SECONDS COUNT, LD (MINS),A ; THE MINUTES, LD (HRS),A ; AND THE HOURS. LD HL,DAg'S ;STORE THE DAYS SINCE JAN-Ist-1982 LD (DÄTE),HL LD A,(IOVÄLU) ;SETUP INITIAL I/O BYTE LD (I0BYTE),A LD A,5 ;ADDRESS DART CH. "B" REGISTER 5 OUT DARTBC,A ; AND TURN ON DTR AND CTS LD A,0EAH OUT DARTBC,A LD HL,CCP ;SET FOR A CCP ENTRY WITH AUTO-COMMAND JP SETLOW ;NOW DO COMMON BOOT CODE. ;****************************************************************************** ; THE FOLLOWING TABLE INITIALISES THE CTC, DART, AND PIO. ; BAUD RATES FOR CTC CHANNELS 0, 1 AND 2 ARE: 300 ,. 80H 4900 8 9 530 .. 40H 9600 .. 4 1200 .. 20H 19200 .. 2 2400 ,. 10H 38400 .. 1 VECTORED INTERRUPTS ARE SET FOR CONSOLE INPUT AND RTC (CTC 2/3) ONLY. INITBL: ;EB2C DEFB 2 DEFB CTCO ;CTC 0 DEFB 45H ;COUNTER, 16X BPSA: EFB 2;19200 BPS DEFB 9 ;9 VALUES IN SET FOLLOW DEFB DARTAC ;DART CHANNEL A DEFB 18H ;CHANNEL RESET DEFB 14H ;RESET, SELECT REG 4 MODEA: DEFB 84H ;16X CLOCK, 1 STOP BIT, NO PARITY DEFB 13H ;RESET, SELECT REG 3 DEFB 0C/H ;RX ENABLE, 8 BITS DEFB 15H ;RESET, SELECT REG 5 DEFB OEAH ;TX ENABLE, 8 BITS, DTR AND RTS ON. DEFB 1 ;SELECT REG 1 DEFB 18H ;INTERUPT ON ALL RX CHARS FROM CH. A 2 DEFB CTC1 ;CTC 1 DEFB 45H ;COUNTER, 16X DEFB 80H ;300 BPS DEFB 11 ;11 VALUES IN SET DEFB DARTBC ;DART CHANNEL B DEFB 18H ;CHANNEL RESET DEFB 12H ;RESET, SELECT REG 2 DEFB (VIR1 ANO OFFH) ;SET INTERRUPT VECTOR DEFB I4H ;RESET, SELECT REG 4 MODEB: DEFB 84H CLOCK, STOP BITS AND PARITY DEFB 134 ;RESET, SELECT REG 3 DEFB (VIR1 AND OFFH) ;SET INTERRUPT VECTOR DEFB 14H ;RESET, SELECT REG 4 'MODEB: DEFB 84H ; CLOCK, STOP BITS AND PARITY DEFB 13H ;RESET, SELECT REG 3 BITSB: DEFB 0E1H ;RX ENABLE, 8 DATA BITS, CTS HANDSHAKE. DEEB 15H ;RESET, SELECT REG 5 DEFB OEAH ;TX ENABLE, 8 BITS, DTR AND RTS ON. DEFB 1' REG 1 DEFB 0 ;NO INTERRUPTS. DEFB 2 DEFB PIOAC ;PIO CHANNEL A DEFB OFH ;CHANNEL A IS OUTPUT DEFB 3 ;NO INTERRUPTS DEFB 4 DEFB PIOBC ;PIO CHANNEL B DEFB 0CFH ;CHANNEL B IS CONTROL DEFB 0FFH ;ALL BITS ARE INPUTS DEFB 37H ;NO INTERRUPTS DEFB 1 DEFB 1 DEFB CTCO ;CTC 0 DEFB (VIR2 AND 0FFH) ;INTERRUPT VECTOR DEFB 2 DEFB CTC2 ;CTC 2 DEFB 45H ;COUNTER, 16X DEFB 1 ; 38400 BPS DEFB 2 DEFB CTC3 ;CTC 3 DEFB 0A5H ;TIMR DEFB 0 ;COUNTDOWN VALUE DEFB 0 1****************************************************************************** ; THE PEMAINING ARE IS UNINITIALISED DATA, BUT MUST OF COURSE BE AVAILABLE. ORG BOOT DIRBUF: ; DEFS 128 ;COMMON DIRECTORY BUFFER AREA ;ALLOCATION AND CHECK VECTORS FOR 8" AND 5" DRIVES ALV0: ; "ALV" STORAGE IS ALLOCATED AS: DEFS 38 ABS(TOTAL-BLOCKS/S) + 1 BYTES ALV1: "CSV" STORAGE IS ALLOCATED AS: DEFS 38 CHECKED DIRECTORY ENTRIES/4 BYTES. ALV2: DEFS 38 ;VALUES ARE SET TO EQUAL THE MAXIMUM REQUIREMENT ALV3: ;FOR 8" DRIVES. DEFS 38 ALVM: DEFS 07 IF MAXI AND NOT MINI;MUST ALLOW 64 BYTES FOR "MORROW" TWO SIDE CSV0: ;DISCS WITH 256 DIRECTORY ENTRIES. SINCE DEFS 64 ;WE ARE GETTING SHORT ON ROOM, THE FOLLOWING CSV1: ;CONDITIONALS PREVENT US HAVING MORE THAN DEFS 64 ;TWO OF THIS TYPE IF THE MINI-DRIVE CODE IS CSV2: ;INCLUDED. DEFS 64 clz;v3; CSV0: DEFS 44 CSV1: ENDIF IF MINI AND NOT MAXI DEFS 32 DEFS 32 CSVO: CSV1: r53V7: CSV3:_ CSV0: CSV1: CSV2: CSV3: DEFS 32 DEFS DEFS 32 DEFS 32 ENDIF IF BOTH DEFS 64 DEFS 64 DEFS 32 DEFS 32 ENDIF CSVM: DEFS 0 ;BECAUSE DRIVE IS NON-EXCHANGABLE ;****************************************************************************** • PRVHLD: DEFS 1 NXTSEC: DEFS 1 REALTRK: DEFS 2 MSRCE: DEFS 2 MDEST: DEFS 2 SEKDMA: DEFS 2 SEKDSK: DEFS 1 SEKTRK: DEFS 1 SEKSEC: DEFS 1 DISK: DEFS 1 TRACK: DEFS 1 MAPMT: DEFS 1 CACHFUL: DEFS 1 OPFAIL: DEFS 1 RWRTRY: DEFS 1 FLAG5: DEFS 1 BLKCNT: DEFS 1 UNITSEL: DEFS 1 SPHOLD3: DEFS 2 DEFS SPHOLD1: DEFS 2 DEFS 16 "•••• FEG'IzAVE: DEFS 6 SPHOLD1: DEFS 2 DEFS 16 REGSAVE: DEFS 48 SPHOLD2: DEFS 2 DEFS 49 FIFOBUF: DEFS 63 CBUFTOP: DEFS 1 PPMSAVE:;AREA TO HOLD DRIVE PARAMS DEFS 2 ; FOR EASY (NON-INDEXED) ACCESS SECMAv: DEFS 1 ;BLOCKS/TRACK SECSIZE: DEFS 2 ;BLOCKS/SECTOR PRECOMP: DEFS 1 ;TEMPSTORE D2 2 ;****************************************************************************** THIS 6 BYTE AREA HOLDS SECTOR HEADER INFORMATION. IDSAVE: DEFS 1 ;TRACK NUMBER IDSIDE: DEFS 1 ;SIDE NUMBER IDSEC: DEFS 1 ;SECTOR NUMBER IDSIZE: DEFS 1 ;SECTOR SIZE (0..3) DEFS 2 ;CRC VALUE ;****************************************************************************** ; THIS AREA IS USED TO FLAG BLOCKS OF THE TRACK BUFFER WHICH HAVE BEEN CHANGED ; (WRITTEN TO). EACH BYTE REPRESENTS A 128 BYTE BLOCK. WHEN A SECTOR IS READ, ; THE CORRESPONDING BYTES ARE ZEROED. ANY BLOCK WHICH IS SUBSEQUENTLY WRITTEN ; TO IS SET TO "FF". THE MAP IS USED TO UPDATE THE DISC WHEN THE HEADS MOVE. 9 BLOKMAP: DEFS 64 ;FLAGS FOR A POSSIBLE 8K TRACK. ;****************************************************************************** EMD