TITLE 'XIOS200, Copyright 1979, ALTOS COMPUTER SYSTEMS' ;----------------------------------------------------------------------- ; ; ; ALTOS COMPUTER SYSTEMS ; 2338A WALSH AVENUE ; SANTA CLARA, CALIFORNIA 95050 ; ; (408) 244-5766 ; ; ; Copyright 1979, ALTOS COMPUTER SYSTEMS ; ; This program is a copyright program product of ; ALTOS COMPUTER SYSTEMS and is distributed to the ; owners of ALTOS SUN SERIES 8000 computers for ; use on those systems only. Any other use of this ; software constitutes a breach of the copyright ; license to the purchaser. ; ; VERSION NUMBER: 1.00 ; VERSION DATE: DECEMBER 31, 1979 ; . Add support for CP/M version 2.0 ; . Add support for Hard disk drives ; . Add support for disk MODE selection ; . Provide compatability MODE for 1.4 operation ; . Remove CTC/1791 counter reset ; ;----------------------------------------------------------------------- ;----------------------------------------------------------------------- ; ; Mode 0 IBM single density ; 1 ALTOS double density Version 2.0 ; 2 ALTOS double density Version 1.4 ; 3 ALTOS hard disk Version 2.0 (8 MEG AT 000) ; 4 ALTOS HARD DISK VERSION 2.0 (8 MEG AT 512) ; 5 ALTOS HARD DISK VERSION 2.0 (8 MEG AT 1024) ; 6 ALTOS HARD DISK VERSION 2.0 (4 MEG AT 512) ; ;----------------------------------------------------------------------- ;----------------------------------------------------------------------- ; ; ASSEMBLER CONTROL STATEMENTS ; ;----------------------------------------------------------------------- MACLIB DISKDEF MACLIB Z80S TRUE EQU 0FFFFH ;VALUE FOR TRUE FALSE EQU NOT TRUE ;VALUE FOR FALSE ;----------------------------------------------------------------------- ; ; THE FOLLOWING EQUATES ARE USER MODIFIABLE BASED ON THE ; PARTICULAR USER SYSTEM AND OPTIONS SELECTED. ; ;----------------------------------------------------------------------- DMA EQU TRUE ;DMA HARDWARE SUPPORT ?? HARDSK EQU TRUE ;HARD DISK SUPPORT ;----------------------------------------------------------------------- ; ; THE FOLLOWING CONSTANTS APPLY TO THE DEBLOCKING OF ; SECTORS LARGER THAN 128 FOR THE ALTOS DOUBLE DENSITY ; AND THE ALTOS HARD DISK. ; ;----------------------------------------------------------------------- BLKSIZ EQU 16384 ;CP/M ALLOCATION SIZE HSTSIZ EQU 1024 ;HOST DISK SECTOR SIZE HSTSPT EQU 16 ;HOST DISK SECTORS PER TRACK HSTBLK EQU HSTSIZ/128 ;CP/M SECTORS PER HOST BUFFER CPMSPT EQU HSTBLK * HSTSPT ;CP/M SECTORS PER TRACK SECMSK EQU HSTBLK - 1 ;SECTOR MASK SECSHF EQU 3 ;LOG2(HHSTBLK) PAGE ;----------------------------------------------------------------------- ; ; THE FOLLOWING EQUATES APPLY TO THE RELOCATABILITY ; OF THE CBIOS AND SHOULD NOT BE USER ALTERED. ; ;----------------------------------------------------------------------- RELOC EQU TRUE ;RELOCATABLE VERSION ?? ;----------------------------------------------------------------------- IF HARDSK MAXDSK EQU 12 ;MAXIMUM NUMBER OF LOGICAL DRIVES ELSE MAXDSK EQU 4 ;MAXIMUM NUMBER OF LOGICAL DRIVES ENDIF IF RELOC ORG 0000H ELSE ORG 0C000H ENDIF BASE EQU $ ;----------------------------------------------------------------------- WRALL EQU 0 ;WRITE TO ALLOCATED WRDIR EQU 1 ;WRITE TO DIRECTORY WRUAL EQU 2 ;WRITE TO UNALLOCATED NMBCNS EQU 4 ; NUMBER OF CONSOLES POLL EQU 131 ; XDOS POLL FUNCTION FLAGWT EQU 132 ; XDOS FLAG WAIT FUNCTION FLAGST EQU 133 ; XDOS FLAG SET FUNCTION PLLPT EQU 0 ; POLL PRINTER PLCO0 EQU PLLPT+1 ; POLL CONSOLE OUT #0 (CRT:) PLCO1 EQU PLCO0+1 ; POLL CONSOLE OUT #1 (CRT:) PLCO2 EQU PLCO1+1 ; POLL CONSOLE OUT #2 (CRT:) PLCO3 EQU PLCO2+1 ; POLL CONSOLE OUT #3 (CRT:) PLCI0 EQU PLCO3+1 ; POLL CONSOLE IN #0 (CRT:) PLCI1 EQU PLCI0+1 ; POLL CONSOLE IN #1 (CRT:) PLCI2 EQU PLCI1+1 ; POLL CONSOLE IN #2 (CRT:) PLCI3 EQU PLCI2+1 ; POLL CONSOLE IN #3 (CRT:) MEMPORT EQU 009H ; MEMORY SELECT PORT MEMSK EQU 002H ; MEMORY SELECT MASK PAGE ;----------------------------------------------------------------------- ; ; JUMP VECTORS FOR ENTRIES TO CBIOS ROUTINES ; ;----------------------------------------------------------------------- ; EXTERNAL JUMP TABLE (BELOW XIOS BASE) PDISP EQU $-3 XDOS EQU PDISP-3 JMP COLDSTART ;COLD START WBOTE: JMP WARMSTART ;WARM START JMP CONST ;CONSOLE STATUS JMP CONIN ;CONSOLE CHARACTER IN JMP CONOUT ;CONSOLE CHARACTER OUT JMP LIST ;LIST CHARACTER OUT JMP RTNEMPTY ;PUNCH NOT IMPLEMENTED JMP RTNEMPTY ;READER NOT IMPLEMENTED JMP HOMEIT ;MOVE HEAD TO HOME JMP SELDSK ;SELECT DISK JMP SETTRK ;SET TRACK NUMBER JMP SETSEC ;SET SECTOR NUMBER JMP SETDMA ;SET DMA ADDRESS JMP READ ;READ DISK JMP WRITE ;WRITE DISK JMP POLLPT ;LIST STATUS JMP SECTRAN ;SECTOR TRANSLATE ; EXTENDED I/O SYSTEM JUMP VECTOR JMP SELMEMORY ; SELECT MEMORY JMP POLLDEVICE ; POLL DEVICE JMP STARTCLOCK ; START CLOCK JMP STOPCLOCK ; STOP CLOCK JMP EXITREGION ; EXIT REGION JMP MAXCONSOLE ; MAXIMUM CONSOLE NUMBER JMP SYSTEMINIT ; SYSTEM INITIALIZATION NOP ; NO JMP HERE NOP ; FOR MP/M DELAY NOP ; JMP SETMOD ;ROUTINE TO SET DISK MODE JMP RETMOD ;ROUTINE TO RETURN CURRENT MODE COLDSTART: WARMSTART: MVI C,0 ; SEE SYSTEM INIT ; COLD & WARM START INCLUDED ONLY ; FOR COMPATIBILITY WITH CP/M JMP XDOS ; SYSTEM RESET, TERMINATE PROCESS RTNEMPTY: XRA A ; NOT USED RET ; LAST: ORG (((LAST-BASE)+0A2H) AND 0FF00H) +05EH INTERUPT: DW FLOPPY$INT ;FLOPPY DISK INTERRUPT DW NULL$INT ; DW NULL$INT ; DW NULL$INT ; DW INT1HND ;CTC INTERRUPT DW NULL$INT ; DW HARD$INT ;HARD DISK INTERRUPT DW NULL$INT ; DW NULL$INT ; NULL$INT: EI RETI PAGE ;----------------------------------------------------------------------- ; ; WORK AND CONTROL AREAS FOR CBIOS SERVICES ; ;----------------------------------------------------------------------- TRK0: DB 0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH SEL0: DB 004H,008H,010H,020H,010H,010H,010H,020H,020H,020H,010H,020H MODE: DB 000H,000H,000H,000H,003H,004H,005H,003H,004H,005H,006H,006H TCNT: DB 000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H PCNT: DB 000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H,000H DISKNO: DB 000H ;CURRENT DRIVE NUMBER TRAKNO: DB 000H ;CURRENT TRACK NUMBER HEADNO: DB 000H ;CURRENT HEAD NUMBER DMAADR: DW 000H ;CURRENT DMA ADDRESS SECTNO: DB 000H ;CURRENT SECTOR NUMBER DPEPTR: DW 000H ;CURRENT DPE ADDRESS DBLKAD: DW 000H ;CURRENT EXTENSION ADDRESS MPARMS: DW 000H ;MISC. PARAMETERS HTK1: DB 10H ;HARD DISK # 1 TRACK HTK2: DB 20H ;HARD DISK # 2 TRACK ; ; PARAMETER FLAGS ; ; 0100H = DOUBLE HEADED DRIVES ; 0200H = CENTRONICS PRINTER FOR LIST DEVICE ; 0400H = FOUR DRIVE SYSTEM [ A B C D ] ;----------------------------------------------------------------------- ; ;----------------------------------------------------------------------- ; ; NOTE: ; NO CHANGES ARE TO BE MADE TO THE ABSOLUTE LOCATIONS OF ; ANY FIELDS PRIOR TO THIS POINT. EXTERNAL PROGRAMS ARE ; DEPENDENT UPON THE LOCATION OF THE PRECEEDING DATA. ; ;----------------------------------------------------------------------- NMIRTN: DB 0EDH,0A2H,0EDH,045H ;FAKE INI AND RETN INST DMAS1: DB 0C3H,07DH ;FIRST PART OF DMA SETUP DMASA: DW 000H ;ADDRESS FOR I/O DMALEN: DW 1025-1 ;LENGTH FOR I/O DMAS2H: DB 054H,0CEH,068H,0CEH,0A5H,020H ;HARD DISK SETUP DMAS2F: DB 014H,028H,085H,007H ;FLOPPY DISK SETUP DMAS3: DB 08AH,0CFH,001H,0CFH ;LAST PART OF DMA SETUP DMAS3F: DB 001H ;001=READ, 005=WRITE DB 0CFH,087H ;SETUP DMA, ENABLE PAGE ;----------------------------------------------------------------------- ; ; CONTROL BLOCKS FOR DISK DRIVER ; ;----------------------------------------------------------------------- DPBASE EQU $ ;START OF DISK PARAMETER BLOCKS DPE0: DW XLT0,0000H ;TRANSLATE TABLE AND WORK AREA DW 0000H,0000H ;SCRATCH AREA DW DIRBUF,DPB0 ;DIR BUFF, PARM BLOCK DW CSV0,ALV0 ;CHECK VECTOR, ALLOC VECTOR DPE1: DW XLT0,0000H ;TRANSLATE TABLE AND WORK AREA DW 0000H,0000H ;SCRATCH AREA DW DIRBUF,DPB0 ;DIR BUFF, PARM BLOCK DW CSV1,ALV1 ;CHECK VECTOR, ALLOC VECTOR DPE2: DW XLT0,0000H ;TRANSLATE TABLE AND WORK AREA DW 0000H,0000H ;SCRATCH AREA DW DIRBUF,DPB0 ;DIR BUFF, PARM BLOCK DW CSV2,ALV2 ;CHECK VECTOR, ALLOC VECTOR DPE3: DW XLT0,0000H ;TRANSLATE TABLE AND WORK AREA DW 0000H,0000H ;SCRATCH AREA DW DIRBUF,DPB0 ;DIR BUFF, PARM BLOCK DW CSV3,ALV3 ;CHECK VECTOR, ALLOC VECTOR IF HARDSK DPE4: DW 0000H,0000H ;TRANSLATE TABLE AND WORK AREA DW 0000H,0000H ;SCRATCH AREA DW DIRBUF,DPB3 ;DIR BUFF, PARM BLOCK DW CSV4,ALV4 ;CHECK VECTOR, ALLOC VECTOR DPE5: DW 0000H,0000H ;TRANSLATE TABLE AND WORK AREA DW 0000H,0000H ;SCRATCH AREA DW DIRBUF,DPB4 ;DIR BUFF, PARM BLOCK DW CSV5,ALV5 ;CHECK VECTOR, ALLOC VECTOR DPE6: DW 0000H,0000H ;TRANSLATE TABLE AND WORK AREA DW 0000H,0000H ;SCRATCH AREA DW DIRBUF,DPB5 ;DIR BUFF, PARM BLOCK DW CSV6,ALV6 ;CHECK VECTOR, ALLOC VECTOR DPE7: DW 0000H,0000H ;TRANSLATE TABLE AND WORK AREA DW 0000H,0000H ;SCRATCH AREA DW DIRBUF,DPB3 ;DIR BUFF, PARM BLOCK DW CSV7,ALV7 ;CHECK VECTOR, ALLOC VECTOR DPE8: DW 0000H,0000H ;TRANSLATE TABLE AND WORK AREA DW 0000H,0000H ;SCRATCH AREA DW DIRBUF,DPB4 ;DIR BUFF, PARM BLOCK DW CSV8,ALV8 ;CHECK VECTOR, ALLOC VECTOR DPE9: DW 0000H,0000H ;TRANSLATE TABLE AND WORK AREA DW 0000H,0000H ;SCRATCH AREA DW DIRBUF,DPB5 ;DIR BUFF, PARM BLOCK DW CSV9,ALV9 ;CHECK VECTOR, ALLOC VECTOR DPEA: DW 0000H,0000H ;TRANSLATE TABLE AND WORK AREA DW 0000H,0000H ;SCRATCH AREA DW DIRBUF,DPB6 ;DIR BUFF, PARM BLOCK DW CSVA,ALVA ;CHECK VECTOR, ALLOC VECTOR DPEB: DW 0000H,0000H ;TRANSLATE TABLE AND WORK AREA DW 0000H,0000H ;SCRATCH AREA DW DIRBUF,DPB6 ;DIR BUFF, PARM BLOCK DW CSVB,ALVB ;CHECK VECTOR, ALLOC VECTOR ENDIF ;----------------------------------------------------------------------- MODL0: DW XLT0,000H ;MODEL DPE FOR MODE 0 DW 000H,000H ; DW DIRBUF,DPB0 ; MODL1: DW XLT1,0000H ;MODEL DPE FOR MODE 1 DW 0000H,0000H ; DW DIRBUF,DPB1 ; MODL2: DW XLT2,0000H ;MODEL DPE FOR MODE 2 DW 0000H,0000H ; DW DIRBUF,DPB2 ; ;----------------------------------------------------------------------- XLT0: DB 1,7,13,19,25,5,11,17,23,3,9,15,21 DB 2,8,14,20,26,6,12,18,24,4,10,16,22 XLT1: DB 01,02,03,04,05,06,07,08,09,10,11,12,13 DB 14,15,16,17,18,19,20,21,22,23,24,25,26 DB 27,28,29,30,31,32,33,34,35,36,37,38,39 DB 40,41,42,43,44,45,46,47,48,49,50,51,52 XLT2: DB 01,02,03,04,05,06,07,08,09,10,11,12 DB 13,14,15,16,17,18,19,20,21,22,23,24 DB 25,26,27,28,29,30,31,32,33,34,35,36 DB 37,38,39,40,41,42,43,44,45,46,47,48 PAGE ;----------------------------------------------------------------------- ; ; THESE ARE THE DISK TYPE DEFINITION BLOCKS ; EACH OF WHICH CORRESPONDS TO A PARTICULAR MODE. ; ;----------------------------------------------------------------------- DPB0: EQU $ ;VERSION 2.0, IBM SINGLE DENSITY DW 26 ;SECTORS PER TRACK DB 3 ;BLOCK SHIFT DB 7 ;BLOCK SHIFT MASK DB 0 ;EXTENT MASK DW 242 ;DISK SIZE MINUS 1 DW 63 ;DIRECTORY MAX DB 192 ;ALLOC0 DB 0 ;ALLOC1 DW 16 ;CHECK AREA SIZE DW 2 ;OFFSET TO START TRACK DPB1: EQU $ ;VERSION 2.0, IBM DOUBLE DENSITY DW 52 ;SECTORS PER TRACK DB 4 ;BLOCK SHIFT DB 15 ;BLOCK SHIFT MASK DB 1 ;EXTENT MASK DW 242 ;DISK SIZE MINUS 1 DW 127 ;DIRECTORY MAX DB 192 ;ALLOC0 DB 0 ;ALLOC1 DW 32 ;CHECK AREA SIZE DW 2 ;OFFSET TO START TRACK DPB2: EQU $ ;VERSION 1.4 ALTOS DOUBLE DENSITY DW 48 ;SECTORS PER TRACK DB 4 ;BLOCK SHIFT DB 15 ;BLOCK SHIFT MASK DB 0 ;EXTENT MASK (1.4 COMPATABILITY) DW 224 ;DISK SIZE MINUS 1 DW 95 ;DIRECTORY MAX DB 192 ;ALLOC0 DB 0 ;ALLOC1 DW 24 ;CHECK AREA SIZE DW 2 ;OFFSET TO START TRACK IF HARDSK DPB3: DISKDEF 3,0,127,,16384,512,256,0,1 DPB4: DISKDEF 4,0,127,,16384,512,256,0,513 DPB5: DISKDEF 5,0,127,,16384,512,256,0,1025 DPB6: DISKDEF 6,0,127,,16384,288,256,0,513 ENDIF PAGE ;----------------------------------------------------------------------- ; ; DISK ACCESS ROUTINES ; ;----------------------------------------------------------------------- SELDSK: MOV A,C ;LIMIT SELECT TO REAL OPTIONS CPI MAXDSK ; JRNC SELERR MVI B,0 LXI H,SEL0 DAD B MOV A,M ORA A JRZ SELERR MOV A,C CPI 4 JRNC CHKHRD MOV A,M OUT 08H PUSH B MVI C,1 CALL DELAY POP B IN 04H RAL JRC SELERR JR SELSDT CHKHRD: MOV A,M OUT 20H PUSH B MVI C,1 CALL DELAY POP B IN 24H RAL JRNZ SELERR SELSDT: LXI H,0 mov a,c STA NEWDSK ;SAVE FOR I/O LATER MOV L,C ;COMPUTE DP HEADER ADDRESS DAD H ;* 2 DAD H ;* 4 DAD H ;* 8 DAD H ;* 16 (DP HEADER SIZE) LXI D,DPBASE ;START OF DP HEADERS DAD D ;POINT TO CORRECT ONE SHLD DPEPTR ;SAVE ADDRESS OF CURRENT DP BLOCK RET ; SELERR: LXI H,0 RET SETDMA: MOV H,B ;TO ALLOW SAVING MOV L,C ; SHLD DMAADR ; RET ;RETURN TO CALLER SETTRK: MOV H,B ;TO ALLOW SAVE MOV L,C ; SHLD NEWTRK ;SAVE NEXT TRACK NUMBER RET ;RETURN TO CALLER SETSEC: MOV A,C ;FOR SAVE STA NEWSEC ; RET ;RETURN TO CALLER SETDEN: LXI D,SEL0 ;START OF SELECT/DENSITY MASKS LHLD NEWDSK ;NEXT DRIVE ADDRESS MVI H,000H ;ENSURE ZERO FOR SINGLE BYTE QUANTITY DAD D ;POINT TO CORRECT MASK MOV A,C ;ISOLATE DENSITY BIT ANI 00000001B ; MOV C,A ;SAVE FOR NOW MOV A,M ;LOAD SELECT DENSITY MASK ANI 11111110B ;RESET CURRENT DENSITY SETTING ORA C ;SET NEW VALUE MOV M,A ;RESTORE MASK IN TABLE RET ;RETURN TO CALLER READ: CALL RETMOD ;WHAT TYPE OF I/O ?? CPI 003H ; JC READSOFT ;FLOPPY DISK DRIVE.... JMP READHARD ;HARD DISK I/O WRITE: CALL RETMOD ;WHAT TYPE OF I/O ?? CPI 003H ; JC WRITESOFT ;FLOPPY DISK JMP WRITEHARD ;HARD DISK I/O PAGE ;----------------------------------------------------------------------- ; ; ROUTINES TO SET AND RETURN THE CURRENT DRIVE MODE ; ;----------------------------------------------------------------------- SETMOD: LHLD NEWDSK ;NEXT DRIVE FOR I/O MVI H,000H ; MOV A,L ;CHECK MODE SET VALIDITY CPI 004H ;ONLY VALID FOR FLOPPY DISK DRIVES RNC ;INVALID DRIVE FOR MODE SET, RETURN LXI D,MODE ;START OF MODE BYTES DAD D ; MOV M,C ;SAVE NEW MODE BYTE PUSH H ;SAVE MODE BYTE ADDRESS MOV A,C ;SETUP FOR DENSITY CHANGE ORA A ; MVI C,000H ;ASSUME SINGLE DENSITY MODE.... JRZ SETSEL ;VERIFY ASSUMPTION MVI C,001H ;SET FOR DOUBLE DENSITY MODE.... SETSEL: CALL SETDEN ;SET DENSITY BASED ON LOW BIT POP H ;RESTORE MOV L,M ;PICKUP MODE AGAIN MVI H,000H ;FOR SINGLE BYTE PRECISION MOV A,L ;SAVE MODE IN ACCUMULATOR FOR LATER DAD H ;* 2 DAD H ;* 4 PUSH H ;SAVE * 4 DAD H ;* 8 POP D ;REGAIN * 4 DAD D ;* 12 LXI D,MODL0 ;FIRST MODEL DPE DAD D ;POINT TO THIS ONE XCHG ;SETUP TEMPORARILY AS DESTINATION LHLD DPEPTR ;ADDRESS OF CURRENTLY SELECTED DPE XCHG ;SETUP TO ALTER LXI B,12 ;LENGTH FOR MOVE LDIR ;DO MOVE RET ;RETURN TO CALLER RETMOD: LXI D,MODE ;START OF MODE BYTES LHLD NEWDSK ;NEXT DRIVE FOR I/O MVI H,000H ;RESET FOR SINGLE BYTE QUANTITY DAD D ;POINT TO IT.... MOV A,M ;LOAD IT FOR CALLER RET ;RETURN, WITH CURRENT MODE SETTING PAGE ;----------------------------------------------------------------------- ; ; THIS IS THE HOME DEVICE ROUTINE ; ;----------------------------------------------------------------------- HOMEIT: LDA NEWDSK ; CHECK FOR FIRST HOME CPI 4 ; CHECK FOR FLOPPY JC HOME ; DO NOT BYPASS FLOPPY HOME MOV C,A ; MVI B,0 ; POINT TO PRESENT TRACK STORED LXI H,TRK0 ; DAD B ; MOV A,M ; CHECK IF INITIALIZED CPI 0FFH ; MVI A,0 ; RNZ ; YES - RETURN WITH NO ERROR MOV M,A ; HOME: LDA NEWDSK ;GET VALUE OF DRIVE FOR HOME CPI 004H ;IS IT A HARD DISK ?? JNC HOMEHARD ;YES, PROCESS.... HOMESOFT: CALL DSKSEL ;SELECT CORRECT DRIVE (IN ACCUMULATOR) CALL POINT ;POINT TO TRACK REGISTER SAVE AREA MVI M,000H ;RESET TO TRACK ZERO CALL DBL$UPDATE ; MVI A,00AH ;HOME COMMAND.... OUT 004H ;DO IT.... HOME1: CALL WAIT0 ;WAIT UNTIL I/O COMPLETE LDA STATUS ;PICKUP STATUS BYTE ANI 10011000B ;CHECK STATUS RZ ;RETURN WITH GOOD ESULT MVI A,001H ;SET ERROR ON HOME RET ;AND RETURN.... HOMEHARD: IF HARDSK CALL DSKSEL ;SELECT CORRECT DRIVE (IN ACCUMULATOR) CALL POINT ;POINT TO SAVE AREA MVI M,000H ;SET TO TRACK ZERO XCHG ;POINT TO SELECT WORD MOV A,M ;LOAD SELECT MASK ANI 11110000B ;RESET HEAD MASK MOV M,A ;SAVE OUT 020H ;WRITE HEAD/SELECT MASK MVI A,020H ;HOME COMMAND OUT 023H ;DO IT.... HOME2: CALL WAIT0 ;WAIT UNTIL I/O COMPLETE MVI C,20 ;DELAY FOR 20 MILLISECONDS CALL DELAY ; XRA A ;SET NEW TRACK REGISTER TO ZERO OUT 022H ;FOR CONTROLLER ; LXI H,MHM ;***DEBUG*** ; CALL MSPRT ;***DEBUG*** LDA STATUS ;PICKUP STATUS BYTE ANI 01011101B ;CHECK STATUS RZ ; MVI A,001H ;SET ERROR ON HOME ENDIF RET ;AND RETURN PAGE ;----------------------------------------------------------------------- ; ; THESE ARE THE HARD DISK UNBLOCK/REBLOCK AND READ AND WRITE ; ROUTINES CALLED BY THE BDOS SOFTWARE. ; ;----------------------------------------------------------------------- READHARD: IF HARDSK XRA A ;RESET UNALLOCATED COUNT STA UNACNT ; MVI A,001H ;READ THE SELECTED CP/M SECTOR STA READOP ; STA RSFLAG ;MUST READ DATA MVI A,WRUAL ; STA WRTYPE ;TREAT AS UNALLOCATED JMP RWOPER ;TO PERFORM THE READ ENDIF WRITEHARD: IF HARDSK XRA A ;WRITE THE SELECTED CP/M SECTOR STA READOP ;NOT A READ OPERATION MOV A,C ;WRITE TYPE IS PASSED IN REG C STA WRTYPE ; CPI WRUAL ;IS IT WRITE UNALLOCATED ?? JRNZ CHKUNA ;CHECK FOR UNALLOCATED ; ; WRITE TO UNALLOCATED, SET PARAMETERS ; MVI A,BLKSIZ/128 ;NEXT UNALLOC RECS STA UNACNT ; LDA NEWDSK ;DISK FOR I/O STA UNADSK ;UNADSK = NEWDSK LHLD NEWTRK ; SHLD UNATRK ;UNATRK = NEWTRK LDA NEWSEC ; STA UNASEC ;UNASEC = NEWSEC ; ; CHECK FOR WRITE TO UNALLOCATED SECTOR ; CHKUNA: LDA UNACNT ;ANY UNALLOCATED REMAIN ?? ORA A ; JZ ALLOC ;SKIP IS NOT ; ; MORE UNALLOCATED RECORDS REMAIN ; DCR A ;UNACNT = UNACNT - 1 STA UNACNT ; LDA NEWDSK ;SAME DISK ?? LXI H,UNADSK ; CMP M ;NEWDSK = UNADSK ?? JNZ ALLOC ;SKIP IF NOT ; ; DISKS ARE THE SAME ; LXI H,UNATRK ; CALL NEWTRKCMP ;NEWTRK = UNATRK ?? JNZ ALLOC ;SKIP IF NOT ; ; TRACKS ARE THE SAME ; LDA NEWSEC ;SAME SECTOR ?? LXI H,UNASEC ; CMP M ;NEWSEC = UNASEC ?? JRNZ ALLOC ;SKIP IF NOT ; ; MATCH, MOVE TO NEXT SECTOR FOR FUTURE REFERENCE ; INR M ;UNASEC = UNASEC + 1 MOV A,M ;END OF TRACK ?? CPI CPMSPT ;COUNT CP/M SECTORS JRC NOOVF ;SKIP IF NO OVERFLOW ; ; OVERFLOW TO NEXT TRACK ; MVI M,000H ;UNASEC = 0 LHLD UNATRK ; INX H ; SHLD UNATRK ;UNATRK = UNATRK + 1 ; ; MATCH FOUND, MARK AS UNNECESSARY READ ; NOOVF: XRA A ;ZERO TO ACCUMULATOR STA RSFLAG ;RSFLAG = 0 JR RWOPER ;TO PERFORM THE WRITE ; ; NOT AN UNALLOCATED RECORD, REQUIRES PRE-READ ; ALLOC: XRA A ;ZERO TO ACCUMULATOR STA UNACNT ;UNACNT = 0 INR A ;ONE TO ACCUMULATOR STA RSFLAG ;RSFLAG = 1 ;----------------------------------------------------------------------- ; ; THE FOLLOWING CODE IS COMMON TO BOTH READ AND WRITE ; ;----------------------------------------------------------------------- RWOPER: XRA A ;ZERO TO ACCUMULATOR STA ERFLAG ;NO ERRORS YET.... LDA NEWSEC ;COMPUTE HOST SECTOR REPT SECSHF ;COMPUTE HOST SECTOR ORA A ;CARRY = 0 RAR ;SHIFT RIGHT ENDM STA NEWHST ;HOST SECTOR TO SEEK ; ; ACTIVE HOST SECTOR ?? ; LXI H,HSTACT ;HOST ACTIVE FLAG MOV A,M ; MVI M,001H ;ALWAYS BECOMES 1 ORA A ;WAS IT ALREADY ?? JZ FILLHST ;FILL HOST IF NOT ; ; HOST BUFFER ACTIVE, SAME AS SEEK BUFFER ; LDA NEWDSK ; LXI H,HSTDSK ;SAME DISK ?? CMP M ;NEWDSK = HSTDSK ?? JNZ NOMATCH ; ; ; SAME DISK, SAME TRACK ?? ; LXI H,HSTTRK ; CALL NEWTRKCMP ;NEWTRK = HSTTRK ?? JRNZ NOMATCH ; ; ; SAME DISK, SAME TRACK, SAME BUFFER ?? ; LDA NEWHST ; LXI H,HSTSEC ;NEWHST = HSTSEC ?? CMP M ; JZ MATCH ;SKIP IF MATCH ; ; PROPER DISK, BUT NOT CORRECT SECTOR ; NOMATCH: LDA HSTWRT ;HOST WRITTEN ?? ORA A ; CNZ WRITEHST ;CLEAR HOST BUFFER ; ; MAY HAVE TO FILL HOST BUFFER ; FILLHST: LDA NEWDSK ; STA HSTDSK ; LHLD NEWTRK ; SHLD HSTTRK ; LDA NEWHST ; STA HSTSEC ; LDA RSFLAG ;NEED TO READ ?? ORA A ; CNZ READHST ;YES, IF 1 XRA A ;ZERO TO ACCUMULATOR STA HSTWRT ;NO PENDING WRITE MATCH: LDA NEWSEC ;MASK BUFFER NUMBER ANI SECMSK ;LEAST SIGNIF BITS MOV L,A ;READY TO SHIFT MVI H,000H ;DOUBLE COUNT REPT 7 DAD H ; ENDM ; ; HL NOW HAS RELATIVE HOST BUFFER ADDRESS ; LXI D,HSTBUF ; DAD D ;HL = HOST ADDRESS XCHG ;NOW IN DE LHLD DMAADR ;GET/PUT CP/M DATA XCHG ;SET FOR Z80 LDIR INSTRUCTION LXI B,128 ;LENGTH OF MOVE LDA READOP ;WHICH WAY ?? ORA A ; JRNZ RWMOVE ;SKIP IF READ ; ; WRITE OPERATION, MARK AND SWITCH DIRECTION ; MVI A,001H ; STA HSTWRT ;HSTWRT = 1 XCHG ;SWAP DIRECTION ; ; MOVE SUBROUTINE ; RWMOVE: LDIR ;MOVE DATA TO/FROM BUFFER ; ; DATA HAS BEEN MOVED TO/FROM HOST BUFFER ; LDA WRTYPE ;WRITE TYPE ?? CPI WRDIR ;TO DIRECTORY ?? JRNZ RWEND ;NO, JUST END UP HERE ; ; CLEAR HOST BUFFER FOR DIRECTORY WRITE ; LDA ERFLAG ;CHECK PRIOR TO DIR ACTIVITY ORA A ;ERRORS ?? JRNZ RWEND ;SKIP IF SO.... XRA A ;ZERO TO ACCUMULATOR STA HSTWRT ;BUFFER WRITTEN CALL WRITEHST ; RWEND: LDA ERFLAG ; ORA A ;IF ERRORS, RESET SO NO MATCH NEXT TIME THRU RZ ;NONE, JUST RETURN LXI H,HSTDSK ; MVI M,0FFH ;CANT POSSIBLY MATCH, MUST REDO I/O ENDIF RET ; MVDTB: LHLD DMAADR ; MOVE DATA TO FLOPPY BUFFER LXI D,FPYBUF ; LXI B,128 ; 128 BYTES LDIR ; RET ; MVDFB: PUSH PSW ; MOVE DATA FROM FLOPPY BUFFER LDA CMD ; ANI 20H ; CHECK FOR READ JNZ MVDFX ; NO - BYPAS MOVE LHLD DMAADR ; XCHG ; DE = DESTINATION LXI H,FPYBUF ; LXI B,128 ; 128 BYTES LDIR ; MVDFX: POP PSW ; RET ; PAGE ;----------------------------------------------------------------------- ; ; UTILITY SUBROUTINE FOR 16 BIT COMPARE ; ;----------------------------------------------------------------------- IF HARDSK NEWTRKCMP: XCHG ;HL = .UNATRK OR .HSTTRK LXI H,NEWTRK ; LDAX D ;LOW BYTE COMPARE CMP M ;SAME ?? RNZ ;RETURN IF NOT INX D ;TO CHECK HIGH BYTE INX H ; LDAX D ; CMP M ;SETS FLAGS RET ; PAGE ;----------------------------------------------------------------------- ; ; WRITEHST PERFORMS THE PHYSICAL WRITE TO THE HOST DISK. ; READHST PERFORMS THE PHYSICAL READ FROM THE HOST DISK. ; ; HSTDSK = HOST DISK NUMBER ; HSTTRK = HOST TRACK NUMBER ; HSTSEC = HOST SECTOR NUMBER ; RETURN ERROR FLAG IN ERFLAG ; ;----------------------------------------------------------------------- WRITEHST: MVI A,005H ;SETUP DMA FOR WRITE STA DMAS3F ; MVI A,002H ;WRITE COMMAND STA CMD ;SAVE FOR LATER LXI H,HSTBUF-1 ;WRITE MUST WRITE CONTROL BYTE SHLD DMASA ; JMP HRW0 ; READHST: MVI A,001H ;SETUP DMA FOR READ STA DMAS3F ; MVI A,004H ;READ COMMAND STA CMD ;SAVE FOR LATER LXI H,HSTBUF ;READ ONLY DATA BYTES SHLD DMASA ; HRW0: LXI H,T$RETRIES ;SETUP TEMPORARY RETRIES COUNT MVI M,003H ; HRW1: LDA HSTSEC ;HOST SECTOR NUMBER STA SECTNO ;SAVE SECTOR NUMBER LDA HSTDSK ;PICKUP DRIVE ID FOR SELECT CALL DSKSEL ;SELECT CORRECT DRIVE FOR I/O CALL POINT ;POINT TO TRACK REGISTER SAVE AREA XCHG ;POINT TO SELECT MASK MVI A,11110000B ;TO REMOVE CURRENT HEAD SELECTION ANA M ; MOV M,A ; PUSH H ;SAVE MASK ADDRESS CALL SETHED ;COMPUTE CORRECT HEAD NUMBER MOV A,L ;TRACK NUMBER AFTER HEAD CALCULATION STA TRAKNO ; POP H ;RESTORE MASK ADDRESS LDA HEADNO ;TO OR IN NEW HEAD NUMBER ORA M ; MOV M,A ;SAVE NEW DRIVE/HEAD SELECTION ANI 07FH ; MASK OFF LARGE DRIVE FLAG OUT 020H ;WRITE IT TO SELECT NEW HEAD.... MVI C,1 ;DELAY FOR 1 MILLISECOND CALL DELAY ; HRW2: CALL POINT ;IS A SEEK NECESSARY ?? LDA TRAKNO ;CHECK CMP M ;WELL ?? JZ HRW5 ;NO SEEK NECESSARY... HRW3: OUT 022H ;WRITE NEW TRACK NUMBER MOV B,M ;SAVE TEMPORARILY MOV M,A ;UPDATE TRACK REGISTER SAVE AREA MOV A,B ;OLD TRACK NUMBER OUT 021H ;TO OLD TRACK REGISTER MVI A,010H ;SEEK COMMAND OUT 023H ;DO IT.... HRW4: CALL WAIT0 ;WAIT FOR I/O MVI C,20 ;DELAY AFTER SEEK FOR 20 MILLISECONDS CALL DELAY ; HRW5: LDA SECTNO ;SET SECTOR OUT 021H ; HRW6: LXI H,DMAS1 ;SETUP DMA FOR HARD DISK I/O LXI B,0600H ; OUTIR ; LXI H,DMAS2H ; LXI B,0600H ; OUTIR ; LXI H,DMAS3 ; LXI B,0700H ; OUTIR ; LDA CMD ;PICKUP I/O COMMAND OUT 023H ;WRITE IT OUT HRW7: CALL WAIT0 ;WAIT FOR COMPLETION MVI A,01011101B ;SETUP STATUS AND MASK STA MASK ;SAVE FOR STATUS CHECK CALL CHECK$STAT ;CHECK STATUS FROM I/O RZ ;OK ?? JMP HRW1 ;RETRY I/O ENDIF PAGE ;----------------------------------------------------------------------- ; ; DOUBLE SIDED TRACK REGISTER UPDATE ROUTINE ; ;----------------------------------------------------------------------- DBL$UPDATE: LDA MPARMS ;CHECK FOR DOUBLE SIDED DRIVES ANI 1 ; IS FLAG SET RZ ; NO - SO RETURN LDA DISKNO ;CURRENT DISK DRIVE CPI 004H ;IS IT A FLOPPY RNC ;NO, RETURN WITHOUT UPDATE ANI 00000010B ;IS THIS DRIVE 2 0R 3 ?? MOV A,M ;WE WERE CALLED WITH (HL) POINTING TO TRACK JRZ DBL$LOW ;IT MUST BE DRIVE ZERO OR ONE DCX H ;BACKUP TO OTHER SIDE POINTER DCX H ; JR DBL$SAVE ; DBL$LOW: INX H ;BUMP UP TO DRIVE TWO OR THREE INX H ; DBL$SAVE: MOV M,A ;UPDATE OTHER SIDE REGISTER RET ; PAGE ;----------------------------------------------------------------------- ; ; ROUTINE TO COMPUTE HEAD NUMBER FROM TRACK NUMBER ; TRACK NUMBER IS IN HL ON ENTRY ; ;----------------------------------------------------------------------- IF HARDSK SETHED: LHLD HSTTRK ;CP/M TRACK NUMBER (0-800) ANI 80H ; CHECK FOR LARGE DRIVE MOV A,L ;LOW ORDER JRZ SETH14 ; SMALL DRIVE ANI 00000111B ;GET TRACK MOD 8 (HEAD NUMBER) MVI C,3 ;LIMIT LOOP FOR DIVIDE BY EIGHT JR SETDVD ; SETH14: ANI 00000011B ;GET TRACK MOD 4 (HEAD NUMBER) MVI C,2 ;LIMIT LOOP FOR DIVIDE BY FOUR SETDVD: STA HEADNO ;SAVE AS HEAD NUMBER SHD1: ORA A ;ENSURE CARRY IS ZERO MOV A,H ;FOR SHIFT RAR ;ONE BIT MOV H,A ; MOV A,L ;LOW ORDER RAR ;CARRY PARTICIPATES FROM HIGH ORDER MOV L,A ; DCR C ;END OF DIVIDE YET ?? JRNZ SHD1 ;NO, CONTINUE RET ;RETURN TO CALLER, TRACK IN HL ENDIF PAGE ;----------------------------------------------------------------------- ; ; DISK DRIVE SELECT ROUTINE ; ON ENTRY, THE ACCUMULATOR CONTAINS THE DRIVE FOR SELECTION ; RETURNS CARRY SET FOR HARD DISK SELECTED ; RETURNS CARRY RESET FOR FLOPPY DISK SELECTED ; ;----------------------------------------------------------------------- DSKSEL: CPI 004H ;IS IT HARD DISK ?? JNC SELHARD ;YES, GO PROCESS.... SELSOFT: LXI H,DISKNO ;CURRENT DRIVE NUMBER CMP M ;SAME DRIVE AS LAST TIME ?? JRZ SLS3 ;YES, DONT BOTHER WITH UNLOAD MOV M,A ;UPDATE WITH CURRENT DRIVE NUMBER ;----------------------------------------------------------------------- ; ; WE WILL NOW FORCE THE HEAD TO UNLOAD PRIOR TO THE SWITCH ; TO ENSURE THAT WHEN WE RETURN TO THIS DISK WE WILL ; LOAD AND WAIT FOR THE HEAD TO SETTLE. ; ;----------------------------------------------------------------------- SLS1: IN 004H ;ENSURE FLOPPY PORT NOT BUSY RAR ; JRC SLS1 ; IN 005H ;READ THE TRACK REGISTER OUT 007H ;ENSURE WE DONT MOVE THE HEAD MVI A,012H ;SEEK AND UNLOAD HEAD OUT 004H ;DO IT.... SLS2: CALL WAIT0 ;WAIT HERE FOR INTERRUPT ;----------------------------------------------------------------------- ; ; WE WILL NOW LOAD THE SELECT MASK AND SELECT THE DRIVE ; EVEN IF ITS THE SAME DRIVE BECAUSE THE DENSITY MAY ; HAVE CHANGED. ; ;----------------------------------------------------------------------- SLS3: CALL POINT ;POINT TO TRACK SAVE AREA XCHG ;POINT TO SELECT MASK LDA TRAKNO ;NEXT TRACK FOR I/O CPI 002H ;IS IT TRACK ZERO OR ONE MVI A,11111111B ;ASSUME NO.... JRNC SLS4 ;VERIFY ASSUMPTION MVI A,11111110B ;FORCE SINGLE DENSITY FOR 0, & 1 SLS4: ANA M ;LOAD MASK AND CORRECT IF NECESSARY OUT 008H ;SELECT IT XCHG ;RESTORE TRACK REGISTER ADDRESS MOV A,M ;PICK UP TRACK NUMBER OUT 005H ;GIVE IT TO CONTROLLER ORA A ;ENSURE CARRY IS RESET RET ;----------------------------------------------------------------------- ; ; THIS ROUTINE SETS UP THE HARD DISK BY SELECTING THE CORRECT ; DRIVE AND RELOADING THE HEAD AND TRACK REGISTERS IN THE ; HARD DISK CONTROLLER READY FOR I/O LATER. ; ;----------------------------------------------------------------------- SELHARD: IF HARDSK LXI H,DISKNO ;CURRENT DRIVE SELECTED CMP M ;SAME ?? RZ ;YES, NO NEW SELECT NECESSARY MOV M,A ;UPDATE DISKNO SLH1: CALL POINT ;TRACK SAVE REGISTER XCHG ;POINT TO SELECT MASK MOV A,M ;LOAD DRIVE/HEAD VALUE OUT 020H ;WRITE IT TO SELECT PORT XCHG ;REGAIN ADDRESS OF TRACK REGISTER MOV A,M ;LOAD OLD TRACK NUMBER OUT 022H ;WRITE IT TO OLD TRACK REGISTER MVI C,20 ;DELAY FOR 20 MILLISECONDS AFTER SELECT CALL DELAY ; STC ;SET CARRY TO SHOW HARD DISK ENDIF RET ;RETURN TO CALLER PAGE ;----------------------------------------------------------------------- ; ; SUBROUTINE TO POINT TO CURRENT TRACK REGISTER SAVE AREA ; ;----------------------------------------------------------------------- POINT: LHLD DISKNO ;PICKUP CURRENT DISK MOV A,L ; MVI H,0 ;RESET HIGH ORDER HALF LXI D,TRK0 ;LOAD TRACK POINTER DAD D ;POINT TO CURRENT TRACK PTR MOV D,H ; DE = TRACK MOV E,L ; LXI B,12 ; DAD B ; HL = SELECT IF HARDSK CPI 4 ; JRC PNTFN ; FLOPPY DISK MVI A,10H ; ANA M ; CHECK DRIVE SELECT JRZ PNTH2 ; MUST BE DRIVE # 2 LXI D,HTK1 ; POINT TO DRIVE 1 JR PNTFN ; PNTH2: LXI D,HTK2 ; POINT TO DRIVE 2 ENDIF PNTFN: XCHG ; SWITCH RET ; HL = TRACK DE = SELECT ;----------------------------------------------------------------------- ; ; ROUTINE TO TRANSLATE SECTOR NUMBER ; ;----------------------------------------------------------------------- SECTRAN: XCHG ;TABLE ADDRESS IS IN DE (NOW HL) MOV A,H ;IS THERE A TABLE ADDRESS ?? ORA L ; JRZ STRN2 ;NO, JUST RETURN ENTERED QUANTITY STRN1: MVI B,000H ;ENSURE OK FOR SINGLE BYTE QUANTITY DAD B ;ADD SECTOR NUMBER MOV L,M ;LOAD TRANSLATED VALUE MVI H,000H ; RET ;NEW VALUE RETURNED IN HL STRN2: DAD B ;RETURN SAME VALUE AS ENTERED RET ; ;----------------------------------------------------------------------- ; ; ROUTINES TO DO FLOPPY I/O ; ;----------------------------------------------------------------------- READSOFT: MVI A,09FH ;MASK FOR READ STATUS STA MASK ; MVI A,001H ;SETUP DMA FOR READ STA DMAS3F ; MVI A,08CH ;READ COMMAND JR SRW1 ; WRITESOFT: MVI A,0FFH ;MASK FOR WRITE STATUS STA MASK ; CALL MVDTB ; MVI A,005H ;SETUP DMA FOR WRITE STA DMAS3F ; MVI A,0ACH ;WRITE COMMAND SRW1: STA CMD ; LXI H,FPYBUF ; SHLD DMASA ; LDA NEWDSK ; CALL DSKSEL ;SELECT DRIVE FOR I/O SRW2: MVI A,003H ;SET NUMBER OF TRIALS STA T$RETRIES ;SAVE FOR RETRY ROUTINE LOAD$HEAD: IN 008H ;IS HEAD LOADED ?? ANI 00000010B ;CHECK IT.... JNZ REMOVE$LD ;YES, ITS LOADED, DONT RELOAD.... IN 005H ;DUMMY SEEK TO START HEAD LOADING OUT 007H ;KEEP IT SHORT.... MVI A,01AH ;START HEAD LOADING OUT 004H ; LDH1: CALL WAIT0 ;WAIT FOR I/O TO COMPLETE MVI C,16 ;WAIT HERE FOR 16 MS CALL DELAY ;CALL WAIT ROUTINE CALL POINT ;REESTABLISH TRACK REGISTER POINTER MVI M,254 ;ENSURE FURTHER SEEK AND DELAY.... JR TRKTST ; REMOVE$LD: LXI H,CMD ;POINT TO I/O COMMAND MVI A,11111011B ;REMOVE HEAD LOAD BIT ANA M ;DO IT.... MOV M,A ;SAVE IT BACK INTO CMD TRKTST: CALL POINT ;RESTORE TRACK REGISTER POINTER LDA NEWTRK ;GET NEW TRACK NUMBER STA TRAKNO ;SAVE IN COMMON PLACE CMP M ;SAME AS LAST TIME ?? JRZ FSECSET ;YES, DONT BOTHER WITH SEEK MOV M,A ;SAVE IT OUT 007H ;ALSO SEND IT TO CONTROLLER CALL DBL$UPDATE ;DOUBLE SIDED SUPPORT FLOPPY$SEEK: MVI A,01AH ;SEEK COMMAND WITH HEAD LOAD OUT 004H ;DO IT.... FPS1: CALL WAIT0 ;WAIT FOR I/O TO COMPLETE MVI C,16 ;SET FOR 16 MS DELAY CALL DELAY ; FSECSET: LDA NEWSEC ;SET SECTOR STA SECTNO ;SAVE IN COMMONN PLACE OUT 006H ; CALL FLOPPYIO ;DO I/O CALL CHECK$STAT ;CHECK STATUS OF I/O LDA ERFLAG ;SETUP TO RETURN TO BDOS CZ MVDFB ; RZ ;EITHER OK OR PERMANENT ERROR JMP LOAD$HEAD ;ERROR, JUST RETRY THIS SAME I/O PAGE ;----------------------------------------------------------------------- ; ; THIS IS THE ROUTINE THAT DOES THE FLOPPY DISK I/O ; ;----------------------------------------------------------------------- FLOPPYIO: IF NOT DMA LXI H,066H ;MOVE DATA FROM 066H TO SAVE LXI D,SAVE1 ; LXI B,004H ; LDIR ;MOVE IT LXI H,NMIRTN ;SET NMI ROUTINE TO NMI ADDRESS LXI D,066H ; LXI B,004H ; LDIR ;MOVE IT LDA CMD ;IS IT A WRITE ?? ANI 20H ; JZ FRD ;NO, LEAVE INI CMD IN LOW MEMORY LXI H,067H ;POINT TO COMMAND AREA MVI M,0A3H ;MAKE IT AN OTI CMD.... FRD EQU $ ;LABEL ENDIF IF DMA LXI H,DMAS1 ;INITIALIZE DMA LXI B,0600H ; OUTIR ;WRITE TO DMA LXI H,DMAS2F ; LXI B,0400H ; OUTIR ;WRITE TO DMA LXI H,DMAS3 ; LXI B,0700H ; OUTIR ;WRITE TO DMA ENDIF MVI C,007H ;PORT ADDRESS FOR I/O LXI H,FPYBUF ;DMA ADDRESS LDA CMD ;I/O COMMAND OUT 004H ;WRITE TO DISK CONTROLLER FWT1: CALL WAIT0 ;WAIT HERE FOR I/O TO COMPLETE IF NOT DMA LXI H,SAVE1 ;SETUP TO REPLACE DATA LXI D,066H ;COPIED FROM NMI LOCATION LXI B,004H ; LDIR ;MOVE IT.... ENDIF RET ;RETURN, I/O COMPLETED ;----------------------------------------------------------------------- ; ; WE WILL NOW CHECK THE STATUS OF THE I/O OPERATION ; RETURN WITH CONDITION CODE ZERO = NO RETRY ; RETURN WITH CONDITION CODE NON ZERO = RETRY ; ;----------------------------------------------------------------------- CHECK$STAT: LXI H,ERFLAG ;POINT TO ERROR INDICATOR MVI M,000H ;ASSUME OK LXI H,STATUS ;CHECK STATUS LDA MASK ;MASK FOR UNWANTED BIT REMOVAL ANA M ; MOV M,A ;SAVE CLEANED STATUS RZ ;OK, SO RETURN CHKS0: CALL RETMOD ; CPI 003H ;HARD DISK ?? LXI H,STATUS ; MOV A,M ;RELOAD STATUS BYTE JRNC CHKS2 ;YES, CHECK FOR DRIVE READY CHKS1: CPI 080H ;IS FLOPPY DISK NOT READY ??? JZ BADIO ;YES, DONT BOTHER WITH RETRY OR MESSAGE JR CHKS3 ;GO TO BAD MESSAGE ROUTINE CHKS2: CPI 000H ;IS HARD DISK NOT READY ?? JZ BADIO ;YES, BYPASS ERROR MESSAGE AND COUNTING ANI 01000000B ;IS IT WRITE FAULT ?? JRZ CHKS3 ;NO, CONTINUE ON CALL POINT ;POINT TO TRACK REGISTER XCHG ;POINT TO SELECT MASK MOV A,M ; ORI 01000000B ;TURN ON WRITE FAULT CLEAR OUT 020H ; MOV A,M ;RESET CLEAR OUT 020H ; MVI C,20 ;DELAY JUST TO BE SAFE CALL DELAY ; CHKS3: LDA STATUS ;SAVE STATUS OVER HOME PUSH PSW ; CALL HOME ;RESET DEVICE TO HOME POP PSW ; STA STATUS ;SAVE FOR ERROR MESSAGE LXI D,TCNT ;BUMP TEMP ERROR COUNT CALL ADDERRORS ; LXI H,T$RETRIES ;PICKUP RETRY COUNT DCR M ;DECREMENT COUNT OF RETRIES RNZ ; LXI D,PCNT ;BUMP PERMANENT ERROR COUNT CALL ADDERRORS ; BADIO: LXI H,ERFLAG ;SET PERMANENT ERROR MVI M,001H ;DO IT.... XRA A ;RESET TO PRECLUDE RETRIES RET ;RETURN TO CALLER ADDERRORS: LHLD DISKNO ;BUMP COUNT OF DISK ERRORS MVI H,000H ; DAD D ;POINT TO ERROR REGISTER INR M ; RET ; PAGE ;----------------------------------------------------------------------- ; ; CENTRONICS PRINTER ROUTINE (WITH SEPARATE BUSY TEST FOR SPOOLER) ; ;----------------------------------------------------------------------- CNSTAT: MVI A,001H ;TO SET STROBE HIGH OUT 010H ; IN 010H ;READ PRINTER STATUS ANI 020H ;REMOVE ALL BUT BUSY BIT MVI A,0FFH ;ASSUME NOT BUSY RZ ;CHECK ASSUMPTION XRA A ;SET TO SHOW STILL BUSY RET ; ; ; WE WILL NOW PERFORM THE PRINT FUNCTION BUSY TEST ; CNTBSY: CALL CNSTAT ;CHECK STATUS OF PRINTER CPI 0FFH ;READY ?? JRNZ CNTBSY ;NO, WAIT HERE RET ; CLIST: CALL CNTBSY ;WAIT FOR PRINTER TO FREE UP MOV A,C ;CHARACTER TO PRINT OUT 011H ;WRITE IT TO DATA PORT MVI A,000H ;TO FORCE STROBE LOW OUT 010H ; MVI A,001H ;TO FORCE STROBE HIGH OUT 010H ; RET ; PAGE ;----------------------------------------------------------------------- ; ; DISK INTERRUPT ROUTINE ; ;----------------------------------------------------------------------- FLOPPY$INT: SHLD SVDHL LXI H,FDINTH JMP INTINIT FDINTH: IN 004H ;GET STATUS STA STATUS ;SAVE FOR I/O ROUTINE JMP HDSTFLG HARD$INT: SHLD SVDHL LXI H,HDINTH JMP INTINIT HDINTH: IN 024H ;GET STATUS STA STATUS ;SAVE FOR CHECK LATER XRA A ;TO RESET INTERRUPT PENDING BIT OUT 023H ;RESET BY RELOADING THE COMMAND REGISTER HDSTFLG: MVI C,FLAGST MVI E,5 CALL XDOS JMP INTDONE PAGE ;----------------------------------------------------------------------- ; ; CONSOLE DISPLAY ROUTINES ; ;----------------------------------------------------------------------- ; CONST: ; CONSOLE STATUS CALL PTBLJMP ; COMPUTE AND JUMP TO HNDLR DW PT0ST ; CONSOLE #0 STATUS ROUTINE DW PT1ST ; CONSOLE #1 STATUS ROUTINE DW PT2ST ; CONSOLE #2 STATUS ROUTINE DW PT3ST ; CONSOLE #3 STATUS ROUTINE CONIN: ; CONSOLE INPUT CALL PTBLJMP ; COMPUTE AND JUMP TO HNDLR DW PT0IN ; CONSOLE #0 INPUT DW PT1IN ; CONSOLE #1 INPUT DW PT2IN ; CONSOLE #2 INPUT DW PT3IN ; CONSOLE #3 INPUT CONOUT: ; CONSOLE OUTPUT CALL PTBLJMP ; COMPUTE AND JUMP TO HNDLR DW PT0OUT ; CONSOLE #0 OUTPUT DW PT1OUT ; CONSOLE #1 OUTPUT DW PT2OUT ; CONSOLE #2 OUTPUT DW PT3OUT ; CONSOLE #3 OUTPUT ; PTBLJMP: ; COMPUTE AND JUMP TO HANDLER ; D = CONSOLE # ; DO NOT DESTROY MOV A,D CPI NMBCNS JC TBLJMP POP PSW ; THROW AWAY TABLE ADDRESS XRA A RET TBLJMP: ; COMPUTE AND JUMP TO HANDLER ; A = TABLE INDEX ADD A ; DOUBLE TABLE INDEX FOR ADR OFFST POP H ; RETURN ADR POINTS TO JUMP TBL MOV E,A MVI D,0 DAD D ; ADD TABLE INDEX * 2 TO TBL BASE MOV E,M ; GET HANDLER ADDRESS INX H MOV D,M XCHG PCHL ; JUMP TO COMPUTED CNS HANDLER PAGE ;--------------------------------------------------------------- ; ; SERIAL PORT ADDRESS EQUATES ; ;--------------------------------------------------------------- DATA0 EQU 01CH ;CONSOLE #0 DATA STS0 EQU DATA0+1 ;CONSOLE #0 STATUS DATA1 EQU 02CH ;CONSOLE #1 DATA STS1 EQU DATA1+1 ;CONSOLE #1 STATUS DATA2 EQU 02EH ;CONSOLE #2 DATA STS2 EQU DATA2+1 ;CONSOLE #2 STATUS DATA3 EQU 02AH ;CONSOLE #3 DATA STS3 EQU DATA3+1 ;CONSOLE #3 STATUS LPTPRT0 EQU 01EH ;PRINTER #0 DATA LPTSTS0 EQU LPTPRT0+1 ;PRINTER #0 STATUS LPTPRT1 EQU 028H ;PRINTER #1 DATA LPTSTS1 EQU LPTPRT1+1 ;PRINTER #1 STATUS PAGE ;--------------------------------------------------------------- ; ; POLL CONSOLE # 0 INPUT ; ;--------------------------------------------------------------- POLCI0: PT0ST: ; TEST CONSOLE STATUS XRA A ; RETURN 0FFH IF READY OUT STS0 ; 000H IF NOT IN STS0 ; ANI 1 ; RX CHAR ? RZ ; NO MVI A,0FFH ; YES - SET FLAG RET ; ; ;--------------------------------------------------------------- ; ; CONSOLE # 0 INPUT ; ;--------------------------------------------------------------- ; PT0IN: ; RETURN CHAR IN REG A MVI C,POLL ; MVI E,PLCI0 ; POLL CONSOLE #0 INPUT CALL XDOS ; IN DATA0 ; READ CHARACTER ANI 7FH ; STRIP PARITY RET ; ; ; ;--------------------------------------------------------------- ; ; CONSOLE # 0 OUTPUT ; ;--------------------------------------------------------------- ; PT0OUT: ; REG C = CHAR TO OUTPUT PUSH B ; MVI C,POLL ; MVI E,PLCO0 ; CALL XDOS ; POLL CONSOLE #0 OUTPUT POP B ; MOV A,C ; OUT DATA0 ; TRANSMIT CHARACTER RET ; ; ; ;--------------------------------------------------------------- ; ; POLL CONSOLE # 0 OUTPUT ; ;--------------------------------------------------------------- ; POLCO0: ; RETURN 0FFH IF READY MVI A,10H ; 000H IF NOT OUT STS0 ; RESET INT BIT IN STS0 ; READ STATUS ANI 0CH ; MASK FOR DTR AND TXE CPI 0CH ; MUST HAVE BOTH MVI A,0 ; RNZ ; RETURN NOT READY MVI A,0FFH ; RET ; RETURN READY PAGE ;--------------------------------------------------------------- ; ; POLL CONSOLE # 1 INPUT ; ;--------------------------------------------------------------- POLCI1: PT1ST: ; TEST CONSOLE STATUS XRA A ; RETURN 0FFH IF READY OUT STS1 ; 000H IF NOT IN STS1 ; ANI 1 ; RX CHAR ? RZ ; NO MVI A,0FFH ; YES - SET FLAG RET ; ; ;--------------------------------------------------------------- ; ; CONSOLE # 1 INPUT ; ;--------------------------------------------------------------- ; PT1IN: ; RETURN CHAR IN REG A MVI C,POLL ; MVI E,PLCI1 ; POLL CONSOLE #1 INPUT CALL XDOS ; IN DATA1 ; READ CHARACTER ANI 7FH ; STRIP PARITY RET ; ; ; ;--------------------------------------------------------------- ; ; CONSOLE # 1 OUTPUT ; ;--------------------------------------------------------------- ; PT1OUT: ; REG C = CHAR TO OUTPUT PUSH B ; MVI C,POLL ; MVI E,PLCO1 ; CALL XDOS ; POLL CONSOLE #1 OUTPUT POP B ; MOV A,C ; OUT DATA1 ; TRANSMIT CHARACTER RET ; ; ; ;--------------------------------------------------------------- ; ; POLL CONSOLE # 1 OUTPUT ; ;--------------------------------------------------------------- ; POLCO1: ; RETURN 0FFH IF READY MVI A,10H ; 000H IF NOT OUT STS1 ; RESET INT BIT IN STS1 ; READ STATUS ANI 0CH ; MASK FOR DTR AND TXE CPI 0CH ; MUST HAVE BOTH MVI A,0 ; RNZ ; RETURN NOT READY MVI A,0FFH ; RET ; RETURN READY PAGE ;--------------------------------------------------------------- ; ; POLL CONSOLE # 2 INPUT ; ;--------------------------------------------------------------- POLCI2: PT2ST: ; TEST CONSOLE STATUS XRA A ; RETURN 0FFH IF READY OUT STS2 ; 000H IF NOT IN STS2 ; ANI 1 ; RX CHAR ? RZ ; NO MVI A,0FFH ; YES - SET FLAG RET ; ; ;--------------------------------------------------------------- ; ; CONSOLE # 2 INPUT ; ;--------------------------------------------------------------- ; PT2IN: ; RETURN CHAR IN REG A MVI C,POLL ; MVI E,PLCI2 ; POLL CONSOLE #2 INPUT CALL XDOS ; IN DATA2 ; READ CHARACTER ANI 7FH ; STRIP PARITY RET ; ; ; ;--------------------------------------------------------------- ; ; CONSOLE # 2 OUTPUT ; ;--------------------------------------------------------------- ; PT2OUT: ; REG C = CHAR TO OUTPUT PUSH B ; MVI C,POLL ; MVI E,PLCO2 ; CALL XDOS ; POLL CONSOLE #2 OUTPUT POP B ; MOV A,C ; OUT DATA2 ; TRANSMIT CHARACTER RET ; ; ; ;--------------------------------------------------------------- ; ; POLL CONSOLE # 2 OUTPUT ; ;--------------------------------------------------------------- ; POLCO2: ; RETURN 0FFH IF READY MVI A,10H ; 000H IF NOT OUT STS2 ; RESET INT BIT IN STS2 ; READ STATUS ANI 0CH ; MASK FOR DTR AND TXE CPI 0CH ; MUST HAVE BOTH MVI A,0 ; RNZ ; RETURN NOT READY MVI A,0FFH ; RET ; RETURN READY PAGE ;--------------------------------------------------------------- ; ; POLL CONSOLE # 3 INPUT ; ;--------------------------------------------------------------- POLCI3: PT3ST: ; TEST CONSOLE STATUS XRA A ; RETURN 0FFH IF READY OUT STS3 ; 000H IF NOT IN STS3 ; ANI 1 ; RX CHAR ? RZ ; NO MVI A,0FFH ; YES - SET FLAG RET ; ; ;--------------------------------------------------------------- ; ; CONSOLE # 3 INPUT ; ;--------------------------------------------------------------- ; PT3IN: ; RETURN CHAR IN REG A MVI C,POLL ; MVI E,PLCI3 ; POLL CONSOLE #3 INPUT CALL XDOS ; IN DATA3 ; READ CHARACTER ANI 7FH ; STRIP PARITY RET ; ; ; ;--------------------------------------------------------------- ; ; CONSOLE # 3 OUTPUT ; ;--------------------------------------------------------------- ; PT3OUT: ; REG C = CHAR TO OUTPUT PUSH B ; MVI C,POLL ; MVI E,PLCO3 ; CALL XDOS ; POLL CONSOLE #3 OUTPUT POP B ; MOV A,C ; OUT DATA3 ; TRANSMIT CHARACTER RET ; ; ; ;--------------------------------------------------------------- ; ; POLL CONSOLE # 3 OUTPUT ; ;--------------------------------------------------------------- ; POLCO3: ; RETURN 0FFH IF READY MVI A,10H ; 000H IF NOT OUT STS3 ; RESET INT BIT IN STS3 ; READ STATUS ANI 0CH ; MASK FOR DTR AND TXE CPI 0CH ; MUST HAVE BOTH MVI A,0 ; RNZ ; RETURN NOT READY MVI A,0FFH ; RET ; RETURN READY PAGE ;--------------------------------------------------------------- ; ; LINE PRINTER #0 DRIVER ; ;--------------------------------------------------------------- ; LIST: ;LIST OUTPUT #0 PUSH B ; MVI C,POLL ; POLL PRINTER STATUS MVI E,PLLPT ; CALL XDOS ; POP B ; MOV A,C ; CHARACTER TO PRINT OUT LPTPRT0 ; cpi 0ch ;** form feed test for tty 40 rnz mvi c,0 ;** output a null call list jmp list ; ;--------------------------------------------------------------- ; ; POLL PRINTER OUTPUT ; ;--------------------------------------------------------------- ; POLLPT: ; RETURN 0FFH IF READY MVI A,10H ; 000H IF NOT OUT LPTSTS0 ; RESET INT BIT IN LPTSTS0 ; READ STATUS ANI 0CH ; MASK FOR DTR AND TXE CPI 0CH ; MUST HAVE BOTH MVI A,0 ; RNZ ; RETURN NOT READY MVI A,0FFH ; RET ; RETURN READY ; PAGE ; ; MP/M 1.0 EXTENDED I/O SYSTEM ; ; POLLDEVICE: ; REG C = DEVICE # TO BE POLLED ; RETURN 0FFH IF READY, ; 000H IF NOT MOV A,C CPI NMBDEV JC DEVOK MVI A,NMBDEV; IF DEV # >= NMBDEV, ; SET TO NMBDEV DEVOK: CALL TBLJMP ; JUMP TO DEV POLL CODE DEVTBL: DW POLLPT ; POLL PRINTER OUTPUT DW POLCO0 ; POLL CONSOLE #0 OUTPUT DW POLCO1 ; POLL CONSOLE #1 OUTPUT DW POLCO2 ; POLL CONSOLE #2 OUTPUT DW POLCO3 ; POLL CONSOLE #3 OUTPUT DW POLCI0 ; POLL CONSOLE #1 INPUT DW POLCI1 ; POLL CONSOLE #1 INPUT DW POLCI2 ; POLL CONSOLE #1 INPUT DW POLCI3 ; POLL CONSOLE #1 INPUT NMBDEV EQU ($-DEVTBL)/2 DW RTNEMPTY; BAD DEVICE HANDLER PAGE ; SELECT / PROTECT MEMORY SELMEMORY: ; REG BC = ADR OF MEM DESCRIPTOR ; BC -> BASE 1 BYTE, ; SIZE 1 BYTE, ; ATTRIB 1 BYTE, ; BANK 1 BYTE. ; ; BIOS TABLE MODIFIED CPI 20H ; JZ $ LXI H,3 ; POINT TO BANK DAD B ; MOV A,M ; GET IT STA BANKNO ; SAVE BANK NUMBER RAL ; RAL ; RAL ; ANI 018H ; MASK FOR PIO ORI MEMSK ; STA CURMEM ; STORE CURRENT BANK MASK OUT 009H ; SET PIO RET BANKNO: DB 0 ; LAST SELECTED MEMORY BANK NUMBER CURMEM: DB 0 ; LAST SELECTED MEMORY BANK MASK ; START CLOCK STARTCLOCK: ; WILL CAUSE FLAG #1 TO BE SET ; AT EACH SYSTEM TIME UNIT TICK MVI A,0FFH STA TICKN RET ; STOP CLOCK STOPCLOCK: ; WILL STOP FLAG #1 SETTING AT ; SYSTEM TIME UNIT TICK XRA A STA TICKN RET ; EXIT REGION EXITREGION: ; EI IF NOT PREEMPTED LDA PREEMP ORA A RNZ EI RET ; MAXIMUM CONSOLE NUMBER MAXCONSOLE: MVI A,NMBCNS RET ; MP/M 1.0 INTERRUPT HANDLERS DSPTCH EQU 142 INT1HND: ; INTERRUPT 1 HANDLER ENTRY POINT ; T20MS: SHLD SVDHL LXI H,TIMERINT JMP INTINIT TIMERINT: LDA TICKN ORA A ; TEST TICKN, INDICATES ; DELAYED PROCESS(ES) JZ NOTICKN MVI C,FLAGST MVI E,1 CALL XDOS ; SET FLAG #1 EACH TICK NOTICKN: LXI H,CNTx DCR M ; DEC TICK CNTR JNZ NOT1SEC mvi a,125 dcx h sub m mov m,a ;** toggle count 62 <-> 63 inx h mov m,a ;** actual #/sec = 62.5 MVI C,FLAGST MVI E,2 CALL XDOS ; SET FLAG #2 @ 1 SEC NOT1SEC: INTDONE: XRA A STA PREEMP ; CLEAR PREEMPTED FLAG POP B POP D LHLD SVDSP SPHL ; RESTORE STK PTR POP PSW LHLD SVDRET PUSH H LXI H,PDISP ; MP/M DISPATCH PUSH H ; PUT ON STACK FOR RETURN LHLD SVDHL ; THE FOLLOWING DISPATCH CALL WILL FORCE ROUND ROBIN ; SCHEDULING OF PROCESSES EXECUTING AT THE SAME PRIORITY ; EACH 1/32ND OF A SECOND. ; NOTE: INTERRUPTS ARE NOT ENABLED UNTIL THE DISPATCHER ; RESUMES THE NEXT PROCESS. THIS PREVENTS INTERRUPT ; OVER-RUN OF THE STACKS WHEN STUCK OR HIGH FREQUENCY ; INTERRUPTS ARE ENCOUNTERED. RETI ; DISPATCH INTINIT: ;SAVE MACHINE STATE FOR INTRPT HNDLNG SHLD ADRINTHD POP H SHLD SVDRET PUSH PSW LXI H,0 DAD SP SHLD SVDSP ; SAVE USERS STK PTR LXI SP,LSTINTSTK ; LCL STK FOR INTR HNDL PUSH D PUSH B MVI A,0FFH STA PREEMP ; SET PREEMPTED FLAG LHLD ADRINTHD PCHL ;JUMP TO INTERRUPT HANDLER ; ; BIOS DATA SEGMENT ; togcnt: db 62 ; toggle counter 62 <-> 63 CNTx: DB 62 ; TICK CNTR to 1 SEC INTSTK: ; LOCAL INTRPT STK DW 0C7C7H,0C7C7H,0C7C7H,0C7C7H,0C7C7H DW 0C7C7H,0C7C7H,0C7C7H,0C7C7H,0C7C7H DW 0C7C7H,0C7C7H,0C7C7H,0C7C7H,0C7C7H DW 0C7C7H,0C7C7H,0C7C7H,0C7C7H,0C7C7H LSTINTSTK: ADRINTHD: DW 0 ; INTERRUPT HANDLER ADDRESS SVDHL: DW 0 ; SAVED REGS HL DURING INT HNDL SVDSP: DW 0 ; SAVED SP DURING INT HNDL SVDRET: DW 0 ; SAVED RETURN DURING INT HNDL TICKN: DB 0 ; TICKING BOOLEAN,TRUE = DELAYED PREEMP: DB 0 ; PREEMPTED BOOLEAN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; THIS IS DISK WAIT ENTRY ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WAIT0: PUSH B ; SAVE RETRY COUNT MVI C,FLAGWT ; FUNCTION FLAG WAIT MVI E,5 ; DEVICE IS DISK CALL XDOS POP B ; RESTORE RETRY COUNTER IN ; READ OR WRITE IS OK, ACCUMULATOR CONTAINS ZERO RET PAGE ;----------------------------------------------------------------------- ; ; THIS IS THE DELAY ROUTINE. IT WILL LOOP HERE FOR THE ; NUMBER OF MILLISECONDS SPECIFIED IN REGISTER C. ; ;----------------------------------------------------------------------- DELAY: DEL1: MVI B,100 ;FORCE DELAY FOR 1 MILLISECOND DEL2: RLC ;INSTRUCTIONS TO FILL IN TIME DAD H ; DAD H ; DCR B ;AT ONE MILLISECOND YET ?? JNZ DEL2 ;NO, KEEP ON LOOPING DCR C ;END OF REQUESTED INTERVAL YET ?? JNZ DEL1 ;NO, KEEP ON RET ;RETURN TO CALLER PAGE ;******************************************** ;* NOTE: THE INITIALIZATION CODE WILL BE ;* OVERWRITTEN BY DIRBUF & FPYBUF ;******************************************** DIRBUF EQU $ ;------------------------------------------------------------ ; ; INITIALIZE MP/M: REAL TIME CLOCK & DISKS ; ;------------------------------------------------------------ SYSTEMINIT: DI ; C = BREAKPOINT RESTART NUMBER ; DE = BREAKPOINT RESTART HANDLER ADDRESS ; HL = DIRECT XIOS INTERCEPT JUMP TABLE ADDRESS SHLD SVDJT MOV L,C MVI H,0 DAD H DAD H DAD H ;HL = RESTART JUMP ADDRESS SHLD SVDBPA MVI A,01AH ; SELECT BANK 3 CALL STMVTR ; SET UP VECTORS MVI A,012H ; SELECT BANK 2 CALL STMVTR ; SET UP VECTORS MVI A,00AH ; SELECT BANK 1 CALL STMVTR ; SET UP VECTORS MVI A,002H ; SELECT BANK 0 CALL STMVTR ; SET UP VECTORS LXI B,003H ;SET THE MODE FOR DRIVES INITIALIZED BY "SETUP" MODESET: CALL SELDSK ;SELECT DRIVE FOR MODESET LXI H,MODE ; DAD B ;POINT TO CORRECT MODE BYTE PUSH B ;SAVE COUNT OF DRIVES MOV C,M ; CALL SETMOD ;SET MODE POP B ; DCR C ;END OF LIST YET ?? JP MODESET ;SET MODE FOR ALL DRIVES CALL SDCONF ;SET DISK CONFIGURATION LXI B,80H CALL SETDMA ;SET DMA ADDRESS MVI A,INTERUPT SHR 8 ;SETUP INTERRUPT VECTOR DB 0EDH,047H ;---- FAKE STAI INSTRUCTION MVI A,60H ; SET VECTOR FOR CTC OUT 30H ; CTC CHANNEL 0 MVI A,0A7H ; RESET / LOAD TIME CONSTANT OUT 33H ; CHANNEL 3 MVI A,250 ; TIME CONSTANT OUT 033H ; IF HARDSK EI MVI A,080H ;ISSUE RESET AGAINST HARD DISK OUT 023H ; MVI A,01010000B ;RESET WRITE FAULT OUT 020H ;DRIVE 1 MVI A,01100000B ; OUT 020H ;DRIVE 2 MVI A,00010000B ;SELECT DRIVE 1/ HEAD 0 OUT 020H ; MVI C,20 ;WAIT FOR 20 MILLISECONDS CALL DELAY ; CALL WAIT0 ;INTERRUPT PRODUCED BY HARD DISK RESET XRA A ;ZERO ACCUMULATOR STA HSTACT ;SET HOST BUFFER INACTIVE STA UNACNT ;SET UNALLOCATED COUNT TO ZERO LXI H,HSTBUF-1 ;SETUP WRITE CONTROL BYTE FOR HARD DISK MVI M,00DH ; ENDIF RET ; STMVTR: OUT MEMPORT MVI A,0C3H ; SET VECTORS FOR BDOS STA 0 ; JMP INSTRUCTION LHLD SVDJT ; SHLD 1 LHLD SVDBPA MOV M,A INX H MOV M,E INX H MOV M,D RET ; SVDJT: DS 2 ; SAVED DIRECT JUMP TABLE ADDRESS SVDBPA: DS 2 ; SAVED BREAK POINT ADDRESS ;----------------------------------------------------------------------- ; ; DISK CONFIGURATION TABLE ; ;----------------------------------------------------------------------- IF HARDSK ; PIN CONFIGURATION DSCN0: DB 00H,00H,00H,00H,00H,00H,00H,00H DB 10H,00H,00H,00H,00H,00H,10H,00H ; 1 DB 90H,90H,90H,00H,00H,00H,00H,00H ; 2 DB 00H,00H,00H,00H,00H,00H,00H,00H DB 10H,00H,00H,20H,00H,00H,10H,20H ; 4 DB 00H,00H,00H,00H,00H,00H,00H,00H DB 90H,90H,90H,20H,00H,00H,00H,20H ; 6 DB 90H,90H,90H,0A0H,0A0H,0A0H,0H,0H ; 7 ENDIF ;----------------------------------------------------------------------- ; ; SET UP DISK CONFIGURATON ; ; [ THIS CODE EXECUTED ONLY ONCE ] ; ;----------------------------------------------------------------------- ; SDCONF: LXI H,SEL0+2 ;POINT TO DRIVE C: LDA MPARMS ; ANI 05H ; TEST FOR FOUR FLOPPIES JMP SDDBL ; YES SKIP THE ZAP MOV M,A ; INX H ; ZAP C: AND D: MOV M,A ; SDDBL: LXI D,SEL0+4 ;POINT TO DRIVE E: IF HARDSK MVI A,1 ; *** TEMP DEBUG ; IN 025H ;READ CONFIGURATION PORT ANI 07H ;STRIP OFF HIGH PART RAL ; RAL ; RAL ; MVI B,0 ; MOV C,A ;POINT TO CONFIGURATION TABLE LXI H,DSCN0 ; DAD B ; INDEX TO RIGHT ENTRY MVI B,8 ; SDL1: MOV A,M ; CHANGE ALL SELECT MASKS STAX D ; SDOK: INX D ; NEXT INX H ; DRIVE DJNZ SDL1 ; ENDIF IF NOT HARDSK XCHG ; MVI B,8 ; XRA A ; SDL2: MOV M,A ; ZAP ALL HARD DRIVES INX H ; DJNZ SDL2 ; ENDIF ; RET INITEND EQU $ PAGE ;----------------------------------------------------------------------- ; ; THE FOLLOWING AREA CONTAINS THE DISK/WORK SAVE AREAS ; USED BY THE CBIOS IN THE NORMAL COURSE OF ACTIVITY. ; ;----------------------------------------------------------------------- TEMPBUF EQU (DIRBUF-BASE)+256 ORG TEMPBUF+((INITEND-BASE)/TEMPBUF)*((INITEND-BASE)-TEMPBUF) BEGDAT EQU $ ;START OF BDOS AREAS ;DIRBUF: DS 128 ;OVERLAYS SYSTEMINIT CODE ALV0: DS 32 CSV0: DS 32 ALV1: DS 32 CSV1: DS 32 ALV2: DS 32 CSV2: DS 32 ALV3: DS 32 CSV3: DS 32 IF HARDSK ALV4: DS 64 CSV4: DS 0 ALV5: DS 64 CSV5: DS 0 ALV6: DS 64 CSV6: DS 0 ALV7: DS 64 CSV7: DS 0 ALV8: DS 64 CSV8: DS 0 ALV9: DS 64 CSV9: DS 0 ALVA: DS 36 CSVA: DS 0 ALVB: DS 36 CSVB: DS 0 DS 1 ;MUST PRECEDE HSTBUF HSTBUF: DS 1024 ;HOST BUFFER AREA DS 1 ;MUST FOLLOW HSTBUF ENDIF FPYBUF EQU DIRBUF+128 ; FLOPPY I/O BUFFER NEWDSK: DS 1 ;SEEK DISK NUMBER NEWTRK: DS 2 ;SEEK TRACK NUMBER NEWSEC: DS 1 ;SEEK SECTOR NUMBER HSTDSK: DS 1 ;HOST DISK NUMBER HSTTRK: DS 2 ;HOST TRACK NUMBER HSTSEC: DS 1 ;HOST SECTOR NUMBER NEWHST: DS 1 ;SEEK SHR SECSHF HSTACT: DS 1 ;HOST ACTIVE FLAG HSTWRT: DS 1 ;HOST WRITTEN FLAG UNACNT: DS 1 ;UNALLOCATED RECORD COUNT UNADSK: DS 1 ;LAST UNALLOCATED DISK UNATRK: DS 2 ;LAST UNALLOCATED TRACK UNASEC: DS 1 ;LAST UNALLOCATED SECTOR ERFLAG: DS 1 ;ERROR REPORTING RSFLAG: DS 1 ;READ SECTOR FLAG READOP: DS 1 ;1 IF READ OPERATION WRTYPE: DS 1 ;WRITE OPERATION TYPE CMD: DB 0 ;COMMANDS FOR NEXT I/O MASK: DB 0 ;STATUS MASKS BUFFER FOR DISK I/O STATUS: DB 0 ;STATUS SAVE LOCATION FOR DISK I/O SAVE1: DB 000H,000H,000H,000H ;SAVE AREA FOR NMI ROUTINE P$RETRIES: DB 000H ;COUNTER FOR PERMANENT ERRORS T$RETRIES: DB 000H ;COUNTER FOR TEMPORARY ERRORS DATSIZE EQU $-BEGDAT END