movlop ;Copy the data lxi h,djread jmp prep ;Select drive, track, and ; sector. Then read the ************************************************************* * * * Mover moves 128 bytes of data. Source pointer in DE, Dest * * pointer in HL. * * * * ************************************************************* CONIN: ;READ A CHARACTER IN 03H ANI 02H JZ CONIN ;WAIT TILL A CHARACTER IS ; READY IN 02H ;GET THE CHARACTER ANI 7FH ;STRIP PARITY RET ************************************************************* * * * L * * * ************************************************************* flushA mvi a,0 ;The 0 is modified to reflect ; if the buffer has been ; written into bufwrtn equ $-1 ana a ;Test if written into rz ;Not written, all done lxi h,djwrite ;Write operation *********************a ;C <- side # call djside ;Select the side pop psw ;A <- sector # ani 7fh ;Strip off side bit mov c,a ;C <- sector # call djsec ;Set the sector to transfer lxi b,buffer ;Set the DMA address call djdma call djread ;The read operation is ; modified to write retryop equ $-2 pop ************************************************************* mover mvi b,128 ;Length of transfer movlop ldax d ;Get a byte of source mov m,a ;Move it inx d ;Bump pointers inx h dcr b ;Update counter jnz movlop ;Continue moving until done ret PAGE ************************************************************* * EFT SERIAL PORT ROUTINES. CONSOLE OUTPUT * * * ************************************************************* CONOUT: ;WRITE A CHARACTER IN 03H ANI 01H JZ CONOUT ;WAIT TILL THE BUFFER IS ; EMPTY MOV A,C ;WRITE THE CHARACTER OUT 02H RET ******************************************************************************** * * * Prep prepares to read/write the disk. Retries are * * attempted.Upon entry, H&L must contain the read or write * * operation address. * * * ************************************************************* prep xra a ;Reset buffer written flag sta bufwrtn b ;Restore the retry counter mvi a,0 ;No error exit status rnc ;Return no error dcr b ;Update the retry counter stc ;Assume retry count expired mvi a,0ffh ;Error return rz jmp retrylp ;Try again PAGE ************************************************************* * * * Terminal driver subroutines. Iobyte is not used. * * Note that the console device is NOT the DJ2D memory * * mapped serial I/O port. The NorthStar serial port is * * used instead. * * * ************************************************************* ;I/O ROUTINES FOR NORTHSTAR MOTHERBOARD ******************************************************************************************** * * * The following DPB defines a diskette as 512 byte sectors, * * double density, and single sided. * * * ************************************************************* dpb512s dw 60 ;CP/M sectors/track db 4 ;BSH db 15 ;BLM db 0 ;8 if double sided. PAGE ************************************************************* * * * The following DPB defines a diskette for 128 byte sectors,* * single density, and double sided. * * * ************************************************************* dpb128d dw 52 ;CP/M sectors/track db 4 ;BSH ************************************************ dpb512d dw 120 ;CP/M sectors/track db 4 ;BSH db 15 ;BLM db 0 ;EXM dw 561 ;DSM dw 255 ;DRM db 0f0h ;AL0 db 0 ;AL1 dw 64 ;CKS dw 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; db 3bh ******* dw alv0 ;Allocation vector DW DIRBCB ;DIRECTORY BUFFER CONTROL ; BLOCK DW 0FFFFH ;DTABCB DATA BUFFER CONTROL ; BLOCK DW 0FFFFH ;HASH DIRECTORY HASHING TABLE DB 0 ;HBANK BANK # OF HASH TABLE dpone dw 0 dw 0,0,0,0 DB 0 DB 0 dw 0 dw csv1 dw alv1 DW DIRBCB DW 0FFFFH DW 0FFFFH DB 0 dptwo dw 0 dw 0,0,0,0 DB 0 DB 0 dw 0 d ;EXM dw 280 ;DSM dw 127 ;DRM db 0c0h ;AL0 db 0 ;AL1 dw 32 ;CKS dw 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; db 33h ;16*((#cpm sectors/physical ;sector) -1) + log2(#bytes ;per sector/128) + 1 + 8 ;if double sid db 15 ;BLM db 1 ;EXM dw 242 ;DSM dw 127 ;DRM db 0c0h ;AL0 db 0 ;AL1 dw 32 ;CKS dw 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; db 9h ************************************************************* * * * The following DPB defin****************************************************** * * * The following DPB defines a diskette as 1024 byte sectors,* * double density, and double sided. * * * ************************************************************* dp1024d dw 128 ;CP/M sectors/track db 4 ;BSH db 15 ;BLM dbw csv2 dw alv2 DW DIRBCB DW 0FFFFH DW 0FFFFH DB 0 dpthre dw 0 dw 0,0,0,0 DB 0 DB 0 dw 0 dw csv3 dw alv3 DW DIRBCB DW 0FFFFH DW 0FFFFH DB 0 ************************************************************* * * * DIRECTORY BUFFER CONTROL BLOCK * * * *****ed. ************************************************************* * * * The following DPB defines a diskette as 1024 byte sectors,* * double density, and single sided. * * * ************************************************************* dp1024s dw 64 ;CP/M sectors/track db 4 ;BSH db 15 ;Bes a diskette as 256 byte sectors, * * double density, and double sided. * * * ************************************************************* dpb256d dw 104 ;CP/M sectors/track db 4 ;BSH db 15 ;BLM db 0 ;EXM dw 486 ;DSM dw 255 ;DRM db 0f0h ;AL0 0 ;EXM dw 599 ;DSM dw 255 ;DRM db 0f0h ;AL0 db 0 ;AL1 dw 64 ;CKS dw 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; db 7ch PAGE ************************************************************* * * * CP/M disk parameter headers, (FOR 4 DRIVES) ******************************************************** DIRBCB: DB 0FFH ;DRV DRIVE NUMBER DB 00,00,00 ;REC# RECORD POSITION IN ; BUFFER DB 00 ;WFLG BUFFER WRITTEN FLAG DB 00 ;00 BIOS SCRATCH FLAG DW 0000 ;TRACK BUFFER CONTENTS' ; PHYSICAL TRACK DW 0000 ;SECTOR BUFFER CONTENTS' ; PHYSICAL SECTOR DW DIRBUF ;BUFFAD BUFFER ADDRESS PAGE ************************************************************* * * LM db 0 ;EXM dw 299 ;DSM dw 127 ;DRM db 0c0h ;AL0 db 0 ;AL1 dw 32 ;CKS dw 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; db 74h ;16*((#cpm sectors/physical ;sector) -1) + log2(#bytes ;per sector/128) + 1 + db 0 ;AL1 dw 64 ;CKS dw 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; db 1ah PAGE ************************************************************* * * * The following DPB defines a diskette as 512 byte sectors, * * double density, and double sided. * * * ************* * * * ************************************************************* dpzero dw 0 ;Address of translation table ; (filled in by setdrv) dw 0,0,0,0 ;Used by BDOS DB 0 DB 0 ;MF MEDIA FLAG dw 0 ;Address of DPB (filled in ; by setdrv) dw csv0 ;Directory check vector mov c,a ;C <- sector # call djsec ;Set the sector to transfer lxi b,buffer ;Set the DMA address call djdma call djread ;The read operation is ; modified to write retryop equ $-2 pop b ;Restore the retry counter mvi a,0 ;No error exit status rnc ;Return no error dcr b mov m,a ;Move it inx d ;Bump pointers inx h dcr b ;Update counter jnz movlop ;Continue moving until done ret PAGE ************************************************************* * * * Terminal driver subroutines. Iobyte is not used. * * Note that the console device is NOT the DJ2D memory * * mapped serial I/**** CONOUT: ;WRITE A CHARACTER IN 03H ANI 01H JZ CONOUT ;WAIT TILL THE BUFFER IS ; EMPTY MOV A,C ;WRITE THE CHARACTER OUT 02H RET ************************************************************* * * * LEFT SERIAL PORT ROUTINES. CONSOLE INPUT STATUS * * *********************************************** * * * RIGHT SERIAL PORT ROUTINES. RIGHT OUTPUT * * * ************************************************************* RTOUT: ;WRITE A CHARACTER IN 05H ANI 01H JZ RTOUT ;WAIT TILL THE BUFFER IS ; EMPTY MOV ;Update the retry counter stc ;Assume retry count expired mvi a,0ffh ;Error return rz jmp retrylp ;Try again PAGE ************************************************************* * * * Fill fills the buffer with a new sector from the disk. * * * ***************************************************O port. The NorthStar serial port is * * used instead. * * * ************************************************************* ;I/O ROUTINES FOR NORTHSTAR MOTHERBOARD ************************************************************* * * * LEFT SERIAL PORT ROUTINES. CONSOLE I/O * * * ************************************************************* CONST: ;RETURN INPUT BUFFER STATUS IN 03H ANI 02H RZ ;RETURN NOT READY MVI A,0FFH RET ;THERE IS A CHARACTER READY ************************************************************* * * * LEFT SERIAL PORT ROUTINES. CONSOLE OUT STATUS A,C ;WRITE THE CHARACTER OUT 04H RET ************************************************************* * * * RIGHT SERIAL PORT ROUTINES. RIGHT INPUT STATUS * * * ************************************************************* RTIST: ;RETURN INPUT BUFFER STATUS IN 05H ANI 02H RZ ********** fill call flushA ;Flush buffer first rc ;Check for error lxi d,cpmdrv ;Update the drive, track, ; and sector lxi h,bufdrv mvi b,3 ;Number of bytes to move call movlop ;Copy the data lxi h,djread jmp prep ;Select drive, track, and ; sector. Then read the * ************************************************************* ************************************************************* * * * LEFT SERIAL PORT ROUTINES. CONSOLE INPUT * * * ************************************************************* CONIN: ;READ A CHARACTER IN 03H ANI 02H JZ * * * ************************************************************* CONOST: ;RETURN OUTPUT BUFFER STATUS IN 03H ANI 01H RZ ;RETURN NOT READY MVI A,0FFH RET ;RETURN READY PAGE ************************************************************* * * * ;RETURN NOT READY MVI A,0FFH RET ;THERE IS A CHARACTER READY ************************************************************* * * * RIGHT SERIAL PORT ROUTINES. RIGHT OUT STATUS * * * ************************************************************* RTOST: ;RETURN OUTPUT BUFFER STATUS IN ************************************************************* * * * Mover moves 128 bytes of data. Source pointer in DE, Dest * * pointer in HL. * * * ************************************************************* mover mvi b,128 ;Length of transfer movlop ldax d ;Get a byte of source CONIN ;WAIT TILL A CHARACTER IS ; READY IN 02H ;GET THE CHARACTER ANI 7FH ;STRIP PARITY RET ************************************************************* * * * LEFT SERIAL PORT ROUTINES. CONSOLE OUTPUT * * * ********************************************************* RIGHT SERIAL PORT ROUTINES. RIGHT INPUT * * * ************************************************************* RTIN: ;READ A CHARACTER IN 05H ANI 02H JZ RTIN ;WAIT TILL A CHARACTER IS ; READY IN 04H ;GET THE CHARACTER ANI 7FH ;STRIP PARITY RET ************** dw alv0 ;Allocation vector DW DIRBCB ;DIRECTORY BUFFER CONTROL ; BLOCK DW 0FFFFH ;DTABCB DATA BUFFER CONTROL ; BLOCK DW 0FFFFH ;HASH DIRECTORY HASHING TABLE DB 0 ;HBANK BANK # OF HASH TABLE dpone dw 0 dw 0,0,0,0 DB 0 DB 0 dw 0 dw csv1 dw alv1 DW DIRBCB DW 0FFFFH DW 0FFFFH DB 0 dptwo dw 0 dw 0,0,0,0 DB 0 DB 0 dw 0 d buftrk db 0 ;Track that buffer belongs to bufsec db 0 ;Sector that buffer belongs to buffer ds 1024 ;Maximum size buffer for 1K ; sector ************************************************************* * * * ALLOCATION VECTORS (FOR 4 DRIVES) * * EACH VECTOR REQUIRES 2 BITS FOR EACH BLOCK ON THE DRIVE * * mov c,a ;Output character in C call cout ;Output the character pop h ;Test for end rz ;Return if done push h ;Save pointer to text e ; message inx h ;Bump text pointer ana a * ************************************************************* message mov a,m ;Get a character of thinto * * the buffer. * * * ************************************************************* write mov a,c ;Save write command type sta writtyp mvi a,1 ;Set write command db (mvi) or (b*8) ;This "mvi b" instruction ; causes the following ; "xra a" to be skipped overw csv2 dw alv2 DW DIRBCB DW 0FFFFH DW 0FFFFH DB 0 dpthre dw 0 dw 0,0,0,0 DB 0 DB 0 dw 0 dw csv3 dw alv3 DW DIRBCB DW 0FFFFH DW 0FFFFH DB 0 ************************************************************* * * * DIRECTORY BUFFER CONTROL BLOCK * * * ***** * ************************************************************* alv0 ds 150 ;Allocation vector for drv A alv1 ds 150 ;Allocation vector for drv B alv2 ds 150 ;Allocation vector for drv C alv3 ds 150 ;Allocation vector for drv D ************************************************************* * * * CHECKSUM VECTORS (FOR 4 DRIV*** xlts dw xlt128 ;Xlt for 128 byte sectors dw xlt256 ;Xlt for 256 byte sectors dw xlt512 ;Xlt for 512 byte sectors dw xlt124 ;Xlt for 1024 byte sectors ************************************************************* * * * The table following the xlt's is a table of the DPB's, * * used by the SETDRV subroutine to calculate density * * . ************************************************************* * * * Read routine to buffer data from the disk. If the sector * * requested from CP/M is in the buffer, then the data is * * simply transferred from the buffer to the desired dma * * address. If the buffer does not contain the desired * * sector, the buffer is flushed to the disk if it has ever * * been written into, then filled with the sector from the * * d******************************************************** DIRBCB: DB 0FFH ;DRV DRIVE NUMBER DB 00,00,00 ;REC# RECORD POSITION IN ; BUFFER DB 00 ;WFLG BUFFER WRITTEN FLAG DB 00 ;00 BIOS SCRATCH FLAG DW 0000 ;TRACK BUFFER CONTENTS' ; PHYSICAL TRACK DW 0000 ;SECTOR BUFFER CONTENTS' ; PHYSICAL SECTOR DW DIRBUF ;BUFFAD BUFFER ADDRESS PAGE ************************************************************* * * ES) * * EACH VECTOR REQUIRES 1 BIT FOR EVERY 4 DIRECTORY ENTRIES * * * ************************************************************* csv0 ds 64 ;Directory check vector ; drive A csv1 ds 64 ;Directory check vector ; drive B csv2 ds 64 ;Directory check vector * ************************************************************* DW DPB128S ; 128 BYTE SECTORS SINGLE SIDE DW DPB256S ; 256 BYTE SECTORS SINGLE SIDE DW DPB512S ; 512 BYTE SECTORS SINGLE SIDE DW DP1024S ; 1024 BYTE SECTORS SINGLE SIDE DW DPB128D ; 128 BYTE SECTORS DOUBLE SIDE DW DPB256D ; 256 BYTE SECTORS DOUBLE SIDE DW DPB512D ; 512 BYTE SECTORS DOUBLE SIDE DW DP1024D ; 1024 BYTE SECTORS DOUBLE SIDE PAGE ***********************************************isk that contains the desired CP/M sector. * * * ************************************************************* read xra a ;Set the command type to read sta rdwr ;Save command type PAGE ************************************************************* * * * Redwrt calculates the physical sector on the disk that * * co * Cbios ram locations that don't need initialization. * * * ************************************************************* cpmsec db 0 ;CP/M sector # cpmdrv db 0 ;CP/M drive # cpmtrk db 0 ;CP/M track # truesec db 0 ;Disk Jockey sector that ; contains CP/M sector bufdrv db 0 ;Drive that buffer belongs to ; drive C csv3 ds 64 ;Directory check vector ; drive D ************************************************************* * * * DIRECTORY BUFFER * * * ************************************************************* dirbuf ds 128 ;Directory buffer ; end ************** * * * Write routine moves data from memory into the buffer. If * * the desired CP/M sector is not contained in the disk * * buffer, the buffer is first flushed to the disk if it has * * ever been written into, then a read is performed into the * * buffer to get the desired sector. Once the correct sector * * is in memory, the buffer written indicator is set, so the * * buffer will be flushed, then the data is transferred *********************************************** * * * RIGHT SERIAL PORT ROUTINES. RIGHT OUTPUT * * * ************************************************************* RTOUT: ;WRITE A CHARACTER IN 05H ANI 01H JZ RTOUT ;WAIT TILL THE BUFFER IS ; EMPTY MOV ;READ A CHARACTER IN 06H ANI 01H JZ PARIN ;WAIT TILL A CHARACTER IS ; READY IN 00H ;GET THE CHARACTER PUSH PSW MVI A,30H ;RESET THE PARALLEL INPUT ; FLAG OUT 06H POP PSW ANI 7FH ;STRIP PARITY RET ************************************************************* * TUS * * * ************************************************************* LISTST: ;RETURN OUTPUT BUFFER STATUS IN 06H ANI 02H RZ ;RETURN NOT READY MVI A,0FFH RET ;RETURN READY PAGE ************************************************************* * 2,53,54,55,56 db 9,10,11,12,13,14,15,16 db 33,34,35,36,37,38,39,40 db 57,58,59,60,61,62,63,64 db 17,18,19,20,21,22,23,24 db 41,42,43,44,45,46,47,48 PAGE ************************************************************* * * * Each of the following tables describes a diskette with * * the specified characteristics. The tables are currently * * stored on track 0 secto A,C ;WRITE THE CHARACTER OUT 04H RET ************************************************************* * * * RIGHT SERIAL PORT ROUTINES. RIGHT INPUT STATUS * * * ************************************************************* RTIST: ;RETURN INPUT BUFFER STATUS IN 05H ANI 02H RZ * * PARALLEL PORT ROUTINES. PRINTER OUTPUT * * * ************************************************************* LIST: ;WRITE A CHARACTER IN 06H ANI 02H JZ LIST ;WAIT TILL THE BUFFER IS ; EMPTY MVI A,20H ;RESET THE PARALLEL OUTPUT * * Xlt tables (sector skew tables) for CP/M 2.0. These * * tables define the sector translation that occurs when * * mapping CP/M sectors to physical sectors on the disk. * * There is one skew table for each of the possible sector * * sizes. Currently the tables are located on track 0 * * sectors 6 and 8. They are loaded into memory in the Cbios * * ram by the cold boot routine. * * * *r 13. They are read into memory by * * the GOCPM routine in the CBIOS for CP/M ver 2.2. * * * ************************************************************* ************************************************************* * * * The following DPB defines a diskette for 128 byte * * sectors, single density, and single sided. * * ;RETURN NOT READY MVI A,0FFH RET ;THERE IS A CHARACTER READY ************************************************************* * * * RIGHT SERIAL PORT ROUTINES. RIGHT OUT STATUS * * * ************************************************************* RTOST: ;RETURN OUTPUT BUFFER STATUS IN ; FLAG OUT 06H MOV A,C ;WRITE THE CHARACTER, STROBE ; BIT 7 NSPOUT: ORI 80H OUT 00H ANI 7FH OUT 00H ORI 80H OUT 00H RET ************************************************************* * * * PARALLEL PORT ROUTINES. INPUT STATUS * * ************************************************************ xlt128 db 0 db 1,7,13,19,25 db 5,11,17,23 db 3,9,15,21 db 2,8,14,20,26 db 6,12,18,24 db 4,10,16,22 xlt256 db 0 db 1,2,19,20,37,38 db 3,4,21,22,39,40 db 5,6,23,24,41,42 db 7,8,25,26,43,44 db 9,10,27,28,45,46 db 11,12,29,30,47,48 db 13,14,31,32,49,50 * ************************************************************* dpb128s dw 26 ;SPT CP/M sectors/track db 3 ;BSH BLOCK SHIFT FACTOR db 7 ;BLM BLOCK MASK db 0 ;EXM EXTENT MASK dw 242 ;DSM DISK SPACE MAXIMUM dw 63 ;DRM DIRECTORY MAXIMUM db 0c0h ;AL0 INITIAL ALLOTARION db 0 ;A 05H ANI 01H RZ ;RETURN NOT READY MVI A,0FFH RET ;RETURN READY PAGE ************************************************************* * * * PARALLEL PORT ROUTINES. PARALLEL INPUT * * * ************************************************************* PARIN: * ************************************************************* PINPST: ;RETURN INPUT BUFFER STATUS IN 06H ANI 01H RZ ;RETURN NOT READY MVI A,0FFH RET ;RETURN READY PAGE ************************************************************* * * * PARALLEL PORT ROUTINES. LIST DEVICE STA db 15,16,33,34,51,52 db 17,18,35,36 xlt512 db 0 db 1,2,3,4,17,18,19,20 db 33,34,35,36,49,50,51,52 db 5,6,7,8,21,22,23,24 db 37,38,39,40,53,54,55,56 db 9,10,11,12,25,26,27,28 db 41,42,43,44,57,58,59,60 db 13,14,15,16,29,30,31,32 db 45,46,47,48 xlt124 db 0 db 1,2,3,4,5,6,7,8 db 25,26,27,28,29,30,31,32 db 49,50,51,5 c,a ;Make new sector the requested ; sector pop d call sideone mvi a,80h ;Side two bit ora l ; and sector mov l,a ret PAGE ************************************************************* * * * Setdrv selects the next drive to be used in read/write * * operations. If the drive has ;Table of XLT addresses PUSH H mov e,a mvi d,0 dad d push h ;Save pointer to proper XLT call getdpb ;Get DPH pointer into DE xchg ; pop d mvi b,2 ;Number of bytes to move call movlop ;Move the address of XLT lxi d,10 ;Offset to DPB pointer dad d ;HL <- &DPH.DPB XCHG POP B address inx h mov h,m ;Get low byte of DPB mov l,a pop d ret ************************************************************* * * * Xlts is a table of address that point to each of the xlt * * tables for each sector size. * * * ********************************************************** operation jnz into ;Transfer data into the buffer outof call mover xra a ret into xchg ; call mover ;Move the data, HL = destination ; DE = source mvi a,1 sta bufwrtn ;Set buffer written into flag mvi a,0 ;Check for directory write writtyp equ $-1 dcr a mvi a,0 sta writ never been selected before, * * a parameter table is created which correctly describes * * the diskette currently in the drive. Diskettes can be of * * four different sector sizes: * * 1) 128 bytes single density. * * 2) 256 bytes double density. * * 3) 512 bytes double density. * * 4) 1024 bytes double density. * * H pop psw ;Offset to correct DPB mov c,a mvi b,0 dad b ;ADD TO TRANSLATE TABLE ; TO POINT TO DENSITY ; (THE DPB TABLE IS CLEVERLY ; LOCATED RIGHT AFTER THE ; XLT TABLE) xchg ;Put DPB address in DPH MVI B,2 ;MOVE DPB ADDRESS INTO DPH CALL MOVLOP setdrv1 call getdpb ;Get address of DPB in HL lxi b,17 ;Offset to sector size dad b mov drv D ************************************************************* * * * CHECKSUM VECTORS (FOR 4 DRIVES) * * EACH VECTOR REQUIRES 1 BIT FOR EVERY 4 DIRECTORY ENTRIES * * * ************************************************************* csv0 ds 64 ;Directory check vector ; drive A csv1 ds 64 typ ;Set no directory write rnz ;No error exit ************************************************************* * * * FlushA writes the contents of the buffer out to the disk * * if it has ever been written into. * * * ************************************************************* flushA mvi a,0 ;The 0 is mod * ************************************************************* setdrv mov a,c ;Save the drive # sta cpmdrv cpi maxdisk ;Check for a valid drive # jnc zret ;Illegal drive # mov a,e ;Test if drive ever logged ; in before ani 1 jnz setdrv1 ;Bit 0 of E = 0 -> Never ; selected before a,m ;Get sector size ani 7h sta secsiz mov a,m rar rar rar rar ani 0fh sta secpsec xchg ;HL <- DPH ret zret lxi h,0 ;Seldrv error exit ret PAGE ************************************************************* * * * Getdpb returns HL pointing to the DPB of the ;Directory check vector ; drive B csv2 ds 64 ;Directory check vector ; drive C csv3 ds 64 ;Directory check vector ; drive D ************************************************************* * * * DIRECTORY BUFFER * * ified to reflect ; if the buffer has been ; written into bufwrtn equ $-1 ana a ;Test if written into rz ;Not written, all done lxi h,djwrite ;Write operation ************************************************************* * * * Prep prepares to read/write the disk. Retries are * * attempted. mvi a,1 ;Select sector 1 of track 1 sta truesec sta cpmtrk call fill ;Flush buffer and refill jc zret ;Test for error return call djstat ;Get status on current drive ani 2ch ;LOK AT SIDE AND DENSITY BITS MOV E,A ANI 20H MOV A,E JNZ SETDR1 ORI 10H SETDR1: RAR push psw ;SAVE DJSTAT 1/2 SIDED INFO ANI 6 lxi h,xlts currently * * selected drive, DE pointing to DPH. * * * ************************************************************* getdpb lda cpmdrv ;Get drive # LXI H,DPZERO LXI D,19H GETDP1: ORA A JZ GETDP2 DAD D DCR A JMP GETDP1 ; GETDP2: push h ;Save address of DPH lxi d,12 ;Offset to DPB dad d mov a,m ;Get low byte of DP * ************************************************************* dirbuf ds 128 ;Directory buffer ; end  $-2 mvi a,0 ;The zero gets modified to ; contain a zero if a read, ; or a 1 if write rdwr equ $-1 ana a ;Test which kind of;THERE IS A CHARACTER READY PAGE ************************************************************* * * * Xlt tables (sector skew tables) for CP/M 2.0. These * * tables define the sector translation that occurs when * * mapping CP/M sectors to physical sectors on the disk. * * There is one skew table for each of the possible sector * * sizes. Currently the tables are located on track 0 * * sectors 6 and 8. They * * Each of the following tables describes a diskette with * * the specified characteristics. The tables are currently * * stored on track 0 sector 13. They are read into memory by * * the GOCPM routine in the CBIOS for CP/M ver 2.2. * * * ************************************************************* ************************************************************* * 52 ;CP/M sectors/track db 4 ;BSH db 15 ;BLM db 0 ;EXM dw 242 ;DSM dw 127 ;DRM db 0c0h ;AL0 db 0 ;AL1 dw 32 ;CKS dw 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; db 12h ;16*((#cpm sectors/physical ;************************************* dp1024s dw 64 ;CP/M sectors/track db 4 ;BSH db 15 ;BLM db 0 ;EXM dw 299 ;DSM dw 127 ;DRM db 0c0h ;AL0 db 0 ;AL1 dw 32 ;CKS dw 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; db 74h ;16*((#cpare loaded into memory in the Cbios * * ram by the cold boot routine. * * * ************************************************************* xlt128 db 0 db 1,7,13,19,25 db 5,11,17,23 db 3,9,15,21 db 2,8,14,20,26 db 6,12,18,24 db 4,10,16,22 xlt256 db 0 db 1,2,19,20,37,38 db 3,4,21,22,39,40 * * The following DPB defines a diskette for 128 byte * * sectors, single density, and single sided. * * * ************************************************************* dpb128s dw 26 ;SPT CP/M sectors/track db 3 ;BSH BLOCK SHIFT FACTOR db 7 ;BLM BLOCK MASK db 0 ;EXM EXTENT MASK dw 242 ;DSM Dsector) -1) + log2(#bytes ;per sector/128) + 1 + 8 ;if double sided. PAGE ************************************************************* * * * The following DPB defines a diskette as 512 byte sectors, * * double density, and single sided. * * * *********************************************m sectors/physical ;sector) -1) + log2(#bytes ;per sector/128) + 1 + ;8 if double sided. PAGE ************************************************************* * * * The following DPB defines a diskette for 128 byte sectors,* * single density, and double sided. * * db 5,6,23,24,41,42 db 7,8,25,26,43,44 db 9,10,27,28,45,46 db 11,12,29,30,47,48 db 13,14,31,32,49,50 db 15,16,33,34,51,52 db 17,18,35,36 xlt512 db 0 db 1,2,3,4,17,18,19,20 db 33,34,35,36,49,50,51,52 db 5,6,7,8,21,22,23,24 db 37,38,39,40,53,54,55,56 db 9,10,11,12,25,26,27,28 db 41,42,43,44,57,58,59,60 db 13,14,15,ISK SPACE MAXIMUM dw 63 ;DRM DIRECTORY MAXIMUM db 0c0h ;AL0 INITIAL ALLOTARION db 0 ;AL1 VECTORS dw 16 ;CKS DIRECTORY CHECK SIZE dw 2 ;OFF TRACK OFFSET DB 00 ;PSH PHYSICAL REC SHIFT FACT DB 00 ;PHM PHYSICAL RECORD MASK ;NEXT BYTE USED BY THE BIOS db 1h ;16*((#cpm sectors/physical ;sector) -1) + log2(#b**************** dpb512s dw 60 ;CP/M sectors/track db 4 ;BSH db 15 ;BLM db 0 ;EXM dw 280 ;DSM dw 127 ;DRM db 0c0h ;AL0 db 0 ;AL1 dw 32 ;CKS dw 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; db 33h ;16*((#cpm sectors/physical * ************************************************************* dpb128d dw 52 ;CP/M sectors/track db 4 ;BSH db 15 ;BLM db 1 ;EXM dw 242 ;DSM dw 127 ;DRM db 0c0h ;AL0 db 0 ;AL1 dw 32 ;CKS dw 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; 16,29,30,31,32 db 45,46,47,48 xlt124 db 0 db 1,2,3,4,5,6,7,8 db 25,26,27,28,29,30,31,32 db 49,50,51,52,53,54,55,56 db 9,10,11,12,13,14,15,16 db 33,34,35,36,37,38,39,40 db 57,58,59,60,61,62,63,64 db 17,18,19,20,21,22,23,24 db 41,42,43,44,45,46,47,48 PAGE ************************************************************* * ytes ;per sector/128) + 1 + 8 if ;double sided. ************************************************************* * * * The following DPB defines a diskette for 256 byte * * sectors, double density, and single sided. * * * ************************************************************* dpb256s dw ;sector) -1) + log2(#bytes ;per sector/128) + 1 + 8 ;if double sided. ************************************************************* * * * The following DPB defines a diskette as 1024 byte sectors,* * double density, and single sided. * * * *********************************************** * * * Settrk saves the track # to seek to. Nothing is done at * * this point, everything is deffered until a read or write. * * * ************************************************************* settrk mov a,c ;A <- track # sta cpmtrk ;CP/M track # ret PAGE *********************************************** ;8 IF DOUBLE SIDED. PAGE ************************************************************* * * * THE FOLLOWING DPB DEFINES A DISKETTE FOR 128 BYTE SECTORS,* * SINGLE DENSITY, AND DOUBLE SIDED. * * * ************************************************************* DPB128D DW 52 ;CP/M SECTORS/TRACK DB 4 ;BSH ************************************************ DPB512D DW 120 ;CP/M SECTORS/TRACK DB 4 ;BSH DB 15 ;BLM DB 0 ;EXM DW 561 ;DSM DW 255 ;DRM DB 0F0H ;AL0 DB 0 ;AL1 DW 64 ;CKS DW 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; DB 3BH ******* DW ALV0 ;ALLOCATION VECTOR DW DIRBCB ;DIRECTORY BUFFER CONTROL ; BLOCK DW 0FFFFH ;DTABCB DATA BUFFER CONTROL ; BLOCK DW 0FFFFH ;HASH DIRECTORY HASHING TABLE DB 0 ;HBANK BANK # OF HASH TABLE DPONE DW 0 DW 0,0,0,0 DB 0 DB 0 DW 0 DW CSV1 DW ALV1 DW DIRBCB DW 0FFFFH DW 0FFFFH DB 0 DPTWO DW 0 DW 0,0,0,0 DB 0 DB 0 DW 0 D ;EXM DW 280 ;DSM DW 127 ;DRM DB 0C0H ;AL0 DB 0 ;AL1 DW 32 ;CKS DW 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; DB 33H ;16*((#CPM SECTORS/PHYSICAL ;SECTOR) -1) + LOG2(#BYTES ;PER SECTOR/128) + 1 + 8 ;IF DOUBLE SID DB 15 ;BLM DB 1 ;EXM DW 242 ;DSM DW 127 ;DRM DB 0C0H ;AL0 DB 0 ;AL1 DW 32 ;CKS DW 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; DB 9H ************************************************************* * * * THE FOLLOWING DPB DEFIN****************************************************** * * * THE FOLLOWING DPB DEFINES A DISKETTE AS 1024 BYTE SECTORS,* * DOUBLE DENSITY, AND DOUBLE SIDED. * * * ************************************************************* DP1024D DW 128 ;CP/M SECTORS/TRACK DB 4 ;BSH DB 15 ;BLM DBW CSV2 DW ALV2 DW DIRBCB DW 0FFFFH DW 0FFFFH DB 0 DPTHRE DW 0 DW 0,0,0,0 DB 0 DB 0 DW 0 DW CSV3 DW ALV3 DW DIRBCB DW 0FFFFH DW 0FFFFH DB 0 ************************************************************* * * * DIRECTORY BUFFER CONTROL BLOCK * * * *****ED. ************************************************************* * * * THE FOLLOWING DPB DEFINES A DISKETTE AS 1024 BYTE SECTORS,* * DOUBLE DENSITY, AND SINGLE SIDED. * * * ************************************************************* DP1024S DW 64 ;CP/M SECTORS/TRACK DB 4 ;BSH DB 15 ;BES A DISKETTE AS 256 BYTE SECTORS, * * DOUBLE DENSITY, AND DOUBLE SIDED. * * * ************************************************************* DPB256D DW 104 ;CP/M SECTORS/TRACK DB 4 ;BSH DB 15 ;BLM DB 0 ;EXM DW 486 ;DSM DW 255 ;DRM DB 0F0H ;AL0 0 ;EXM DW 599 ;DSM DW 255 ;DRM DB 0F0H ;AL0 DB 0 ;AL1 DW 64 ;CKS DW 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; DB 7CH PAGE ************************************************************* * * * CP/M DISK PARAMETER HEADERS, (FOR 4 DRIVES) ******************************************************** DIRBCB: DB 0FFH ;DRV DRIVE NUMBER DB 00,00,00 ;REC# RECORD POSITION IN ; BUFFER DB 00 ;WFLG BUFFER WRITTEN FLAG DB 00 ;00 BIOS SCRATCH FLAG DW 0000 ;TRACK BUFFER CONTENTS' ; PHYSICAL TRACK DW 0000 ;SECTOR BUFFER CONTENTS' ; PHYSICAL SECTOR DW DIRBUF ;BUFFAD BUFFER ADDRESS PAGE ************************************************************* * * LM DB 0 ;EXM DW 299 ;DSM DW 127 ;DRM DB 0C0H ;AL0 DB 0 ;AL1 DW 32 ;CKS DW 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; DB 74H ;16*((#CPM SECTORS/PHYSICAL ;SECTOR) -1) + LOG2(#BYTES ;PER SECTOR/128) + 1 + DB 0 ;AL1 DW 64 ;CKS DW 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; DB 1AH PAGE ************************************************************* * * * THE FOLLOWING DPB DEFINES A DISKETTE AS 512 BYTE SECTORS, * * DOUBLE DENSITY, AND DOUBLE SIDED. * * * ************* * * * ************************************************************* DPZERO DW 0 ;ADDRESS OF TRANSLATION TABLE ; (FILLED IN BY SETDRV) DW 0,0,0,0 ;USED BY BDOS DB 0 DB 0 ;MF MEDIA FLAG DW 0 ;ADDRESS OF DPB (FILLED IN ; BY SETDRV) DW CSV0 ;DIRECTORY CHECK VECTOR***************************** * * * To install this BIOS into CP/M 3.0, perform the following * * steps: * * 1. Add your own console and printer I/O to this file* * at CONIN:, CONOUT:, CONST:, LIST:, and LISTST: * * 2. Add any initialization that you need at TINIT: * * 3. Set the LDRBIOS equate in this file to TRUE * * 4. RMAC SCB (ASSEMBLE SCB.ASM, supplied) * * 5. RMAC BIOS3 (ASSEMble LDRBIOS) * * 6. REN L**************************** ORIGIN EQU 0E000H ;EPROM ORIgin of your DJ2D board DJRAM EQU ORIGIN+400H ;RAM address DJHOME EQU DJRAM+9H ;DJ2D track zero seek DJTRK EQU DJRAM+0CH ;DJ2D track seek routine DJSEC EQU DJRAM+0FH ;DJ2D set sector routine DJDMA EQU DJRAM+012H ;SEt DMA address DJREAD EQU DJRAM+15H ;REad routine DJWRITE EQU DJRAM+18H ;Write routine DJSEL EQU DJRAM+1BH ;DJ2D select drive routine DJSTAT EQU DJRAM+27H ;STatus routine DJSIDE EQU DJRAM+30H ;SEt side routine *********** * * THE BIOS JUMP TABLE * * * * The jump table below must remain in the same order, the * * routines may be changed, but the function executed must be* * the same. There are 33 jumps in the CP/M Plus BIOS vector* * * ************************************************************* ; ?BOOT: JMP CBOOT ;cOLD STArt entry point WBOOTE: ?WBOOT: JMP WBOOT ;WARM STart entry point ?CONST: JMP RESERV2 ;RESERVED FOr CP/M Plus ; ; Device Table is not implemented, so return HL=0 DEVTBL: LXI H,0 RET ; ; Flush routine is not implemented, so return A=0 FLUSH: XRA A RET ; ; Drive Table is not used, so return HL=0FFFEH DRVTBL: LXI H,0FFFEH RET ; ; The following jumps from the BIOS jump vector ; are not implemented: AUXIST: AUXOUT: AUXIN: AUXOST: DEVINI: MULTIO: XMOVE: SELMEM: SETBNK: RESERV1: RESERV2: ?TIME: RET ******************************************DRBIOS.REL=BIOS3.REL * * 7. Set the LDRBIOS equate in this file FALSE * * 8. RMAC BIOS3 (assemble BIOS) * * 9. LINK BIOS3[B]=BIOS3,SCB * * 10. GENCPM * * (Answer all questions with a carriage return * * EXCEPT ANSswer "N" at "Bank switched memory?" * * Question, and answer with your top page of * * MEMORY WHen asked "Top page of memory?") * * 11. LINK CPMLDR[L100]=CPMLDR,LDRBIOS * * ************************************************** * * * Miscellaneous internal BIOS equates. * * We've tried to maintain compatibility with the Morrow's * * DJ2D BIOS. * * * ************************************************************* LDRBIOS EQU FALSE ;TRUE IF YOU want to assemble as Loader BIOS UD2 EQU FALSE ;TRUE if want to use User/Drive byte @ addr 4 CDISK EQU 4 ;Address of last logge JMP CONST ;CONSOLE status A=ff=ready ?CONIN: JMP CONIN ;CONSOLE input data in A COUT: ?CONO: JMP CONOUT ;CONSOLE output data in C ?LIST: JMP LIST ;LIST DEVice data in C ?AUXO: JMP AUXOUT ;PUNCH Device none ?AUXI: JMP AUXIN ; reader device none ?HOME JMP HOME ;SEEK HOME track ?SLDSK: JMP SETDRV ;SELECT disk disk in C ?STTRK: JMP SETTRK ;SEEK Track track in BC ?STSEC: JMP SETSEC ;SET SEctor sector in BC ?STDMA: JMP SETDMA ;SET DMa dma in BC ?READ: JMP READ ;R******************* * * * Cold-boot sign-on message * * * ************************************************************* PROMPT: IF LDRBIOS DB ACR,ALF,ALF DB 'Loader for Morrow Designs DJ2D Controller.' DB ACR,ALF,0 ENDIF ; IF NOT LDRBIOS DB ACR,ALF,ALF DB 'CP/M 3.0 (V' ;CP/M VERsion number DB CPMREV/10+'0' DB '.' DB (CPMREV MOD 10)+'0' DB '), BIOS rev ' DB REVNUM/10+'0','.' ;revision