home *** CD-ROM | disk | FTP | other *** search
- TITLE 'BIOS - NORTH STAR DD CP/M 2.2 OF 02/21/82'
- ; PAGE 44
- ;
- ; These routines copyright (c) 1980, 1981, 1982 by Steve Bogolub,
- ; 2338 S. Scoville Ave., Berwyn, IL 60402. Jade Double D (tm)
- ; disk handlers contributed to the public domain for use on Jade
- ; equipment by special permission of Jade Computer Products.
- ; This software may be used freely for non-commercial purposes
- ; only, and may not be sold.
- ;
- ; THIS BIOS CONTAINS ROUTINES TO SUPPORT THE
- ; FOLLOWING HARDWARE:
- ;
- ; DISK: NORTH STAR MDS-AD2 DOUBLE DENSITY 5.25"
- ; FLOPPY DISK UNITS 1 AND 2 AS CP/M DRIVES
- ; A: AND B:
- ;
- ; JADE DOUBLE D REV C 8" FLOPPY DISK UNITS
- ; 0 AND 1 AS CP/M DRIVES C: AND D:
- ;
- ; SERIAL I/O: HORIZON LEFT (LOW) SERIAL I/O PORT AS
- ; CP/M DEVICE CRT:
- ;
- ; QT IO+ BLOCK D (RIGHT) USART AS CP/M DEVICE
- ; UC1:, INIT'ED TO 19.2K BAUD RATE
- ;
- ; QT IO+ BLOCK C (LEFT) USART AS CP/M DEVICE
- ; TTY:, INIT'ED TO 300 BAUD RATE
- ;
- ; HORIZON RIGHT (HIGH) SERIAL I/O PORT AS
- ; CP/M DEVICE LPT:, WHICH IS SUPPORTED AS
- ; A MODEL 40 TELETYPE WITH THE SIMPLIFIED
- ; (HANDSHAKE) EIA INTERFACE, AND IS GENNED-IN
- ; AS THE LIST DEVICE.
- ;
- ; THE GENNED-IN CONSOLE IS DETERMINED BY SOLICITING
- ; A SPACE CODE (20H) FROM CRT:, TTY:, AND UC1:. IF
- ; NO SPACE CODE IS RECEIVED AFTER ABOUT EIGHT SECONDS
- ; (AT 4 MHZ), CRT: IS ASSUMED TO BE THE CONSOLE. IF
- ; A SPACE IS READ FROM ONE OF THE DEVICES, THAT DEVICE
- ; IS ASSUMED TO BE THE CONSOLE.
- ;
- ; LIST DEVICE UL1: PRINTS ON THE CURRENT CON: DEVICE.
- ; IF TTY: IS THE LIST DEVICE, DTR MUST BE HIGH, PROVIDING
- ; A SERIAL PRINTER PORT. BAT: IS NOT SUPPORTED, AND IS
- ; SET TO LPT: FOR OUTPUT AND CRT: FOR INPUT.
- ;
- ; SINCE THIS BIOS IS SO LARGE, MOVCPM SHOULD BE
- ; RUN FOR TWO LESS THAN THE DESIRED SYSTEM SIZE
- ; IN K, I.E. SPECIFY 30 FOR A 32K SYSTEM.
- ;
- ; *** IMPORTANT BOOTSTRAP INFO ***
- ;
- ; THIS BIOS IS INTENDED TO RUN IN THE LAST
- ; 3.5K OF MEMORY. THE LAST .5K IS SET ASIDE
- ; FOR A NORTH STAR SECTOR DEBLOCKING BUFFER.
- ; THE FIRST 3K IS GENNED-IN BIOS CODE, AND
- ; IS EXPECTED TO RESIDE ON TRACK 0 OF NORTH
- ; STAR DISK UNIT 1 (A:) IN SECTORS 5-9, AND
- ; 4. THE NORTH STAR BOOT PROM READS IN SECTOR
- ; 4 INTO CONSECUTIVE PAGES OF MEMORY, STARTING
- ; WITH THE PAGE NUMBER SPECIFIED BY THE FIRST
- ; BYTE OF SECTOR DATA, THEN JUMPS TO THAT
- ; ADDRESS + 10 (0AH). THIS BIOS IS SET UP TO
- ; USE THAT METHOD TO COLD BOOT ITSELF. CODE
- ; AT THAT ADDRESS READS THE LAST FIVE SECTORS
- ; OF TRACK ZERO INTO MEMORY AT ADDRESS "BIOS",
- ; THEN JUMPS TO THE BIOS COLD START ADDRESS.
- ; THE BIOS COLD BOOT EXPECTS THE JADE DOUBLE D
- ; CONTROL CODE ("NDCM") TO RESIDE ON SECTORS
- ; ONE AND TWO OF TRACK ZERO, AND LOADS THOSE
- ; SECTORS FROM THE DISK INTO THE JADE DD MEMORY,
- ; THEN RESETS AND STARTS UP THE JADE DD RESIDENT
- ; Z80. THE BIOS WARM BOOT EXPECTS THE CCP/BDOS
- ; CODE TO RESIDE ON TRACKS 0-9 OF TRACK ONE
- ; (IN OTHER WORDS, THE WHOLE TRACK), AND THE
- ; LAST SECTOR IS EXPECTED TO BE ON TRACK ZERO,
- ; SECTOR 3. TRACK ZERO, SECTOR ZERO IS RESERVED
- ; FOR LIFEBOAT-COMPATIBLE ID INFO AND FUTURE
- ; ADDITIONS. THE MODIFIED VERSION OF SYSGEN
- ; NAMED "NSGEN" IS SET UP TO TRANSFER CP/M TO
- ; AND FROM DISK IN THIS REQUIRED MANNER.
- ;
- ; WE USE THE Z80 INSTRUCTION "LD A,I" ON ENTRY
- ; TO THE DISK READ AND WRITE ROUTINES TO GET
- ; THE STATUS OF THE INTERRUPT FLIP/FLOP, SINCE
- ; WE MUST DISABLE INTERRUPTS WHILE THE NORTH
- ; STAR DISK READS OR WRITES ARE PERFORMED.
- ; USING THE Z80 STATUS, WE CAN RE-ENABLE
- ; INTERRUPTS AFTER WE LEAVE. THIS CHECK IS
- ; DONE BY THE ROUTINES "INTDI" AND "INDEN",
- ; AND CAN EASILY BE REMOVED IF WE EVER GO
- ; TO A NON-Z80 CPU (NEVER, I HOPE).
- ;
- LDAI EQU 057EDH ;Z80 "LD A,I" BYTE-SWAPPED
- ; FOR "DW" USE
- ;
- ; DISK OPERATING SYSTEM ADDRESSES
- ;
- NKSYS EQU 56 ;SYS SIZE IN K BYTES
- KBYTE EQU 1024 ;1K BYTE SIZE
- CPMSZ EQU NKSYS*KBYTE ;TOP SYSTEM ADDRESS
- CPMBS EQU CPMSZ-(22*KBYTE);CP/M BIAS VALUE
- CCP EQU CPMBS+3400H ;ADDRESS OF CCP
- BDOS EQU CPMBS+3C00H ;ADDRESS OF BDOS
- BIOS EQU CPMBS+4A00H ;ADDRESS OF BIOS
- BIOSR EQU 1F80H-BIOS+400H ;DDT LOAD OFFSET
- ;(LEAVES ROOM FOR NDCM)
- IOBYTE EQU 0003H ;IOBYTE ADDRESS
- DEFDSK EQU 0004H ;DEFAULT DISK FOR CCP
- SECSZ EQU 128 ;BYTES PER SECTOR
- HSTSIZ EQU 512 ;BYTES PER N* SECTOR
- NDRVS EQU 4 ;# DRIVES IN SYSTEM
- ;
- ; BDOS CONSTANTS ON ENTRY TO WRITE
- ;
- WRALL EQU 0 ;WRITE TO ALLOCATED
- WRDIR EQU 1 ;WRITE TO DIRECTORY
- WRUAL EQU 2 ;WRITE TO UNALLOCATED
- ;
- ; NORTH STAR MEMORY MAPPED I/O ADDRESSES
- ;
- NSROM EQU 0E800H ;COLD BOOT ROM ADDRESS
- WDATA EQU 0E900H ;WRITE DATA. DATA IS
- ; LOW 8 ADRESS BITS.
- CORDER EQU 0EA00H ;CONTROLLER ORDER
- CCMND EQU 0EB00H ;CONTROLLER COMMAND
- ;
- ; DOUBLE D HARDWARE PARAMETERS
- ;
- DPORT EQU 043H ;DOUBLE D PORT ADDRESS
- DBASE EQU 0E000H ;DOUBLE D WINDOW MEM BASE ADDR
- DSHLT EQU 001H ;STATUS PORT INDICATOR
- ;
- ; DOUBLE D HARDWARE COMMANDS
- ;
- DCSIN EQU 001H ;SWITCH DD BANK 0 INTO SYS
- DCMB0 EQU 001H ;SELECT DD BANK 0
- DCMB1 EQU 003H ;SELECT DD BANK 1
- DCSOT EQU 000H ;SWITCH DD MEM OUT OF SYS
- DCINT EQU 002H ;ISSUE DD Z80A INTERRUPT
- DCBGN EQU 080H ;RESET DD Z80A AND EXECUTE
- ;
- ; DISK CONTROLLER MODULE LINKAGE (DCM - VER 2.2)
- ;
- ; -- COMMAND BLOCK DEFINED
- ;
- DDCBT EQU 0370H ;COMMAND BYTE (BANK 0)
- DDDRV EQU 0371H ;DRIVE NUMBER (BANK 0)
- DDTRK EQU 0372H ;TRACK NUMBER (BANK 0)
- DDSEC EQU 0373H ;SECTOR NUMBER (BANK 0)
- DDSTS EQU 0377H ;COMMAND STATUS (BANK 0)
- DDBBF EQU 0000H ;1024 SECTOR BUFFER (BANK 1)
- DDFBF EQU 0300H ;FORMAT BUFFER (BANK 1)
- FMTSZ EQU 0100H ;FORMAT BUFF SIZE
- DDDPB EQU 0020H ;ID SEC DPB (BANK 1)
- DDDDF EQU DDDPB+0011H ;ID SEC FLAGS (BANK 1)
- ;
- ; -- DCM COMMANDS
- ;
- DCLOG EQU 000H ;LOG ON DISKETTE
- DCRDS EQU 001H ;READ SECTOR
- DCWRS EQU 002H ;WRITE SECTOR
- DCFMT EQU 003H ;FORMAT TRACK
- DCIDL EQU 007H ;STAY IDLE
- ;
- ; CONSOLE DEFINITIONS
- ;
- MOTHR EQU 000H ;HORIZON MOTHERBOARD BASE
- CRT EQU MOTHR+2 ;HORIZON LEFT SERIAL BASE
- ;
- QTIO EQU 0A0H ;QT IO+ BOARD BASE
- QTCTRL EQU QTIO+03H ;QT CONTROL PORT
- QTBAUD EQU QTIO+01H ;QT BAUD RATE PORT
- TTY EQU QTIO+08H ;QT LEFT SERIAL BASE
- UC1 EQU QTIO+0CH ;QT RIGHT SERIAL BASE
- ;
- CR EQU 0DH ;ASCII CARRIAGE RETURN
- LF EQU 0AH ;ASCII LINE FEED
- SPACE EQU 20H ;ASCII SPACE
- ;
- ; PRINTER DEFINITIONS
- ;
- LPD EQU MOTHR+4 ;DATA OUT
- LPC EQU LPD+1 ;STATUS
- LPIO EQU MOTHR+6 ;CHAIN CONTROL WORD
- CHAIN EQU 10H ;CHAIN RUNNING BIT IN LPIO
- FF EQU 0CH ;ASCII FORM FEED
- ;
- ;
- ; BIOS JUMP VECTOR TABLE
- ;
- ORG BIOS ;START OF BIOS CODE
- ;
- JMP NSROM ;COLD BOOT FROM ROM
- JMP WARM ;RELOAD CCP/BDOS
- ;
- ; USE VECTORS FOR INTERNAL CALLS ON CONSOLE ROUTINES
- ; INSTEAD OF CALLING THE ROUTINES DIRECTLY SO THAT
- ; BIOS ERROR I/O CAN BE HANDLED BY "BYE" AND OTHER
- ; VECTOR-PATCHING PROGRAMS.
- ;
- BCNSCK: JMP CNSCK ;GET CONSOLE STATUS
- BCNSIN: JMP CNSIN ;CONSOLE INPUT
- BCNSOT: JMP CNSOT ;CONSOLE OUTPUT
- ;
- JMP LIST ;PRINTER OUTPUT
- JMP PUNCH ;PUNCH OUTPUT
- JMP READER ;READER INPUT
- JMP HOME ;HOME SELECTED DRIVE
- JMP SELDSK ;SELECT DISK DRIVE
- JMP SETTRK ;SET TRACK NUMBER
- JMP SETSEC ;SET SECTOR NUMBER
- JMP SETDMA ;SET TRANSFER ADDRESS
- JMP DISKRD ;PERFORM DISK READ
- JMP DISKWR ;PERFORM DISK WRITE
- JMP LISTST ;RETURN LIST STAT
- JMP SECTRN ;TRANSLATE SECTOR
- JMP FORMAT ;FORMAT A JADE DD TRACK
- ;
- ; INIT - COLD START ENTRY ** DIRECTORY BUFFER OVERLAY **
- ;
- DIRBF EQU $ ;BUFFER BEGINNING
- ;
- ; SCRATCH RAM FOR BDOS OVERLAY
- ;
- D0ALL EQU DIRBF+SECSZ ;OVERLAY ALLOCATE AND CHECK
- D0CHK EQU D0ALL+23 ; BUFFERS HERE TOO
- D1ALL EQU D0CHK+16
- D1CHK EQU D1ALL+23
- D2ALL EQU D1CHK+16 ;NOTE THAT THE JADE DISKS
- D2CHK EQU D2ALL+39 ; (C: AND D:) MAY NEED
- D3ALL EQU D2CHK+32 ; MUCH MORE ALLOC AND
- D3CHK EQU D3ALL+39 ; CHECK SPACE THAN N*
- ;
- ENDOV EQU D3CHK+32 ;END OF OVERLAY AREA
- ;
- ; THE INIT ROUTINE IS ACTUALLY A CONTINUATION OF THE
- ; COLD BOOT BEGUN DOWN AT "BOOT".
- ;
- INIT: LXI SP,HSTBUF+HSTSIZ ;SET SP TO SCRATCH AREA
- LXI H,CCP ;WHERE TO START CP/M
- PUSH H
- XRA A ;INIT HORIZON MOTHERBOARD
- OUT MOTHR+6
- STA COLDB ;BIOS NOW IN MEMORY
- MVI A,0B1H ;INIT QT IO+ BOARD
- OUT QTCTRL
- MVI A,01FH ;INIT UC1: TO 19.2K BAUD
- OUT QTBAUD
- MVI A,005H ;INIT TTY: TO 300 BAUD
- OUT QTBAUD
- CALL DELAY ;DELAY FOR 8251'S
- MVI A,0AEH ;INIT SERIAL PORTS
- OUT CRT+1 ;OUTPUT DUMMY MODE TO INSURE
- OUT TTY+1
- OUT UC1+1
- OUT LPC
- CALL DELAY
- MVI A,040H ; CMD EXPECTED, THEN OUTPUT
- OUT CRT+1 ; RESET CMD
- OUT TTY+1
- OUT UC1+1
- OUT LPC
- CALL DELAY
- MVI A,04EH ;MODE: 1 STOP BIT, 16X CLK,
- OUT CRT+1 ; 8 DATA BITS, NO PARITY
- OUT TTY+1
- OUT UC1+1
- OUT LPC
- CALL DELAY
- MVI A,037H ;CMD: RTS, ER, RXEN, DTR, TXEN
- OUT CRT+1
- OUT TTY+1
- OUT UC1+1
- CALL DELAY
- CALL LGOOSE ;FINISH INIT OF MODEL 40
- IN CRT ;FLUSH RECEIVER INPUTS
- IN TTY
- IN UC1
- ;
- ; WAIT APPROX 8 SECONDS FOR OPERATOR TO STRIKE
- ; THE SPACE BAR ON CRT:, UC1:, OR TTY: TO DETERMINE
- ; CONSOLE. IF NO SPACE RECEIVED, DEFAULT TO CRT:.
- ;
- LXI H,0 ;SET UP WAIT
- MVI B,2 ; FOR ABOUT 8 SECS
- ;
- ICHK: CALL CRTCHK ;CHECK CRT:
- JZ ICHK5 ;PASS IF NOTHING
- IN CRT ; ELSE READ CHAR
- ANI 07FH ;STRIP PARITY
- CPI SPACE ;IS IT SPACE?
- JNZ ICHK5 ;TOSS IF NOT
- JMP ICHK20 ;IF SO, CON:=CRT:
- ;
- ICHK5: CALL TTYCHK ;CHECK TTY:
- JZ ICHK10
- IN TTY
- ANI 07FH
- CPI SPACE
- JNZ ICHK10
- MVI A,00B ;CON:=TTY:
- JMP ICHK25 ;GO SET IT
- ;
- ICHK10: CALL UC1CHK ;CHECK UC1:
- JZ ICHK15
- IN UC1
- ANI 07FH
- CPI SPACE
- JNZ ICHK15
- MVI A,11B ;CON:=UC1:
- JMP ICHK25 ;GO SET IT
- ;
- ICHK15: DCX H ;COUNT DOWN
- MOV A,H
- ORA L
- JNZ ICHK
- DCR B
- JNZ ICHK
- ;
- ICHK20: MVI A,01B ;TIME UP, SET CON:=CRT:
- ;
- ICHK25: ADI 80H ;DEFAULT LST:=LPT:
- STA IOBYTE ;SET INITIAL I/O BYTE
- LXI H,MSGSO ;SIGN-ON MSG ADDRESS
- CALL MSGOT ;ISSUE MESSAGE
- ;
- ; MUST NOW LOAD UP THE JADE DOUBLE D CONTROL CODE
- ; OFF THE DISK AND START UP THE DOUBLE D.
- ;
- MVI A,DCSIN ;REQUEST BANK ZERO
- OUT DPORT
- MVI A,1 ;CODE STARTS ON SEC 1
- STA HSTSEC ;WE KNOW HSTTRK STILL 0
- IN DPORT ;INPUT DD BOARD STATUS
- ANI 0EH ;MASK FOR ADDRESS SWITCHES
- RLC ;POSITION BITS
- ORI DBASE SHR 8 ;OR IN BASE ADDRESS
- MOV H,A ;FORM WINDOW ADDRESS IN HL
- MVI L,0
- SHLD DADDR ;SAVE ADDRESS FOR ALL JADE I/O
- SHLD HSTADR ;SET NS I/O ADDR TO DD MEM
- CALL WSETUP ;KICK MOTORS AND SEEK TRK
- CALL WRMRD ;READ SECTOR AND CHECK ERR
- MVI A,2 ;CODE EXTENDS INTO SEC 2
- STA HSTSEC
- LXI D,512
- LHLD DADDR
- DAD D
- SHLD HSTADR
- CALL WRMRD
- MVI A,DCBGN ;NOW START UP DD Z80
- OUT DPORT
- ;
- JMP CPMLD ;GO PERFORM WARM BOOT FUNCS
- ;
- ; THIS DELAY SUBROUTINE IS USED TO HELP US OUT ON
- ; TIMING WHEN RESETTING THE 8251 CONSOLE SERIAL DEVICE.
- ;
- DELAY: LXI B,600H
- DEL5: DCX B
- MOV A,B
- ORA C
- JNZ DEL5
- RET
- ;
- MSGSO: DB CR,LF,'North Star / '
- DB 'Jade DD '
- DB (NKSYS/10)+'0',(NKSYS MOD 10)+'0'
- DB 'K CP/M 2.2 of 02/21/82',CR,LF+80H
- ;
- IF ($-ENDOV) SHR 15
- ORG ENDOV ;FILL OUT OVERLAY SIZE
- ENDIF
- ;
- ; SELECT DRIVE - LOGON
- ;
- SELDSK: LXI H,0 ;ERROR RETURN CODE
- MOV A,C ;PUT DRIVE # IN A
- CPI NDRVS ;CHECK IF LEGAL DRIVE
- RNC ;NO CARRY IF ILLEGAL
- STA SEKDSK ;STORE DRIVE NUMBER
- MOV B,E ;SAVE LOGON REQ REG
- MOV L,C ;L = DISK NUMBER
- MVI H,0 ;ZERO H REG
- DAD H ; *2
- DAD H ; *4
- DAD H ; *8
- DAD H ; *16 (SIZE OF HEADER)
- LXI D,D0DPH ;DRIVE 0 DPH
- DAD D ;HL = DRIVE N DPH
- SHLD DTPTR ;STORE DRIVE TBL PTR
- ;
- ; LOG-ON - SET DISK PARAMETER BLOCK
- ;
- ; -- CHECK IF LOG-ON REQUESTED
- ;
- XRA A
- STA LOGFLG ;ASSUME NO JADE LOGON
- MOV A,B ;CHECK LOG REQUEST
- ANI 001H ;LOG ON BIT TEST
- JNZ NOLOG ;PASS IF NO REQUEST
- CALL HFLUSH ;MAKE SURE HOST BUF
- JNZ LOGERR ; AVAILABLE, OUT ON ERR
- ;
- ; SEE IF DISK IS JADE OR NORTH STAR.
- ;
- LDA SEKDSK ;GET DISK #
- CPI 2
- JNC LOGJAD ;IF JADE, GO ELSEWHERE
- ;
- ; LOG ON NORTH STAR BY READING ID SECTOR, THEN DECIDE
- ; WHICH TABLE TO USE BASED ON SINGLE OR DOUBLE DENSITY.
- ; IF DOUBLE DENSITY, LOOK FOR LIFEBOAT 2.X FLAG BYTE
- ; AT OFFSET 05CH IN THE SECTOR, AND USE LIFEBOAT 2.X
- ; DPB IF THAT BYTE CONTAINS 0B0H. IF NOT, ASSUME OUR
- ; NORMAL LIFEBOAT 1.4-COMPATIBLE DPB FOR DOUBLE DENSITY.
- ;
- STA HSTDSK ;GOING TO ACCESS THIS DISK
- XRA A
- STA HSTTRK ;TRACK ZERO
- STA HSTSEC ;N* SECTOR ZERO
- CALL INTDI ;INTERRUPTS OFF
- CALL READHST ;READ THE SECTOR
- CALL INTEN ;INTERRUPTS RESTORED
- LDA ERFLAG ;CHECK FOR READ ERROR
- ORA A
- JNZ LOGERR ;LOG-ON ERROR IF SO
- LDA NSDENS ;IF OK, GET DENSITY FLAG
- LXI B,TRAN5S ;ASSUME SINGLE DENSITY,
- LXI D,DPBNSS ; EVEN THO USUALLY WRONG
- ORA A ;CHECK
- JNZ LOGNSD ;GO ON IF RIGHT
- LXI B,TRAN5D ;DOUBLE DENS, COMMON XLATE
- LXI D,DPBNSD ; BUT ASSUME OUR 1.4 DPB
- LDA HSTBUF+05CH ;GET LIFEBOAT FLAG BYTE
- CPI 0B0H ;IS IT LIFEBOAT 2.X FLAG?
- JNZ LOGNSD ;KEEP OUR DPB IF NOT
- LXI D,DPBNSL ;GO TO LIFEBOAT 2.X IF NOT
- ;
- LOGNSD: LHLD DTPTR ;LOAD DRIVE TBL PTR
- MOV M,C ;SET TRANSLATE TABLE ADDR
- INX H
- MOV M,B
- LXI B,9 ;PT TO DPB ADDR
- DAD B
- MOV M,E ;SET DPB ADDR
- INX H
- MOV M,D
- JMP NOLOG ;GO COMPLETE LOGON NOW
- ;
- ; -- READ JADE IDENTITY SECTOR
- ;
- LOGJAD: STA LOGFLG ;LOGGING ON JADE DISK
- MVI A,DCSIN ;SWITCH DD INTO SYS
- OUT DPORT ;ISSUE HARDWARE CMND
- MVI A,DCLOG ;LOAD DCM LOG-ON CMND
- CALL DSKEX ;PERFORM DISK OP
- JZ LOGCK ;PASS IF OK
- CALL DSKER ;ERROR, BAD LOG ON
- ;
- LOGERR: LXI H,0
- RET
- ;
- ; -- CHECK FOR JADE ID
- ;
- LOGCK: MVI A,DCMB1 ;SELECT BANK 1
- OUT DPORT ; BECAUSE BUFFER IS THERE
- LHLD DADDR ;GET DD BUFFER ADDR IN HL
- LXI D,JADEID ;DE PNTS TO BIOS ID
- MVI B,IDSZE ;SET LABEL SIZE
- LOGID: LDAX D ;GET LABEL CHARACTER
- CMP M ;DOES ID SECTOR MATCH?
- JNZ LG3740 ;ASSUME 3740 IF NOT
- INX H ;ADVANCE PTRS
- INX D
- DCR B
- JNZ LOGID ;GO BACK IF MORE TO MATCH
- ;
- ; -- DISKETTE CONTAINS ID
- ;
- CALL TRNONE ;ASSUME DDENS
- CALL DPBAD ;GET DPB ADDR IN DE
- LXI B,DDDPB ;GET ID DPB ADDR IN HL
- LHLD DADDR
- DAD B
- LXI B,DPBSZ ;DPB SIZE IN BYTES
- CALL BLOCK ;MOVE INTO DPB
- LXI B,DDDDF ;CALC ADDR OF ID FLAGS
- LHLD DADDR
- DAD B
- MOV A,M ;GET ID FLAGS IN ACC
- PUSH PSW ;SAVE FLAGS
- ANI 0F0H ;STRIP LOW FLAGS
- RAR ;MOVE SECTOR SHIFT BIT
- RAR ; FLAG RIGHT
- RAR
- DCX D ;PT INTO DPB ADD-ON
- STAX D ;SAVE SECTOR SHIFT
- ORA A ;IS THERE A SHIFT?
- CNZ TR1024 ;USE 1024 BYTES/SECTOR
- ; XLATE TABLE IF SO
- POP PSW ;GET ORIG FLAGS AGAIN
- ANI 04H ;TEST DATA DENSITY
- CZ TR3740 ;IF ZERO USE 3740 TRN
- ;
- ; SET UP DEBLOCKING VARIABLES FROM DPB VALUES
- ;
- NOLOG: CALL DPBAD ;GET DPB ADDR
- XCHG ; IN HL
- MOV A,M ;SET UP DEBLOCK
- STA CPMSPT ; SECTORS PER TRACK
- INX H ;GET TO GROUP MASK
- INX H
- INX H
- MOV A,M ;GET IT
- INR A ;CALC # BLOCKS/GROUP
- STA UNAVAL ; AND SAVE THAT
- LXI D,12
- DAD D ;PT TO SECTOR SHIFT
- MOV A,M ; BIT FLAG
- ORA A ;HAVE WE GOT ONE?
- JZ NOSHF ;PASS IF NOT
- MVI B,0FFH ;INIT SHIFT COUNT
- ;
- CALCSH: INR B ;COUNT UP A SHIFT
- RAR ;SEE IF DONE
- JNC CALCSH ;GO BACK IF NOT YET
- MOV A,B ;SHIFT COUNT TO ACC
- ;
- NOSHF: STA SECSHF ;STORE SHIFT COUNT
- MOV A,M ;RELOAD BIT FLAG
- DCR A ;FORM SECTOR MASK
- STA SECMSK ; AND SET IT
- LHLD DTPTR ;RELOAD PTR
- LDA LOGFLG ;WAS JADE LOGGED ON?
- ORA A ;FLAG NON-ZERO IF SO,
- JNZ DSKOK ; GO HANDLE DCM MORE
- RET ;IF NOT, DONE, RET ZERO
- ;
- ; -- ASSUME 3740 DISKETTE
- ;
- LG3740: CALL TR3740 ;SET SECTOR TRANSLATE
- CALL DPBAD ;SET REGISTER DE
- LXI B,DPBSZ ;DPB SIZE IN BYTES
- LXI H,DPB8 ;ADDRESS OF BLK IMAGE
- CALL BLOCK ;MOVE INTO DPB
- JMP NOLOG ;GO SET UP (CLEAR) THE
- ; DEBLOCK VARIABLES
- ;
- ; -- SET 3740 SECTOR TRANSLATION
- ;
- TR3740: LXI D,TRAN8 ;SECTOR TRAN TBL ADDR
- ;
- TRCOM: LHLD DTPTR ;ADDR DISK PARA HDER
- MOV M,E
- INX H
- MOV M,D
- RET
- ;
- ; -- SET 1024 BYTES/SECTOR TRANSLATION
- ;
- TR1024: LXI D,TRN124 ;SECTOR TRAN TBL ADDR
- JMP TRCOM ;GO SET IT
- ;
- ; -- SET NO SECTOR TRANSLATION
- ;
- TRNONE: XRA A ;ZERO A REG
- LHLD DTPTR
- MOV M,A
- INX H
- MOV M,A
- RET
- ;
- ; -- GET DRIVE PARA BLK ADDR
- ;
- DPBAD: LHLD DTPTR ;ADDR DISK PARA HDED
- LXI D,10 ;DPB TBL PNTR OFFSET
- DAD D ;NOW AT DPB PNTR
- MOV E,M ;LOAD INTO DE
- INX H
- MOV D,M
- RET ;RETURN TO LOG USER
- ;
- ; HOME DRIVE
- ;
- HOME: MVI C,0 ;SET TRACK TO ZERO TO HOME
- LDA HSTWRT ;CHECK FOR PENDING WRITE
- ORA A
- JNZ SETTRK
- STA HSTACT ;CLEAR HOST ACTIVE IF NOT
- ;
- ; SET TRACK
- ;
- SETTRK: MOV A,C ;MOVE TRACK NUMBER
- STA SEKTRK ; THEN SAVE IT
- RET ;RETURN TO CALLER
- ;
- ; SET SECTOR
- ;
- SETSEC: MOV A,C ;MOVE SECTOR NUMBER
- STA SEKSEC ; THEN SAVE IT
- RET ;RETURN TO CALLER
- ;
- ; SET TRANSFER ADDRESS
- ;
- SETDMA: MOV H,B ;MOVE ADDR TO HL
- MOV L,C
- SHLD DMAADR ; THEN SAVE IT
- RET ;RETURN TO CALLER
- ;
- ; SECTOR TRANSLATION
- ;
- SECTRN: MOV A,E ;IS THERE A TABLE?
- ORA D
- JZ JTRAN ;JADE SPECIAL XLATE IF NOT
- XCHG ;MAP OFF TABLE IF SO
- DAD B
- MOV L,M
- MVI H,0
- RET
- ;
- JTRAN: MOV H,B ;JADE XLATE OFF BY ONE
- MOV L,C ; SO FIX FOR CALLER
- INX H
- RET ; THEN DONE
- ;
- ; IOBYTE IS SUPPORTED FOR CONSOLE AND LIST DEVICE
- ;
- ; CONSOLE STATUS
- ;
- CNSCK: CALL CONS ;GET HARDWARE STATUS
- RZ ;IF NO CHAR READY, RETURN 0
- MVI A,0FFH ; ELSE RETURN 0FFH
- RET
- ;
- CONS: LDA IOBYTE ;GET IOBYTE
- CALL ROUTE ;DISPATCH TO STATUS ROUTINE
- DW TTYCHK ;TTY:
- DW CRTCHK ;CRT:
- DW CRTCHK ;BAT: (RDR: NOT SUPPORTED)
- DW UC1CHK ;UC1:
- ;
- ; CONSOLE INPUT
- ;
- CNSIN: CALL CONS ;GET HARDWARE STATUS
- JZ CNSIN ;WAIT FOR CHAR READY
- CALL CONIN ; THEN GET CHAR
- ANI 07FH ;STRIP PARITY
- RET ; AND RETURN IN ACC
- ;
- CONIN: LDA IOBYTE
- CALL ROUTE ;DISPATCH TO INPUT ROUTINE
- DW TTYIN ;TTY:
- DW CRTIN ;CRT:
- DW CRTIN ;BAT: NOT SUPPORTED, USE CRT:
- DW UC1IN ;UC1:
- ;
- ; HXBOT DISPLAYS HEXIDECIMAL EQUIV OF ACC CONTENTS.
- ;
- HXBOT: PUSH PSW ;SAVE CHAR
- RRC ;SWAP NIBBLES
- RRC
- RRC
- RRC
- CALL HXNOT ;OUTPUT HIGH NIBBLE
- POP PSW ; THEN LOW NIBBLE
- HXNOT: ANI 0FH ;STRIP HIGH NIBBLE
- ADI 90H ;CVT TO ASCII DECIMAL
- DAA
- ACI 40H
- DAA
- MOV C,A ;CHAR TO C
- JMP BCNSOT ;THRU VECTOR TO CNSOT
- ;
- ; CONSOLE OUTPUT
- ;
- CNSOT: LDA IOBYTE
- CALL ROUTE ;DISPATCH TO OUTPUT ROUTINE
- DW TTYOT ;TTY:
- DW CRTOT ;CRT:
- DW LPTOT ;BAT: NOT SUPPORTED, USE LPT:
- DW UC1OT ;UC1:
- ;
- ; READER INPUT
- ;
- READER: EQU CNSIN ;SAME AS CONSOLE INPUT
- ;
- ; PUNCH OUTPUT
- ;
- PUNCH: EQU CNSOT ;SAME AS CONSOLE OUTPUT
- ;
- ; LIST STATUS
- ;
- LISTST: XRA A ;SAY IT'S READY
- DCR A
- RET
- ;
- ; LIST OUTPUT
- ;
- LIST: LDA IOBYTE
- RLC ;ROTATE LST: BITS TO LOW
- RLC ; BIT POSITIONS
- CALL ROUTE ;DISPATCH TO LIST ROUTINE
- DW TTYOTS ;TTY: WITH DTR FOR
- ; SERIAL PRINTERS
- DW CRTOT ;CRT:
- DW LPTOT ;LPT:
- DW CNSOT ;UL1: USES CURRENT CON:
- ;
- ; THE ROUTING ROUTINE
- ;
- ROUTE: RLC ;DOUBLE FOR WORD OFFSET
- ANI 06H ;STRIP UNUSED BITS
- XTHL ;GET DISPATCH TABLE ADDR
- ADD L ;ADD OFFSET TO GET
- MOV L,A ; TO CORRECT VECTOR
- JNC ROUTE5
- INR H
- ROUTE5: MOV A,M ;PULL VECTOR
- INX H
- MOV H,M
- MOV L,A
- XTHL ;STACK VECTOR, RESTORE HL
- RET ; THEN OFF TO ROUTINE
- ;
- ; HORIZON TTY: ROUTINES
- ;
- TTYCHK: IN TTY+1 ;GET PORT STATUS
- ANI 2 ;CHECK RECEIVER
- RET ;RET NON-ZERO IF READY
- ;
- TTYIN: IN TTY ;GET PORT DATA
- RET
- ;
- TTYOT: IN TTY+1 ;GET PORT STATUS
- RRC ;XMIT BUFFER EMPTY?
- JNC TTYOT ;IF NOT, WAIT TIL IS
- ;
- ; HERE FROM TTYOTS BELOW TO OUTPUT CHAR FROM C
- ;
- TTYOTC: MOV A,C ; THEN OUTPUT CHAR FROM C
- OUT TTY
- RET
- ;
- ; SERIAL PRINTER ROUTINE. WAIT FOR DTR HIGH, XMIT
- ; BUFFER EMPTY, AND XMITTER READY BEFORE SENDING NEXT
- ; CHAR. THIS ROUTINE HAS BEEN TESTED WITH THE EPSON
- ; MX-80 WITH 2K SERIAL BUFFER, WHICH SHOULD BE
- ; TYPICAL OF SERIAL PRINTERS.
- ;
- TTYOTS: IN TTY+1
- ANI 85H
- CPI 85H ;NEED ALL 3 BITS HIGH
- JNZ TTYOTS
- JMP TTYOTC ;NOW OUTPUT
- ;
- ; HORIZON CRT: ROUTINES. SAME AS TTY:, BUT DIFF PORT
- ;
- CRTCHK: IN CRT+1 ;GET PORT STATUS
- ANI 2 ;CHECK RECEIVER
- RET ;RET NON-ZERO IF READY
- ;
- CRTIN: IN CRT ;GET PORT DATA
- RET
- ;
- CRTOT: IN CRT+1 ;GET PORT STATUS
- RRC ;XMIT BUFFER EMPTY?
- JNC CRTOT ;IF NOT, WAIT TIL IS
- MOV A,C ; THEN OUTPUT CHAR FROM C
- OUT CRT
- RET
- ;
- ; UC1 CONSOLE SERIAL ROUTINES
- ;
- UC1CHK: IN UC1+1 ;GET PORT STATUS
- ANI 02H ;CHECK RECEIVER
- RET ;RET NON-ZERO IF READY
- ;
- UC1IN: IN UC1 ;GET PORT DATA
- RET
- ;
- UC1OT: IN UC1+1 ;GET PORT STATUS
- RRC ;XMIT BUFFER EMPTY?
- JNC UC1OT ;IF NOT, WAIT TIL IS
- MOV A,C ; THEN OUTPUT CHAR FROM C
- OUT UC1
- RET
- ;
- ; LIST CHAR OUT TO MODEL 40 LINE PRINTER
- ;
- LPTOT: PUSH H ;SAVE HL
- PUSH B ;SAVE CHAR TO OUTPUT
- IN LPIO ;SEE IF M40 CHAIN RUNNING
- ANI CHAIN
- JZ LOUT7 ;SKIP RE-INIT IF SO
- ;
- LOUT5: CALL LGOOSE ;GOOSE PRINTER
- ;
- LOUT7: LXI H,0 ;LOAD UP FOR NICE LONG DELAY
- MVI B,8
- ;
- LOUT10: DCX H ;COUNT DOWN
- MOV A,H ;SEE IF ZERO YET
- ORA L
- JNZ LOUT20 ;PASS IF NOT
- DCR B ;COUNT OFF HIGHER BITS
- JNZ LOUT20 ;PASS IF NOT ZERO YET
- ;
- LOUT15: MVI A,'P' ;DISK P: NOT READY, FOR PRINTER
- CALL PNTRDY ;REPORT, AND RETURN IF NO CTRL-C
- JMP LOUT5 ;NOW GO RE-INIT THE PRINTER
- ;
- LOUT20: IN LPIO ;CHECK FOR CHAIN NOT RUNNING
- ANI CHAIN
- JNZ LOUT10 ;COUNT DOWN TIMEOUT IF SO
- IN LPC ;GET 8251 STATUS
- ANI 85H ;STRIP OUT REQ NXT CHAR, XMIT
- CPI 85H ; BUF RDY, AND XMIT EMPTY,
- ; THEN CHECK THEM
- JNZ LOUT10 ;ALL 3 MUST BE UP TO SEND
- ;
- ; PRINTER NOW READY. OUTPUT CHAR.
- ;
- POP B ;RESTORE CHAR TO C
- MOV A,C ; AND GET IT TO ACC
- ANI 7FH ;STRIP PARITY
- OUT LPD ;OUTPUT THE CHAR
- CPI FF ;WAS CHAR FORM FEED?
- JNZ LOUT35 ;PASS IF NOT
- MVI L,6 ;MUST FOLLOW WITH NULLS IF SO
- ;
- LOUT30: IN LPC ;WAIT FOR BUFFER READY
- RRC
- JNC LOUT30
- XRA A ; THEN OUTPUT NULL
- OUT LPD
- DCR L ; AND COUNT IT OFF
- JNZ LOUT30 ;GO BACK IF MORE TO DO
- ;
- LOUT35: MOV A,C ;RESTORE CHAR TO ACC
- POP H ;RESTORE HL
- RET ; AND RETURN
- ;
- ; TOGGLE DTR FOR PRINTER TO GOOSE IT INTO STARTING CHAIN UP
- ;
- LGOOSE: MVI A,035H ;RAISE DTR
- OUT LPC
- CALL LWAIT ;DELAY
- MVI A,037H ;NOW DROP DTR TO TOGGLE
- OUT LPC
- LWAIT: XRA A ;DELAY
- LPIL: XTHL
- XTHL
- XTHL
- XTHL
- DCR A
- JNZ LPIL
- RET
- ;
- ; DEBLOCKING DISK WRITE
- ;
- DISKWR: CALL INTDI ;MASK INTERRUPTS
- CALL DSKWR ;DO THE WRITE
- JMP INTEN ;GO RESTORE INTS
- ;
- ; DEBLOCKING DISK READ. NOTE THAT ON DEBLOCKING READ
- ; AND WRITE, THE CALLER SECTOR NUMBERS RANGE FROM 1-XX
- ; DECIMAL. THIS IS FOR COMPATIBILITY WITH 8" FORMATS
- ; THAT ARE 1-ORIGIN. WE ADJUST FOR THIS THROUGHOUT THE
- ; DEBLOCKING ROUTINES BY SUBTRACTING 1 FROM SEKSEC
- ; BEFORE WE USE IT. VARIABLES TO CONTROL DEBLOCKING
- ; ARE SET UP FOR US WHEN DISK IS SELECTED.
- ;
- DISKRD: CALL INTDI ;DISABLE INTERRUPTS
- CALL DSKRD ;DO THE I/O
- ;
- INTEN: PUSH PSW ;SAVE DISK I/O ERROR CODE
- LHLD ENTPSW ;GET ENTRY PSW TO TEST
- PUSH H
- POP PSW
- JPO INTEN5 ;PASS IF INTS OFF WHEN ENTERED
- EI ; ELSE RE-ENABLE INTS
- ;
- INTEN5: POP PSW ;RESTORE DISK I/O ERROR CODE
- RET ; THEN RETURN TO CALLER
- ;
- INTDI: MVI A,7FH ;CHECK FOR RUNNING ON
- INR A ; 8080 OR Z80
- JPO NOTZ80 ;CAN'T GET INT STATE ON 8080
- DW LDAI ;GET INT STATE INTO
- PUSH PSW ; PARITY FLAG, THEN
- POP H ; SAVE PSW IN MEMORY
- SHLD ENTPSW
- ;
- NOTZ80: DI ;ALLOW NO INTERRUPTS
- RET ; DURING THE I/O XFER
- ;
- DSKRD: LDA SECSHF ;SEE IF DEBLOCKING
- ORA A
- JZ JADERD ;MUST BE JADE IF NOT
- LDA SEKDSK ;IF SO, SEE IF JADE ANYWAY
- CPI 2
- JC NOTJR ;PASS IF NOT, N* READ
- LDA SEKTRK ;IF SO, IS TRACK 0 OR 1?
- CPI 2
- JC JADERD ;NORMAL SECTOR SIZE IF SO
- ;
- NOTJR: MVI A,WRUAL
- STA WRTYPE ;TREAT AS UNALLOC
- STA READOP ;READ OPERATION
- JMP ALLOC ;GO END UNALLOC SECTORS
- ; AND FORCE READ
- ;
- DSKWR: LDA SECSHF ;SEE IF DEBLOCKING
- ORA A
- JZ JADEWR ;MUST BE JADE IF NOT
- LDA SEKDSK ;IF SO, SEE IF JADE ANYWAY
- CPI 2
- JC NOTJW ;PASS IF NOT, N* WRITE
- LDA SEKTRK ;IF SO, IS TRACK 0 OR 1?
- CPI 2
- JC JADEWR ;NORMAL SECTOR SIZE IF SO
- ;
- NOTJW: XRA A
- STA READOP ;NOT A READ OPERATION
- MOV A,C ;WRITE TYPE IN C
- STA WRTYPE
- CPI WRUAL ;WRITE UNALLOCATED?
- JNZ CHKUNA ;CHECK FOR UNALLOC
- ;
- ; WRITE TO UNALLOCATED, SET PARAMETERS
- ;
- LDA UNAVAL ;NEXT UNALLOC RECS
- STA UNACNT
- LHLD SEKDSK ;PICK UP SEKDSK AND SEKTRK
- SHLD UNADSK ;UNADSK=SEKDSK, UNATRK=SEKTRK
- LDA SEKSEC
- STA UNASEC ;UNASEC = SEKSEC
- ;
- ; CHECK FOR WRITE TO UNALLOCATED SECTOR
- ;
- CHKUNA: LDA UNACNT ;ANY UNALLOC REMAIN?
- ORA A
- JZ ALLOC ;SKIP IF NOT
- ;
- ; MORE UNALLOCATED RECORDS REMAIN
- ;
- DCR A ;UNACNT = UNACNT - 1
- STA UNACNT
- LDA SEKDSK ;SAME DISK?
- LXI H,UNADSK
- CMP M ;SEKDSK = UNADSK?
- JNZ ALLOC ;SKIP IF NOT
- ;
- ; DISKS ARE THE SAME, CHECK TRACKS
- ;
- LDA SEKTRK
- LXI H,UNATRK
- CMP M ;SEKTRK = UNATRK?
- JNZ ALLOC ;SKIP IF NOT
- ;
- ; TRACKS ARE THE SAME, CHECK SECTORS
- ;
- LDA SEKSEC
- LXI H,UNASEC
- CMP M ;SEKSEC = UNASEC?
- JNZ ALLOC ;SKIP IF NOT
- ;
- ; MATCH, MOVE TO NEXT SECTOR FOR FUTURE REF
- ;
- INR M ;UNASEC = UNASEC+1
- LDA CPMSPT ;CHECK FOR END OF TRACK
- CMP M
- JNC NOOVF ;SKIP IF STILL ON TRACK
- ;
- ; OVERFLOW TO NEXT TRACK
- ;
- MVI M,1 ;UNASEC = 1
- LXI H,UNATRK
- INR M ;UNATRK = UNATRK+1
- ;
- ; MATCH FOUND, MARK AS UNNECESSARY READ
- ;
- NOOVF: XRA A
- STA RSFLAG ;RSFLAG = 0
- JMP RWOPER ;GO DO WRITE
- ;
- ; NOT AN UNALLOCATED RECORD, REQUIRES PRE-READ
- ;
- ALLOC: XRA A
- STA UNACNT ;UNACNT = 0
- INR A
- STA RSFLAG ;RSFLAG = 1
- ;
- ; COMMON CODE FOR READ AND WRITE FOLLOWS
- ;
- RWOPER: XRA A
- STA ERFLAG ;NO ERRORS (YET)
- LDA SECSHF ;GET SECTOR SHIFT COUNT
- MOV B,A ; IN COUNT REG
- LDA SEKSEC ;COMPUTE HOST SECTOR
- DCR A ;ADJUST FOR 1-ORIGIN
- ;
- RWOPSH: ORA A ;CARRY = 0
- RAR ;SHIFT RIGHT
- DCR B ;COUNT OFF A SHIFT
- JNZ RWOPSH ;LOOP IF MORE
- STA SEKHST ;HOST SECTOR TO SEEK
- ;
- ; ACTIVE HOST SECTOR?
- ;
- LXI H,HSTACT ;HOST ACTIVE FLAG
- MOV A,M
- MVI M,1 ;ALWAYS BECOMES 1
- ORA A ;WAS IT ALREADY?
- JZ FILHST ;FILL HOST IF NOT
- ;
- ; HOST BUFFER ACTIVE, SAME AS SEEK BUFFER?
- ;
- LDA SEKDSK
- LXI H,HSTDSK ;SAME DISK?
- CMP M ;SEKDSK = HSTDSK?
- JNZ NOMATCH
- ;
- ; SAME DISK, CHECK TRACK
- ;
- LDA SEKTRK
- LXI H,HSTTRK
- CMP M ;SEKTRK = HSTTRK?
- JNZ NOMATCH
- ;
- ; SAME DISK AND TRACK, CHECK SECTOR
- ;
- LDA SEKHST
- LXI H,HSTSEC
- CMP M ;SEKHST = HSTSEC?
- JZ MATCH ;SKIP IF MATCH
- ;
- ; MUST FLUSH HOST BUFFER FOR NEW SECTOR
- ;
- NOMATCH: LDA HSTWRT ;HOST WRITTEN?
- ORA A
- CNZ WRITEHST ;CLEAR HOST BUFFER
- LDA ERFLAG ;CHECK FOR ERROR
- ORA A
- RNZ ;RETURN ERROR IF SO
- ;
- FILHST: LHLD SEKDSK ;MAY HAVE TO FILL HOST BUFFER
- SHLD HSTDSK ;HSTDSK=SEKDSK,HSTTRK=SEKTRK
- LDA SEKHST
- STA HSTSEC
- XRA A
- STA HSTWRT ;NO PENDING WRITE
- LDA RSFLAG ;NEED TO READ?
- ORA A
- JZ MATCH ;NO IF FLAG ZERO
- LDA HSTDSK ;SEE WHICH DISK
- CPI 2 ;IF C: OR D:, JADE
- JNC NOTNSR ;BRANCH IF JADE
- CALL READHST ;IF A: OR B:, READ N*
- LDA ERFLAG ;CHECK FOR ERRORS
- ORA A
- RNZ ;NO MORE IF SO
- CALL GNSDEN ;CHECK DENSITY
- LXI H,NSDENS
- CMP M ;IS DENSITY RIGHT?
- JZ MATCH ;OK IF SO
- LXI H,SDEMSG ;ERROR IF NOT
- CALL DSKERR ;REPORT IT
- MVI A,5
- STA ERFLAG
- RET ;RET NZ ACC TO CALLER
- ;
- NOTNSR: CALL JHREAD ;READ JADE DISK
- LDA ERFLAG ;READ ERROR?
- ORA A
- RNZ ;LEAVE BUF ALONE IF SO
- ;
- ; COPY DATA TO OR FROM BUFFER
- ;
- MATCH: LDA SECMSK ;GET MASK
- MOV H,A ; INTO TEMP REG
- LDA SEKSEC ;MASK SECTOR BUFFER NUMBER
- DCR A ;ADJUST FOR 1-ORIGIN
- ANA H ;LEAST SIGNIF BITS
- RAR ;GET VALUE SHIFTED
- MOV H,A ; LEFT 7 IN HL
- MVI A,0
- RAR
- MOV L,A
- ;
- ; HL CONTAINS RELATIVE HOST BUFFER ADDRESS
- ;
- LXI D,HSTBUF ;ASSUME USING N* BUFFER
- LDA HSTDSK ;CHECK DISK SELECTED
- CPI 2
- JC NJBUF ;RIGHT IF NOT JADE DISK
- MVI A,DCMB1 ;USING JADE BUFFER,
- OUT DPORT ; SWITCH BANK ONE IN
- XCHG ;PUT OFFSET IN DE NOW
- LHLD DADDR ;PT HL AT BUFFER
- ;
- NJBUF: DAD D ;HL = HOST ADDRESS
- XCHG ;NOW IN DE
- LHLD DMAADR ;GET/PUT CP/M DATA
- MVI C,SECSZ ;LENGTH OF MOVE
- LDA READOP ;WHICH WAY?
- ORA A
- JNZ RWMOVE ;SKIP IF READ
- ;
- ; WRITE OPERATION, MARK AND SWITCH DIRECTION
- ;
- INR A ;ACC KNOWN ZERO ABOVE
- STA HSTWRT ;HSTWRT = 1
- XCHG ;SOURCE/DEST SWAP
- ;
- RWMOVE: LDAX D ;SOURCE CHARACTER
- INX D
- MOV M,A ;TO DEST
- INX H
- DCR C ;LOOP 128 TIMES
- JNZ RWMOVE
- LDA HSTDSK ;IS THIS JADE DISK?
- CPI 2
- CNC DSKOUT ;FIX MEM STATUS IF SO
- ;
- ; DATA HAS BEEN MOVED TO/FROM HOST BUFFER
- ;
- LDA WRTYPE ;WRITE TYPE
- CPI WRDIR ;TO DIRECTORY?
- MVI A,0 ;NO ERROR AT THIS PT
- RNZ ;RET IF NOT DIR WRITE
- ;
- ; CLEAR HOST BUFFER FOR DIRECTORY WRITE
- ;
- CALL WRITEHST
- LDA ERFLAG
- RET
- ;
- ; WRITEHST PERFORMS THE PHYSICAL WRITE TO THE
- ; NORTH STAR DISK. ON ENTRY, DRIVE IS IN HSTDSK,
- ; TRACK IS IN HSTTRK, SECTOR IS IN HSTSEC. ON
- ; EXIT, ERROR FLAG IS IN ERFLAG (ZERO IF NONE).
- ;
- ; IT IS ASSUMED INTERRUPTS ARE DISABLED AT
- ; THIS POINT. IF NOT, I/O MAY BE DISRUPTED.
- ;
- WRITEHST: ;WRITE HOST
- XRA A ;BUFFER WILL BE CLEARED
- STA HSTWRT
- LDA HSTDSK ;SEE IF N* DISK SELECTED
- CPI 2
- JNC JHWRIT ;IF NOT, DO JADE WRITE
- CALL GNSDEN ;GET DENSITY BASED ON ID
- STA NSCNT ;SET WRITE BYTE COUNT
- CALL SETUP ;SELECT DRIVE AND
- ; SEEK TO TRACK
- LDA ERFLAG ;CHECK FOR ERRORS
- ORA A
- RNZ ;INDEX PULSE NOT FOUND IS FATAL
- CALL POSEC ;POSITION TO SECTOR
- JNZ SNFERR ;OUT ON ERROR
- LDA CCMND+20H ;GET B-STATUS
- ANI 02H ;IS DISK WRITE-PROTECTED?
- MVI A,6 ;ASSUME SO, ERROR CODE 6
- STA ERFLAG
- JNZ WPERR ;WRITE ALWAYS FAILS IF SO
- LHLD HSTADR ;GET ADDRESS TO WRITE FROM
- MVI B,31 ;ASSUME DOUBLE DENSITY
- MVI E,2
- LDA NSCNT ;CHECK
- MOV C,A ;SAVE COUNT FOR LATER
- ORA A
- JZ WRIT5 ;GO ON IF COUNTS RIGHT
- MVI B,15 ;CORRECT FOR SINGLE DENS
- DCR E
- ;
- WRIT5: LDA CCMND+16H ;INITIATE SECTOR WRITE
- ;
- WRIT10: LDA CCMND+15H ;KEEP MOTORS RUNNING, GET A-STAT
- ANI 08H ;MUST LOOP UNTIL 96 USEC WINDOW
- JNZ WRIT10 ; PAST, SO LOOP WHILE WI TRUE
- ;
- ; NOW WRITE THE 31 OR 15 BYTES OF LEADING ZEROES ON THE SECTOR
- ;
- WRIT15: LDA WDATA+00H ;WRITE A BYTE OF ZEROES
- NOP ;KILL TIME
- MVI D,WDATA SHR 8 ;KILL TIME BY LOADING D FOR LATER
- DCR B ;COUNT OFF A ZERO BYTE
- JNZ WRIT15 ;DO THEM ALL
- ;
- ; FOLLOW WITH ONE OR TWO SYNCH BYTES
- ;
- WRIT17: LDA WDATA+0FBH ;WRITE A SYNCH BYTE
- DCR E ;CHECK FOR 2ND NEEDED
- JNZ WRIT17 ;GO BACK IF SO
- ;
- ; NOW WRITE OUT 256 OR 512 BYTES. DO THIS TWO AT A
- ; TIME SO WE CAN USE A SINGLE PRECISION COUNTER. B IS
- ; ZERO FROM ABOVE TO INIT THE CRC BYTE.
- ;
- WRIT20: MOV A,M ;GET NEXT BYTE TO OUTPUT
- MOV E,A ; IN OUTPUT REG
- XRA B ;ADD INTO CHECKSUM
- RLC
- MOV B,A ;LEAVE CHECKSUM IN B
- LDAX D ;WRITE DATA BYTE TO DISK
- INX H ;BOP BUF PTR
- MOV A,M ;REPEAT FOR NEXT BYTE
- MOV E,A
- XRA B
- RLC
- MOV B,A
- LDAX D
- INX H
- DCR C ;COUNT OFF LAST PAIR OF BYTES
- JNZ WRIT20 ;GO BACK IF MORE TO WRITE
- MOV E,B ;IF NOT, TIME TO WRITE CHECKSUM
- INX B ;KILL TIME
- LDAX D ; THEN WRITE THE BYTE
- XRA A ;DONE, INDICATE NO ERROR
- STA ERFLAG
- RET ;RETURN TO CALLER
- ;
- WPERR: LXI H,WPEMSG ;WRITE PROTECT ERROR
- JMP DSKERR ;TELL OPERATOR ON WAY OUT
- ;
- ; GNSDEN IS CALLED BY N* I/O ROUTINES TO DETERMINE THE
- ; DENSITY OF THE CURRENT BLOCK BASED ON THE DENSITY OF
- ; THE ID BLOCK. THAT IS DETERMINED BY TAKING ADVANTAGE
- ; OF THE FACT THAT THE HOST DISK HAS NO TRANSLATE TABLE
- ; IF SINGLE DENSITY.
- ;
- GNSDEN: LXI H,D0DPH ;ASSUME A:
- LDA HSTDSK ;NOW CHECK
- ORA A
- JZ GNSDA ;GO ON IF SO
- LXI H,D1DPH ;B: IF NOT
- GNSDA: MOV A,M ;SEE IF GOT XLATE TABLE
- INX H
- ORA M ;IF NOT, SINGLE DENSITY
- MVI A,80H ;ASSUME SINGLE
- RZ ;DONE IF RIGHT
- XRA A ;CORRECT IF DOUBLE DENSITY
- RET
- ;
- ; DISK I/O ROUTINES FOR JADE DOUBLE D CONTROLLER
- ;
- ; JADE HOST WRITE FOR FLUSHING BIG SECTOR BUFFER.
- ; LIKE JADE HOST READ, THESE ROUTINES ARE CALLED BY
- ; SECTOR DEBLOCKING I/O ROUTINES TO HANDLE JADE DISKS
- ; WITH DATA SECTORS OF LARGER THAN 128 BYTES/SECTOR.
- ;
- JHWRIT: MVI B,DCWRS ;WRITE OP
- JMP JHOP
- ;
- ; JADE HOST READ FOR FILLING BIG SECTOR BUFFER
- ;
- JHREAD: MVI B,DCRDS ;READ OP
- ;
- JHOP: LDA HSTDSK ;SET UP DISK TO USE
- SUI 2 ;OFFSET FOR 2ND CTRLR
- STA BTDSK
- LDA HSTTRK ;THIS TRACK
- STA BTTRK
- LDA HSTSEC ;THIS SECTOR
- INR A ;ADJUST FOR 1-ORIGIN
- STA BTSEC
- MVI A,DCSIN ;SWITCH IN JADE MEM
- OUT DPORT
- MOV A,B ;SET READ OR WRITE
- STA BTCMD
- CALL DSKEXR ;DO THE OPERATION
- JZ DSKOK ;IF OK, GO THERE
- JMP DSKER ;IF ERROR, GO REPORT
- ;
- ; READ A JADE DISK SECTOR ROUTINE. LIKE JADE DISK
- ; WRITE, THIS ROUTINE IS CALLED TO DO A NORMAL, NON-
- ; DEBLOCKING SECTOR I/O TO A DISK WITH 128-BYTE SECTORS.
- ;
- JADERD: CALL JFLUSH ;FLUSH JADE BUF MAYBE
- RNZ ;OUT ON ERROR
- MVI A,DCSIN ;SWITCH DD INTO SYS
- OUT DPORT
- MVI A,DCRDS ;READ SECTOR COMMAND
- CALL DSKEX ;PERFORM OPERATION
- JNZ DSKER ;ERROR EXIT
- LHLD DMAADR ;LOAD USER BUF ADDRESS
- XCHG
- LHLD DADDR ;GET SECTOR BUF ADDR IN HL
- LXI B,SECSZ ;LOAD SECTOR SIZE
- MVI A,DCMB1 ;BUFFER IS IN BANK ONE
- OUT DPORT
- CALL BLOCK ;BLOCK MOVE ROUTINE
- JMP DSKOK ;NORMAL RETURN
- ;
- ; WRITE A JADE DISK SECTOR
- ;
- JADEWR: CALL JFLUSH ;FLUSH JADE BUF MAYBE
- RNZ ;OUT ON ERROR
- MVI A,DCMB1 ;SWITCH DD BANK ONE IN
- OUT DPORT
- LHLD DADDR ;LOAD BUFFER ADDR
- XCHG ;GET IT IN DE
- LHLD DMAADR ;LOAD USER BUF ADDRESS
- LXI B,SECSZ ;LOAD SECTOR SIZE
- CALL BLOCK ;BLOCK MOVE ROUTINE
- MVI A,DCMB0 ;DSKEX NEEDS BANK 0
- OUT DPORT ; SO SWITCH IT IN
- MVI A,DCWRS ;LOAD WRITE SEC COMMAND
- CALL DSKEX ;CALL DISK EXEC
- JNZ DSKER ;IF ERROR, JUMP, ELSE
- ; FALL INTO DSKOK
- ;
- ; JADE DISK READ/WRITE/FORMAT EXITS
- ;
- DSKOK: XRA A ;ZERO PSW
- JMP DSKOUT
- ;
- DSKER: PUSH PSW ;SAVE ERROR CODE
- LXI H,JIOMSG ;PT TO LEADER
- CALL MSGOT ;OUTPUT MESSAGE
- POP PSW
- CALL HXBOT ;FORMAT AND OUTPUT HEX CODE
- LDA BTTRK ;IT HAPPENED ON THIS TRK
- STA HSTTRK
- LDA BTSEC ; AND THIS SECTOR
- STA ERSEC
- LDA BTDSK ; WITH THIS DISK
- ADI 2 ;OFFSET FOR C:
- CALL JAERR ;CALL COMMON CODE TO DO REST
- ;
- FMTER: XRA A ;SIGNAL ERROR TO CALLER
- DCR A ; WITH NON-ZERO STATUS
- ;
- DSKOUT: PUSH PSW ;SAVE RETURN STATUS
- PUSH H ; AND OTHER REGS
- PUSH D
- LHLD DADDR ;PT TO DD MEM
- LXI D,DDCBT ;CALC DCM CMD BUF ADDR
- DAD D
- MVI A,DCMB0 ;CALL FOR BANK ZERO
- OUT DPORT
- MVI M,DCIDL ;MAKE SURE DCM STAYS IDLE
- MVI A,DCSOT ;SWITCH OUT DD MEM
- OUT DPORT
- POP D ;RESTORE REGS NOW
- POP H
- POP PSW ;GET RETURN PSW
- RET ;RET ZERO OR NON-ZERO
- ;
- ; JFLUSH IS CALLED BY NORMAL JADE SECTOR ROUTINES TO
- ; MAKE SURE THE JADE BUFFER IS NOT IN USE WHEN A
- ; NORMAL READ, WRITE, OR FORMAT OPERATION NEEDS
- ; THE BUFFER.
- ;
- JFLUSH: XRA A ;NO ERROR YET
- STA ERFLAG
- LDA HSTDSK ;IF N* DISK,
- CPI 2
- JC NOJFL ; NOT USING OUR BUFFER
- ;
- ; COME HERE FROM SELDSK TO CLEAR ALL PENDING HOST WRITES
- ;
- HFLUSH: LDA HSTWRT ;SEE IF BUFFER NEEDS FLUSH
- STA ERFLAG ;NO ERROR IF NOT
- ORA A
- CNZ WRITEHST ;FLUSH IF SO, IF JADE
- ; WILL USE BUFFER
- XRA A
- STA HSTACT ;TOSS READ CONTENTS
- STA UNACNT ;BUFFER LEAVING, NEED
- ; PRE-READ ON NEXT UNALLOC
- ;
- NOJFL: LDA ERFLAG ;SET UP ERROR STATUS
- ORA A
- RET
- ;
- ; FORMAT A JADE DISK TRACK ROUTINE
- ;
- FORMAT: LDA SEKDSK ;ONLY FORMAT JADE DISK
- CPI 2
- JC FMTER ;ERROR IF ANY OTHER
- CALL JFLUSH ;FLUSH JADE BUF MAYBE
- RNZ ;OUT ON ERROR
- MVI A,DCMB1 ;SWITCH DD BANK ONE
- OUT DPORT ; INTO SYS
- LXI B,FMTSZ ;FORMAT PROG SIZE
- LXI D,DDFBF ;CALC FORMAT BUF ADDR
- LHLD DADDR
- DAD D
- XCHG ;GET IT IN DE
- LHLD DMAADR ;FORMAT PROGRAM ADDR
- CALL BLOCK ;BLOCK MOVE ROUTINE
- MVI A,DCMB0 ;RESELECT DD BANK 0
- OUT DPORT
- MVI A,DCFMT ;LOAD FORMAT TRK CMND
- CALL DSKEX ;CALL DISK EXEC
- JMP DSKOK ;GO RETURN STATUS TO CALLER
- ;
- ; DOUBLE D EXECUTION SUBROUTINE
- ;
- DSKEX: STA BTCMD ;STORE DCM COMMAND
- LDA SEKDSK ;MAP DISK TO JADE DD #
- SUI 2
- STA BTDSK ; AND STORE JADE DISK #
- LDA SEKTRK ;SET TRACK #
- STA BTTRK
- LDA SEKSEC ; AND SECTOR #
- STA BTSEC
- ;
- ; HERE ON RETRY AFTER DISK NOT READY
- ;
- DSKEXR: LXI B,7 ;# BYTES TO MOVE
- LXI D,DDCBT ;CALC DCM COMMAND BUF ADDR
- LHLD DADDR
- DAD D
- XCHG ;GET IT IN DE
- LXI H,BTCMD ;BIOS COMMAND BLOCK
- CALL BLOCK ;PERFORM BLOCK MOVE
- MVI A,DCINT ;INTERRUPT DD
- OUT DPORT
- XCHG ;EXCHANGE SRC/DST
- DSKWT: IN DPORT ;READ DD STATUS
- ANI DSHLT ;TEST HALT* FLAG
- JNZ DSKWT ;WAIT UNTIL DD HALTED
- MVI A,DCSIN ;SWITCH DD INTO SYS
- OUT DPORT
- MOV A,M ;GET DD STATUS BYTE
- STAX D ;SAVE IN MEM
- STA ERFLAG ;SET ERFLAG FOR JHOP
- ANA A ;TEST FOR ERRORS
- RP ;RETURN TO CALLER IF DISK READY
- CALL NOTRDY ;IF NOT READY, REPORT
- JMP DSKEXR ;IF CAME BACK, RETRY
- ;
- ; BLOCK - BLOCK MOVE (Z80 LDIR REGISTER USAGE)
- ;
- BLOCK: MOV A,M ;GET BYTE
- STAX D ;STORE IT
- INX H ;BOP PTRS
- INX D
- DCX B ;COUNT OFF BYTE
- MOV A,B ;CHECK FOR DONE
- ORA C
- JNZ BLOCK ;GO BACK IF NOT
- RET
- ;
- ;
- ; HERE TO REPORT DISK NOT READY. TELL CONSOLE WHICH
- ; DISK IT WAS, THEN SOLICIT REPLY. IF CTRL-C, WARM
- ; BOOT TO A:, ELSE RETURN TO CALLER.
- ;
- NOTRDY: LDA SEKDSK ;STUFF DISK
- ADI 'A'
- ;
- ; ENTER HERE TO REPORT LINE PRINTER NOT READY
- ;
- PNTRDY: STA NRD ; INTO MSG
- LXI H,NRDMSG
- CALL MSGOT ;REPORT TO OPERATOR
- CALL BCNSIN ;GET REPLY
- SUI 3 ;IS ANSWER CTRL-C?
- RNZ ;RETURN TO CALLER IF NOT
- STA DEFDSK ;SELECT A: IF SO,
- ; THEN WARM BOOT IT
- ;
- ; WARM BOOT ENTRY. LOAD CCP/BDOS AND INITIALIZE
- ;
- WARM: DI ;NO PROCESSOR INTS DURING BOOT
- LDA DEFDSK ;GET CURRENT DEFAULT DISK
- MOV B,A ;SAVE IT
- ANI 0F0H ;GET USER #
- MOV C,A ;SAVE THAT
- MOV A,B
- ANI 00FH ;ISOLATE DISK #
- CPI NDRVS ;IS IT LEGAL?
- JC WRMOK ;GO ON IF SO
- XRA A ;BACK TO DRIVE ZERO IF NOT
- MOV C,A ;USER # PROB BAD TOO
- WRMOK: ORA C ;COMBINE WITH USER #
- STA DFIMG ;PUT TO BASE PAGE IMAGE
- LXI SP,HSTBUF+HSTSIZ ;SET SP TO SCRATCH RAM
- LXI H,CCP+3 ;CP/M WARM START ADDR
- PUSH H
- ;
- ; MERGE HERE FROM COLD BOOT
- ;
- CPMLD: LDA IOBYTE ;GET CURRENT IOBYTE
- STA IOIMG ; INTO BASE PAGE IMAGE
- LXI B,8 ;MOVE ZERO PAGE STUFF
- LXI D,0 ; DOWN TO ZERO
- LXI H,BSIMG
- CALL BLOCK
- LXI H,05959H ;FORCE HOME OF N* DRIVES
- SHLD NSTRK ; A, B
- MOV A,H ;MAKE SURE NEW DISK SELECTED
- STA CURDSK
- XRA A ;DRIVE ZERO VALUE
- STA HSTDSK
- STA HSTACT ;HOST BUFFER INACTIVE
- STA HSTWRT ;NO HOST WRITE PENDING
- STA UNACNT ;CLEAR UNALLOC COUNT
- LXI H,CCP ;CP/M CCP ADDRESS
- SHLD HSTADR ;READ INTO THERE
- INR A ;GET 1 IN ACC
- STA HSTTRK ;READ FROM TRACK ONE
- CALL WSETUP ;KICK MOTORS AND SEEK TRK
- XRA A ;SECTOR ZERO
- ;
- ; READ ALL TEN SECTORS FROM TRACK ONE THEN ONE SECTOR
- ; FROM TRACK ZERO (SECTOR 3).
- ;
- WREAD: STA HSTSEC ;SET CURRENT SECTOR TO READ
- CALL WRMRD ;READ SECTOR AND CHK STATUS
- LXI D,HSTSIZ ;SECTOR SIZE
- LHLD HSTADR ;CALC NEW ADDRESS
- DAD D
- SHLD HSTADR
- LDA HSTSEC ;BOP SECTOR #
- INR A
- CPI 10 ;OFF END OF TRACK ONE?
- JNZ WREAD ;GO GET NEXT SECTOR IF NOT
- XRA A ;TO TRACK ZERO,
- STA HSTTRK
- CALL WSETUP
- MVI A,3 ; SECTOR 3 IF SO
- STA HSTSEC
- CALL WRMRD ;READ THE LAST SECTOR
- LXI H,HSTBUF ;NOW READ AND WRITE
- SHLD HSTADR ; USING DEBLOCK BUFFER
- LDA DFIMG ;RETRIEVE LAST USED DRIVE
- MOV C,A ; FOR BDOS
- RET ; THEN GO TO CP/M
- ;
- WSETUP: CALL SETUP ;KICK MOTORS AND SEEK TRK
- JMP WECHK
- ;
- WRMRD: CALL READNS ;READ HOST SECTOR
- WECHK: LDA ERFLAG ;CHECK FOR ERROR
- ORA A
- RZ ;RETURN IF NONE
- LXI H,MSGLE ;GET ERROR MESSAGE
- CALL MSGOT ;TYPE IT
- HLT ; THEN GIVE UP
- ;
- ; MSGOT DISPLAYS STRING OF CHARS PT'ED AT BY HL ON
- ; CONSOLE, UNTIL CHAR WITH PARITY BIT SET IS OUTPUT.
- ;
- MSGOT: PUSH PSW ;SAVE CALLER FLAGS
- MSGL: MOV C,M ;LOAD CHAR
- PUSH H ;SAVE HL
- CALL BCNSOT ;OUTPUT CHAR IN C
- POP H ;RESTORE HL
- MOV A,M ;GET CHAR BACK TO LOOK AT
- INX H ;LEAVE PTR ON NEXT CHAR
- RAL ;IS HIGH BIT ON?
- JNC MSGL ;GO BACK IF NOT
- POP PSW ; ELSE RESTORE FLAGS
- RET ; AND RETURN
- ;
- ; DISK ERROR MESSAGES
- ;
- WPEMSG: DB 'Protec','t'+80H
- SDEMSG: DB 'Densit','y'+80H
- RERMSG: DB 'CR','C'+80H
- SYEMSG: DB 'Syn','c'+80H
- NIPMSG: DB 'Inde','x'+80H
- SNFMSG: DB 'Secto','r'+80H
- JIOMSG: DB CR,LF,'Jade DD',' '+80H
- ;
- ERRMSG: DB ' err '
- ASCDSK: DB ' : trk',' '+80H
- SECMSG: DB ' sec',' '+80H
- NRDMSG: DB CR,LF,'Disk '
- NRD: DB ' : not ready',' '+80H
- CRLF: DB CR,LF+80H
- ;
- MSGLE: DB CR,LF,'Boot er','r'+80H
- ;
- ; JADE ID LABEL DEFINITIONS
- ;
- JADEID: DB 'Jade DD ' ;ID LABEL
- IDSZE EQU $-JADEID ;LABEL SIZE
- ;
- ; NORTH STAR DD SECTOR TRANSLATE TABLE. AFTER
- ; DEBLOCKING, WORKS OUT TO SKEW FACTOR OF 5.
- ;
- TRAN5D: DB 01,02,03,04
- DB 21,22,23,24
- DB 05,06,07,08
- DB 25,26,27,28
- DB 09,10,11,12
- DB 29,30,31,32
- DB 13,14,15,16
- DB 33,34,35,36
- DB 17,18,19,20
- DB 37,38,39,40
- ;
- ; NORTH STAR DD DISK PARAMETER BLOCK. THIS IS OUR
- ; NORMAL DPB, AND IS COMPATIBLE WITH LIFEBOAT CP/M 1.4
- ; DISKS.
- ;
- DPBNSD: DW 40 ;SECTORS PER TRACK
- DB 3 ;BLOCK SHIFT FACTOR
- DB 07H ;BLOCK MASK
- DB 0 ;EXM MASK
- DW 165-1 ;DISK SIZE - 1
- DW 63 ;DIRECTORY MAX
- DB 11000000B ;ALLOC 0
- DB 0 ;ALLOC 1
- DW 16 ;CHECK SIZE
- DW 2 ;TRACK OFFSET
- ;
- ; THE NEXT BYTE IS ONE WE HAVE ADDED SPECIFICALLY
- ; FOR THIS BIOS TO CONVENIENCE OUR DEBLOCKING ROUTINES.
- ; IT IS A SECTOR SHIFT MASK, AND EACH DISK PARAMETER
- ; BLOCK HAS ONE IN THIS POSITION. THE ALLOWABLE VALUES
- ; ARE AS FOLLOWS:
- ;
- ; 1000B ;1024 BYTES/SECTOR
- ; 0100B ; 512 BYTES/SECTOR
- ; 0010B ; 256 BYTES/SECTOR
- ; 0000B ; 128 BYTES/SECTOR
- ;
- ; FOR THE NORTH STAR DD DISKS, 512 IS HARD-CODED. FOR
- ; THE NORTH STAR SD DISKS, 256 IS HARD-CODED. FOR
- ; JADE DISKS, THE VALUE IS READ IN FROM THE ID SECTOR.
- ; IF THE ID LOOKS BOGUS, THE STANDARD 8" DPB IS USED,
- ; WHICH HAS 128 CANNED-IN.
- ;
- DB 0100B ;512 BYTES/SECTOR
- ;
- ; NORTH STAR DD DISK PARAMETER BLOCK, SET UP
- ; FOR COMPATIBILITY WITH LIFEBOAT CP/M 2.X
- ; FORMAT DISKS.
- ;
- DPBNSL: DW 40 ;SECTORS PER TRACK
- DB 4 ;BLOCK SHIFT FACTOR
- DB 0FH ;BLOCK MASK
- DB 1 ;EXM MASK
- DW 82-1 ;DISK SIZE - 1
- DW 63 ;DIRECTORY MAX
- DB 10000000B ;ALLOC 0
- DB 0 ;ALLOC 1
- DW 16 ;CHECK SIZE
- DW 2 ;TRACK OFFSET
- DB 0100B ;512 BYTES/SECTOR
- ;
- ; THERE IS NO NORTH STAR SINGLE DENSITY TRANSLATE
- ; TABLE.
- ;
- TRAN5S: EQU 0 ;TELL SECTRN TO JUST ADD 1
- ;
- ; NORTH STAR SD DISK PARAMETER BLOCK
- ;
- DPBNSS: DW 20 ;SECTORS PER TRACK
- DB 3 ;BLOCK SHIFT FACTOR
- DB 07H ;BLOCK MASK
- DB 0 ;EXM MASK
- DW 80-1 ;DISK SIZE - 1
- DW 63 ;DIRECTORY MAX
- DB 11000000B ;ALLOC 0
- DB 0 ;ALLOC 1
- DW 16 ;CHECK SIZE
- DW 3 ;TRACK OFFSET
- DB 0010B ;256 BYTES/SECTOR
- ;
- ; STANDARD 8" SECTOR TRANSLATE TABLE
- ;
- TRAN8: DB 1,7,13,19,25,5,11,17,23
- DB 3,9,15,21,2,8,14,20,26
- DB 6,12,18,24,4,10,16,22
- ;
- ; STANDARD 8" DISK PARAMETER BLOCK
- ;
- DPB8: DW 26
- DB 3
- DB 7
- DB 0
- DW 242
- DW 63
- DB 0C0H
- DB 0
- DW 16
- DW 2
- ;
- DB 0000B ;128 BYTES/SECTOR
- ;
- ; 1024 BYTES/SECTOR TRANSLATE TABLE
- ;
- TRN124: DB 1,2,3,4,5,6,7,8
- DB 25,26,27,28,29,30,31,32
- DB 49,50,51,52,53,54,55,56
- DB 9,10,11,12,13,14,15,16
- DB 33,34,35,36,37,38,39,40
- DB 57,58,59,60,61,62,63,64
- DB 17,18,19,20,21,22,23,24
- DB 41,42,43,44,45,46,47,48
- ;
- ; DRIVE PARAMETER HEADER AREA
- ;
- ; DRIVES A: AND B: ARE NORTH STAR 5"
- ;
- D0DPH: DW 0 ;SECTOR TRAN TBL SET BY SELDSK
- DW 0 ;SCRATCH
- DW 0 ;SCRATCH
- DW 0 ;SCRATCH
- DW DIRBF ;DIRECTORY BUFFER
- DW 0 ;DRIVE PARAM BLK SET BY SELDSK
- DW D0CHK ;DRIVE CHANGE BLK
- DW D0ALL ;DRIVE ALLOCATION
- ;
- D1DPH: DW 0,0,0,0,DIRBF,0,D1CHK,D1ALL
- ;
- ; DRIVES C: AND D: ARE JADE 8" SHUGART
- ;
- D2DPH: DW 0,0,0,0,DIRBF,D2DPB,D2CHK,D2ALL
- ;
- D3DPH: DW 0,0,0,0,DIRBF,D3DPB,D3CHK,D3ALL
- ;
- ; ZERO PAGE IMAGE -- BLOCK MOVED TO BASE PAGE
- ;
- BSIMG: JMP BIOS+03H ;WARM BOOT VECTOR
- IOIMG: DS 1 ;IOBYTE SET BY CPMLD
- DFIMG: DB 0 ;DEFAULT DISK -- ZERO
- ; AFTER COLD BOOT
- JMP BDOS+06H ;BDOS CALL VECTOR
- ;
- ; BIOS VARIABLE STORAGE
- ;
- SEKDSK: DB 0 ;DRIVE NUMBER
- SEKTRK: DS 1 ;TRACK NUMBER (MUST IMM FOLLOW
- ; SEKDSK FOR LHLD)
- SEKSEC: DS 1 ;SECTOR NUMBER
- SEKHST: DS 1 ;SEEK SHR SECSHF
- HSTACT: DS 1 ;HOST ACTIVE FLAG
- HSTWRT: DS 1 ;HOST WRITTEN FLAG
- DTPTR: DW 0 ;DRIVE TABLE PTR
- LOGFLG: DB 0 ;NON-ZERO IF SELDSK
- ; LOGGED ON JADE DISK
- ;
- UNACNT: DS 1 ;UNALLOC REC CNT
- UNADSK: DS 1 ;LAST UNALLOC DISK
- UNATRK: DS 1 ;LAST UNALLOC TRACK (MUST IMM
- ; FOLLOW UNADSK FOR LHLD)
- UNASEC: DS 1 ;LAST UNALLOC SECTOR
- ;
- ; DEBLOCKING INFO ABOUT THE CURRENTLY-SELECTED DISK
- ;
- UNAVAL: DS 1 ;# UNALLOC RECS/GROUP
- CPMSPT: DS 1 ;# CP/M SECTORS/TRACK
- SECSHF: DS 1 ;SECTOR SHIFT COUNT,
- ; LOG2 (# CP/M SECTORS/HOST BLOCK)
- SECMSK: DS 1 ;SECTOR MASK, # CP/M
- ; SECTORS/HOST BLOCK - 1
- ;
- ; JADE DOUBLE D DCM PARAMETER BLOCK. ENTRIES
- ; MUST BE IN THIS ORDER TO MATCH DCM ROUTINE
- ; BLOCK.
- ;
- BTCMD: DB 0 ;DCM COMMAND
- BTDSK: DS 1 ;JADE DD DRIVE #
- BTTRK: DS 1 ;TRACK NUMBER
- BTSEC: DS 1 ;SECTOR NUMBER
- BTSP0: DB 0 ;SPARE BYTE 0
- BTCHR: DB 0 ;LIST CHAR
- BTMOD: DB 0 ;MODE CONTROLS
- BTSTS: DB 0 ;COMMAND STATUS
- BTLAD: DW 0 ;LOAD ADDRESS
- BTLNG: DW 0 ;LOAD LENGTH
- ;
- ; JADE-ONLY VARIABLES
- ;
- DADDR: DW 0 ;DD MEMORY WINDOW ADDRESS
- ;
- ; RESERVE DRIVE PARAMETER BLOCKS FOR JADE DRIVES
- ;
- DPBSZ EQU 16 ;SIZE IS 16 BYTES
- D2DPB: DS DPBSZ ;RESERVE 16 BYTES/DISK C-D
- ;
- ; EVERYTHING FROM THIS POINT FOR THE NEXT
- ; 512 BYTES IS READ INTO MEMORY BY THE NORTH
- ; STAR BOOT PROM. OUR GOAL HERE IS TO GET
- ; A REASONABLE AMOUNT OF NORMAL BIOS CODE IN,
- ; BUT AT THE SAME TIME WE NEED THE PORTIONS
- ; THAT CAN READ THE DISK.
- ;
- ; IF THIS SECTION OVERLAYS PREVIOUS BIOS CODE
- ; OR DATA SPACE, THE PRECEDING BIOS MUST BE
- ; TRIMMED DOWN.
- ;
- PRVCHK EQU $ ;** MUST NOT EXCEED BOOTA **
- ;
- ORG BIOS+(HSTSIZ*5) ;ORG TO COLD BOOT
- ;
- BOOTA: DB BOOTA SHR 8 ;TELL PROM LOAD ADDR
- ;
- ; THE NEXT NINE LOCATIONS ARE SKIPPED OVER
- ; BY THE BOOT PROM, WHICH READS THIS SECTOR
- ; THEN JUMPS TO BOOTA+0AH, SO PUT USEFUL VARIABLES
- ; HERE. NOTE THAT ALL VARIABLES IN THIS SECTOR
- ; WITH GENNED-IN VALUES ARE SET UP FOR COLD
- ; BOOT LOADING OF BIOS.
- ;
- HSTADR: DW BIOS ;READ BIOS INTO HERE TO START,
- ; BUT NORMALLY PTS TO HSTBUF
- HSTDSK: DB 0 ;HOST DISK NUMBER
- HSTTRK: DB 0 ;HOST TRACK NUMBER (MUST IMM
- ; FOLLOW HSTDSK FOR LHLD)
- HSTSEC: DB 5 ;HOST SECTOR NUMBER
- ERFLAG: DB 0 ;ERROR REPORTING
- CURDSK: DB 059H ;CURRENT ACTIVE DISK,
- ; GENNED-IN FORCE SELECT
- COLDB: DB 1 ;COLD BOOT WHEN NON-ZERO
- ERSEC: DS 1 ;SECTOR IN ERROR
- ;
- ; THIS IS THE SECTION OF THE COLD BOOT THAT
- ; READS IN THE REST OF BIOS. ON MORE CONVENTIONAL
- ; CP/M SYSTEMS, THIS WOULD BE THE BLOCK ZERO
- ; BOOT. READ BIOS INTO MEMORY, THEN JUMP TO
- ; IT TO FINISH COLD BOOTING.
- ;
- D3DPB: EQU $ ;*** OVERLAY N* COLD BOOT ***
- ;
- BOOT: DI ;ALLOW NO PROCESSOR INTERRUPTS
- LXI SP,HSTBUF+HSTSIZ ;SET SP TO SCRATCH RAM
- CALL SETUP ;GIVE MOTORS EXTRA KICK
- ; AND SEEK TRK 0
- ;
- BOOTL: CALL READNS ;READ NEXT SECTOR OF BIOS
- ;WITH COLDB NON-ZERO, NO
- ; RETURN IF I/O ERROR
- LXI H,HSTSEC ;IF OK, BOP SEC NUM
- INR M
- LHLD HSTADR ; AND ADVANCE READ ADDR
- LXI D,HSTSIZ
- DAD D
- SHLD HSTADR
- MVI A,BOOTA SHR 8 ;SEE IF READ ENUFF
- CMP H
- JNZ BOOTL ;LOOP IF NOT
- JMP INIT ;GO START BIOS IF SO
- ;
- ; REMAINING NEEDED VARIABLES
- ;
- RTCNT: DS 1 ;ERROR RETRY COUNTER
- NSDENS: DS 1 ;DENSITY OF LAST NS DISK BLOCK
- ; READ, SD=128, DD=0
- NSCNT: DB 00H ;COUNT AND DENSITY FLAG, SET
- ; BY WRITEHST TO MATCH ID SECTOR
- ;
- ; NORTH STAR CURRENT TRACK TABLE
- ;
- NSTRK: DB 059H ;NO CURRENT TRACK YET
- DB 059H ;EACH ENTRY CONTAINS
- ; DB 059H ; THE LAST TRACK POSITION
- ; DB 059H ; FOR THE UNIT 1-4
- ;
- ; OTHER VARIABLES HERE BECAUSE THERE IS SPACE, CAN
- ; BE MOVED IF NECESSARY
- ;
- RSFLAG: DS 1 ;READ SECTOR FLAG
- READOP: DS 1 ;1 IF READ OPERATION
- WRTYPE: DS 1 ;WRITE OPERATION TYPE
- DMAADR: DS 2 ;LAST DMA ADDRESS
- ENTPSW: DW 0 ;ENTRY PSW AT DISK READ/WRITE
- ;
- ; READHST PERFORMS THE PHYSICAL READ FROM THE
- ; NORTH STAR DISK. ON ENTRY, DRIVE IS IN HSTDSK,
- ; TRACK IS IN HSTTRK, SECTOR IS IN HSTSEC. ON
- ; EXIT, ERROR FLAG IS IN ERFLAG (ZERO IF NONE).
- ;
- ; *** INTERRUPTS MUST BE DISABLED HERE ***
- ;
- READHST:
- MVI A,10 ;RETRY COUNT ON ERROR
- STA RTCNT
- ;
- READRT: CALL SETUP ;SELECT DRIVE AND
- ; SEEK TO TRACK
- LDA ERFLAG ;CHECK FOR ERRORS
- ORA A
- RNZ ;INDEX PULSE NOT FOUND IS FATAL
- ;
- ; HERE TO READ NORTH STAR WITHOUT TRACK SEEK FOR SPEED
- ;
- READNS: CALL POSEC ;POSITION TO OUR SECTOR
- JNZ SNFERR ;ERROR IF NOT FOUND
- MVI B,08CH ;COUNT FOR SYNC CHAR LOOP
- LXI D,CCMND+40H ;SET UP READ DATA REGS
- ;
- ; WAIT FOR RE SO WE CAN DO SECTOR READ, AND TEST
- ; THE DOUBLE DENSITY BIT.
- ;
- WAITRE: LDA CCMND+10H ;GET A-STATUS
- ANI 04H ;CHECK RE
- JZ WAITRE ;LOOP UNTIL RE TRUE
- XTHL ;KILL TIME TO GET INTO ZEROES
- XTHL
- XTHL
- XTHL
- XTHL
- XTHL
- XTHL
- XTHL
- LDA CCMND+10H ;GET A-STATUS AGAIN
- ANI 20H ;ARE WE READING DOUBLE DENS?
- RAL ;MAKE 80H IF NOT, ZERO IF SO
- RAL
- XRI 80H
- STA NSDENS ;SAVE DENSITY FOR CALLER
- ;
- ; NOW WAIT FOR SYNC CHAR DETECTED. ERROR IF WE HAVE TO
- ; WAIT TOO LONG.
- ;
- READ5: LDA CCMND+10H ;WAIT FOR SYNC CHAR DETECTED
- RRC ;CHECK BIT
- JC READ15 ;OUT IF GOT IT
- DCR B ;COUNT DOWN IF NOT
- JNZ READ5 ;GO BACK IF STILL OK
- MVI A,1 ;SYNC ERROR IF WAITED TOO LONG
- LXI H,SYEMSG ;SYNC ERROR MESSAGE
- ;
- RERR: STA ERFLAG ;STORE ERROR CODE
- LDA RTCNT ;COUNT OFF A RETRY
- DCR A
- STA RTCNT
- JNZ READRT ;IF COUNT LEFT, GO RETRY
- ;
- ; READ ERROR RETRIES FAILED. FLAG ERROR.
- ;
- JMP DSKERR ;TELL OPERATOR OF ERROR THEN OUT
- ;
- SNFERR: STA ERFLAG ;SET ERROR FLAG
- LXI H,SNFMSG
- JMP DSKERR ;REPORT ERROR ON WAY OUT
- ;
- ; READ THE DATA INTO HSTBUF
- ;
- READ15: LHLD HSTADR ;READ INTO HERE
- MVI B,0 ;INIT CHECKSUM BYTE
- LDA NSDENS ;GET # BYTES TO READ
- MOV C,A ;PUT READ COUNT IN C-REG
- ;
- READ20: LDAX D ;READ NEXT DATA BYTE
- MOV M,A ; AND PUT IT IN BUFFER
- XRA B ;ADD TO CHECKSUM
- RLC
- MOV B,A
- INX H ;BOP BUFFER PTR
- NOP ;KILL TIME
- LDAX D ;GET NEXT BYTE
- MOV M,A
- XRA B
- RLC
- MOV B,A
- INX H
- DCR C ;COUNT OFF LAST PAIR
- JNZ READ20 ;GO BACK IF MORE TO DO
- LDAX D ; ELSE READ CRC BYTE
- XRA B ; AND CHECK IT AGAINST OURS
- STA ERFLAG ;IF OK, ZERO EFLAG
- RZ ; AND RETURN TO CALLER
- MVI A,2 ; ELSE FLAG CHECKSUM ERROR
- LXI H,RERMSG ;MESSAGE IF NEEDED
- JMP RERR ;GO MAYBE RETRY
- ;
- ; SETUP SELECTS THE UNIT CORRESPONDING TO HSTDSK,
- ; THEN SEEKS TO THE TRACK SPECIFIED BY HSTTRK.
- ; WRITE PRECOMPENSATION IS SET IF REQUIRED AS
- ; WELL. ON ERROR, ERFLAG CONTAINS A NON-ZERO
- ; VALUE ON RETURN. ONLY UNITS 1 AND 2 ARE SUPPORTED
- ; TO SAVE SPACE.
- ;
- SETUP: LDA NSCNT ;GET DENSITY FLAG
- XRI 80H ;INVERT TO SET DD
- MOV C,A ;SAVE MASK
- LDA HSTDSK ;WANT THIS DISK
- INR A ;REMAP TO CONTROLLER MASK
- ; CPI 03H ;IF UNIT 1 OR 2,
- ; JC SET0 ; GOT CORRECT MASK
- ; RAL ;IF 3 OR 4, MUST MAP
- ; ANI 0CH ; TO 4 OR 8 RESPECTIVELY
- ;SET0:
- ORA C ;OR IN DENSITY MASK
- MOV C,A ;SAVE IN REG C
- CALL WAIT1S ;WAIT A SECTOR TIME, GET A-STAT
- ANI 10H ;ARE MOTORS ALREADY ON?
- LDA CCMND+15H ;GIVE THEM EXTRA KICK ANYWAY
- JNZ SET5 ;BRANCH IF SO
- MVI D,17H ;WAIT FOR MOTORS TO
- CALL SCWAIT ; COME UP TO SPEED IF NOT
- JMP SET10 ; THEN GO SELECT DRIVE
- ;
- SET5: LDA CURDSK ;IS THIS THE CURRENT DISK?
- CMP C
- JZ SET20 ;GO SEEK TO TRACK IF SO
- ;
- ; MUST SELECT NEW DISK
- ;
- SET10: MOV A,C
- STA CURDSK ;NEW CURRENT DISK
- MVI B,CORDER SHR 8 ;SET UP FOR SELECT
- LDAX B ; AND DO IT
- MVI D,2 ;WAIT TWO SECTOR TIMES
- CALL SCWAIT ; BEFORE LOOKING FOR INDEX
- MVI B,12 ;DON'T LOOK TOO LONG
- ;
- SET15: CALL WAIT1S ;WAIT A SECTOR TIME, GET A-STAT
- ANI 40H ;INDEX HOLE SEEN?
- JNZ SET20 ;CAN GO SEEK NOW IF SO
- DCR B ;COUNT DOWN IF NOT
- JNZ SET15 ; AND MAYBE GO LOOK AGAIN
- ;
- ; INDEX HOLE NOT FOUND. DISK IS PROBABLY NOT LOADED.
- ;
- MVI A,4 ;NO INDEX PULSE
- STA ERFLAG
- LXI H,NIPMSG
- CALL DSKERR ;TELL OPERATOR
- CALL NOTRDY ; AND CLAIM DISK NOT READY
- MVI A,059H ;FORCE RESELECT OF DISK
- STA CURDSK
- JMP SETUP ;TRY TO GET DISK AGAIN
- ;
- ; SEEK TO TRACK SPECIFIED BY HSTTRK NOW, AND SET
- ; WRITE PRECOMPENSATION IF APPROPRIATE.
- ;
- SET20: LDA HSTDSK ;GET NSTRK INDEX
- MOV C,A
- MVI B,0
- LXI H,NSTRK ;PT AT TABLE
- DAD B ; THEN AT CORRECT ENTRY
- MOV A,M ;GET CURRENT TRACK
- PUSH H ;SAVE NSTRK PTR
- XRI 59H ;DISK EVER ACCESSED?
- CZ SEEK ;IF NOT, HOME DRIVE
- POP H ;RESTORE NSTRK PTR
- LDA HSTTRK ;SEEK TO THIS TRACK
- PUSH PSW ;SAVE OVER CALL
- CALL SEEK ;DO FINAL SEEK
- POP PSW ;GET HSTTRK BACK
- CPI 14H+1 ;ARE WE BEYOND TRACK 14H?
- JC SET25 ;GO ON IF NOT
- LDA NSCNT ;SEE IF DD OR SD
- ORA A
- JNZ SET25 ;NO PRECOMP IF SD
- LDA CURDSK ;IF SO, GET CURRENT MASK
- ORI 20H ; AND SET PRECOMP BIT
- MVI H,CORDER SHR 8
- MOV L,A
- MOV A,M ;SET BIT IN CONTROLLER
- ;
- SET25: XRA A
- STA ERFLAG ;NO ERRORS
- RET
- ;
- ; POSEC IS CALLED TO POSITION TO HSTSEC WITHIN
- ; THE CURRENT TRACK. ERROR IS RETURNED BY NON-ZERO
- ; IF WE CAN'T FIND THE SECTOR AFTER 30 TRIES.
- ;
- POSEC: LDA HSTSEC ;GET TARGET SECTOR
- MOV C,A ;IN C
- STA ERSEC ;SET UP FOR POSSIBLE ERROR
- MVI B,30 ;LOOK AT THIS MANY SECTORS
- ;
- POSC5: CALL WAIT1S ;WAIT FOR NEXT SECTOR
- LDA CCMND+35H ;KICK MOTORS AND GET SECNUM
- ANI 0FH ;STRIP NON-SECTOR BITS
- SUB C ;IS THIS THE TARGET SECTOR?
- RZ ;OUT IF GOT IT
- DCR B ;COUNT OFF IF DIDN'T
- JNZ POSC5 ;GO BACK IF NOT GIVING UP
- INR B ;SET NON-ZERO IF NOT FOUND
- RET
- ;
- ; SEEK TO TRACK SPECIFIED BY ACC. CURRENT PTR INTO
- ; NSTRK TABLE IS GIVEN BY HL. IF TRACK SPECIFIED IS
- ; ZERO, SEEK WILL BE DONE UNTIL TRACK ZERO FLAG IS
- ; SEEN, REGARDLESS OF CURRENT POSITION, UNLESS
- ; WE ARE ALREADY THERE, SINCE NO SEEK IS DONE
- ; IF ALREADY AT THE DESIRED TRACK.
- ;
- SEEK: MOV B,A ;SAVE TARGET TRK #
- SUB M ;SEE HOW FAR AWAY WE ARE
- ; FROM TARGET TRACK
- MOV M,B ; BUT ALWAYS SET NEW TRACK
- RZ ;IF THERE, DONE
- LXI H,CORDER+30H ;ASSUME STEPPING IN
- MOV C,A ;SAVE STEP COUNT
- JP STEPIN ;BRANCH IF RIGHT
- CMA ;IF WRONG, NEGATE COUNT
- INR A
- MOV C,A ; THEN SAVE THAT
- LDA CCMND+20H ;GET B-STATUS
- ANI 01H ;ARE WE ON TRACK ZERO?
- RNZ ;MUST BE DONE IF SO
- MVI L,10H ;IF NOT, STEPPING OUT
- ;
- STEPIN: LDA CURDSK ;GET CURRENT UNIT MASK
- ORA L ;FORM FINAL CORDER VALUE
- MOV L,A
- MOV D,M ;SET THE STEP FLIP-FLOP
- ORI 10H
- MOV L,A
- MOV D,M ;SET IT AGAIN FOR SOME REASON
- XRI 10H
- MOV L,A
- MOV D,M ;NOW RESET THE STEP FLIP-FLOP
- ;
- ; WAIT WHILE HEAD STARTS MOVING
- ;
- MVI A,14H
- STEPW1: MVI D,38H
- STEPW2: DCR D ;KILL TIME
- JNZ STEPW2
- DCR A
- JNZ STEPW1
- ;
- ; THE STEP RATE DETERMINES HOW LONG TO WAIT. ONE SECTOR
- ; TIME IS 20 MSEC. A SLOW SHUGART SA400 MAY REQUIRE 40
- ; MSEC, OR TWO SECTOR TIMES. MOST TYPICAL SA400'S WILL
- ; WORK WITH 20 MSEC, SO THAT'S WHAT WE'LL USE HERE. WE
- ; WILL CALL SCWAIT INSTEAD OF WAIT1S IN CASE WE NEED TO
- ; PATCH THIS VALUE.
- ;
- MVI D,1 ;NOW WAIT 20 MSEC
- ; MVI D,2 ;NOW WAIT 40 MSEC
- CALL SCWAIT
- LDA CCMND+25H ;GET B-STATUS AND KICK MOTORS
- ANI 01H ;ARE WE AT TRACK ZERO?
- JNZ WAIT1S ;DONE STEPPING IF SO
- DCR C ; ELSE COUNT OFF LAST TRACK
- JNZ STEPIN ;GO BACK IF MORE TO DO
- CALL WAIT1S ;WAIT ONE MORE SECTOR TIME
- ; TO MAKE SURE DONE STEPPING
- INR B ;SEEK TO TRACK ZERO?
- DCR B
- RNZ ;DONE IF NOT
- LDA CCMND+25H ;MUST HAVE TRK ZERO FLAG IF SO
- ANI 01H
- RNZ ;OK IF SO
- JMP STEPIN ;GO STEP MORE IF NOT
- ;
- ; SECTOR WAIT. ON ENTRY, # SECTORS TO WAIT IS IN D.
- ; ON EXIT, D=0 AND ACC=A-STATUS. CALL WAIT1S TO WAIT
- ; ONE SECTOR TIME.
- ;
- WAIT1S: MVI D,1 ;WAIT ONE SECTOR TIME
- ;
- SCWAIT: LDA CCMND+11H ;RESET SECTOR FLAG
- SCW5: LDA CCMND+10H ;GET A-STATUS
- ORA A ;CHECK SECTOR FLAG
- JP SCW5 ;WAIT FOR IT IF NOT UP
- LDA CCMND+11H ; ELSE RESET SECTOR FLAG
- DCR D ;COUNT DOWN WAIT COUNTER
- JNZ SCW5 ;GO BACK IF MORE TO DO
- RET ; ELSE RETURN A-STATUS IN ACC
- ;
- ; DISK ERRORS REPORTED HERE, BECAUSE STUPID BDOS GIVES
- ; NO USEFUL INFORMATION.
- ;
- DSKERR: LDA COLDB ;IN COLD BOOT?
- ORA A ;IF SO, CNSOT NOT IN MEM YET
- JNZ NSROM ;BACK TO N* BOOT ROM ON SAME
- PUSH H ;SAVE BODY ADDRESS
- LXI H,CRLF ;EJECT LINE
- CALL MSGOT
- POP H
- CALL MSGOT ;REPORT BODY
- LDA HSTDSK ;THIS DISK
- ;
- ; ENTER HERE AFTER JADE DD I/O ERROR
- ;
- JAERR: ADI 'A'
- STA ASCDSK
- LXI H,ERRMSG
- CALL MSGOT
- LDA HSTTRK ;THIS TRACK
- CALL HXBOT
- LXI H,SECMSG
- CALL MSGOT
- LDA ERSEC ;THIS SECTOR
- JMP HXBOT ;OFF TO HXBOT TO FINISH
- ;
- EBOOT EQU $-1 ;LAST USED COLD BOOT BYTE
- ;
- ;
- ; NORTH STAR HOST SECTOR BUFFER
- ;
- HSTBUF: DS HSTSIZ ;HOST BUFFER
- ;
- LAST EQU $-1 ;LAST USED BYTE IN MEM
- ;
- END
-