DataMuseum.dk

Presents historical artifacts from the history of:

RegneCentralen RC700 "Piccolo"

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about RegneCentralen RC700 "Piccolo"

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦7cf144912⟧ TextFile

    Length: 31232 (0x7a00)
    Types: TextFile
    Names: »FLOPPY.MAC«

Derivation

└─⟦72577d508⟧ Bits:30003297 Diverse BIOS typer til RC703
    └─ ⟦this⟧ »FLOPPY.MAC« 

TextFile

        SUBTTL	FLOPPY DISK DRIVER
;========================================================
;= FLOPPY DISK DRIVER                                   =
;========================================================

WRALL   EQU     0               ; WRITE TO ALLOCATED SECTOR.
WRDIR   EQU     1               ; WRITE TO DIRECTORY SECTOR.
WRUAL   EQU     2               ; WRITE TO UNALLOCATED SECTOR (FIRST SECTOR OF A
                                ; NEW DATA BLOCK).

	PAGE
;================================================
;= PROCEDURE SECTION                            =
;================================================

        ;SELECT DISK DRIVE
        ;ENTRY: C=DRIVE NUMBER
        ;EXIT : HL=DISK PARAMETER HEADER
SELD:   LD      HL,0            ; PROCEDURE SELECT_DISK;
        ADD     HL,SP           ; 
        LD      SP,STACK        ; SP := LOCAL_STACK;
        PUSH    HL              ; 
        LD      HL,0            ; ERROR CODE
        LD      A,(DRNO)        ; DRIVE OK?
        CP      C               ; CY IF SO
        JP      C,RSELD         ; RET IF ERROR
        LD      A,C             ; 
        LD      (SEKDSK),A      ; INIT. SEEK DISK WITH NEW DRIVE NO.
	LD	BC,10H		; INIT. DPH LENGTH
	LD	DE,FD0		; GET FD0 ADDRESS
	LD	HL,00H		; INIT. DPH OFFSET
SELD10:	OR	A		;
	JP	Z,SELD20	;
	INC	DE		; DE:=DE+DRIVE_NO 
	ADD	HL,BC		; HL:=HL+(DRIVE_NO.*DPH_LENGTH)
	DEC	A		;
	JP	SELD10		;
SELD20:	LD	C,L		;
	LD	B,H		;
	EX	DE,HL		;
        LD      A,(HL)          ;                 
        LD      HL,CFORM        ;
        CP      (HL)            ;
        JP      Z,SELN          ;
	PUSH    AF              ;   IF: NEW_FORMAT # CURRENT_FORMAT THEN
	PUSH    BC              ;         IF: HOST_WRITE # 0 THEN
	LD      A,(HSTWRT)      ;             WRITE BUFFER TO DISK
	OR      A               ;       ELSE:
	CALL    NZ,WRTHST       ; ELSE:
	XOR     A               ;
	LD      (HSTWRT),A      ;
	POP     BC              ;
	POP     AF              ;
	LD	(CFORM),A	; TFj	VÆLG FLOPPY-
	CP	16		; TFj	CLOCKFREKVENS
	JP	Z,MINIFL	; TFj
	LD	A,2		; TFj
MINIFL: INC	A		; TFj
	OUT	(SW1),A		; TFj
	LD	A,(CFORM)	; TFj
SELN:   LD      (CFORM),A       ; CURRENT_FORMAT := FORMAT(DRIVE_NO);
        CALL    GFPA            ; GET NEW FLOPPY_DISK_PARMS ADDRESS
        LD      (FORM),HL       ;
        INC     HL              ;
        INC     HL              ;
        INC     HL              ;
        INC     HL              ;
        LD      A,(HL)          ; INIT. NUMBER OF TRACKS ON ONE DISK PAGE
        LD      (EOTV),A        ;
        PUSH    BC              ;
        LD      A,(CFORM)       ;
	AND	11111000B	; REMOVE POSITION BITS
	OR      A               ;
        RLA                     ;
        LD      E,A             ;
        LD      D,0             ;
        LD      HL,FSPA00       ;
        ADD     HL,DE           ; INIT. ACTUAL DISK_PARMS_BLOCK
        LD      DE,DPBLCK       ;
        LD      BC,10H          ;
        LDIR                    ;
	LD	HL,(DPBLCK)	; GET ADDRESS OF DPBXX (XX=0,08,16,,56,64)
	LD	BC,13		; REL. TO START
	ADD	HL,BC		; ADDRESS OF OFFSET WORD
	EX	DE,HL		;
	LD	HL,TRKOFF	; TRACK OFFSET TABLE
	LD	B,0		;
	LD	A,(SEKDSK)	; BC= SEEK DISK NO.
	LD	C,A		;
	ADD	HL,BC		;
	ADD	HL,BC		; HL= ADDRESS OF OFFSET VALUE IN OFFSET TBL
	LD	BC,2		; NO OF BYTES TO MOVE
	LDIR			;
        POP     BC              ;
        LD      HL,DPBASE       ;
        ADD     HL,BC           ; GET ADR. OF ACTUAL DISK_PARMS_HEADER
        EX      DE,HL           ;
        LD      HL,10           ;
        ADD     HL,DE           ;
        EX      DE,HL           ;
        LD      A,(DPBLCK)      ; INIT. DISK_PARMS_HEADER WITH  
        LD      (DE),A          ; ACTUAL DISK_PARMS_BLOCK
        INC     DE              ;
        LD      A,(DPBLCK+1)    ;
        LD      (DE),A          ;
