IMD 1.18: 19/12/2012 10:12:50  Disk Descriptor30?00M40 ( ) *!+",#-$.%/ &0 '0 ( ) *!+",#-$.%/ &0 'ISHA200 Z80 ISHA200 Z80[HDISK100DEF ISHA101 DEF !gister contents (D1..7). ; ; 1.6 - 3 MAY 84 GRH ; Change block move subroutine to allow for 1..65,536 byte moves. ; Fix bu ;*INCLUDE JDDDISK.DEF ; LIST OFF *INCLUDE JDDCONT.DEF *INCLUDE JDDDISK.DEF LIST ON SUBTTL DEFINITIONS ;===========******************************************** ; ; REVISIONS: ; 1.0 - 28 DEC 83 GRH ; DIAGNOSTIC VERSION FOR TESTING THE BOAISHA200AZ80"#$%&'()*+,-./01ISHA200AZ80[23456789:;<=>?FMTH000 Z80@ABCDEFGHIHDMD202 Z80,JKLMNOPQRSTgs in Jade driver. Add printer output diagnostic. ; ; 1.7 - 2 JUN 84 GRH ; Fix bug in HSTIN & HSTOUT macros outputting bit ==================== ; ; ASSEMBLY TIME CONSTANTS ; ;=============================== S100D EQU 0D8H ;DATA PORT VISIBLE TORD. ; 1.1 - 2 JAN 84 GRH ; ADD HARD DISK CONTROLLER FIRMWARE. ; 1.2 - 1 APR 84 GRH ; Fix Bug in host xfer subr. that cauHDMM210 Z80UVWXYZ[\]^_`abcdHDMM210 Z80efIMON100 C ~ghijklmnopqrstuvHDMON201Z80wxyz{|}~7 data to XADDR ; register instead of to HXAD15 register. ; Add JADE FDC dump to dump diagnostic command. ; ; 1.8 - 2 JUN  S100 BUS S100S EQU S100D + 1 ;STATUS PORT VISIBLE TO S100 BUS S100C EQU S100S ;COMMAND PORT VISIBLE TO S100 BUS ; LOCPRTS sed problems on 32k boundary ; crossings. Enable parity checking for received data. Enable ; controller retrys. ; 1.3 - 2 APRHDMON201Z80HDMON202Z80,ISASI203Z80ISASI203Z80V84 GRH ; Change floppy disk read/write sector to logical sector for uniformity ; in IOPB parameters. (0..N-1 now changed EQU 0 ;BASE ADDRESS OF LOCAL PORTS LOCMEM EQU 0 ;BASE ADDRESS OF LOCAL RAM ; S1PRTS EQU 80H ;BASE ADDRESS OF S100 PORTS ; 84 GRH ; Fix Bug in read buffer routine which caused 1st 4 bytes of sector ; to be 0 and read not retryed but sense status to 1..N) ; ; 1.9 - 3 OCT 84 GRH ; Fix bug in Jade driver which allowed errors to go undetected. ; ; 1.A - 18 APR 85 GRH S1MEM EQU 8000H ;BASE ADDRESS OF S100 MEMORY WINDOW ; LOCROM EQU LOCMEM ;BASE ADDRESS OF LOCAL ROM LOCRAM EQU LOCMEM + 40to be issued instead. ; The CDB had to be re-initialized with the read command after getting ; results command issued. ; ; 1 ; Fix logon problem. Code is only now showing bugs with 2nd hard ; disk installed. ; 1.B - 6 DEC 85 GRH ; Changed code 00H ;BASE ADDRESS OF LOCAL RAM RAMSIZE EQU 2048 ;SIZE OF LOCAL RAM ROMSIZE EQU 2048 ;SIZE OF LOCAL ROM ;===============.4 - 28 APR 84 GRH ; Add Jade FDC routines. Change host block move subrs into general ; purpose subrs. ; ; 1.5 - 30 APR 8to return new values for logon. ; 2.0 - 31 JAN 86 GRH ; 1. Remove SASI floppy driver. ; 2. Streamline code for speed & stru TITLE INTELLIGENT SASI HOST ADAPTOR (ISHA) FIRMWARE LIST NOCOND ;***********************************************************============================================================= ; SASI BUS DATA LOCAL PORT ;==================================4 GRH ; Change hardware to reflect the state of the interrupt flip-flop ; as the busy bit (D0). Hardware will now allow softcture. ; 3. Modify error reporting (separate IOPB errors). ; 4. Modify Jade code to talk to new Jade firmware. ; 5. Modify di*************** ; ; THIS MODULE CONTAINS THE INTELLIGENT HOST ADAPTER FIRMWARE. ; ;*****************************************========================================== SASIDATA EQU LOCPRTS ;=========================================================ware setting of ; the interrupt flip-flop to allow passing a busy state if required. ; Normally this change will allow transpaagnostics to pass address data in IOPB_PTR. ; 6. Add reset (power on) diagnostics. ; VERSN EQU 20H ;********************************************************* ; ; IOPB CONFIGURATION: ; ; DRIVE USAGE ; 0 SASI physical drive 0 ; 1 SASI physic=================== ; SASI BUS CONTROL LOCAL PORT ;=========================================================================rent operation of the soft- ; ware, without concern to the busy status. All other status bits ; reflect the software status re************************************************** FALSE EQU 0 TRUE EQU NOT FALSE DEBUG EQU FALSE ; ;*INCLUDE JDDCONT.DEFal drive 1 ; 2 SASI physical drive 2 (OPTIONAL) ; 3 SASI physical drive 3 (OPTIONAL) ; ;******************************0 ( ) *!+",#-$.%/ &0 '=== SASICMD EQU LOCPRTS + 1 ; ; 7 6 5 4 3 2 1 0 ; |X|X|X| | | | | | ; ^ ^ ^ ^ ^__ INTERRUPT SELECT; 0: HOST, 1: ON SASI R 6 ;HOST A15 SET PORT ; ; 7 6 5 4 3 2 1 0 ; | |X|X|X|X|X|X|X| ; ^________________ BIT APPLIED TO HOST BUS A15 WHEN ACCESSI10110B ;XFER CONTROL MASK SGTCMD EQU 1 SHL SCD ;GET COMMAND FROM H/A SGTDAT EQU 0 ;GET DATA FROM H/A SSNDDAT EQU 1 SHL SIO ;ER FERR11 EQU -11 ;PARITY ERROR ;============================================================================ ; ; HARD DSKS: HFERR EQU (1 SHL HSERRB) + (1 SHL HFERRB) ;FIRMWARE ERROR BYTE ;=====================================================EQUEST ; | | | |____ 1: SASI RESET ; | | |______ 1: SASI DEVICE SELECT STROBE ; | |________ 0: SASI PARITY ERROR CLEAR ; NG ITS MEMORY ; AND BIT 7 WHEN ACCESSING ITS I/O ; ; BIT #S: A15B EQU 7 ;HOST A15 BIT ;=============================SEND DATA TO H/A SSNDST EQU (1 SHL SIO) + (1 SHL SCD) ;SEND STATUS TO H/A SCMDDN EQU (1 SHL SIO) + (1 SHL SCD) + (1 SHL SMSG) ISK DEFINITIONS ; ;============================================================================ HDCONT EQU 0 ;THIS CONTROLLE======================= ; HOST COMMAND LOCAL INPUT PORT ;=================================================================== |__________ 1: HOST VECTORED INTERRUPT ; ; BIT #S: SINTE EQU 0 ;SASI INTERRUPT SRESET EQU 1 ;SASI RESET SSELECT EQU 2 ;S=============================================== ; HOST EXTENDED ADDRESS LOCAL OUTPUT PORT ;==================================;COMMAND DONE ;============================================================================ ; HOST'S INTERRUPT CLEAR LOCAR'S ADDRESS BIT HDBASD EQU 0 ;BASE DRIVE # OF HD CONTROLLER HDNDRV EQU 4 ;NUMBER OF PHYSICAL DRIVES SUPPORTED HDNLUN EQU HD========= HCMD EQU LOCPRTS + 4 ;HOST COMMAND PORT ; ; 7 6 5 4 3 2 1 0 ; | | |0| | | | | | ; ^ ^ \_____/ ^__ 1: HOST INTASI DEVICE SELECT STROBE SERRCLR EQU 3 ;SASI PARITY ERROR CLEAR* HINT EQU 4 ;HOST VECTORED INTERRUPT ;============================================================= HXADDR EQU LOCPRTS + 7 ;EXTENDED ADDRESS PORT (A16..A23) ; ; 7 6 5 4 3 2 1 0 ; |L OUTPUT PORT ; (DATA= DON'T CARE) ;============================================================================ HINTC EQUNDRV INLEV EQU 6 ;INTERLEAVE FACTOR FOR FORMAT ;=========================================================================ERRUPT ; | | |_______ NON-IOPB COMMAND CODE (0..F) ; | |______________ 1: EXECUTE HOST IOPB ; |________________ 1: HA========================================================= ; SASI BUS STATUS LOCAL PORT ;==================================== | | | | | | | | ; ^ ^ ^ ^ ^ ^ ^ ^__ A16 ; | | | | | | |____ A17 ; | | | | | |______ A18 ; | | | | |________ A19 ; | | LOCPRTS + 2 ;============================================================================ ; HOST'S INTERRUPT SET LOCAL O=== ; ; SASI DEFINITIONS ; ;============================================================================ SCRDY EQU 0 ;TEST RDWARE LOCAL RESET ; ; BIT #S: HINTRB EQU 0 ;HOST INTERRUPT REQUEST BIT HIOPBB EQU 6 ;HOST EXECUTE IOPB BIT HRESB EQU 7 ======================================== SASIST EQU LOCPRTS + 1 ; ; 7 6 5 4 3 2 1 0 ; | |X|X| | | | | | ; ^ ^ ^ ^ ^ ^ | |__________ A20 ; | | |____________ A21 ; | |______________ A22 ; |________________ A23 ;=========================UTPUT PORT ; (DATA= DON'T CARE) ;============================================================================ HINTS EQU LOCDRIVE READY COMMAND SCREC EQU 1 ;RECALIBRATE SCSNSE EQU 3 ;REQUEST SENSE SCFMTD EQU 4 ;FORMAT ENTIRE DRIVE SCFMTT EQU 6 ;FOR;HOST RESET LOCAL PROCESSOR BIT ;============================================================================ ; HOST DATA__ 1: BUSY ; | | | | |____ 1: MESSAGE ; | | | |______ 1: COMMAND, 0: DATA ; | | |________ 0: REQUEST ; | =================================================== ; ; FIRMWARE ERROR CODES IN HOST DATA REGISTER IF HOST STATUS ; BIT 1 IS PRTS + 3 ;============================================================================ ; HOST STATUS LOCAL OUTPUT PORT ;MAT TRACK SCFMTBT EQU 7 ;FORMAT BAD TRACK SCREAD EQU 8 ;READ SECTOR(S) SCWRIT EQU 10 ;WRITE SECTOR(S) SCSEEK EQU 11 ;SEEK TR TRANSFER LOCAL I/O PORT ;============================================================================ HDATA EQU LOCPRTS + 5 ; |__________ 0: INPUT TO ISASI, 1: OUTPUT (TO CONTROLLER) ; |________________ 1: PARITY ERROR ; ; BIT #S: SBUSY EQU 0 ;BUSSET ; ;============================================================================ FERR00 EQU -1 ;UNKNOWN ERROR FERR02 EQU ============================================================================ HSTAT EQU LOCPRTS + 4 ; ; 7 6 5 4 3 2 1 0 ; | ACK SCCOPY EQU 20H ;COPY BLOCK(S) ;============================================================================ ; ; JAHOST DATA TRANSFER PORT ;============================================================================ ; HOST ACCESS ADDREY BIT SMSG EQU 1 ;MESSAGE BIT SCD EQU 2 ;C/D BIT SREQ EQU 3 ;REQUEST* BIT SIO EQU 4 ;I/O* BIT SPERR EQU 7 ;PARITY ERRO-2 ;ROM TEST FAILURE FERR03 EQU -3 ;ILLEGAL COMMAND FERR04 EQU -4 ;ILLEGAL INTERRUPT FERR07 EQU -7 ;CONTROLLER HANDSHAKE TIMO|0|0|0|0|0| | | ; ^ ^ ^__ 1: ISASI BUSY ; | |____ 1: FIRMWARE ERROR ; |________________ 1: ERROR ; ;DE DEFINITIONS ; ;============================================================================ JADBASD EQU 4 ;BASE DRIVE # OSS BIT 15 LOCAL OUTPUT PORT ;============================================================================ HXAD15 EQU LOCPRTS +R DETECTED BIT ; MASKS: SSTMSK EQU 10011111B ;STATUS BIT MASK SSTINV EQU 00011000B ;STATUS BIT INVERSION MASK SSXMSK EQU 000UT FERR08 EQU -8 ;CONTROLLER SYNC ERROR ??? FERR09 EQU -9 ;CONTROLLER SENSE STATUS ERROR FERR10 EQU -10 ;ILLEGAL IOPB PARAMET BIT #S: HBUSY EQU 0 ;HOST BUSY STATUS BIT HFERRB EQU 1 ;HOST FIRMWARE ERROR BIT HSERRB EQU 7 ;HOST ERROR STATUS BIT ; MA0 ( ) *!+",#-$.%/ &0 'F JADE CONTROLLER JADNDRV EQU 4 ;NUMBER OF LOGICAL JADE CONTROLLER DRIVES SUBTTL MACROS ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@; ; EXECUTE THE COMMAND ; CMDOK: LD E,A ;SAVE COMMAND ; XOR A,A ;ASSUME NO ERRORS OUT (HSTAT),A ; LD HL,CMDTBL ;C@@@@@@@@@@@@@ HSTOUT: MACRO #PORT, #DATA IF #PORT < 80H XOR A ELSE LD A,#PORT ;SET UP BIT 7 ENDIF OUT (HXAD10 THEN OR L JR NZ,HWAIT ; ; TIMED OUT, DESELECT SASI BUS ; CALL DESELECT ; ; SAFE TO ALLOW INTERRUPT HERE ALSO ; ; ; DO RESET TESTS ; CALL PUTEST ; ; INIT THE REMAINDER ; CALL INIT ;ANY OTHER INITIALIZATION ; ; GO WAIT FOR@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ; ; GET DATA MACRO ; ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ALCULATE THE TABLE ENTRY FROM THE COMMAND LD D,0 ADD HL,DE ;VALUE ALREADY *2 (BIT 0 = 0) ; LD E,(HL) ;FETCH THE COMMAND5),A ; IF (#DATA = 0) AND (#PORT >= 80H) XOR A ENDIF IF #DATA <> 0 LD A,#DATA ;OUTPUT DATA ENDIF OUT (#P EI JR HWAIT ;############################################################################ ; ; COMMAND TABLE FOR NON- HOST COMMAND ; LD HL,0 ;FORCE NO TIMEOUT LD (TIMOUT),HL ; OUT (HINTC),A ;TELL HOST IT'S OK NOW ; JP HWAIT ;GO WAIT@@@@@@@@@@@@@@@@@@@ GETDATA MACRO AA#SYM: CALL GETSTAT ;IF REQUEST FALSE THEN WAIT BIT SREQ,A JR Z,AA#SYM ; INI ;GET HANDLER ADDRESS FROM TABLE INC HL LD D,(HL) EX DE,HL ; IN A,(HDATA) ;PREFETCH THE DATA FOR THE COMMAND ; ; CALL THORT OR 80H),A ENDM ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ; ; HOST INPUT MACRO ; IOPB COMMANDS ; ;############################################################################ CMDTBL: DW IOPBLO ;(1) SET IOP FOR HOST INTERRUPT ; ; ; RAM ERROR ENCOUNTERED ; MEMERR: LD A,RAMERR ;PASS ERROR TO HOST & HALT CALL FERR HALT ;FA DATA ; ENDM ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ; ; PUTDATA MACRO ; ;@@@@E COMMAND HANDLER ; LD DE,CMDRET ;PUT RETURN ADDRESS ON STACK PUSH DE JP (HL) ; ;-------------------------------------- ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ HSTIN: MACRO #PORT IF #PORT < 80H XOR A B LO COMMAND DW IOPBHI ;(3) SET IOPB HI COMMAND DW IOPBX ;(5) SET IOPB XADDR COMMAND DW DIAG0 ;(7) DUMP LOCAL MEMORY DITAL! IF $ > 38H CONMSG **** ERROR! RESET CODE OVERLAPS INTERRUPT CODE! **** ENDIF ;------------------------------------@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PUTDATA MACRO AC#SYM: CALL GETSTAT ;IF REQUEST NOT T-------------------------------------- ; ; ALL COMMANDS RETURN HERE WITH ERROR STATUS ALREADY SET FOR HOST ; ;-------------- ELSE LD A,#PORT ;SET UP BIT 7 ENDIF OUT (HXAD15),A ; IN A,(#PORT OR 80H) ;FETCH DATA ENDM SUBTTL CODE ;****AGNOSTIC CMD DW DIAG1 ;(9) SET OUTPUT PORTS DIAG. COMMAND DW DIAG2 ;(B) TEST S100 MEMORY ACCESS COMMAND DW DIAG3 ;(D) B---------------------------------------- ; ; INTERRUPT ENTRY VECTOR FOR MODE 1 ; ;------------------------------------------RUE THEN WAIT BIT SREQ,A JR Z,AC#SYM ; OUTI ;ASSUME CALLER SET UP ; DON'T WAIT ENDM ;@@@@@@@@@@@@@@@@@@@@@@@@@-------------------------------------------------------------- CMDRET: OUT (HINTC),A ;TELL HOST WE'RE DONE RET ;RETURN TO T******************************************** ; ; PROCESSOR REGISTER USAGE: ; IY= PTR TO CURRENT COMMAND DESCRIPTOR BLOCK ; LOCK MOVE 01000H TO 02000H COMMAND DW PRINT ;(F) PRINT ASCII STRING TO PORT COMMAND DW RETVERS ;(11) RETURN FIRMWARE VERSI---------------------------------- ORG LOCROM + 38H ; ; CHECK FOR SASI INTERRUPT ; IN A,(HCMD) ;GET COMMAND BIT HINTR@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ; ; BUFFER HALF SELECT MACRO ; ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@HE INTERRUPTED ROUTINE ;---------------------------------------------------------------------------- ; ; MAIN INTERRUPT;************************************************ ORG LOCROM ; RESETV: ; ; INIT SOME THINGS ; OUT (HINTS),A ;SET BUSYON NUMCMDS EQU ($ - CMDTBL) / 2 ;NUMBER OF COMMANDS ;*********************************************************************B,A ;IF NOT HOST INTERRUPT THEN MUST BE SASI JP Z,SASINT ; ; CHECK FOR IOPB EXECUTE INTERRUPT ; BIT HIOPBB,A ;IF IOPB B@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ SELCTBUF MACRO LD HL,HDSECB ;ASSUME 1ST HALF LD A,(IOPB + PBSECO) ;IF SECTOR IS ODD THED LOOP ; ;---------------------------------------------------------------------------- HWAIT: ; ; TO PRESERVE DATA, ALLO FLAG ; XOR A ;PASS NOT -1 TO BOOT OUT (HSTAT),A ; IM 1 ;ONLY 1 INTERRUPT ; LD SP,STACK ;INIT STACK ; ; TEST RA******* ; ; FIRMWARE ERROR ENCOUNTERED, SET THE ERROR FLAGS SUBR ; ENTRY- A= ERROR CODE ; ;********************************IT SET THEN EXECUTE IOPB JP NZ,EXIOPB ; ; COMMAND INTERRUPT ; AND 00011110B ;MASK OFF UNUSED COMMANDS ; CP NUMCMDS *EN SELECT UPPER HALF AND 1 JR Z,BB#SYM ; LD HL,HDSECB + 128 BB#SYM: ENDM ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@W INTERRUPT HERE ONLY ; EI NOP DI ; ; IF TIMED OUT THEN CONTINUE TO WAIT ; LD HL,(TIMOUT) ;IF TIMED OUT THEN JUST M ; LD HL,LOCRAM ;DO RAM TEST LD BC,RAMSIZE ; MTLP: LD A,(HL) ;COMPLEMENT & TEST CPL LD (HL),A CP (HL) JR NZ,MEM******************************************** FERR: OUT (HDATA),A ;OUTPUT THE ERROR CODE ; LD A,HFERR ;PASS ERROR FLAGS TO H 2 ;IF COMMAND ERROR THEN RETURN FIRMWARE ERR JR C,CMDOK ; ; ILLEGAL COMMAND, RETURN ERROR ; LD A,FERR03 JP FERR ; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ; ; HOST OUTPUT MACRO ; ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@WAIT LD A,H OR L JR Z,HWAIT ; ; ELSE DELAY SOME MORE ; DEC HL LD (TIMOUT),HL LD A,H ;IF TIME OUT JUST WENT TO ERR ;IF NO COMPARE THEN ERROR ; CPL ;RESTORE LD (HL),A ; INC HL ;NEXT LOCATION DEC BC LD A,B OR C JR NZ,MTLP 0 ( ) *!+",#-$.%/ &0 'OST OUT (HSTAT),A ; OUT (HINTC),A ;CLEAR ANY PENDING INTERRUPT RET SUBTTL FIRMWARE COMMANDS ;++++++++++++++++++++++++++++++++++++++++++++++++++ DIAG3: ; ; IF SUBCOMMAND 0 THEN GO DO MOVE ; OR A JR Z,DOMOVE ; ; LOOP ON COMMAND ; LD (HL),A ;SET NEW DATA LD A,C ;PASS OLD DATA TO HOST OUT (HDATA),A ; RET ;+++++++++++++++++++++++++++++++++++++++; ; OUTPUT NEW LINE ; CALL CRLF ; ; OUTPUT A LINE ; LD E,'0' ;START WITH '0' LD B,80 ;DO 1 LINE PRINT1: CALL PRT +FFFH ; EXIT- (IOPBL)= LAST LOCATION CHECKED ; (IOPBXA)= DATA READ FROM LAST LOCATION ; STATUS PORT= 0: NO ERRORS, -1 ERRO+++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; SET IOPB LOW ADDRESS COMMAND 1 ; MUST BE INITIALIZED BEFORE DISK ACD3LP: IN A,(HDATA) ;IF DATA CHANGED THEN CHECK ; CP 2 JR C,DOREAD ;IF SUBCOMMAND == READ ADDRESS THEN EXIT ; JR Z,DO+++++++++++++++++++++++++++++++++++++ ; ; DIAGNOSTIC DUMP COMMAND 7 LOADS HOST MEMORY WITH RAM IMAGE ; EXIT - (IOPB_PTR) OFFS INC E DJNZ PRINT1 ; ; OUTPUT A NEW LINE ; CRLF: LD E,0DH CALL PRT LD E,0AH JP PRT ;-----------------------R ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ DIAG2: ; ; SET UP FOR TEST ; CALL SECESS ; ENTRY- A= LOW BYTE OF IOPB ADDRESS ; EXIT - HDATA= OLD DATA ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++WRITE ;IF SUBCOMMAND == WRITE THEN THEN EXIT CP 3 JR Z,DOBLKH ;IF SUBCOMMAND == HIGH BLOCK MOVE THEN EXIT ; RET ; ;ETS: ; +0000H..+07FFH= RAM IMAGE ; +0800H..+0FFFH= ROM IMAGE ; +1000H..+17FFH= JADE FDC IMAGE ; ;+++++++++++++++++++++++----------------------------------------------------- ; ; RETURN FIRMWARE VERSION COMMAND 17 ; EXIT - HDATA= VERSION # (HEX) TPTRS ; ; TEST THE S100 ACCESS ; D2LP: LD A,(HL) CPL LD (HL),A CP (HL) CPL ;RESTORE LD (HL),A JR NZ,D2ERR ;++++++++++++++++++++++ IOPBLO: LD HL,IOPBL ;POINT TO LOW BYTE TO ALTER JR IOPBST ;++++++++++++++++++++++++++++++++++++++ ; WRITE TO SINGLE LOCATION SUBCOMMAND ; DOWRITE: LD (S1MEM + 1000H),A JR D3LP ; ; ; READ FROM SINGLE LOCATION SUB+++++++++++++++++++++++++++++++++++++++++++++++++++++ DIAG0: ; ; DUMP LOCAL RAM 1ST ; IF 0 LD HL,LOCRAM LD DE,(IOP ; ;---------------------------------------------------------------------------- RETVERS: LD A,VERSN ;LOAD DATA REGISTER WI CALL BUMPHL DEC BC LD A,B OR C JR NZ,D2LP ; ; ERROR OR DONE, PASS BACK THE DATA ; D2ERR: LD (IOPBL),HL ;FAILURE++++++++++++++++++++++++++++++++++++++ ; ; SET IOPB HIGH ADDRESS COMMAND 3 ; MUST BE INITIALIZED BEFORE DISK ACCESS ; ENTRY-COMMAND ; DOREAD: LD A,(S1MEM + 1000H) JR D3LP ; ; ; BLOCK MOVE IN LOW HOST MEMORY THEN RETURN SUBCOMMAND ; DOMOVE:BL) LD A,(IOPBXA) LD BC,RAMSIZE CALL MOV2HST ELSE XOR A,A OUT (HXADDR),A OUT (HXAD15),A LD HL,LOCRAM LD DE,STH VERSION OUT (HDATA),A ; RET ;**************************************************************************** ; ; PRI LOCATION LD (IOPBXA),A ;ORIGINAL DATA RET Z ;RETURN IF NO ERROR ; ; TEST ERROR, PASS BACK TO HOST ; LD A,FERR00 J A= HIGH BYTE OF IOPB ADDRESS ; EXIT - HDATA= OLD DATA ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ XOR A,A ;DO IN LOW 32K OUT (HXAD15),A ; LD HL,S1MEM + 1000H LD DE,S1MEM + 2000H LD BC,1000H LDIR ; RET ; ; ;1MEM OR 4000H LD BC,RAMSIZE LDIR ENDIF ; ; FOLLOW WITH ROM IMAGE ; IF 0 LD A,(IOPBXA) ;MUST RESTORE BANK ADDNT A CHARACTER TO HOST PORT ; ENTRY- C= PORT # ; E= CHARACTER TO OUTPUT ; ;************************************************P FERR ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; DIAG3 COMMAND 13 DOES S100 MEMOR+++++++++ IOPBHI: LD HL,IOPBH ;POINT TO HIGH BYTE TO ALTER JR IOPBST ;++++++++++++++++++++++++++++++++++++++++++++++++++ BLOCK MOVE IN HIGH HOST MEMORY THEN RETURN SUBCOMMAND ; DOBLKH: LD A,1 SHL A15B ;SET HIGH PAGE OUT (HXAD15),A LD HL,0ERESS ENDIF LD HL,LOCROM LD BC,ROMSIZE JP MOV2HST ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++**************************** PRT: IN A,(C) ;IF BUSY THEN WAIT AND 1 JR NZ,PRT ; ; OUTPUT STROBE* ON BIT 7 ; LD A,E ;Y ACCESSES DEPENDING ON DATA ; NOTE: SCOPING TESTS CONTINUE UNTIL ANOTHER DATA WORD IS WRITTEN TO THE DATA ; REGISTER BY THE ++++++++++++++++++++++++++ ; ; SET IOPB EXTENDED ADDRESS COMMAND 5 ; MUST BE INITIALIZED BEFORE DISK ACCESS ; ENTRY- A= EXTE000H LD DE,0E800H LD BC,800H LDIR ; RET ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; DIAGNOSTIC 1 COMMAND 9 LOADS DATA INTO DATA OUT & STATUS REGS ; ENTRY- A= DATA ; ;+++++++++++++++++++++++OUTPUT CHARACTER WITH STROBE HIGH SET 7,A OUT (C),A ; RES 7,A OUT (C),A ; SET 7,A OUT (C),A ; RET SUBTTL HOST. ; ; ENTRY- A= 0: BLOCK MOVE FROM 1000H TO 2000H ; 1: READ FROM 1000H (SCOPING TEST) ; 2: WRITE TO 1000H (SCOPNDED ADDRESS BYTE OF IOPB ADDRESS ; EXIT - HDATA= OLD DATA ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; PRINT TEXT ON THE PRINTER COMMAND 15 ; EXERCISES THE I/O CAPABILITY ; ENTRY- A= PORT # ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ DIAG1: OUT (HDATA),A OUT (HSTAT),A RET ;++++++++++++++++++++++++SASI INTERRUPT ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; INTERRUPT WITHOUT HOST BIT SING TEST) ; 3: BLOCK MOVE FROM E000H TO E800H ; ALL OTHERS: NOP ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ IOPBX: LD HL,IOPBXA ;POINT TO EXTENDED BYTE TO ALTER ; ; COMMON CODE ; IOPBST: LD C,(HL) ;SAVE OLD DATA ++++++++++++++++++++++++++++++++++++++++++++++++++++ PRINT: OUT (HXAD15),A ;SET PORT TO DATA SET 7,A ;MAP TO HOST LD C,A ++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; DIAG2 COMMAND 11 TESTS S100 MEMORY READS & WRITES FROM (IOPB_PTR) TO0 ( ) *!+",#-$.%/ &0 'ET ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SASINT: ; ; THIS VERSION DOESN'T SUPPOLOG: ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; JADE CONTROLLER READ SECTOR COMMANDE LD A,(HL) ;GET COMMAND FROM TABLE INC HL LD H,(HL) LD L,A ; ; CALL THE COMMAND ; LD DE,XRET ;PUT RETURN ADDT ; ; EXECUTE THE COMMAND ; CALL FDSKEX ;EXECUTE WRITE SECTOR CMD ; ; REMOVE THE JADE WINDOW ; HSTOUT DDPORT,DDOUDW JADEXEC ;7: IDLE DW JADEXEC ;8: RETURN FIRMWARE VERSION DW JADEXEC ;9: SET DISK FLAGS DW JADEXEC ;10: LOAD HEAD & IRT THE INTERRUPT! ; LD A,FERR04 ;OUTPUT ERROR FOR NOW JP FERR SUBTTL IOPB EXECUTION ;--------------------------------D ; EXIT - (IOPB + PBSTATO)= 0 OR ERROR CODE ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ RESS ON STACK PUSH DE JP (HL) ;EXECUTE COMMAND ; XRET: ; ; MOVE LOCAL IOPB TO HOST IOPB AREA FOR STATUS RETURN ; T ;REMOVE WINDOW ; RET ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; JADE CONTROLLDLE DW JADEXEC ;11: SEEK TRACK DW JADEXEC ;12: SET DRIVE PARAMETERS DW JADEXEC ;13: RETURN DRIVE STATUS DW JADEXEC ;-------------------------------------------- ; ; EXECUTE IOPB COMMAND ; ;------------------------------------------------- JADREAD: ; ; EXECUTE THE READ COMMAND ; HSTOUT DDPORT,DDMB0 ;SWITCH DD INTO MEMORY CALL FDSKEX ; ; XFER THE JADE CLD HL,IOPB ;SOURCE := LOCAL IOPB IMAGE LD DE,(IOPBL) ;GET ADDRESS OF IOPB IN USER RAM LD A,(IOPBXA) ; SET BANK # ; LD BER FORMAT COMMAND (NOT IMPLEMENTED) ; EXIT - (IOPB + PBSTATO)= 0 OR ERROR CODE ; ;+++++++++++++++++++++++++++++++++++++++++++14: SET EIA BAUD RATES DW JADEXEC ;15: CLEAR ; HDCMDS: DW HDLOG ;0: LOG ON DISK (SELECT DISK) DW HDREAD ;1: READ DEBL--------------------------- EXIOPB: ; ; MOVE HOST IOPB INTO OUR LOCAL IOPB ; LD HL,IOPB ;DESTINATION := LOCAL IOPB IMAONTROLLER DATA TO LOCAL BUFFER ; HSTOUT DDPORT,DDMB1 ;DATA IN BANK 1 LD HL,(FDADDR) ;GET FDC ADDRESS LD DE,JADSECB EX DC,IOPBSZ ; CALL MOV2HST ; ; RETURN ERROR CODE IN STATUS REGISTER FOR COMPATABILITY ; LD A,(IOPB + PBSTATO) OR A,A +++++++++++++++++++++++++++++++++ JADFORM: ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ OCKED SECTOR DW HDWRT ;2: WRITE DEBLOCKED SECTOR DW HDFORM ;3: FORMAT TRACK DW HDCERR ;4: RESERVED DW HDCERR ;5: RESGE LD DE,(IOPBL) ;GET ADDRESS OF IOPB IN USER RAM ; LD A,(IOPBXA) ; SET BANK # LD BC,IOPBSZ ; CALL MOVFHST ; ; E,HL LD BC,128 ;FETCH SECTOR DATA XOR A CALL MOVFHST ; ; REMOVE THE JADE CONTROLLER WINDOW ; HSTOUT DDPORT,DDOUT JP Z,IOPBCDN ; LD A,1 SHL HSERRB ; IOPBCDN: OUT (HSTAT),A ; ; SET DISK SELECT TIMEOUT ; LD HL,-1 ;MAX TIME LD (; ; JADE CONTROLLER READ ADDRESS COMMAND (NOT IMPLEMENTED) ; EXIT - (IOPB + PBSTATO)= 0 OR ERROR CODE ; ;+++++++++++++++++++ERVED DW HDCERR ;6: RESERVED DW HDCERR ;7: RESERVED DW HDCERR ;8: RETURN FIRMWARE VERSION DW HDCERR ;9: RESERVED DASSUME NO ERRORS ; LD HL,0 LD (IOPB + PBSTATO),HL LD (IOPB + PBST2O),HL LD (IOPB + PBST4O),HL ; ; CHECK FOR HARD DI; ; XFER THE SECTOR DATA FROM THE LOCAL BUFFER TO THE HOST MEMORY ; LD HL,JADSECB ;NOW WRITE TO HOST JP HDHSTW ;+++TIMOUT),HL ; ; TELL HOST WE'RE DONE ; OUT (HINTC),A RET ; ; ; ILLEGAL DRIVE ERROR ; XILDRV: LD A,SELERR JR SET+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ JADRDAD: ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++W HDCERR ;10: RESERVED DW HDSEEK ;11: SEEK TRACK (NORMALLY IMPLIED) DW HDCERR ;12: RESERVED DW HDCERR ;13: RETURN DRIVSK ; LD A,(IOPB + PBDRVO) LD HL,HDCMDS ;ASSUME HARD DISK COMMAND CP HDNDRV JR C,XTABL ; ; NOT HARD DISK SO CHECK F+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; JADE CONTROLLER WRITE SECTOR COMMAND ; EXIT - (STAT ; ; ; ILLEGAL COMMAND ERROR ; XILCMD: LD A,CMDERR SETSTAT: LD (IOPB + PBSTATO),A JR XRET ;################++++++++++++++++++++ ; ; JADE CONTROLLER ILLEGAL COMMAND(S) (NOT IMPLEMENTED) ; EXIT - (IOPB + PBSTATO)= 0 OR ERROR CODE ; E STATUS DW HDCERR ;14: RESERVED DW HDCERR ;15: CLEAR ; MAXCMDS EQU ($ - HDCMDS) / 2 SUBTTL JADE IOPB COMMANDS ;+++OR JADE DISK ; CHKJAD: LD HL,JADCMDS ;ASSUME JADE CISK COMMAND SUB JADBASD ;4..11 -> 0..7 CP JADNDRV JR NC,XILDRV IOPB + PBSTATO)= 0 OR ERROR CODE ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ JADWRT: ; ############################################################ ; ; IOPB COMMANDS ; ;##########################################;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ JADEXEC: LD A,CMDERR ;UNSUPPORTED FOR NOW! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; JADE CONTROLLER LOGON COMMAND IS SAME AS READ ;; LD (IOPB + PBDRVO),A ;CHANGE DRIVE ; ; CHECK IF COMMAND IS ILLEGAL ; XTABL: LD A,(IOPB + PBCMDO) ;CHECK IF LEGAL CP ; XFER DATA FROM HOST TO LOCAL BUFFER ; LD HL,JADSECB ;GET DATA TO BUFFER CALL HDHSTR ; ; XFER LOCAL BUFFER TO JADE C################################## JADCMDS: DW JADLOG ;0: LOG ON DISK DW JADREAD ;1: READ SECTOR DW JADWRT ;2: WRITE S ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; SET IOPB STATUS BYTE FUNCTION ; ENTRY- A=  EXIT - (IOPB + PBSTATO)= 0 OR ERROR CODE ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ JADMAXCMDS JR NC,XILCMD ; ; COMPUTE DRIVER ADDRESS ; LD E,A LD D,0 ADD HL,DE ;MULTIPLY CMD BY 2 FOR OFFSET ADD HL,ONTROLLER ; HSTOUT DDPORT,DDMB1 ;GET FDC WINDOW LD HL,(FDADDR) EX DE,HL LD HL,JADSECB LD BC,128 XOR A CALL MOV2HSECTOR DW JADFORM ;3: FORMAT TRACK DW JADRDAD ;4: READ ADDRESS DW JADEXEC ;5: EIA OUTPUT DW JADEXEC ;6: EIA STATUS 0 ( ) *!+",#-$.%/ &0 'STATUS BYTE ; EXIT - NZ= ERROR ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ IOPBERR: LDECTOR DATA RET NZ ; ; SELECT THE BUFFER HALF ; SELCTBUF ; ; XFER THE DATA FROM THE HOST MEMORY ; CALL HDHSTR ;RUBTTL HARD DISK IOPB COMMANDS ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; UNSUPPORTED C SELECT DRIVE ; CALL HDSELCT RET NZ ; ; USE PRIMITIVE ; JP RECALC ;+++++++++++++++++++++++++++++++++++++++++++ WRITE THE HOST BUFFER ; LD HL,HDSECB ;WRITE ID SECTOR TO HOST CALL HDHSTW ; ; FLUSH BUFFER OF DESCRIPTOR SECTOR ;  (IOPB + PBSTATO),A OR A,A RET SUBTTL JADE FDC SUBR ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++EAD HOST BUFFER ; ; WRITE THE SECTOR BUFFER ; JP HDWRBUF ;WRITE TO DISK ;++++++++++++++++++++++++++++++++++++++++++OMMAND ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ HDCERR: LD A,CMDERR JP IOPBERR +++++++++++++++++++++++++++++++++ ; ; SEEK COMMAND ; EXIT - (IOPB + PBSTATO)= 0 OR ERROR CODE ; ;++++++++++++++++++++++++++ JP CLRBUFR ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; READ DEBLOCKED SECTOR COMMA++++++++++ ; ; EXECUTE THE COMMAND BLOCK FUNCTION ; EXIT - NZ= ERROR ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; FORMAT TRACK COMMAND ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; DRIVE SELECT/LOG-ON COMMAND ; EXIT - (IOPB ++++++++++++++++++++++++++++++++++++++++++++++++++ HDSEEK: ; ; SELECT DRIVE ; CALL HDSELCT ;IMPLIED SELECT RET NZ ; ND ; EXIT - (IOPB + PBSTATO)= 0 OR ERROR CODE ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ FDSKEX: ; ; CHANGE LOGICAL SECTOR {0..N-1} TO PHYSICAL {1..N} ; LD A,(IOPB + PBSECO) INC A +++++++++++++++ HDFORM: ; ; SELECT THE DRIVE ; CALL HDSELCT ;IMPLIED SELECT RET NZ ; ; SET UP THE CDB ; LD IY,+ PBSTATO)= 0 OR ERROR CODE ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ HDLOG: ; ; SE ; SET UP CDB ; LD IY,LAXCDB ;USE XFER CDB LD (IY+CMD),SCSEEK ;SEEK COMMAND CALL GETLUN CALL GETLAD ;GET USER'S BLOC HDREAD: ; ; SELECT DRIVE ; CALL HDSELCT ;IMPLIED SELECT RET NZ ; ; SET UP AND READ THE SECTOR ; LD IY,LAXCDB  LD (IOPB + PBSECO),A ; ; MOVE IOPB INTO JADE CONTROLLER ; LD DE,DDCBO ;OFFSET OF IOPB IN MEMORY BANK 0 LD HL,(FDADDR) LAXCDB ;ELSE USE XFER CDB LD (IY + CMD),SCFMTT ; LD A,(IOPB + PBSECO) ;SECTOR BYTE HAS INTERLEAVE FACTOR AND 00011111B ;MLECT THE CONTROLLER ; CALL HDSELCT RET NZ ; ; READ THE ID SECTOR ; LD IY,IDRCDB ;READ THE ID SECTOR CALL GETLUN K ; ; EXECUTE THE SEEK ; CALL XCDB6 ;SEND CDB RET NZ ; ; RETURN THE RESULTS ; JP GETRES ;GET ANY ERRORS SU;USE XFER CDB CALL GETLUN CALL GETLAD CALL HDRDBUF RET NZ ; ; SELECT THE BUFFER HALF ; SELCTBUF ; ; WRITE THE;BASE ADDRESS OF JADE MEMORY BANKS ADD HL,DE EX DE,HL LD HL,IOPB LD BC,PBDMAXO + 1 ;COUNT, INCLUSIVE XOR A CALL MOV2ASK OFF HEAD BITS LD (IY+ILV),A ; ; FORCE SECTOR TO 0 FOR CLEANLINESS ; XOR A LD (IOPB + PBSECO),A ; ; SET UP CDB CALL HDRDBUF RET NZ ; ; CHECK FOR LEGAL ID SECTOR ; LD DE,IDTXT ;TXT PTR LD HL,HDSECB ;TEXT IN SECTOR BUFFER LD B,BTTL HARD DISK SUBROUTINES ;**************************************************************************** ; ; CLEAR CONTROLLER SECTOR BUFFER TO THE HOST MEMORY ; JP HDHSTW ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++HST ; ; ISSUE COMMAND TO JADE CONTROLLER ; HSTOUT DDPORT,DDEXC ;ISSUE COMMAND ; ; SET UP FOR RETURN ; LD BC,IOPBS FROM IOPB ; CALL GETLUN ;GET DRIVE CALL GETLAD ;GET LOGICAL ADDRESS ; ; EXECUTE ; CALL XCDB6 ; ; RESTORE ILV IDSZE ;SIZE ; HDCKID: LD A,(DE) ;COMPARE CP (HL) JR NZ,HDNTID ;IF NOT SAME THEN EXIT ; INC HL ;NEXT CHAR INC DE  SUBR ; ;**************************************************************************** INIT: ; ; INIT VARIABLES ; LD A,+++ ; ; WRITE SECTOR COMMAND ; EXIT - (IOPB + PBSTATO)= 0 OR ERROR CODE ; ;++++++++++++++++++++++++++++++++++++++++++++++++Z - PBSTATO ;SET UP TO MOVE STATUS DOWN ; ; WAIT FOR JADE CONTROLLER TO FINISH ; FDSKWT: HSTIN DDPORT ;WAIT UNTIL DONE BYTE OF CDB FOR SUBSEQUENT OPS ; LD (IY+ILV),0 ;RESTORE ILV BYTE TO 0 RET NZ ;ERR? ; ; RETURN RESULTS ; JP GETRES DJNZ HDCKID ;DO UNTIL DONE ; ; ID CHECKS, RETURN VALID ID FLAG ; LD A,-2 JR HDLOG2 ; ; NO ID, USE DEFAULT ; HDNT-1 LD (CURDRV),A ;CURRENT DRIVE = NONE ; ; INIT COMMAND DESCRIPTOR BLOCKS (CDB) ; LD HL,NULCDB ;ZERO CDBS LD B,CDBINI++++++++++++++++++++++++++++ HDWRT: ; ; SELECT THE DRIVE ; CALL HDSELCT ;IMPLIED SELECT RET NZ ; ; PREREAD THE SE AND DDSHLT JR NZ,FDSKWT ; ; DONE, GET WINDOW ; HSTOUT DDPORT,DDMB0 ;GET WINDOW ; ; FETCH COMMAND RESULT STATUS ;;FINISH UP ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; RECAL COMMAND ; EXIT - (IOPID: LD HL,DEFDSEC ;PASS BACK DEFAULT DESCRIPTOR SECTOR LD DE,HDSECB LD BC,128 LDIR ; LD A,-2 ;DEFAULT IS EXTENDED T INITRAM: LD (HL),0 INC HL DJNZ INITRAM ; ; RESET THE HARD DISK CONTROLLER ; LD A,1 SHL SRESET ;RESET CONTROLLER CTOR BUFFER, IF APPLICABLE ; LD IY,LAXCDB ;USE XFER CDB CALL GETLUN CALL GETLAD ; CALL HDRDBUF ;REFRESH BUFFER WITH S XOR A CALL MOVFHST ; ; CHECK FOR ERRORS ; LD A,(IOPB + PBSTATO) ;IF NO ERROR THEN RETURN 0, NC OR A RET SB + PBSTATO)= 0 OR ERROR CODE ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ HDRECAL: ; ; TYPE ; ; RETURN THE DESCRIPTOR SECTOR FLAG TO HOST ; HDLOG2: LD (IOPB + PBST2O),A ;STORE THE DESCRIPTOR SECTOR TYPE ; ; 0 ( ) *!+",#-$.%/ &0 ' OUT SASICMD,A ; EX (SP),HL ;GIVE A LITTLE EXTRA TIME EX (SP),HL ; LD A,1 SHL SERRCLR ;RELEASE RESET OUT SASICMD,A ****************************************** HDWRBUF: ; ; SET UP CDB ; LD (IY+CMD),SCWRIT ;WRITE COMMAND ; LD (IY+NBK),********************************************************** HDRDBUF: ; ; IF BUFFER DATA VALID THEN SKIP PREREAD ; CALL QB+++++++++++++++++ QBUFR: ; ; IF NOT SAME DRIVE THEN RETURN NZ ; LD A,(IOPB + PBDRVO) ;CHECK DRIVE 1ST LD HL,BUFDRV CD A,(RETRYS) SUB A,1 LD (RETRYS),A JP NC,HDRDRTY ; ; ERROR OCCURRED, CLEAR BUFFER PTRS TO FORCE SUBSEQUENT READ ; C; ; CLEAR THE SECTOR BUFFER ; CALL CLRBUFR ;START WITH FRESH BUFFER READ ; ; SET UP THE JADE CONTROLLER POINTERS ; 1 ;ALLWAYS USE 1 BLOCK (SECTOR) ; ; EXECUTE THE COMMAND 1ST ; CALL XCDB6 ;SEND CDB RET NZ ; ; SET UP FOR DATA XFERUFR RET Z ; ; SET UP RETRY COUNT ; LD C,4 ;ASSUME RETRIES ; LD HL,IOPB + PBFLGO LD A,(HL) ;FETCH FLAGS BIT PBRP (HL) RET NZ ; ; IF SECTOR NOT SAME THEN RETURN NZ ; LD DE,(IOPB + PBSECO) ;NOW CHECK SECTOR ; RES 0,E ;CLEAR BLOCALL CLRBUFR ;BUFFER CONTAMINATED ; ; RETURN ERROR STATUS ; OR A,A ;CLRBUFR RETURNS -1 RET ; ; ; DATA REQUEST TRU HSTIN DDPORT ;FETCH FDC ADDRESS AND DDSASW RLCA OR HIGH DDBASE LD H,A LD L,0 LD (FDADDR),HL ; ; ALL DONE ;  ; LD BC,[HDBUFSZ SHL 8] + SASIDATA ;SET COUNT, PORT LD HL,HDSECB ; ; WAIT FOR DATA REQUEST ; HDWRLP: CALL GETSTAT ;TRY,A JR Z,HDRTRY1 ; LD C,0 ;IF NO RETRIES ALLOWED THEN COUNT = 0 ; HDRTRY1: LD A,C LD (RETRYS),A ; ; SEND RETRYKING BIT ; LD HL,(BUFSEC) SBC HL,DE RET NZ ; ; IF TRACK NOT = THEN RETURN NZ ; LD DE,(IOPB + PBTRKO) ;LAST, CHECK E, XFER THE DATA ; HDRD2: INI ;*PTR++ = SASI DATA; CNT-- JP NZ,HDRDLP ; ; XFER OVERFLOW (CONTROLLER REQUESTED MORE DATRET ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; SELECT DRIVE FUNCTION ; EXIT - NZ=IF READY THEN BIT SREQ,A JR Z,HDWRLP ; ; IF DATA REQUEST THEN GO XFER IT ; AND SSXMSK ; IF DATA READY THEN PUT IT  DISABLE FLAG TO CONTROLLER ; LD A,(HL) ;CHECK FOR CONTROLLER RETRY DISABLE AND 80H LD (IY + RTY),A ; ; EXECUTE THE TRACK LD HL,(BUFTRK) SBC HL,DE RET ;**************************************************************************** ; A THAN 1 SECTOR'S WORTH) ; DETERMINE WHAT CONTROLLER WANTS & RE-SYNC SASI BUS ; HDRDOV: CALL GETSTAT ;IF READY THEN INPUT  ERROR ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ HDSELCT: ; ; IF CURRENT DRIVE == R CP SGTDAT JP Z,HDWR2 ; ; IF STATUS MODE THEN GET IT ; CP SSNDST ; ELSE IF READY FOR STATUS THEN GET IT JP NZ,HDRREAD COMMAND ; HDRDRTY: LD (IY+CMD),SCREAD ;READ COMMAND LD (IY+NBK),1 ;ALLWAYS USE 1 BLOCK (SECTOR) ; CALL XCDB6 ;SEN; CLEAR BUFFER SUBR ; EXIT - A= -1 ; ;**************************************************************************** CLRBUFR: DATA BIT SREQ,A JR Z,HDRDOV ; AND SSXMSK CP SSNDST ;IF READY FOR STATUS THEN GET IT JP Z,HDRDDN ; ; IGNORE THE EEQUESTED DRIVE THEN RETURN ; LD A,(IOPB + PBDRVO) ;IF REQUESTED DRIVE = CURRENT DRIVE THEN LD HL,CURDRV SUB A,(HL) RET WFER ; ELSE UNKNOWN CONDITION! ; JP GETRES ; ; ; DATA REQUEST, XFER DATA ; HDWR2: OUTI ;SASI DATA = *PTR++; CNT-- D CDB RET NZ ;IF ERROR HERE THEN HARD ERROR! ; ; SET UP FOR DATA XFER ; LD BC,[HDBUFSZ SHL 8] + SASIDATA ;SET COUNT, P ; ; STORING -1 INTO DRIVE FORCES A READ ; LD A,-1 LD (BUFDRV),A RET ;*******************************************XCESS DATA ; HDWASTE: CALL HDXWST ;OVERFLOW, WASTE DATA CALL GETRES ;FINISH UP ; ; ASSUME DATA BUFFER CONTAMINATED, Z ; RETURN ; ; TEST DRIVE READY ; LD IY,NULCDB ;USE NUL CDB LD (IY+CMD),SCRDY ;TEST READY COMMAND ; CALL GETLUN  JP NZ,HDWRLP ; ; DATA XFER COUNT EXHAUSTED, BETTER BE REQUESTING STATUS NOW ; HDWROV: CALL GETSTAT ;OVERFLOW, WASTE DATORT LD HL,HDSECB ;XFER PTR ; ; WAIT FOR DATA REQUEST ; HDRDLP: CALL GETSTAT ;IF NOT READY THEN WAIT BIT SREQ,A JR********************************* ; ; MAKE BUFFER PTRS = PB PTRS ; ;********************************************************CLEAR IT! ; HDRWFER: CALL CLRBUFR ;BUFFER CONTAMINATED ; ; RETURN UNKNOWN FIRMWARE ERROR ; LD A,FERR08 ; UNKNOWN C;REQUEST LUN FROM USER CALL XCDB6 ;EXECUTE CDB RET NZ ;NOT READY, EXIT ; ; GET RESULTS ; CALL GETRES ;GET RESULT BA BIT SREQ,A JR Z,HDWROV ; AND SSXMSK CP SSNDST JP NZ,HDWASTE ;IF NOT STATUS THEN WASTE DATA ; ; STATUS IS BEING  Z,HDRDLP ; AND SSXMSK ; IF DATA READY THEN GET IT CP SSNDDAT JP Z,HDRD2 ; CP SSNDST ; ELSE IF NOT READY FOR STA******************** MAKSAME: ; ; STORE IOPB PTRS INTO BUFFER PTRS ; LD A,(IOPB + PBDRVO) LD (BUFDRV),A LD HL,(IOPB ONDITION, USE HANDSHAKE JP IOPBERR ;**************************************************************************** ; ; WRYTE RET ;CAN'T EVEN GET RESULT STATUS..HARD ERROR ;********************************************************************REQUESTED, GO GET IT ; JP GETRES ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; QUETUS THEN ERR JR NZ,HDRWFER ; ; OPERATION DONE, GET RESULTS ; HDRDDN: CALL GETRES ; ; BUFFER CONTAINS GOOD DATA, SET + PBTRKO) LD (BUFTRK),HL LD HL,(IOPB + PBSECO) RES 0,L ;CLEAR BLOCKING BIT 1ST LD (BUFSEC),HL RET ;*************ITE HD SECTOR FROM BUFFER SUBR ; ENTRY- IY= CDB PTR ; CDB= SET UP ; EXIT - NZ= ERROR ; ;****************************************** ; ; READ HD SECTOR INTO BUFFER SUBR ; ENTRY- IY= CDB PTR ; CDB= SET UP ; EXIT - NZ= ERROR ; ;******************RY BUFFER THE SAME FUNCTION ; EXIT - ZF= SAME ; NZ= NOT SAME ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++BUFFER PTRS ; PUSH AF CALL Z,MAKSAME ;MAKE BUFFER PTRS REFLECT DISK DATA POP AF RET Z ; ; ELSE CHECK RETRIES ; L 0 ( ) *!+",#-$.%/ &0 '*************************************************************** ; ; READ DATA FROM HOST IOPB SUBR ; MOVES 128 BYTES FROM (PED THEN EXIT ; MOV3: JP PO,MOV6 ;IF DONE THEN RETURN ; ; IF NO ROLLOVER THEN DO NEXT ; EX AF,AF' BIT 7,D ;IF NOT ROSTINATION PTR LD A,(IOPB + PBDMAXO) ;SET BANK REGISTER LD BC,128 ;MOVE 128 BYTES ;***********************************RETURN THE RESULTS ; JP GETRES ;FINISH UP ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ INSURE DIRECTION FLAGS ARE SET ; EX AF,AF' ;SET FLAGS OR A EX AF,AF' ; ; SET UP BIT 15 REGISTER ; LD A,D ;SET BDMA) TO (HL) ; ENTRY- HL= DESTINATION PTR ; EXIT - BC, DE, HL= ? ; ;*******************************************************LLOVER THEN REPEAT JP NZ,MOV4 ; ; ELSE TOGGLE HOST BIT 15 ; LD A,I ;TOGGLE BIT 15 CPL LD I,A OUT (HXAD15),A ; ***************************************** ; ; BLOCK MOVE TO HOST SUBR ; ENTRY- HL= LOCAL PTR (SRC) ; DE= HOST PTR (DST) ;  ; ; GET STATUS FUNCTION ; EXIT- A= STATUS WORD ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++BIT 15 OUT (HXAD15),A ; ; CHECK FOR LONG MOVE ; DEC BC ;IF > 32K MOVE THEN DO LONG WAY LD A,B CP 32768 / 256 JR ********************* HDHSTR: LD DE,(IOPB + PBDMAO) ;GET DESTINATION PTR LD A,(IOPB + PBDMAXO) ;SET BANK REGISTER LD BC,128; IF BIT 15 TOGGLED TO 0 THEN BUMP EXTENDED ADDRESS ; BIT 7,A JP NZ,NO64KX ; LD A,(MOVX) INC A LD (MOVX),A OUT ( BC= BYTE COUNT ; A= BANK ADDRESS (DST) ; EXIT - DE= DE + BYTE COUNT ; HL= HL + BYTE COUNT ; A, BC= ? ; ;**************++++ GETSTAT: IN A,SASIST ;GET STATUS WORD AND SSTMSK ;REMOVE UNUSED BITS XOR SSTINV ;INVERT SOME RET ;+++++++++NC,DOLONG ; LD A,E ;IF 64K CROSS THEN DO LONG WAY ADD C LD A,D ADC B JR C,DOLONG ; XOR D ;IF 32K CROSS THEN DO L ;MOVE 128 BYTES ;**************************************************************************** ; ; BLOCK MOVE FROM HOST HXADDR),A JP NO64KX ;**************************************************************************** ; ; WASTE OVERFLOW DA************************************************************** MOV2HST: ; ; SET UP EXTENDED ADDRESS REGISTER ; LD (MOVX)+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; TRANSMIT CDB FUNCTION ; ENTRY- IY= CDB TO XMIT PTR ;ONG WAY JP M,DOLONG ; ; SET UP FOR BLOCK MOVE INSTRUCTION ; INC BC ;RESTORE COUNT ; SET 7,D ;INSURE S100 MAP ; ;SUBR ; ENTRY- HL= LOCAL PTR (DST) ; DE= HOST PTR (SRC) ; BC= BYTE COUNT ; A= BANK ADDRESS (SRC) ; EXIT - HL= DE + BYTE CTA SUBR ; ;**************************************************************************** HDXWST: ; ; WAIT UNTIL DATA REQUE,A ;SAVE EXTENDED ADDRESS VALUE FOR BUMPING OUT (HXADDR),A ; ; PASS DIRECTION TO MOVER ; LD A,1 ;TRANSFER TO S100 OR EXIT - NZ= ERROR ; BC= ? ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ XCDB6: ; ; ISSU SET DIRECTION ; EX AF,AF' ;IF FROM S100 THEN JP NZ,MOV1 ; EX DE,HL ; SWAP ; ; DO FAST MOVE ; MOV1: LDIR ; OUNT ; DE= HL + BYTE COUNT ; A, BC= ? ; ;**************************************************************************** MOVST ; CALL GETSTAT ;IF READY THEN INPUT DATA BIT SREQ,A JR Z,HDXWST ; ; IF READY FOR STATUS THEN RETURN FOR STATUS ; A EX AF,AF' ;**************************************************************************** ; ; MOVE SUBR CHECKS FOR A ME CONTROLLER SELECT PER SHUGART MANUAL ; LD A,[1 SHL HDCONT] ;SELECT DB0 OUT SASIDATA,A ; LD A,[1 SHL SSELECT] OR [1 SHL; RESTORE PTRS ; JP NZ,MOV6 ; EX DE,HL ; SWAP BACK ; ; RETURN NO ERRORS ; MOV6: EX AF,AF' XOR A RET ; ; ;FHST: ; ; SET EXTENDED ADDRESS REGISTER ; LD (MOVX),A ;SAVE EXTENDED ADDRESS FOR BUMPING OUT (HXADDR),A ; ; PASS DI AND SSXMSK CP SSNDST ;IF READY FOR STATUS THEN GET IT RET Z ; ; XFER DATA & IGNORE ; LD A,0E5H ;OUTPUT WILL ALSOOVE CROSSING ANY 32K BOUNDARY ; AND SELECTING A FAST BLOCK MOVE IF NOT, AND A SLOWER BLOCK MOVE ; WHICH CHECKS AFTER EACH BYTE SERRCLR] ;OUTPUT STROBE OUT SASICMD,A ; ; INIT TIMEOUT COUNT ; LD BC,0 ; ; WAIT FOR BUSY ; BSYWT2: CALL GETSTAT  LONG TRANSFER PART TESTS EACH BYTE FOR THRESHOLDS ; DOLONG: ; ; SET UP ; INC BC ;RESTORE COUNT ; LD A,D ;SET UPRECTION TO MOVER ; XOR A ;TRANSFER FROM S100 EX AF,AF' JP MOVIT ;************************************************** DO FOR INPUT OUT SASIDATA,A JR HDXWST ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; FOR AN OVERFLOW CONDITION IF TRUE. ; ENTRY- HL= LOCAL MEMORY PTR ; DE= S100 MEMORY PTR ; BC= BYTE COUNT TO TRANSFER ; AF ;WAIT FOR BUSY BIT SBUSY,A JR NZ,BSYOK2 ; DEC BC ;CHECK FOR TIMEOUT LD A,C OR B JR NZ,BSYWT2 ; ; TIMED OUT, R CURRENT BIT 15 LD I,A ; NO64KX: SET 7,D ;INSURE S100 ; ; SET DIRECTION ; MOV4: EX AF,AF' ;IF HL= S100 THEN JP NZ,************************** ; ; WRITE DATA TO HOST IOPB SUBR ; MOVE 128 BYTES OF DATA FROM (HL) TO (PBDMA) ; ENTRY- HL= SOU ; RECALIBRATE FUNCTION ; EXIT - NZ= ERROR ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ '= 0: XFER FROM S100 MEMORY TO LOCAL MEMORY ; 1: XFER FROM LOCAL MEMORY TO S100 MEMORY ; ; EXIT - AF, AF'= ? ; BC= 0 ETURN TIMEOUT ERROR ; LD A,FERR07 ;HANDSHAKE TIMEOUT ERR JP IOPBERR ; ; ; CONTROLLER WENT BUSY, CLEAR SELECT STROBE ;MOV2 ; EX DE,HL ; ; MOVE 1 BYTE ; MOV2: LDI ; ; RESTORE PTRS ; JP NZ,MOV3 ; EX DE,HL ; ; IF COUNT EXHAUSTRCE PTR ; ;**************************************************************************** HDHSTW: LD DE,(IOPB + PBDMAO) ;GET DERECALC: ; ; EXECUTE THE COMMAND ; LD IY,NULCDB LD (IY+CMD),SCREC ;RECAL COMMAND CALL GETLUN ; CALL XCDB6 ; ;  ; HL= HL + BC ; DE= DE + BC ; ;**************************************************************************** MOVIT: ; ;  0 ( ) *!+",#-$.%/ &0 ' BSYOK2: LD A,1 SHL SERRCLR ;REMOVE SELECT STROBE OUT SASICMD,A ; ; CHECK FOR COMMAND MODE ; XCDB2: CALL GETSTAT BIT. TEST COMMAND PORT WITH INTERRUPTS DISABLED ; C. TEST INTERRUPT WITH ILLEGAL COMMAND & TEST STATUS ; 4. TEST SASI: ; A. TE CHECK FOR CONTROLLER PARITY ERROR ; BIT 1,A ;IF CONTROLLER PARITY ERROR THEN EXIT JR Z,HDPERR ; ; ISSUE REQUEST SENNXTPRT ; ; POSSIBLE PORT FOUND ; LD A,0AAH ;CHECK OTHER DATA PATTERN OUT (HDATA),A IN A,(C) CP A,0AAH ; ; RESUT DRIVE # INTO PROPER CDB FIELD ; RRCA RRCA RRCA ; ; STORE INTO ALL CDBS ; LD (NULCDB + LUN), A LD (LAXCDB + LU SREQ,A ; WAIT FOR REQUEST JR Z,XCDB2 ; BIT SCD,A ;IF NOT COMMAND THEN ??? JR NZ,XOK ; ; NOT COMMAND MODE, RETURN CST SASI INTERRUPT & RESULTANT ERROR. ; B. TEST SASI PARITY BY DESLECTING & OUTPUTTING ODD/EVEN DATA ; C. TEST REQUEST BY SELSE COMMAND ; LD (IY+CMD),SCSNSE CALL XCDB6 RET NZ ;HARD ERROR ; ; READ 4 BYTES OF STATUS INTO IOPB ; GETR1: LD HL,TORE DATA PATTERN BEFORE RETURNING ; LD A,55H OUT (HDATA),A JR NZ,NXTPRT ; ; PORT FOUND, SAVE PORT # ; DEC C ;SEAN), A LD (IDRCDB + LUN), A RET ;**************************************************************************** ; ; GET ONTROLLER SYNC ERROR ; XCDBER: LD A,FERR08 ;CONTROLLER SYNC ERROR JP IOPBERR ; ; ; READY FOR COMMAND, SET UP FOR CDB XFECTING CONTROLLER & SENSING REQUEST ETC. ; D. TEST DRIVE READY ON DRIVE 0 ; ;***********************************************IOPB + PBSTATO ;READ SENSE STATUS BYTES LD BC,[4 SHL 8] + SASIDATA ; GETR2: GETDATA JR NZ,GETR2 ; ; READ STATUS OF SENRCHED DATA PORT IS BASE + 1, COMPENSATE LD A,C AND 7FH LD B,A LD A,I ;MERGE IN HOST BIT 7 AND 80H OR A,B LD (HPOLOGICAL ADDR FROM IOPB SUBR ; ENTRY- IY= CDB PTR ; ;*************************************************************************ER ; XOK: LD BC,[6 SHL 8] + SASIDATA ;BYTE COUNT IN B ; ; CHECK DIRECTION ; BIT SIO,A ;IF DIRECTION NOT OUT THEN ERR ***************************** PUTEST: ; ; CLEAR THE EXTENDED ADDRESS PORT TO TALK TO BANK 0 FIRST ; XOR A,A OUT (HXADDSE COMMAND ; GETR3: CALL GETSTAT ;FINISH OUT COMMAND BIT SREQ,A JR Z,GETR3 ; ; IF NO ERROR IN SENSE COMMAND THEN RETURT),A JR TST5 ; NXTPRT: INC C ;IF ++PORT == 0 THEN DONE THIS HALF JR NZ,TST4A ; LD A,I ;NOW DO 80H..FFH CPL LD *** GETLAD: ; ; XFER COUNT = SECTOR SIZE ; LD HL,256 ;SECTOR SIZE LD (BYTCNT),HL ; ; CALCULATE LOGICAL ADDRESS FR JR NZ,XCDBER ; ; SET XFER PTR PUSH IY POP HL ; ; XFER CDB DATA ; XCDB3: PUTDATA ;GET CDB DATA JR NZ,XCDB3 R),A ; ; TEST HOST LOCATION 0F800H FOR 0C3H ; LD A,-1 OUT (HXAD15),A LD A,(0F800H) SUB A,0C3H JR Z,TST2 ; ; ERN ERROR ; IN A,(C) ;GET RESULT BYTE OF COMMAND AND 00000011B ;IF ERROR THEN HARD ERROR ; LD A,FERR09 JP NZ,IOPBERR I,A OUT (HXAD15),A BIT 7,A ;IF TOGGLED FROM 1 TO 0 THEN DONE JR NZ,TST4B ; LD A,-4 ;NOT FOUND SO ERROR JP FERR ;OM SECTOR & TRACK ; LD A,(IOPB + PBSECO) ;FETCH SECTOR LD E,A ; LD A,(IOPB + PBTRKO) ;PICK UP TRACK LSB & PUT INTO LA0 B ; ; DONE WITH CDB, CONTROLLER SHOULD BE WAITING FOR DATA XFER OR RESULT ; XOR A ;RETURN NO ERRORS RET ;++++++++++RROR! ; LD (IOPBL),A LD A,-1 JP FERR ; ; NON-DESTRUCTIVE TEST HOST LOCATION 100H ; TST2: OUT (HXAD15),A ;A HAS 0; OR A,A ;ERROR ANYWAY RET ; ; ; PARITY ERROR ENCOUNTERED ; HDPERR: ; ; CLEAR THE PARITY ERROR LATCH ; XOR A  ; TEST HOST STATUS/COMMAND PORT ACCESS (DATA PORT ALREADY TESTED) ; TST5: LD A,55H OUT (HSTAT),A IN A,(C) ;C ALREADY IT 7 SRL A ; SECTOR BIT 0 IS WASTED RR E LD (IY+LA0),E ;PHEW! LA0 DONE ; LD (IY+LA1),A ;LA1 HAPPENS TO BE IN A R++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; GET CONTROLLER RESULTS FUNCTION ; EXIT - NZ= HARD ERRO FROM PREVIOUS TEST ; LD HL,S1MEM + 100H LD A,(HL) LD C,A CPL LD (HL),A LD B,(HL) CP B CPL LD (HL),A JR Z,T ;CLEAR ERROR OUT (SASICMD),A LD A,1 SHL SERRCLR OUT (SASICMD),A ; ; RETURN PARITY ERROR CODE ; LD A,FERR11 ;RETURNHAS STATUS/COMMAND PORT # CP A,55H JR NZ,TST5A ; LD A,0AAH OUT (HSTAT),A IN A,(C) CP A,0AAH OR 1 ;BUSY BIT IS SET ET ;**************************************************************************** ; ; POWER UP TESTS PERFORM THE FOLLOWINGR ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ GETRES: ; ; SET UP TO RETURN RESULT IN ST3 ; LD (IOPBL),BC ;RETURN FAILURE DATA LD A,-2 JP FERR ; ; 32K BOUNDARY TEST ; TST3: ;NOT IMPLEMENTED ; ; FIN PARITY ERROR JP IOPBERR ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; GET LUN FROM JR Z,TST6 ; TST5A: LD A,-5 JP FERR ; ; TEST COMMAND PORT ; TST6: DI ;NO INTERRUPTS LD A,55H OUT (C),A IN A,(H: ; 1. TEST HOST DMA ACCESS: ; A. READ LOCATION 0F800H FOR 0C3H. ; B. NON-DESTRUCTIVELY TEST LOCATION 100H ; C. TEST 32K IOPB ; LD HL,RSTAT ;INSURE DESTINATION CORRECT LD C,SASIDATA GETDATA ;GET RESULT STATUS BYTE ; ; CHECK FOR HARDWARED OWN PORT NUMBER IN HOST MEMORY ; TST4: LD A,55H ;START WITH DATA IMAGE OUT (HDATA),A ; XOR A,A ;START WITH BANK 0 USER FUNCTION ; ENTRY- IY= CDB PTR ; EXIT - BC, DE, AF= ? ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++CMD) CP A,55H JR NZ,TST6A ; LD A,2AH ;NOTE: AAH WOULD RESET THE PROCESSOR OUT (C),A IN A,(HCMD) CP A,2AH JR Z,TSBOUNDARY (A15). ; 2. FIND OWN PORT # IN HOST SPACE. ; 3. TEST PORT REGISTERS: ; A. READ/WRITE TEST DATA & STATUS PORTS ; B PARITY ERROR ; BIT SPERR,A JR NZ,HDPERR ; ; IF NO ERROR THEN RETURN ZF ; LD A,(RSTAT) AND 00000011B RET Z ; ; OUT (HXAD15),A LD I,A ; TST4B: LD C,[0 OR 80H] ;PORT # ; TST4A: IN A,(C) ;SEARCH FOR 1ST PATTERN CP A,55H JR NZ,++++++++++++++ GETLUN: ; ; FETCH & CONDITION THE DRIVE # ; LD A,(IOPB + PBDRVO) ;FETCH DRIVE # AND 00000011B ; ; P 0 ( ) *!+",#-$.%/ &0 'T7 ; TST6A LD A,-6 JP FERR ; ; TEST HOST INTERRUPT WITH ILLEGAL COMMAND ; TST7: LD A,3FH ;USE AN UNSUPPORTED COMMANLD (MOVX),A OUT (HXADDR),A RET SUBTTL CONSTANTS ;######################################################################DATA) ;CLOCK PARITY CHECK IN A,(SASIST) ;CHECK BIT BIT SPERR,A JR Z,TST9 ;DATA == 1 THEN NO PARITY ERROR ; TST8A: LD A,B IOPBXA DS 1 ;BANK ADDRESS OF IOPB ; CURDRV DS 1 ;CURRENT DRIVE SELECTED BYTCNT DS 2 ;SECTOR SIZE RETRYS DS 1 ;RETRY COUNANK ADDRESS (IOPBXA) ; I, HOST BIT 15 REGISTER= IOPB_PTR HOST BIT 15 IN BIT 7 ; ;*******************************************D OUT (C),A ; PUSH BC EI ;ALLOW INTERRUPT NOP ;NEXT INSTRUCTION GETS EXECUTED NOP ;THIS INSTRUCTION SHOULD GET ###### ; ; DEFAULT DISK DESCRIPTOR SECTOR FOR LOGON ; ;#####################################################################-8 JP FERR ; ; SASI DATA REQUEST INTERRUPT TEST ; TST9: ; ; SASI REQUEST BIT TEST ; TST10: ; ; SASI COMMUNICATT MOVX DS 1 ;HOST BANK ADDRESS SAVE FOR BLOCK MOVE SUBRS FDADDR DS 2 ;FDC ADDRESS PTR TIMOUT DS 2 ;UNSELECT SASI DELAY HPORT********************************* SETPTRS: LD HL,(IOPBL) ;FETCH IOPB BASE ADDRESS LD A,(IOPBXA) OUT (HXADDR),A ;SET THE BINTERRUPTED ; DI ;RESTORE BUSY STATUS OUT (HINTS),A ; POP BC ;FETCH STATUS IN A,(C) AND A,0FEH ;MASK OFF BUSY B####### DEFDSEC: DB 0,0,0 ;POSSIBLE JUMP VECTOR IDTXT: DB 'Disk Descriptor Sector' IDSZE EQU $ - IDTXT ; REPT DEFDSEC +ION TEST ; TST11: CALL INIT ;INIT CDB, IOPB LD IY,TESTCDB LD (IY + CMD),SCRDY ;DO A TEST DRIVE READY COMMAND CALL XCDB6 DS 1 ;HOST'S BASE PORT # FOR DATA REGISTER ;############################################################################ ANK ADDRESS LD (MOVX),A ; LD A,H ;SELECT HOST BIT 15 OUT (HXAD15),A LD I,A ;SAVE IN INTERRUPT REGISTER SET 7,H ;SEIT CP A,HFERR JR NZ,TST7A ; INC C ;TEST COMMAND ERROR IN A,(C) CP A,FERR03 JR Z,TST8 ; TST7A: LD A,-7 JP FERR  20H - $ LIST OFF DB 0 LIST ON ENDM DW 128 ;SPT DB 5 ;BSH DB 31 ;BLM DB 1 ;EXM DW 1015 ;DSM DW 1152 / 2 JR NZ,TST11A ; CALL GETRES ;FETCH COMMAND RESULTS JR NZ,TST11A ; LD A,(IOPB + PBSTATO) ;TEST FOR ERROR OR A JR ; ; I/O PARAMETER BLOCK SAVE AREA ; ;############################################################################ IOPB DS IOT LOCAL BIT 15 RET ;**************************************************************************** ; ; BUMP HL FUNCTION C ; ; TEST SASI PARITY ERROR DETECTION ; TST8: XOR A,A ;DESELECT CONTROLLER OUT (SASIDATA),A LD A,1 SHL SSELECT OUT ;DRM DB 0FFH ;AL0 DB 80H ;AL1 DW 0 ;CKS DW 2 ;OFF ; REPT DEFDSEC + 30H - $ LIST OFF DB 0 LIST ON ENDM Z,TST12 ; TST11A: CALL DESELECT LD A,-11 ;PASS ERROR TO HOST JP FERR ; ; END OF TESTS ; TST12: ; ; FALL INTO DEPBSZ ; PBRTRY EQU PBNRT ;RETRY DISABLE BIT ;############################################################################ARRIES THROUGH TO HOST BIT 15 & BANK ADDRESS ; ENTRY- HL= HOST ADDRESS ; I= HOST BIT 15 IN BIT 7 ; (MOVX)= BANK ADDRESS IMA (SASICMD),A ; LD A,1 SHL SERRCLR ;ENABLE PARITY DETECTION OUT (SASICMD),A ; IN A,(SASIST) ;TEST PARITY STROBE GATE BIDB 0 ;STAGGER (NOT USED) DB [1 SHL DFDBLB] OR [1 SHL DFHARDB] OR [1 SHL DFTSDB] ; 256 B/S, HARD DISK, 2 SIDED DB 64,64,SELECT ; ;**************************************************************************** ; ; DESELECT SASI BUS SUBROUTINE  ; ; HARD DISK SECTOR BUFFER ; ;############################################################################ HDBUFSZ EQU 25GE ; EXIT - HL= HL + 1 (BIT 15 SET) ; I= HOST BIT 15, INCLUDING ANY CARRY ; (MOVX), BANK ADDRESS= UPDATED IF HOST BIT 15 CAT SPERR,A JR NZ,TST8A ;IF PARITY ERROR NOW THEN NOT INHIBITED ; IN A,(SASIDATA) ;CLOCK THE PARITY DATA IN A,(SASIST) ;WIT64 ;PHYSICAL SPT (0,1,DATA) ; REPT DEFDSEC + 128 - $ LIST OFF DB 0 LIST ON ENDM DB 0 IF $ >= (LOCROM + ROMSIZE)  ; EXIT - A= ? ; ;**************************************************************************** DESELECT: XOR A,A ;DESELECT6 HDSECB DS HDBUFSZ ; RSTAT DS 1 ;COMMAND STATUS RETURNED ; BIT 1: ERROR (ISSUE SENSE COMMAND) ; BIT 5..7: LUN BUFDRRRIED ; A= ? ; ;**************************************************************************** BUMPHL: INC HL ;PTR++ BIT 7H DATA == 0 THEN S/B PARITY ERROR BIT SPERR,A JR Z,TST8A ; XOR A,A ;DISABLE PARITY DETECTION TO STOP GLITCHES OUT (SAS; PROTECTION MESSAGE CONMSG **** ERROR! CODE TOO LARGE FOR DECLARED PROM SIZE! **** ENDIF SUBTTL RAM AREA ORG LOCRAM OUT (SASIDATA),A LD A,[1 SHL SSELECT] OR [1 SHL SERRCLR] OUT (SASICMD),A ; LD A,1 SHL SERRCLR ;LEAVE PARITY ERROR DETEV DS 1 ;BUFFER CONTENTS DRIVE BYTE BUFSEC DS 2 ;BUFFER CONTENTS SECTOR WORD BUFTRK DS 2 ;BUFFER CONTENTS TRACK WORD ;####,H ;IF NO BIT 15 CARRY THEN RETURN RET NZ ; SET 7,H ;SET LOCAL BIT 15 LD A,I ;COMPLEMENT HOST BIT 15 CPL OUT (HXADICMD),A ; INC A ;FORCE AN EVEN PARITY BIT GENERATION OUT (SASIDATA),A LD A,1 SHL SERRCLR ;RE-ENABLE PARITY DETECTION O ;############################################################################ ; ; VARIABLES ; ;###########################CTION ENABLED OUT (SASICMD),A RET ;**************************************************************************** ; ; S######################################################################## ; ; JADE SECTOR BUFFER ; ;#########################15),A LD I,A BIT 7,A ;IF NO HOST BIT 15 CARRY INTO BANK THEN RETURN RET NZ ; LD A,(MOVX) ;BUMP BANK ADDRESS INC A UT (SASICMD),A ; IN A,(SASIST) ;RE-CHECK THE GATE BIT SPERR,A JR NZ,TST8A ;IF PARITY ERROR NOW THEN ERROR ; IN A,(SASI################################################# IOPBL DS 1 ;LOW ADDRESS OF IOPB TO EXECUTE IOPBH DS 1 ;HIGH ADDRESS OF IOPET ADDRESS PTRS FROM IOPB_PTRS FUNCTION ; EXIT - HL= IOPB PTR (BIT 15 SET FOR HOST ACCESS) ; A, BANK ADDRESS REGISTER= IOPB B 0 ( ) *!+",#-$.%/ &0 '################################################### JADSECB DS 256 ;###################################################### - 32) CONMSG **** ERROR! DATA TOO LARGE FOR DECLARED RAM SIZE! **** ENDIF DS 32 STACK EQU LOCRAM + RAMSIZE END HABAS EQU 0D8H ;BASE ADDRESS OF ISHA PORTS HDATA EQU ISHABAS + 1 ;HOST INTERFACE DATA I/O PORT ; ;==========================E SECTOR HDFREL DS 1 ;(48) TRACK FREE SPACE SECTOR COUNT ; HDCCPS DS 1 ;(3) START SECTOR OF CP/M CCP HDCCPL DS 1 ;(16) CP/M ###################### ; ; DISK CONTROLLER COMMAND DESCRIPTOR BLOCKS (CDB) ; ;##############################################================================================== ; ; STATUS PORT ; ;===================================================CCP SECTOR COUNT ; HDBDOSS DS 1 ;(19) START SECTOR OF CP/M BDOS HDBDOSL DS 1 ;(28) CP/M BDOS SECTOR COUNT ; HDBLTS DS 1 ;(5############################## NULCDB: DS 6 ;NO TRANSFER CDB LAXCDB: DS 6 ;MAIN XFER CDB IDRCDB DS 6 ;ID SECTOR READ CDB ========================= HSTATUS EQU ISHABAS ;HOST INTERFACE CONTROL/STATUS INPUT PORT ; ; 7 0 ; | | | | | | | | |4) START SECTOR OF JADE CONTROLLER BLT HDBLTL DS 1 ;(1) JADE CONTROLLER BLT SECTOR COUNT ; HDDCMS DS 1 ;(56) START SECTOR OF TESTCDB DS 6 ;TEST CDB CDBINIT EQU $ - NULCDB ; ; CDB OFFSETS ; STRUCT 0 CMD DS 1 ;COMMAND LUN DS 1 ;LOGICAL UNIT NUMBE SUBTTL INTELLIGENT SASI HOST ADAPTER HOST DEFINITIONS ;*********************************************************************** ; ^ ^ ^___ 1: ADAPTOR BUSY, 0: ADAPTOR FREE ; | |_____ 1: FIRMWARE ERROR ; |_________________ 1: ERROR ; JADE CONTROLLER DCM HDDCML DS 1 ;(9) JADE CONTROLLER DCM SECTOR COUNT ; HDBIOSS DS 1 ;(65) START SECTOR OF CP/M BIOS HDBIOSLR IN BITS 5..7 LA2 EQU LUN ;LOGICAL ADDRESS 2 IN BITS 0..4 LA1 DS 1 ;LOGICAL ADDRESS 1 LA0 DS 1 ;LOGICAL ADDRESS 0 ILV DS 1 ***** ; ; THIS MODULE DEFINES THE ISHA DEFINITIONS NEEDED BY A HOST COMPUTER TO ; INTERFACE ITS SOFTWARE TO THE ISHA BOARD AN ; BIT DEFINITIONS: HBUSYB EQU 0 ;HOST BUSY STATUS BIT HFERRB EQU 1 ;HOST FIRMWARE ERROR BIT HERRB EQU 7 ;HOST ERROR BIT DS 1 ;(14) CP/M BIOS SECTOR COUNT ENDM ; HCCPSEC EQU 3 ;1ST SECTOR OF CCP HBDOSEC EQU 19 ;1ST SECTOR OF BDOS HBLTSEC EQU ;FORMAT COMMAND INTERLEAVE FACTOR NBK EQU ILV ;XFER COMMANDS BLOCK (SECTOR) COUNT RTY DS 1 ;RETRY FLAG 0: RETRY 3 TIMES, 80H: D ITS FIRMWARE. ; ;**************************************************************************** ; ; REVISIONS: ; ; 1.0 - 1 ; ;============================================================================ ; ; HOST COMMAND PORT ; ;==============54 ;1ST SECTOR OF JADE BIOS LOADER TRANSIENT HDCMSEC EQU 56 ;1ST SECTOR OF JADE DISK CONTROLLER MODULE HBIOSEC EQU 65 ;1ST SECNO RETRYS LUND EQU RTY ;COPY COMMAND DEST. LUN IN BITS 5..7 LA2D EQU RTY ;COPY COMMAND DEST. LOGICAL ADDR 2 IN BITS 0..4 LA1D8 MAR 84 GRH ; Removed from the HDMON program and extended for the Boot PROM. ; ; 1.1 - 22 FEB 86 GRH ; Removed extraneo;**************************************************************************** ; ; M5B HARD DISK DEFINITION FILE ; ;********============================================================== HCMD EQU HSTATUS ;HOST INTERFACE COMMAND PORT ; ; 7 0TOR OF CBIOS HFRESEC EQU 79 ;1ST SECTOR OF FREE SECTORS  DS 1 ;COPY COMMAND DEST. LOGICAL ADDR 1 LA0D DS 1 ;COPY COMMAND DEST. LOGICAL ADDR 0 CDBSPR DS 1 ;COPY COMMAND SPARE RTYD DSus definitions already defined in 'COMIOPB.DEF' file. ; Improved the bit definitions. ; Changed 'ISASI' to 'ISHA'. ; ;************************************************************************** ; ; REVISIONS: ; ; 1.0 - 13 FEB 86 GRH ; RELEASE ;  ; | | |0| | | | | | ; ^ ^ \_____/ ^___ 1: HOST INTERRUPT FOR COMMAND ; | | |________ COMMANDS (SEE BELOW) ; | |_____ 1 ;COPY COMMAND RETRY FLAG CDBSIZ DS 0 ENDM ;##########################################################################********************************************************************** ;===================================================== ;**************************************************************************** ; HIDSEC EQU 0 ;DISK DESCRIPTOR SECTOR HDIRSEC__________ 1: EXECUTE IOPB COMMAND ; |_________________ 1: RESET, 0: RELEASE THE ADAPTOR ; ; BIT DEFINITIONS: HINT EQU 0 ## ; ; STACK AREA ; ;############################################################################ IF $ > (LOCRAM + RAMSIZE======================= ; ; DATA PORT ; ;============================================================================ IS EQU 2 ;SYSTEM TRACK DIRECTORY SECTOR STRUCT 0 HDNTS DS 1 ;(6) NUMBER OF DIRECTORY ENTRIES HDFRES DS 1 ;(79) TRACK FREE SPAC 0 ( ) *!+",#-$.%/ &0 ' ;HOST INTERRUPT (CMD EXECUTE) BIT HXIOPBB EQU 6 ;HOST EXECUTE IOPB COMMAND BIT HRESET EQU 7 ;HOST ADAPTER RESET BIT ; ; gister contents (D1..7). ; ; 1.6 - 3 MAY 84 GRH ; Change block move subroutine to allow for 1..65,536 byte moves. ; Fix bu ;*INCLUDE JDDDISK.DEF ; LIST OFF *INCLUDE JDDCONT.DEF *INCLUDE JDDDISK.DEF LIST ON SUBTTL DEFINITIONS ;===========******************************************** ; ; REVISIONS: ; 1.0 - 28 DEC 83 GRH ; DIAGNOSTIC VERSION FOR TESTING THE BOA COMMANDS: ; HIOPBL EQU 00000001B ;SET IOPB LO ADDR CMD HIOPBH EQU 00000011B ;SET IOPB HI ADDR CMD HIOPBX EQU 00000101B ;SETgs in Jade driver. Add printer output diagnostic. ; ; 1.7 - 2 JUN 84 GRH ; Fix bug in HSTIN & HSTOUT macros outputting bit ==================== ; ; ASSEMBLY TIME CONSTANTS ; ;=============================== S100D EQU 0D8H ;DATA PORT VISIBLE TORD. ; 1.1 - 2 JAN 84 GRH ; ADD HARD DISK CONTROLLER FIRMWARE. ; 1.2 - 1 APR 84 GRH ; Fix Bug in host xfer subr. that cau IOPB XADDR CMD HDIAG0 EQU 00000111B ;DUMP FIRMWARE DIAGNOSTIC HDIAG1 EQU 00001001B ;ECHO DATA IN TO DATA OUT & STATUS REGS H7 data to XADDR ; register instead of to HXAD15 register. ; Add JADE FDC dump to dump diagnostic command. ; ; 1.8 - 2 JUN  S100 BUS S100S EQU S100D + 1 ;STATUS PORT VISIBLE TO S100 BUS S100C EQU S100S ;COMMAND PORT VISIBLE TO S100 BUS ; LOCPRTS sed problems on 32k boundary ; crossings. Enable parity checking for received data. Enable ; controller retrys. ; 1.3 - 2 APRDIAG2 EQU 00001011B ;TEST HOST MEMORY R/W HDIAG3 EQU 00001101B ;BLOCK MOVE HDIAG4 EQU 00001111B ;PRINT ASCII TEXT TO PORT HRE84 GRH ; Change floppy disk read/write sector to logical sector for uniformity ; in IOPB parameters. (0..N-1 now changed EQU 0 ;BASE ADDRESS OF LOCAL PORTS LOCMEM EQU 0 ;BASE ADDRESS OF LOCAL RAM ; S1PRTS EQU 80H ;BASE ADDRESS OF S100 PORTS ; 84 GRH ; Fix Bug in read buffer routine which caused 1st 4 bytes of sector ; to be 0 and read not retryed but sense status TF EQU 00010001B ;RETURN FIRMWARE VERSION ; HEXEC EQU (1 SHL HXIOPBB) + (1 SHL HINT) ;EXECUTE IOPB COMMAND ; ; END FILE to 1..N) ; ; 1.9 - 3 OCT 84 GRH ; Fix bug in Jade driver which allowed errors to go undetected. ; ; 1.A - 18 APR 85 GRH S1MEM EQU 8000H ;BASE ADDRESS OF S100 MEMORY WINDOW ; LOCROM EQU LOCMEM ;BASE ADDRESS OF LOCAL ROM LOCRAM EQU LOCMEM + 40to be issued instead. ; The CDB had to be re-initialized with the read command after getting ; results command issued. ; ; 1 ; Fix logon problem. Code is only now showing bugs with 2nd hard ; disk installed. ; 1.B - 6 DEC 85 GRH ; Changed code 00H ;BASE ADDRESS OF LOCAL RAM RAMSIZE EQU 2048 ;SIZE OF LOCAL RAM ROMSIZE EQU 2048 ;SIZE OF LOCAL ROM ;===============.4 - 28 APR 84 GRH ; Add Jade FDC routines. Change host block move subrs into general ; purpose subrs. ; ; 1.5 - 30 APR 8to return new values for logon. ; 2.0 - 31 JAN 86 GRH ; 1. Remove SASI floppy driver. ; 2. Streamline code for speed & stru TITLE INTELLIGENT SASI HOST ADAPTOR (ISHA) FIRMWARE LIST NOCOND ;***********************************************************============================================================= ; SASI BUS DATA LOCAL PORT ;==================================4 GRH ; Change hardware to reflect the state of the interrupt flip-flop ; as the busy bit (D0). Hardware will now allow softcture. ; 3. Modify error reporting (separate IOPB errors). ; 4. Modify Jade code to talk to new Jade firmware. ; 5. Modify di*************** ; ; THIS MODULE CONTAINS THE INTELLIGENT HOST ADAPTER FIRMWARE. ; ;*****************************************========================================== SASIDATA EQU LOCPRTS ;=========================================================ware setting of ; the interrupt flip-flop to allow passing a busy state if required. ; Normally this change will allow transpaagnostics to pass address data in IOPB_PTR. ; 6. Add reset (power on) diagnostics. ; VERSN EQU 20H ;********************************************************* ; ; IOPB CONFIGURATION: ; ; DRIVE USAGE ; 0 SASI physical drive 0 ; 1 SASI physic=================== ; SASI BUS CONTROL LOCAL PORT ;=========================================================================rent operation of the soft- ; ware, without concern to the busy status. All other status bits ; reflect the software status re************************************************** FALSE EQU 0 TRUE EQU NOT FALSE DEBUG EQU FALSE ; ;*INCLUDE JDDCONT.DEFal drive 1 ; 2 SASI physical drive 2 (OPTIONAL) ; 3 SASI physical drive 3 (OPTIONAL) ; ;******************************0 ( ) *!+",#-$.%/ &0 '=== SASICMD EQU LOCPRTS + 1 ; ; 7 6 5 4 3 2 1 0 ; |X|X|X| | | | | | ; ^ ^ ^ ^ ^__ INTERRUPT SELECT; 0: HOST, 1: ON SASI R 6 ;HOST A15 SET PORT ; ; 7 6 5 4 3 2 1 0 ; | |X|X|X|X|X|X|X| ; ^________________ BIT APPLIED TO HOST BUS A15 WHEN ACCESSI10110B ;XFER CONTROL MASK SGTCMD EQU 1 SHL SCD ;GET COMMAND FROM H/A SGTDAT EQU 0 ;GET DATA FROM H/A SSNDDAT EQU 1 SHL SIO ;ER FERR11 EQU -11 ;PARITY ERROR ;============================================================================ ; ; HARD DSKS: HFERR EQU (1 SHL HSERRB) + (1 SHL HFERRB) ;FIRMWARE ERROR BYTE ;=====================================================EQUEST ; | | | |____ 1: SASI RESET ; | | |______ 1: SASI DEVICE SELECT STROBE ; | |________ 0: SASI PARITY ERROR CLEAR ; NG ITS MEMORY ; AND BIT 7 WHEN ACCESSING ITS I/O ; ; BIT #S: A15B EQU 7 ;HOST A15 BIT ;=============================SEND DATA TO H/A SSNDST EQU (1 SHL SIO) + (1 SHL SCD) ;SEND STATUS TO H/A SCMDDN EQU (1 SHL SIO) + (1 SHL SCD) + (1 SHL SMSG) ISK DEFINITIONS ; ;============================================================================ HDCONT EQU 0 ;THIS CONTROLLE======================= ; HOST COMMAND LOCAL INPUT PORT ;=================================================================== |__________ 1: HOST VECTORED INTERRUPT ; ; BIT #S: SINTE EQU 0 ;SASI INTERRUPT SRESET EQU 1 ;SASI RESET SSELECT EQU 2 ;S=============================================== ; HOST EXTENDED ADDRESS LOCAL OUTPUT PORT ;==================================;COMMAND DONE ;============================================================================ ; HOST'S INTERRUPT CLEAR LOCAR'S ADDRESS BIT HDBASD EQU 0 ;BASE DRIVE # OF HD CONTROLLER HDNDRV EQU 4 ;NUMBER OF PHYSICAL DRIVES SUPPORTED HDNLUN EQU HD========= HCMD EQU LOCPRTS + 4 ;HOST COMMAND PORT ; ; 7 6 5 4 3 2 1 0 ; | | |0| | | | | | ; ^ ^ \_____/ ^__ 1: HOST INTASI DEVICE SELECT STROBE SERRCLR EQU 3 ;SASI PARITY ERROR CLEAR* HINT EQU 4 ;HOST VECTORED INTERRUPT ;============================================================= HXADDR EQU LOCPRTS + 7 ;EXTENDED ADDRESS PORT (A16..A23) ; ; 7 6 5 4 3 2 1 0 ; |L OUTPUT PORT ; (DATA= DON'T CARE) ;============================================================================ HINTC EQUNDRV INLEV EQU 6 ;INTERLEAVE FACTOR FOR FORMAT ;=========================================================================ERRUPT ; | | |_______ NON-IOPB COMMAND CODE (0..F) ; | |______________ 1: EXECUTE HOST IOPB ; |________________ 1: HA========================================================= ; SASI BUS STATUS LOCAL PORT ;==================================== | | | | | | | | ; ^ ^ ^ ^ ^ ^ ^ ^__ A16 ; | | | | | | |____ A17 ; | | | | | |______ A18 ; | | | | |________ A19 ; | | LOCPRTS + 2 ;============================================================================ ; HOST'S INTERRUPT SET LOCAL O=== ; ; SASI DEFINITIONS ; ;============================================================================ SCRDY EQU 0 ;TEST RDWARE LOCAL RESET ; ; BIT #S: HINTRB EQU 0 ;HOST INTERRUPT REQUEST BIT HIOPBB EQU 6 ;HOST EXECUTE IOPB BIT HRESB EQU 7 ======================================== SASIST EQU LOCPRTS + 1 ; ; 7 6 5 4 3 2 1 0 ; | |X|X| | | | | | ; ^ ^ ^ ^ ^ ^ | |__________ A20 ; | | |____________ A21 ; | |______________ A22 ; |________________ A23 ;=========================UTPUT PORT ; (DATA= DON'T CARE) ;============================================================================ HINTS EQU LOCDRIVE READY COMMAND SCREC EQU 1 ;RECALIBRATE SCSNSE EQU 3 ;REQUEST SENSE SCFMTD EQU 4 ;FORMAT ENTIRE DRIVE SCFMTT EQU 6 ;FOR;HOST RESET LOCAL PROCESSOR BIT ;============================================================================ ; HOST DATA__ 1: BUSY ; | | | | |____ 1: MESSAGE ; | | | |______ 1: COMMAND, 0: DATA ; | | |________ 0: REQUEST ; | =================================================== ; ; FIRMWARE ERROR CODES IN HOST DATA REGISTER IF HOST STATUS ; BIT 1 IS PRTS + 3 ;============================================================================ ; HOST STATUS LOCAL OUTPUT PORT ;MAT TRACK SCFMTBT EQU 7 ;FORMAT BAD TRACK SCREAD EQU 8 ;READ SECTOR(S) SCWRIT EQU 10 ;WRITE SECTOR(S) SCSEEK EQU 11 ;SEEK TR TRANSFER LOCAL I/O PORT ;============================================================================ HDATA EQU LOCPRTS + 5 ; |__________ 0: INPUT TO ISASI, 1: OUTPUT (TO CONTROLLER) ; |________________ 1: PARITY ERROR ; ; BIT #S: SBUSY EQU 0 ;BUSSET ; ;============================================================================ FERR00 EQU -1 ;UNKNOWN ERROR FERR02 EQU ============================================================================ HSTAT EQU LOCPRTS + 4 ; ; 7 6 5 4 3 2 1 0 ; | ACK SCCOPY EQU 20H ;COPY BLOCK(S) ;============================================================================ ; ; JAHOST DATA TRANSFER PORT ;============================================================================ ; HOST ACCESS ADDREY BIT SMSG EQU 1 ;MESSAGE BIT SCD EQU 2 ;C/D BIT SREQ EQU 3 ;REQUEST* BIT SIO EQU 4 ;I/O* BIT SPERR EQU 7 ;PARITY ERRO-2 ;ROM TEST FAILURE FERR03 EQU -3 ;ILLEGAL COMMAND FERR04 EQU -4 ;ILLEGAL INTERRUPT FERR07 EQU -7 ;CONTROLLER HANDSHAKE TIMO|0|0|0|0|0| | | ; ^ ^ ^__ 1: ISASI BUSY ; | |____ 1: FIRMWARE ERROR ; |________________ 1: ERROR ; ;DE DEFINITIONS ; ;============================================================================ JADBASD EQU 4 ;BASE DRIVE # OSS BIT 15 LOCAL OUTPUT PORT ;============================================================================ HXAD15 EQU LOCPRTS +R DETECTED BIT ; MASKS: SSTMSK EQU 10011111B ;STATUS BIT MASK SSTINV EQU 00011000B ;STATUS BIT INVERSION MASK SSXMSK EQU 000UT FERR08 EQU -8 ;CONTROLLER SYNC ERROR ??? FERR09 EQU -9 ;CONTROLLER SENSE STATUS ERROR FERR10 EQU -10 ;ILLEGAL IOPB PARAMET BIT #S: HBUSY EQU 0 ;HOST BUSY STATUS BIT HFERRB EQU 1 ;HOST FIRMWARE ERROR BIT HSERRB EQU 7 ;HOST ERROR STATUS BIT ; MA0 ( ) *!+",#-$.%/ &0 'F JADE CONTROLLER JADNDRV EQU 4 ;NUMBER OF LOGICAL JADE CONTROLLER DRIVES SUBTTL MACROS ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@; ; EXECUTE THE COMMAND ; CMDOK: LD E,A ;SAVE COMMAND ; XOR A,A ;ASSUME NO ERRORS OUT (HSTAT),A ; LD HL,CMDTBL ;C@@@@@@@@@@@@@ HSTOUT: MACRO #PORT, #DATA IF #PORT < 80H XOR A ELSE LD A,#PORT ;SET UP BIT 7 ENDIF OUT (HXAD1OPB LO COMMAND DW IOPBHI ;(3) SET IOPB HI COMMAND DW IOPBX ;(5) SET IOPB XADDR COMMAND DW DIAG0 ;(7) DUMP LOCAL MEMORY  ; ; DO RESET TESTS ; CALL PUTEST ; ; INIT THE REMAINDER ; CALL INIT ;ANY OTHER INITIALIZATION ; ; GO WAIT FOR@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ; ; GET DATA MACRO ; ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ALCULATE THE TABLE ENTRY FROM THE COMMAND LD D,0 ADD HL,DE ;VALUE ALREADY *2 (BIT 0 = 0) ; LD E,(HL) ;FETCH THE COMMAND5),A ; IF (#DATA = 0) AND (#PORT >= 80H) XOR A ENDIF IF #DATA <> 0 LD A,#DATA ;OUTPUT DATA ENDIF OUT (#PDIAGNOSTIC CMD DW DIAG1 ;(9) SET OUTPUT PORTS DIAG. COMMAND DW DIAG2 ;(B) TEST S100 MEMORY ACCESS COMMAND DW DIAG3 ;(D) HOST COMMAND ; LD HL,0 ;FORCE NO TIMEOUT LD (TIMOUT),HL ; OUT (HINTC),A ;TELL HOST IT'S OK NOW ; JP HWAIT ;GO WAIT@@@@@@@@@@@@@@@@@@@ GETDATA MACRO AA#SYM: CALL GETSTAT ;IF REQUEST FALSE THEN WAIT BIT SREQ,A JR Z,AA#SYM ; INI ;GET HANDLER ADDRESS FROM TABLE INC HL LD D,(HL) EX DE,HL ; IN A,(HDATA) ;PREFETCH THE DATA FOR THE COMMAND ; ; CALL THORT OR 80H),A ENDM ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ; ; HOST INPUT MACRO ;  BLOCK MOVE 01000H TO 02000H COMMAND DW PRINT ;(F) PRINT ASCII STRING TO PORT COMMAND DW RETVERS ;(11) RETURN FIRMWARE VER FOR HOST INTERRUPT ; ; ; RAM ERROR ENCOUNTERED ; MEMERR: LD A,RAMERR ;PASS ERROR TO HOST & HALT CALL FERR HALT ;FA DATA ; ENDM ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ; ; PUTDATA MACRO ; ;@@@@E COMMAND HANDLER ; LD DE,CMDRET ;PUT RETURN ADDRESS ON STACK PUSH DE JP (HL) ; ;-------------------------------------- ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ HSTIN: MACRO #PORT IF #PORT < 80H XOR A SION NUMCMDS EQU ($ - CMDTBL) / 2 ;NUMBER OF COMMANDS ;*******************************************************************TAL! IF $ > 38H CONMSG **** ERROR! RESET CODE OVERLAPS INTERRUPT CODE! **** ENDIF ;------------------------------------@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PUTDATA MACRO AC#SYM: CALL GETSTAT ;IF REQUEST NOT T-------------------------------------- ; ; ALL COMMANDS RETURN HERE WITH ERROR STATUS ALREADY SET FOR HOST ; ;-------------- ELSE LD A,#PORT ;SET UP BIT 7 ENDIF OUT (HXAD15),A ; IN A,(#PORT OR 80H) ;FETCH DATA ENDM SUBTTL CODE ;************* ; ; FIRMWARE ERROR ENCOUNTERED, SET THE ERROR FLAGS SUBR ; ENTRY- A= ERROR CODE ; ;******************************---------------------------------------- ; ; INTERRUPT ENTRY VECTOR FOR MODE 1 ; ;------------------------------------------RUE THEN WAIT BIT SREQ,A JR Z,AC#SYM ; OUTI ;ASSUME CALLER SET UP ; DON'T WAIT ENDM ;@@@@@@@@@@@@@@@@@@@@@@@@@-------------------------------------------------------------- CMDRET: OUT (HINTC),A ;TELL HOST WE'RE DONE RET ;RETURN TO******************************************** ; ; PROCESSOR REGISTER USAGE: ; IY= PTR TO CURRENT COMMAND DESCRIPTOR BLOCK ; ********************************************** FERR: OUT (HDATA),A ;OUTPUT THE ERROR CODE ; LD A,HFERR ;PASS ERROR FLAGS TO---------------------------------- ORG LOCROM + 38H ; ; CHECK FOR SASI INTERRUPT ; IN A,(HCMD) ;GET COMMAND BIT HINTR@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ; ; BUFFER HALF SELECT MACRO ; ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ THE INTERRUPTED ROUTINE ;---------------------------------------------------------------------------- ; ; MAIN INTERRU;************************************************ ORG LOCROM ; RESETV: ; ; INIT SOME THINGS ; OUT (HINTS),A ;SET BUSY HOST OUT (HSTAT),A ; OUT (HINTC),A ;CLEAR ANY PENDING INTERRUPT RET SUBTTL FIRMWARE COMMANDS ;+++++++++++++++++++++B,A ;IF NOT HOST INTERRUPT THEN MUST BE SASI JP Z,SASINT ; ; CHECK FOR IOPB EXECUTE INTERRUPT ; BIT HIOPBB,A ;IF IOPB B@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ SELCTBUF MACRO LD HL,HDSECB ;ASSUME 1ST HALF LD A,(IOPB + PBSECO) ;IF SECTOR IS ODD THPTED LOOP ; ;---------------------------------------------------------------------------- HWAIT: ; ; ALLOW INTERRUPT NOW  FLAG ; XOR A ;PASS NOT -1 TO BOOT OUT (HSTAT),A ; IM 1 ;ONLY 1 INTERRUPT ; LD SP,STACK ;INIT STACK ; ; TEST RA+++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; SET IOPB LOW ADDRESS COMMAND 1 ; MUST BE INITIALIZED BEFORE DISK IT SET THEN EXECUTE IOPB JP NZ,EXIOPB ; ; COMMAND INTERRUPT ; AND 00011110B ;MASK OFF UNUSED COMMANDS ; CP NUMCMDS *EN SELECT UPPER HALF AND 1 JR Z,BB#SYM ; LD HL,HDSECB + 128 BB#SYM: ENDM ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ; EI JR HWAIT ;############################################################################ ; ; COMMAND TABLE FOR NOM ; LD HL,LOCRAM ;DO RAM TEST LD BC,RAMSIZE ; MTLP: LD A,(HL) ;COMPLEMENT & TEST CPL LD (HL),A CP (HL) JR NZ,MEMACCESS ; ENTRY- A= LOW BYTE OF IOPB ADDRESS ; EXIT - HDATA= OLD DATA ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 ;IF COMMAND ERROR THEN RETURN FIRMWARE ERR JR C,CMDOK ; ; ILLEGAL COMMAND, RETURN ERROR ; LD A,FERR03 JP FERR ; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ; ; HOST OUTPUT MACRO ; ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@N-IOPB COMMANDS ; ;############################################################################ CMDTBL: DW IOPBLO ;(1) SET IERR ;IF NO COMPARE THEN ERROR ; CPL ;RESTORE LD (HL),A ; INC HL ;NEXT LOCATION DEC BC LD A,B OR C JR NZ,MTLP 0 ( ) *!+",#-$.%/ &0 '++++++++++++++++++++++++ IOPBLO: LD HL,IOPBL ;POINT TO LOW BYTE TO ALTER JR IOPBST ;++++++++++++++++++++++++++++++++++++CK MOVE THEN EXIT ; RET ; ; ; WRITE TO SINGLE LOCATION SUBCOMMAND ; DOWRITE: LD (S1MEM + 1000H),A JR D3LP ; ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++ DIAG0: ; ; DUMP LOCAL RAM 1ST ; IF 0 LD HL,LOCRAM LD DE,(I; EXIT - HDATA= VERSION # (HEX) ; ;---------------------------------------------------------------------------- RETVERS: LDORE LD (HL),A JR NZ,D2ERR ; CALL BUMPHL DEC BC LD A,B OR C JR NZ,D2LP ; ; ERROR OR DONE, PASS BACK THE DATA ++++++++++++++++++++++++++++++++++++++++ ; ; SET IOPB HIGH ADDRESS COMMAND 3 ; MUST BE INITIALIZED BEFORE DISK ACCESS ; ENTR READ FROM SINGLE LOCATION SUBCOMMAND ; DOREAD: LD A,(S1MEM + 1000H) JR D3LP ; ; ; BLOCK MOVE IN LOW HOST MEMORY THOPBL) LD A,(IOPBXA) LD BC,RAMSIZE CALL MOV2HST ELSE XOR A,A OUT (HXADDR),A OUT (HXAD15),A LD HL,LOCRAM LD DE A,VERSN ;LOAD DATA REGISTER WITH VERSION OUT (HDATA),A ; RET ;******************************************************; D2ERR: LD (IOPBL),HL ;FAILURE LOCATION LD (IOPBXA),A ;ORIGINAL DATA RET Z ;RETURN IF NO ERROR ; ; TEST ERROR, PASS BY- A= HIGH BYTE OF IOPB ADDRESS ; EXIT - HDATA= OLD DATA ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++EN RETURN SUBCOMMAND ; DOMOVE: XOR A,A ;DO IN LOW 32K OUT (HXAD15),A ; LD HL,S1MEM + 1000H LD DE,S1MEM + 2000H LD B,S1MEM OR 4000H LD BC,RAMSIZE LDIR ENDIF ; ; FOLLOW WITH ROM IMAGE ; IF 0 LD A,(IOPBXA) ;MUST RESTORE BANK A********************** ; ; PRINT A CHARACTER TO HOST PORT ; ENTRY- C= PORT # ; E= CHARACTER TO OUTPUT ; ;****************ACK TO HOST ; LD A,FERR00 JP FERR ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; +++++++++++ IOPBHI: LD HL,IOPBH ;POINT TO HIGH BYTE TO ALTER JR IOPBST ;++++++++++++++++++++++++++++++++++++++++++++++++C,1000H LDIR ; RET ; ; ; BLOCK MOVE IN HIGH HOST MEMORY THEN RETURN SUBCOMMAND ; DOBLKH: LD A,1 SHL A15B ;SET HIGH DDRESS ENDIF RES 7,D ;MAP DOWN FOR NOW LD HL,LOCROM LD BC,ROMSIZE JP MOV2HST ;+++++++++++++++++++++++++++++++************************************************************ PRT: IN A,(C) ;IF BUSY THEN WAIT AND 1 JR NZ,PRT ; ; OUTPUDIAG3 COMMAND 13 DOES S100 MEMORY ACCESSES DEPENDING ON DATA ; NOTE: SCOPING TESTS CONTINUE UNTIL ANOTHER DATA WORD IS WRITTEN ++++++++++++++++++++++++++++ ; ; SET IOPB EXTENDED ADDRESS COMMAND 5 ; MUST BE INITIALIZED BEFORE DISK ACCESS ; ENTRY- A= EXPAGE OUT (HXAD15),A LD HL,0E000H LD DE,0E800H LD BC,800H LDIR ; RET ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; DIAGNOSTIC 1 COMMAND 9 LOADS DATA INTO DATA OUT & STATUS REGS ; ENTRY- A= DT STROBE* ON BIT 7 ; LD A,E ;OUTPUT CHARACTER WITH STROBE HIGH SET 7,A OUT (C),A ; RES 7,A OUT (C),A ; SET 7,A TO THE DATA ; REGISTER BY THE HOST. ; ; ENTRY- A= 0: BLOCK MOVE FROM 1000H TO 2000H ; 1: READ FROM 1000H (SCOPING TEST)TENDED ADDRESS BYTE OF IOPB ADDRESS ; EXIT - HDATA= OLD DATA ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; PRINT TEXT ON THE PRINTER COMMAND 15 ; EXERCISES THE I/O CAPABILITY ; ENTRY- A= PORTATA ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ DIAG1: OUT (HDATA),A OUT (HSTAT),A REOUT (C),A ; RET SUBTTL SASI INTERRUPT ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; 2: WRITE TO 1000H (SCOPING TEST) ; 3: BLOCK MOVE FROM E000H TO E800H ; ALL OTHERS: NOP ; ;++++++++++++++++++++++++++++++++ IOPBX: LD HL,IOPBXA ;POINT TO EXTENDED BYTE TO ALTER ; ; COMMON CODE ; IOPBST: LD C,(HL) ;SAVE OLD DATA  # ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ PRINT: OUT (HXAD15),A ;SET PORT TO DATA T ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; DIAG2 COMMAND 11 TESTS S100 MEMORY R ; INTERRUPT WITHOUT HOST BIT SET ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SASINT: ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ DIAG3: ; ; IF SUBCOMMAND 0 THEN GO DO MOVE ; OR A JR Z,DOM LD (HL),A ;SET NEW DATA LD A,C ;PASS OLD DATA TO HOST OUT (HDATA),A ; RET ;+++++++++++++++++++++++++++++++++++++SET 7,A ;MAP TO HOST LD C,A ; ; OUTPUT NEW LINE ; CALL CRLF ; ; OUTPUT A LINE ; LD E,'0' ;START WITH '0' LD BEADS & WRITES FROM (IOPB_PTR) TO +FFFH ; EXIT- (IOPBL)= LAST LOCATION CHECKED ; (IOPBXA)= DATA READ FROM LAST LOCATION ; ST ; THIS VERSION DOESN'T SUPPORT THE INTERRUPT! ; LD A,FERR04 ;OUTPUT ERROR FOR NOW JP FERR SUBTTL IOPB EXECUTION ;OVE ; ; LOOP ON COMMAND ; D3LP: IN A,(HDATA) ;IF DATA CHANGED THEN CHECK ; CP 2 JR C,DOREAD ;IF SUBCOMMAND == REA+++++++++++++++++++++++++++++++++++++++ ; ; DIAGNOSTIC DUMP COMMAND 7 LOADS HOST MEMORY WITH RAM IMAGE ; EXIT - (IOPB_PTR) OF,80 ;DO 1 LINE PRINT1: CALL PRT INC E DJNZ PRINT1 ; ; OUTPUT A NEW LINE ; CRLF: LD E,0DH CALL PRT LD E,0AH JP PATUS PORT= 0: NO ERRORS, -1 ERROR ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ DIAG2: ; ---------------------------------------------------------------------------- ; ; EXECUTE IOPB COMMAND ; ;-----------------D ADDRESS THEN EXIT ; JR Z,DOWRITE ;IF SUBCOMMAND == WRITE THEN THEN EXIT CP 3 JR Z,DOBLKH ;IF SUBCOMMAND == HIGH BLOFSETS: ; +0000H..+07FFH= RAM IMAGE ; +0800H..+0FFFH= ROM IMAGE ; +1000H..+17FFH= JADE FDC IMAGE ; ;+++++++++++++++++++++RT ;---------------------------------------------------------------------------- ; ; RETURN FIRMWARE VERSION COMMAND 17 ; SET UP FOR TEST ; CALL SETPTRS ; ; TEST THE S100 ACCESS ; D2LP: LD A,(HL) CPL LD (HL),A CP (HL) CPL ;REST0 ( ) *!+",#-$.%/ &0 '----------------------------------------------------------- EXIOPB: ; ; MOVE HOST IOPB INTO OUR LOCAL IOPB ; LD HL,IOPB ADE CONTROLLER DATA TO LOCAL BUFFER ; HSTOUT DDPORT,DDMB1 ;DATA IN BANK 1 LD HL,(FDADDR) ;GET FDC ADDRESS LD DE,JADSECB (IOPBXA) ; SET BANK # ; LD BC,IOPBSZ ; CALL MOV2HST ; ; RETURN ERROR CODE IN STATUS REGISTER FOR COMPATABILITY ; L++++++++++++++++++++++++++++++++++++++ JADFORM: ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ DEBLOCKED SECTOR DW HDWRT ;2: WRITE DEBLOCKED SECTOR DW HDFORM ;3: FORMAT TRACK DW HDCERR ;4: RESERVED DW HDCERR ;5 ;DESTINATION := LOCAL IOPB IMAGE LD DE,(IOPBL) ;GET ADDRESS OF IOPB IN USER RAM ; LD A,(IOPBXA) ; SET BANK # LD BC,I EX DE,HL LD BC,128 ;FETCH SECTOR DATA XOR A CALL MOVFHST ; ; REMOVE THE JADE CONTROLLER WINDOW ; HSTOUT DDPORT,DDD A,(IOPB + PBSTATO) OR A,A JP Z,IOPBCDN ; LD A,1 SHL HSERRB ; IOPBCDN: OUT (HSTAT),A ; ; DESELECT CONTROLLER ; +++ ; ; JADE CONTROLLER READ ADDRESS COMMAND (NOT IMPLEMENTED) ; EXIT - (IOPB + PBSTATO)= 0 OR ERROR CODE ; ;++++++++++++++: RESERVED DW HDCERR ;6: RESERVED DW HDCERR ;7: RESERVED DW HDCERR ;8: RETURN FIRMWARE VERSION DW HDCERR ;9: RESERVEOPBSZ ; CALL MOVFHST ; ; ASSUME NO ERRORS ; LD HL,0 LD (IOPB + PBSTATO),HL LD (IOPB + PBST2O),HL LD (IOPB + PBSTOUT ; ; XFER THE SECTOR DATA FROM THE LOCAL BUFFER TO THE HOST MEMORY ; LD HL,JADSECB ;NOW WRITE TO HOST JP HDHSTW  CALL DESELECT ; ; TELL HOST WE'RE DONE ; OUT (HINTC),A RET ; ; ; ILLEGAL DRIVE ERROR ; XILDRV: LD A,SELERR J++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ JADRDAD: ;+++++++++++++++++++++++++++++++++++++++++++++++++++D DW HDCERR ;10: RESERVED DW HDSEEK ;11: SEEK TRACK (NORMALLY IMPLIED) DW HDCERR ;12: RESERVED DW HDCERR ;13: RETURN4O),HL ; ; CHECK FOR HARD DISK ; LD A,(IOPB + PBDRVO) LD HL,HDCMDS ;ASSUME HARD DISK COMMAND CP HDNDRV JR C,XTABL  ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; JADE CONTROLLER WRITE SECTOR COMMAND ; EXIR SETSTAT ; ; ; ILLEGAL COMMAND ERROR ; XILCMD: LD A,CMDERR SETSTAT: LD (IOPB + PBSTATO),A JR XRET ;###########+++++++++++++++++++++++++ ; ; JADE CONTROLLER ILLEGAL COMMAND(S) (NOT IMPLEMENTED) ; EXIT - (IOPB + PBSTATO)= 0 OR ERROR CODE DRIVE STATUS DW HDCERR ;14: RESERVED DW HDCERR ;15: CLEAR ; MAXCMDS EQU ($ - HDCMDS) / 2 SUBTTL JADE IOPB COMMANDS  ; ; NOT HARD DISK SO CHECK FOR JADE DISK ; CHKJAD: LD HL,JADCMDS ;ASSUME JADE CISK COMMAND SUB JADBASD ;4..11 -> 0.T - (IOPB + PBSTATO)= 0 OR ERROR CODE ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ JADWRT:################################################################# ; ; IOPB COMMANDS ; ;##################################### ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ JADEXEC: LD A,CMDERR ;UNSUPPORTED FOR NOW! ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; JADE CONTROLLER LOGON COMMAND IS SAME AS RE.7 CP JADNDRV JR NC,XILDRV ; LD (IOPB + PBDRVO),A ;CHANGE DRIVE ; ; CHECK IF COMMAND IS ILLEGAL ; XTABL: LD A,(IOPB ; ; XFER DATA FROM HOST TO LOCAL BUFFER ; LD HL,JADSECB ;GET DATA TO BUFFER CALL HDHSTR ; ; XFER LOCAL BUFFER TO J####################################### JADCMDS: DW JADLOG ;0: LOG ON DISK DW JADREAD ;1: READ SECTOR DW JADWRT ;2: WR ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; SET IOPB STATUS BYTE FUNCTION ; ENTRYAD ; EXIT - (IOPB + PBSTATO)= 0 OR ERROR CODE ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + PBCMDO) ;CHECK IF LEGAL CP MAXCMDS JR NC,XILCMD ; ; COMPUTE DRIVER ADDRESS ; LD E,A LD D,0 ADD HL,DE ;MULTIPADE CONTROLLER ; HSTOUT DDPORT,DDMB1 ;GET FDC WINDOW LD HL,(FDADDR) EX DE,HL LD HL,JADSECB LD BC,128 XOR A CALL MITE SECTOR DW JADFORM ;3: FORMAT TRACK DW JADRDAD ;4: READ ADDRESS DW JADEXEC ;5: EIA OUTPUT DW JADEXEC ;6: EIA STAT- A= STATUS BYTE ; EXIT - NZ= ERROR ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ IOPBERR: JADLOG: ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; JADE CONTROLLER READ SECTOR CLY CMD BY 2 FOR OFFSET ADD HL,DE LD A,(HL) ;GET COMMAND FROM TABLE INC HL LD H,(HL) LD L,A ; ; CALL THE COMMAND OV2HST ; ; EXECUTE THE COMMAND ; CALL FDSKEX ;EXECUTE WRITE SECTOR CMD ; ; REMOVE THE JADE WINDOW ; HSTOUT DDPORTUS DW JADEXEC ;7: IDLE DW JADEXEC ;8: RETURN FIRMWARE VERSION DW JADEXEC ;9: SET DISK FLAGS DW JADEXEC ;10: LOAD HEA LD (IOPB + PBSTATO),A OR A,A RET SUBTTL JADE FDC SUBR ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++OMMAND ; EXIT - (IOPB + PBSTATO)= 0 OR ERROR CODE ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; LD DE,XRET ;PUT RETURN ADDRESS ON STACK PUSH DE JP (HL) ;EXECUTE COMMAND ; XRET: ; ; MOVE LOCAL IOPB TO HOST I,DDOUT ;REMOVE WINDOW ; RET ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; JADE COND & IDLE DW JADEXEC ;11: SEEK TRACK DW JADEXEC ;12: SET DRIVE PARAMETERS DW JADEXEC ;13: RETURN DRIVE STATUS DW JADEX+++++++++++++++ ; ; EXECUTE THE COMMAND BLOCK FUNCTION ; EXIT - NZ= ERROR ; ;++++++++++++++++++++++++++++++++++++++++++++++++++ JADREAD: ; ; EXECUTE THE READ COMMAND ; HSTOUT DDPORT,DDMB0 ;SWITCH DD INTO MEMORY CALL FDSKEX ; ; XFER THE JOPB AREA FOR STATUS RETURN ; LD HL,IOPB ;SOURCE := LOCAL IOPB IMAGE LD DE,(IOPBL) ;GET ADDRESS OF IOPB IN USER RAM LD A,TROLLER FORMAT COMMAND (NOT IMPLEMENTED) ; EXIT - (IOPB + PBSTATO)= 0 OR ERROR CODE ; ;++++++++++++++++++++++++++++++++++++++EC ;14: SET EIA BAUD RATES DW JADEXEC ;15: CLEAR ; HDCMDS: DW HDLOG ;0: LOG ON DISK (SELECT DISK) DW HDREAD ;1: READ0 ( ) *!+",#-$.%/ &0 '++++++++++++++++++++++++++++++ FDSKEX: ; ; CHANGE LOGICAL SECTOR {0..N-1} TO PHYSICAL {1..N} ; LD A,(IOPB + PBSECO) IN++++++++++++++++++++ HDFORM: ; ; SELECT THE DRIVE ; CALL HDSELCT ;IMPLIED SELECT RET NZ ; ; SET UP THE CDB ; LIOPB + PBSTATO)= 0 OR ERROR CODE ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ HDLOG: ; ;Z ; ; SET UP CDB ; LD IY,LAXCDB ;USE XFER CDB LD (IY+CMD),SCSEEK ;SEEK COMMAND CALL GETLUN CALL GETLAD ;GET USER'S+++++ HDREAD: ; ; SELECT DRIVE ; CALL HDSELCT ;IMPLIED SELECT RET NZ ; ; SET UP AND READ THE SECTOR ; LD IY,LAC A LD (IOPB + PBSECO),A ; ; MOVE IOPB INTO JADE CONTROLLER ; LD DE,DDCBO ;OFFSET OF IOPB IN MEMORY BANK 0 LD HL,(FDAD IY,LAXCDB ;ELSE USE XFER CDB LD (IY + CMD),SCFMTT ; LD A,(IOPB + PBSECO) ;SECTOR BYTE HAS INTERLEAVE FACTOR AND 0001111 SELECT THE CONTROLLER ; CALL HDSELCT RET NZ ; ; READ THE ID SECTOR ; LD IY,IDRCDB ;READ THE ID SECTOR CALL GET BLOCK ; ; EXECUTE THE SEEK ; CALL XCDB6 ;SEND CDB RET NZ ; ; RETURN THE RESULTS ; JP GETRES ;GET ANY ERRORS XCDB ;USE XFER CDB CALL GETLUN CALL GETLAD CALL HDRDBUF RET NZ ; ; SELECT THE BUFFER HALF ; SELCTBUF ; ; WRITDDR) ;BASE ADDRESS OF JADE MEMORY BANKS ADD HL,DE EX DE,HL LD HL,IOPB LD BC,PBDMAXO + 1 ;COUNT, INCLUSIVE XOR A CALL1B ;MASK OFF HEAD BITS LD (IY+ILV),A ; ; FORCE SECTOR TO 0 FOR CLEANLINESS ; XOR A LD (IOPB + PBSECO),A ; ; SET ULUN CALL HDRDBUF RET NZ ; ; CHECK FOR LEGAL ID SECTOR ; LD DE,IDTXT ;TXT PTR LD HL,HDSECB ;TEXT IN SECTOR BUFFER  SUBTTL HARD DISK SUBROUTINES ;**************************************************************************** ; ; CLEAR CONTRE THE SECTOR BUFFER TO THE HOST MEMORY ; JP HDHSTW ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ MOV2HST ; ; ISSUE COMMAND TO JADE CONTROLLER ; HSTOUT DDPORT,DDEXC ;ISSUE COMMAND ; ; SET UP FOR RETURN ; LD BC,P CDB FROM IOPB ; CALL GETLUN ;GET DRIVE CALL GETLAD ;GET LOGICAL ADDRESS ; ; EXECUTE ; CALL XCDB6 ; ; RESTORELD B,IDSZE ;SIZE ; HDCKID: LD A,(DE) ;COMPARE CP (HL) JR NZ,HDNTID ;IF NOT SAME THEN EXIT ; INC HL ;NEXT CHAR INC OLLER SUBR ; ;**************************************************************************** INIT: ; ; INIT VARIABLES ; ++++++++ ; ; WRITE SECTOR COMMAND ; EXIT - (IOPB + PBSTATO)= 0 OR ERROR CODE ; ;+++++++++++++++++++++++++++++++++++++++++++IOPBSZ - PBSTATO ;SET UP TO MOVE STATUS DOWN ; ; WAIT FOR JADE CONTROLLER TO FINISH ; FDSKWT: HSTIN DDPORT ;WAIT UNTIL D ILV BYTE OF CDB FOR SUBSEQUENT OPS ; LD (IY+ILV),0 ;RESTORE ILV BYTE TO 0 RET NZ ;ERR? ; ; RETURN RESULTS ; JP GETDE DJNZ HDCKID ;DO UNTIL DONE ; ; ID CHECKS, RETURN VALID ID FLAG ; LD A,-2 JR HDLOG2 ; ; NO ID, USE DEFAULT ; LD A,-1 LD (CURDRV),A ;CURRENT DRIVE = NONE ; ; INIT COMMAND DESCRIPTOR BLOCKS (CDB) ; LD HL,NULCDB ;ZERO CDBS LD B,C+++++++++++++++++++++++++++++++++ HDWRT: ; ; SELECT THE DRIVE ; CALL HDSELCT ;IMPLIED SELECT RET NZ ; ; PREREAD TONE AND DDSHLT JR NZ,FDSKWT ; ; DONE, GET WINDOW ; HSTOUT DDPORT,DDMB0 ;GET WINDOW ; ; FETCH COMMAND RESULT STATRES ;FINISH UP ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; RECAL COMMAND ; EXIT - HDNTID: LD HL,DEFDSEC ;PASS BACK DEFAULT DESCRIPTOR SECTOR LD DE,HDSECB LD BC,128 LDIR ; LD A,-2 ;DEFAULT IS EXTEDBINIT INITRAM: LD (HL),0 INC HL DJNZ INITRAM ; ; RESET THE HARD DISK CONTROLLER ; LD A,1 SHL SRESET ;RESET CONTROHE SECTOR BUFFER, IF APPLICABLE ; LD IY,LAXCDB ;USE XFER CDB CALL GETLUN CALL GETLAD ; CALL HDRDBUF ;REFRESH BUFFER WUS ; XOR A CALL MOVFHST ; ; CHECK FOR ERRORS ; LD A,(IOPB + PBSTATO) ;IF NO ERROR THEN RETURN 0, NC OR A RET  (IOPB + PBSTATO)= 0 OR ERROR CODE ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ HDRECAL: NDED TYPE ; ; RETURN THE DESCRIPTOR SECTOR FLAG TO HOST ; HDLOG2: LD (IOPB + PBST2O),A ;STORE THE DESCRIPTOR SECTOR TYPE LLER OUT (SASICMD),A ; LD A,1 SHL SERRCLR ;RELEASE RESET OUT SASICMD,A ; ; DELAY A WHILE ; LD BC,0 INIT2: DEC BC ITH SECTOR DATA RET NZ ; ; SELECT THE BUFFER HALF ; SELCTBUF ; ; XFER THE DATA FROM THE HOST MEMORY ; CALL HDHST SUBTTL HARD DISK IOPB COMMANDS ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; UNSUPPOR; ; SELECT DRIVE ; CALL HDSELCT RET NZ ; ; USE PRIMITIVE ; JP RECALC ;++++++++++++++++++++++++++++++++++++++; ; WRITE THE HOST BUFFER ; LD HL,HDSECB ;WRITE ID SECTOR TO HOST CALL HDHSTW ; ; FLUSH BUFFER OF DESCRIPTOR SECTOR LD A,B OR A,C JR NZ,INIT2 ; ; CLEAR THE SECTOR BUFFER ; CALL CLRBUFR ;START WITH FRESH BUFFER READ ; ; SET UP R ;READ HOST BUFFER ; ; WRITE THE SECTOR BUFFER ; JP HDWRBUF ;WRITE TO DISK ;+++++++++++++++++++++++++++++++++++++TED COMMAND ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ HDCERR: LD A,CMDERR JP IOPBERR ++++++++++++++++++++++++++++++++++++++ ; ; SEEK COMMAND ; EXIT - (IOPB + PBSTATO)= 0 OR ERROR CODE ; ;+++++++++++++++++++++ ; JP CLRBUFR ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; READ DEBLOCKED SECTOR THE JADE CONTROLLER POINTERS ; HSTIN DDPORT ;FETCH FDC ADDRESS AND DDSASW RLCA OR HIGH DDBASE LD H,A LD L,0 LD (+++++++++++++++++++++++++++++++++++++++ ; ; FORMAT TRACK COMMAND ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; DRIVE SELECT/LOG-ON COMMAND ; EXIT - (+++++++++++++++++++++++++++++++++++++++++++++++++++++++ HDSEEK: ; ; SELECT DRIVE ; CALL HDSELCT ;IMPLIED SELECT RET NCOMMAND ; EXIT - (IOPB + PBSTATO)= 0 OR ERROR CODE ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++0 ( ) *!+",#-$.%/ &0 'FDADDR),HL ; ; ALL DONE ; RET ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; SEQUEST ; HDWRLP: CALL GETSTAT ;IF READY THEN BIT SREQ,A JR Z,HDWRLP ; ; IF DATA REQUEST THEN GO XFER IT ; AND SSXMS LD (RETRYS),A ; ; SEND RETRY DISABLE FLAG TO CONTROLLER ; LD A,(HL) ;CHECK FOR CONTROLLER RETRY DISABLE AND 80H LD  DE,(IOPB + PBTRKO) ;LAST, CHECK TRACK LD HL,(BUFTRK) SBC HL,DE RET ;************************************************OW (CONTROLLER REQUESTED MORE DATA THAN 1 SECTOR'S WORTH) ; DETERMINE WHAT CONTROLLER WANTS & RE-SYNC SASI BUS ; HDRDOV: CALECT DRIVE FUNCTION ; EXIT - NZ= ERROR ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ HDSELK ; IF DATA READY THEN PUT IT CP SGTDAT JP Z,HDWR2 ; ; IF STATUS MODE THEN GET IT ; CP SSNDST ; ELSE IF READY F(IY + RTY),A ; ; EXECUTE THE READ COMMAND ; HDRDRTY: LD (IY+CMD),SCREAD ;READ COMMAND LD (IY+NBK),1 ;ALLWAYS USE 1 BLO**************************** ; ; CLEAR BUFFER SUBR ; EXIT - A= -1 ; ;******************************************************LL GETSTAT ;IF READY THEN INPUT DATA BIT SREQ,A JR Z,HDRDOV ; AND SSXMSK CP SSNDST ;IF READY FOR STATUS THEN GET IT CT: ; ; IF CURRENT DRIVE == REQUESTED DRIVE THEN RETURN ; LD A,(IOPB + PBDRVO) ;IF REQUESTED DRIVE = CURRENT DRIVE THEN OR STATUS THEN GET IT JP NZ,HDRWFER ; ELSE UNKNOWN CONDITION! ; JP GETRES ; ; ; DATA REQUEST, XFER DATA ; HDWR2: OCK (SECTOR) ; CALL XCDB6 ;SEND CDB RET NZ ;IF ERROR HERE THEN HARD ERROR! ; ; SET UP FOR DATA XFER ; LD BC,[HDBUFS********************** CLRBUFR: ; ; STORING -1 INTO DRIVE FORCES A READ ; LD A,-1 LD (BUFDRV),A RET ;********** JP Z,HDRDDN ; ; IGNORE THE EXCESS DATA ; HDWASTE: CALL HDXWST ;OVERFLOW, WASTE DATA CALL GETRES ;FINISH UP ; ;  LD HL,CURDRV SUB A,(HL) RET Z ; RETURN ; ; TEST DRIVE READY ; LD IY,NULCDB ;USE NUL CDB LD (IY+CMD),SCRDY ;TESTUTI ;SASI DATA = *PTR++; CNT-- JP NZ,HDWRLP ; ; DATA XFER COUNT EXHAUSTED, BETTER BE REQUESTING STATUS NOW ; HDWROV: CZ SHL 8] + SASIDATA ;SET COUNT, PORT LD HL,HDSECB ;XFER PTR ; ; WAIT FOR DATA REQUEST ; HDRDLP: CALL GETSTAT ;IF NOT ****************************************************************** ; ; MAKE BUFFER PTRS = PB PTRS ; ;***********************ASSUME DATA BUFFER CONTAMINATED, CLEAR IT! ; HDRWFER: CALL CLRBUFR ;BUFFER CONTAMINATED ; ; RETURN UNKNOWN FIRMWARE ERR READY COMMAND ; CALL GETLUN ;REQUEST LUN FROM USER CALL XCDB6 ;EXECUTE CDB RET NZ ;NOT READY, EXIT ; ; GET RESULTALL GETSTAT ;OVERFLOW, WASTE DATA BIT SREQ,A JR Z,HDWROV ; AND SSXMSK CP SSNDST JP NZ,HDWASTE ;IF NOT STATUS THEN WAREADY THEN WAIT BIT SREQ,A JR Z,HDRDLP ; AND SSXMSK ; IF DATA READY THEN GET IT CP SSNDDAT JP Z,HDRD2 ; CP SSND***************************************************** MAKSAME: ; ; STORE IOPB PTRS INTO BUFFER PTRS ; LD A,(IOPB + PBDRVOR ; LD A,FERR08 ; UNKNOWN CONDITION, USE HANDSHAKE JP IOPBERR ;****************************************************S ; CALL GETRES ;GET RESULT BYTE RET ;CAN'T EVEN GET RESULT STATUS..HARD ERROR ;***********************************STE DATA ; ; STATUS IS BEING REQUESTED, GO GET IT ; JP GETRES ;+++++++++++++++++++++++++++++++++++++++++++++++++++++ST ; ELSE IF NOT READY FOR STATUS THEN ERR JR NZ,HDRWFER ; ; OPERATION DONE, GET RESULTS ; HDRDDN: CALL GETRES ; ; O) LD (BUFDRV),A LD HL,(IOPB + PBTRKO) LD (BUFTRK),HL LD HL,(IOPB + PBSECO) RES 0,L ;CLEAR BLOCKING BIT 1ST LD (BUF************************ ; ; WRITE HD SECTOR FROM BUFFER SUBR ; ENTRY- IY= CDB PTR ; CDB= SET UP ; EXIT - NZ= ERROR ; ;****************************************** ; ; READ HD SECTOR INTO BUFFER SUBR ; ENTRY- IY= CDB PTR ; CDB= SET UP ; EXIT - +++++++++++++++++++++++ ; ; QUERY BUFFER THE SAME FUNCTION ; EXIT - ZF= SAME ; NZ= NOT SAME ; ;++++++++++++++++++++++++++ BUFFER CONTAINS GOOD DATA, SET BUFFER PTRS ; PUSH AF CALL Z,MAKSAME ;MAKE BUFFER PTRS REFLECT DISK DATA POP AF RET Z SEC),HL RET ;**************************************************************************** ; ; READ DATA FROM HOST IOPB *************************************************************************** HDWRBUF: ; ; SET UP CDB ; LD (IY+CMD),SCWRITNZ= ERROR ; ;**************************************************************************** HDRDBUF: ; ; IF BUFFER DATA VAL++++++++++++++++++++++++++++++++++++++++++++++++++ QBUFR: ; ; IF NOT SAME DRIVE THEN RETURN NZ ; LD A,(IOPB + PBDRVO) ;C ; ; ELSE CHECK RETRIES ; LD A,(RETRYS) SUB A,1 LD (RETRYS),A JP NC,HDRDRTY ; ; ERROR OCCURRED, CLEAR BUFFER PTRSUBR ; MOVES 128 BYTES FROM (PBDMA) TO (HL) ; ENTRY- HL= DESTINATION PTR ; EXIT - BC, DE, HL= ? ; ;********************** ;WRITE COMMAND ; LD (IY+NBK),1 ;ALLWAYS USE 1 BLOCK (SECTOR) ; ; EXECUTE THE COMMAND 1ST ; CALL XCDB6 ;SEND CDB REID THEN SKIP PREREAD ; CALL QBUFR RET Z ; ; SET UP RETRY COUNT ; LD C,4 ;ASSUME RETRIES ; LD HL,IOPB + PBFLGO HECK DRIVE 1ST LD HL,BUFDRV CP (HL) RET NZ ; ; IF SECTOR NOT SAME THEN RETURN NZ ; LD DE,(IOPB + PBSECO) ;NOW CHECKS TO FORCE SUBSEQUENT READ ; CALL CLRBUFR ;BUFFER CONTAMINATED ; ; RETURN ERROR STATUS ; OR A,A ;CLRBUFR RETURNS -1 ****************************************************** HDHSTR: LD DE,(IOPB + PBDMAO) ;GET DESTINATION PTR LD A,(IOPB + PBDMAXT NZ ; ; SET UP FOR DATA XFER ; LD BC,[HDBUFSZ SHL 8] + SASIDATA ;SET COUNT, PORT LD HL,HDSECB ; ; WAIT FOR DATA RELD A,(HL) ;FETCH FLAGS BIT PBRTRY,A JR Z,HDRTRY1 ; LD C,0 ;IF NO RETRIES ALLOWED THEN COUNT = 0 ; HDRTRY1: LD A,C  SECTOR ; RES 0,E ;CLEAR BLOCKING BIT ; LD HL,(BUFSEC) SBC HL,DE RET NZ ; ; IF TRACK NOT = THEN RETURN NZ ; LD RET ; ; ; DATA REQUEST TRUE, XFER THE DATA ; HDRD2: INI ;*PTR++ = SASI DATA; CNT-- JP NZ,HDRDLP ; ; XFER OVERFL0 ( ) *!+",#-$.%/ &0 'O) ;SET BANK REGISTER LD BC,128 ;MOVE 128 BYTES ;***********************************************************************VX) INC A LD (MOVX),A OUT (HXADDR),A JP NO64KX ;******************************************************************* ; A, BC= ? ; ;**************************************************************************** MOV2HST: ; ; SET UP EXTENDEV ;INVERT SOME RET ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; TRANSMIT CDB FUNC XOR D ;IF 32K CROSS THEN DO LONG WAY JP M,DOLONG ; ; SET UP FOR BLOCK MOVE INSTRUCTION ; INC BC ;RESTORE COUNT ; ***** ; ; BLOCK MOVE FROM HOST SUBR ; ENTRY- HL= LOCAL PTR (DST) ; DE= HOST PTR (SRC) ; BC= BYTE COUNT ; A= BANK ADDRES********* ; ; WASTE OVERFLOW DATA SUBR ; ;**************************************************************************** HDXWD ADDRESS REGISTER ; LD (MOVX),A ;SAVE EXTENDED ADDRESS VALUE FOR BUMPING OUT (HXADDR),A ; ; PASS DIRECTION TO MOVER ;TION ; ENTRY- IY= CDB TO XMIT PTR ; EXIT - NZ= ERROR ; BC= ? ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SET 7,D ;INSURE S100 MAP ; ; SET DIRECTION ; EX AF,AF' ;IF FROM S100 THEN JP NZ,MOV1 ; EX DE,HL ; SWAP ; ; S (SRC) ; EXIT - HL= DE + BYTE COUNT ; DE= HL + BYTE COUNT ; A, BC= ? ; ;************************************************ST: ; ; WAIT UNTIL DATA REQUEST ; CALL GETSTAT ;IF READY THEN INPUT DATA BIT SREQ,A JR Z,HDXWST ; ; IF READY FOR LD A,1 ;TRANSFER TO S100 OR A EX AF,AF' ;**************************************************************************++++++++++++++++++ XCDB6: ; ; ISSUE CONTROLLER SELECT PER SHUGART MANUAL ; LD A,[1 SHL HDCONT] ;SELECT DB0 OUT (SASIDA DO FAST MOVE ; MOV1: LDIR ; ; RESTORE PTRS ; JP NZ,MOV6 ; EX DE,HL ; SWAP BACK ; ; RETURN NO ERRORS ; MOV6:**************************** MOVFHST: ; ; SET EXTENDED ADDRESS REGISTER ; LD (MOVX),A ;SAVE EXTENDED ADDRESS FOR BUMPING STATUS THEN RETURN FOR STATUS ; AND SSXMSK CP SSNDST ;IF READY FOR STATUS THEN GET IT RET Z ; ; XFER DATA & IGNORE ** ; ; MOVE SUBR CHECKS FOR A MOVE CROSSING ANY 32K BOUNDARY ; AND SELECTING A FAST BLOCK MOVE IF NOT, AND A SLOWER BLOCK MOVTA),A ; ; CLEAR ANY ERRORS ; XOR A,A OUT (SASICMD),A ; ; OUTPUT SELECT STROBE ; LD A,[1 SHL SSELECT] OR [1 SHL S EX AF,AF' XOR A RET ; ; ; LONG TRANSFER PART TESTS EACH BYTE FOR THRESHOLDS ; DOLONG: ; ; SET UP ; INC BC ;R OUT (HXADDR),A ; ; PASS DIRECTION TO MOVER ; XOR A ;TRANSFER FROM S100 EX AF,AF' JP MOVIT ;***************** ; LD A,0E5H ;OUTPUT WILL ALSO DO FOR INPUT OUT (SASIDATA),A JR HDXWST ;++++++++++++++++++++++++++++++++++++++++++++E ; WHICH CHECKS AFTER EACH BYTE FOR AN OVERFLOW CONDITION IF TRUE. ; ENTRY- HL= LOCAL MEMORY PTR ; DE= S100 MEMORY PTR ; ERRCLR] ;OUTPUT STROBE OUT (SASICMD),A ; ; WAIT FOR BUSY FOR AWHILE ; LD BC,0 ;SET ALARM ; BSYWT2: CALL GETSTAT ;WAESTORE COUNT ; LD A,D ;SET UP CURRENT BIT 15 LD I,A ; NO64KX: SET 7,D ;INSURE S100 ; ; SET DIRECTION ; MOV4: EX A*********************************************************** ; ; WRITE DATA TO HOST IOPB SUBR ; MOVE 128 BYTES OF DATA FROM ++++++++++++++++++++++++++++++++ ; ; RECALIBRATE FUNCTION ; EXIT - NZ= ERROR ; ;+++++++++++++++++++++++++++++++++++++++++++BC= BYTE COUNT TO TRANSFER ; AF'= 0: XFER FROM S100 MEMORY TO LOCAL MEMORY ; 1: XFER FROM LOCAL MEMORY TO S100 MEMORY IT FOR BUSY BIT SBUSY,A JR NZ,BSYOK2 ; DEC BC ;CHECK FOR TIMEOUT LD A,C OR B JR NZ,BSYWT2 ; ; TIMED OUT, RETURF,AF' ;IF HL= S100 THEN JP NZ,MOV2 ; EX DE,HL ; ; MOVE 1 BYTE ; MOV2: LDI ; ; RESTORE PTRS ; JP NZ,MOV3 ; (HL) TO (PBDMA) ; ENTRY- HL= SOURCE PTR ; ;**************************************************************************** HDHS+++++++++++++++++++++++++++++++++ RECALC: ; ; EXECUTE THE COMMAND ; LD IY,NULCDB LD (IY+CMD),SCREC ;RECAL COMMAND C; ; EXIT - AF, AF'= ? ; BC= 0 ; HL= HL + BC ; DE= DE + BC ; ;**********************************************************N TIMEOUT ERROR ; LD A,FERR07 ;HANDSHAKE TIMEOUT ERR JP IOPBERR ; ; ; CONTROLLER WENT BUSY, CLEAR SELECT STROBE ; BSEX DE,HL ; ; IF COUNT EXHAUSTED THEN EXIT ; MOV3: JP PO,MOV6 ;IF DONE THEN RETURN ; ; IF NO ROLLOVER THEN DO NEXT ; TW: LD DE,(IOPB + PBDMAO) ;GET DESTINATION PTR LD A,(IOPB + PBDMAXO) ;SET BANK REGISTER LD BC,128 ;MOVE 128 BYTES ;**ALL GETLUN ; CALL XCDB6 ; ; RETURN THE RESULTS ; JP GETRES ;FINISH UP ;+++++++++++++++++++++++++++++++++++++++++****************** MOVIT: ; ; INSURE DIRECTION FLAGS ARE SET ; EX AF,AF' ;SET FLAGS OR A EX AF,AF' ; ; SET UP BYOK2: LD A,1 SHL SERRCLR ;REMOVE SELECT STROBE OUT (SASICMD),A ; ; CHECK FOR COMMAND MODE ; XCDB2: CALL GETSTAT BIT S EX AF,AF' BIT 7,D ;IF NOT ROLLOVER THEN REPEAT JP NZ,MOV4 ; ; ELSE TOGGLE HOST BIT 15 ; LD A,I ;TOGGLE BIT 15 C************************************************************************** ; ; BLOCK MOVE TO HOST SUBR ; ENTRY- HL= LOCAL PTR+++++++++++++++++++++++++++++++++++ ; ; GET STATUS FUNCTION ; EXIT- A= STATUS WORD ; ;+++++++++++++++++++++++++++++++++++++IT 15 REGISTER ; LD A,D ;SET BIT 15 OUT (HXAD15),A ; ; CHECK FOR LONG MOVE ; DEC BC ;IF > 32K MOVE THEN DO LONG WAREQ,A ; WAIT FOR REQUEST JR Z,XCDB2 ; BIT SCD,A ;IF NOT COMMAND THEN ??? JR NZ,XOK ; ; NOT COMMAND MODE, RETURN CONPL LD I,A OUT (HXAD15),A ; ; IF BIT 15 TOGGLED TO 0 THEN BUMP EXTENDED ADDRESS ; BIT 7,A JP NZ,NO64KX ; LD A,(MO (SRC) ; DE= HOST PTR (DST) ; BC= BYTE COUNT ; A= BANK ADDRESS (DST) ; EXIT - DE= DE + BYTE COUNT ; HL= HL + BYTE COUNT+++++++++++++++++++++++++++++++++++++++ GETSTAT: IN A,(SASIST) ;GET STATUS WORD AND SSTMSK ;REMOVE UNUSED BITS XOR SSTINY LD A,B CP 32768 / 256 JR NC,DOLONG ; LD A,E ;IF 64K CROSS THEN DO LONG WAY ADD C LD A,D ADC B JR C,DOLONG ;0 ( ) *!+",#-$.%/ &0 'TROLLER SYNC ERROR ; XCDBER: LD A,FERR08 ;CONTROLLER SYNC ERROR JP IOPBERR ; ; ; READY FOR COMMAND, SET UP FOR CDB XFERTING CONTROLLER & SENSING REQUEST ETC. ; D. TEST DRIVE READY ON DRIVE 0 ; ;*************************************************PB + PBSTATO ;READ SENSE STATUS BYTES LD BC,[4 SHL 8] + SASIDATA ; GETR2: GETDATA JR NZ,GETR2 ; ; READ STATUS OF SENSEHED DATA PORT IS BASE + 1, COMPENSATE LD A,C AND 7FH LD B,A LD A,I ;MERGE IN HOST BIT 7 AND 80H OR A,B LD (HPORTGICAL ADDR FROM IOPB SUBR ; ENTRY- IY= CDB PTR ; ;*************************************************************************** ; XOK: LD BC,[6 SHL 8] + SASIDATA ;BYTE COUNT IN B ; ; CHECK DIRECTION ; BIT SIO,A ;IF DIRECTION NOT OUT THEN ERR *************************** PUTEST: ; ; CLEAR THE EXTENDED ADDRESS PORT TO TALK TO BANK 0 FIRST ; XOR A,A OUT (HXADDR) COMMAND ; GETR3: CALL GETSTAT ;FINISH OUT COMMAND BIT SREQ,A JR Z,GETR3 ; ; IF NO ERROR IN SENSE COMMAND THEN RETURN),A JR TST5 ; NXTPRT: INC C ;IF ++PORT == 0 THEN DONE THIS HALF JR NZ,TST4A ; LD A,I ;NOW DO 80H..FFH CPL LD I,* GETLAD: ; ; XFER COUNT = SECTOR SIZE ; LD HL,256 ;SECTOR SIZE LD (BYTCNT),HL ; ; CALCULATE LOGICAL ADDRESS FROMJR NZ,XCDBER ; ; SET XFER PTR PUSH IY POP HL ; ; XFER CDB DATA ; XCDB3: PUTDATA ;GET CDB DATA JR NZ,XCDB3 ;,A ; ; TEST HOST LOCATION 0F800H FOR 0C3H ; LD A,-1 OUT (HXAD15),A LD A,(0F800H) SUB A,0C3H JR Z,TST2 ; ; ERR ERROR ; IN A,(C) ;GET RESULT BYTE OF COMMAND AND 00000011B ;IF ERROR THEN HARD ERROR ; LD A,FERR09 JP NZ,IOPBERR ; A OUT (HXAD15),A BIT 7,A ;IF TOGGLED FROM 1 TO 0 THEN DONE JR NZ,TST4B ; LD A,-4 ;NOT FOUND SO ERROR JP FERR ;  SECTOR & TRACK ; LD A,(IOPB + PBSECO) ;FETCH SECTOR LD E,A ; LD A,(IOPB + PBTRKO) ;PICK UP TRACK LSB & PUT INTO LA0 BIT ; DONE WITH CDB, CONTROLLER SHOULD BE WAITING FOR DATA XFER OR RESULT ; XOR A ;RETURN NO ERRORS RET ;++++++++++++OR! ; LD (IOPBL),A LD A,-1 JP FERR ; ; NON-DESTRUCTIVE TEST HOST LOCATION 100H ; TST2: OUT (HXAD15),A ;A HAS 0 F OR A,A ;ERROR ANYWAY RET ; ; ; PARITY ERROR ENCOUNTERED ; HDPERR: ; ; CLEAR THE PARITY ERROR LATCH ; XOR A ;; TEST HOST STATUS/COMMAND PORT ACCESS (DATA PORT ALREADY TESTED) ; TST5: LD A,55H OUT (HSTAT),A IN A,(C) ;C ALREADY HA 7 SRL A ; SECTOR BIT 0 IS WASTED RR E LD (IY+LA0),E ;PHEW! LA0 DONE ; LD (IY+LA1),A ;LA1 HAPPENS TO BE IN A RET++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; GET CONTROLLER RESULTS FUNCTION ; EXIT - NZ= HARD ERROR ROM PREVIOUS TEST ; LD HL,S1MEM + 100H LD A,(HL) LD C,A CPL LD (HL),A LD B,(HL) CP B CPL LD (HL),A JR Z,TSTCLEAR ERROR OUT (SASICMD),A LD A,1 SHL SERRCLR OUT (SASICMD),A ; ; RETURN PARITY ERROR CODE ; LD A,FERR11 ;RETURN PS STATUS/COMMAND PORT # CP A,55H JR NZ,TST5A ; LD A,0AAH OUT (HSTAT),A IN A,(C) CP A,0AAH OR 1 ;BUSY BIT IS SET J ;**************************************************************************** ; ; POWER UP TESTS PERFORM THE FOLLOWING:  ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ GETRES: ; ; SET UP TO RETURN RESULT IN IO3 ; LD (IOPBL),BC ;RETURN FAILURE DATA LD A,-2 JP FERR ; ; 32K BOUNDARY TEST ; TST3: ;NOT IMPLEMENTED ; ; FIND ARITY ERROR JP IOPBERR ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; GET LUN FROM UR Z,TST6 ; TST5A: LD A,-5 JP FERR ; ; TEST COMMAND PORT ; TST6: DI ;NO INTERRUPTS LD A,55H OUT (C),A IN A,(HCM ; 1. TEST HOST DMA ACCESS: ; A. READ LOCATION 0F800H FOR 0C3H. ; B. NON-DESTRUCTIVELY TEST LOCATION 100H ; C. TEST 32K BOPB ; LD HL,RSTAT ;INSURE DESTINATION CORRECT LD C,SASIDATA GETDATA ;GET RESULT STATUS BYTE ; ; CHECK FOR HARDWARE POWN PORT NUMBER IN HOST MEMORY ; TST4: LD A,55H ;START WITH DATA IMAGE OUT (HDATA),A ; XOR A,A ;START WITH BANK 0 SER FUNCTION ; ENTRY- IY= CDB PTR ; EXIT - BC, DE, AF= ? ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++D) CP A,55H JR NZ,TST6A ; LD A,2AH ;NOTE: AAH WOULD RESET THE PROCESSOR OUT (C),A IN A,(HCMD) CP A,2AH JR Z,TST7UNDARY (A15). ; 2. FIND OWN PORT # IN HOST SPACE. ; 3. TEST PORT REGISTERS: ; A. READ/WRITE TEST DATA & STATUS PORTS ; B. ARITY ERROR ; BIT SPERR,A JR NZ,HDPERR ; ; IF NO ERROR THEN RETURN ZF ; LD A,(RSTAT) AND 00000011B RET Z ; ;  OUT (HXAD15),A LD I,A ; TST4B: LD C,[0 OR 80H] ;PORT # ; TST4A: IN A,(C) ;SEARCH FOR 1ST PATTERN CP A,55H JR NZ,NX++++++++++++ GETLUN: ; ; FETCH & CONDITION THE DRIVE # ; LD A,(IOPB + PBDRVO) ;FETCH DRIVE # AND 00000011B ; ; PUT ; TST6A LD A,-6 JP FERR ; ; TEST HOST INTERRUPT WITH ILLEGAL COMMAND ; TST7: LD A,3FH ;USE AN UNSUPPORTED COMMAND TEST COMMAND PORT WITH INTERRUPTS DISABLED ; C. TEST INTERRUPT WITH ILLEGAL COMMAND & TEST STATUS ; 4. TEST SASI: ; A. TEST CHECK FOR CONTROLLER PARITY ERROR ; BIT 1,A ;IF CONTROLLER PARITY ERROR THEN EXIT JR Z,HDPERR ; ; ISSUE REQUEST SENSETPRT ; ; POSSIBLE PORT FOUND ; LD A,0AAH ;CHECK OTHER DATA PATTERN OUT (HDATA),A IN A,(C) CP A,0AAH ; ; RESTO DRIVE # INTO PROPER CDB FIELD ; RRCA RRCA RRCA ; ; STORE INTO ALL CDBS ; LD (NULCDB + LUN), A LD (LAXCDB + LUN) OUT (C),A ; PUSH BC EI ;ALLOW INTERRUPT NOP ;NEXT INSTRUCTION GETS EXECUTED NOP ;THIS INSTRUCTION SHOULD GET IN SASI INTERRUPT & RESULTANT ERROR. ; B. TEST SASI PARITY BY DESLECTING & OUTPUTTING ODD/EVEN DATA ; C. TEST REQUEST BY SELEC COMMAND ; LD (IY+CMD),SCSNSE CALL XCDB6 RET NZ ;HARD ERROR ; ; READ 4 BYTES OF STATUS INTO IOPB ; GETR1: LD HL,IORE DATA PATTERN BEFORE RETURNING ; LD A,55H OUT (HDATA),A JR NZ,NXTPRT ; ; PORT FOUND, SAVE PORT # ; DEC C ;SEARC, A LD (IDRCDB + LUN), A RET ;**************************************************************************** ; ; GET LO0 ( ) *!+",#-$.%/ &0 'TERRUPTED ; DI ;RESTORE BUSY STATUS OUT (HINTS),A ; POP BC ;FETCH STATUS IN A,(C) AND A,0FEH ;MASK OFF BUSY BIT########### ; ; DEFAULT DISK DESCRIPTOR SECTOR FOR LOGON ; ;################################################################; TST9: ; ; SASI REQUEST BIT TEST ; TST10: ; ; SASI COMMUNICATION TEST ; TST11: CALL INIT ;INIT CDB, IOPB ; XOR COUNT MOVX DS 1 ;HOST BANK ADDRESS SAVE FOR BLOCK MOVE SUBRS FDADDR DS 2 ;FDC ADDRESS PTR TIMOUT DS 2 ;UNSELECT SASI DELAY ************************************** SETPTRS: LD HL,(IOPBL) ;FETCH IOPB BASE ADDRESS LD A,(IOPBXA) OUT (HXADDR),A ;SET  CP A,HFERR JR NZ,TST7A ; INC C ;TEST COMMAND ERROR IN A,(C) CP A,FERR03 JR Z,TST8 ; TST7A: LD A,-7 JP FERR ;############ DEFDSEC: DB 0,0,0 ;POSSIBLE JUMP VECTOR IDTXT: DB 'Disk Descriptor Sector' IDSZE EQU $ - IDTXT ; REPT DEFD A,A ;ASSUME NO ERROR LD (IOPB + PBSTATO),A ; LD IY,TESTCDB LD (IY + CMD),SCRDY ;DO A TEST DRIVE READY COMMAND CALL XCHPORT DS 1 ;HOST'S BASE PORT # FOR DATA REGISTER ;#########################################################################THE BANK ADDRESS LD (MOVX),A ; LD A,H ;SELECT HOST BIT 15 OUT (HXAD15),A LD I,A ;SAVE IN INTERRUPT REGISTER SET 7,H ; TEST SASI PARITY ERROR DETECTION ; TST8: XOR A,A ;DESELECT CONTROLLER OUT (HSTAT),A ;CLEAR ERROR FROM PREVIOUS ILLESEC + 20H - $ LIST OFF DB 0 LIST ON ENDM DW 128 ;SPT DB 5 ;BSH DB 31 ;BLM DB 1 ;EXM DW 1015 ;DSM DW 115DB6 JR NZ,TST11A ; CALL GETRES ;FETCH COMMAND RESULTS JR NZ,TST11A ; LD A,(IOPB + PBSTATO) ;TEST FOR ERROR OR A,A ### ; ; I/O PARAMETER BLOCK SAVE AREA ; ;############################################################################ IOPB  ;SET LOCAL BIT 15 RET ;**************************************************************************** ; ; BUMP HL FUNCTGAL COMMAND OUT (HDATA),A OUT (SASIDATA),A LD A,1 SHL SSELECT OUT (SASICMD),A ; LD A,1 SHL SERRCLR ;ENABLE PARITY DET2 / 2 ;DRM DB 0FFH ;AL0 DB 80H ;AL1 DW 0 ;CKS DW 2 ;OFF ; REPT DEFDSEC + 30H - $ LIST OFF DB 0 LIST ON EN JR Z,TST12 ; TST11A: CALL DESELECT LD A,-11 ;PASS ERROR TO HOST JP FERR ; ; END OF TESTS ; TST12: ; ; FALL INDS IOPBSZ ; PBRTRY EQU PBNRT ;RETRY DISABLE BIT ;#######################################################################ION CARRIES THROUGH TO HOST BIT 15 & BANK ADDRESS ; ENTRY- HL= HOST ADDRESS ; I= HOST BIT 15 IN BIT 7 ; (MOVX)= BANK ADDRESECTION OUT (SASICMD),A ; IN A,(SASIST) ;TEST PARITY STROBE GATE BIT SPERR,A JR NZ,TST8A ;IF PARITY ERROR NOW THEN NOT IDM DB 0 ;STAGGER (NOT USED) DB [1 SHL DFDBLB] OR [1 SHL DFHARDB] OR [1 SHL DFTSDB] ; 256 B/S, HARD DISK, 2 SIDED DB 6TO DESELECT ; ;**************************************************************************** ; ; DESELECT SASI BUS SUBROU##### ; ; HARD DISK SECTOR BUFFER ; ;############################################################################ HDBUFSZ ES IMAGE ; EXIT - HL= HL + 1 (BIT 15 SET) ; I= HOST BIT 15, INCLUDING ANY CARRY ; (MOVX), BANK ADDRESS= UPDATED IF HOST BIT NHIBITED ; IN A,(SASIDATA) ;CLOCK THE PARITY DATA IN A,(SASIST) ;WITH DATA == 0 THEN S/B PARITY ERROR BIT SPERR,A JR Z,4,64,64 ;PHYSICAL SPT (0,1,DATA) ; REPT DEFDSEC + 128 - $ LIST OFF DB 0 LIST ON ENDM DB 0 IF $ >= (LOCROM + ROMSITINE ; EXIT - A= ? ; ;**************************************************************************** DESELECT: XOR A,A ;DESQU 256 HDSECB DS HDBUFSZ ; RSTAT DS 1 ;COMMAND STATUS RETURNED ; BIT 1: ERROR (ISSUE SENSE COMMAND) ; BIT 5..7: LUN 15 CARRIED ; A= ? ; ;**************************************************************************** BUMPHL: INC HL ;PTR++ TST8A ; XOR A,A ;DISABLE PARITY DETECTION TO STOP GLITCHES OUT (SASICMD),A ; INC A ;FORCE AN EVEN PARITY BIT GENERATIOZE) ; PROTECTION MESSAGE CONMSG **** ERROR! CODE TOO LARGE FOR DECLARED PROM SIZE! **** ENDIF SUBTTL RAM AREA ORG LELECT OUT (SASIDATA),A LD A,[1 SHL SSELECT] OR [1 SHL SERRCLR] OUT (SASICMD),A ; LD A,1 SHL SERRCLR ;LEAVE PARITY ERRORBUFDRV DS 1 ;BUFFER CONTENTS DRIVE BYTE BUFSEC DS 2 ;BUFFER CONTENTS SECTOR WORD BUFTRK DS 2 ;BUFFER CONTENTS TRACK WORD BIT 7,H ;IF NO BIT 15 CARRY THEN RETURN RET NZ ; SET 7,H ;SET LOCAL BIT 15 LD A,I ;COMPLEMENT HOST BIT 15 CPL OUT N OUT (SASIDATA),A LD A,1 SHL SERRCLR ;RE-ENABLE PARITY DETECTION OUT (SASICMD),A ; IN A,(SASIST) ;RE-CHECK THE GATE OCRAM ;############################################################################ ; ; VARIABLES ; ;###################### DETECTION ENABLED OUT (SASICMD),A RET ;**************************************************************************** ;;############################################################################ ; ; JADE SECTOR BUFFER ; ;####################(HXAD15),A LD I,A BIT 7,A ;IF NO HOST BIT 15 CARRY INTO BANK THEN RETURN RET NZ ; LD A,(MOVX) ;BUMP BANK ADDRESS INCBIT SPERR,A JR NZ,TST8A ;IF PARITY ERROR NOW THEN ERROR ; IN A,(SASIDATA) ;CLOCK PARITY CHECK IN A,(SASIST) ;CHECK BIT ###################################################### IOPBL DS 1 ;LOW ADDRESS OF IOPB TO EXECUTE IOPBH DS 1 ;HIGH ADDRESS O ; SET ADDRESS PTRS FROM IOPB_PTRS FUNCTION ; EXIT - HL= IOPB PTR (BIT 15 SET FOR HOST ACCESS) ; A, BANK ADDRESS REGISTER= I######################################################## JADSECB DS 256 ;################################################# A LD (MOVX),A OUT (HXADDR),A RET SUBTTL CONSTANTS ;#################################################################BIT SPERR,A JR Z,TST9 ;DATA == 1 THEN NO PARITY ERROR ; TST8A: LD A,-8 JP FERR ; ; SASI DATA REQUEST INTERRUPT TEST F IOPB IOPBXA DS 1 ;BANK ADDRESS OF IOPB ; CURDRV DS 1 ;CURRENT DRIVE SELECTED BYTCNT DS 2 ;SECTOR SIZE RETRYS DS 1 ;RETRYOPB BANK ADDRESS (IOPBXA) ; I, HOST BIT 15 REGISTER= IOPB_PTR HOST BIT 15 IN BIT 7 ; ;**************************************0 ( ) *!+",#-$.%/ &0 '########################### ; ; DISK CONTROLLER COMMAND DESCRIPTOR BLOCKS (CDB) ; ;#########################################====== REBOOT: EQU 0 ;REBOOT ADDR TPA: EQU 100H ;TRANSIENT PROGRAM AREA ;============================================== ------------------------------------------------------------------ ; ; MAIN PROGRAM CONTINUES ; ;--------------------------- ; Modify from FORMAT8 for hard disk. Need caused by hard disk data ; errors. Realized I have no format utility! ; ; VERSN ################################### NULCDB: DS 6 ;NO TRANSFER CDB LAXCDB: DS 6 ;MAIN XFER CDB IDRCDB DS 6 ;ID SECTOR READ ============================= ; ; BDOS CALL VECTORS ; ;===================================================================------------------------------------------------ INIT: ; ; SET UP LOCAL STACK ; LD SP,(BDOS + 1) DEC SP DEC SP ; EQU 000 ;CHANGE HERE FOR SIGN-ON CHANGE ; ;*************************************************************************** SUBCDB TESTCDB DS 6 ;TEST CDB CDBINIT EQU $ - NULCDB ; ; CDB OFFSETS ; STRUCT 0 CMD DS 1 ;COMMAND LUN DS 1 ;LOGICAL UNIT ======== WBOOT EQU 0000H ;SYSTEM WARM BOOT BDOS: EQU 0005H ;SYSTEM CALL ADDR ;=========================================; OUTPUT SIGNON MESSAGE ; LD DE,SIGNON ;OUTPUT MESSAGE CALL MSGOT ; ; TEST IF CONTROLLER PRESENT ; IN A,(HSTATUS) TTL DECLARATIONS ;=========================================================================== ; ; ASSEMBLY CONTROL ; ;=====NUMBER IN BITS 5..7 LA2 EQU LUN ;LOGICAL ADDRESS 2 IN BITS 0..4 LA1 DS 1 ;LOGICAL ADDRESS 1 LA0 DS 1 ;LOGICAL ADDRESS 0 ILV ================================== ; ;*INCLUDE COMIOPB.DEF ;*INCLUDE ISASI.DEF ; ;=========================================;FETCH STATUS PORT DATA INC A ;IF 0FFH THEN NOT INSTALLED JR NZ,CINSTLD ; ; CONTROLLER NOT INSTALLED, ERROR ; LD DE,====================================================================== FALSE EQU 0 TRUE EQU NOT FALSE ; DIAG EQU TRUE ;DS 1 ;FORMAT COMMAND INTERLEAVE FACTOR NBK EQU ILV ;XFER COMMANDS BLOCK (SECTOR) COUNT RTY DS 1 ;RETRY FLAG 0: RETRY 3 TIMES, ================================== LIST OFF *INCLUDE COMIOPB.DEF *INCLUDE ISASI.DEF LIST ON SUBTTL MAIN PROGRAM ORCNIM CALL MSGOT JP REBOOT ;QUIT ; ; CINSTLD: ; ; CLEAR THE CONTROLLER ; LD A,1 SHL HRESET OUT (HCMD),A ; EX =========================================================================== ; ; CONSTANTS ; ;=============================80H: NO RETRYS LUND EQU RTY ;COPY COMMAND DEST. LUN IN BITS 5..7 LA2D EQU RTY ;COPY COMMAND DEST. LOGICAL ADDR 2 IN BITS 0..4 G TPA ;--------------------------------------------------------------------------- ; ; PROGRAM ENTRY POINT ; ;-----------(SP),HL ;WAIT FOR FDC TO CATCH UP EX (SP),HL EX (SP),HL EX (SP),HL ; CLRWT: IN A,(HSTATUS) ;WAIT FOR DONE AND A,1 SHL============================================== CTRLC: EQU 3 ;REQUEST REBOOT CPM LF: EQU 0AH ;LINE FEED CR: EQU 0DH ;CARRIA LA1D DS 1 ;COPY COMMAND DEST. LOGICAL ADDR 1 LA0D DS 1 ;COPY COMMAND DEST. LOGICAL ADDR 0 CDBSPR DS 1 ;COPY COMMAND SPARE RT---------------------------------------------------------------- JP INIT ;INITIALIZE ;################################## TITLE HARD DISK FORMAT UTILITY LIST NOCOND ;*************************************************************************** ;  HBUSYB JR NZ,CLRWT ; ; TOP OF DRIVE FORMAT LOOP ; FMTDSK: ; ; SET UP REGS ; LD A,DDFMT LD (FIOPB + PBCMDO),A GE RETURN BS EQU 08H ;BACKSPACE ; NDRVS EQU 4 ;MAX NUMBER OF DRIVES SECSZ: EQU 128 ;128 BYTES PER SECTOR DSIZE EQU 8 ;DYD DS 1 ;COPY COMMAND RETRY FLAG CDBSIZ DS 0 ENDM ;############################################################################################################## ; ; COPYRIGHT NOTICE ; ;##########################################################; HARD DISK FORMAT PROGRAM ; ;*************************************************************************** ; ; FORMATH is; ; SELECT DRIVE ; @@@ MUST CORRECT DRIVE A/B INTO HEAD BIT 1 CALL SELDR JP C,0 ;ERROR- QUIT ; ; REQUEST INTERLEAVISK SIZE {5, 8} ; SKEW EQU 6 ;SKEW FACTOR HDSPT EQU 128 ;MAX SECTORS PER TRACK ;======================================####### ; ; STACK AREA ; ;############################################################################ IF $ > (LOCRAM + RA################# SIGNON: DB 'M5b 8" Hard Disk Format Utility Ver ' DB (VERSN / 100) + '0' DB '.' DB ((VERSN - ((VERSN  a system utility which provides a means to write a ; format on any of the drives accessed by the hard disk controller. ; ;E FACTOR ; LD DE,INITLM CALL GETDPAR ; ; IF INTERLEAVE OUT OF BOUNDS THEN ERROR ; LD HL,16 SBC HL,DE JP NC,FMTDK===================================== ; ; LOCATIONS ; ;=====================================================================MSIZE - 32) CONMSG **** ERROR! DATA TOO LARGE FOR DECLARED RAM SIZE! **** ENDIF DS 32 STACK EQU LOCRAM + RAMSIZE END / 100) * 100)) / 10) + '0' DB (VERSN % 10) + '0' DB CR,LF DB 'Copyright (c) 1988 GRH Enterprises' DB '$' ;---------*************************************************************************** ; ; REVISION STATUS: ; ; 0.00 - 10 MAY 88 GRH 0 ( ) *!+",#-$.%/ &0 '2 ; ; PARAMETER ERROR ; PARERR: LD DE,PERRM CALL MSGOT JR FMTDSK ; ; ; ELSE SET INTERLEAVE ; FMTDK2: LD A,(FIOP 5 DIGITS ; RET ;*************************************************************************** ; ; OUTPUT CRLF SUBROUTIN************************************* ; ; MESSAGE OUTPUT SUBR ; ENTRY- DE= PTR TO '$' TERMINATED TEXT ; EXIT - ? ; ;**** ERROR ; ;*************************************************************************** WRTID: ; ; SET UP IOPBs ; LD A,(******************************** PUTD: ; ; PUT DATA IN PROPER REGISTERS ; EX DE,HL ; ; INIT DIGITS TO 0 ; LD HL,UB + PBSECO) OR A,E ;ADD INTO DRIVE (HEAD) LD (FIOPB + PBSECO),A ; ; REQUEST USER FOR START ; LD DE,REQSTM CALL MSGE ; EXIT - HL, DE, BC, AF= ? ; ;*************************************************************************** CRLF: LD DE,CRLF*********************************************************************** MSGOT: LD C,9 ;PRINT STRING FUNCTION JP BDOS FIOPB + PBDRVO) LD (WIDIOPB + PBDRVO),A LD (LOGIOPB + PBDRVO),A ; LD HL,IDSIMG LD (WIDIOPB + PBDMAO),HL ; LD HL,IDSENIT LD B,5 ; SET0: LD (HL),0 INC HL DJNZ SET0 ; ; PROCESS TENTHOUSANDS DIGIT ; DEC HL LD BC,-10000 CALL DECDIOT ; ; IF NOT CORRECT RESPONSE THEN ABORT ; CALL CI CP A,CR JP NZ,FMTDSK ; ; SET UP IOPB FOR 1ST TRACK ; LD HLM JP MSGOT ;*************************************************************************** ; ; CREATE DECIMAL DIGIT SUBROU;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; CONSOLE INPUT SUBR ; EXIT - A= CHAR AND 7FCT ;SET ID SECTOR LD (WIDIOPB + PBSECO),HL ; ; EXECUTE THE IOPB ; LD HL,WIDIOPB ;PASS PTR TO IOPB CALL EXECIOPB JR G ; ; PROCESS THOUSANDS DIGIT ; LD BC,-1000 CALL DECDIG ; ; PROCESS HUNDREDS DIGIT ; LD BC,-100 CALL DECDIG ;,0 LD (FIOPB + PBTRKO),HL ; ; FORMAT TRACK 0 UNIQUE DUE TO ID SECTOR ; CALL FMTTRK JR NZ,FMTDSK ;IF ERROR THEN ABORT TINE ; ENTRY- HL= PTR TO PLACE TO STORE DIGIT ; DE= VALUE TO CONVERT ; BC= DIVISOR FOR DIGIT ; EXIT - HL= PTR TO NEXT DIGIH ; BC, DE, HL= ? ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ CI: ; ; GET CHARACTER NZ,WIDERR ;IF ERROR THEN RETURN ; ; OK SO FAR, PERFORM LOGON TO SET CONTROLLER FLAGS ; LD HL,LOGIOPB CALL EXECIOPB RE ; PROCESS TENS DIGIT ; LD BC,-10 CALL DECDIG ; ; REMAINDER IS UNITS DIGIT ; LD (HL),E ; ; OUTPUT DIGITS WITH ; ; WHILE ON TRACK 0, WRITE THE DESCRIPTOR SECTOR & LOGON DRIVE ; CALL WRTID ;WHILE WE'RE HERE, WRITE ID SECTOR JR NZ,T ; DE= REMAINDER ; BC= -BC ; ;*************************************************************************** DECDIG: ; ;  ; LD C,1 ;CONSOLE READ FUNCTION # CALL BDOS ; ; MASK BIT 7 ; AND A,7FH ; ; IF CTRL-C THEN ABORT ; CP A,CTRLCT Z ;IF LOGON OK THEN RETURN ; ; ERROR ENCOUNTERED, TELL IT ; WIDERR: LD DE,MSGNC ;ELSE OUTPUT ERROR & RETURN CALL MSGO LEADING SPACES ; LD HL,TTHOU ;SET PTR LD BC,500H ;5 DIGITS, NOCONVERT 0 TO SPACE = FALSE ; NXTDEC: LD A,(HL) ;FETCH DIFMTDSK ; ; DO SIDE 1 ; DOSID1: LD HL,FIOPB + PBSECO SET 6,(HL) ; CALL FMTTRK JR NZ,FMTDSK ; ; TRACK 0 DONE, GO  SAVE DIGIT PTR ; PUSH HL ; ; SUBTRACT DIVISOR FROM VALUE ; EX DE,HL ADD HL,BC ; ; IF OVERFLOW THEN EXIT ; J JP Z,REBOOT ; ; CONVERT LOWER CASE TO UPPER CASE ; CP A,'a' RET C ; CP A,'z' + 1 RET NC ; AND A,5FH RET T XOR A,A DEC A RET ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; FORMAT TRACK FGIT DEC HL ;NEXT DIGIT ADD A,'0' ;CONVERT TO ASCII CP A,'0' ;IF NOT 0 THEN NOCONVERT TO SPACE = TRUE JR NZ,FIRST ; DO REMAINING TRACKS ; FMTLP: ; ; BUMP TRACK ; LD HL,(FIOPB + PBTRKO) INC HL LD (FIOPB + PBTRKO),HL ; ; IF LAST R NC,ADDIT ; ; ELSE RESTORE DIGIT PTR AND INCREMENT DIGIT ; EX DE,HL ; POP HL INC (HL) ; ; NO OVERFLOW, TRY AGAI ;*************************************************************************** ; ; CONSOLE OUTPUT SUBR ; ENTRY- E= CHAR ; UNCTION ; EXIT - AF= /0: ERROR ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ FMTTRK: ; ;  INC C ;ELSE IF FLAG != 0 THEN DIGIT OCCURRED DEC C JR NZ,OUTNUM ; LD A,B ;AT LEAST ONE 0 DEC A LD A,'0' JR Z,OUTTRACK DONE THEN EXIT LOOP ; LD DE,MAXTRKS OR A,A SBC HL,DE JP NC,DOCHK ; ; ELSE FORMAT NEXT TRACK, SIDE 0 ; LD HN ; JR DECDIG ; ; ; OVERFLOW PRODUCED NEGATIVE NUMBER, RESTORE BY ADDING BACK ; ADDIT: OR A,A ;ADD BACK BY SUBTRACT;*************************************************************************** CO: LD C,2 ;CONSOLE OUTPUT FUNCTION # JP BDOS  DISPLAY FORMATTING DATA ON CONSOLE ; LD DE,FMTGM ;OUTPUT FORMATTING MESSAGE CALL MSGOT ; LD HL,(FIOPB + PBTRKO) CALLNUM ; LD A,' ' ;PAD WITH LEADING BLANKS UNTIL DIGIT JR OUTNUM ; ; NON-0 DIGIT OCCURRED, FLAG = TRUE ; FIRST: INC C L,FIOPB + PBSECO RES 6,(HL) ; CALL FMTTRK JP DOSID1 ; ; ; FORMAT DONE, GO TEST FOR READ ERRORS ; DOCHK CALL CHECK ING -N SBC HL,BC EX DE,HL ; ; SET UP FOR NEXT LEAST SIGNIFICANT DIGIT ; POP HL DEC HL RET UNIT: DS 4 TTHOU:  ;*************************************************************************** ; ; PUT DECIMAL SUBROUTINE OUTPUT 5 DIGIT DEC PUTD ; LD DE,ENDEQM CALL MSGOT ; ; EXECUTE FORMAT TRACK ; LD HL,FIOPB CALL EXECIOPB RET Z ;IF NO ERROR THEN RE; ; OUTPUT DIGIT ; OUTNUM: PUSH HL PUSH BC LD E,A LD C,2 CALL BDOS POP BC POP HL DJNZ NXTDEC ; ; DONE ALL ;CHECK FOR READ ERRORS JP FMTDSK ;READY FOR ANOTHER DISK SUBTTL SUBROUTINES ;**************************************DS 1 ;*************************************************************************** ; ; WRITE ID SECTOR ; EXIT - AF= /0:IMAL NUMBER ON CONSOLE ; ENTRY- HL= VALUE TO OUTPUT ; EXIT - HL, DE, BC, A= ? ; ;*******************************************0 ( ) *!+",#-$.%/ &0 'TURN ; ; IF SEEK ERROR THEN TELL DIFFERENT MESSAGE ; LD DE,MSGNC ;ELSE OUTPUT ERROR MSG CP A,SEEKERR ;IF SEEK ERROR THE 0 THEN RETURN ; JP P,RDLP ; LD DE,OKM JP MSGOT ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ PAUSE: ; ; OUTPUT PROMPT ; LD DE,MSGXX ;PRINT TYPE CR WHEN READY MSG CALL MSGOT ; ; GET USER RESPONSE ; CALL C; PUT IOPB PTR WHERE WE CAN USE OFFSETS ; PUSH HL POP IY ; ; FETCH RESULT STATUS ; LD A,(IY+PBSTATO) ; ; PRESE: ; ; IF LAST SECTOR OF TRACK THEN DONE ; LD HL,NSECTS LD A,(CURSEC) AND A,7FH ;MASK OFF DRIVE BIT CP A,(HL) JR N DIFFERENT MESSAGE JR NZ,FTE1 ; LD DE,SKERM ; FTE1: CALL MSGOT ; ; RETURN ERROR FLAG ; XOR A,A DEC A RET +++++++++ ; ; EXECUTE IOPB FUNCTION ; ENTRY- HL= IOPB PTR ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++I ; ; IF NOT CR THEN RETURN NZ ; CP A,CR RET ;********************************************************************T RETURN DATA ; OR A,A PUSH AF ; ; DISPLAY PREFIX MESSAGE ; PUSH IY ;SAVE REGS 1ST PUSH AF ; LD DE,IOPBERM CNC,TDONE ; ; OUTPUT TESTING TRACK MESSAGE ; LD DE,TSTGM CALL MSGOT ; LD HL,(RDIOPB + PBTRKO) CALL PUTD ; ; OUT ;*************************************************************************** ; ; SELECT DRIVE SUBR ; EXIT - CF= ERROR ; +++++++++++++ EXECIOPB: ; ; SET UP IOPB ADDRESS ; LD A,L OUT (HDATA),A LD A,HIOPBL OUT (HCMD),A ; EXEC1: IN A,(H******* ; ; CHECK FUNCTION CHECKS ALL TRACKS BY READING BACKWARD FROM LAST TRACK ; ;**************************************ALL MSGOT ; ; DISPLAY ERROR DATA ; POP AF LD L,A LD H,0 CALL PUTD ; POP IY PUSH IY LD L,(IY + PBST1O) LD HPUT SIDE NO. ; LD DE,SIDEM CALL MSGOT ; LD A,(RDIOPB + PBSECO) RLCA RLCA AND A,1 LD L,A LD H,0 CALL PUTD ; ;*************************************************************************** SELDR: ; ; OUTPUT PROMPT ; LD DE,MSGFD CASTATUS) BIT HBUSYB,A JR NZ,EXEC1 ; CALL GETRES RET C ; LD A,H OUT (HDATA),A LD A,HIOPBH OUT (HCMD),A ; EXEC2************************************* CHECK: ; ; SET UP ; LD HL,(FIOPB + PBTRKO) ;START WITH LAST TRACK FORMATTED DEC ,0 CALL PUTD ; ; RESTORE REGS ; POP HL ;IOPB PTR POP AF ;STATUS POP IY ;IY ; ; DONE ; RET ;%%% ; *I ; OUTPUT SECTOR ; LD DE,SECM CALL MSGOT ; LD HL,(RDIOPB + PBSECO) RES 7,L ;MASK OFF SIDE BIT RES 6,L CALL PUTLL MSGOT ; ; GET RESPONSE ; CALL CI ; ; IF RETURN THEN RETURN CF ; CP A,CR SCF RET Z ; ; SAVE DRIVE LETTER: IN A,(HSTATUS) BIT HBUSYB,A JR NZ,EXEC2 ; CALL GETRES RET C ; XOR A,A OUT (HDATA),A LD A,HIOPBX OUT (HCMD),AHL LD (RDIOPB + PBTRKO),HL ; LD A,(FIOPB + PBDRVO) ;SAME DRIVE LD (RDIOPB + PBDRVO),A ; ; NEW LINE ; LD DE,CRLFM NCLUDE DPBDEF.Z80 SUBTTL DISK DESCRIPTOR SECTOR DATA ;#####################################################################D ; ; EXECUTE THE READ ; LD HL,RDIOPB CALL EXECIOPB ; LD DE,ERM ;IF READ ERROR THEN OUTPUT ERROR CALL NZ,MSGOT  IN MESSAGES ; LD (DRLTR),A ;ELSE SAVE DRIVE LETTER & TEST FOR LEGAL LD (LTRSE),A ; ; TEST FOR LEGAL DRIVE {0..3} ;  ; EXEC3: IN A,(HSTATUS) BIT HBUSYB,A JR NZ,EXEC3 ; CALL GETRES RET C ; ; EXECUTE THE IOPB ; LD A,HEXEC OUT  CALL MSGOT ; ; ALL SET TO DO TRACK ; VLP: ; ; SET TRACK SIZE ; RDTRKL: SETNSEC: LD A,HDSPT ;OFFSET FOR TEST L###### ; ; DESCRIPTOR SECTOR ; ;########################################################################### IDSIMG: ; ;  ; ; NEXT SECTOR & REPEAT ; LD A,(CURSEC) INC A JP RDLP ; ; ; TRACK IS DONE ; TDONE: ; ; IS DOUBLE SIDED, TSUB A,'0' CP A,4 JR C,NMBRD ;IF LEGAL THEN CONTINUE ; ; ILLEGAL DRIVE, REPEAT ; LD DE,MSGSE ;PRINT SELECT ERROR MESS(HCMD),A EXEC4: IN A,(HSTATUS) BIT HBUSYB,A JR NZ,EXEC4 ; ; FALL INTO GET RESULTS FUNCTION ; ;*******************D (NSECTS),A ; ; START WITH 1ST SECTOR ; LD A,(FIOPB + PBSECO) ;FETCH HEAD DATA AND A,10000000B ;MASK OFF SIDE & SECTO RESERVE FIRST 16 BYTES FOR BOOT, IF NEEDED ; REPT 16 LIST OFF DB 0E5H LIST ON ENDM ; ; DISK DESCRIPTOR SECTOR KEOGGLE SIDE ; LD A,(RDIOPB + PBSECO) XOR A,40H ; ; BACK TO 1ST SECTOR ; AND A,11000000B ; ; IF SIDE == 1 THEN GO AGE CALL MSGOT JR SELDR ; ; ; DRIVE SELECTED ; NMBRD: LD (FIOPB + PBDRVO),A LD (WIDIOPB + PBDRVO),A LD (RDIOPB + ******************************************************** ; ; GET FUNCTION RESULT PROCEDURE DISPLAYS ERRORS ; ENTRY- HL= IOPB R BITS ; ; READ LOOP ; RDLP: ; ; SAVE CURRENT SECTOR ; LD (CURSEC),A ; ; SET SECTOR ; RDSOK: LD (RDIOPB + PBSY ; DB 'Disk Descriptor ' ; REPT IDSIMG + 20H - $ LIST OFF DB 0E5H LIST ON ENDM ; ; DISK PARAMETER BLOCK IMAGE, DO IT ; BIT 6,A JP NZ,RDLP ; TD1: ; ; TOGGLED BACK TO SIDE 0, NEXT TRACK ; RDNXTT: ; ; SAVE NEW SECTOR DATA ; PBDRVO),A ; ; DONE ; RET ;*************************************************************************** ; ; PAUSE FOPTR ; EXIT - NZ= ERROR ; ;*************************************************************************** GETRES: ; ; IF NO ECO),A ;SAVE CURRENT SECTOR ; ; CHECK CONSOLE FOR ABORT ; LD C,11 ;GET CONSOLE STATUS CALL BDOS ; OR A,A JP Z,NOATO BE TRANSFERRED TO BIOS AT LOGON TIME ; DW 128 ;SECTORS PER TRACK DB 5 ;BLOCK SHIFT FACTOR DB 31 ;BLOCK MASK DB 1  LD (RDIOPB + PBSECO),A ; ; NEXT TRACK ; LD A,(RDIOPB + PBTRKO) DEC A LD (RDIOPB + PBTRKO),A ; ; IF NEXT TRACK <R USER SETUP ; EXIT - ZF= PROPER USER RESPONSE ; ;***************************************************************************ERRORS THEN RETURN ; IN A,(HSTATUS) AND A,[1 SHL HERRB] + [1 SHL HFERRB] RET Z ; ; ERROR, SAVE REGS ; PUSH IY ; BRT ; LD C,1 ;FLUSH CONSOLE CHAR BEFORE ABORT CALL BDOS ; LD DE,ABRTDM ;OUTPUT ABORTED MESSAGE JP MSGOT ; ; NOABRT0 ( ) *!+",#-$.%/ &0 ' ;NULL MASK DW 1015 ;DISK SIZE -1 DW 1152/2 ;DIRECTORY MAXIMUM DB 11111111B ;ALLOC 0 DB 10000000B ;ALLOC 1 DW 0 ;CHB ' ** ABORTED **',CR,LF,'$' CNIM DB CR,LF,'Controller not installed!$' IF DIAG IOPBERM DB CR,LF,'IOPB error = (status 0005H TPA EQU 0100H ;============================ ; ; PORTS & BITS ; ;============================ ISASIBAS EQU 0D8H ;ECK SIZE DW 2 ;TRACK OFFSET ; ; PAD TO FORMAT DATA WITH E5H ; REPT IDSIMG + 40H - $ LIST OFF DB 0E5H LIST ON Efdc status) $' ENDIF SUBTTL VARIABLE DECLARATIONS NSECTS DS 1 ;NUMBER OF SECTORS IN TRACK CURSEC DS 1 ;CURRENT SECBASE ADDRESS OF ISASI PORTS HDATA EQU ISASIBAS + 1 ;HOST INTERFACE DATA I/O PORT HSTATUS EQU ISASIBAS ;HOST INTERFACE CONTRONDM ; ; DISKETTE FORMAT DATA ; DB 01101000B ;DISKETTE FLAGS ; REPT 3 DB 32 ;;SECTORS PER TRACK DB 1 ;;BYTES PER STOR LASTTRK DS 2 ;LAST TRACK ; ; FORMAT TRACK IOPB ; FIOPB DB 3 ;FORMAT TRACK DB 0 ;DRIVE DW 0 ;TRACK DW 6 ;HEAD/IL/STATUS INPUT PORT HBUSYB EQU 0 ;HOST BUSY STATUS BIT HFERRB EQU 1 ;HOST FIRMWARE ERROR BIT HERRB EQU 7 ;HOST ERROR BIT ECTOR {0:128, 1:256, 2:512, 3:1024} ENDM ; DB 0,0 ;MED & HIGH PRECOMP START TRACKS ; ; FILL REMAINING SECTOR DATA WITH  TITLE HARD DISK TEST LIST NOCOND ;*************************************************************************** ; ; HARD DISNTERLEAVE DB 01101000B ;FLAGS DW SECBUF ;DMA XFER DB 0 ;DMA XADDR DB 0 ;STATUS DB 0,0,0,0,0 ; ; WRITE ID SECTOR IO HCMD EQU HSTATUS ;HOST INTERFACE COMMAND PORT HINT EQU 0 ;HOST INTERRUPT (CMD EXECUTE) BIT HXIOPBB EQU 6 ;HOST EXECUTE IOE5H ; REPT IDSIMG + 128 - $ ;FILL OUT SECTOR LIST OFF DB 0E5H LIST ON ENDM ;####################################K INTERFACE TEST PROGRAM ; ;*************************************************************************** ; ; REVISIONS: ; ;PB ; WIDIOPB: DB 2 ;WRITE SECTOR DB 0 ;DRIVE DW 0 ;TRACK DW 1 ;SECTOR DB 0 ;FLAGS DW SECBUF ;DMA XFER DB 0 ;DMA PB COMMAND BIT HRESET EQU 7 ;HOST ADAPTER RESET BIT HIOPBL EQU 01H ;SET IOPB LO ADDR CMD HIOPBH EQU 03H ;SET IOPB HI ADDR ####################################### ; ; MESSAGES ; ;################################################################# X.0 - 5 AUG 83 GRH ; RELEASE ; 2.0 - 2 JAN 84 GRH ; MODIFIED TO INTERFACE TO THE ISASI INTELLIGENT HOST ADAPTER. ; 2.1 XADDR DB 0 ;STATUS DB 0,0,0,0,0 ; ; READ SECTOR IOPB ; RDIOPB: DB 1 ;READ SECTOR DB 0 ;DRIVE DW 0 ;TRACK DW 0 ;SCMD HIOPBX EQU 05H ;SET IOPB XADDR CMD HEXEC EQU (1 SHL HXIOPBB) + (1 SHL HINT) ;EXECUTE IOPB COMMAND DIAG0C EQU 7 ;DUMP ########## MSGSE: DB CR,LF,LF LTRSE: DB ' Is not a valid selection.$' MSGFD: DB CR,LF,LF,'Write format on drive (CR to abort- 26 FEB 84 GRH ; MODIFIED COMMANDS TO ALLOW INCLUSION IN USER MODULE ; 2.2 - 13 APR 85 GRH ; Modified parameters to alloECTOR DB 0 ;FLAGS DW SECBUF ;DMA XFER DB 0 ;DMA XADDR DB 0 ;STATUS DB 0,0,0,0,0 ; ; LOGON IOPB ; LOGIOPB: DB 0 BUFFER COMMAND DMPBUF EQU 4000H ; WHERE THE DUMP BUFFER COMMAND PUTS IT BS EQU 08H LF EQU 0AH CR EQU 0DH SUBTTL MACRO): $' MSGNC: DB CR,LF,LF,'Execution Error!$' SKERM: DB CR,LF,'Seek Error. Is Drive Double Sided?$' MSGXX: DB CR,LF,LF,'Type Cw hard disks & floppies to be mixed ; (drive parameters not fixed) ; Modify to make easier to use. ; VERS EQU '22' ; ;**** DB 0 ;DRIVE DW 0 ;TRACK DW 1 ;SECTOR DB 0 ;FLAGS DW SECBUF ;DMA XFER DB 0 ;DMA XADDR DB 0 ;STATUS DB 0,0,0,0,0 ;S ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ; ; CONVERT TO HEX MACRO CONVERTS A BINARY BYTER when drive ' DRLTR: DB ' is ready. $' FMTGM DB CR,'Formatting track $' ENDEQM DB ' End = $' TSTGM DB CR,'Testing track $*********************************************************************** SUBTTL DEFINITIONS FALSE EQU 0 TRUE EQU NOT FALSE D ; READ SECTOR BUFFER ; SECBUF DS 1024 ;SECTOR BUFFER END  ASSEMBLY-TIME CONSTANT ; TO ASCII-HEX CHARS. ; ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ' SIDEM DB ' Side $' SECM DB ' Sector $' CRLFM DB CR,LF,'$' OKM DB ' Ok',CR,LF,'$' ERM DB ' Error!',CR,LF,'$' ABRTDM DIAGMODE EQU FALSE ;============================ ; ; ADDRESSES ; ;============================ RBOOT EQU 0000H BDOS EQU 0 ( ) *!+",#-$.%/ &0 'CVHEX MACRO #VAL HVAL DL #VAL SHR 4 LVAL DL #VAL AND 0FH IF HVAL > 9 ;;CONVERT HIGH NIBBLE DB HVAL + '7' ELSE DB HVA ;IF DRIVE_TYPE = 0 THEN DO HARD JR Z,FHD1 PUSH IY ;IY IS CHANGED BY DEFF1 CALL DEFF1 ;ELSE DEFINE FLOPPY FORMAT PED BY A COMMAND BYTE ; COUNT OF 0. FORMAT: ; BYTE 0: COMMAND CHAR BYTE COUNT, N ; BYTE 1-N: COMMAND TEXT ; BYTE N+1: LOW BYTA),L ;SET SECTOR BUFFER DMA LD (IY+[PBDMA+1]),H LD (IY + PBCMD),1 ;CHANGE TO READ COMMAND DEC (IY + PBTRK) ;BACK UP TO ************************* INIT: LD HL,($MEMRY) ;INIT IOPB XFER ADDRESSES LD (XFERPB),HL RET ;***********************AL + '0' ENDIF IF LVAL > 9 ;;CONVERT HIGH NIBBLE DB LVAL + '7' ELSE DB LVAL + '0' ENDIF ENDM SUBTTL REQUIOP IY FHD1: LD L,(IX + DTBLID) ;SET ID SECTOR PTR LD H,(IX + [DTBLID + 1]) LD (IDIOPB + PBDMA),HL LD DE,INTLM ;ASK FOE OF COMMAND EXECUTION ADDRESS ; BYTE N+2: HIGH BYTE OF COMMAND EXECUTION ADDRESS ; BYTE N+3: NEXT COMMAND ENTRY (BYTE 0) OR 0LAST TRACK FORMATTED VNXTTRK: PUSH IX PUSH IY LD C,11 ;CHECK FOR USER ABORT CALL BDOS POP IY POP IX OR A JR*************** ; ; CLEAR CONTROLLER COMMAND ; ;************************************** CLEARC: LD A,1 SHL HRESET ;RESET RED CODE FOR MAIN MODULE REL ;############################ ; ; SIGN ON MESSAGE ; ;############################ ENTRY SIR INTERLEAVE FACTOR CALL GETDPAR LD HL,16 ;CHECK LIMITS SBC HL,DE JP C,PARERR LD (IY+PBSEC),E ;LOAD IT LD DE IF NO MORE ENTRIES ; ;########################################################################## ENTRY UCMDT UCMDT: DB 3 NZ,FABRT LD (IY+PBSEC),0 ;START AT 1ST SECTOR XOR A ;ERROR_FLAG := FALSE LD (ERRFLG),A LD DE,VTRKM PUSH IX  OUT (HCMD),A XOR A OUT (HCMD),A EX (SP),HL ;WAIT FOR RESULTS OF RESET EX (SP),HL CLRWT: IN A,(HSTATUS) CP 0FFH GNON ;PUBLIC FOR MAIN MODULE SIGNON: DB CR,LF,'Hard Disk Monitor Utility Ver ' DB HIGH VERS DB '.' DB LOW VERS DB ,TRKSM ;ASK FOR TRACKS CALL GETDPAR LD L,(IX + DTBLTRK) LD H,(IX + [DTBLTRK + 1]) SBC HL,DE JP C,PARERR LD A,E L,'REC' ;RECALIBRATE DW RECALC DB 6,'FORMAT' ;FORMAT DISK DW FORMC DB 4,'READ' ;READ BLOCK(S) DW DREADC DB 4,'PUSH IY CALL EDITOR POP IY POP IX VNXTSEC: PUSH IX PUSH IY CALL EXECUTE ;READ SECTOR POP IY POP IX JR NC,V ;IF BOARD NOT INSTALLED THEN EXIT JR Z,NOHDW BIT HBUSYB,A JR NZ,CLRWT CALL GETRES RET C LD HL,-1 ;INIT DTYPECR,LF,'Copyright (c) 1983' DB ' GRH Enterprises Cupertino, CA' DB CR,LF,'Type ''HELP'' for commands' DB CR,LF,'$' ;##D (MAXTRK),A LD (IY + PBTRK),0 ;START AT TRACK 0 CALL EXECUTE ;FORMAT TRACK 0 JP C,FABRT PUSH IY CALL CRLF LDWRIT' ;WRITE BLOCK(S) DW WRITC DB 3,'SEE' ;SEEK TRACK DW SEEKC DB 2,'DE' ;DEFINE DISK PARAMS DW DEFINC DB 2,NOERR LD A,-1 ;ERROR_FLAG := TRUE LD (ERRFLG),A VNOERR: INC (IY + PBSEC) ;NEXT SECTOR LD A,(IY + PBSEC) ;CHECK IF TRS LD (DTYPE0),HL LD (DTYPE0 + 2),HL LD A,L LD (THISDRV),A RET NOHDW: LD DE,NOHDWM ;ALERT USER JP EDITOR ;***#################################### ; ; COMMAND LIST FOR HELP COMMAND ; ;###################################### ENTRY UCM DE,FMTM ;PRINT '*' CALL EDITOR LD IY,IDIOPB ;WRITE ID SECTOR WHILE HERE CALL EXECUTE POP IY JP C,FABRT CALL 'CL' ;CLEAR CONTROLLER DW CLEARC DB 2,'DU' ;DUMP ADAPTER RAM DW DUMPC DB 0 ;TERMINATOR SUBTTL COMMANDS ;====ACK DONE CP (IX + DTBLSEC) JR NZ,VNXTSEC LD A,(ERRFLG) ;CHECK FOR ERRORS IN TRACK OR A LD DE,VERRM ;ASSUME ERROR J*********************************** ; ; RECALIBRATE COMMAND ; ;************************************** RECALC: LD IY,NULPBDTX UCMDTX: DB CR,LF,'RECalibrate drive |' DB ' SEEk track' DB CR,LF,'READ sector(s) LOGON ;INSURE HOST ADAPTER GETS DRIVE INFO JR NXTTRK FMTLP: CALL EXECUTE JP C,FABRT LD A,(THISDRV) ;IF FLOPPY THEN======================== ; ; PUBLIC PROCEDURES ; ;============================ ENTRY INIT ;============================R NZ,VOUTV LD DE,VOKM ;CHANGE TO NO ERROR VOUTV: PUSH IX PUSH IY CALL EDITOR POP IY POP IX LD A,(IY+PBTRK) ; LD (IY+PBCMD),4 ;RECAL COMMAND CALL GETLUN RET C JP EXECUTE ;************************************** ; ; FOR |' DB ' WRITe sector(s)' DB CR,LF,'FORMAT drive |' DB ' DEfine disk params' DB  SKIP HEAD CHANGE OR A JR NZ,FMTLP1 LD A,64 ;BUMP HEAD # ADD A,(IY + PBSEC) LD (IY + PBSEC),A JR NC,FMTLP ;IF BAC ; ; EXTERNAL PROCEDURES ; ;============================ EXTRN CRLF, RDCON, SKIP, SEARCH, SYNERR, EDITOR, PRTHEX EXTRN CNEXT TRACK SUB A,1 LD (IY+PBTRK),A JR NC,VNXTTRK FABRT: LD (IY+PBSEC),0 ;RESTORE ILV BYTE TO 0 CALL CRLF ;MOVE CUMAT DRIVE COMMAND ; ;************************************** FORMC: LD IY,XFERPB LD (IY+PBCMD),3 CALL GETLUN ;ASK FORCR,LF,'CLear controller hang-up |' DB ' DUmp adapter RAM' DB CR,LF,'CTRL-C To Exit to CP/M' DB CR,LF,'$'K TO 00 (CF) THEN DROP OUT FMTLP1: PUSH IX PUSH IY LD DE,FMTM ;PRINT '*' CALL EDITOR POP IY POP IX NXTTRK: INKBNDS, CPBNDS, GET1PAR, SPACE ;============================ ; ; EXTERNAL VARIABLES ; ;============================ EXTRRSOR AWAY FROM VERIFY LINES CALL CRLF CALL CRLF JP CRLF ;************************************** ; ; READ SECTOR(S)  DRIVE RET C ;ALLOW FOR CHANGE OF MIND LD IX,HDTBL ;USE HARD DISK AS DEFAULT LD A,(THISDRV) ;FETCH DRIVE PARAMS OR  ;########################################################################## ; ; COMMAND TABLE FOR LOCAL COMMANDS, TERMINATC (IY+PBTRK) ;NEXT TRACK LD A,(MAXTRK) CP (IY+PBTRK) JR NZ,FMTLP ; ; NOW CHECK SECTORS ; LD HL,SECBUF LD (IY+PBDMN CMDPTR, $MEMRY, PARAM1, PARAM2 ;************************************** ; ; INITIALIZE INTERFACE SUBR ; ;*************0 ( ) *!+",#-$.%/ &0 'COMMAND ; ;************************************** DREADC: LD IY,XFERPB ;USE XFER CDB LD (IY+PBCMD),1 ;READ COMMAND JR  PUSH IY ;SAVE IOPB LD IY,LOGIOPB LD (IY + PBDRV),A CALL EXECUTE ;LOG ON DRIVE IN HOST ADAPTER POP IY ;RESTORE IOPB  ;************************************************ ; ; DEFINE FLOPPY DISK PARAMS COMMAND ; ;********************************ER SUBR ; ENTRY- DE= PROMPT MESSAGE PTR ; EXIT - DE= VALUE ; CF= 0 ; ;************************************************ GE HL,DMPBUF ;OUTPUT BUFFER OFFSET LD DE,($MEMRY) SBC HL,DE LD A,H PUSH HL CALL PRTHEX POP HL LD A,L CALL PRTHEX DOXFER ;************************************** ; ; WRITE SECTOR(S) COMMAND ; ;************************************** W LD A,(THISDRV) ;RETURN DRIVE FLAGS RET ;******************************************* ; ; GET LOGICAL ADDR FROM USER **************** DEFINC: CALL GETLUN RET C DEFF1: LD IY,NULPB ;USE NUL CDB LD (IY+PBCMD),7 ;DEFINE CMD LD DE,QSITDPAR: CALL EDITOR ;OUTPUT PROMPT CALL RDCON ;GET INPUT LD HL,(CMDPTR) CALL SKIP ;SKIP LEADING SPACES CALL GETD RET SUBTTL SUBROUTINES ;************************************** ; ; GET LUN FROM USER SUBR ; EXIT - CF= ERROR ; HL= RITC: LD IY,XFERPB ;USE XFER CDB LD (IY+PBCMD),2 ;WRITE COMMAND DOXFER: CALL GETLUN RET C CALL GETLAD ;GET USER'S SUBR ; ;******************************************* GETLAD: LD A,(THISDRV) ;MODIFY TEXT MESSAGES FOR MAX VALUES OR A JRDEM ;ASK FOR SIDES CALL GETDPAR LD HL,2 ;CHECK FOR LIMIT SBC HL,DE JP C,PARERR LD A,E DEC A JP M,PARERR LEC ;CONVERT EX DE,HL ;SET UP FOR CALLER TO CHECK LIMITS OR A RET ;***********************************************CDB PTR ; BC, DE, AF= ? ; ;************************************** GETLUN: LD DE,LUNMSG ;OUTPUT PROMPT CALL EDITOR CBLOCK RET C CALL GETXADR ;GET WHERE USER WANT'S TO PUT IT JP NC,DOXFER1 LD DE,PARERM ;OUTPUT ERROR JP EDITOR D Z,DOLUN0 LD DE,QSEC1M ;ASK FOR SECTOR CALL GETDPAR LD HL,26 ;CHECK FOR LIMIT STRSEC: SBC HL,DE JR C,PARERR SECD (IY+PBSEC),A ;SET SECTOR BYTE TO SIDES LD IX,SDTBL LD DE,QDENSM ;ASK FOR DENSITY CALL EDITOR CALL RDCON ;GET DENS* ; ; GET DECIMAL VALUE SUBR ; ENTRY- HL= PTR TO ASCII TEXT ; EXIT - HL= NUMBER ; ;***************************************ALL RDCON LD HL,(CMDPTR) CALL SKIP ;IF NO ENTRY THEN DO AGAIN JR Z,GETLUN LD A,(HL) SUB '0' RET C CP 4 CCF OXFER1: RDDLP: ; DIAGNOSTIC FOR NOW ; CALL DUMP CALL EXECUTE ;SEND CDB RET C LD A,(IY+PBDMA) ;INCREMENT PTR OK: LD A,E ;SET SECTOR LD (XFERPB + PBSEC),A JP GETTRK PARERR: LD DE,PARERM ;OUT OF LIMIT CALL EDITOR SCF RET DITY LD HL,(CMDPTR) CALL SKIP LD A,(HL) AND 5FH CP 'S' ;IF SINGLE THEN BYTE OK AS IS JR Z,SINGLE CP 'D' ;IF N********* GETDEC: EX DE,HL ;DE = PTR LD HL,-1 ;IF 1ST CHAR NOT NUMBER THEN RETURN -1 LD A,(DE) CP '0' RET C CP  RET C LD (LUNSV),A ;SAVE IT FOR OTHERS LD (NULPB + PBDRV), A LD (XFERPB + PBDRV),A LD (IDIOPB + PBDRV),A LD HL,DADD A,128 LD (IY+PBDMA),A LD A,(IY+[PBDMA + 1]) ADC A,0 LD (IY+[PBDMA + 1]),A LD A,(IY+PBDMAX) ADC A,0 LD (IY+PBDMOLUN0: LD DE,QSEC0M ;ASK FOR SECTOR CALL GETDPAR LD HL,255 ;CHECK LIMIT JR STRSEC ;*******************************OT DOUBLE THEN ERR JP NZ,PARERR LD A,(IY+PBSEC) ;IF DOUBLE THEN SET DOUBLE BITS OR 00000110B LD (IY+PBSEC),A LD IX'9' + 1 CCF RET C INC HL ;START WITH 0 GETDLP: LD A,(DE) ;GET CHAR SUB '0' ;IF NOT NUMBER THEN RETURN RET C TYPE0 ;CHECK FOR DRIVE PARAMETERS ADD A,L LD L,A LD A,0 ADC A,H LD H,A LD A,(HL) ;IF ALREADY SET THEN RETURN LD (AX),A LD A,(IY+PBSEC) ;NEXT SECTOR INC A LD (IY + PBSEC),A JR NZ,TRKOK INC (IY + PBTRK) ;1ST SECTOR OF NEW TRACK ***************** ; ; GET TRACK FROM USER SUBR ; ;************************************************ GETTRK: LD A,(THISDRV),DDTBL SINGLE: JP EXECUTE ;EXECUTE ;************************************** ; ; DUMP ADAPTER RAM INTO BUFFER ; ;**** CP 10 CCF RET C PUSH HL ;X = X * 10 + N POP BC ADD HL,HL ; X * 10 = (X * 4 + 1) * 2 ADD HL,HL ADD HL,BC ADTHISDRV),A ;SET FLAG INC A LD A,(LUNSV) RET NZ PUSH HL LD DE,DTYPEM ;OUTPUT TYPE PROMPT CALL EDITOR CALL RDCON TRKOK: LD HL,(COUNT) DEC HL ;IF NOT DONE THEN LOOP LD (COUNT),HL LD A,L OR H JP NZ,RDDLP RET ;************ ;IF HARD DISK THEN EXIT OR A JR Z,HARDTRK LD DE,QTRK1M ;ASK FOR TRACK CALL GETDPAR LD HL,76 ;CHECK LIMITS STRTR********************************** DUMPC: XOR A ;XADDR = 0 OUT HDATA,A LD A,DIAG0C ;EXECUTE COMMAND OUT HCMD,A DUD HL,HL ADD L LD L,A INC DE ;PTR ++ JR NC,GETDLP INC H JR GETDLP ;**************************************** ;GET USER RESPONSE LD HL,(CMDPTR) CALL SKIP RET Z LD A,(HL) CP 'H' LD A,0 JR Z,SETTYPE LD A,1 SETTYPE: ************************** ; ; SEEK COMMAND ; ;************************************** SEEKC: LD IY,XFERPB ;USE XFER CDB K: SBC HL,DE JR C,PARERR LD (XFERPB + PBTRK),DE ;STORE TRACK # RET HARDTRK: LD DE,QTRK0M ;ASK FOR TRACK CALL GETDMPWT: IN A,(HSTATUS) ;WAIT FOR DONE BIT HBUSYB,A JR NZ,DUMPWT LD A,0 ;INSURE JADE CONTROLLER OUT OF MEMORY MAP OUT (4******** ; ; GET TRANSFER ADDR FROM USER SUBR ; EXIT - (PARAM1)= XFER ADDR ; (BYTCNT)= XFER BYTE COUNT ; CF= BOUNDS ERRORPOP HL ;STORE NEW DRIVE TYPE LD (HL),A LD (THISDRV),A ; ; LOG ON DRIVE ; LOGON: LD A,(IY + PBDRV) ;SET UP LOGON DRIVE  LD (IY+PBCMD),5 ;SEEK COMMAND CALL GETLUN RET C CALL GETTRK ;GET USER'S TRACK RET C JP EXECUTE ;SEND CDB PAR LD HL,255 ;CHECK FOR LIMIT JR STRTRK ;************************************************ ; ; GET DECIMAL PARAMET3H),A ; THIS CORRECTS A BUG IN ISASI! CALL GETRES ;CHECK FOR FIRMWARE ERROR ; RET C LD DE,DMPBM CALL EDITOR LD0 ( ) *!+",#-$.%/ &0 ' ; ;************************************************ GETXADR: LD DE,XADRM ;ASK FOR XFER ADDR CALL EDITOR CALL RDCON  SUBTTL IDENTITY SECTORS ;############################ ; ; HARD DISK ID SECTOR ; ;############################ HDIDSEC: LD A,HEXEC ;GO EXECUTE IT OUT (HCMD),A EXEC4: IN A,(HSTATUS) BIT HBUSYB,A JR NZ,EXEC4 ; FALL INTO GET RESULTS ;######################### ; ; DOUBLE DENSITY ID SECTOR ; ;################################# DDIDSEC: DB 'Jade DD Double dM1) ; CALL PRTHEX ; LD A,(PARAM1 + 1) ; CALL PRTHEX ; CALL SPACE ; LD A,(COUNT) ; CALL PRTHEX ; LD A,(COUNT + 1) ; CAL;GET PARAMETER LD HL,(CMDPTR) LD DE,PARAM1 CALL GET1PAR RET C LD DE,XCNTM ;ASK FOR XFER COUNT CALL GETDPAR LD A, DB 'Jade DD Hard disk format ' ;CONFIRMATION TEXT ; ; DISK PARAMETER BLOCK IMAGE FOR BIOS AT LOGON ; ; DISK SIZE= 4,161,53************************************** ; ; GET RESULTS SUBR OUTPUTS ERROR ; IF ERROR. ; EXIT - CF= HARD ERROR ; ;********ensity format ' ;CONFIRMATION TEXT ; ; DISK PARAMETER BLOCK IMAGE FOR BIOS AT LOGON ; ; DISK SIZE= 492,500 ; CLUSTER SIZE= L PRTHEX CALL CRLF RET ENDIF SUBTTL MESSAGES LUNMSG DB CR,LF,'Logical Unit (0..3) - $' FMTM DB '*$' FERRM DB CRE ;IF CNT == 0 THEN ABORT OR D SCF RET Z LD (COUNT),DE ;SAVE COUNT LD DE,(PARAM1) ;CHECK LIMITS ADD HL,DE LD 6 ; CLUSTER SIZE= 4096 (4K) ; DIRECTORY SIZE= 1152 / 2 ; ALLOCATION TABLE SIZE (BIOS)= 127 BYTES ; REPT HDIDSEC + 32 - $ ****************************** GETRES: IN A,(HSTATUS) AND (1 SHL HERRB) + (1 SHL HFERRB) RET Z BIT HFERRB,A JR Z,D2048 (2k) ; DIRECTORY SIZE= 128 ; ALLOCATION TABLE SIZE (BIOS)= 32 BYTES ; REPT DDIDSEC + 32 - $ ;POSITION DPB OFFSET LI,LF,'FIRMWARE ERROR # $' HDERM DB CR,LF,'DISK ERROR # $' SPM DB ' $' PBHDRM DB CR,LF,'C D TRK SEC F DMA X STATUS (PARAM2),HL CALL CKBNDS ;ADD OFFSET & CHECK BOUNDS LD HL,(PARAM1) ;SET IOPB LD (XFERPB + PBDMA),HL RET ;****;POSITION DPB OFFSET LIST OFF DB 0E5H ;FILL WITH E5 LIST ON ENDM DW 128 ;SECTORS PER TRACK (SPT) DB 5 ;BLOCK SSKERR LD DE,FERRM CALL EDITOR IN A,(HDATA) ;GET ERROR CODE CALL PRTHEX CALL CRLF SCF RET DSKERR: LD DE,HDST OFF DB 0E5H ;FILL WITH E5 LIST ON ENDM ; DW 52 ;SECTORS PER TRACK (SPT) DB 4 ;BLOCK SHIFT FACTOR (BSH) DB 15 SPARES$' PARERM DB CR,LF,'PARAMETER ERROR$' NOHDWM DB CR,LF,'Controller Not Responding to Port ' CVHEX ISASIBAS DB 'H !********************************** ; ; EXECUTE THE IOPB ROUTINE ; ENTRY- IY= IOPB PTR ; EXIT - CF= ERROR ; ;**************HIFT FACTOR (BSH) DB 31 ;BLOCK MASK (BLM) DB 1 ;NULL MASK (EXM) DW 1015 / 2 ;DISK SIZE (CLUSTERS)-1 (DSM) DW 1152 ;ERM CALL EDITOR LD A,(IY+PBSTAT) CALL PRTHEX LD DE,SPM CALL EDITOR LD A,(IY+[PBSTAT + 1]) CALL PRTHEX LD DE, ;BLOCK MASK (BLM) DB 1 ;NULL MASK (EXM) DW 242 ;DISK SIZE (CLUSTERS)-1 (DSM) DW 63 ;DIRECTORY MAX (DRM) DB 10000$' QSEC0M DB CR,LF,'Enter Sector # (0..255) - $' QTRK0M DB CR,LF,'Enter Track # (0..255) - $' QSEC1M DB CR,LF,'Enter Sector************************ EXECUTE: IF DIAGMODE CALL DUMP ;DIAGNOSTIC ENDIF PUSH IY ;GET IOPB PTR POP HL LD ADIRECTORY MAX (DRM) DB 11111111B ;ALLOCATION 0 (AL0) DB 10000000B ;ALLOCATION 1 (AL1) DW 0 ;CHECK SIZE (CKS) DW 2 SPM CALL EDITOR LD A,(IY+[PBSTAT + 2]) CALL PRTHEX LD DE,SPM CALL EDITOR LD A,(IY+[PBSTAT + 3]) CALL PRTHEX 000B ;ALLOCATION 0 (AL0) DB 00000000B ;ALLOCATION 1 (AL1) DW 16 ;CHECK SIZE (CKS) DW 2 ;TRACK OFFSET (OFF) ; ; DIS # (0..25) - $' QTRK1M DB CR,LF,'Enter Track # (0..76) - $' XADRM DB CR,LF,'Enter Xfer Address - $' XCNTM DB CR,LF,'Enter Sec,L ;OUTPUT IOPB ADDRESS TO HOST ADAPTER OUT (HDATA),A LD A,HIOPBL OUT (HCMD),A EXEC1: IN A,(HSTATUS) BIT HBUSYB,A JR;TRACK OFFSET (OFF) ; ; DISK CONTROLLER PARAMETERS ; REPT HDIDSEC + 48 - $ ;LOCATE BLOCK LIST OFF DB 0E5H LIST ON IF DIAGMODE CALL DUMP ENDIF CALL CRLF SCF RET IF DIAGMODE ;************************************** ; ; DUMK CONTROLLER PARAMETERS ; REPT DDIDSEC + 48 - $ ;LOCATE BLOCK LIST OFF DB 0E5H LIST ON ENDM DB 0 ;SECTOR STAGGERtor Count - $' TRKSM DB CR,LF,'Tracks to format? (1..256) - $' INTLM DB CR,LF,'Enter Interleave Factor (0..16) - $' QSIDEM DB NZ,EXEC1 CALL GETRES ;IF ERROR THEN ??? RET C LD A,H OUT (HDATA),A LD A,HIOPBH OUT (HCMD),A EXEC2: IN A,(HSTAENDM DB 0 ;SECTOR STAGGER (NOT USED FOR HARD DISK) DB 01100000B ;256B/SEC, HARD, 1 DENS, 1 SIDE REPT HDIDSEC + 256 - P THE CDB TO THE CONSOLE ; ;************************************** DUMP: PUSH IY LD DE,PBHDRM ;OUTPUT HEADER FOR IOPB FIE DB 01100000B ;256B/SEC, HARD, 1 DENS, 1 SIDE REPT DDIDSEC + 256 - $ ;FILL OUT SECTOR LIST OFF DB 0E5H LIST ON END CR,LF,'Enter sides (1..2) - $' QDENSM DB CR,LF,'Enter Density (Single/Double) - $' VTRKM DB BS,'V',BS,'$' VOKM DB '-',BS,'$'TUS) BIT HBUSYB,A JR NZ,EXEC2 CALL GETRES ;IF ERROR THEN ??? RET C XOR A ;XADDR ALLWAYS BANK 0 OUT (HDATA),A $ ;FILL OUT SECTOR LIST OFF DB 0E5H LIST ON ENDM ;################################# ; ; SINGLE DENSITY ID SECTOR ;LDS CALL EDITOR CALL CRLF ;GET IOPB PTR POP HL LD B,16 ;IOPB = 16 BYTES LONG OUTLP: LD A,(HL) PUSH HL PM SUBTTL DATA AREAS DATA ;####################### ; ; DRIVE TABLES ; ;####################### HDTBL: DB 0 DW H VERRM DB BS,'?',BS,'$' DMPBM DB CR,LF,'Dumped to Buffer location: $' DTYPEM: DB CR,LF,'Enter drive type (Hard/Floppy) - $'  LD A,HIOPBX OUT (HCMD),A EXEC3: IN A,(HSTATUS) BIT HBUSYB,A JR NZ,EXEC3 CALL GETRES ;IF ERROR THEN ??? RET C  ;################################# SDIDSEC: REPT 128 ;FILL OUT SECTOR LIST OFF DB 0E5H LIST ON ENDM ;########USH BC CALL PRTHEX CALL SPACE POP BC POP HL INC HL DJNZ OUTLP ; CALL CRLF ;OUTPUT XFER ADDR, COUNT ; LD A,(PARA0 ( ) *!+",#-$.%/ &0 'DIDSEC DW 256 ;# SECTORS DW 256 ;# TRACKS SDTBL: DB 1 DW SDIDSEC DW 26 DW 77 DDTBL: DB 2 DW DDIDSEC DWent data value then waits for the user response. ; If the user enters hex data, the 2 Hex digits are loaded into ; the 'addr' RIFY SECTOR ERROR FLAG THISDRV DB -1 ;THIS DRIVE TYPE FLAGS 0: HARD, 1: FLOPPY, -1: UNSP. DTYPE0 DB -1 ;DRIVE 0 TYPE (-1 := UN EQU 128 ;STACK SIZE SECSIZ: EQU 128 ;DISK SECTOR SIZE TYPE: EQU 8 ;OFFSET LOCATION OF TYPE EXTENSION OF FILENMAE SUBTTses the following commands: ; ;*HElp ; Displays the command summary list. ;*LOAD addr filename ; Reads file 'filename' with 52 + 1 DW 77 DTBLFLG EQU 0 ;FLAG OFFSET DTBLID EQU 1 ;ID SECTOR PTR OFFSET DTBLSEC EQU 3 ;MAX SECTORS OFFSET DTBLTRK Elocation then 'addr' is incremented by 1 & the process ; is repeated. If a RETURN is entered (nul line) the data value is ; leSPECIFIED) DTYPE1 DB -1,-1,-1 LOGBUF DS 128 ;LOGON XFER BUFFER SECBUF DS 256 ;VERIFY SECTOR BUFFER REL END L PROGRAM AREA REL ; ; PUBLIC PROCEDURES ; ENTRY SYNERR, ASC2HX, SPACE, CONOUT, CONIN, CSTS, SEARCH, SKIP ENTRY CRLF, E optional 'HEX' format starting at buffer ; relative location 'addr'. Buffer bounds are checked. ;*SAve first, last filename QU 5 ;MAX TRACKS OFFSET ;################## ; ; IOPBS ; ;################## IOPBDEF MACRO #CMD,#DRV,#TRK,#SEC,#FLG,#Dft as is & 'addr' is incremented by 1 & the process is repeated. ; If a period '.' is entered as the 1st character, the commandDITOR, RDCON, GET3PAR, GET2PAR, GET1PAR, CKBNDS ENTRY CPBNDS, GETNUM, PRT2H, PRTHEX, HX2ASC ; ; GLOBAL VARIABLES ; ENTRY ; Saves the buffer image starting at buffer relative location 'first' ; through 'last' in Hex file format as file 'filename' ;MAW,#DMAX DB #CMD,#DRV,#TRK,0,#SEC,0 DB #FLG DW #DMAW DB #DMAX DS 6 ENDM NULPB: IOPBDEF 0,0,0,0,0,0,0 XFERPB:  is ; terminated. Note, the Hex values entered must have 0 in the high ; byte. I.E. 00xx or just plain xx or even yy00xx will CMDPTR, PARAM1, PARAM2, PARAM3, MEMTOP, $MEMRY ; ; EXTERNAL PROCEDURES ; EXTRN INIT EXTRN UCMDT, UCMDTX, SIGNON ; *FIll first, last, value ; Fills buffer relative locations from 'first' to 'last' (inclusive) ; with 'value'. Buffer bounds arIOPBDEF 1,0,0,0,0,0,0 IDIOPB: IOPBDEF 2,0,0,0,0,HDIDSEC,0 LOGIOPB IOPBDEF 0,0,0,0,0,LOGBUF,0 ;======================= ; ;be ok. ; ;********************************************************* ; ; REVISION STATUS: ; 2.0 - 6 Jul 83 GRH ; Te ; PTR TO END OF PROGRAM ; DATA ;FIRST BYTE OF DATA AREA SHOULD BE 103H $MEMRY DS 2 ;SET BY LINK-80 REL ;BACK TO CSEGe checked. ;*MOve first, last, dest ; Moves code from buffer relative position 'first' through 'last' ; into new buffer relat IOPB OFFSETS ; ;======================= PBCMD EQU 0 ;COMMAND BYTE PBDRV EQU 1 ;DRIVE BYTE PBTRK EQU 2 ;TRACK WORD PBSEC Est release ; 2.1 - 26 Feb 84 GRH ; Changed Sign-on, Command table & help messages to user module ; REVSN: EQU '21' ; ; ; ; SIGN ON MESSAGE HERE TO GIVE COPYRIGHT VISIBILITY ; ;SIGNON: DB CR,LF,'Hard Disk Monitor Utility Ver ' DB Hive location starting at 'dest'. Buffer ; bounds for 'dest' are checked. ;*DIsplay first <,last> ; Display buffer data from bQU 4 ;SECTOR WORD (FORMAT INTERLEAVE, FLOPPY PARAMS) PBFLG EQU 6 ;FLAGS (LOG- 0: FULL, BLOCKING (SAME AS CP/M)) PBLOG EQU 0 ;L********************************************************* SUBTTL DECLARATIONS FALSE EQU 0 TRUE EQU NOT FALSE LISTINC EQU FA TITLE BASE UTILITY DRIVER ;******************************************************** ; ; Base Utility Driver Main Module ;IGH REVSN DB '.' DB LOW REVSN DB CR,LF,'Copyright (c) 1983' DB ' GRH Enterprises Cupertino, CA' DB CR,LF,'Type ''HELuffer relative location 'first' through ; buffer relative location 'last'. If 'last' is not specified then ; 256 bytes are disOGON REQUEST BIT # PBRTRY EQU 7 ;DISABLE RETRYS BIT PBDMA EQU 7 ;XFER ADDRESS WORD PBDMAX EQU 9 ;XFER BANK ADDRESS BYTE PBLSE ; ; SYSTEM PARAMS ; SYSTEM EQU 0000H DFLTDK: EQU 0004H ;DEFAULT DISK STORAGE LOC BDOS: EQU 0005H ;CP/M ENTRY POI ; Copyright (c) 1983 GRH Enterprisess, Cupertino, CA ; by Girvin Herr ; ;********************************************P'' for commands' DB CR,LF,'$' ; ; MAIN PROGRAM ; START: LD SP,STACK ;INITIALIZE LD HL,(BDOS+1) ;GET LAST MEMORY Lplayed. If 'first' is not specified, then the ; previous 'last' is used for 'first'. ;*Substitute addr ; Allows changing byteSTAT EQU 10 ;SENSE STATUS WORDS (4 BYTES) PBSP1 EQU 14 PBSP2 EQU 15 ;####################### ; ; VARIABLES ; ;#########NT DEFBFR: EQU 0080H ;DEFAULT BUFFER LOC TPA EQU 0100H ;START OF PROGRAM ; CPMEOF: EQU 1AH ;CP/M END OF FILE CHAR (CTRL-Z************ ; ; 1- Implements the loading of object files ; in the Intel HEX format into the memory buffer. ; 3-OC. DEC HL LD (MEMTOP),HL LD HL,($MEMRY) ;SET UP FOR EVEN NIBBLE LD A,L AND 0FH ;IF NIBBLE == 0 THEN OK JR Z,MEMO values starting at buffer relative location ; 'addr' one at a time. Upon execution, this command outputs: ; 'addr' & the curr############## COUNT DW 0 ;TRANSFER COUNT LUNSV DB 0 ;LOGICAL UNIT STORAGE MAXTRK DB 0 ;LAST FORMAT TRACK +1 ERRFLG DB 0 ;VE) RDCF: EQU 10 OPENF: EQU 15 RDF: EQU 20 ; ; ASCII CHARACTERS ; LF EQU 0AH CR EQU 0DH ; ; CONSTANTS ; STKSIZ: Extensive error checking against memory buffer bounds, will not allow ; operating system or code to be compromised. ; ; U0 ( ) *!+",#-$.%/ &0 'K LD A,L ;ELSE BUMP AND 0F0H ADD A,10H LD L,A LD A,0 ADC A,H LD H,A LD ($MEMRY),HL MEMOK: LD (DISTRT),HL ; CP ':' ;IF CHAR <> COLON THEN IGNORE JR NZ,HEXRD LD D,0 ;CHECKSUM = 0 CALL BYTE JR C,HXERR ;FILE EMPTY AND AOMMAND CMDFND: INC HL ;FETCH SERVICE ADDR LD E,(HL) INC HL LD D,(HL) PUSH DE ;SET UP FOR COMMAND SCANNING LD  HEX FILENAME ; ;******************************* SAVEC: JP Z,SYNERR ;IF NO OPERANDS THEN ERR LD DE,PARAM1 ;GET 1ST & LAST OUTPUT 'FILE NOT FOUND' JP EDITOR ; ; OUTPUT BOUNDS ERROR MESSAGE ; BNDSM: LD DE,BOUNDM ;THEN OUTPUT ERROR MESSAGE JPINIT DISPLAY VARS LD (DISEND),HL LD DE,SIGNON ;OUTPUT SIGN-ON MSG CALL EDITOR CALL INIT ;GO DO INITIALIZATION ;  ;IF RECORD LENGTH = 0 THEN DONE JP Z,CONT1 LD E,A ;RECORD COUNT = BYTE CALL BYTE ;GET LOAD ADDRESS JR C,HXERR HL,(CMDPTR) ;SET UP OPERANDS FOR SOME COMMANDS LD C,' ' CALL SEARCH CALL SKIP ;ALSO PASS IN ZF IF NO FIELDS LD (CMDPTR) LD HL,(CMDPTR) CALL GET2PAR JP C,SYNERR LD HL,(PARAM2) ;COUNT = LAST - FIRST + 1 LD DE,(PARAM1) OR A SBC HL,DE  EDITOR MEMER1: LD DE,MEMERM CALL EDITOR JP CONT1 ; ; HEX FILE READ ROUTINE ; RDC1: RDC2: XOR A ;SET UP BUFFER  ; COMMAND INPUT ENTRY. ALL COMMANDS RETURN HERE IF OK. ; CONT1: CALL CRLF ;NEW LINE LD C,'*' ;OUTPUT PROMPT CALL CONOLD H,A CALL BYTE JR C,HXERR LD L,A LD BC,(HEXBASE) ;IF NEW ADDR < BASE ADDR THEN ERR SBC HL,BC JR C,HXADERR ,HL LD HL,CONT1 ;SET UP RETURN ADDR EX (SP),HL ;EXECUTE COMMAND JP (HL) ; COMMAND NOT FOUND IN TABLE CMDERR: LD JP C,SYNERR ;IF FIRST > LAST THEN ERR INC HL LD (PARAM3),HL ;SAVE COUNT IN P3 EX DE,HL ;OFFSET FIRST FOR PTR CALL CFOR 1ST READ LD (BFRCNT),A LD HL,(PARAM1) ;SET PTR TO LOAD ADDR LD (BFRPTR),HL HEXRD1: CALL GETCH ;FETCH CHARACTER OUT CALL RDCON ;GET USER INPUT LD HL,(CMDPTR) CALL SKIP ;IF NO INPUT THEN ERR JR Z,CONT1 LD (CMDPTR),HL ;UPDATELD BC,(BFRPTR) ;ELSE COMPUTE NEW PTR ADD HL,BC LD (HEXPTR),HL LD C,E ;IF PTR + COUNT > BFR_TOP THEN ERR LD B,0 ADD  DE,CMDERM ;ELSE OUTPUT ERROR MESSAGE CALL EDITOR JR CONT1 ;TRY NEXT COMMAND SYNERR: POP DE ;WASTE RETURN ADDR FOR SUBRPBNDS LD (PARAM1),HL LD HL,(CMDPTR) LD C,' ' ;POINT TO FILENAME CALL SEARCH CALL SKIP LD (CMDPTR),HL JP Z,SYNERF FILE JP C,HXEMPT ;IF FILE EMPTY THEN ERR CP ':' ;IF CHAR <> COLON THEN IGNORE JR NZ,HEXRD1 LD D,0 ;CHECKSUM = 0  PTR EX DE,HL ;DE := COMMAND PTR ; ; DO USER MODULE'S COMMANDS FIRST ; LD HL,UCMDT NXTUCMD: LD A,(HL) ;IF CHAR CHL,BC LD BC,(MEMTOP) INC BC OR A SBC HL,BC JP NC,MEMER1 ; GETREC: CALL BYTE ;GET RECORD TYPE JR C,HXERR ;FILE EMS LD DE,SYNERM CALL EDITOR JR CONT1 SUBTTL COMMANDS ;********************************** ; ; READ FILE INTO BUR LD HL,FCB ;FORMAT FCB CALL FORMAT JP C,SYNERR JP NZ,SYNERR LD DE,FCB ;OPEN FILE, IF EXISTING THEN PROMPT FOR D CALL BYTE ;IF FILE EMPTY THEN ERR JP C,HXERR AND A ;IF RECORD LENTH == 0 THEN DONE JP Z,CONT1 LD E,A ;RECORD OUNT = 0 THEN DONE WITH USER OR A JR Z,DOINTC LD B,A ;USE AS COUNT UCMDCK: INC HL ;IF CHARS NOT MATCH THEN EXIT LD PTY OR A ;IF RECORD TYPE <> 0 THEN ERROR JR NZ,HXTYPER LD HL,(HEXPTR) ;RESTORE PTR LOOP: CALL BYTE ;INPUT DATA JRFFER COMMAND ; READ ADDR FILENAME ; ;********************************** READC: JP Z,SYNERR ;IF NO OPERAND THEN ERR ELETE CALL OPEN INC A JR Z,WRC1 LD DE,DELMSG CALL EDITOR CALL CONIN ;IF 'Y' OR 'y' THEN DELETE AND 5FH ;CONVERCOUNT = BYTE CALL BYTE ;GET LOAD ADDRESS OF 1ST RECORD & USE AS BASE JP C,HXERR LD H,A ;HIGH BYTE OF ADDR CALL BYTA,(DE) CP (HL) CALL NZ,NOT1ST JR NZ,NXTUCMD INC DE ;NEXT CHAR DJNZ UCMDCK ;IF COUNT EXHAUSTED THEN MUST BE COM C,HXERR LD (HL),A INC HL DEC E ;IF (COUNT = COUNT -1) =<> 0 THEN LOOP JR NZ,LOOP CALL BYTE ;CHECK CHECKSUM J LD HL,(CMDPTR) ;GET ADDR CALL GETNUM JP C,SYNERR ;IF ILLEGAL NUMBER THEN ERR CALL CPBNDS ;IF READ AREA INTO RESERVED T TO LOWER CASE CP 'Y' RET NZ ;ELSE RETURN TO COMMAND MODE WRC2: LD DE,FCB ;DELETE FILE 1ST LD C,19 CALL BDOS E JP C,HXERR LD L,A ;LOW BYTE OF ADDR LD (HEXBASE),HL ;SAVE BASE ADDRESS LD HL,(BFRPTR) ;SET LOAD PTR TO START OF BMAND JR CMDFND ; ; NOW DO INTERNAL COMMANDS ; DOINTC: LD HL,CMDTBL LD DE,(CMDPTR) ;RESTORE PTR NXTCMD: LD B,(HL)R C,HXERR XOR A ADD D JP Z,HEXRD HXERR: LD DE,HXERM ;IF ERROR THEN TELL SO JP EDITOR HXADERR: LD DE,HXADRM ;OUAREA THEN JP C,BNDSM ;ABORT LD (PARAM1),HL LD HL,(CMDPTR) ;SEEK FILENAME LD C,' ' CALL SEARCH LD (CMDPTR),HL ;WRC1: LD DE,FCB ;MAKE NEW FILE LD C,22 CALL BDOS ; ; MAIN LOOP OF HEX OUTPUT ROUTINE ; LD A,0 ;CLEAR WRITE BUFFER LUFFER LD (HEXPTR),HL LD C,E ;IF LOAD_PTR + COUNT <= LAST THEN GET DATA LD B,0 ADD HL,BC LD BC,(MEMTOP) INC BC O ;B := CMD CHAR CNT LD A,B ;IF COUNT == 0 THEN DONE OR A JR Z,CMDERR CMDCHK: INC HL ;IF CHARS NOT MATCH THEN EXIT TPUT ILLEGAL LOAD ADDRESS REGRESSION JP EDITOR HXTYPER: LD DE,HXTYPM ;OUTPUT ILLEGAL HEX RECORD TYPE JP EDITOR HXEMP ; WE SHOULD NOW BE AT THE FILENAME ; RC1: LD HL,FCB ;FORMAT FCB CALL FORMAT JP C,SYNERR JP NZ,SYNERR ;IF WILDCARDS USD (BFRCNT),A LD HL,DEFBFR LD (DBPTR),HL LD HL,(PARAM1) ;INIT START ADDR WR0: LD C,':' ;OUTPUT START OF RECORD SYMBOLR A SBC HL,BC JR C,GETREC JR MEMER1 ;ELSE OUTPUT MEMORY ERROR ; HEXRD: CALL GETCH ;GET CHAR OF FILE JR C,HXERR  LD A,(DE) CP (HL) CALL NZ,NOT1ST JR NZ,NXTCMD INC DE ;NEXT CHAR DJNZ CMDCHK ;IF COUNT EXHAUSTED THEN MUST BE CT: LD DE,HXEMTM ;OUTPUT FILE EMPTY JP EDITOR ;******************************* ; ; SAVE FILE COMMAND ; SAVE FIRST, LASTED THEN ERR ; ; FORMAT OK, SO OPEN FILE ; LD DE,FCB CALL OPEN INC A ;IF NOT THERE THEN JR NZ,RDC1 LD DE,FNFM ;  0 ( ) *!+",#-$.%/ &0 ' CALL PCHAR JP C,WERR LD BC,16 PUSH HL ;SAVE START ADDR WR1: LD HL,(PARAM3) ;IF COUNT - 16 >= 0 THEN OR A LD A,L VALUE OF END CALL SKIP JP Z,SYNERR LD (CMDPTR),HL CALL GETNUM JP C,SYNERR CALL CPBNDS ;ADD OFFSET TOWARD BUFFE A CALL PBYTE JR C,WERR DJNZ WR4 CALL CLOSE JR C,WERR RET ;NORMAL EXIT WERRP: POP HL ;BALANCE STACK WERR:SYNERR CALL CPBNDS ;IF ADDR OUT OF BOUNDS THEN ERR JP C,BNDSM SUBS2: LD (DISTMP),HL ;SAVE ADDR PUSH HL ;OUTPUT ADDR,(PARAM3) SBC HL,DE JR C,SPLIT ;TOP DOWN INC BC ;ELSE BOTTOM UP LD HL,(PARAM1) LD A,C ;IF COUNT = 0 THEN ERR OR ;SAVE COUNT FOR RESTORING SBC HL,BC LD B,C ; REC_COUNT = 16 LD (PARAM3),HL ; COUNT -= 16 JR NC,WR2 ; ELSE RR DISP3: LD (DISEND),HL DISP4: CALL CRLF ;NEW LINE CALL CSTS ;IF KEY PRESSED THEN ABORT RET NZ LD HL,(DISTRT) ;T LD DE,WRERRM ;OUTPUT WRITE ERROR JP EDITOR ;************************* ; ; FILL COMMAND ; FILL FIRST, LAST, VALUE ; CALL CRLF POP HL PUSH HL OR A ;ADD OFFSET LD DE,($MEMRY) SBC HL,DE CALL PRT2H CALL SPACE ;OUTPUT SPACE  B JP Z,SYNERR LDIR RET ; SPLIT: LD HL,(PARAM3) ;DEST = DEST + CNT ADD HL,BC EX DE,HL LD HL,(PARAM2) INC BC ;EC_COUNT = COUNT LD B,A LD HL,0 ; COUNT = 0 FOR LAST RECORD LD (PARAM3),HL WR2: POP HL ;RESTORE START PTR LD D,0 EMP = START LD (DISTMP),HL LD DE,($MEMRY) ;OUTPUT OFFSET ADDR SBC HL,DE CALL PRT2H LD HL,(DISTRT) ;RESTORE PTR DISP ;************************* FILLC: JP Z,SYNERR ;IF NO OPERANDS THEN ERR CALL GET3PAR JP C,SYNERR CALL CKBNDS JP C, POP DE LD A,(DE) ;OUTPUT CURRENT DATA CALL PRTHEX CALL SPACE ;OUTPUT ANOTHER SPACE CALL RDCON ;GET USER INPUT INCLUSIVE LD A,C OR B JP Z,SYNERR LDDR RET ;************************ ; ; HELP COMMAND ; HELP ; ;******** ;CHECKSUM = 0 LD A,B ;OUTPUT RECORD LENGTH OR A ;IF COUNT = 0 THEN SKIP TO EOF JR Z,WR5 CALL PBYTE JR C,WERR 5: PUSH HL CALL SPACE POP HL LD A,(HL) ;PRINT DATA INC HL PUSH HL CALL PRTHEX POP HL CALL CKDONE ;IF PTR = ENDBNDSM LD DE,(PARAM1) ;FIRST LD HL,(PARAM2) ;LAST SBC HL,DE ;IF FIRST > LAST THEN ERR JP C,SYNERR PUSH HL ;ELSE C LD HL,(CMDPTR) ;IF NULL LINE THEN SKIP LOCATION CALL SKIP LD DE,(DISTMP) JR Z,SUBS1 LD A,(HL) ;IF CHAR = '.' THEN **************** HELPC: LD DE,HELPM ;DO INTERNAL COMMANDS CALL EDITOR LD DE,UCMDTX ;NOW DO USER MODULE JP EDITOR ;PUSH HL ;SAVE PTR PUSH DE ;SAVE CS LD DE,($MEMRY) ;REMOVE OFFSET FOR OUTPUT OR A SBC HL,DE POP DE ;CS LD A,H ;OU THEN DONE JR C,DISP6 LD A,L AND 0FH JR NZ,DISP5 DISP6: LD (DISTRT),HL ;UPDATE TO NEW START CALL SPACE LD HL,(DOUNT = LAST - FIRST POP BC LD A,C ;IF CNT = 0 THEN ERR OR B JP Z,SYNERR LD A,(PARAM3) ;GET VALUE LD HL,(PARAM1) ABORT CP '.' RET Z CALL GETNUM ;ELSE CONVERT TO NUMBER LD A,H ;IF NUMBER > 255 THEN ERR OR A JP NZ,SYNERR LD***************************** ; ; DISPLAY MEMORY COMMAND ; DISPLAY <,LAST> ; ;***************************** DISPCTPUT LOAD ADDR CALL PBYTE JR C,WERRP LD A,L CALL PBYTE POP HL ;PTR JR C,WERR XOR A ;OUTPUT 0 RECORD TYPE CISTMP) ;START OVER DISP7: LD A,(HL) ;IF CHAR = PRINTING THEN OK AS IS CP 7FH JR NC,OUTDEC CP ' ' JR NC,DISPOK O LD (HL),A ;SET FIRST LOCATION PUSH HL ;DESTINATION = SOURCE + 1 POP DE INC DE LDIR ;FILL RET ;************** A,L ;LOAD DATA INTO LOCATION LD DE,(DISTMP) LD (DE),A SUBS1: INC DE ;NEXT LOCATION EX DE,HL JR SUBS2 ;*******: LD HL,(CMDPTR) JR Z,DISP1 ;IF NO OPERANDS THEN USE DEFAULTS LD A,(HL) ;IF 1ST CHAR = ',' THEN USE DEFAULT CP ',' JALL PBYTE JR C,WERR WR3: LD A,(HL) ;OUTPUT BYTE FROM MEMORY CALL PBYTE JR C,WERR INC HL ;PTR += 1 DJNZ WR3 ;NEUTDEC: LD A,'.' ;ELSE OUTPUT '.' DISPOK: PUSH HL LD C,A CALL CONOUT POP HL INC HL ;PTR = PTR + 1 LD DE,(DISTRT) ;********** ; ; MOVE COMMAND ; MOVE FIRST, LAST, DEST ; ;************************ MOVEC: CALL GET3PAR JP C,SYNERR L******************************* ; ; NON DOCUMENTED QUERY COMMAND ; OUTPUTS BUFFER OFFSET ADDR ; ;**************************R Z,DISP1 CALL GETNUM ;ELSE GET PARAMETER 1 JP C,SYNERR CALL CPBNDS ;ADD OFFSET LD (DISTRT),HL DISP1: LD HL,(CMXT BYTE XOR A ;OUTPUT -CHECKSUM SUB A,D CALL PBYTE JR C,WERR LD C,CR ;OUTPUT CR-LF CALL PCHAR JR C,WERR IF PTR = NEXT START THEN DONE LD A,E SUB L JR NZ,DISP7 LD A,D SUB H JR NZ,DISP7 EX DE,HL CALL CKDONE ;IF NOD HL,(PARAM3) ;IF DESTINATION OUT OF BOUNDS THEN ERR CALL CPBNDS JP C,BNDSM LD (PARAM3),HL LD HL,(PARAM1) ;ADD BUFFER ************ QUERYC: CALL CRLF LD HL,($MEMRY) CALL PRT2H JP CRLF SUBTTL SUBROUTINES ;*****************************DPTR) ;IF NO ,NNNN THEN END= START + 12 LINES LD A,',' CP (HL) JR Z,DISP2 LD C,A CALL SEARCH JR NZ,DISP2 LD HLLD C,LF CALL PCHAR JR C,WERR PUSH HL LD HL,(PARAM3) ;IF COUNT = 0 THEN DONE LD A,L OR H POP HL JP NZ,WR0 ;ELST DONE THEN DO NEXT LINE RET C JR DISP4 ;****************************** ; ; SUBSTITUTE MEMORY COMMAND ;SUBSTITUTBIAS TO VALUES CALL CPBNDS LD (PARAM1),HL LD HL,(PARAM2) CALL CPBNDS LD (PARAM2),HL LD DE,(PARAM1) ;IF FIRST > LAST ********************************** ; ; NOT 1ST SUBR SKIPS COMMAND TABLE ENTRY TO NEXT ENTRY ; ENTRY- HL= TABLE PTR ; B= COM,(DISTRT) ;ELSE END = START MOD 16 + 255 LD A,L AND 0F0H LD L,A LD DE,255 ADD HL,DE JR DISP3 ; DISP2: INC HL ;GETE DO ANOTHER LINE LD C,':' ;OUTPUT END OF FILE RECORD CALL PCHAR JR C,WERR WR5: LD B,5 ;OUTPUT 5 00 BYTES WR4: XORE ADDR ; ;****************************** SUBSC: JP Z,SYNERR ;IF NO OPERANDS THEN ERR LD HL,(CMDPTR) CALL GETNUM JP C,THEN ERR OR A SBC HL,DE JP C,SYNERR PUSH HL ;ELSE CNT = # OF BYTES POP BC EX DE,HL ;IF DEST > FIRST THEN LD DE!0 ( ) *!+",#-$.%/ &0 'MAND CHAR COUNT ; EXIT - HL= NEXT COMMAND PTR ; FLAGS NOT AFFECTED ; ;*****************************************************ER EMPTY THEN NO NEED TO WRITE OR A JR Z,CLOSRET PUSH HL ;PUT NEW RETURN ADDRESS ON STACK LD HL,CLOSRET EX (SP),HL SO RETURN ERROR FLAG RET ;************************************************ ; ; CONVERT ASCII-HEX CHAR TO BINARY SUBR ;******************** ; ; CONSOLE OUTPUT SUBR ; ENTRY- C= CHAR TO OUTPUT ; EXIT - ALL REGS ? ; ;***************************POP DE POP HL RET ;*************************************************************************** ; ; PUT CHAR ROUTINE O********** NOT1ST: INC HL ;WASTE ENTRY DJNZ NOT1ST INC HL ;SKIP ADDRESS INC HL LD DE,(CMDPTR) ;RESTORE CMD PTR TO PUSH HL ;THEN SAVE REGS FOR STACK BALANCE PUSH DE PUSH BC JR CLOS1 ;WRITE REMAINDER OF BUFFER CLOSRET: RET C ;IF ENTRY- A= CHAR ; EXIT - A= BINARY VALUE ; CF= ERROR ; ;************************************************ ASC2HX: SUB '0' ***************** CONOUT: LD E,C ;SETUP LD C,2 JP BDOS ;************************************* ; ; CONSOLE INPUT SUBUTPUTS CHAR TO OUTPUT BUFFER & WRITES TO OUTPUT ; FILE WHEN FULL. BUFFER IS DEFAULT BUFFER AT 80H ; ENTRY- C= CHAR TO OUTPUT  START OF CMD RET ;******************************************************* ; ; OUTPUT MEMORY ERROR & RETURN TO SYSTEM  WRITE ERROR THEN RETURN CF LD DE,FCB ;THEN CLOSE FILE LD C,16 CALL BDOS OR A ;CLEAR POSSIBLE CARRY INC A ;IF NO ;REMOVE ASCII BIAS RET C CP 10 ;IF 0..9 THEN OK CCF RET NC SUB 7 ;CONVERT 'A'..'F' TO 10..15 CP 10 RET C R ; EXIT - A= CHAR ; ALL OTHER REGS ? ; ;************************************ CONIN: LD C,1 JP BDOS ;************** ; FCB= OPENED FILE ; EXIT - CF= ERROR ; ;*************************************************************************** PCHAR; EXIT - FLAGS SAVED FOR CALLER'S CONDITIONAL ; ;******************************************************* MEMER: PUSH AF LD ERROR THEN RETURN NC RET NZ SCF ;ELSE RETURN CF RET ;************************************************************ CP 16 CCF RET ;*************************************************************************** ; ; GET CHARACTER SUBR ********************************************** ; ; CONSOLE STATUS SUBR ; EXIT - A= 0 : NONE READY, A= NOT 0 : CHAR READY ; : PUSH HL ;SAVE REGS PUSH DE PUSH BC LD HL,(DBPTR) ;GET BUFFER PTR LD (HL),C ;ADD CHAR TO BUFFER INC HL ;PTR += 1 DE,MEMERM CALL EDITOR POP AF RET ;****************************************************** ; ; BYTE SUBR CONVERTS 2*************** ; ; PUT BYTE SUBR CONVERTS BYTE TO ASCII-HEX & OUTPUTS IT TO FILE BUFFER ; ENTRY- A= BYTE ; EXIT - CF= WRITERETURNS NEXT CHAR OF INPUT FILE ; ENTRY- FCB FORMATTED & FILE OPENED, (BFRCNT INIT'D FOR NEW FILE) ; EXIT - CHAR FROM FILEZF = REFLECTS CONDITION OF A ; ;************************************************************ CSTS: LD C,11 CALL BDOS OR A LD (DBPTR),HL LD A,(BFRCNT) ;IF BUFFER FULL THEN WRITE IT INC A LD (BFRCNT),A CP SECSIZ CCF ;SWAP FLAG SENSE TO RET ASCII-HEX CHARS TO BINARY ; ENTRY- D= CHECKSUM ; EXIT - A= BYTE FROM ASCII-HEX ; D= NEW CHECKSUM ; CF= ERROR ; ;******* ERROR ; ;*************************************************************************** PBYTE: PUSH BC LD B,A ;SAVE BYTE IN  IN A ; CF = EOF ; ;*************************************************************************** GETCH: PUSH HL LD RET ;********************************************************************* ; ; SEARCH SUBR SEARCHES A NUL TERMINATEDURN NC JP NC,NOWRT CLOS1: LD DE,DEFBFR ;SET WRITE PTR LD (DBPTR),DE CALL SETDMA LD DE,FCB ;WRITE IT LD C,21 CALL*********************************************** BYTE: CALL GETCH ;GET 1ST DIGIT RET C CALL ASC2HX ;TRY TO CONVERT BUT IB ADD D ;ADD TO CHECKSUM LD D,A LD A,B ;RESTORE BYTE SRL A ;DO HIGH NIBBLE 1ST SRL A SRL A SRL A CALL HX2ASC  A,(BFRCNT) ;IF BUFFER EMPTY THEN READ OR A JP NZ,GC1 PUSH DE ;READ SECTOR INTO DEFAULT BUFFER PUSH BC LD DE,DEFBFR STRING FOR A CHAR THE SAME ; AS CONTENTS OF C. ; ENTRY- HL= STRING PTR ; C= CHAR TO SEARCH FOR ; EXIT - HL= CH BDOS OR A ;IF WRITE ERR THEN RETURN CF JR NZ,WRERR LD (BFRCNT),A ;ELSE BUFFER COUNT = 0 NOWRT: POP BC POP DE POF DIGIT NOT HEX THEN ERR JR C,CVERR SLA A ;MOVE OVER 1 NIBBLE SLA A SLA A SLA A LD B,A CALL GETCH ;GET 2ND DIG ;CONVERT IT TO ASCII LD C,A ;THEN OUTPUT IT CALL PCHAR JR C,PBYT1 LD A,B ;THEN DO LO NIBBLE CALL HX2ASC LD C,A  CALL SETDMA LD DE,FCB CALL RDSEC OR A ;IF FILE EMPTY THEN RETURN CF SCF JR NZ,FEMPTY LD HL,DEFBFR LD (DBPTR)AR PTR ; Z= NOT FOUND (END OF TEXT) ; ;********************************************************************* SEARCHP HL RET WRERR: SCF JR NOWRT ;************************************ ; ; CLOSE OUTPUT BUFFER SUBR ; EXIT - CF= ERROIT RET C CALL ASC2HX ;CONVERT 2ND NIBBLE JR C,CVERR ADD B ;ADD 2ND TO 1ST LD B,A ;COMPUTE CHECKSUM ADD D LD ;& OUTPUT IT CALL PCHAR PBYT1: POP BC RET ;******************************************** ; ; OUTPUT A SPACE TO CON,HL ;SET VARS LD A,SECSIZ LD (BFRCNT),A POP BC POP DE GC1: LD HL,(DBPTR) ;GET CHAR FROM BFR LD A,(HL) INC HL LD: LD A,(HL) ;IF CHAR = NUL THEN RETURN Z OR A RET Z CP C ;ELSE IF CHAR=C THEN RETURN NZ JR Z,FOUND INC HL ;ELSER ; ;************************************ CLOSE: LD C,CPMEOF ;OUTPUT EOF CHAR CALL PCHAR RET C LD A,(BFRCNT) ;IF BUFF D,A LD A,B OR A ;CLEAR FLAG RET ; HEX CONVERSION ERROR MESSAGE OUTPUT CVERR: LD DE,CVERM CALL EDITOR SCF ;ALSOLE SUBR ; EXIT - ALL REGS ? ; ;******************************************** SPACE: LD C,' ' ;************************ (DBPTR),HL LD HL,BFRCNT ;COUNT = COUNT - 1 DEC (HL) POP HL OR A ;INSURE NC RET ; FEMPTY: POP BC ;RESTORE STACK "0 ( ) *!+",#-$.%/ &0 ' TRY NEXT CHAR JR SEARCH FOUND: OR A RET ;*********************************************************************** ;******************************* ; ; OPEN FILE SUBR ; ENTRY- DE= FCB PTR ; EXIT - A= -1 IF NOT ON DISK ; ;*****************; ZROSIZ: EQU 22 NAMCNT: EQU 8 ;FILENAME CHAR CNT TYPCNT: EQU 3 ;FILE EXTENSION CHAR CNT ; FORMAT: PUSH HL ;SAVE FPB PTRRROR ; ;********************************************************** RDFILE: LD (RDPTR),BC ;SAVE ACTUAL READ PTR LD DE,DEFBFRERVED CHAR THEN EXIT JR Z,LE9 INC HL ;IF CHAR <> '*' THEN EXIT CP '*' JR NZ,LD9 LD (HL),'?' JR LDB LD9: LD ( ; SKIP BYPASSES TRAILING SPACES UNTIL NON-SPACE CHAR IS FOUND ; ENTRY- HL= STRING PTR ; EXIT - HL= 1ST NON-SPACE CHAR PTR ;********************* OPEN: LD C,OPENF JP BDOS ;************************************** ; ; READ SECTOR SUBR ; ENTRY-  IN IY POP IY LD HL,(CMDPTR) CALL SKIP ;SKIP LEADING SPACES LD (CMDPTR),HL ;SAVE NEW PTR EX DE,HL PUSH IY POP HL  ;READ 1ST SECTOR INTO DEFAULT BUFFER FOR NOW CALL SETDMA LD DE,FCB CALL RDSEC OR A ;IF BAD READ THEN RETURN ERR RET HL),A ;ADD CHAR TO FCB INC DE LDB: DJNZ LC8 LDF: CALL RSVP ;IF RESERVED CHAR THEN EXIT JR Z,LF0 INC DE ;WASTE C A= NON-SPACE CHAR ; ZF= NOT FOUND ; ;*********************************************************************** SKIP: LD A,(DE= FCB PTR ; EXIT - A= 0 IF OK ; ;************************************** RDSEC: LD C,RDF JP BDOS ;****************** ;FPB PTR LD A,(DE) ;IF CHAR = 0 THEN DONE OR A JR Z,L89 SBC 'A' - 1 ;MAKE 'A'-'P' = 1-15 FOR DRIVE # LD B,A INCNZ ; IF FILE STARTS WITH JP 0000H THEN ASSUME IT IS A HEADER BLOCK LD A,(DEFBFR) CP 0C3H JR NZ,RESCAN ;ELSE ASSUME THARS JR LDF LE9: INC HL ;FILL REMAINING TYPE WITH SPACES LD (HL),' ' DJNZ LE9 LF0: LD B,ZROSIZ ;ZERO EXTENT, S1, S2HL) CP ' ' ;IF CHAR <> ' ' THEN RETURN JR NZ,FOUND INC HL JR SKIP ;************************************* ; ; ******************** ; ; SET DISK READ ADDRESS SUBR ; ENTRY- DE= ADDRESS ; ;************************************** SETDMA: DE ;IF NEXT CHAR = ':' THEN MUST BE DRIVE LD A,(DE) CP ':' JR Z,L90 DEC DE ;ELSE BACK UP & USE DEFAULT DRIVE L89HE 1ST SECTOR IS GOOD & LOAD IT LD HL,(DEFBFR+1) LD A,H OR L JR Z,READ1 ; NOT HEADER IF HERE, MOVE INTO LOAD AREA & C, RECORD COUNT LF2: INC HL LD (HL),0 DJNZ LF2 LD (CMDPTR),DE PUSH IY POP HL ;COUNT WILDCARDS LD BC,NAMCNT + TY CARRIAGE RETURN/LINE FEED SUBR ; EXIT - ALL REGS ? ; ;************************************* CRLF: LD C,CR CALL CONOUT L LD C,26D JP BDOS ;************************************** ; ; READ CONSOLE BUFFER SUBR ; EXIT - CMDBFR = CONSOLE INPUT: LD A,(DFLTDK) LD (HL),A ;FCB(DISK) := DRIVE # JR L96 L90: LD A,B ;USE SPECIFIED DISK LD (HL),B INC DE ;SKIP OVERONTINUE WITH NEXT SECTOR RESCAN: LD HL,DEFBFR LD DE,(RDPTR) LD BC,SECSIZ LDIR LD (RDPTR),DE ;UPDATE READ PTR ; IF PCNT L01: INC HL LD A,(HL) CP '?' JR NZ,L09 INC B L09: DEC C JR NZ,L01 LD A,B OR A RET ;*********D C,LF JP CONOUT ;******************************************************* ; ; MESSAGE EDITOR SUBR OUTPUTS TEXT STRING  ; ;************************************** RDCON: LD DE,CMDBFR ;INIT BUFFER LD A,CBFRSZ ;CMDBFR[0] = CBFRSZ LD (DE),A P ':' L96: LD B,NAMCNT ;B := MAX CHARS L98: CALL RSVP JR Z,LB9 INC HL ;PTR := PTR +1 CP '*' ;IF WILDCARD THEN ENTHERE, EITHER WE ARE DISCARDING THE 1ST SECTOR OR READING THE 2ND READ1: LD DE,(RDPTR) ;READ INTO LOAD AREA DIRECTLY CALL SE*************************** ; ; RESERVED CHAR TEST SUBR ; ENTRY- (DE) = CHAR TO TEST ; EXIT - ZF = FOUND ; ;********; ; ENTRY- DE= STRING PTR ; EXIT - ALL REGS ? ; ;****************************************************** EDITOR: LD C,9 JPUSH DE ;BUFFER PTR LD C,RDCF ;GET INPUT FROM USER CALL BDOS POP HL ;BUFFER PTR INC HL ;COUNT = CMDBFR[1] AND 7FH LER '?' JR NZ,LA9 LD (HL),'?' JR LAB LA9: LD (HL),A ;ADD CHAR TO FCB FILENAME INC DE LAB: DJNZ L98 ;IF NOT DONETDMA LD DE,FCB CALL RDSEC OR A ;IF END OF FILE THEN DONE JR NZ,RDDONE LD DE,SECSIZ ;PTR = PTR + SECTOR$SIZE LD HL,(**************************** RSVP: LD A,(DE) ;IF CHAR <= ' ' THEN RETURN Z CP ' ' + 1 JR NC,RSVP1 XOR A RET RSVP1 BDOS ;*************************************************** ; ; CP/M FILE CONTROL BLOCK FORMATTER ; ENTRY- (CMDPTR) =D C,(HL) LD B,0 RES 7,C ;MAKE SURE < 128 INC HL ;CMDPTR = .CMDBFR[2] LD (CMDPTR),HL ADD HL,BC ;CMDBFR[COUNT + 2] =  THEN LOOP LAF: CALL RSVP ;IF RESERVED CHAR THEN EXIT JR Z,LC0 INC DE ;SKIP OVER EXTRA CHARS TO '.' JR LAF LB9: RDPTR) ADD HL,DE LD (RDPTR),HL LD A,(MEMTOP+1) ;IF NEW PAGE > RESERVED_PAGE - 1 THEN DEC A ; GOING INTO RSVP SO ABOR: PUSH BC PUSH HL LD B,TABCNT ;B := ENTRY COUNT LD HL,RSVPT RSVPL: CP (HL) JR Z,RSVPX ;IF FOUND THEN EXIT INC HL ASCII STRING PTR OF FILE ; HL = FCB TO FORMAT ; EXIT - ZF = NO WILDCARDS USED ; NZ = WILDCARD(S) USED, A0 /* END OF LINE = NUL */ LD (HL),0 RET ;********************************************************** ; ; READ FILE SINC HL ;FILL REMAINDER OF FCB WITH SPACES LD (HL),' ' DJNZ LB9 LC0: LD B,TYPCNT ;COUNT := TYPE CHAR COUNT CP '.' ;IF T BY RETURNING CF CP H RET C JP READ1 ; RDDONE: XOR A ;RETURN Z RET ;******************************************* DJNZ RSVPL INC B ;RETURN NZ RSVPX: POP HL POP BC RET RSVPT: DB '=_.:;,<>' TABCNT: EQU $ - RSVPT ;******* REG. = NUMBER OF ; WILDCARDS ; ;********************************************************* ; ; CONSTANTS KIPS ANY HEADER BLOCK & ONLY LOADS CODE ; ENTRY- BC = LOAD BUFFER PTR ; EXIT - Z = SUCCESSFUL READ ; NZ = READ ERESERVED CHAR NOT '.' THEN FILL ; WITH SPACES JR NZ,LE9 INC DE ;GET NEXT CHAR AFTER '.' LC8: CALL RSVP ;IF RES#0 ( ) *!+",#-$.%/ &0 '*************** ; ; FETCH PARAMETERS SUBR ; ENTRY- CMDPTR= PTR TO 1ST NUMERICAL PARAMETER ; EXIT - CF= ERR ; ;**********ACCUM = 0 GETLP: LD A,(BC) ;CHAR = (PTR) CALL ASC2HX ;ATTEMPT TO CONVERT CHAR JR C,GETCHK ;IF ILLEGAL THEN CHECK FOR DE*** ; ; GET 1 PARAMETER SUBR SAME AS ABOVE ; ;************************************************ GET1PAR: CALL SKIP ;SKIP Y- A= BINARY NIBBLE ; EXIT - A= ASCII REPRESENTATION OF THE NIBBLE ; ;*******************************************************DS VALUE TO THE BASE OF THE BUFFER & CHECKS FOR ; OVERFLOW. THEN CHECKS NEW VALUE'S PAGE AGAINST THE TOP OF AVAILABLE ; MEMO************************************************ GET3PAR: LD HL,(CMDPTR) ;IF NO PARAMETERS THEN RETURN CF CALL SKIP SCF LIMITER ADD HL,HL ;ACCUM = ACCUM * 16 ADD HL,HL ADD HL,HL ADD HL,HL ADD L ;ACCUM = ACCUM + DATA LD L,A INC BC ANY SPACES SCF RET Z LD (CMDPTR),HL ;SAVE NEW PTR CALL GETNUM ;GET PARAMETER RET C CALL LOAD16 OR A ;RETURN ******************** HX2ASC: AND 0FH ;ONLY NIBBLE PLEASE CP 10 ;IF 0..9 THEN OK JR C,NTALPH ADD 7 ;ELSE OFFSET 10..1RY'S PAGE & RETURNS CARRY IF EITHER IS OUT. ; ENTRY- HL = VALUE TO COMPARE ; EXIT - HL = CORRECTED VALUE ; CF = BOUNDS ERROR RET Z LD (CMDPTR),HL ;SAVE NEW PTR CALL GETNUM ;GET 1ST PARAMETER RET C LD DE,PARAM1 ;INIT PTR TO PARAM STORAG ;PTR = PTR + 1 LD A,(GETFLG) ;BUMP FLAG TO NOT 0 INC A LD (GETFLG),A JR GETLP GETCHK: LD A,(GETFLG) ;IF FLAG = 0 THENO ERR RET ;********************************************************** ; ; LOAD WORD SUBR ; ENTRY- DE= WORD PTR ; HL5 TO 'A'..'F' NTALPH: ADD '0' ;CONVERT TO ASCII RET ;**************************** ; ; CHECK FOR DONE SUBR ; ;** ; ;*************************************************************************** CPBNDS: LD A,(MEMTOP+1) ;SET UP MEMTOP PAGE -E CALL LOAD16 LD HL,(CMDPTR) ;SEARCH FOR 2ND PARAMETER (AFTER ',') LD C,',' CALL SEARCH SCF ;IF NO 2ND PARAMETER TN RETURN CF SUB 1 RET C LD A,(BC) ;GE-GET CHAR CP ' ' ;IF SPACE THEN RETURN NC RET Z CP ',' ;IF COMMA THEN RE= VALUE ; EXIT - DE= WORD PTR + 2 (NEXT WORD IN SEQUENCE) ; ;********************************************************** LOAD************************** CKDONE: EX DE,HL LD HL,(DISEND) OR A SBC HL,DE EX DE,HL RET SUBTTL MESSAGES RDERRM:1 DEC A LD DE,($MEMRY) ;ADD VALUE TO BUFFER START (FROM OVERLAY) ADD HL,DE RET C ;IF OVERFLOW THEN RETURN CF CP H HEN RETURN CF RET Z INC HL ;PASS OVER ',' ;********************************************************** ; ; GET 2 PTURN NC RET Z OR A ;IF END OF LINE THEN RETURN NC RET Z SCF ;ELSE RETURN CF RET ;*************************16: EX DE,HL ;STORE IT LD (HL),E INC HL LD (HL),D INC HL EX DE,HL RET ;*************************************** DB CR,LF,'Disk Read Error$' WRERRM: DB CR,LF,'Disk Write Error, Probably Full!$' DELMSG: DB CR,LF,'File Exists, Delete?..(Y/N;ELSE COMPARE PAGE VALUE TO MEMTOP PAGE -1 RET ;RETURN CF IF PAGE > MEMTOP PAGE -1 ;***********************************ARAMETERS SUBR. SAME AS ABOVE EXCEPT: ; ENTRY- DE= PARAMETER STORAGE PTR ; HL= CMDPTR ; EXIT - CF= ERR ; ;************************ ; ; PRINT HEX VALUE SUBR ; ENTRY- HL = VALUE ; ;******************************** PRT2H: LD A,H CALL PRTHEX LD************************************ ; ; CHECK BOUNDS SUBR TESTS PARAM 1 & 2 FOR OUT OF BOUNDS VALUES & IF OK, ; STORES TH) - $' CMDERM: SYNERM: DB CR,LF,'*** Syntax Error ***...Type ''HElp'' For List$' FNFM: DB CR,LF,'File Not Found$' BOUNDM: DB***************************************** ; ; GET NUMBER SUBR CONVERTS ASCII-HEX CHARS IN STRING TO BINARY WORDS UNTIL ; A****************************************** GET2PAR: CALL SKIP ;SKIP ANY TRAILING SPACES SCF ;IF END OF LINE THEN RETUR A,L ;************************************************ ; ; PRINT BYTE HEX VALUE TO CONSOLE SUBR ; ENTRY- A= VALUE ; ;*E OFFSETTED VALUES BACK INTO THE RESPECTIVE LOCATIONS. ; EXIT - CF= OUT OF BOUNDS ; ;**************************************** CR,LF,'Value Out of Bounds$' MEMERM: DB CR,LF,'Memory Error$' HXERM: DB CR,LF,'Hex File Error$' CVERM: DB CR,LF,'Hex Convers NON- HEX CHAR IS ENCOUNTERED. IF NOT SPACE OR COMMA THEN RETURNS CARRY. ; ENTRY- HL = TEXT POINTER ; EXIT - HL = NUMBER ; CN CF RET Z LD (CMDPTR),HL ;SAVE NEW PTR CALL GETNUM ;GET 2ND PARAM. RET C CALL LOAD16 ;****************************************************************** PRTHEX: OR A RLA CALL PRHXDG PRHXDG: RLA RLA RLA RLA PUSH AF C*********************************** CKBNDS: LD HL,(PARAM1) ;START WITH PARAM 1 CALL CPBNDS ;IF OUT THEN RETURN CF RET C ion Error$' HXADRM: DB CR,LF,'Hex Load Address Lower Than 1st Record Load Address!$' HXTYPM: DB CR,LF,'Illegal Hex Record TypeF= NON HEX CHAR (BUT NOT SPACE OR COMMA) ; BC= PTR TO NON-HEX CHAR ; A= NON-HEX CHAR ; ;**************************************************** ; ; THIS ENTRY IS SAME AS ABOVE ; EXCEPT DOES SEARCH FOR COMMA. ; ;************************************ALL HX2ASC ;CONVERT NIBBLE TO ASCII-HEX PUSH HL LD C,A CALL CONOUT POP HL POP AF RET ;************************ LD (PARAM1),HL ;ELSE STORE NEW VALUE LD HL,(PARAM2) ;THEN CHECK PARAM 2 CALL CPBNDS LD (PARAM2),HL ;STORE IT & RETU!$' HXEMTM: DB CR,LF,'Hex File Empty!$' HELPM: DB CR,LF,'HElp' DB CR,LF,'LOad addr d:file (MUST BE ''HEX''FORMAT)' DB CR****************************************** GETNUM: PUSH HL ;HL -> BC POP BC LD A,0 ;FLAG = 0 LD (GETFLG),A LD HL,0 ;** GET1PC: LD HL,(CMDPTR) LD C,',' CALL SEARCH SCF RET Z INC HL ;************************************************************************************************ ; ; HEX TO ASCII-HEX CONVERTER CONVERTS BINARY NIBBLE TO ASCII-HEX ; ENTRRN RESULT RET ;*************************************************************************** ; ; COMPARE BOUNDS SUBR AD$0 ( ) *!+",#-$.%/ &0 ',LF,'SAve first, last d:file (WILL BE ''HEX'' FORMAT)' DB CR,LF,'FIll first, last, value' DB CR,LF,'MOve first, last, dest' WORD ret_cmd(), str_size(), get_n_args(), scan_hex(); FILE *fopen(); /************************************** HEXBASE: DW 0 ;HEX FILE BASE LOAD ADDR HEXPTR: DW 0 ;HEX FILE READ PTR FCB: EQU $ ;FILE CONTROL BLOCK STORAGE REP ecc, cntl; }; struct v { WORD hd_eng, /* Head engage time */ step, /* Step interval */ tls, /* Time after lafine BYTE unsigned char #define WORD unsigned int #define DIAG FALSE /* Turn off execution code */ #define n_args 8 /* DB CR,LF,'DIsplay <, last>' DB CR,LF,'SUbstitute addr$' SUBTTL COMMAND TABLE ;------------------ ; ; COMMAND************************************** Structure declarations ***********************************************************T 33 LIST OFF DB 0 LIST ON ENDM DS STKSIZ STACK: EQU $ DB 0 REL END START st step */ mo_dly; /* Motor on delay */ }; /*************************************************************** Max number of command args */ #define IDATA 0xd9 /* ISHA data port */ #define ICMD 0xd8 /* ISHA command port */ #define  TABLE ; ;------------------ CMDTBL: DB 2,'LO' ;READ DW READC DB 2,'FI' ;FILL DW FILLC DB 2,'MO' ;MOVE DW M*****************/ /* I/O Parameter Block (IOPB) declaration */ struct iopb_struct{ BYTE pb_cmd, /* command */ pb_dr************* main program ****************************************************************************/ main () { ISTAT 0xd8 /* ISHA status port */ /**************************************************************************** Local OVEC DB 2,'DI' ;DISPLAY DW DISPC DB 2,'SU' ;SUBSTITUTE DW SUBSC DB 2,'SA' ;SAVE DW SAVEC DB 2,'HE' ;HELP v; /* drive */ WORD pb_trk, /* track */ pb_sec; /* sector */ BYTE pb_flg; /* flags */ WORD pb_dma; /* Unused static WORD temp, /* temporary storage */ i; /* counter */ /* Display signon and prompt user with command list */ global vars ****************************************************************************/ char *cptr, /* module global t DW HELPC DB 2,'?',0 ; " DW HELPC DB 2,'H',0 ; " DW HELPC DB 2,'QU' ;QUERY BUFFER START DW QUERYC DB 0 ;T dma address */ BYTE pb_dmax;/* Unused dma extended address */ WORD pb_bcnt; /* Byte count to xfer */ BYTE pb_ puts(SIGNON); help(); /* Initialize data buffer */ sbuf = malloc(8192); memtop = (*((BYTE *) 0x6) - 2048) & 0xfext ptr */ tbuf[80]; /* Input buffer */ BYTE *sbuf, /* ptr to sector buffer dynamically allocated */ *memtop; /* ptABLE TERMINATOR SUBTTL VARIABLES DATA CMDPTR: DW CMDBFR CMDBFR: EQU $ ;COMMAND INPUT TEXT BUFFER REPT 130 LIST stat, /* Controller status */ pb_st1, /* fdc status if dd_mod == 0x1f */ pb_st2, /* returned value #1 */ pb_st3; /* returnf00; crlf(); puthxw(memtop - sbuf); puts(" byte buffer size."); /* Do forever (almost) */ while (TRUE) { /r to last byte of buffer */ WORD arg[ n_args + 1 ]; /* storage for command arguments */ int hexfile; /* 'HEX' keyword OFF DB 0 LIST ON ENDM CBFRSZ: EQU $-CMDBFR-2 ; ; INPUT PARAMETER STORAGE ; PARAM1: DW 0 PARAM2: DW 0 PARAM3: DW 0ed value #2 */ } iopb; /* SASI Command Descriptor Block (CDB) declaration */ struct { BYTE cmd, /* command */ /**************************************************************************** Intelligent Sasi Host Adapter (ISHA) control**** Prompt user for command */ crlf(); CO('-'); /**** Get user option */ uc_gets(cptr = tbuf); tfound for file I/O */ FILE *filekey; /**************************************************************************** F ; MEMTOP: DW 0 ;TOP OF AVAILABLE MEMORY PTR RDPTR: DW 0 ;FILE READ PTR DISTRT: DW 0 ;DISPLAY COMMAND LAST START PTR lun, /* logical unit number */ la1, /* logical address 1 */ la0, /* logical address 0 */ blk_cnt, /* block count */ ctrller test/exercisor program ***************************************************************************** Revisions: 1.emp = ret_cmd(cptr); /**** Pre-position to possible argument */ nxt_field(); /**** Execute option */ switch unction templates ****************************************************************************/ char CI(), /* Console in DISEND: DW 0 ;DISPLAY COMMAND LAST END PTR DISTMP: DW 0 ;DISPLAY COMMAND TEMP STORAGE TEMP: DW 0 ;TEMPORARY STORAGE GET; /* control byte */ } cdb; /* Disk descriptor sector physical data declarations */ struct d { BYTE flags, sp00 - 11-2-88 grh Convert from V2.00 of JDD.C exerciser. *****************************************************************(temp) { /*------------------------------------------------------------------------- H Display help message ---------------put */ *gets(), /* Tell cc this is a char ptr */ *uc_gets(), *skip(), *ret_siz(); BYTE xwait(), execute_i(); FLG: DB 0 ;FLAG FOR GETNUM BFRCNT: DB 0 ;FILE READ COMMAND BUFFER COUNT DBPTR: DW DEFBFR BFRPTR: DW 0 ;HEX FILE READ PTRt0, ssz0, spt1, ssz1, sptd, sszd, type; WORD cyls; BYTE heads; WORD rwcc; BYTE pcm, pch, ***********/ #define SIGNON "\nISHA Monitor/Controller Exercisor Vers. 1.00a\n" #include stdio.h #include ctype.h #de%0 ( ) *!+",#-$.%/ &0 '----------------------------------------------------------*/ case 1: help(); break; /*---------------------------- Fetch & test user args */ if ((temp = get_n_args(1)) < 1) { invargs(); break; } /******* Select file type */ if (uthxb(cdb.lun); puts("\nLA1 = "); puthxb(cdb.la1); puts("\nLA0 = "); puthxb(cdb.la0); puts("\nBlk Cnt = ");----------------------------------------*/ case 11: /******* Fetch & test user args */ if ((temp = get_n_args(5)) < 4) erlap then use top down process */ if (arg[3] > arg[1] && arg[3] <= arg[2]) { arg[3] += (arg[2] - arg[1] + 1); wh--------------------------------------------- EX Exit to DOS -----------------------------------------------------------------strncmp(cptr, "HEX", 3) == 0) { hexfile = TRUE; nxt_field(); } else { hexfile = FALSE; } /** puthxb(cdb.blk_cnt); puts("\nControl = "); puthxb(cdb.ctrl); crlf(); break; /*-------------------------------{ invargs(); break; } /******* Set defaults */ if (temp < 5) arg[5] = 1; /******* Set up iopb */ iopb.pb_cmd = ile ( arg[1] <= arg[2]) sbuf[ arg[3]--] = sbuf[ arg[2]--]; } /******* Else bottom up process */ else { while--------*/ case 2: exit(0); break; /*--------------------------------------------------------***** Open file for reading */ filekey = fopen(cptr, "r"); if (filekey == 0) { puts("\nFile open error!\n"); b------------------------------------------ DI Dump the IOPB ------------------------------------------------------------------1; iopb.pb_drv = arg[2]; iopb.pb_trk = arg[3]; iopb.pb_sec = arg[4]; iopb.pb_dma = &sbuf[ arg[1]]; iopb.pb_dmax = ( arg[1] <= arg[2]) sbuf[ arg[3]++] = sbuf[ arg[1]++]; } break; /*------------------------------------------------------------ DB 1st last Dump the sector buffer -------------------------------------------------------------------------reak; } /******* Process */ notimp(); break; /*--------------------------------------------------------------------*/ case 5: /******* Process */ dmp_iopb(); break; /*---------------------------------------------------- 0; iopb.pb_flg = 0; iopb.pb_bcnt = 128; /******* Process */ for ( ; arg[5] > 0; arg[5]--) { if (execute_i( &i------------------------------ SU 1st Substitute buffer data ---------------------------------------------------------------*/ case 3: /******* Fetch & test user args */ if ((temp = get_n_args(2)) < 1) { invargs(); break; } /******* Set ------------ SA 1st last file.name Save buffer data to file --------------------------------------------------------------------------------- FI 1st last value Fill buffer with data ----------------------------------------------------------------opb) != 0) break; } /******* Display results */ if (iopb.pb_stat != 0) { dmp_iopb(); puts("\nError!!")----------*/ case 8: /******* Fetch & test user args */ if ((temp = get_n_args(1)) < 1) { invargs(); break; } /**defaults */ if (temp < 2) arg[2] = arg[1] + 127; /******* Process */ for ( ; arg[1] <= arg[2] && CIS() == 0; arg[1] +-------------*/ case 10: /******* Fetch & test user args */ if ((temp = get_n_args(2)) < 2) { invargs(); break; } ---------*/ case 6: /******* Fetch & test user args */ if ((temp = get_n_args(3)) < 3) { invargs(); break; } if (; } break; /*------------------------------------------------------------------------- WR addr drv trk sect = 16) ? 16 : ( /******* Select file type */ if (strncmp(cptr, "HEX", 3) == 0) { hexfile = TRUE; nxt_field(); } else { arg[1] > arg[2]) { invargs(); break; } /******* Process */ while (arg[1] <= arg[2]) sbuf[ arg[1]++] = (BYTE) arg[3]> Write sector(s) -------------------------------------------------------------------------*/ case 12: /******* Fetch & teuts(" - "); uc_gets(cptr = tbuf); if (tbuf[0] == '.') break; if (get_n_args(1) == 1) sbuf[temp] = (BYTE) aarg[2] - arg[1] + 1) ); } /******* Dump any abort character */ if (CIS()) CI(); break; /*--------------- hexfile = FALSE; } /******* Open file for reading */ filekey = fopen(cptr, "w"); if (filekey == 0) { ; break; /*------------------------------------------------------------------------- MO 1st last dest Move buffer datst user args */ if ((temp = get_n_args(5)) < 4) { invargs(); break; } /******* Set defaults */ if (temp < 5) argrg[1]; } break; /*------------------------------------------------------------------------- LO 1st file.n---------------------------------------------------------- DC Display CDB ----------------------------------------------------puts("\nFile open error!\n"); break; } /******* Process */ notimp(); break; /*------------------------a -------------------------------------------------------------------------*/ case 7: /******* Fetch & test user args */ [5] = 1; /******* Set up iopb */ iopb.pb_cmd = 2; iopb.pb_drv = arg[2]; iopb.pb_trk = arg[3]; iopb.pb_sec = arg[4ame Load data file into buffer -------------------------------------------------------------------------*/ case 9: /*******---------------------*/ case 4: /******* Process */ puts("\nCommand = "); puthxb(cdb.cmd); puts("\nLUN = "); p------------------------------------------------- RE addr drv trk sect Read sector(s) --------------------------------- if ((temp = get_n_args(3)) < 3) { invargs(); break; } if (arg[1] > arg[2]) { invargs(); break; } /******* If ov&0 ( ) *!+",#-$.%/ &0 ']; iopb.pb_dma = &sbuf[ arg[1]]; iopb.pb_dmax = 0; iopb.pb_flg = 0; iopb.pb_bcnt = 128; /******* Process */ fo register WORD i; /* command counter */ for (i = 0; i < n_cmds; i++) { if (strncmp(text, cmds[i], str_size( cmds /*************************************************************************** Command error **************************e if needed */ for ( i = 0; tptr[i] != '\0'; i++) tptr[i] = toupper( tptr[i]); /* Return ptr for gets() compatability * Display IOPB data", /* 5 */ "FI 1st last value Fill buffer with value", /* 6 */ "MO 1st last dest r ( ; arg[5] > 0; arg[5]--) { if (execute_i( &iopb) != 0) break; } /******* Display results */ if (iopb.pb_s[i])) == 0) return i + 1; } return 0; } /******************************************************************************************************************/ cmderr() { puts("\nCommand Error!\n"); } /*********************/ return tptr; } /*************************************************************************** Skip to next fiel Move buffer data", /* 7 */ "SU 1st Substitute buffer data", /* 8 */ "LO 1st file.name Loatat != 0) { dmp_iopb(); puts("\nError!!"); } break; /*-----------------------------------------------*********** return size of null terminated character string function returns number of non-space chars in string, not count****************************************************** command not implemented function *********************************d procedure ***************************************************************************/ nxt_field() { cptr = skip(cptr,d data file into buffer", /* 9 */ "SA 1st last file.name Save buffer data to file", /* 10 */ "RE addr drv trk sect Read sector(s)", /* 11 */ "WR addr drv trk sect Write sector(s)", /* 12 */ "T Execuse 13: notimp(); break; /*------------------------------------------------------------------------- XC '9') ? (c - 7 -'0') : (c - '0') ); } /* Done, return accumulated value  sector */ iopb.pb_sec = 2; iopb.pb_bcnt = 128; if (get_drive()) break; /**** Get buffer location from puts( " St3 = "); puthxb(iopb.pb_st3); puts("\nFlags = "); puthxb(iopb.pb_flg); puts("\nDMA *************/ WORD get_n_args(n) WORD n; /* max number of args to scan */ { register unsigned argn; /* current Execute the IOPB function ***************************************************************************/ x_iopb() { regi*/ return acc; } /**************************************************************************** Query func user */ if ( get_bufr()) break; if ( execute_i( &iopb) ) dmp_iopb(); break; /*----------------- = "); puthxb(iopb.pb_dmax); puthxw(iopb.pb_dma); puts("\nByte Cnt= "); puthxw(iopb.pb_bcnt); } /************argument number {1..n_args} */ /* If args out of range then return error */ if (n < 1 || n > n_args) return 0; /* Elster BYTE *bptr; /* ptr to data in sector buffer */ register WORD i; /* temporary storage */ static char *iopb_ction returns user option entry- ptr to text question exit - TRUE= user answered Yes FALSE= User did not answer Yes ***---------------------------------------------------------- 3 Format Track ----------------------------------------------------**************************************************************** Dump a line of buffer data to console in Hex - ASCII outpuse process up to n arguments */ for (argn = 1; *cptr != '\0' && n > 0; n--, argn++) { arg[argn] = scan_hex(cptr); mds[] = { "0 : Log on drive", /* 0 */ "3 : Format track", /* 1 */ "8 : Return Firmware Version", /* 2 */ "9 : Get *************************************************************************/ query(cptr) char *cptr; /* question prompt text -----------------------*/ case 1: notimp(); break; /*-------------------------------------------------t format is ": " argument = address of data area ********************************************** nxt_field(); } /* Return number of args processed */ return argn -1; } /*****************************Disk Physical Data", /* 3 */ "A : Set disk Physical Data", /* 4 */ "B : Seek track", /* 5 */ "F : Clear Controller" /*/ { crlf(); puts(cptr); puts("? (Y/N) : "); uc_gets(tbuf); return ( tbuf[0] == 'Y') ? TRUE : FALSE; } -------------------------- 8 Return firmware version -------------------------------------------------------------------------******************************/ dump_16(addr, cnt) BYTE *addr; /* ptr to data area to output */ WORD cnt; /* byte coun********************************************** Return hex word function ************************************************** 6 */ }; /* Display commands */ for (i = 0; i < 7; i++) { puts(iopb_cmds[i]); crlf(); } /* Fetch user comman /**************************************************************************** Dump IOPB function *******************--*/ case 2: /**** set up iopb */ iopb.pb_cmd = 8; /**** execute it */ if ( execute_i( &iopb) ) dmpt to display */ { register char c; /* fast storage for current char */ unsigned int j; /* loop counter */ /**************************/ WORD scan_hex(ptr) char *ptr; /* ptr to text to convert to binary */ { WORD acc; /* d */ puts("Enter Command - "); uc_gets(cptr = tbuf); for (i = 0; i < 7; i++) { if (strncmp( cptr, iopb_cmds[i*********************************************************/ dmp_iopb() { puts("\nCommand: Status Returned:\n_iopb(); /**** display version data */ i = (iopb.pb_st3 << 8) + iopb.pb_st2; puts("\nFirmware version = "); * Display hex data bytes */ for (j = 0; j < 16; j++) { if (j == 8) puts("- "); if (j < cnt) { puthaccumulator for value to return */ register char c; /* fast storage for current working char */ /* Convert chars until], str_size( iopb_cmds[i])) == 0) break; } /* Select command */ switch (i) { /*------------------------------\ Command = " ); puthxb(iopb.pb_cmd); puts(" Status = "); puthxb(iopb.pb_stat); puts("\nDrive  putdec(i / 100); CO('.'); putdec(i % 100 ); break; /*-------------------------------------------------------xb(addr[j]); CO(' '); } else puts(" "); } /* Now repeat for ascii */ puts(" "); for (j = a non-hex char is encountered */ for (acc = 0, c = *ptr; TRUE; c = *(++ptr)) { /**** If char not hex then abort with cur--------------------------------------------- 0 Log on drive -----------------------------------------------------------------= "); puthxb(iopb.pb_drv); puts(" St1 = "); puthxb(iopb.pb_st1); puts("\nTrack = "); puthxw(i-------------------- 9 Get Physical disk parameters -------------------------------------------------------------------------- 0; j < 16; j++) { if (j < cnt) { c = addr[j] & 0x7f; CO( (c >= ' ' && c < 0x7f) ? c : '.'); rent value */ if (c < '0' || (c > '9' && c < 'A') || c > 'F') break; /**** Else convert to binary and add to accumul----------*/ case 0: iopb.pb_cmd = 0; iopb.pb_flg = 0; iopb.pb_trk = 0; /* Now need to specify trk &opb.pb_trk); puts( " St2 = "); puthxb(iopb.pb_st2); puts("\nSector = "); puthxw(iopb.pb_sec); (0 ( ) *!+",#-$.%/ &0 '-*/ case 3: iopb.pb_cmd = 9; /**** Get buffer location from user */ if ( get_bufr()) break; /**** Ga; /* Byte to convert */ { /* Do upper nibble 1st */ puthxn(data >> 4); /* Now do lower nibble */ puthxn( data ------------------*/ case 4: notimp(); break; /*------------------------------------------------------rt printing */ if (flag || divisor == 1) CO(a + '0'); /**** Do next digit until no more digits */ } } CP/M function */ return bdos(11, 0); } /***************************************************************************et drive from user */ get_drive(); /**** Fetch user option */ iopb.pb_flg = 1 + (( query( "Disable logon") ) ? ); } /*************************************************************************** Output hex word to console proced--------------------- B Seek track ---------------------------------------------------------------------------*/ case 5 /*************************************************************************** Print text string on console procedure *** Return next console char function exit - char ************************************************************************0 : 2); /**** Execute the request */ if ( execute_i( &iopb) ) dmp_iopb(); /**** Display current data */ bpure ***************************************************************************/ puthxw(data) WORD data; /* word to conv: iopb.pb_cmd = 11; /**** Get drive from user */ get_drive(); /**** Get track from user */ if (get_tr************************************************************************/ puts(tptr) char *tptr; /* text ptr */ { /* ***/ char CI() { /* Use console read CP/M function */ return bdos(1, 0); } /***********************************tr = &sbuf[arg[1]]; puts("\nFlags = "); puthxb( *bptr++); puts("\nTrk0 SPT, Size = "); puthxb( *bptr++); ert to hex */ { /* Do upper byte 1st */ puthxb( data >> 8 ); /* Now do lower byte */ puthxb( data ); } k()) break; /**** Execute it */ if ( execute_i( &iopb) ) dmp_iopb(); break; /*------------------------Do until end of text char */ for ( ; *tptr != '\0'; tptr++) { /**** If char == new line then output carriage return 1st ***************************************** Console output procedure *******************************************************puthxb( *bptr++); puts("\nTrk1 SPT, Size = "); puthxb( *bptr++); puthxb( *bptr++); puts("\nData SPT, Size = "); pu/*************************************************************************** Output decimal number procedure does not output--------------------------------------------------- F Clear controller -------------------------------------------------------/ if (*tptr == '\n') CO('\r'); /**** Now output character */ CO(*tptr); } /* Done */ } /**********************/ CO(c) char c; { bdos(2, c); } /******************************************************thxb( *bptr++); puthxb( *bptr++); puts("\nDisk Type = "); puthxb( *bptr++); puts("\nCylinders = "); puth any preceeding blanks or zeros. ***************************************************************************/ putdec( n) --------------------*/ case 6: iopb.pb_cmd = 15; if ( execute_i( &iopb) ) dmp_iopb(); break; ************************************************************************* Execute the IOPB function returns iopb.pb_stat ********************* Output hex nibble to console procedure ************************************************************xw( *(WORD *) bptr++); puts("\nHeads = "); puthxb( *bptr++); puts("\nRed. Wr. I Cyl = "); puthxw( *(WORD WORD n; /* number to output */ { int flag; /* flag to determine when to output zeros */ WORD divisor, /* digi/*--------------------------------------------------------------------------- ??? Unknown command ---------------------------- ***************************************************************************/ BYTE execute_i(iptr) struct iopb_struct *iptr***************/ puthxn(data) BYTE data; /* Nibble to convert */ { data &= 0xf; CO( (data <= 9) ? (data + '0') *) bptr++); puts("\nPrecomp Cyl = "); puthxw( *(WORD *) bptr++); puts("\nECC Burst Len. = "); puthxb( *bptr++);t divisor */ a; /* accumulator for digit */ for (flag = FALSE, divisor = 10000; divisor > 0; divisor /= 10) { /**** -----------------------------------------------*/ default: cmderr(); } } /************************; /* ptr to the iopb data */ { BYTE temp; /* temporary result storage */ #if DIAG iptr->pb_stat = -1; ret: (data + '0' + 7) ); } /*************************************************************************** Output hex byt puts("\nControl Byte = "); puthxb( *bptr++); crlf(); break; /*--------------------------------Fetch digit from number */ a = n / divisor; /**** Extract remainder for next loop */ n %= divisor; /**** If *************************************************** Fetch console input status function exit - 0: no char ready, /0: char urn -1; } #else /* Output the iopb address to the host adapter */ out(IDATA, ((WORD) iptr) & 0xff); out(ICMD, 1)e to console procedure ***************************************************************************/ puthxb(data) BYTE dat------------------------------------------- A Set disk physical data ---------------------------------------------------------not 0 then set flag for subsequent zero printing */ if (a > 0) flag = TRUE; /**** If flag set or last digit then staready ***************************************************************************/ int CIS() { /* Use get console status )0 ( ) *!+",#-$.%/ &0 '; temp = xwait(); if (temp) { iptr->pb_stat = temp; return temp; } out(IDATA, ( ( (WORD) i; iopb.pb_dmax = 0; } ******************************************************** Get drive from user returns TRUE if error, FALSE if ok ******FIll first, last, value ; Fills buffer relative locations from 'first' to 'last' (inclusive) ; with 'value'. Buffer bounds arentry - cptr= ptr to place to put data exit - cptr= sectors per track cptr + 1= sector size {0,1,..n} cptr = cptr + 2 ptr) >> 8) & 0xff); out(ICMD, 3); temp = xwait(); if (temp) { iptr->pb_stat = temp; return temp; ***********************************************************************/ int get_drive() { puts("\nEnter drive number {0.e checked. ;*MOve first, last, dest ; Moves code from buffer relative position 'first' through 'last' ; into new buffer relat ***************************************************************************/ gt_trk(tptr) char *tptr; { unsigned x; } out(IDATA, 0); out(ICMD, 5); temp = xwait(); if (temp) { iptr->pb_stat = temp; return temp; .3}: "); uc_gets(cptr = tbuf); iopb.pb_drv = scan_hex( cptr); return FALSE; } /**************************ive location starting at 'dest'. Buffer ; bounds for 'dest' are checked. ;*DIsplay first <,last> ; Display buffer data from b puts("\nEnter "); puts(tptr); puts(" sectors per track : "); uc_gets(tbuf); if (tbuf[0] != '\0') *cptr = atoi(tbuf } /* Now execute the iopb */ out(ICMD, 0x41); temp = xwait(); if (temp) return temp; else return  TITLE BASE UTILITY DRIVER ;******************************************************** ; ; Base Utility Driver Main Module ;************************************************** Get sector & track info from user returns TRUE if error, FALSE if ok uffer relative location 'first' through ; buffer relative location 'last'. If 'last' is not specified then ; 256 bytes are dis); cptr++; puts("Enter "); puts(tptr); puts(" sector size {128, 256, 512, 1024}: "); uc_gets(tbuf); if (tbuf[0] iptr->pb_stat; } #endif /*************************************************************************** Wait for comm ; Copyright (c) 1983 GRH Enterprisess, Cupertino, CA ; by Girvin Herr ; ;******************************************** ****************************************************************************/ int get_sec_trk() { puts("\nEnter sectorplayed. If 'first' is not specified, then the ; previous 'last' is used for 'first'. ;*Substitute addr ; Allows changing byte!= '\0') { x = atoi(tbuf); switch (x) { case 128: x = 0; break; case 256: x = 1; break; case 5and execution function returns command status ***************************************************************************/ ************ ; ; 1- Implements the loading of object files ; in the Intel HEX format into the memory buffer. ; 3- number : "); uc_gets(tbuf); iopb.pb_sec = atoi(tbuf); get_trk(); } /************************************** values starting at buffer relative location ; 'addr' one at a time. Upon execution, this command outputs: ; 'addr' & the curr12: x = 2; break; case 1024: x = 3; break; default: x = 100; } if (x < 100) *cptr = x; } cptr BYTE xwait() { BYTE temp; /* temporary result storage */ WORD i; /* timer count */ /* Wait for busy bit to c Extensive error checking against memory buffer bounds, will not allow ; operating system or code to be compromised. ; ; U************************************** Get track info from user returns TRUE if error, FALSE if ok ******************ent data value then waits for the user response. ; If the user enters hex data, the 2 Hex digits are loaded into ; the 'addr' ++; } /*************************************************************************** get buffer address from user lear */ while (TRUE) { for (i = 0; i < 40000; i++) { if ((( temp = in( ISTAT) ) & 0x01) == 0) break; } /**ses the following commands: ; ;*HElp ; Displays the command summary list. ;*LOAD addr filename ; Reads file 'filename' with**********************************************************/ int get_trk() { unsigned int d; /* temporary track storage location then 'addr' is incremented by 1 & the process ; is repeated. If a RETURN is entered (nul line) the data value is ; le***************************************************************************/ get_bufr() { WORD d; /* buffer offset add** If timed out then ask user to continue */ if (i == 40000) { if (query("Controller timeout, Quit") ) return temp;  optional 'HEX' format starting at buffer ; relative location 'addr'. Buffer bounds are checked. ;*SAve first, last filename */ puts("\nEnter decimal track number : "); uc_gets(cptr = tbuf); d = atoi(tbuf); iopb.pb_trk = d; return ft as is & 'addr' is incremented by 1 & the process is repeated. ; If a period '.' is entered as the 1st character, the commandress */ puts("\nEnter buffer address - "); uc_gets( cptr = tbuf); d = scan_hex(cptr); iopb.pb_dma = &sbuf[d] } /**** Else stop */ else break; } /* Return no error */ return 0; } /********************; Saves the buffer image starting at buffer relative location 'first' ; through 'last' in Hex file format as file 'filename' ;FALSE; } /*************************************************************************** get track data function *0 ( ) *!+",#-$.%/ &0 ' is ; terminated. Note, the Hex values entered must have 0 in the high ; byte. I.E. 00xx or just plain xx or even yy00xx will  DE,CMDERM ;ELSE OUTPUT ERROR MESSAGE CALL EDITOR JR CONT1 ;TRY NEXT COMMAND SYNERR: POP DE ;WASTE RETURN ADDR FOR SUBRCMDPTR, PARAM1, PARAM2, PARAM3, MEMTOP, $MEMRY ; ; EXTERNAL PROCEDURES ; EXTRN INIT EXTRN UCMDT, UCMDTX, SIGNON ; F FILE JP C,HXEMPT ;IF FILE EMPTY THEN ERR CP ':' ;IF CHAR <> COLON THEN IGNORE JR NZ,HEXRD1 LD D,0 ;CHECKSUM = 0  PTR EX DE,HL ;DE := COMMAND PTR ; ; DO USER MODULE'S COMMANDS FIRST ; LD HL,UCMDT NXTUCMD: LD A,(HL) ;IF CHAR Cbe ok. ; ;********************************************************* ; ; REVISION STATUS: ; 2.0 - 6 Jul 83 GRH ; TeS LD DE,SYNERM CALL EDITOR JR CONT1 SUBTTL COMMANDS ;********************************** ; ; READ FILE INTO BU ; PTR TO END OF PROGRAM ; DATA ;FIRST BYTE OF DATA AREA SHOULD BE 103H $MEMRY DS 2 ;SET BY LINK-80 REL ;BACK TO CSEG CALL BYTE ;IF FILE EMPTY THEN ERR JP C,HXERR AND A ;IF RECORD LENTH == 0 THEN DONE JP Z,CONT1 LD E,A ;RECORD OUNT = 0 THEN DONE WITH USER OR A JR Z,DOINTC LD B,A ;USE AS COUNT UCMDCK: INC HL ;IF CHARS NOT MATCH THEN EXIT LD st release ; 2.1 - 26 Feb 84 GRH ; Changed Sign-on, Command table & help messages to user module ; REVSN: EQU '21' ; ;FFER COMMAND ; READ ADDR FILENAME ; ;********************************** READC: JP Z,SYNERR ;IF NO OPERAND THEN ERR  ; ; SIGN ON MESSAGE HERE TO GIVE COPYRIGHT VISIBILITY ; ;SIGNON: DB CR,LF,'Hard Disk Monitor Utility Ver ' DB HCOUNT = BYTE CALL BYTE ;GET LOAD ADDRESS OF 1ST RECORD & USE AS BASE JP C,HXERR LD H,A ;HIGH BYTE OF ADDR CALL BYTA,(DE) CP (HL) CALL NZ,NOT1ST JR NZ,NXTUCMD INC DE ;NEXT CHAR DJNZ UCMDCK ;IF COUNT EXHAUSTED THEN MUST BE COM********************************************************* SUBTTL DECLARATIONS FALSE EQU 0 TRUE EQU NOT FALSE LISTINC EQU FA LD HL,(CMDPTR) ;GET ADDR CALL GETNUM JP C,SYNERR ;IF ILLEGAL NUMBER THEN ERR CALL CPBNDS ;IF READ AREA INTO RESERVED IGH REVSN DB '.' DB LOW REVSN DB CR,LF,'Copyright (c) 1983' DB ' GRH Enterprises Cupertino, CA' DB CR,LF,'Type ''HELE JP C,HXERR LD L,A ;LOW BYTE OF ADDR LD (HEXBASE),HL ;SAVE BASE ADDRESS LD HL,(BFRPTR) ;SET LOAD PTR TO START OF BMAND JR CMDFND ; ; NOW DO INTERNAL COMMANDS ; DOINTC: LD HL,CMDTBL LD DE,(CMDPTR) ;RESTORE PTR NXTCMD: LD B,(HL)LSE ; ; SYSTEM PARAMS ; SYSTEM EQU 0000H DFLTDK: EQU 0004H ;DEFAULT DISK STORAGE LOC BDOS: EQU 0005H ;CP/M ENTRY POIAREA THEN JP C,BNDSM ;ABORT LD (PARAM1),HL LD HL,(CMDPTR) ;SEEK FILENAME LD C,' ' CALL SEARCH LD (CMDPTR),HL ;P'' for commands' DB CR,LF,'$' ; ; MAIN PROGRAM ; START: LD SP,STACK ;INITIALIZE LD HL,(BDOS+1) ;GET LAST MEMORY LUFFER LD (HEXPTR),HL LD C,E ;IF LOAD_PTR + COUNT <= LAST THEN GET DATA LD B,0 ADD HL,BC LD BC,(MEMTOP) INC BC O ;B := CMD CHAR CNT LD A,B ;IF COUNT == 0 THEN DONE OR A JR Z,CMDERR CMDCHK: INC HL ;IF CHARS NOT MATCH THEN EXIT NT DEFBFR: EQU 0080H ;DEFAULT BUFFER LOC TPA EQU 0100H ;START OF PROGRAM ; CPMEOF: EQU 1AH ;CP/M END OF FILE CHAR (CTRL-Z ; WE SHOULD NOW BE AT THE FILENAME ; RC1: LD HL,FCB ;FORMAT FCB CALL FORMAT JP C,SYNERR JP NZ,SYNERR ;IF WILDCARDS USOC. DEC HL LD (MEMTOP),HL LD HL,($MEMRY) ;SET UP FOR EVEN NIBBLE LD A,L AND 0FH ;IF NIBBLE == 0 THEN OK JR Z,MEMOR A SBC HL,BC JR C,GETREC JR MEMER1 ;ELSE OUTPUT MEMORY ERROR ; HEXRD: CALL GETCH ;GET CHAR OF FILE JR C,HXERR  LD A,(DE) CP (HL) CALL NZ,NOT1ST JR NZ,NXTCMD INC DE ;NEXT CHAR DJNZ CMDCHK ;IF COUNT EXHAUSTED THEN MUST BE C) RDCF: EQU 10 OPENF: EQU 15 RDF: EQU 20 ; ; ASCII CHARACTERS ; LF EQU 0AH CR EQU 0DH ; ; CONSTANTS ; STKSIZ:ED THEN ERR ; ; FORMAT OK, SO OPEN FILE ; LD DE,FCB CALL OPEN INC A ;IF NOT THERE THEN JR NZ,RDC1 LD DE,FNFM ; K LD A,L ;ELSE BUMP AND 0F0H ADD A,10H LD L,A LD A,0 ADC A,H LD H,A LD ($MEMRY),HL MEMOK: LD (DISTRT),HL ; CP ':' ;IF CHAR <> COLON THEN IGNORE JR NZ,HEXRD LD D,0 ;CHECKSUM = 0 CALL BYTE JR C,HXERR ;FILE EMPTY AND AOMMAND CMDFND: INC HL ;FETCH SERVICE ADDR LD E,(HL) INC HL LD D,(HL) PUSH DE ;SET UP FOR COMMAND SCANNING LD  EQU 128 ;STACK SIZE SECSIZ: EQU 128 ;DISK SECTOR SIZE TYPE: EQU 8 ;OFFSET LOCATION OF TYPE EXTENSION OF FILENMAE SUBTT OUTPUT 'FILE NOT FOUND' JP EDITOR ; ; OUTPUT BOUNDS ERROR MESSAGE ; BNDSM: LD DE,BOUNDM ;THEN OUTPUT ERROR MESSAGE JPINIT DISPLAY VARS LD (DISEND),HL LD DE,SIGNON ;OUTPUT SIGN-ON MSG CALL EDITOR CALL INIT ;GO DO INITIALIZATION ;  ;IF RECORD LENGTH = 0 THEN DONE JP Z,CONT1 LD E,A ;RECORD COUNT = BYTE CALL BYTE ;GET LOAD ADDRESS JR C,HXERR HL,(CMDPTR) ;SET UP OPERANDS FOR SOME COMMANDS LD C,' ' CALL SEARCH CALL SKIP ;ALSO PASS IN ZF IF NO FIELDS LD (CMDPTR)L PROGRAM AREA REL ; ; PUBLIC PROCEDURES ; ENTRY SYNERR, ASC2HX, SPACE, CONOUT, CONIN, CSTS, SEARCH, SKIP ENTRY CRLF, E EDITOR MEMER1: LD DE,MEMERM CALL EDITOR JP CONT1 ; ; HEX FILE READ ROUTINE ; RDC1: RDC2: XOR A ;SET UP BUFFER  ; COMMAND INPUT ENTRY. ALL COMMANDS RETURN HERE IF OK. ; CONT1: CALL CRLF ;NEW LINE LD C,'*' ;OUTPUT PROMPT CALL CONOLD H,A CALL BYTE JR C,HXERR LD L,A LD BC,(HEXBASE) ;IF NEW ADDR < BASE ADDR THEN ERR SBC HL,BC JR C,HXADERR ,HL LD HL,CONT1 ;SET UP RETURN ADDR EX (SP),HL ;EXECUTE COMMAND JP (HL) ; COMMAND NOT FOUND IN TABLE CMDERR: LDDITOR, RDCON, GET3PAR, GET2PAR, GET1PAR, CKBNDS ENTRY CPBNDS, GETNUM, PRT2H, PRTHEX, HX2ASC ; ; GLOBAL VARIABLES ; ENTRY FOR 1ST READ LD (BFRCNT),A LD HL,(PARAM1) ;SET PTR TO LOAD ADDR LD (BFRPTR),HL HEXRD1: CALL GETCH ;FETCH CHARACTER OUT CALL RDCON ;GET USER INPUT LD HL,(CMDPTR) CALL SKIP ;IF NO INPUT THEN ERR JR Z,CONT1 LD (CMDPTR),HL ;UPDATE+0 ( ) *!+",#-$.%/ &0 'LD BC,(BFRPTR) ;ELSE COMPUTE NEW PTR ADD HL,BC LD (HEXPTR),HL LD C,E ;IF PTR + COUNT > BFR_TOP THEN ERR LD B,0 ADD BNDSM LD DE,(PARAM1) ;FIRST LD HL,(PARAM2) ;LAST SBC HL,DE ;IF FIRST > LAST THEN ERR JP C,SYNERR PUSH HL ;ELSE CPBNDS LD (PARAM1),HL LD HL,(CMDPTR) LD C,' ' ;POINT TO FILENAME CALL SEARCH CALL SKIP LD (CMDPTR),HL JP Z,SYNER**************** HELPC: LD DE,HELPM ;DO INTERNAL COMMANDS CALL EDITOR LD DE,UCMDTX ;NOW DO USER MODULE JP EDITOR ;PUSH HL ;SAVE PTR PUSH DE ;SAVE CS LD DE,($MEMRY) ;REMOVE OFFSET FOR OUTPUT OR A SBC HL,DE POP DE ;CS LD A,H ;OUHL,BC LD BC,(MEMTOP) INC BC OR A SBC HL,BC JP NC,MEMER1 ; GETREC: CALL BYTE ;GET RECORD TYPE JR C,HXERR ;FILE EMOUNT = LAST - FIRST POP BC LD A,C ;IF CNT = 0 THEN ERR OR B JP Z,SYNERR LD A,(PARAM3) ;GET VALUE LD HL,(PARAM1) R LD HL,FCB ;FORMAT FCB CALL FORMAT JP C,SYNERR JP NZ,SYNERR LD DE,FCB ;OPEN FILE, IF EXISTING THEN PROMPT FOR D***************************** ; ; DISPLAY MEMORY COMMAND ; DISPLAY <,LAST> ; ;***************************** DISPCTPUT LOAD ADDR CALL PBYTE JR C,WERRP LD A,L CALL PBYTE POP HL ;PTR JR C,WERR XOR A ;OUTPUT 0 RECORD TYPE CPTY OR A ;IF RECORD TYPE <> 0 THEN ERROR JR NZ,HXTYPER LD HL,(HEXPTR) ;RESTORE PTR LOOP: CALL BYTE ;INPUT DATA JR LD (HL),A ;SET FIRST LOCATION PUSH HL ;DESTINATION = SOURCE + 1 POP DE INC DE LDIR ;FILL RET ;**************ELETE CALL OPEN INC A JR Z,WRC1 LD DE,DELMSG CALL EDITOR CALL CONIN ;IF 'Y' OR 'y' THEN DELETE AND 5FH ;CONVER: LD HL,(CMDPTR) JR Z,DISP1 ;IF NO OPERANDS THEN USE DEFAULTS LD A,(HL) ;IF 1ST CHAR = ',' THEN USE DEFAULT CP ',' JALL PBYTE JR C,WERR WR3: LD A,(HL) ;OUTPUT BYTE FROM MEMORY CALL PBYTE JR C,WERR INC HL ;PTR += 1 DJNZ WR3 ;NE C,HXERR LD (HL),A INC HL DEC E ;IF (COUNT = COUNT -1) =<> 0 THEN LOOP JR NZ,LOOP CALL BYTE ;CHECK CHECKSUM J********** ; ; MOVE COMMAND ; MOVE FIRST, LAST, DEST ; ;************************ MOVEC: CALL GET3PAR JP C,SYNERR LT TO LOWER CASE CP 'Y' RET NZ ;ELSE RETURN TO COMMAND MODE WRC2: LD DE,FCB ;DELETE FILE 1ST LD C,19 CALL BDOS R Z,DISP1 CALL GETNUM ;ELSE GET PARAMETER 1 JP C,SYNERR CALL CPBNDS ;ADD OFFSET LD (DISTRT),HL DISP1: LD HL,(CMXT BYTE XOR A ;OUTPUT -CHECKSUM SUB A,D CALL PBYTE JR C,WERR LD C,CR ;OUTPUT CR-LF CALL PCHAR JR C,WERR R C,HXERR XOR A ADD D JP Z,HEXRD HXERR: LD DE,HXERM ;IF ERROR THEN TELL SO JP EDITOR HXADERR: LD DE,HXADRM ;OUD HL,(PARAM3) ;IF DESTINATION OUT OF BOUNDS THEN ERR CALL CPBNDS JP C,BNDSM LD (PARAM3),HL LD HL,(PARAM1) ;ADD BUFFER WRC1: LD DE,FCB ;MAKE NEW FILE LD C,22 CALL BDOS ; ; MAIN LOOP OF HEX OUTPUT ROUTINE ; LD A,0 ;CLEAR WRITE BUFFER LDPTR) ;IF NO ,NNNN THEN END= START + 12 LINES LD A,',' CP (HL) JR Z,DISP2 LD C,A CALL SEARCH JR NZ,DISP2 LD HLLD C,LF CALL PCHAR JR C,WERR PUSH HL LD HL,(PARAM3) ;IF COUNT = 0 THEN DONE LD A,L OR H POP HL JP NZ,WR0 ;ELSTPUT ILLEGAL LOAD ADDRESS REGRESSION JP EDITOR HXTYPER: LD DE,HXTYPM ;OUTPUT ILLEGAL HEX RECORD TYPE JP EDITOR HXEMPBIAS TO VALUES CALL CPBNDS LD (PARAM1),HL LD HL,(PARAM2) CALL CPBNDS LD (PARAM2),HL LD DE,(PARAM1) ;IF FIRST > LAST D (BFRCNT),A LD HL,DEFBFR LD (DBPTR),HL LD HL,(PARAM1) ;INIT START ADDR WR0: LD C,':' ;OUTPUT START OF RECORD SYMBOL,(DISTRT) ;ELSE END = START MOD 16 + 255 LD A,L AND 0F0H LD L,A LD DE,255 ADD HL,DE JR DISP3 ; DISP2: INC HL ;GETE DO ANOTHER LINE LD C,':' ;OUTPUT END OF FILE RECORD CALL PCHAR JR C,WERR WR5: LD B,5 ;OUTPUT 5 00 BYTES WR4: XORT: LD DE,HXEMTM ;OUTPUT FILE EMPTY JP EDITOR ;******************************* ; ; SAVE FILE COMMAND ; SAVE FIRST, LASTTHEN ERR OR A SBC HL,DE JP C,SYNERR PUSH HL ;ELSE CNT = # OF BYTES POP BC EX DE,HL ;IF DEST > FIRST THEN LD DE CALL PCHAR JP C,WERR LD BC,16 PUSH HL ;SAVE START ADDR WR1: LD HL,(PARAM3) ;IF COUNT - 16 >= 0 THEN OR A LD A,L VALUE OF END CALL SKIP JP Z,SYNERR LD (CMDPTR),HL CALL GETNUM JP C,SYNERR CALL CPBNDS ;ADD OFFSET TOWARD BUFFE A CALL PBYTE JR C,WERR DJNZ WR4 CALL CLOSE JR C,WERR RET ;NORMAL EXIT WERRP: POP HL ;BALANCE STACK WERR: HEX FILENAME ; ;******************************* SAVEC: JP Z,SYNERR ;IF NO OPERANDS THEN ERR LD DE,PARAM1 ;GET 1ST & LAST,(PARAM3) SBC HL,DE JR C,SPLIT ;TOP DOWN INC BC ;ELSE BOTTOM UP LD HL,(PARAM1) LD A,C ;IF COUNT = 0 THEN ERR OR ;SAVE COUNT FOR RESTORING SBC HL,BC LD B,C ; REC_COUNT = 16 LD (PARAM3),HL ; COUNT -= 16 JR NC,WR2 ; ELSE RR DISP3: LD (DISEND),HL DISP4: CALL CRLF ;NEW LINE CALL CSTS ;IF KEY PRESSED THEN ABORT RET NZ LD HL,(DISTRT) ;T LD DE,WRERRM ;OUTPUT WRITE ERROR JP EDITOR ;************************* ; ; FILL COMMAND ; FILL FIRST, LAST, VALUE ; LD HL,(CMDPTR) CALL GET2PAR JP C,SYNERR LD HL,(PARAM2) ;COUNT = LAST - FIRST + 1 LD DE,(PARAM1) OR A SBC HL,DE  B JP Z,SYNERR LDIR RET ; SPLIT: LD HL,(PARAM3) ;DEST = DEST + CNT ADD HL,BC EX DE,HL LD HL,(PARAM2) INC BC ;EC_COUNT = COUNT LD B,A LD HL,0 ; COUNT = 0 FOR LAST RECORD LD (PARAM3),HL WR2: POP HL ;RESTORE START PTR LD D,0 EMP = START LD (DISTMP),HL LD DE,($MEMRY) ;OUTPUT OFFSET ADDR SBC HL,DE CALL PRT2H LD HL,(DISTRT) ;RESTORE PTR DISP ;************************* FILLC: JP Z,SYNERR ;IF NO OPERANDS THEN ERR CALL GET3PAR JP C,SYNERR CALL CKBNDS JP C, JP C,SYNERR ;IF FIRST > LAST THEN ERR INC HL LD (PARAM3),HL ;SAVE COUNT IN P3 EX DE,HL ;OFFSET FIRST FOR PTR CALL CINCLUSIVE LD A,C OR B JP Z,SYNERR LDDR RET ;************************ ; ; HELP COMMAND ; HELP ; ;******** ;CHECKSUM = 0 LD A,B ;OUTPUT RECORD LENGTH OR A ;IF COUNT = 0 THEN SKIP TO EOF JR Z,WR5 CALL PBYTE JR C,WERR ,0 ( ) *!+",#-$.%/ &0 '5: PUSH HL CALL SPACE POP HL LD A,(HL) ;PRINT DATA INC HL PUSH HL CALL PRTHEX POP HL CALL CKDONE ;IF PTR = END CP 16 CCF RET ;*************************************************************************** ; ; GET CHARACTER SUBR  LD HL,(CMDPTR) ;IF NULL LINE THEN SKIP LOCATION CALL SKIP LD DE,(DISTMP) JR Z,SUBS1 LD A,(HL) ;IF CHAR = '.' THEN : PUSH HL ;SAVE REGS PUSH DE PUSH BC LD HL,(DBPTR) ;GET BUFFER PTR LD (HL),C ;ADD CHAR TO BUFFER INC HL ;PTR += 1 DE,MEMERM CALL EDITOR POP AF RET ;****************************************************** ; ; BYTE SUBR CONVERTS 2 THEN DONE JR C,DISP6 LD A,L AND 0FH JR NZ,DISP5 DISP6: LD (DISTRT),HL ;UPDATE TO NEW START CALL SPACE LD HL,(DRETURNS NEXT CHAR OF INPUT FILE ; ENTRY- FCB FORMATTED & FILE OPENED, (BFRCNT INIT'D FOR NEW FILE) ; EXIT - CHAR FROM FILEABORT CP '.' RET Z CALL GETNUM ;ELSE CONVERT TO NUMBER LD A,H ;IF NUMBER > 255 THEN ERR OR A JP NZ,SYNERR LD LD (DBPTR),HL LD A,(BFRCNT) ;IF BUFFER FULL THEN WRITE IT INC A LD (BFRCNT),A CP SECSIZ CCF ;SWAP FLAG SENSE TO RET ASCII-HEX CHARS TO BINARY ; ENTRY- D= CHECKSUM ; EXIT - A= BYTE FROM ASCII-HEX ; D= NEW CHECKSUM ; CF= ERROR ; ;*******ISTMP) ;START OVER DISP7: LD A,(HL) ;IF CHAR = PRINTING THEN OK AS IS CP 7FH JR NC,OUTDEC CP ' ' JR NC,DISPOK O IN A ; CF = EOF ; ;*************************************************************************** GETCH: PUSH HL LD A,L ;LOAD DATA INTO LOCATION LD DE,(DISTMP) LD (DE),A SUBS1: INC DE ;NEXT LOCATION EX DE,HL JR SUBS2 ;*******URN NC JP NC,NOWRT CLOS1: LD DE,DEFBFR ;SET WRITE PTR LD (DBPTR),DE CALL SETDMA LD DE,FCB ;WRITE IT LD C,21 CALL*********************************************** BYTE: CALL GETCH ;GET 1ST DIGIT RET C CALL ASC2HX ;TRY TO CONVERT BUT IUTDEC: LD A,'.' ;ELSE OUTPUT '.' DISPOK: PUSH HL LD C,A CALL CONOUT POP HL INC HL ;PTR = PTR + 1 LD DE,(DISTRT) ; A,(BFRCNT) ;IF BUFFER EMPTY THEN READ OR A JP NZ,GC1 PUSH DE ;READ SECTOR INTO DEFAULT BUFFER PUSH BC LD DE,DEFBFR******************************* ; ; NON DOCUMENTED QUERY COMMAND ; OUTPUTS BUFFER OFFSET ADDR ; ;************************** BDOS OR A ;IF WRITE ERR THEN RETURN CF JR NZ,WRERR LD (BFRCNT),A ;ELSE BUFFER COUNT = 0 NOWRT: POP BC POP DE POF DIGIT NOT HEX THEN ERR JR C,CVERR SLA A ;MOVE OVER 1 NIBBLE SLA A SLA A SLA A LD B,A CALL GETCH ;GET 2ND DIGIF PTR = NEXT START THEN DONE LD A,E SUB L JR NZ,DISP7 LD A,D SUB H JR NZ,DISP7 EX DE,HL CALL CKDONE ;IF NO CALL SETDMA LD DE,FCB CALL RDSEC OR A ;IF FILE EMPTY THEN RETURN CF SCF JR NZ,FEMPTY LD HL,DEFBFR LD (DBPTR)************ QUERYC: CALL CRLF LD HL,($MEMRY) CALL PRT2H JP CRLF SUBTTL SUBROUTINES ;*****************************P HL RET WRERR: SCF JR NOWRT ;************************************ ; ; CLOSE OUTPUT BUFFER SUBR ; EXIT - CF= ERROIT RET C CALL ASC2HX ;CONVERT 2ND NIBBLE JR C,CVERR ADD B ;ADD 2ND TO 1ST LD B,A ;COMPUTE CHECKSUM ADD D LDT DONE THEN DO NEXT LINE RET C JR DISP4 ;****************************** ; ; SUBSTITUTE MEMORY COMMAND ;SUBSTITUT,HL ;SET VARS LD A,SECSIZ LD (BFRCNT),A POP BC POP DE GC1: LD HL,(DBPTR) ;GET CHAR FROM BFR LD A,(HL) INC HL LD********************************** ; ; NOT 1ST SUBR SKIPS COMMAND TABLE ENTRY TO NEXT ENTRY ; ENTRY- HL= TABLE PTR ; B= COMR ; ;************************************ CLOSE: LD C,CPMEOF ;OUTPUT EOF CHAR CALL PCHAR RET C LD A,(BFRCNT) ;IF BUFF D,A LD A,B OR A ;CLEAR FLAG RET ; HEX CONVERSION ERROR MESSAGE OUTPUT CVERR: LD DE,CVERM CALL EDITOR SCF ;ALE ADDR ; ;****************************** SUBSC: JP Z,SYNERR ;IF NO OPERANDS THEN ERR LD HL,(CMDPTR) CALL GETNUM JP C, (DBPTR),HL LD HL,BFRCNT ;COUNT = COUNT - 1 DEC (HL) POP HL OR A ;INSURE NC RET ; FEMPTY: POP BC ;RESTORE STACK MAND CHAR COUNT ; EXIT - HL= NEXT COMMAND PTR ; FLAGS NOT AFFECTED ; ;*****************************************************ER EMPTY THEN NO NEED TO WRITE OR A JR Z,CLOSRET PUSH HL ;PUT NEW RETURN ADDRESS ON STACK LD HL,CLOSRET EX (SP),HL SO RETURN ERROR FLAG RET ;************************************************ ; ; CONVERT ASCII-HEX CHAR TO BINARY SUBR ;SYNERR CALL CPBNDS ;IF ADDR OUT OF BOUNDS THEN ERR JP C,BNDSM SUBS2: LD (DISTMP),HL ;SAVE ADDR PUSH HL ;OUTPUT ADDRPOP DE POP HL RET ;*************************************************************************** ; ; PUT CHAR ROUTINE O********** NOT1ST: INC HL ;WASTE ENTRY DJNZ NOT1ST INC HL ;SKIP ADDRESS INC HL LD DE,(CMDPTR) ;RESTORE CMD PTR TO PUSH HL ;THEN SAVE REGS FOR STACK BALANCE PUSH DE PUSH BC JR CLOS1 ;WRITE REMAINDER OF BUFFER CLOSRET: RET C ;IF ENTRY- A= CHAR ; EXIT - A= BINARY VALUE ; CF= ERROR ; ;************************************************ ASC2HX: SUB '0'  CALL CRLF POP HL PUSH HL OR A ;ADD OFFSET LD DE,($MEMRY) SBC HL,DE CALL PRT2H CALL SPACE ;OUTPUT SPACE UTPUTS CHAR TO OUTPUT BUFFER & WRITES TO OUTPUT ; FILE WHEN FULL. BUFFER IS DEFAULT BUFFER AT 80H ; ENTRY- C= CHAR TO OUTPUT  START OF CMD RET ;******************************************************* ; ; OUTPUT MEMORY ERROR & RETURN TO SYSTEM  WRITE ERROR THEN RETURN CF LD DE,FCB ;THEN CLOSE FILE LD C,16 CALL BDOS OR A ;CLEAR POSSIBLE CARRY INC A ;IF NO ;REMOVE ASCII BIAS RET C CP 10 ;IF 0..9 THEN OK CCF RET NC SUB 7 ;CONVERT 'A'..'F' TO 10..15 CP 10 RET C  POP DE LD A,(DE) ;OUTPUT CURRENT DATA CALL PRTHEX CALL SPACE ;OUTPUT ANOTHER SPACE CALL RDCON ;GET USER INPUT  ; FCB= OPENED FILE ; EXIT - CF= ERROR ; ;*************************************************************************** PCHAR; EXIT - FLAGS SAVED FOR CALLER'S CONDITIONAL ; ;******************************************************* MEMER: PUSH AF LD -0 ( ) *!+",#-$.%/ &0 'ERROR THEN RETURN NC RET NZ SCF ;ELSE RETURN CF RET ;************************************************************ DE ;IF NEXT CHAR = ':' THEN MUST BE DRIVE LD A,(DE) CP ':' JR Z,L90 DEC DE ;ELSE BACK UP & USE DEFAULT DRIVE L89********************************************** ; ; CONSOLE STATUS SUBR ; EXIT - A= 0 : NONE READY, A= NOT 0 : CHAR READY ; , RECORD COUNT LF2: INC HL LD (HL),0 DJNZ LF2 LD (CMDPTR),DE PUSH IY POP HL ;COUNT WILDCARDS LD BC,NAMCNT + TY CARRIAGE RETURN/LINE FEED SUBR ; EXIT - ALL REGS ? ; ;************************************* CRLF: LD C,CR CALL CONOUT L*************** ; ; PUT BYTE SUBR CONVERTS BYTE TO ASCII-HEX & OUTPUTS IT TO FILE BUFFER ; ENTRY- A= BYTE ; EXIT - CF= WRITE: LD A,(DFLTDK) LD (HL),A ;FCB(DISK) := DRIVE # JR L96 L90: LD A,B ;USE SPECIFIED DISK LD (HL),B INC DE ;SKIP OVERZF = REFLECTS CONDITION OF A ; ;************************************************************ CSTS: LD C,11 CALL BDOS OR APCNT L01: INC HL LD A,(HL) CP '?' JR NZ,L09 INC B L09: DEC C JR NZ,L01 LD A,B OR A RET ;*********D C,LF JP CONOUT ;******************************************************* ; ; MESSAGE EDITOR SUBR OUTPUTS TEXT STRING  ERROR ; ;*************************************************************************** PBYTE: PUSH BC LD B,A ;SAVE BYTE IN  ':' L96: LD B,NAMCNT ;B := MAX CHARS L98: CALL RSVP JR Z,LB9 INC HL ;PTR := PTR +1 CP '*' ;IF WILDCARD THEN ENT RET ;********************************************************************* ; ; SEARCH SUBR SEARCHES A NUL TERMINATED*************************** ; ; RESERVED CHAR TEST SUBR ; ENTRY- (DE) = CHAR TO TEST ; EXIT - ZF = FOUND ; ;********; ; ENTRY- DE= STRING PTR ; EXIT - ALL REGS ? ; ;****************************************************** EDITOR: LD C,9 JPB ADD D ;ADD TO CHECKSUM LD D,A LD A,B ;RESTORE BYTE SRL A ;DO HIGH NIBBLE 1ST SRL A SRL A SRL A CALL HX2ASC ER '?' JR NZ,LA9 LD (HL),'?' JR LAB LA9: LD (HL),A ;ADD CHAR TO FCB FILENAME INC DE LAB: DJNZ L98 ;IF NOT DONE STRING FOR A CHAR THE SAME ; AS CONTENTS OF C. ; ENTRY- HL= STRING PTR ; C= CHAR TO SEARCH FOR ; EXIT - HL= CH**************************** RSVP: LD A,(DE) ;IF CHAR <= ' ' THEN RETURN Z CP ' ' + 1 JR NC,RSVP1 XOR A RET RSVP1 BDOS ;*************************************************** ; ; CP/M FILE CONTROL BLOCK FORMATTER ; ENTRY- (CMDPTR) = ;CONVERT IT TO ASCII LD C,A ;THEN OUTPUT IT CALL PCHAR JR C,PBYT1 LD A,B ;THEN DO LO NIBBLE CALL HX2ASC LD C,A  THEN LOOP LAF: CALL RSVP ;IF RESERVED CHAR THEN EXIT JR Z,LC0 INC DE ;SKIP OVER EXTRA CHARS TO '.' JR LAF LB9: AR PTR ; Z= NOT FOUND (END OF TEXT) ; ;********************************************************************* SEARCH: PUSH BC PUSH HL LD B,TABCNT ;B := ENTRY COUNT LD HL,RSVPT RSVPL: CP (HL) JR Z,RSVPX ;IF FOUND THEN EXIT INC HL ASCII STRING PTR OF FILE ; HL = FCB TO FORMAT ; EXIT - ZF = NO WILDCARDS USED ; NZ = WILDCARD(S) USED, A ;& OUTPUT IT CALL PCHAR PBYT1: POP BC RET ;******************************************** ; ; OUTPUT A SPACE TO CONINC HL ;FILL REMAINDER OF FCB WITH SPACES LD (HL),' ' DJNZ LB9 LC0: LD B,TYPCNT ;COUNT := TYPE CHAR COUNT CP '.' ;IF : LD A,(HL) ;IF CHAR = NUL THEN RETURN Z OR A RET Z CP C ;ELSE IF CHAR=C THEN RETURN NZ JR Z,FOUND INC HL ;ELSE DJNZ RSVPL INC B ;RETURN NZ RSVPX: POP HL POP BC RET RSVPT: DB '=_.:;,<>' TABCNT: EQU $ - RSVPT ;******* REG. = NUMBER OF ; WILDCARDS ; ;********************************************************* ; ; CONSTANTS SOLE SUBR ; EXIT - ALL REGS ? ; ;******************************************** SPACE: LD C,' ' ;************************RESERVED CHAR NOT '.' THEN FILL ; WITH SPACES JR NZ,LE9 INC DE ;GET NEXT CHAR AFTER '.' LC8: CALL RSVP ;IF RES TRY NEXT CHAR JR SEARCH FOUND: OR A RET ;*********************************************************************** ;******************************* ; ; OPEN FILE SUBR ; ENTRY- DE= FCB PTR ; EXIT - A= -1 IF NOT ON DISK ; ;*****************; ZROSIZ: EQU 22 NAMCNT: EQU 8 ;FILENAME CHAR CNT TYPCNT: EQU 3 ;FILE EXTENSION CHAR CNT ; FORMAT: PUSH HL ;SAVE FPB PTR******************** ; ; CONSOLE OUTPUT SUBR ; ENTRY- C= CHAR TO OUTPUT ; EXIT - ALL REGS ? ; ;***************************ERVED CHAR THEN EXIT JR Z,LE9 INC HL ;IF CHAR <> '*' THEN EXIT CP '*' JR NZ,LD9 LD (HL),'?' JR LDB LD9: LD ( ; SKIP BYPASSES TRAILING SPACES UNTIL NON-SPACE CHAR IS FOUND ; ENTRY- HL= STRING PTR ; EXIT - HL= 1ST NON-SPACE CHAR PTR ;********************* OPEN: LD C,OPENF JP BDOS ;************************************** ; ; READ SECTOR SUBR ; ENTRY-  IN IY POP IY LD HL,(CMDPTR) CALL SKIP ;SKIP LEADING SPACES LD (CMDPTR),HL ;SAVE NEW PTR EX DE,HL PUSH IY POP HL ***************** CONOUT: LD E,C ;SETUP LD C,2 JP BDOS ;************************************* ; ; CONSOLE INPUT SUBHL),A ;ADD CHAR TO FCB INC DE LDB: DJNZ LC8 LDF: CALL RSVP ;IF RESERVED CHAR THEN EXIT JR Z,LF0 INC DE ;WASTE C A= NON-SPACE CHAR ; ZF= NOT FOUND ; ;*********************************************************************** SKIP: LD A,(DE= FCB PTR ; EXIT - A= 0 IF OK ; ;************************************** RDSEC: LD C,RDF JP BDOS ;****************** ;FPB PTR LD A,(DE) ;IF CHAR = 0 THEN DONE OR A JR Z,L89 SBC 'A' - 1 ;MAKE 'A'-'P' = 1-15 FOR DRIVE # LD B,A INCR ; EXIT - A= CHAR ; ALL OTHER REGS ? ; ;************************************ CONIN: LD C,1 JP BDOS ;**************HARS JR LDF LE9: INC HL ;FILL REMAINING TYPE WITH SPACES LD (HL),' ' DJNZ LE9 LF0: LD B,ZROSIZ ;ZERO EXTENT, S1, S2HL) CP ' ' ;IF CHAR <> ' ' THEN RETURN JR NZ,FOUND INC HL JR SKIP ;************************************* ; ; .0 ( ) *!+",#-$.%/ &0 '******************** ; ; SET DISK READ ADDRESS SUBR ; ENTRY- DE= ADDRESS ; ;************************************** SETDMA:= VALUE ; EXIT - DE= WORD PTR + 2 (NEXT WORD IN SEQUENCE) ; ;********************************************************** LOADHE 1ST SECTOR IS GOOD & LOAD IT LD HL,(DEFBFR+1) LD A,H OR L JR Z,READ1 ; NOT HEADER IF HERE, MOVE INTO LOAD AREA & C1 DEC A LD DE,($MEMRY) ;ADD VALUE TO BUFFER START (FROM OVERLAY) ADD HL,DE RET C ;IF OVERFLOW THEN RETURN CF CP H HEN RETURN CF RET Z INC HL ;PASS OVER ',' ;********************************************************** ; ; GET 2 P LD C,26D JP BDOS ;************************************** ; ; READ CONSOLE BUFFER SUBR ; EXIT - CMDBFR = CONSOLE INPUT16: EX DE,HL ;STORE IT LD (HL),E INC HL LD (HL),D INC HL EX DE,HL RET ;***************************************ONTINUE WITH NEXT SECTOR RESCAN: LD HL,DEFBFR LD DE,(RDPTR) LD BC,SECSIZ LDIR LD (RDPTR),DE ;UPDATE READ PTR ; IF ;ELSE COMPARE PAGE VALUE TO MEMTOP PAGE -1 RET ;RETURN CF IF PAGE > MEMTOP PAGE -1 ;***********************************ARAMETERS SUBR. SAME AS ABOVE EXCEPT: ; ENTRY- DE= PARAMETER STORAGE PTR ; HL= CMDPTR ; EXIT - CF= ERR ; ;**************** ; ;************************************** RDCON: LD DE,CMDBFR ;INIT BUFFER LD A,CBFRSZ ;CMDBFR[0] = CBFRSZ LD (DE),A P************************************ ; ; CHECK BOUNDS SUBR TESTS PARAM 1 & 2 FOR OUT OF BOUNDS VALUES & IF OK, ; STORES THHERE, EITHER WE ARE DISCARDING THE 1ST SECTOR OR READING THE 2ND READ1: LD DE,(RDPTR) ;READ INTO LOAD AREA DIRECTLY CALL SE***************************************** ; ; GET NUMBER SUBR CONVERTS ASCII-HEX CHARS IN STRING TO BINARY WORDS UNTIL ; A****************************************** GET2PAR: CALL SKIP ;SKIP ANY TRAILING SPACES SCF ;IF END OF LINE THEN RETURUSH DE ;BUFFER PTR LD C,RDCF ;GET INPUT FROM USER CALL BDOS POP HL ;BUFFER PTR INC HL ;COUNT = CMDBFR[1] AND 7FH LE OFFSETTED VALUES BACK INTO THE RESPECTIVE LOCATIONS. ; EXIT - CF= OUT OF BOUNDS ; ;****************************************TDMA LD DE,FCB CALL RDSEC OR A ;IF END OF FILE THEN DONE JR NZ,RDDONE LD DE,SECSIZ ;PTR = PTR + SECTOR$SIZE LD HL,( NON- HEX CHAR IS ENCOUNTERED. IF NOT SPACE OR COMMA THEN RETURNS CARRY. ; ENTRY- HL = TEXT POINTER ; EXIT - HL = NUMBER ; CN CF RET Z LD (CMDPTR),HL ;SAVE NEW PTR CALL GETNUM ;GET 2ND PARAM. RET C CALL LOAD16 ;*******************D C,(HL) LD B,0 RES 7,C ;MAKE SURE < 128 INC HL ;CMDPTR = .CMDBFR[2] LD (CMDPTR),HL ADD HL,BC ;CMDBFR[COUNT + 2] = *********************************** CKBNDS: LD HL,(PARAM1) ;START WITH PARAM 1 CALL CPBNDS ;IF OUT THEN RETURN CF RET C RDPTR) ADD HL,DE LD (RDPTR),HL LD A,(MEMTOP+1) ;IF NEW PAGE > RESERVED_PAGE - 1 THEN DEC A ; GOING INTO RSVP SO ABORF= NON HEX CHAR (BUT NOT SPACE OR COMMA) ; BC= PTR TO NON-HEX CHAR ; A= NON-HEX CHAR ; ;**************************************************** ; ; THIS ENTRY IS SAME AS ABOVE ; EXCEPT DOES SEARCH FOR COMMA. ; ;************************************0 /* END OF LINE = NUL */ LD (HL),0 RET ;********************************************************** ; ; READ FILE S LD (PARAM1),HL ;ELSE STORE NEW VALUE LD HL,(PARAM2) ;THEN CHECK PARAM 2 CALL CPBNDS LD (PARAM2),HL ;STORE IT & RETUT BY RETURNING CF CP H RET C JP READ1 ; RDDONE: XOR A ;RETURN Z RET ;************************************************************************************* GETNUM: PUSH HL ;HL -> BC POP BC LD A,0 ;FLAG = 0 LD (GETFLG),A LD HL,0 ;** GET1PC: LD HL,(CMDPTR) LD C,',' CALL SEARCH SCF RET Z INC HL ;*********************************************KIPS ANY HEADER BLOCK & ONLY LOADS CODE ; ENTRY- BC = LOAD BUFFER PTR ; EXIT - Z = SUCCESSFUL READ ; NZ = READ ERN RESULT RET ;*************************************************************************** ; ; COMPARE BOUNDS SUBR AD*************** ; ; FETCH PARAMETERS SUBR ; ENTRY- CMDPTR= PTR TO 1ST NUMERICAL PARAMETER ; EXIT - CF= ERR ; ;**********ACCUM = 0 GETLP: LD A,(BC) ;CHAR = (PTR) CALL ASC2HX ;ATTEMPT TO CONVERT CHAR JR C,GETCHK ;IF ILLEGAL THEN CHECK FOR DE*** ; ; GET 1 PARAMETER SUBR SAME AS ABOVE ; ;************************************************ GET1PAR: CALL SKIP ;SKIP RROR ; ;********************************************************** RDFILE: LD (RDPTR),BC ;SAVE ACTUAL READ PTR LD DE,DEFBFRDS VALUE TO THE BASE OF THE BUFFER & CHECKS FOR ; OVERFLOW. THEN CHECKS NEW VALUE'S PAGE AGAINST THE TOP OF AVAILABLE ; MEMO************************************************ GET3PAR: LD HL,(CMDPTR) ;IF NO PARAMETERS THEN RETURN CF CALL SKIP SCF LIMITER ADD HL,HL ;ACCUM = ACCUM * 16 ADD HL,HL ADD HL,HL ADD HL,HL ADD L ;ACCUM = ACCUM + DATA LD L,A INC BC ANY SPACES SCF RET Z LD (CMDPTR),HL ;SAVE NEW PTR CALL GETNUM ;GET PARAMETER RET C CALL LOAD16 OR A ;RETURN  ;READ 1ST SECTOR INTO DEFAULT BUFFER FOR NOW CALL SETDMA LD DE,FCB CALL RDSEC OR A ;IF BAD READ THEN RETURN ERR RET RY'S PAGE & RETURNS CARRY IF EITHER IS OUT. ; ENTRY- HL = VALUE TO COMPARE ; EXIT - HL = CORRECTED VALUE ; CF = BOUNDS ERROR RET Z LD (CMDPTR),HL ;SAVE NEW PTR CALL GETNUM ;GET 1ST PARAMETER RET C LD DE,PARAM1 ;INIT PTR TO PARAM STORAG ;PTR = PTR + 1 LD A,(GETFLG) ;BUMP FLAG TO NOT 0 INC A LD (GETFLG),A JR GETLP GETCHK: LD A,(GETFLG) ;IF FLAG = 0 THENO ERR RET ;********************************************************** ; ; LOAD WORD SUBR ; ENTRY- DE= WORD PTR ; HLNZ ; IF FILE STARTS WITH JP 0000H THEN ASSUME IT IS A HEADER BLOCK LD A,(DEFBFR) CP 0C3H JR NZ,RESCAN ;ELSE ASSUME T ; ;*************************************************************************** CPBNDS: LD A,(MEMTOP+1) ;SET UP MEMTOP PAGE -E CALL LOAD16 LD HL,(CMDPTR) ;SEARCH FOR 2ND PARAMETER (AFTER ',') LD C,',' CALL SEARCH SCF ;IF NO 2ND PARAMETER T/0 ( ) *!",#-$.%/ &0 '+N RETURN CF SUB 1 RET C LD A,(BC) ;GE-GET CHAR CP ' ' ;IF SPACE THEN RETURN NC RET Z CP ',' ;IF COMMA THEN RE************************** CKDONE: EX DE,HL LD HL,(DISEND) OR A SBC HL,DE EX DE,HL RET SUBTTL MESSAGES RDERRM:0005H TPA EQU 0100H ;============================ ; ; PORTS & BITS ; ;============================ ISASIBAS EQU 0D8H ; DW HELPC DB 2,'?',0 ; " DW HELPC DB 2,'H',0 ; " DW HELPC DB 2,'QU' ;QUERY BUFFER START DW QUERYC DB 0 ;TTURN NC RET Z OR A ;IF END OF LINE THEN RETURN NC RET Z SCF ;ELSE RETURN CF RET ;************************* DB CR,LF,'Disk Read Error$' WRERRM: DB CR,LF,'Disk Write Error, Probably Full!$' DELMSG: DB CR,LF,'File Exists, Delete?..(Y/NBASE ADDRESS OF ISASI PORTS HDATA EQU ISASIBAS + 1 ;HOST INTERFACE DATA I/O PORT HSTATUS EQU ISASIBAS ;HOST INTERFACE CONTROABLE TERMINATOR SUBTTL VARIABLES DATA CMDPTR: DW CMDBFR CMDBFR: EQU $ ;COMMAND INPUT TEXT BUFFER REPT 130 LIST ******** ; ; PRINT HEX VALUE SUBR ; ENTRY- HL = VALUE ; ;******************************** PRT2H: LD A,H CALL PRTHEX LD) - $' CMDERM: SYNERM: DB CR,LF,'*** Syntax Error ***...Type ''HElp'' For List$' FNFM: DB CR,LF,'File Not Found$' BOUNDM: DBL/STATUS INPUT PORT HBUSYB EQU 0 ;HOST BUSY STATUS BIT HFERRB EQU 1 ;HOST FIRMWARE ERROR BIT HERRB EQU 7 ;HOST ERROR BIT OFF DB 0 LIST ON ENDM CBFRSZ: EQU $-CMDBFR-2 ; ; INPUT PARAMETER STORAGE ; PARAM1: DW 0 PARAM2: DW 0 PARAM3: DW 0 A,L ;************************************************ ; ; PRINT BYTE HEX VALUE TO CONSOLE SUBR ; ENTRY- A= VALUE ; ;* TITLE HARD DISK TEST LIST NOCOND ;*************************************************************************** ; ; HARD DIS CR,LF,'Value Out of Bounds$' MEMERM: DB CR,LF,'Memory Error$' HXERM: DB CR,LF,'Hex File Error$' CVERM: DB CR,LF,'Hex Convers ; MEMTOP: DW 0 ;TOP OF AVAILABLE MEMORY PTR RDPTR: DW 0 ;FILE READ PTR DISTRT: DW 0 ;DISPLAY COMMAND LAST START PTR *********************************************** PRTHEX: OR A RLA CALL PRHXDG PRHXDG: RLA RLA RLA RLA PUSH AF CK INTERFACE TEST PROGRAM ; ;*************************************************************************** ; ; REVISIONS: ; ;ion Error$' HXADRM: DB CR,LF,'Hex Load Address Lower Than 1st Record Load Address!$' HXTYPM: DB CR,LF,'Illegal Hex Record TypePB COMMAND BIT HRESET EQU 7 ;HOST ADAPTER RESET BIT HIOPBL EQU 01H ;SET IOPB LO ADDR CMD HIOPBH EQU 03H ;SET IOPB HI ADDR  DISEND: DW 0 ;DISPLAY COMMAND LAST END PTR DISTMP: DW 0 ;DISPLAY COMMAND TEMP STORAGE TEMP: DW 0 ;TEMPORARY STORAGE GETALL HX2ASC ;CONVERT NIBBLE TO ASCII-HEX PUSH HL LD C,A CALL CONOUT POP HL POP AF RET ;************************ X.0 - 5 AUG 83 GRH ; RELEASE ; 2.0 - 2 JAN 84 GRH ; MODIFIED TO INTERFACE TO THE ISASI INTELLIGENT HOST ADAPTER. ; 2.1 !$' HXEMTM: DB CR,LF,'Hex File Empty!$' HELPM: DB CR,LF,'HElp' DB CR,LF,'LOad addr d:file (MUST BE ''HEX''FORMAT)' DB CRCMD HIOPBX EQU 05H ;SET IOPB XADDR CMD HEXEC EQU (1 SHL HXIOPBB) + (1 SHL HINT) ;EXECUTE IOPB COMMAND DIAG0C EQU 7 ;DUMP FLG: DB 0 ;FLAG FOR GETNUM BFRCNT: DB 0 ;FILE READ COMMAND BUFFER COUNT DBPTR: DW DEFBFR BFRPTR: DW 0 ;HEX FILE READ PTR*************************************************** ; ; HEX TO ASCII-HEX CONVERTER CONVERTS BINARY NIBBLE TO ASCII-HEX ; ENTR- 26 FEB 84 GRH ; MODIFIED COMMANDS TO ALLOW INCLUSION IN USER MODULE ; 2.2 - 13 APR 85 GRH ; Modified parameters to allo,LF,'SAve first, last d:file (WILL BE ''HEX'' FORMAT)' DB CR,LF,'FIll first, last, value' DB CR,LF,'MOve first, last, dest' BUFFER COMMAND DMPBUF EQU 4000H ; WHERE THE DUMP BUFFER COMMAND PUTS IT BS EQU 08H LF EQU 0AH CR EQU 0DH SUBTTL MACRO HEXBASE: DW 0 ;HEX FILE BASE LOAD ADDR HEXPTR: DW 0 ;HEX FILE READ PTR FCB: EQU $ ;FILE CONTROL BLOCK STORAGE REPY- A= BINARY NIBBLE ; EXIT - A= ASCII REPRESENTATION OF THE NIBBLE ; ;*******************************************************w hard disks & floppies to be mixed ; (drive parameters not fixed) ; Modify to make easier to use. ; VERS EQU '22' ; ;**** DB CR,LF,'DIsplay <, last>' DB CR,LF,'SUbstitute addr$' SUBTTL COMMAND TABLE ;------------------ ; ; COMMANDS ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ; ; CONVERT TO HEX MACRO CONVERTS A BINARY BYTET 33 LIST OFF DB 0 LIST ON ENDM DS STKSIZ STACK: EQU $ DB 0 REL END START ******************** HX2ASC: AND 0FH ;ONLY NIBBLE PLEASE CP 10 ;IF 0..9 THEN OK JR C,NTALPH ADD 7 ;ELSE OFFSET 10..1*********************************************************************** SUBTTL DEFINITIONS FALSE EQU 0 TRUE EQU NOT FALSE D ASSEMBLY-TIME CONSTANT ; TO ASCII-HEX CHARS. ; ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5 TO 'A'..'F' NTALPH: ADD '0' ;CONVERT TO ASCII RET ;**************************** ; ; CHECK FOR DONE SUBR ; ;**IAGMODE EQU FALSE ;============================ ; ; ADDRESSES ; ;============================ RBOOT EQU 0000H BDOS EQU OVEC DB 2,'DI' ;DISPLAY DW DISPC DB 2,'SU' ;SUBSTITUTE DW SUBSC DB 2,'SA' ;SAVE DW SAVEC DB 2,'HE' ;HELP  HCMD EQU HSTATUS ;HOST INTERFACE COMMAND PORT HINT EQU 0 ;HOST INTERRUPT (CMD EXECUTE) BIT HXIOPBB EQU 6 ;HOST EXECUTE IO00 ( ) *!",#-$.%/ &0 '+CVHEX MACRO #VAL HVAL DL #VAL SHR 4 LVAL DL #VAL AND 0FH IF HVAL > 9 ;;CONVERT HIGH NIBBLE DB HVAL + '7' ELSE DB HVA ;IF DRIVE_TYPE = 0 THEN DO HARD JR Z,FHD1 PUSH IY ;IY IS CHANGED BY DEFF1 CALL DEFF1 ;ELSE DEFINE FLOPPY FORMAT PED BY A COMMAND BYTE ; COUNT OF 0. FORMAT: ; BYTE 0: COMMAND CHAR BYTE COUNT, N ; BYTE 1-N: COMMAND TEXT ; BYTE N+1: LOW BYTA),L ;SET SECTOR BUFFER DMA LD (IY+[PBDMA+1]),H LD (IY + PBCMD),1 ;CHANGE TO READ COMMAND DEC (IY + PBTRK) ;BACK UP TO ************************* INIT: LD HL,($MEMRY) ;INIT IOPB XFER ADDRESSES LD (XFERPB),HL RET ;***********************AL + '0' ENDIF IF LVAL > 9 ;;CONVERT HIGH NIBBLE DB LVAL + '7' ELSE DB LVAL + '0' ENDIF ENDM SUBTTL REQUIOP IY FHD1: LD L,(IX + DTBLID) ;SET ID SECTOR PTR LD H,(IX + [DTBLID + 1]) LD (IDIOPB + PBDMA),HL LD DE,INTLM ;ASK FOE OF COMMAND EXECUTION ADDRESS ; BYTE N+2: HIGH BYTE OF COMMAND EXECUTION ADDRESS ; BYTE N+3: NEXT COMMAND ENTRY (BYTE 0) OR 0LAST TRACK FORMATTED VNXTTRK: PUSH IX PUSH IY LD C,11 ;CHECK FOR USER ABORT CALL BDOS POP IY POP IX OR A JR*************** ; ; CLEAR CONTROLLER COMMAND ; ;************************************** CLEARC: LD A,1 SHL HRESET ;RESET RED CODE FOR MAIN MODULE REL ;############################ ; ; SIGN ON MESSAGE ; ;############################ ENTRY SIR INTERLEAVE FACTOR CALL GETDPAR LD HL,16 ;CHECK LIMITS SBC HL,DE JP C,PARERR LD (IY+PBSEC),E ;LOAD IT LD DE IF NO MORE ENTRIES ; ;########################################################################## ENTRY UCMDT UCMDT: DB 3 NZ,FABRT LD (IY+PBSEC),0 ;START AT 1ST SECTOR XOR A ;ERROR_FLAG := FALSE LD (ERRFLG),A LD DE,VTRKM PUSH IX  OUT (HCMD),A XOR A OUT (HCMD),A EX (SP),HL ;WAIT FOR RESULTS OF RESET EX (SP),HL CLRWT: IN A,(HSTATUS) CP 0FFH GNON ;PUBLIC FOR MAIN MODULE SIGNON: DB CR,LF,'Hard Disk Monitor Utility Ver ' DB HIGH VERS DB '.' DB LOW VERS DB ,TRKSM ;ASK FOR TRACKS CALL GETDPAR LD L,(IX + DTBLTRK) LD H,(IX + [DTBLTRK + 1]) SBC HL,DE JP C,PARERR LD A,E L,'REC' ;RECALIBRATE DW RECALC DB 6,'FORMAT' ;FORMAT DISK DW FORMC DB 4,'READ' ;READ BLOCK(S) DW DREADC DB 4,' ;IF BOARD NOT INSTALLED THEN EXIT JR Z,NOHDW BIT HBUSYB,A JR NZ,CLRWT CALL GETRES RET C LD HL,-1 ;INIT DTYPECR,LF,'Copyright (c) 1983' DB ' GRH Enterprises Cupertino, CA' DB CR,LF,'Type ''HELP'' for commands' DB CR,LF,'$' ;##D (MAXTRK),A LD (IY + PBTRK),0 ;START AT TRACK 0 CALL EXECUTE ;FORMAT TRACK 0 JP C,FABRT PUSH IY CALL CRLF LDWRIT' ;WRITE BLOCK(S) DW WRITC DB 3,'SEE' ;SEEK TRACK DW SEEKC DB 2,'DE' ;DEFINE DISK PARAMS DW DEFINC DB 2,NOERR LD A,-1 ;ERROR_FLAG := TRUE LD (ERRFLG),A VNOERR: INC (IY + PBSEC) ;NEXT SECTOR LD A,(IY + PBSEC) ;CHECK IF TRS LD (DTYPE0),HL LD (DTYPE0 + 2),HL LD A,L LD (THISDRV),A RET NOHDW: LD DE,NOHDWM ;ALERT USER JP EDITOR ;***#################################### ; ; COMMAND LIST FOR HELP COMMAND ; ;###################################### ENTRY UCM DE,FMTM ;PRINT '*' CALL EDITOR LD IY,IDIOPB ;WRITE ID SECTOR WHILE HERE CALL EXECUTE POP IY JP C,FABRT CALL 'CL' ;CLEAR CONTROLLER DW CLEARC DB 2,'DU' ;DUMP ADAPTER RAM DW DUMPC DB 0 ;TERMINATOR SUBTTL COMMANDS ;====ACK DONE CP (IX + DTBLSEC) JR NZ,VNXTSEC LD A,(ERRFLG) ;CHECK FOR ERRORS IN TRACK OR A LD DE,VERRM ;ASSUME ERROR J*********************************** ; ; RECALIBRATE COMMAND ; ;************************************** RECALC: LD IY,NULPBDTX UCMDTX: DB CR,LF,'RECalibrate drive |' DB ' SEEk track' DB CR,LF,'READ sector(s) LOGON ;INSURE HOST ADAPTER GETS DRIVE INFO JR NXTTRK FMTLP: CALL EXECUTE JP C,FABRT LD A,(THISDRV) ;IF FLOPPY THEN======================== ; ; PUBLIC PROCEDURES ; ;============================ ENTRY INIT ;============================R NZ,VOUTV LD DE,VOKM ;CHANGE TO NO ERROR VOUTV: PUSH IX PUSH IY CALL EDITOR POP IY POP IX LD A,(IY+PBTRK) ; LD (IY+PBCMD),4 ;RECAL COMMAND CALL GETLUN RET C JP EXECUTE ;************************************** ; ; FOR |' DB ' WRITe sector(s)' DB CR,LF,'FORMAT drive |' DB ' DEfine disk params' DB  SKIP HEAD CHANGE OR A JR NZ,FMTLP1 LD A,64 ;BUMP HEAD # ADD A,(IY + PBSEC) LD (IY + PBSEC),A JR NC,FMTLP ;IF BAC ; ; EXTERNAL PROCEDURES ; ;============================ EXTRN CRLF, RDCON, SKIP, SEARCH, SYNERR, EDITOR, PRTHEX EXTRN CNEXT TRACK SUB A,1 LD (IY+PBTRK),A JR NC,VNXTTRK FABRT: LD (IY+PBSEC),0 ;RESTORE ILV BYTE TO 0 CALL CRLF ;MOVE CUMAT DRIVE COMMAND ; ;************************************** FORMC: LD IY,XFERPB LD (IY+PBCMD),3 CALL GETLUN ;ASK FORCR,LF,'CLear controller hang-up |' DB ' DUmp adapter RAM' DB CR,LF,'CTRL-C To Exit to CP/M' DB CR,LF,'$'K TO 00 (CF) THEN DROP OUT FMTLP1: PUSH IX PUSH IY LD DE,FMTM ;PRINT '*' CALL EDITOR POP IY POP IX NXTTRK: INRSOR AWAY FROM VERIFY LINES CALL CRLF CALL CRLF JP CRLF ;************************************** ; ; READ SECTOR(S)  DRIVE RET C ;ALLOW FOR CHANGE OF MIND LD IX,HDTBL ;USE HARD DISK AS DEFAULT LD A,(THISDRV) ;FETCH DRIVE PARAMS OR  ;########################################################################## ; ; COMMAND TABLE FOR LOCAL COMMANDS, TERMINATC (IY+PBTRK) ;NEXT TRACK LD A,(MAXTRK) CP (IY+PBTRK) JR NZ,FMTLP ; ; NOW CHECK SECTORS ; LD HL,SECBUF LD (IY+PBDMN CMDPTR, $MEMRY, PARAM1, PARAM2 ;************************************** ; ; INITIALIZE INTERFACE SUBR ; ;*************PUSH IY CALL EDITOR POP IY POP IX VNXTSEC: PUSH IX PUSH IY CALL EXECUTE ;READ SECTOR POP IY POP IX JR NC,VKBNDS, CPBNDS, GET1PAR, SPACE ;============================ ; ; EXTERNAL VARIABLES ; ;============================ EXTR10 ( ) *!",#-$.%/ &0 '+COMMAND ; ;************************************** DREADC: LD IY,XFERPB ;USE XFER CDB LD (IY+PBCMD),1 ;READ COMMAND JR  PUSH IY ;SAVE IOPB LD IY,LOGIOPB LD (IY + PBDRV),A CALL EXECUTE ;LOG ON DRIVE IN HOST ADAPTER POP IY ;RESTORE IOPB  ;************************************************ ; ; DEFINE FLOPPY DISK PARAMS COMMAND ; ;********************************ER SUBR ; ENTRY- DE= PROMPT MESSAGE PTR ; EXIT - DE= VALUE ; CF= 0 ; ;************************************************ GE HL,DMPBUF ;OUTPUT BUFFER OFFSET LD DE,($MEMRY) SBC HL,DE LD A,H PUSH HL CALL PRTHEX POP HL LD A,L CALL PRTHEX DOXFER ;************************************** ; ; WRITE SECTOR(S) COMMAND ; ;************************************** W LD A,(THISDRV) ;RETURN DRIVE FLAGS RET ;******************************************* ; ; GET LOGICAL ADDR FROM USER **************** DEFINC: CALL GETLUN RET C DEFF1: LD IY,NULPB ;USE NUL CDB LD (IY+PBCMD),7 ;DEFINE CMD LD DE,QSITDPAR: CALL EDITOR ;OUTPUT PROMPT CALL RDCON ;GET INPUT LD HL,(CMDPTR) CALL SKIP ;SKIP LEADING SPACES CALL GETD RET SUBTTL SUBROUTINES ;************************************** ; ; GET LUN FROM USER SUBR ; EXIT - CF= ERROR ; HL= RITC: LD IY,XFERPB ;USE XFER CDB LD (IY+PBCMD),2 ;WRITE COMMAND DOXFER: CALL GETLUN RET C CALL GETLAD ;GET USER'S SUBR ; ;******************************************* GETLAD: LD A,(THISDRV) ;MODIFY TEXT MESSAGES FOR MAX VALUES OR A JRDEM ;ASK FOR SIDES CALL GETDPAR LD HL,2 ;CHECK FOR LIMIT SBC HL,DE JP C,PARERR LD A,E DEC A JP M,PARERR LEC ;CONVERT EX DE,HL ;SET UP FOR CALLER TO CHECK LIMITS OR A RET ;***********************************************CDB PTR ; BC, DE, AF= ? ; ;************************************** GETLUN: LD DE,LUNMSG ;OUTPUT PROMPT CALL EDITOR CBLOCK RET C CALL GETXADR ;GET WHERE USER WANT'S TO PUT IT JP NC,DOXFER1 LD DE,PARERM ;OUTPUT ERROR JP EDITOR D Z,DOLUN0 LD DE,QSEC1M ;ASK FOR SECTOR CALL GETDPAR LD HL,26 ;CHECK FOR LIMIT STRSEC: SBC HL,DE JR C,PARERR SECD (IY+PBSEC),A ;SET SECTOR BYTE TO SIDES LD IX,SDTBL LD DE,QDENSM ;ASK FOR DENSITY CALL EDITOR CALL RDCON ;GET DENSALL RDCON LD HL,(CMDPTR) CALL SKIP ;IF NO ENTRY THEN DO AGAIN JR Z,GETLUN LD A,(HL) SUB '0' RET C CP 4 CCF OXFER1: RDDLP: ; DIAGNOSTIC FOR NOW ; CALL DUMP CALL EXECUTE ;SEND CDB RET C LD A,(IY+PBDMA) ;INCREMENT PTR OK: LD A,E ;SET SECTOR LD (XFERPB + PBSEC),A JP GETTRK PARERR: LD DE,PARERM ;OUT OF LIMIT CALL EDITOR SCF RET DITY LD HL,(CMDPTR) CALL SKIP LD A,(HL) AND 5FH CP 'S' ;IF SINGLE THEN BYTE OK AS IS JR Z,SINGLE CP 'D' ;IF N********* GETDEC: EX DE,HL ;DE = PTR LD HL,-1 ;IF 1ST CHAR NOT NUMBER THEN RETURN -1 LD A,(DE) CP '0' RET C CP  RET C LD (LUNSV),A ;SAVE IT FOR OTHERS LD (NULPB + PBDRV), A LD (XFERPB + PBDRV),A LD (IDIOPB + PBDRV),A LD HL,DADD A,128 LD (IY+PBDMA),A LD A,(IY+[PBDMA + 1]) ADC A,0 LD (IY+[PBDMA + 1]),A LD A,(IY+PBDMAX) ADC A,0 LD (IY+PBDMOLUN0: LD DE,QSEC0M ;ASK FOR SECTOR CALL GETDPAR LD HL,255 ;CHECK LIMIT JR STRSEC ;*******************************OT DOUBLE THEN ERR JP NZ,PARERR LD A,(IY+PBSEC) ;IF DOUBLE THEN SET DOUBLE BITS OR 00000110B LD (IY+PBSEC),A LD IX'9' + 1 CCF RET C INC HL ;START WITH 0 GETDLP: LD A,(DE) ;GET CHAR SUB '0' ;IF NOT NUMBER THEN RETURN RET C TYPE0 ;CHECK FOR DRIVE PARAMETERS ADD A,L LD L,A LD A,0 ADC A,H LD H,A LD A,(HL) ;IF ALREADY SET THEN RETURN LD (AX),A LD A,(IY+PBSEC) ;NEXT SECTOR INC A LD (IY + PBSEC),A JR NZ,TRKOK INC (IY + PBTRK) ;1ST SECTOR OF NEW TRACK ***************** ; ; GET TRACK FROM USER SUBR ; ;************************************************ GETTRK: LD A,(THISDRV),DDTBL SINGLE: JP EXECUTE ;EXECUTE ;************************************** ; ; DUMP ADAPTER RAM INTO BUFFER ; ;**** CP 10 CCF RET C PUSH HL ;X = X * 10 + N POP BC ADD HL,HL ; X * 10 = (X * 4 + 1) * 2 ADD HL,HL ADD HL,BC ADTHISDRV),A ;SET FLAG INC A LD A,(LUNSV) RET NZ PUSH HL LD DE,DTYPEM ;OUTPUT TYPE PROMPT CALL EDITOR CALL RDCON TRKOK: LD HL,(COUNT) DEC HL ;IF NOT DONE THEN LOOP LD (COUNT),HL LD A,L OR H JP NZ,RDDLP RET ;************ ;IF HARD DISK THEN EXIT OR A JR Z,HARDTRK LD DE,QTRK1M ;ASK FOR TRACK CALL GETDPAR LD HL,76 ;CHECK LIMITS STRTR********************************** DUMPC: XOR A ;XADDR = 0 OUT HDATA,A LD A,DIAG0C ;EXECUTE COMMAND OUT HCMD,A DUD HL,HL ADD L LD L,A INC DE ;PTR ++ JR NC,GETDLP INC H JR GETDLP ;**************************************** ;GET USER RESPONSE LD HL,(CMDPTR) CALL SKIP RET Z LD A,(HL) CP 'H' LD A,0 JR Z,SETTYPE LD A,1 SETTYPE: ************************** ; ; SEEK COMMAND ; ;************************************** SEEKC: LD IY,XFERPB ;USE XFER CDB K: SBC HL,DE JR C,PARERR LD (XFERPB + PBTRK),DE ;STORE TRACK # RET HARDTRK: LD DE,QTRK0M ;ASK FOR TRACK CALL GETD******** ; ; GET TRANSFER ADDR FROM USER SUBR ; EXIT - (PARAM1)= XFER ADDR ; (BYTCNT)= XFER BYTE COUNT ; CF= BOUNDS ERRORPOP HL ;STORE NEW DRIVE TYPE LD (HL),A LD (THISDRV),A ; ; LOG ON DRIVE ; LOGON: LD A,(IY + PBDRV) ;SET UP LOGON DRIVE  LD (IY+PBCMD),5 ;SEEK COMMAND CALL GETLUN RET C CALL GETTRK ;GET USER'S TRACK RET C JP EXECUTE ;SEND CDB PAR LD HL,255 ;CHECK FOR LIMIT JR STRTRK ;************************************************ ; ; GET DECIMAL PARAMET3H),A ; THIS CORRECTS A BUG IN ISASI! CALL GETRES ;CHECK FOR FIRMWARE ERROR ; RET C LD DE,DMPBM CALL EDITOR LD* ; ; GET DECIMAL VALUE SUBR ; ENTRY- HL= PTR TO ASCII TEXT ; EXIT - HL= NUMBER ; ;***************************************MPWT: IN A,(HSTATUS) ;WAIT FOR DONE BIT HBUSYB,A JR NZ,DUMPWT LD A,0 ;INSURE JADE CONTROLLER OUT OF MEMORY MAP OUT (420 ( ) *!",#-$.%/ &0 '+ ; ;************************************************ GETXADR: LD DE,XADRM ;ASK FOR XFER ADDR CALL EDITOR CALL RDCON  SUBTTL IDENTITY SECTORS ;############################ ; ; HARD DISK ID SECTOR ; ;############################ HDIDSEC: LD A,HEXEC ;GO EXECUTE IT OUT (HCMD),A EXEC4: IN A,(HSTATUS) BIT HBUSYB,A JR NZ,EXEC4 ; FALL INTO GET RESULTS ;######################### ; ; DOUBLE DENSITY ID SECTOR ; ;################################# DDIDSEC: DB 'Jade DD Double dM1) ; CALL PRTHEX ; LD A,(PARAM1 + 1) ; CALL PRTHEX ; CALL SPACE ; LD A,(COUNT) ; CALL PRTHEX ; LD A,(COUNT + 1) ; CAL;GET PARAMETER LD HL,(CMDPTR) LD DE,PARAM1 CALL GET1PAR RET C LD DE,XCNTM ;ASK FOR XFER COUNT CALL GETDPAR LD A, DB 'Jade DD Hard disk format ' ;CONFIRMATION TEXT ; ; DISK PARAMETER BLOCK IMAGE FOR BIOS AT LOGON ; ; DISK SIZE= 4,161,53************************************** ; ; GET RESULTS SUBR OUTPUTS ERROR ; IF ERROR. ; EXIT - CF= HARD ERROR ; ;********ensity format ' ;CONFIRMATION TEXT ; ; DISK PARAMETER BLOCK IMAGE FOR BIOS AT LOGON ; ; DISK SIZE= 492,500 ; CLUSTER SIZE= L PRTHEX CALL CRLF RET ENDIF SUBTTL MESSAGES LUNMSG DB CR,LF,'Logical Unit (0..3) - $' FMTM DB '*$' FERRM DB CRE ;IF CNT == 0 THEN ABORT OR D SCF RET Z LD (COUNT),DE ;SAVE COUNT LD DE,(PARAM1) ;CHECK LIMITS ADD HL,DE LD 6 ; CLUSTER SIZE= 4096 (4K) ; DIRECTORY SIZE= 1152 / 2 ; ALLOCATION TABLE SIZE (BIOS)= 127 BYTES ; REPT HDIDSEC + 32 - $ ****************************** GETRES: IN A,(HSTATUS) AND (1 SHL HERRB) + (1 SHL HFERRB) RET Z BIT HFERRB,A JR Z,D2048 (2k) ; DIRECTORY SIZE= 128 ; ALLOCATION TABLE SIZE (BIOS)= 32 BYTES ; REPT DDIDSEC + 32 - $ ;POSITION DPB OFFSET LI,LF,'FIRMWARE ERROR # $' HDERM DB CR,LF,'DISK ERROR # $' SPM DB ' $' PBHDRM DB CR,LF,'C D TRK SEC F DMA X STATUS (PARAM2),HL CALL CKBNDS ;ADD OFFSET & CHECK BOUNDS LD HL,(PARAM1) ;SET IOPB LD (XFERPB + PBDMA),HL RET ;****;POSITION DPB OFFSET LIST OFF DB 0E5H ;FILL WITH E5 LIST ON ENDM DW 128 ;SECTORS PER TRACK (SPT) DB 5 ;BLOCK SSKERR LD DE,FERRM CALL EDITOR IN A,(HDATA) ;GET ERROR CODE CALL PRTHEX CALL CRLF SCF RET DSKERR: LD DE,HD SPARES$' PARERM DB CR,LF,'PARAMETER ERROR$' NOHDWM DB CR,LF,'Controller Not Responding to Port ' CVHEX ISASIBAS DB 'H !********************************** ; ; EXECUTE THE IOPB ROUTINE ; ENTRY- IY= IOPB PTR ; EXIT - CF= ERROR ; ;**************HIFT FACTOR (BSH) DB 31 ;BLOCK MASK (BLM) DB 1 ;NULL MASK (EXM) DW 1015 / 2 ;DISK SIZE (CLUSTERS)-1 (DSM) DW 1152 ;ERM CALL EDITOR LD A,(IY+PBSTAT) CALL PRTHEX LD DE,SPM CALL EDITOR LD A,(IY+[PBSTAT + 1]) CALL PRTHEX LD DE, ;BLOCK MASK (BLM) DB 1 ;NULL MASK (EXM) DW 242 ;DISK SIZE (CLUSTERS)-1 (DSM) DW 63 ;DIRECTORY MAX (DRM) DB 10000$' QSEC0M DB CR,LF,'Enter Sector # (0..255) - $' QTRK0M DB CR,LF,'Enter Track # (0..255) - $' QSEC1M DB CR,LF,'Enter Sector************************ EXECUTE: IF DIAGMODE CALL DUMP ;DIAGNOSTIC ENDIF PUSH IY ;GET IOPB PTR POP HL LD ADIRECTORY MAX (DRM) DB 11111111B ;ALLOCATION 0 (AL0) DB 10000000B ;ALLOCATION 1 (AL1) DW 0 ;CHECK SIZE (CKS) DW 2 SPM CALL EDITOR LD A,(IY+[PBSTAT + 2]) CALL PRTHEX LD DE,SPM CALL EDITOR LD A,(IY+[PBSTAT + 3]) CALL PRTHEX 000B ;ALLOCATION 0 (AL0) DB 00000000B ;ALLOCATION 1 (AL1) DW 16 ;CHECK SIZE (CKS) DW 2 ;TRACK OFFSET (OFF) ; ; DIS # (0..25) - $' QTRK1M DB CR,LF,'Enter Track # (0..76) - $' XADRM DB CR,LF,'Enter Xfer Address - $' XCNTM DB CR,LF,'Enter Sec,L ;OUTPUT IOPB ADDRESS TO HOST ADAPTER OUT (HDATA),A LD A,HIOPBL OUT (HCMD),A EXEC1: IN A,(HSTATUS) BIT HBUSYB,A JR;TRACK OFFSET (OFF) ; ; DISK CONTROLLER PARAMETERS ; REPT HDIDSEC + 48 - $ ;LOCATE BLOCK LIST OFF DB 0E5H LIST ON IF DIAGMODE CALL DUMP ENDIF CALL CRLF SCF RET IF DIAGMODE ;************************************** ; ; DUMK CONTROLLER PARAMETERS ; REPT DDIDSEC + 48 - $ ;LOCATE BLOCK LIST OFF DB 0E5H LIST ON ENDM DB 0 ;SECTOR STAGGERtor Count - $' TRKSM DB CR,LF,'Tracks to format? (1..256) - $' INTLM DB CR,LF,'Enter Interleave Factor (0..16) - $' QSIDEM DB NZ,EXEC1 CALL GETRES ;IF ERROR THEN ??? RET C LD A,H OUT (HDATA),A LD A,HIOPBH OUT (HCMD),A EXEC2: IN A,(HSTAENDM DB 0 ;SECTOR STAGGER (NOT USED FOR HARD DISK) DB 01100000B ;256B/SEC, HARD, 1 DENS, 1 SIDE REPT HDIDSEC + 256 - P THE CDB TO THE CONSOLE ; ;************************************** DUMP: PUSH IY LD DE,PBHDRM ;OUTPUT HEADER FOR IOPB FIE DB 01100000B ;256B/SEC, HARD, 1 DENS, 1 SIDE REPT DDIDSEC + 256 - $ ;FILL OUT SECTOR LIST OFF DB 0E5H LIST ON END CR,LF,'Enter sides (1..2) - $' QDENSM DB CR,LF,'Enter Density (Single/Double) - $' VTRKM DB BS,'V',BS,'$' VOKM DB '-',BS,'$'TUS) BIT HBUSYB,A JR NZ,EXEC2 CALL GETRES ;IF ERROR THEN ??? RET C XOR A ;XADDR ALLWAYS BANK 0 OUT (HDATA),A $ ;FILL OUT SECTOR LIST OFF DB 0E5H LIST ON ENDM ;################################# ; ; SINGLE DENSITY ID SECTOR ;M SUBTTL DATA AREAS DATA ;####################### ; ; DRIVE TABLES ; ;####################### HDTBL: DB 0 DW H VERRM DB BS,'?',BS,'$' DMPBM DB CR,LF,'Dumped to Buffer location: $' DTYPEM: DB CR,LF,'Enter drive type (Hard/Floppy) - $'  LD A,HIOPBX OUT (HCMD),A EXEC3: IN A,(HSTATUS) BIT HBUSYB,A JR NZ,EXEC3 CALL GETRES ;IF ERROR THEN ??? RET C  ;################################# SDIDSEC: REPT 128 ;FILL OUT SECTOR LIST OFF DB 0E5H LIST ON ENDM ;########USH BC CALL PRTHEX CALL SPACE POP BC POP HL INC HL DJNZ OUTLP ; CALL CRLF ;OUTPUT XFER ADDR, COUNT ; LD A,(PARAST OFF DB 0E5H ;FILL WITH E5 LIST ON ENDM ; DW 52 ;SECTORS PER TRACK (SPT) DB 4 ;BLOCK SHIFT FACTOR (BSH) DB 15LDS CALL EDITOR CALL CRLF ;GET IOPB PTR POP HL LD B,16 ;IOPB = 16 BYTES LONG OUTLP: LD A,(HL) PUSH HL P30 ( ) *!",#-$.%/ &0 '+DIDSEC DW 256 ;# SECTORS DW 256 ;# TRACKS SDTBL: DB 1 DW SDIDSEC DW 26 DW 77 DDTBL: DB 2 DW DDIDSEC DWusy state if required. ; Normally this change will allow transparent operation of the soft- ; ware, without concern to the busRIFY SECTOR ERROR FLAG THISDRV DB -1 ;THIS DRIVE TYPE FLAGS 0: HARD, 1: FLOPPY, -1: UNSP. DTYPE0 DB -1 ;DRIVE 0 TYPE (-1 := UNisk format clearing of PBSECO. This effectively ; prevented formatting other than side 0. ; ; 2.00 - 24 MAY 88 GRH ; Remo; 5 JADE floppy disk controller physical drive 1 ; 6 JADE floppy disk controller physical drive 2 ; 7 JADE floppy dis 52 + 1 DW 77 DTBLFLG EQU 0 ;FLAG OFFSET DTBLID EQU 1 ;ID SECTOR PTR OFFSET DTBLSEC EQU 3 ;MAX SECTORS OFFSET DTBLTRK Ey status. All other status bits ; reflect the software status register contents (D1..7). ; ; 1.6 - 3 MAY 84 GRH ; Change bSPECIFIED) DTYPE1 DB -1,-1,-1 LOGBUF DS 128 ;LOGON XFER BUFFER SECBUF DS 256 ;VERIFY SECTOR BUFFER REL END ve SASI floppy option. Fix bug in GETRES which failed to return ; error properly. ; IOPB xfer only returns status bytes now. k controller physical drive 3 ; ;************************************************************************** ; ; REVISIONS: QU 5 ;MAX TRACKS OFFSET ;################## ; ; IOPBS ; ;################## IOPBDEF MACRO #CMD,#DRV,#TRK,#SEC,#FLG,#Dlock move subroutine to allow for 1..65,536 byte moves. ; Fix bugs in Jade driver. Add printer output diagnostic. ; ; 1.7 - 2Return logon flag for ; CBIOS 3.xx. ; Remove option to swap Jade & SASI drive #s. ; Change LOGON & delete disk tables (hard ; 1.0 - 28 DEC 83 GRH ; DIAGNOSTIC VERSION FOR TESTING THE BOARD. ; 1.1 - 2 JAN 84 GRH ; ADD HARD DISK CONTROLLER FIRMWARMAW,#DMAX DB #CMD,#DRV,#TRK,0,#SEC,0 DB #FLG DW #DMAW DB #DMAX DS 6 ENDM NULPB: IOPBDEF 0,0,0,0,0,0,0 XFERPB:  JUN 84 GRH ; Fix bug in HSTIN & HSTOUT macros outputting bit 7 data to XADDR ; register instead of to HXAD15 register. ;E. ; 1.2 - 1 APR 84 GRH ; Fix Bug in host xfer subr. that caused problems on 32k boundary ; crossings. Enable parity checkiIOPBDEF 1,0,0,0,0,0,0 IDIOPB: IOPBDEF 2,0,0,0,0,HDIDSEC,0 LOGIOPB IOPBDEF 0,0,0,0,0,LOGBUF,0 ;======================= ; ; Add JADE FDC dump to dump diagnostic command. ; ; 1.8 - 2 JUN 84 GRH ; Change floppy disk read/write sector to logical sec ; Add error recovery attempt by resetting controller & retrying. ; Add additional timeouts to lessen the 'hang' conditions. ng for received data. Enable ; controller retrys. ; 1.3 - 2 APR 84 GRH ; Fix Bug in read buffer routine which caused 1st 4  IOPB OFFSETS ; ;======================= PBCMD EQU 0 ;COMMAND BYTE PBDRV EQU 1 ;DRIVE BYTE PBTRK EQU 2 ;TRACK WORD PBSEC Etor for uniformity ; in IOPB parameters. (0..N-1 now changed to 1..N) ; ; 1.9 - 3 OCT 84 GRH ; Fix bug in Jade driver w; Correct Logon problems with sector & data xfer. ; Make retrys more reasonable & change flags to disable retrys only. ; Add Ibytes of sector ; to be 0 and read not retryed but sense status to be issued instead. ; The CDB had to be re-initialized with QU 4 ;SECTOR WORD (FORMAT INTERLEAVE, FLOPPY PARAMS) PBFLG EQU 6 ;FLAGS (LOG- 0: FULL, BLOCKING (SAME AS CP/M)) PBLOG EQU 0 ;Lhich allowed errors to go undetected. ; ; 1.A - 18 APR 85 GRH ; Fix logon problem. Code is only now showing bugs with 2nd h TITLE INTELLIGENT SASI HOST ADAPTOR INTERFACE LIST NOCOND ;*****************************************************************OPB track & sector limits checks. ; ; 2.02 7 JUN 88 GRH ; Add conditional print for diagnostics, floppy & hard disk listingthe read command after getting ; results command issued. ; ; 1.4 - 28 APR 84 GRH ; Add Jade FDC routines. Change host blocOGON REQUEST BIT # PBRTRY EQU 7 ;DISABLE RETRYS BIT PBDMA EQU 7 ;XFER ADDRESS WORD PBDMAX EQU 9 ;XFER BANK ADDRESS BYTE PBard ; disk installed. ; ; 1.B - 21 FEB 87 GRH ; Add error return to IOPB.PBSTAT thus allowing user to only check ; th********* ; ; THIS MODULE CONTAINS THE INTELLIGENT HOST ADAPTER FIRMWARE. ; ;***********************************************. ; Recode the SASI protocol. Add ACK* sensing to hardware. ; ; 2.03 24 JUL 88 GRH ; Lengthen controller reset wait time ik move subrs into general ; purpose subrs. ; ; 1.5 - 30 APR 84 GRH ; Change hardware to reflect the state of the interrupSTAT EQU 10 ;SENSE STATUS WORDS (4 BYTES) PBSP1 EQU 14 PBSP2 EQU 15 ;####################### ; ; VARIABLES ; ;#########is byte for errors rather than checking HSTATUS and then HDATA. ; ; 1.12 - 25 MAY 87 GRH ; Change JADE code to allow interin CLRCONT. The old time proved ; inadequate for a different DTC 140x controller. ; Change global definitions to add standardt flip-flop ; as the busy bit (D0). Hardware will now allow software setting of ; the interrupt flip-flop to allow passing a b############## COUNT DW 0 ;TRANSFER COUNT LUNSV DB 0 ;LOGICAL UNIT STORAGE MAXTRK DB 0 ;LAST FORMAT TRACK +1 ERRFLG DB 0 ;VEm communication with new JADE ; firmware. ; Change version # to decimal number. ; ; 1.13 - 11 MAY 88 GRH ; Remove hard dsical drive 1 ; 2 SASI physical drive 2 ; 3 SASI physical drive 3 ; 4 JADE floppy disk controller physical drive 0 disk only) & only return ; descriptor sector type. ; Change version number return to IOPB function. ; ; 2.01 4 JUN 88 GRH*************************** ; ; IOPB CONFIGURATION: ; ; DRIVE # TRANSLATES TO ; 0 SASI physical drive 0 ; 1 SASI phy40 ( ) *!+",#-$.%/ 0 '& prefixes. ; VERSN EQU 203 ;************************************************************************** FALSE EQU 0 TRUE EQU4 ; ; 7 6 5 4 3 2 1 0 ; ^ ^ \_____/ ^__ HOST INTERRUPT (1) ; | | |_______ NON-IOPB COMMAND CODE (0..F) ; | |________ ; RAMSIZE EQU 2048 ;SIZE OF LOCAL RAM ROMSIZE EQU 2048 ;SIZE OF LOCAL ROM ;======================================================================================================= ; ; SASI HARD DISK DEFINITIONS ; ;=============================EQ EQU 3 ;REQUEST* SIO EQU 4 ;I/O* SACK EQU 5 ;ACK SPERR EQU 7 ;PARITY ERROR DETECTED ; ; MASKS: SSTMSK EQU 10111111B ;S NOT FALSE ; DEBUG EQU FALSE ; LDIAG EQU FALSE ;TRUE TURNS ON DIAGNOSTICS CODE LISTING LFLOPY EQU FALSE ;TRUE TURNS ON JA______ EXECUTE IOPB (1) ; |________________ BOARD RESET (1) ; ; BIT DEFINITIONS: HINTRB EQU 0 ;HOST INTERRUPT REQUEST BIT================================ ; ; LOCAL PORT DEFINITIONS ; ;=========================================================================================================== HDCONT EQU 0 ;THIS CONTROLLER'S ADDRESS BIT HDBASD EQU 0 ;BASE DRIVE # OF HD TATUS BIT MASK SSTINV EQU (1 SHL SIO) + (1 SHL SREQ) ;STATUS BIT INVERSION MASK SSXMSK EQU (1 SHL SIO) + (1 SHL SCD) + (1 SHL DE FLOPPY CODE LISTING LSASI EQU TRUE ;TRUE TURNS ON SASI CODE LISTING ; ;*INCLUDE JDDCONT.DEF ;*INCLUDE COMIOPB.DEF ; HIOPBB EQU 6 ;HOST EXECUTE IOPB BIT HRESB EQU 7 ;HOST RESET LOCAL PROCESSOR BIT ; ; HOST DATA XFER REGISTER ; HDATA E============== ; ; SASI BUS DATA TRANSFER ; SASIDATA EQU LOCPRTS ; ; SASI BUS CONTROL ; SASICMD EQU LOCPRTS + 1 ; CONTROLLER HDNDRV EQU 4 ;NUMBER OF PHYSICAL DRIVES SUPPORTED HDNLUN EQU HDNDRV INLEV EQU 6 ;INTERLEAVE FACTOR FOR FORMAT SMSG) ;XFER CONTROL MASK ; ; CONTROL DATA: SGTCMD EQU 1 SHL SCD ;GET COMMAND FROM H/A SGTDAT EQU 0 ;GET DATA FROM H/A SS LIST OFF *INCLUDE JDDCONT.DEF *INCLUDE COMIOPB.DEF LIST ON SUBTTL DEFINITIONS ;=====================================QU LOCPRTS + 5 ; ; HOST BUS A15 CONTROL REGISTER FOR DMA ; HXAD15 EQU LOCPRTS + 6 ; ; 7 6 5 4 3 2 1 0 ; ^______________; 7 6 5 4 3 2 1 0 ; ^ ^ ^ ^ ^__ SASI INTERRUPT ON REQUEST ENABLE (1), HOST (0) ; | | | |____ SASI RESET BIT (1) ; ;=========================================================================== ; ; SASI COMMANDS ; ;=====================NDDAT EQU 1 SHL SIO ;SEND DATA TO H/A SSNDST EQU (1 SHL SIO) + (1 SHL SCD) ;SEND STATUS TO H/A SCMDDN EQU (1 SHL SIO) + (1 SHL====================================== ; ; I/O PORTS ; ;====================================================================__ BIT APPLIED TO HOST BUS A15 WHEN ACCESSING ITS MEMORY ; ; BIT DEFINITIONS: A15B EQU 7 ;HOST A15 BIT ; ; HOST BUS EX | | |______ SASI DEVICE SELECT STROBE (1) ; | |________ SASI PARITY ERROR CLEAR (0) ; |__________ HOST VECT====================================================== SCRDY EQU 0 ;TEST DRIVE READY COMMAND SCREC EQU 1 ;RECALIBRATE SCSNSE ======= S100D EQU 0D8H ;DATA PORT VISIBLE TO S100 BUS S100S EQU S100D + 1 ;STATUS PORT VISIBLE TO S100 BUS S100C EQU S100S TENDED ADDRESS REGISTER FOR DMA ; HXADDR EQU LOCPRTS + 7 ; ; 7 6 5 4 3 2 1 0 ; ^ ^ ^ ^ ^ ^ ^ ^__ A16 ; | | | | | | |____ AORED INTERRUPT (1) ; ; BIT DEFINITIONS: SINTE EQU 0 ;SASI INTERRUPT SRESET EQU 1 ;SASI RESET SSELECT EQU 2 ;SASI DEVICEQU 3 ;REQUEST SENSE SCFMTD EQU 4 ;FORMAT ENTIRE DRIVE SCFMTT EQU 6 ;FORMAT TRACK SCFMTBT EQU 7 ;FORMAT BAD TRACK SCREAD EQUNTERRUPT SET (W/O, DATA= DON'T CARE) ; HINTS EQU LOCPRTS + 3 ; ; HOST STATUS ; HSTAT EQU LOCPRTS + 4 ;HOST STATUS PORT ;COMMAND PORT VISIBLE TO S100 BUS ; LOCPRTS EQU 0 ;BASE ADDRESS OF LOCAL PORTS LOCMEM EQU 0 ;BASE ADDRESS OF LOCAL RAM ; 17 ; | | | | | |______ A18 ; | | | | |________ A19 ; | | | |__________ A20 ; | | |____________ A21 ; | |______________ A22 E SELECT STROBE SERRCLR EQU 3 ;SASI PARITY ERROR CLEAR* HINT EQU 4 ;HOST VECTORED INTERRUPT ; ; SASI BUS STATUS ; SASI 8 ;READ SECTOR(S) SCWRIT EQU 10 ;WRITE SECTOR(S) SCSEEK EQU 11 ;SEEK TRACK ; SCCOPY EQU 20H ;COPY BLOCK(S) ; SCDEF EQU 0C; ; 7 6 5 4 3 2 1 0 ; ^ ^ ^__ BOARD BUSY (1) ; | |____ FIRMWARE ERROR (1) ; |________________ ERROR (1) S1PRTS EQU 80H ;BASE ADDRESS OF S100 PORTS ;=========================================================================== ; ; |________________ A23 ;=========================================================================== ; ; FIRMWARE ERROR ST EQU LOCPRTS + 1 ; ; 7 6 5 4 3 2 1 0 ; ^ ^ ^ ^ ^ ^ ^__ BUSY (1) ; | | | | | |____ MESSAGE (1) ; | | | | |______ COM0H ;DEFINE FLOPPY DISK PARAMETERS ;=========================================================================== ; ; JADE ; ; BIT DEFINITIONS: HBUSY EQU 0 ;HOST BUSY STATUS BIT HFERRB EQU 1 ;HOST FIRMWARE ERROR BIT HSERRB EQU 7 ;HOST ERROR  ; MEMORY AREAS ; ;=========================================================================== S1MEM EQU 8000H ;BASE ADDRESMAND (1) / DATA (0) ; | | | |________ REQUEST* (0) ; | | |__________ INPUT (0) / OUTPUT (1) ; | |____________ ACKNOWLEG DEFINITIONS ; ;=========================================================================== JADBASD EQU 4 ;BASE DRIVE # OF JSTATUS BIT HFERR EQU (1 SHL HSERRB) + (1 SHL HFERRB) ;FIRMWARE ERROR BYTE ; ; HOST COMMAND REGISTER ; HCMD EQU LOCPRTS + S OF S100 MEMORY WINDOW ; LOCROM EQU LOCMEM ;BASE ADDRESS OF LOCAL ROM LOCRAM EQU LOCMEM + 4000H ;BASE ADDRESS OF LOCAL RAM ======================================================== TMOERR EQU ?HNDSERR ;CONTROLLER HANDSHAKE TIMOUT ;===============E (1) ; |________________ PARITY ERROR (1) ; ; BIT DEFINITIONS: SBUSY EQU 0 ;BUSY SMSG EQU 1 ;MESSAGE SCD EQU 2 ;C/D SR SCD) + (1 SHL SMSG) ;COMMAND DONE ; ; HOST INTERRUPT CLEAR (W/O, DATA= DON'T CARE) ; HINTC EQU LOCPRTS + 2 ; ; HOST ICODES ; RETURNED IN HOST DATA REGISTER IF HOST STATUS BIT 1 SET AND IN IOPB.PBSTATO ; IF APPLICABLE. ; ;===================50 ( ) *!+",#-$.%/ 0 '&ADE CONTROLLER JADNDRV EQU 4 ;NUMBER OF LOGICAL JADE CONTROLLER DRIVES ;DDPORT EQU ?DDPORT8 DDBUF EQU 0380H ;BUFFER OFF ; COMMAND OK. PERFORM COMPUTED GOSUB TO EXECUTE IT ; CMDOK: LD HL,CMDTBL ;POINT TO TABLE ADD A,L ;COMPUTE ENTRY ADDRESS@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ;; ;; HOST INPUT MACRO ;; ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@SICMD),A LD A,[1 SHL SERRCLR] OUT (SASICMD),A ; ; ENABLE NEXT HOST INTERRUPT & WAIT FOR IT ; EI JR $ ;########OMMAND ; JP HWAITC ; ; ; RAM ERROR ENCOUNTERED ; MEMERR: ; ; PASS ERROR TO HOST ; LD A,?RAMERR ;PASS ERROR TO HOSSET IDFLGO EQU 0031H ;ID SECTOR DISK FLAGS OFFSET DFHARD EQU 5 ;HARD DISK FLAG BIT DFDBL EQU 6 ; DFT0D EQU 0 ;TRACK 0 DE LD L,A LD A,0 ADC A,H LD H,A LD E,(HL) ;FETCH EXECUTION ADDRESS INC HL LD D,(HL) EX DE,HL IN A,(HDATA) ;PREF@@@@@@@@@@@@@@@@@ HSTIN: MACRO #PORT ;; ;; SELECT PROPER INSTRUCTION BASED ON PORT BIT 7 ;; ; ; SELECT BIT 7 OF PORT ;################################################################### ; ; COMMAND TABLE FOR NON-IOPB COMMANDS ; ;#############T & HALT OUT (HDATA),A ; ; SET ERROR FLAG TO HOST ; LD A,HFERR OUT (HSTAT),A ; ; CLEAR PENDING INTERRUPT & GO TO NSITY FLAG BIT SUBTTL MACROS ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ; ; BUFFER HALFETCH ARGUMENT ; LD DE,CMDRET ;PUT RETURN ADDRESS ON STACK PUSH DE JP (HL) ; ; ; ; ALL COMMANDS RETURN HERE ; ENTRY-  IF #PORT < 80H XOR A,A ELSE LD A,#PORT ;SET UP BIT 7 ENDIF OUT (HXAD15),A ; ; INPUT DATA ; IN A,(#PORT OR 8############################################################## CMDTBL: DW IOPBLO ;(1) SET IOPB LO COMMAND DW IOPBHI ;(3) SLEEP ; OUT (HINTC),A HALT IF $ > 38H CONMSG **** ERROR! RESET CODE OVERLAPS INTERRUPT CODE! **** ENDIF ;------- SELECT MACRO ; ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ SELCTBUF MACRO ; ; ASSUME 1SA= 0: NO ERROR ; /0: ERROR CODE ; CMDRET: ; ; IF ERROR THEN PASS IT TO HOST ; OR A,A ;IF A= 0 THEN NO ERROR JR Z0H) ;FETCH DATA ENDM SUBTTL MAIN CODE ORG LOCROM ;---------------------------------------------------------------------SET IOPB HI COMMAND DW IOPBX ;(5) SET IOPB XADDR COMMAND DW DIAG0 ;(7) DUMP LOCAL MEMORY DIAGNOSTIC CMD DW DIAG1 ;(9) S-------------------------------------------------------------------- ; ; INTERRUPT ENTRY VECTOR OCCURRS WHEN HOST INTERRUPTS OT HALF ; LD HL,HDSECB ; ; SELECT BUFFER HALF BASED ON SECTOR BIT 0 ; LD A,(PBSEC) ;IF SECTOR IS ODD THEN SELECT UPPER ,CMDR1 ; ; ELSE PASS ERROR CODE TO HOST ; OUT (HDATA),A ;PUT ERROR IN DATA REG ; LD A,HFERR ;SET ERROR FLAGS ; CMDR------ ; ; PROCESSOR REGISTER USAGE: ; IY= PTR TO CURRENT COMMAND DESCRIPTOR BLOCK ; ;-------------------------------------ET OUTPUT PORTS DIAG. COMMAND DW DIAG2 ;(B) TEST S100 MEMORY ACCESS COMMAND DW DIAG3 ;(D) BLOCK MOVE 01000H TO 02000H COMMHALF AND A,1 JR Z,BB#SYM ; LD HL,HDSECB + 128 BB#SYM: ENDM ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@1: OUT (HSTAT),A ;PASS ERROR TO HOST ; ; SET UP FOR TERMINATION ; POP HL ;WASTE RETURN ADDRESS TO WAIT RTN ; HWAITC: -------------------------------------- ; ; MAIN CODE FROM RESET ; RESETV: ; ; SET BUSY FLAG UNTIL WE'RE DONE ; OUT AND DW PRINT ;(F) PRINT ASCII STRING TO PORT COMMAND DW RETVERS ;(11) RETURN FIRMWARE VERSION ; NUMCMDS EQU ($ - CMDTBL)------------------------------------- ORG LOCROM + 38H ; ; GET HOST COMMAND ; IN A,(HCMD) ; ; IF NOT HOST INTERRUPT@@@@@@@@@@@@@@@@@@@@@@ ;; ;; HOST OUTPUT MACRO ;; ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@; ; TELL HOST WE'RE DONE ; OUT (HINTC),A ; ; FALL INTO MAIN LOOP ; ;--------------------------------------------(HINTS),A ; ; PASS 0 TO HOST IN STATUS ; XOR A,A OUT (HSTAT),A ; ; SET UP INTERRUPT ; IM 1 ; ; SET UP STACK  / 2 ;NUMBER OF COMMANDS SUBTTL COMMANDS ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; THEN ASSUME SASI ; BIT HINTRB,A JP Z,SASINT ; ; IF IOPB COMMAND THEN GO EXECUTE IT ; BIT HIOPBB,A JP NZ,EXIOPB ;@@ HSTOUT: MACRO #PORT, #DATA ;; ;; SELECT INSTRUCTION BASED ON EFFICIENCY ;; ; ; SET BIT 7 OF PORT ; IF #PORT < 80------------------------------- ; ; MAIN INTERRUPTED LOOP ; ;--------------------------------------------------------------- ; LD SP,STACK ;INIT STACK ; ; DO RAM TEST 1ST ; LD HL,LOCRAM LD BC,RAMSIZE ; MTLP: LD A,(HL) ;COMPLEMENT & TEST  SET IOPB ADDRESS FUNCTION ; MUST BE INITIALIZED BEFORE DISK ACCESS ; ENTRY- A= DATA ; EXIT - A= 0 ; ;+++++++++++++++++++++ ; MUST BE DIRECT COMMAND FOR EXECUTION ; AND A,00011110B ;MASK OFF UNUSED COMMANDS ; CP A,NUMCMDS * 2 ;IF COMMAND ERROH XOR A,A ELSE LD A,#PORT ENDIF OUT (HXAD15),A ; ; OUTPUT DATA ; IF (#DATA = 0) AND (#PORT <> 0) XOR A,A EN CPL LD (HL),A CP A,(HL) JR NZ,MEMERR ; CPL ;RESTORE LD (HL),A ; INC HL ;NEXT LOCATION DEC BC LD A,B OR A++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; SET LOW BYTE ; IOPBLO: LD HL,IOPBL ;POINT TO BYTE TO ALTER R THEN RETURN FIRMWARE ERR JR C,CMDOK ; ; ILLEGAL DIRECT COMMAND. RETURN ERROR TO HOST ; LD A,?CMDERR JR CMDRET ; ;DIF IF #DATA <> 0 LD A,#DATA ;OUTPUT DATA ENDIF OUT (#PORT OR 80H),A ENDM ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@),A LD A,[1 SHL SSELECT] OR [1 SHL SERRCLR] ; ; DISALLOW INTERRUPTS WHILE THIS SEQUENCE IS IN PROCESS ; DI ; OUT (SA,C JR NZ,MTLP ; ; RAM OK. DO ANY OTHER INITIALIZATION ; CALL INIT ;ANY OTHER INITIALIZATION ; ; GO WAIT FOR HOST CR IF SASI IS ; IMPLEMENTED WITH INTERRUPT THEN MEANS SASI IS REQUESTING SOMETHING. ; ;-------------------------------------------------- HWAIT: ; ; SET UP TO DESELECT SASI IN ORDER TO DESELECT DRIVE ON SOME CONTROLLERS ; XOR A,A OUT (SASIDATA60 ( ) *!+",#-$.%/ 0 '&JR IOPBST ; ; SET HIGH BYTE ; IOPBHI: LD HL,IOPBH JR IOPBST ; ; SET EXTENDED ADDRESS BYTE ; IOPBX: LD HL,IOPBX,A RET ; ; ; CONTINUOUS WRITES COMMAND ; DOWRITE: LD (S1MEM + 1000H),A ;USE ARGUMENT AS DATA JR D3LP ; ; ; CON LD A,H ;SET BUS BIT 15 OUT (HXAD15),A LDIR ; ; NOW JADE BANK 1 AT 5400H ; HSTOUT ?DDPORT8,?DDMB1 ;FOLLOW WITH FDCPRINT THE CHAR SUBROUTINE ; ENTRY- E= CHAR TO OUTPUT ; C= PORT # ; ;*******************************************************E ; ; DO TEST ; D2LP: LD A,(HL) CPL LD (HL),A CP A,(HL) CPL ;RESTORE LD (HL),A JR NZ,D2ERR ; ; TEST OK. A ; ; COMMON SET CODE ; IOPBST: LD C,(HL) ;SAVE OLD DATA LD (HL),A ;SET NEW DATA LD A,C ;PASS OLD DATA TO HOST OUTINUOUS READS COMMAND ; DOREAD: LD A,(S1MEM + 1000H) JR D3LP ; ; ; BLOCK MOVE COMMAND TO LOW MEMORY ; DOMOVE: LD  BANK 1 POP HL LD A,H ;SET BUS BIT 15 OUT (HXAD15),A LD BC,1024 LDIR ; HSTOUT ?DDPORT8,?DDFREE ;REMOVE DD WINDOW S******************** PRT: IN A,(C) ;IF BUSY THEN WAIT AND A,1 JR NZ,PRT ; LD A,E ;OUTPUT THE CHAR SET 7,A OUT (C),A DO NEXT ; INC HL ; ; CHECK FOR DONE ; DEC BC LD A,B OR A,C JR NZ,D2LP ; ; PASS ERROR DATA TO HOST MEMORY ; T (HDATA),A ; ; RETURN NO ERRORS ; XOR A ;RETURN NO ERRORS (PREVENTS DATA OVERWRITE) RET IF LDIAG = FALSE LIHL,S1MEM + 1000H LD DE,S1MEM + 2000H LD BC,1000H LDIR ; ; ONLY DO THIS ONE ONCE ; XOR A,A RET ; ; ; BLOCK MOO HOST WON'T CRASH ; ; PASS NO ERRORS TO HOST ; XOR A,A ;NO ERRORS OUT (HSTAT),A ; ; DIRECT RETURN TO WAIT LOOP ; ; RES 7,A OUT (C),A ; SET 7,A OUT (C),A ; RET IF LDIAG = FALSE LIST ON ENDIF SUBTTL IOPB EXECUTION  D2ERR: LD (S1MEM + 0FF2H),HL LD (S1MEM + 0FF4H),A LD A,(HL) LD (S1MEM + 0FF5H),A ; ; RETURN NO ERRORS ; XOR A,A ST OFF ENDIF ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; DIAGNOSTIC DUMP LOADS HOST VE TO HIGH MEMORY COMMAND ; DOBLKH: LD A,1 SHL A15B ;SET HIGH PAGE OUT (HXAD15),A LD HL,0E000H LD DE,0E800H LD BC,800 DIAGR: LD SP,STACK ;FLUSH RETURN ADDR FROM STACK JP HWAITC ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ;--------------------------------------------------------------------------- ; ; EXECUTE IOPB ; ;------------------------RET ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; DIAG3 DOES S100 MEMORY ACCESSES DEPEMEMORY WITH RAM IMAGE ; ENTRY- A= BANK ADDRESS ; EXIT - XX4000H..XX47FFH= RAM IMAGE ; XX4800H..XX4FFFH= ROM IMAGE ; XX5000H LDIR ; ; ONLY DO THIS ONE ONCE ALSO ; XOR A,A RET ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; DIAGNOSTIC 1 LOADS DATA INTO DATA OUT & STATUS REGS ; ENTRY- A= DATA ; ;++++++++++++++++++++++++++++++--------------------------------------------------- EXIOPB: ; ; MOVE HOST'S IOPB TO LOCAL ARRAY ; LD DE,PBCMD ;DESTINATH..XX57FFH= JADE FDC IMAGE ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ DIAG0: ; ;*** COM++++++++++++++++ ; ; PRINT TEXT ON THE PRINTER COMMAND EXERCISES THE I/O CAPABILITY ; ENTRY- A= PORT # ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ DIAG1: ; ; SET DATA & STATUS REGISTERS WITH HOST ARGUMENT ; OUT (HDATA),A ION LD HL,(IOPBL) ;GET HOST'S ADDRESS OF IOPB EX DE,HL ; LD A,(IOPBXA) ; SET BANK # ; LD BC,IOPBSIZE CALL MOVFHSTA= 0: BLOCK MOVE FROM 1000H TO 2000H ; 1: READ FROM 1000H (SCOPING TEST) ; 2: WRITE TO 1000H (SCOPING TEST) ; 3:MENTED OUT FOR NOW *** ; ; OUT (HXADDR),A ;USE DATA FOR EXTENDED ADDRESS ; ; SET UP FOR LOWER 32K ; XOR A,A OUT (HXA++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ PRINT: ; ; USE HOST ARGUMENT AS PORT # ; OUT (HXAD15),A ;SET  OUT (HSTAT),A ; ; DIRECT RETURN TO WAIT LOOP ; JP DIAGR ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; SELECT SASI OR JADE BASED ON IOPB.PBDRV ; LD A,(PBDRV) ;IF HARD DISK CONTROLLER THEN DO IT LD HL,HDCMDS ; CP A BLOCK MOVE FROM E000H TO E800H ; ALL OTHERS: NOP ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++DDR),A OUT (HXAD15),A ; ; DUMP LOCAL RAM TO S100 RAM AT 4000H ; LD HL,LOCRAM LD DE,S1MEM + 4000H LD BC,RAMSIZE LDPORT TO DATA SET 7,A ;MAP TO HOST LD C,A ; CALL CRLF ; LD E,'0' ;START WITH '0' LD B,80 ;DO 1 LINE PRINT1: CALL PR++++++++++++++++++ ; ; DIAG2 TESTS S100 MEMORY READS & WRITES FROM XX1000H TO XX1FFFH ; EXIT- XX0FF2H= LAST LOCATION CHECKED ,HDBASD + HDNDRV JR C,XTABL ; ; CHECK IF JADE CONTROLLER ; LD HL,JADCMDS SUB A,JADBASD ;BIAS DOWN TOO JR C,XILDRV+++++++ DIAG3: ; ; DO TESTS BASED ON HOST ARGUMENT ; OR A,A JR Z,DOMOVE ; D3LP: IN A,(HDATA) ;IF DATA CHANGED THEN IR ; ; DUMP LOCAL ROM TO S100 RAM AT 4800H ; LD HL,LOCROM LD BC,ROMSIZE LDIR ; ; JUST FOR GRINS.. DUMP JADE CONTR ; XX0FF4H= 0: OK ; READ DATA IF ERROR ; XX0FF5H= CONTENTS OF LAST LOCATION ; ;++++++++++++++++++++++++++++++++++++++++ ;IF NOT JADE THEN DOESN'T EXIST ; CP A,JADNDRV JR NC,XILDRV ; LD (PBDRV),A ;IS JADE, OFFSET DRIVE # ; ; COMMAND ECHECK CP A,2 JR C,DOREAD JR Z,DOWRITE CP A,3 JR Z,DOBLKH ; ; IF UNKNOWN COMMAND THEN QUIT WITHOUT ERROR ; XOR AOLLER BANK 0 TO HOST RAM AT 5000H ; HSTOUT ?DDPORT8,?DDMB0 ;FOLLOW WITH FDC BANK 0 LD HL,(FDADDR) LD BC,1024 PUSH HL ; RETURN NO ERRORS ; XOR A,A RET ;*************************************************************************** ; ; +++++++++++++++++++++++++++++++++++ DIAG2: ; ; SET UP TO TEST HOST MEMORY ; LD HL,S1MEM + 1000H LD BC,ROMSIZE + RAMSIZNDING ON DATA ; NOTE: SCOPING TESTS CONTINUE UNTIL ANOTHER DATA WORD IS ; WRITTEN TO THE DATA REGISTER BY THE HOST. ; ENTRY- T ; ; NEXT CHAR ; INC E DJNZ PRINT1 ; ; END WITH A NEWLINE ; CRLF: LD E,0DH CALL PRT LD E,0AH CALL PRT ; 70 ( ) *!+",#-$.%/ 0 '&XECUTION ADDRESS TABLE SELECTED ; XTABL: ; ; IF ILLEGAL COMMAND THEN RETURN ERROR TO HOST ; LD A,(PBCMD) CP A,(HL) ;ERROR STATUS TO HOST ; POP AF RET ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; ?CMDERR JP XRET ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; RETURN FIRMWARE VERSIO+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ JADEXEC: ; ; RETURN ILLEGAL COMMAND ERROR ; LD A,?DCERR DW HDSEEK ;SEEK TRACK (NORMALLY IMPLIED) DW HDCERR DW HDCERR DW HDCERR DW HDCERR ; MXHCMDS EQU ($ - HDCMDS -1COUNT IS 1ST TABLE BYTE JR NC,XILCMD ; ; VALID COMMAND. DO COMPUTED GOSUB TO COMMAND ; INC HL ;SKIP COUNT ; ADD A,A WRITE SECTOR COMMAND ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ JADWRT: ; ; XFER HOSN COMMAND ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ RETVERS: LD HL,VERSN LD (PBSTAT CMDERR RET SUBTTL JADE FDC SUBR ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; EXECU) / 2 IF LFLOPY = FALSE LIST OFF ENDIF SUBTTL JADE IOPB COMMANDS ;+++++++++++++++++++++++++++++++++++++++++++++++ ;MULTIPLY CMD BY 2 FOR OFFSET LD E,A LD D,0 ADD HL,DE ; LD E,(HL) ;GET COMMAND FROM TABLE INC HL LD D,(HL) EX T DATA TO LOCAL BUFFER ; LD HL,JADSECB CALL HDHSTR ; ; OPEN JADE FDC WINDOW ; HSTOUT ?DDPORT8,?DDMB1 ; ; XFER LO+ 2),HL ; ; RETURN NO ERRORS ; XOR A RET ;########################################################################TE THE COMMAND BLOCK FUNC. ; EXIT - NZ= ERROR, A= ERROR CODE ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; LOGON COMMAND IS SAME AS READ ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++DE,HL ; LD DE,XRET ;PUT RETURN ADDRESS ON STACK PUSH DE JP (HL) ;EXECUTE COMMAND ; ; ; IOPB COMMANDS RETURN HERE. CAL BUFFER DATA TO JADE FDC BUFFER ; LD HL,(FDADDR) EX DE,HL LD HL,JADSECB LD BC,128 XOR A,A CALL MOV2HST ; ; E### ; ; IOPB COMMAND EXECUTION TABLES ; ;########################################################################### ; ; ++++++++++++++ FDSKEX: ; ; FORMAT DATA ; LD A,(PBSEC) INC A ;CHANGE FROM LOGICAL ADDR TO SECTOR # LD (PBSEC),A ; ++++++++++++++++++ JADLOG: ; ; FALL INTO READ COMMAND ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++; THIS RETURN MUST RETURN IOPB TO HOST FOR STATUS UPDATE ; AF= ERROR STATUS ; XRET: PUSH AF ;SAVE POSSIBLE ERROR CODE ; XECUTE THE WRITE COMMAND ; CALL FDSKEX ; ; REMOVE JADE FDC WINDOW ; PUSH AF ;SAVE ERROR STATUS HSTOUT ?DDPORT8,?DDF JADE FLOPPY CONTROLLER COMMANDS ; JADCMDS: DB MXJCMDS DW JADLOG ;LOG ON DISK DW JADREAD ;READ SECTOR DW JADWRT ;W; OUTPUT IOPB TO THE CONTROLLER ; HSTOUT ?DDPORT8,?DDMB0 ;GET BANK 0 ; LD DE,?DDCBO ;CALCULATE FDC ADDRESS LD HL,(FD; RETURN ERROR IN IOPB ALSO (REV 1.B) ; LD (PBSTAT),A ; ; XFER LOCAL IOPB STATUS BYTES TO HOST'S IOPB ; LD DE,PBSTAREE ;REMOVE WINDOW ; ; RETURN ERROR STATUS ; POP AF RET ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++RITE SECTOR DW JADFORM ;FORMAT TRACK DW JADRDAD ;READ ADDRESS DW JADEXEC ;EIA OUTPUT DW JADEXEC ;EIA STATUS DW JADADDR) ADD HL,DE EX DE,HL LD HL,PBCMD LD BC,PBSTAT - PBCMD XOR A,A CALL MOV2HST ; ; HAVE JADE FDC EXECUTE THE COMDREAD: ; ; SWITCH JADE FDC INTO HOST MEMORY ; HSTOUT ?DDPORT8,?DDMB0 ; ; EXECUTE COMMAND ; CALL FDSKEX ; ; XFET - PBCMD ;CALCULATE USER OFFSET TO STATUS LD HL,(IOPBL) ;ADD TO USER IOPB BASE ADD HL,DE EX DE,HL ;PUT IN DE LD HL++++++++++++++++++ ; ; FORMAT COMMAND ; (NOT IMPLEMENTED) ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++EXEC ;IDLE DW JADEXEC ;RET VERS DW JADWRT ;SET FLAGS DW JADEXEC ;LOAD HEAD DW JADEXEC ;SEEK DW JADWRT ;SET DRV PMAND ; HSTOUT ?DDPORT8,?DDEXC ;ISSUE COMMAND ; FDSKWT: HSTIN ?DDPORT8 ;WAIT UNTIL DONE AND A,?DDSHLT JR NZ,FDSKWT ; R DATA TO LOCAL BUFFER ; PUSH AF ;SAVE ERROR STATUS ; HSTOUT ?DDPORT8,?DDMB1 ;GET BANK 1 FOR SECTOR BUFFER LD HL,(FDADD,PBSTAT ;SOURCE := LOCAL IOPB IMAGE ; LD A,(IOPBXA) ;GET BANK # ADC A,0 ;ADD IN CARRY FROM CALCULATION ABOVE ; LD BC+++++++++++++++ JADFORM: ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; READ ADDRESSARAMS DW JADEXEC ;RET DRV STATUS DW JADEXEC ;SET BAUD DW JADEXEC ;CLEAR ; MXJCMDS EQU ($ - JADCMDS-1) / 2 HDCMDS:  ; MOVE STATUS BYTES TO LOCAL IOPB ; HSTOUT ?DDPORT8,?DDMB0 ;GET WINDOW LD BC,[PBCMD + IOPBSIZE] - PBSTAT ; XOR A,A R) ;GET FDC ADDRESS LD DE,JADSECB EX DE,HL LD BC,128 ;FETCH SECTOR DATA XOR A,A CALL MOVFHST ; ; REMOVE JADE FDC ,IOPBSIZE - (PBSTAT - PBCMD) ;ONLY RETURN STATUS BYTES CALL MOV2HST ; ; RETURN ERROR STATUS TO HOST ; POP AF JP CMDRE DB MXHCMDS DW HDLOG ;LOG ON DISK (SELECT DISK) DW HDREAD ;READ DEBLOCKED SECTOR DW HDWRT ;WRITE DEBLOCKED SECTOR DW CALL MOVFHST ; ; PASS ERROR STATUS TO HOST ; LD A,(PBSTAT) ;IF NO ERROR THEN RETURN 0, NC OR A,A RET IF LFLOPY WINDOW ; HSTOUT ?DDPORT8,?DDFREE ; ; XFER LOCAL BUFFER DATA TO HOST ; LD HL,JADSECB CALL HDHSTW ; ; RETURN JADE T ; ; ; ILLEGAL DRIVE REQUESTED ; XILDRV: LD A,?SELERR JP XRET ; ; ; ILLEGAL COMMAND REQUESTED ; XILCMD: LD A,++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; IDLE COMMAND ; (NOT IMPLEMENTED) ; ;++++++ HDFORM ;FORMAT TRACK DW HDRECAL ;RECAL DW HDCERR DW HDCERR DW HDCERR DW RETVERS ;RETURN VERSION DW HDCERR DW H+++++++++++++++ ; ; READ SECTOR COMMAND ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ JA COMMAND ; (NOT IMPLEMENTED) ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ JADRDAD: ;+80 ( ) *!+",#-$.%/ 0 '&= FALSE LIST ON ENDIF IF LSASI = FALSE LIST OFF ENDIF SUBTTL HARD DISK IOPB COMMANDS ;---------------------+++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; FORMAT TRACK COMMAND ; ;++++++++++++++++++++++++++++++++++++++++++H HL ;SAVE BUFFER PTR FOR RETRY OR XFER ; LD DE,16 ;ADD OFFSET TO DESCRIPTOR TEXT ADD HL,DE ; LD DE,IDTXT ;POINT TO TE+++++++++++++++++++++++++++++++++ ; ; SEEK COMMAND ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++; ; SELECT DRIVE ; CALL HDSELCT RET NZ ; ; SET UP FOR READ ; LD IY,LAXCDB ;USE XFER CDB ; LD A,(LUNSV) ;STILL ------------------------------------------------------ ; ; INTERRUPT WITHOUT HOST BIT SET ; ;-------------------------------+++++++++++++++++++++++++++++++++ HDFORM: ; ; SELECT DRIVE ; CALL HDSELCT RET NZ ; ; SET UP FOR FORMAT ; LD IY,XT CONSTANT LD B,IDSZE ;SIZE OF COMPARE ; HDCKID: LD A,(DE) ;IF NO MATCH THEN EXIT CP A,(HL) JR NZ,HDNTID ; INC HL +++++++ HDSEEK: ; ; SELECT DRIVE ; CALL HDSELCT RET NZ ; ; SET UP CDB DATA ; LD IY,LAXCDB ;USE XFER CDB LD (IHAS SELECTED LUN LD (IY + LUN),A ; CALL GETLAD RET NZ ; ; READ SECTOR INTO LOCAL BUFFER ; CALL HDRDBUF RET NZ ;-------------------------------------------- SASINT: ; ; THIS INTERRUPT NOT IMPLEMENTED. RETURN ERROR TO HOST ; LD A,?INLAXCDB LD (IY + CMD),SCFMTT ; ; FETCH INTERLEAVE FACTOR FROM SECTOR DATA ; LD A,(PBSEC) ;SECTOR BYTE HAS INTERLEAVE FAC ;ELSE NEXT CHAR INC DE DJNZ HDCKID ; ; ID CHECKS, SET FLAG ; LD A,-2 ;NEW DESCRIPTOR SECTOR FLAG XFRID: LD (PBSTATY + CMD),SCSEEK ;SEEK COMMAND ; LD A,(LUNSV) ;STILL HAS SELECTED LUN LD (IY + LUN),A ; CALL GETLAD ;GET USER'S BLOCK  ; DEBLOCK DATA BUFFER ; SELCTBUF ; ; XFER DATA TO HOST ; CALL HDHSTW ;WRITE TO HOST ; ; SUCCESSFUL READ. RETUTERR JP CMDRET ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; UNSUPPORTED COMMAND TOR LD C,A AND A,00001111B ;MASK OFF HEAD BITS LD (IY + ILV),A ; ; MASK OFF INTERLEAVE BUT LEAVE HEAD DATA IN SECTOR  + 2),A ; ; XFER ID SECTOR TO HOST BUFFER ; POP HL ;RESTORE PTR TO BUFFER HALF CALL HDHSTW ; CALL CLRBUFR ;FLUSH BRET NZ ; ; SEND THE COMMAND TO THE SASI CONTROLLER ; CALL SNDCDB RET NZ ; ; RETURN THE COMMAND STATUS TO HOST ; RN NO ERRORS ; XOR A,A ;NO ERRORS RET ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ;; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ HDCERR: ; ; RETURN ILLEGAL COMMAND ERROR ;; LD A,C AND A,11000000B LD (PBSEC),A ; ; SET UP CDB ; LD A,(LUNSV) ;STILL HAS SELECTED LUN LD (IY + LUN),A ; UFFER OF IOPB SECTOR (DON'T CARE) ; ; DONE, RETURN NO ERRORS TO HOST ; XOR A,A RET ; ; ; NOT ID SECTOR, CHECK FOR JP GETRES LIST ON SUBTTL HARD DISK SUBROUTINES ;*********************************************************************** LD A,?CMDERR RET ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; DRIVE SELECT/LOG-CALL GETLAD ;GET LOGICAL ADDRESS JR NZ,FRILV ; ; IF NO ERROR THEN SEND THE FORMAT COMMAND TO THE SASI CONTROLLER ; CALOLD FORMAT ID SECTOR ; HDNTID: POP HL ;RESTORE BUFFER PTR PUSH HL ; LD DE,JIDTXT ;USE JADE ID CONSTANT LD B,JIDSZE ;**** ; ; ADDITIONAL INITIALIZATION CODE ; ;*************************************************************************** INITCT DRIVE ; CALL HDSELCT ;IMPLIED SELECT RET NZ ; ; SET UP DATA TO PRE-READ SECTOR ; LD IY,LAXCDB ;USE XFER CDB ; ON COMMAND ; CHECK DRIVE READY ; EXIT - A= 0: OK, /0: ERROR CODE ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++L SNDCDB ; ; RETURN RESULT STATUS TO HOST ; CALL Z,GETRES ;FINISH UP ; ; RESTORE CDB INTERLEAVE BYTE ; FRILV: LDJADE ID SIZE ; HDCKJID: LD A,(DE) ;IF NO MATCH THEN RETURN CP A,(HL) JR NZ,HDLOG1 ; INC HL INC DE DJNZ HDCKJID : ; ; SET CURRENT DRIVE TO NONE ; LD HL,CURDRV LD (HL),-1 ; ; INIT CDB DATA ; LD HL,NULCDB ;ZERO CDBS LD B,CDB LD A,(LUNSV) ;STILL HAS SELECTED LUN LD (IY + LUN),A ; CALL GETLAD RET NZ ; ; PRE-READ SECTOR ; CALL HDRDBUF ;RE+++++++++++++++++++ HDLOG: ; ; SELECT DRIVE ; CALL HDSELCT RET NZ ; ; READ THE DISK DESCRIPTOR SECTOR ; LD IY,I (IY+ILV),0 ;RESTORE ILV BYTE TO 0 RET ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ;; ; IS JADE FORMAT, RETURN ITS FLAG ; LD A,-1 JR XFRID ; ; ; NO ID SECTOR, RETURN SO ; HDLOG1: XOR A,A ;PASS NOTINIT INITRAM: LD (HL),0 INC HL DJNZ INITRAM ; ; RESET SASI CONTROLLER ; CALL CLRCONT ; ; FLUSH SECTOR BUFFER FRESH BUFFER WITH SECTOR DATA RET NZ ; ; BLOCK SECTOR ; SELCTBUF ; ; XFER HOST DATA TO LOCAL BUFFER ; CALL HDHSTDRCDB ; LD A,(LUNSV) ;LUN STILL THERE FROM SELECT LD (IY + LUN),A ; CALL GETLAD ;GET WHERE THE ID SECTOR IS LOCATED R ID SECTOR FLAG JR XFRID ;XFER DATA ANYWAY ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; CALL CLRBUFR ;START WITH FRESH BUFFER READ ; ; INITIALIZE JADE FDC ADDRESS PTR ; HSTIN ?DDPORT8 ;FETCH FDC ADDRESS R ;READ HOST BUFFER ; ; WRITE SECTOR & RETURN STATUS TO HOST ; JP HDWRBUF ;WRITE TO DISK ;++++++++++++++++++++++++ET NZ ; CALL HDRDBUF RET NZ ; ; VERIFY THE SECTOR AS A LEGAL DESCRIPTOR SECTOR ; SELCTBUF ;SELECT BUFFER HALF PUS ; CALL HDSELCT RET NZ ; ; CONTINUE WITH RECAL FUNCTION ; JP RECALC ;++++++++++++++++++++++++++++++++++++++++++ ; ; READ DEBLOCKED SECTOR COMMAND ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ HDREAD:  ; WRITE SECTOR COMMAND ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ HDWRT: ; ; SELE RECAL COMMAND ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ HDRECAL: ; ; SELECT DRIVE90 ( ) *!+",#-$.%/ 0 '& AND A,?DDSASW RLCA OR A,HIGH ?DDBASE LD H,A LD L,0 LD (FDADDR),HL ; ; DONE. RETURN TO MAIN CODE ; RET ;*RBCKR: PUSH AF LD A,(RETRYS) SUB A,1 LD (RETRYS),A JR C,HDRBRE ; ; RETRY ; POP AF JP HDRBRTY ; ; ; HARD S ; LD A,(PBDRV) AND A,00000011B LD C,A ;SAVE DRIVE LD HL,CURDRV SUB A,(HL) RET Z ; ; FIRST SAVE DRIVE FOR GET CONTROLLER RETRYS ; ; TOP OF WRITE SECTOR DATA LOOP ; HDWBRTY: ; ; ISSUE COMMAND BLOCK TO CONTROLLER ; LD (IY+CMD) ; TOP OF READ SECTOR DATA LOOP ; HDRBRTY: ; ; ISSUE COMMAND BLOCK TO CONTROLLER ; LD (IY+CMD),SCREAD ;READ COMMAND ************************************************************************** ; ; RESET SASI CONTROLLER PROCEDURE ; EXIT - A= 0 ERROR, CLEAR CONTAMINATED BUFFER ; HDRBRE: CALL CLRBUFR ; POP AF RET ; ; ; POSSIBLE OVERFLOW ERROR ; HDRBGER: ;LUN ; LD (HL),C ; ; SEE IF REQUESTED DRIVE IS READY ; LD IY,NULCDB ;USE NUL CDB LD (IY+CMD),SCRDY ;TEST READY COMMAN,SCWRIT ;WRITE COMMAND LD (IY+NBK),1 ;ALLWAYS USE 1 BLOCK (SECTOR) ; CALL SNDCDB JR NZ,HDWBERR ; ; SET UP FOR DATA XF LD (IY+NBK),1 ;ALLWAYS USE 1 BLOCK (SECTOR) ; CALL SNDCDB JR NZ,HDRBERR ; ; SET UP FOR DATA XFER FROM CONTROLLER ;  ; ;**************************************************************************** CLRCONT: ; ; ASSERT RESET ; LD A,1 SHL ; IF NO OVERFLOW THEN USE NORMAL RETURN ; LD DE,-[HDSECB + HDBUFSZ] ;TEST PTR FOR 1 PAST BUFFER END ADC HL,DE ;MUST USD ; CALL GETLUN ;REQUEST LUN FROM USER CALL SNDCDB ;EXECUTE CDB JR NZ,HDSERR ; CALL GETRES ;GET RESULT BYTE RET ZER FROM CONTROLLER ; LD BC,[HDBUFSZ * 256] + SASIDATA ;SET PORT LD HL,HDSECB ; ; TOP OF WRITE DATA LOOP ; HDWBLP: ; LD BC,[HDBUFSZ * 256] + SASIDATA ;SET PORT LD HL,HDSECB ; ; TOP OF READ DATA LOOP ; HDRBLP: ; ; WAIT FOR REQUEST ;  SRESET OUT (SASICMD),A ; ; DELAY A WHILE FOR CONTROLLER TO SENSE IT ; EX (SP),HL EX (SP),HL ; ; RELEASE RESET ;E ADC FOR ZF! WAITRQ CLEARS CF. JP Z,HDRBGET ; ; ELSE PROCESS AS ERROR ; CALL GETRES JR NZ,HDRBERR ; ; IF NO CONT ; ; SELECT ERROR, RESET CONTROLLER & TRY AGAIN ; HDSERR: CALL CLRCONT CALL SNDCDB ; CALL Z,GETRES RET Z ; ; SE ; WAIT FOR REQUEST ; CALL WAITRQ ;IF NOT READY THEN WAIT JR C,HDWBERR ;IF TIMEOUT THEN PROCESS ; ; IF C/D ASSERTED  CALL WAITRQ ;IF NOT READY THEN WAIT JR C,HDRBERR ;IF TIMEOUT THEN PROCESS ; ; IF C/D ASSERTED THEN XFER DONE ; BIT S LD A,1 SHL SERRCLR ;RELEASE RESET OUT (SASICMD),A ; ; WAIT FOR CONTROLLER TO DO IT'S THING ; PUSH HL ;SAVE REGS PROLLER ERROR THEN RETURN SYNC ERROR ; LD A,1 ;SUB-ERROR 1, READ OVERFLOW LD C,-1 ;NO STATUS CALL SYNERR ;SET THE IOPB LECT ERROR EXIT ; LD HL,CURDRV ;CURRENT DRIVE = NONEXISTENT LD (HL),-1 RET ;++++++++++++++++++++++++++++++++++++++++THEN XFER DONE ; BIT SCD,A JR NZ,HDWBGET ; ; XFER DATA ; OUTI ; ; IF BUFFER NOT FULL THEN REPEAT FOR NEXT BYTE USH BC ; LD HL,0 ;SET DELAY TIME LD B,3 ;STRETCH TIME DELAY FOR SLOW TARGETS ; CLRCON1: DEC HL ;DECRIMENT COUNT UNTI& RETURN JR HDRBERR ;CHECK RETRYS ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; W+++++++++++++++++++++++++++++++++++ ; ; READ HD SECTOR INTO BUFFER FUCTION ; ENTRY- IY= CDB PTR ; CDB= SET UP ; EXIT - NZ=; JP NZ,HDWBLP ; ; ELSE WASTE BYTES UNTIL COMMAND REQUESTED ; HDWBWST: CALL WAITRQ JR C,HDWBERR ; ; IF C/D ASSERLSE WASTE BYTES UNTIL COMMAND REQUESTED ; HDRBWST: CALL WAITRQ JR C,HDRBERR ; ; IF C/D ASSERTED THEN EXIT WITH ERROR L EXHAUSTED LD A,L OR A,H JR NZ,CLRCON1 ; DJNZ CLRCON1 ;IF EXTENDED DELAY NOT EXHAUSTED THEN REPEAT ; ; DONE, RESTRITE HD SECTOR FROM BUFFER FUNCTION ; ENTRY- IY= CDB PTR ; CDB= SET UP ; EXIT - NZ= ERROR, A= CODE ; ;++++++++++++++++++++ ERROR, A= CODE ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ HDRDBUF: ; ; IF BUFFER DATTED THEN EXIT WITH ERROR ; BIT SCD,A JR NZ,HDWBGER ; ; ELSE WASTE DATA ; LD A,0E5H OUT (C),A INC HL ;FORCE OVER; BIT SCD,A JR NZ,HDRBGER ; ; ELSE WASTE DATA ; IN A,(C) INC HL ;BUMP PTR TO FORCE OVERFLOW ERROR JP HDRBWST ; ORE REGS & RETURN ; POP BC POP HL ; ; DONE ; RET ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ HDWRBUF: ; ; SET UP RETRY COUNT ; LD A,4 ;ASSUME 12 RETRYS (THIA VALID THEN RETURN ; CALL QBUFR RET Z ; ; SET UP RETRY COUNT ; LD A,4 ;ASSUME 12 RETRYS (THIS # X 3 IN CONTROLLER)FLOW ERROR JP HDWBWST ; ; ; NORMAL FINISH ; HDWBGET: CALL GETRES RET Z ; ; ERROR, IF TIMEOUT THEN RESET CONTROL ; ; NORMAL FINISH ; HDRBGET: CALL GETRES CALL Z,MAKSAME RET Z ; ; ERROR, IF TIMEOUT THEN RESET CONTROLLER & RETR++++++++++++++ ; ; SELECT DRIVE FUNCTION ; EXIT - NZ= ERROR, A= CODE ; BC,HL= ? ; IY= NULCDB ; ;+++++++++++++++++++++++ LD (RETRYS),A ; LD (IY + RTY),0 ;TURN ON CONTROLLER RETRYS ; ; IF RETRYS DISABLED THEN RETRY COUNT = 0 ; LD A,(PBFLER & RETRY ; HDWBERR: CP A,TMOERR JP NZ,HDWBCKR ; CALL CLRCONT PUSH IY CALL RECALC POP IY ; ; CHECK RETRY COY ; HDRBERR: CP A,TMOERR JP NZ,HDRBCKR ; CALL CLRCONT PUSH IY CALL RECALC POP IY ; ; CHECK RETRY COUNT ; HD++++++++++++++++++++++++++++++++++++++++++++++++++++ HDSELCT: ; ; IF SAME DRIVE AS LAST OPERATION THEN JUST RETURN NO ERRORNT = 0 ; LD A,(PBFLG) BIT PBRTRY,A JP Z,HDWBRTY ; XOR A,A ;COUNT = 0 LD (RETRYS),A ; LD (IY + RTY),80H ;DISABLELG) BIT PBRTRY,A JP Z,HDRBRTY ; XOR A,A ;COUNT = 0 LD (RETRYS),A ; LD (IY + RTY),80H ;DISABLE CONTROLLER RETRYS ; CD,A JR NZ,HDRBGET ; ; XFER DATA ; INI ; ; IF BUFFER NOT FULL THEN REPEAT FOR NEXT BYTE ; JP NZ,HDRBLP ; ; ES # X 3 IN CONTROLLER) LD (RETRYS),A ; LD (IY + RTY),0 ;TURN ON CONTROLLER RETRYS ; ; IF RETRYS DISABLED THEN RETRY COU:0 ( ) *!+",#-$.%/ 0 '&UNT ; HDWBCKR: PUSH AF LD A,(RETRYS) SUB A,1 LD (RETRYS),A JR C,HDWBRE ; ; RETRY ; POP AF JP HDWBRTY ; ; THEN DO LONG WAY ; XOR A,D ;IF 32K CROSS THEN DO LONG WAY JP M,DOLONGF ; ; NO BOUNDARY CROSSING. USE BLOCK MOVE INSTRU - AF= NZ ; ;*************************************************************************** CLRBUFR: ; ; JUST SET DRIVE TO NLD DE,(PBDMA) ;GET DESTINATION PTR LD A,(PBDMAX) ;SET BANK REGISTER LD BC,128 ;MOVE 128 BYTES ; ; FALL INTO MOVE ROUTINS (SRC) ; ;*************************************************************************** MOVFHST: ; ; SET UP EXTENDED ADDRE ; HARD ERROR ; HDWBRE: POP AF RET ; ; ; POSSIBLE OVERFLOW ERROR ; HDWBGER: ; ; IF NO OVERFLOW THEN USE NORMACTION ; INC BC ;RESTORE COUNT SET 7,D ;INSURE S100 MAP EX DE,HL ; SWAP LDIR EX DE,HL ; SWAP BACK ; ; MOVE DON-EXISTENT # SO FAILS COMPARE ; LD A,-2 LD (BUFDRV),A OR A,A RET ;***********************************************E ; ;*************************************************************************** ; ; BLOCK MOVE TO HOST SUBR ; ENTRY- HSS REGISTER ; LD (MOVX),A ;SAVE EXTENDED ADDRESS FOR BUMPING OUT (HXADDR),A ; ; FALL INTO MOVER ; ;**************L RETURN ; LD DE,-[HDSECB + HDBUFSZ] ;TEST PTR FOR 1 PAST BUFFER END ADC HL,DE JP Z,HDWBGET ; ; ELSE PROCESS AS ERRORONE ; RET ; ; ; LONG TRANSFER TESTS EACH BYTE FOR THRESHOLDS ; DOLONGF: INC BC ;RESTORE COUNT LD A,D ;SET UP CUR**************************** ; ; MAKE BUFFER PTRS = PB PTRS ; EXIT - AF= UNCHANGED ; HL= ? ; ;***************************L= LOCAL PTR (SRC) ; DE= HOST PTR (DST) ; BC= BYTE COUNT ; A= BANK ADDRESS (DST) ; ;************************************************************************************************* ; ; MOVE SUBR CHECKS FOR A MOVE CROSSING ANY 32K BOUNDARY AND SE ; CALL GETRES JR NZ,HDWBERR ; ; IF NO CONTROLLER ERROR THEN RETURN SYNC ERROR ; LD A,2 ;SUB-ERROR 2, WRITE OVERFLORENT BIT 15 LD I,A ;SAVE IN I SINCE NOT USING MODE 2 INTERRUPTS ; ; INSURE S100 ACCESS FOR SOURCE ; NO64KXF: SET 7,D ************************************************ MAKSAME: LD A,(PBDRV) ;BUFFER_DRIVE = CURRENT_DRIVE LD (BUFDRV),A ; LD *************************************** MOV2HST: ; ; SET UP EXTENDED ADDRESS REGISTER ; LD (MOVX),A ;SAVE EXTENDED ADDRELECTING ; A FAST BLOCK MOVE IF NOT, AND A SLOWER BLOCK MOVE WHICH CHECKS AFTER EACH ; BYTE FOR AN OVERFLOW CONDITION IF TRUE. W LD C,-1 ;NO STATUS CALL SYNERR JR HDWBERR ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; MOVE 1 BYTE ; MOV4F: EX DE,HL ; SWAP PTRS LDI ;SINGLE BYTE MOVE EX DE,HL ;SWAP BACK ; ; IF COUNT EXHAUHL,(PBTRK) ;BUFFER_TRACK = CURRENT_TRACK LD (BUFTRK),HL ; LD HL,(PBSEC) ;BUFFER_SECTOR = CURRENT_SECTOR & FEH RES 0,L LSS VALUE FOR BUMPING LD (HXADDR),A ; ; FALL INTO MOVE PRIMITIVE ; ;*************************************************++++ ; ; QUERY BUFFER THE SAME FUNCTION ; EXIT - ZF= SAME ; NZ= NOT SAME ; ;+++++++++++++++++++++++++++++++++++++++++++++STED THEN DONE ; RET PO ; ; IF NO ROLLOVER THEN REPEAT ; BIT 7,D JP NZ,MOV4F ; ; S100 PTR ROLLED OVER 32K BOUNDAD (BUFSEC),HL ; ; DONE ; RET ;*************************************************************************** ; ; READ************************** ; ; MOVE SUBR CHECKS FOR A MOVE CROSSING ANY 32K BOUNDARY AND SELECTING ; A FAST BLOCK MOVE IF NOT ; BC= 0 ; HL= HL + BC ; DE= DE + BC ; ;*************************************************************************** ; ;++++++++++++++++++++++++++++++ QBUFR: ; ; IF DRIVE NOT SAME THEN RETURN NZ ; LD A,(PBDRV) LD HL,BUFDRV CP A,(HL) RRY, TOGGLE BIT 15 ; LD A,I XOR A,80H LD I,A OUT (HXAD15),A ; ; IF BIT 15 TOGGLED TO 0 THEN 64K ROLLOVER, NEXT BANK  DATA FROM HOST IOPB SUBR ; ENTRY- HL= DESTINATION PTR ; ;*******************************************************************, AND A SLOWER BLOCK MOVE WHICH CHECKS AFTER EACH ; BYTE FOR AN OVERFLOW CONDITION IF TRUE. ; ENTRY- HL= LOCAL MEMORY (SOURCE) SET BIT 15 REGISTER TO S100 PTR BIT 15 ; LD A,D ;SET BIT 15 OUT (HXAD15),A ; ; IF > 32K MOVE THEN DO LONG WAY ; ET NZ ; ; IF SECTOR NOT SAME THEN RETURN NZ ; LD DE,(PBSEC) ;NOW CHECK SECTOR RES 0,E ;CLEAR BLOCKING BIT ; LD HL,( ; BIT 7,A JP NZ,NO64KXF ; LD A,(MOVX) INC A LD (MOVX),A OUT (HXADDR),A ; ; XFER ANOTHER BYTE ; JP NO64KXF ******** HDHSTR: ; ; SET UP FOR XFER ; LD DE,(PBDMA) ;GET DESTINATION PTR LD A,(PBDMAX) ;SET BANK REGISTER LD BC,128 PTR ; DE= S100 MEMORY (DESTINATION) PTR ; BC= BYTE COUNT TO TRANSFER ; ; EXIT - AF= ? ; BC= 0 ; HL= HL + BC ; DE= DDEC BC LD A,B CP A,32768 / 256 JR NC,DOLONGF ; ; IF GOING TO CROSS 64K BOUNDARY THEN DO LONG WAY ; LD A,E ;ADD COUBUFSEC) SBC HL,DE RET NZ ; ; IF TRACK NOT SAME THEN RETURN NZ ; LD DE,(PBTRK) ;LAST, CHECK TRACK LD HL,(BUFTRK) S ;MOVE 128 BYTES ; ; FALL INTO MOVE ROUTINE ; ;**********************************************************************E + BC ; ;*************************************************************************** ; ; SET BIT 15 REGISTER TO PTR BIT 1NT TO PTR ADD A,C LD A,D ADC A,B JR C,DOLONGF ;IF OVERFLOW THEN WILL WRAP-AROUND ; ; IF GOING TO CROSS 32K BOUNDARY BC HL,DE RET ;*************************************************************************** ; ; CLEAR BUFFER SUBR ; EXIT= SOURCE PTR ; ;*************************************************************************** HDHSTW: ; ; SET UP DATA ; ***** ; ; BLOCK MOVE FROM HOST SUBR ; ENTRY- HL= LOCAL PTR (DST) ; DE= HOST PTR (SRC) ; BC= BYTE COUNT ; A= BANK ADDRES ; ENTRY- HL= LOCAL MEMORY (DESTINATION) PTR ; DE= S100 MEMORY (SOURCE) PTR ; BC= BYTE COUNT TO TRANSFER ; ; EXIT - AF= ?  ;*************************************************************************** ; ; WRITE DATA TO HOST IOPB SUBR ; ENTRY- HL;0 ( ) *!+",#-$.%/ 0 '&5 ; LD A,D ;SET BIT 15 OUT (HXAD15),A ; ; IF > 32K MOVE THEN DO LONG WAY ; DEC BC LD A,B CP A,32768 / 256 JR  ; IN A,(SASIDATA) LD (RSTAT),A ; ; ENTER MESSAGE PHASE ; CALL WAITRQ RET C ; ; IF NOT MESSAGE PHASE THEN RETUR+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ RECALC: ; ; SEND RECAL COMMAND TO SASI CONTROLLERZ,GETR3A ; ; XFER BYTE INTO BIT BUCKET ; IN A,(SASIDATA) JP GETR2A ; ; ; STATUS OVERFLOW, TELL SO ; GETR3A: LD A ; AND A,[1 SHL SCD] OR [1 SHL SIO] ;C/D & /I/O CP A,[1 SHL SCD] OR [1 SHL SIO] ;SIO IS INVERTED! JR NZ,SNDCDN ; ; ELSNC,DOLONG ; ; IF GOING TO CROSS 64K BOUNDARY THEN DO LONG WAY ; LD A,E ADD A,C LD A,D ADC A,B JR C,DOLONG ; ; N SYNC ERROR ; LD B,C LD C,A AND A,[1 SHL SCD] OR [1 SHL SIO] OR [1 SHL SMSG] ;C/D & I/O & MSG CP A,[1 SHL SCD] OR [1 S ; LD IY,NULCDB LD (IY+CMD),SCREC ;RECAL COMMAND ; LD A,(LUNSV) ;STILL HAS SELECTED LUN LD (IY + LUN),A ; CALL SND,?FDCERR LD (PBSTAT),A LD A,-2 LD (PBSTAT + 1),A ; ; DATA PHASE DONE, ENTER STATUS PHASE ; GETR3: CALL WAITRQ RET E CONTINUE OUTPUTING BYTES UNTIL CONTROLLER SATISFIED ; OUTI JP SNDCDB3 ; ; ; BUSY STILL FALSE, CHECK ALARM ; SNDC2: IF GOING TO CROSS 32K BOUNDARY THEN DO LONG WAY ; XOR A,D JP M,DOLONG ; ; NO BOUNDARY CROSSING. USE BLOCK MOVE INSTRUCHL SMSG] ;SIO IS INVERTED! LD A,4 ;SUB-ERROR 4, MESSAGE PHASE EXPECTED JP NZ,SYNERR ; ; ACKNOWLEDGE MESSAGE PHASE BY SCDB RET NZ ; ; RETURN COMMAND RESULTS STATUS ; JP GETRES ;FINISH UP ;++++++++++++++++++++++++++++++++++++++++++++C ; ; IF NOT STATUS PHASE THEN SYNC ERROR ; LD C,A ;SAVE STATUS FOR LATER AND A,[1 SHL SCD] OR [1 SHL SIO] CP A,[1 S DEC DE LD A,E OR A,D JR NZ,SNDCBW ; ; ALARM WENT OFF! RETURN TIMEOUT ERR ; LD A,1 ;TELL USER WHERE OCCURRED ; STION ; INC BC ;RESTORE COUNT SET 7,D ;INSURE S100 MAP ; LDIR ; ; MOVE DONE. RETURN ; RET ; ; ; LONG TRANSFERENDING ACK ; IN A,(SASIDATA) ; ; CHECK FOR HARDWARE PARITY ERROR DURING WHOLE OPERATION ; BIT SPERR,B ;B STILL HAS ST+++++++++++++++++++++++++++++++ ; ; TRANSMIT CDB FUNCTION ; ENTRY- IY= CDB TO XMIT ; EXIT - NZ= ERROR, A= CODE ; DE= ? ; HL SCD] LD A,5 ;SUB-ERROR 5, EXPECTED STATUS PHASE CALL NZ,SYNERR ; ; FETCH STATUS BYTE TO COMPLETE STATUS PHASE ; INDCTO: LD (PBSTAT + 1),A LD A,TMOERR OR A,A RET ; ; ; DONE WITH COMMAND PHASE, RETURN NO ERRORS ; SNDCDN: XOR A,A  TESTS EACH BYTE FOR THRESHOLDS ; DOLONG: INC BC ;RESTORE COUNT LD A,D ;SET UP CURRENT BIT 15 LD I,A ;SAVE IN I SINCE NATUS RESULT STATUS JR NZ,HDPERR ; ; ALL PHASES DONE, IF NO ERROR THEN RETURN NO ERROR ; LD A,(RSTAT) AND A,00000011B  ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SNDCDB: ; ; CONTROLLER SELECT PHASE ; LD AN A,(SASIDATA) LD (RSTAT),A ; ; ENTER MESSAGE PHASE ; CALL WAITRQ RET C ; ; IF NOT MESSAGE PHASE THEN RETURN SYNCOT USING MODE 2 INTERRUPTS ; NO64KX: SET 7,D ;INSURE S100 ; ; XFER 1 BYTE ; MOV4: LDI ; ; IF COUNT EXHAUSTED THEN R RET Z ; ; ELSE IF CONTROLLER PARITY ERROR THEN RETURN THE ERROR ; BIT 1,A JR Z,GRESPE ; ; ERROR ENCOUNTERED. REQU,[1 SHL HDCONT] ;ASSERT TARGET ADDRESS BIT OUT (SASIDATA),A ; LD A,[1 SHL SSELECT] OR [1 SHL SERRCLR] ;ASSERT SEL OUT (SA ERROR ; LD B,C LD C,A AND A,[1 SHL SCD] OR [1 SHL SIO] OR [1 SHL SMSG] CP A,[1 SHL SCD] OR [1 SHL SMSG] LD A,6 ;SUBEXIT - NZ= ERROR, A & (PBSTAT)= CODE ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ GETRES: ETURN ; RET PO ; ; IF NO ROLLOVER THEN REPEAT ; BIT 7,D JP NZ,MOV4 ; ; S100 PTR ROLLED OVER 32K BOUNDARY, TOGGLEEST SENSE ; LD (IY+CMD),SCSNSE CALL SNDCDB RET NZ ; ; ENTER DATA PHASE & GET STATUS BYTES ; LD HL,PBSTAT LD BC,[SICMD),A ; ; WAIT FOR BUSY ACKNOWLEDGE OF SELECT ; LD DE,0 ;SET ALARM ; SNDCBW: IN A,(SASIST) BIT SBUSY,A JR Z,SND-ERROR 6, EXPECTED MESSAGE PHASE CALL NZ,SYNERR ; ; ACKNOWLEDGE MESSAGE PHASE BY SENDING ACK ; IN A,(SASIDATA) ; ; ; ; START STATUS PHASE ; CALL WAITRQ ;WAIT FOR CONTROLLER RET C ;IF TIMEOUT THEN RETURN ERROR ; ; IF NOT STATUS PH BIT 15 ; LD A,I XOR A,80H LD I,A OUT (HXAD15),A ; ; IF BIT 15 TOGGLED TO 0 THEN NEXT BANK ; BIT 7,A JP NZ,NO66 SHL 8] + SASIDATA ;MAX BYTES + PORT ; GETR2: CALL WAITRQ RET C ;IF TIMEOUT THEN RETURN ERROR ; ; IF NOT DATA PHASE THC2 ; ; SELECT ACKNOWLEDGED, FINISH SELECT PHASE ; LD A,1 SHL SERRCLR ;DEASSERT SEL OUT (SASICMD),A ; ; SELECT PHASCHECK FOR HARDWARE PARITY ERROR DURING WHOLE OPERATION ; BIT SPERR,B JR NZ,HDPERR ; ; ALL PHASES DONE, IF NO ERROR THENASE THEN SYNC ERROR ; LD C,A ;SAVE STATUS FOR LATER AND A,[1 SHL SCD] OR [1 SHL SIO] ;C/D & I/O CP A,[1 SHL SCD] ;SIO 4KX ; LD A,(MOVX) INC A LD (MOVX),A OUT (HXADDR),A ; ; NEXT BYTE ; JP NO64KX ;+++++++++++++++++++++++++++++E DONE, ENTER COMMAND PHASE ; LD C,SASIDATA ;SET PORT # ; PUSH IY ;PUT PTR TO CDB IN HL POP HL ; ; WAIT FOR COMMAND RETURN CONTROLLER ERROR ; LD A,(RSTAT) AND A,00000011B JR NZ,GETR4 ; ; ELSE RETURN CONTROLLER'S ERROR CODE ; LD AIS INVERTED! ; LD A,3 ;SUB-ERROR 3, STATUS PHASE EXPECTED JP NZ,SYNERR ; ; FETCH STATUS BYTE TO COMPLETE STATUS PHASE ++++++++++++++++++++++++++++++++++++++++++++++ ; ; RECALIBRATE FUNCTION ; EXIT - NZ= ERROR (A= CODE #) ; IY= NULCDB ; ;++R2 ; ; STATUS OVERFLOW! KEEP GOING ; GETR2A: CALL WAITRQ RET C ; ; IF NOT DATA PHASE THEN STOP ; BIT SCD,A JR N REQUEST ; SNDCDB3: CALL WAITRQ ;WAIT FOR REQUEST RET C ;RETURN ERROR IF TIMEOUT ; ; IF NOT COMMAND PHASE THEN DONE  RET ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; GET CONTROLLER RESULTS FUNCTION ; EN DONE ; BIT SCD,A JR NZ,GETR3 ; ; GET STATUS BYTE ; INI ; ; IF IOPB STATUS NOT FULL THEN REPEAT ; JP NZ,GET<0 ( ) *!+",#-$.%/ 0 '&,(PBSTAT) OR A,A RET ; ; ; IF CONTROLLER PARITY ERROR THEN RETURN THE ERROR ; GETR4: BIT 1,A JR Z,HDPERR ; ; ELORG LOCRAM ;########################################################################### ; ; VARIABLES ; ;################VE # ; LD A,(CURDRV) ;FETCH DRIVE # ; RRCA ;PUT IN PROPER FIELD RRCA RRCA ; ; SAVE LUN # FOR LATER USE ; LD (S 5..7 LA2 EQU LUN ;LOGICAL ADDRESS 2 IN BITS 0..4 LA1 EQU 2 ;LOGICAL ADDRESS 1 LA0 EQU 3 ;LOGICAL ADDRESS 0 NBK EQU 4 ;XFER++++++++++++++ WAITRQ: ; ; INSURE NC RETURNED IF ALL TESTS PASS ; OR A,A ; ; FIRST INSURE ACK IS FALSE (PREVIOUS BYTSE HARD ERROR ; LD A,-1 ;CONTROLLER ERROR MUST HAVE BYTE 2 SET LD (PBSTAT + 1),A ; LD A,?FDCERR OR A,A RET ; ; ;########################################################### ; ; IOPB PTRS ; IOPBL DS 1 ;LOW ADDRESS OF IOPB TO EXECUTE IOLUNSV), A LD (IY + LUN), A ; RET ;*************************************************************************** ; ; GE COMMANDS BLOCK (SECTOR) COUNT ILV EQU NBK ;FORMAT COMMAND INTERLEAVE FACTOR RTY EQU 5 ;RETRY FLAG 0: RETRY 3 TIMES, 80H: NO RE HAS BEEN READ) ; LD DE,0 ;SET ALARM ; WTRQ3: IN A,(SASIST) BIT SACK,A JR NZ,WTRQ2 ; ; ACK FALSE, WAIT FOR REQUES DATA XFER PARITY ERROR ; HDPERR: XOR A,A ;CLEAR ERROR OUT (SASICMD),A LD A,1 SHL SERRCLR OUT (SASICMD),A ; ; RETPBH DS 1 ;HIGH ADDRESS OF IOPB IOPBXA DS 1 ;BANK ADDRESS OF IOPB ; ; STATUS PHASE RESULT BYTE ; RSTAT DS 1 ;COMMAND STATUT LOGICAL ADDR FROM IOPB SUBR ; ENTRY- IY= CDB PTR ; EXIT - A= 0: OK, /0: ERROR CODE ; DE= ? ; ;**************************ETRYS ;########################################################################### ; ; I/O PARAMETER BLOCK SAVE AREA ; T ; LD DE,0 ;SET ALARM ; ; IF REQUEST == TRUE (0) THEN RETURN ; WTRQ1: IN A,(SASIST) BIT SREQ,A RET Z ; ; CHECURN THE ERROR ; GRESPE: LD A,?PARERR ;RETURN PARITY ERROR OR A,A RET ;+++++++++++++++++++++++++++++++++++++++++++++++S RETURNED ;BIT 1: ERROR (ISSUE SENSE COMMAND) ;BIT 5..7: LUN ; ; SECTOR BUFFER DEBLOCKING PTRS ; BUFDRV DS 1 ;BUF************************************************* GETLAD: ; ; IF SECTOR DATA OUT OF RANGE THEN RETURN ERROR ; LD DE,(PBS ;########################################################################### PBCMD DS 1 ;COMMAND BYTE PBDRV DS 1 ;DRIVE BYTK ALARM ; DEC DE LD A,E OR A,D JP NZ,WTRQ1 ; ; ALARM WENT OFF! RETURN REQUEST TIMEOUT ERROR ; LD A,3 ; WTRQ9: ++++++++++++++++++++++++++++ ; ; SASI CONTROLLER SYNC ERROR FUNCTION ; ENTRY- A= SUB-ERROR TO GO INTO PBSTAT + 1 ; C= SASI FER CONTENTS DRIVE BYTE BUFSEC DS 2 ;BUFFER CONTENTS SECTOR WORD BUFTRK DS 2 ;BUFFER CONTENTS TRACK WORD ; ; DISCRETE VARIAEC) ;{0..255} LD A,D OR A,A JR NZ,GETLADE ; ; IF TRACK DATA OUT OF RANGE THEN RETRUN ERROR ; LD A,(PBTRK + 1) ;{0..E PBTRK DS 2 ;TRACK # PBSEC DS 2 ;SECTOR #, FORMAT INTERLEAVE, FLOPPY PARAMS PBFLG DS 1 ;INPUT FLAG BYTE (LOG-ON, BLOCKINGBUS STATUS WORD CAUSING ERROR TO GO INTO PBSTAT + 2 ; EXIT - AF= SYNCER, NZ ; ;++++++++++++++++++++++++++++++++++++++++++++++BLES ; LUNSV DS 1 ;LUN # {0..3} RETRYS DS 1 ;RETRY COUNT MOVX DS 1 ;HOST BANK ADDRESS SAVE FOR BLOCK MOVE SUBRS FDADDR DS 2255} OR A,A JR NZ,GETLADE ; ; COMPUTE LOGICAL ADDRESS FROM SECTOR, TRACK ; LD A,(PBTRK) ;PICK UP TRACK LSB & PUT INTO FLAGS) ; SELECT DISK - 0: NOT SELECTED BEFORE ; BLOCKING - 0: NORMAL WRITE (READ-WRITE) ; 1: DIRECTORY WRITP NZ,WTRQ3 ; ; ALARM WENT OFF, RETURN ACK TIMEOUT ERROR ; LD A,2 JR WTRQ9 SUBTTL CONSTANTS ;####################+++++++++++++++++++++++++++++ SYNERR: ; ; STORE SUB-ERROR FOR HOST ; LD (PBSTAT + 1),A ; ; STORE STATUS FOR HOST ;  ;FDC ADDRESS PTR TIMOUT DS 2 ;UNSELECT SASI DELAY CURDRV DS 1 ;CURRENT PHYSICAL DRIVE {0..3} ;########################## LA0 BIT 7 SRL A ; SECTOR BIT 0 IS WASTED RR E LD (IY + LA0),E ;PHEW! LA0 DONE ; LD (IY + LA1),A ;LA1 HAPPENS TO BE IE (READ-WRITE) ; 2: UNALLOCATED WRITE (NO READ) PBLOG EQU 0 ;LOGON REQUEST BIT PBRTRY5 EQU 6 ;RETRY 5 TIMES BIT (A####################################################### ; ; ID SECTOR TEXT ; ;############################################ LD A,C LD (PBSTAT + 2),A ; ; RETURN ERROR ; LD A,?SYNCER OR A,A RET ;+++++++++++++++++++++++++++++++++++++++################################################# ; ; SASI CONTROLLER COMMAND DESCRIPTOR BLOCKS (CDB) ; ;###################N A ; ; RETURN NO ERRORS ; XOR A,A RET ; ; ; DATA OUT OF RANGE ; GETLADE: LD A,?ADDRERR OR A,A RET ;+LONG WITH BIT 7 SET) PBRTRY EQU 7 ;DISABLE RETRYS BIT PBDMA DS 2 ;TRANSFER ADDRESS PBDMAX DS 1 ;TRANSFER BANK ADDRESS P############################### IDTXT DB 'Disk Descriptor ' IDSZE EQU $ - IDTXT ; JIDTXT DB 'Jade DD ' JIDSZE EQU $ - JIDTX++++++++++++++++++++++++++++++++++++ ; ; GET LUN FROM USER FUNCTION ; ENTRY- IY= CDB PTR ; (CURDRV)= FORMATTED DRIVE # {0..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; WAIT FOR REQUEST FROM CONTROLLER FUNCTION ; EBSTAT DS 4 ;SENSE STATUS BYTES (IF ERROR) DS 2 ;SPARES IOPBSIZE EQU $ - PBCMD ;#######################################T IF $ >= (LOCROM + ROMSIZE) CONMSG **** ERROR! CODE TOO LARGE FOR DECLARED PROM SIZE! **** ENDIF SUBTTL RAM AREA 3} ; EXIT - AF= ? ; ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ GETLUN: ; ; COMPUTE DRIDS 6 ;ID SECTOR READ CDB CDBINIT EQU $ - NULCDB ; ; CDB OFFSETS ; CMD EQU 0 ;COMMAND LUN EQU 1 ;LOGICAL UNIT NUMBER IN BITXIT - CF= TIMEOUT: NZ, A= TMOERR ; NC= A: STATUS ; DE= ? ; ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++LD (PBSTAT + 1),A ; LD A,TMOERR OR A,A SCF RET ; ; ; ACK FALSE ALARM CHECK ; WTRQ2: DEC DE LD A,E OR A,D J######################################################## ; NULCDB: DS 6 ;NO TRANSFER CDB LAXCDB: DS 6 ;MAIN XFER CDB IDRCDB =0 ( ) *!+",#-$.%/ 0 '&#################################### ; ; HARD DISK SECTOR BUFFER ; ;########################################################################### HDBUFSZ EQU 256 HDSECB DS HDBUFSZ ; ;########################################################################### ; ; JADE SECTOR BUFFER ; ;########################################################################### JADSECB DS 256 ;########################################################################### ; ; STACK AREA ; ;########################################################################### IF $ > (LOCRAM + RAMSIZE - 32) CONMSG **** ERROR! DATA TOO LARGE FOR DECLARED RAM SIZE! **** ENDIF DS 32 STACK EQU LOCRAM + RAMSIZE END >0 ( ) *!+",#-$.%/ 0 '&?0 ( ) *!+",#-$.%/ 0 '&@0 ( ) *!+",#-$.%/ 0 '&A0 ( ) *!+",#-$.%/ 0 '&B0 ( ) *!+",#-$.%/ 0 '&C0 ( ) *!+",#-$.%/ 0 '&D0 ( ) *!+",#-$.%/ 0 '&E0 ( ) *!+",#-$.%/ 0 '&F0 ( ) *!+",#-$.%/ 0 '&G0 ( ) *!+",#-$.%/ 0 '&H0 ( ) *!+",#-$.%/ 0 '&I0 ( ) *!+",#-$.%/ 0 '&J0 ( ) *!+",#-$.%/ 0 '&K0 ( ) *!+",#-$.%/ 0 '&L0 ( ) *!+",#-$.%/ 0 '&