From: Sergey Kiselev Date: Wed, 11 Mar 2015 20:43:43 +0000 (-0700) Subject: p112 and zeta-v2: use common FDC code X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=03fa66a8299ea29836626c793ccf9490427889e8;p=FUZIX.git p112 and zeta-v2: use common FDC code --- diff --git a/Kernel/platform-p112/devfd.c b/Kernel/dev/devfd.c similarity index 99% rename from Kernel/platform-p112/devfd.c rename to Kernel/dev/devfd.c index 34798581..7e9d32db 100644 --- a/Kernel/platform-p112/devfd.c +++ b/Kernel/dev/devfd.c @@ -11,7 +11,7 @@ #include #include #include -#include "devfd.h" +#include /* functions implemented in devfd2.s */ extern int devfd_init(uint8_t minor); diff --git a/Kernel/platform-p112/devfd.h b/Kernel/dev/devfd.h similarity index 100% rename from Kernel/platform-p112/devfd.h rename to Kernel/dev/devfd.h diff --git a/Kernel/platform-zeta-v2/devfd_hw.s b/Kernel/dev/devfd_hw.s similarity index 98% rename from Kernel/platform-zeta-v2/devfd_hw.s rename to Kernel/dev/devfd_hw.s index 280fe03d..7db48278 100644 --- a/Kernel/platform-zeta-v2/devfd_hw.s +++ b/Kernel/dev/devfd_hw.s @@ -6,6 +6,11 @@ .module devfd_hw +CPU_Z180 .equ Z80_TYPE-2 +.ifeq CPU_Z180 + .z180 +.endif + ; imported symbols .globl map_kernel .globl map_process_always @@ -22,9 +27,10 @@ .globl _devfd_userbuf .globl _fd_tick - .include "kernel.def" + .include "../platform/kernel.def" .include "../kernel.def" + ;------------------------------------------------------------------------------ .area _CODE @@ -332,12 +338,15 @@ Setup: LD A,(drive) LD A,#0x01 ; Else set to 300 kbps (@360 rpm = 250kbps) StSiz0: OUT (FDC_CCR),A ; Set Rate in FDC Reg LD D,A ; preserve Rate bits -; FIXME: Sergey - delay should be just a constant? -; IN0 A,(0x1F) ; Read Z80182 CPU Cntrl Reg (B7=1 if Hi Speed) -; RLA ; Speed to Bit Carry..Turbo? - LD A,#(CPU_CLOCK_KHZ/1000) ; (Get Processor Rate in MHz) -; JR C,StSiz1 ; ..jump if Turbo for longer delay - SRL A ; Else divide rate by 2 +.ifeq CPU_Z180 + IN0 A,(0x1F) ; Read Z80182 CPU Cntrl Reg (B7=1 if Hi Speed) + RLA ; Speed to Bit Carry..Turbo? + LD A,#(CPU_CLOCK_KHZ/1000) ; (Get Processor Rate in MHz) + JR C,StSiz1 ; ..jump if Turbo for longer delay +.else + LD A,#(CPU_CLOCK_KHZ/1000) ; (Get Processor Rate in MHz) +.endif + SRL A ; Divide rate by 2 StSiz1: INC D DEC D ; 500 kb/s (Hi-Speed) Rate (D=0)? JR NZ,StSiz2 ; ..jump if Not diff --git a/Kernel/platform-p112/Makefile b/Kernel/platform-p112/Makefile index a7c80e19..2f9d0ef7 100644 --- a/Kernel/platform-p112/Makefile +++ b/Kernel/platform-p112/Makefile @@ -1,16 +1,19 @@ -ASRCS = crt0.s z180.s commonmem.s p112.s ds1302-p112.s devfd2.s monitor.s flopboot.s -CSRCS += devices.c main.c devtty.c devfd.c +ASRCS = crt0.s z180.s commonmem.s p112.s ds1302-p112.s monitor.s flopboot.s +CSRCS += devices.c main.c devtty.c DISCARD_CSRCS = discard.c DISCARD_DSRCS = ../dev/devide_discard.c ../dev/ds1302_discard.c -DSRCS = ../dev/blkdev.c ../dev/devide.c ../dev/mbr.c ../dev/ds1302.c +DSRCS = ../dev/blkdev.c ../dev/devide.c ../dev/devfd.c ../dev/mbr.c +DSRCS += ../dev/ds1302.c +DASRCS = ../dev/devfd_hw.s AOBJS = $(ASRCS:.s=.rel) COBJS = $(CSRCS:.c=.rel) DISCARD_COBJS = $(DISCARD_CSRCS:.c=.rel) DISCARD_DOBJS = $(patsubst ../dev/%.c,%.rel, $(DISCARD_DSRCS)) DOBJS = $(patsubst ../dev/%.c,%.rel, $(DSRCS)) +DAOBJS = $(patsubst ../dev/%.s,%.rel, $(DASRCS)) -OBJS = $(AOBJS) $(COBJS) $(DOBJS) $(DISCARD_DOBJS) $(DISCARD_COBJS) +OBJS = $(AOBJS) $(COBJS) $(DOBJS) $(DAOBJS) $(DISCARD_DOBJS) $(DISCARD_COBJS) CROSS_CCOPTS += -I../dev/ @@ -27,6 +30,9 @@ $(COBJS): %.rel: %.c $(DOBJS): %.rel: ../dev/%.c $(CROSS_CC) $(CROSS_CCOPTS) -c $< +$(DAOBJS): %.rel: ../dev/%.s + $(CROSS_AS) $(ASOPTS) $@ $< + $(DISCARD_COBJS): %.rel: %.c $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEGDISC) -c $< diff --git a/Kernel/platform-p112/devfd2.s b/Kernel/platform-p112/devfd2.s deleted file mode 100644 index 03b77690..00000000 --- a/Kernel/platform-p112/devfd2.s +++ /dev/null @@ -1,667 +0,0 @@ -;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -; D-X Designs Pty Ltd P112 Floppy disk Routines -; Copyright (C) 1998 by Harold F. Bower -;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -; 2015-01-17 Will Sowerbutts: Ported to sdas/Fuzix from UZI-180 - - .module devfd2 - .z180 - - ; imported symbols - .globl map_kernel - .globl map_process_always - .globl _devfd_dtbl - - ; exported sybols - .globl _devfd_init - .globl _devfd_read - .globl _devfd_write - .globl _devfd_track - .globl _devfd_sector - .globl _devfd_error - .globl _devfd_buffer - .globl _devfd_userbuf - .globl _fd_tick - - .include "kernel.def" - .include "../kernel.def" - -;------------------------------------------------------------------------------ - .area _CODE - -; 092 - Drive Control Register (Write Only) -; 7 6 5 4 3 2 1 0 -; | | | | | | +-+-- Drive (00=0, 01=1, 10=2, 11=3) -; | | | | | +------ 1 = Normal Opn, 0 = Reset Controller -; | | | | +-------- 1 = Enable DMA Pins, 0 = Disable DRQ,DAK,INT pins -; | | | +---------- 1 = Enable Drive 0 Motor -; | | +------------ 1 = Enable Drive 1 Motor -; | +-------------- 1 = Enable Drive 2 Motor -; +---------------- 1 = Enable Drive 3 Motor -; 093 - (Not Used) -; 094 - Data-Rate Select (Write) / Main Status Register (Read) -; 7 6 5 4 3 2 1 0 (Write) - -; 7 6 5 4 3 2 1 0 (Read) -; | | | | +-+-+-+-- Drives Seeking (0=B0 Set, 1=B1 Set,.. 3=B3 Set) -; | | | +---------- 1 = Command In Progress, 0 = Command Ended -; | | +------------ 1 = Non-DMA Execution, 0 = DMA Execution -; | +-------------- 1 = Read, 0 = Write -; +---------------- 1 = Request for Master, 0 = Internal Execution -; -; 095 - Data/Command Register (Read/Write) -; (Byte Writes/Reads) -; 096 - (Not Used) -; 097 - Data Rate Register (Write) / Disk Changed Bit (Read) -; 7 6 5 4 3 2 1 0 (Write) -; | | | | | | +-+-- 00=500 kb/s, RPM/LC Hi, 01=250/300 kb/s (RPM/LC Lo) -; | | | | | | 10=250 kb/s, RPM/LC Lo, 11=1000 kb/s (RPM/LC Hi/Lo) -; +-+-+-+-+-+------ (Not Used) -; -; 7 6 5 4 3 2 1 0 (Read) -; | +-+-+-+-+-+-+-- (Tri-State, used for HD Controller) -; +---------------- 1 = Disk Changed (latched complement of DSKCHG inp) -; -; 0A0 - DMA I/O Select Port (DMA configuration Only) -;------------------------------------------------------------- -FDCBAS .equ 0x90 ; SMC 37C665 Controller Base Address -DCR .equ FDCBAS+2 ; Drive Control Register -MSR .equ FDCBAS+4 ; Main Status Register -DR .equ FDCBAS+5 ; Data Register -DRR .equ FDCBAS+7 ; Data Rate Register/Disk Changed Bit in B7 - -MONTIM .equ 250 ; Motor On time (Seconds * TICKSPERSEC) - -; Offsets into _devfd_dtbl -oFLG .equ 0 ; logged: 0 = Not Logged, 1 = Drive Logged -oPRM1 .equ 1 ; cbyte0: Step Rate (B7-4), HUT (3-0) -oPRM2 .equ 2 ; cbyte1: Hd Load in 4mS steps (0=infinite) -oGAP3 .equ 3 ; gap3: Gap 3 Length for Read -oSPT .equ 4 ; spt: Sectors-per-Track -oSEC1 .equ 5 ; sector1: First Sector Number -oFMT .equ 6 ; format: Bit-mapped Format byte -oSPIN .equ 7 ; spinup: Spinup delay (1/20-secs) -oTRK .equ 8 ; curtrk: Current Head Position (Track) -oNCYL .equ 9 ; ncyl: Number of cylinders -TBLSIZ .equ 10 ; sizeof() entry in _devfd_dtbl - -;------------------------------------------------------------- -; Determine if the controller exists and a drive is attached -; fdInit (int minor); -; Enter: Drive Minor # is on Stack -; Exit : HL = 0 if All is Ok, Non-Zero if Error - -_devfd_init: - XOR A - LD (motim),A ; Mark Motors as initially OFF - LD (hd),A ; and initially Head #0 - - POP HL ; Return Addr - POP BC ; minor (in C) - PUSH BC ; Keep on Stack for Exit - PUSH HL - LD A,C - LD (drive),A ; Save Desired Device - CP #4 ; Legal? - JR NC,NoDrv ; ..Exit if Error - CALL ActivA ; Else force Reset (B2=0) - LD B,#0 -indel1: DJNZ indel1 ; (settle) - CALL Activ8 ; then bring out of Reset -indel2: DJNZ indel2 ; (settle, B already =0) - IN A,(MSR) - CP #0x80 ; Do we have correct Ready Status? - JR NZ,NoDrv ; ..exit Error if Not - - LD A,(drive) - CALL GetPrm ; Pt to this drive's table entry - PUSH HL - POP IY - LD oFLG(IY), #0 ; Ensure drive is Unlogged - CALL Spec ; Set Controller Params - JR C,NoDrv ; ..Error if TimeOut, Else.. - CALL Recal ; Recalibrate (home) Drive - JR NZ,NoDrv ; ..Error if it failed - LD oFLG(IY), #1 ; Mark drive as active - LD HL,#0 ; Load Ok Status - RET - -NoDrv: LD HL,#0xFFFF ; Set Error Status - RET - -;------------------------------------------------------------- -; This routine Reads/Writes data from buffer trying up to 4 times -; before giving up. If an error occurs after the next-to-last -; try, the heads are homed to force a re-seek. -; -; Enter: Drive Minor # is on Stack. Entry Point sets Read/Write Flag -; Exit : A = 0, Zero Set if Ok, A <> 0, Zero Reset if Errors -; (also returns H = 0 and L set to A for compatibilty with C code) -; Uses : AF,HL - -_devfd_read: - LD A,#1 - .db 0x21 ;..Trash HL, fall thru.. -_devfd_write: - LD A,#0 ; has to be two bytes -- do not optimise to xor a! - LD (rdOp),A - - POP HL ; Return Addr - POP BC ; minor (->C) - PUSH BC ; Keep on Stack for Exit - PUSH HL - LD A,C - LD (drive),A ; Save Desired Device -;; CP 4 ; Legal? -;; JR NC,NoDrv ; ..Exit if Error - - CALL Setup ; Set up subsystem -;;-- LD HL,buffer ; Point to the host buffer -;;-- LD (actDma),HL ; and set Memory Pointer - - LD A,#4 ; Get the maximum retry count -Rwf1: LD (rwRtry),A - LD D,#0xFF ; (Verify needed) - CALL SEEK ; Try to seek to the desired track - JR NZ,Rwf2 ; ..jump if No Good - - LD A,(rdOp) - OR A ; Read operation? - LD A,#0x05 ; Load DP8473 Write Command - JR Z,SWrite ; No, must be Write - INC A ; (A=06H) Load DP8473 Read Command -SWrite: OR #0x40 ; Set MFM Mode Bit - PUSH BC ; Save Regs - LD C,A ; Save - LD B,#9 ; Read/Write Comnds are 9 bytes - - LD A,(eot) ; Get Last Sctr # - PUSH AF ; (save for Exit) - LD A,(sect) ; Get Desired Sector # - LD (eot),A ; make last to Read only one Sector - -;;-- LD HL,(actDma) ; Get actual DMA Addr - ld hl,(_devfd_buffer) ;;-- - CALL FdCmd ; Execute Read/Write - - POP AF ; Restore Last Sctr # - LD (eot),A ; to Comnd Blk - - LD A,(st1) ; Get Status Reg 1 - AND #0x34 ; Return Any Error Bits - POP BC ; Restore Regs - LD (_devfd_error),A ; (store Error bits) - JR Z,FhdrX ; ..jump to return if No Errors - -Rwf2: LD A,(rwRtry) ; Get retry count - CP #2 ; Are we on Next to last try? - CALL Z,Recal ; Return to Track 0 if so - LD A,(rwRtry) ; and re-fetch try count - DEC A ; Do we have more retries left? - JR NZ,Rwf1 ; ..jump to try again if more tries remain - - OR #0xFF ; Else show Error -FhdrX: LD L,A - LD H,#0 - RET ; and Exit - -;------------------------------------------------------------- -; SPEC - Do a Specify Command, setting Step Rate and Head -; Load/Unload Time. Settings require tailoring to Drive. -; -; Enter: IY -> Drive Table entry for current drive -; Exit : Nothing -; Uses : AF,BC - -Spec: CALL WRdyT ; Wait for RQM (hope DIO is Low!), Disable Ints - RET C ; ..Error if Timed Out - LD A,#0x03 ; Do an FDC Specify Command - OUT (DR),A - - CALL WRdyT - RET C ; ..Error if Timed Out - LD A,oPRM1(IY) ; first Rate Byte (Step Rate, HUT) - OUT (DR),A - - CALL WRdyT - RET C ; ..Error if Timed Out - LD A,oPRM2(IY) ; Get Head Load Time - ADD A,A ; Shift value left (doubles count) - INC A ; Set LSB for Non-DMA Operation - OUT (DR),A - XOR A ; Return Ok Flag - RET - -;------------------------------------------------------------- -; RECAL Recalibrate Current "drive" (moves heads to track 0). -; Enter : IY -> Current Drive Table Entry -; Variable "drive" set to desired floppy unit -; Return: A = 0 if Ok, NZ if Error. Flags reflect A -; Uses : AF All other Registers Preserved/Not Affected -; -; NOTE: BC Must be preserved by this routine. - -Recal: LD A,(hd) ; Get head # - ADD A,A - ADD A,A ; Shift to B3 - PUSH HL ; (preserve regs) - LD HL,#drive - OR (HL) ; add Drive bits - POP HL ; (restore regs) - - LD (hdr),A ; in Command Block - LD A,#3 ; Give this 3 chances to Home -Recal1: LD (retrys),A - PUSH BC ; Save needed regs - PUSH HL - LD BC,#(2*256+7) ; (2-byte Recalibrate Comnd = 07H) - CALL FdCmd ; execute Recalibrate - CALL FdcDn ; Clear Pending Ints, Wait for Seek Complete - POP HL ; (restore regs) - POP BC - AND #0x10 ; Homed? (B4=1 if No Trk0 found) - JR Z,RecOk ; ..jump to Store if Ok - LD A,(retrys) - DEC A ; Any trys left? - JR NZ,Recal1 ; ..loop if So - DEC A ; Else set Error Flag (0-->FF) - RET - -RecOk: XOR A ; Get a Zero (track / flag) - LD oTRK(IY),A ; Set in Table - RET ; and return - -;------------------------------------------------------------- -; READID - Read the first Valid Address Mark on a track. -; -; Enter : "hdr" byte set in Command Blk -; Return: A = 0 if Ok, NZ if Error. Flags reflect A -; Uses : AF All other Registers Preserved/Not Affected - -ReadID: LD A,#0x4a ; Load ReadID Command + MFM Mode byte - PUSH BC ; Save regs - LD B,#2 ; two bytes in ReadID Command - LD C,A ; move Command to C - CALL FdCmd ; Activate DP8473 FDC - - LD A,(st1) ; Get Status Reg 1 - AND #0x25 ; Return Any Error Bits - POP BC ; Restore regs - RET ; ..and quit - -;------------------------------------------------------------- -; SETUP - Set parameters necessary to Read/Write from Active Drive -; Enter: Variable "drive" set to current Drive (0..3) -; Variables _devfd_track and _devfd_sector set to desired block address -; Exit : IY -> Drive's Table entry -; Uses : AF,BC,HL - -Setup: LD A,(drive) - PUSH AF - CALL GetPrm ; Pt to Current Drive's Table - PUSH HL - POP IY - POP BC - LD A,(active) ; Get current Activation Byte - AND #0xf0 ; keep only motors - OR B ; add drive bits - CALL Activ8 ; save new byte and activate FDC - LD A,(_devfd_track) ; Get Host Track # - SRL A ; Div by 2 (LSB to Carry) - LD (trk),A ; Physical Track # to Comnd Blk - LD A,#0 - ADC A,A ; LSB becomes Head # - LD (hd),A ; save in Comnd Blk - ADD A,A - ADD A,A ; Shift to B3 - LD HL,#drive - OR (HL) ; add Drive bits - LD (hdr),A ; Save in Comnd Blk - LD A,oGAP3(IY) - LD (gpl),A ; Set Gap3 Length - LD A,oSPT(IY) - LD (eot),A ; Final Sector # on Trk - LD A,oFMT(IY) - AND #3 ; B0/1 of Format byte is Sector Size - LD (rsz),A ; save in Comnd Blk - LD A,#0xFF - LD (dtl),A ; Set Data Length code - LD A,(_devfd_sector) - ADD A,oSEC1(IY) ; Offset Sector # (base 0) by 1st Sector # - LD (sect),A ; set in Comnd Blk - - XOR A ; (Preset Hi 500 kbps, 3.5 & 5.25" Rate) - BIT 7,oFMT(IY) ; Hi (500 kbps) Speed? - JR NZ,StSiz0 ; ..jump if Hi-Density/Speed to Set if Yes - LD A,oFMT(IY) - AND #0x0c ; Else Get Drive size - CP #0x08 ; 5.25"? - LD A,#0x02 ; (Prepare for 250 kbps) - JR NZ,StSiz0 ; ..jump if Not 5.25" w/Rate Set - BIT 4,oFMT(IY) ; Hi-Density capable drive? - LD A,#0x02 ; (Prepare for 250 kbps) - JR Z,StSiz0 ; ..jump if No - LD A,#0x01 ; Else set to 300 kbps (@360 rpm = 250kbps) -StSiz0: OUT (DRR),A ; Set Rate in FDC Reg - LD D,A ; preserve Rate bits - IN0 A,(0x1F) ; Read Z80182 CPU Cntrl Reg (B7=1 if Hi Speed) - RLA ; Speed to Bit Carry..Turbo? - LD A,#(CPU_CLOCK_KHZ/1000) ; (Get Processor Rate in MHz) - JR C,StSiz1 ; ..jump if Turbo for longer delay - SRL A ; Else divide rate by 2 -StSiz1: INC D - DEC D ; 500 kb/s (Hi-Speed) Rate (D=0)? - JR NZ,StSiz2 ; ..jump if Not - LD A,#1 ; Else minimum delay for "High-Speed" -StSiz2: LD (dlyCnt),A ; save delay count - RET - -;------------------------------------------------------------- -; SEEK - Set the Track for disk operations and seek to it. -; -; Enter : A = Desired Track Number -; D = Verify flag (0=No, FF=Yes) -; Return: A = 0, Zero Flag Set (Z) if Ok, A <> 0 Zero Clear (NZ) if Error -; Uses : AF All other Registers Preserved/Not Affected - -SEEK: PUSH HL ; Save Regs used here - PUSH DE - PUSH BC - - LD A,(trk) ; Get Track # - CP oTRK(IY) ; Is desired Track same as last logged? - LD oTRK(IY),A ; (set as if we made it there) - JR NZ,SEEKNV ; ..jump if Not Same - INC D ; Else Set to No Verify (FF->0) -SEEKNV: LD A,#4 ; Get the maximum Retry Count -SEEK1: LD (retrys),A ; save remaining Retry Count - LD BC,#(3*256+0x0F); (3-byte Seek Command = 0FH) - CALL FdCmd ; Execute the Seek - CALL FdcDn ; Clear Pending Int, wait for Seek Complete - - AND #0xE0 - CP #0x20 - JR NZ,SEEK2 ;; - - AND #0x40 ; Set NZ if Abnormal Termination - - LD B,A ;; Save Seek Status - LD A,(trk) ;; Check track # - CP C ;; Same track? - JR NZ,SEEK2 ;; Jump to Retry if NOT - LD A,B ;; Restore Seek Status - - INC D ; Are we Verifying (FF -> 0)? - CALL Z,ReadID ; Read next ID Mark if So - DEC D ; (Correct for Test, 0 -> FF) - - OR A ; Set Status (Seek Status if No ReadID) - JR Z,SEEKX ; ..exit if Ok - -SEEK2: LD A,(retrys) ; Else get trys remaining - DEC A ; Any left (80-track could need two)? - JR NZ,SEEK1 ; ..loop to try again if More - DEC A ; Else set Error Flag (0->FF) - -SEEKX: POP BC ; Restore Regs - POP DE - POP HL - RET - - -;------------------------------------------------------------- -; Check for Proper Termination of Seek/Recalibrate Actions by -; executing a Check Interrupt Command returning ST0 in A. -; Enter: None. Used after Seek/Recalibrate Commands -; Exit : A = ST0 Result Byte, C = PCN result byte -; Uses : AF and C. All other registers preserved/unused - -FdcDn: PUSH HL ; Don't alter regs -FdcDn0: CALL WRdy1 - LD A,#8 ; Sense Interrupt Status Comnd - OUT (DR),A - CALL WRdy1 - IN A,(DR) ; Get first Result Byte (ST0) - LD L,A - CP #0x80 ; Invalid Command? - JR Z,FdcDn0 ; ..jump to exit if So - CALL WRdy1 - IN A,(DR) ; Read Second Result Byte (Trk #) - LD C,A ; ..into C - LD A,L - BIT 5,A ; Command Complete? - JR Z,FdcDn0 ; ..loop if Not - POP HL - RET - -;------------------------------------------------------------- -; MOTOR CONTROL. This routine performs final selection of -; the drive control latch and determines if the Motors are -; already spinning. If they are off, then the Motors are -; activated and the spinup delay time in tenths-of-seconds -; is performed before returning. -; -; Enter : None -; Return: None -; Uses : HL. Remaining Registers Preserved/Not Affected - -Motor: PUSH AF ; Save Regs - LD A,(motim) ; Get remaining Seconds - OR A ; Already On? - LD A,#MONTIM ; (get On Time) - LD (motim),A ; always reset - JR NZ,MotorX ; ..exit if already running - PUSH BC - LD A,(hdr) ; Get current Drive - OR #0xF4 ; Set All Motors On and Controller Active - CALL Activ8 ; Do It! - LD A,(drive) ; Get Current drive - CALL GetPrm ; Pt to Param table - LD BC,#oSPIN - ADD HL,BC ; offset to Spinup Delay - LD A,(HL) ; Get value - LD (mtm),A ; to GP Counter - EI ; Ensure Ints are ABSOLUTELY Active.. -MotoLp: LD A,(mtm) ; ..otherwise, loop never times out! - OR A ; Up to Speed? - JR NZ,MotoLp ; ..loop if Not - DI ; No Ints now.. - POP BC -MotorX: POP AF ; Restore Reg - RET - -;------------------------------------------------------------- -; Wait for FDC RQM to become Ready with Timeout indicator. -; Timeout Length is arbitrary and depends on CPU Clock Rate. - -WRdyT: ;DI ; No Ints while we are doing I/O - LD BC,#30000 ; << Arbitrary >> -WRdyT0: DEC BC - LD A,B - OR C ; Timed Out? - SCF ; (set Error Flag in case) - RET Z ; ..return Error Flag if Yes - IN A,(MSR) ; Read Status Reg - AND #0x80 ; Interrupt Present (also kill Carry)? - RET NZ ; ..return Ok if Yes - JR WRdyT0 ; ..else loop to try again - -;------------------------------------------------------------- -; Return Pointer to Parameters of selected Drive -; Enter: A = Drive (0..3) -; Exit : HL -> Parameter entry of drive -; Uses : AF,HL - -GetPrm: PUSH DE - LD DE,#TBLSIZ ; Entry Size - LD HL,#_devfd_dtbl ; Init to table start - INC A -GetPr0: DEC A ; End? - JR Z,GetPrX ; ..quit if Yes, Ptr set - ADD HL,DE ; Else step to next - JR GetPr0 ; ..loop til found - -GetPrX: POP DE - RET - -;------------------------------------------------------------- -; This routine called at each Clock Interrupt. It is used -; to provide any necessary timer/timeout functions. -; Enter: None. -; Exit : HL -> mtm byte variable -; AF - destroyed -; Uses : AF,HL - -_fd_tick: - LD HL,#motim ; Point to FDC Motor-On timer - LD A,(HL) - OR A ; Already Timed out? - JR Z,TDone ; ..jump if Yes - DEC (HL) ; Else count down - CALL Z,MotOff ; stop motors if timed out -TDone: INC HL ; Advance ptr to watchdog/spinup timer (mtm) - LD A,(HL) - OR A ; Timed out? - RET Z ; ..quit if Yes - DEC (HL) ; Else count down - RET ; exit - -;------------------------------------------------------------- -; Motor Off routine. Force Off to delay on next select -; Enter: None. (Motoff) -; A = FDC Device Control Reg bits (Activ8/ActivA) -; Exit : A = Current DCR Register / "active" byte settings -; Uses : AF - -MotOff: XOR A - LD (motim),A ; Ensure Motors Marked as OFF - LD A,(active) ; Get current settings - AND #7 ; strip off Motor bits -Activ8: OR #4 ; (ensure FDC out of Reset) -ActivA: LD (active),A ; save - OUT (DCR),A ; and Command! - RET - -;------------------------------------------------------------- -; FDCMD - Send Command to DP-8473 FDC -; Enter: B = # of Bytes in Command, C = Command Byte -; HL -> Buffer for Read/Write Data (If Needed) -; Exit : AF = Status byte -; Uses : AF. All other registers preserved/unused - -FdCmd: PUSH HL ; Save regs (for Exit) - PUSH BC - PUSH DE - - PUSH HL ; save pointer for possible Transfer - CALL Motor ; Ensure motors are On - LD HL,#comnd ; Point to Command Block - LD (HL),C ; command passed in C - LD C,#DR ; DP8473 Data Port - LD A,(_devfd_userbuf) - LD D,A ; store userbuf flag in D -OtLoop: CALL WRdy ; Wait for RQM (hoping DIO is Low) (No Ints) - OUTI ; Output Command bytes to FDC - JR NZ,OtLoop ; ..loop til all bytes sent - POP HL ; Restore Possible Transfer Addr - - CALL FdCmdXfer ; Do the data transfer (using code in _COMMONMEM) - - LD HL,#st0 ; Point to Status Result area -IsGo: CALL WRdy - BIT 4,A ; End of Status/Result? - JR Z,FdcXit ; ..exit if So - BIT 6,A ; Another byte Ready? - JR Z,FdcXit ; ..exit if Not - INI ; Else Read Result/Status Byte - JR IsGo ; ..loop for next -FdcXit: - POP DE ; Restore Regs - POP BC - POP HL - RET - -;------------------------------------------------------------ -; COMMON MEMORY -;------------------------------------------------------------ - .area _COMMONMEM - -; inner section of FdCmd routine, has to touch buffers etc -FdCmdXfer: - BIT 0,D ; Buffer in user memory? - CALL NZ, map_process_always - -FdCi1: CALL WRdy - BIT 5,A ; In Execution Phase? - JR Z,FdCmdXferDone ; ... tidy up and return if not - BIT 6,A ; Write? - JR NZ,FdCi2 ; ... jump if Not to Read - OUTI ; Write a Byte from (HL) to (C) - JR FdCi1 ; check for next byte -FdCi2: INI ; Read a byte from (C) to (HL) - JR FdCi1 ; check for next byte -FdCmdXferDone: - BIT 0,D ; Buffer in user memory? - RET Z ; done if not - JP map_kernel ; else remap kernel and return - -;------------------------------------------------------------- -; Wait for FDC RQM to become Ready, return DIO status in -; Zero Flag. Pause before reading status port (~12 mS -; specified, some assumed in code). - -WRdy: -WRdy1: LD A,(dlyCnt) ; Get delay count -WRdy0: DEC A ; count down - JR NZ,WRdy0 ; for ~6 uS Delay - -WRdyL: IN A,(MSR) ; Read Main Status Register - BIT 7,A ; Interrupt Present? - RET NZ ; Return if So - JR WRdyL ; Else Loop - -dlyCnt: .db (CPU_CLOCK_KHZ/1000) ; Delay to avoid over-sampling status register - -;------------------------------------------------------------ -; DATA MEMORY -;------------------------------------------------------------ - .area _DATA - -drive: .ds 1 ; (minor) Currently Selected Drive -active: .ds 1 ; Current bits written to Dev Contr Reg (DCR) - -_devfd_sector: .ds 1 -_devfd_track: .ds 1 ; LSB used as Head # in DS formats -_devfd_error: .ds 1 -_devfd_buffer: .ds 2 -_devfd_userbuf: .ds 1 - -; DISK Subsystem Variable Storage -comnd: .ds 1 ; Storage for Command in execution -hdr: .ds 1 ; Head (B2), Drive (B0,1) -trk: .ds 1 ; Track (t) -hd: .ds 1 ; Head # (h) -sect: .ds 1 ; Physical Sector Number -rsz: .ds 1 ; Bytes/Sector (n) -eot: .ds 1 ; End-of-Track Sect # -gpl: .ds 1 ; Gap Length -dtl: .ds 1 ; Data Length - -; FDC Operation Result Storage Area -st0: .ds 1 ; Status Byte 0 -st1: .ds 1 ; Status Byte 1 (can also be PCN) - .ds 1 ; ST2 - Status Byte 2 - .ds 1 ; RC - Track # - .ds 1 ; RH - Head # (0/1) - .ds 1 ; RR - Sector # - .ds 1 ; RN - Sector Size - -; -->>> NOTE: Do NOT move these next two variables out of sequence !!! <<<-- -motim: .ds 1 ; Motor On Time Counter -mtm: .ds 1 ; Floppy Spinup Time down-counter - -rdOp: .ds 1 ; Read/write flag -retrys: .ds 1 ; Number of times to try Opns -rwRtry: .ds 1 ; Number of read/write tries -DRVSPD: .ds 1 ; Drive Speed -DRVSIZ: .ds 1 ; Drive Size diff --git a/Kernel/platform-p112/devices.c b/Kernel/platform-p112/devices.c index 10643085..41d75aec 100644 --- a/Kernel/platform-p112/devices.c +++ b/Kernel/platform-p112/devices.c @@ -8,7 +8,7 @@ #include #include #ifdef CONFIG_P112_FLOPPY -#include "devfd.h" +#include #endif struct devsw dev_tab[] = /* The device driver switch table */ diff --git a/Kernel/platform-p112/fuzix.lnk b/Kernel/platform-p112/fuzix.lnk index 38ad9a3e..8b726543 100644 --- a/Kernel/platform-p112/fuzix.lnk +++ b/Kernel/platform-p112/fuzix.lnk @@ -42,5 +42,5 @@ platform-p112/ds1302_discard.rel platform-p112/ds1302-p112.rel platform-p112/monitor.rel platform-p112/devfd.rel -platform-p112/devfd2.rel +platform-p112/devfd_hw.rel -e diff --git a/Kernel/platform-p112/kernel.def b/Kernel/platform-p112/kernel.def index 44c1dd9a..0fd1bac0 100644 --- a/Kernel/platform-p112/kernel.def +++ b/Kernel/platform-p112/kernel.def @@ -19,3 +19,10 @@ TICKSPERSEC .equ 40 ; timer interrupt rate (Hz) PROGBASE .equ 0x0000 PROGLOAD .equ 0x0100 + +; 37C665 FDC ports +FDC_BASE .equ 0x90 ; SMC 37C665 Controller Base Address +FDC_CCR .equ FDC_BASE+7 ; Configuration Control Register (W/O) +FDC_MSR .equ FDC_BASE+4 ; 8272 Main Status Register (R/O?) +FDC_DATA .equ FDC_BASE+5 ; 8272 Data Port (R/W) +FDC_DOR .equ FDC_BASE+2 ; Digital Output Register (W/O) diff --git a/Kernel/platform-zeta-v2/Makefile b/Kernel/platform-zeta-v2/Makefile index 50046b56..7fcdb22e 100644 --- a/Kernel/platform-zeta-v2/Makefile +++ b/Kernel/platform-zeta-v2/Makefile @@ -1,17 +1,20 @@ ASRCS = crt0.s tricks.s commonmem.s zeta-v2.s monitor.s -ASRCS += ds1302-n8vem.s devfd_hw.s devrd_hw.s -CSRCS = devices.c main.c devtty.c devfd.c devrd.c +ASRCS += ds1302-n8vem.s devrd_hw.s +CSRCS = devices.c main.c devtty.c devrd.c DISCARD_CSRCS = discard.c DISCARD_DSRCS = ../dev/ds1302_discard.c -DSRCS = ../dev/devsd.c ../dev/mbr.c ../dev/blkdev.c ../dev/ds1302.c +DSRCS = ../dev/devfd.c ../dev/devsd.c ../dev/mbr.c ../dev/blkdev.c +DSRCS += ../dev/ds1302.c +DASRCS = ../dev/devfd_hw.s AOBJS = $(ASRCS:.s=.rel) COBJS = $(CSRCS:.c=.rel) DISCARD_COBJS = $(DISCARD_CSRCS:.c=.rel) DISCARD_DOBJS = $(patsubst ../dev/%.c,%.rel, $(DISCARD_DSRCS)) DOBJS = $(patsubst ../dev/%.c,%.rel, $(DSRCS)) +DAOBJS = $(patsubst ../dev/%.s,%.rel, $(DASRCS)) -OBJS = $(AOBJS) $(COBJS) $(DOBJS) $(DISCARD_DOBJS) $(DISCARD_COBJS) +OBJS = $(AOBJS) $(COBJS) $(DOBJS) $(DAOBJS) $(DISCARD_DOBJS) $(DISCARD_COBJS) CROSS_CCOPTS += -I../dev/ @@ -28,6 +31,9 @@ $(COBJS): %.rel: %.c $(DOBJS): %.rel: ../dev/%.c $(CROSS_CC) $(CROSS_CCOPTS) -c $< +$(DAOBJS): %.rel: ../dev/%.s + $(CROSS_AS) $(ASOPTS) $@ $< + $(DISCARD_COBJS): %.rel: %.c $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEGDISC) -c $< diff --git a/Kernel/platform-zeta-v2/devfd.c b/Kernel/platform-zeta-v2/devfd.c deleted file mode 100644 index 34798581..00000000 --- a/Kernel/platform-zeta-v2/devfd.c +++ /dev/null @@ -1,168 +0,0 @@ -/*************************************************************** - UZI (Unix Z80 Implementation) Kernel: devflop.c ----------------------------------------------------------------- - Adapted from UZI By Doug Braun, and UZI280 by Stefan Nitschke - Copyright (C) 1998 by Harold F. Bower - Portions Copyright (C) 1995 by Stefan Nitschke -****************************************************************/ -/* 2015-01-17 Will Sowerbutts: Ported from UZI-180 to Fuzix */ -/* Assumes 512-byte sectors, 3.5" 1.44 MB formatted disks */ - -#include -#include -#include -#include "devfd.h" - -/* functions implemented in devfd2.s */ -extern int devfd_init(uint8_t minor); -extern int devfd_read(uint8_t minor); -extern int devfd_write(uint8_t minor); - -/* variables in devfd2.s */ -extern uint8_t devfd_track, devfd_sector, devfd_error, devfd_userbuf; -extern char *devfd_buffer; - -/* D D D D D D D D Format Byte - 7 6 5 4 3 2 1 0 - | | | | | | +-+----- Sector Size: 000=128, 001=256, 010=512, 011=1024 bytes - | | | | +-+--------- Disk Size: 00=fixed disk, 01=8", 10=5.25", 11=3.5" - | | | +------------- 0 = Normal 300 RPM MFM, 1 = "High-Density" Drive - | | +--------------- 0 = Single-Sided, 1 = Double-Sided - | +----------------- 0 = Double-Density, 1 = Single-Density - +------------------- 0 = 250 kbps (normal MFM), 1 = 500 kbps (Hi-Density) */ - -#define IBMPC3 0xAE /* 10101110B HD, DD, DS, 3.5", 512-byte Sctrs (1.44 MB) */ -#define UZIHD3 0xAF /* 10101111B HD, DD, DS, 3.5", 1024-byte Sctrs (1.76 MB) */ -#define IBMPC5 0xAA /* 10101010B HD, DD, DS, 5.25", 512-byte Sctrs (1.2 MB) */ -#define UZIHD5 0xAB /* 10101011B HD, DD, DS, 5.25", 1024-byte Sctrs (1.44 MB) */ -#define DSQD3 0x2F /* 00101111B MFM, DD, DS, 3.5", 1024-byte Sctrs (800 KB) */ -#define DSDD3 0x2E /* 00101110B MFM, DD, DS, 3.5", 512-byte Sctrs (800 KB) */ -#define DSQD5 0x2B /* 00101011B MFM, DD, DS, 5.25", 1024-byte Sctrs (800 KB) */ -#define DSDD5 0x2A /* 00101010B MFM, DD, DS, 5.25", 512-byte Sctrs (800 KB) */ - -struct { - uint8_t logged; /* logged (0xff), unlogged (0) */ - uint8_t cbyte0; /* bits 7-4: step rate (4ms), bits 3-0: HUT (240ms) */ - uint8_t cbyte1; /* head load time in 4ms steps (0=infinite) */ - uint8_t gap3; /* gap3 (size 512 = 27, 1024 = 13) */ - uint8_t spt; /* physical sectors per track */ - uint8_t sector1; /* first sector number */ - uint8_t format; /* format byte */ - uint8_t spinup; /* spinup (1/20-secs) */ - uint8_t curtrk; /* current tranck number */ - uint8_t ncyl; /* number of cylinders x heads */ -} devfd_dtbl[4] = { - { 0, 0xCF, 1, 27, 18, 1, IBMPC3, 10, 0, 160 }, - { 0, 0xCF, 1, 27, 18, 1, IBMPC3, 10, 0, 160 }, - { 0, 0xCF, 1, 27, 18, 1, IBMPC3, 10, 0, 160 }, - { 0, 0xCF, 1, 27, 18, 1, IBMPC3, 10, 0, 160 }, -}; - -static int fd_transfer(bool rwflag, uint8_t minor, uint8_t rawflag) -{ - uint8_t nblocks, blocks; - uint16_t firstblk; - uint16_t retc; - irqflags_t irq; - - switch(rawflag){ - case 0: - nblocks = 1; - devfd_buffer = udata.u_buf->bf_data; - devfd_userbuf = 0; - firstblk = udata.u_buf->bf_blk; - break; - case 1: - nblocks = udata.u_count >> BLKSHIFT; - devfd_buffer = udata.u_base; - devfd_userbuf = 0xFF; - firstblk = udata.u_offset >> BLKSHIFT; - break; -#ifdef SWAPDEV - case 2: - nblocks = swapcnt >> 9; - devfd_buffer = swapbase; - devfd_userbuf = 0xFF; - firstblk = swapblk; - break; -#endif - default: - goto failout; - } - - devfd_track = firstblk / devfd_dtbl[minor].spt; - devfd_sector = firstblk % devfd_dtbl[minor].spt; /* Base 0 Sect # */ - devfd_error = 0; - - if (devfd_track >= devfd_dtbl[minor].ncyl){ - goto failout; - } - - blocks = nblocks; - for (;;) - { - irq = di(); - if (rwflag) - retc = devfd_read(minor); - else - retc = devfd_write(minor); - irqrestore(irq); - - if (retc) - break; - - if(--nblocks == 0) - break; - - if (++devfd_sector > devfd_dtbl[minor].spt) - { - devfd_sector = 0; - ++devfd_track; - } - devfd_buffer += 128 << (devfd_dtbl[minor].format & 3); - } - - if (devfd_error) { - kprintf("fd_%s: error %d track %d sector %d\n", - rwflag ? "read" : "write", devfd_error, devfd_track, devfd_sector); - panic("fd_transfer"); - } - - if (retc) - goto failout; - - return blocks; -failout: - udata.u_error = ENXIO; - return -1; -} - -int fd_read(uint8_t minor, uint8_t rawflag, uint8_t flag) -{ - flag; /* unused */ - return fd_transfer(true, minor, rawflag); -} - -int fd_write(uint8_t minor, uint8_t rawflag, uint8_t flag) -{ - flag; /* unused */ - return fd_transfer(false, minor, rawflag); -} - -int fd_open(uint8_t minor, uint16_t flags) -{ - flags; /* unused */ - - if (devfd_init(minor)) { - udata.u_error = ENXIO; - return -1; - } - - return 0; -} - -int fd_close(uint8_t minor) -{ - devfd_dtbl[minor].logged = 0; /* Mark Drive as logged out */ - return 0; -} diff --git a/Kernel/platform-zeta-v2/devfd.h b/Kernel/platform-zeta-v2/devfd.h deleted file mode 100644 index 2019c576..00000000 --- a/Kernel/platform-zeta-v2/devfd.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __DEVFD_DOT_H__ -#define __DEVFD_DOT_H__ - -/* public interface */ -int fd_read(uint8_t minor, uint8_t rawflag, uint8_t flag); -int fd_write(uint8_t minor, uint8_t rawflag, uint8_t flag); -int fd_open(uint8_t minor, uint16_t flags); -int fd_close(uint8_t minor); -void fd_tick(void); - -#endif diff --git a/Kernel/platform-zeta-v2/kernel.def b/Kernel/platform-zeta-v2/kernel.def index 9715bb7e..ae762f1b 100644 --- a/Kernel/platform-zeta-v2/kernel.def +++ b/Kernel/platform-zeta-v2/kernel.def @@ -24,7 +24,7 @@ CTC_CH3 .equ 0x23 ; CTC channel 3 (PPI interrupt) ; 37C65 FDC ports FDC_CCR .equ 0x28 ; Configuration Control Register (W/O) -FDC_MSR .equ 0x30 ; 8272 Main Status Register (R/O?) +FDC_MSR .equ 0x30 ; 8272 Main Status Register (R/O) FDC_DATA .equ 0x31 ; 8272 Data Port (R/W) FDC_DOR .equ 0x38 ; Digital Output Register (W/O) FDC_TC .equ 0x38 ; Pulse terminal count (R/O) diff --git a/Kernel/tools/bihx.c b/Kernel/tools/bihx.c index b94b18ae..65328039 100644 --- a/Kernel/tools/bihx.c +++ b/Kernel/tools/bihx.c @@ -101,7 +101,7 @@ void split_bihx(char *name) else if (*buf == 'B') save_patch_rule(fr, buf); else - fprintf(stderr, "%s: invalid bihx line.\n", name, buf); + fprintf(stderr, "%s: invalid bihx line: %s.\n", name, buf); } fclose(fp); fclose(fr); @@ -117,6 +117,3 @@ int main(int argc, char *argv[]) close_segs(); bin_segs(); } - - - \ No newline at end of file