RSELD:  EX      DE,HL           ; HL:=DPH(DISK)
        POP     HL              ;
        LD      SP,HL           ;
        EX      DE,HL           ;
        RET                     ;
        
        PAGE 

GFPA:   LD      HL,FDF1         ;
        LD      A,(CFORM)       ;
	AND	11111000B	; REMOVE POSITION BITS
        LD      E,A             ;
        LD      D,0             ;
        ADD     HL,DE           ;
        RET                     ;

;SETTRACK
;ENTRY: BC=TRACK NUMBER
SETT:   LD      H,B             ;
        LD      L,C             ;
        LD      (SEKTRK),HL     ;
        RET                     ;
        
;SETSECTOR
;ENTRY: BC=SECTOR NUMBER
SETS:   LD      L,C             ;
        LD      H,B             ;
        LD      (SEKSEC),HL     ;
        RET                     ;
        
;SET DMA ADDRESS
;ENTRY: BC=DMA ADDRESS
SETD:   LD      H,B             ;
        LD      L,C             ;
        LD      (DMAADR),HL     ;
        RET                     ;
                
;TRANSLATE SECTOR NUMBER
;ENTRY: BC=SECTOR NUMBER
SECTRA: LD      H,B             ;
        LD      L,C             ;
        RET                     ;
        
        PAGE 

;READ THE SELECTED CP/M SECTOR
;ENTRY:
;EXIT : A=RESULT (0 OK,1 HARD ERROR)

XREAD:	XOR	A		;PATCHES FROM DIGITAL
	LD	(UNACNT),A	;
	LD      A,1             ;
        LD      (READOP),A      ; READ OPERATION
        LD      (RSFLAG),A      ; MUST READ DATA
        LD      A,WRUAL         ;
        LD      (WRTYPE),A      ; TREAT AS UNALLOCATED
        JP      RWOPER          ; TO PERFORM THE READ
        
;WRITE THE SELECTED CP/M SECTOR
;ENTRY:
;EXIT : C=WRITETYPE A=RESULT

XWRITE: XOR     A               ;
        LD      (READOP),A      ; NOT A READ OPERATION
        LD      A,C             ; WRITE TYPE IN C
        LD      (WRTYPE),A      ;
        CP      WRUAL           ; WRITE UNALLOCATED?
        JP      NZ,CHKUNA       ; CHECK FOR UNALLOCATED
        
;WRITE TO UNALLOCATED, SET PARAMETERS
        
        LD      A,(CPMRBP)      ;   UNACNT := BLKSIZE/128;
        LD      (UNACNT),A      ;
        LD      A,(SEKDSK)      ;   UNADSK := SEKDSK;
        LD      (UNADSK),A      ;
        LD      HL,(SEKTRK)     ;   UNATRK := SEKTRK;
        LD      (UNATRK),HL     ;
        LD      HL,(SEKSEC)     ;   UNASEC := SEKSEC;
        LD      (UNASEC),HL     ;
        
;CHECK FOR WRITE TO UNALLOCATED SECTOR

CHKUNA: LD      A,(UNACNT)      ; ANY UNALLOCATED REMAIN?
        OR      A               ; 
        JP      Z,ALLOC         ; SKIP IF NOT
        
	PAGE

;MORE UNALLOCATED RECORDS REMAIN
        
        DEC     A               ; UNACNT := UNACNT -1;
        LD      (UNACNT),A      ;
        LD      A,(SEKDSK)      ; SAME DISK?
        LD      HL,UNADSK       ;
        CP      (HL)            ; SEKDSK=UNADSK?
        JP      NZ,ALLOC        ; SKIP IF NOT
        
;DISKS ARE THE SAME
        
        LD      HL,UNATRK       ; SAME TRACK?
        CALL    TRKCMP          ; SEKTRK=UNATRK?
        JP      NZ,ALLOC        ; SKIP IF NOT
        
