(0000) 0521+ LP: DL AA0011 *** undefined symbol on pass one *** (0000) 0565+ LP: DL AA0015 *** undefined symbol on pass one *** (0000) 0608+ LP: DL AA0019 *** undefined symbol on pass one *** (0000) 0651+ LP: DL AA0023 *** undefined symbol on pass one *** Pass One Errors 4 CROMEMCO Z80 Macro Assembler version 03.07 Nov 30, 1980 09:46:29 Page 0001 *** MDS *** 0001 ; INTEL MDS FDC CARD EMULATOR 0002 ; 0003 ; SOURCED NOV 79 BY TREVOR MARSHALL 0004 ; Dept E & E Eng 0005 ; University of West Australia 0006 ; NEDLANDS, W.A. 6009 0007 ; 0008 ; This version of the source produces, after linking, 0009 ; object code in memory from 600H to A000H to enable 0010 ; a Prom Programmer resident in the host system 0011 ; to directly program the object file 0012 ; 0013 ; A version ORGed at F800H is compiled seperately 0014 ; and is provided on the master disk as MDSABS.Z80 0015 ; 0016 ; 0017 ; REGISTER USAGE DURING READ AND WRITE: 0018 ; D contains the (auto wait) drive control byte 0019 ; IX points to the IOPB base 0020 ; HL points to the current memory DMA address 0021 ; B contains the input byte counter for INI & OUTI 0022 ; C contains DDATA for INI & OUTI 0023 ; B' (alternate) contains the number of records required 0024 ; D' (alternate) contains the current sector address 0025 ; E' (alternate) contains the retry count 0026 ; H' (alternate) contains the previously logged track 0027 ; AF' (alternate) contains the previous drive mask 0028 ; to skip read trk# if it is already logged 0029 ; and allow for fast response without interleaving 0030 ; 0031 ; FDC CONTROLLER DEFINITIONS: (0063) 0032 DCONTROL:EQU 63H ;Control Port (0063) 0033 DFLAGS: EQU 63H ;FDC Status Port (0067) 0034 DDATA: EQU 67H ;1793 Data Port (0064) 0035 DSTATUS: EQU 64H ;1793 Status Port (0064) 0036 DCOMMAND:EQU 64H ;1793 Command Port (0065) 0037 DTRACK: EQU 65H ;1793 Track Port (0066) 0038 DSECTOR: EQU 66H ;1793 Sector Port (0004) 0039 DSIDE: EQU 4 ;Bit 1=0 selects side 1 0040 ; of D/S drives 0041 ; 0042 ; DISK CONTROL PORT HARDWARE ENVIRONMENT 0043 ; Bits 0-3 select drives 1-4 0044 ; Bit 7 enables auto wait on accesses to DDATA 0045 ; Bit 5 enables dsk drive motors 0046 ; Bit 4 selects single density (S/D) 0047 ; 0048 ; DISK STATUS PORT HARDWARE REQUIREMENTS 0049 ; Bit 0 is 1793 INTREQ status output 0050 ; Bit 5 indicates head is loaded 0051 ; 0052 ; DISK DENSITY DEFINITIONS (001A) 0053 MAXSECTORS: EQU 1AH ;Single Density (004C) 0054 MAXTRACKS: EQU 4CH ; 8" Disks 0055 ; 0056 ; PIO DEFINITIONS: (007A) 0057 ACOMMAND:EQU 7AH (0078) 0058 ADATA: EQU 78H (007B) 0059 BCOMMAND:EQU 7BH (0079) 0060 BDATA: EQU 79H 0061 ; CROMEMCO Z80 Macro Assembler version 03.07 Nov 30, 1980 09:46:29 Page 0002 *** MDS *** 0062 ; BUS CONTROL: (007F) 0063 RELEASE: EQU 7FH ;I/O To this addr releases bus (007C) 0064 HOLD: EQU 7CH ;I/O to this addr requests bus 0065 ; 0066 ; MDS PORT DEFINITIONS: (007E) 0067 STATUS: EQU 7EH ;S100 Bus reads 78H 0068 ;Note that port 78H is referenced directly in ASERVICE 0069 ;TYPE: Not Implemented (007D) 0070 RESULT: EQU 7DH ;S100 Bus reads 7BH 0071 ;RESET: Not Implemented (0079) 0072 IOPBLOW: EQU 79H (007A) 0073 IOPBHIGH:EQU 7AH 0074 ; 0075 ; DISKETTE INSTRUCTION CODES: (0000) 0076 NOP: EQU 0 (0001) 0077 SEEK: EQU 1 (0002) 0078 FORMAT: EQU 2 (0003) 0079 RECALIB: EQU 3 (0004) 0080 READ: EQU 4 (0005) 0081 VERIFY: EQU 5 (0006) 0082 WRITE: EQU 6 (0007) 0083 WRITEDEL:EQU 7 ;Write deleted data mark; 0084 ; 0085 ; AS THERE IS NO STACK RAM AVAILABLE ALL CODE 0086 ; MUST BE SEQUENTIAL 0087 ; 0088 ; THE PROM PROGRAMMER REQUIRES AN ADDRESS OFFSET 0089 ; OF 0F200H FOR THIS ORG 0F800H CODE 0090 ; 0091 ; THE FOLLOWING MACROS FORM COMMONLY USED ROUTINES 0092 ; 0093 STOP: MACRO 0094 LD SP,STACK; Point at ROM stack 0095 IN A,RELEASE 0096 RETI 0097 MEND 0098 DONE: MACRO ;Set up status port & stop 0099 LD A,0FH 0100 OUT STATUS,A 0101 STOP 0102 MEND 0103 ; 0104 INTREQ: MACRO ;Wait for intreq 0105 LL#SYM: IN A,DFLAGS ;Loop until 1793 INTREQ active 0106 RRA 0107 JR NC,LL#SYM 0108 MEND 0109 ; 0110 ERRORS: MACRO #LOOP,#MASK ;Check 1793 for errors 0111 INTREQ 0112 IN A,DSTATUS 0113 EXX ;Save working registers 0114 LD C,A ;Save error byte 0115 AND 80H ;Not ready mask 0116 EXX 0117 JR NZ,#LOOP ;Loop until drive ready 0118 EXX 0119 LD A,C 0120 AND #MASK ;General error mask 0121 JP NZ,SELECT+OFFSET ;Retry if any errors 0122 EXX CROMEMCO Z80 Macro Assembler version 03.07 Nov 30, 1980 09:46:29 Page 0003 *** MDS *** 0123 MEND 0124 ; 0125 SETUP: MACRO ;Set up read and write common parameters 0126 LP: DL AA#SYM 0127 AA#SYM: INC D ;Sector # 0128 LD A,D 0129 OUT DSECTOR,A 0130 EXX 0131 LD A,D 0132 OUT DCONTROL,A 0133 LD B,80H ;Input byte count 0134 IN A,DFLAGS ;Is head loaded? 0135 AND 20H 0136 JR Z,J2#SYM ;No 0137 LD A,0 0138 JR J3#SYM 0139 J2#SYM: LD A,04H ;Head load mask for 1793 0140 J3#SYM DL $ 0141 MEND 0142 ; 0143 CHECK: MACRO ;See if read or write is complete 0144 EXX 0145 DJNZ LP 0146 EXX 0147 LD B,0 ;Done 0148 JP FINISH+OFFSET 0149 MEND 0150 ; 0151 ; NOTE THAT THE 1793 NEEDS TIME TO CALCULATE CRC 0152 ; BEFORE THE ERROR STATUS IS AVAILABLE 0153 ; IF THE DRQ IS NOT SERVICED 0154 ; The following delay loop is sufficient (4MHz Z-80) 0155 DELAY: MACRO 0156 LD B,30H ;12 to 15 give CRC errors 0157 ; 0 to 12 give BUSY flag 0158 DJNZ $ 0159 MEND 0160 ; 0161 ; Check for 1793 errors during read and write 0162 DERROR: MACRO #MASK 0163 INTREQ 0164 IN A,DSTATUS 0165 EXX 0166 LD C,A ;Save error byte 0167 EXX 0168 ; Note that we will not check for deleted data marks 0169 AND #MASK 0170 JP NZ,S2+OFFSET ; Retry errors 0171 MEND 0172 0173 ; LINKER AND PROM PROGRAMMER CODE REQUIREMENTS (0100) 0174 ORG 100H 0100 C30000 0175 JP 0 (F200) 0176 OFFSET: EQU 0F800H-600H 0177 ; Setup vectors at top of ROM (09F4) 0178 ORG 9F4H ;Effectively FBF4 09F4 37F8 0179 VEC1: DW ASERVICE+OFFSET 09F6 50F8 0180 VEC2: DW BSERVICE+OFFSET 09F8 FB 0181 WAIT: EI 09F9 76 0182 HALT ;wait for interrupt 0183 ; STACK: To enable interrupt structure we need a 'stack' CROMEMCO Z80 Macro Assembler version 03.07 Nov 30, 1980 09:46:29 Page 0004 *** MDS *** 09FA F8FB 0184 DW WAIT+OFFSET (FBFC) 0185 STACK: EQU $+OFFSET 09FC F8FB 0186 DW WAIT+OFFSET 09FE F8FB 0187 DW WAIT+OFFSET 0188 ; 0189 ; Hardware Reset Code (0600) 0190 ORG 600H 0600 C304F8 0191 START: JP 0F804H 0603 00 0192 NOP 0193 ; The ORG address is now effectively F804H 0194 ; Now setup PIO & Interupts 0195 ; 0604 ED5E 0196 IM2 0606 3EFB 0197 LD A,0FBH 0608 ED47 0198 LD I,A ;Int vector table near FBF2 060A 3EF4 0199 LD A,0F4H ;IVEC(A) = FBF4 060C D37A 0200 OUT ACOMMAND,A 060E 3EF6 0201 LD A,0F6H ;IVEC(B) = FBF6 0610 D37B 0202 OUT BCOMMAND,A 0612 3E4F 0203 LD A,4FH ;MODE 1 0614 D37A 0204 OUT ACOMMAND,A 0616 D37B 0205 OUT BCOMMAND,A 0618 DB78 0206 IN A,ADATA ;Set READY handshake 061A DB79 0207 IN A,BDATA 061C 3E87 0208 LD A,87H ;Enable PIO interrupt mode 061E D37A 0209 OUT ACOMMAND,A 0620 D37B 0210 OUT BCOMMAND,A 0211 ; Now setup output latches 0622 3E00 0212 LD A,00 0624 D37D 0213 OUT RESULT,A 0626 3E0B 0214 LD A,0BH ;:F0:,:F1: ready, not D/D 0628 D37E 0215 OUT STATUS,A 062A 08 0216 EX AF,AF' 062B 3E00 0217 LD A,0 ;Clear drive select mask 062D 08 0218 EX AF,AF' 062E D9 0219 EXX 062F 26FF 0220 LD H,0FFH ;Clear logged trk 0631 D9 0221 EXX 0632 31FCFB 0222 LD SP,STACK 0635 FB 0223 EI 0636 76 0224 HALT 0225 ; Routine to service PIO inputs 0226 ; (79) go to IX lower, (7A) to IX upper 0227 ; 0637 F3 0228 ASERVICE: DI 0638 D37C 0229 OUT HOLD,A ; Lock out bus until done 063A 00 0230 NOP ;Allow time for bus control 063B 00 0231 NOP 063C DB78 0232 IN A,78H ; S100 Status port read (& reset) 0233 ; ; must be done during bus access 063E DB78 0234 IN A,ADATA 0640 DD210000 0235 LD IX,0 0644 4F 0236 LD C,A 0645 0600 0237 LD B,0 0647 DD09 0238 ADD IX,BC ;Now have A in IX 0649 0239 STOP 0649 31FCFB 0240+ LD SP,STACK; Point at ROM stack 064C DB7F 0241+ IN A,RELEASE 064E ED4D 0242+ RETI 0650 F3 0243 BSERVICE: DI 0651 D37C 0244 OUT HOLD,A ; Lock out bus until done CROMEMCO Z80 Macro Assembler version 03.07 Nov 30, 1980 09:46:29 Page 0005 *** MDS *** 0653 DB79 0245 IN A,BDATA 0655 47 0246 LD B,A 0656 0E00 0247 LD C,0 0658 DD09 0248 ADD IX,BC ; IX now points to IOPB 0249 ; Now select side 0 of disks 065A 3E02 0250 LD A,2 ;Set bit 1 065C D304 0251 OUT DSIDE,A 0252 ; 065E D9 0253 EXX 065F 1E0A 0254 LD E,0AH ;10 retries 0661 1803 0255 JR SELECT 0256 ; 0257 ; NOW BEGIN DECODING COMMAND WORD 0258 ; 0259 ; FIRST SELECT THE DRIVE (:F0:=A:, :F1:=C:) 0260 ; 0663 D9 0261 S2: EXX 0664 26FF 0262 LD H,0FFH ;Log off track if error occurs 0263 ; ;This will cause a RESTORE cmd 0264 ; ;To be executed for SEEK errors 0666 7B 0265 SELECT: LD A,E 0667 FE00 0266 CP 0 ;Have we retried 10 times? 0669 79 0267 LD A,C ;Error byte 0268 066A CAC8FA 0269 JP Z,EXIT+OFFSET 066D 1D 0270 DEC E 066E D9 0271 EXX 066F DD7E00 0272 LD A,(IX+0) 0672 E63F 0273 AND 3FH ;Check for acceptable channel word 0674 C27EFB 0274 JP NZ,CHERROR+OFFSET ; Channel error 0275 ; 0276 ;If the op is NOP,FORMAT or RECALIBRATE 0277 ;Dont check address field 0677 DD7E01 0278 LD A,(IX+1) 067A E607 0279 AND 07H ;Now have opcode field 067C FE01 0280 CP 1 ;Seek 067E 2804 0281 JR Z,DONTSKIP 0680 D604 0282 SUB 4 0682 3823 0283 JR C,SKIP ; <=3 0284 DONTSKIP: 0285 0286 ; Now check for valid IOPB addresses 0684 DD7E03 0287 N12: LD A,(IX+3) ;Track address 0687 D64D 0288 SUB MAXTRACKS+1 ;max track # + 1 0689 D269FB 0289 JP NC,ADDERROR+OFFSET 068C DD7E04 0290 LD A,(IX+4) 0291 ; 0292 ; Must reset bits 4 & 5 of sector byte (a drive select b it) 0293 ; to retain compatibility with S/D MDS systems 068F E69F 0294 AND A,09FH 0691 CA69FB 0295 JP Z,ADDERROR+OFFSET ;Zero sector # 0694 D61B 0296 SUB MAXSECTORS+1 ;Max sector # + 1 0696 D269FB 0297 JP NC,ADDERROR+OFFSET 0699 DD7E04 0298 LD A,(IX+4) ;Sector addr 0299 ; 0300 ; Must reset bit 5 of sector byte (a drive select bit) 0301 ; to retain compatibility with S/D MDS systems 069C E69F 0302 AND A,09FH 069E DD4E02 0303 LD C,(IX+2) ;Number of records requested 06A1 81 0304 ADD A,C CROMEMCO Z80 Macro Assembler version 03.07 Nov 30, 1980 09:46:29 Page 0006 *** MDS *** 06A2 D61C 0305 SUB A,MAXSECTORS+2 06A4 D269FB 0306 JP NC,ADDERROR+OFFSET ;Final sector >1AH 0307 ; Address errors trapped, now seek to required track 0308 ; 06A7 DD7E01 0309 SKIP: LD A,(IX+1) ;Instruction word 06AA E630 0310 AND 30H ;Get drive mask 06AC CB0F 0311 RRC A 06AE CB0F 0312 RRC A 06B0 CB0F 0313 RRC A 06B2 CB0F 0314 RRC A 06B4 FE03 0315 CP 3 ; S/D MDS drive #1 mask 06B6 2804 0316 JR Z,BSELECT ;Select drive B 0317 ; Dont allow for more than 2 drives 06B8 16B1 0318 LD D,0B1H ;Auto wait,motor on,S/D,A: 06BA 1802 0319 JR J3 06BC 16B2 0320 BSELECT: LD D,0B2H ;Auto wait,motor on,S/D,B: 0321 ; D contains the drive control byte with auto wait set 0322 ; 0323 ; Now check for recalibrate, nop & format instructions 0324 ; 06BE DD7E01 0325 J3: LD A,(IX+1) 06C1 E607 0326