DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1 ;======================================================================= TITLE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs ;======================================================================= .Z80 ;Written in Z80 Assembly Language 0000' ASEG ;Absolute Code Segment ORG 0 ;Starting Address is Zero ;---------------------------------------------------------------------- ;System Equates ;-------------- ; ; Constants 000A MAXHS5 EQU 10 ;Maximum number of sectors on a 5" hard sectored disk 0032 HLDLY EQU 50 ;Head Load Delay Time (50ms) 03E8 MODLY EQU 1000 ;Motor On Delay Time (1 Sec) ;Addresses 1030 STACK EQU 1030H ;Base of Normal Stack Area 132E STKSAV EQU 132EH ;Stack save during READS/WRITES - Deselect time MAIN 13C7 MONRAM EQU 13C7H ;Base of the Monitor Ram Area (extends to 13EF) ; Drive Parameter Table flag definitions 1340 BASEIY EQU 1340H ;Base of the (IY area) drive parameter tables 000E YFLAG EQU 0Eh ;Drive Configuration Byte offset 0000 @VER EQU 0 ; 1 = Sector Header has been verified 0001 @HRD EQU 1 ; 1 = Media is Hard Sectored 0002 @5IN EQU 2 ; 1 = Drive size is five inch 0003 @MOC EQU 3 ; 1 = Motor has on/off control 0004 @DBL EQU 4 ; 1 = Media is Double Density 0005 @NRC EQU 5 ; 1 = Drive doesn't have testable ready line 0006 @NHC EQU 6 ; 1 = Drive can't unload Heads 0007 @HDL EQU 7 ; 1 = Heads are currently loaded ; System Status flag definitions 13F0 BASEIX EQU 13F0H ;Base of the (IX area) System status and control area 000E XFLAG EQU 0Eh ;System Status Byte offset 0000 @SER EQU 0 ; 1 = Serial_Input_Status = Active 0001 @MON EQU 1 ; 1 = Monitor_Status = Active 0002 @MOT EQU 2 ; 1 = Motor_Status = Active 0003 @SCT EQU 3 ; 1 = Sector Count is Calibrated 0004 @HOL EQU 4 ; 1 = Sector/Index Hole has been processed 0005 @FHF EQU 5 ; 1 = First hole found PAGE 64 ;Page Length is 64 Lines DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-1 ; Table of Contents ;------------------ ; ; Misc Vectors, Routines and Tables ; ENTPOC - Reset Entry ; PATC21 - VCO test ; ENTIRQ - Maskable Interrupt Vector ; MULT - Multiply DE * B and return result in HL ; IPLPAT - Handshake Routine for Bootstrapping ; WFLAG - Wait for selected bit in the status reg to assert ; ENTNMI - Non-Maskable Interrupt Entry ; SPT8S - 8" Default Soft Sectored Default Sectors/Track Table ; SPT5S - 5" Default Soft Sectored Number of Sectors/Track ; SPT5H - 5" Default Hard Sectored Number of Sectors/Track ; RPOINT - Entry Vector Tables for Sector R/W Routines ; BRANCH - Vector table ; LOADHL - Load the HL register pair ; DSPTCH - General Purpose Dispatch Routine ; SDELAY - Delay while counting Sector/Index holes ; DLY1MS - Delay 1 millisecond ; DLYnMS - Delay n milliseconds ; CSTART - Start the Controller ; CSTOP - Stop the Controller ; ; Major Entry Routines ; POC - Power on Clear (Reset) Entry ; REXEC - Normal Command Completion Re:Entry Point ; EXEC - Normal Entry point after an Non-Maskable_Interrupt ; TRMCER - Termination by Channel Error ; TRMHLT - Termination by Halt (HALTC) or Illegal Command ; TRMIRQ - Termination by Set Interrupt Request Command (INTRQC) ; MAIN - Main Entry Point to Controller ; ; Controller Commands ; SETCRC - Set CRC Error Retry Count ; SETLFT - Set Head Unload Time-Out ; TRACKZ - Set Track Size ; SETDP - Set The Disk's Parameters ; SETMP - Set The Media's Parameters ; LOGICAL - Change Logical Drives ; SETDMA - Set DMA Address ; SETCCW - Set Channel Command Word Address ; SETCAW - Branch in Channel ; HALTC - Halt Controller ; INTRQC - Set Interrupt Request ; SEROUT - Output to Serial Port ; SRENBL - Seial Input Enable ; DUMPM - Dump Controller Memory ; LOADM - Load Controller Memory ; GOMEM - Execute Controller Routine ; GSTAT - Sense Drive Status ; WRSECT - Write a Sector ; RDSECT - Read a Sector ; WTRACK - Write a Track ; RTRACK - Read a Track PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-2 ; ; Disk Read/Write Support Subroutines ; PREP - Prepare Selected Disk for Reading or Writing ; CDISK - Change Drive Parameter Tables & Decalibrate Drive ; SIMAKE - Get New Drive Constants Table & do a Test Read ; SECTOR - Read/Compare a Sector Header ; HOME - Home the Disk Head(s) ; SEEK - Seek Routine ; STP - Step the disk head once ; FSECT - Find a Sector (Soft Sectored Disk) ; SETXFR - Setup the DMA Address for Disk Transfer ; READS - Read a Sector (5" or 8" Soft Sectored) ; WRITES - Write a Sector (5" or 8" Soft Sectored) ; FSECT5 - Find a Sector (Hard Sectored Disk) ; READ5 - Read a Sector (5" Hard Sectored) ; WRITE5 - Write a Sector (5" Hard Sectored) ; ; Channel Read/Write Routines ; RDCH - Read a Block from the Host's Memory ; WRCH - Write a Block to the Host's Memory ; RBYTE - Read a Byte from the Host's Memory ; WBYTE - Write a Byte to the Host's Memory ; CASTOR - Store the Channel Address ; RCMD - Setup for a Read from the Host's Memory ; WCMD - Setup for a Write from the Host's Memory ; INCIO - Read/Write to Channel & Increment Address ; RESTOR - Restore the Channel Command Address ; ; Serial Input/Output Routines ; HSPIN - Hang until Serial Input is Active ; SPIN - Input a Character from the Serial Port ; SPOUT - Output a Charactor to the Serial Port ; ; Internal Monitor ; MONTR - Monitor main line ; GETC - Get a Character ; GO - Go Execute a Subroutine ; WRITE - Write to Controller Memory ; PRINT - Print the Contents of Controller Memory ; CMDTBL - Command Table for Monitor ; ERROR - Error and Prompt Strings for Monitor ; ; Disk Sector/Index Synchronization Routines ; HSYNC - Hard Sectored Disk Sector/Index Synchronization ; COUNT - Count Sector/Index Holes ; DRVOFF - Deselect the current drive and turn off the motor ; DESEL - Deselect the current drive (but not the motor) ; MOTOFF - Turn off the motor on line ; ; Other Tables ; CTABLE - Command Table ; RTBL - Disk Read Vector Table ; WTBL - Disk Write Vector Table ; SECT8 - Drive Constants Tables ; DRIVE8 - Initial Values for 8" Drive Parameter Tables ; DRIVE5 - Initial Values for 5" Drive Parameter Tables ; CONST - Initial Values for Drive's Scratchpad Area PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-3 ;********************************************************************** ; Reset entry ;************ ; -Execution begins here after a reset or power_on_clear ; 0000 C3 00F9 ENTPOC: JP POC ;---------------------------------------------------------------------- ; VCO test ;--------- ; 0003 DD 21 13F0 PATC21: LD IX,BASEIX 0007 FD 2A 13F0 LD IY,(BASEIX) 000B 3E 40 LD A,40H ;Set mode to read disk data 000D 32 4007 LD (4007H),A 0010 3E 64 LD A,64H ;Single Density 5 1/4" 0012 32 4006 LD (4006H),A 0015 CD 0CC7 CALL HSPIN ;Wait for input to go active 0018 3E 44 LD A,44H ;Single Density 8" 001A 32 4006 LD (4006H),A 001D CD 0CC7 CALL HSPIN ;Wait for input to go active 0020 3E 04 LD A,04H ;Double Density 8" 0022 32 4006 LD (4006H),A 0025 CD 0CC7 CALL HSPIN ;Wait for input to go active 0028 3E 44 LD A,44H ;Single Density 8" 002A 32 4006 LD (4006H),A 002D CD 0CC7 CALL HSPIN ;Wait for input to go active 0030 3E 64 LD A,64H ;Single Density 5 1/4" 0032 32 4006 LD (4006H),A 0035 C3 0CC7 JP HSPIN ;Wait for input to go active ;********************************************************************** ; Maskable Interrupt entry ;************************* ; 1) Execution begins here after any maskable interrupts (caused ; by 'data rq' still being hi when 'bus stb' is issued) ; 0038 C3 1000 ENTIRQ: JP 1000H ;branch to interrupt jump vector ;---------------------------------------------------------------------- ; Multiply DE * B and return result in HL ;---------------------------------------- ; 003B 21 0000 MULT: LD HL,0 ;Result:= Zero 003E B7 OR A ;If (Parameter eq null) 003F C8 RET Z ; Return (no parameter = zero flag set) 0040 47 LD B,A ;B:= Multiplier 0041 19 MULTLP: ADD HL,DE ;Repeat Add increment (DE) to the result (HL) 0042 10 FD DJNZ MULTLP ;Until (Multiplier eq zero) 0044 C9 RET ;(Note that the zero flag is still cleared) PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-4 ;---------------------------------------------------------------------- ; Handshake Routine for Bootstrapping ;------------------------------------ ; This is the handshake routine that is moved into the host computer's ; memory starting at location 38H. ; 0045 IPLPAT: ;This label is used to reference the following handshake routine. .PHASE 038H 0038 21 004A HNDSHK: LD HL,HFLG ;HL:= Pointer to Flag 003B 36 00 LD (HL),0 ;Flag:= 0 003D 7E HLP1: LD A,(HL) ;Repeat 003E B7 OR A ; (get Flag) 003F CA 003D JP Z,HLP1 ;Until (Flag ne zero) 0042 FE 40 CP 40H ;If (Flag ne Normal_Completion) 0044 C2 003D JP NZ,HLP1 ; GOTO Loop 0047 C3 0080 JP 80H ;GOTO Cold Boot Loader 004A FF HFLG: DB 0FFH ;THIS IS A FLAG TO THE LOADER .DEPHASE ;---------------------------------------------------------------------- ; Wait for the selected bit in the status register to go high ;------------------------------------------------------------ ; 1) Enter this routine with the DE pair equal to the max.time delay ; and the L reg set as a mask for the appropriate bit in the status ; register ; 2) Each iteration takes 13.75us ; 0058 1B WFLAG: DEC DE ;Repeat 0059 7A LD A,D ; delay:= delay - 1 005A B3 OR E ; if (delay eq 0) 005B C8 RET Z ; error exit w/zero flag set 005C 3A 4003 LD A,(4003H) ; A:= status register 005F A5 AND L ; if (chosen_bit eq active) 0060 28 F6 JR Z,WFLAG ; 0062 C9 RET ; exit zero flag clear (no error) 0063 DS 66H - $, 0FFH ;********************************************************************** ; Non-Maskable Interrupt entry ;***************************** ; -Execution begins here after an out 0EFh instruction ; 0066 D9 ENTNMI: EXX 0067 08 EX AF,AF' ;save machine status 0068 D1 POP DE ;get the program counter 0069 21 F19B LD HL,-COUNT 006C 19 ADD HL,DE ;test of PC is in the COUNT routine 006D 21 022A LD HL,EXEC ;command processing routine 0070 E5 PUSH HL 0071 30 01 JR NC,SWBANK ;carry => PC in COUNT routine 0073 D5 PUSH DE ;first finish the COUNT routine 0074 D9 SWBANK: EXX 0075 08 EX AF,AF' ;restore machine status 0076 C9 RET PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-5 ;---------------------------------------------------------------------- ; Sector Size Table ;------------------ ; 1) These tables are used by the read track command to 1) figure out ; the default number of sectors per track given a sector size/data ; density and 2) to determine the lowest numbered sector. ; ; 8" Soft Sectored Formats 0077 1A 01 SPT8S: DB 26d, 1 ;26 sectors per track (Single Density) 0079 1A 01 DB 26d, 1 ;26 " " " (Double Density) 007B 0F 01 DB 15d, 1 ;15 " " " (Micronix Standard) 007D 08 01 DB 08d, 1 ;8 " " " (CPM system Standard) ; 5" Soft Sectored Format 007F 05 01 SPT5S: DB 05d, 1 ;5 Sectors per Track (Micro-Decision) ; 5" Hard Sectored Format 0081 0A 00 SPT5H: DB 10d, 0 ;10 Sectors per Track (North Star) ;---------------------------------------------------------------------- ; Entry Vector Tables for Sector Read and Write Routines ;------------------------------------------------------- ; 0083 0A28 RPOINT: DW RZRO ;Read (Soft Sectored) Routine Entry Points 0085 0A24 DW RONE 0087 0A20 DW RTWO 0089 0B22 WPOINT: DW WLOOP ;Write (Soft Sectored) Routine Entry Points 008B 0B1B DW WONE 008D 0B10 DW WTWO 008F DS 0A0H - $, 0FFH ;Put this table at 0A0h for formatdj.com ;---------------------------------------------------------------------- ; Vector Table ;------------- ; 00A0 C3 0855 BRANCH: JP HOME ;Home the Disk Heads 00A3 C3 08AE JP SEEK ;Seek to a track 00A6 C3 0755 JP CDISKA ;Get the current disk parameter table 00A9 C3 00AF JP HPATCH ;Get in sync with a disk 00AC C3 0186 JP IMLOAD ;Re:Initialize 00AF DD CB 0A 7E HPATCH: BIT 7,(IX+0AH) 00B3 CA 0E2B JP Z,HSYNC 00B6 DD CB 0E 9E RES @SCT,(IX+XFLAG) 00BA C3 0E2B JP HSYNC ;---------------------------------------------------------------------- ; Load the HL register pair ;-------------------------- ; 00BD 7E LOADHL: LD A,(HL) 00BE 23 INC HL 00BF 66 LD H,(HL) 00C0 6F LD L,A 00C1 C9 RET PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-6 ;---------------------------------------------------------------------- ; General Purpose Dispatch Routine ;--------------------------------- ; 00C2 E9 DSPTCH: JP (HL) ;Goto the address given in the HL pair ;---------------------------------------------------------------------- ; Delay while counting Sector/Index holes ;---------------------------------------- ; 1) The DE register pair contains the delay count. A count of 22 hex ; is equal to 1 millisecond. ; 2) Each iteration of the loop takes about 45.45us. 12us are spent ; here with the remaining 33.45us spent in the count routine. ; 3) See the table in the Documentation Section (currently at the end ; of this file) for a list of pre-calculated values of SDELAY ; in milliseconds ; 00C3 E5 SDELAY: PUSH HL 00C4 CD 0E65 SDLP1: CALL COUNT ;Repeat 00C7 1B DEC DE ; count any sector holes 00C8 7B LD A,E ; time_delay:= time_delay - 1 00C9 B2 OR D 00CA 20 F8 JR NZ,SDLP1 ;until (time_delay eq 0) 00CC E1 POP HL ;recover the pointer 00CD C9 RET ;---------------------------------------------------------------------- ; Delay one millisecond ;---------------------- ; 1) This routine delays one millisecond before returning. ; 2) None of the registers are altered. ; 00CE C5 DLY1MS: PUSH BC 00CF 06 C8 LD B,200d ;Time delay:= 1 ms 00D1 7F DSSLLP: LD A,A ;Repeat NOP 00D2 10 FD DJNZ DSSLLP ;Until (Time delay eq 0) 00D4 C1 POP BC 00D5 C9 RET ;---------------------------------------------------------------------- ; Delay N milliseconds ;--------------------- ; 1) This routine calls the DLY1MS routine 'DE' times. ; 2) If the DE pair is zero then there is no delay. ; 3) Register Usage: ; A -> General Purpose ; DE -> Initially the number of milliseconds, returned = 0 ; 00D6 7A DLYnMS: LD A,D ;While (Delay ne 0) 00D7 B3 OR E 00D8 C8 RET Z ; (return) 00D9 CD 00CE D10LP: CALL DLY1MS ; Call delay 1 millisecond 00DC 1B DEC DE ; Delay_Count:= Delay_Count - 1 00DD 18 F7 JR DLYnMS PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-7 ;---------------------------------------------------------------------- ; Start the Controller ;--------------------- ; 00DF 3A 1311 CSTART: LD A,(1311H) 00E2 32 4007 LD (4007H),A ;Set up the controller clocks etc 00E5 3A 1310 LD A,(1310H) 00E8 32 4006 LD (4006H),A ;Start the controller 00EB C9 RET ;---------------------------------------------------------------------- ; Stop the controller ;-------------------- ; 00EC E5 CSTOP: PUSH HL ;Save hl pair 00ED 2A 1310 LD HL,(1310H) ;control bytes for 4006 and 4007 00F0 26 00 LD H,0 ;turn off the clocks and write gate 00F2 CB CD SET 1,L ;set controller idle byte 00F4 22 4006 LD (4006H),HL ;send command to controller 00F7 E1 POP HL ;Restore hl pair 00F8 C9 RET ;exit without zero flag set (no error) PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-8 ;====================================================================== ; Power on Clear (Reset) Entry ;============================= ; ; Primary register Initialization 00F9 ED 56 POC: IM 1 ;force restart 7 on interrupt 00FB 32 4000 LD (4000H),A ;reset the interrupt flip-flop 00FE 31 1030 LD SP,STACK ;initialize the stack pointer 0101 21 FFFF LD HL,0FFFFH 0104 22 4004 LD (4004H),HL ;initialize the drive ports 0107 3E C3 LD A,0C3H ;initialize the interrupt vector 0109 32 1000 LD (1000H),A ; (jump instruction) 010C 21 0000 LD HL,0 010F 22 1001 LD (1001H),HL ; (to the reset entry for now) ; Move Read/Write table and Drive Constants Tables into RAM 0112 21 0F2C LD HL,RTBL 0115 11 1290 LD DE,1290H 0118 01 0070 LD BC,DRIVE8-RTBL 011B ED B0 LDIR ;load constants from ROM ; Move Drive Parameter tables into RAM 011D 11 1340 LD DE,BASEIY ;pointer to start of drive tables 0120 06 02 LD B,2 ;number of types of drives 0122 AF XOR A ;start drive numbering with zero 0123 08 EX AF,AF' ;save the drive number 0124 3E 80 FTLOOP: LD A,80H ;select bit for drive zero 0126 0E 04 LD C,4 ;number of drives of a givin type 0128 E5 TILOOP: PUSH HL ;save the ROM pointer 0129 C5 PUSH BC ;save the two counts 012A 01 000E LD BC,0EH ;length of drive table minus two 012D ED A0 LDI ;move the 1st byte of the table 012F ED A0 LDI ;move the 2nd byte of the table 0131 F5 PUSH AF ;save the select bit 0132 AE XOR (HL) ;merge with basic drive pattern 0133 12 LD (DE),A ;store pattern in table 0134 F1 POP AF ;recover the select bit 0135 0F RRCA ;shift right for next drive 0136 13 INC DE ;advance the RAM pointer 0137 23 INC HL ;advance the ROM pointer 0138 08 EX AF,AF' ;recover the drive number 0139 12 LD (DE),A ;store the drive number 013A 3C INC A ;advance the drive number 013B 08 EX AF,AF' ;save the drive number 013C 13 INC DE ;advance the RAM pointer 013D ED B0 LDIR ;load the rest of the table 013F C1 POP BC ;recover the counts 0140 0D DEC C ;decrement the drive count 0141 28 03 JR Z,DISCRD ;zero => ROM pointer to advance 0143 E1 POP HL ;recover the old ROM pointer 0144 18 E2 JR TILOOP ;load the next drive table 0146 E3 DISCRD: EX (SP),HL ;new ROM pointer to TOS 0147 E1 POP HL ;discard the old ROM pointer 0148 10 DA DJNZ FTLOOP ;test for both drive types loaded PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-9 ; Move Global Constants Table into RAM 014A 11 13F0 LD DE,BASEIX ;pointer to start of global constants 014D 01 0010 LD BC,10H ;total number of global constants 0150 ED B0 LDIR ;initialize global constants from ROM ; Initialize command addresses 0152 3E 00 LD A,0 0154 21 0050 LD HL,50H ;pointer to host command byte addr. 0157 22 13C0 LD (13C0H),HL ;Current_Command_Pointer:= 50h 015A 32 13C2 LD (13C2H),A 015D 22 13C4 LD (13C4H),HL ;Initial_Command_Pointer:= 50h 0160 32 13C6 LD (13C6H),A ; Misc Initialization 0163 DD 21 13F0 LD IX,BASEIX ;initialize index registers 0167 FD 2A 13F0 LD IY,(BASEIX) 016B 3E 06 LD A,6 016D 32 1310 LD (1310H),A ;Initialize port 4006's memory image ; Test for Bootstrapping 0170 3A 4003 LD A,(4003H) ;If (terminal/shunt is present) 0173 E6 02 AND 2 0175 C2 0186 JP NZ,IMLOAD 0178 3A 4005 LD A,(4005H) ; set channel to cycle steal mode 017B DD CB 0E CE SET @MON,(IX+XFLAG) ; Monitor_Status:= Active 017F DD CB 0E 86 RES @SER,(IX+XFLAG) ; Serial_Input_Status:= Inactive 0183 C3 02B7 JP MAIN ; do not do boot-strap - goto main ; Begin the Bootstrap Process 0186 DD 21 13F0 IMLOAD: LD IX,BASEIX ;initialize index registers 018A FD 2A 13F0 LD IY,(BASEIX) 018E 31 1030 LD SP,STACK ; Wait one second for the bus to settle down. 0191 11 03E8 LD DE,1000 ;Delay:= 1 second 0194 CD 00D6 CALL DLYnMS ;Do Delay ; Move the first 38 loctions of main memory into controller ram 0197 AF XOR A 0198 47 LD B,A 0199 4F LD C,A ;Main_mem_start:= Location 0 019A 08 EX AF,AF' ;Extended_Page:= 0 019B 11 0038 LD DE,38H ;Byte_Count:= 38h 019E 21 1030 LD HL,STACK ;Controller_Memory_Start:= 1030h 01A1 E5 PUSH HL 01A2 D5 PUSH DE ;(save Byte_Count and Controller_Memory_Start) 01A3 CD 0C4E CALL RDCH ;Move main-memory -> controller-memory PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-10 ; Zero the first 38 locations of main memory 01A6 11 3813 LD DE,3813H ;D:=38(start addr), E:=13(length handshake rtn) 01A9 CD 0C96 CALL WCMD ;Set channel to write 01AC AF XOR A 01AD 4F LD C,A ;Main_mem_start:= 0 01AE CD 0CAD MZLOAD: CALL INCIO ;Repeat Write a zero 01B1 15 DEC D ; Counter:= Counter + 1 01B2 20 FA JR NZ,MZLOAD ;Until (Counter eq 0) ; Move the Handshake routine (HNDSHK) into main memory 01B4 21 0045 LD HL,IPLPAT ;Controller_Memory_Start:= start handshake 01B7 CD 0C62 CALL CWRITE ;Move controller-memory -> main-memory 01BA 3A 4005 LD A,(4005H) ;STOP cycle stealing 01BD CD 0C8B CALL RCMD ;Set channel to read 01C0 0B DEC BC ;Move Main_mem_start back to point at flag ; Wait for the Main CPU to write a zero to the flag location 01C1 ED 79 WPZERO: OUT (C),A 01C3 3A 4002 LD A,(4002H) 01C6 B7 OR A 01C7 20 F8 JR NZ,WPZERO ; Restore the first 38 bytes of main memory 01C9 4F LD C,A ;Main_mem_start:= Location 0 01CA D1 POP DE ;Byte_Count:= 38h 01CB E1 POP HL ;Controller_Memory_Start:= 1030h 01CC CD 0C5F CALL WRCH ;Move controller-memory -> main memory PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-11 01CF 21 1320 BSTART: LD HL,1320H 01D2 06 05 LD B,5 01D4 36 80 LD (HL),80H ;Lo_Byte_DMA_Address:= 80h 01D6 23 DPLOAD: INC HL ;Repeat 01D7 36 00 LD (HL),0 ; set remainder of DMA_Address:=0 01D9 10 FB DJNZ DPLOAD ; Set track,side & sector = 0 01DB 11 4004 LD DE,4004H ;DE:= 8" Drive control port 01DE 01 0104 LD BC,104H ;B:=1(side sel), C:=4(drive select) ; Bootstrap 01E1 3E FF TESTDR: LD A,0FFH 01E3 12 LD (DE),A ;Deselect the current drive 01E4 FD 77 01 LD (IY+1),A ;DeCalibrate the current drive 01E7 78 LD A,B ;Select the port address 01E8 AB XOR E 01E9 5F LD E,A 01EA 3E 04 LD A,4 ;Select the drive 01EC A9 XOR C 01ED 4F LD C,A 01EE C5 PUSH BC ;(Current start-sector and drive) 01EF D5 PUSH DE ;(Current port address 01F0 CD 0393 CALL LOGCAL ;Set the logical drive number 01F3 CD 0752 CALL CDISK ;Install the new drive's parameters 01F6 CD 05B6 CALL PREP ;Prepare for a disk access 01F9 D1 POP DE 01FA C1 POP BC 01FB 28 E4 JR Z,TESTDR ;If any errors then return to selecting a drive 01FD FD 7E 0C LD A,(IY+0CH) 0200 32 1324 LD (1324H),A ;Set Sector Number:= lowest sector number 0203 CD 0442 CALL RDSECT ;Read 1st Sector on Track 0 Side 0 0206 20 C7 JR NZ,BSTART 0208 FD CB 0E 4E BIT @HRD,(IY+YFLAG) 020C C4 0E2B CALL NZ,HSYNC 020F 3E 40 LD A,40H ;A:= Bootstrap completion code 0211 01 004A LD BC,HFLG ;BC:= Pointer to Main Memory 0214 ED 79 OUT (C),A ;Main_Memory:= operation complete 0216 DD CB 0E 8E RES @MON,(IX+XFLAG) ;Monitor_Status:= Inactive 021A DD CB 0E C6 SET @SER,(IX+XFLAG) ;Serial_Input_Status:= Active 021E C3 02B7 JP MAIN ;Goto Start of Main Loop PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-12 ; Normal command completion re:entry point ;----------------------------------------- ; 0221 F5 REXEC: PUSH AF ;save the status 0222 CD 0E65 CALL COUNT ;check for sector hole 0225 F1 POP AF ;recover the status 0226 B7 OR A ;set/reset the zero flag 0227 C4 0C72 CALL NZ,WBYTE ;zero => no status to be reported ; Normal Entry point after an Non-Maskable_Interrupt ;--------------------------------------------------- ; 022A 3A 1310 EXEC: LD A,(1310H) ;port 4006 control byte 022D E6 FE AND 0FEH ;strip off the interrupt bit 022F 32 1310 LD (1310H),A ;restore the control byte 0232 CB CF SET 1,A ;Controller_stop_bit:= set 0234 32 4006 LD (4006H),A PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-13 ;---------------------------------------------------------------------- ; Start of Command Lookup ;------------------------ ; 1) Note that data overrun errors will cause the command processing ; to restart at RELOOK. ; 0237 31 1030 RELOOK: LD SP,STACK ;initialize the command stack pointer 023A 21 0237 LD HL,RELOOK 023D 22 1001 LD (1001H),HL ;Interrupt_Vector:= Retry lookup command 0240 FB EI ;enable interrupts 0241 CD 0C6D CALL RBYTE ;Read the next command from main memory 0244 3A 4002 LD A,(4002H) ;get the data from the channel 0247 21 0ED3 LD HL,CTABLE-4 ;command table pointer 024A 11 0004 LD DE,4 ;entry length 024D 19 LOOKUP: ADD HL,DE ;repeat advance the table pointer 024E F5 PUSH AF ; save the new command 024F 7E LD A,(HL) ; command entry 0250 FE 80 CP 80H ; compare with end of table 0252 CA 0292 JP Z,TRMHLT ; illegal command error exit 0255 F1 POP AF ; recover new command 0256 BE CP (HL) ; compare with table entry 0257 20 F4 JR NZ,LOOKUP ;until (command found) 0259 11 0221 LD DE,REXEC ;Get address of normal termination as return 025C D5 PUSH DE ;Put return address on stack 025D 23 INC HL ;Get address of the command 025E 5E LD E,(HL) ;(low byte) 025F 23 INC HL 0260 56 LD D,(HL) ;(high byte) 0261 D5 PUSH DE ;Put command execution address on stack 0262 23 INC HL ;Pointer:= number of parameters byte 0263 5E LD E,(HL) ;length of command argument list 0264 16 00 LD D,0 0266 21 1323 LD HL,1323H ;HL:= Pointer to the Parameter save area 0269 E5 PUSH HL ;Save Pointer in the Parameter save area 026A CD 0C51 CALL CREAD ;read the arguments from main memory 026D CD 0C81 CALL CASTOR ;save the current channel address 0270 21 0286 LD HL,TRMCER ;Interrupt_Vector:= data_error 0273 22 1001 LD (1001H),HL ;update the interrupt vector 0276 E1 POP HL ;recover Pointer to the Parameter save area 0277 4E LD C,(HL) ;C:= parameter #1 0278 23 INC HL 0279 46 LD B,(HL) ;B:= parameter #2 027A 23 INC HL 027B 7E LD A,(HL) 027C 08 EX AF,AF' ;A':= parameter #3 027D 23 INC HL 027E 5E LD E,(HL) ;E:= parameter #4 027F 23 INC HL 0280 56 LD D,(HL) ;D:= parameter #5 0281 23 INC HL ;L:= parameter #6 0282 CD 00BD CALL LOADHL ;H:= parameter #7 0285 C9 RET ;Execute the command PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-14 ;---------------------------------------------------------------------- ; Command String Termination Entries ;----------------------------------- ; Termination by Channel Error ;----------------------------- ; 0286 3E 91 TRMCER: LD A,91H ;data type channel error code 0288 31 1030 LD SP,STACK ;adjust the stack pointer 028B 32 4000 LD (4000H),A ;clear the interrupt 028E CD 00EC CALL CSTOP ;Insure that the controller is stopped 0291 FB EI ;enable interrupts again ; Termination by Halt (HALTC) or Illegal Command ;----------------------------------------------- ; 0292 08 TRMHLT: EX AF,AF' ;save the completion code 0293 ED 4B 13C4 LD BC,(13C4H) ;Initial command address - low word 0297 3A 13C6 LD A,(13C6H) ;Initial command address - extended page 029A 08 EX AF,AF' ;save the address - high page ; Termination by Set Interrupt Request Command (INTRQC) ;------------------------------------------------------ ; 029B F5 TRMIRQ: PUSH AF ;save the completion code 029C D9 EXX ;save the new address - low word 029D ED 4B 13C0 LD BC,(13C0H) ;current command address - low word 02A1 3A 13C2 LD A,(13C2H) ;current command address - extended page 02A4 D9 EXX ;save current command address - low word 02A5 CD 0C81 CALL CASTOR ;update current command address 02A8 D9 EXX ;recover old address - low word 02A9 08 EX AF,AF' ;save old address - high page 02AA F1 POP AF ;recover completion code 02AB CD 0C96 CALL WCMD ;set up channel for writing 02AE CD 0CAD CALL INCIO ;write the status code 02B1 CD 0C8B CALL RCMD ;set up the channel for reading 02B4 CD 0CAD CALL INCIO ;do a dummy read for interrupts PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-15 ;---------------------------------------------------------------------- ; Main Loop ;---------- ; 02B7 31 1030 MAIN: LD SP,STACK ;Initialize the stack pointer 02BA DD 21 13F0 LD IX,BASEIX ;Pointer to global constants 02BE FD 2A 13F0 LD IY,(BASEIX) ;Pointer to current drive table 02C2 21 0000 LD HL,0 02C5 22 132E LD (STKSAV),HL ;Set the drive select time out constant 02C8 DD CB 0E 56 MNLP1: BIT @MOT,(IX+XFLAG) ;Loop If (Motor_Status eq active) 02CC 28 0F JR Z,MSKP1 02CE CD 0E65 CALL COUNT 02D1 2A 132E LD HL,(STKSAV) ; Time-Out:= Time-Out - 1 02D4 2B DEC HL 02D5 22 132E LD (STKSAV),HL 02D8 7C LD A,H ; If (Time-Out eq 0) 02D9 B5 OR L 02DA CC 0EA4 CALL Z,DRVOFF ; Deselect the drive 02DD DD CB 0E 46 MSKP1: BIT @SER,(IX+XFLAG) ; If (serial port is active) 02E1 28 25 JR Z,MSKP2 02E3 CD 0CCD CALL SPIN ; If (character present) 02E6 20 E0 JR NZ,MNLP1 02E8 AF XOR A ; If (BRK_CHR eq true) 02E9 B1 OR C 02EA 20 09 JR NZ,MSKP10 02EC DD 34 0F INC (IX+0FH) ; Increment break count 02EF 20 04 JR NZ,MSKP10 ; If (count eq MAX) 02F1 DD CB 0E 86 RES @SER,(IX+XFLAG) ; Disable input 02F5 AF MSKP10: XOR A ; Extended page 02F6 08 EX AF,AF' 02F7 79 LD A,C ; Get the character 02F8 01 003E LD BC,3EH ; Address for character 02FB CD 0C96 CALL WCMD 02FE CD 0CAD CALL INCIO ; Write character into memory 0301 3E 40 LD A,40H ; Completion code 0303 CD 0CAD CALL INCIO 0306 18 C0 JR MNLP1 0308 DD CB 0E 4E MSKP2: BIT @MON,(IX+XFLAG) ; Else If (the monitor is active) 030C C4 0D20 CALL NZ,MONTR ; Call the internal Monitor 030F 18 A6 JR MAIN PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-16 ;====================================================================== ; SET CRC ERROR RETRY COUNT ;========================== ; 1) This constant determines the number of retries that will be ; made when a CRC error (either in the sector header or the data ; field) is encountered in a SECTOR read/write. ; 2) The default is 10 decimal. ; 0311 DD 71 0C SETCRC: LD (IX+0CH),C ;Set the Retry Counter Initial Value 0314 AF XOR A ;Return_Status:= None 0315 C9 RET ;====================================================================== ; Set Head Unload Time-Out ;========================= ; 1) This constant determines the number of revolutions made by a ; disk before it is deselected (see the subroutine COUNT). ; 2) The default is 16 decimal. ; 0316 DD 71 0D SETLFT: LD (IX+0DH),C ;Set Head Unload Counter 0319 AF XOR A ;Return_Status:= None 031A C9 RET ;====================================================================== ; SET TRACK SIZE ;=============== ; 1) This routine sets the maximum track number (actually the ; highest track number plus one). ; 2) Notice that CDISK is used to set the IY register to point ; to the start of the drive's parameter table. CDISK will return ; with the zero flag cleared if the drive number was out of range. ; 031B 79 TRACKZ: LD A,C ;drive value 031C 32 1325 LD (1325H),A ;Current_Drive_Number:= Updated 031F C5 PUSH BC ;Save the New Track Size 0320 CD 0752 CALL CDISK ;IY:= Base of current drive parameter table 0323 C1 POP BC ;Restore the Track Size 0324 C0 RET NZ ;If (Drive number eq non-Existant) Error Return 0325 FD 70 00 LD (IY+0),B ;load new track value 0328 3E 40 LD A,40H ;completion code 032A C9 RET PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-17 ;====================================================================== ; SET DRIVE PARAMETERS ;===================== ; 1) This routine sets characteristics that are unique to a certain ; kind of drive. The parameters are ; 1) Drive Number (C reg & 1323h) ; 2) Step Rate (1324h) ; 3) Step Settle Time (1325h) ; 4) Head Load Delay (1326h) ; 5) Motor On Delay (1327h) ; 2) Notice that CDISKA is used to set the IY reg to the start of the ; chosen drive's Parameter Table. ; 032B 79 SETDP: LD A,C ;A:= Drive_Number 032C CD 0755 CALL CDISKA ;Select new DPT and set IY to its start 032F C0 RET NZ ;If (drive eq non-existant) Return Error 0330 11 0022 LD DE,22H ;Scale factor:= 1_m.s. 0333 3A 1324 LD A,(1324H) ;A:= Step_Rate 0336 CD 003B CALL MULT 0339 28 06 JR Z,SETSK1 ;If (parameter ne null) 033B FD 75 04 LD (IY+4),L 033E FD 74 05 LD (IY+5),H ; Set the Step Rate 0341 3A 1325 SETSK1: LD A,(1325H) ;A:= Step_Settle_Time 0344 CD 003B CALL MULT 0347 28 06 JR Z,SETSK2 ;If (parameter ne null) 0349 FD 75 0A LD (IY+0AH),L 034C FD 74 0B LD (IY+0BH),H ; Set the Step Settle Time 034F 3A 1326 SETSK2: LD A,(1326H) ;A:= Head_Load_Delay_Time 0352 B7 OR A 0353 28 07 JR Z,SETSK3 ;If (parameter ne null) 0355 FD 77 06 LD (IY+6),A 0358 FD 36 07 00 LD (IY+7),0 ; Set the Head Load Delay Time 035C 11 000A SETSK3: LD DE,10 ;Scale Factor:= 10_m.s. 035F 3A 1327 LD A,(1327H) ;A:= Motor_On_Delay_Time 0362 CD 003B CALL MULT 0365 28 06 JR Z,SETSK4 ;If (parameter ne null) 0367 FD 75 08 LD (IY+8),L 036A FD 74 09 LD (IY+9),H ; Set the Motor_On_Delay_Time 036D 3E 40 SETSK4: LD A,40H ;Return Status equal Normal Completion 036F C9 RET PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-18 ;====================================================================== ; SET MEDIA PARAMETERS ;===================== ; 1) This command sets the parameters that are specific to the media ; in the drive. The parameters are ; 1) Drive number (C reg) ; 2) Starting Track of Write Precompensation (B' reg) ; 3) Highest Track (A' reg) ; 4) First Sector's Number (E reg) ; 5) Total number of sectors per track (D reg) ; 0370 79 SETMP: LD A,C ;A:= Drive_Number 0371 D9 EXX 0372 CD 0755 CALL CDISKA ;Select new DPT and set IY to its start 0375 D9 EXX 0376 C0 RET NZ ;If (drive eq non-existant) Return Error 0377 FD 70 0F LD (IY+0FH),B ;Save the starting track of precomp. 037A 08 EX AF,AF' 037B B7 OR A 037C 28 03 JR Z,SMPSK1 ;If (Track Number Parameter is Non-Zero) 037E FD 77 00 LD (IY),A ; Save the new Highest Track Number 0381 7B SMPSK1: LD A,E ;If (Sectors per track/Starting Sector given) 0382 B2 OR D 0383 28 0B JR Z,SMPSK2 0385 7B LD A,E 0386 E6 01 AND 00000001B ; (Insure that the sector number = 0 ! 1) 0388 F6 80 OR 10000000B ; Set the MSB to indicate user spec 038A FD 77 0C LD (IY+0CH),A ; Save the first sector's number 038D FD 72 0D LD (IY+0DH),D ; Save the number of sectors per track 0390 3E 40 SMPSK2: LD A,40H ;Normal Completion Code 0392 C9 RET PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-19 ;====================================================================== ; CHANGE LOGICAL DRIVES ;====================== ; 1) This routine command changes the logical ordering of the 8" ; and 5" drives. This is done by changing the drive number that ; is kept for each drive in its Drive Parameter Table (DPT). The ; DPT's for 8" drives come first in memory (starting at location ; BASEIY) and are immediatly followed by the 5" DPT's. The drive ; number is the fourth byte of any given DPT (which are 10h bytes ; long). ; 2) The drive number of the first 8" drive is returned 'ored' with ; the status ; 0393 21 1343 LOGCAL: LD HL,BASEIY+3 ;HL:= pointer to drive number in first DPT 0396 7E LD A,(HL) ;current logical drive number for 1st 8" drive 0397 08 EX AF,AF' ;save 0398 11 0010 LD DE,10H ;table length 039B 06 08 LD B,8 ;drive count 039D 3E 04 LD A,4 ;mask 039F A1 AND C ;mask the data 03A0 77 LOGCAW: LD (HL),A ;load the count 03A1 3C INC A ;advance the count 03A2 E6 07 AND 7 ;modulo 8 03A4 19 ADD HL,DE ;advance the pointer 03A5 10 F9 DJNZ LOGCAW ;decrease the count 03A7 08 EX AF,AF' ;recover original logical drive number 03A8 F6 40 OR 40H ;merge completion code 03AA C9 RET ;exit with no status report ;====================================================================== ; SET DMA ADDRESS ;================ ; 03AB ED 43 1320 SETDMA: LD (1320H),BC ;initialize low order 16 bits of DMA 03AF 08 EX AF,AF' 03B0 32 1322 LD (1322H),A ;initialize high order 8 bits of DMA 03B3 AF XOR A ;zero => no status reported 03B4 C9 RET ;====================================================================== ; SET CHANNEL COMMAND WORD ADDRESS ;================================= ; 03B5 ED 43 13C4 SETCCW: LD (13C4H),BC ;low order 16 bits of channel address 03B9 08 EX AF,AF' 03BA 32 13C6 LD (13C6H),A ;high order 8 bits of channel address 03BD AF XOR A 03BE C9 RET PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-20 ;====================================================================== ; BRANCH IN CHANNEL ;================== ; 03BF CD 0C81 SETCAW: CALL CASTOR ;store the new channel address 03C2 AF XOR A 03C3 C9 RET ;====================================================================== ; HALT CONTROLLER ;================ ; 03C4 3E 40 HALTC: LD A,40H ;normal completion code 03C6 C3 0292 JP TRMHLT ;restore the CCWA and idle ;====================================================================== ; SET INTERRUPT REQUEST ;====================== ; 03C9 3A 1310 INTRQC: LD A,(1310H) ;port 4006 control byte 03CC CB C7 SET 0,A ;Interrupt_request_bit:= set 03CE 32 1310 LD (1310H),A ;restore the control byte 03D1 CB CF SET 1,A ;Controller_stop_bit:= set 03D3 32 4006 LD (4006H),A ;generate an interrupt request 03D6 3A 13C2 LD A,(13C2H) ;extended page byte 03D9 08 EX AF,AF' 03DA ED 4B 13C0 LD BC,(13C0H) ;channel address - low word 03DE CD 0CB4 CALL INCR3 ;do a 24 bit increment 03E1 3E 40 LD A,40H ;completion code 03E3 C3 029B JP TRMIRQ ;update channel address & write code ;====================================================================== ; OUTPUT TO SERIAL PORT ;====================== ; 03E6 79 SEROUT: LD A,C ;ASCII character to accumulator 03E7 CD 0CEF CALL SPOUT ;transmit the character 03EA 3E 40 LD A,40H ;completion code 03EC C9 RET ;exit ;====================================================================== ; SERIAL INPUT ENABLE ;==================== ; 1) Parameter 1 is in the C register and is equal to: ; 0 - if the serial port is to be disabled ; 1 - if the serial port is to be enabled ; 03ED DD CB 0E 86 SRENBL: RES @SER,(IX+XFLAG) ;Serial_Input_Enabled:= False 03F1 CB 41 BIT @SER,C ;If (Serial_Input is to be enabled) 03F3 28 04 JR Z,SRESKP 03F5 DD CB 0E C6 SET @SER,(IX+XFLAG) ; Serial_Input_Enabled:= true 03F9 AF SRESKP: XOR A 03FA C9 RET ;return with no status report PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-21 ;====================================================================== ; DUMP CONTROLLER MEMORY ;======================= ; 03FB CD 0C96 DUMPM: CALL WCMD ;set up channel for writing 03FE CD 0C62 CALL CWRITE ;transfer data from controller to host 0401 AF XOR A 0402 C9 RET ;====================================================================== ; LOAD CONTROLLER MEMORY ;======================= ; 0403 CD 0C51 LOADM: CALL CREAD ;transfer data from host to controller 0406 AF XOR A ;set zero flag for no status report 0407 C9 RET ;====================================================================== ; EXECUTE CONTROLLER ROUTINE ;=========================== ; 0408 C5 GOMEM: PUSH BC ;put branch address on the stack 0409 C9 RET ;branch to desired routine ;====================================================================== ; SENSE DRIVE STATUS ;=================== ; 040A 79 GSTAT: LD A,C ;drive number 040B 32 1325 LD (1325H),A ;set up for CDISK routine 040E CD 0752 CALL CDISK ;change drives if necessary 0411 20 16 JR NZ,STPUSH ;illegal drive condition 0413 FD 7E 01 LD A,(IY+1) ;get current track value 0416 FE FF CP 0FFH 0418 20 02 JR NZ,STOTRK 041A 3E 01 LD A,1 041C 32 1323 STOTRK: LD (1323H),A ;Jam the 'new track register' to track 1 041F 32 1324 LD (1324H),A ;(Make sure we select side zero - MSB = 0) 0422 CD 05B6 CALL PREP ;ready the drive for data transfer 0425 28 02 JR Z,STPUSH ;zero => error drive access 0427 3E 40 LD A,40H ;normal completion code 0429 F5 STPUSH: PUSH AF ;save completion code 042A FD 7E 0E LD A,(IY+YFLAG) ;drive configuration byte from DPT 042D CD 0C72 CALL WBYTE ;send byte to the channel 0430 3A 1319 LD A,(1319H) ;sector length code 0433 CD 0C72 CALL WBYTE 0436 3A 4003 LD A,(4003H) ;status byte 0439 CD 0C72 CALL WBYTE 043C F1 POP AF ;recover completion code 043D C9 RET PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-22 ;====================================================================== ; Read/Write a Sector ;==================== ; ; Begin 'write sector' command 043E 0E 08 WRSECT: LD C,8 ;offset into transfer function table 0440 18 02 JR RDSECT+2 ; Begin 'read sector' command 0442 0E 00 RDSECT: LD C,0 0444 CD 0752 CALL CDISK ;change the drive if required 0447 C0 RET NZ ;non-existant drive error exit 0448 06 0A LD B,0AH ;retry count for header reads 044A C5 PRLOOP: PUSH BC ;save the parameters 044B CD 05B6 CALL PREP ;select drive, load head, test header 044E C1 POP BC ;recover the parameters 044F 20 06 JR NZ,PREPOK ;non-zero => no errors 0451 FE 8D CP 8DH ;test for CRC error in header read 0453 C0 RET NZ ;zero => CRC error in sector header 0454 10 F4 DJNZ PRLOOP ;test for 10 retrys 0456 C9 RET ;error exit 0457 3A 1324 PREPOK: LD A,(1324H) ;load the new sector 045A 47 LD B,A ;save the side bit 045B E6 7F AND 7FH ;strip off the side select bit 045D 32 1318 LD (1318H),A ;initialize the sector number in sector image 0460 3E 80 LD A,80H ;side bit mask 0462 A0 AND B 0463 07 RLCA ;move side bit into bit 0 0464 32 1317 LD (1317H),A ;initialize side byte in sector image 0467 FD CB 0E C6 SET @VER,(IY+YFLAG) ;set the no verify flag 046B CD 0C96 CALL WCMD ;assume a read sector command 046E 06 80 LD B,80H ;B:= Read/Write Control Bit 0470 AF XOR A 0471 B1 OR C ;C not equal to zero for write 0472 28 0C JR Z,LOADCH ;zero => disk READ - channel write 0474 3A 4003 LD A,(4003H) 0477 E6 40 AND 40H ; test for diskette write protected 0479 47 LD B,A ; initialize read/write bit 047A 3E 90 LD A,90H ; write protect error code 047C C0 RET NZ ; Write Protect Error Exit PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-23 047D CD 0C8B CALL RCMD ;prepare for channel read (disk write) 0480 3A 1310 LOADCH: LD A,(1310H) ;port 4006 control byte 0483 E6 7F AND 7FH ;strip off old read/write flag 0485 B0 OR B ;merge new read/write flag 0486 32 1310 LD (1310H),A ;update port 4006 control byte 0489 16 00 LD D,0 048B 59 LD E,C ;offset into function table (0 or 8) 048C 21 1290 LD HL,1290H ;function table pointer 048F 19 ADD HL,DE ;add offset for read or write 0490 FD CB 0E 4E BIT @HRD,(IY+YFLAG) ;If (drive eq hard-sectored) 0494 28 04 JR Z,FCLOOP 0496 11 0002 LD DE,2 ; offset the vector to hard-sectored 0499 19 ADD HL,DE 049A CD 00BD FCLOOP: CALL LOADHL ;get the dispatch address 049D DD 46 0C LD B,(IX+0CH) ;B:= retry_count for data field CRC errors 04A0 0E 04 LD C,4 ;A:= retry_count for missing data ID marks 04A2 C5 TRLOOP: PUSH BC ;Repeat 04A3 E5 PUSH HL ; save the pointer and count 04A4 CD 00C2 CALL DSPTCH ; execute the routine 04A7 E1 POP HL 04A8 C1 POP BC 04A9 20 09 JR NZ,TESTER ; If (there were no errors) 04AB CD 00EC CALL CSTOP ; Stop the controller 04AE CD 00CE CALL DLY1MS ; Delay 1 Millisecond 04B1 3E 40 LD A,40H ; A:= Normal completion code 04B3 C9 RET ; Normal Exit 04B4 FE 93 TESTER: CP 93H ; If (error code = NO data field ID mark) 04B6 20 03 JR NZ,TRCNT 04B8 0D DEC C ; If (retry_count - 1 NE 0) 04B9 20 E7 JR NZ,TRLOOP ; Retry 04BB FE 8E TRCNT: CP 8EH ; If (Other error) or (NO data ID mark) 04BD C0 RET NZ ; error exit (zero flag cleared) 04BE 10 E2 DJNZ TRLOOP 04C0 C9 RET ;Error Exit hard CRC error PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-24 ;====================================================================== ; Read/Write Track ;================= ; ; Begin 'write track' command 04C1 0E 08 WTRACK: LD C,8 ;offset into function table 04C3 18 02 JR RTRACK+2 ; Begin 'read track' command 04C5 0E 00 RTRACK: LD C,0 04C7 CD 0752 CALL CDISK ;change drives if necessary 04CA C0 RET NZ ;drive select error exit 04CB FD CB 0E 86 RES @VER,(IY+YFLAG) ;clear the no verify bit 04CF 06 0A LD B,0AH ;retry count for sector headers 04D1 C5 PELOOP: PUSH BC ;save the parameters 04D2 CD 05B6 CALL PREP ;find the current sector 04D5 C1 POP BC ;recover the parameters 04D6 20 06 JR NZ,CLRVFY ;no error in prep routine 04D8 FE 8D CP 8DH ;header CRC error 04DA C0 RET NZ ;error exit 04DB 10 F4 DJNZ PELOOP ;try again 04DD C9 RET ;error exit 04DE FD CB 0E C6 CLRVFY: SET @VER,(IY+YFLAG) ;set the no verify bit 04E2 2A 1320 LD HL,(1320H) ;low order word of DMA address 04E5 22 13E0 LD (13E0H),HL ;save in upper memory 04E8 3A 1322 LD A,(1322H) ;extended page of DMA address 04EB 32 13E2 LD (13E2H),A ;save also in upper memory 04EE 3A 1324 LD A,(1324H) ;get the side bit 04F1 06 80 LD B,80H ;side bit mask 04F3 A0 AND B ;strip off low order bits 04F4 07 RLCA ;shift to bit 0 of accumulator 04F5 32 1317 LD (1317H),A ;update side byte in header image 04F8 CB 59 BIT 3,C ;test the read/write flag 04FA 28 09 JR Z,RWFLAG ;zero => READ track command 04FC 3A 4003 LD A,(4003H) ; get the drive status 04FF E6 40 AND 40H ; strip off write protect status 0501 47 LD B,A ; zero out B for read/write flag 0502 3E 90 LD A,90H ; write protect error code 0504 C0 RET NZ ; write protect error exit 0505 3A 1310 RWFLAG: LD A,(1310H) ;port 4006 control byte 0508 E6 7F AND 7FH ;strip off old R/W flag 050A B0 OR B ;merge new flag 050B 32 1310 LD (1310H),A ;restore the control byte 050E 16 00 LD D,0 0510 59 LD E,C ;DE:= read/write offset into table (0 or 8) 0511 21 1290 LD HL,1290H ;function table pointer 0514 19 ADD HL,DE ;add offset for read or write 0515 FD CB 0E 4E BIT @HRD,(IY+YFLAG) ;If (drive eq hard-sectored) 0519 28 02 JR Z,FCODE 051B 23 INC HL ; offset the vector to hard-sectored 051C 23 INC HL 051D CD 00BD FCODE: CALL LOADHL ;Function_Address -> HL PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-25 0520 FD 46 0D LD B,(IY+0DH) ;B:= Sectors_per_Track 0523 FD 7E 0C LD A,(IY+0CH) ;D:= 1st Sector's Number 0526 E6 01 AND 00000001B ;(Mask off the 'Active User Spec Flag') 0528 57 LD D,A 0529 04 INC B ;Sector_Count:= Sectors_per_Track + 1 052A 48 LD C,B ;Highest_Sector+1:= Sector_Count 052B 7A LD A,D ;If (Starting_Sector is 0) 052C B7 OR A 052D 20 07 JR NZ,TTLOOP 052F DD 7E 0A LD A,(IX+0AH) 0532 32 1318 LD (1318H),A ; Sector_Register:= Current_Sector_Number 0535 0D DEC C ; Highest_Sector+1:= Highest_Sector+1 - 1 0536 10 15 TTLOOP: DJNZ TCONT ;reduce the sector count 0538 2A 13E0 LD HL,(13E0H) ; original DMA address 053B 22 1320 LD (1320H),HL 053E 3A 13E2 LD A,(13E2H) 0541 32 1322 LD (1322H),A ; restore the old DMA address 0544 CD 00EC CALL CSTOP ; Stop the controller 0547 CD 00CE CALL DLY1MS ; Delay 1 Millisecond before returning 054A 3E 40 LD A,40H ; completion code 054C C9 RET ; track operation complete 054D 3A 1318 TCONT: LD A,(1318H) ;get the old sector value 0550 3C INC A 0551 B9 CP C ;If (Current_Sector+1 eq Last_Sector+1) 0552 20 01 JR NZ,LOADSE 0554 7A LD A,D ; Current_Sector:= First_Sector 0555 32 1318 LOADSE: LD (1318H),A ;update the sector value 0558 92 SUB D ;Adjust Sector Offset 0559 D9 EXX ;save the register bank 055A 5F LD E,A ;offset to E 055B 57 LD D,A ;count to D 055C B7 OR A ;set the zero flag 055D 2A 13E0 LD HL,(13E0H) ;base DMA address 0560 3A 13E2 LD A,(13E2H) 0563 ED 4B 132A LD BC,(132AH) ;sector length 0567 28 06 JR Z,DMASTO ;zero => no offset needed 0569 09 DMLOOP: ADD HL,BC 056A CE 00 ADC A,0 ; take care of page overflow 056C 15 DEC D ; reduce the sector count 056D 20 FA JR NZ,DMLOOP 056F 22 1320 DMASTO: LD (1320H),HL ;load current DMA pointer 0572 32 1322 LD (1322H),A PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-26 0575 2A 1326 LD HL,(1326H) ;get address of sector table 0578 3A 1328 LD A,(1328H) 057B 19 ADD HL,DE ;(E still = offset, D now = 0) 057C CE 00 ADC A,0 ;form offset into sector table 057E 08 EX AF,AF' 057F 44 LD B,H 0580 4D LD C,L ;set up channel address 0581 CD 0C8B CALL RCMD 0584 CD 0CAD CALL INCIO ;read the table entry 0587 3A 4002 LD A,(4002H) 058A D9 EXX ;restore the registers 058B 3C INC A ;test the table entry 058C 28 A8 JR Z,TTLOOP ;skip current sector 058E FE 81 CP 81H 0590 28 A6 JR Z,TTLOOP+2 ;abort command at this point 0592 CB 5B BIT 3,E ;test the read/write flag 0594 CC 0C96 CALL Z,WCMD ;zero => read track command 0597 C5 PUSH BC 0598 D5 PUSH DE 0599 E5 PUSH HL ;save the registers 059A D9 EXX 059B E3 EX (SP),HL ;put sector table pointer on the stack 059C E5 PUSH HL ;save the function pointer 059D 08 EX AF,AF' ;extended page of table pointer 059E F5 PUSH AF 059F CD 00C2 CALL DSPTCH ;read or write the sector 05A2 20 02 JR NZ,SVSTAT ;zero => no error 05A4 3E 40 LD A,40H 05A6 08 SVSTAT: EX AF,AF' 05A7 F1 POP AF ;recover page byte of table pointer 05A8 E1 POP HL ;recover function pointer 05A9 C1 POP BC ;sector table pointer 05AA 08 EX AF,AF' ;recover the status 05AB CD 0C96 CALL WCMD 05AE CD 0CAD CALL INCIO ;report the status 05B1 D1 POP DE 05B2 C1 POP BC ;recover the other registers 05B3 C3 0536 JP TTLOOP ;transfer the next sector PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-27 ;---------------------------------------------------------------------- ; Prepare the Currently selected disk for reading or writing ;----------------------------------------------------------- ; ; Select the Drive 05B6 DD 36 0B 00 PREP: LD (IX+0BH),0 ;reset the index count 05BA FD 4E 0E LD C,(IY+YFLAG) ;C:= Drive_Configuration_Byte 05BD FD 46 02 LD B,(IY+2) ;B:= Drive_Pattern 05C0 CB C8 SET 1,B ;clear the side select bit 05C2 3A 1324 LD A,(1324H) ;load the sector/side byte 05C5 17 RLA ;side bit to the carry 05C6 30 02 JR NC,PSKP1 ;carry => side select to be active 05C8 CB 88 RES 1,B ;select side 1 05CA 11 4004 PSKP1: LD DE,4004H ;Drive_Control_Port:= 5" drive (4004h) 05CD 3E FF LD A,0FFH 05CF CB 51 BIT @5IN,C 05D1 20 09 JR NZ,PSKP3 ;If (drive-size .eq. 8") 05D3 13 INC DE ; Drive_Control_Port:= 8" drive (4005h) 05D4 3A 1323 LD A,(1323H) ; get the new track 05D7 D6 2B SUB 2BH ; carry = 0 if track >= 43 05D9 9F SBC A,A ; ripple the carry through the acc. 05DA F6 FE OR 11111110B ; mask to the low write current bit 05DC A0 PSKP3: AND B ;merge mask with drive pattern 05DD FD 77 02 LD (IY+2),A ;update drive pattern byte 05E0 F6 0C OR 00001100B ;turn off the step command 05E2 12 LD (DE),A ;select the drive ; Start the drive (Do the Head-Load/Motor-On delays) 05E3 FD 5E 06 LD E,(IY+6) 05E6 FD 56 07 LD D,(IY+7) ;DE:= Head_Load_Delay 05E9 7B LD A,E 05EA B2 OR D ; If (Head_Load_Delay eq 0) 05EB 20 03 JR NZ,PSKP4 ; (set delay to default) 05ED 11 0032 LD DE,HLDLY ; Head_Load_Delay:=50ms 05F0 CB 79 PSKP4: BIT @HDL,C ;If (Heads are currently UNloaded) 05F2 20 02 JR NZ,PSKP5 ; zero => head not loaded => read header 05F4 CB 81 RES @VER,C ; clear the no verify bit 05F6 CB 71 PSKP5: BIT @NHC,C ;test for the head always loaded 05F8 28 02 JR Z,PSKP6 ;zero => head can physically unload 05FA CB F9 SET @HDL,C ; set the head loaded bit PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-28 05FC CB 59 PSKP6: BIT @MOC,C ;If (Drive has motor control) 05FE 28 15 JR Z,PSKP7 0600 DD CB 0E 56 BIT @MOT,(IX+XFLAG) ; If (Motor_Status eq Active) 0604 20 0F JR NZ,PSKP7 0606 CB B9 RES @HDL,C ; clear the head loaded flag 0608 FD 5E 08 LD E,(IY+8) 060B FD 56 09 LD D,(IY+9) ; DE:= Motor_on_Delay 060E 7B LD A,E 060F B2 OR D ; If (motor_on_delay eq 0) 0610 20 03 JR NZ,PSKP7 ; (set delay to default) 0612 11 03E8 LD DE,MODLY ; motor_on_delay:=1_sec 0615 CB 79 PSKP7: BIT @HDL,C ;If (Head_Status eq not currently loaded) 0617 20 05 JR NZ,PSKP8 0619 CD 00D6 CALL DLYnMS ; DELAY for head load or motor on 061C CB 81 RES @VER,C ; force a read sector header operation 061E CB F9 PSKP8: SET @HDL,C ;Head_Stauts:= loaded 0620 DD CB 0E D6 SET @MOT,(IX+XFLAG) ;Motor_Statue:= Acitve 0624 11 8000 LD DE,8000H ;Delay:= .45 sec 0627 2E 80 LD L,10000000b ;Mask:= Drive ready flag 0629 CB 69 BIT @NRC,C ;If (drive has a ready line to test) 062B CC 0058 CALL Z,WFLAG ; Test the ready line 062E 20 07 JR NZ,PSKP9 ; If (Drive Not Ready) 0630 3E 82 NREXIT: LD A,82H ; drive not ready error code 0632 CD 0EAB CALL DESEL ; Deselect the drive 0635 BF CP A ; set zero flag to indicate error 0636 C9 RET ; error exit 0637 FD 71 0E PSKP9: LD (IY+YFLAG),C ;update the drive configuration byte ; Move the heads (if necessary) 063A FD 7E 01 LD A,(IY+1) ;get the current track 063D 3C INC A ;test for the head(s) calibrated 063E 20 06 JR NZ,PSKP10 ;zero => heads not calibrated 0640 CD 0855 CALL HOME ; If (Drive won't Home) 0643 C2 0630 JP NZ,NREXIT ; GOTO Error Exit 0646 3A 1323 PSKP10: LD A,(1323H) ;If (Desired track ne current track) 0649 CD 08AE CALL SEEK ; move the heads to the desired track 064C D2 0651 JP NC,PSKP12 ; If (desired track out of bounds) 064F BF CP A ; Set the error flag 0650 C9 RET ; Error Return 0651 FD CB 0E 46 PSKP12: BIT @VER,(IY+YFLAG) ;If (Track_Number doesn't have to be verified) 0655 C0 RET NZ ; exit without error PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-29 ; Determine the Media's Density 0656 21 12A0 LD HL,12A0H ;HL:= offset to 8" SS 0659 FD CB 0E 56 BIT @5IN,(IY+YFLAG) ;If (drive = 5") 065D 28 2A JR Z,PSKP13 065F FD CB 0E 8E RES @HRD,(IY+YFLAG) ; Hard_Sectored _Flag:= False 0663 06 02 LD B,2 ; Hole_Count:= 2 0665 11 0640 PLOP1: LD DE,640H ; Repeat Delay:= 22ms 0668 2E 10 LD L,00010000B ; Mask:= Index 066A CD 0058 CALL WFLAG ; If (Flag is not active) 066D 21 12C0 LD HL,12C0H ; (HL:= offset to 5" SS) 0670 28 17 JR Z,PSKP13 ; Break 0672 11 01B4 LD DE,1B4H ; Delay:= 6ms 0675 2E 10 LD L,00010000B ; Mask:= Index 0677 CD 0058 PLOP2: CALL WFLAG ; Repeat Look for a hole 067A 20 FB JR NZ,PLOP2 ; Until (Hole no longer active) 067C 10 E7 DJNZ PLOP1 ; Until (2 holes have passed) 067E 21 12E0 LD HL,12E0H ; HL:= offset to 5" HS 0681 DD CB 0E 9E RES @SCT,(IX+XFLAG) ; Sector_Count_Calibrated:= False 0685 FD CB 0E CE SET @HRD,(IY+YFLAG) ; Hard_Sectored_Flag:= True 0689 11 0000 PSKP13: LD DE,0 ;sector image offset:= Single density 068C FD CB 0E 56 BIT @5IN,(IY+YFLAG) ;If (drive size is 5") or (track number not 0) 0690 20 06 JR NZ,PSKP14 ; (skip if 5") 0692 FD 7E 01 LD A,(IY+1) 0695 B7 OR A 0696 28 08 JR Z,PSKP15 ; (skip on track zero) 0698 FD CB 0E 66 PSKP14: BIT @DBL,(IY+YFLAG) ; If (Density currently equal Double) 069C 28 02 JR Z,PSKP15 069E 1E 10 LD E,10H ; adjust entry to double density 06A0 19 PSKP15: ADD HL,DE 06A1 06 06 LD B,6 ;Retries:= 6 06A3 CD 00EC SIMAGL: CALL CSTOP ;Repeat reset the disk controller 06A6 E5 PUSH HL 06A7 D5 PUSH DE ; save the parameters 06A8 C5 PUSH BC 06A9 CD 077A CALL SIMAKE ; create sector image and do test read 06AC CD 00EC CALL CSTOP ; Stop the controller 06AF C1 POP BC 06B0 D1 POP DE 06B1 E1 POP HL 06B2 20 0D JR NZ,PSKP16 ; zero => the test read is no good 06B4 DA 0630 JP C,NREXIT ; carry => hard sectored drive not ready 06B7 3E 10 LD A,10H 06B9 AD XOR L ; change entry into sector image table 06BA 6F LD L,A ; update the HL register pair 06BB 10 E6 DJNZ SIMAGL ;Until (Retries - 1 eq 0) 06BD 3E 84 LD A,84H ; media unreadable error code 06BF BF BMEXIT: CP A ; set the error flag 06C0 C9 RET ; error exit PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-30 ; Set the Density Flag 06C1 FD CB 0E 4E PSKP16: BIT @HRD,(IY+YFLAG) ;If (Media is hard sectored) or (Track ne 0) 06C5 20 06 JR NZ,PSKP17 ; (skip on hard sectored) 06C7 FD 7E 01 LD A,(IY+1) 06CA B7 OR A 06CB 28 0E JR Z,PSKP18 ; (skip on track 0) 06CD FD CB 0E E6 PSKP17: SET @DBL,(IY+YFLAG) ; Density_Flag:= Double 06D1 3A 131A LD A,(131AH) 06D4 B7 OR A 06D5 20 04 JR NZ,PSKP18 ; If (media is Single Density) 06D7 FD CB 0E A6 RES @DBL,(IY+YFLAG) ; Density_Flag:= Single ; If media is soft sectored then verify the track number 06DB FD CB 0E 4E PSKP18: BIT @HRD,(IY+YFLAG) ;If (Media is Soft Sectored) 06DF 20 27 JR NZ,PSKP20 06E1 06 08 LD B,8 ; Retry_Count:= 8 06E3 DD E5 RHLOOP: PUSH IX ; Repeat 06E5 DD 21 081D LD IX,SCTRDS ; Sector_vector:= read header 06E9 CD 07B8 CALL SECTOR ; Read header into sector image 06EC DD E1 POP IX ; If (read was ok) 06EE 28 04 JR Z,PSKP19 ; Break 06F0 10 F1 DJNZ RHLOOP ; Until (Retry_Count - 1 eq 0) 06F2 BF CP A ; set the error flag 06F3 C9 RET ; error exit 06F4 3A 1316 PSKP19: LD A,(1316H) ; If (Current track ne Desired Track) 06F7 FD BE 01 CP (IY+1) 06FA 28 0C JR Z,PSKP20 06FC FD CB 0E 86 RES @VER,(IY+YFLAG) ; Heads calibrated flag:= false 0700 FD 36 01 FF LD (IY+1),0FFH ; Decalibrate head(s) 0704 3E 87 LD A,87H ; seek error code 0706 BF CP A ; set the error flag 0707 C9 RET ; error exit ; Check that the sector length code is in bounds 0708 3A 1319 PSKP20: LD A,(1319H) ;If (Sector Number is out of range) 070B FE 04 CP 4 070D 38 04 JR C,PSKP21 070F 3E 85 LD A,85H ; Error:= Sector Number out of range 0711 BF CP A 0712 C9 RET ; Error_Return PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-31 ; Figure the starting sector and the number of sectors per track 0713 FD CB 0C 7E PSKP21: BIT 7,(IY+0CH) ;If (Starting_Sector and SPT are NOT specified) 0717 20 27 JR NZ,PSKP23 0719 21 0081 LD HL,SPT5H ; HL:= 5" Hard Sectored Tables 071C FD CB 0E 4E BIT @HRD,(IY+YFLAG) ; If (Drive Soft Sectored) 0720 20 15 JR NZ,PSKP22 0722 21 007F LD HL,SPT5S ; HL:= 5" Soft Sectored SPT 0725 FD CB 0E 56 BIT @5IN,(IY+YFLAG) 0729 20 0C JR NZ,PSKP22 ; If (Drive size is 8") 072B 21 0077 LD HL,SPT8S ; HL:= 8" SPT Table 072E 3A 1319 LD A,(1319H) ; A:= Sector Size Code 0731 CB 27 SLA A ; Offset:= Offset * 2 0733 5F LD E,A ; Adjust Offset 0734 16 00 LD D,0 0736 19 ADD HL,DE ; calculate entry 0737 7E PSKP22: LD A,(HL) 0738 FD 77 0D LD (IY+0DH),A ; Set the Number of Sectors_per_Track 073B 23 INC HL 073C 7E LD A,(HL) 073D FD 77 0C LD (IY+0CH),A ; Set the Starting Sector's Number ; Figure the number of bytes per sector 0740 3A 1319 PSKP23: LD A,(1319H) ;Accm:= Sector Length Code 0743 21 0040 LD HL,40H 0746 29 SIZE: ADD HL,HL ;double previous value 0747 D6 01 SUB 1 0749 30 FB JR NC,SIZE 074B 22 132A LD (132AH),HL ;update the DMA length registers 074E CD 00EC CALL CSTOP ;Stop the controller 0751 C9 RET PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-32 ;---------------------------------------------------------------------- ; Change Drive Parameter Tables & Decalibrate Drive ;-------------------------------------------------- ; 1) Entry a CDISK makes the drive whose number is stored at 1325h ; the current drive. Entry at CDISKA makes current the drive whose ; number is passed in the accumulator current. This entails ; -Setting current drive parameter table (DPT) pointer (IY reg) ; -Setting the DPT save location (13F0h) ; -Resetting the head loaded bit on the new drive ; -Setting the sector decalibrated flag ; 2) If the drive was within range (0 - 7) then the z-flag is returned ; cleared else its returned set and the accm is equal to 81h. ; 0752 3A 1325 CDISK: LD A,(1325H) ;load new drive number 0755 FD BE 03 CDISKA: CP (IY+3) ;If (new_drive_number eq current_drive_number) 0758 C8 RET Z ; Normal Return (zero flag set) ; Find Current Drive's Parameter Table 0759 CD 0EAB CALL DESEL ;Deselect the current drive but not the motor 075C 06 08 LD B,8 ;B:= total available drives 075E 11 0010 LD DE,10H ;DE:= drive table length 0761 FD 21 1330 LD IY,1330H ;IY:= drive table pointer 0765 FD 19 CDLOOP: ADD IY,DE ;Repeat advance table pointer 0767 FD BE 03 CP (IY+3) ; If (drive number eq parameter table) 076A 28 09 JR Z,DFOUND ; goto drive found 076C 10 F7 DJNZ CDLOOP ;Until (all parameter tables have been checked) ; Drive not found 076E FD 2A 13F0 LD IY,(BASEIX) ;restore the original drive table pointer 0772 3E 81 LD A,81H ;A:= illegal drive error code 0774 C9 RET ;Error Return (zero flag cleared) ; Drive Found 0775 FD 22 13F0 DFOUND: LD (BASEIX),IY ;update the drive table pointer 0779 C9 RET ;Normal Return (zero flag set) PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-33 ;---------------------------------------------------------------------- ; Get a New Drive Constants Table Table and Do a test read ;--------------------------------------------------------- ; 1) This routine moves a Drive Constants Table into the current ; drive constants area (@ 1310h), sets the starting track of ; write pre-compensation and then does a test read. ; 2) This program is only called by PREP (around SILOOP). ; 3) If the test read was successful then the carry is returned ; cleared. ; ;Move the Current Disk Parameter Table to 1310h 077A 11 1310 SIMAKE: LD DE,1310H ;target of image 077D 01 0010 LD BC,10H ;length of image 0780 ED B0 LDIR ;move the data 0782 FD 7E 0F LD A,(IY+0FH) ;If (Starting track of precomp is specified) 0785 B7 OR A 0786 28 03 JR Z,SISKIP 0788 32 1312 LD (1312H),A ; Set starting track of pre-compensation 078B FD CB 0E 4E SISKIP: BIT @HRD,(IY+YFLAG) ;test for hard sectored media 078F 28 05 JR Z,HOLEOK ;If (Disk is Hard Sectored) 0791 CD 0E2B CALL HSYNC ; find a hole 0794 37 SCF ; if (hole not found) 0795 C8 RET Z ; Return Error (Carry Set) 0796 06 0E HOLEOK: LD B,14 ;delay past edge of hole 0798 10 FE DJNZ HOLEOK+2 ;cycle 079A 2A 1310 LD HL,(1310H) ;control bytes for 4006 & 4007 079D CB CD SET 1,L ;controller idle bit 079F 22 4006 LD (4006H),HL ;set controller parameters 07A2 CB 8D RES 1,L ;clear controller idle bit 07A4 22 4006 LD (4006H),HL ;start the disk controller 07A7 2E 01 LD L,1 ;controller ID found bit 07A9 11 0D80 LD DE,0D80H ;time out delay for controller 07AC FD CB 0E 4E BIT @HRD,(IY+YFLAG) ;test for hard sectored media 07B0 28 02 JR Z,SISKP1 ;If (disk is hard sectored) 07B2 16 00 LD D,0 ; shorten the delay 07B4 CD 0058 SISKP1: CALL WFLAG ;Look for ID bit until time-out 07B7 C9 RET PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-34 ;---------------------------------------------------------------------- ; Read/Compare a Sector Header ;----------------------------- ; 1) The BC register pair is preserved. ; 2) The alternate register set is preserved. ; 3) The IX register must be pointing to either: ; SCTCMP - to compare the disk sector ID to the sector ; image ID block. ; SCTRDS - to read the disk sector ID block into the ; sector image ID block. ; 4) An error return clears the Zero flag (non-zero value) ; 07B8 C5 SECTOR: PUSH BC ;Save BC register pair 07B9 3A 1311 LD A,(1311H) 07BC 4F LD C,A ;4007 control byte to C 07BD 06 04 LD B,4 ;header length to B 07BF 21 1316 LD HL,1316H ;pointer to start of sector header area 07C2 11 4001 LD DE,4001H ;pointer to controller data port 07C5 08 EX AF,AF' 07C6 F5 PUSH AF ;Save the alternate accm/flag set 07C7 3E 09 LD A,9 ;Alternate_accm:= Retry_count (actually 8) 07C9 08 EX AF,AF' 07CA D9 EXX 07CB C5 PUSH BC ;Save the alternalte reg. set 07CC D5 PUSH DE 07CD E5 PUSH HL 07CE 08 SCTRTY: EX AF,AF' ;Repeat 07CF 3D DEC A ; Retry_Count:= Retry_Count -1 07D0 28 73 JR Z,SCTER1 ; If (Retry_Count .le. 0) 07D2 08 EX AF,AF' ; Save Retry_Count 07D3 01 0010 LD BC,0010H ; Time_delay:= max 07D6 11 4001 LD DE,4001H ; Pointer:= disk_data 07D9 21 4003 LD HL,4003H ; Pointer:= disk_status 07DC CD 00EC CALL CSTOP ; stop controller & set clock speed 07DF CD 00DF CALL CSTART ; Start the controller 07E2 FD 7E 0E LD A,(IY+YFLAG) 07E5 E6 06 AND 00000110B ; If drive is 5" soft sectored 07E7 FE 04 CP 00000100B ; (bit2=1=5"drive, bit1=1=hard_sectored) 07E9 28 12 JR Z,SCTLP2 ; Skip to 5" Read Header ID byte ; Read the Header ID Byte from an 8" disk 07EB 10 07 SCTLP1: DJNZ SCTSK1 ; Repeat If (primary-timer != 0) 07ED CB 46 BIT 0,(HL) ; If (attn/err == active) 07EF 20 07 JR NZ,SCTSK2 ; Break 07F1 0D DEC C ; If (secondary-timer == 0) 07F2 28 DA JR Z,SCTRTY ; GOTO RETRY 07F4 CB 46 SCTSK1: BIT 0,(HL) ; If (attn/err == active) 07F6 28 F3 JR Z,SCTLP1 ; Break 07F8 00 SCTSK2: NOP ; This is a time pad 07F9 1A LD A,(DE) ; Read disk data 07FA D9 EXX 07FB DD E9 JP (IX) ; Goto either SCTCMP or SCTRDS DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-35 ; Read the Header ID Byte from a 5" disk 07FD 10 07 SCTLP2: DJNZ SCTSK3 ; Repeat If (primary-timer != 0) 07FF CB 46 BIT 0,(HL) ; If (attn/err == active) 0801 20 07 JR NZ,SCTSK4 ; Break 0803 0D DEC C ; If (secondary-timer == 0) 0804 28 C8 JR Z,SCTRTY ; GOTO RETRY 0806 CB 46 SCTSK3: BIT 0,(HL) ; If (attn/err == active) 0808 28 F3 JR Z,SCTLP2 ; Break 080A 06 05 SCTSK4: LD B,5 080C 10 FE SCTLP3: DJNZ SCTLP3 ; This is a time pad 080E 1A LD A,(DE) ; Read disk data 080F D9 EXX 0810 DD E9 JP (IX) ; Goto either SCTCMP or SCTRDS ;Compare the track number through Sector number to sector image 0812 1A SCTCLP: LD A,(DE) ;Repeat 0813 BE SCTCMP: CP (HL) ; If (Disk_Data.ne.Image(Pointer) 0814 C2 0847 JP NZ,SCTER2 ; goto Error Exit 0817 23 INC HL ; Pointer:= Pointer + 1 0818 10 F8 DJNZ SCTCLP ;Until (counter.eq.0) 081A 18 05 JR SCTCNT ;Read the track number through Sector number to sector image 081C 1A SCTRLP: LD A,(DE) ;Repeat 081D 77 SCTRDS: LD (HL),A ; Image(Pointer):= Disk_Data 081E 23 INC HL ; Pointer:= Pointer + 1 081F 10 FB DJNZ SCTRLP ;Until (counter.eq.0) ;Read the CRC bytes through first two ID gap bytes and check the CRC 0821 1A SCTCNT: LD A,(DE) ;read first CRC data byte 0822 00 NOP 0823 00 NOP 0824 1A LD A,(DE) ;read second CRC data byte 0825 79 LD A,C 0826 E6 EF AND 0EFH ;CRC error control byte 0828 32 4007 LD (4007H),A ;issue the command 082B 1A LD A,(DE) ;sync with data - 1st FF/4E 082C 79 LD A,C ;(c is the disk_control byte) 082D 32 4007 LD (4007H),A ;stop CRC error captures 0830 3A 4003 LD A,(4003H) ;get the status byte 0833 2F CPL 0834 CB 47 BIT 0,A ;zero => no CRC error 0836 1A LD A,(DE) ;Read the 2nd FF/4E 0837 20 0E JR NZ,SCTER2 ;If (Error .eq. true) Goto Error Exit 0839 D9 EXX ;Restore alternate register set 083A E1 POP HL 083B D1 POP DE 083C C1 POP BC 083D D9 EXX 083E 1A LD A,(DE) ;Read the 3rd FF/4E 083F 08 EX AF,AF' ;Restore the alternate accm 0840 F1 POP AF 0841 08 EX AF,AF' 0842 C1 POP BC ;Restore BC register pair 0843 1A LD A,(DE) ;Read the 4th FF/4E 0844 C9 RET DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-36 ; Error Return for Missing Header ID Byte 0845 2E 15 SCTER1: LD L,15H ;(Error code = 88h = 15h + 73h) ; Error Return form Sector Header Compare 0847 D9 SCTER2: EXX 0848 E1 POP HL ;Restore alternate register set 0849 D1 POP DE 084A C1 POP BC 084B D9 EXX 084C 08 EX AF,AF' ;Restore the Alt_Accm. 084D F1 POP AF 084E 08 EX AF,AF' 084F 7D LD A,L ;Generte the Error Code 0850 C6 73 ADD A,73H ;(88=no-ID-byte; 89-8C=Compare errors; 8D=CRC) 0852 B7 SCTSK5: OR A ;Error_Flag:= set 0853 C1 POP BC 0854 C9 RET ;Return PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-37 ;---------------------------------------------------------------------- ; Home the disk heads ;-------------------- ; 1) This routine Homes the disk head ; 2) The current track number is reset to zero and the track verified ; flag is set to false. ; 3) If the head is over track zero then the head is stepped out 4 times ; and then homed (insures that heads sitting at track -2 will home). ; 4) If a 5 1/4" drive fails to find track zero then a second attempt ; is made at a slower step rate. ; 5) The z-flag is set if track 0 was found else its cleared (error-94H). ; 6) After the settle delay the t-0 flag is rechecked before returning. ; 7) Register Usage ; A -> General Purpose ; B -> Step Count ; DE -> Settle Constant (See SETTLE) and Slow step rate ; HL -> Disk Status Port and Current step rate ; 0855 FD CB 0E 86 HOME: RES @VER,(IY+YFLAG) ;Sector Header Verified:= false 0859 FD 36 01 00 LD (IY+1),0 ;Current track:= 0 085D 21 4003 LD HL,4003H ;HL:= Pointer to Disk Status Port 0860 CB 6E BIT 5,(HL) ;If (track zero flag is true) 0862 28 09 JR Z,HOMLP1 0864 3E 00 LD A,0 ; Direction:= Step_In (away from home) 0866 06 04 LD B,4 ; Step_Count:= 4 0868 CD 08E0 HOMLP0: CALL STP ; Repeat Step in 086B 10 FB DJNZ HOMLP0 ; Until (4 steps IN have been taken) 086D 3E 08 HOMLP1: LD A,8 ;Direction:= Step_Out (towards home) 086F 06 00 LD B,0 ;Step-count:= 256 (default for 8" drives) 0871 FD CB 0E 56 BIT @5IN,(IY+YFLAG) 0875 28 02 JR Z,HOMLP2 ;If (Drive is 5") 0877 06 64 LD B,64H ; Step_count:= 100 0879 CD 08E0 HOMLP2: CALL STP ;Repeat get the drive pattern 087C CB 6E BIT 5,(HL) ; If (track zero flag is active) 087E CA 088A JP Z,HOMSK1 0881 CD 08D6 CALL SETTLE ; Do settle delay 0884 CB 6E BIT 5,(HL) ; If (track zero flag isn't true) 0886 28 E5 JR Z,HOMLP1 ; GOTO Home the heads 0888 BF CP A ; Else Set the zero flag 0889 C9 RET ; Normal Return 088A 10 ED HOMSK1: DJNZ HOMLP2 ;Until (Step_count .eq. 0) 088C FD CB 0E 56 BIT @5IN,(IY+YFLAG) ;If (drive_size .eq. 5) and (step rate ne slow) 0890 28 16 JR Z,NOTHOM 0892 11 0554 LD DE,554H ; DE:= Slow_Step_Rate (40ms) 0895 E5 PUSH HL 0896 FD 6E 04 LD L,(IY+4) 0899 FD 66 05 LD H,(IY+5) ; HL:= Current_Step_rate 089C B7 OR A ; (Clear the Carry Flag) 089D ED 52 SBC HL,DE ; 089F E1 POP HL 08A0 FD 73 04 LD (IY+4),E 08A3 FD 72 05 LD (IY+5),D ; Step_rate:= slow (40ms) 08A6 20 C5 JR NZ,HOMLP1 ; Try to Home a again at a slower rate 08A8 FD 35 01 NOTHOM: DEC (IY+1) ;decalibrate & set error flag 08AB 3E 94 LD A,94H ;Error_Code:= Drive won't home 08AD C9 RET ;Error Return (zero flag cleared) PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-38 ;---------------------------------------------------------------------- ; Seek Routine ;------------- ; 1) This routine seeks to the track passed in the ACCM. ; 2) If the track number is in bounds then the head is moved over it and ; the carry flag is cleared Else, the carry is SET to indicate ERRORS. ; 3) Register Usage: ; A - Enter equal desired Track, becomes Current Step Pattern ; B - Current_Track and Absolute Number of Steps ; 08AE FD BE 01 SEEK: CP (IY+1) ;If (Desired_Track eq Current_Track) 08B1 C8 RET Z ; Exit 08B2 FD CB 0E 86 RES @VER,(IY+YFLAG) ;clear the no verify bit 08B6 FD BE 00 CP (IY+0) ; If (new track out of bounds) 08B9 38 04 JR C,SEKSK1 08BB 3F CCF ; Set the Error Flag 08BC 3E 83 LD A,83H ; improper track value error code 08BE C9 RET ; Error Exit 08BF FD 46 01 SEKSK1: LD B,(IY+1) ;B:= Current Track 08C2 FD 77 01 LD (IY+1),A ;Current Track:= Updated 08C5 90 SUB B ;find the difference 08C6 30 02 JR NC,SEKSK2 ;carry => must compliment 08C8 2F CPL 08C9 3C INC A 08CA 47 SEKSK2: LD B,A ;C:= absolute difference 08CB 9F SBC A,A ;ripple the carry throughout A (A:=0 ! A:=FF) 08CC E6 08 AND 8 ;isolate the direction bit 08CE FD B6 02 OR (IY+2) ;merge with direction bit 08D1 CD 08E0 SEKLP1: CALL STP ;Repeat Step the Heads 08D4 10 FB DJNZ SEKLP1 ;Until (Step_Count eq 0) 08D6 FD 5E 0A SETTLE: LD E,(IY+0AH) 08D9 FD 56 0B LD D,(IY+0BH) ;DE:= settling time 08DC CD 00C3 CALL SDELAY ;Do Settle Delay 08DF C9 RET PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-39 ;---------------------------------------------------------------------- ; Step the Disk Head Once ;------------------------ ; Description: ; This routine steps the head once. The direction is passed ; in the A register (8=Step_Out, 0=Step_In). ; Notes: ; 1) None of the registers are altered in this routine (See SDELAY and ; COUNT for possible register alteration). ; 08E0 D5 STP: PUSH DE ;(Save the DE pair and the accm) 08E1 F5 PUSH AF 08E2 E6 08 AND 8 ;Remove all but the direction bit 08E4 11 4005 LD DE,4005H ;BC:= 4005 (8"-drive control port) 08E7 FD CB 0E 56 BIT @5IN,(IY+YFLAG) 08EB 28 01 JR Z,STPSK1 ;If (drive is 5") 08ED 1B DEC DE ; BC:= 4004 (5"-drive control port) 08EE FD B6 02 STPSK1: OR (IY+2) ;Combine direction bit with drive pattern 08F1 12 LD (DE),A ;start the step command 08F2 EE 04 XOR 4 ;toggle the step bit 08F4 12 LD (DE),A ;finish the step command 08F5 FD 5E 04 LD E,(IY+4) 08F8 FD 56 05 LD D,(IY+5) ;DE:= step_delay 08FB CD 00C3 CALL SDELAY ;Do step delay 08FE F1 POP AF 08FF D1 POP DE ;(Restore the DE pair and the accm) 0900 C9 RET PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-40 ;====================================================================== ; Find a Sector Header (soft sectored) ;===================================== ; 1) This routine is called by both the soft sectored read and write ; routines. ; 2) The HL pair is set to the start of WPOINT or RPOINT by the calling ; routine. These tables contain vectors used in the actual read/write ; routines. ; 0901 E5 FSECT: PUSH HL ;save the read/write pointer 0902 CD 0936 CALL SETXFR ;setup transfer parameters 0905 E1 POP HL ;restore the pointer 0906 AF XOR A ;clear the accumulator and flags 0907 B3 OR E ;set the flags for leftover bytes 0908 3E A1 LD A,0A1H ;CRC control byte code 090A 08 EX AF,AF' ;save for the end of the command 090B 5A LD E,D ;number of initial bytes to e 090C 16 00 LD D,0 090E 19 ADD HL,DE ;form the table entry (into RPOINT/WPOINT) 090F 19 ADD HL,DE 0910 5E LD E,(HL) ;get dispatch address from table 0911 23 INC HL 0912 56 LD D,(HL) 0913 D5 PUSH DE 0914 DD E1 POP IX ;dispatch address to IX 0916 FD 46 0D LD B,(IY+0DH) 0919 CB 20 SLA B ;Retries:= (Number of sectors per track) * 2 091B DD E5 FSLOOP: PUSH IX ;Repeat 091D DD 21 0813 LD IX,SCTCMP ; Sector_vector:= compare w/sector image 0921 CD 07B8 CALL SECTOR ; If (disk_image .eq. memory_image) 0924 DD E1 POP IX 0926 C8 RET Z ; return 0927 FE 88 CP 88H ; If (error .eq. No ID Byte Found) 0929 28 07 JR Z,FSCNT ; retry 092B FE 8B CP 8BH ; If (error .eq. sector_number) 092D 28 03 JR Z,FSCNT ; retry 092F FE 8D CP 8DH ; If (error .eq. CRC Error) 0931 C0 RET NZ ; retry 0932 10 E7 FSCNT: DJNZ FSLOOP ;Until (Retry count .eq. zero) 0934 B7 OR A ;reset the error (zero) flag 0935 C9 RET ;error exit PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-41 ;---------------------------------------------------------------------- ; Setup the DMA address for a disk transfer ;------------------------------------------ ; 0936 CD 0C8B SETXFR: CALL RCMD ;set up the channel to do reads 0939 ED 4B 1320 LD BC,(1320H) ;get the DMA address 093D ED 5B 132A LD DE,(132AH) ;get the DMA byte count 0941 3A 1322 LD A,(1322H) ;get the extended page address 0944 08 EX AF,AF' ;save the accumulator 0945 21 132C LD HL,132CH ;data storage pointer 0948 3E 02 LD A,2 ;page overflow value 094A 81 ADD A,C ;test for a two byte page 094B 3E 00 LD A,0 094D 30 10 JR NC,ADJUST ;carry => 1 or 2 bytes to page end 094F 91 SUB C ;calculate the count 0950 F5 PUSH AF ;save on the stack 0951 CD 0CAD LOOP22: CALL INCIO ;do channel read and inc. DMA addr. 0954 1B DEC DE ;decrement the DMA count 0955 3A 4002 LD A,(4002H) ;get the channel data 0958 77 LD (HL),A ;put the data in the buffer 0959 23 INC HL ;advance the buffer pointer 095A AF XOR A ;clear the accumulator 095B B1 OR C ;test for page boundary 095C 20 F3 JR NZ,LOOP22 ;zero => page boundary found 095E F1 POP AF ;adjust the stack 095F F5 ADJUST: PUSH AF ;save the byte count for exit 0960 CD 0CAD CALL INCIO ;do the read before the transfer 0963 0B DEC BC ;adjust the DMA address 0964 21 1330 LD HL,1330H ;parameter buffer pointer 0967 AF XOR A 0968 B3 OR E ;test for full page count 0969 20 04 JR NZ,PTEST ;zero => full page transfers 096B 91 SUB C ;calculate left over bytes 096C 59 LD E,C ;save left over in E 096D 18 0F JR SDATA ;go fill the parameter buffer 096F AF PTEST: XOR A 0970 B1 OR C ;test for even page boundary 0971 28 0B JR Z,SDATA ;zero => full page transfers 0973 93 SUB E ;difference between data & addr. 0974 38 08 JR C,SDATA ;carry => no negation 0976 5F LD E,A ;leftover in E 0977 79 LD A,C ;starting amount in A 0978 ED 44 NEG ;2s compliment 097A CD 09A5 LOOPD: CALL STORE ;write the parameters 097D AF XOR A ;full page code 097E 15 SDATA: DEC D ;reduce the page count 097F F2 097A JP P,LOOPD ;more pages left 0982 7B LD A,E ;leftover bytes 0983 FE 03 CP 3 ;test for less than three 0985 38 05 JR C,EMARK ;carry => leftover less than three 0987 CD 09A5 CALL STORE ;leftover bytes parameters to buffer 098A 1E 00 LD E,0 ;adjust E PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-42 098C F1 EMARK: POP AF ;recover the front-end count 098D 57 LD D,A ;save in D 098E 3E 02 LD A,2 0990 CD 09A5 CALL STORE ;write an end mark in buffer 0993 08 EX AF,AF' 0994 3E 3F LD A,3FH ;get ready for the zero flag 0996 47 LD B,A ;prevent B from overflowing 0997 08 EX AF,AF' 0998 BB CP E ;test for two bytes leftover 0999 DC 09A5 CALL C,STORE ;store the parameters 099C 08 EX AF,AF' 099D 3C INC A ;the zero flag 099E 08 EX AF,AF' 099F 3E A2 LD A,0A2H ;CRC control code 09A1 CD 09A5 CALL STORE ;store the control codes 09A4 3C INC A ;adjust the accumulator 09A5 3D STORE: DEC A ;adjust the byte count 09A6 08 EX AF,AF' 09A7 77 LD (HL),A ;extended page addr to buffer 09A8 08 EX AF,AF' 09A9 23 INC HL ;advance the pointer 09AA 77 LD (HL),A ;byte count less one to buffer 09AB 23 INC HL ;advance the pointer 09AC 04 INC B ;advance the DMA page byte 09AD C0 RET NZ ;zero => 65K overflow 09AE 08 EX AF,AF' 09AF 3C INC A ;advance the extended page addr. 09B0 08 EX AF,AF' 09B1 C9 RET PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-43 ;---------------------------------------------------------------------- ; Read a sector 5" or 8" Soft Sectored ;------------------------------------- ; 1) Note the use of the flag register in this routine. Before entering ; this body of code the Z_Flag is set to tell how many bytes are ; going to be transferred. In the first part of this routine the ; carry flag is added to the flag register to indicate the data ; density and consequently how many data address marks to read. ; 2) The alternate register set is preserved. ; 3) The alternate accm is modified. ; 09B2 21 0083 READS: LD HL,RPOINT ;read table entry pointer 09B5 CD 0901 CALL FSECT ;locate current sector 09B8 C0 RET NZ ; error exit - sector not found 09B9 CD 0C96 CALL WCMD ;prepare for channel write (disk read) 09BC CD 00EC CALL CSTOP ;reset the disk controller 09BF D9 EXX 09C0 C5 PUSH BC ;Save the alternate reg. set 09C1 D5 PUSH DE 09C2 E5 PUSH HL 09C3 06 00 LD B,00H ;B:= time delay 09C5 11 4001 LD DE,4001H ;DE:= read disk data location 09C8 21 4003 LD HL,4003H ;HL:= disk status 09CB D9 EXX 09CC 3A 1311 LD A,(1311H) ;load the 4007 mode control byte 09CF CB D7 SET 2,A ;change to sync byte to data header 09D1 32 4007 LD (4007H),A ;update port 4007 09D4 06 2D LD B,2DH ;Delay:= 144us + 16us 09D6 10 FE RDLP0: DJNZ RDLP0 ;Wait (5 bytes in single density) 09D8 ED 73 132E LD (STKSAV),SP ;save the stack pointer 09DC 31 1330 LD SP,1330H ;transfer parameter pointer 09DF ED 4B 1320 LD BC,(1320H) ;load the DMA address 09E3 E1 POP HL ;byte count to h - extended page to l 09E4 25 DEC H ;adjust the count for the loop 09E5 7D LD A,L 09E6 32 4002 LD (4002H),A ;initialize the extended page register 09E9 D9 EXX PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-44 09EA FD 7E 0E LD A,(IY+YFLAG) 09ED E6 06 AND 00000110B ;If drive is 5" soft sectored 09EF FE 04 CP 00000100B ;(bit2=1=5"drive, bit1=1=hard_sectored) 09F1 3A 1310 LD A,(1310H) 09F4 32 4006 LD (4006H),A ;(start the controller looking for A.M.) 09F7 28 12 JR Z,RDLP2 ;Skip to the 5" read-the-address-mark routine ; Find the address mark on an 8" disk 09F9 10 07 RDLP1: DJNZ RDSKP1 ;Repeat 09FB D9 EXX ; If (time-out == .true.) 09FC 3E 93 LD A,93H ; accm:= error code 09FE B7 OR A ; error_flag:= set 09FF C3 0A63 JP RDRTN ; exit 0A02 CB 46 RDSKP1: BIT 0,(HL) ; Accm:= attn/err 0A04 28 F3 JR Z,RDLP1 ;Until (attn/err == active) 0A06 00 NOP ;(Small time pad for single density) 0A07 1A LD A,(DE) ;READ data 0A08 D9 EXX ;Restore the original reg set 0A09 DD E9 JP (IX) ;Goto RTWO, RONE or RZRO ; Find the address mark on a 5" disk 0A0B 10 07 RDLP2: DJNZ RDSKP2 ;Repeat 0A0D D9 EXX ; If (time-out == .true.) 0A0E 3E 93 LD A,93H ; accm:= error code 0A10 B7 OR A ; error_flag:= set 0A11 C3 0A63 JP RDRTN ; exit 0A14 CB 46 RDSKP2: BIT 0,(HL) ; Accm:= attn/err 0A16 28 F3 JR Z,RDLP2 ;Until (attn/err == active) 0A18 06 05 LD B,5 0A1A 10 FE RDLP3: DJNZ RDLP3 ;Wait an extra 8us before reading the data 0A1C 1A LD A,(DE) ;READ data 0A1D D9 EXX ;Restore the original reg set 0A1E DD E9 JP (IX) ;Goto RTWO, RONE or RZRO PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-45 0A20 ED 79 RTWO: OUT (C),A ;write to the channel 0A22 03 INC BC ;advance the DMA address pointer 0A23 1A LD A,(DE) ;get the first/second data byte 0A24 ED 79 RONE: OUT (C),A 0A26 03 INC BC 0A27 1A RLOOP: LD A,(DE) ;read data from the disk 0A28 ED 79 RZRO: OUT (C),A ;write data to the DMA channel 0A2A 03 INC BC ;advance the DMA address pointer 0A2B 25 DEC H ;decrement the byte count 0A2C 20 F9 JR NZ,RLOOP 0A2E 1A LD A,(DE) ;read next to last data byte 0A2F E1 POP HL ;get the new block count and page 0A30 ED 79 OUT (C),A ;write next to last byte to channel 0A32 03 INC BC ;advance the counter 0A33 25 DEC H ;test for last block to transfer 0A34 1A LD A,(DE) ;read the last byte 0A35 ED 79 OUT (C),A ;last byte to the channel 0A37 03 INC BC ;increment the DMA address 0A38 7D LD A,L 0A39 32 4002 LD (4002H),A ;update the extended page register 0A3C C2 0A27 JP NZ,RLOOP ;drop back to the block loop 0A3F 08 EX AF,AF' ;flag for extra bytes 0A40 1A LD A,(DE) ;read data/CRC from disk 0A41 28 0A JR Z,LASTR ;zero flag means no extra bytes 0A43 ED 79 OUT (C),A ;data to the channel 0A45 03 INC BC 0A46 F1 POP AF ;flag to indicate two extra bytes 0A47 1A LD A,(DE) ;disk data/CRC byte 0A48 28 03 JR Z,LASTR ;again - zero flag means no byte 0A4A ED 79 OUT (C),A 0A4C 1A LD A,(DE) ;read first CRC byte 0A4D 1A LASTR: LD A,(DE) ;read second CRC byte 0A4E 3A 131B LD A,(131BH) ;CRC error mode byte 0A51 32 4007 LD (4007H),A 0A54 1A LD A,(DE) ;get in sync with error flag 0A55 3A 1311 LD A,(1311H) ;control byte for 4007 0A58 32 4007 LD (4007H),A ;turn off error mode 0A5B 3A 4003 LD A,(4003H) ;status byte 0A5E 2F CPL 0A5F CB 47 BIT 0,A ;set zero flag if no CRC error 0A61 3E 8E LD A,8EH ;data field CRC error code 0A63 DD 21 13F0 RDRTN: LD IX,BASEIX ;restore the IX register 0A67 ED 7B 132E LD SP,(STKSAV) ;restore the stack pointer 0A6B D9 EXX 0A6C E1 POP HL ;Restore the original reg. set 0A6D D1 POP DE 0A6E C1 POP BC 0A6F D9 EXX 0A70 C3 00EC JP CSTOP ;turn off the controller PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-46 ;---------------------------------------------------------------------- ; Write a Sector (5" or 8" Soft sectoring) ;----------------------------------------- ; ; 1) The DE pair is set up in SECTOR (called by FSECT) to point ; to location 4001h. ; 2) The HL pair is also set up in SECTOR. Initially the HL reg. ; pair points to the start of the sector image. Once the header ; has been successfully read the HL pair is left pointing to ; the density byte (131Ah) which is 0 for single density and ; one for double density. ; 0A73 21 0089 WRITES: LD HL,WPOINT ;write table entry pointer 0A76 CD 0901 CALL FSECT ;locate the current sector 0A79 C0 RET NZ ;sector not found if zero flag not set 0A7A 1A LD A,(DE) ;<5th FF/4E> 0A7B ED 73 132E LD (STKSAV),SP ;save the stack pointer 0A7F 31 1330 LD SP,1330H ;transfer parameters pointer 0A82 7E LD A,(HL) ;get the density byte 0A83 1F RRA ;save the density flag in the carry 0A84 1A LD A,(DE) ;<6th FF/4E> 0A85 C1 POP BC ;byte count (b) & extended page (c) 0A86 05 DEC B ;adjust for the prefetch of data 0A87 21 400B LD HL,400BH ;page 40 & 4E field count for dbl den 0A8A 1A LD A,(DE) ;<7th FF/4E> 0A8B D9 EXX ;change register banks 0A8C 11 4001 LD DE,4001H ;DMA data port 0A8F 21 4002 LD HL,4002H ;extended page port 0A92 ED 4B 1320 LD BC,(1320H) ;get the DMA address 0A96 1A LD A,(DE) ;<8th FF/4E> 0A97 03 INC BC ;adjust for the prefetch of data 0A98 D9 EXX ;change register banks again 0A99 38 2D JR C,DOUBLE ;If (media is single density) 0A9B 2E 06 LD L,6 ; port 4006 - control port of 82S105 0A9D 1A LD A,(DE) ; <9th FF> 0A9E 1A LD A,(DE) ; <10th FF> 0A9F 3A 131E LD A,(131EH) ; control byte for 4006 0AA2 F6 02 OR 2 0AA4 77 LD (HL),A ; turn controller off 0AA5 2C INC L 0AA6 36 80 LD (HL),80H ; switch clocks and turn on write gate 0AA8 2D DEC L 0AA9 E6 FD AND 0FDH 0AAB 77 LD (HL),A ; turn controller back on 0AAC 3E AA LD A,0AAH ; half byte of zero 0AAE 2E 0C LD L,0CH ; half-zero count 0AB0 12 LOOP1: LD (DE),A ; write half a zero 0AB1 2D DEC L 0AB2 20 FC JR NZ,LOOP1 ; Write the Sync-Byte 0AB4 2E 02 LD L,2 ; HL now points to the extended page reg. 0AB6 3E 81 LD A,81H 0AB8 32 4007 LD (4007H),A ; enable the CRC generator 0ABB 3E F5 LD A,0F5H ; first half of FB 0ABD 12 LD (DE),A 0ABE 3E 91 LD A,91H DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-47 0AC0 32 4007 LD (4007H),A ; change controller to normal data 0AC3 3E 6F LD A,6FH ; second half of FB 0AC5 12 LD (DE),A 0AC6 DD E9 JP (IX) ; dispatch to write data routine ;Else (media is double density) 0AC8 1A DOUBLE: LD A,(DE) ; <9th - 19th 4E> 0AC9 2D DEC L 0ACA 20 FC JR NZ,DOUBLE 0ACC 1A LD A,(DE) ; <20th 4E> ; Set the Write Pre-Compensation 0ACD 3A 1312 LD A,(1312H) ; Get the Starting Track of Write Precomp 0AD0 FD BE 01 CP (IY+1) ; compare with present track 0AD3 9F SBC A,A ; extend the carry to the accumulator 0AD4 E6 10 AND 10H ; mask off the write precompensation bit 0AD6 6F LD L,A ; save the result in L 0AD7 1A LD A,(DE) ; <21th 4E> 0AD8 3A 131E LD A,(131EH) ; get controller command byte 0ADB E6 EF AND 0EFH ; mask off old precompensation bit 0ADD B5 OR L ; merge new precomp bit 0ADE F6 02 OR 2 ; controller disable bit 0AE0 2E 06 LD L,6 ; HL now points to port 4006 0AE2 77 LD (HL),A ; set precomp. & turn off controller 0AE3 2C INC L 0AE4 36 80 LD (HL),80H ; change clocks and turn on write gate 0AE6 E6 FD AND 0FDH 0AE8 2D DEC L 0AE9 77 LD (HL),A ; turn the controller back on 0AEA 3E AA LD A,0AAH ; one half of a byte of zero 0AEC 2E 16 LD L,16H 0AEE 12 LOOP2: LD (DE),A ; write 22 half zeros 0AEF 2D DEC L 0AF0 20 FC JR NZ,LOOP2 ;Write the Sync-Bytes 0AF2 12 LD (DE),A ; 23rd half zero 0AF3 2E 07 LD L,7 ; HL points to mode port again 0AF5 12 LD (DE),A ; write 24th half zero 0AF6 36 81 LD (HL),81H ; enable the CRC generator 0AF8 EB EX DE,HL 0AF9 36 44 LD (HL),44H ; write first half of A1 0AFB 36 89 LD (HL),89H ; write second half of A1 0AFD 36 44 LD (HL),44H 0AFF 36 89 LD (HL),89H 0B01 36 44 LD (HL),44H 0B03 3E 91 LD A,91H ; normal data mode byte 0B05 12 LD (DE),A 0B06 36 89 LD (HL),89H 0B08 EB EX DE,HL 0B09 2E 02 LD L,2 ; HL now points to extended page reg. 0B0B 3E FB LD A,0FBH ; ID byte for data record 0B0D 12 LD (DE),A 0B0E DD E9 JP (IX) ; dispatch to write routine PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-48 0B10 D9 WTWO: EXX 0B11 3A 132C LD A,(132CH) ;get the first byte of data 0B14 03 INC BC ;advance the DMA address 0B15 12 LD (DE),A ;write to the disk 0B16 3A 132D LD A,(132DH) ;get the second byte of data 0B19 18 04 JR WONEP 0B1B D9 WONE: EXX 0B1C 3A 132C LD A,(132CH) ;get the first byte of data 0B1F 03 WONEP: INC BC ;advance the DMA address 0B20 12 LD (DE),A ;write the second/first byte to the disk 0B21 D9 EXX 0B22 D9 WLOOP: EXX 0B23 7E LD A,(HL) ;get data from the DMA channel 0B24 ED 79 OUT (C),A ;start a new DMA cycle 0B26 03 INC BC ;increment the DMA address 0B27 12 LD (DE),A ;write the data to the disk 0B28 D9 EXX ;swap register banks for byte count 0B29 10 F7 DJNZ WLOOP 0B2B C1 POP BC ;get the new byte count & extended page 0B2C D9 EXX 0B2D 7E LD A,(HL) ;get next to last data byte 0B2E ED 79 OUT (C),A ;start the last DMA cycle 0B30 12 LD (DE),A ;write next to last data to disk 0B31 03 INC BC ;advance DMA address pointer across page 0B32 D9 EXX 0B33 71 LD (HL),C ;load extended page register w/new value 0B34 05 DEC B ;test for block transfers done 0B35 D9 EXX 0B36 7E LD A,(HL) ;get the last data byte 0B37 ED 79 OUT (C),A ;start first DMA cycle of new block 0B39 12 LD (DE),A ;write the last data byte to the disk 0B3A 03 INC BC ;advance the DMA address pointer 0B3B 20 E6 JR NZ,WLOOP+1 ;jump back to block transfer loop 0B3D 08 EX AF,AF' ;flag to indicate extra bytes to xfer 0B3E 28 0C JR Z,DONE 0B40 F1 POP AF ;flag to indicate two extra bytes 0B41 7E LD A,(HL) ;channel data 0B42 12 LD (DE),A ;write to the disk 0B43 ED 79 OUT (C),A ;start next DMA cycle 0B45 28 04 JR Z,DONE-1 ;exit if only one extra byte 0B47 7E LD A,(HL) ;get last data byte from channel reg. 0B48 ED 79 OUT (C),A ;extra DMA cycle for lost data INTR 0B4A 12 LD (DE),A ;write last byte to the disk 0B4B F1 POP AF ;control byte for port 4007 0B4C 32 4007 DONE: LD (4007H),A ;mode to write the CRC data bytes 0B4F 12 LD (DE),A ;first CRC data byte 0B50 12 LD (DE),A ;second CRC data byte 0B51 3E 91 LD A,91H ;normal data mode byte 0B53 32 4007 LD (4007H),A 0B56 AF XOR A 0B57 12 LD (DE),A ;flush the registers with a zero 0B58 DD 21 13F0 LD IX,BASEIX ;restore the IX register 0B5C ED 7B 132E LD SP,(STKSAV) ;restore the stack pointer 0B60 3E 8E LD A,8EH ;data field CRC error code 0B62 C3 00EC JP CSTOP ;turn off the controller PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-49 ;====================================================================== ; Find a Sector (hard sectored disk) ;=================================== ; 1) This routine does both the common initialization for the 5" hard ; sectored read and write routines as well as finding the desired ; sector on the disk. ; 2) If the disk is not turning or the desired sector is greater than ; the maximum number of sectors on a 5" hard sectored disk (MAXHS5) ; then the carry is returned set. ; 0B65 CD 00EC FSECT5: CALL CSTOP ;stop the controller ; Setup the Alternate Register Set 0B68 16 00 LD D,0 ;read routine check byte 0B6A 21 4002 LD HL,4002H ;channel data/extended page pointer 0B6D 3A 1322 LD A,(1322H) ;extended page byte 0B70 5F LD E,A ;initialize extended page register 0B71 77 LD (HL),A ;initialize channel extended page 0B72 ED 4B 1320 LD BC,(1320H) ;initialize DMA address pointer 0B76 D9 EXX ;save in shadow register bank ; Find the Desired Sector 0B77 06 0A LD B,MAXHS5 ;Counter:= Max number of sectors on a 5" disk 0B79 C5 FS5LP: PUSH BC 0B7A CD 0E2B CALL HSYNC ;repeat 0B7D C1 POP BC ; if (disk not turining) 0B7E 28 0A JR Z,FS5ERR ; break 0B80 3A 1318 LD A,(1318H) ; if (desired sector eq current sector) 0B83 DD BE 0A CP (IX+0AH) 0B86 28 04 JR Z,FS5SKP ; Goto Final Initialization 0B88 10 EF DJNZ FS5LP ;Until (Max sector count reached) 0B8A 37 FS5ERR: SCF ;set the error flag 0B8B C9 RET ;Exit error ; Final Initialization 0B8C 11 4001 FS5SKP: LD DE,4001H ;channel data/extended page pointer 0B8F 0E 00 LD C,0 ;write routine check register 0B91 DD CB 0E AE RES @FHF,(IX+XFLAG) 0B95 C9 RET ;return with carry flag cleared PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-50 ;---------------------------------------------------------------------- ; Read a 5" disk (hard sectored) ;------------------------------- ; 0B96 CD 0B65 READ5: CALL FSECT5 ;find the sector if drive is ready 0B99 D8 RET C ;error exit - diskette not turning 0B9A 06 2C LD B,2CH 0B9C 10 FE RSTALL: DJNZ RSTALL ;preamble delay 0B9E CD 00DF CALL CSTART ;Start the controller 0BA1 06 00 LD B,0 ;single density byte count 0BA3 3A 131A LD A,(131AH) ;get the density bit 0BA6 B7 OR A ;set the zero flag 0BA7 08 EX AF,AF' ;Save the flag ; Find the data field address mark 0BA8 3A 1310 LD A,(1310H) 0BAB 32 4006 LD (4006H),A ;Start the controller looking for an ADDR mark 0BAE 3A 4003 R5LP1: LD A,(4003H) ;Repeat 0BB1 CB 67 BIT 4,A ; If (index hole has passed) 0BB3 20 04 JR NZ,R5SKP1 0BB5 3E 93 LD A,93H ; Error_Code:= missing ADDR mark 0BB7 B7 OR A ; set error flag 0BB8 C9 RET ; Error Return 0BB9 CB 47 R5SKP1: BIT 0,A ;Until (Address mark found) 0BBB 28 F1 JR Z,R5LP1 0BBD 08 EX AF,AF' 0BBE 28 01 JR Z,R5SKP2 ;If (drive is double density) 0BC0 1A LD A,(DE) ; Read second data field address mark 0BC1 E3 R5SKP2: EX (SP),HL ;delay 0BC2 E3 EX (SP),HL ;delay 0BC3 08 EX AF,AF' ;save the flags (specifically the density) 0BC4 1A R5LOOP: LD A,(DE) ;Repeat Repeat read data from disk 0BC5 D9 EXX ; exchange register banks 0BC6 ED 79 OUT (C),A ; transfer data to the DMA channel 0BC8 AA XOR D 0BC9 07 RLCA 0BCA 57 LD D,A ; update the check byte 0BCB 03 INC BC ; advance the DMA pointer 0BCC 78 LD A,B 0BCD B1 OR C ; test for 65K page overflow 0BCE 20 01 JR NZ,REAOK 0BD0 1C INC E ; advance extended page pointer 0BD1 73 REAOK: LD (HL),E ; update extended page register 0BD2 D9 EXX ; swap the register banks 0BD3 10 EF DJNZ R5LOOP ; Until (block is transfered) 0BD5 AF XOR A ; clear the zero flag 0BD6 08 EX AF,AF' ; swap the flags (to find out if its DD) 0BD7 20 EB JR NZ,R5LOOP ;Until (the whole sector has been read) 0BD9 1A LD A,(DE) ;read the check byte 0BDA D9 EXX ;get the check byte 0BDB AA XOR D ;calculate error check byte 0BDC 3E 8E LD A,8EH ;data field CRC error code DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-51 0BDE C3 00EC JP CSTOP ;turn off the controller PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-52 ;---------------------------------------------------------------------- ; Write a sector (5" hard sectored) ;---------------------------------- ; 0BE1 CD 0B65 WRITE5: CALL FSECT5 ;find the sector if drive is ready 0BE4 D8 RET C ;diskette not turning in drive 0BE5 06 11 LD B,11H ;single density preamble length 0BE7 3A 131A LD A,(131AH) ;density byte 0BEA 1F RRA ;density bit to the carry flag 0BEB 3A 1310 LD A,(1310H) 0BEE CB CF SET 1,A ;Set controller to inactive 0BF0 32 4006 LD (4006H),A 0BF3 3E 90 LD A,90H ;control byte for port 4007 0BF5 32 4007 LD (4007H),A ;turn on write gate 0BF8 3A 1310 LD A,(1310H) 0BFB 30 15 JR NC,CSTR ;carry => media is double density ; Set Write Pre-comp and adjust preamble length if double density 0BFD 3A 1312 LD A,(1312H) ;Get the starting track of write pre-comp 0C00 6F LD L,A 0C01 FD 7E 01 LD A,(IY+1) ;If (current track ge 22) 0C04 BD CP L 0C05 3E 24 LD A,24H ; (A:= pre-comp + DD Control Byte) 0C07 38 02 JR C,W5SKP1 ; If (Current track ge start wrt-pre-cmp) 0C09 F6 10 OR 10H ; set write precompensation bit 0C0B 32 4006 W5SKP1: LD (4006H),A ; Setup the controller 0C0E 06 20 LD B,20H ; adjust the preamble length 0C10 CB 8F RES 1,A ; Write the Preamble 0C12 32 4006 CSTR: LD (4006H),A ;start the controller 0C15 AF XOR A ;clear the accumulator 0C16 12 ZEROW: LD (DE),A ;write the preamble 0C17 E3 EX (SP),HL ;delay 0C18 E3 EX (SP),HL ;delay 0C19 10 FB DJNZ ZEROW 0C1B 21 4002 LD HL,4002H ;channel data/extended page pointer 0C1E 47 LD B,A ;single density byte count 0C1F 3A 131A LD A,(131AH) ;get the density byte 0C22 B7 OR A ;set the flags 0C23 3E FB LD A,0FBH ;sync byte 0C25 28 03 JR Z,LASTS ;non-zero => double density 0C27 12 LD (DE),A ; write the first sync byte 0C28 E3 EX (SP),HL ; delay 0C29 E3 EX (SP),HL ; delay 0C2A 12 LASTS: LD (DE),A ;write the last sync byte PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-53 ; Write the Data 0C2B 08 EX AF,AF' ;save the flags 0C2C D9 W5LOOP: EXX ;exchange the register banks 0C2D ED 79 OUT (C),A ;start the data channel 0C2F 03 INC BC ;advance the DMA address 0C30 78 LD A,B 0C31 B1 OR C ;test for 65K page overflow 0C32 20 01 JR NZ,WEAOK ;zero => advance extended page 0C34 1C INC E 0C35 73 WEAOK: LD (HL),E ;update the extended page register 0C36 D9 EXX ;exchange register banks 0C37 7E LD A,(HL) ;get the channel data 0C38 12 LD (DE),A ;write data to the disk 0C39 A9 XOR C 0C3A 07 RLCA ;update the check byte 0C3B 4F LD C,A 0C3C 10 EE DJNZ W5LOOP ;test first/second half of data done 0C3E AF XOR A ;set the zero flag 0C3F 08 EX AF,AF' ;exchange the accumulator 0C40 20 EA JR NZ,W5LOOP ;test for transfer done 0C42 79 LD A,C ;get the data check byte 0C43 12 LD (DE),A ;write to the disk 0C44 E3 EX (SP),HL ;delay 0C45 E3 EX (SP),HL ;delay 0C46 AF XOR A 0C47 12 LD (DE),A ;write a trailing zero 0C48 E3 EX (SP),HL ;delay 0C49 E3 EX (SP),HL ;delay 0C4A 12 LD (DE),A ;delay until previous byte written 0C4B C3 00EC JP CSTOP ;stop controller and exit PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-54 ;====================================================================== ; Commands for Reading and Writing to Main Memory ;================================================ ; Read a Block of the Host's Memory into the Controller's Memory ;--------------------------------------------------------------- ; 0C4E CD 0C8B RDCH: CALL RCMD 0C51 7B CREAD: LD A,E 0C52 B2 OR D ;test for block transfered 0C53 C8 RET Z 0C54 CD 0CAD CALL INCIO ;do a DMA cycle 0C57 3A 4002 LD A,(4002H) ;get the DMA channel data 0C5A 77 LD (HL),A ;store data at pointer 0C5B 23 INC HL ;advance the pointer 0C5C 1B DEC DE ;decrement the data block count 0C5D 18 F2 JR CREAD ; Write a Block of Controller Memory to the Host's Memory ;-------------------------------------------------------- ; 0C5F CD 0C96 WRCH: CALL WCMD 0C62 7B CWRITE: LD A,E 0C63 B2 OR D ;test for block transfered 0C64 C8 RET Z 0C65 7E LD A,(HL) ;get the memory data 0C66 23 INC HL ;advance the pointer 0C67 CD 0CAD CALL INCIO ;do a DMA cycle 0C6A 1B DEC DE ;decrement the block count 0C6B 18 F5 JR CWRITE ; Read/Write a Byte from/to Main Memory and Increment the Channel Address ;------------------------------------------------------------------------ ; 0C6D CD 0C8B RBYTE: CALL RCMD ;Set the channel up for reading 0C70 18 03 JR RWBYTE 0C72 CD 0C96 WBYTE: CALL WCMD ;set the channel up for writing 0C75 08 RWBYTE: EX AF,AF' ;save the accumulator 0C76 3A 13C2 LD A,(13C2H) ;get the extended page 0C79 08 EX AF,AF' ;restore the accumulator 0C7A ED 4B 13C0 LD BC,(13C0H) ;load lower channel address 0C7E CD 0CAD CALL INCIO ;do the channel command & increment ; Channel Address Store ;---------------------- ; 0C81 08 CASTOR: EX AF,AF' 0C82 32 13C2 LD (13C2H),A ;save new extended page 0C85 ED 43 13C0 LD (13C0H),BC ;save new lower address 0C89 08 EX AF,AF' ;recover the accumulator 0C8A C9 RET PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-55 ; Setup for a Read from the Host's Memory ;---------------------------------------- ; 0C8B F5 RCMD: PUSH AF ;save the accumulator 0C8C 3E A1 LD A,0A1H ;S-100 status byte for reading 0C8E F5 PUSH AF ;save the status 0C8F 3A 1310 LD A,(1310H) ;memory image of 4006 cmd. port 0C92 E6 7F AND 7FH ;force channel read/write bit to read 0C94 18 09 JR EXCMD ; Setup for a Write into the Host's Memory ;----------------------------------------- ; 0C96 F5 WCMD: PUSH AF ;save the accumulator 0C97 3E 01 LD A,1 ;S-100 status byte for writing 0C99 F5 PUSH AF 0C9A 3A 1310 LD A,(1310H) 0C9D F6 80 OR 80H ;force channel read/write bit to write 0C9F 32 1310 EXCMD: LD (1310H),A ;update memory image of port 4006 0CA2 CB CF SET 1,A ;Controller_stop_bit:= set 0CA4 32 4006 LD (4006H),A ;update command port 4006 0CA7 F1 POP AF ;recover the status byte 0CA8 32 4003 LD (4003H),A ;update the S-100 status register 0CAB F1 POP AF ;recover the accumulator 0CAC C9 RET ; Read/Write to/from Host Memory and increment Host address (in A & BC) ;---------------------------------------------------------------------- ; 0CAD 08 INCIO: EX AF,AF' ;get extended page value 0CAE 32 4002 LD (4002H),A ;initialize extended page register 0CB1 08 EX AF,AF' ;recover the data 0CB2 ED 79 OUT (C),A ;Read/Write Data to/from Host Memory (BC=Addr) 0CB4 0C INCR3: INC C ;advanve the LSB of DMA address 0CB5 C0 RET NZ 0CB6 04 INC B ;advance the MSB of DMA address 0CB7 C0 RET NZ 0CB8 08 EX AF,AF' 0CB9 3C INC A ;advance the extended page value 0CBA 08 EX AF,AF' 0CBB C9 RET ; Diagnostic Routine - Restore the channel command address ;--------------------------------------------------------- ; 0CBC ED 4B 13C4 RESTOR: LD BC,(13C4H) ;get the channel command address 0CC0 08 EX AF,AF' ;save the accumulator 0CC1 3A 13C6 LD A,(13C6H) ;extended page of address 0CC4 C3 0C82 JP CASTOR+1 ;restore the channel command address PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-56 ;---------------------------------------------------------------------- ; Input a Character from the Serial Port ;--------------------------------------- ; 1) This routine returns Non-Zero if it didn't get a character. ; 2) Notice the routine COUNT is constantly called. ; 3) Register Usage ; A - General Purpose/Returned Character ; B - Bit Cell Timer ; C - Bit Count/Returned Character ; HL - Pointer to Disk Status Port ; ; Entry Point 1 - Hang Until a character is present 0CC7 CD 0CCD HSPIN: CALL SPIN ;Repeat 0CCA 20 FB JR NZ,HSPIN ;Until (Character present) 0CCC C9 RET ; Entry Point 2 - Get character (if present) and return 0CCD CD 0E65 SPIN: CALL COUNT ;look for index/sector hole 0CD0 21 4003 LD HL,4003H ;HL:= Pointer to the Disk Status Port 0CD3 CB 4E BIT 1,(HL) ;If (serial port not active) 0CD5 C0 RET NZ ; Return 0CD6 01 0A08 LD BC,0A08H ;Else (B:=Half_Bit_Time, C:=Bit_Count) 0CD9 10 FE INLP1: DJNZ INLP1 ; wait half a bit time 0CDB CB 4E BIT 1,(HL) ; If (serial port no longer active) 0CDD 20 EE JR NZ,SPIN ; Go back and count another hole 0CDF 06 19 INLP2: LD B,19H ;Repeat (9600 baud cell time) 0CE1 10 FE INLP3: DJNZ INLP3 ; wait one cell time 0CE3 37 SCF ; assume a 1 bit is present 0CE4 CB 4E BIT 1,(HL) ; If (bit is NOT a 1) 0CE6 20 01 JR NZ,INSKP1 0CE8 3F CCF ; clear the bit to a zero 0CE9 1F INSKP1: RRA ; shift new bit into the accumulator 0CEA 0D DEC C ; Bit_Count:= Bit_Count - 1 0CEB 20 F2 JR NZ,INLP2 ;Until (Bit_Count eq 0) 0CED 4F LD C,A ;C:= Character 0CEE C9 RET PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-57 ;---------------------------------------------------------------------- ; Output a Character to the Serial Port ;-------------------------------------- ; 3) Register Usage ; A - General Purpose ; B - Bit Cell Timer ; C - Save of the character to output ; H - Save of the character to output ; L - Bit cell count ; IX - 13F0 => Current Drive scratch pad area ; 0CEF F5 SPOUT: PUSH AF 0CF0 3A 1310 LD A,(1310H) 0CF3 CB CF SET 1,A ;Set the controller stop bit 0CF5 DD 77 06 LD (IX+6H),A ;memory image of 4006 to 1310 0CF8 F1 POP AF 0CF9 F6 80 OR 80H ;append a rest bit 0CFB 4F LD C,A ;save the character in C 0CFC CD 0E65 CALL COUNT ;look for index/sector hole 0CFF 79 LD A,C ;restore the character 0D00 E6 7F AND 7FH ;make character into 7 bit ASCII 0D02 67 LD H,A ;save ASCII character in H 0D03 3E 08 LD A,8 ;start bit 0D05 2E 0B LD L,0BH ;total bit count of character 0D07 DD 86 06 OLOOP: ADD A,(IX+6) ;merge with port 4006 image 0D0A 32 4006 LD (4006H),A ;send bit to the serial port 0D0D AF XOR A ;clear the accumulator 0D0E 06 18 LD B,18H ;9600 baud cell delay time 0D10 10 FE BTIME: DJNZ BTIME ;wait one cell time 0D12 CB 29 SRA C ;get the next serial bit from C 0D14 3F CCF ;compliment the carry 0D15 17 RLA 0D16 17 RLA 0D17 17 RLA 0D18 17 RLA ;rotate carry to serial bit 0D19 2D DEC L ;decrement the bit count 0D1A 20 EB JR NZ,OLOOP ;0 => character done 0D1C 4C LD C,H ;restore the ASCII character to C 0D1D C3 0E65 JP COUNT PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-58 ;====================================================================== ; Internal Monitor ;================= ; 0D20 ED 73 13C7 MONTR: LD (MONRAM),SP ;Save the stack pointer 0D24 31 13DC MONE2: LD SP,MONRAM+15H ;Stack_Pointer:= Start of Monitor stack 0D27 11 0E27 LD DE,PROMT ;Pointer:= Start of Prompt 0D2A 1A MONE3: LD A,(DE) ;Repeat Get next character of Prompt string 0D2B CD 0CEF CALL SPOUT ; Print character 0D2E 13 INC DE ; Pointer:= Pointer + 1 0D2F 1A LD A,(DE) ; Get_Next_Character 0D30 B7 OR A 0D31 20 F7 JR NZ,MONE3 ;Until (Character eq 0) 0D33 11 0000 LD DE,0 ;Argument:= 0 0D36 CD 0E02 MONLP1: CALL GETC ;Repeat 0D39 38 0C JR C,MONCMD ; if (character eq command) 0D3B 06 04 LD B,4 ; goto Identify_a_Command 0D3D CB 23 SHIFT: SLA E ; else 0D3F CB 12 RL D ; move new nibble into arg. reg. 0D41 10 FA DJNZ SHIFT 0D43 83 ADD A,E 0D44 5F LD E,A 0D45 18 EF JR MONLP1 ; Identify a command ;------------------- ; 1) This routine checks if the input is a proper command (upper- ; case G (go-execute), P (print), or W (write)). ; 2) If the command is identified then control is transferred to ; the following routine (FOUND) ; 0D47 06 03 MONCMD: LD B,3 ;Counter:= Max number of commands 0D49 21 0E1D LD HL,CMDTBL ;Pointer:= Command_Table_Base 0D4C BE MONLP2: CP (HL) ;While (char ne command) 0D4D 23 INC HL ; pointer:= (start of vector) 0D4E 28 09 JR Z,FOUND ; goto Execute_a_Command 0D50 23 INC HL 0D51 23 INC HL ; Pointer:= Pointer+2 (start next entry) 0D52 10 F8 DJNZ MONLP2 ;Until (all commands checked) 0D54 11 0E26 LD DE,ERROR ;Pointer:= start of error prompt string 0D57 18 D1 JR MONE3 ;Goto monitor output prompt string ; Execute a command ;------------------ ; 1) If a command was identified by CMD then the HL pair is left ; pointing to the execution vector in the command table (CMDTBL). ; 0D59 7E FOUND: LD A,(HL) ;Move the vector into the HL pair 0D5A 23 INC HL 0D5B 66 LD H,(HL) 0D5C 6F LD L,A 0D5D E9 JP (HL) ;Execute the command (GO, WRITE or PRINT) PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-59 ;---------------------------------------------------------------------- ; Go Execute a Routine ;--------------------- ; 1) This routine executes a routine in controller memory (execution ; address is sent in the DE register pair). ; 2) Both the Normal and Alternate register loaded from and saved to: ; MONRAM+15H 13DC F - AF 13E6 IY - IY ; 13DD A 13E7 IY ; 13DE B - BC 13E8 F - AF' ; 13DF C 13E9 A ; 13E0 E - DE 13EA C - BC' ; 13E1 D 13EB B ; 13E2 L - HL 13EC E - DE' ; 13E3 H 13ED D ; 13E4 IX - IX 13EE L - HL' ; 13E5 IX 13EF H ; 0D5E 21 0D7A GO: LD HL,SRETRN ;SRETRN is return address after cmnd finishes 0D61 E5 PUSH HL ;Put return address on stack (13DA & 13DB) 0D62 D5 PUSH DE ;Put Execution address on stack (13D8 & 13D9) 0D63 31 13DC LD SP,MONRAM+15H ;Stack_Pointer:= start of register save area 0D66 F1 POP AF ;Setup Registers 0D67 C1 POP BC 0D68 D1 POP DE 0D69 E1 POP HL 0D6A DD E1 POP IX 0D6C FD E1 POP IY 0D6E 08 EX AF,AF' 0D6F F1 POP AF 0D70 08 EX AF,AF' 0D71 D9 EXX 0D72 C1 POP BC 0D73 D1 POP DE 0D74 E1 POP HL 0D75 D9 EXX 0D76 31 13D8 LD SP,MONRAM+11H ;Stack Pointer to Execution Address 0D79 C9 RET ;Execute the command 0D7A 31 13F0 SRETRN: LD SP,MONRAM+29H ;Stack_Pointer:= End of register save area 0D7D D9 EXX ;Restore registers 0D7E E5 PUSH HL 0D7F D5 PUSH DE 0D80 C5 PUSH BC 0D81 D9 EXX 0D82 08 EX AF,AF' 0D83 F5 PUSH AF 0D84 08 EX AF,AF' 0D85 FD E5 PUSH IY 0D87 DD E5 PUSH IX 0D89 E5 PUSH HL 0D8A D5 PUSH DE 0D8B C5 PUSH BC 0D8C F5 PUSH AF 0D8D C3 0D24 JP MONE2 ;Goto The Idle loop PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-60 ;---------------------------------------------------------------------- ; Write To Controller Memory ;--------------------------- ; 0D90 CD 0DD8 WRITE: CALL FORMAT ;Print newline followed by starting location 0D93 3E 20 WRLOOP: LD A,20H ;Repeat 0D95 CD 0CEF CALL SPOUT ; Print a space 0D98 CD 0E02 CALL GETC ; If (current character isn't hex) 0D9B 38 0A JR C,LEAVE ; Return 0D9D 07 RLCA ; Move current character into m.s.n 0D9E 07 RLCA 0D9F 07 RLCA 0DA0 07 RLCA 0DA1 4F LD C,A ; Save the character 0DA2 D9 EXX 0DA3 CD 0E02 CALL GETC ; Get the l.s.n 0DA6 D9 EXX ; If (current character isn't hex) 0DA7 DA 0D24 LEAVE: JP C,MONE2 ; Return 0DAA 81 ADD A,C ; Combine the two halves of the number 0DAB 12 LD (DE),A ; Store number at current location 0DAC 13 INC DE ; Pointer:= Pointer + 1 0DAD 7B LD A,E 0DAE E6 0F AND 0FH 0DB0 20 E1 JR NZ,WRLOOP ;Until (l.s.b of location is zero) 0DB2 18 DC JR WRITE ;GOTO Start a new line PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-61 ;---------------------------------------------------------------------- ; Print the contents of controller memory ;---------------------------------------- ; 0DB4 CD 0DD8 PRINT: CALL FORMAT ;Repeat New line followed by starting address 0DB7 3E 20 PRNLP1: LD A,20H ; Repeat 0DB9 CD 0CEF CALL SPOUT ; Print a space 0DBC 1A LD A,(DE) 0DBD CD 0DF1 CALL PUTL ; Print m.s.n of current location 0DC0 1A LD A,(DE) 0DC1 CD 0DF5 CALL PUTR ; Print l.s.n of current location 0DC4 13 INC DE 0DC5 7B LD A,E 0DC6 E6 0F AND 0FH 0DC8 20 ED JR NZ,PRNLP1 ; Until (the l.s.n of address is zero) 0DCA CD 0CC7 CALL HSPIN ; Wait for a character from serial port 0DCD CD 0CEF CALL SPOUT ; Echo the character to the serial port 0DD0 79 LD A,C 0DD1 FE 20 CP 20H 0DD3 28 DF JR Z,PRINT ;Until (input character is not a space) 0DD5 C3 0D24 JP MONE2 ;GOTO Monitor 0DD8 3E 0D FORMAT: LD A,0DH ;Output a carriage return - line feed 0DDA CD 0CEF CALL SPOUT 0DDD 3E 0A LD A,0AH 0DDF CD 0CEF CALL SPOUT 0DE2 7A LD A,D 0DE3 CD 0DF1 CALL PUTL ;Print most-signifigant nibble of m.s.d 0DE6 7A LD A,D 0DE7 CD 0DF5 CALL PUTR ;Print least-signifigant nibble of m.s.d 0DEA 7B LD A,E 0DEB CD 0DF1 CALL PUTL ;Print most-signifigant nibble of l.s.d 0DEE 7B LD A,E 0DEF 18 04 JR PUTR ;Print least-signifigant nibble of l.s.d 0DF1 0F PUTL: RRCA ;Print the Left half of the accm as ascii-hex 0DF2 0F RRCA 0DF3 0F RRCA 0DF4 0F RRCA 0DF5 E6 0F PUTR: AND 0FH ;Print the Right half of the accm as ascii-hex 0DF7 C6 30 ADD A,'0' 0DF9 FE 3A CP ':' ;If (number is lt ascii-hex) 0DFB DA 0CEF JOUT: JP C,SPOUT ; Print it 0DFE D6 F9 SUB 0F9H ;Else add offset (makes A-F print properly) 0E00 18 F9 JR JOUT ; Print it PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-62 ;---------------------------------------------------------------------- ; Get a Character ;---------------- ; 1) This routine returns with a character in the accm. ; 2) If the character is a hex digit then it is translated into ; binary. ; 3) If the character is NOT hexadecimal then the carry is returned set ; 0E02 CD 0CC7 GETC: CALL HSPIN ;Wait for a character from the serial port 0E05 CD 0CEF CALL SPOUT ;Echo the character to the serial port 0E08 79 LD A,C 0E09 FE 30 CP '0' ;If (Character lt the smallest number) 0E0B D8 RET C ; Return 0E0C FE 47 CP 'G' ;If (Character gt the largest alpha) 0E0E 3F CCF ; (adjust the return status) 0E0F D8 RET C ; Return 0E10 06 30 LD B,'0' ;Offset:= Number 0E12 FE 3A CP ':' ;If (Character gt the largeset number) 0E14 38 05 JR C,MHEX 0E16 FE 41 CP 'A' ; If (Character lt smallest alpha) 0E18 D8 RET C ; Return 0E19 06 37 LD B,37H ; Offset:= alpha 0E1B 90 MHEX: SUB B ;convert ascii character into hex 0E1C C9 RET ;Return ;---------------------------------------------------------------------- ; Command table for Monitor ;-------------------------- ; 0E1D 47 CMDTBL: DB 'G' ;Go Execute a Subroutine 0E1E 0D5E DW GO 0E20 50 DB 'P' ;Print Controller Memory 0E21 0DB4 DW PRINT 0E23 57 DB 'W' ;Write to Controller Memory 0E24 0D90 DW WRITE ;---------------------------------------------------------------------- ; Error and Prompt strings for Monitor ;------------------------------------- ; 0E26 3F ERROR: DB '?' ;Question Mark 0E27 0D PROMT: DB 0DH ;Carriage Return 0E28 0A DB 0AH ;Line Feed 0E29 3A DB ':' ;Colon 0E2A 00 DB 0 ;End of String PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-63 ;---------------------------------------------------------------------- ; Hard Sectored Disk Sector/Index Synchronization ;------------------------------------------------ ; General Description: ; This routine Keeps track of the sector counts for 5" hard ; disks. The program HANGS, calling COUNT looking for a Sector/Index ; hole or until a Time-Out (about 3.11 seconds) occurs. If current ; sector isn't known (decalibrated = bit-7 set) then a synchronization ; process takes place. ; Initial synchronization with the disk occurs directly after ; counting 2 successive hole with a delay of 12ms or less between them ; (the program can get fooled by two counts greater than 24 ms). The ; sector following these two closely spaced holes is sector 0. ; Notes: ; 1) Each iteration takes about 47.45us. 14us here and 33.45 in COUNT. ; 2) If the disk isn't turning then the Z-Flag is returned set. ; 3) The constant MAXHS5 is the max. number of sectors on a 5" (hs) disk. ; 4) Register Usage: ; A - General Purpose ; B - Hole Count ; DE - Time_Delay ; HL - Pointer to Disk Status Register (4003h - setup in COUNT) ; ; Look for an index/sector hole 0E2B 11 0000 HSYNC: LD DE,0 ;Time_Delay:= Max_Delay 0E2E CD 0E65 CALL COUNT ;while (Hole ne Found) 0E31 20 06 JR NZ,TSYNC 0E33 13 INC DE ; Time_Delay:= Time_Delay + 1 0E34 7A LD A,D 0E35 B3 OR E ; if (Time_Delay eq 0) 0E36 20 F5 JR NZ,HSYNC+2 ; (Disk not turning) 0E38 C9 RET ; error exit w/zero flag set 0E39 DD CB 0E 5E TSYNC: BIT @SCT,(IX+XFLAG) ;If (sector count eq uncalibrated) 0E3D 20 1E JR NZ,SLEAVE ; ; Repeat 0E3F 06 02 ISYNC: LD B,2 ; Short_Counts:= 2 0E41 11 0000 LD DE,0 ; Time_Delay:= Max_Delay 0E44 CD 0E65 HSLOOP: CALL COUNT ; While (Hole ne Found) 0E47 20 06 JR NZ,HFOUND 0E49 13 INC DE ; Time_Delay:=Time_Dely+1 0E4A 7A LD A,D ; 0E4B B3 OR E ; If (Time_Delay eq 0) 0E4C 20 F6 JR NZ,HSLOOP 0E4E C9 RET ; exit Error 0E4F CB 4A HFOUND: BIT 1,D ; if (delay le 12.15ms) (or gt 24.3ms) 0E51 20 EC JR NZ,ISYNC ; go reset short delay count ; if (only one short delay counted) 0E53 10 EC DJNZ ISYNC+2 ; go check for 2nd short count ; Else 0E55 DD 36 0A 00 LD (IX+0AH),0 ; Sector_Count:= 0 0E59 DD CB 0E DE SET @SCT,(IX+XFLAG) ; Sector_Calibrated:= true 0E5D 3E 0A SLEAVE: LD A,MAXHS5 ;if (index hole eq found) 0E5F DD BE 0A CP (IX+0AH) ; 0E62 28 C7 JR Z,HSYNC ; go back & wait for sector zero 0E64 C9 RET ;exit without error PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-64 ;---------------------------------------------------------------------- ; Count Sector/Index Holes ;------------------------- ; 1) This routine returns with the zero flag cleared if a new hole ; was found. ; 2) If the maximum number of index holes has been counted then the ; drive is deselected. Deselection is done by jumping to the ; deselect routine. This is done to avoide premature termination ; (see ENTNMI). ; 3) Register Usage: ; A -> General purpose ; HL -> Pointer (4003h-4005h) (Left Pointing to 4003) ; 0E65 21 4003 COUNT: LD HL,4003H ;HL:= Pointer to status register 0E68 CB 66 BIT 4,(HL) ;if (index/sector_bit eq inactive) 0E6A 20 05 JR NZ,SIHIGH ; 0E6C DD CB 0E E6 SET @HOL,(IX+XFLAG) ; hole_processed:= false 0E70 C9 RET ; exit (hole not found) 0E71 DD CB 0E 66 SIHIGH: BIT @HOL,(IX+XFLAG) ;if (hole_processed eq true) 0E75 C8 RET Z ; exit (hole found but already processed) 0E76 DD CB 0E A6 RES @HOL,(IX+XFLAG) ;hole_processed:= true 0E7A FD CB 0E 4E BIT @HRD,(IY+YFLAG) ;if (media eq hard_sectored) 0E7E 28 17 JR Z,ICOUNT ; 0E80 DD 34 0A INC (IX+0AH) ; sector_count:= sector_count + 1 0E83 3E 0A LD A,MAXHS5 ; (max_sectors = last sector number + 1) 0E85 DD CB 0E 6E BIT @FHF,(IX+XFLAG) ; If (first hole found is true) 0E89 28 01 JR Z,SIDLE 0E8B 3C INC A ; max_sectors:= max_sectors + 1 0E8C DD CB 0E EE SIDLE: SET @FHF,(IX+XFLAG) ; Set first hole found to true 0E90 DD 96 0A SUB (IX+0AH) ; if (sector ne 0) 0E93 C0 RET NZ ; exit (hole found & not sect 0) 0E94 DD 77 0A LD (IX+0AH),A ; sector_count:= 0 0E97 DD 34 0B ICOUNT: INC (IX+0BH) ;index_count:= index_count + 1 0E9A DD 7E 0D LD A,(IX+0DH) ;A:= max revs before drive deselect 0E9D DD 96 0B SUB (IX+0BH) ;if (index_count EQ max revs before deselect) 0EA0 CA 0EA4 JP Z,DRVOFF ; deselect the drive (DO NOT CALL) 0EA3 C9 RET PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-65 ;---------------------------------------------------------------------- ; Turn off the current drive ;--------------------------- ; 1) This routine sets the drive's status inactive and then turns ; the motor. ; 0EA4 CD 0EAB DRVOFF: CALL DESEL ;Set the drive status to inactive 0EA7 CD 0ECB CALL MOTOFF ;Turn off the motor 0EAA C9 RET ;---------------------------------------------------------------------- ; Deselect the Drive but not the motor ;------------------------------------- ; 1) This routine set the status of the current drive to inactive. ; 2) To turn off the motor line you must call MOTOFF. ; 3) Register Usage: ; HL -> Pointer to Drive Control Port ; 0EAB F5 DESEL: PUSH AF ;Save the accm and the flags 0EAC 3E FE LD A,11111110B ;Setup to Deselect everything but the motor 0EAE 21 4004 LD HL,4004H 0EB1 FD CB 0E 56 BIT @5IN,(IY+YFLAG) ;if (drive_control_port ne 5") 0EB5 20 01 JR NZ,DESKP1 0EB7 2C INC L ; (move pointer to 8" control port 4005h) 0EB8 DD CB 0E 56 DESKP1: BIT @MOT,(IX+XFLAG) ;If (Motor_Staus eq Inactive) 0EBC 20 02 JR NZ,DESKP2 0EBE 3E FF LD A,11111111B ; Setup to Deselect everything 0EC0 77 DESKP2: LD (HL),A ;Deselect 0EC1 FD CB 0E BE RES @HDL,(IY+YFLAG) ;Head_loaded:= False 0EC5 DD CB 0E 9E RES @SCT,(IX+XFLAG) ;Sector_Count_Calibrated:= False 0EC9 F1 POP AF ;Restore the accm and the flags 0ECA C9 RET ;---------------------------------------------------------------------- ; Turn off the motor line ;------------------------ ; 1) Register Usage: ; HL -> Pointer to Drive Control Port (left pointing to 4003) 0ECB 21 4004 MOTOFF: LD HL,4004H ;HL:= 5" Drive control port (4004h) 0ECE 36 FF MOSKP1: LD (HL),11111111B ;deselect the drive 0ED0 2E 03 LD L,3 ;HL:= Disk status port (4003h) 0ED2 DD CB 0E 96 RES @MOT,(IX+XFLAG) ;Motor_Status:= Inactive 0ED6 C9 RET PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-66 ;====================================================================== ; COMMAND TABLE ;============== ; 1) the byte count at the end of each title line tells how many ; bytes the total command takes. This includes both the command ; code (always present) and the status (sometimes present). ; 2) The parameters are enumerated following each title line. ; 3) Commands are grouped according to function. ; ;---------------------------------------------------------------------- ;Initial Setup Commands: ;----------------------- ; ;Set CRC Error Retry Count (2 bytes) ; 1 - retry count + 1 ; 0ED7 28 CTABLE: DB 28H 0ED8 0311 DW SETCRC 0EDA 01 DB 1 ;Unload Head Timeout (2 bytes) ; 1 - count ; 0EDB 2F DB 2FH 0EDC 0316 DW SETLFT 0EDE 01 DB 1 ;Set Track Size (4 bytes) ; 1 - drive ; 2 - highest track ; 0EDF 2D DB 2DH 0EE0 031B DW TRACKZ 0EE2 02 DB 2 PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-67 ;Set Drive Parameters ; 1 - drive ; 2 - step rate ; 3 - step settle time ; 4 - head load delay time ; 5 - motor on delay time ; 0EE3 30 DB 30H 0EE4 032B DW SETDP 0EE6 05 DB 5 ;Set Media Parameters ; 1 - drive ; 2 - starting track of write pre-compensation ; 3 - highest track number ; 4 - first sector's number ; 5 - total number of sectors per track ; 0EE7 31 DB 31H 0EE8 0370 DW SETMP 0EEA 05 DB 5 ;Change Logical Drives (3 bytes) ; 1 - mask ; 0EEB 2E DB 2EH 0EEC 0393 DW LOGCAL 0EEE 01 DB 1 ;Set DMA Address (4 bytes) ; 1 - New DMA Address low byte ; 2 - " " " med byte ; 3 - " " " high byte ; 0EEF 23 DB 23H 0EF0 03AB DW SETDMA 0EF2 03 DB 3 ;Set Channel Command Word Address (4 bytes) ; 1 - New Channel Command Address low byte ; 2 - " " " " med byte ; 3 - " " " " high byte ; 0EF3 27 DB 27H 0EF4 03B5 DW SETCCW 0EF6 03 DB 3 PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-68 ;---------------------------------------------------------------------- ; Disk Access Commands ;--------------------- ; ;Sense Drive Status (6 bytes) ; 1 - drive ; 0EF7 22 DB 22H 0EF8 040A DW GSTAT 0EFA 01 DB 1 ;Read Sector (5 bytes) ; 1 - track ; 2 - side/sector ; 3 - drive ; 0EFB 20 DB 20H 0EFC 0442 DW RDSECT 0EFE 03 DB 3 ;Write Sector (5 bytes) ; 1 - track ; 2 - side/sector ; 3 - drive ; 0EFF 21 DB 21H 0F00 043E DW WRSECT 0F02 03 DB 3 ;Read Track (5 bytes) ; 1 - track ; 2 - side ; 3 - drive ; 4 - sector table low byte ; 5 - " " med byte ; 6 - " " high byte ; 0F03 29 DB 29H 0F04 04C5 DW RTRACK 0F06 06 DB 6 ;Write Track (8 bytes) ; 1 - track ; 2 - side ; 3 - drive ; 4 - sector table low byte ; 5 - " " med byte ; 6 - " " high byte ; 0F07 2A DB 2AH 0F08 04C1 DW WTRACK 0F0A 06 DB 6 PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-69 ;---------------------------------------------------------------------- ; Controlling Process Execution ;------------------------------ ; ;Branch in Channel (4 bytes) ; 1 - New Channel Address low byte ; 2 - " " " med byte ; 3 - " " " high byte ; 0F0B 26 DB 26H 0F0C 03BF DW SETCAW 0F0E 03 DB 3 ;Halt Controller (2 bytes) ; 0 - No Parameters ; 0F0F 25 DB 25H 0F10 03C4 DW HALTC 0F12 00 DB 0 ;Set Interrupt Request (2 bytes) ; 0 - No Parameters ; 0F13 24 DB 24H 0F14 03C9 DW INTRQC 0F16 00 DB 0 PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-70 ;---------------------------------------------------------------------- ; Other Commands ;--------------- ; ;Output to Serial Port (3 bytes) ; 1 - ASCII character ; 0F17 2B DB 2BH 0F18 03E6 DW SEROUT 0F1A 01 DB 1 ;Serial Input Enable (2 bytes) ; 1 - mask ; 0F1B 2C DB 2CH 0F1C 03ED DW SRENBL 0F1E 01 DB 1 ;Dump Controller Memory (8 bytes) ; 1 - main memory lo byte ; 2 - " " med byte ; 3 - " " high byte ; 4 - number of bytes to transfer low cnt ; 5 - " " " " " high cnt ; 6 - address in controller memory low byte ; 7 - " " " " high byte ; 0F1F A0 DB 0A0H 0F20 03FB DW DUMPM 0F22 07 DB 7 ;Load Controller Memory (8 bytes) ; 1 - main memory lo byte ; 2 - " " med byte ; 3 - " " high byte ; 4 - number of bytes to transfer low cnt ; 5 - " " " " " high cnt ; 6 - address in controller memory low byte ; 7 - " " " " high byte ; 0F23 A1 DB 0A1H 0F24 0403 DW LOADM 0F26 07 DB 7 ;Execute Controller Routine (4 bytes) ; 1 - Execution Address low byte ; 2 - " " high byte ; 3 - " " status ; 0F27 A2 DB 0A2H 0F28 0408 DW GOMEM 0F2A 02 DB 2 ; 0F2B 80 DB 80H ;End of Table PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-71 ;====================================================================== ; Tables That are Moved into the controller's ram ;================================================ ; Vector Table (loaded into memory starting at location 1290H) ;============================================================= ; 0F2C 09B2 RTBL: DW READS ;Vector to Soft Sectored Read a Sector Routine 0F2E 0B96 DW READ5 ;Vector to Hard Sectored Read a Sector Routine 0F30 0000 DW 0 ;Spare 0F32 0000 DW 0 ;Spare 0F34 0A73 WTBL: DW WRITES ;Vector to Soft Sectored Write a Sector Routine 0F36 0BE1 DW WRITE5 ;Vector to Hard Sectored Write a Sector Routine 0F38 0000 DW 0 ;Spare 0F3A 0000 DW 0 ;Spare ; 8" Soft Sectored Drive constants ;================================= ; 8" drive single density [addr = 12A0] ;-------------------------------------- 0F3C 44 SECT8: DB 44H ;port 4006 control byte 0F3D 73 DB 73H ;port 4007 control byte 0F3E 2B DB 43 ;Default Starting Track of Write Pre-Compensation 0F3F 00 DB 0 ;not used 0F40 00 DB 0 ;not used 0F41 00 DB 0 ;not used 0F42 00 DB 0 ;track number 0F43 00 DB 0 ;side number 0F44 00 DB 0 ;sector number 0F45 00 DB 0 ;sector length code 0F46 00 DB 0 ;single density ID byte 0F47 63 DB 63H ;port 4007 CRC control byte 0F48 00 DB 0 ;not used 0F49 00 DB 0 ;not used 0F4A 44 DB 44H ;Port 4006 write control byte 0F4B 00 DB 0H ;not used ; 8" drive double density [addr = 12B0] ;-------------------------------------- 0F4C 04 DB 4 ;port 4006 control byte 0F4D 70 DB 70H ;port 4007 control byte 0F4E 2B DB 43 ;Default Starting Track of Write Pre-Compensation 0F4F 00 DB 0 ;not used 0F50 00 DB 0 ;not used 0F51 00 DB 0 ;not used 0F52 00 DB 0 ;track number 0F53 00 DB 0 ;side number 0F54 00 DB 0 ;sector number 0F55 00 DB 0 ;sector length code 0F56 01 DB 1 ;double density ID byte 0F57 61 DB 61H ;port 4007 CRC control byte 0F58 00 DB 0 ;not used 0F59 00 DB 0 ;not used 0F5A 04 DB 4H ;Port 4006 write control byte 0F5B 00 DB 0H ;not used PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-72 ; 5" Soft Sectored Drive Constants ;================================= ; 5" drive single density (soft sectored) [addr = 12C0] ;------------------------------------------------------ 0F5C 64 DB 64H ;port 4006 control byte 0F5D 7B DB 7BH ;port 4007 control byte 0F5E 11 DB 17 ;Default Starting Track of Write Pre-Compensation 0F5F 00 DB 0 ;not used 0F60 00 DB 0 ;not used 0F61 00 DB 0 ;not used 0F62 00 DB 0 ;track number 0F63 00 DB 0 ;side number 0F64 00 DB 0 ;sector number 0F65 00 DB 0 ;sector length code 0F66 00 DB 0 ;double density flag 0F67 63 DB 63H ;checksum control code 0F68 00 DB 0 ;not used 0F69 00 DB 0 ;not used 0F6A 64 DB 64H ;Port 4006 write control byte 0F6B 00 DB 0H ;not used ; 5" drive double density (soft sectored) [addr = 12D0] ;------------------------------------------------------ 0F6C 54 DB 54H ;port 4006 control byte 0F6D 70 DB 70H ;port 4007 control byte 0F6E 11 DB 17 ;Default Starting Track of Write Pre-Compensation 0F6F 00 DB 0 ;not used 0F70 00 DB 0 ;not used 0F71 00 DB 0 ;not used 0F72 00 DB 0 ;track number 0F73 00 DB 0 ;side number 0F74 00 DB 0 ;sector number 0F75 00 DB 0 ;double density flag 0F76 01 DB 1 ;sector length code 0F77 60 DB 60H ;checksum control 0F78 00 DB 0 ;not used 0F79 00 DB 0 ;not used 0F7A 24 DB 24H ;Port 4006 write control byte FM=false & MINI=true 0F7B 00 DB 0H ;not used PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-73 ;5" Hard sectored Drive Constants ;================================ ; 5" drive single density (hard sectored) [addr = 12E0] ;------------------------------------------------------ 0F7C 64 SECT5: DB 64H ;port 4006 control byte 0F7D 73 DB 73H ;port 4007 control byte 0F7E 11 DB 17 ;Default Starting Track of Write Pre-Compensation 0F7F 00 DB 0 ;not used 0F80 00 DB 0 ;not used 0F81 00 DB 0 ;not used 0F82 00 DB 0 ;track number (not used in this format) 0F83 00 DB 0 ;side number (not used in this format) 0F84 00 DB 0 ;sector number (not used in this format) 0F85 01 DB 1 ;sector length code 0F86 00 DB 0 ;double density flag 0F87 73 DB 73H ;checksum control byte 0F88 00 DB 0 ;not used 0F89 00 DB 0 ;not used 0F8A 64 DB 64H ;Port 4006 write control byte 0F8B 00 DB 0H ;not used ; 5" drive double density (hard sectored) [addr = 12F0] ;------------------------------------------------------ 0F8C 54 DB 54H ;port 4006 control byte 0F8D 7B DB 7BH ;port 4007 control byte 0F8E 11 DB 17 ;Default Starting Track of Write Pre-Compensation 0F8F 00 DB 0 ;not used 0F90 00 DB 0 ;not used 0F91 00 DB 0 ;not used 0F92 00 DB 0 ;track number (not used in this format) 0F93 00 DB 0 ;side number (not used in this format) 0F94 00 DB 0 ;sector number (not used in this format) 0F95 02 DB 2 ;sector length code 0F96 01 DB 1 ;double density flag 0F97 7B DB 7BH ;checksum control byte 0F98 00 DB 0 ;not used 0F99 00 DB 0 ;not used 0F9A 54 DB 54H ;Port 4006 write control byte 0F9B 00 DB 0H ;not used PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-74 ; Drive parameter tables (loaded starting at location BASEIY) ;============================================================ ; 8" drive table 0F9C 4D DRIVE8: DB 4DH ;high track + 1 0F9D FF DB 0FFH ;current track 0F9E F3 DB 0F3H ;drive pattern ; - ;Logical drive Number (Inserted by Reset routine) 0F9F 11 DB 11H ;Step Time (LSB) 0FA0 01 DB 1 ;Step Time (MSB) 0FA1 00 DB 0 ;Head Load Delay Time (LSB) Default set in PREP to 50ms 0FA2 00 DB 0 ;Head Load Delay Time (MSB) 0FA3 00 DB 0 ;Motor on Delay Time (LSB) Default set in PREP to .5sec 0FA4 00 DB 0 ;Motor on Delay Time (MSB) 0FA5 11 DB 11H ;Step Settle Time (LSB) 0FA6 01 DB 1 ;Step Settle Time (MSB) 0FA7 00 DB 0H ;First Sector's Number 0FA8 00 DB 0H ;User's Specification - Number of sectors per track 0FA9 10 DB 10H ;default drive configuration byte 0FAA 00 DB 0 ;User's Specification - Starting track of Write Precomp ; 5" drive table 0FAB 28 DRIVE5: DB 28H ;high track + 1 0FAC FF DB 0FFH ;current track 0FAD F2 DB 0F2H ;drive pattern ; - - ;Logical drive Number (Inserted by Reset routine) 0FAE CC DB 0CCH ;Step Time (LSB) 0FAF 00 DB 0 ;Step Time (MSB) 0FB0 00 DB 0 ;Head Load Delay Time (LSB) Default set in PREP to 50ms 0FB1 00 DB 0 ;Head Load Delay Time (MSB) 0FB2 00 DB 0 ;Motor on Delay Time (LSB) Default set in PREP to .5sec 0FB3 00 DB 0 ;Motor on Delay Time (MSB) 0FB4 00 DB 0 ;Step Settle Time (LSB) 0FB5 02 DB 2 ;Step Settle Time (MSB) 0FB6 00 DB 0H ;User's Specification - First Sector's Number 0FB7 00 DB 0H ;User's Specification - Number of sectors per track +1 0FB8 3C DB 3CH ;default drive configuration byte (2EH = hard sect.) 0FB9 00 DB 0 ;User's Specification - Starting track of Write Precomp ; System Status and Control Area (loaded into memory at 13F0h) 0FBA 40 CONST: DB 40H ;current drive table pointer LSB 0FBB 13 DB 13H ;current drive table pointer MSB 0FBC 00 DB 0 ;Not Used 0FBD 00 DB 0 ;Not Used 0FBE 00 DB 0 ;Not Used 0FBF 00 DB 0 ;Not Used 0FC0 06 DB 6 ;port 4006 memory image 0FC1 00 DB 0 ;Not Used 0FC2 00 DB 0 ;Not Used 0FC3 00 DB 0 ;Not Used 0FC4 00 DB 0 ;sector count - sector_decalibrated_flag 0FC5 00 DB 0 ;index count 0FC6 0A DB 0AH ;Retries on CRC error 0FC7 16 DB 16H ;Max. number of revolutions before drive deselected 0FC8 00 DB 0 ;System Status Byte 0FC9 00 DB 0 ;break character count 0FCA DS 1000H - $, 0FFH PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-75 ;====================================================================== ; MEMORY LAYOUT ;============== ; ;---------------------------------------------------------------------- ; Stack ;------ ; ; 1000 - 102F ; ;---------------------------------------------------------------------- ; User Area ;---------- ; ; 1030 - 128F ; ;---------------------------------------------------------------------- ; Read/Write Vector Tables ;------------------------- ; ; 1290 - 1297 RTBL ; 1298 - 129F WTBL ; ;---------------------------------------------------------------------- ; Drive constants Tables (see SECT8 and SECT5 for table definitions) ;------------------------------------------------------------------- ; ; 12A0 8" single density ; 12B0 8" double " ; 12C0 5" single " soft sectored ; 12D0 5" double " " sectored ; 12E0 5" single " hard sectored ; 12F0 5" double " " sectored ; ; Each drive table is organized as follows: ; ...0 port 4006 control byte ; ...1 port 4007 control byte ; ...2 Default Starting Track of Write Pre-Compensation ; ...3 not used ; ...4 not used ; ...5 not used ; ...6 track number ; ...7 side number ; ...8 sector number ; ...9 sector length code ; ...A double density ID byte ; ...B port 4007 CRC control byte ; ...C not used ; ...D not used ; ...E Port 4006 write control byte ; ...F not used ; ; 1300 - 130F Not used PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-76 ;---------------------------------------------------------------------- ; Current Drive's Constants ;-------------------------- ; 1) This area is loaded by CDISK from the Drive Constants Tables ; ; 1310 port 4006 read control byte ; 1311 port 4007 control byte ; 1312 Starting Track of Write Pre-Compensation ; 1313 not used ; 1314 not used ; 1315 not used ; 1316 track number ; 1317 0/1 (side 0/ side 1) ; 1318 sector number ; 1319 sector length code (0-128, 1-256, 2-512, 3-1024) ; 131A 0/1 (single density/double density) ; 131B port 4007 CRC control code ; 131C not used ; 131D not used ; 131E port 4006 write control byte ; 131F not used ; ;---------------------------------------------------------------------- ; DMA Pointer ;------------ ; ; 1320 DMA address LSB ; 1321 DMA address MSB ; 1322 DMA address extended page ; ;---------------------------------------------------------------------- ; Parameter Save Area (See EXEC) ;------------------------------- ; ; 1323 track number ; 1324 sector number (side number in high order bit) ; 1325 drive number ; ;---------------------------------------------------------------------- ; Misc Storage ;------------- ; ; 1326 status address LSB ; 1327 status address MSB ; 1328 status address extended page ; 1329 next command ; 132A DMA byte count LSB ; 132B DMA byte count MSB ; 132C data byte ; 132D data byte ; 132E STKSAV stack pointer location during READS and WRITES (lsb) ; 132F " " " " " " " (msb) ; PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-77 ;---------------------------------------------------------------------- ; Transfer Parameter Buffer ;-------------------------- ; 1330 block#1 extended page address ; block#1 byte count less one ; . ; . ; . ; block#k extended page address ; block#k byte count less one ; extended page address ; 1 (signal to stop block transfers) ; (conditional) 40/3F (zero flag set/zero flag not set) ; (conditional) A1/0 (port 4007 CRC control code/nop) ; 40 (zero flag set) ; A1 (port 4007 CRC control) ; ;---------------------------------------------------------------------- ; Drive Parameter Tables (DPT) ;----------------------------- ; 1340 - 134F Physical Drive A Logical drive 0/4 (first 8" drive) ; 1350 - 135F " " B " " 1/5 ; 1360 - 136F " " C " " 2/6 ; 1370 - 137F " " D " " 3/7 ; 1380 - 138F " " E " " 4/0 (first 5.25" drive) ; 1390 - 139F " " F " " 5/1 ; 13A0 - 13AF " " G " " 6/2 ; 13B0 - 13BF " " H " " 7/3 ; ; Each DPT is organized as follows: ; ...0 maximum track value plus one ; ...1 current track (FF if heads not calibrated) ; ...2 drive pattern for port 4004/4005 ; ...3 logical drive number ; ...4 Step Time (LSB) ; ...5 Step Time (MSB) ; ...6 Head Load Delay Time (LSB) ; ...7 Head Load Delay Time (MSB) ; ...8 Motor on Delay Time (LSB) ; ...9 Motor on Delay Time (MSB) ; ...A Step Settle Time (LSB) ; ...B Step Settle Time (MSB) ; ...C User Specified Lowest Sector Number ; ...D User Specified Number of Sectors per Track + 1 ; ...E drive configuration byte ; bit 0 1 = (@VER) Sector Header has been verified ; " 1 1 = (@HRD) Media is Hard Sectored ; " 2 1 = (@5IN) Drive is five inch (4004 = 5" port) ; " 3 1 = (@MOC) Motor has on/off control ; " 4 1 = (@DBL) Media is Double Density ; " 5 1 = (@NRC) Drive doesn't have ready line ; " 6 1 = (@NHC) Drive can't unload Heads ; " 7 1 = (@HDL) Heads are currently loaded ; ...F User Specified Starting Track of Write Precompensation ; PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-78 ;---------------------------------------------------------------------- ; Channel Command Pointers and Stack Areas ;----------------------------------------- ; ; 13C0 current command pointer LSB ; 13C1 " " " MSB ; 13C2 " " " extended page ; 13C3 Not Used (was = retry constant) ; 13C4 Initial command pointer address LSB ; 13C5 " " " " MSB ; 13C6 " " " " extended page ; ; 13C7 - 13D7 Stack Space used during monitor GO: command execution ; 13D8 & 13D9 Monitor Execution address (see GO:) ; 13DA & 13DB Monitor 'Normal Return' address (see GO:) ; ; 13DC Stack for Monitor, after any Errors, a halt or interrupt request ; ; Monitor Save locations for registers (see GO: in monitor) ; --------------------------------------------------------- ; 13DC F - AF 13E2 L - HL 13E8 F - AF' 13EE L - HL' ; 13DD A 13E3 H 13E9 A 13EF H ; 13DE B - BC 13E4 IX - IX 13EA C - BC' ; 13DF C 13E5 IX 13EB B ; 13E0 E - DE 13E6 IY - IY 13EC E - DE' ; 13E1 D 13E7 IY 13ED D ; ;---------------------------------------------------------------------- ; System Status and Control Area ;------------------------------- ; ; 13F0 current drive pointer LSB ; 13F1 current drive pointer MSB ; 13F2 Not Used ; 13F3 Not Used ; 13F4 Not Used ; 13F5 Not Used ; 13F6 memory image of port 4006 - ONLY USED BY SEROUT ; 13F7 Not Used ; 13F8 Not Used ; 13F9 Not Used ; 13FA sector count ; 13FB index count ; 13FC Max. number of retries on encountering a CRC error ; 13FD Max. number of revolutions before drive deselected ; 13FE (XFLAG) System Status Byte ; bit 0 1 = (@SER) Serial_Input_Status = Active ; " 1 1 = (@MON) Monitor_Status = Active ; " 2 1 = (@MOT) Motor_Status = Active ; " 3 1 = (@SCT) Sector Count is Calibrated ; " 4 1 = (@HOL) Sector/Index Hole has been processed ; " 5 1 = (@FHF) First hole found ; 13FF break character count PAGE DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE 1-79 ;---------------------------------------------------------------------- ; TIMING CONSTANTS FOR THE SDELAY ROUTINE (MSB first) ;---------------------------------------------------- ; 1) Any constants used in the HOME routine should be unique in ; the lsb (1 digit in the lsb causes roughly a 3% change) ; ; time msb lsb ; 1ms - 00 22 (hex) ; 3ms - 00 66 ; 5ms - 00 AA ; 6ms - 00 CC ; 8ms - 01 11 ; 15ms - 02 00 ; 20ms - 02 AB ; 26ms - 03 74 ; 30ms - 04 01 ; 40ms - 05 54 ; ;---------------------------------------------------------------------- ; ERROR CODE SUMMARY ;------------------- ; 40 - Normal completion code - no error in operation ; 80 - Host issued improper command code ; 81 - Host issued improper disk drive number ; 82 - Drive Not Ready ; 83 - Track number out of range for selected drive ; 84 - Unreadable Media ; 85 - Sector Length code is too large ; 86 . Not used (was = Error in sector header scan) ; 87 - Seek error ; 88 - Missing Sector Header ID (Sync) Byte ; 89 - Track number mis-match ; 8A - Side number (0=bottom or first) mis-match ; 8B - Sector number mis-match ; 8C - Sector length mis-match ; 8D - CRC error in Sector Header ; 8E - CRC error in Data Field ; 8F - Host issued improper sector number for current media ; 90 - Diskette is write protected ; 91 - Lost data - DMA channel did not respond in time ; 92 - Lost command - channel did not respond in time ; 93 - Time-out waiting for data ID mark ; 94 - Heads failed to move to the home position END DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE S Macros: Symbols: 0002 @5IN 0004 @DBL 0005 @FHF 0007 @HDL 0004 @HOL 0001 @HRD 0003 @MOC 0001 @MON 0002 @MOT 0006 @NHC 0005 @NRC 0003 @SCT 0000 @SER 0000 @VER 095F ADJUST 13F0 BASEIX 1340 BASEIY 06BF BMEXIT 00A0 BRANCH 01CF BSTART 0D10 BTIME 0C81 CASTOR 0752 CDISK 0755 CDISKA 0765 CDLOOP 04DE CLRVFY 0E1D CMDTBL 0FBA CONST 0E65 COUNT 0C51 CREAD 00DF CSTART 00EC CSTOP 0C12 CSTR 0ED7 CTABLE 0C62 CWRITE 00D9 D10LP 0EAB DESEL 0EB8 DESKP1 0EC0 DESKP2 0775 DFOUND 0146 DISCRD 00CE DLY1MS 00D6 DLYNMS 056F DMASTO 0569 DMLOOP 0B4C DONE 0AC8 DOUBLE 01D6 DPLOAD 0FAB DRIVE5 0F9C DRIVE8 0EA4 DRVOFF 00C2 DSPTCH 00D1 DSSLLP 03FB DUMPM 098C EMARK 0038 ENTIRQ 0066 ENTNMI 0000 ENTPOC 0E26 ERROR 0C9F EXCMD 022A EXEC 049A FCLOOP 051D FCODE 0DD8 FORMAT 0D59 FOUND 0B8A FS5ERR 0B79 FS5LP 0B8C FS5SKP 0932 FSCNT 0901 FSECT 0B65 FSECT5 091B FSLOOP 0124 FTLOOP 0E02 GETC 0D5E GO 0408 GOMEM 040A GSTAT 03C4 HALTC 004A HFLG 0E4F HFOUND 0032 HLDLY 003D HLP1 0038 HNDSHK 0796 HOLEOK 0855 HOME 0868 HOMLP0 086D HOMLP1 0879 HOMLP2 088A HOMSK1 00AF HPATCH 0E44 HSLOOP 0CC7 HSPIN 0E2B HSYNC 0E97 ICOUNT 0186 IMLOAD 0CAD INCIO 0CB4 INCR3 0CD9 INLP1 0CDF INLP2 0CE1 INLP3 0CE9 INSKP1 03C9 INTRQC 0045 IPLPAT 0E3F ISYNC 0DFB JOUT 0A4D LASTR 0C2A LASTS 0DA7 LEAVE 0480 LOADCH 00BD LOADHL 0403 LOADM 0555 LOADSE 0393 LOGCAL 03A0 LOGCAW 024D LOOKUP 0AB0 LOOP1 0AEE LOOP2 0951 LOOP22 097A LOOPD 02B7 MAIN 000A MAXHS5 0E1B MHEX 02C8 MNLP1 03E8 MODLY 0D47 MONCMD 0D24 MONE2 0D2A MONE3 0D36 MONLP1 0D4C MONLP2 13C7 MONRAM 0D20 MONTR 0ECE MOSKP1 0ECB MOTOFF 02DD MSKP1 02F5 MSKP10 0308 MSKP2 003B MULT 0041 MULTLP 01AE MZLOAD 08A8 NOTHOM 0630 NREXIT 0D07 OLOOP 0003 PATC21 04D1 PELOOP 0665 PLOP1 0677 PLOP2 00F9 POC 05B6 PREP 0457 PREPOK 0DB4 PRINT 044A PRLOOP 0DB7 PRNLP1 0E27 PROMT 05CA PSKP1 0646 PSKP10 0651 PSKP12 0689 PSKP13 0698 PSKP14 06A0 PSKP15 06C1 PSKP16 06CD PSKP17 06DB PSKP18 06F4 PSKP19 0708 PSKP20 0713 PSKP21 0737 PSKP22 0740 PSKP23 05DC PSKP3 DJDMA (Rev 2.049 Rel_2.3 9_Aug_83) Copyright 1983 Morrow Designs MACRO-80 3.44 09-Dec-81 PAGE S-1 05F0 PSKP4 05F6 PSKP5 05FC PSKP6 0615 PSKP7 061E PSKP8 0637 PSKP9 096F PTEST 0DF1 PUTL 0DF5 PUTR 0BC4 R5LOOP 0BAE R5LP1 0BB9 R5SKP1 0BC1 R5SKP2 0C6D RBYTE 0C8B RCMD 0C4E RDCH 09D6 RDLP0 09F9 RDLP1 0A0B RDLP2 0A1A RDLP3 0A63 RDRTN 0442 RDSECT 0A02 RDSKP1 0A14 RDSKP2 0B96 READ5 09B2 READS 0BD1 REAOK 0237 RELOOK 0CBC RESTOR 0221 REXEC 06E3 RHLOOP 0A27 RLOOP 0A24 RONE 0083 RPOINT 0B9C RSTALL 0F2C RTBL 04C5 RTRACK 0A20 RTWO 0C75 RWBYTE 0505 RWFLAG 0A28 RZRO 0812 SCTCLP 0813 SCTCMP 0821 SCTCNT 0845 SCTER1 0847 SCTER2 07EB SCTLP1 07FD SCTLP2 080C SCTLP3 081D SCTRDS 081C SCTRLP 07CE SCTRTY 07F4 SCTSK1 07F8 SCTSK2 0806 SCTSK3 080A SCTSK4 0852 SCTSK5 097E SDATA 00C3 SDELAY 00C4 SDLP1 0F7C SECT5 0F3C SECT8 07B8 SECTOR 08AE SEEK 08D1 SEKLP1 08BF SEKSK1 08CA SEKSK2 03E6 SEROUT 03BF SETCAW 03B5 SETCCW 0311 SETCRC 03AB SETDMA 032B SETDP 0316 SETLFT 0370 SETMP 0341 SETSK1 034F SETSK2 035C SETSK3 036D SETSK4 08D6 SETTLE 0936 SETXFR 0D3D SHIFT 0E8C SIDLE 0E71 SIHIGH 06A3 SIMAGL 077A SIMAKE 078B SISKIP 07B4 SISKP1 0746 SIZE 0E5D SLEAVE 0381 SMPSK1 0390 SMPSK2 0CCD SPIN 0CEF SPOUT 0081 SPT5H 007F SPT5S 0077 SPT8S 03ED SRENBL 03F9 SRESKP 0D7A SRETRN 1030 STACK 132E STKSAV 09A5 STORE 041C STOTRK 08E0 STP 08EE STPSK1 0429 STPUSH 05A6 SVSTAT 0074 SWBANK 054D TCONT 01E1 TESTDR 04B4 TESTER 0128 TILOOP 031B TRACKZ 04BB TRCNT 04A2 TRLOOP 0286 TRMCER 0292 TRMHLT 029B TRMIRQ 0E39 TSYNC 0536 TTLOOP 0C2C W5LOOP 0C0B W5SKP1 0C72 WBYTE 0C96 WCMD 0C35 WEAOK 0058 WFLAG 0B22 WLOOP 0B1B WONE 0B1F WONEP 0089 WPOINT 01C1 WPZERO 0C5F WRCH 0D90 WRITE 0BE1 WRITE5 0A73 WRITES 0D93 WRLOOP 043E WRSECT 0F34 WTBL 04C1 WTRACK 0B10 WTWO 000E XFLAG 000E YFLAG 0C16 ZEROW No Fatal error(s)