;TRACKS ARE THE SAME
        
        LD      A,(SEKSEC)      ; SAME SECTOR?
        LD      HL,UNASEC       ;
        CP      (HL)            ; SEKSEC=UNASEC?
        JP      NZ,ALLOC        ; SKIP IF NOT
        LD      A,(SEKSEC+1)    ;
        INC     HL              ;
        CP      (HL)            ; COMPARE MSB
        JP      NZ,ALLOC        ;
        
;MATCH, MOVE TO NEXT SECTOR FOR FUTURE REFERENCE

        LD      HL,(UNASEC)     ;
        INC     HL              ;
        LD      (UNASEC),HL     ; UNASEC:=UNASEC+1
        EX      DE,HL           ;
        LD      HL,CPMSPT       ; GET SECTORS PER TRACK
        PUSH    BC              ;
        LD      C,(HL)          ;
        INC     HL              ;
        LD      B,(HL)          ;
        EX      DE,HL           ;
        AND     A               ; RESET CARRY
        SBC     HL,BC           ; END OF TRACK 
        POP     BC              ;
        JP      C,NOOVF         ; SKIP IF NO OVERFLOW

	PAGE
        
;OVERFLOW TO NEXT TRACK
        
        LD      HL,00           ; UNASEC:=0
        LD      (UNASEC),HL     ;
        LD      HL,(UNATRK)     ;
        INC     HL              ;
        LD      (UNATRK),HL     ; UNATRK:=UNATRK+1
        
;MATCH FOUND, MARK AS UNNECESSARY READ

NOOVF:  XOR     A               ;
        LD      (RSFLAG),A      ; RSFLAG:=0
        LD      A,(SEKSEC)      ;
        LD      HL,SECMSK       ;
        AND     (HL)            ;
        CP      (HL)            ;
        LD      A,0             ;
        JP      NZ,SETMSK       ;
        INC     A               ;
SETMSK: LD      (UNAMSK),A      ;
        JP      RWOPER          ; TO PERFORM THE WRITE
        
;NOT AN UNALLOCATED RECORD, REQUIRES PRE-READ

ALLOC:  XOR     A               ;
        LD      (UNACNT),A      ; UNACNT:=0
        LD      A,(SECMSK)      ;
        LD      (RSFLAG),A      ; RSFLAG:=1
        
        PAGE 
        
; COMMON CODE FOR READ AND WRITE FOLLOWS

RWOPER: LD      HL,0            ;
        ADD     HL,SP           ;
        LD      SP,STACK        ; ESTABLISH LOCAL STACK
        PUSH    HL              ; SAVE OLD SP
        LD      A,(SECSHF)      ; COMPUTE HOST SECTOR
        LD      B,A             ;
        LD      HL,(SEKSEC)     ;
RSECS:  DEC     B               ;
        JP      Z,SETSH         ;
        SRL     H               ; HOST_SECTOR := SEEK_SECTOR DIVIDED
        RR      L               ; WITH SECTOR SHIFT CONSTANT
        JP      RSECS           ;
SETSH:  LD      (SEKHST),HL     ; HOST SECTOR TO SEEK

;ACTIVE HOST SECTOR?
        
        LD      HL,HSTACT       ; HOST ACTIVE FLAG
        LD      A,(HL)          ;
        LD      (HL),1          ; ALWAYS BECOMES 1
        OR      A               ; WAS IT ALREADY?
        JP      Z,FILHST        ; FILL HOST IF NOT
        
;HOST BUFFER ACTIVE, SAME AS SEEK BUFFER?
        
        LD      A,(SEKDSK)      ;
        LD      HL,HSTDSK       ; SAME DISK?
        CP      (HL)            ; SEKDSK=HSTDSK?
        JP      NZ,NOMATC       ;
        
;SAME DISK, SAME TRACK?
        
        LD      HL,HSTTRK       ;
        CALL    TRKCMP          ; SEKTRK=HSTTRK
        JP      NZ,NOMATC       ;
        
	PAGE

;SAME DISK, SAME TRACK, SAME SECTOR?
        
        LD      A,(SEKHST)      ;
        LD      HL,HSTSEC       ; SEKHST=HSTSEC?
        CP      (HL)            ;
        JP      NZ,NOMATC       ; LSB COMPARE  
        LD      A,(SEKHST+1)    ;
        INC     HL              ;
        CP      (HL)            ; MSB COMPARE
        JP      Z,MATCH         ; SKIP IF MATCH
        
;PROPER DISK, BUT NOT CORRECT SECTOR

NOMATC: LD      A,(HSTWRT)      ; HOST WRITTEN?
        OR      A               ;
        CALL    NZ,WRTHST       ; WRITE HOST BUFFER TO DISK
        
