home *** CD-ROM | disk | FTP | other *** search
- TITLE 'SDNBIOS - N* SD CP/M 2.2 BIOS OF 06/19/81'
- ;
- ; THIS BIOS CONTAINS ROUTINES TO SUPPORT THE
- ; FOLLOWING HARDWARE:
- ;
- ; DISK: NORTH STAR MDC-A4 SINGLE DENSITY 5.25"
- ; FLOPPY DISK UNITS 1 AND 2 AS CP/M DRIVES
- ; A: AND B:
- ;
- ; CONSOLE AND LIST ROUTINES ARE LOCATED IN A
- ; SEPARATE MODULE LOADED BY THE BOOTSTRAP ROUTINE
- ; INTO HIGH MEMORY AT ADDRESS USER. THAT VALUE IS
- ; ASSUMED TO BE ON A 1K BOUNDARY, AND THE USER
- ; ROUTINES ARE RESTRICTED TO 2 PAGES (SEE BOOTSTRAP
- ; INFO BELOW), WITH 2 PAGES OF SCRATCH ABOVE AVAILABLE
- ; FOR USE. THIS BIOS USES THE 1ST OF THOSE SCRATCH
- ; PAGES FOR BDOS BUFFERS AND ITS OWN VARIABLES.
- ;
- ; SINCE THIS BIOS IS SO LARGE, MOVCPM SHOULD BE
- ; RUN FOR TWO LESS THAN THE DESIRED SYSTEM SIZE
- ; IN K, I.E. SPECIFY 18 FOR A 20K SYSTEM.
- ;
- ; *** IMPORTANT BOOTSTRAP INFORMATION ***
- ;
- ; OUR WARM BOOT EXPECTS CCP TO RESIDE ON TRACK
- ; 1, SECTORS 0-7 INCLUSIVE. BDOS MUST BE ON TRACK
- ; 1, SECTORS 8-9, THEN CONTINUE ON TRACK 2, SECTORS
- ; 0-9, THEN FINISH ON TRACK 0, SECTORS 1 AND 9.
- ;
- ; THE BOOTSTRAP BLOCK IS LOADED BY THE CONTROLLER
- ; PROM ROUTINES FROM TRACK 0, SECTOR 4 INTO MEMORY
- ; AT 2000H. THE BOOTSTRAP ROUTINE WILL THEN LOOK
- ; FOR THIS BIOS ON TRACK 0, SECTORS 5-8. THE USER
- ; ROUTINES FOR CONSOLE AND LIST ARE STORED ON TRACK
- ; 0, SECTORS 2-3. TRACK 0, SECTOR 0 IS RESERVED FOR
- ; LIFEBOAT-COMPATIBLE ID AND FUTURE EXPANSION.
- ;
- ; DISK OPERATING SYSTEM ADDRESSES
- ;
- NKSYS EQU 20 ;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+200H ;DDT LOAD OFFSET
- ; (LEAVES ROOM FOR "USER")
- USER EQU 0A000H ;NON-CONTIGUOUS 1K HIGH RAM
- IOBYTE EQU 0003H ;CP/M I/O BYTE ADDRESS
- TPA EQU 100H ;ADDRESS OF TPA
- SECSZ EQU 128 ;BYTES PER SECTOR
- HSTSIZ EQU 256*10 ;BYTES PER N* TRACK
- NDRVS EQU 2 ;# DRIVES IN SYSTEM
- ;
- CR EQU 0DH ;ASCII CARRIAGE RETURN
- LF EQU 0AH ;ASCII LINE FEED
- ;
- ; 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
- ;
- WDATA EQU 0EA00H ;WRITE DATA. DATA IS
- ; LOW 8 ADRESS BITS.
- CCMND EQU 0EB00H ;CONTROLLER COMMAND
- ;
- ; KEYPAD LIGHTS
- ;
- LHEX EQU 0DFH ;LEFT HEX LITES
- MHEX EQU 0DDH ;MIDDLE HEX LITES
- RHEX EQU 0DBH ;RIGHT HEX LITES
- ;
- ; BIOS JUMP VECTOR TABLE
- ;
- ORG BIOS ;START OF BIOS CODE
- ;
- JMP COLD ;COLD BOOT FROM ROM
- JMP WARM ;RELOAD CCP/BDOS
- JMP USER+3 ;GET CONSOLE STATUS
- JMP USER+6 ;CONSOLE INPUT
- JMP USER+9 ;CONSOLE OUTPUT
- JMP USER+12 ;PRINTER OUTPUT
- JMP USER+15 ;PUNCH OUTPUT
- JMP USER+18 ;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 USER+21 ;RETURN LIST STAT
- JMP SECTRN ;TRANSLATE SECTOR
- ;
- MSGOT: EQU USER+24 ;MSG OUT ROUTINE
- HXBOT: EQU USER+27 ;HEX CONVERSION ROUTINE
- DISKER: EQU USER+30 ;DISK ERROR REPORTER
- ;
- ; SELECT DRIVE
- ;
- 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 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
- RET ;RETURN THAT IN HL
- ;
- ; 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 H,B
- MOV L,C
- INX H ;JUST ADD ONE TO SECNUM
- RET ; THEN DONE
- ;
- ; 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.
- ;
- ; TRACK BUFFERING IS DONE HERE. A HOST BLOCK IS
- ; CONSIDERED THE ENTIRE HOST TRACK.
- ;
- DISKRD: XRA A ;END OF UNALLOC SECTORS
- STA UNACNT ; AFTER READ
- INR A
- STA READOP ;READ OPERATION
- STA RSFLAG ;MUST READ DATA
- MVI A,WRUAL
- STA WRTYPE ;TREAT AS UNALLOC
- JMP RWOPER ;TO PERFORM THE READ
- ;
- ; DEBLOCKING DISK WRITE
- ;
- DISKWR: 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 BLKMSK ;NEXT UNALLOC RECS
- INR A
- STA UNACNT
- LDA SEKDSK ;DISK TO SEEK
- STA UNADSK ;UNADSK = SEKDSK
- LDA SEKTRK
- STA UNATRK ;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 DPBNSS ;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)
- ;
- ; ACTIVE HOST TRACK?
- ;
- 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?
- JZ MATCH ;SKIP IF MATCH
- ;
- ; MUST FLUSH HOST BUFFER FOR NEW TRACK
- ;
- 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: LDA SEKDSK ;MAY HAVE TO FILL HOST BUFFER
- STA HSTDSK
- LDA SEKTRK
- STA HSTTRK
- XRA A
- STA HSTWRT ;NO PENDING WRITE
- LDA RSFLAG ;NEED TO READ?
- ORA A
- JZ MATCH ;NO IF FLAG ZERO
- CALL READHST ;READ HOST
- LDA ERFLAG ;CHECK FOR ERRORS
- ORA A
- RNZ ;NO MORE IF SO
- ;
- ; COPY DATA TO OR FROM BUFFER
- ;
- MATCH: LDA SEKSEC ;GET SECTOR NUMBER
- DCR A ;ADJUST FOR 1-ORIGIN
- 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 ;PT TO TRACK BUFFER
- 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
- ;
- ; 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,
- ; AND TRACK IS IN HSTTRK. ON EXIT, ERROR FLAG
- ; IS IN ERFLAG (ZERO IF NONE).
- ; 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
- STA ERSEC ;NO SECTOR IN ERROR YET
- CALL SETUP ;SELECT DRIVE, SEEK, AND
- ; POSITION TO SECTOR ZERO
- RNZ ;SECTOR NOT FOUND IS FATAL
- LHLD HSTADR ;GET ADDRESS TO WRITE FROM
- MVI A,10 ;INIT # BLKS TO WRITE
- ;
- ; HERE TO WRITE NEXT SECTOR. WRITE-PROTECT CHECK IS
- ; DONE EVERY SECTOR TO HELP KILL TIME.
- ;
- WRIT5: PUSH PSW ;SAVE # BLKS LEFT
- LDA CCMND+10H ;GET A-STATUS
- ANI 02H ;IS DISK WRITE-PROTECTED?
- MVI A,6 ;ASSUME SO, ERROR CODE 6
- JNZ WPERR ;WRITE ALWAYS FAILS IF SO
- LDA CCMND+04H ;INITIATE SECTOR WRITE
- ;
- WRIT10: LDA CCMND+10H ;GET A-STATUS
- ANI 08H ;MUST LOOP UNTIL 96 USEC WINDOW
- JZ WRIT10 ; PAST, SO LOOP UNTIL WRT TRUE
- ;
- ; NOW WRITE THE 15 BYTES OF LEADING ZEROES ON THE SECTOR
- ;
- LXI B,15 ;GET ZERO IN C-REG, AND
- ; LOAD CNT IN B-REG
- ;
- WRIT15: MOV E,B ;KILL TIME AND GET ZERO IN E-REG
- MVI D,WDATA SHR 8 ;KILL TIME BY LOADING D FOR LATER
- LDAX D ;WRITE A ZERO BYTE
- MOV A,M ;KILL MORE TIME
- DCR C ;COUNT OFF A ZERO BYTE
- JNZ WRIT15 ;DO THEM ALL
- ;
- ; FOLLOW WITH SYNCH BYTE
- ;
- MOV E,A ;KILL TIME
- MVI E,0FBH ;THIS IS THE SYNCH BYTE VALUE
- LDAX D ;WRITE OUT SYNCH BYTE
- MOV A,M ;KILL TIME
- MOV A,M
- ;
- ; NOW WRITE OUT 256 BYTES. B IS ZERO FROM ABOVE TO INIT
- ; THE CRC BYTE. C IS ZERO FROM COUNTING OUT ABOVE TO INIT
- ; 256-BYTE COUNTER FOR HERE.
- ;
- 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
- DCR C ;COUNT OFF LAST BYTE
- JNZ WRIT20 ;GO BACK IF MORE TO WRITE
- MOV E,B ;IF NOT, TIME TO WRITE CHECKSUM
- MOV E,B ;KILL TIME
- INX B ;KILL MORE TIME
- LDAX D ; THEN WRITE THE BYTE
- CALL WAIT1S ;WAIT FOR NEXT SECTOR
- POP PSW ;GET COUNT OFF STACK
- DCR A ;COUNT OFF LAST SECTOR
- JNZ WRIT5 ;GO BACK IF MORE TO WRITE
- STA ERFLAG ;FLAG NO ERRORS
- RET ; THEN RETURN TO CALLER
- ;
- WPERR: STA ERFLAG ;STORE ERROR CODE
- POP PSW ;CLEAN OFF STACK
- LXI H,WPEMSG ;WRITE PROTECT ERROR
- ;
- DSKERR: XCHG
- LHLD HSTDSK ;PICK UP DISK AND TRACK
- XCHG ;LEAVE IN DE
- LDA ERSEC ;GET SECTOR IN ERROR
- JMP DISKER ;GO REPORT
- ;
- ; 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, SEEK, AND
- ; POSITION TO SECTOR ZERO
- RNZ ;SECTOR NOT FOUND IS FATAL
- XRA A
- STA ERFLAG ;NO ERRORS YET
- LHLD HSTADR ;READ INTO HERE
- MVI A,10 ;INIT # BLKS TO READ
- ;
- ; HERE TO READ NEXT SECTOR. START BY LOOKING FOR
- ; SYNCH BYTE.
- ;
- RNEXTS: PUSH PSW ;SAVE # BLKS LEFT TO READ
- MVI B,08CH ;COUNT FOR SYNC CHAR LOOP
- LXI D,CCMND+50H ;SET UP READ DATA REGS
- MVI C,0 ;LOAD COUNT OF 256 FOR READ
- ;
- ; NOW WAIT FOR SYNC CHAR DETECTED. ERROR IF WE HAVE TO
- ; WAIT TOO LONG.
- ;
- READ5: LDA CCMND+10H ;GET A-STATUS
- ANI 04H ;SYNCH CHAR DETECTED?
- JNZ 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
- POP B ;GET BLK CNT IN B
- MVI A,10
- SUB B ;CALC SECTOR # IN ERROR
- STA ERSEC ;SAVE FOR REPORTING
- LDA RTCNT ;COUNT OFF A RETRY
- DCR A
- STA RTCNT
- JNZ READRT ;IF COUNT LEFT, GO RETRY
- ;
- ; READ ERROR RETRIES FAILED. FLAG ERROR.
- ;
- FRERR: JMP DSKERR ;TELL OPERATOR OF ERROR THEN OUT
- ;
- ; READ THE DATA INTO HSTBUF
- ;
- READ15: MOV B,C ;INIT CHECKSUM FROM ZERO IN C
- ;
- 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
- DCR C ;COUNT OFF LAST BYTE
- JNZ READ20 ;GO BACK IF MORE TO DO
- LDAX D ; ELSE READ CRC BYTE
- XRA B ; AND CHECK IT AGAINST OURS
- JZ READ25 ;GO ON IF READ OK
- MVI A,2 ;IF NOT, FLAG CHECKSUM ERROR
- LXI H,RERMSG ;MESSAGE IF NEEDED
- JMP RERR ;GO MAYBE RETRY
- ;
- READ25: CALL WAIT1S ;WAIT FOR NEXT SECTOR
- POP PSW ;GET # BLKS LEFT
- DCR A ;COUNT ONE OFF
- JNZ RNEXTS ;GO BACK IF MORE
- STA ERFLAG ;IF DONE, FLAG NO ERROR
- RET ; THEN RETURN TO CALLER
- ;
- ; SETUP SELECTS THE UNIT CORRESPONDING TO HSTDSK,
- ; THEN SEEKS TO THE TRACK SPECIFIED BY HSTTRK.
- ; ON RETURN, ERFLAG CONTAINS A NON-ZERO VALUE IF
- ; AN ERROR WAS DETECTED. ONLY UNITS 1 AND 2 ARE
- ; SUPPORTED TO SAVE CODE.
- ;
- SETUP: LDA HSTDSK ;WANT THIS DISK
- INR A ;REMAP TO CONTROLLER MASK
- MOV C,A ;SAVE IN REG C
- LDA CCMND+90H ;KICK MOTORS AND GET A-STATUS
- ANI 10H ;ARE MOTORS ALREADY ON?
- JNZ SET5 ;BRANCH IF SO
- MVI D,50 ;WAIT 1 SECOND 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,CCMND SHR 8 ;SET UP FOR SELECT
- LDAX B ; AND DO IT
- MVI D,13 ;WAIT 13 SECTOR TIMES AFTERWARDS
- CALL SCWAIT
- ;
- ; SEEK TO TRACK SPECIFIED BY HSTTRK NOW.
- ;
- 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
- XRI 59H ;WAS DISK EVER ACCESSED?
- PUSH H ;SAVE TABLE PTR
- CZ SEEK ;HOME DISK IF 1ST SEEK
- POP H ;RESTORE TABLE PTR
- LDA HSTTRK ;GET DESIRED TRACK #
- CALL SEEK ;SEEK TO HSTTRK
- ;
- ; HERE TO POSITION TO SECTOR ZERO WITHIN THE
- ; CURRENT TRACK. ERROR IS RETURNED BY NON-ZERO
- ; IF WE CAN'T FIND THE SECTOR AFTER 30 TRIES.
- ;
- MVI B,30 ;LOOK AT THIS MANY SECTORS
- ;
- POSEC: CALL WAIT1S ;WAIT FOR NEXT SECTOR
- LDA CCMND+030H ;GET B-STATUS WITH SECTOR #
- ANI 0FH ;STRIP NON-SECTOR BITS
- RZ ;OUT IF GOT SECTOR ZERO
- DCR B ;COUNT OFF IF DIDN'T
- JNZ POSEC ;GO BACK IF NOT GIVING UP
- MVI A,1
- STA ERFLAG ;SET ERROR FLAG
- LXI H,SNFMSG
- CALL DSKERR ;REPORT ERROR
- XRA A
- INR A
- RET ;RETURN NON-ZERO TO CALLER
- ;
- ; SEEK TO TRACK SPECIFIED BY ACC. CURRENT PTR INTO
- ; NSTRK TABLE IS IN HL.
- ;
- SEEK: MVI D,LHEX
- MOV E,A
- STAX D ;DISPLAY TARGET TRK #
- MVI D,MHEX
- MOV E,M
- STAX D ;DISPLAY SOURCE TRK #
- MOV C,A ;SAVE TARGET # IN C
- SUB M ;SEE HOW FAR AWAY WE ARE
- ; FROM TARGET TRACK
- MOV M,C ; BUT ALWAYS SET NEW TRACK
- MVI D,RHEX
- MOV E,A
- STAX D ;DISPLAY DIFF
- RZ ;IF THERE, DONE
- LXI H,CCMND+1DH ;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
- MOV E,A
- STAX D ;SHOW CORRECTED COUNT
- LDA CCMND+10H ;GET A-STATUS
- ANI 01H ;ARE WE ON TRACK ZERO?
- RNZ ;MUST BE DONE IF SO
- LXI H,CCMND+1CH ;IF NOT, STEPPING OUT
- ;
- STEPIN: MOV A,M ;SET STEP DIRECTION
- ;
- STEP: LDA CCMND+09H ;SET STEP FLIP-FLOP
- XTHL ;DELAY AT LEAST 10 USEC
- XTHL
- LDA CCMND+08H ; THEN RESET FLIP-FLOP TO PULSE
- MVI D,2 ;NOW WAIT TWO SECTOR TIMES
- CALL SCWAIT ; WHILE HEAD MOVES (40 MSEC)
- LDA CCMND+10H ;GET A-STATUS
- ANI 01H ;ARE WE AT TRACK ZERO?
- JZ STEP5 ;PASS IF NOT
- MVI C,1 ;LAST STEP IF SO
- ;
- STEP5: DCR C ;COUNT OFF LAST TRACK
- JNZ STEPIN ;GO BACK IF MORE TO DO
- RET ; ELSE RETURN TO CALLER
- ;
- ; SECTOR WAIT. ON ENTRY, # SECTORS TO WAIT IS IN D.
- ; ON EXIT, D=0 AND ACC=GARBAGE. CALL WAIT1S TO WAIT
- ; ONE SECTOR TIME.
- ;
- WAIT1S: MVI D,1 ;WAIT ONE SECTOR TIME
- ;
- SCWAIT: LDA CCMND+14H ;RESET SECTOR FLAG
- SCW5: LDA CCMND+90H ;GET A-STATUS AND KICK MOTORS
- ANI 80H ;CHECK SECTOR FLAG
- JZ SCW5 ;WAIT FOR IT IF NOT UP
- DCR D ;COUNT DOWN WAIT COUNTER
- RZ ;RETURN IF DONE COUNTING
- JMP SCWAIT ; ELSE GO COUNT MORE
- ;
- ; 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
-
-
- ;
- ; COLD BOOT ENTRY. SET UP FIRST-TIME BIOS STUFF.
- ;
- COLD: LXI SP,80H ;SET SP TO SCRATCH AREA
- LXI H,CCP ;WHERE TO START CP/M
- PUSH H
- JMP CPMLD ;GO LOAD CCP/BDOS
- ;
- ; WARM BOOT ENTRY. LOAD CCP/BDOS AND INITIALIZE
- ;
- WARM: LDA 4 ;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,80H ;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 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 WRMRD ; RIGHT INTO MEMORY
- LXI H,CCP+HSTSIZ ;NEXT CHUNK
- SHLD HSTADR
- MVI A,2 ; OFF OF TRACK TWO
- STA HSTTRK
- CALL WRMRD ;READ IT
- LXI H,HSTBUF ;NOW READ AND WRITE
- SHLD HSTADR ; USING DEBLOCK BUFFER
- XRA A ;READING TRACK ZERO
- STA HSTTRK
- CALL WRMRD ;READ IT
- LXI H,HSTBUF+256 ;MOVE A SECTOR OF BDOS
- LXI D,CCP+(HSTSIZ*2); TO HERE
- LXI B,256
- CALL BLOCK
- LXI H,HSTBUF+(256*9);LAST BDOS SECTOR
- LXI D,CCP+(HSTSIZ*2)+256
- LXI B,256
- CALL BLOCK
- LDA DFIMG ;RETRIEVE LAST USED DRIVE
- MOV C,A ; FOR BDOS
- RET ; THEN GO TO CP/M
- ;
- WRMRD: CALL READHST ;READ HOST TRACK
- 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
- ;
- ; DISK ERROR MESSAGES
- ;
- WPEMSG: DB 'Protec','t'+80H
- RERMSG: DB 'CR','C'+80H
- SNFMSG: DB 'Secto','r'+80H
- SYEMSG: DB 'Syn','c'+80H
- ;
- MSGLE: DB CR,LF,'Boot er','r'+80H
- ;
- ; NORTH STAR SD DISK PARAMETER BLOCK
- ;
- DPBNSS: DW 20 ;SECTORS PER TRACK
- DB 3 ;BLOCK SHIFT FACTOR
- BLKMSK: DB 07H ;BLOCK MASK
- DB 0 ;NULL 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
- ;
- ; DRIVE PARAMETER HEADER AREA
- ;
- D0DPH: DW 0 ;SECTOR TRAN TBL (NONE)
- DW 0 ;SCRATCH
- DW 0 ;SCRATCH
- DW 0 ;SCRATCH
- DW DIRBF ;DIRECTORY BUFFER
- DW DPBNSS ;DRIVE PARAM BLK
- DW D0CHK ;DRIVE CHANGE BLK
- DW D0ALL ;DRIVE ALLOCATION
- ;
- D1DPH: DW 0,0,0,0,DIRBF,DPBNSS,D1CHK,D1ALL
- ;
- ; 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
- ;
- LASTG EQU $-1 ;LAST GENNED-IN BYTE
- ;
- ; BDOS DIRECTORY BUFFER
- ;
- DIRBF: EQU USER+200H ;ALLOCATED ABOVE USER ROUTINES
- ;
- ; SCRATCH RAM FOR BDOS
- ;
- D0ALL: EQU DIRBF+SECSZ ;A: ALLOCATION BUF
- D0CHK: EQU D0ALL+12 ;A: CHECK BUF
- D1ALL: EQU D0CHK+16 ;B: ALLOCATION BUF
- D1CHK: EQU D1ALL+12 ;B: CHECK BUF
- ;
- ; BIOS VARIABLE STORAGE
- ;
- SEKDSK: EQU D1CHK+16 ;DRIVE NUMBER
- SEKTRK: EQU SEKDSK+1 ;TRACK NUMBER
- SEKSEC: EQU SEKTRK+1 ;SECTOR NUMBER
- CURDSK: EQU SEKSEC+1 ;CURRENT ACTIVE DISK,
- ; GENNED-IN FORCE SELECT
- ERSEC: EQU CURDSK+1 ;SECTOR IN ERROR
- HSTADR: EQU ERSEC+1 ;HOST BUFFER ADDRESS, NORMALLY
- ; PTS TO HSTBUF UNLESS BOOTING
- ;
- ; HSTDSK MUST BE IMMEDIATELY FOLLOWED BY HSTTRK
- ; FOR ERROR REPORTING, SO THEY CAN BE LOADED WITH
- ; A SINGLE LHLD.
- ;
- HSTDSK: EQU HSTADR+2 ;HOST DISK NUMBER
- HSTTRK: EQU HSTDSK+1 ;HOST TRACK NUMBER
- HSTACT: EQU HSTTRK+1 ;HOST ACTIVE FLAG
- HSTWRT: EQU HSTACT+1 ;HOST WRITTEN FLAG
- ERFLAG: EQU HSTWRT+1 ;ERROR REPORTING
- RTCNT: EQU ERFLAG+1 ;ERROR RETRY COUNTER
- RSFLAG: EQU RTCNT+1 ;READ SECTOR FLAG
- READOP: EQU RSFLAG+1 ;1 IF READ OPERATION
- WRTYPE: EQU READOP+1 ;WRITE OPERATION TYPE
- DMAADR: EQU WRTYPE+1 ;LAST DMA ADDRESS
- ;
- UNACNT: EQU DMAADR+2 ;UNALLOC REC CNT
- UNADSK: EQU UNACNT+1 ;LAST UNALLOC DISK
- UNATRK: EQU UNADSK+1 ;LAST UNALLOC TRACK
- UNASEC: EQU UNATRK+1 ;LAST UNALLOC SECTOR
- ;
- ; NORTH STAR CURRENT TRACK TABLE
- ;
- NSTRK: EQU UNASEC+1 ;NO CURRENT TRACK YET
- NSTRK1: EQU NSTRK+1 ;EACH ENTRY CONTAINS
- ; THE LAST TRACK POSITION
- ; FOR THE UNIT (1 OR 2)
- ;
- ; NORTH STAR HOST SECTOR BUFFER
- ;
- HSTBUF: DS HSTSIZ ;HOST BUFFER
- ;
- LAST EQU $-1 ;LAST USED BYTE IN MEM
- ;
- END
-