; NOVAXIS Turbo-R SCSI BIOS version 1.0 ; (C) 1994 KMcs ; Written by Jurgen Kramer - 05/05/94 - ; - 06/05/94 - ; - 15/05/94 - ; - 20/05/94 - ; - 23/05/94 - ; - 26/05/94 - V1.02 ; - 27/05/94 - Adding new CALL command SETHOSTID (variable) ; - 01/06/94 - ; - 04/06/94 - Extended NOVAXIS JUMP table ; - 13/06/94 - ; - 15/06/94 - ; - 16/06/94 - NOVAXIS Turbo-R/MSX version 0.01 ; - 17/06/94 - Added part between *M* 2* ; - 20/06/94 - NOVAXIS Turbo-R/MSX version 0.02 ; Target ID is software setable (0 - 3) stored in clockchip ; - 23/06/94 - version 0.03 - Added GetHOST_ID, fixed bug for HOST ID ; - 28/06/94 - Setup/Diag updated ; - 06/07/94 - ; - 25/07/94 - v0.05 ; - 02/08/94 - ; - 03/08/94 - ; - 04/08/94 - ; - 07/08/94 - v0.06 ; - 08/08/94 - v0.10 ; - 26/08/94 - V9990 call statements deleted ; - 27/08/94 - v0.20 Temporary test routines added ; - 28/08/94 - v0.21 GetInq routine modified because of errors in BASIC ; - 02/09/94 - v0.30 Temporary other TermAct and SetWD3393 ; - 04/09/94 - v0.31 Added Multiple HDD support switch ; - 07/09/94 - v0.32 SBIC error msg changed, Controller test and SCSI bus ; test switched ; - 11/09/94 - v0.40 CALL statement routine modified ; - 21/09/94 - v0.41 original TermAct & SetWD3393 restored ; - 25/09/94 - Bug removed in GetInq routine ; - 27/09/94 - v0.42 GetInq modified, revision added ; - 28/09/94 - v0.43 TermAct replaced ; - 07/10/94 - v0.44 _SETHOSTID modified ; - 08/10/94 - v0.45 Get_ID, SetHTID modified, HOST ID now only occupies 3 ; bits in the clockchip instead of 4 ; - 09/10/94 - v0.46 _INQUIRY added ; - 12/10/94 - ; - 16/10/94 - v0.47 Temporary test routines deleted ; - 19/10/94 - v0.48 GetSense added, bug removed in PrInitTxt ; - 28/10/94 - v0.49 GetUnitsOn routine modified ; - 30/10/94 - v0.50 Temporary stuff added for test purpose ; Changed name of routine SetWD33C93 in SetWD3393 ; - 03/11/94 - ; - 13/11/94 - TermAct modified because of a bug in the SCSI controller chip ; - v0.60 Beta Release 1, v0.50 test functions disabled ; - 22/11/94 - v0.61 Added RdDefect routine ; - 29/11/94 - Preparing for final version, deleted some temporary routines ; 'finished' Setup ; v1.00 !! version for export to Japan ; - 17/12/94 - v1.01 Removed ExtSetWD33C93 routine, added new comments to ; some routines, modified SetWD3393 routine ; - 23/12/94 - Testing new SCSI read routine ; - 28/12/94 - v1.02 DSKIO modified, now also recognizes 0f8h as media id. ; this is implemented for use with a IBM compatible PC which ; uses 0f0h as media id. But this media is also used for MSX ; SSDD diskettes! ; - 28/12/94 - v1.03 SCSI COPY command added for high end applications. ; - 02/01/95 - v1.04 Work Area expanded to store data of new driver functions ; - 03/01/95 - Started with NExtBIOS (NOVAXIS Extended BIOS) mechanism ; - 12/01/95 - continued with NExtBIOS ; - 13/01/95 - InsNExt routine extended ; - 15/01/95 - New toggle added for use of driver support, Setup menu ; modified. ; If Driver Support is disabled, the extra memory needed for the drivers will ; not be allocated ; - 16/01/95 - Complete new screen layout for Setup menu ; - 19/01/95 - 'help' texts added to Setup menu ; - 20/01/95 - New toggle added to Setup menu for Extended Partition ; The HOST ID now only occupies 2 bits instead of 3, modified SetHOST_ID and ; Get_ID ; - 21/01/95 - v1.05Beta, small beta release. DRV_SIZE set to 1024 ; Beta testers: J. Botman, G. de Boom, R. Muit ; - 22/01/95 - v1.06 Again _INQUIRY added ; - 23/01/95 - Work Area now initialy filled with 00h instead of 0ffh ; continued with _INQUIRY command, found a small 'bug' in FastExec, is you ; use a transfer address that is just one byte higher than the transfer address ; it will still use the sectorbuffer to store the temporary ML code to read/ ; write which means if you're using the sectorbuffer to store data/code it ; will be overwritten! ; Modified Get_Inq ; - 24/01/95 - Updated CALL INFO command, at system setup the Driver support ; toggle is copied to the Work Area byte 7, bit 2. Modified InsWork, InsNExt ; Fast RAM transfer toggle removed, ChkDrvS removed ; Finished Extended Partitions toggle in Setup menu ; - 25/01/95 - Finished GetDWA ; - 26/02/95 - Made some changes in Setup menu ; - 28/02/95 - v1.07 Timeout in RdHDDPart changed to 560ms for slow devices ; like CD-ROM ; After the hardware reset (out (36h),1) it takes a very long time for the ; CD-ROM (my CD-ROM) to recover, and is therefore not printed during setup ; - 01/02/95 - Removed one space from the string Stripe, Timeout in RdHDDPart ; reset to it's original value ; Continued developing driver functions (modified DSKIO) ; - 02/03/95 - ; - 18/03/95 - Removed some redunant code ; - 19/03/95 - v1.08 Enlarged Extended Partitions Work Area to 256 bytes, ; Removed initial hardware reset by software reset ; - 24/03/95 - GetInq routine modified ; PrInitTxt modified, ROM revision level added, if the revision level equals ; 00h, it will not be displayed. PrintPBCD added ; - 26/03/95 - Rev. 04 - Continued with modifieing RdHDDPart, so it will ; display CD-ROM devices during initial setup ; - 30/03/95 - CD-ROM is still not printed sometimes...temporarily fixed with ; software loops ; - 31/03/95 - v1.09.01 ; - 01/04/95 - ; - 03/04/95 - v1.09.02 - Temporary restored old routines to convert partition ; sector ; - v1.09.03 - MedRemoval added, SCSI PREVENT ALLOW MEDIUM REMOVAL ; - v1.09.04 - Modified Write ID checking, so it's easy to update to the new ; Read/Write byte from the Extended Partitions ; - 05/04/95 - Extended partition Write checking is working ; - 06/04/95 - Changed date presentation in initial screen, now it displays ; the date as follows: March 6th, 1995. So there is not confusion about the ; date format. ; - 10/04/95 - v1.10.01 - Started with adding new MS-DOS compatible Extended ; partitions ; v1.11.01 - Organized the program a bit, RdSecDir renamed to RdLogBlk and ; WrSecDir renamed to WrLogBlk, _TEST removed ; v1.11.02 - Made InsPCTab, installs PC partitions, Network write ID is the ; same as Host ID ; v1.11.05 - Made InsMSXTab, installs MSX partitions, Network write ID is ; same as Write ID on partition sector ; v1.11.06 - Made InsNOVTab, installs Extended partitions, Network Write ID ; is set according to write ID on partition sector ; v1.11.07 - Changed GetInq routine, now the Inquiry for all SCSI device ; types is printed, not only device type 0, device type other then 0 will not ; be installed ; v1.11.08 - Modified InsMSXTab, InsPCTab and InsNOVTab to check for the ; right partition type, so 16-bit FAT part. will not be installed ; v1.11.16 - Now all devices are printed, even if there is no log. drive left ; to install. ; v1.11.17 - 26/04/95, Modified InsNOVTab to check if the Extended Partitions ; are enabled ; v1.11.22 - Removed a bug from Rd_Cnv_Prt, when Extended partitions are used ; and the was no 'Drv' found 01f3h in the part. table, IX was not proparly ; loaded ; v1.11.27 - 28/04/95, Added RdPartSecs routine to RdHDDPart, reads partition ; sectors, and when needed retries when a error occurs ; v1.12.01 - 07/05/95, NExtBIOS modified, now it does not destroy IX when ; calling EXTBIO, NExtBIOS version 0.11 ; v1.13.01 - 14/05/95, Preparing for 'final' version, Driver routine develop- ; ment temporary discontinued because of a dead-line, calls to DrvRdBlk and ; DrvWrBlk removed from DSKIO routine ; ** IMPORTANT ** further development of the ROM should be done with ; version 1.12.01, this version cannot be used because the NExtBIOS routines ; are removed ** ; InsNExt, ChkDrv, DrvRdBlk, DrvRdBlk, SuppDrv and GetDWA removed, CalcWA_1 ; and CalcWA_3 modified ; Driver support toggle removed from Setup ; v1.13.02 - Added a security string to some routines so a NOVAXIS ROM can ; always be recognized (I hope) ; v1.13.03 - 16/05/95 - ; v1.13.04 - 17/05/95 - ; v1.49.01 - 19/05/95 - Final Beta version ; v1.49.02 - 20/05/95 - Bug removed from InsNOVTab ; v1.49.07 - 21/05/95 - Spell error removed from DevTxt ; v1.49.20 - 29/05/95 - Add two CALL commands, 'TARGETID' and 'SETTARGETID' ; v1.49.21 - 30/05/95 - I/O base address message removed ; ** FINAL VERSION 1.50 ** ; I/O port 1ch ; v1.50 - 30/05/95 - ; v1.50 - 05/06/95 - Added small delay after printing all connected devices, ; Init text changed: 'MSX' extended to 'MSX2' ; *T*vX.XX marks the beginning of a temporary part of code, where X is the ; version number of NOVAXIS ; *T* marks the end ; *N*vX.XX marks the start of a newly added part ; *N* end mark .comment * NOVAXIS Turbo-R/MSX version 1.06 highlights: - Pressing GRAPH key will prevent SCSI BIOS to be installed - Pressing CTRL key will - First HDD can have ID 0-3 - Multiple HDD support (max 7) - data transfer approx. 248Kb/s (IBM, tested on Turbo-R) - approx. 100Kb/s on a MSX2/2+ - new calls commands: - HOSTID - get Host ID in variable - SETHOSTID - set Host ID _ INQUIRY - get INQUIRY of specified Target New JUMP entries for SCSI DIAGNOSTIC Address: 07FB6h - Reserved 07FB9h - Reserved 07FBCh - Copy - SCSI COPY 07FBFh - RdDefect - Read Defect Data 07FC2h - GETWRK, Get work area in [IX] 07FC5h - PartInfo, Get work area of current drive [IX] 07FC8h - GetUnitsOn - Get # of units online 07FCBh - SetHOST_ID - Set HOST ID (4-7) 07FCEh - SetTargetID (0 - 3) 07FD1h - GetTargetID (0 - 3) 07FD4h - GetHOST_ID - Get HOST ID (4-7) 07FD7h - GetSense - Get Sense info 07FDAh - MedRemove - Prevent Allow Medium Removal Clockchip block 2 nibble 12, bits 1 - 0 are used for storage of HOST ID " " 2 nibble 3 bits 3 and 2 are used to set TARGET ID (0 - 3) " " 2 nibble 11 bit 2 is used to store Multiple HDD support " " 2 nibble 11 bit 3 is used to store Driver Support " " 2 nibble 12 bit 2 is used to store Extended Partitions " " 2 nibble 12, bit 3 is AVAILABLE NOVAXIS clock-chip memory layout: Block 2 nibble | B3 | B2 | B1 | B0 | +------------------------------------+ 0 | MSX | +------------------------------------+ 1 | MSX | +------------------------------------+ 2 | MSX | +------------------------------------+ 3 | Target ID | MSX | +------------------------------------+ 4 | MSX | +------------------------------------+ 5 | MSX | +------------------------------------+ 6 | MSX | +------------------------------------+ 7 | MSX | +------------------------------------+ 8 | MSX | +------------------------------------+ 9 | MSX | +------------------------------------+ 10 | MSX | +------------------------------------+ 11 | DrvSup | MulHDD | MSX | +------------------------------------+ 12 | AVAILA | ExtPrt | HOST ID | -------------------------------------- Nibbles filled with 'MSX' are used by MSX BIOS Nibble 12 normaly contains Native code * ; Assemble with M80 .Z80 ; calbas equ 0159h ; ; BASIC interpreter routines ; rom_error equ 406fh ; 'xxxx error' rom_chrgtr equ 4666h ; get next character from text rom_frmevl equ 4c64h ; evaluate an expression (general purpose) rom_docnvf equ 517ah ; type conversion rom_getin2 equ 520fh ; get an integer (-32768..32767) to DE rom_getbyt equ 521ch ; get a byte (0..255) to A and E rom_frmqnt equ 542fh ; get an integer (-32768..65535) to DE rom_ptrget equ 5ea4h ; get a pointer to variable to DE rom_strini equ 6627h ; make a room in string space rom_frestr equ 67d0h ; get a pointer to string ; ; Work area ; buf equ 0f55eh ; line input buffer (used as a temp) valtyp equ 0f663h ; value type dsctmp equ 0f698h ; string descriptor temp dac equ 0f7f6h ; decimal accumulator ; ; Macros ; synchk macro token call synchr defb token endm chrget macro call chrgtr endm POSIT EQU 0C6h CHGET EQU 09Fh CALSLT EQU 001CH ENASLT EQU 0024H BASVER EQU 002DH WRTVDP equ 0047h INITXT EQU 006CH SNSMAT EQU 0141H KILBUF equ 0156h EXTROM EQU 015FH LINL40 equ 0f3aeh CHGMOD equ 005fh ERAFNK equ 00cch fdscr EQU 0185H ; Restore screen with clockchip parameters NSTWRT equ 0171h RDPRIM equ 0f365h ; Read primairy slot CTRL EQU 0F33FH ; Byte to keep CTRL key (no use at all) RAMAD1 EQU 0F342H $SECBUF EQU 0F34DH MEMSIZ EQU 0F672H STKTOP EQU 0F674H AUTLIN EQU 0F6ABH ; Temporary storage SAVSTK EQU 0F6B1H FILTAB EQU 0F860H NULBUF EQU 0F862H CMASK EQU 0F92CH ; Used to store CPU mode EXBRSA EQU 0FAF8H BOTTOM EQU 0FC48H HIMEM EQU 0FC4AH EXPTBL EQU 0FCC1H SLTWRK EQU 0FD09H PROCNM EQU 0FD89H DEVICE EQU 0FD99H HOKVLD equ 0fb20h EXTBIO EQU 0FFCAH ; Extended BIOS call RG12SV equ 0ffebh RG13SV equ 0ffech DCOMPR equ 0020h ; RST 20H - compare HL and DE OUTDO equ 0018h ; RST 18H - print character ; CR equ 0dh ; Carriage Return LF equ 0ah ; Line Feed ESC equ 27 ; ESCAPE ; DRV_SIZE equ 1024 ; Size of Work Area for driver management DRVENTRY equ 32 ; Size of driver entry EXT_SIZE equ 256 ; Size of Work Area for Extended partitions NRM_SIZE equ 48 ; Size of normal Work Area ; PSecBuf equ 8400h ; Sectorbuffer address (1024 bytes) TmpPDat equ 8800h ; Temporary buffer for transforming part. LogDrv equ 83fah ; # of log. drives installed WrkSav equ 83fbh ; Work Area address save TrgID equ 83fdh ; Target ID NrParts equ 83feh ; Number of partitions found TabType equ 83ffh ; Partition type DrMAPDat equ 83f2h ; Drive MAP data DiffDrv equ 83f1h ; Used to calc. number of installed drives MaxRet equ 83f0h ; Max. # of retries in RdPartSecs maxdrv equ 6 ; Max. supported log. drives ; XYpos equ 81fdh ; Cursor position for printing device info TrgID2 equ 81ffh ; Target ID for GetInq TrgStt equ 81fch ; Target status for GetInq ; controller I/O port definition baseport equ 1ch ; Base I/O port AUXSTAT equ baseport+0 ; Auxiliary Status Read REGSET equ baseport+0 ; Register set RDWREG equ baseport+1 ; Read / Write data of selected register HARDWR equ baseport+2 ; Hardware Reset WD33C93A ; Version # VERSION equ 0150h ; BCD version #, 1.50 ; ROM revision level ROMREVISION equ 0h ; Revision 0 ; default SCSI HOST ID HOSTID equ 0b0h ; B0h = 7, B1h = 6, B2h = 5 etc. ; SCSI commands - Direct Access - group 0 FORMAT equ 04h ; Format Unit READ equ 08h ; Read WRITE equ 0Ah ; Write MODSEL equ 15h ; Mode Select MODSNS equ 01ah ; Mode Sense STSTOP equ 01bh ; Start / Stop Unit MEDREM equ 01eh ; Prevent Allow Medium Removal ; SCSI commands - Direct Access - group 1 RDCAPAC equ 025h ; Read Capacity _VERIFY equ 02fh ; Verify RDEFDAT equ 037h ; Read Defect Data ; SCSI commands - All Peripheral Device Types - group 0 TSTUNRD equ 00h ; Test Unit Ready REQSENS equ 03h ; Request Sense INQUIR equ 12h ; Inquiry COPY_ equ 18h ; Copy SENDIAG equ 01dh ; Send Diagnostic ; commands for WD3393A SCSI controller ; ! indicates negative logic AssertATN equ 02h ; Assert ATN NegateACK equ 03h ; Negate ACK SelATNTrn equ 08h ; Select-with-!ATN and-Transfer TranAdd equ 18h ; Translate address TransInfo equ 20h ; Transfer Info ; .phase 4000h defm 'AB' ; ID defw INIT ; Init routine defw STTMNT ; Call statements defw 0 ; No device defw 0 ; No text defw 0,0,0 ; Reserved ; 4010h - start of diskrom jump table JP DSKIO ; DISKIO - read/write sectors ; 4013h - Check if disk is changed JP DSKCHG ; 4016h - Get DPB (Disk Parameter Block) JP GETDPB ; 4019h - JP CHOICE ; Get address of format text ; 401Ch - JP DSKFMT ; FORMAT ; 401Fh - STPDRV (stop all drives of current DISKROM) JP STPDRV ; 4022h - JP NotSupp ; BASENT - entry to start BASIC ; 4025h - (Execute FORMAT routine) NOP JP NotSupp ; 4029h - Shutdown - stop disk motor (of all connected DISKROMs) JP NotSupp ; Not supported ; 402Ch - NOP JP WHEREAMI ; WHEREAMI - Get current slot ID of page 1 ; Input : - ; Output: A = slot ID current page 1 ; Modify: WHEREAMI: CALL CalcExp ; OR (HL) ; Expanded slot? RET P ; No ; LD C,A ; Save primairy slot INC HL INC HL INC HL INC HL LD A,(HL) ; Read contents of SLTTBL AND 0Ch OR C ; Form slot address RET ; GETWRK - Get Work Area - Get base address of work area in [IX] and [HL] ; ; Work area: 6 * 8 bytes (six entries of eight bytes for each drive) ; ; Entry: ; +00 - PxxFXTAR ; + ++ +++---- Target ID ; | |+-------- Normaly 1, can be reset after DSKIO (???) ; | +-------- Formatted, 1 = partition not (MSX) formatted ; +------------ Partition enable, 1 = enable (in use) ; +01 - 03 - First sector of partition ; +04 - 05 - Number of sectors in partition ; +06 - WxxxxNNN ; + +++----- Network write ID ; +------------ Write protect partition, 0 = protected ; +07 - NxxxEDHM ; | |||+-- MSX type, 0 = normal MSX (2/2+), 1 is Turbo-R ; | ||+--- Multiple HDD support, 1 = on ; | |+---- Driver support, 1 = on ; | +----- Extended partitions, 1 = on (not supported yet) ; +--------- NExtBIOS, 1 = installed ; ; byte 7 is only filled in the first entry, in all other entries this byte ; is zero GETWRK: CALL GetSLTWRK LD A,(HL) INC HL LD H,(HL) LD L,A PUSH HL POP IX RET ; GetSLTWRK: CALL CalcExp ; ADD A,A ADD A,A ADD A,A SCF ADC A,A LD C,A LD A,(HL) ADD A,A SBC A,A AND 0CH INC HL INC HL INC HL INC HL AND (HL) OR C ADD A,A LD HL,SLTWRK JR J$40D1 ; CalcExp: CALL RDPRIM ; Read primairy slot register RRCA RRCA AND 00000011b LD HL,EXPTBL ; See if slot is expanded or not LD B,0 J$40D1: LD C,A ADD HL,BC RET ; ; Text handlers ; synchr: ld a,(hl) ; get text ex (sp),hl cp (hl) ; compare with correct token inc hl ex (sp),hl jr nz,snerr ; no match, error chrgtr: ld ix,rom_chrgtr call calbas ei ret ; ; Error handlers ; errsn equ 2 ; syntax error errfc equ 5 ; illegal function call errom equ 7 ; out of memory errtm equ 13 ; type mismatch errdio equ 19 ; device I/O error ; ** SECURITY DUMMY defb 'K' xor 'c' defb 'M' xor 's' defb 'c' xor 'K' defb 's' xor 'M' ld e,12 defb 1 ; ** dioerr: ld e,errdio defb 1 tmerr: ld e,errtm defb 1 fcerr: ld e,errfc defb 1 snerr: ld e,errsn diverr: ld ix,rom_error jr jcalbas ; ; Interface routines between ROM BASIC routines ; strini: ld ix,rom_strini jr jcalbas ptrget: ld ix,rom_ptrget jr jcalbas docnvf: ld ix,rom_docnvf jr jcalbas frmevl: ld ix,rom_frmevl jr jcalbas frestr: ld ix,rom_frestr jr jcalbas getbyt: ld ix,rom_getbyt jcalbas: call calbas ; call ROM routines ei ret ; ; Return value (integer only) to variable specified ; ; Entry: HL = pointer to variable (returned from PTRGET) ; VALTYP = type of variable ; DAC+2 = integer value to be returned ; ; Destroyes all registers ; ret_number: push hl ; save pointer to variable ld hl,valtyp ; get variable type ld a,(hl) ld c,a ; set it as length of data (2,4,8) ld (hl),2 ; set integer type ld hl,dac+2 ; assume integer cp 2 ; is it integer ? jr z,numint ; yes, just copy and done cp 4 ; is it single real ? jr z,numflt ; yes cp 8 ; is it double real ? jp nz,tmerr ; no, cannot return a value to string numflt: push bc ; save length of data call docnvf ; coerce to desired type pop bc ; restore length of data ld hl,dac ; prepare to transfer value to variable numint: ld b,0 pop de ; restore pointer to variable ldir ; store to variable ret ; ; assign a string to a variable ; ; Entry: A = length of string ; HL = pointer to variable (returned from PTRGET) ; BUF = string itself ; ; Destroyes all registers ; ret_string: push hl ; save pointer to variable push af ; save length of string call strini ld de,(dsctmp+1) ld hl,buf pop af ; restore length of string and a ; null string? jr z,ret_null ; yes ld c,a ld b,0 ldir ret_null: pop de ; restore pointer to variable ld hl,dsctmp ld bc,3 ldir ret ; *************** CALL STATEMENTS *************** ; Execute CALL SLOW statement _SLOW: LD A,80H JR J.40DE ; Execute CALL MEDIUM statement _MEDIUM: LD A,81H JR J.40DE ; Execute CALL FAST statement _FAST: LD A,82H J.40DE: PUSH AF LD A,(0180h) ; Check if BIOS is enabled CP 0C3H ; CHGCPU call available? JR Z,J$40E9 ; Yes ; POP AF ; No AND A RET J$40E9: POP AF PUSH IX PUSH IY CALL 0180h ; Change CPU mode ; POP IY POP IX AND A RET ; Execute CALL MAP2 statement _MAP2: DI PUSH HL LD HL,0C000h LD BC,03FFCh J.40FF: LD A,3AH CPIR JR NZ,J.4122 ; INC HL LD A,(HL) CP 0F2H JR NZ,J.40FF ; DEC HL LD A,(HL) CP 0C8H JR C,J.40FF ; CP 0CBH JR NC,J.40FF ; DEC HL LD (HL),0DBH INC HL LD A,(HL) ADD A,35H LD (HL),A INC HL LD (HL),00H JR J.40FF J.4122: AND A POP HL EI RET ; Execute CALL MAP statement (MAP 1) ; Fix DOS2 memory map routine _MAP: DI PUSH HL LD HL,0C000h LD BC,03FFCh J.412E: LD A,3AH CPIR JR NZ,J.4122 ; INC HL LD A,(HL) CP 0F2H JR NZ,J.412E ; DEC HL LD A,(HL) CP 0C7H JR C,J.412E ; CP 0CBH JR NC,J.412E ; DEC HL LD (HL),0DBH INC HL LD A,(HL) ADD A,35H LD (HL),A INC HL LD (HL),00H JR J.412E ; Execute CALL INFO statement _INFO: PUSH HL ; Save text pointer CALL PRINT ; DEFM 'Available CALL statements:',CR,LF,CR,LF DEFM 'CALL INFO Shows this text',CR,LF DEFM 'CALL SLOW Z80 mode.',CR,LF DEFM 'CALL MEDIUM R800 ROM mode.',CR,LF DEFM 'CALL FAST R800 RAM mode.',CR,LF DEFM 'CALL MAP Fix DOS2 mapper routine',CR,LF DEFM 'CALL MAP2 ditto - version 2',CR,LF defm 'CALL HOSTID(variable) Get SCSI Host ID',CR,LF defm 'CALL SETHOSTID(var.) Set SCSI Host ID',CR,LF defm 'CALL TARGETID(variable) Get SCSI Target ID',CR,LF defm 'CALL SETTARGETID(var.) Set SCSI Target ID',CR,LF defm 'CALL INQUIRY(var,str,str,str) Get INQUIRY of specified' defm ' Target',CR,LF,CR,LF,0 POP HL ; Restore text pointer AND A RET ; Execute CALL HOSTID command ; Syntax: _HOSTID (variable) _HOSTID: synchk '(' call ptrget ; get a pointer to variable push de ; save a pointer to variable ld a,(valtyp) push af ; save the type of variable call Get_ID cpl and 7 ld (dac+2),a xor a ld (dac+3),a pop af ; restore type of variable ld (valtyp),a ; set it to VALTYP ex (sp),hl ; save text pointer ; restore pointer to variable call ret_number pop hl ; restore text pointer synchk ')' ret ; Execute CALL SETHOSTID command ; Syntax: _SETHOSTID (x) ; x can be: - integer, singel precision, double precision ; - numeric value ; - expression _SETHOSTID: call getbyt ; Evaluate expression to a byte cp 4 ; < 4 ? jp c,fcerr ; Yes, print illegal function call cp 8 ; > 7 ? jp nc,fcerr ; Yes call ROM_SetHost ; Set HOST ID and a ; Clear CY ret ; Execute CALL TARGETID command ; Syntax: _TARGETID (variable) _TARGETID: synchk '(' call ptrget ; get a pointer to variable push de ; save a pointer to variable ld a,(valtyp) push af ; save the type of variable call GetTargetID ld (dac+2),a xor a ld (dac+3),a pop af ; restore type of variable ld (valtyp),a ; set it to VALTYP ex (sp),hl ; save text pointer ; restore pointer to variable call ret_number pop hl ; restore text pointer synchk ')' ret ; Execute CALL SETTARGETID command ; Syntax: _SETTARGETID (x) ; x can be: - integer, singel precision, double precision ; - numeric value ; - expression _SETTARGETID: call getbyt ; Evaluate expression to a byte cp 4 ccf jp c,fcerr call SetTargetID ; Set Target ID and a ; Clear CY ret ; Execute CALL INQUIRY command ; Syntax: call inquiry (x,A$,B$,C$) ; x can be - integer single of double precision ; - numeric value ; - expression _INQUIRY: ld a,(hl) cp '(' jp nz,snerr inc hl call getbyt and a ; x < 0 ? jp m,fcerr ; Yes, illegal function call cp 8 ; x > 7 ? jp nc,fcerr ; Yes, illegal function call ld ix,($SECBUF) ; Get addres of sectorbuffer ld (ix+70h),a ; Store ID ld a,(hl) cp ',' jp nz,snerr inc hl ; String to Manufacturer push ix call ptrget pop ix ld a,(valtyp) cp 3 ; String ? jp nz,tmerr ; No, 'Type mismatch' error ld (ix+71h),d ld (ix+72h),e ; Store pointer to var. ld a,(hl) cp ',' jp nz,snerr inc hl ; String to Product push ix call ptrget pop ix ld a,(valtyp) cp 3 jp nz,tmerr ld (ix+73h),d ld (ix+74h),e ld a,(hl) cp ',' jp nz,snerr inc hl ; String to Revision push ix call ptrget pop ix ld a,(valtyp) cp 3 jp nz,tmerr ld (ix+75h),d ld (ix+76h),e ld a,(hl) cp ')' jp nz,snerr push hl ; Save text pointer ld a,(ix+70h) ; Get ID call Get_Inq ; Get inquiry jp c,diverr ld hl,($SECBUF) ld bc,8 add hl,bc ld de,buf ld bc,8 ld a,c ldir push hl ld h,(ix+71h) ld l,(ix+72h) push ix call ret_string ; Manufacturer pop ix pop hl ld de,buf ld bc,16 ld a,c ldir push hl ld h,(ix+73h) ld l,(ix+74h) push ix call ret_string ; Product pop ix pop hl ld de,buf ld bc,4 ld a,c ldir ld h,(ix+75h) ld l,(ix+76h) call ret_string ; Revision pop hl ; Restore text pointer inc hl and a ret ; _TEST added for test purpose ; Syntax: call test (....) ;_TEST: ; ld a,(hl) ; cp '(' ; jp nz,snerr ; inc hl ; call getbyt ; and a ; x < 0 ? ; jp m,fcerr ; Yes, illegal function call ; cp 8 ; x > 7 ? ; jp nc,fcerr ; Yes, illegal function call ; ld ix,($SECBUF) ; Get addres of sectorbuffer ; ld (ix+00h),a ; Store ID ; ld a,(hl) ; cp ',' ; jp nz,snerr ; inc hl ; ; String to Manufacturer ; ld (ix+01h),h ; ld (ix+02h),l ; Save text pointer, points to first string ; push ix ; call ptrget ; pop ix ; ld a,(valtyp) ; cp 3 ; String ? ; jp nz,tmerr ; No, 'Type mismatch' error ; ld a,(hl) ; cp ',' ; jp nz,snerr ; inc hl ; String to Product ; push ix ; call ptrget ; pop ix ; ld a,(valtyp) ; cp 3 ; jp nz,tmerr ; ld a,(hl) ; cp ',' ; jp nz,snerr ; inc hl ; String to Revision ; push ix ; call ptrget ; pop ix ; ld a,(valtyp) ; cp 3 ; jp nz,tmerr ; ld a,(hl) ; cp ')' ; jp nz,snerr ; The syntax of the command is now completely checked ; inc hl ; ld (ix+09h),h ; Save text pointer after command ; ld (ix+0ah),l ; ld a,(ix+00h) ; Get ID ; call Get_Inq ; Get inquiry ; jp c,diverr ; ld h,(ix+01h) ; ld l,(ix+02h) ; Get text pointer, points to first string ; push ix ; call ptrget ; pop ix ; inc hl ; Skip ',' ; ld (ix+01h),h ; ld (ix+02h),l ; Save text pointer, points to second string ; push de ; Save pointer to var. ; ld hl,($SECBUF) ; ld bc,0bh ; add hl,bc ; ld de,buf ; ld bc,8 ; ld a,c ; ldir ; Move Manufacturer to buf ; pop de ; push hl ; ex de,hl ; push ix ; call ret_string ; Manufacturer ; pop ix ; ld h,(ix+01h) ; ld l,(ix+02h) ; Get text pointer, points to second string ; push ix ; call ptrget ; pop ix ; inc hl ; Skip ',' ; ld (ix+01h),h ; ld (ix+02h),l ; Save text pointer, points to second string ; pop hl ; push de ; Save pointer to var ; ld de,buf ; ld bc,16 ; ld a,c ; ldir ; pop de ; push hl ; ex de,hl ; push ix ; call ret_string ; Product ; pop ix ; ld h,(ix+01h) ; ld l,(ix+02h) ; Get text pointer, points to third string ; push ix ; call ptrget ; pop ix ; pop hl ; push de ; Save pointer to var ; ld de,buf ; ld bc,8 ; ld a,c ; ldir ; pop hl ; call ret_string ; Revision ; ld h,(ix+09h) ; ld l,(ix+0ah) ; and a ; ret ; ************** END CALL STATEMENTS *************** ; AllocMem - Allocate Memory ; Input : HL = required memory size ; Output: HL = address of allocated memory ; if Carry is set there was not enough room, no mem allocated ; AllocMem: LD A,L OR H RET Z ; No memory to allocate ; XOR A SUB L LD L,A LD A,0 SBC A,H LD H,A LD C,L LD B,H ADD HL,SP CCF RET C ; LD DE,(BOTTOM) ; Get start of RAM SBC HL,DE RET C ; LD A,H CP 3 RET C ; PUSH BC LD HL,0 ADD HL,SP LD E,L LD D,H ADD HL,BC PUSH HL LD HL,(STKTOP) AND A SBC HL,DE LD C,L LD B,H INC BC POP HL LD SP,HL EX DE,HL LDIR POP BC LD HL,(HIMEM) ADD HL,BC LD (HIMEM),HL LD DE,0FDEAh ADD HL,DE LD (FILTAB),HL EX DE,HL LD HL,(MEMSIZ) ADD HL,BC LD (MEMSIZ),HL LD HL,(NULBUF) ADD HL,BC LD (NULBUF),HL LD HL,(STKTOP) ADD HL,BC LD (STKTOP),HL DEC HL DEC HL LD (SAVSTK),HL LD L,E LD H,D INC HL INC HL INC HL INC HL LD A,2 J$436B: EX DE,HL LD (HL),E INC HL LD (HL),D INC HL EX DE,HL LD BC,7 LD (HL),B ADD HL,BC LD (HL),B LD BC,0102h ADD HL,BC DEC A JR NZ,J$436B ; RET ; Init routine - is executed at system startup INIT: CALL DoTests ; Check MSX type and keys ; LD A,(DEVICE) OR A RET M ; DOS 2.x not initialised JP NZ,DskROM ; Install drives (DISKROM already ; installed) ; There is no DiskROM installed (yet), setup work area LD A,(BASVER) CP 1 RET C ; LD HL,HOKVLD BIT 0,(HL) ; Extended BIOS already installed? JR NZ,EXBIO_INS ; Yes ; SET 0,(HL) LD HL,EXTBIO LD B,0FH Clear3: LD (HL),0C9H INC HL DJNZ Clear3 ; EXBIO_INS: LD HL,(BOTTOM) LD DE,0C001h RST DCOMPR ; BOTTOM > 0c001h? ; RET NC ; Yes ; LD A,6 CALL SNSMAT ; RRCA ; SHIFT pressed? RET NC ; Yes, do not install HDD ; ; *M*v1.04 ; LD HL,0F3B0h ; LD DE,0F1C9h ; OR A ; Clear carry flag ; SBC HL,DE ; HL = 487 ; CALL NC,AllocMem call CalcWA_2 ; Calculate size of Work Area call AllocMem ; Allocate memory ; *M* ; RET C ; Not enough room ; PUSH HL ; Save address of allocated memory LD HL,0FE49h ; 439 bytes (65536 - 0fe49h) LD BC,0F1C9h Clear: XOR A LD (BC),A INC BC INC HL LD A,L OR H JR NZ,Clear ; LD HL,512 LD (AUTLIN),HL LD B,20 LD HL,0FB21h Clear1: LD (HL),A ; Fill with 0 INC HL DJNZ Clear1 ; LD HL,0F24Fh LD B,69h ; 105 Clear2: LD (HL),0C9h ; RET code INC HL DJNZ Clear2 ; ; Install code for RDPRIM routine (IN A,(0a8h) + RET) LD A,0DBH ; IN A,xx LD HL,0C9A8h LD (RDPRIM),A ; code for IN A,(xx) LD (RDPRIM+1),HL ; xx = a8h + RET code LD A,6 ; Keyboard ROW 6 CALL SNSMAT ; AND 00000010b ; Extract CTRL key LD (CTRL),A LD A,7 ; BEEP RST OUTDO ; LD C,0 LD DE,0FB21h EXX POP DE ; Work Area address JR J$443E ; Install drive(s) DskROM: LD HL,0FB21h LD B,4 ; Count all installed software drives XOR A DrvCnt: ADD A,(HL) ; Get # of drives RET C ; INC HL INC HL DJNZ DrvCnt ; CP 8 ; Allready 8 drives installed? RET NC ; Yes... ; LD HL,(AUTLIN) LD DE,512 RST DCOMPR ; JR NC,J$4424 ; LD (AUTLIN),DE J$4424: LD DE,0FB21h LD BC,0400h NxtEntr: LD A,(DE) ; Get # of software drives AND A ; Entry not used? JR Z,FreEntry ; No ; ADD A,C LD C,A INC DE INC DE DJNZ NxtEntr ; RET ; All entries used, can not install ; drives ; FreEntry: ; C contains # of already installed drives EXX call CalcWA_1 ; Calculate size of Work Area CALL AllocMem ; Allocate memory for Work Area ; RET C ; Not enough memory ; EX DE,HL ; DE = address of alloc. mem. J$443E: CALL GetSLTWRK ; Get SLTWRK address ; LD (HL),E ; Set Work Area address INC HL LD (HL),D EXX LD A,(CTRL) AND A ; CTRL key pressed? LD A,C ; Get # of installed drives CALL InsWork ; ADD A,L ; L contains # of partitions CP 9 LD A,L JR C,AllUsed ; LD A,8 ; Max # of drives SUB C ; Substract # of installed drvs AllUsed: PUSH BC LD (DE),A ; Store # of drives INC DE CALL WHEREAMI ; LD (DE),A ; Store slot ID POP BC ; C = number of drives to install LD B,0 LD HL,0F355h ADD HL,BC ADD HL,BC ; HL = 0F355h + 2 * drives PUSH HL DEC DE LD A,(DE) ; Get # of drives PUSH AF push de LD L,A LD H,0 LD D,H LD E,L ; DE = number of drives to inst. ADD HL,HL ADD HL,HL ADD HL,DE ADD HL,HL ADD HL,HL ADD HL,DE CALL AllocMem ; POP DE ; DE points to # of log. drives JR C,J$44C1 ; PUSH HL ; Address of alloc. mem. CALL ClrEndLn ; POP DE ; Alloc. mem. addr. POP BC ; B = # of drives to install POP HL ; HL = 0F355h + 2 * drives LD C,0 J$4484: LD (HL),E INC HL LD (HL),D INC HL PUSH BC PUSH DE PUSH HL LD HL,0FE00h ADD HL,SP LD SP,HL LD ($SECBUF),HL ; Set address of sector buffer LD A,C LD BC,(DPB) LD B,0 EX DE,HL CALL GETDPB ; LD HL,512 EX AF,AF' ADD HL,SP EX AF,AF' LD SP,HL POP HL POP DE LD BC,15h JR C,J$44B1 ; EX DE,HL ADD HL,BC EX DE,HL JR J$44B8 ; ; ----------------- J$44B1: PUSH HL LD HL,I$4508 ; Table-1 LDIR POP HL J$44B8: POP BC INC C DJNZ J$4484 ; LD HL,DEVICE INC (HL) RET ; ; ----------------- J$44C1: POP AF POP AF ; Dump XOR A LD (DE),A INC DE LD (DE),A RET ; Not supported calls NotSupp: RET ; Just return to caller DI HALT ; PRINT - Print a character PRINT: pop hl ; Points to text ld a,(hl) inc hl push hl or a ret z rst OUTDO jr PRINT ; OldCPUmode - Restore old CPU mode OldCPUmode: PUSH AF PUSH IX PUSH IY LD A,(CMASK) ; Get old CPU mode JR RestCPUmd ; Restore CPU mode ; ChgCPU ChgCPU: PUSH AF PUSH IX PUSH IY LD IX,0183h ; Get CPU mode LD IY,(EXPTBL-1) CALL CALSLT ; LD (CMASK),A ; Store CPU mode call Get_ID CPL RLCA RLCA AND 01H RestCPUmd: LD IX,0180h ; Change CPU mode LD IY,(EXPTBL-1) CALL CALSLT ; POP IY POP IX POP AF I$4508: RET ; DBP - Disk Paramter Block ; DPB: defb 0f0h ; Media ID defw 0200h ; Sector size defb 0fh ; Directory mask defb 04h ; Directory shift defb 01fh ; Cluster mask defb 06h ; Cluster shift defw 1h ; Top sector of FAT defb 02h ; Number of FATs defb 0feh ; Number of directory entries defw 29h ; Top sector of data area defw 0514h ; Amount of clusters + 1 defb 0ch ; Number of sector required for one FAT defw 19h ; Top sector of directory area ; DoTests - Check for Turbo-R, test GRAPH key etc. ; Also check for HDD (Target ID = 0-3) and set Host ID DoTests: EI LD A,(BASVER) CP 1 ; MSX2 or up? JR NC,TurboR ; pop af ; Not a MSX2 ret TurboR: LD A,6 ; Keyboard row 6 CALL SNSMAT ; BIT 2,A ; Test GRAPH JR NZ,IniScr ; pop af ; GRAPH is pressed ret IniScr: ld a,80 ld (LINL40),a xor a call CHGMOD ; Init text mode width 80 ; call ERAFNK ; Erase function keys ; Print InitTXT, Init WD33C93A, do selftest etc. ; Initialise: ; *N* ld a,(BASVER) cp 3 push af call nc,ChgCPU ; *N* call PrInitTxt ROMchk: ; *M*v1.08 ld a,1 ; *N* out (HARDWR),a ; Hardware reset WD3393A in a,(AUXSTAT) cp 30h ; BUSY + COMMAND IN PROGRESS ? jr nz,NoCHIP ; No, probably no WD3393A ld b,0 ; B=256 WaitIntP: in a,(AUXSTAT) dec b and 10000000b ; INTERRUPT PENDING? jr nz,WaitIntP ld a,17h out (REGSET),a in a,(RDWREG) ; Clear pending interrupt ; ld a,18h ; out (REGSET),a ; xor a ; out (RDWREG),a ; Execute RESET command NoCHIP: ; *M* LD HL,04000h LD (HL),A ChkROM: ADD A,(HL) INC HL BIT 7,H ; Address = 8000H ? JR Z,ChkROM ; No ; ; *N* pop af call nc,OldCPUmode ; *N* xor a OR A ; Error? JP NZ,ChkSumErr ; *M*v0.32 ; ; *N*v.032 ld bc,0640ch in a,(AUXSTAT) and c cp 0ch ; No SCSI controller? jr z,BusOk ; *N* ld c,20h Rtry: in a,(AUXSTAT) ; Read Auxiliary Status and c ; Busy? jr z,BusOk ; No ; call WAITL1 ; Wait ; djnz Rtry ; jp BusDown ; Failed, SCSI bus probably down BusOk: ; Test SCSI controller - WD3393A ld d,2 ld bc,baseport ChkLoop: out (c),d ld a,b out (RDWREG),a out (c),d in a,(RDWREG) cp b jp nz,SBICerr ; SBIC error ; djnz ChkLoop ; inc d ld a,d cp 0fh jr nz,ChkLoop call ChkSETDIAG ; Check DEL key for SETUP/DIAG call PRINT ; defb 'please wait --',0 ; Wait for HDD (ID = 0 - 3) ld b,30 WAITHDD: call TALE ; Print 'jumping' '-' ; *M* call GetTargetID ; Get Target ID ; *M* push bc call TstUnitRdy ; pop bc inc d dec d ; Status GOOD ? jp z,NOVAXIS ; Yes ; cp 42h ; call nz,WAIT ; djnz WAITHDD ; Try again ; Harddisk offline call PRINT defb CR,'Hard disk offline',CR,LF,0 pop af ; Dump return address ret ; ChkSumErr - ROM checksum error ChkSumErr: call PRINT ; defb 'ROM checksum error',CR,LF,0 jr HostFail ; BusDown - SCSI bus is down BusDown: call PRINT ; defb 'SCSI bus is down',CR,LF,0 ; jr HostFail ; SBICerr: call PRINT defb 'Controller test failed',CR,LF,0 HostFail: call PRINT ; defb 7 ; BELL defb 'Host interface self test failed',CR,LF,0 ; ld b,5 Wait3: call WAIT djnz Wait3 pop af ; Dump return address ret ; WAITL1: LD HL,01266h JR WAITL ; WAIT - wait WAIT: LD HL,0B7FBh WAITL: LD A,H OR L RET Z EX (SP),HL EX (SP),HL DEC HL JR WAITL ; InsWork - Install Workspace InsWork: PUSH AF PUSH BC PUSH DE ; ** SECURITY DUMMY ld hl,SECURE ; ** CALL GETWRK ; Get Drive Work Area in [HL] and [IX] ; LD (HL),0 LD D,H ; DE = Work Area address LD E,L INC DE ; DE = HL + 1 call CalcWA_3 ; Calculate size of Work Area LDIR ; Fill with 00h ; *N* ld a,(BASVER) cp 3 ld a,1 jr z,MSX_TBR dec a MSX_TBR: ; *N*v0.31 push af ld a,2 call CLKMOD ld b,11 call REDRAM and 00001100b ; Only bits 2 and 3 are needed srl a ld d,a pop af or d ; Now bit 0 contains MSX type ; bit 1 contains Multiple HDD support toggle ; bit 2 contains Driver Support toggle ; *M*v1.13.10 call ChkAut ld e,a ld a,2 call CLKMOD ld b,11 call REDRAM set 3,a bit 2,e jr nz,SecChk res 3,a SecChk: ld d,a ld b,11 call WRTRAM ld a,e ; *M* ; *M* ld d,a ld a,2 call CLKMOD ld b,12 call REDRAM and 00000100b ; Only bit 2 needed, contains ExtPrt sla a or d ld (ix+07h),a ; *N*v0.10 ld hl,CRLF call Print2 ld hl,220bh ld (XYpos),hl ld h,1 call POSIT ; *N*v0.10 LD HL,0FE00h ADD HL,SP LD SP,HL ; *** ; Test for HDD, start with Target ID read from clockchip ; Each ID is tested 8 times call CalcTab ld a,(iy+00h) ; Get Target ID ld c,0 TestID: push af ; Save Target ID push iy ; Save pointer call RdHDDpart ; Read partition table pop iy ; Restore pointer ; *M*v1.11.16 ; ld a,c ; Get # of installed log. drives ; cp maxdrv ; Exceeded max. drives? ; jr nc,J$468F ; Yes ; *M* pop af ; Restore Target ID inc d dec d ; Status GOOD? jr nz,HDDresp ; Yes add a,32 ; Try again jr nc,TestID HDDresp: inc iy ld a,(iy+00h) ; Get next ID bit 7,a ; End of table? jr z,TestID ; No ; *M* LD A,C OR A JR NZ,J$4690 ; INC C LD A,0F1H J$468F EQU $-1 J$4690: LD L,C LD IX,512 ADD IX,SP LD SP,IX POP DE POP BC POP AF ; v1.50 - 05/06/95 ei halt halt halt halt RET ; *N*v0.31 ; CalcTab - calculate ID table ; Input : - ; Output: IY = address of ID table, terminated with 128 CalcTab: ld a,2 call CLKMOD ld b,11 call REDRAM bit 2,a ; Multiple HDD support on? jr nz,MakMulTab ; Yes ; Calculate IDtable for single Target environment call GetTargetID ld iy,IDsTable and a ; Target ID 0 ? ret z ; Yes ld de,2 MaksTab: add iy,de dec a jr nz,MaksTab ret ; Calculate IDtable for Multiple HDD environment MakMulTab: ; *N*v0.31 call Get_ID and 7 ld iy,IDtable-32 ld de,32 inc a ld b,a MakTab: add iy,de djnz MakTab call GetTargetID and a ; Target ID 0? ; *M*v0.31 ; jr z,RghtT ; Yes ret z ; *M* ld b,a ld de,8 MakTab2: add iy,de djnz MakTab2 ; RghtT: ret ; RdHDDpart - Read HDD partition table ; Input : A = ID ; Output: C contains total # of log. drives ; IX = Address of free Work Area entry ; Modify: RdHDDpart: LD HL,4 ADD HL,SP LD ($SECBUF),HL ; Change sectorbuffer address PUSH BC ; C = number of installed log. drives PUSH IX ; Work Area address PUSH AF ; Save Target ID LD E,A call Get_ID INC A ADD A,E AND 7 jp z,NoResp ; LD A,2 OUT (REGSET),A LD A,12 ; Set Timeout to 96ms OUT (RDWREG),A LD A,E ; ID CALL TstUnitRdy LD E,A LD A,2 OUT (REGSET),A LD A,7Dh OUT (RDWREG),A ; Set Timeout Period to 1 second LD A,D OR A ; Status GOOD? jp z,TrnsPart ; Yes ; LD A,E CP 42H ; Error? jp z,NoResp ; POP AF PUSH AF CALL TstUnitRdy ; LD A,D OR A ; Status GOOD? jp z,TrnsPart ; Yes ; *N*v1.08 - added for CD-ROM cp 2 ; CHECK CONDITION? jr nz,NoResp ld b,0 ; Test max. 256 times pop af ; Get Target ID push af push bc call TstUnitRdy ld a,d or a ; STATUS GOOD? jr z,UnitRdy cp 2 ; CHECK CONDITION? jr nz,UnitNrdy ChkCnd: pop bc RetryCDR: pop af ; Target ID push af push bc push af call TstUnitRdy pop af inc d dec d ; STATUS GOOD? jr z,UnitRdy dec d dec d ; CHECK CONDITION? jr nz,UnitNRdy call GetSense push af call WAIT pop af dec d dec d ; CHECK CONDITION? jp z,UnitNrdy ; Yes and a ; NO SENSE? jr z,UnitNrdy ; Yes cp 2 ; NOT READY? jr z,ChkNrdy ; Yes cp 6 ; UNIT ATTENTION? jr nz,UnitNrdy ; No ChkNrdy: ld a,b ; Get Sense Code cp 29h ; POWER ON? jr z,UnitRdy ; Yes cp 3ah ; MEDIUM NOT PRESENT? jr z,UnitRdy ; Yes cp 04h ; LOGICAL UNIT NOT READY? jr nz,UnitNrdy ld a,c ; Get Additional Sense Code and a jr z,UnitNrdy dec a ; Becoming ready? jr nz,UnitNrdy ; No pop bc djnz RetryCDR ; Try again UnitNrdy: pop bc NoResp: POP AF ; No response from device POP IX POP BC LD D,2 ; Check Condition ; *N*v1.09.02 ; xor a ; inc a ; *N* RET UnitRdy: pop bc TrnsPart: POP AF PUSH AF ; ID ; Now get INQUIRY data of Device of current ID ; *N*v0.10 call GetInq pop af ; Target ID pop ix pop bc ; C = number of installed log. drv. inc d dec d ; Status GOOD ? ret nz ; No ld (TrgID),a ; Save Target ID ld a,c ld (LogDrv),a ; Save # of installed log. drives ; *N*v1.11.12 ld (DiffDrv),a ; *N* ld (WrkSav),ix ; Save Work Area address ; *N*v1.11.16 cp maxdrv jp nc,NrLogEx ; *N* call Rd_Cnv_Prt ; Read and convert partition table(s) jp c,ErrPartT ld a,(TabType) ; Get table type cp 1 ; PC ? jp z,InsPCTab cp 2 ; MSX ? jp z,InsMSXTab and a ; NOVAXIS ? jp z,InsNOVTab ; There's no partition table found ld a,'N' ; Indicate no partition found jp NoPartT ; ** SECURITY DUMMY ** ChkAut: push af push bc push ix ld hl,JurgenKramer ld de,0b200h ld bc,13 ldir ld hl,RevTxtJK push de ld bc,13 ldir pop de ld bc,0c7bh SecDecode: ld a,(de) xor c dec c ld (de),a inc de djnz SecDecode ld hl,0b200h push hl pop iy ld ix,0b200h+26 ld b,11 ChkAutStr: ld a,(ix-13) ld c,(iy+14) xor c cp (hl) jr nz,SecError inc hl inc ix inc iy djnz ChkAutStr ld hl,(C1_ADD) ld de,0b00h add hl,de ld d,l ld e,h ld b,11 ld hl,0b200h+13 ChkC1: ld a,(de) cp (hl) jr nz,SecError inc de inc hl djnz ChkC1 ld hl,(C2_ADD) ld de,0b00h add hl,de ld d,l ld e,h ld b,11 ld hl,0b200h+13 ChkC2: ld a,(de) cp (hl) jr nz,SecError inc de inc hl djnz ChkC2 pop ix pop bc pop af and 11111011b ret SecError: pop ix pop bc pop af or 4 ret ; ***** MSX PARTITIONS ***** ; InsMSXTab - Install MSX partition table InsMSXTab: ld ix,(WrkSav) ; Get Work Area address ld iy,TmpPDat ; Get address of temp. part. data ld a,(NrParts) ; Get # of partitions ld b,a ld a,(LogDrv) ; Get # of installed drives ld c,a ld de,8 ; Entry size ; Fill Network Write ID push bc ; Save # of partitions and installed drives push ix ; Save WA address push iy ; Save address of temp. part. data ld ix,PSecBuf+19eh ; Points to first partition entry FillMSXN: ld a,(ix+00h) ; Get Network Write ID rrca xor 11000000b ld (iy+07h),a ; Store in TmpPDat add ix,de add ix,de ; Next entry in PSecBuf add iy,de ; Next entry in TmpPDat djnz FillMSXN call CalcExtDrv pop iy pop ix pop bc NxtMSXP: dec (iy+00h) ; 12-bit FAT? jr nz,NoMSXPFAT ; No ld a,(TrgID) ; Get Target ID ld (ix+00h),a ; Store it WA ld a,(iy+07h) ; Get Write ID ld (ix+06h),a ; Store in WA call RdToggles bit 1,a ; Extended Partitions enabled? jr z,SkipMSXExt ld a,(iy+07h) ; and 00001111b call CalcExWrtID ld a,h ld (de),a ; Store Write ID in Ext. WA SkipMSXExt: ld a,(iy+01h) ; Get startsector LSB ld (ix+01h),a ; Store in WA ld a,(iy+02h) ld (ix+02h),a ld a,(iy+03h) ; Get startsector MSB ld (ix+03h),a ; Store in WA ld a,(iy+04h) ; Get # of sectors LSB ld (ix+04h),a ; Store in WA ld a,(iy+05h) ; Get # of sectors MSB ld (ix+05h),a ; Store in WA inc c ; Increase # of installed log. drives NoMSXPFAT: push de ld de,8 add ix,de add iy,de pop de inc de ld a,c cp maxdrv ; Exceeded max. # of log. drives? jp nc,NrLogEx djnz NxtPCP ; No, next MSX Partition jp NrLogEx ; ***** END MSX PARTITIONS ***** ; ****** PC PARTITIONS ****** ; InsPCTab - Install PC partition table InsPCTab: ld ix,(WrkSav) ; Get Work Area address ld iy,TmpPDat ; Get address of temp. part. data ld a,(NrParts) ; Get # of partitions ld b,a ld a,(LogDrv) ; Get # of installed drives ld c,a ld de,8 ; Entry size ; Set Network Write ID to Host ID call Get_ID ; Get Host ID add a,10h ; !!!!! push bc push iy push af call CalcExWrtID pop af FillPCN: ld (iy+07h),a ; Store network write ID add iy,de ; Next entry djnz FillPCN call CalcExtDrv pop iy pop bc ; NxtPCP: dec (iy+00h) ; 12-bit FAT? jr nz,NoMSXFAT ; No ld a,(TrgID) ; Get Target ID ld (ix+00h),a ; Store it WA ld a,(iy+07h) ; Get Write ID ld (ix+06h),a ; Store in WA call RdToggles bit 1,a ; Ext. Partitions enbled? jr z,NoExtPC ld a,h ; Get Network Write ID ld (de),a ; Store in Ext. WA NoExtPC: ld a,(iy+01h) ; Get startsector LSB ld (ix+01h),a ; Store in WA ld a,(iy+02h) ld (ix+02h),a ld a,(iy+03h) ; Get startsector MSB ld (ix+03h),a ; Store in WA ld a,(iy+04h) ; Get # of sectors LSB ld (ix+04h),a ; Store in WA ld a,(iy+05h) ; Get # of sectors MSB ld (ix+05h),a ; Store in WA inc c ; Increase # of installed log. drives NoMSXFAT: push de ld de,8 add ix,de add iy,de pop de inc de ld a,c cp maxdrv ; Exceeded max. # of log. drives? jr nc,NrLogEx djnz NxtPCP ; No, next PC Partition NrLogEx: ld (LogDrv),a ; Store # of log. drives ld (WrkSav),ix ; Store WA address push af ld a,(DiffDrv) ; Get # of driver installed before ld b,a pop af sub b ; Calc # of drives installed this run add a,30h jp NoPartT ; *N* ; ****** END PC PARTITIONS ****** ; ******* NOVAXIS PARTITIONS ******* ; InsNOVTab - Install NOVAXIS (Extended) partition table InsNOVTab: ; *N*v1.11.17 call RdToggles bit 1,a ; Extended Partitions enabled? ld a,'0' jp z,NoPartT ; No ; *N* ; *N*v1.11.06 ; ** SECURITY DUMMY ld hl,SECURE ; ** call GETWRK ld de,NRM_SIZE add ix,de set 7,(ix+01h) ; Indicate that the Ext. part. are in use ld de,NRM_SIZE+10h add hl,de ld a,(LogDrv) ; Get # of installed drives ld d,0 ld e,a add hl,de ex de,hl ; DE points to Write ID in Ext. WA ; ld ix,(WrkSav) ; Get Work Area address ld iy,TmpPDat ; Get address of temp. part. data call GetHost_ID ; Get Host ID ld h,1 ; Start with ID 0 and a ; Host ID 0? jr z,RdIDOk ld b,a MkRdID: sla h djnz MkRdID RdIDOk: ld a,(NrParts) ; Get # of partitions ld b,a ld a,(LogDrv) ; Get # of installed drives ld c,a ; NxtNOV: dec (iy+00h) ; 12-bit FAT? jr nz,NoRdPerm ; No ld a,(iy+06h) ; Get Read ID and h ; Permission to read this partition? jr z,NoRdPerm ; No, skip this partition ld a,(TrgID) ; Get Target ID ld (ix+00h),a ; Store in WA ld a,(iy+07h) ; Get Write ID ld (de),a ; Store in Ext. WA ld a,(iy+01h) ; Get startsector LSB ld (ix+01h),a ; Store in WA ld a,(iy+02h) ld (ix+02h),a ld a,(iy+03h) ; Get startsector MSB ld (ix+03h),a ; Store in WA ld a,(iy+04h) ; Get # of sectors LSB ld (ix+04h),a ; Store in WA ld a,(iy+05h) ; Get # of sectors MSB ld (ix+05h),a ; Store in WA inc c ; Increase # of log. drives NoRdPerm: push de ld de,8 add ix,de add iy,de pop de inc de ; Next Write ID in Ext. WA ld a,c cp maxdrv ; Exceeded max. # of log. drives? jp nc,NrLogEx djnz NxtNOV ; No, next PC Partition jp NrLogEx ; ErrPartT: ld a,'E' ; Indicate there was a error reading NoPartT: rst OUTDO ; Print message OkPartT: ld hl,CRLF call Print2 ld ix,(WrkSav) ld a,(LogDrv) ld c,a ret ; ******* END NOVAXIS PARTITIONS ******* ; CalcExtDrv - Calculate address of Extended Write ID table ; Input : - ; Output: DE points to Ext. Write ID table (only if Ext. Part. are enabled) ; Modify: AF,BC CalcExtDrv: call RdToggles bit 1,a ; Extended Partitions enabled? ret z ; No push hl push ix push iy call GETWRK ld de,NRM_SIZE add ix,de ld de,NRM_SIZE+10h add hl,de ld a,(LogDrv) ; Get # of installed drives ld d,0 ld e,a add hl,de ex de,hl ; DE points to Write ID in Ext. WA pop iy pop ix pop hl ret ; ** SECURITY DUMMY ** RevTxtJK: defb 'J' xor 123 defb 'u' xor 122 defb 'r' xor 121 defb 'g' xor 120 defb 'e' xor 119 defb 'n' xor 118 defb ' ' xor 117 defb 'K' xor 116 defb 'r' xor 115 defb 'a' xor 114 defb 'm' xor 113 defb 'e' xor 112 defb 'r' xor 111 ; CalcExWrtID - Calculate Extendend Write ID ; Input : A = old Network Write ID (c1h = ID 6 etc) ; Output: H = new network write ID ; Modify: AF CalcExWrtID: xor 255 and 7 push bc ld h,1 ; Start with ID 0 ld b,a and a ; ID 0? jr z,MSX_ID0 MakeMSXRd: sla h djnz MakeMSXRd MSX_ID0: pop bc ret ; PARTTAB.MAC - derived from READTAB.GEN ; Reads partition table ; Written by Roderik Muit ; Adapted by Jurgen Kramer for NOVAXIS SCSI BIOS ; (c) 1995 KMcs ; - 10/04/95 - ; Modified - 12/04/95 - .comment % Gebruikte labels: (NrParts)= aantal partities. (TabType) = type partitie, weet niet of je die nodig hebt dus heb hem maar laten zitten... 0 = Extended DOS/BERT/Novaxis 1.x(?) 1 = (oude) PC 2 = (oude) MSX (3 = gereserveerd voor MAK 3.0 in FDISK) 255 = No (valid) partition DrMAPDat = Drive-map-data. Formaat: 8 bytes voor A:-H: 0-(x-1) = partitienummer x staat naar deze drive toegemapt (x is nu 15?) 255 = Deze drive is niet meer aan een SCSI-partitie gekoppeld. Als de tabel niet gevonden wordt, wordt er 8 keer 255 in ingevuld. Ik heb geen flauw idee of dat handig is en heb het er dus voor de zekerheid maar in laten staan. PSecBuf = buffer voor inlezen partitiesector(s) TmpPDat = de uiteindelijke data: - Type (1 = MSX, enz.) - Beginsector (3 bytes LSB,MSB,MMSB) - Aantal sectoren (2 bytes LSB,MSB) - Read ID (bit 7 = ID 7, ..., Bit 0 = ID 0 - Write ID 1 = toegestaan, 0 = niet ) Partitie-indeling extended: (In principe HOEF je dit niet te weten omdat mijn leesroutine het allemaal afhandelt. Maar wie weet wanneer het van pas komt. Ook is het niet leuk als je ROM dingen kan inlezen waarvna je niet eens weet hoe ze in elkaar zitten, misschien...) Op partitie-entry 1 van de 4 (Dus op +1BEh) staat een normale partitie zoals je die kent. Op partitie-entry 2 staat een partitie met gegevens: - type nr. 5 - beginsector = sector waar volgende partitiedata staat (- aantal sectoren: heb ik op 1 gezet, weet niet zeker of dat moet.) Die volgende sector is weer precies zo opgebouwd met op +1BE een entry en op +1CE een type 5 en een verwijzing naar een volgende sector. Totdat er niet meer partities zijn, dan staat er gewoon niets op +1CE. (Verder staat aan het begin van elke partitiesector ook de 'EB FE 90' en de ID-naam daarachter ingevuld. Ik weet niet of het noodzakelijk is, bij de BERT is dit ook zo.) Verdere opmerking: De beginsector van elke partitie (en de 'beginsector' van de type 5 volgende partitietabel) zijn relatief ten opzichte van de partitiesector waarin die partitiedata staat. In de praktijk betekent dat dus dat voor de partitiedata overal beginsector 1 ingevuld staat, en voor de volgende partitiesector (partitielengte+1). (Dit is ook allemaal afgekeken van de BERT indeling.) - Nieuwe dingen toegevoegd aan deze standaard Extended MS-DOS partitie indeling: 1.) Door HPN (denk ik, ik neem aan dat dit geen standaard is): Vlak voor de 1e partitiedata, dus op bytes +1B6h - +1BDh, staan de lees/schrijftoegangen van deze partitie. - +1B6 is voor ID 0, ..., +1BD is voor ID 7 - bit 0 = schrijftoegang (1 = verboden) bit 1 = leestoegang (1 = verboden) Dus: 0 = lezen en schrijven 1 = niet schrijven (2 komt nooit voor volgens mij) 3 = deze partitie bestaat niet voor dit ID. 2.) Door mij (nog niet, maar in de toekomst misschien. Dit zal eraan liggen of jij het ooit in een ROM toepast): +1F6 - +1FD = de partitie-map-data voor drive A: t/m H: (0-254 = partitienummer dat bij opstarten naar deze drive toegemapt staat 255 = deze drive is niet meer aan deze HD toegewezen, alle volgende zijn ook 255. % ; Rd_Cnv_Prt - Read and Convert Parition table(s) ; Input : TrgID = ID, PSecBuf = address of 1k buffer, TmpPDat = temp. buffer ; DrMAPDat = address of drive MAP data ; Output: TabType = partition table type, 0 = Extended DOS, 1 = PC, 2 = MSX ; NrParts = # of partitions ; Error : Carry flag is set ; Modify: All Rd_Cnv_Prt: ld a,(TrgID) ; Get Target ID ld b,2 ld de,0 ld c,e ; Block 0 ld hl,PSecBuf call RdPartSecs ld a,d or a ; Status GOOD? jp nz,Error_0 ld hl,(PSecBuf+1fEH) ; Partitiontable found on block 0? ld de,0AA55h rst DCOMPR jr nz,readp2 ld a,(PSecBuf+1D2h) ; 2e part. = Extended DOS? Dan BERT formaat sub 5 jr z,readp6 ld hl,(PSecBuf+1A0h) ; Als 0,0,1,0 in '1e entry' dan MSX tabel ld de,0 rst DCOMPR jr nz,readp5 ld hl,(PSecBuf+1A2h) ld e,1 rst DCOMPR jr nz,readp5 ; MSX tabel ld a,2 ld ix,PSecBuf+19Eh jr readp4 ; Standaard (PC) tabel readp5: ld a,1 ld ix,PSecBuf+1BEh readp4: ld (TabType),a redp45: call inidmap jr fillp ; Geen partitietabel gevonden. readp2: ld a,255 ld (TabType),a ; call inidmap ; xor a inc a jp redpzx ; BERT tabel readp6: ; *N*v1.11.22 ld ix,PSecBuf+1beh ; *N* ld (TabType),a ; A=0 ld a,(PSecBuf+1F3h) ; Controleer op 'Drv' cp 68 jr nz,redp45 ld hl,(PSecBuf+1F4h) ld de,7672h rst DCOMPR jr nz,redp45 ld hl,PSecBuf+1F6h ; Klopt: neem drive-tabel over ld de,DrMAPDat ld bc,8 ldir ; *R*v1.11.22 ld ix,PSecBuf+1BEh ; *R*v1.11.22 ; vul gegevens in in TmpPDat ; IX = plaats in parttabel (al ingevuld) ; HL = plaats in TmpPDat ; B = partitienr. ; A'DE = sectornr. van partitietabel (<>0 bij BERT-partities) fillp: ld hl,TmpPDat ld de,0 xor a ld b,a fillpl: push bc push af push de ex af,af' ld a,(ix+4) ; type or a jp z,redpzz ld (hl),a inc hl ld c,(ix+8) ; beginsector ld b,(ix+9) ex af,af' ex de,hl add hl,bc ex de,hl adc a,(ix+10) ld (hl),e inc hl ld (hl),d inc hl ld (hl),a inc hl ex de,hl ; aantal sect. push ix pop hl ld bc,12 add hl,bc ldi ldi ld a,(TabType) cp 2 jr nc,fillp2 dec a jr z,fillp1 push ix ;BERT: codeer read/write ID pop hl push de ld b,8 fillpm: dec hl ld a,(hl) cp 4 jr nc,filp1b ; ID's niet goed ingevuld: zet op 255 cpl rrca ; write rl d rrca ; read rl e djnz fillpm pop hl ld (hl),e ; vul ID's in inc hl ld (hl),d jr filp1c fillp2: ex de,hl ; MSX tabel: read ID = 255, write ID = byte ld (hl),255 inc hl ld b,(ix) srl b inc b ld a,1 wid1a: rrca djnz wid1a ld (hl),a jr filp1c filp1b: pop de fillp1: ex de,hl ld (hl),255 ; oude DOS tabel: ID's 255 inc hl ld (hl),255 filp1c: inc hl redp01: ld a,(TabType) or a jr z,redp02 ; BERT ld bc,16 ; volgende partitie add ix,bc push hl push ix ; controle op laatste entry pop hl ld de,PSecBuf+1FEh rst DCOMPR pop hl jr c,redp03 redpbb: pop de pop af pop bc inc b redpzv: ld a,b redpzx: ld (NrParts),a and a ret redpzz: pop de pop af pop bc ld a,b ld (NrParts),a and a ret redp02: ld a,(PSecBuf+1D2h) cp 5 jr nz,redpbb ; Klaar pop de ; BERT: lees nieuwe partitiesector pop af ld c,(ix+24) ld b,(ix+25) ex de,hl add hl,bc ex de,hl adc a,(ix+26) ld c,a push af push de push hl ld b,1 ld hl,PSecBuf ld a,(TrgID) call RdPartSecs ld a,d or a jp nz,Error_1 ld ix,PSecBuf+1BEh pop hl redp03: pop de pop af pop bc inc b jp fillpl inidmap: ld hl,DrMAPDat ; Ini DrMAPDat ld b,8 redp22: ld (hl),255 inc hl djnz redp22 ret ; ** SECURITY ** C1_ADD: defb HIGH SecureC1 defb LOW SecureC1 ; ** Error_1: pop hl pop de pop af pop bc Error_0: scf ret ; RdPartSecs - Read Partition Sectors, with retries if necesarry ; Input : (TrgID) = Target ID ; B = # of blocks to read ; C D E = Start block ; HL = Data address ; Output: A = SCSI status ; D = Target Status ; E = Target Message ; Modify: BC,HL,IX,IY RdPartSecs: ld a,3 ; Max number of retries ld (MaxRet),a RetrPSR: push bc ; Save # of sectors & high block # push de ; Save block # low push hl ; Save data address ld a,(TrgID) ; Get Target ID call RdLogBlk ; Read blocks ld a,d ; Get Target Status and a ; Status GOOD? jr z,PartRdOk cp 2 ; CHECK CONDITION ? jr nz,PartRdOk ; No, just quit ld a,(TrgID) ; ID call GetSense inc d dec d ; GOOD? jr nz,PartRdOk ; No, quit and a ; NO SENSE? jr z,PartRdOk cp 6 ; UNIT ATTENTION? jr nz,PartRdOk ; No ld a,b ; Get Sense Code cp 29h ; POWER ON? jr z,RetryPSRd cp 30h ; MEDIUM error? jr nz,PartRdOk RetryPSRd: ld a,(MaxRet) dec a ld (MaxRet),a jr z,PartRdOk ; Retries exhausted pop hl pop de pop bc jr RetrPSR PartRdOk: ld hl,6 ; Dump saved paramters add hl,sp ld sp,hl ret ; ClrEndLn - Clear to End of Line ClrEndLn: CALL PRINT ; defb CR,ESC,'K',00h ret ; PartInfo - Calculate address of partition info of drive in Work Area ; 8 bytes / drive ; Input : A = drive # (0 - 5) ; Output: IX = Work Area address PartInfo: ADD A,A ; *2 ADD A,A ; *4 ADD A,A ; *8 LD E,A LD D,0 ; DE = A * 8 (A = drive no) CALL GETWRK ; Get work area in [IX] and [HL] ; ADD IX,DE ; IX = IX + (drvnr) * 8 RET ; GetUnitsOn - Get # of SCSI units online ; Input : - ; Output: A = # of units online, C = ID vector, D = HOST ID ; Modify: AF,BC,DE GetUnitsOn: ld a,2 out (REGSET),a ld a,12 out (RDWREG),a ; Set Timeout to 96ms call Get_Id cpl and 7 ld d,a ; D = HOST ID ld bc,0700h ; B = # of ID to test, C = # of units online ld a,c ld e,a ChkNxtId: cp d ; Host ID? jr z,UnNoRdy ; Yes, do not check this ID push bc push de call TstUnitRdy pop de pop bc cp 085h ; Ready? ; *M*0.49 jr nz,UnNoRdy ld a,c set 0,a ; Set LSB rrca ld c,a jr UnGoOn ; inc c UnNoRdy: ld a,c res 0,a ; Reset LSB rrca ld c,a ; *M* UnGoOn: inc e ; Next ID ld a,e djnz ChkNxtId ld a,2 out (REGSET),a ld a,7dh out (RDWREG),a ; Set Timeout to 1 second ld a,c ; Get # of units online rrca ld c,a ld b,8 ld e,0 CntUnits: rra jr nc,NotRDY inc e NotRDY: djnz CntUnits ld a,e ret ; DSKIO - Read / Write sectors ; ; Input : A = drive # (0 - 6) ; HL = transfer address ; DE = start sector ; B = # of sector to read ; C = media ID - F0h / F8h (for use with PC) ; Carry = 0 - read sectors otherwise write sectors (Carry = 1) ; Output: Carry = 0 - No error occurred ; Carry = 1 - error occurred -> A = error code, B = sectors remaining ; ; (error codes are taken from org. diskrom) ; 0 - Disk Write Protected ; 2 - Drive Not Ready ; 4 - CRC error ; 6 - Seek error ; 8 - Record Not Found ; 10 - Write error ; 12 - Bad parameter ; ; New DOS 2 errors: ; 18 - Not a DOS disk (DOS err) ; 20 - Incompatible disk (DOS err) ; ; 22 - Unformated disk (DOS err) ; ; Modify: all DSKIO: EI PUSH AF ; Save drive no. CP maxdrv ; Drive # exceeded max? JP NC,BADPRM ; Yes ; PUSH BC ; Save # of sectors & media ID PUSH DE ; Save start sector PUSH HL ; Save transfer address ; *M*v1.09.04 call DrvWork ; CALL PartInfo ; IX = work area address of curr. drv ; *N* ; POP HL POP DE POP BC POP AF ; C$4787: BIT 4,(IX+00h) ; 'Unformated disk'? JP NZ,NotFmt ; PUSH AF LD A,C ; Media ID ; *M*v1.02 cp 0f0h ; Normal MSX partition? jr z,MedIDok cp 0f8h ; PC partition? jp nz,BADPRM MedIDok: ; LD C,A ; C = 0 ld c,0 ; *M* PUSH DE ; Sector # LD A,B ; # of sectors to read DEC A ADD A,E LD E,A LD A,C ADC A,D LD D,A LD A,C ADC A,C LD C,A LD A,(IX+04h) ; Get max. sector # of current drive SUB E LD A,(IX+05h) SBC A,D LD A,0 SBC A,C POP DE ; Sector # JP C,J$485F ; LD A,E ; Calculate start sector # ADD A,(IX+01h) LD E,A LD A,D ADC A,(IX+02h) LD D,A LD A,0 ADC A,(IX+03h) LD C,A POP AF ; C D E = start sector # on HDD PUSH DE PUSH BC PUSH IX JR C,WRTSEC ; Carry = 1 > write sectors ; Test Purpose ; *N*E ; call Get_ID ; or 128 ; xor (ix+06h) ; and 10001111b ; jp nz,WrngID ; *N*E ; LD A,(IX+00h) ; Target ID CALL RdLogBlk ; JR J.4807 WRTSEC: ; *M*v1.09.04 call WrtPermit ; Permission to write? jp c,WrngID ; No ; call Get_ID ; *** ; OR 10000000b ; XOR (IX+06h) ; Network Write ID # ; AND 10001111b ; JP NZ,WrngID ; Wrong ID, not allowed to write ; *M* ; LD A,(IX+00h) ; Target ID PUSH AF ; Save ID PUSH BC ; Save # of blocks to read PUSH DE ; and save start block # PUSH HL ; Save data address ; *T*v1.05 ; bit 7,(ix+35h) ; Driver functions enabled? ; call nz,ChkDrvID ; Yes, check driver ID ; jp c,ToExtDrv ; Jump to driver ; *T* CALL WrLogBlk ; Write sector ; LD B,A LD A,(0F30Dh) ; Get VERIFY byte OR A ; VERIFY ON? JP Z,J.4801 ; No ; LD A,D OR A ; Status GOOD? JR NZ,J.4801 ; No ; call Get_ID ; *** BIT 4,A JR NZ,J.4801 ; POP HL POP DE POP BC POP AF CALL Verify ; Verify written blocks ; jr J.4807 J.4801: LD A,B LD HL,8 ADD HL,SP LD SP,HL ; Dump saved parameters J.4807: POP IX POP BC POP HL ; Sector # CP 42H LD A,2 ; 'Drive Not Ready' SCF RET Z ; LD A,D ; C$4812: OR A ; Status GOOD? RET Z ; Yes ; PUSH HL PUSH BC LD A,(IX+00h) ; Get Target ID PUSH IX CALL ReqSense ; POP HL ; Work Area address PUSH AF INC D DEC D ; Status GOOD? JR NZ,J$4843 ; No ; LD A,(IX+02h) ; Get (Extended) Sense Key CP 06h ; 'Unit Attention' ? JR NZ,J$4847 ; No ; PUSH HL ; ** SECURITY DUMMY ld hl,SECURE ; ** CALL GETWRK ; POP IX LD A,(IX+00h) ; Target ID OR 08H LD DE,8 LD B,6 J$483B: CP (HL) JR NZ,J$4840 ; RES 3,(HL) J$4840: ADD HL,DE DJNZ J$483B ; J$4843: POP AF POP BC POP DE RET ; ; ----------------- J$4847: POP AF POP BC POP DE BIT 7,(IX) ; Sense Data Valid ? RET Z ; No ; PUSH AF LD A,B SUB (IX+6) ADD A,E LD B,A POP AF RET ; Drive 'Write Protected' - Network Write ID # incorrect WrngID: POP AF POP BC POP AF LD A,0 ; 'Write protected error' SCF RET J$485F: LD A,(IX+04h) ; Get # of sectors in partition (MSB) SUB E LD C,A INC C LD A,(IX+05h) ; Get # of sectors in partition (LSB) SBC A,D JR C,J$487A ; LD A,B SUB C LD B,A POP AF PUSH BC LD B,C LD C,0F0H ; Media ID CALL C$4787 ; JR C,J$487F ; POP BC LD A,0F1H J$487A EQU $-1 ; 'POP AF' LD A,8 ; 'Sector not found' SCF RET ; ; ----------------- J$487F: POP DE PUSH AF LD A,B ADD A,D LD B,A POP AF RET ; Bad Parameter Error BADPRM: POP AF PRMBAD: LD A,12 ; 'Bad parameter' SCF ; Set carry to indicate error occurred RET ; Called from entry 4013h ; DSKCHG - Check if disk is changed ; Input : A = drive # (0-5) ; HL = base address of DPB ; Output: If Carry is set, reg A contains error code else ; register B contains diskstatus ; B = 1 , disk unchanged ; B = 0 , unknown ; B = 255, disk is changed ; Modify: AF,BC,DE,HL,IX DSKCHG: EI CP 6 ; Drive # > 5 JR NC,PRMBAD ; Yes ; OR A PUSH AF PUSH HL CALL PartInfo ; Get Work Area of current drive ; POP HL call Get_ID ; *** XOR (IX+06h) AND 7 JR NZ,J$48B2 ; POP AF LD B,1 BIT 3,(IX+00h) RET NZ ; SET 3,(IX+00h) CALL GETDPB ; LD B,255 RET ; ; ----------------- J$48B2: POP AF CALL GETDPB ; LD B,0 RET ; Called from entry 4016h (Get DPB address) ; GETDPB - Get Disk Parameter block ; Input : A = drive # ; HL = data address ; Output: if carry is set, the A contains error code ; Modify: AF,BC,DE,HL,IX,IY ; Disk Parameter Block: ; ; +00 - Drive # ; +01 - Media ID (0f0h) ; +02/03 - Bytes/sector (0200h) ; +04 - Directory mask ; +05 - Directory shift ; +06 - Cluster mask ; +07 - Cluster shift ; +08/09 - First FAT sector ; +0a - Number of FATs ; +0b - # of directory entries ; +0c/0d - First data sector ; +0e - # of clusters + 1 ; +10 - # of sectors/FAT ; +11/12 - First directory sector ; +13/14 - FAT address (not used) GETDPB: EI CP 6 ; Drive # > 5 ? JR NC,PRMBAD ; Yes ; PUSH AF PUSH HL CALL PartInfo ; Get drive work area of current drive ; in [IX] ; POP HL POP AF BIT 4,(IX+00h) JR Z,J$48CF ; NotFmt: LD A,22 ; 'Unformated disk' error SCF RET ; ; ----------------- J$48CF: PUSH HL LD HL,($SECBUF) ; Transfer to sectorbuffer PUSH HL LD A,(IX+00h) ; Target ID LD B,1 ; 1 sector read LD C,(IX+03h) LD D,(IX+02h) LD E,(IX+01h) ; Form first sector # of partition CALL RdLogBlk ; Read bootsector ; POP IY ; Sectorbuffer address POP IX ; Memory address LD A,D CALL C$4812 ; Request Sense ; RET C ; Error ; LD A,(IY+15h) ; Get Media descriptor LD (IX+01h),A CP 0F0h LD A,18 ; 'Not a DOS disk' error SCF RET NZ ; LD L,(IY+0eh) LD H,(IY+0fh) ; Get # of reserved sectors LD (IX+08h),L LD (IX+09h),H ; Store LD A,(IY+10h) ; Get # of FATs LD (IX+10),A LD E,(IY+16h) LD D,(IY+17h) ; Get # of sectors/FAT LD (IX+16),E LD B,A J$4916: ADD HL,DE DJNZ J$4916 ; LD (IX+17),L LD (IX+18),H LD E,(IY+11h) LD D,(IY+12h) ; Get # of directory entries LD (IX+11),E LD C,(IY+0bh) LD B,(IY+0ch) ; Get # of bytes/sector LD (IX+2),C LD (IX+3),B SRL B RR C SRL B RR C SRL B RR C SRL B RR C SRL B RR C DEC C LD (IX+4),C ADD A,E LD E,A RL D J$4950: INC B RR C JR C,J$4950 ; DEC B LD (IX+5),B J$4959: SRL D RR E DJNZ J$4959 ; ADD HL,DE LD (IX+12),L LD (IX+13),H EX DE,HL LD L,(IY+13h) LD H,(IY+14h) ; Get total # sectors OR A SBC HL,DE LD A,(IY+0dh) ; Get # of sectors/cluster DEC A LD (IX+6),A J$4977: INC B RRCA JR C,J$4977 ; LD (IX+7),B DEC B JR Z,J$4987 ; J$4981: SRL H RR L DJNZ J$4981 ; J$4987: INC HL LD (IX+14),L LD (IX+15),H OR A RET CHOICE: LD HL,FmtMsg RET ; FmtMsg: DEFM CR,LF defm '1 - Write protect partition',CR,LF DEFM '2 - Write enable partition',CR,LF,CR,LF,0 ; DSKFMT - 'Format' disk (write enable- or protect partition) ; Input : A = choice, D = drive # ; Output: Carry = 1 > error, A contains error code: A = 12 Bad Parameter ; Modify: AF,DE,HL,IX DSKFMT: LD E,A CP 3 ; Choice within range? JR NC,WrngChc ; No ; LD A,D CP 6 ; Drive # within range? WrngChc: LD A,12 ; Bad Parameter CCF RET C ; DEC E ; Choice was 0? SCF RET M ; Yes ; PUSH DE ; D = drive, E = choice (0 - 1) LD A,D CALL PartInfo ; Get Work Area of drive # ; POP DE LD D,0 LD HL,Table2 ADD HL,DE ADD HL,DE LD A,(HL) INC HL LD H,(HL) LD L,A JP (HL) ; Write Enable- or Protect Partition Table2: defw WpPart defw WePart ; Write enable partition WePart: call Get_ID xor (ix+06h) and 7 jr z,FmtIDok ; Host is allowed to WE partition DskWP: ld a,0 ; 'Disk Write Protected' scf ret FmtIDok: set 7,(ix+06h) ret ; SET 7,(IX+06h) ; call Get_ID ; **** ; XOR (IX+06h) ; AND 7 ; RET Z ; ; LD A,0 ; 'Disk Write Protected' ; SCF ; RET ; Write protect partition WpPart: RES 7,(IX+6) RET ; ?.4A08: SCF ; RET ; Logically format partition ; ;LogFmt: bit 7,(ix+06h) ; Disk write protected? ; jr z,DskWP ; Yes ; call Get_ID ; xor (ix+06h) ; and 7 ; Is host allowed to format? ; jr nz,DskWP ; No ; ld a,6 ; Just for test ; scf ; ret ; ** SECURITY ** C2_ADD: defb HIGH SecureC2 defb LOW SecureC2 ; ** ; Called from entry 401fh ; STPDRV - Stop all connected drives ; Input : - ; Output: - ; Modify: AF,BC,DE,HL,IX STPDRV: CALL GETWRK ; LD BC,6 OR C J$4A11: LD A,(HL) PUSH HL PUSH BC PUSH AF CALL NZ,StrtStpUn ; POP AF POP BC POP HL J$4A1B: DEC C RET Z ; LD DE,8 ADD HL,DE BIT 4,(HL) JR NZ,J$4A1B ; XOR (HL) AND 0E7H JR J$4A11 ; SetHOST_ID - Set host ID ; Input : A = ID (4-7) ; Output: Carry is set when error occurred ; Modify: AF,D SetHOST_ID: cp 4 ret c cp 8 ret nc ROM_SetHost: ld d,a push bc push de push hl xor a out (REGSET),a out (RDWREG),a ; Set Own ID to zero ; *M*v0.45 ld a,2 call CLKMOD ld b,12 call REDRAM and 00001100b ; Bit 2 and 3 must be saved res 2,a or d ; *M* ld a,2 call CLKMOD ld b,12 call WRTRAM ; Store new ID call SetWD3393 ; Reinitialise pop hl pop de pop bc ret ; SndDiag - 'Send Diagnostics' (perform Self Test) ; Input : A = LUN + ID ; Output: A = SCSI status ; E = msg, D = Target Status SndDiag: PUSH AF ; ID LD A,03H OUT (REGSET),A LD A,SENDIAG ; Send Diagnostic command OUT (RDWREG),A POP AF PUSH AF AND 11100000b PUSH AF OR 00000100b ; Set SelfTest bit JR J$4C34 ; TstUnitRdy - 'Test Unit Ready' ; Input : A = ID ; Output: A = SCSI status ; D = Target Status ; E = msg ; Modify: AF,bC, TstUnitRdy: PUSH AF ; ID LD A,03H OUT (REGSET),A XOR A OUT (RDWREG),A ; Test Unit Ready command POP AF PUSH AF AND 11100000b PUSH AF J$4C34: OUT (RDWREG),A ; Logical Unit Number LD C,RDWREG XOR A OUT (RDWREG),A ; Reserved OUT (RDWREG),A ; Reserved OUT (RDWREG),A ; Reserved JR J$4C5A ; StrtStpUn - 'Start / Stop Unit' ; Input : A = ID ; B = 0 - Stop Unit ; B = 1 - Start Unit ; Output: A = SCSI status, D = Target Status, E = msg StrtStpUn: PUSH AF ; ID LD A,03H OUT (REGSET),A LD A,STSTOP ; Start / Stop Unit command OUT (RDWREG),A POP AF PUSH AF AND 11100000b PUSH AF OUT (RDWREG),A ; Logical Unit Number LD C,RDWREG XOR A OUT (RDWREG),A ; Reserved OUT (RDWREG),A ; Reserved OUT (C),B ; Start / Stop J$4C5A: OUT (RDWREG),A ; 0 LD A,0FH OUT (REGSET),A POP AF RLCA RLCA RLCA OUT (RDWREG),A ; Target LUN LD A,12H OUT (REGSET),A XOR A OUT (RDWREG),A ; Transfer count (MSB) OUT (RDWREG),A ; Transfer count OUT (RDWREG),A ; Transfer count (LSB) POP AF AND 07H OUT (RDWREG),A ; Destination ID J.4C76: IN A,(AUXSTAT) OR A ; Interrupt pending? JP P,J$4C8A ; No ; LD A,17H OUT (REGSET),A EX (SP),HL EX (SP),HL IN A,(RDWREG) ; Read SCSI status OR A ; Reset state? CALL Z,SetWD3393 ; Yes ; JR J.4C76 J$4C8A: AND 00110000b ; Level 2 Command In Progress? JR NZ,J.4C76 ; Yes ; LD IX,RT_01 CIP_5: IN A,(AUXSTAT) AND 00010000b ; Command In Progress ? JR NZ,CIP_5 ; Yes ; LD A,10h OUT (REGSET),A XOR A OUT (RDWREG),A ; Set Command Phase LD A,18H OUT (REGSET),A LD A,SelATNTrn ; Select-with-!ATN and-Transfer OUT (RDWREG),A JP TermAct ; RdLogBlk - Read Sector Direct ; Input : A = ID ; B = # of sectors to read ; C D E = 21 bits sector # ; HL = transfer address ; ; Output: ; A = SCSI status ; D = Target Status ; E = msg ; HL = data address RdLogBlk: PUSH AF ; Save SCSI ID LD A,3 OUT (REGSET),A LD A,READ ; Direct Access read cmd OUT (RDWREG),A POP AF ; ID PUSH AF AND 11100000b PUSH AF OR C ; Form LUN + Log. Block Addr. (MSB) OUT (RDWREG),A LD C,RDWREG OUT (C),D ; Logical Block Address OUT (C),E ; Logical Block Address (LSB) XOR A OUT (C),B ; Transfer length (blocks) ; OUT (RDWREG),A out (c),a LD A,0FH OUT (REGSET),A ; Select target LUN register POP AF RLCA RLCA RLCA ; OUT (RDWREG),A ; Set target LUN out (c),a LD A,12H OUT (REGSET),A XOR A ; OUT (RDWREG),A ; Transfer count (MSB) out (c),a SLA B ; Calculate # of bytes to read OUT (C),B ; Transfer count OUT (RDWREG),A ; Transfer count (LSB) POP AF ; SCSI ID AND 07H out (c),a ; OUT (RDWREG),A ; Set Destination ID Level2_CIP: IN A,(AUXSTAT) ; Read Auxiliary status OR A ; Interrupt pending? JP P,NoIntP_1 ; No ; LD A,17H OUT (REGSET),A ; Interrupt pending EX (SP),HL EX (SP),HL IN A,(RDWREG) ; Read SCSI status OR A ; Reset state ? CALL Z,SetWD3393 ; Yes ; JR Level2_CIP ; NoIntP_1: AND 00110000b ; Level II command in progress? JR NZ,Level2_CIP ; Yes ; LD IX,RT_02 CIP_6: IN A,(AUXSTAT) AND 00010000b ; Command In Progress ? JR NZ,CIP_6 ; Yes ; LD A,10h OUT (REGSET),A XOR A OUT (RDWREG),A ; Set command phase to disconnect state LD A,18h OUT (REGSET),A LD A,SelATNTrn ; Select-with-!ATN and-Transfer OUT (RDWREG),A LD A,19h OUT (REGSET),A ; Select Data Register ; ** SECURITY call RdToggles rrca jr c,SecSlowRd ; ** CALL FastExec ; Change CPU mode and move transfer ; routine to sectorbuffer ; This part of code can be moved to the sectorbuffer for highspeed data ; transfer ; *** BEGMOV *** GetData: IN A,(AUXSTAT) ; (2) RRCA ; (1) Data Buffer Ready? JR NC,BufNrdy_1 ; (2) No ld b,64 ; (2) inir ; (2) JR GetData ; (2) nop ; (1) nop ; (1) BufNrdy_1: AND 01000000b ; (2) Interrupt pending? JR NZ,IntP_1 ; (2) Yes ; JR GetData ; (2) ; *** ENDMOV *** IntP_1: call TbrCPUres ; Restore CPU mode when Turbo-R JP TermAct ; Terminate actions ; *** SECURITY *** SecSlowRd: IN A,(AUXSTAT) ; (2) RRCA ; (1) Data Buffer Ready? JR NC,SecBufNrdy ; (2) No ini ; (2) JR SecSlowRd ; (2) nop ; (1) nop ; (1) nop ; (1) nop ; (1) SecBufNrdy: AND 01000000b ; (2) Interrupt pending? JR NZ,SecIntP ; (2) Yes ; JR SecSlowRd ; (2) SecIntP: call TbrCPUres ; Restore CPU mode when Turbo-R JP TermAct ; Terminate actions ; ModeSel - 'Mode Select' ; Input : A = LUN + ID ; B = Parameter List Length ; ; Output: A = SCSI Status ; D = Target status ; E = Message ModeSel: EI PUSH AF ; Save ID LD A,03H OUT (REGSET),A LD A,MODSEL ; Mode Select command OUT (RDWREG),A POP AF PUSH AF AND 11100000b ; Form Target LUN PUSH AF OUT (RDWREG),A LD C,RDWREG XOR A OUT (RDWREG),A ; Reserved OUT (RDWREG),A ; Reserved OUT (C),B ; Parameter List Length OUT (RDWREG),A ; 0 LD A,0FH OUT (REGSET),A POP AF RLCA RLCA RLCA OUT (RDWREG),A ; Target LUN LD A,12H OUT (REGSET),A XOR A OUT (RDWREG),A ; Transfer count (MSB) OUT (RDWREG),A ; Transfer count OUT (C),B ; Transfer count (LSB) JP J.50BC ; FmtUnit - 'Format Unit' ; Input : A = ID , B = FmtData, CmpLst, Defect List Format ; DE = interleave (MSB - LSB) ; HL = address for format data ; Output: FmtUnit: EI PUSH AF ; Save ID LD A,03H OUT (REGSET),A LD A,FORMAT OUT (RDWREG),A POP AF PUSH AF AND 11100000b PUSH AF OR B OUT (RDWREG),A ; Target LUN, FmtData, CmpLst, Defect ; List Format LD C,RDWREG XOR A OUT (RDWREG),A ; 0 OUT (C),D ; Interleave (MSB) OUT (C),E ; Interleave (LSB) OUT (RDWREG),A ; 0 LD A,0FH OUT (REGSET),A POP AF RLCA RLCA RLCA OUT (RDWREG),A ; Target LUN LD A,12H OUT (REGSET),A XOR A OUT (RDWREG),A ; Transfer count (MSB) LD D,A LD E,A BIT 4,B ; FmtData = 1 ? JR Z,J$4DA6 ; No ; PUSH HL INC HL INC HL LD D,(HL) INC HL LD E,(HL) POP HL INC DE INC DE INC DE INC DE J$4DA6: OUT (C),D ; Transfer count (defect list length?) OUT (C),E ; Transfer count (LSB) JP J.50BC ; Verify - 'Verify' ; Input : A = ID, B = Verification Length ; C D E = 21 bits Logical Block # ; Output: Verify: PUSH AF ; ID LD A,03H OUT (REGSET),A LD A,_VERIFY ; Verify command OUT (RDWREG),A POP AF PUSH AF AND 11100000b PUSH AF OUT (RDWREG),A ; Logical Unit Number XOR A OUT (RDWREG),A ; Logical Block Address (MSB) LD A,C OUT (RDWREG),A ; Logical Block Address LD C,RDWREG OUT (C),D ; Logical Block Address OUT (C),E ; Logical Block Address (LSB) XOR A OUT (RDWREG),A ; Reserved OUT (RDWREG),A ; Verification Length (MSB) OUT (C),B ; Verification Length (LSB) OUT (RDWREG),A ; 0 LD A,0FH OUT (REGSET),A POP AF RLCA RLCA RLCA OUT (RDWREG),A ; Target LUN LD A,12H OUT (REGSET),A XOR A OUT (RDWREG),A ; Transfer count (MSB) SLA B ; Calc # of bytes to compare OUT (C),B ; Transfer count OUT (RDWREG),A ; Transfer count (LSB) JP J.50BC ; WrLogBlk - Write Sector Direct ; Input : A = ID ; B = # of sectors to read ; C D E = 21 bits sector # ; HL = transfer address ; Output: A = ; D = Target Status ; E = msg WrLogBlk: PUSH AF ; Save ID LD A,03H OUT (REGSET),A LD A,WRITE ; Write command OUT (RDWREG),A POP AF ; ID PUSH AF AND 11100000b PUSH AF OR C OUT (RDWREG),A ; Target LUN + Log. Block Addr. (MSB) LD C,RDWREG OUT (C),D ; Logical Block Address OUT (C),E ; Logical Block Address (LSB) XOR A OUT (C),B ; Transfer Length OUT (RDWREG),A ; 0 LD A,0FH OUT (REGSET),A POP AF ; Target LUN (always 0) RLCA RLCA RLCA OUT (RDWREG),A ; Write Target LUN register LD A,12H OUT (REGSET),A XOR A OUT (RDWREG),A ; Transfer count (MSB) SLA B ; Calculate # of bytes to be transf. OUT (C),B ; Transfer count OUT (RDWREG),A ; Transfer count (LSB) POP AF ; ID AND 07h OUT (RDWREG),A ; Destination ID J.4E24: IN A,(AUXSTAT) ; Read Auxiliary status OR A ; Interrupt pending JP P,J$4E38 ; No ; LD A,17H OUT (REGSET),A EX (SP),HL EX (SP),HL IN A,(RDWREG) ; Read SCSI status OR A ; Reset State? CALL Z,SetWD3393 ; Yes ; JR J.4E24 J$4E38: AND 00110000b ; BuSY? , Command In Progress? JR NZ,J.4E24 ; LD IX,RT_03 J$4E40: IN A,(AUXSTAT) AND 00010000b ; Command In Progress? JR NZ,J$4E40 ; Yes ; LD A,10H OUT (REGSET),A XOR A OUT (RDWREG),A ; Command Phase = 0 LD A,18H OUT (REGSET),A LD A,SelATNTrn ; Select-with-!ATN and-Transfer OUT (RDWREG),A LD A,19H OUT (REGSET),A ; Select data register CALL FastExec ; ***** BEGMOV ***** WrLogBlk WrData: IN A,(AUXSTAT) RRCA ; Data Buffer Ready? JR NC,BufNrdy2 ; No ; LD B,4 ; Write 4 bytes a time OTIR nop nop JR WrData BufNrdy2: AND 01000000b ; Interrupt pending? JR NZ,IntP_2 JR WrData ; ***** ENDMOV **** WrLogBlk IntP_2: call TbrCPUres jp TermAct ; FastExec - Move Read/Write code to RAM and execute command ; (only when Transfer address and $SECBUF address do not overlap) FastExec: call TbrCPUset BIT 7,H ; Transfer address above 7FFFh ? JR Z,Pag1_Trn ; No LD DE,($SECBUF) ; Get address of sectorbuffer LD A,E ; Compare DE and HL SUB L JR NZ,MovCode ; Lower bytes don't match ; LD A,D SUB H AND 3FH RET Z ; DE = HL, so the transfer program ; can not be moved to RAM (secbuff) ; just execute transfer routine ; in (slow) ROM ; ***** following comments are for RdLogBlk only ***** MovCode: EX (SP),HL ; HL = (SP) = GetData ; (SP) = transfer address ($SECBUF) PUSH BC ; Save # of sectors (reg. B) LD BC,19 ; 19 bytes to be transfered LDIR ; Move to sectorbuffer LD A,0c9h LD (DE),A ; Put 'RET' at end of code POP BC EX (SP),HL ; HL = transf. addr, (SP) = ret. addr LD IY,($SECBUF) JP (IY) ; Execute routine (Read sectors) ; Transfer address < 8000h Pag1_Trn: EX (SP),HL ; HL = GetData, (SP) = transf. addr. PUSH BC ; Save # of sectors to read (reg. B) PUSH HL ; Save address of tranf. routine LD BC,6 LD DE,($SECBUF) LD HL,SltRtn ; Slot routine LDIR ; Move to sectorbuffer EX (SP),HL ; HL = 4D1AH, (SP) = 4ECEh+6h LD BC,19 LDIR ; Move transf. routine EX (SP),HL ; HL = 4ECEh+6h, (SP) = 4D1Ah + 19 LD BC,16 LDIR CALL WHEREAMI ; Get slot ID ; POP HL ; HL = 4D1AH POP BC ; B = # sectors to read EX (SP),HL ; HL = 4D1Ah + 19, (SP) = 4ECEh+6+16 LD IY,($SECBUF) ; Get sectorbuffer address LD (IY+26),A ; Store slot ID LD A,(RAMAD1) ; Get RAM slot ID for page 1 PUSH IX PUSH BC PUSH HL LD H,40H JP (IY) ; Enable RAM slot and read sectors ; Moved when transfer address < 8000h SltRtn: CALL ENASLT ; 3 ; POP HL ; 1 POP BC ; 1 EI ; 1, total = 6 ; Moved when transfer address < 8000h PUSH HL ; 1 CALL 0F368h ; 3 ; LD A,0 ; 2 (value 00h is replaced by ROM slot ID) LD H,40H ; 2 CALL ENASLT ; 3 ; POP HL ; 1 POP IX ; 2 EI ; 1 RET ; 1, tot. = 16 ; ***** End RdLogBlk comments ***** ; ReqSense - 'Request Sense' (12h bytes) (Extended Sense Data Format) ; Input : A = LUN + ID ; Output: Carry flag set when error occurred ; A = error code (DOS error code) ; ; ; IX = address of sectorbuffer filled with Sense info ReqSense: PUSH AF ; Save ID LD A,03H OUT (REGSET),A OUT (RDWREG),A ; Request Sense command POP AF PUSH AF AND 11100000b ; Logical Unit Number PUSH AF OUT (RDWREG),A LD C,RDWREG XOR A OUT (RDWREG),A ; Reserved OUT (RDWREG),A ; Reserved LD B,12H OUT (C),B ; Allocation length = 12h OUT (RDWREG),A ; 0 LD A,0FH OUT (REGSET),A POP AF ; Logical Unit Number RLCA RLCA RLCA OUT (RDWREG),A ; Target LUN LD A,12H OUT (REGSET),A XOR A OUT (RDWREG),A ; Transfer count (MSB) OUT (RDWREG),A ; Transfer count OUT (C),B ; Transfer count (LSB) POP AF AND 07H OUT (RDWREG),A ; Destination ID LD HL,($SECBUF) ; Get address of sectorbuffer PUSH HL CALL C.506B ; Execute command ; POP IX ; Address of sectorbuffer CP 42h LD A,2 ; 'Drive Not Ready' SCF RET Z ; BIT 3,D ; Status BUSY? LD A,24 ; SCF RET NZ ; INC D DEC D ; Status GOOD? LD A,12 ; Bad Parameter SCF RET NZ ; No ; ; Noextended Sense Data Format ; ; ======================================================================= ; Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; Byte | | | | | | | | | ; ======================================================================= ; 0 |AdValid| Error Class | Error Code | ; ----------------------------------------------------------------------- ; 1 | Vendor Unique | Logical Block Address (MSB) | ; ----------------------------------------------------------------------- ; 2 | Logical Block Address | ; ----------------------------------------------------------------------- ; 3 | Logical Block Address (LSB) | ; ----------------------------------------------------------------------- LD A,(IX) AND 01111111b CP 70H ; Error Class 7? LD A,12 ; Bad Parameter SCF RET NZ ; No ; ; Extended Sense Data Format ; ; ======================================================================= ; Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; Byte | | | | | | | | | ; ======================================================================= ; 0 | Valid | Error Class (7) | Error Code (0) | ; ----------------------------------------------------------------------- ; 1 | Segment Number | ; ----------------------------------------------------------------------- ; 2 |Filemark| EOM | ILI |Reservd| Sense Key | ; ----------------------------------------------------------------------- ; 3 | Information Byte (MSB) | ; ----------------------------------------------------------------------- ; 4 | Information Byte | ; ----------------------------------------------------------------------- ; 5 | Information Byte | ; ----------------------------------------------------------------------- ; 6 | Information Byte (LSB) | ; ----------------------------------------------------------------------- ; 7 | Additional Sense Length (n) | ; ----------------------------------------------------------------------- ; 8 - | Additional Sense Bytes | ; n+7 | | ; ----------------------------------------------------------------------- LD A,(IX+12) ; Get Sense Code ; CP 0A0H ; Sense Code > 0a0h ? ; *M*v0.10 cp 2BH ; Sense Code > 2ah? ; *M* LD E,A JR NC,OutRange ; Yes ; LD HL,SnsTable ADD HL,DE LD A,(HL) OR A SCF RET P ; call Get_ID AND 20H RET NZ ; OutRange: LD A,12 ; Bad Parameter SCF RET ; Inquiry - 'Inquiry' (24h bytes) ; Input : A = ID ; HL = transfer address ; Output: A = error code ; A = 42h > error ; A = 85h > Ok ; ; 'Inquiry' data: ; Transfer address + 00h - Device Type Code ; + 01h - ; + ; ; Inquiry: PUSH AF ; ID LD A,03H OUT (REGSET),A LD A,INQUIR ; Inquiry command OUT (RDWREG),A POP AF PUSH AF AND 11100000b PUSH AF OUT (RDWREG),A ; Logical Unit Number LD C,RDWREG XOR A OUT (RDWREG),A ; Reserved OUT (RDWREG),A ; Reserved LD B,24H OUT (C),B ; Allocation Length - 24h bytes OUT (RDWREG),A JR J.5051 ; ModeSense - 'Mode Sense' (max. 128 bytes) ; Input : A = LUN + ID ; HL = transfer addres ; B = Page Control Field & Page Code ; ; bits 7 - 6 - 00b = Actual value ; 01b = Changeable value ; 10b = Default value ; 11b = vastgezette waarde ; bits 5 - 0 - page code ; ; Mode-Parameters for magnet discs ; ; 01h - Read/Write error ; 02h - Disconnect/Reconnect ; 03h - Format ; 04h - Non removable HDD-geometrie ; 05h - Floppy disc ; 07h - Verify-error ; 08h - Cache ; 09h - Peripheral ; 0Ah - Steuermodus-Seite ; 0Bh - Mediatype ; 0Ch - Notch ; Output: A = SCSI Status ; D = Target status ; E = Message ModeSense: PUSH AF ; ID LD A,3 OUT (REGSET),A LD A,MODSNS ; Mode Sense command OUT (RDWREG),A POP AF PUSH AF AND 11100000b PUSH AF OUT (RDWREG),A ; Logical Unit Number LD C,RDWREG OUT (C),B ; Page Code XOR A OUT (RDWREG),A ; Reserved LD B,128 OUT (C),B ; Allocation Length = 128 bytes OUT (RDWREG),A ; 0 JR J.5051 ; ReadCap - 'Read Capacity' ; Input : A = ID ; HL = transer address (8h bytes) ; Output: A = error code ; A = 42h > error ; A = 85h > Ok ; Read Capacity Data (8 bytes) ; transfer address + 00h - 03h -> # of sector on HDD (MSB - LSB) ; " " + 04h - 07h -> sector size (MSB - LSB) always 512 on HDD ReadCap: PUSH AF ; ID LD A,03H OUT (REGSET),A LD A,RDCAPAC ; Read Capacity command OUT (RDWREG),A POP AF PUSH AF AND 11100000b PUSH AF OUT (RDWREG),A ; Logical Unit Number LD C,RDWREG XOR A LD B,08H J$504B: OUT (RDWREG),A ; 8 * 0 DJNZ J$504B ; LD B,08H J.5051: LD A,0FH OUT (REGSET),A POP AF RLCA RLCA RLCA OUT (RDWREG),A ; Target LUN LD A,12H OUT (REGSET),A XOR A OUT (RDWREG),A ; Transfer count (MSB) OUT (RDWREG),A ; Transfer count OUT (C),B ; Transfer count (LSB) 8 bytes POP AF AND 07H OUT (RDWREG),A ; Destination ID ; C.506B: IN A,(AUXSTAT) ; Read Auxiliary Status OR A ; Interrupt Pending? JP P,J$507F ; No ; LD A,17H OUT (REGSET),A EX (SP),HL EX (SP),HL IN A,(RDWREG) ; Read SCSI status OR A ; Reset State ? CALL Z,SetWD3393 ; Yes ; JR C.506B J$507F: AND 00110000b ; BuSY? , Command In Progress ? JR NZ,C.506B ; Yes ; LD IX,RT_02 ; CIP_7: IN A,(AUXSTAT) AND 00010000b ; Command In Progress? JR NZ,CIP_7 ; Yes ; LD A,10H OUT (REGSET),A XOR A OUT (RDWREG),A ; Set Command Phase LD A,18H OUT (REGSET),A LD A,SelATNTrn OUT (RDWREG),A ; Select-with-!ATN and-Transfer LD A,19H OUT (REGSET),A ; Select data register CALL FastExec ; Read Capacity (or other) ; *** BEGMOV ReadCap *** J.50A3: IN A,(AUXSTAT) RRCA ; Data Buffer Ready ? JR NC,J$50B0 ; INI JR J.50A3 DEFB 0,0,0,0 ; Dummy J$50B0: AND 01000000b ; Interrupt Pending ? JR NZ,J$50B6 ; Yes ; JR J.50A3 ; *** ENDMOV ReadCap *** J$50B6: call TbrCPUres JP TermAct J.50BC: POP AF AND 7 OUT (RDWREG),A ; Destination ID Level2_CIP2: IN A,(AUXSTAT) ; Read Auxiliary Status OR A ; Interrupt Pending? JP P,J$50D5 ; No ; LD A,17H OUT (REGSET),A EX (SP),HL EX (SP),HL IN A,(RDWREG) ; Read SCSI status OR A ; Reset state? CALL Z,SetWD3393 ; Yes ; JR Level2_CIP2 J$50D5: AND 00110000b ; Level 2 Command In Progress? JR NZ,Level2_CIP2 ; Yes ; LD IX,RT_03 CIP_8: IN A,(AUXSTAT) AND 00010000b ; Command In Progress? JR NZ,CIP_8 ; Yes ; LD A,10H OUT (REGSET),A XOR A OUT (RDWREG),A ; Set Command Phase LD A,18H OUT (REGSET),A LD A,SelATNTrn ; Select-with-!ATN and-Transfer OUT (RDWREG),A LD A,19H OUT (REGSET),A ; Select data register CALL FastExec ; *** BEGMOV xxxxx *** J.50F9: IN A,(AUXSTAT) ; Read Auxiliary status RRCA ; Data Buffer Ready? JR NC,J$5106 ; No ; OUTI JR J.50F9 DEFB 0,0,0,0 ; Dummy J$5106: AND 01000000b ; Interrupt pending? JR NZ,IntP_3 ; Yes ; JR J.50F9 ; *** ENDMOV xxxxx *** IntP_3: call TbrCPUres JP TermAct ; RdDefect - Read Defecf Data ; Input : A = LUN + ID ; B = Plist, Glist and Defect List Format ; DE = Allocation length ; HL = Data address ; Output: A = SCSI Status ; D = Target Status ; E = Target msg ; Modify: RdDefect: push af ld a,3 out (REGSET),a ld a,RDEFDAT out (RDWREG),a pop af push af and 11100000b push af out (RDWREG),a ; Logical Unit Number ld c,RDWREG out (c),b ; PList, GList and Defect List Format xor a out (c),a ; Reserved out (c),a ; Reserved out (c),a ; Reserved out (c),a ; Reserved out (c),d ; Allocation length (MSB) out (c),e ; Allocation length (LSB) out (c),a fill_regs: ld a,0fh out (REGSET),a pop af ; Target LUN rlca rlca rlca out (c),a ld a,12h out (REGSET),a xor a out (c),a ; Transfer count (MSB) out (c),d ; Transfer count (2ND) out (c),e ; Transfer count (LSB) pop af and 7 out (c),a ; Destination ID jp C.506B ; Execute command ; Copy - SCSI COPY function ; Input : A = LUN + ID ; DE = Parameter List length ; HL = data address ; Output: A = SCSI Status ; D = Target Status ; E = Target message ; Modify: Copy: push af ld a,3 out (REGSET),a ld a,COPY_ out (RDWREG),a ; Copy command pop af push af and 11100000b push af out (RDWREG),a ; Logical Unit Number ld c,RDWREG xor a out (c),a ; Parameter List Length (MSB) out (c),d ; Parameter List Length out (c),e ; Parameter List Length (LSB) out (c),a ; 0 jr fill_regs ; MedRemoval - PREVENT ALLOW MEDIUM REMOVAL ; Input : A = LUN + ID ; B = 0 = Prevent disabled, 1 = Prevent enabled ; Output: A = SCSI Status ; D = Target Status ; E = Target message ; Modify: MedRemoval: push af ld a,3 out (REGSET),a ld a,MEDREM out (RDWREG),a ; PREVENT ALLOW MEDIUM REMOVAL command pop af push af and 11100000b push af out (RDWREG),a ; Logical Unit Number ld c,RDWREG xor a out (c),a ; Reserved out (c),a ; Reserved out (c),b ; Prevent out (c),a ; Control jp J$4C5A ; TermAct - Terminate (HDD) Actions ; Output: D = Target Status, E = message, A = SCSI status TermAct: ; Terminate Actions MAK 3.0 LD DE,0008h ; D = 0 status GOOD ; , E = 8 NO OPERATION msg LD C,RDWREG TermLp: IN A,(AUXSTAT) BIT 0,A ; Data Buffer Ready? JP NZ,Jx4BBD ; Yes ; BIT 5,A ; BuSY? JR NZ,TermLp ; Yes ; LD A,17H OUT (REGSET),A nop nop IN A,(RDWREG) ; Read SCSI status ; Filter possible bug in the WD33C93A cp 4 jr nz,no4bug res 2,a no4bug: BIT 3,A ; MCI contains new SCSI bus phase? JR NZ,GetNwPh ; Yes ; CP 16H ; A Select-and-Transfer cmd compl succ? JP Z,Jx4BB4 ; Yes ; BIT 4,A ; Successful Completion Interrupt? RET NZ ; Yes ; OR A ; Reset state ; JP Z,Cx4BC3 ; Yes jp z,SetWD3393 ; CP 21H ; Save Data Pointer? JR NZ,Jx4AFC ; No ; PUSH HL POP IY DEC A Jx4AFC: CP 20H ; Message ready JP Z,Jx4B9C ; Yes ; CP 85H ; Disconnect occurred? JR NZ,Jx4B0A ; No ; BIT 7,D ; Service Required Interrupt? RET Z ; No ; JR TermLp ; ; ----------------- Jx4B0A: CP 80H ; Reselected? JR NZ,Jx4B12 ; No ; RES 7,D JR TermLp ; ; ----------------- Jx4B12: BIT 6,A ; Terminated Interrupt? JR NZ,Jx4B18 ; No ; OUT (HARDWR),A ; Reset WD3393 Jx4B18: LD D,02H ; D = 2, CHECK CONDITION RET ; GetNwPh: AND 07H LD B,A LD A,18H OUT (REGSET),A LD A,TransInfo+128 ; Transfer Info (one single byte) OUT (RDWREG),A Jx4B26: IN A,(AUXSTAT) RRCA ; Data Buffer Ready? JR NC,Jx4B26 ; No ; LD A,19H OUT (REGSET),A ; Select Data register INC B DJNZ Jx4B36 ; RT_03: Ix4B32: OUTI ; Data Out Phase call RT_01 jp TermLp ; ; ----------------- Jx4B36: DJNZ Jx4B3D ; RT_02: Ix4B38: INI ; Data In Phase call RT_01 JP TermLp ; ; ----------------- Jx4B3D: DJNZ Jx4B44 ; Jx4B3F: XOR A ; Command Phase OUT (RDWREG),A jp TermLp ; ; ----------------- Jx4B44: DJNZ Jx4B4A ; IN D,(C) ; Status Phase jp TermLp ; ; ----------------- Jx4B4A: DJNZ Jx4B4F ; JP Jx4B3F ; Unspecified Info Out Phase ; ; ----------------- Jx4B4F: DJNZ Jx4B56 ; IN A,(RDWREG) ; Unspecified Info In Phase JP TermLp ; ; ----------------- Jx4B56: DJNZ Jx4B5F ; OUT (C),E ; Message Out Phase LD E,08H JP TermLp ; ; ----------------- Jx4B5F: IN A,(C) ; Message In Phase JP Z,TermLp ; Command Complete msg ; JP M,TermLp ; Identify ; CP 02H ; Save Data Pointers? JR Z,Jx4B90 ; Yes ; CP 03h ; Restore Pointers? JR Z,Jx4B96 ; Yes ; CP 04h ; Disconnect? JR Z,Jx4B85 ; Yes ; CP 07h ; Message Reject? JR Z,Jx4B8A ; Yes ; CP 08h ; No Operation? JP Z,TermLp ; Yes ; CP 09H ; Message Parity Error? JR Z,Jx4B8A ; Yes ; LD E,07H ; Message Reject JP TermLp ; ; ----------------- Jx4B85: SET 7,D ; Service Required Interrupt JP TermLp ; ; ----------------- Jx4B8A: LD DE,0206h ; D = Check Condition, E = Abort JP TermLp ; ; ----------------- Jx4B90: PUSH HL POP IX JP TermLp ; ; ----------------- Jx4B96: PUSH IX POP HL JP TermLp ; ; ----------------- Jx4B9C: LD A,E CP 08H ; No Operation? JR Z,Jx4BA9 ; Yes ; LD A,18H OUT (REGSET),A LD A,02H ; Issue Assert ATN cmd OUT (RDWREG),A Jx4BA9: LD A,18H OUT (REGSET),A LD A,03H ; Issue Negate ACK cmd OUT (RDWREG),A JP TermLp ; ; ----------------- Jx4BB4: LD A,0FH OUT (REGSET),A ; Select Target LUN register IN D,(C) ; Read Target Status JP TermLp ; ; ----------------- Jx4BBD: CALL 0F398h ; JP (IX) ; JP TermLp ; SetWD3393 - Set host ID, Timeout etc. SetWD3393: xor a OUT (REGSET),A EX (SP),HL EX (SP),HL IN A,(RDWREG) OR A ; Own ID = 0 ? JR NZ,J$4B7B ; No ; OUT (REGSET),A call Get_ID ; A = 10110000b CPL ; A = 01001111b AND 07H ; A = 00000111b OUT (RDWREG),A ; Set Own ID to 7 ; Avanced Features disabled ; No Host Parity checking ; Select divisor CIP_2: IN A,(AUXSTAT) AND 00010000b ; Command In Progress? JR NZ,CIP_2 ; Yes ; LD A,18H OUT (REGSET),A XOR A OUT (RDWREG),A ; Execute RESET command to ; configure the WD3393A BUSY_01: EX (SP),HL EX (SP),HL IN A,(AUXSTAT) AND 00100000b ; BuSY? JR NZ,BUSY_01 ; Yes ; LD A,17H OUT (REGSET),A EX (SP),HL EX (SP),HL IN A,(RDWREG) ; Read SCSI status to clear ; interrupt J$4B7B: LD A,1 OUT (REGSET),A ; call Get_ID ; CPL ; A = 01001111b ; RRCA ; RRCA ; RRCA ; A = 11101001b ; AND 01H xor a ; ld a,00000100B ; No halt on SCSI PAR. ERR. ; No halt on ATTENTION ; DMA mode 0 ; Intermediate disconn. int. OUT (RDWREG),A LD A,7DH OUT (RDWREG),A ; Set Timeout Period to 1 sec. LD A,11H OUT (REGSET),A XOR A OUT (RDWREG),A ; Select asynchronous transfer LD A,16H OUT (REGSET),A ; M*v1.01 XOR A ; call GetTargetID ; OUT (RDWREG),A ; Set Source ID out (RDWREG),a ; Disable selection ; Disable reselection ; JP J.4AAD ; (ld d,2 + ret) ld d,2 ret ; Save Data Pointer SavDatPnt: PUSH HL POP IY JP TermLp ; Restore Data Pointer ResDatPnt: PUSH IY POP HL JP TermLp ; Clear Pending Interrupt, when necessary send Status to Target RT_01: IN A,(AUXSTAT) OR A ; Interrupt Pending? JP P,J$4BBA ; No ; LD A,17H OUT (REGSET),A EX (SP),HL EX (SP),HL IN A,(RDWREG) ; Read SCSI status ; to clear interrupt JR RT_01 ; ; ----------------- J$4BBA: IN A,(AUXSTAT) RRCA ; Data Buffer Ready? JR NC,J$4BCB ; No ; LD A,19H OUT (REGSET),A ; EX (SP),HL EX (SP),HL IN A,(RDWREG) ; Read Data Register OUT (RDWREG),A JR RT_01 ; ; ----------------- J$4BCB: LD DE,0206h ; D = Check Condition ; E = Abort msg CIP_3: IN A,(AUXSTAT) AND 10H ; Command In Progress? JR NZ,CIP_3 ; Yes ; LD A,18H OUT (REGSET),A LD A,AssertATN ; Assert ATTENTION OUT (RDWREG),A RET ; ; ----------------- J.4BDD: LD DE,0205h ; D = 2 Check Condition ; E = 5 Initiator detected ; error msg JR CIP_9 ; J$4BE2: LD A,E CP 08H ; No operation message? JR Z,CIP_4 ; CIP_9: IN A,(AUXSTAT) AND 10H JR NZ,CIP_9 ; LD A,18H OUT (REGSET),A LD A,AssertATN OUT (RDWREG),A ; Assert ATN to inform the ; Target there is a msg ready CIP_4: IN A,(AUXSTAT) ; Read Auxiliary status AND 10H ; Command In Progress? JR NZ,CIP_4 ; LD A,18H OUT (REGSET),A LD A,NegateACK OUT (RDWREG),A ; Negate ACK JP TermLp ; Get Target Status byte GetTargStat: LD A,0FH OUT (REGSET),A IN D,(C) ; Read Target LUN register ; (Target Status) JP TermLp ; ; ----------------- J$4C0F: CALL 0F398h ; JP (IX) ; JP TermLp ; CalcWA_3 - Calculates total size of Work Area ; Input : - ; Output: BC = total size ; Modify: AF CalcWA_3: call RdToggles ld bc,NRM_SIZE-1 ret z ; ExtPrt and DrvSup are disabled push hl ld h,b ld l,c ld bc,EXT_SIZE bit 1,a ; Extended Partitions enabled? jr z,NoDrv2 add hl,bc NoDrv2: push hl pop bc pop hl ret ; CalcWA_2 - Calculates size of Work Area ; Input : - ; Output: HL size of Work Area ; Modify: AF ; Note : Used when NOVAXIS is the first DISKROM CalcWA_2: ld hl,487 jr CalcWA ; CalcWA_1 - Calculates size of Work Area ; Input : - ; Output: HL size of Work Area ; Modify: AF ; Note : Used when NOVAXIS is not the first DISKROM CalcWA_1: ld hl,30h CalcWA: call RdToggles ret z ; ExtPrt and DrvSup are disabled ld de,EXT_SIZE bit 1,a ; Extended Partitions enabled? ret z add hl,de ret ; RdToggles - Read ExtPrt and DrvSup toggles from clockchip ; Input : - ; Output: A = 000000ED ; |+---- DrvSup (not used in this version) ; +----- ExtPrt ; Modify: F RdToggles: push bc push de ld a,2 call CLKMOD ld b,11 call REDRAM rra rra rra ; Move DrvSup bit to bit 0 and 1 ; Leave bit 0 only ld d,a ld a,2 call CLKMOD ld b,12 call REDRAM rra ; Move ExtPrt bit to bit 1 and 00000010b or d pop de pop bc and a ret ; DrvWork - Get Work Area address of specified drive (Ext. Partitions) ; Input : A = log. drive number (0-5) ; Output: IX = Work Area address ; Modify: AF,BC,DE,HL DrvWork: push af call GETWRK ; Get Work Area address bit 3,(ix+07h) ; Extended partitions enabled? jr nz,ExtEna ; Yes pop af ClcPrtInf: add a,a add a,a add a,a ld e,a ld d,0 add ix,de ret ExtEna: pop af ; Get log. drive # push ix ; Save Work Area address ld de,NRM_SIZE ; Get size of Work Area add ix,de ; Calc start of Extended Work Area ld (ix+00h),a ; Store it pop ix jr ClcPrtInf ; WrtPermit - Check for Write Permission ; Input : - ; Output: Carry is set when there is no write permission ; Modify: AF WrtPermit: push bc push de push hl push ix ; ** SECURITY DUMMY ld hl,SECURE ; ** call GETWRK bit 3,(ix+07h) ; Extended Partitions enabled? jr z,ExtDis1 ; No bit 7,(ix+NRM_SIZE+1) ; Extended partitions in use? jr nz,ExtEna2 ; Yes ExtDis1: pop ix pop hl pop de pop bc call Get_ID ; Get Host ID OR 10000000b XOR (IX+06h) ; Network Write ID # AND 10001111b scf ret nz ; No write rights on this drive ccf ret ExtEna2: ld de,NRM_SIZE add ix,de ld a,(ix+00h) ; Get log. drive number ld e,a ld d,0 add ix,de call GetHost_ID ; Get Host ID ld c,1 ; Write ID 0 and a ; Host ID is 0? jr z,HostID0 ld b,a MakeWr: rlc c djnz MakeWr HostID0: ld a,c and (ix+10h) ; Write permission for this drive? pop ix pop hl pop de pop bc scf ret z ; No write rights ccf ret ; TALE - print moving '-' TALE: PUSH AF PUSH HL LD A,(0F6A0h) INC A AND 01H LD (0F6A0h),A LD HL,TALETX ADD A,L LD L,A JR NC,TALES ; INC H TALES: LD A,(HL) RST OUTDO ; LD A,08H ; BackSpace RST OUTDO ; POP HL POP AF RET ; Get_Inq - Get INQUIRY for _INQUIR command ; Input : A = ID ; Output: if Carry is set E contains BASIC error code ; Otherwise sectorbuffer if filled with inquiry data ; Modify: AF,BC,DE,HL Get_Inq: ld b,a call GetHOST_ID ; Get Host ID cp b ; Inquiry from Host ID requested? jr z,HostInq ld a,b ; Target ID push ix call TstUnitRdy ; Check if Target is connected / online pop ix inc d dec d ; Status GOOD? jr z,IDrdy ; Yes ld a,d cp 2 ; UNIT ATTENTION? jr z,IDua ; Yes DskOff: ld e,70 ; 'Disk offline' error scf ret IDua: ld a,(ix+70h) ; Get ID call ReqSense inc d dec d ; Status GOOD? jr nz,DskOff ld a,(ix+00h) ; Get error code and 011111111b cp 70h ; Error class 7? ld e,69 ; 'Disk I/O error' error scf ret nz ld a,(ix+02h) and 00001111b ; Get Sense-key cp 2 ; NOT READY? jr z,DskOff ret HostInq: ld hl,($SECBUF) ld de,8 add hl,de ex de,hl ld hl,HSTinq+8 MoveInq: ld bc,8+16+4 ldir and a ; Clear carry ret IDrdy: ld a,(ix+70h) ; Get ID ld hl,($SECBUF) push ix call Inquiry pop ix inc d dec d ret z ld a,d cp 2 jr z,IDua jr DskOff ; ** SECURITY STRING ** SECURE: defb 128,129,130,131,132,133,134,135,136,137 ; ** ; SOFTID.ASM - Get soft SCSI host ID (1 - 7) ; (C) 1994 KMcs ; Written by Jurgen Kramer - 05/05/94 - ; Input : - ; Output: A = HOST ID (4-7) (7 = B0h, 6 = B1h etc.) ; Modify: AF Get_ID: push bc ld a,2 call CLKMOD ld b,12 call REDRAM pop bc ; *M* v0.45 and 00000011b ; Reset bit 2 and 3 ; *M* set 2,a cpl sub 48h ret ; GetHOST_ID - Get HOST ID (4 - 7) ; Input : - ; Output: A = HOST ID ; Modify: AF GetHOST_ID: call Get_ID cpl and 7 ret ; *N* ; TbrCPUres - Restore old CPU mode (only Turbo-R) TbrCPUres: push af push bc push de push hl push ix push iy call GETWRK ; ld a,(ix+07h) ; ; cp 3 ; call nc,oldCPUmode ; bit 0,(ix+07h) ; Turbo-R ? call nz,oldCPUmode ; Yes pop iy pop ix pop hl pop de pop bc pop af ret ; TbrCPUset - set CPU in R800 DRAM mode (only Turbo-R) TbrCPUset: push af push bc push de push hl push ix push iy call GETWRK bit 0,(ix+07h) call nz,chgCPU pop iy pop ix pop hl pop de pop bc pop af ret ; *N* ; NOVAXIS - special features NOVAXIS: call SetHostID ret ; ChkSETDIAG - Check DEL key, if pressed start SETUP/DIAGS ChkSETDIAG: ld hl,InfSetTxt call Print2 ld hl,32000 ChkDEL: ld a,8 call SNSMAT bit 3,a ; pressed? jp z,SetDiag dec hl ld a,l or h jr nz,ChkDEL jp ClrEndLn ; SetHostID - Set SCSI HOST ID ; Input : - ; Output: clockchip block 2, nibble 12 bits 0 and 1 contents host ID ; Modify: SetHostID: call Get_ID cpl and 7 cp 4 ; ID < 4 jr nc,IDok ; No ld a,(07ff7h) ; Get default HOST ID cpl and 7 ld d,a push af call SetHTID pop af IDok: ld d,a call ClrEndLn ; ld hl,IObaseTxt ; call Print2 ; ld a,(07ff8h) ; Get I/O base ; call PrintBCD ld hl,HostIDTxt call Print2 ld a,d ; Get Host ID add a,30h rst OUTDO ld hl,TargIDTxt call Print2 call GetTargetID add a,30h rst OUTDO ld a,CR rst OUTDO ld a,LF rst OUTDO xor a out (REGSET),a out (RDWREG),a call SetWD3393 jp WAIT ; ** SECURITY ** MovDat: ld hl,ScrSecDat ld de,8000h ld bc,1522 ldir ret ; GetSense - Get Sense-Key, Sense code and additional Sense code ; Input : A = LUN + ID ; Output: A = Sense-key, B = Sense code, C = add. sense code ; IX = pointer to Sense data, D = Target Status ; Modify: HL ; Note : This routine must only be called when the Target which Sense is ; requested is in Check Condition status. GetSense: call ReqSense ld a,(ix+2) ; Get Sense-key and 00001111b ld b,(ix+12) ; Get Sense-code ld c,(ix+13) ; Get extra Sense-code ret ; SetHTID - Set HosT ID ; Input : D = ID (4 - 7) ; Output: - ; Modify: AF,BC,D SetHTID: ld a,2 call CLKMOD ld b,12 ld a,d and a jr nz,SoftOk ld a,(07ff7h) cpl and 7 ld d,a SoftOk: ; *M*v0.45 call REDRAM and 00000111b ; Reset bit 3 or d ld a,2 call CLKMOD ld b,12 ; *M* jp WRTRAM ; GetTargetID - Read target ID from clockchip (block 2, nibble 3, bits 3 and 2 ; Input : - ; Output: A = (1st.) Target ID (0 - 3) ; Modify: AF,B GetTargetID: push bc call ReadTrgID rra rra and 00000011b pop bc ret ReadTrgID: ld a,2 call CLKMOD ld b,3 jr REDRAM ; SetTargetID - Set Target ID (0-3) ; Input : A = ID (0-3) ; Output: Carry is set when error occurred ; Modify: AF,B,D SetTargetID: cp 4 ccf ret c sla a sla a ld d,a call ReadTrgID and 00000011b or d ld d,a ld a,2 call CLKMOD ld b,3 call WRTRAM ret ; CLKCHP.ASC - Clockchip routines ; (C) 1992 KMcs ; Jurgen Kramer ; CLKMOD - Select block (0 - 3) ; Input : A = block # ; Output: ; Modify: AF CLKMOD: PUSH BC PUSH AF LD B,0DH CALL REDRAM di AND 0CH POP BC OR B OUT (0B5H),A POP BC ei RET ; REDRAM - Read from clockchip ; Input : B = nibble # (0 - 12) ; Output: A = data (four lower bits) ; Modify: AF,B REDRAM: di LD A,B OUT (0B4H),A INC B IN A,(0B5H) AND 0FH ei RET ; WRTRAM - Write to clockchip ; Input : D = data, b = nibble # (0 - 12) WRTRAM: di LD A,B OUT (0B4H),A LD A,D inc b OUT (0B5H),A ei RET ; PrintBCD - print byte as BCD ; Input : A = BCD number ; Output: - ; Modify: AF,B ; Note : first digit of zero is surpressed PrintBCD: ld b,a and 11110000b rlca rlca rlca rlca and a ; First digit zero? jr z,Surpress0 ; Yes add a,30h rst OUTDO Surpress0: ld a,b and 00001111b add a,30h rst OUTDO ret ; PrintPBCD - Print packed BCD (first digit of zero is not surpressed) ; Input : A = Packed BCD ; Output: - ; Modify: AF,B PrintPBCD: ld b,a and 11110000b rlca rlca rlca rlca add a,30h rst OUTDO jr Surpress0 ; PrInitTxt - Print Init text ; Input : - ; Output: - ; Modify: AF,BC,HL,DE PrInitTxt: LD HL,InitTXT call Print2 ld de,07ff5h ; Get version # ld a,(de) call PrintBCD ; Print low part ld a,'.' rst OUTDO inc de ld a,(de) call PrintPBCD ; Print high part ld a,(07ff9h) ; Get ROM revision level and a ; Revision is 00 ? jr z,NoRevLev push af ld a,'.' rst OUTDO pop af call PrintPBCD NoRevLev: ld hl,InitTXT2 jp Print2 ; ** SECURITY CHECK ROUTINE - 'call IDENTIFYOURSELF' ; ErrSTTMNT: push ix push hl push bc ld ix,PROCNM+120 ld hl,IDEN_TXT ld b,14 chkSECURE: ld a,(ix-120) ld c,(ix-119) xor c cp (hl) jr nz,NotSECURE inc hl inc ix djnz chkSECURE ld ix,(DummyAdd) call 0f398h NotSECURE: pop bc pop hl pop ix scf ret ; GetInq - Get & Print Inquiry data (only used during init) ; Input : A = Target ID ; Output: D = 2 if Device is not a HDD, else D = 0 ; Modify: D GetInq: ld (TrgID2),a ; Save Target ID push hl ld hl,8400h call Inquiry inc d dec d jr z,InqOk ld a,2 ld (TrgStt),a pop hl jp DoCRLF InqOk: ld hl,IDTxt call Print2 ld a,(TrgID2) add a,30h rst OUTDO ; Print ID ld hl,8400h ld a,(hl) and 00011111b ; Extract device type ld a,0 jr z,DevHDD ; Yes device is a HDD ld a,2 DevHDD: ld (TrgStt),a ld hl,Stripe call Print2 xor a ld hl,8408h ld de,8200h ld bc,8 ldir ; Move manufacturer to 8200h push hl ld (de),a ld hl,8200h call Print2 ; Print Manufacturer pop hl ld de,8200h ld bc,16 ldir ; Move produkt to 8200h ld (de),a ; *A*v0.42 inc de ld bc,4 ldir ld (de),a ld hl,(XYpos) call POSIT ld hl,8200h ; Print Product call Print2 ld hl,(XYpos) ld de,1300h add hl,de call POSIT ld hl,RevTxt call Print2 ld hl,8200h+16+1 call Print2 ; Print Revision ld hl,(XYpos) push hl ld h,74 call POSIT pop hl inc l ld (XYpos),hl call Clean ; Clear BASIC memory pop hl ld a,(TrgStt) ld d,a and a ret z DoCRLF: ld hl,StripeCRLF call Print2 ld d,2 ret Clean: ld hl,8200h ld de,8201h ld bc,0230h ld (hl),0 ldir ret ; CALL statement routines ; *M*v0.40 STTMNT: ld de,StatTable ; Table for Turbo-R only ld a,(BASVER) cp 3 ; Turbo-R jr nc,TBRok LD DE,StatT2 ; Table for MSX2/2+ & Turbo-R TBRok: CALL ChkStmnt ; jp c,ErrSTTMNT ; Error, unknown statement ; PUSH DE ; Execute Call statement RET ; Print2 - Print string terminated by 0 (ASCIIZ) ; Input : HL = string address ; Output: - ; Modify: AF,HL Print2: ld a,(hl) and a ret z inc hl rst OUTDO jr Print2 ; NOVAXIS Setup / Info version 0.01 - Turbo-R / MSX version ; (C) KMcs 1994 ; Written by Jurgen Kramer - 15/05/94 - ; - 20/06/94 - ; - 04/09/94 - v0.98 ; - 18/11/94 - v0.99 ; - 15/01/95 - v1.01 Added 'Driver support' toggle ; - 16/01/95 - v1.02 Complete new layout ; - 17/01/95 - v1.03 'Help' texts added for SD_mul and SD_drv ; - 20/01/95 - v1.04 Added 'Extended Partitions' toggle (not completely) ; - 26/02/95 - Current Target line is now always cleared before printing ; - 03/04/95 - v1.05 Added 'Rescan' function ; IX: (08200h) ; +00 - HOST ID ; +01 - Target ID ; +02 - # of Units online ; +03 - SCSI status of current HDD ; +04 - 0 = no changes made ; +05 - 1 = Multiple HDD support ; +06 - 1 = Driver support ; ; +07-08 - storage of old $SECBUF address ; +09-0a - storage of old Work Area address ; +0b - Device type ; +0c - ID vector ; +0d - 1 = Extended partitions ; During SetDiag the SECTORBUFFER is at 8400h and the Work Area set to 8600h ; ; 8700h used for Inquiry ; 8800h used for printing Inquiry SetDiag: call ClrEndLn ld hl,WaitTxt call Print2 ; Print wait msg call TempSet ; Set $SECBUF to temporary address ld ix,8200h call Get_ID ; Read Host ID from clock cpl and 7 ld (ix+00h),a ; Store call GetTargetID ; Get Target ID from clockchip ld (ix+01h),a push ix call SetWD3393 ; Init Host ID etc. call GetUnitsOn pop ix ld (ix+02h),a ; Store # of units online ld (ix+0ch),c ; Store ID vector ld a,2 call CLKMOD ld b,11 call REDRAM ld d,0 bit 2,a ; Multiple HDD support? jr z,NoMulHDD set 0,d NoMulHDD: ld (ix+05h),d xor a ld (ix+04h),a ; *N*v1.06 ld a,2 call CLKMOD ld b,12 call REDRAM ld (ix+0dh),0 ; Set Extended Partitions to disabled bit 2,a ; Extended Partition enabled? jr z,ExtDis ; No set 0,(ix+0dh) ; Set Extended Partitions to enabled ExtDis: call SetBlnk ; Set blinking ld hl,SetDiagTxt ; Print Setup screen call PrintXY SD_loop: push ix ld a,(ix+01h) call TstUnitRdy pop ix ld (ix+03h),a ; 85h = Unit ok ; ld a,(ix+04h) ; and a ; jr nz,SD_skip ; ; ld hl,SetDiagTxt ; Print Setup / Diags msg ; call PrintXY ; SD_skip: ld hl,2009h call POSIT ld a,(ix+00h) ; Get Host ID add a,30h rst OUTDO ld hl,4809h call POSIT ld a,(ix+01h) ; Get Target ID add a,30h rst OUTDO ld hl,200ah call POSIT bit 0,(ix+05h) ; Multiple HDD enabled? ld hl,DisTxt jr z,NoMulp ld hl,EnaTxt NoMulp: call Print2 ld hl,200bh call POSIT bit 0,(ix+0dh) ; Extended Partitions enabled? ld hl,DisTxt jr z,NExtPar ld hl,EnaTxt NExtPar: call Print2 ld hl,UnitTxt call PrintXY ld a,(ix+02h) ; Get # of units add a,30h rst OUTDO call BlnkIDVect ; Print ID vector ld hl,CurTrg call PrintXY ld a,(ix+03h) cp 85h ld hl,NokTxt ld a,10 ld (ix+0bh),a ; Set device type to unknown jr nz,HDOnln ld a,(ix+01h) ; Get Target ID push hl ld hl,8700h push ix call Inquiry pop ix inc d dec d jr nz,NotOK pop hl ld hl,8700h ld a,(hl) and 00011111b ; Extract device type ld (ix+0bh),a ; Store device type xor a ld hl,8708h ld de,8800h ld bc,8 ldir ; Move manufacturer to 8800h ld (de),a push hl ld hl,8800h call Print2 ; Print Manufacturer pop hl ld de,8800h ld bc,16 ldir ; Move produkt to 8800h ld (de),a ld hl,EmpStr16 ; Print 16 spaces and locate cursor call PrintXY ld hl,8800h jr HDOnln NotOK: ld a,d cp 2 ; UNIT ATTENTION? jr nz,NoRqS ld a,(ix+01h) push ix call ReqSense pop ix NoRqS: pop hl HDOnln: call Print2 ld hl,DevTypTxt call PrintXY ld a,(ix+0bh) ; Get Device type cp 11 ; Device type between 0 - 10 ? jr c,DevIn ld a,10 DevIn: ld hl,DevTxt and a ; Direct Access Device ? jr z,DirAcc ld b,a ld de,25 NxtDv2: add hl,de djnz NxtDv2 DirAcc: ld de,4 add hl,de call Print2 ; Print Device Type SD_nokey: ld hl,InputTXT call PrintXY call CHGET cp 27 ; ESC pressed? jr z,SD_quit set 5,a cp 'q' ; Quit without save? jr z,SD_quit cp 's' ; Save and quit? jr z,SD_save cp 'h' ; Set Host ID? jp z,SD_host cp 't' jp z,SD_target cp 'm' ; Toggle multiple HDD support? jp z,SD_mul cp 'e' ; Toggle Extended Partitions? jp z,SD_ext cp 'r' ; Rescan jp z,SD_rescan jr SD_nokey ; ld a,(ix+02h) ; Get number of units online ; and a ; No units ready? ; jr nz,SD_nokey ; One or more units online SD_quit: call TempRes ; Restore temporary settings call ResBlnk ; Blinking off ld a,12 rst OUTDO ; Clear Screen jp PrInitTxt SD_save: dec (ix+04h) ; Changes made? jr nz,SD_quit ld d,(ix+00h) ; Host ID call SetHTID ; Write to clockchip ld a,(ix+01h) ; Target ID call SetTargetID ; *N*v1.06 ld a,2 call CLKMOD ld b,12 call REDRAM and 00001011b ; Reset bit 2 ld d,a ld a,(ix+0dh) sla a sla a ; Move bit 0 to bit 2 or d ld d,a ld a,2 call CLKMOD ld b,12 call WRTRAM ; Save ExtPrt toggle ; *N* ld a,2 call CLKMOD ld b,11 call REDRAM ld d,(ix+05h) set 2,a bit 0,d jr nz,OkMul res 2,a OkMul: ld d,(ix+06h) set 3,a bit 0,d jr nz,OkDrv res 3,a OkDrv: ld d,a ld a,2 call CLKMOD ld b,11 call WRTRAM jr SD_quit SD_host: ld hl,EraHelp call PrintXY ; Clear 'help' line ld hl,SDhstTxt call PrintXY ld hl,2009h call POSIT call CHGET cp 27 jr z,SD_hstESC sub 30h cp 8 jr nc,SD_host ; Yes, wrong host ID cp 4 jr c,SD_host ld (ix+00h),a ld a,1 ld (ix+04h),a SD_hstESC: ld hl,0116h call POSIT call ClrEndLn jp SD_loop SD_target: ld hl,EraHelp call PrintXY ; Clear 'help' line ld hl,SDtrgTxt call PrintXY ld hl,4809h call POSIT call CHGET cp 27 jr z,SD_tarESC sub 30h jr c,SD_target ; Yes, wrong target ID cp 4 jr nc,SD_target ld (ix+01h),a ld a,1 ld (ix+04h),a SD_tarESC: jr SD_hstESC SD_mul: ld a,1 ld (ix+04h),a ld a,(ix+05h) xor 1 ld (ix+05h),a ld hl,mulEnaHelp jr nz,DrvEna ld hl,mulDisHelp DrvEna: call PrintXY jp SD_loop SD_ext: ld a,1 ld (ix+04h),a ld a,(ix+0dh) xor 1 ld (ix+0dh),a ld hl,extEnaHelp jr nz,DrvEna ld hl,extDisHelp jr DrvEna SD_rescan: ld hl,EraHelp call PrintXY ; Clear 'help' line push ix call GetUnitsOn pop ix ld (ix+02h),a ; Store # of units online ld (ix+0ch),c ; Store ID vector jp SD_loop ; ** SECURITY TEXT for 'CALL IDENTIFYOURSELF' IDEN_TXT: defb 'I' xor 'D' defb 'D' xor 'E' defb 'E' xor 'N' defb 'N' xor 'T' defb 'T' xor 'I' defb 'I' xor 'F' defb 'F' xor 'Y' defb 'Y' xor 'O' defb 'O' xor 'U' defb 'U' xor 'R' defb 'R' xor 'S' defb 'S' xor 'E' defb 'E' xor 'L' defb 'L' xor 'F' defb 'F' xor 'I' ; TempSet - Set $SECBUF and SLTWRK to a temporary address ; Input : - ; Output: - ; Modify: TempSet: ld de,($SECBUF) ; Get old address ld (8207h),de ; Store it ld de,8400h ld ($SECBUF),de ; ** SECURITY DUMMY ld hl,SECURE ; ** call GETWRK ld (8209h),hl ; Store old Work Area address call GetSLTWRK ld de,8600h ld (hl),e inc hl ld (hl),d ; Set temp. Work Area address push de pop hl inc de ld (hl),0 ld bc,8 ldir ; Clean temp. Work Area ret ; TempRes - Restore temporary settings ; Input : - ; Output: - ; Modify: DE TempRes: ld de,(8207h) ld ($SECBUF),de call GetSLTWRK ld de,(8209h) ld (hl),e inc hl ld (hl),d ret ; SetBlnk - Set blinking ; Input : - ; Output: - ; Modify: SetBlnk: ld hl,2048 call NSTWRT ld a,(7) ld c,a ld b,0 ld hl,BlnkDat di otir ld b,270-256 otir ex (sp),hl ex (sp),hl ; *N*v1.09.03 - safety for all ex (sp),hl ex (sp),hl ; *N* ld bc,0a40ch call WRTVDP ld bc,0f00dh call WRTVDP ei ret ; ResBlnk - Reset Blinking ; Input : - ; Output: - ; Modify: ResBlnk: ld bc,0000ch call WRTVDP ld bc,0000dh call WRTVDP ret ; BlnkIDVect - Let all online Targets blink BlnkIDVect: ld hl,2048+178 call NSTWRT ld a,(ix+0ch) ; Get ID vector ld hl,IDBlnkDat ld c,a ld de,0 and a jr z,AllIDOff ; No Targets online ld b,8 NxtIDBl: rrc c jr nc,IDoffl ld a,(hl) add a,d ld d,a inc hl ld a,(hl) add a,e ld e,a inc hl djnz NxtIDBl jr AllIDOff IDoffl: inc hl inc hl djnz NxtIDBl AllIDoff: ld a,(7) ld c,a out (c),d ex (sp),hl ex (sp),hl ex (sp),hl ex (sp),hl out (c),e ex (sp),hl ex (sp),hl ; *N*v1.09.03 ex (sp),hl ex (sp),hl ; *N* ret ; PrintXY - Print ASCIIZ string with X and Y coordinats ; Input : HL = string address ; Output: - ; Modify: ; String format: ; defb 255 <- indicates that the next 2 bytes are coordinats ; defb X ; defb Y ; defb 'etc. etc.' ; defb 0 <- end of string mark PrintXY: push ix call PR_XY pop ix ret PR_XY: ld a,(hl) and a ret z cp 255 jr nz,NoPosXY inc hl ld a,(hl) ; Get X value inc hl push hl ld l,(hl) ; Get Y value ld h,a call POSIT pop hl inc hl jr PR_XY NoPosXY: rst OUTDO inc hl jr PR_XY ; ChkStmnt - Check Call statement ; Input : DE = statement text ; Output: Carry if error (unknown call) ChkStmnt: LD A,(DE) OR A ; All statements checked? SCF RET Z ; LD IX,PROCNM ; Address of statement in RAM J$517B: BIT 7,A INC DE JR NZ,J$5192 ; CP (IX) INC IX LD A,(DE) JR Z,J$517B ; J$5188: AND 80H INC DE LD A,(DE) JR Z,J$5188 ; J.518E: INC DE INC DE JR ChkStmnt ; J$5192: AND 7FH CP (IX) JR NZ,J.518E ; LD A,(IX+1) OR A JR NZ,J.518E ; LD A,(DE) ; Form address LD C,A INC DE LD A,(DE) LD D,A LD E,C RET ; ** SECURITY DUMMY ** DummyAdd: defw DummStrt ; ********** DATA AREA ********** TALETX: defb 02dh ; - sign defb 027h ; ' sign ; MSX disk error codes for SCSI-Sense-Codes ; Translate SCSI-Sense-Codes to a MSX disk error ; MSX errors: ; 00 - Write Protected Disk ; 02 - Drive Not Ready ; 04 - CRC error ; 06 - Seek error ; 08 - Record Not Found ; 10 - Write Error ; 12 - Bad Parameter ; ; 18 - Not a DOS disk ; 20 - Incompatible Disk ; 22 - Unformated Disk ; 24 - SnsTable: defb 24 ; Sense Code 0 defb 12 ; Sense Code 1 defb 6 ; Sense Code 2 defb 10 ; Sense Code 3 defb 2 ; SC 4 defb 12,12,12,12,12,12,12,12,12,12,12 ; SC 5 - 0FH defb 8,4 ; SC 10H,11H defb 12,12 ; SC 12H,13H defb 8,6 ; 14H,15H defb 12 ; 16H defb 0ffh,0ffh ; 17H,18H defb 12,12 ; 19H,1AH defb 8,22 ; 1BH,1CH defb 12 ; 1DH defb 0ffh ; 1EH defb 12,12 ; 1FH,20H defb 8 ; 21H defb 12,12 ; 22H,23H defb 8,2 ; 24H,25H defb 12,12,12 ; 26H,27H,28H defb 24,24 ; 29H,2AH ; Table for call statements ; *M*v0.40* StatTable: ; Turbo-R calls defm 'SLO' ; SLO(W) defb 'W' or 128 defw _SLOW ; defm 'MEDIU' ; MEDIU(M) defb 'M' or 128 defw _MEDIUM ; defm 'FAS' ; FAS(T) defb 'T' or 128 defw _FAST ; MSX2/2+ and Turbo-R calls StatT2: defm 'INF' ; INF(O) defb 'O' or 128 defw _INFO ; defm 'MAP' ; MAP(2) defb '2' or 128 defw _MAP ; defm 'MA' ; MA(P) defb 'P' or 128 defw _MAP2 ; defb 'HOSTI' ; HOSTI(D) defb 'D' or 128 defw _HOSTID ; defb 'SETHOSTI' ; SETHOSTI(D) defb 'D' or 128 defw _SETHOSTID ; defb 'TARGETI' ; TARGETI(D) defb 'D' or 128 defw _TARGETID ; defb 'SETTARGETI' ; SETTARGETI(D) defb 'D' or 128 defw _SETTARGETID ; defb 'INQUIR' ; INQUIRY (x,A$,B$,C$) defb 'Y' or 128 defw _INQUIRY ; defb 0 ; End of statement list InitTXT: defb 'NOVAXIS MSX2/Turbo-R SCSI BIOS version ',0 InitTXT2: defb CR,LF,'(C) 1994-1995 KMcs / MSX Club Gouda',CR,LF SecureC1: defb 'Written by Jurgen Kramer - June 5th. 1995 -',CR,LF defb CR,LF defb 'Hardware by H.G. 1993. version 1.1',CR,LF defb CR,LF,LF,0 ;IObaseTxt: defb 'I/O base: ',0 ;HostIDTxt: defb 'h, Host ID : ',0 HostIDTxt: defb 'Host ID : ',0 TargIDTxt: defb ', Target ID : ',0 InfSetTxt: defb CR,LF,'Hit to run SETUP',0 ; Texts for PrintInq IDTxt: defb 'ID #',0 DevTxt: defb ' - Direct Access Device',0 defb ' - Tape streamer ',0 defb ' - Printer device ',0 defb ' - Processor device ',0 defb ' - WORM ',0 defb ' - CD-ROM ',0 defb ' - Scanner ',0 defb ' - Optical device ',0 defb ' - Medium changer ',0 defb ' - Communication device',0 defb ' - Unknown device type ',0 CRLF: defb CR,LF,0 Stripe: defb ' - ',0 NotInsTxt: defb ' -- Not installed --',CR,LF,0 ; StripeCRLF: defb '-',CR,LF,0 RevTxt: defb 'Revision : ',0 ; Texts for Setup / Diags WaitTxt: defb 'Wait...',0 SetDiagTxt: defb 12,255,16,1 defb 'NOVAXIS Setup version 1.06 (C) 1994-1995 KMcs' defb 255,22,2 SecureC2: defb 'Written by Jurgen Kramer - 14/05/95 -' defb 255,03,09,'[H] - Host ID :' defb 255,43,09,'[T] - Target ID :' defb 255,03,10,'[M] - Multiple HDD support :' defb 255,03,11,'[E] - Extended Partitions :' defb 255,43,12,'[R] - Rescan' defb 255,03,14,'[Q] - Quit without save' defb 255,43,14,'[S] - Save and quit' defb 255,60,18,'ID #: 0 1 2 3 4 5 6 7' defb 0 UnitTxt: defb 255,1,18,'Units online: ',0 CurTrg: defb 255,1,20,'Current Target: ',255,17,20,0 EmpStr16: defb 255,27,20,' ',255,27,20,0 NokTxt: defb 'Offline ',0 DevTypTxt: defb 255,45,20,'Device type: ',0 DisTxt: defb 'Disabled',0 EnaTxt: defb 'Enabled ',0 SDhstTxt: defb 255,1,22,'Enter new Host ID (4 - 7)',0 SDtrgTxt: defb 255,1,22,'Enter new Target ID (0 - 3)',0 InputTXT: defb 255,1,22,'Input : ',0 JurgenKramer: defb 'J' xor 'u' defb 'u' xor 'r' defb 'r' xor 'g' defb 'g' xor 'e' defb 'e' xor 'n' defb 'n' xor ' ' defb ' ' xor 'K' defb 'K' xor 'r' defb 'r' xor 'a' defb 'a' xor 'm' defb 'm' xor 'e' defb 'e' xor 'r' defb 'r' xor 'J' drvEnaHelp: defb 255,1,24,'Driver support: when enabled you can loa' defb 'd drivers for devices like CD-ROM ',0 drvDisHelp: defb 255,1,24,'Driver support: when disabled you cannot' defb ' load drivers, but it frees memory ',0 mulEnaHelp: defb 255,1,24,'Multiple HDD: when enabled all online Di' defb 'rect Access Devices will be installed',0 mulDisHelp: defb 255,1,24,'Multiple HDD: when disabled only the Tar' defb 'get you''ve selected will be installed',0 extEnaHelp: defb 255,1,24,'Extended Partitions: when enabled you ca' defb 'n use up to 15 partitions per drive ',0 extDisHelp: defb 255,1,24,'Extended Partitions: when disabled you c' defb 'an only use up to 6 part. per drive ',0 EraHelp: defb 255,1,24,CR,ESC,'K',0 ; ** SECURITY DUMMY ** ScrTbl: defb 8,0+128 defb 96,1+128 defb 31,2+128 defb 39,3+128 defb 2,4+128 defb 239,5+128 defb 15,6+128 defb 5,7+128 defb 136,8+128 ; HOST Inquiry HSTinq: defb 00000011b ; Peripheral Device Type - 3 defb 0 ; Not removable defb 1 ; ANSI-version: SCSI-1 with CCS defb 0 ; defb 31 ; Length defb 0,0 ; Reserved defb 0 ; defb 'KMcs ' ; Manufacturer defb 'NOVAXIS SCSI ' ; Product defb '- ' ; Revision ; Table for blinking - Setup menu BlnkDat: defb 0,0,0,0,0,0,0,0,0,0 defb 0,0,0,0,0,0,0,0,0,0 defb 0,0,0,0,0,0,0,0,0,0 defb 0,0,0,0,0,0,0,0,0,0 defb 0,0,0,0,0,0,0,0,0,0 defb 0,0,0,0,0,0,0,0,0,0 defb 0,0,0,0,0,0,0,0,0,0 defb 0,0,0,0,0,0,0,0,0,0 defb 10h,80h,0,1,0,10h,80h,0,1,0 defb 10h,80h,0,1,0feh,0,0,0,0,0 defb 10h,80h,0,1,0feh,0,0,0,0,0 defb 0,0,0,0,0,10h,80h,0,0,0 defb 0,0,0,0,0,0,0,0,0,0 defb 10h,80h,0,0,0,10h,80h,0,0,0 defb 0,0,0,0,0,0,0,0,0,0 defb 0,0,0,0,0,0,0,0,0,0 defb 0,0,0,0,0,0,0,0,0,0 defb 0,2,0,0,0,0,0,0,0,0 defb 0,0,0,0,0,0,0,0,0,0 defb 0,0,0ffh,0ffh,0ffh,0c0h,0,07fh,0ffh,0f8h defb 0,0,0,0,0,0,0,0,0,0 defb 0,0,0,0,0,0,0,0,0,0 defb 0,0,0,0,0,0,0,0,0,0 defb 0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh ; ** SECURITY DUMMY defb 'K' xor 130 defb 'M' xor 131 defb 'c' xor 132 defb 's' xor 133 defb ' ' xor 134 defb 'w' xor 135 defb 'r' xor 136 defb 'o' xor 137 defb 't' xor 130 defb 'e' xor 131 defb ' ' xor 132 defb 't' xor 133 defb 'h' xor 134 defb 'i' xor 135 defb 's' xor 136 defb '!' xor 137 ; ** ; Table for blinking of online Targets - setup menu IDBlnkDat: defb 64,0 ; ID 1 defb 16,0 defb 4,0 defb 1,0 defb 0,64 defb 0,16 defb 0,4 defb 0,1 ; ID 7 ; ID tables ; ID table for Multi Target (HDD) environment IDtable: defb 0,1,2,3,4,5,6,128 ; Host ID 7 defb 1,0,2,3,4,5,6,128 defb 2,0,1,3,4,5,6,128 defb 3,0,1,2,4,5,6,128 defb 0,1,2,3,4,5,7,128 ; Host ID 6 defb 1,0,2,3,4,5,7,128 defb 2,0,1,3,4,5,7,128 defb 3,0,1,2,4,5,7,128 defb 0,1,2,3,4,6,7,128 ; Host ID 5 defb 1,0,2,3,4,6,7,128 defb 2,0,1,3,4,6,7,128 defb 3,0,1,2,4,6,7,128 defb 0,1,2,3,5,6,7,128 ; Host ID 4 defb 1,0,2,3,5,6,7,128 defb 2,0,1,3,5,6,7,128 defb 3,0,1,2,5,6,7,128 ; ID table for single Target environment IDsTable: defb 0,128 defb 1,128 defb 2,128 defb 3,128 ; ********** END DATA AREA ********** ; ** DUMMY PROGRAM ** DummStrt: di call MovDat ld b,9 ld hl,ScrTbl ld c,099h InitScr: ld a,(hl) out (c),a inc hl ld e,(hl) out (c),e inc hl djnz InitScr ex (sp),hl ex (sp),hl ld b,0 ld hl,0 call SETVDP ld hl,8000h ld d,(hl) inc hl inc hl inc hl inc hl SecLp: ld a,(hl) inc hl cp d jr z,SecMore out (c),a jr SecLp SecMore: ld a,(hl) inc hl cp d jp z,NotSupp+1 ld b,(hl) inc hl SecMore2: out (c),a djnz SecMore2 jr SecLp ; SETVDP - Set VDP to write/read ; Input : HL = VRAM address, B = bit 0 > page, bit 6 > 0=write, 1=read ; Ouput : C = VDP dataread/write port ; Modify: AF,BC SETVDP: ld c,99h ld a,h and 0c0h push bc res 6,b or b rlca rlca out (c),a ld a,14 or 128 out (c),a ld a,h out (c),l pop bc res 0,b and 3fh or b xor 64 out (c),a dec c ret ; ** ; ** SECURITY DATA ScrSecDat: defb 'DATA' defs 1522-4 defm 'HD#' ; 'Standard' SCSI ROM ID ; 'Standard' SCSI jump table JP SetWD3393 ; Init OWN ID, Parity Check, Timeout, ; Source ID etc. JP TermAct ; Terminate actions JP RdLogBlk ; Direct Sector Read JP WrLogBlk ; Direct Sector Write JP ReqSense ; 'Request Sense' JP Inquiry ; 'Inquiry' JP ReadCap ; 'Read Capacity' JP ModeSense ; 'Mode Sense' JP ModeSel ; 'Mode Select' JP FmtUnit ; 'Format Unit' JP TstUnitRdy ; 'Test Unit Ready' JP Initialise ; Print InitTXT, reset WD3393A, make ; 'CRC ROM check', selftest JP InsWork ; Install Workspace JP ClrEndLn ; Clear to End of Line JP Verify ; 'Verify' JP StrtStpUn ; 'Start / Stop Unit' JP SndDiag ; 'Send Diagnostics' ; New JUMP entries for SCSI DIAGNOSTIC jp NotSupp ; Reserved jp NotSupp ; Reserved jp Copy ; 'COPY' jp RdDefect ; 'READ DEFECT DATA' jp GETWRK ; Get work area address in [IX] jp PartInfo ; Get work area address of curr drive jp GetUnitsOn ; Get # of units online jp SetHOST_ID ; Set HOST ID (4-7) jp SetTargetID ; Set Target ID (0 - 3) clkchip jp GetTargetID ; Get Target ID (0 - 3) clkchip jp GetHOST_ID ; Get HOST ID (4 - 7) jp GetSense ; Get Sense codes and Sense key jp MedRemoval ; 'PREVENT ALLOW MEDIUM REMOVAL' jp NotSupp ; Reserved jp NotSupp ; Reserved jp NotSupp ; Reserved jp NotSupp ; Reserved jp NotSupp ; Install NExtBIOS jp NotSupp ; Reserved defb 0 ; Reserved defb 'KMcs' ; NOVAXIS SCSI ID - 7FF0h defb 2 ; 1 = Turbo-R, 0 = MSX2, 2 = MSX/Turbo - 7FF4h defb HIGH VERSION ; Version #, Hi (BCD) (1 digit) - 7FF5h defb LOW VERSION ; " #, Lo (Packed BCD, 2 digits - 7FF6h defb HOSTID ; Default host ID - 7FF7h defb baseport ; Base I/O port - 7FF8h defb ROMREVISION ; ROM revision level - 7FF9h defb 0,0,0,0,0,0 ; Reserved - 7FFAh .dephase END