;MAY HAVE TO FILL THE HOST BUFFER

FILHST: LD      A,(SEKDSK)      ;
        LD      (HSTDSK),A      ;
        LD      HL,(SEKTRK)     ;
        LD      (HSTTRK),HL     ;
        LD      HL,(SEKHST)     ;
        LD      (HSTSEC),HL     ;
        LD      A,(RSFLAG)      ; NEAD TO READ?
        OR      A               ;
        CALL    NZ,RDHST        ; YES, IF 1
        XOR     A               ;
        LD      (HSTWRT),A      ; NO PENDING WRITE
        
	PAGE

;COPY DATA TO OR FROM BUFFER

MATCH:  LD      A,(SEKSEC)      ; MASK BUFFER NUMBER
        LD      HL,SECMSK       ; LEAST SIGNIF BITS
        AND     (HL)            ; TO POINT OUT POSISTION IN HOST BUFFER
        LD      L,A             ; READY TO SHIFT
        LD      H,00H           ;
        ADD     HL,HL           ; SHIFT LEFT 7
        ADD     HL,HL           ;
        ADD     HL,HL           ;
        ADD     HL,HL           ;
        ADD     HL,HL           ;
        ADD     HL,HL           ;
        ADD     HL,HL           ; BUFF_OFFSET:=128*(SEEKSEC AND SECMASK);
        
;HL HAS RELATIVE HOST BUFFER ADDRESS
        
        LD      DE,HSTBUF       ;
        ADD     HL,DE           ; HL:=HOST BUFFER ADDRESS
        EX      DE,HL           ; NOW IN DE
        LD      HL,(DMAADR)     ; GET/PUT CP/M DATA
        LD      BC,128          ; LENGTH OF MOVE
        EX      DE,HL           ;
        LD      A,(READOP)      ; WHICH WAY?
        OR      A               ;
        JP      NZ,RWMOVE       ; SKIP IF READ
        
;WRITE OPERATION, MARK AND SWITCH DIRECTION
        
        LD      A,1             ; HOSTWRT:=1;
        LD      (HSTWRT),A      ; 
        EX      DE,HL           ; SOURCE/DEST SWAP

        PAGE 

;BC INITIALLY 128, HL IS SOURCE, DE IS DEST

RWMOVE: LDIR                    ;

;DATA HAS BEEN MOVED TO/FROM HOST BUFFER
        
        LD      A,(WRTYPE)      ; WRITE TYPE
        CP      WRDIR           ; TO DIRECTORY?
        LD      HL,ERFLAG       ; IN CASE OF ERRORS
        LD      A,(HL)          ;
	PUSH	AF		;
	OR 	A		;
	JP	Z,RRWOPX	;
	XOR	A		;	
	LD	(HSTACT),A	; DO: SET HOST_ACTIVE:=FALSE
RRWOPX:	POP	AF		;
        LD      (HL),0          ;
        JP      NZ,RRWOP        ; NO FURTHER PROCESSING
        
;CLEAR HOST BUFFER FOR DIRECTORY WRITE
        
        OR      A               ; ERRORS?
        JP      NZ,RRWOP        ; SKIP IF NOT SO
        XOR     A               ;
        LD      (HSTWRT),A      ; BUFFER WRITTEN
        CALL    WRTHST          ;
        LD      HL,ERFLAG       ; 
        LD      A,(HL)          ; 
        LD      (HL),0          ;
         
RRWOP:  POP     HL              ; RETURN:
        LD      SP,HL           ; SP:=GLOBAL_SP;
        RET                     ;
        
        PAGE 
        
;UTILITY SUBROUTINE FOR 16-BIT COMPARE
;HL=UNATRK OR HSTTRK, COMPARE WITH SEKTRK

TRKCMP: EX      DE,HL           ;
        LD      HL,SEKTRK       ;
        LD      A,(DE)          ; LOW BYTE COMPARE
        CP      (HL)            ; SAME?
        RET     NZ              ; RETURN IF NOT
        
;LOW BYTES EQUAL, TEST HIGH LS
        
        INC     DE              ;
        INC     HL              ;
        LD      A,(DE)          ;
        CP      (HL)            ; SETS FLAGS
        RET                     ;
            

        PAGE 
;==========================================================
;= WRITEHOST performs the physical write to the host disk.=
;==========================================================
WRTHST:	LD	A,(DSKTYP)	;   IF: DISK TYPE := HARD
	OR	A		; THEN: GOTO HARD WRITE HOST
	JP	NZ,HWRHST	; ELSE:
        CALL    CHKTRK          ;
        JP      SECWR           ;
        
