Subttl -IBM Soft_Sectored Single_Density Format (5_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 .z80 sd: ;Define the load address of the program in main memory .phase 1030h sdstr: ;Define the starting address of the program PAGE 64 ;---------------------------------------------------------------------- ; Begin Tables ;------------- ; Default Parameter Table (5" Xerox) sdpt: db 0 ;Drive Number db 77 ;Total Number of Tracks db 0 ;Current Track Number db 0 ;Side Number (0 -> 1) db 0 ;Sector Length Code (0 -> 3) db 1 ;Starting Sector Number (0 -> 1) db 27 ;Last Sector Number + 1 db 0E5h ;Fill Byte db 0 ;Starting Track of Write Pre-Compensation db 28h ;Pre-Index Gap (Gap_4) db 1Bh ;Post-Data Field Gap (Gap_3) db 0FFh ;Flag: Skip Index Mark (0=skip, not-0=write) db 0 ;Number of Sides (0=1_Side, 1=2_Sides) ds 3,0 ;Spares ; Entry Points sdjt: jp sde1 ;Fill in parameters jp sde2 ;Format Initial Entry Point jp sde3 ;Format Re:Entry Point jp sde4 ;Format Next Surface (Current Surface Plus One) jp sde5 ;Format Last Surface (Current Surface Minus One) ; Vectors to Parameters sdvt: dw sd1+1 ;Drive number dw sdnul ;Total Number of Tracks dw sd3+1 ;Current Track Number dw sd4+1 ;Current Side Number dw sd5+1 ;Sector Length Code dw sd6 ;Starting Sector Number dw sd7+1 ;Last Sector Number + 1 dw sd8+1 ;Fill byte dw sdnul ;Starting Track of Write Pre-Compensation dw sd10+1 ;Pre-Index Gap (Gap_4) dw sd11+1 ;Post-Data Field Gap (Gap_3) dw sd12+1 ;Flag: Skip Index Mark (0=skip, not-0=write) dw sd13 ;Number of Sides (0=1_Side, 1=2_Sides) dw sdnul ;Spare dw sdnul ;Spare dw sdnul ;Spare PAGE ;---------------------------------------------------------------------- ; Begin Transfer Parameters Routine ;---------------------------------- ; 1) This routine stuffs the values from the parameter table (xxxxpt) ; into the appropriate locations in the code. ; Save the Registers sde1: push bc ;Save The Primary registers push de push hl ld (sds1),sp ;save the stack pointer ; Set up the registers for the transfer loop ld sp,sdvt ;SP:= Vector Table ld de,sdpt ;DE:= Parameter Table ld b,16 ;Counter:= max count ; Move the parameters into the code section sdlp: ld a,(de) ;Repeat pop hl ld (hl),a ; Vector_Location:= Parameter inc de djnz sdlp ;Until (all parameters have been transferred) ; Restore the Registers ld sp,(sds1) ;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 ;-------------------- ; ; Set the byte count sde2: ld d,0 ld a,(sd5+1) ld e,a ;DE:= Offset ld hl,sdbtbl ;HL:= Pointer to Table base add hl,de ld a,(hl) ld (sdint1+1),a ; Select The Drive sd1: ld a,0 ;Second byte filled with proper drive number call sdrive ;Select the new drive ret nz ;Return if wrong value ld a,(iy+2) ;Get the drive pattern bit 2,(iy+0Eh) ;If (Drive is 8") jr nz,sd5dr or 0Fh ; Side 0 and no step command ld (4005h),a ; Update drive control register ld bc,50 call fsdw ; Wait 50 ms for the head to load jr sdcnt1 sd5dr: and 0FEh ;Else ld (4004h),a ; Side 0 no_Step and motor on ld bc,1000 call fsdw ; wait 1 sec for the motor to reach speed sdcnt1: ld (ix+0Bh),0 ;Reset the index counter (A eq 0) set 2,(ix+0eh) ;set the motor status to on call home ;Calibrate the head(s) ld hl,status ;HL:= Pointer to the status register bit 5,(hl) ;If (Track 0 Flag ne Active) jr z,snrext ; Return Error (82h - Drive not Ready) bit 5,(iy+0Eh) ;If (drive has a ready line) jr nz,sdcnt2 bit 7,(hl) ; If (drive is not ready) snrext: ld a,82h ; ret z ; Return Error (82h) sdcnt2: bit 6,(hl) ;If (Drive is write protected) ld a,90h ;Write protect error code ret nz PAGE ; Re:Entry Point ;--------------- ; sde3: ld (ix+0Bh),0 ;Reset the index counter (A eq 0) ld a,(sd6) ld (sdint2+1),a ;Set the Starting Sector Number ; Find the proper track ld a,(sd3+1) ;Get the new track cp (iy+1) ;Compare with current track call nz,seek ;Do track seek if necessary ; Setup the Write Control Byte (4006h) ld a,44h bit 2,(iy+0Eh) ;If (Drive is 5") jr z,sdcnt3 or 00100000b ; Set MINI to true sdcnt3: ld (sdint3+1),a ;Set the Write Control byte (4006h) ; Select the proper side ld a,(iy+2) or 0Ch ;Turn off step command and 0FDè ;Deselect the side ld b,a ld a,(sd4+1) ;(must be either 0 or 1) sla a ;A:= Side-Number shifted into bit 2 and 02 xoò 0² ;(Bit_²: Side_1=1» Side_2=0© or b ld hl,4004h ;HL:= Pointer to 5" Control Port bit 2,(iy+0Eh) ;If (Drive is 8") jr nz,sdin inc hl ; HL:= Pointer to 8" Control Port sdin: ld (hl),a ;Select the Current side ld hl,diskd ;Controller data register ld de,contrl ;Control register ; Sync with the index sdlbl1: ld a,(status) and INDEX jr nz,sdlbl1 ;Wait for no index pulse sdlbl2: ld a,(status) and INDEX jr z,sdlbl2 ;Wait for leading edge of new index pulse ld a,90h ;Clear the crc register & turn on write gate ld (de),a ;Change modes sdint3: ld a,44h ;Single density & start bit ld (4006h),a ;Start the controller PAGE ; Write the Index Mark ;--------------------- ; FF(40), 00(6), FC(1), 4E(26) ; sd10: ld b,28h ;Preamble length sdlbl3: ld (hl),0FFh djnz sdlbl3 ;Write the preamble sd12: ld a,0FFh ;If (flag eq Skip-Index-Mark) or a jp z,smloop ; goto Write a sector ld a,80h ;16 bit write mode ld (de),a ;Change modes ld b,0ch ;Zero preamble length sdlbl4: ld (hl),0AAh ;Half a zero cell djnz sdlbl4 ;Write the zero preamble ld (hl),0F7h ;First half of fc ld a,90h ;8 bit write mode ld (de),a ;Change modes ld (hl),7Ah ;Second half of fc ld b,1ah ;Postamble length sdlbl5: ld (hl),0ffh djnz sdlbl5 ;Write the postamble PAGE ; Write a Header ;--------------- ; 00(6), FE(1), Track, Side, Sector, Size, CRC(2), FF(11) ; smloop: ld a,80h ;16 bit write mode ld (de),a ;Change modes ld b,0ch ;Sector header preamble length sdlbl6: ld (hl),0aah ;Half a zero cell djnz sdlbl6 ;Write the preamble ld a,81h ;Enable crc & 16 bit write ld (de),a ;Change modes ld (hl),0f5h ;First half of fe ld a,91h ;Enable crc & 8 bit write ld (de),a ;Change modes ld (hl),7eh ;Second half of fe nop nop sd3: ld (hl),0 ;Write the track nop nop sd4: ld (hl),0 ;Write the side byte nop nop sdint2: ld (hl),1 ;Write the sector number nop nop sd5: ld (hl),0 ;Write the sector length code ld a,0a1h ld (de),a ;Change modes ld (hl),a nop nop ld (hl),a ;Write the crc bytes ld a,90h ;Reset the crc ld (de),a ;Change modes ld b,0bh ;Sector header postamble length sdlbl7: ld (hl),0ffh djnz sdlbl7 ;Write the postamble PAGE ; Write the Data Field ;--------------------- ; 00(6), FB(1), Fill-Byte(128-1024), CRC(2), FF(27) ; ld a,80h ;16 bit write mode ld (de),a ;Change modes ld b,0ch ;Data field preamble length sdlbl8: ld (hl),0aah ;Half a zero cell djnz sdlbl8 ;Write the preamble ld a,81h ;Enable crc & 16 bit write ld (de),a ;Change modes ld (hl),0f5h ;First half of fb ld a,91h ;8 bit write ld (de),a ;Change modes ld (hl),6fh ;Second half of fb sdint1: ld b,20h ;Sector_data_field_length/4 sd8: ld a,0E5h ;Fill Byte sdlbl9: ld (hl),a nop nop ld (hl),a nop nop lä (hl),a nop nop ld (hl),a djnz sdlbl9 ;Write the data field ld a,0a1h ld (de),a ;Change modes ld (hl),a nop nop ld (hl),a ;Write the crc bytes ld a,90h ;Reset the crc ld (de),a ;Change modes ld a,(sdint2+1) inc a lä (sdint2+1),á ;Sector_Number:= Sector_Number + 1 ld (hl),0FFh ; sd7: cp 1bh ;If (all Sector have been written [26=default]) jr z,sdlblb ; Goto Write Postamble sd11: lä b,1Bè ;Sector Postamblå lengtè dec b ;(adjust length) sdlblaº lä (hl),0FFh djnz sdlbla ;Write the sector postamble jp smloop PAGE ; Write the Postamble ;-------------------- ; FF(to the start of the index) ; sdlblb: ld (hl),0FFh ;Write a fill byte ld a,(status) and INDEX jr z,sdlblb ;Wait for the index hole ld (hl),0FFh ;Trailing byte xoò a ld (de),a ;Turn off write gate ld a,6 ld (4006h),a ;Turn off the controller call fsd1ms ;Delay 1 millisecond before returning ld a,40h ;Status code ret ;---------------------------------------------------------------------- ; Time Delay Routines ;-------------------- ; ; Wait the time Specified in the BC register pair ;------------------------------------------------ ; fsdw: call fsd1ms ;Repeat dec bc ; Wait a millisecond ld a,b or c jr nz,fsdw ;Until (Time_Delay eq 0) ret ; Delay 1 Millisecond ;-------------------- ; fsd1ms: push bc ld b,200d ;B:= Tic-Count sdllp: ld a,a ;Repeat djnz sdllp ;Until (Tic-count eq 0) pop bc ret PAGE ;---------------------------------------------------------------------- ; Format the Next Surface ;------------------------ ; sde4: ld a,(sd13) ld b,a ;B:= Max Surface Number ld a,(sd4+1) inc a ;Current_Surface:= Current_Surface + 1 cp b ;If (Current_Surface le Max_Surfaces) jp m,sds41 jp z,sds41 ld a,(sd3+1) ;Else inc a ld (sd3+1),a ; Track_Number:= Track_Number + 1 ld a,0 ; Surface:= 0 sds41: ld (sd4+1),a ;Update Surface Number call sde3 ;Format the Track ret ;Return with track value ;---------------------------------------------------------------------- ; Format the Last Surface ;------------------------ ; sde5: ld a,(sd4+1) dec a ;Current_Surface:= Current_Surface - 1 jp p,sds51 ;If (Current_Surface lt Zero) ld a,(sd3+1) dec a ; Track_Number:= Track_Number - 1 ld (sd3+1),a ld a,(sd13) ; Surface:= Max Surface Number sds51: ld (sd4+1),a ;Update Surface Number call sde3 ;Format the Track ret ;Return with track value ;---------------------------------------------------------------------- ; Data Area ;---------- ; sd6: db 1 ;First Sector Number sd13: db 0 ;Maximum Surface Number sdnul: db 0 ;null parameter location sds1: dw 0 ;save location for the stack pointer ;Table of Bytes per Sector/4 sdbtbl: db 128/4 ;20 = 128 Bytes (single density standard) db 256/4 ;40 = 256 Bytes db 512/4 ;80 = 512 Bytes äb LOW (1024/4) ;0 = 1024 Bytes sdend: ;Define the ending address of the program .dephase end