Subttl -North Star Hard_Sectored Double_Density Format (6_Jul_83) ;================================================================ ; ; Internal DJDMA Routines home equ 0a0h ;DJDMA Home Routine seek equ 0a3h ;DJDMA Seek Routine sdrive equ 0a6h ;DJDMA Select Drive Routine hsync equ 0a9h ;DJDMA Hole Sync. Routine (hard sectored disks only) ; Registers diskd equ 4001h ;Disk Data Port status equ 4003h ;Status Register Location on DJDMA board contrl equ 4007h ;Disk Control Port ; Bit Masks for the disk status port (4003h) INDEX equ 10h ;Index Pulse Mask WRTPRO equ 40h ;Write Protected DREADY equ 80h ;Drive Ready .z80 nsd: ;Define the starting address of the program .phase 1030h nsdstr: ;Define the starting address of the code PAGE ;---------------------------------------------------------------------- ; Begin Tables ;------------- ; Parameter Table nsdpt: db 4 ;Drive Number db 40 ;Total Number of Tracks dâ ° ;Currenô Tracë Number db 0 ;Side Number db 0 ;(Sector Length Code) db 0 ;(Starting Sector Number) db 0 ;(Last sector Number + 1) db 0E5h ;Fill Byte db 0 ;(Starting Track of Write Pre-Comp) db 0 ;(Pre-Index Gap (Gap_4)) db 0 ;(Post-Data Field Gap (Gap_3)) db 0 ;(Flag: Skip Index Mark (0=skip, Not-0=write)) db 1 ;Number of Sides (0=1_Side, 1=2_Sides) ds 3,0 ;Spares ; Entry Points nsdjt: jp nsde1 ;Fill in parameters jp nsde2 ;Format Initial Entry Point jp nsde3 ;Format Re:Entry Point jp nsde4 ;Format Next Surface (Current Surface Plus One) jp nsde5 ;Format Last Surface (Current Surface Minus One) ; Vectors to Parameters nsdvt: dw nsde2+1 ;Drive number (nsform) dw nsd2 ;Total Number of Tracks dw nsd3 ;Current Track Number dw nsd4 ;Current Side Number dw nsdnul ;Sector Length Code - NULL dw nsdnul ;Starting Sector Number - NULL dw nsdnul ;Last sector Number + 1 - NULL dw nsd8+1 ;Fill Byte (data) dw nsdnul ;Starting Track of Write Pre-Comp - NULL dw nsdnul ;Pre-Index Gap (Gap_4) - NULL dw nsdnul ;Post-Data Field Gap (Gap_3) - NULL dw nsdnul ;Flag: Skip Index Mark (0=skip, Not-0=write) - NULL dw nsd13 ;Number of Sides (0=1_Side, 1=2_Sides) dw nsdnul ;Spare dw nsdnul ;Spare dw nsdnul ;Spare PAGE ;---------------------------------------------------------------------- ; Begin The Transfer Parameters Routine ;-------------------------------------- ; 1) This routine stuffs the values from the parameter table (xxxxpt) ; into the appropriate locations in the code. ; Save the Registers nsde1: push bc ;Save The Primary registers push de push hl ld (nsds1),sp ;save the stack pointer ; Set up the registers for the transfer loop ld sp,nsdvt ;SP:= Vector Table ld de,nsdpt ;DE:= Parameter Table ld b,16 ;Counter:= max count ; Move the parameters into the code section nsdlp: ld a,(de) ;Repeat pop hl ld (hl),a ; Vector_Location:= Parameter inc de djnz nsdlp ;Until (all parameters have been transferred) ; Restore the Registers ld sp,(nsds1) ;Restore the stack pointer pop hl pop de pop bc ;Restore the register set ld a,40h ;Flag:= Normal Status ret ;Return PAGE ;---------------------------------------------------------------------- ; Begin The Format Routine ;------------------------- ; ; Initial Entry Point ;-------------------- ; nsde2: ld a,0 ;Select the drive call sdrive ;If (drive is non-Existant) ret nz ; Error Return (81h) Bad Drive Number ld a,(iy+2) ;A:= Drive_Pattern or 0eh ;(Mask out step, side-select & direction bits) ld (4004h),a ;Select the drive ld bc,1000 call nsdw ;Wait 1 second for motor to come up to speed ld (ix+0bh),0 ;Reset the index counter set 2,(ix+0eh) ;set the motor status to on call hsync ;Synchronize with the disk index hole nsexit: ld a,82h ;If (Disk not turning/Not Ready) ret z ; Error Return (82h) Not Ready call home ;Home the disk heads bit 5,(hl) ;If (heads failed to home) jr z,nsexit ; goto Not_Ready error exit ld b,3 ;Loop_Counter:= Number of table entries ld de,0 ;DE:= Offset ld hl,cnft1 ;HL:= Pointer to Table of Track Sizes nsdlp1: ld a,(nsd2) ;Repeat cp (hl) ; If (Table Entry eq Total Number Tracks) jr z,nsdsk1 ; Break inc de ; offset:= offset + 1 inc hl ; Pointer:= Pointer + 1 djnz nsdlp1 ;Until (Whole table searched) ld a,83h ; (A:= Illegal Track Value Error Code) ret nsdsk1: ld a,(nsd13) ;(A:= Number of Sides - 0 or 1) sla e ;offset:= offset * 2 add a,e ;offset:= offset + Number of sides ld e,a ld hl,cnft2 ;HL:= Start of Drive Configuration Byte Table add hl,de ;HL:= Pointer to Configuration byte ld a,(hl) ld (nsdcnf),a ;Set the Configuration Byte ld a,(4003h) ;If (Disk is Write Protected) and WRTPRO ld a,90h ret nz ; Error Return (90h) Write Protect PAGE ; Re:Entry Point ;--------------- ; nsde3: ld (ix+0bh),0 ;Reset the index count to zero ld a,(nsd3) ;If (Current_Track ne Desired_Track) cp (iy+1) call nz,seek ; Seek Desired_Track ; Select the Proper Side ld a,(iy+2) or 0Ch ;Turn off step command and 0FDh ;Deselect the side ld b,a ld a,(nsd4) ;(Current_side must be 0 or 1) sla a and 02 xor 02 ;(Bit_2: Side_1=1; Side_2=0) or b ld (4004h),a ; Set the Configuration byte (if necessary) ld a,(nsd3) ;If ((Current_Track eq 0) and (side eq 0)) ld b,a ; (Save the track number) ld a,(nsd4) or b ; (OR Crnt_Track_# & Crnt_Side_#) ld a,(nsd8+1) ; (initialize A to the current fill byte) jr nz,ndskp1 ld a,(nsdcnf) ; (Reset A to the Configuration Byte) ndskp1: ld (nsdint+1),a ; Set the configuration byte ld (ix+0ah),80h ;Resync with the disk wsect0: call hsync ;If (disk has stopped turning) jr z,nsexit ; goto Not_Ready error exit xor a cp (ix+0ah) jr nz,wsect0 ;(Wait for sector 0) ld a,90h ld (contrl),a ;Set up the controller (82s105) ld c,0 ;C:= Current_Sector ld (ix+9),c ;De-sync the disk ;Set Write Precompensation ld a,(iy+0fh) ;If (write precomp is NOT user specified) or a jr nz,nsdsk2 ld a,17 ; A:= default start of write pre-comp nsdsk2: ld b,a ld a,(iy+01) cp b ld a,24h ;(A:= pre-comp + DD Control Byte) jr c,nsdsk3 ;If (current track ge start write pre-comp) or 10h ; set write precompensation bit nsdsk3: ld (4006h),a ;Start the controller ld hl,diskd ;HL:= Pointer to Disk Data Port ;Write Sector Pre-amble nxtsct: ld b,20h ;B:= D.D. Count of zero fill zerow: ld (hl),0 ;Repeat Write a zero to the disk ex (sp),hl ; (kill some time) ex (sp),hl djnz zerow ;Until Zero fill has been written PAGE ;Write Data ID Marks ld (hl),0fbh ;Write Data ID Mark ex (sp),hl ;(kill some time) ex (sp),hl ld (hl),0fbh ;Write Data ID Mark ld b,5ch ;Counter:= Number of byte to the config. byte nsd8: ld e,20h ;E:= Fill_Character nsdint: ld d,20h ;D:= Configuration_Byte xor a ;A:= Zero ;Write the first 5Ch Fill Bytes d1loop: ex (sp),hl ;Repeat ex (sp),hl ; (kill some time) ld (hl),e ; Write fill byte xor e rlca djnz d1loop ;Until (5C Bytes written) ld b,0D1h ;Counter:= Remaining Byte count in sector ex (sp),hl ex (sp),hl ld (hl),d ;Write Configuration byte xor d rlca ex Af,Af' ld a,e ld (nsdint+1),a ;(Reset the configuration byte to be fill byte) ex Af,Af' ex (sp),hl ex (sp),hl ld (hl),e ;Write another fill byte xor e rlca ;Write the remaining fill bytes d2loop: ex (sp),hl ;Repeat ex (sp),hl ; (kill some time) ld (hl),e ; Write a Fill Byte xor e rlca ex (sp),hl ex (sp),hl ld (hl),e ; Write another fill byte xor e rlca djnz d2loop ;Until (remaining fill bytes written) ex (sp),hl ex (sp),hl ;(kill some time) ld (hl),a ;Write a zero fill byte PAGE ;Write the Post_Amble iloop: ex (sp),hl ;Repeat ex (sp),hl ; (kill some time) ld (hl),e ; write fill byte ld a,(status) and INDEX jr z,iloop ;Until (Next sector/index hole detected) inc c ;If (there's another sector to format) ld a,0ah cp c jp nz,nxtsct ; GOTO (write next sector) ld a,0 ld (contrl),a ;Turn off the controller (& write gate) call nsd1ms ;Delay 1 Millisecond ld a,40h ;Status:= Normal Return ret PAGE ;---------------------------------------------------------------------- ; Format the Next Surface ;------------------------ ; nsde4: ld a,(nsd13) ld b,a ;B:= Max Surface Number ld a,(nsd4) inc a ;Current_Surface:= Current_Surface + 1 cp b ;If (Current_Surface le Max_Surfaces) jp m,nsd41 jp z,nsd41 ld a,(nsd3) ;Else inc a ld (nsd3),a ; Track_Number:= Track_Number + 1 ld a,0 ; Surface:= 0 nsd41: ld (nsd4),a ;Update Surface Number call nsde3 ;Format the Track ret ;Return with track value ;---------------------------------------------------------------------- ; Format the Last Surface ;------------------------ ; nsde5: ld a,(nsd4) dec a ;Current_Surface:= Current_Surface - 1 jp p,nsd51 ;If (Current_Surface lt Zero) ld a,(nsd3) dec a ; Track_Number:= Track_Number - 1 ld (nsd3),a ld a,(nsd13) ; Surface:= Max Surface Number nsd51: ld (nsd4),a ;Update Surface Number call nsde3 ;Format the Track ret ;Return with track value ;---------------------------------------------------------------------- ; Time Delay Routines ;-------------------- ; ; Wait the time Specified in the BC register pair ;------------------------------------------------ ; nsdw: call nsd1ms ;Repeat dec bc ; Wait a millisecond ld a,b or c jr nz,nsdw ;Until (Time_Delay eq 0) ret ; Delay 1 Millisecond ;-------------------- ; nsd1ms: push bc ld b,200d ;B:= Tic-Count nsd1lp: ld a,a ;Repeat djnz nsd1lp ;Until (Tic-count eq 0) pop bc ret PAGE ;---------------------------------------------------------------------- ; Data Area ;---------- ; nsd2: db 40 ;Maximum track number nsd3: db 0 ;Current track number nsd4: db 0 ;Current side nsd13: db 1 ;Number of Sides (0=1_Side, 1=2_Sides) nsdnul: db 0 ;Null Parameter Pointer nsds1: dw 0 ;Save location for the stack nsdcnf: db 0D0h ;Double Density Double Sided Configuration Byte ;Configuration Table #1 (Number of Tracks) cnft1: db 35 ;35 Tracks db 40 ;40 Tracks db 80 ;80 Tracks ;Configuration Table #2 (Configuration Bytes, Single Sided first) cnft2: db 090h,0F0h ;35 Track Single_Sided/Double_Sided db 0A0h,0D0h ;40 Track Single_Sided/Double_Sided db 0C0h,0E0h ;80 Track Single_Sided/Double_Sided nsdend: ;Define the ending address of the code .dephase end