;==========================================================
;= READHOST performs the physical read from the host disk =
;==========================================================
RDHST:  LD      A,(UNAMSK)      ;
        OR      A               ;
        JP      NZ,RCHECK       ; IF UNAMSK THEN FORCE PRE_READ;
        LD      (UNACNT),A      ;
RCHECK: LD	A,(DSKTYP)	;   IF: DISK TYPE := HARD
	OR	A		; THEN: GOTO HARD READ HOST
	JP	NZ,HRDHST	; ELSE:
	CALL    CHKTRK          ;
        JP      SECRD           ;
        
        PAGE 
        
;==============================================================================
;= CHECK HOST DISK AND TRACK EQUAL TO LAST HOST AND DISK                      =
;=                                                                            =
;=   S U P P O R T S   O N L Y   2 5 6   S E C T O R S   A N D   T R A C K S  =
;==============================================================================
CHKTRK: LD      A,(HSTSEC)      ;
        LD      C,A             ; SECTOR:=HSTSEC;
        LD      A,(EOTV)        ; HEADNO:=0;
        LD      B,A             ;
        DEC     A               ;
        CP      C               ;
        LD      A,(HSTDSK)      ;
        JP      NC,SET1         ; IF HSTSEC>EOTV-1 THEN END;
        OR      4               ; BEGIN
        LD      (DSKNO),A       ;   HEADNO:=1;
        LD      A,C             ;   SECTOR:=SECTOR-EOTV;
        SUB     B               ; END;
        LD      C,A             ;
        JP      SET2            ;
SET1:   LD      (DSKNO),A       ;
SET2:   LD      B,0             ;
        LD      HL,(TRANTB)     ; TRANSLATE SECTOR
        ADD     HL,BC           ;
        LD      A,(HL)          ;
        LD      (ACSEC),A       ; ACTUAL_SECTOR := TRANSLATED_SECTOR
        LD      A,(HSTTRK)      ;
        LD      (ACTRA),A       ; ACTUAL_TRACK := HOST_TRACK
        LD      HL,HSTBUF       ;
        LD      (DSKAD),HL      ;
        LD      A,(HSTDSK)      ;   IF: HOST_DISK := LAST_DISK THEN
        LD      HL,LSTDSK       ;
        CP      (HL)            ;         IF: HOST_TRACK := LAST_TRACK THEN
        JP      NZ,SEEKT        ;
        LD      A,(HSTTRK)      ;             END
        LD      HL,LSTTRK       ;
        CP      (HL)            ;       ELSE:
        JP      NZ,SEEKT        ;
        LD      A,(HSTTRK+1)    ; ELSE:
        INC     HL              ;
        CP      (HL)            ; COMPARE MSB
        RET     Z               ;
        
        PAGE 
        
SEEKT:  LD      A,(HSTDSK)      ; LAST_DISK := HOST_DISK
        LD      (LSTDSK),A      ;
        LD      HL,(HSTTRK)     ; LAST_TRACK := HOST_TRACK
        LD      (LSTTRK),HL     ;
        CALL    CLFIT           ; CLEAR FLOPPY INTERRUPT FLAG
        CALL    FL07            ; SEEK DRIVE_NO, HEAD AND SECTOR
        CALL    WFITR           ; AWAIT FLOPPY INTERRUPT
        LD      A,(DSKNO)       ;
        AND     3               ;
        ADD     A,32            ; REG. BC := COMPLETION CODE
        CP      B               ; IF STATUS=SEEK_END THEN
        RET     Z               ;   RETURN;
RECA:   CALL    CLFIT           ;
        CALL    FL04            ; RECALIBRATE;
        PUSH    BC              ;
        CALL    WFITR           ;
        CALL    FL07            ; SEEK(ACTRA);
        CALL    WFITR           ;
        POP     BC              ;
        RET                     ; RETURN;
        
        PAGE 

SECRD:  LD      A,10            ;
        LD      (REPET),A       ;
RPSC:   CALL    FDSTART         ;
        CALL    CLFIT           ;
        LD      HL,(FORM)       ;
        LD      C,(HL)          ;
        INC     HL              ;
        LD      B,(HL)          ;
        INC     HL              ;
        CALL    FLPW            ;
        CALL    RFDAT           ;
        CALL    WATIR           ;
        LD      C,0             ;
SECCH:  LD      HL,RSTAB        ;
        LD      A,(HL)          ;
        AND     0F8H            ;
        RET     Z               ;
SCRP:	AND     8               ;
        JP      NZ,SCR1         ;
        LD      A,(REPET)       ;
        DEC     A               ;
        LD      (REPET),A       ;
        JP      Z,SCR1          ;
        CP      5               ;
        CALL    Z,RECA          ;
        XOR     A               ;
        CP      C               ;
        JP      Z,RPSC          ;
        JP      RPSW            ;
