TITLE 'COLD BOOT LOADER FOR VISUAL 1050' PAGE 55 ;*******************************************************; ; ; ; COLD BOOT LOADER ; ;*******************************************************; ; ; ; V1.2 L. LAMMI 03/27/84 ; ; ; ; V1.1 S. SHERMAN 1/24/84 ; ; ; ; V1.0 K. BAILEY 4/12/83 ; ; ; ;*******************************************************; ;*******************************************************; ; ; ; THE FOLLOWING CODE IS CONTAINED IN ; ; VISUAL PART NO. IC244-032, V1050 ; ; ZBOOT FIRMWARE. ; ; ; ;*******************************************************; MACLIB Z80 MACLIB PORTS DISOUT MACRO MESSAGE LOCAL LOOP,EXIT LXI H,&MESSAGE ;POINTER TO ERROR MESSAGE LOOP: IN P$DISP$C ;GET PIO STATUS RRC ;TEST READY JRNC LOOP ;BR IF NOT MOV A,M ;GET A CHARACTER CPI '$' ;TEST TERMINATION JRZ EXIT ;BR IF IT IS OUT P$DISP$OUT ;PUT IN THE DATA REG MVI A,0EH ;STROBE OUT P$DISP$CONTROL ;. . INR A ;STROBE OFF OUT P$DISP$CONTROL ;. . INX H ;BUMP ADDRESS POINTER JR LOOP ;AND LOOP EXIT: ENDM ASEG ORG 0000H LXI SP,STACK ;LOAD THE STACK POINTER JMP PIOINT ;AND CONTINUE PAGE ASEG ;*******************************************************; ; ; ; READ DATA INTERRUPT ; ; ; ;*******************************************************; ORG 0066H ;NMI LOCATION NMI: LXI H,0D000H ;NEW ADDRESS PCHL ;JUMP TO ADDRESS IN HL REGS RETN ;AND RETURN PAGE ;*******************************************************; ; ; ; INITIALIZE DISPLAY ; ; ; ;*******************************************************; PIOINT: MVI A,0B4H ;INIT THE DISPLAY PIO OUT P$DISP$CONTROL ;. . MVI A,5 ;SET BIT 2 OF PORT C OUT P$DISP$CONTROL ;. . MVI A,9 ;SET BIT 4 OF PORT C OUT P$DISP$CONTROL ;. . MVI A,0DH ;SET BIT 6 OF PORT C OUT P$DISP$CONTROL ;. . MVI A,0FH ;SET BIT 7 OF PORT C OUT P$DISP$CONTROL ;. . MVI A,91H ;A=IN;B=OUT;CLO=OUT;CHI=IN;MODE 0 OUT P$CLK$CONTROL ;WRITE TO 8255A PAGE ;*******************************************************; ; ; ; HASH TOTAL TEST ; ; ; ;*******************************************************; ; ;NOTE: AT THIS POINT, THE BOOT PROM HAS NOT BEEN RELOCATED... ; IT IS AT ADDRESS 0000H - 1FFFH. ; PIOI10: XRA A ;A=0 MOV C,A ;CLEAR REG C (HOLDS ACCUMULATING TOTAL) ; ;START SUMMING HERE... (ADDRESS 0000H - 1FFFH) ; LXI H,0000H ;STARTING ADDRESS HASH: ADD M ;ADD PROM DATA MOV C,A ;STORE VALUE INX H ;INCREMENT ADDRESS MOV A,H ;GET UPPER BYTE OF ADDRESS CPI 20H ;CHECK END ADDRESS + 1 (HI BYTE) JRZ HASH1 ;DONE, SO CHECK HASH TOTAL MOV A,C ;RESTORE ACCUMULATING TOTAL JR HASH ;LOOP BACK FOR NEXT ADDRESS HASH1: MOV A,C ;GET FINAL HASH TOTAL CPI 00H ;HASH TOTAL VALUE (IS IT CORRECT ?) JRNZ HASH3 ;NO -- THERE WAS AN ERROR JMP HASH2 ;DONE -- CONTINUE WITH RAM TEST ; ; ; HASH$ERR: DB 0CH,'Z80 PROM FAIL','$' HASH3: LXI H,HASH$ERR ;POINT TO ERROR MESSAGE HASH$ERR1: IN P$DISP$C ;GET PIO STATUS RRC ;TEST READY JRNC HASH$ERR1 ;LOOP UNTIL READY MOV A,M ;GET CHAR CPI '$' ;TEST TERMINATION JRZ HASH$ERR2 ;IF TERMINATOR, CONTINUE OUT P$DISP$OUT ;PUT DATA MVI A,0EH ;STROBE OUT P$DISP$CONTROL ; INR A ;STROBE OFF OUT P$DISP$CONTROL ; INX H ;INCREMENT POINTER JR HASH$ERR1 ;GO LOOK FOR ANOTHER CHARACTER ; ; ; HASH$ERR2: HLT ;HALT PAGE ;*******************************************************; ; ; ; MEMORY TEST ; ; ; ;*******************************************************; ; ;LOAD RAM WITH FF'S... (4000H - 0FFFFH) [BANK 0] ; HASH2: LXI H,4000H ;START ADDRESS RAM00: MVI A,0FFH ;A=FF (DATA TO WRITE TO RAM) MOV M,A ;WRITE RAM INX H ;INCREMENT ADDRESS XRA A ;HI BYTE OF (ADDRESS + 1) CMP H ;CHECK END ADDRESS + 1 (HI BYTE) JRNZ RAM00 ;NOT DONE, SO DO SOME MORE ; ;CHECK TO SEE IF LOADED CORRECTLY... (4000H - 0FFFFH) [BANK 0] ; LXI H,4000H ;START ADDRESS RAM01: MVI A,0FFH ;A=FF (DATA TO LOOK FOR) CMP M ;COMPARE JRNZ ERROR ;MEMORY ERROR INX H ;INCREMENT ADDRESS XRA A ;HI BYTE OF (ADDRESS + 1) CMP H ;CHECK END ADDRESS + 1 (HI BYTE) JRNZ RAM01 ;NOT DONE, SO DO SOME MORE ; ;LOAD RAM WITH 00'S... (4000H - 0FFFFH) [BANK 0] ; LXI H,4000H ;START ADDR XRA A ;A=00 (DATA TO WRITE TO RAM) RAM02: MOV M,A ;WRITE RAM INX H ;INCREMENT ADDR CMP H ;CHECK END ADDRESS + 1 (HI BYTE) JRNZ RAM02 ;NOT DONE, SO DO SOME MORE ; ;CHECK TO SEE IF LOADED CORRECTLY... (4000H - 0FFFFH) [BANK 0] ; LXI H,4000H ;START ADDR XRA A ;A=00 (DATA TO LOOK FOR) RAM03: CMP M ;COMPARE JRNZ ERROR ;MEMORY ERROR INX H ;INCREMENT ADDRESS CMP H ;CHECK END ADDRESS + 1 (HI BYTE) JRNZ RAM03 ;NOT DONE, SO DO SOME MORE ; ; ; JMP MOVE ;GO RELOCATE MEMORY ; ; ; ERROR: LXI H,ERRMES ;GO REPORT ERROR stats: IN P$DISP$C ;READ STATUS RRC ;ROTATE BIT JRNC STATs ;IF NOT READY, LOOP MOV A,M ;GET MESSAGE CHARACTER CPI '$' ;LOOK FOR END JRZ RTLP70 ;IF TERMINATOR, CONTINUE OUT P$DISP$OUT ;WRITE DISPLAY MVI A,0EH ; OUT P$DISP$CONTROL ;STROBE PORT INR A ; OUT P$DISP$CONTROL ;FINISH STROBING INX H ; JR STATs ;GO LOOK FOR ANOTHER MESSAGE CHARACTER ; ; ; RTLP70: HLT ;HALT PAGE ; ;RELOCATE PROM BASED RAM TEST TO COMMON BANKED RAM (0C000H - 0FFFFH)... [BANK 0] ; MOVE: LXI H,0000H ;PROM START ADDRESS LXI D,0C000H ;RAM START ADDRESS LXI B,MRES ;BYTE COUNT (INCLUDES ALL OF RAM TEST) ; LDIR ;MOVE BOOT PROM ; ;RUN RAM TEST... ; LXI H,(MAGIC1+0C000H) ;NEW ADDRESS (IN RAM) PCHL ;JUMP ; ; ; MAGIC1: MVI A,01H ;CODE TO DISABLE PROM OUT P$BANK$SELECT ;DISABLE PROM -- ALL RAM ENABLED ; ;CHECK RAM WHERE PROM WAS LOCATED... (0000H - 3FFFH) [BANK 0] ; ;LOAD RAM WITH FF'S... ; LXI H,0000H ;START ADDRESS RAM04: MVI A,0FFH ;A=FF MOV M,A ;WRITE RAM INX H ;INCREMENT ADDRESS MVI A,40H ;HIGH ADDR BYTE CMP H ;COMPARE JRNZ RAM04 ;BACK ; ;CHECK TO SEE IF LOADED CORRECTLY... ; LXI H,0000H ;START ADDRESS RAM05: MVI A,0FFH ;A=FF CMP M ;COMPARE JRNZ ERROR2 ;MEMORY ERROR INX H ;INCREMENT ADDRESS MVI A,40H ;HIGH ADDR BYTE CMP H ;COMPARE JRNZ RAM05 ;BACK ; ;LOAD RAM WITH 00'S... (0000H - 3FFFH) [BANK 0] ; LXI H,0000H ;START ADDRESS RAM06: XRA A ;A=00 MOV M,A ;WRITE RAM INX H ;INCREMENT ADDRESS MVI A,40H ;HIGH ADDR BYTE CMP H ;COMPARE JRNZ RAM06 ;BACK ; ;CHECK TO SEE IF LOADED CORRECTLY... (0000H - 3FFFH) [BANK 0] ; LXI H,0000H ;START ADDRESS RAM07: XRA A ;A=00 CMP M ;COMPARE JRNZ ERROR2 ;MEMORY ERROR INX H ;INCREMENT ADDRESS MVI A,40H ;HIGH ADDRESS BYTE CMP H ;COMPARE JRNZ RAM07 ;BACK JR TEST1 ;GO TO PAGE 1 ERROR2: XRA A ;SET PAGE 0 BIT OUT P$BANK$SELECT ;WRITE PROM ENABLE JMP ERROR ;GO REPORT ERROR ; ;CHECK BANK 1 RAM... ; ;...BUT FIRST CHECK BANK SWITCHING... ; ;CURRENTLY IN BANK 0... ; BNK$ERROR: XRA A ;MASK FOR BANK 0 & SELECTING PROM OUT P$BANK$SELECT ;SELECT BANK LXI H,BNKERR ;POINT TO ERROR MESSAGE JMP STATs ;DISPLAY MESSAGE & HALT ; BNKERR: DB 'BANK SELECT ERROR. SYSTEM HALTED.',0DH,0AH,'$' ; ; ; TEST1: MVI A,11H ;PATTERN FOR BANK 0 STA 0 ;STORE AT LOCATION 0 ; MVI A,03H ;MASK FOR SELECTING BANK 1 OUT P$BANK$SELECT ;SELECT BANK MVI A,22H ;PATTERN FOR BANK 1 STA 0 ;STORE AT LOCATION 0 ; MVI A,01H ;MASK FOR SELECTING BANK 0 OUT P$BANK$SELECT ;SELECT BANK LDA 0 ;READ PATTERN FROM LOCATION 0 CPI 11H ;SAME AS WAS ORIGINALLY STORED ? JRNZ BNK$ERROR ;NO, BANK SELECT ERROR ; MVI A,05H ;MASK FOR SELECTING BANK 2 OUT P$BANK$SELECT ;SELECT BANK MVI A,33H ;PATTERN FOR BANK 2 STA 0 ;STORE AT LOCATION 0 ; MVI A,01H ;MASK FOR SELECTING BANK 0 OUT P$BANK$SELECT ;SELECT BANK LDA 0 ;READ PATTERN FROM LOCATION 0 CPI 11H ;SAME AS WAS ORIGINALLY STORED ? JRNZ BNK$ERROR ;NO, BANK SELECT ERROR ; MVI A,03H ;MASK FOR SELECTING BANK 1 OUT P$BANK$SELECT ;SELECT BANK LDA 0 ;READ PATTERN FROM LOCATION 0 CPI 22H ;SAME AS ORIGINALLY STORED ? JRNZ BNK$ERROR ;NO, BANK SELECT ERROR JR TEST1A ;LINK ADDRESS ; ERROR$LINK: JR ERROR2 ;LINK ADDRESS ; TEST1A: ; ;LOAD RAM WITH FF'S... (0000H - 0BFFFH) [BANK 1] ; LXI H,0000H ;START ADDRESS RAM08: MVI A,0FFH ;A=FF MOV M,A ;WRITE RAM INX H ;INCREMENT ADDRESS MVI A,0C0H ;HIGH ADDRESS BYTE CMP H ;COMPARE JRNZ RAM08 ;BACK ; ;CHECK TO SEE IF LOADED CORRECTLY... (0000H - 0BFFFH) [BANK 1] ; LXI H,0000H ;START ADDRESS RAM09: MVI A,0FFH ;A=FF CMP M ;COMPARE JRNZ ERROR$LINK ;MEMORY ERROR INX H ;INCREMENT ADDRESS MVI A,0C0H ;HIGH ADDRESS BYTE CMP H ;COMPARE JRNZ RAM09 ;BACK ; ;LOAD RAM WITH 00'S... (0000H - 0BFFFH) [BANK 1] ; LXI H,0000H ;START ADDRESS RAM10: XRA A ;A=00 MOV M,A ;WRITE RAM INX H ;INCREMENT ADDRESS MVI A,0C0H ;HIGH ADDRESS BYTE CMP H ;COMPARE JRNZ RAM10 ;BACK ; ;CHECK TO SEE IF LOADED CORRECTLY... (0000H - 0BFFFFH) [BANK 1] ; LXI H,0000H ;START ADDRESS RAM11: XRA A ;A=00 CMP M ;COMPARE JRNZ ERROR$LINK ;MEMORY ERROR INX H ;INCREMENT ADDRESS MVI A,0C0H ;HIGH ADDRESS BYTE CMP H ;COMPARE JRNZ RAM11 ;BACK ; ;CHECK BANK 2 RAM... ; MVI A,05 ;MASK FOR BANK 2 OUT P$BANK$SELECT ;SELECT BANK ; ;LOAD RAM WITH FF'S... (0000H - 3FFFH) [BANK 2] ; LXI H,0000H ;START ADDRESS RAM12: MVI A,0FFH ;A=FF MOV M,A ;WRITE RAM INX H ;INCREMENT ADDRESS MVI A,40H ;HIGH ADDRESS BYTE CMP H ;COMPARE JRNZ RAM12 ;BACK ; ;CHECK TO SEE IF LOADED CORRECTLY... (0000H - 3FFFH) [BANK 2] ; LXI H,0000H ;STAR ADDRESS RAM13: MVI A,0FFH ;A=FF CMP M ;COMPARE JRNZ ERROR3 ;MEMORY ERROR INX H ;INCREMENT ADDRESS MVI A,40H ;HIGH ADDRESS BYTE CMP H ;COMPARE JRNZ RAM13 ;BACK ; ;LOAD RAM WITH 00'S... (0000H - 3FFFH) [BANK 2] ; LXI H,0000H ;START ADDRESS RAM14: XRA A ;A=00 MOV M,A ;WRITE RAM INX H ;INCREMENT ADDRESS MVI A,40H ;HIGH BYTE ADDRESS CMP H ;COMPARE JRNZ RAM14 ;BACK ; ;CHECK TO SEE IF LOADED CORRECTLY... (000H - 3FFFH) [BANK 2] ; LXI H,0000H ;START ADDRESS RAM15: XRA A ;A=00 CMP M ;COMPARE JRNZ ERROR3 ;MEMORY ERROR INX H ;INCREMENT ADDRESS MVI A,40H ;HIGH BYTE ADDRESS CMP H ;COMPARE JRNZ RAM15 ;BACK ; JMP (TEST3+0C000H) ;MEMORY OK ; ERROR3: XRA A ;SELECT BANK 0 & PROM OUT P$BANK$SELECT ;WRITE PROM ENABLE JMP ERROR ;GO REPORT ERROR TEST3: XRA A ;SELECT BANK 0 & PROM OUT P$BANK$SELECT ;WRITE PROM ENABLE JMP MRES ;GO BACK TO PROM PAGE ;*******************************************************; ; ; ; INITIALIZE HARDWARE ; ; ; ;*******************************************************; MRES: DI ;INTERRUPTS OFF MVI A,0D0H ;RESET THE FDC OUT P$DISK$CONTROL ;. . MVI A,88H ;INIT THE MISC. PIO OUT P$8255$CONTROL ;. . mvi a,4fh ;deselct; disable motor (LEL0384) ; MVI A,0FH ;DESELECT THE DRIVES (LEL0384) OUT P$DISK$BITS ;. . ; ; RESET THE SIO CHIPS TO STOP INTERRUPTS ; XRA A ;RESET THE SIOS OUT P$KB$CONTROL ;FIRST 3 NULL COMMANDS OUT P$AUX1$CONTROL ;. . OUT P$KB$CONTROL ;. . OUT P$AUX1$CONTROL ;. . OUT P$KB$CONTROL ;. . OUT P$AUX1$CONTROL ;. . MVI A,40H ;THEN A RESET OUT P$KB$CONTROL ;. . OUT P$AUX1$CONTROL ;. . MVI A,4EH ;SET UP AN ASYNCH OPERATING MODE OUT P$AUX1$CONTROL ;. . INR A ;64X ON THE KEYBOARD OUT P$KB$CONTROL ;. . MVI A,10H ;AND ISSUE A COMMAND OUT P$AUX1$CONTROL ;. . MVI A,14H ; OUT P$KB$CONTROL ;. . ; ; IN P$AUX1$DATA ;DUMMY READ OF 8251-A IN P$KB$DATA ;DUMMY READ OF 8251-A ; ;NOTE: THESE TWO READS ARE FOR 'SMC' AND SIMILIAR PARTS ;---> THEN REPEAT COMMAND SEQUENCE... ; MVI A,10H ;AND ISSUE A COMMAND OUT P$AUX1$CONTROL ;. . MVI A,14H ; OUT P$KB$CONTROL ;. . ; ; MUST INIT THE IPT CONTROLLER HERE ; CALL INTVECTS ;SET UP INTERRUPT VECTORS ; ; IM2 ;SET INTERRUPT MODE 2 MVI A,0EEH ;INTERRUPT MASK OUT P$CLK$PORTB ;OUTPUT TO 8214 BY WAY OF 8255A MVI A,INT$INITIAL ;GET PRIORITY MASK FOR 8214 OUT INT$PORT ;CLEAR 8214 INTERRUPT CONTROLLER MVI A,15H ; OUT P$KB$CONTROL ; MVI A,80H ; OUT P$KB$DATA ;SEND BEEP ; EI ; PAGE IMES1: ; (LEL0284) IMES: LXI D,BOOMES ;DISPLAY INSERTION MESSAGE CALL DSPMSG ;. . PAGE ;*******************************************************; ; ; ; TRY TO READ LABEL FROM WINCHESTER ; ; ; ;*******************************************************; CALL CRLF ; ; SET UP TO READ THE LABEL OFF OF THE WINCHESTER ; TRY$ALL: mvi a,04fh ; deselect drives (LEL0384) out p$disk$bits ; (LEL0384) MVI A,07 ;SIGNAL BOOT FROM G: (LEL0284) STA BOOT$DRV ;STORE FOR CPMLDR (LEL0284) MVI A,6 ;USE DRIVE 6 ("G") (LEL0284) STA MDRV ; (LEL0284) LXI H,0 ;TRACK 0 (LEL0284) SHLD MTRK ; (LEL0284) XRA A ;SET READ FLAG (LEL0284) STA MRWFLAG ; (LEL0284) STA MSEC ;SECTOR 0 (LEL0284) MVI A,2 ;SET UP # HEADS (LEL0384) STA MHED ;(ASSUME 5 MEG) (LEL0384) LXI H,BUFFER ;SET DMA POINTER (LEL0284) SHLD MDMAA ; (LEL0284) MVI A,19 ;SET INTERLEAVE (LEL0284) STA MFIXMOD+0 ; (LEL0284) ; ; READ FROM WINCHESTER ; LXI D,MATBL ;POINTER TO TABLE (LEL0284) CALL WINCH ;TRY READING WINCH (LEL0284) ORA A ;CHECK RESULT (LEL0284) JRNZ REDO ;IF ERROR, TRY DISK (LEL0284) Call LABEL$CHK ;IF OK, CHK LABEL (LEL0284) JRNZ REDO ;IF BAD LABEL, TRY DISK (LEL0284) PAGE ;*******************************************************; ; ; ; READ REST OF SYSTEM ; ; FROM WINCHESTER ; ; ; ;*******************************************************; LXI H,BUFFER+7 ; GET # HEADS FROM LBL (LEL0384) MOV A,M ; (LEL0384) RAL ;*2 (LEL0384) STA MHED ; STORE (LEL0384) MVI A,1 JR W$RESTX ;FIRST TIME: FOR SECT:=1 ; ; READ A TRACK ; W$ATRACK: XRA A ;START NEW TRACK WITH SECTOR 0 W$RESTX: STA MSEC ;SET SECTOR W$RT0: LXI D,MATBL CALL WINCH ;READ A SECTOR ORA A ;TEST RESULTS JNZ REDO ;BR IF ERROR MVI C,'*' ;FLAG GOOD READ CALL MDSPOT ;ON CONSOLE LDED BSECSIZ ;UPDATE DMA POINTER FOR NEXT READ LHLD MDMAA ;DMAA+=SECSIZE DAD D ;. . SHLD MDMAA ;. . LHLD GOTTEN ;GOTTEN+=SECSIZE DAD D ;. . SHLD GOTTEN ;. . LDED BLDLN ;(IF GOTTEN>=LOADLENGTH THEN DONE) XCHG ;SWAP REGS XRA A ;RESET CARRY DSBC DE ;SUBTRACT JC BYE ;BR IF DONE LDA MSEC ;BUMP THE SECTOR INR A ;. . STA MSEC ;. . DCR A ;UNTIL FINISHED WITH THE TRACK LXI H,BNSECS ;. . CMP M ;. . JRNZ W$RT0 ;BR IF MORE ON THIS TRACK LHLD MTRK ;THEN SWITCH TRACKS INX H ;. . SHLD MTRK ;TRACK+=1 JR W$ATRACK ;AND BACK INTO LOOP PAGE ; ; NOT ABLE TO READ WINCHESTER. TRY READING FROM DISK. ; REDO: MVI A,1 ;SIGNAL A: DRIVE (LEL0284) STA BOOT$DRV ;STORE FOR CPMLDR (LEL0284) XRA A ;USE DRIVE 0 ("A") STA MDRV LXI H,0 ;TRACK 0 SHLD MTRK STA MHED ;SIDE 0 INR A ;SECTOR 1 STA MSEC LXI H,BUFFER ;SET DMA POINTER SHLD MDMAA XRA A ;SET READ FLAG STA MRWFLAG ;SET 5" DBL DENSITY STA MFIXMOD+0 ;. . MVI A,0FFH ;SET PRECOM TRACK=255 STA MFIXMOD+1 ;. . MVI A,01H ;SET STEP RATE=MAX STA MFIXMOD+2 ;. . LXI D,MATBL ;POINTER TO TABLE COUNT: DI ; MVI A,0EAH ; OUT P$CLK$PORTB ; EI ; MVI A,INT$INITIAL ;MASK FOR 8214 OUT INT$PORT ; XRA A ;CLEAR ACCUM LXI H,4000H ;GET TIMEOUT VALUE MOV A,M ;READ COUNTER VALUE DCR A ;DECREMENT VALUE CPI 0 ;COMPARE WITH COUNT OF 0 JRZ TIME1 ;TIME OUT FINISHED MOV M,A ;PUT BACK COUNT JMP LOOP0 ;CONTINUE NORMAL TIME1: MVI A,0D0H ;RESET FDC OUT P$DISK$CONTROL ; MVI A,88H ;PORTC,BIT4,RESET OUT P$8255$CONTROL ; MVI A,4FH ;DESELECT DRIVE OUT P$DISK$BITS ; ; LXI H,KEYMES ;SET ADDRESS FOR '...KEY...' MESSAGE CALL MESDPLY ;DISPLAY MESSAGE ; LOOP1: DI ;DISABLE INTERRUPTS XRA A ; OUT P$CLK$PORTB ;OUTPUT TO 8214 EI ;ENABLE INTERRUPTS IN P$KB$CONTROL ;READ STATUS BIT 1,A ;TEST FOR ANY KEY JRZ LOOP1 ;BACK NO KEY IN P$KB$DATA ;READ CODE CPI 21H ;TEST FOR SHIFT 1 JRNZ FINISH ;BRANCH IF NOT JMP DIAGS ;GO TO INTERACTIVE TEST ;IMES1: ; JMP IMES ;TEMP JUMP FINISH: DI ;DISABLE INTERRUPTS MVI A,0EEH ; OUT P$CLK$PORTB ; EI ;ENABLE INTERRUPTS JMP MRES ;BACK TO LOAD DISC LOOP0: CALL FLOPPY ;EXECUTE THE OPERATION ORA A ;TEST RESULTS JNZ try$all ;BR IF ERROR CALL LABEL$CHK ;ELSE CHECK LABEL (LEL0284) jnz TRY$ALL ; Jump if error (LEL0284) PAGE ;*******************************************************; ; ; ; READ REST OF SYSTEM ; ; AS SPECIFIED BY LABEL ; ; ; ;*******************************************************; MVI A,2 JMP RESTX ;FIRST TIME: FOR SECT:=2 ; ; READ A TRACK ; ATRACK: MVI A,1 ;START NEW TRACK WITH SECTOR 1 RESTX: STA MSEC ;SET SECTOR RT0: LXI D,MATBL CALL FLOPPY ;READ A SECTOR ORA A ;TEST RESULTS JNZ REDO ;BR IF ERROR MVI C,'*' ;FLAG GOOD READ CALL MDSPOT ;ON CONSOLE LDED BSECSIZ ;UPDATE DMA POINTER FOR NEXT READ LHLD MDMAA ;DMAA+=SECSIZE DAD D ;. . SHLD MDMAA ;. . LHLD GOTTEN ;GOTTEN+=SECSIZE DAD D ;. . SHLD GOTTEN ;. . LDED BLDLN ;(IF GOTTEN>=LOADLENGTH THEN DONE) XCHG ;SWAP REGS XRA A ;RESET CARRY DSBC DE ;SUBTRACT JRC BYE ;BR IF DONE LDA MSEC ;BUMP THE SECTOR INR A ;. . STA MSEC ;. . DCR A ;UNTIL FINISHED WITH THE TRACK LXI H,BNSECS ;. . CMP M ;. . JRNZ RT0 ;BR IF MORE ON THIS TRACK LDA BNHEDS ;TEST NUMBER OF HEADS CPI 1 ;. . JRNZ MO0$0 ;IF TWO SIDED THEN LHLD MTRK ;THEN SWITCH TRACKS INX H ;. . SHLD MTRK ;TRACK+=1 JR ATRACK ;AND BACK INTO LOOP MO0$0: LDA MHED ;DOUBLE SIDED THEREFORE INR A ;WE MUST SWITCH HEADS STA MHED ;. . ; ;***HEAD ARITHMETIC NOT COMPLETE. ;***DOES NOT ADVANCE TRACK, ;***IF MORE THAN TW0 TRACKS NEEDED ; JMP ATRACK ;AND BACK INTO LOOP SIGNATURE DB 'FMT' ; (LEL0284) PAGE ;*******************************************************; ; ; ; TEST VALIDITY OF LABEL ; ; ; ;*******************************************************; LABEL$CHK: ; (LEL0284) LXI H,BUFFER ;POINT TO BUFFER AREA LXI B,3 ;LENGTH TO MATCH (LEL0284) LXI D,SIGNATURE ;WHAT TO MATCH (LEL0284) LABEL$5: ; (LEL0284) LDAX D ;GET SIGNATURE CHAR (LEL0284) CCI ;COMPARE (LEL0284) INX D ;INC POINTER (LEL0284) JNZ Label$error ;JUMP IF NO MATCH (LEL0284) JPE LABEL$5 ;LOOP WHILE BC<>0 (LEL0284) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; Commented out 02/23/84 ; ; ; ; MOV A,M ;GET A CHAR (LEL0284) ; CPI 'F' ;TEST FOR F (LEL0284) ; JRNZ IMES1 ;BR IF NOT (LEL0284) ; INX H ;NEXT CHAR (LEL0284) ; MOV A,M ;GET A CHAR (LEL0284) ; CPI 'M' ;TEST FOR F (LEL0284) ; JRNZ IMES1 ;BR IF NOT (LEL0284) ; INX H ;NEXT CHAR (LEL0284) ; MOV A,M ;GET A CHAR (LEL0284) ; CPI 'T' ;TEST FOR F (LEL0284) ; JRNZ IMES1 ;BR IF NOT (LEL0284) ; INX H ;NEXT CHAR (LEL0284) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LHLD MDMAA ;UPDATE DMA POINTER FOR FIRST READ LDED BSECSIZ ;BY ADDING IN SECTOR SIZE DAD D ;. . SHLD MDMAA ;DMAA<=LOAD ADDRESS SDED GOTTEN ;GOTTEN<=SECSIZE LDA BSTEPR ;UPDATE THE STEP RATE STA MFIXMOD+2 ;. . lxi h,buffer ; Point to start of buf (LEL0284) lxi d,22 ; Add 22 (LEL0284) dad d ; Get load length (LEL0284) mov a,m ; Get byte (LEL0284) inx h ; point to next one (LEL0284) ora m ; Both = 0? (LEL0284) jz label$error ; If yes => error (LEL0284) MVI C,'*' ;FLAG GOOD READ CALL MDSPOT ;ON CONSOLE xra a ; A=0 if no error (LEL0284) RET ; (LEL0284) label$error: mvi a,0ffh ; A<>0 if error (LEL0284) ora a ; (LEL0284) ret ; (LEL0284) PAGE ;*******************************************************; ; ; ; DONE READING ; ; MOVE SYSTEM AND EXIT ; ; AS SPECIFIED BY LABEL ; ; ; ;*******************************************************; BYE: CALL CRLF ;CURSOR TO NEW LINE ; ;SET UP EXIT AREA ;SET UP THE FOLLOWING SEQUENCE OF CODE INTO THE EXIT AREA ; MVI A,01H ; OUT 00H,A ; RET ; ; MVI A,3EH ;OP CODE FOR 'MVI A,' STA EXIT+0 ;STORE AT 'EXIT' MVI A,01H ;DATA TO LOAD INTO ACC STA EXIT+1 ;STORE AT 'EXIT'+1 MVI A,(OUT) ;OP CODE FOR AN 'OUT' INSTRUCTION STA EXIT+2 ;STORE AT 'EXIT'+2 MVI A,00H ;PORT ADDRESS FOR 'OUT' INSTRUCTION STA EXIT+3 ;STORE AT 'EXIT'+3 MVI A,(RET) ;OP CODE FOR A 'RETURN' INSTRUCTION STA EXIT+4 ;STORE AT 'EXIT'+4 ; ; NOW MOVE THE DATA WE HAVE READ ; ; FROM ADDRESS = BUFFER+128 ; TO ADDRESS = BEGIN ADDRESS ; COUNT = LENGTH ; FIRST MUST TEST THE MOVE CONDITIONS LDED BLDBG ;GET THE DESTINATION ADDRESS LXI H,2000H-1 ;START OF AVAILABLE RAM XRA A ;RESET CARRY DSBC D ;SUBTRACT JRNC MOVERR ;BR IF ERROR : TOO LOW LXI H,BUFFER+128 ;TEST BETWEEN RAM AND BUFFER XRA A ;CARRY OFF DSBC D ;SUBTRACT JRZ MOVDON ;IF THE SAME : DONE LBCD BLDLN ;GET THE LENGTH JRNC MOVOK ;BR IF LESS : OK LXI H,BUFFER+128 ;CALCULATE TOP OF DATA DAD B ;. . INX H ;BUMPT BY ONE XRA A ;RESET CARRY DSBC D ;SUBTRACT JRNC MOVERR ;BR IF LESS : ERROR MOVOK: LXI H,BUFFER+128 ;GET BEGINNING ADDRESS LDIR ;AND MOVE THE DATA ; SET UP STARTING ADDRESS AND EXIT MOVDON: LHLD BJMPA PUSH H ;PUT JMP ADDRESS ON STACK MVI A,0EAH ;RESET MASK OUT P$CLK$PORTB ; MVI A,INT$INITIAL ;MASK FOR 8214 OUT INT$PORT ; EI ; JMP EXIT MOVERR: LXI D,MOVMES CALL DSPMSG ;DISPLAY ERROR MESSAGE MOVLP: JR MOVLP ;AND HANG PAGE ;*******************************************************; ; ; ; DISPLAY ROUTINES ; ; ; ;*******************************************************; CRLF: MVI C,0DH ;FIRST SEND A CR CODE CALL MDSPOT ;. . MVI C,0AH ;THEN SEND A LINE FEED JMP MDSPOT ;. . DSPMSG: LDAX DE ;GET A CHARACTER INX DE ;BUMP THE POINTER CPI '$' ;TEST FOR TERMINATION RZ ;EXIT IF IT IS MOV C,A ;ELSE DISPLAY THE CHARACTER PUSH DE ;SAVE POINTER CALL MDSPOT ;DISPLAY IT POP DE ;RESTORE THE POINTER JR DSPMSG ;LOOP MDSPOT: IN P$DISP$C ;GET STATUS ANI 1 ;TEST BIT 0 JRZ MDSPOT ;WAIT IF IT IS MOV A,C ;GET THE CHARACTER OUT P$DISP$OUT ;AND PUT IN THE REG MVI A,0EH ;STROBE OUT P$DISP$CONTROL ;. . INR A ;STROBE OFF OUT P$DISP$CONTROL ;. . RET ;AND EXIT ; ; ; BOOMES: DB 0CH,'V1050 BOOT Insert system diskette in left drive.' DB 0DH,0AH,'Ver:1.2','$' ; ; MOVMES: DB 'BOOT V1.2 Invalid Load Address.',0DH,0AH,'$' ; ; ERRMES: DB 'Z80 MEMORY ERROR1. SYSTEM HALTED.',0DH,0AH,'$' ; ; INIMES: DB 0,1BH,'c',0,'$' ; ; KEYMES: DB 13,'Type any key when ready.',0DH,0AH,'$' ; ; ACTMES: DB 0CH,'INTERACTIVE DIAGNOSTIC TEST',0DH,0AH,'Select one:' DB 0DH,0AH,'A. KEYBOARD TEST' DB 0DH,0AH,'B. ALIGNMENT TEST' DB 0DH,0AH,'C. RS232 PORT TEST' DB 0DH,0AH,'D. PRINTER WINCHESTER PORT TEST' DB 0DH,0AH,'E. EXIT DIAGNOSTICS','$' ; ; NCTMES: DB 0CH,'NONINTERACTIVE DIAGNOSTIC TEST' DB 0DH,0AH,'REAL TIME CLOCK' DB 0DH,0AH,'Select one:' DB 0DH,0AH,'A. SET REAL TIME CLOCK' DB 0DH,0AH,'B. READ REAL TIME CLOCK' DB 0DH,0AH,'C. NEXT','$' PAGE ;***************************************************************; ; ; ; FLOPPY READ/WRITE/SEEK/FORMAT ; ; ; ;***************************************************************; FLOPPY: ; ; < < < RESET FDC > > > ; MVI A,0D0H ;(Ends current command) OUT P$DISK$CONTROL LXI H,FIRQ SHLD IVECT+2 ;Clear deselect interrupt. ; ; < < < GET PARAMETERS > > > ; XCHG ;USING ADDRESS IN DE AS SOURCE... LXI D,FADR LXI B,FADRLEN LDIR ;CLONE ADDRESS TABLE MVI A,03H OUT P$8255$CONTROL ;ENABLE FDC INTERRUPT ; ; < < < SELECT MODES, DRIVE, HEAD > > > ; LDA FPT+0 ANI 0C0H ;DD/SD AND 5"/8" BITS MOV B,A ;INTO B LDA FDRV INR A ;0123->1234 CPI 3 JM FSEL$0 ;12 DONE ANI 06H ;34->24 ADD A ;24->48 DONE FSEL$0: XRI 0FH ;1 BIT OF 4 IS 0 (DECODED DRIVE SELECT) ORA B MOV B,A ;INTO B LDA FHED ORA A JZ FSEL$1 ;IF HEAD 1 THEN MVI A,10H ORA B MOV B,A ;SET HEAD 1 BIT IN B FI FSEL$1: LDA FTRK LXI H,FPT+1 CMP M JC FSEL$2 ;IF TRACK>=WPRECOMP TRACK THEN MVI A,20H ORA B MOV B,A ;SET WPRECOMP BIT IN B FI FSEL$2: MOV A,B OUT P$DISK$BITS ;MODES,DRIVE,HEAD SELECTED PAGE ; ; < < < ACTIVATE MOTORS > > > ; IN P$DISK$CONTROL ;IF MOTORS NOT ON RLC ;(READY LINE TELLS) JNC FM$99 ;BR IF MOTOR IS ON IN P$DISK$TRACK ;THEN TURN MOTOR ON OUT P$DISK$DATA MVI A,18H ;DO A DUMMY SEEK TO ACTIVATE HLD CALL FDOIT ;HLD RUNS MOTORS LXI H,560 ;WAIT 500 mS FM$00: XRA A FM$01: DCR A JNZ FM$01 ;896uS DCX H MOV A,L ORA H JNZ FM$00 ;560*896uS=502mS ; ; < < < ACCESS TRACK > > > ; FM$99: LDA FTRK ;TRACK TO C REG MOV C,A LXI H,FTRKA LDA FDRV MOV E,A MVI D,0 DAD D MOV A,M OUT P$DISK$TRACK ;P$DISK$TRACK:=FTRKA[DRV] ; ;IF FTRKA[DRV]<>TRACK THEN ; CMP C ; JZ FT$99 ;BR IF FTRKA[DRV]<>TRACK LDA FWF ;TEST LAST OPERATION ORA A ;. . JZ FT$50 ;BR IF IT WAS A READ MVI A,29 ;THEN WAIT 1 mS FT$X0: DCR A JNZ FT$X0 ;104 uS FT$X1: DCR A JNZ FT$X1 ;+896 uS=1 mS DELAY STA FWF ;RESET "LAST WAS A WRITE" FLAG FT$50: MOV A,M ;IF FIRST ACCESS THEN HOME DISK INR A ;FLAG IS FF WHEN FIRST ACCESS CZ FHOME ;HOME IF FIRST MOV M,C ;FTRKA[DRV]:=TRACK MOV A,C ;P$DISK$DATA:=TRACK CALL FSEEK ;SEEK CORRECT TRACK FT$99: LDA FSEC ;SELECT SECTOR OUT P$DISK$SECTOR ;P$DISK$SECTOR:=FSEC PAGE ; ; < < < DO THE DATA TRANSFER (IF ANY) > > > ; XRA A STA FTRYCNT ;CLEAR THE RETRY COUNT FTRY: LXI H,FWF ;RESET "LAST WAS A WRITE" FLAG MVI M,0 ;. . LDA FRWF ;GET OPERATION FLAGS MOV C,A ;TO C REG LDA FHED ;GET HEAD ANI 1 ;MASK RLC ;SHIFT RLC ;. . RLC ;SETUP HEAD BIT DCR C ;TEST OPERATION INR C JRZ FREAD ;0:FREAD XRA A ;RETURN CODE ZERO FOR SEEK JMP FDONE ;4,(OTHER):NO DATA TRANSFER ("SEEK") FREAD: ORI 82H ;SET READ FLAGS PAGE ;Setup registers for NMI ; EXAF ;GO TO ALTERNATE BANK EXX ;. . PUSH H ;SAVE HL PUSH B ;SAVE BC PUSH PSW ;SAVE A AND FLAGS LHLD FDMAA ;HL TO DMA ADDRESS MVI C,P$DISK$DATA ;FLOPPY DATA REG ADDRESS EXAF ;BACK TO NORMAL BANK EXX ;. . CALL FDOIT ;DO THE OPERATION EXAF ;GO TO ALTERNATE BANK EXX ;. . POP PSW ;RESTORE A AND FLAGS POP B ;RESTORE B AND C POP H ;RESTORE H AND L EXAF ;BACK TO NORMAL BANK EXX ;. . ; ;Determine error code, retry if data error, else exit with error ; MOV C,A ;RETURN CODE TO C REG ORA A ;TEST SUCCESSFUL JZ FDONE ;EXIT IF SUCCESSFUL INR A ;TEST FOR FF ERROR CODE MVI A,5 ;ASSUME ERROR CODE 5 JZ FDONE ;EXIT CODE 5 IF TIMED OUT BIT 6,C ;TEST WRITE PROTECT MVI A,4 ;SET RETURN CODE FOR WRITE PROTECT JNZ FDONE ;EXIT IF WRITE PROTECT VIOLATION BIT 2,C ;TEST LOST DATA MVI A,7 ;SET RETURN CODE FOR LOST DATA JRNZ FRETRY ;RETRY CODE 7 IF LOST DATA BIT 4,C ;TEST NOT FOUND MVI A,2 ;RETURN CODE FOR NOT FOUND JRNZ FRETRY ;RETRY CODE 2 IF NOT FOUND MVI A,1 ;RETRY CODE 1 IF CRC ERROR PAGE FRETRY: MOV C,A ;SAVE THE RETURN CODE LDA FTRYCNT ;GET THE RETRY COUNT INR A ;AND BUMP IT STA FTRYCNT ;. . CPI 10 ;TEST 10 RETRIES MOV A,C ;RETURN CODE BACK TO A REG JNC FDONE ;IF 10 FAILURES: EXIT LDA FTRYCNT ;GET THE RETRY COUNT AGAIN CPI 4 ;TEST FOR 4 OR MORE JC FTRY ;IF LESS THEN JUST TRY AGAIN ; ;ELSE (4 OR MORE), DO A HEAD RESTORE TOO. ; ; WE SEEK TRACK 5 THEN RESTORE IN ORDER TO ASSURE HEAD TRAVEL. ; THIS SHOULD CURE 1): PERSISTENT LINT ON THE HEADS 2): SEEK ERRORS. ; XRA A ;ACC = 0 CALL FSEEK ;SEEK TRACK 5 CALL FHOME ;HOME LDA FTRK CALL FSEEK ;BACK TO CORRECT TRACK JMP FTRY ;AND TRY AGAIN FDONE: PUSH PSW ;SAVE THE RETURN CODE IN P$DISK$TRACK OUT P$DISK$DATA MVI A,10H ;SEEK CODE CALL FDOIT ;DUMMY SEEK TO SHUT OFF HLD LXI H,FTIRQ ;SET UP DESELECT INTERRUPT SHLD IVECT+2 ;. . MVI A,0D2H ;IPT ON READY FALL OUT P$DISK$CONTROL ;. . POP PSW ;GET THE RETURN CODE ORA A ;SET Z FLAG IF NO ERROR RET ;AND WE ARE DONE PAGE ; SUBROUTINES ; HOME DISK FHOME: ;NOTE: ; We do not restore at the maximum step rate (6 mS per step) ; because we have some early versions of the Shugart 455 ; double-sided drive in the field which cannot be restored ; that fast. (The TRACK 0 flag doesn't respond fast enough.) LDA FPT+2 ;STEP RATE ANI 3 ;TEST FOR RATE = 0 JRNZ FHOM$0 ;BR IF NOT INR A ;BUMP RATE UP FHOM$0: ORI 08H ;HOME,HLD,NO VERIFY JR FDOSKH ;AND DO IT ; ;SEEK TRACK GIVEN BY ACC AT STEP RATE ; FSEEK: OUT P$DISK$DATA ;SET DATA REG TO DESIRED TRACK LDA FPT+2 ;STEP RATE ANI 3 ;MASK ORI 18H ;SEEK,HLD,NO VERIFY ;AND DO IT ;Floppy command routine for seek/home: ;Starts controller with command from A. ;Returns with status byte from controller. ;Doesn't do timeout. Does 20 mS settle wait after completion. ; Start controller. ; FDOSKH: OUT P$DISK$CONTROL ;ISSUE COMMAND MVI A,18 ;Delay at least 56 usec FDWAIT1: DCR A JNZ FDWAIT1 ;63 usec ; ;Wait for completion ; FS$0: IN P$DISK$CONTROL RRC JRC FS$0 IN P$DISK$CONTROL ;Return with A==Status byte. ; ;allow for settling time. ; LXI D,1A00H ;Delay at least 20 mS FS$X0: DCR E JNZ FS$X0 ;896uS DCR D JNZ FS$X0 ;26*896uS=23.3mS RET PAGE ;Floppy command routine: ;Starts controller with command from A. ;Returns with status byte from controller else 0FFH if timed out. ;(FF is OK as signal because status byte cannot be FF. (Busy bit cannot be ;high at completion.)) ; Start controller. ; FDOIT: OUT P$DISK$CONTROL ;ISSUE COMMAND ; ;(CAN'T USE ALTERNATE REGISTERS UNTIL COMPLETION ;IN CASE OPERATION INVOLVES DATA TRANSFER.) ; Delay at least 56 usec after command. ; MVI A,18 FDWAIT: DCR A JNZ FDWAIT ;63 usec ; ;Wait for completion, but TIME OUT after 1.2 sec ; LXI D,60000+1 FD0: IN P$DISK$CONTROL ;GET STATUS RRC ;TEST COMPLETE JNC FD1 ;BR IF COMPLETE INX D ;(WASTE TIME) DCX D ;(WASTE TIME) INX D ;(WASTE TIME) DCX D ;(WASTE TIME) DCX D ;NOW TEST FOR TIME OUT MOV A,D ;TIME OUT IF DE=0 ORA E ;. . JRNZ FD0 ;20 uS*60000=1.2 sec ; ;TIMED OUT ; MVI A,0D0H OUT P$DISK$CONTROL ;RESET FDC MVI A,0FFH ;RETURN WITH "TIMED-OUT" SIGNAL RET ; ;COMPLETION ; FD1: IN P$DISK$CONTROL ;Return with A==Status byte. RET PAGE ; INTERRUPTS ;Floppy completion interrupt: does nothing. ; FIRQ: PUSH PSW ;SAVE A AND FLAGS IN P$DISK$CONTROL ;Relieve interrupt MVI A,INT$INITIAL ;LOAD A REG WITH PRIORITY MASK OUT INT$PORT ;RESET 8214 INTERRUPT CONTROLLER POP PSW ;RESTORE EI ;IPTS BACK ON RET ;AND EXIT ; ;Floppy post-completion interrupt: deselects drive at motor shutoff. ; FTIRQ: PUSH PSW ;SAVE A AND FLAGS MVI A,0D0H ;RESET FDC OUT P$DISK$CONTROL ;RESET FDC MVI A,02H ;DISABLE INTERRUPT OUT P$8255$CONTROL ;. . IN P$DISK$BITS ;DESELECT THE DRIVE ORI 0FH ;. . OUT P$DISK$BITS ;. . MVI A,INT$INITIAL ;LOAD A REG WITH PRIORITY MASK OUT INT$PORT ;RESET 8214 INTERRUPT CONTROLLER POP PSW ;RESTORE A AND FLAGS EI ;IPTS BACK ON RET ;AND RETURN PAGE ;***************************************************************; ; ; ; WINCHESTER READ/WRITE/SEEK/FORMAT ; ; ; ;***************************************************************; ;Tandon TM501 drive on Xebec controller on our own host adaptor ;on the Winchester/general-purpose connector port. ;Supports 32 256-byte sectors/trk only. ;Supports one drive only. MAXBAD EQU 10 X EQU 0 CYLS EQU 306 REDUCE EQU 128 ;REDUCE CYL PRECOMP EQU 0 ;PRECOMP CYL MAXECC EQU 11 ;MAX ECC ;Get parameters. WINCH: XCHG ;USING ADDRESS IN DE AS SOURCE... LXI D,WADR LXI B,WADRLEN LDIR ;CLONE ADDRESS TABLE MVI A,4 ; SET UP STEP (LEL0384) STA STEPM ; STORE (LEL0384) MVI A,MAXECC ; GET MAX ECC (LEL0384) STA MAXIECC ; STORE (LEL0384) LXI H,CYLS ; (LEL0384) MOV A,H ; (REVERSE BYTES) (LEL0384) STA WCB1 ; (LEL0384) MOV A,L ; (LEL0384) STA WCB1+1 ; STORE (LEL0384) LXI H,REDUCE ; (LEL0384) MOV A,H ; (REVERSE BYTES) (LEL0384) STA STARTRED ; (LEL0384) MOV A,L ; (LEL0384) STA STARTRED+1 ; STORE (LEL0384) LXI H,PRECOMP ; (LEL0384) MOV A,H ; (REVERSE BYTES) (LEL0384) STA STARTPRE ; (LEL0384) MOV A,L ; (LEL0384) STA STARTPRE+1 ; STORE (LEL0384) lda Whed sta heds ;TOP LEVEL: FIRST ACCESS, RETRIES LDA WACCF ORA A JNZ W$0 ;IF FIRST ACCESS ;THEN ;RESET AND CONFIGURE THE WINCHESTER CALL WINRES RNZ ;(RETURN A=5 IF TIME OUT ERROR) ;MARK WINCHESTER ACCESSED MVI A,0FFH STA WACCF ;FI W$0: CALL WINCH2 ;TRY ONCE. RZ ;(DONE IF NO ERROR) CALL WINRES ;RESET AND CONFIGURE THE WINCHESTER RNZ ;(RETURN A=5 IF TIME OUT ERROR) ;JMP WINCH2;=CALL WINCH2/RET ;TRY AGAIN, ERROR CODE PASSES TO CALLER ;SECOND LEVEL WINCH2: ;IF LOGICAL READ OF TRACK 0, SECTOR 0, (I.E. ASSIMILATE OF LABEL) LDA WRWF ORA A ;(LOGICAL READ IS 00) JNZ W$1 LDA WSEC LHLD WTRK ORA H ORA L JNZ W$1 ;THEN RESET DRIVE CALL WINRES RNZ ;(RETURN A=5 IF TIME OUT ERROR) ;ASSIMILATE THE BAD TRACK TABLE XRA A STA BADTRACK-1 ;DEFAULT BAD TRACK COUNT TO 0 LXI H,0 SHLD ADH ;TRACK 0, SECTOR 0 MVI H,1 ;BLOCK COUNT OF 1 SHLD ADL ;XRA A CALL WAZ ;READ ABSOLUTE TRACK 0, SECTOR 0 RNZ ;(RETURN A=5 IF TIME OUT ERROR) LHLD WDMAA ;BAD TRACK TABLE FROM DISK IS SOURCE MOV A,M CPI 'W' ;"SIGNATURE" SHOULD BE "WXYZ" JNZ RETFF INX H MOV A,M CPI 'X' ; BUT CHECK ONLY THE FIRST 2 BYTES JNZ RETFF INX H INX H INX H ;SKIP OVER THE "SIGNATURE" MOV A,M CPI MAXBAD+1 JNC RETFF ;(ERROR FF IF MORE THAN (10) BAD) LXI D,BADTRACK-1;BAD TRACK TABLE IN MEMORY IS DESTINATION LXI B,(MAXBAD*2)+1 ;ROOM FOR BAD TRACK COUNT, (10) BAD TRACKS LDIR ;MOVE IT ;FI w$1: ;TRACK MAPPING: SKIP RESERVED TRACK 0, NUMBER AROUND BAD TRACKS (IF ANY) LHLD WTRK XCHG ;DE:=TRACK LDA WRWF ORA A JM MAPDONE ;(IDENTITY MAPPING IF "ABSOLUTE" FLAG SET) INX D ;TRACK+=1 (TRACK 0 RESERVED) LXI H,BADTRACK-1 MOV C,M INX H ;C:=# OF BAD TRACKS, HL:=POINTS TO BADTRACK LIST ;SCHEME: SCAN BAD TRACK LIST. BUMP TRACK FOR EACH BAD TRACK # THAT IS ; REACHED OR PASSED. INR C MAPMOR: DCR C JZ MAPDONE ;(DONE IF OUT OF BAD TRACKS) INX H MOV A,D CMP M DCX H JNZ MAP$0 MOV A,E CMP M MAP$0: JC MAPDONE ;(DONE IF BADTRACK>TRACK) INX D ;TRACK+=1 (SKIPS BAD TRACK) INX H INX H ;POINT TO NEXT BAD TRACK JMP MAPMOR MAPDONE: XCHG ;(HL=TRACK) ;ASSEMBLE "LOGICAL ADDRESS" XRA A MVI D,5 WWW: DAD H RAL DCR D JNZ WWW ;AHL:=TRACK*32 STA ADH ;(DRIVE ALWAYS 0) MOV A,H STA ADM LDA WSEC ADD L STA ADL ;AD(HML):=WTRK*32+WSEC MVI A,1 STA INTL ;SELECT OPCODE,DIRECTION LDA WRWF WAZ: LHLD WDMAA LXI B,0 ;B=0(=256) BYTE COUNT FOR DATA TRANSFER ;C=0 INPUT DIRECTION UNLESS CHANGED ANI 00FH JZ WREAD ;0=READ DCR A JZ WWRITE ;1=WRITE DCR A JZ WCHECK ;2=CHECK SEC SUI 3 ;3,4=NO OP JZ WFORMAT ;5=FORMAT DRIVE DCR A JZ WFMTBAD ;6=FORMAT BAD TRACK XRA A RET ;OTHER=NO OP RETURN CODE 0 WREAD: MVI A,8 JMP WACTR WWRITE: MVI A,10 JMP WACTW WCHECK: MVI A,8 ;READ JMP WACTW ;WRITE DIRECTION TO IGNORE DATA WFORMAT:LDA WPT ANI 31 STA INTL MVI A,4 JMP WACTW ;WRITE DIRECTION TO IGNORE DATA JUST IN CASE WFMTBAD:LDA WPT ANI 31 STA INTL MVI A,7 ;JMP WACTW ;WRITE DIRECTION TO IGNORE DATA JUST IN CASE WACTW: INR C;=MVI C,1 ;SET WRITE DIRECTION WACTR: CALL WDOIT RZ ;(RETURN OK IF OK) CPI 0FEH RNZ ;(RETURN ERROR (5/7) IF ERROR NOT STATUS BYTE) MVI A,3 ;"REQUEST SENSE STATUS" LXI H,LSTAT ;TO LSTAT LXI B,256*4;=MVI B,4/MVI C,0 ;4 BYTES IN CALL WDOIT RNZ ;(RETURN ERROR STATUS (5/7/FE)) LDA WRWF CPI 085H JNZ WEXIT ;IF FORMAT DRIVE LHLD WDMAA XCHG LXI H,LSTAT+1 LXI B,3 LDIR ;THEN DELIVER DISK ADDRESS TO DMA ADDRESS FI WEXIT: LDA LSTAT ANI 03FH CPI 4 ;IF THE CONTROLLER RETURNS 4 (DRIVE NOT READY) RNZ INR A;=MVI A,5/ORA A ; THEN CHANGE IT TO 5 RET ;RETURN CONTROLLER'S ERROR CODE ;RESET AND CONFIGURE THE WINCHESTER WINRES: MVI A,080H ; OUT p$winch$control ;PULSE THE RESET LINE MVI A,12 ;SET DRIVE CHARS COMMAND LXI H,WCB1 ;FROM DRIVE CHARS DATA LXI B,256*8+1;=MVI B,8/MVI C,1 ;8 BYTES OUT ;JMP WDOIT;=CALL WDOIT/RET ;RETURN A=ERROR STATUS WDOIT: ;LOWEST LEVEL COMMAND HANDLER. ;INPUT: DATA: C: DIRECTION (0=IN,1=OUT) ; B: HOW MANY ; HL: WHERE TO GET/PUT THEM ; ; CMD: A: COMMAND BYTE ; ; ;RETURN: A: STATUS BYTE ;SETUP OPCODE STA OP IN p$winch$control ANI 2 MVI A,7 RNZ ;(RETURN ERROR 7 IF BUSY) ;SELECT CONTROLLER MVI A,1 OUT p$winch$data ;p$winch$data:=DECODED CONTROLLER SELECTION (1) ;MVI A,1 OUT p$winch$control ;RAISE.. DCR A OUT p$winch$control ;..THEN LOWER.. THE SELECT LINE IN p$winch$control CMA ANI 2 MVI A,7 RNZ ;(RETURN ERROR 7 IF NOT BUSY) ;WAIT FOR REQUEST CALL WREQT RNZ ;(RETURN A=5 IF TIME OUT ERROR) IN p$winch$control CMA ANI 8 MVI A,7 RNZ ;(RETURN ERROR 7 IF REQUEST IS NOT COMMAND) ;JAM OUT COMMAND PUSH H PUSH B ;CALL WSND(WCB,6) LXI H,WCB MVI B,6 CALL WSND POP B POP H CALL WREQ ;IF REQ IS DATA IN p$winch$control ANI 8 JNZ NODATA ;THEN GET/PUT DATA MOV A,C ORA A PUSH PSW CZ WREC POP PSW CNZ WSND ;WAIT FOR REQUEST CALL WREQ IN p$winch$control CMA ANI 8 MVI A,7 RNZ ;(RETURN ERROR 7 IF REQUEST IS NOT COMMAND) ;FI NODATA: ;GET STATUS BYTE IN p$winch$data STA STAT MVI A,2 OUT p$winch$control ;THROW AWAY NULL STATUS BYTE CALL WREQT RNZ ;(RETURN A=5 IF TIME OUT ERROR) MVI A,2 OUT p$winch$control LDA STAT ANI 2 RZ ;(RETURN ZERO IF STATUS BYTE ZERO) MVI A,0FEH RET ;(RETURN 0FEH IF STATUS BYTE NOT OK) ;PROCEDURE WREC(HL,B) 'RECEIVE B BYTES FROM WINCH TO (HL) WREC: MVI C,p$winch$data MVI A,2 ;(ONLY WORKS UP TO 256 BYTES) ;REPEAT WREC1: ;(HL):=IN(C) *HL+=1 *B-=1 DW 0A2EDH;"INI" ;[ACKNOWLEDGE] - (SHOULD BE AUTOMATIC WITH DATA) OUT p$winch$control ;UNTIL B=0 JNZ WREC1 ;END WREC RET ;PROCEDURE WSND(HL,B) 'SEND B BYTES FROM (HL) TO WINCH WSND: MVI C,p$winch$data MVI A,2 ;(ONLY WORKS UP TO 256 BYTES) ;REPEAT WSND1: ;OUT(C):=(HL) *HL+=1 *B-=1 DW 0A3EDH;"OUTI" ;[ACKNOWLEDGE] - (SHOULD BE AUTOMATIC WITH DATA) OUT p$winch$control ;UNTIL B=0 JNZ WSND1 ;END WSND RET ;WAIT FOR WINCHESTER REQUEST WREQ: CALL WREQT JNZ WREQ RET ;WAIT FOR "REQUEST", RETURN Z=1 ;WAIT FOR WINCHESTER REQUEST; TIME OUT IF TOO LONG. WREQT: PUSH D LXI D,0 WREQT1: IN p$winch$control ANI 1 JZ WREQT1A ;DONE IF REQUEST, RETURN Z=1 DCX D MOV A,D ORA E JNZ WREQT1 ;XRA A ORI 5 ;DONE IF TIME OUT, RETURN A=5, Z=0 WREQT1A:POP D RET RETFF: ORI 0FFH RET ;END OF WINCH PAge ; ;===== NULL INTERRUPT HANDLERS ===== ; AINT: EXTINT: ZVINT: ZDINT: XINTB: XINTA: DI ;DISABLE FURTHER INTERRUPTS PUSH PSW ;SAVE CURRENT ACC OUT VID$VERT$INT ;CLEAR VIDEO VERT INTERRUPT OUT VID$DISP$INT ;CLEAR VIDEO DISP INTERRUPT MVI A,INT$INITIAL ;PRIORITY MASK FOR 8214 OUT INT$PORT ;SEND TO 8214 POP PSW ;RESTORE SAVED ACC EI ;ENABLE INTERRUPTS RET ;RETURN FROM INTERRUPT ; ; KINT: DI ;DISABLE FURTHER INTERRUPTS OUT VID$VERT$INT ;CLEAR VIDEO VERT INTERRUPT OUT VID$DISP$INT ;CLEAR VIDEO DISP INTERRUPT MVI A,INT$INITIAL ;PRIORITY MASK FOR 8214 OUT INT$PORT ;SEND TO 8214 IN P$KB$DATA ;READ 8251 DATA EI ;ENABLE INTERRUPTS RET ;RETURN FROM INTERRUPT PAGE ;############################################################################# ;# # ;# V 1 0 5 0 M I C R O - D I A G N O S T I C S # ;# # ;# BY D.Banks / S.Sherman Dec. 7, 1983 # ;# # ;############################################################################# ; KEY DEFINITIONS F1 EQU 0D4H F2 EQU 0D8H F3 EQU 0DCH F4 EQU 0E0H F5 EQU 0E4H F6 EQU 0E8H F7 EQU 0ECH F8 EQU 0F0H F9 EQU 0FCH F10 EQU 90H F13 EQU 94H ; CR EQU 0DH ;CARRIAGE RETURN CHARACTER ESC EQU 1BH ;ESCAPE CHARACTER FF EQU 0CH ;FORM FEED CHARACTER LF EQU 0AH ;LINE FEED ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Main Diagnostic Menu ; DIAGS: MVI A,4FH ;TURN FLOPPY MOTORS OFF AND DESELECT DRIVES OUT P$DISK$BITS ; LXI H,DIAGM1 ;POINT TO MAIN DIAG MENU CALL MESDPLY ;DISPLAY MENU CALL GETKEY ;GET KEYBOARD INPUT IN A REG CPI F1 ;SET CLOCK? CZ CLOCK0 ;GO SET CLOCK CPI F2 ;AUTOMATIC TESTS? JZ DOAUTO ;GO DO AUTOMATIC TESTS CPI F3 ;AUTOMATIC WITH OUT FLOPPIES ? JZ AUTOWOF ;GO DO AUTO WITH OUT FLOPPIES CPI F4 ;MANUAL TESTS? JZ DOMANUAL ;GO DO MANUAL TESTS CPI F13 ;IS IT AN EXIT? JZ DIAGEXIT ;REBOOT JMP DIAGS ;START OVER ; DIAGEXIT: MVI A,0CH ;FORM FEED CHARACTER CALL PUTKEY ;SEND TO SCREEN (6502) MVI A,0 ;NULL CHARACTER CALL PUTKEY ;SEND TO SCREEN (6502) ; XRA A ;MASK FOR BANK SELECT OUT P$BANK$SELECT ;SELECT BANK 0 ; JMP 0 ;RE-BOOT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Automatic Diagnostic Process ; DOAUTO: CALL MICRO8 ;ALIGNMENT CHECK CALL MICRO9 ;SERIAL TEST CALL MICROA ;WINY/PRINTER TEST CALL FLOPRDY ;FLOPPY READY CHECK ; LXIX -1 ;SET IX FLAG FOR FAST MEMORY DIAGNOSTIC CALL GALPAT ;MEMORY TEST ; JR DOAUTO ;LOOP FOREVER ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Automatic Diagnostic Process with out floppies ; AUTOWOF: CALL MICRO8 ;ALIGNMENT CHECK CALL MICRO9 ;SERIAL TEST CALL MICROA ;WINY/PRINTER TEST ; LXIX -1 ;SET IX FLAG FOR FAST MEMORY DIAGNOSTIC CALL GALPAT ;MEMORY TEST ; JR AUTOWOF ;LOOP FOREVER ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Manual Diagnostic Menu ; DOMANUAL: CALL INTVECTS ;SET UP INTERRUPT VECTORS ; LXI H,DIAGM2 ;POINT TO MANUAL MENU CALL MESDPLY ;DISPLAY MENU CALL GETKEY ;GET KEYBOARD INPUT MOV B,A ;SAVE KEYBOARD INPUT LXI H,DIAGTABLE ;POINT TO DIAG CALL TABLE DOMAN1: MOV A,M ;GET CODE FROM TABLE CPI 0 ;END OF TABLE? JZ DOMANUAL ;GO BACK IF END CMP B ;DOES KEY MATCH TABLE? JRZ FNDCALL ;JUMP IF MATCH INX H ;POINT TO NEXT IN TABLE INX H ; INX H ; JMP DOMAN1 ;LOOP UNTIL FOUND ; FNDCALL: CPI F13 ;EXIT CODE? JZ DIAGS ;REBOOT IF YES ; PUSH B ;SAVE KEYBOARD INPUT ; INX H ;POINT TO CALL LSB MOV E,M ;GET LSB INX H ;POINT TO CALL MSB MOV D,M ;GET MSB LXI H,DIAGRET ;RETURN ADDRESS PUSH H ;TO TOP OF STACK XCHG ;PUT CALL ADDRESS IN HL PCHL ;MAGIC CALL OF THAT ROUTINE DIAGRET: ; POP B ;RESTORE SAVED KEYBOARD INPUT MOV A,B ;MOVE TO ACC FOR CHECKS ; CPI F2 ;SCREEN ALIGNMENT TEST ? JZ HOLD ;WAIT FOR KEYBOARD INPUT CPI F6 ;READ RTC ? JZ HOLD ;WAIT FOR KEYBOARD INPUT ; JMP DOMANUAL ;START OVER ; HOLD: CALL GETKEY ;GET A KEYBOARD INPUT JMP DOMANUAL ;START OVER ; DIAGTABLE: DB F1 DW MICRO7 DB F2 DW MICRO8 DB F3 DW MICRO9 DB F4 DW MICROA DB F5 DW CLOCK0 DB F6 DW TIME$20 DB F7 DW GALPLINK DB F8 DW FLOP DB F9 DW ATTTEST DB F10 DW FASTLINK DB F13 DW 0000 DB 0 ;TERMINATOR ; DIAGM1: DB FF,ESC,'[7m' DB ' V1050 MICRO-DIAGNOSTICS ',CR,LF DB ESC,'[m' DB 'F1 - Set Real Time Clock',CR,LF DB 'F2 - Run Automatic Diagnostics',CR,LF DB 'F3 - Run Automatic Diagnostics w/o floppies',CR,LF DB 'F4 - Run Manual Diagnostics',CR,LF DB 'F13 - Exit Diagnostics / Reboot',CR,LF DB LF DB 'Enter Selection ... ','$' ; DIAGM2: DB FF,ESC,'[7m' DB 'Manual Diagnostics',CR,LF DB ESC,'[m' DB 'F1 - Keyboard Test',CR,LF DB 'F2 - Display Alignment Test',CR,LF DB 'F3 - Serial Interface Test',CR,LF DB 'F4 - Winchester/Printer Interface Test',CR,LF DB 'F5 - Set Real Time Clock',CR,LF DB 'F6 - Read Real Time Clock',CR,LF DB 'F7 - Galpat Memory Diagnostic',CR,LF DB 'F8 - Floppy Read/Write Test',CR,LF DB 'F9 - Visual Attribute Test',CR,LF DB 'F10 - Fast Memory Diagnostic',CR,LF DB 'F13 - Exit Manual Diagnostics',CR,LF,LF DB 'Enter Selection ... ','$' ; GALPLINK: LXIX 0 ;INDICATE NORMAL GALPAT TEST JR GLINK ;GO TO COMMON CODE FASTLINK: LXIX -1 ;INDICATE FAST TEST (MKBTST) GLINK: JMP GALPAT ;JUMP TO MEMORY TESTS ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ;VISUAL ATTRIBUTE TEST ; ATTTEST: LXI H,NORMSCRN ;SET SCREEN TO NORNAL CALL MESDPLY ;SEND TO 6502 ; MVI B,2 ;SET COUNTER MOREATTS: LXI H,ATTMES ;GET TITLE MESSAGE CALL MESDPLY ;DISPLAY IT ; MOV A,B ;GET PASS COUNTER CPI 1 ;ARE WE DOING THE SECOND PASS ? JRNZ NO$MSG ;NO, SO CONTINUE LXI H,INVS$MSG ;YES, SO POINT TO 'INVERSE' MESSAGE CALL MESDPLY ;...DISPLAY IT ; NO$MSG: LXI H,DIMMES ;TEST NORMAL INTENSITY ATTRIB. CALL MESDPLY ;DO TEST ; LXI H,BLINKMES ;TEST BLINK ATTRIB. CALL MESDPLY ;DO TEST ; LXI H,BOLDMES ;TEST BRIGHT ATTRIB. CALL MESDPLY ;DO TEST ; LXI H,REVMES ;TEST REVERSE CHARACTER VIDEO ATTRIB. CALL MESDPLY ;DO TEST ; LXI H,PRESSMES ;POINT TO 'PRESS...' MESSAGE CALL MESDPLY ;DISPLAY MESSAGE ; CRCHECK: CALL GETKEY ;GET KEYBOARD INPUT CPI CR ;CARRIAGE RETURN ? JRNZ CRCHECK ;NO, CHECK AGAIN ; LXI H,REVSCRN ;REVERSE WHOLE SCREEN CALL MESDPLY ;CHANGE ATTRIBUTE ; DJNZ MOREATTS ;DO ATT TEST AGAIN ; LXI H,NORMSCRN ;CHANGE BACK TO NORMAL ATTRIBUTES CALL MESDPLY ;CHANGE ATTRIBUTE ; RET ;RETURN FROM TEST ; ; ATTMES: DB FF,ESC,'[7m' DB 'VISUAL ATTRIBUTE TEST' DB ESC,'[m',CR,LF,LF,LF,'$' DIMMES: DB ESC,';P' ;SET SCREEN TO NORMAL DB 'This line should be NORMAL intensity' DB ESC,'[m',CR,LF,LF,'$' BLINKMES: DB ESC,'[5m' ;SET BLINK ATTRIBUTE DB 'This line should be BLINKING' DB ESC,'[m',CR,LF,LF,'$' BOLDMES: DB ESC,'[1m' ;SET SCREEN TO BRIGHT DB 'This line should be BRIGHT' DB ESC,'[m',CR,LF,LF,'$' REVMES: DB ESC,'[7m' ;REVERSE INTENSITY ATTRIBUTE DB 'This line should be in REVERSE VIDEO' DB ESC,'[m',CR,LF,LF,'$' REVSCRN: DB ESC,';Y','$' ;REVERSE WHOLE SCREEN NORMSCRN: DB ESC,';Q','$' ;NORNAL SCREEN INVS$MSG: DB CR,LF DB 'INVERSE SCREEN MODE' DB CR,LF,LF,'$' PRESSMES: DB 'Press RETURN key when ready to continue.','$' ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Get key from keyboard into register A ; GETKEY: MVI A,14H ;RESET KEYBOARD ERRORS OUT P$KB$CONTROL ; DI ;DISABLE INTERRUPTS XRA A ;CLEAR INTERRUPT MASK OUT P$CLK$PORTB ; EI ;ENABLE INTERRUPTS IN P$KB$CONTROL ;GET KEYBOARD STATUS BYTE BIT 1,A ;CHECK RECV BIT JRZ GETKEY ;LOOP UNTIL KEY PRESSED IN P$KB$DATA ;GET KEYBOARD DATA RET ;RETURN TO CALLER ; PUTKEY: PUSH PSW ;SAVE CHARACTER PUSH PSW ;SAVE CHARACTER AGAIN PUTKEY1: IN P$DISP$C ;GET DISPLAY STATUS RRC ;GET BUSY BIT JRNC PUTKEY1 ;LOOP IF BUSY POP PSW ;RESTORE CHARCATER OUT P$DISP$OUT ;SEND CHARACTER OUT TO DISPLAY MVI A,0EH ;SET DISPLAY STROBE LOW OUT P$DISP$CONTROL ;BANG BIT INR A ;SET DISPLAY STROBE HIGH OUT P$DISP$CONTROL ;BANG BIT POP PSW ;GET SAVED CHARACTER RET ;RETURN FROM SUBROUTINE ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Check Floppy ready for both drives within 850ms ; FLOPRDY: LXI H,FLRDY ;POINT TO FLOPPY TEST MESSAGE CALL MESDPLY ;DISPLAY MESSAGE MVI A,00001110B ;FLOPPY MOTORS ON, SELECT DRIVE 0 CALL FLOPRDY1 ;CHECK DRIVE 0 LXI H,FLDR1 ;POINT TO DRIVE 1 MESSAGE CALL MESDPLY ;DISPLAY MESSAGE MVI A,00001101B ;FLOPPY MOTORS ON, SELECT DRIVE 1 CALL FLOPRDY1 ;CHECK DRIVE 1 MVI A,01001111B ;DESELECT ALL OUT P$DISK$BITS ; RET ;RETURN TO CALLER FLOPRDY1: OUT P$DISK$BITS ;SELECT DRIVE ; CALL FHOME ;RECAL DRIVE ; MVI A,18H ;DUMMY SEEK CALL FDOIT1 ; ; PUSH PSW ;SAVE STATE PUSH B ; LXI B,0349H ;850 MILLISECOND VALUE FLOPRDY2: CALL DEL1MS ;WAIT 1 MILLISECOND DCX B ;DECREMENT MILLISECOND COUNTER MOV A,B ;GET UPPER BYTE ORA C ;COMBINE WITH LOWER BYTE JRNZ FLOPRDY2 ;LOOP IF NOT DONE POP B ;RESTORE STATE POP PSW ; ; IN P$DISK$CONTROL ;READ CONTROLLER STATUS ANI 80H ;GET READY BIT RZ ;RETURN IF OK ; FLOPERR: POP B ;CHEAT STACK JMP ERRORA ;TELL ERROR IF NOT READY FLRDY: DB FF,ESC,'[7m' DB 'Floppy Ready Check',CR,LF DB ESC,'[m' DB 'Drive 0',CR,LF,'$' FLDR1: DB 'Drive 1',CR,LF,'$' ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;***************************************************; ; ; ; TEST A ; ; KEY BOARD TEST ; ; ; ;***************************************************; MICRO7: ; LXI H,KEYTEST ;POINT TO MESSAGE CALL MESDPLY ;DISPLAY MESSAGE ; MIC7B: MVI A,14H ; OUT P$KB$CONTROL ;RESET BIT DI ;DIABLE INTERRUPTS XRA A ; OUT P$CLK$PORTB ; EI ;ENABLE INTERRUPTS MVI C,61H ;FIRST ASCII CHARACTER TO TEST MVI D,71H ;LAST ASCII CHARACTER TO TEST MIC7BA: MOV A,C ;GET CURRENT CHARACTER CMP D ;ARE WE DONE ? RZ ;IF WE ARE, RETRUN CALL GETKEY ;READ A CHARACTER FROM KEYBOARD CALL PUTKEY ;ECHO CHARACTER TO SCREEN CMP C ;CHECK FOR CHARACTER LIMIT JRNZ LERRORA ;INDICATE ERROR INR C ;C REG HAS NEXT CHARACTER TO CHECK FOR JR MIC7BA ;GO BACK RET ;TEST OVER LERRORA: JMP ERRORA ;LINK ADDRESS ; ; KEYTEST: DB FF,ESC,'[7m' DB 'KEYBOARD TEST, TYPE LOWER CASE a THRU p' DB ESC,'[m','$' PAGE ;***************************************************; ; ; ; TEST B ; ; GRAPHIC DISPLAY ; ; ; ;***************************************************; MICRO8: LXI H,AUTONLOFF ;POINT TO AUTO NEW LINE OFF MESSAGE CALL MESDPLY ;TURN AUTO N.L. OFF ; LXI H,CLS ;POINT TO SCREEN CLEAR MESSAGE CALL MESDPLY ;CLEAR SCREEN ; MVI B,26 ;LOAD COUNTER FOR 25 LINES + 1 XTRA ALIGNM: ; LXI H,CURPOS ;CR/LF CALL MESDPLY ;DO A CARRIAGE RETURN/LINE FEED ; CALL XESS ;DISPLAY A LINE OF X'S ; DJNZ ALIGNM ;IF NOT DONE, DO SOME MORE ; LXI H,BOX ;FINISH WITH BORDER AND TITLE CALL MESDPLY ;DISPLAY THEM... ; RET ;...TEST OVER... ; ; XESS: PUSH B ;SAVE LINE COUNTER MVI B,80 ;CHARACTER COUNTER MOREX: LXI H,XMES ;POINT TO 'X' CHARACTER CALL MESDPLY ;DISPLAY IT ON SCREEN ; DJNZ MOREX ;CONTINUE TILL 80 ON A LINE ; POP B ;RESTORE LINE COUNTER ; RET ;RETURN FROM SUBROUTINE ; ; AUTONLOFF: DB ESC,';D','$' ;AUTO NEW LINE OFF SEQUENCE BOX: DB ESC,'?0;0C' ;GRAPHIC HOME POSITION DB ESC,'?639;0L' ;TOP LINE DB ESC,'?639;299L' ;RIGHT SIDE LINE DB ESC,'?0;299L' ;BOTTOM LINE DB ESC,'?0;0L' ;LEFT SIDE LINE DB ESC,'[11;31f' ;LINE 12, COLUMN 32 DB ' Screen Alignment ' ;TITLE DB '$' ;MESSAGE TERMINATOR CLS: DB FF,'$' ;FORM FEED CHARACTER CURPOS: DB CR,LF,'$' ;CR/LF SEQUENCE XMES: DB 'X','$' ;'X' CHARACTER ; ; PAGE ;*************************************************; ; ; ; TEST C ; ; RS232 PORT TEST ; ; ; ;*************************************************; MICRO9: LXI H,SERIALTST ;POINT TO MESSAGE ; CALL MESDPLY ;DISPLAY MESSAGE ; MIC9B: ; MVI A,2EH ; OUT P$CLK$PORTB XRA A ; OUT P$AUX1$CONTROL ; OUT P$AUX1$CONTROL ; OUT P$AUX1$CONTROL ; MVI A,40H ; OUT P$AUX1$CONTROL ; MVI A,4DH ; OUT P$AUX1$CONTROL ; MVI A,15H ; OUT P$AUX1$CONTROL ; MIC9D: IN P$AUX1$CONTROL ;TEST TRANSMIT READY BIT 0,A ; BIT TEST JRZ MIC9D ;NO BIT SET MVI A,55H ;DATA PATTERN OUT P$AUX1$DATA ;WRITE RS232 PORT CALL DEL1SEC ;WAIT 1 SECOND MIC9E: IN P$AUX1$CONTROL ;RECEIVE READY BIT 1,A ;TEST BIT JRZ ERROR0 ;NO BIT SET IN P$AUX1$DATA ;READ RS232 PORT CPI 55H ;COMPARE DATA JRNZ ERROR0 ;RS232 LOOPBACK ERROR MIC9F: IN P$AUX1$CONTROL ;TEST TRANSMIT READY BIT 0,A ;BIT SET JRZ MIC9F ;NO BIT SET MVI A,0AAH ;DATA PATTERN OUT P$AUX1$DATA ;WRITE RS232 PORT CALL DEL1SEC ;WAIT 1 SECOND MIC9G: IN P$AUX1$CONTROL ;RECEIVE READY BIT 1,A ;TEST BIT JRZ ERROR0 ;NO BIT SET IN P$AUX1$DATA ;READ RS232 PORT CPI 0AAH ;COMPARE DATA JRNZ ERROR0 ;RS232 LOOPBACK ERROR ; RET ;TEST OVER TEMP JUMP ; SERIALTST: DB FF,ESC,'[7m' DB 'SERIAL PORT TEST',CR,LF DB 'LOOPBACK REQUIRED' DB ESC,'[m','$' ; ERROR0: JMP ERRORA ;GO TO ERROR DISPLAY ; ; DEL1SEC: ;DELAY 1 SECOND PUSH B ;SAVE BC REGISTER PAIR LXI B,1000 ;1000 MSECS DEL1SECA: CALL DEL1MS ;DELAY 1 MILLISECOND DCX B ;DECREMENT DELAY COUNT MOV A,B ;GET UPPER BYTE OF DELAY COUNT ORA C ;COMBINE WITH LOWER BYTE JRNZ DEL1SECA ;IF NOT DONE, DO SOME MORE POP B ;RESTORE BC REGISTERS RET ;RETURN FROM SUBROUTINE PAGE ;******************************************************; ; ; ; TEST D ; ; PRINTER WINCHESTER PORT TEST ; ; ; ;******************************************************; MICROA: LXI H,WINYTST ;POINT TO MESSAGE ; CALL MESDPLY ;DISPLAY MESSAGE ; CALL DEL1SEC ;WAIT 1 SECOND CALL DEL1SEC ;WAIT 1 SECOND ; XRA A ;SET UP OUT P$8255$CONTROL ;SET UP 8255 MVI A,055H ;DATA PATTERN OUT P$PRINTER ;WRITE PRINTER PORT IN P$WINCH$DATA ;READ WINCHESTER PORT CPI 0AAH ;CHECK DATA JRNZ ERRORE ;LOOPBACK ERROR MVI A,0AAH ;FF DATA PATTERN OUT P$PRINTER ;WRITE PRINTER PORT IN P$WINCH$DATA ;READ WINCHESTER PORT CPI 055H ;CHECK DATA JRNZ ERRORE ;LOOPBACK ERROR ; RET ;TEST FINISHED -- BACK TO USER INTERACTIVES ERRORE: JMP ERRORA ;GO DISPLAY ERROR ; WINYTST: DB FF,ESC,'[7m' DB 'WINCHESTER / PRINTER PORT TEST',CR,LF DB 'LOOPBACK REQUIRED' DB ESC,'[m','$' ; PAGE ERRORA: LXI H,ERROR1 ; ; CALL MESDPLY ;DISPLAY MESSAGE ; ERRORC: DI ; XRA A ; OUT P$CLK$PORTB ; EI ; IN P$KB$CONTROL ; BIT 1,A ; JRZ ERRORC ; ERRORC1: IN P$KB$DATA ;GET KEYBOARD DATA CPI 0DH ;IS IT A CARRIAGE RETURN ? JRNZ ERRORC1 ;NO, WAIT FOR ONE RET ; ERROR1: DB ESC,'[7;5m',CR,LF,LF DB 'ERROR IN TEST ',CR,LF DB 'TYPE RETURN KEY TO EXIT' DB ESC,'[m','$' PAGE ;*******************************************************; ; ; ; SET REAL TIME CLOCK ; ; ; ;*******************************************************; TIME0: DB FF,ESC,'[7m' DB CR,LF,'SET REAL TIME CLOCK',ESC,'[m' DB CR,LF,'ENTER TODAY''S DATE (MM/DD/YY):','$' TIMEA: DB CR,LF,'ENTER THE TIME (HH:MM:SS):','$' BAD$DATE: ; (LEL0284) DB CR,LF,LF,'ERROR IN DATE',CR,LF,'$' ; (LEL0284) BAD$TIME: ; (LEL0284) DB CR,LF,LF,'ERROR IN TIME',CR,LF,'$' ; (LEL0284) CONT$MSG: ; (LEL0284) DB CR,LF,'TYPE RETURN KEY TO REENTER',CR ; (LEL0284) DB LF,'TYPE ESC TO EXIT' ; (LEL0284) DB '$' ; (LEL0284) ; ; Beginning of routine to set time and date. ; Set PASS$FLG = 1 to indicate that you are getting TIME info. ; CLOCK$0: LXI H,PASS$FLG ;ADDRESS FOR FLAG (LEL0284) MVI A,01H ; MOV M,A ;SET PASS FLAG LXI H,TIME0 ;GET DATA FOR MESSAGE ; ; Display "ENTER..." message ; CLOCK$1: CALL MESDPLY ;DISPLAY MESSAGE LXI H,PASS$FLG ;FLAG ADDRESS (LEL0284) MOV A,M ;READ FLAG CPI 02 ;SEE IF PASS 2 JRZ CLOCK$2 ;IF YES, THEN CONTINUE ; ; If first pass, enter the date ; ; MVI B,08H ;BYTE COUNT (LEL0284) MVI B,09H ;BYTE COUNT=9 (LEL0284) LXI H,THE$DATE ;CODE ADDRESS (LEL0284) JR CLOCK$3 ; ; ; If second pass, enter the time ; CLOCK$2: ; MVI B,08H ;BYTE COUNT (LEL0284) MVI B,09H ;BYTE COUNT=9 (LEL0284) LXI H,THE$TIME ;CODE ADDRESS (LEL0284) ; ; Get key from keyboard ; CLOCK$3: MVI A,14H ; OUT P$KB$CONTROL ;RESET BIT DI ; XRA A ;RESET ACC TO ZERO OUT P$CLK$PORTB ; EI ; IN P$KB$CONTROL ;TEST BIT SET BIT 1,A ; JRZ CLOCK3 ;NO BIT SET IN P$KB$DATA ;READ CODE ; ; Examine incoming code. If it is a BACKSPACE, back up two ; character positions (one for the BACKSPACE and one for the ; previous data). ; CPI 08H ;BACKSPACE? (LEL0284) JRNZ CLOCK$4 ;JUMP IF NOT (LEL0284) MOV C,A ;STORE BACKSPACE IN C (LEL0284) MOV A,B ;GET COUNT (LEL0284) CPI 9 ;ALREADY AT START? (LEL0284) JRZ CLOCK3 ;THEN DO NOT BACKSPACE (LEL0284) DCX H ;DEC MEMORY POINTER (LEL0284) INR B ;INC COUNT (LEL0284) INR B ;TWICE (LEL0284) JR CLOCK5 ;GO STORE IT (LEL0284) ; ; Check to see if 8 characters have already been received. If ; yes, then the only characters that are allowable at this point ; are BACKSPACE (already handled above) and CARRIAGE RETURN. ; CLOCK$4: ; (LEL0284) MOV C,A ;SAVE KEY CODE (LEL0284) MOV A,B ;GET COUNT (LEL0284) CPI 01 ;LAST ONE? (LEL0284) JRNZ CLOCK$5 ;JUMP IF NOT (LEL0284) MOV A,C ;GET KEY CODE AGAIN (LEL0284) CPI CR ;CARRIAGE RETURN? (LEL0284) JRNZ CLOCK$3 ;NO. WAIT FOR ONE. (LEL0284) ; ; Have received valid keycode. Store it. ; CLOCK$5: ; (LEL0284) MOV M,C ;STORE CODE (LEL0284) ; MOV M,A ;STORE CODE (LEL0284) ; ; Send character to display ; CLOCK$6: IN P$DISP$C ; RRC ; JRNC CLOCK6 ;LOOP UNTIL READY MOV A,M ; OUT P$DISP$OUT ; MVI A,0EH ; OUT P$DISP$CONTROL ; INR A ; OUT P$DISP$CONTROL ; ; ; Decrement count. If it is 0, or if character was a CR, we are done. ; DCR B ;DECREMENT COUNTER MOV A,B ;GET COUNT CPI 00H ;SEE IF DONE JRZ CLOCK7 ; MOV A,M ;WAS CHAR A CR? (LEL0284) CPI CR ; (LEL0284) JRZ CLOCK7 ;JUMP IF YES (LEL0284) CPI 08H ;WAS IT A BACKSPACE? (LEL0284) JRZ CLOCK3 ;IF YES DON'T INCREMENT (LEL0284) INX H ; JR CLOCK3 ; ; ; Check to see if both time and date have been entered. ; CLOCK$7: LXI H,PASS$FLG ;FLAG ADDRESS (LEL0284) MOV A,M ;READ CPI 02 ;TEST 2ND PASS JRZ CLOCK$10 ;IF YES, CONTINUE MVI A,02H ;SET FLAG MOV M,A ;STORE LXI H,TIMEA ;NEW LOGO Jr CLOCK1 ;BACK TILL DONE ; ; Have input Date and time. Do a quick run through the data to ; make sure that numeric data is where it should be. ; CLOCK$10: LXI H,THE$DATE ;START WITH DATE (LEL0284) CALL DIGIT$CHK ;CHECK DIGITS (LEL0284) JRNZ DATE$ERROR ;JUMP IF WRONG (LEL0284) LXI H,THE$TIME ;THEN CHECK THE TIME (LEL0284) CALL DIGIT$CHK ;CHECK DIGITS (LEL0284) JRNZ TIME$ERROR ;JUMP IF ERROR (LEL0284) JMP TIME$XX ;TEMP JUMP page ; ; Subroutine to check that digits are where the n's are in the ; following: ; ; nn/nn/nn ; ; (other positions are DON'T CARES) ; DIGIT$CHK: ; (LEL0284) mvi b,3 ; Load count (LEL0284) mvi c,0 ; Load flag (LEL0284) DIGIT$10: ; (LEL0284) mov a,m ; Get character (LEL0284) cpi 30h ; is it <0? (LEL0284) jm bad$num ; if yes => error (LEL0284) cpi 03ah ; Is it >9? (LEL0284) jp bad$num ; That is bad too (LEL0284) inx h ; Else, point to next (LEL0284) mov a,c ; Get flag (LEL0284) xri 0ffh ; Flip it (LEL0284) mov c,a ; Store new value (LEL0284) jrnz digit$10 ; Do twice (LEL0284) inx h ; Then inc past DC (LEL0284) djnz digit$10 ; loop till done (LEL0284) ret ; RET w/z flag if good (LEL0284) BAD$NUM: ; (LEL0284) mvi a,0FFH ; Make Z-flag not true (LEL0284) ora a ; for error (LEL0284) ret ; RET (LEL0284) ; ; Error in time or date. ; DATE$ERROR: ; (LEL0284) lxi h,bad$date ; point to message (LEL0284) jr err$path ; (LEL0284) TIME$ERROR: ; (LEL0284) lxi h,bad$time ; point to message (LEL0284) ERR$PATH: ; (LEL0284) call MESDPLY ; Display error (LEL0284) lxi h,cont$msg ; Print continue msg (LEL0284) call mesdply ; (LEL0284) ; ; Wait for user to indicate ESC to exit test or CR to reenter data. ; ERR$P6: ; (LEL0284) MVI A,14H ; (LEL0284) OUT P$KB$CONTROL ;RESET BIT (LEL0284) DI ; (LEL0284) XRA A ;RESET ACC TO ZERO (LEL0284) OUT P$CLK$PORTB ; (LEL0284) EI ; (LEL0284) IN P$KB$CONTROL ;TEST BIT SET (LEL0284) BIT 1,A ; (LEL0284) JRZ ERR$P6 ;NO BIT SET (LEL0284) IN P$KB$DATA ;READ CODE (LEL0284) CPI CR ;CR? (LEL0284) jz clock$0 ;Yes => try again (LEL0284) cpi 01bh ;ESC? (LEL0284) rz ;RET if yes (LEL0284) Jmp ERR$P6 ;loop till ESC or CR (LEL0284) page ; ;ADD EXTRAS FOR DISPLAY ;FOR DATE ; TIME$AA: LXI H,4070H ;START ADDRESS MVI A,0DH ; CR MOV M,A ;STORE INX H ;INCREMENT POINTER MVI A,0AH ; LF MOV M,A ;STORE INX H ;INCREMENT POINTER MVI A,44H ; D MOV M,A ;STORE INX H ;INCREMENT POINTER MVI A,41H ; A MOV M,A ;STORE INX H ;INCREMENT POINTER MVI A,54H ; T MOV M,A ;STORE INX H ;INCREMENT POINTER MVI A,45H ; E MOV M,A ;STORE INX H ;INCREMENT POINTER MVI A,3AH ; : MOV M,A ;STORE INX H ;INCREMENT POINTER MVI A,20H ; SP MOV M,A ;STORE LXI H,407AH ;NEW POINTER MVI A,2FH ; / MOV M,A ;STORE LXI H,407DH ;NEW POINTER MOV M,A ;STORE ; ;FOR TIME ; LXI H,4080H ;START ADDRESS MVI A,0DH ; CR MOV M,A ;STORE INX H ;INCREMENT POINTER MVI A,0AH ; LF MOV M,A ;STORE INX H ;INCREMENT POINTER MVI A,54H ; T MOV M,A ;STORE INX H ;INCREMENT POINTER MVI A,49H ; I MOV M,A ;STORE INX H ;INCREMENT POINTER MVI A,4DH ; M MOV M,A ;STORE INX H ;INCREMENT POINTER MVI A,45H ; E MOV M,A ;STORE INX H ;INCREMENT POINTER MVI A,3AH ; : MOV M,A ;STORE INX H ;INCREMENT POINTER MVI A,20H ; SP MOV M,A ;STORE LXI H,408AH ;NEW POINTER MVI A,3AH ; : MOV M,A ;STORE LXI H,408DH ;NEW POINTER MOV M,A ;STORE LXI H,4090H ;RAM POINTER LXI D,RETURN ;PROM POINTER REST: LDAX D ;READ PROM MOV M,A ;STORE CPI '$' ;TEST TERMINATION JRZ TIME$LO ;IF TERMINATOR, CONTINUE INX H ;INCREMENT RAM POINTER INX D ;INCREMENT PROM POINTER JR REST ;BACK TILL DONE RETURN: DB 0DH,0AH,'$' ; TIME$LO: LXI H,4070H ;RESTORE POINTER ; CALL MESDPLY ;DISPLAY MESSAGE ; ;#TIME$EE: ; MVI A,14H ; ; OUT P$KB$CONTROL ; ; DI ; ; XRA A ;RESET ACC TO ZERO ; OUT P$CLK$PORTB ; ; EI ; ; IN P$KB$CONTROL ; ; BIT 1,A ; ; JRZ TIME$EE ; ; RET ;RETURN FROM SUBROUTINE PAGE ;*****************************************************; ; ; ; READ REAL TIME CLOCK ; ; ; ;*****************************************************; ; ;GET YEAR ; TIME$20: MVI A,0BH ;GET Y1 CALL GET$DATA ; JRC TIME$20 ;IF CHANGE TRY AGAIN MOV A,C ;MOVE TO A ADI 30H ;MASK FOR DISPLAY LXI H,407FH ;ADDRESS MOV M,A ;STORE MVI A,0CH ;GET Y10 CALL GET$DATA ; JRC TIME$20 ;IF CHANGED, DO AGAIN MOV A,C ; ADI 30H ;MASK FOR DISPLAY LXI H,407EH ;ADDRESS MOV M,A ;STORE ; ;GET MONTH ; MVI A,09H ;GET M1 CALL GET$DATA ; JRC TIME$20 ;IF CHANGE TRY AGAIN MOV A,C ;MOVE TO A ADI 30H ;MASK FOR DISPLAY LXI H,4079H ;ADDRESS MOV M,A ;STORE MVI A,0AH ;GET M10 CALL GET$DATA ; JRC TIME$20 ;IF CHANGE DO AGAIN MOV A,C ; ADI 30H ;MASK FOR DISPLAY LXI H,4078H ;NEW ADDRESS MOV M,A ;STORE ; ;GET DAY ; MVI A,07H ;GET D1 CALL GET$DATA ; JRC TIME$20 ;IF CHANGE TRY AGAIN MOV A,C ;MOV TO A ADI 30H ;MASK FOR DISPLAY LXI H,407CH ;ADDRESS MOV M,A ;STORE MVI A,08H ;GET D10 CALL GET$DATA ; JRC TIME$20 ;IF CHANGED TRY AGAIN MOV A,C ; ; ANI 03H ;MAKE SURE LEAP YEARS BITS LOW ADI 30H ;MASK FOR DISPLAY LXI H,407BH ;NEW ADDRESS MOV M,A ;STORE ; ;GET HOURS ; MVI A,04H ;GET H1 CALL GET$DATA ; JRC TIME$20 ;JUMP IF CHANGED MOV A,C ;SAVE IN A ANI 0FH ;MASK HIGH BITS ADI 30H ;MASK FOR DISPLAY LXI H,4089H ;ADDRESS MOV M,A ;STORE MVI A,05H ;GET H10 CALL GET$DATA ; JRC TIME$YY ;JUMP IF CHANGED MOV A,C ;GET H10 ANI 01H ;MASK HIGH BITS ADI 30H ;MASK FOR DISPLAY LXI H,4088H ;NEW ADDRESS MOV M,A ;STORE ; ;GET MINUTES ; MVI A,02H ;GET M1 CALL GET$DATA ;GET IT JRC TIME$YY ;BACK IF CHANGED MOV A,C ;SAVE IN A REG ANI 0FH ;MASK HIGH BITS ADI 30H ;MASK FOR DISPLAY LXI H,408CH ;ADDRESS MOV M,A ;STORE MVI A,03H ;GET M10 CALL GET$DATA ; JRC TIME$YY ;JUMP IF CHANGED MOV A,C ; ANI 07H ;MASK HIGH BITS ADI 30H ;MASK FOR DISPLAY LXI H,408BH ;NEW ADDRESS MOV M,A ;STORE ; ;GET SECONDS ; XRA A ;GET S1 CALL GET$DATA ;GET IT JRC TIME$YY ;JUMP IF CHANGED MOV A,C ;SAVE IN A ANI 0FH ;MASK HIGH BITS ADI 30H ;MASK FOR DISPLAY LXI H,408FH ;ADDRESS MOV M,A ;STORE MVI A,01H ;GET S10 CALL GET$DATA ; JC TIME$20 ;BACK IF CHANGED MOV A,C ; ANI 07H ;MASK HIGH BITS ADI 30H ;MASK FOR DISPLAY LXI H,408EH ;NEW ADDRESS MOV M,A ;STORE JMP TIME$AA ;GO DO CONVERSION TIME$YY: JMP TIME$20 ;BACK ; ;CONVERSION FOR MONTH ; TIME$XX: LXI H,5050H ;ADDRESS HIGH BYTE MOV A,M ;READ MONTH ANI 0FH ;CLEAR HIGH BITS RAL ;ROTATE LEFT RAL ; RAL ; RAL ; MOV B,A ;SAVE REG B INX H ;INCREMENT HL MOV A,M ;READ LOW BYTE ANI 0FH ;CLEAR HIGH BITS ORA B ;COMBINE LXI H,2051H ;NEW DESTINATION MOV M,A ;WRITE MONTH ; ;CONVERSION FOR DAY ; LXI H,5053H ;ADDRESS HIGH BYTE MOV A,M ;READ DAY ANI 0FH ;CLEAR HIGH BITS RAL ;ROTATE LEFT RAL ; RAL ; RAL ; MOV B,A ;SAVE IN REG B INX H ;INCREMENT HL MOV A,M ;READ LOW BYTE ANI 0FH ;CLEAR HIGH BITS ORA B ;COMBINE LXI H,2052H ;NEW DESTINATION MOV M,A ;WRITE DAY ; ;CONVERSION FOR YEAR ; LXI H,5056H ;ADDRESS HIGH BYTE MOV A,M ;READ YEAR ANI 0FH ;CLEAR HIGH BITS RAL ;ROTATE LEFT RAL ; RAL ; RAL ; MOV B,A ;SAVE REG B INX H ;INCREMENT HL MOV A,M ;READ LOW BYTE ANI 0FH ;CLEAR HIGH BITS ORA B ;COMBINE LXI H,2050H ;NEW DESTINATION MOV M,A ;WRITE YEAR ; ;CONVERSION FOR HOUR ; LXI H,5058H ;ADDRESS HIGH BYTE MOV A,M ;READ HOUR ANI 0FH ;CLEAR HIGH BITS RAL ;ROTATE LEFT RAL ; RAL ; RAL ; MOV B,A ;SAVE REG B INX H ;INCREMENT HL MOV A,M ;READ LOW BYTE ANI 0FH ;CLEAR HIGH BITS ORA B ;COMBINE LXI H,2053H ;NEW DESTINATION MOV M,A ;WRITE HOUR ; ;CONVERSION FOR MIN ; LXI H,505BH ;ADDRESS HIGH BYTE MOV A,M ;READ MIN ANI 0FH ;CLEAR HIGH BITS RAL ;ROTATE LEFT RAL ; RAL ; RAL ; MOV B,A ;SAVE REG B INX H ;INCREMENT HL MOV A,M ;READ LOW BYTE ANI 0FH ;CLEAR HIGH BITS ORA B ;COMBINE LXI H,2054H ;NEW DESTINATION MOV M,A ;WRITE MIN ; ;CONVERSION FOR SEC ; LXI H,505EH ;ADDRESS HIGH BYTE MOV A,M ;READ SEC ANI 0FH ;CLEAR HIGH BITS RAL ;ROTATE LEFT RAL ; RAL ; RAL ; MOV B,A ;SAVE REG B INX H ;INCREMENT HL MOV A,M ;READ LOW BYTE ANI 0FH ;CLEAR HIGH BITS ORA B ;COMBINE LXI H,2055H ;NEW DESTINATION MOV M,A ;WRITE SEC ; ;SET HOUR ; LDA HOUR ;GET HOUR ANI 0FH ;CLEAR HIGH BITS MOV C,A ;MOVE TO REG C MVI A,4 ;SEND H 1 CALL PUT$DATA ; LDA HOUR ;GET HOUR AGAIN RAR ;ROTATE INTO LOW BYTE RAR ; RAR ; RAR ; ANI 0FH ;CLEAR HIGH BITS ORI 08H ;SET 24 HOUR CLOCK MOV C,A ;MOVE TO REG C MVI A,5 ;SEND H10 CALL PUT$DATA ; ; ;SET MINUTES ; LDA MIN ;GET MINUTES ANI 0FH ;CLEAR HI BITS MOV C,A ;MOVE TO REG C MVI A,2 ;SEND M1 CALL PUT$DATA ; LDA MIN ;SEND MIN AGAIN RAR ;ROTATE INTO LOW BYTE RAR ; RAR ; RAR ; ANI 0FH ;CLEAR HI BITS MOV C,A ;MOVE TO REG C MVI A,3 ;SEND M10 CALL PUT$DATA ; ; ;SET SECONDS ; LDA SEC ;GET SECONDS ANI 0FH ;CLEAR HI BITS MOV C,A ;MOVE TO REG C MVI A,0 ;SEND S1 CALL PUT$DATA ; LDA SEC ;GET SEC AGAIN RAR ;ROTATE INTO LOW BYTE RAR ; RAR ; RAR ; ANI 0FH ;CLEAR HI BITS MOV C,A ;MOVE TO REG C MVI A,01H ;SEND S10 CALL PUT$DATA ; ; ;SEND YEAR ; LDA YEAR ;GET YEAR ANI 0FH ;CLEAR HI BITS MOV C,A ;MOVE TO REG C MVI A,11 ;SEND Y1 CALL PUT$DATA ; LDA YEAR ;GET YEAR AGAIN RAR ;ROTATE INTO LOW BYTE RAR ; RAR ; RAR ; ANI 0FH ;CLEAR HIGH BITS MOV C,A ;MOV TO REG C MVI A,12 ;SEND Y10 CALL PUT$DATA ; ; ;SEND MONTH ; LDA MONTH ;GET MONTH ANI 0FH ;CLEAR HIGH BITS MOV C,A ; MVI A,09 ;SEND M1 CALL PUT$DATA ; LDA MONTH ;GET MONTH AGAIN RAR ;ROTATE INTO LOW BYTE RAR ; RAR ; RAR ; ANI 0FH ;CLEAR HI BITS MOV C,A ; MVI A,10 ;SEND M10 CALL PUT$DATA ; ; ;SEND DAY ; LDA DAY ;GET DAY ANI 0FH ;CLEAR HI BITS MOV C,A ; MVI A,07 ; CALL PUT$DATA ; LDA DAY ;GET DAY AGAIN RAR ;ROTATE INTO LOW BYTE RAR ; RAR ; RAR ; ANI 03H ;CLEAR HIGH BITS AND LEAP YEAR BITS MOV C,A ; MVI A,08 ; CALL PUT$DATA ; RET ; ; ; PAGE ; ;WRITE DATA TO REAL TIME CLOCK CHIP ; ;ENTER WITH: A REG = CLOCK REGISTER TO ADDRESS ; C REG = DATA TO WRITE TO CHIP ; PUT$DATA: PUSH PSW ;SAVE ADDRESS FOR WRITE DI ;DISABLE INTERRUPTS MVI A,RTC$WRITE ;WRITING OUT P$CLK$CONTROL ;SET PORT OUT MVI A,RTC$SELECT ; SELECT CHIP OUT P$CLK$CONTROL ; POP PSW ;RESTOTE WRITE aADDRESS OUT P$CLK$PORTA ;SEND OUT ADDRESS MVI A,ADD$WRITE$HI ;SET UP ADDRESS WRITE OUT P$CLK$CONTROL ; MVI A,ADD$WRITE$LO ;CLEAR ADDRESS WRITE OUT P$CLK$CONTROL ; MVI A,WRITE$HI ;SET DATE WRITE HI OUT P$CLK$CONTROL ; ; IN P$CLK$PORTC ;GET STATUS ANI 08H ;BUSY ? JRZ $-5 ;LOOP TILL FREE ; MOV A,C ;GET DATA OUT P$CLK$PORTA ;WRITE DATA MVI A,WRITE$LO ; OUT P$CLK$CONTROL ; MVI A,RTC$READ ;LEAVE PORT AS IS OUT P$CLK$CONTROL ; ; MVI A,0EH ;DESELECT COMMAND OUT P$CLK$CONTROL ; ; MVI A,0EEH ;SET UP INTERRUPT MASK OUT P$CLK$PORTB ; MVI A,INT$INITIAL ;REINIT INT PORTS OUT INT$PORT ; EI ;ENABLE INTERRUPTS RET ; ; ; PAGE ; ;READ DATA FROM REAL TIME CLOCK CHIP ; ;ENTER WITH: A REG = CLOCK REGISTER TO ADDRESS ; C REG = DATA READ FROM CHIP ; (CARRY FLAG SET INDICATES ROLLOVER) ; GET$DATA: PUSH PSW ;SAVE READ ADDRESS MVI A,RTC$WRITE ;A=OUT;B=OUT;CLO=IN;CHI=OUT DI ;DISABLE EXTERNAL INTERRUPTS OUT P$CLK$CONTROL ;SET PORT TO OUT MVI A,RTC$SELECT ;DEVICE SELECT OUT P$CLK$CONTROL ; POP PSW ;RESTORE READ ADDRESS OUT P$CLK$PORTA ;SEND OUT ADDRESS MVI A,ADD$WRITE$HI ;SET UP ADDRESS WRITE OUT P$CLK$CONTROL ; MVI A,ADD$WRITE$LO ;CLEAR ADDRESS WRITE OUT P$CLK$CONTROL ; ; MVI A,0EH ;DESELECT COMMAND OUT P$CLK$CONTROL ; ; MVI A,RTC$READ ;READING OUT P$CLK$CONTROL ;SET PORT TO IN MVI A,RTC$SELECT ;CHIP SELECT OUT P$CLK$CONTROL ; MVI A,READ$HI ;SET DATA READ HIGH OUT P$CLK$CONTROL ; ; IN P$CLK$PORTC ;GET STATUS ANI 08H ;BUSY ? JRZ $-5 ;LOOP TILL FREE ; IN P$CLK$PORTA ;GET DATA ANI 0FH ;CLEAR HI BITS MOV C,A ;SAVE IN C-REG MVI A,READ$LO ;SET DATA READ LOW OUT P$CLK$CONTROL ; MVI A,READ$HI ;SET DATA READ HIGH OUT P$CLK$CONTROL ; ; IN P$CLK$PORTC ;GET STATUS ANI 08H ;BUSY ? JRZ $-5 ;LOOP TILL FREE ; IN P$CLK$PORTA ;GET DATA AGAIN ANI 0FH ;CLEAR HI BITS CMP C ;DATA SAME AS LAST ? JRZ GET$20 ;JUMP IF YES STC ;ELSE, SET CARRY GET$20: MVI A,READ$LO ;YES. SET DATA READ LOW OUT P$CLK$CONTROL ; ; MVI A,0EH ;DESELECT COMMAND OUT P$CLK$CONTROL ; ; MVI A,INT$INITIAL ;REINIT INT PORTS OUT INT$PORT ; EI ;REENABLE EXTERNAL INTERRUPTS RET ; ; ; PAGE ;######################################################################### ;# ####### #### ## ######### #### ######### # ;# ######### ###### ## ########## ###### ######### # ;# ## ## ## ## ## ## ## ## ### # ;# ## ## ## ## ## ## ## ## ### # ;# ## #### ######## ## ########## ######## ### # ;# ## ### ######## ## ######### ######## ### # ;# ######### ## ## ######### ## ## ## ### # ;# ####### ## ## ######### ## ## ## ### # ;######################################################################### ; ; Galloping pattern (GALPAT) & Fast (MKBTST) memory diagnostic for Visual 1050 ; ; By S.Sherman / D.Banks 23 JAN 84 ; 17 JAN 84 ; 07 DEC 83 ; 05 DEC 83 ; 28 NOV 83 ; ; Procedure GALPAT ; Set stack to 8000H ; Set page = 0 ; Set error numb =0 ; Set prompt to 'T' ; Set range = 0C000H to 0FFFFH ; Call Test procedure (GALPAT or MKBTST) ; ; Relocate GALPAT2 to top 16K ; ; Set stack to 0000H ; Set page = 0 ; Set prompt to '0' ; Set error numb =1 ; Set range = 0000 to 0BFFFH ; Call Test procedure (GALPAT or MKBTST) ; Set page = 1 ; Set prompt to '1' ; Set error num =2 ; Set range = 0000 to 0BFFFH ; Call Test procedure (GALPAT or MKBTST) ; Set page = 2 ; Set prompt to '2' ; Set error num =3 ; Set range = 0000 to 3FFFH ; Call Test procedure (GALPAT or MKBTST) ; End Procedure GALPAT ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; INCRMT EQU 0080H ;GALPAT INCREMENT ;PROVIDES TEST TIME OF 14.5 MIN. ; REF1: GALPAT: DI ;DISABLE INTERRUPTS ; POP D ;GET RETURN ADDRESS FROM STACK POP B ;GET LAST KEYCODE FROM STACK LXI SP,8000H ;SET TEMP STACK PUSH B ;PLACE LAST KEYCODE BACK ON STACK PUSH D ;PLACE RETURN ADDRESS ON STACK ; XRA A ;MASK FOR BANK SELECT OUT P$BANK$SELECT ;SELECT BANK 0 ; PUSHIX ;PUT IX FLAG ON STACK POP PSW ;...AND COPY TO AF ORA A ;SET CONDITION FLAGS LXI H,LOGMSG ;POINT TO LOG MESSAGE JRZ SKIP2 ;IF GALPAT TEST, SKIP OVER LXI H,MKBMSG ;OTHERWISE, POINT TO 'FAST' MESSAGE SKIP2: CALL MESDPLY ;DISPLAY LOG MESSAGE ; CALL TIME$20 ;LOG CURRENT TIME ; MVI C,0 ;SET RELOCATION FLAG TO 0 ; LXI H,0C000H ;START OF UPPER 16K RAM LXI D,0FFFFH+1 ;END+1 OF UPPER 16K RAM MVI B,0 ;SET ERROR NUMB = 0 CALL CHKTST ;PERFORM GALPAT OR MKBTST ; ; Relocate GALPAT code to top 16K of RAM ; LXI H,REF1 ;POINT TO START OF RELOC CODE LXI D,REF1+0C000H ;POINT TO DEST OF RELOC CODE LXI B,LOGMSG-REF1 ;LENGTH OF RELOC CODE LDIR ;RELOCATE GALPAT CODE MVI C,0FFH ;SET RELOCATION FLAG TO FF MVI A,76H ;HALT CODE STA DPLYEXIT+OFFSET ;CHANGE DISPLAY EXIT ; JMP GALPAT2+0C000H ;JUMP TO RELOCATED CODE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; THE FOLLOWING CODE GETS RELOCATED INTO RAM BEFORE EXECUTION ; OFFSET EQU 0C000H ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GALPAT2: POP D ;GET RETURN ADDRESS FROM STACK POP H ;GET LAST KEYCODE FROM STACK LXI SP,STACK ;SET STACK TO TOP OF RAM PUSH H ;PLACE LAST KEYCODE BACK ON STACK PUSH D ;PLACE RETURN ADDRESS BACK ON STACK ; MVI A,01H ;MASK FOR PAGE 0, ROM OFF OUT P$BANK$SELECT ;SELECT BANK 0 MVI A,'0' ;PROMPT CHARACTER STA CHAR+OFFSET ;PROMPT STORE LOCATION LXI H,0 ;START OF RANGE LXI D,0BFFFH+1 ;END+1 OF RANGE MVI B,1 ;SET ERROR NUMB = 1 CALL CHKTST+OFFSET ;PERFORM GALPAT OR MKBTST ; MVI A,03H ;MASK FOR PAGE 1 OUT P$BANK$SELECT ;SELECT BANK 1 MVI A,'1' ;PROMPT CHARACTER STA CHAR+OFFSET ;PROMPT STORE LOCATION LXI H,0 ;START OF RANGE LXI D,0BFFFH+1 ;END+1 OF RANGE MVI B,2 ;SET ERROR NUMB = 2 CALL CHKTST+OFFSET ;PERFORM GALPAT OR MKBTST ; MVI A,05H ;MASK FOR PAGE 2 OUT P$BANK$SELECT ;SELECT BANK 2 MVI A,'2' ;PROMPT CHARACTER STA CHAR+OFFSET ;PROMPT STORE LOCATION LXI H,0 ;START OF RANGE LXI D,3FFFH+1 ;END+1 OF RANGE MVI B,3 ;SET ERROR NUMB = 3 CALL CHKTST+OFFSET ;PERFORM GALPAT OR MKBTST ; EXITG: MVI A,0 ;RESET ACC TO ZERO OUT P$BANK$SELECT ;SELECT BANK 0 AND PROM RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Procedure Test ; Do until pointer = end of range ; Fill range with 00H ; Set Test location to 0FFH ; Check rest of range for 00H ; If rest not 00H ; Then ; Display error message + error numb ; HALT ; Fill range with FFH ; Set Test location to 00H ; Check rest of range for FFH ; If rest not FFH ; Then ; Display error message + error numb ; HALT ; Point to next test byte ; End ; End procedure Test ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CHKTST: PUSHIX ;SAVE IX REGISTER ON STACK POP PSW ;...AND XFER TO AF ORA A ;SET CONDITION FLAGS JRNZ MKBTST ;FAST MEMORY TEST GTEST: PUSH H ;SAVE ADDRESS FOR GTEST2 PUSH H ;SAVE STARTING ADDRESS GTEST0: ; ; BACKGROUND OF FF / TEST WITH 00 ; MVI M,0FFH ;FILL RAM LOCATIONS INX H ;POINT TO NEXT LOCATION MOV A,D ;END OF RANGE / HIGH BYTE CMP H ;AT END? JRNZ GTEST0 ;CONTINUE TILL DONE ; POP H ;RESTORE STARTING ADDRESS MVI M,0 ;SET TEST LOCATION TO 00 MOV A,M ;READ BYTE BACK CPI 00 ;STILL THERE? JRNZ BADCHIP1 ;ERROR IF NOT INX H ;NEXT LOCATION TO CHECK ; GTEST1: MVI A,0FFH ;DATA TO CHECK FOR CMP M ;HAS DATA CHANGED? JRNZ GALERROR ;JUMP IF ERROR INX H ;NEXT LOCATION TO CHECK MOV A,D ;GET END+1 OF RANGE / HIGH BYTE CMP H ;AT END? JRNZ GTEST1 ;CONTINUE TILL DONE ; POP H ;RESTORE ORIGINAL ADDRESS PUSH H ;SAVE IT AGAIN PUSH H ;SAVE STARTING ADDRESS GTEST2: ; ; BACKGROUND OF 00 / TEST WITH FF ; MVI M,00 ;FILL RAM LOCATION WITH 00 INX H ;POINT TO NEXT LOCATION MOV A,D ;END OF RANGE / HIGH BYTE CMP H ;AT END? JRNZ GTEST2 ;CONTINUE TILL DONE POP H ;RESTORE STARTING ADDRESS ; MVI M,0FFH ;SET TEST LOCATION TO FF MOV A,M ;READ BYTE BACK CPI 0FFH ;STILL THERE? JRNZ BADCHIP ;ERROR IF NOT INX H ;NEXT LOCATION TO CHECK ; GTEST3: MVI A,00 ;DATA TO CHECK FOR CMP M ;HAS DATA CHANGED? JRNZ GALERROR ;JUMP IF ERROR INX H ;NEXT LOCATION TO CHECK MOV A,D ;GET END+1 OF RANGE / HIGH BYTE CMP H ;AT END? JRNZ GTEST3 ;CONTINUE TILL DONE ; POP H ;RESTORE ORIGINAL ADDRESS PUSH B ;SAVE ERROR NUMBER PROMPT: IN P$DISP$C ;GET DISPLAY STATUS RRC ;GET BUSY BIT JRNC PROMPT ;LOOP IF BUSY MOV A,C ;GET RELOCATION FLAG ORA A ;CHECK FOR ZERO JRZ NOTREL ;JUMP,CODE NOT RELOCATED LDA CHAR+OFFSET ;GET PROMPT CHARACTER JR PROMPT1 ;GO DISPLAY PROMPT NOTREL: LDA CHAR ;GET PROMPT CHARACTER PROMPT1: OUT P$DISP$OUT ;SEND TO DISPLAY MVI A,0EH ;DISPLAY STROBE LOW OUT P$DISP$CONTROL ;SET STROBE LOW INR A ;DISPLAY STROBE HIGH OUT P$DISP$CONTROL ;SET STROBE HIGH ; DI ;DISABLE EXTERNAL INTERRUPTS XRA A ;ZERO OUT ACC OUT P$CLK$PORTB ;...OUTPUT TO INTERRUPT MASK PORT EI ;RE ENABLE EXTERNAL INTERRUPTS IN P$KB$CONTROL ;GET KEYBOARD STATUS BIT 1,A ;TEST BIT... JRZ CONTIN ;NO KEY...CONTINUE ; IN P$KB$DATA ;GET KEYSTROKE CPI 1BH ;IS IT AN ESCAPE KEY ? JRNZ CONTIN ;NO, SO CONTINUE ; LXI SP,STACK ;YES, SET UP NEW STACK... ; MVI A,0 ;RESET ACC TO ZERO OUT P$BANK$SELECT ;... SELECT BANK 0 AND PROM ; JMP DOMANUAL ;START OVER, YOU'RE LOST . . . ; CONTIN: LXI B,INCRMT ;GET TEST INCREMENT DAD B ;INCREMENT TEST POINTER POP B ;RESTORE ERROR NUMBER ; MOV A,H ;GET CURRENT TEST POINTER CMP D ;AT END OF RANGE+1 ? JRNZ GTEST ;DO UNTIL COMPLETE ; RET ; ; PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MKBTST: ;Fast Memory Test PUSH H ;SAVE START ADDRESS RTLP10: MOV A,L ;START TO CALCULATE PATTERN XRA H ;.. XRI 0FFH ;PATTERN MODIFIER MOV M,A ;STORE PATTERN IN RAM ; INR L ;POINT TO NEXT ADDRESS JRNZ RTLP10 ;CONTINUE FOR 256 BYTES ; INR H ;POINT TO NEXT PAGE OF MEMORY MOV A,H ;XFER PAGE NUMBER TO ACC CMP D ;DONE WITH RANGE ? JRNZ RTLP10 ;NO, SO CONTINUE ; POP H ;RESTORE RANGE START ADDRESS PUSH H ;SAVE ADDRESS AGAIN RTLP20: MOV A,L ;START TO CALCULATE PATTERN XRA H ;.. XRI 0FFH ;PATTERN MODIFIER XRA M ;CHECK TO SEE IF STORED CORRECTLY JRNZ JTERR ;ERROR, SO REPORT IT ; INR L ;POINT TO NEXT ADDRESS JRNZ RTLP20 ;CONTINUE FOR 256 BYTES ; INR H ;POINT TO NEXT PAGE OF MEMORY MOV A,H ;XFER PAGE NUMBER TO ACC CMP D ;DONE WITH RANGE ? JRNZ RTLP20 ;NO, SO CONTINUE ; POP H ;RESTORE RANGE START ADDRESS PUSH H ;SAVE ADDRESS AGAIN RTLP30: MOV A,L ;START TO CALCULATE PATTERN XRA H ;.. MOV M,A ;STORE IN RAM ; INR L ;POINT TO NEXT ADDRESS JRNZ RTLP30 ;CONTINUE FOR 256 BYTES ; INR H ;POINT TO NEXT PAGE OF MEMORY MOV A,H ;XFER PAGE NUMBER TO ACC CMP D ;DONE WITN RANGE ? JRNZ RTLP30 ;NO, SO CONTINUE ; POP H ;RESTORE RANGE START ADDRESS PUSH H ;SAVE ADDRESS AGAIN RTLP40: MOV A,L ;START TO CALCULATE PATTERN XRA H ;.. XRA M ;CHECK TO SEE IF STORED CORRECTLY JRNZ JTERR ;ERROR, SO REPORT IT ; INR L ;POINT TO NEXT ADDRESS JRNZ RTLP40 ;CONTINUE FOR 256 BYTES ; INR H ;POINT TO NEXT PAGE OF MEMORY MOV A,H ;XFER PAGE NUMBER TO ACC CMP D ;DONE WITH RANGE ? JRNZ RTLP40 ;NO, SO CONTINUE ; POP H ;ADJUST STACK... ; RET ;... & RETURN FROM SUBROUTINE ; ; JTERR: POP H ;ADJUST STACK JR BADCHIP1 ;...AND REPORT ERROR ; ; PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BADCHIP: CMA ;COMPLEMENT DATA RECEIVED BADCHIP1: PUSH B ;PUT RELOC FLAG ON STACK ANI 0FFH ;ISOLATE ERROR BIT MVI C,0FFH ;INITIALIZE BIT COUNTER BC1: RRC ;ROTATE BIT INTO CARRY INR C ;COUNT ONE BIT JRNC BC1 ;LOOP UNTIL BIT FOUND ; MOV A,B ;GET TEST NUMBER ANI 0FEH ;MASK OFF TESTS 0 & 1 JRZ BC2 ;JUMP IF TEST 0 OR 1 MVI A,08H ;MESSAGE OFFSET FOR TEST 2 & 3 ADD C ;ADD BIT OFFSET JR COMN ;CONTINUE AT COMMON CODE BC2: MOV A,C ;GET BIT OFFSET COMN: ADI 04H ;CHIP TABLE OFFSET POP B ;RESTORE RELOC FLAG MOV B,A ;SAVE MESSAGE OFFSET JR GALERROR ;REPORT ERROR ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ERROR NUMBER PAGE/RANGE ; ; 0 PAGE 0 / RANGE C000 TO FFFF ; 1 PAGE 0 / RANGE 0000 TO BFFF ; 2 PAGE 1 / RANGE 0000 TO BFFF ; 3 PAGE 2 / RANGE 0000 TO 3FFF ; GALERROR: LXI H,JGALER0 ;POINT TO JUMP TABLE ERRREPORT: LXI D,0 ;INITIAL OFFSET OF ZERO MOV A,C ;GET RELOCATION FLAG ORA A ;SET FLAGS JRZ SKIP ;IF ERROR 0 THEN NOT RELOCATED LXI D,OFFSET ;RELOCATED,GET OFFSET SKIP: DAD D ;ADD IN RELOCATE OFFSET MVI D,0 ;CLEAR TEMP STORAGE MOV E,B ;GET ERROR NUMBER DAD D ;MODIFY POINTER WITH ERROR NUMBER DAD D ;ADJUST FOR TWO BYTES MOV E,M ;GET LOWBYTE OF ERROR MESSAGE ADDR INX H ;POINT TO HIGH BYTE MOV D,M ;GET HIGHBYTE OF ERROR MESSAGE ADDR XCHG ;MOV ADDRESS TO HL LXI D,0 ;INITIAL OFFSET OF ZERO MOV A,C ;GET RELOCATION FLAG ORA A ;SET FLAGS JRZ SKIP1 ;IF ERROR 0 THEN NOT RELOCATED LXI D,OFFSET ;RELOCATED,GET OFFSET SKIP1: DAD D ;ADD IN RELOCATE OFFSET JR MESDPLY ;DISPLAY MESSAGE HLT ;STOP EVERYTHING ; JGALER0: DW GALERR0,GALERR1,GALERR2,GALERR3 DW CHIP00,CHIP01,CHIP02,CHIP03 DW CHIP04,CHIP05,CHIP06,CHIP07 DW CHIP10,CHIP11,CHIP12,CHIP13 DW CHIP14,CHIP15,CHIP16,CHIP17 ; ; > > > MESSAGE DISPLAY SUBROUTINE < < < ; MESDPLY: IN P$DISP$C ;GET PIO STATUS RRC ;TEST READY JRNC MESDPLY ;NOT READY, CHECK AGAIN MOV A,M ;GET CHARATER CPI '$' ;TEST TERMINATION JRZ DPLYEXIT ;MESSAGE DONE -- RETURN OUT P$DISP$OUT ;PUT IN DATA MVI A,0EH ;STROBE OUT P$DISP$CONTROL ; INR A ;STROBE OFF OUT P$DISP$CONTROL ; INX H ;BUMP ADDRESS POINTER JR MESDPLY ;GO CHECK NEXT CHARACTER DPLYEXIT: RET ;RETURN TO CALLER ; GALERR0: DB ESC,'[5;7m' DB 'Ram Error Page 0 / Range C000 to FFFF',CR,LF,'$' GALERR1: DB ESC,'[5;7m' DB 'Ram Error Page 0 / Range 0000 to BFFF',CR,LF,'$' GALERR2: DB ESC,'[5;7m' DB 'Ram Error Page 1 / Range 0000 to BFFF',CR,LF,'$' GALERR3: DB ESC,'[5;7m' DB 'Ram Error Page 2 / Range 0000 to 3FFF',CR,LF,'$' CHIP00: DB 'Ram Error U105','$' CHIP01: DB 'Ram Error U104','$' CHIP02: DB 'Ram Error U103','$' CHIP03: DB 'Ram Error U110','$' CHIP04: DB 'Ram Error U109','$' CHIP05: DB 'Ram Error U108','$' CHIP06: DB 'Ram Error U107','$' CHIP07: DB 'Ram Error U106','$' CHIP10: DB 'Ram Error U128','$' CHIP11: DB 'Ram Error U127','$' CHIP12: DB 'Ram Error U126','$' CHIP13: DB 'Ram Error U133','$' CHIP14: DB 'Ram Error U132','$' CHIP15: DB 'Ram Error U131','$' CHIP16: DB 'Ram Error U130','$' CHIP17: DB 'Ram Error U129','$' LOGMSG: DB ESC,'c',00H ;RESET SCREEN DB ESC,'[7m' ;REVERSE VIDEO DB 'Galpat Memory Diagnostic' DB ESC,'[m',CR,LF,'$' ; MKBMSG: DB ESC,'c',0 ;RESET SCREEN DB ESC,'[7m' ;REVERSE VIDEO DB 'Fast Memory Diagnostic' DB ESC,'[m',CR,LF,'$' ; CHAR DB 'T' ;PROMPT CHARACTER TO BE DISPLAYED RELOC DB 0 ;RELOCATION FLAG 0=NOT RELOCATED ; 1=RELOCATED PAGE ; ; FLOP: LXI H,WRNMES ;PRINT WARNING MESSAGE JMP FLOP1 ;GO TO FLOPPY TEST FLPTST: DB FF,ESC,'[7m' DB CR,LF,'FLOPPY DISK TEST IN PROGRESS',ESC,'[m','$' WRNMES: DB FF,LF,LF,ESC,'[7m' DB ' **** WARNING **** ' DB CR,LF,'DATA WILL BE DESTROYED' DB ESC,'[m' DB CR,LF,LF,'INSERT FORMATTED' DB ' DISKETTES INTO DRIVES.' DB CR,LF,LF,'PRESS RETURN WHEN READY.','$' DELYERR: DB CR,LF,ESC,'[7m' DB 'SELECTED DRIVE NOT READY',ESC,'[m','$' ; ; > > > WAIT 1 MILLISECOND < < < ; DEL1MS: PUSH PSW ;SAVE ACC AND STATUS FLAGS PUSH B ;SAVE BC REGISTERS LXI B,0098H ;LOAD BC WITH PARAMETER FOR 1 MSEC DELAY: DCX B ;DECREMENT COUNTER MOV A,B ;GET UPPER BYTE OF COUNTER ORA C ;COMBINE WITH LOWER BYTE JRNZ DELAY ;IF NOT DONE, DO SOME MORE POP B ;RESTORE SAVED BC REGISTERS POP PSW ;RESTORE SAVED ACC AND STATUS RET ;RETURN FROM SUBROUTINE ; ; PAGE ;**********************************************************; ; ; ; FLOPPY DISK TEST ; ; ; ;**********************************************************; FLOP1: CALL MESDPLY ;DISPLAY MESSAGE ; FLOP2: DI ;DISABLE INTERRUPTS XRA A ;ZERO ACC OUT P$CLK$PORTB ;MASK INTERRUPTS EI ;ENABLE INTERRUPTS IN P$KB$CONTROL ;READ KEYBOARD PORT CONTROL BIT 1,A ;CHECK BIT 1 OF ACC JRZ FLOP2 ;NO CHARACTER SO GO LOOK AGAIN IN P$KB$DATA ;READ KEYBOARD DATA PORT CPI 0DH ;IS IT A CARRIAGE RETURN ? JRNZ FLOP2 ;NO, SO GO LOOK AGAIN ; ; LXI H,FLPTST ;POINT TO IN PROGRSS MESSAGE CALL MESDPLY ;DISPLAY MESSAGE ; ; MVI A,0EH ;MOTORS ON, SELECT DRIVE 0 OUT P$DISK$BITS ;DO IT MVI A,18H ;DO DUMMY SEEK TO ACT HLD CALL FDOIT1 ;HLD STARTS MOTORS ; ; > > > WAIT 850 MILLISECONDS < < < ; PUSH PSW ;SAVE ACC AND STATUS PUSH B ;SAVE BC REGISTERS LXI B,0349H ;PARAMATER FOR 850 MILLISECONDS DEL850: CALL DEL1MS ;WAIT 1 MILLISECOND DCX B ;DECREMENT COUNT MOV A,B ;GET UPPER COUNTER BYTE ORA C ;COMBINE WITH LOWER COUNT BYTE JRNZ DEL850 ;IF NOT DONE, DO SOME MORE POP B ;RESTORE SAVDE BC REGISTERS POP PSW ;RESTORE SAVED ACC AND STATUS ; ; > > > CHECK TO SEE IF READY < < < ; IN P$DISK$CONTROL ;READ READY BIT ANI 80H ;ISOLATE READY BIT JRZ FLOPCONT ;IF READY, CONTINUE WITH TEST LXI H,DELYERR ;OTHERWISE, POINT TO ERROR MESSAGE CALL MESDPLY ;DISPLAY MESSAGE ; ; FLOPCONT: CALL FHOME ;RECAL DISK FIRST LXI H,8200H ;START ADDRESS FLOP6: MVI A,6DH ;DATA MOV M,A ;WRITE MEM INX H ;INCREMENT POINTER MVI A,0B8H ;DATA MOV M,A ;WRITE MEM INX H ;INCREMENT POINTER MOV A,H ;READ ADDRESS CPI 84H ;TEST FOR MAX ADDRESS JRNZ FLOP6 ;BACK TILL DONE XRA A ;USE DRIVE 0 STA FDRV ; LXI H,0 ;TRACK 0 SHLD FTRK ; STA FHED ;SIDE 0 INR A ; STA FSEC ;SET SECTOR =1 LXI H,8200H ;SET DMA POINTER SHLD FDMAA ; MVI A,01H ;SET WRITE SECTOR FLAG STA FRWF ; XRA A ;SET 5" DBL DENSITY STA FPT+0 ; MVI A,0FFH ;SET PRECOMP TRK 255 STA FPT+1 ; MVI A,01H ;SET STEP RATE STA FPT+2 ; CALL FLOPPE ; JMP FLOP7 ;NEXT TEST FDOIT1: OUT P$DISK$CONTROL ;COMMAND MVI A,18 ; FLOPB: DCR A ; JNZ FLOPB ;63 USEC LXI D,60000+1 ; FLOPC: IN P$DISK$CONTROL ;READ STATUS RRC ;TEST COMPLETE JNC FLOPD ;BR IF DONE INX D ;WASTE TIME DCX D ; INX D ; DCX D ; DCX D ;TEST FOR TIMEOUT MOV A,D ;TIME OUT IF D=0 ORA E ; JRNZ FLOPC ;1.2 SEC MVI A,0D0H ; OUT P$DISK$CONTROL ;RESET FDC MVI A,0FFH ;RETURN CODE FOR TIMEOUT RET ; FLOPD: IN P$DISK$CONTROL ;READ STATUS RET ; FLOPPE: MVI A,0D0H ;END CURRENT COMMAND OUT P$DISK$CONTROL ; LXI H,FIRQ ; SHLD IVECT+2 ;CLEAR DESELECT INTERRUPT XCHG ;DE IS ADDRESS SOURCE ; MVI A,03H ; OUT P$8255$CONTROL ;FDC INTERRUPT ENABLE ; LDA FPT+0 ; ANI 0C0H ;DD/SD AND 5"/8" BITS MOV B,A ;IN B LDA FDRV ; INR A ;0123->1234 CPI 3 ; JM FSEL$0A ;12 DONE ANI 06H ;34->24 ADD A ;24->48 DONE FSEL$0A: XRI 0FH ;DECODED DRIVE SELECT ORA B ; MOV B,A ;INTO B LDA FHED ; ORA A ; JZ FSEL$1A ;IF HEAD 1 THEN MVI A,10H ; ORA B ; MOV B,A ;SET HEAD 1 BIT IN B FSEL$1A: LDA FTRK ; LXI H,FPT+1 ; CMP M ; JC FSEL$2A ;IF TRACK>=WPRECOMP MVI A,20H ; ORA B ; MOV B,A ;SET PRECOMP BIT FSEL$2A: MOV A,B ; OUT P$DISK$BITS ;MODES,DRIVE,HEAD SELECTED IN P$DISK$CONTROL ;IF MOTORS ON RLC ;READY LINE TELLS JNC FM$99A ;BR IF MOTOR IS ON IN P$DISK$TRACK ;THEN TURN MOTOR ON OUT P$DISK$DATA ; MVI A,18H ;DO DUMMY SEEK TO ACT HLD CALL FDOIT1 ;HLD STARTS MOTORS LXI H,560 ;WAIT 500 MS FM$00A: XRA A ; FM$01A: DCR A ; JNZ FM$01A ;896 US DCX H ; MOV A,L ; ORA H ; JNZ FM$00A ;560*896US=502MS FM$99A: LDA FTRK ;TRACK TO REG C OUT P$DISK$TRACK ;P$DISK$TRACK:=FTRKA[DRV] MVI A,29 ;THEN WAIT 1 MS FT$X0A: DCR A ; JNZ FT$X0A ;104 US FT$X1A: DCR A ; JNZ FT$X1A ;+896 US=1 MS DELAY ; LDA FTRK ;GET TRACK CALL FSEEK ;SEEK CORRECT TRACK ; LDA FSEC ;SELECT SECTOR OUT P$DISK$SECTOR ; ; LXI H,FWF ;RESET LAST WRITE FLAG MVI M,0 ; LDA FRWF ;GET OPERATIONS FLAG MOV C,A ;TO REG C LDA FHED ;GET HEAD ANI 1 ;MASK RLC ;SHIFT RLC ; RLC ; DCR C ;SET UP HEAD BIT INR C ;TEST OPERATION JZ FREAD$1 ;0=FREAD DCR C ; JZ FWRITE$1 ;1=WRITE DCR C ; JZ FCHECK$1 ;2=CHECK SECTOR DCR C ; JZ FFORMAT$1 ;3=FORMAT TRACK XRA A ;RETURN CODE 0 FOR SEEK JMP FDONE1 ;NO DATA TRANSFER FREAD$1: ORI 82H ; LXI H,0A2EDH ;IN I JMP FOPER1 ;GO READ FWRITE$1: ORI 0A2H ; JMP FW2 ;GO WRITE FFORMAT$1: MVI A,0F0H ;GO WRITE TRACK JMP FW2 ;GO WRITE FW2: MVI M,0FFH ;SET LAST OPERATION FLAG LXI H,0A3EDH ;OUT I JMP FOPER1 ; FCHECK$1: ORI 0C2H ; LXI H,040EDH ;IN B,C JMP FOPER1 ; FOPER1: SHLD 0D002H ; EXAF ;GO TO ALT BANK EXX ; PUSH H ;SAVE HL PUSH B ;SAVE BC PUSH PSW ;SAVE A AND FLAGS LHLD FDMAA ;HL TO DMA ADDRESS MVI C,P$DISK$DATA ;DATA REG ADDRESS EXAF ;BACK TO NORMAL BANK EXX ; CALL FDOIT1 ;DO THE OPERATION EXAF ;GO TO ALT BANK EXX ; POP PSW ;RESTORE A,F POP B ;BC POP H ;HL EXAF ;BACK TO NORMAL BANK EXX ; MOV C,A ;RETURN CODE TO REG C ORA A ;TEST OK JZ FDONE1 ; INR A ;TEST FOR FF ERROR CODE MVI A,5 ;ASSUME ERROR CODE 5 LXI H,DSK$OVR ;OVERRUN UNDERRUN ERROR JZ DSK$ERR ;EXIT CODE 5 IF TIMED OUT BIT 6,C ;TEST WRITE PROTECT MVI A,4 ;RETURN CODE FOR WRITE PROTECT LXI H,DSK$WP ;POINT TO WRITE PROTECT ERROR JNZ DSK$ERR ;WRITE PROTECT VIOLATION BIT 2,C ;TEST LOST DATA MVI A,7 ;SET RETURN CODE FOR LOST DATA LXI H,DSK$LD ;POINT TO LOST DATA ERROR JRNZ DSK$ERR ;TEMP CODE 7 BIT 4,C ;TEST NOT FOUND MVI A,2 ;RETURN CODE FOR NOT FOUND LXI H,DSK$ID ;POINT TO ID NOT FOUND ERROR JRNZ DSK$ERR ;TEMP CODE 2 LXI H,DSK$CRC ;POINT TO CRC ERROR MVI A,1 ;CODE 1 FOR CRC ERROR DSK$ERR: JMP FMTER0 ;GO REPORT ERROR DSK$ERR1: LXI H,DSK$DTA ;GO REPORT DATA ERROR JMP FMTER0 ; FDONE1: IN P$DISK$TRACK ; OUT P$DISK$DATA ; MVI A,10H ;SEEK CODE CALL FDOIT1 ;DUMMY SEEK LXI D,NMI ; LXI H,NMIBUF ; LXI B,8 ; LDIR ;RESTORE NMI LOCS LXI H,FTIRQ ;SET UP DESELT INTERRUPT SHLD IVECT+2 ; MVI A,0D2H ;IPT ON READY FALL OUT P$DISK$CONTROL ; RET ; FLOP7: XRA A ;DRIVE 0 STA FDRV ; LXI H,0 ;TRACK 0 SHLD FTRK ; STA FHED ;SIDE 0 INR A ; STA FSEC ;SECTOR 1 LXI H,8500H ;DMA POINTER SHLD FDMAA ; XRA A ;READ FLAG STA FRWF ; STA FPT+0 ; MVI A,0FFH ;PRECOMP STA FPT+1 ; MVI A,01H ;STEP RATE STA FPT+2 ; CALL FLOPPE ;GO READ LXI H,8500H ; MOV A,M ; CPI 6DH ;TEST DATA JRNZ DSK$ERR1 ;DATA ERROR INX H ;INCREMENT POINTER MOV A,M ; CPI 0B8H ;TEST DATA JRNZ DSK$ERR1 ; ; LXI H,8200H ;RAM START ADDRESS FLOP8A: MVI A,68H ;DATA MOV M,A ; INX H ;INCREMENT POINTER MVI A,6DH ;DATA MOV M,A ; INX H ;INCREMENT POINTER MOV A,H ; CPI 84H ;MAX ADDRESS JRNZ FLOP8A ;BACK TILL DONE ; XRA A ;DRIVE 0 STA FDRV ; LXI H,0040H ;TRACK XX SHLD FTRK ; XRA A ;SIDE 0 STA FHED ; INR A ; STA FSEC ;SECTOR 1 LXI H,8200H ;SET DMA POINTER SHLD FDMAA ; MVI A,01H ;SET WRITE DATA FLAG STA FRWF ; XRA A ;SET 5" DBL DENSITY STA FPT+0 ; MVI A,43 ;SET PRECOMP TRK 43 STA FPT+1 ; MVI A,01H ;SET STEP RATE STA FPT+2 ; MVI A,40H ;SET TRK CALL FSEEK ;SEEK TO TRK XX CALL FLOPPE ; ; XRA A ;DRIVE 0 STA FDRV ; LXI H,0040H ;TRACK XX SHLD FTRK ; XRA A ;SIDE 0 STA FHED ; INR A ; STA FSEC ;SECTOR 1 LXI H,8500H ;DMA POINTER SHLD FDMAA ; XRA A ;READ FLAG STA FRWF ; STA FPT+0 ;SET 5" DBL DENSITY MVI A,43H ;SET PRECOMP TRK 43 STA FPT+1 ; MVI A,01H ;SET STEP RATE STA FPT+2 ; CALL FLOPPE ; LXI H,8500H ;SET DMA POINTER MOV A,M ;READ DATA CPI 68H ;COMPARE JRNZ DSK$ERR2 ;BAD DATA INX H ;INCREMENT POINTER MOV A,M ;READ DATA CPI 6DH ;COMPARE JRNZ DSK$ERR2 ;BAD DATA CALL FHOME ;RECAL DISK JMP FLOPAX ;NEXT TEST DSK$ERR2: LXI H,DSK$DTA ;GO REPORT DATA ERROR JMP FMTER0 ; ; FLOPAX: LXI H,8200H ;START ADDRESS FLOPBX: MVI A,6DH ;DATA MOV M,A ;WRITE MEM INX H ;INCREMENT POINTER MVI A,0B8H ;DATA MOV M,A ;WRITE MEM INX H ;INCREMENT POINTER MOV A,H ; CPI 84H ;TEST FOR MAX ADDRESS JRNZ FLOPBX ;BACK TILL DONE MVI A,01H ;USE DRIVE 01 STA FDRV ; LXI H,0 ;TRACK 0 SHLD FTRK ; XRA A ; STA FHED ;SIDE 0 INR A ; STA FSEC ;SET SECTOR =1 LXI H,8200H ;SET DMA POINTER SHLD FDMAA ; MVI A,01H ;SET WRITE SECTOR FLAG STA FRWF ; XRA A ;SET 5" DBL DENSITY STA FPT+0 ; MVI A,0FFH ;SET PRECOMP TRK 255 STA FPT+1 ; MVI A,01H ;SET STEP RATE STA FPT+2 ; ; MVI A,0DH ;SELECT DRIVE 1 (B:) OUT P$DISK$BITS ;DO IT ; CALL FHOME ;RECAL DRIVE ; CALL FLOPPE ; ; MVI A,01H ;DRIVE 1 STA FDRV ; LXI H,0 ;TRACK 0 SHLD FTRK ; XRA A ; STA FHED ;SIDE 0 INR A ; STA FSEC ;SECTOR 1 LXI H,8500H ;DMA POINTER SHLD FDMAA ; XRA A ;READ FLAG STA FRWF ; STA FPT+0 ; MVI A,0FFH ;PRECOMP STA FPT+1 ; MVI A,01H ;STEP RATE STA FPT+2 ; CALL FLOPPE ;GO READ LXI H,8500H ; MOV A,M ; CPI 6DH ;COMPARE DATA JRNZ DSK$ERR3 ;GO REPORT ERROR INX H ; MOV A,M ; CPI 0B8H ;COMPARE DATA JRNZ DSK$ERR3 ;GO REPORT ERROR JMP FLOPDX ;NEXT TEST DSK$ERR3: LXI H,DSK$DTA ;POINTER FOR DATA ERROR JMP FMTER0 ;GO REPORT ERROR FLOPDX: LXI H,8200H ;RAM START ADDRESS FLOPEX: MVI A,0B8H ;DATA MOV M,A ; INX H ;INCREMENT POINTER MVI A,6DH ; MOV M,A ; INX H ; MOV A,H ; CPI 84H ;MAX ADDRESS JRNZ FLOPEX ;BACK TILL DONE ; MVI A,01H ;DRIVE 1 STA FDRV ; LXI H,0040H ;TRACK XX SHLD FTRK ; XRA A ;SIDE 0 STA FHED ; INR A ; STA FSEC ;SECTOR 1 LXI H,8200H ;SET DMA POINTER SHLD FDMAA ; MVI A,01H ;SET WRITE DATA FLAG STA FRWF ; XRA A ;SET 5" DBL DENSITY STA FPT+0 ; MVI A,43 ;SET PRECOMP TRK 43 STA FPT+1 ; MVI A,01H ;SET STEP RATE STA FPT+2 ; MVI A,40H ;TRACK CALL FSEEK ; CALL FLOPPE ; ; MVI A,01H ;DRIVE 1 STA FDRV ; LXI H,0040H ;TRACK XX SHLD FTRK ; XRA A ;SIDE 0 STA FHED ; INR A ; STA FSEC ;SECTOR 1 LXI H,8500H ;DMA POINTER SHLD FDMAA ; XRA A ;READ FLAG STA FRWF ; STA FPT+0 ;SET 5" DBL DENSITY MVI A,43 ;SET PRECOMP STA FPT+1 ; MVI A,01H ;SET STEP RATE STA FPT+2 ; CALL FLOPPE ;GO READ CALL FHOME ;RECAL DISK LXI H,8500H ; MOV A,M ; CPI 0B8H ;COMPARE DATA JRNZ DSK$ERR4 ;DATA ERROR INX H ; MOV A,M ; CPI 6DH ;COMPARE DATA JRNZ DSK$ERR4 ;DATA ERROR MVI A,4FH ;DESELECT DRIVES & TURN MOTORS OFF OUT P$DISK$BITS ;TELL FLOPPIES ABOUT IT RET ;DISK TEST DONE DSK$ERR4: LXI H,DSK$DTA ;DATA ERROR JMP FMTER0 ;GO REPORT ERROR DSK$WP: DB FF,'FLOPPY DISK TEST' DB CR,LF,'WRITE PROTECT ERROR' DB CR,LF,'TYPE RETURN TO EXIT','$' DSK$LD: DB FF,'FLOPPY DISK TEST' DB CR,LF,'LOST DATA ERROR' DB CR,LF,'TYPE RETURN TO EXIT','$' DSK$ID: DB FF,'FLOPPY DISK TEST' DB CR,LF,'ID NOT FOUND' DB CR,LF,'TYPE RETURN TO EXIT','$' DSK$CRC: DB FF,'FLOPPY DISK TEST' DB CR,LF,'CRC ERROR' DB CR,LF,'TYPE RETURN TO EXIT','$' DSK$DTA: DB FF,'FLOPPY DISK TEST' DB CR,LF,'READ DATA ERROR' DB CR,LF,'TYPE RETURN TO EXIT','$' DSK$OVR: DB FF,'FLOPPY DISK TEST' DB CR,LF,'OVERRUN UNDERRUN ERROR' DB CR,LF,'TYPE RETURN TO EXIT','$' ; FMTER0: CALL MESDPLY ;DISPLAY MESSAGE ; FMTER1: DI ;DISABLE INTERRUPTS XRA A ;RESET ACC TO ZERO OUT P$CLK$PORTB ;MASK INTERRUPTS EI ;ENABLE INTERRUPTS IN P$KB$CONTROL ;READ KEYBOARD BIT 1,A ;TEST FOR KEY JRZ FMTER1 ;NO KEY RET ;BACK ; ; INTVECTS: ;>>> SET UP INTERRUPT VECTORS <<< LXI H,(EI)+256*(RET) ;SET UP NULL INTERRUPT HANDLER SHLD NINT ;. . LXI H,AINT ;LOAD HL WITH 1-ST INTERRUPT (I0) SHLD IVECT+14 ;...STORE IN TABLE LXI H,EXTINT ;LOAD HL WITH 2-ND INTERRUPT (I1) SHLD IVECT+12 ;...STORE IN TABLE LXI H,KINT ;LOAD HL WITH 3-RD INTERRUPT (I2) SHLD IVECT+10 ;...STORE IN TABLE LXI H,FIRQ ;LOAD HL WITH 4-TH INTERRUPT (I3) SHLD IVECT+8 ;...STORE IN TABLE LXI H,ZVINT ;LOAD HL WITH 5-TH INTERRUPT (I4) SHLD IVECT+6 ;...STORE IN TABLE LXI H,ZDINT ;LOAD HL WITH 6-TH INTERRUPT (I5) SHLD IVECT+4 ;...STORE IN TABLE LXI H,XINTB ;LOAD HL WITH 7-TH INTERRUPT (I6) SHLD IVECT+2 ;...STORE IN TABLE LXI H,XINTA ;LOAD HL WITH 8-TH INTERRUPT (I7) SHLD IVECT ;...STORE IN TABLE MVI A,IVECT/256 ;SET UP I REGISTER STAI ;. . ; LXI H,0FFFFH ;RESET CURRENT TRACK STATUS SHLD FTRKA ;. . SHLD FTRKA+2 ;. . XRA A ;RESET LAST WAS WRITE STA FWF ;. . MVI A,07H ;SET DISK TIMEOUT LXI H,4000H ;SET ADDRESS MOV M,A ;STORE IT LXI H,0D000H ;START ADDRESS FOR NMI MVI A,08H ;08 ('EX') MOV M,A ; INX H ; MVI A,0D9H ;D9 ('EXX') MOV M,A ; INX H ; MVI A,0EDH ;ED ('INI') MOV M,A ; INX H ; MVI A,0A2H ;A2 MOV M,A ; INX H ; MVI A,0D9H ;D9 ('EXX') MOV M,A ; INX H ; MVI A,08H ;08 ('EX') MOV M,A ; INX H ; MVI A,21H ;21 ('LXI H,006AH') MOV M,A ; INX H ; MVI A,6AH ;6A MOV M,A ; INX H ; XRA A ;00 MOV M,A ; INX H ; MVI A,0E9H ;E9 ('PCHL') MOV M,A ; ; RET ;RETURN FROM SUBROUTINE ; ; ORG 1FFFH ; ; DB 00H ;<<< CHECK SUM VALUE >>> ; ; ORG 2000H ; ; ;*** VARIABLES ;* FOR FLOPPY RW ; ; FTRKA: DS 4 ;FLOPPY TRACK TABLE FWF: DS 1 ;"LAST OPERATION WAS A WRITE" FLAG FTRYCNT:DS 1 ;TRY COUNTER WHEN RETRYING FADR: ;OPERATION TABLE FDRV: DS 1 ;DRIVE FTRK: DS 2 ;TRACK FHED: DS 1 ;HEAD FSEC: DS 1 ;SECTOR FDMAA: DS 2 ;DMA ADDRESS FRWF: DS 1 ;READ/WRITE/CHECK/FORMAT FLAG FPT: DS 1 ;(MODE PARAM) MODE BITS (8"/5",SD/DD) DS 1 ;(HARD PARAM ) WPRECOMP IF >= THIS TRACK DS 1 ; STEP RATE FADRLEN EQU $-FADR ;* ADDRESSES FOR MONITOR OPERATIONS MATBL: MDRV: DS 1 ;DRIVE # MTRK: DS 2 ;TRACK # MHED: DS 1 ;HEAD # MSEC: DS 1 ;SECTOR # MDMAA: DS 2 ;BUFFER POINTER MRWFLAG:DS 1 ;READ WRITE FLAG MFIXMOD:DS 7 MVARMOD:DS 9 WADR: WDRIVE: DS 1 WTRK: DS 2 WHED: DS 1 WSEC: DS 1 WDMAA: DS 2 WRWF: DS 1 ;READ/WRITE/CHECK/FORMAT FLAG WPT: DS 1 WADRLEN EQU $-WADR WCB: OP: DS 1 ADH: DS 1 ADM: DS 1 ADL: DS 1 INTL: DS 1 ;BLOCK COUNT/INTERLEAVE STEPM DS 1 ;(STEP MODES) ;(EXTENTION OF WCB WHEN SETTING DRIVE CHARACTERISTICS ONLY) WCB1 DS 2 HEDS DS 1 START$RED DS 2 START$PRE DS 2 MAXIECC DS 1 ; MAX ECC DATA BURST LENGTH (LEL0384) ORG 2050H ; ; YEAR DS 1 MONTH DS 1 DAY DS 1 HOUR DS 1 MIN DS 1 SEC DS 1 GOTTEN: DS 2 ;AMOUNT OF SYSTEM ALREADY GOTTEN NMIBUF: DS 8 ;HOLDS NMI LOCS WHILE OVERLAYED WACCF: Ds 1 ;FIRST ACCESS FLAG STAT: DS 1 ;COARSE STATUS BYTE (EVERYTIME) LSTAT: DS 4 ;FINE STATUS BYTES (FROM REQUEST SENSE STATUS COMMAND) Ds 1 ;NUMBER OF BAD TRACKS BADTRACK:DS MAXBAD*2 ;ROOM FOR (10) BAD TRACKS ; ; Data areas used in Real Time Clock operations ; ORG 504FH PASS$FLG DS 1 ; Flag used to tell pass thru code (LEL0284) THE$DATE DS 8 ; Date in form xx/xx/xx (LEL0284) THE$TIME DS 8 ; Time in form xx:xx:xx (LEL0284) DS 1 ; (overflow area) (LEL0284) ; THESE TAGS PERTAIN TO THE LABEL RECORD ; ; ORG 8000H ; ; BUFFER: BSIG: DS 4 ;LABEL FLAG BSECSIZ:DS 2 ;SECTOR SIZE BNSECS: DS 1 ;# SECTORS/TRACK BNHEDS: DS 1 ;NUMBER OF HEADS BNTRKS: DS 2 ;# OF TRACKS BTSKEW: DS 1 ;SKEW FACTOR DS 9 ;DEAD SPACE BLDBG: DS 2 ;LOAD START ADDRESS BLDLN: DS 2 ;LOAD LENGTH BJMPA: DS 2 ;JUMP ADDRESS DS 30 ;MORE DEAD SPACE BSTEPR: DS 1 ;STEP RATE 0 = FASTEST BORDR: DS 1 ;ORDER (0 = ALTERNATING HEADS) BFSEC: DS 1 ;FIRST SECTOR # ON A TRACK BFTRK: DS 1 ;FIRST TRACK ON A SURFACE BFHED: DS 1 ;FIRST HEAD ; ORG 0C000H BOOT$DRV DS 1 ;SIGNAL AS TO WHICH DRIVE BOOTING FROM (LEL0284)` ; ORG 0FFDAH ; ; EXIT: EQU $ ;3-BYTE EXIT JUMP STACK: EQU EXIT-1 ;STACK AREA ; ; ORG 0FFF0H ; ; IVECT EQU $ ;INTERRUPT VECTOR TABLE NINT EQU IVECT-2 ;LOCATION FOR NULL HANDLER ; ; END