; BASIC INPUT/OUTPUT SYSTEM DRIVERS ; FOR MSD D-100 DISK SYSTEM ; ; SET UP DATA ; MEMSIZE:EQU 51 ;MEMORY SIZE DCMMD: EQU 30H ;DISK COMMAND PORT DSTAT: EQU 30H ;DISK STATUS PORT DDRQ: EQU 34H ;DRQ PORT DTRK: EQU 31H ;DISK TRACK PORT DSEC: EQU 32H ;DISK SECTOR PORT DDAT: EQU 33H ;DISK DATA PORT DENB: EQU 35H ;DISK ENABLE PORT RETRY: EQU 10 ;RETRY COUNT SIGNON: EQU 056H ;SIGNON MESSAGE IN BOOT CPMOF: EQU (MEMSIZE-16)*1024;BASE OFFSET CPMBAS EQU 0B900H ;CPM START BDOS EQU 0C106H ;BDOS ENTERY POINT ; ORG MEMSIZE*1024-512;BIOS START CPMLEN: EQU $-CPMBAS ;CPM LENGTH NSECT: EQU 11H ;REBOOT SECTOR COUNT ; ;EQUATES FOR SNOOPY ; OUTVDM EQU 0F03CH ;OUTPUT TO VDM ONLY OUTPUT EQU 0F042H ;MAIN OUTPUT OF SNOOPY OTLINE EQU 0F040H ;OUTPUT TO LIST INPUT EQU 0F046H ;MAIN INPUT ROUTINE STATUS EQU 0F04CH ;STATUS OF SNOOPY ; ; ; JUMP TABLE FOR FUNCTIONS ; START: JP BOOT ;COLD START ENTRY WBOOTE: JP WBOOT ;WARM BOOT ENTRY JP CONST ;CONSOLE STATUS JP CONIN ;CONSOLE INPUT JP CONOT ;CONSOLE OUTPUT JP LIST ;LIST DEVICE OUTPUT JP PUNCH ;PUNCH DEVICE OUTPUT JP READER ;READER DEVICE INPUT JP HOME1 ;HOME DISK JP SELDSK ;SELECT DISK JP SETTRK ;SET TRACK NUMBER JP SETSEC ;SET SECTOR NUMBER JP SETDMA ;SET DMA ADDRESS JP READ ;READ SECTOR JP WRITE ;WRITE SECTOR F.DMA LD HL,(DMAADD) ;GET DAM ADDRESS RET ; ; COLD BOOT ENTRY ; BOOT: LD SP,100H ;SET STACK POINTER LD HL,0 LD (TRKTBL),HL ;ZERO OUT TRACK ;REGISTERS LD (TRKTBL+2),HL CALL IOINIT ;INITIALIZE I/O DEVICES LD HL,SIGNON CALL PRMSG ;PRINT SIGNON MESSAGE CALL CONIN ;GET RESPONSE LD C,A ;SAVE IN C AND 3 ;GET 3 BITS LD (NDISKS),A CALL CONOT ;ECHO NUMBER BACK XOR A ;CLEAR A LD (CDISK),A ;START WITH DIRVE 1 INC A LD (CDSKA),A ;IN TWO PLACES ; ; SET UP CP/M ENTRIES ; GOCPM: LD A,0C3H ;GET JUMP INSTRUCTION LD (0),A ;STORE FOR WARM BOOT LD HL,WBOOTE ;WARM BOOT ENTRY LD (1),HL ;FINISH JP INSTRUCTION LD (5),A ;CP/M ENTRY JUMP LD HL,BDOS LD (6),HL ;FINISH JP INSTRUCTION LD HL,0080H ;DEFAULT BUFFER ADDRESS LD (DMAADD),HL ;SET IT LD C,H ;BOOT FROM DISK ZERO ;ZERO FROM H REG JP CPMBAS ;GO TO CP/M ; ; WARM BOOT ENTRY ; WBOOT: LD SP,100H ;SET STACK LD HL,100H ;SET FOR DRIVE 1 LD (CDISK),HL ;STORE IN CDISK & CDSKA CALL HOME ;HOME THE DISK LD HL,CPMBAS LD C,0 ;TRACK ZERO LD B,NSECT ;SECTOR COUNT LD D,2 ;START WITH SECTOR 2 WBOOT0: LD A,C ;TRACK NUMBER TO A LD (TRACK),A ;STORE IT WBOOT1: LD A,D ;SECTOR TO A LD (SECTOR),A ;STORE IT FOR READ LD (DMAADD),HL ;SET DMA ADDRESS PUSH BC ;SAVE REGISTERS PUSH DE PUSH HL CALL READ ;READ A SECTOR JR NZ,WBOOT ;RETRY IF ERROR POP HL ;RESTORE ADDRESS LD DE,80H ADD HL,DE ;UPDATE ADDRESS POP DE ;RESTORE REGISTERS POP BC DEC B ;ALL DONE? JR Z,GOCPM ;START CP/M INC D ;BUMP SECTOR LD A,D CP 19 ;TRACK OVERFLOW? JR C,WBOOT1 ;READ MORE ON THIS ;TRACK LD D,1 ;RESET SECTOR COUNT INC C ;BUMP TRACK JR WBOOT0 ;READ FROM NEXT TRACK ; ; SELECT DISK ; SELDSK: LD HL,CDISK ;SET DISK ADDRESS LD A,C ;DESIRED DRIVE TO A CP (HL) ;CHECK OLD RET Z ;DONE IF SAME LD A,(NDISKS) ;GET DISK COUNT CP 1 ;TEST FOR ONLY ONE JR NZ,SELDK1 ;OK IF MORE THAN 1 LD A,'A' ADD C ;FROM ASCII DRIVE ;IDENTIFIER LD (MMSG+8),A ;SET MESSAGE LD (HL),C ;STORE NEW DRIVE LD HL,MMSG CALL PRMSG ;OUTPUT MOUNT MESSAGE CALL CONIN ;WAIT FOR RESPONSE LD C,A JP CONOT ;ECHO IT AND RETURN ; SELDK1: LD (HL),C ;DRIVE NUMBER TO MEMORY INC HL ;BUMP ADDRESS INC C ;BUMP DRIVE LD (HL),C ;STORE IT TOO RET ;THAT'S ALL ; ; SET SECTOR ; SETSEC: LD A,C ;SECTOR TO A LD (SECTOR),A ;STORE IT RET ;THAT'S ALL ; ; SET TRACK ; HOME1: LD C,0 SETTRK: LD A,C LD (TRACK),A RET ; ; SET DMA ADDRESS ; SETDMA: LD (DMAADD),BC ;STORE DMA ADDRESS RET ; ; SET UP FOR READ/WRITE ; SETUP: CALL ENABLE ;ENABLE DRIVE LD A,(TRACK) ;GET TRACK NUMBER LD D,A ;TO D REGISTER SEEK: IN A,DTRK ;GET CURRENT TRACK SUB D ;SUBTRACT DESIRED JR Z,NSEEK ;NO SEEK IF SAME LD A,D ;DESIRED TRACK TO A OUT DDAT,A ;OUTPUT TO CONTROLLER LD A,1FH ;GET SEEK COMMAND CALL HOMEA ;USE HOME ROUTINE NSEEK: LD A,(SECTOR) ;SECTOR NUMBER TO A OUT DSEC,A ;OUTPUT TO CONTROLLER LD HL,(DMAADD) ;GET ADDRESS RET ;READY FOR DISK ;OPERATION ; ; HOME FOR INTERNAL OPERATIONS ; HOME: CALL ENABLE ;ENABLE DRIVE LD A,3 HOMEA: OUT DCMMD,A ;OUTPUT HOME COMMAND HOMEB: IN A,DDRQ ;GET STATUS ADD A ;TEST STATUS JP P,HOMEB ;LOOP UNTIL DONE RET ; ; ENABLE DISK DRIVE ; ENABLE: LD A,(CDSKA) ;GET DRIVE NUMBER LD C,A ;SAVE IN C IN A,DDRQ ;GET CURRENT STATUS AND 23H ;MASK MOTOR, DRIVE ;NUMBER CP C ;TEST WITH DESIRED RET Z ;DONE IF SAME PUSH HL ;SAVE REGISTERS PUSH DE LD DE,TRKTBL-1 ;TRACK TABLE ADDRESS LD H,0 ;CLEAR H AND 3 ;CLEAR MOTOR STATUS LD L,A ;DRIVE NUMBER TO L ADD HL,DE ;ADD TO ADDRESS IN A,DTRK ;GET CURRENT TRACK LD (HL),A ;SAVE IN TABLE LD L,C ;NEW DRIVE TO L LD H,0 ;CLEAR H ADD HL,DE ;FORM ADDRESS LD A,(HL) ;GET TRACK NUMBER OUT DTRK,A ;TO CONTROLLER POP DE ;RESTORE REGISTERS POP HL LD A,20H ;GET MOTOR ON BIT OR C ;SET IN DRIVE NUMBER OUT DENB,A ;ENABLE DRIVE ELOOP IN A,DSTAT ;GET STATUS RLA JR C,ELOOP ;WAIT UNTIL READY RET ;THEN RETURN ; ; READ A SECTOR ; READ: LD B,RETRY ;SET RETRY COUNT READ1: CALL SETUP ;SET UP DISK LD A,8CH OUT DCMMD,A ;ISSUE READ COMMAND READA: IN A,DDRQ ;GET STATUS ADD A ;TEST TWO BITS JP M,READB ;DONE IF NEGATIVE JP NC,READA ;WAIT FOR DATA IN A,DDAT ;GET DATA LD (HL),A ;STORE IT INC HL ;BUMP ADDRESS JP READA ;GET NEXT BYTE READB: IN A,DSTAT ;GET DISK STATUS AND 1DH ;TEST FOR ERRORS RET Z ;OK IF ZERO DEC B ;BUMP RETRY COUNT JR Z,DIOERR ;ERROR, EXIT AND 10H ;IDF ERROR? JR Z,READ1 ;TRY AGAIN IF CRC CALL HOME ;FORCE HOME JR READ1 ;TRY AGAIN ; DIOERR: LD A,1 ;SET ERROR FLAG OR A ;SET FLAGS RET ; ; SECTOR WRITE ; WRITE: LD B,RETRY/2 ;SET RETRY COUNT WRTRY: CALL SETUP ;SET UP DISK LD A,0ACH OUT DCMMD,A ;ISSUE WRITE COMMAND WRITEA: IN A,DDRQ ;GET STATUS ADD A ;TEST TWO BITS JP M,WRITEB ;DONE IF NEGATIVE JP NC,WRITEA ;WAIT FOR DATA REQUEST LD A,(HL) ;DATA TO A OUT DDAT,A ;OUTPUT TO DISK INC HL ;BUMP ADDRESS JP WRITEA ;DO NEXT BYTE WRITEB: IN A,DSTAT ;GET STATUS AND 15H ;OK? RET Z ;RETURN IF SO CALL HOME ;OTHERWISE FORCE HOME DEC B ;BUMP RETRY COUNT JR NZ,WRTRY ;RETRY IF NOT ZERO JR DIOERR ;REPORT I/O ERROR ; ; PRINT MESSAGE ROUTINE ; PRMSG: LD A,(HL) ;GET CHARACTER OR A ;TEST FOR END RET Z ;RETURN IF DONE LD C,A ;DATA TO C CALL CONOT ;OUTPUT IT INC HL ;BUMP ADDRESS JR PRMSG ;LOOP UNTIL DONE ; ;TRACK - SECTOR - DRIVE - DMA ;DISK INFOMATION STORAGE ; CDISK DB 0 CDSKA DB 0 ;CURRENT DRIVE FOR ;CONTROLLER SECTOR DB 0 ;CURRENT SECTOR NDISKS DB 0 ;NUMBER OF DISKS DMAADD DB 0,0 ;DMA ADDRESS TRACK DB 0 ;CURRENT TRACK TRKTBL DB 0,0,0,0 ;TRACK TABLE ; ; TERMINAL I/O ROUTINES ; ORG START+1ACH ; CONST: CALL STATUS ;GET STATUS FROM SNOOPY RET DB 0,0,0,0,0 ;FILL ; ; CONSOLE INPUT ; CONIN CALL INPUT ;GET INPUT FROM SNOOPY CP 08H ;TEST FOR {HOME} RET NZ ;NO MODIFICATIONS OR 1AH ;CONVERT TO ^Z RET NOP NOP ; ; CONSOLE OUTPUT ; CONOT LD A,C CALL OUTPUT RET DB 0,0,0,0,0,0 ;FILL ; ; LIST DEVICE OUTPUT ; LIST CALL OTLINE ;CALL LINE PRINTER RET DB 0,0,0,0,0,0,0 ;FILL ; ; PUNCH - NOT IMPLEMENTED ; PUNCH: NOP ;LEAVE ROOM FOR NOP ;CALL TO PROM NOP ;ROUTINE RET ; ; READER - SECOND 2-SIO PORT ; READER RET DB 0,0,0,0,0,0 ;FILL DB 0,0,0 ; ; I/O INITIALIZATION ; IOINIT LD A,0CH ;FORM FEED TO CLEAR ;VDM CALL OUTVDM ;CLEAR SCREEN RET DB 0,0,0,0,0,0,0 ;FILL ; ; MESSAGES ; MMSG: DEFB 0DH,0AH,'MOUNT ',0 ; ; END OF MSD BIOS ; END