SCR1:   LD      A,C             ;
        LD      (HSTACT),A      ;
        LD      A,1             ;
        LD      (ERFLAG),A      ;
        RET                     ;
        
        PAGE 

SECWR:  LD      A,10            ;
        LD      (REPET),A       ;
RPSW:   CALL    FDSTART         ;
        CALL    CLFIT           ;
        LD      HL,(FORM)       ;
        LD      C,(HL)          ;
        INC     HL              ;
        LD      B,(HL)          ;
        INC     HL              ;
        CALL    FLPR            ;
        CALL    WFDAT           ;
        CALL    WATIR           ;
        LD      C,1             ;
        JP      SECCH           ;
        
RFDAT:  LD      A,6             ;
        JP      GNCOM           ;
        
WFDAT:  LD      A,5             ;
        JP      GNCOM           ;
        
        PAGE 
FDSTAR: IN      A,(SW1)         ; PROCEDURE START_FLOPPY_MOTOR;
        AND     80H             ; BEGIN
; TFj	RET     Z               ;   IF MINI_DRIVE THEN BEGIN
        DI                      ;   BEGIN
        LD      HL,(EXCNT1)     ;     STOPPED:=STOP_TIMER=0;
        LD      A,L             ;     STOP_TIMER:=FD_TIME_OUT; 
        OR      H               ;     IF STOPPED THEN
        LD      HL,(FDTIMO)     ;     BEGIN
        LD      (EXCNT1),HL     ;       START_MOTOR;
        EI                      ;       WAITD(50); (* WAIT 1 SEC *)
        RET     NZ              ;     END;
; TFj	LD      A,1             ;   END;
	IN	A,(SW1)		; TFj jeg bruger motorswitchen på
	SET	0,A		; TFj drive C og D også
        OUT     (SW1),A         ; END;
; TFj	LD      HL,50           ;
	LD	HL,15		; TFj virker vist godtnok alligevel
        CALL    WAITD           ;
        RET                     ;
        
FDSTOP: IN      A,(SW1)         ; PROCEDURE STOP_FLOPPY_MOTOR;
        AND     80H             ; BEGIN (* CALLED WHEN STOP_TIMER REACH 0 *)
; TFj	RET     Z               ;   IF MINI_DRIVE THEN
; TFj	LD      A,0             ;     STOP_MOTOR;
	IN	A,(SW1)		; TFj
	RES	0,A		;
        OUT     (SW1),A         ; END;
        RET                     ;
        
WAITD:  LD      (DELCNT),HL     ; PROCEDURE WAITD;
WAIT10: LD      HL,(DELCNT)     ;
        LD      A,L             ;
        OR      H               ;
        JP      NZ,WAIT10       ;
        RET                     ;
        
	PAGE
XHOME:	LD	A,(HSTWRT)	;PATCH FROM DIG. CHECK FOR PENDING WRITE
	OR	A		;
	JR	NZ,XHOM01	;
	LD	(HSTACT),A	;CLEAR HOST ACTIVE FLAG
				;END PATCH FROM DIGITAL.
XHOM01:	LD	A,(DSKTYP)	;   IF: DISK TYPE := HARD
	AND	A		; THEN:
	JP	Z,XHOM20	;
	LD	A,(SEKDSK)	;
	LD	(LSTDSK),A	;	LAST_DISK:=SEEK_DISK
	LD	HL,(DPBLCK)	;
	LD	DE,13		;	GET TRACK OFFSET IN DISK PARMS. BLOCK
	ADD	HL,DE		;
	LD	E,(HL)		;
	INC	HL		;
	LD	D,(HL)		;
	LD	(LSTTRK),DE	; 	LAST_TRACK:=TRACK_OFFSET
	CALL	STSKFL		;	SET UP TASK FILE TO WD1000
	CALL	HDSEEK		;	POSITION HEADS
	RET	NC		;  	  IF: NO COMMAND ISSUED
	CALL	WAITHD		;	THEN: END
XHOM10:	IN	A,(HDSTRG)	;	ELSE: 
	AND	10H		;	AWAIT HARD DISK INTERRUPT
	JP	Z,XHOM10	;	AWAIT SEEK COMPLETE
	RET			;	END.
XHOM20: CALL    FDSTAR          ; ELSE:
        LD      A,(SEKDSK)      ;
        LD      (DSKNO),A       ;
        LD      (LSTDSK),A      ;
        XOR     A               ;
        LD      (LSTTRK),A      ; LASTTRACK:=0
        LD      (LSTTRK+1),A    ;
        CALL    CLFIT           ; CLEAR FLOPPY INTERRUPT
        CALL    FL04            ; RECALIBRATE FLOPPY
        CALL    WFITR           ; AWAIT FLOPPY INTERRUPT
        RET                     ;
                PAGE 
                                ; PROCEDURE WAIT_READY_WRITE;
FL02:   IN      A,(FDC)         ;
        AND     0C0H            ;
        CP      080H            ;
        JP      NZ,FL02         ;
        RET                     ;
        
                                ; PROCEDURE WAIT_READY_READ;
FL03:   IN      A,(FDC)         ;
        AND     0C0H            ;
        CP      0C0H            ;
        JP      NZ,FL03         ;
        RET                     ;
        
                                ; PROCEDURE RECALIBRATE;
FL04:	CALL	FL041		;   RECALIBRATE
	CALL	WATIR		;   WAIT FINISHED
	LD	A,(RSTAB)	;
	BIT	4,A		;
	RET	Z		;   IF EQUIPTMENT CHECK THEN

FL041:	CALL	CLFIT		;
	CALL    FL02            ;   WAIT_READY_WRITE;
        LD      A,7             ;
        OUT     (FDD),A         ;   RECALIBRATE;
        CALL    FL02            ;   WAIT_READY_WRITE;
        LD      A,(DSKNO)       ;
        AND     3               ;
        OUT     (FDD),A         ;   SELECT_DRIVE;
        RET                     ;

                                ; PROCEDURE SENSE_DRIVE_STATUS;
FL05:   CALL    FL02            ; WAIT_READY_WRITE;
        LD      A,4             ;
        OUT     (FDD),A         ;
        CALL    FL02            ; WAIT_READY_WRITE;
        LD      A,(DSKNO)       ;
        AND     3               ;
        OUT     (FDD),A         ; SELECT_DRIVE;
        CALL    FL03            ; WAIT_READY_READ;
        IN      A,(FDD)         ;
        LD      (RSTAB),A       ; RSTAB:=INTERRUPT_REGISTER;
        RET                     ;
        
        PAGE 
        
                                ; PROCEDURE SENSE_INTERRUPT_STATUS;
FL06:   CALL    FL02            ; WAIT_READY_WRITE;
        LD      A,8             ;
        OUT     (FDD),A         ; SENSE_INT;
        CALL    FL03            ; WAIT_READY_READ;
        IN      A,(FDD)         ;
        LD      (RSTAB),A       ; RSTAB:=STATUS_REGISTER_0;
        AND     0C0H            ;
        CP      080H            ;
        RET     Z               ;
        CALL    FL03            ; WAIT_READY_READ;
        IN      A,(FDD)         ;
        LD      (RSTAB+1),A     ; RSTAB1:=STATUS_REGISTER_1;
        RET                     ;
        
                                ; PROCEDURE SEEK;
FL07:   CALL    FL02            ; WAIT_READY_WRITE;
        LD      A,15            ;
        OUT     (FDD),A         ; SEEK;
        CALL    FL02            ; WAIT_READY_WRITE;
        LD      A,(DSKNO)       ; SELECT_DRIVE_AND_HEAD;
        AND     3               ;
        OUT     (FDD),A         ;
        CALL    FL02            ; WAIT_READY_WRITE;
        LD      A,(ACTRA)       ;
        OUT     (FDD),A         ; SELECT_CYLINDER;
        RET                     ;
                                
        PAGE 
                                ; PROCEDURE READ_RESULT;
RSULT:  LD      HL,RSTAB        ; FOR D:=7 DOWNTO 0 DO
        LD      D,7             ; BEGIN
RSL1:   CALL    FL03            ;   WAIT_READY_READ;
        IN      A,(FDD)         ;   RESULT_TABLE(D):=READCHAR(FDD);
        LD      (HL),A          ;
        INC     HL              ;
        LD      A,4             ;
RSL2:   DEC     A               ;   DELAY;
        JP      NZ,RSL2         ;
        IN      A,(FDC)         ;
        AND     10H             ;
        RET     Z               ;
        DEC     D               ;
        JP      NZ,RSL1         ;
        RET                     ; END;

CLFIT:  DI                      ; PROCEDURE CLEAR_FLOPPY_INTERRUPT;
        XOR     A               ;
        LD      (FL_FLG),A      ;
        EI                      ;
        RET                     ;
        
WFITR:  CALL    WATIR           ; PROCEDURE WAIT_CLEAR_FD_INTERRUPT;
        LD      A,(RSTAB)       ;
        LD      B,A             ;
        LD      A,(RSTAB+1)     ;
        LD      C,A             ;
        CALL    CLFIT           ;
        RET                     ;

        PAGE 
        
WATIR:  LD      A,(FL_FLG)      ; PROCEDURE WAIT_FD_INTERRUPT;
        OR      A               ;
        JP      Z,WATIR         ;
        RET                     ;
        
FLPR:   LD      A,5             ; PROCEDURE START_DMA_READ;
        DI                      ;
        OUT     (DMAMAS),A      ; SET_CH1_MASK;
        LD      A,49H           ; MODE:=READ;
FLFW:   OUT     (DMAMOD),A      ; SELECT_MODE;
        OUT     (DMACBC),A      ; CLEAR_BYTECOUNTER;
        LD      A,(DSKAD+0)     ;
        OUT     (DMAAD1),A      ; SET_LOW_ADDRESS;
        LD      A,(DSKAD+1)     ;
        OUT     (DMAAD1),A      ; SET_HIGH_ADDRESS;
        LD      A,C             ;
        OUT     (DMACN1),A      ; SET_LOW_COUNT;
        LD      A,B             ;
        OUT     (DMACN1),A      ; SET_HIGH_COUNT;
        LD      A,1             ;
        OUT     (DMAMAS),A      ; CLEAR_CH1_MASK;
        EI                      ;
        RET                     ;
        
FLPW:   LD      A,5             ; PROCEDURE START_DMA_WRITE;
        DI                      ;
        OUT     (DMAMAS),A      ; SET_CH1_MASK;
        LD      A,45H           ; MODE:=WRITE;
        JP      FLFW            ; GOTO START_DMA_COMMON;
        
        PAGE 
GNCOM:  PUSH    AF              ; PROCEDURE GENERAL_COMMAND;
        DI                      ;
        CALL    FL02            ; WAIT_READY_WRITE;
        POP     AF              ;
        LD      B,(HL)          ;
        INC     HL              ;
        ADD     A,B             ; ADD MF/FMF TO COMMAND;
        OUT     (FDD),A         ;
        CALL    FL02            ; WAIT_READY_WRITE;
        LD      A,(DSKNO)       ;
        OUT     (FDD),A         ; SELECT_HEAD_AND_DRIVE;
        CALL    FL02            ; WAIT_READY_WRITE;
        LD      A,(ACTRA)       ;
        OUT     (FDD),A         ; SELECT_CYLINDER;
        CALL    FL02            ; WAIT_READY_WRITE;
        LD      A,(DSKNO)       ;
        RRA                     ;
        RRA                     ;
        AND     3               ;
        OUT     (FDD),A         ; SELECT_HEAD;
        CALL    FL02            ; WAIT_READY_WRITE;
        LD      A,(ACSEC)       ;
        OUT     (FDD),A         ; SELECT_SECTOR;
        CALL    FL02            ; WAIT_READY_WRITE;
        LD      A,(HL)          ;
        INC     HL              ;
        OUT     (FDD),A         ; SELECT_NUMBER_TYPE;
        CALL    FL02            ; WAIT_READY_WRITE;
        LD      A,(HL)          ;
        INC     HL              ;
        OUT     (FDD),A         ; SELECT_FINAL_SECTOR;
        CALL    FL02            ;
        LD      A,(HL)          ;
        OUT     (FDD),A         ; SELECT_GAP_LENGTH;
        CALL    FL02            ;
        LD      A,(DTLV)        ;
        OUT     (FDD),A         ; SELECT_DATA_LENGTH;
        EI                      ;
        RET                     ;
        
        PAGE 
;========================================================
;= UP765 FLOPPY DISK CONTROLLER INTERRUPT ROUTINE       =
;========================================================

FLITR:  LD      (SP_SAV),SP     ; SAVE ACCUMULATOR AND FLAGS
        LD      SP,ISTACK       ; SAVE REGISTERS
        PUSH    AF              ;
        PUSH    BC              ;
        PUSH    DE              ; ESTABLISH LOCAL STACK
        PUSH    HL              ; SAVE GLOBAL STACK POINTER
        LD      A,0FFH          ;
        LD      (FL_FLG),A      ; FLOPPY_BUSY:=FALSE;
        LD      A,5             ;
FITX:   DEC     A               ;
        JP      NZ,FITX         ;
        IN      A,(FDC)         ;
        AND     16              ;
        JP      NZ,FIT1         ;
        CALL    FL06            ; SENSE_INTERRUPT_STATUS;
        JP      FIT2            ;
FIT1:   CALL    RSULT           ; READ_RESULT;
FIT2:   POP     HL              ;
        POP     DE              ; RESTORE GLOBAL STACKPOINTER
        POP     BC              ; RESTORE REGISTERS
        POP     AF              ; RESTORE ACCUMULATOR AND FLAGS
	LD	SP,(SP_SAV)	;
        EI                      ;
        RETI                    ;
        
	PAGE
«eof»