TITLE 'MP/M LOADER, COPYRIGHT 1979, ALTOS COMPUTER SYSTEMS' ;----------------------------------------------------------------------- ; ; ALTOS COMPUTER SYSTEMS ; 2338A WALSH AVENUE ; SANTA CLARA, CA 95050 ; ; (408) 244-5766 ; ; COPYRIGHT 1979, ALTOS COMPUTER SYSTEMS ; ; THIS PROGRAM IS INTENDED TO PERFORM THE LOADING OF THE ; CCP AND BDOS INTO MEMORY DURING THE FIRST COLD START ; OF THE ALTOS SYSTEM. ; ONCE THE SYSTEM IS LOADED IT WILL LOAD THE FULL CBIOS ; ROUTINES WHICH WILL CONTROL THE LOADING AND OPERATION ; OF THE SYSTEM FROM THAT POINT ONWARD. ; IF THE INITIAL LOAD OF THE SYSTEM IS UNABLE TO FIND THE ; FULL CBIOS ON THE CURRENT DISK IT WILL CONTINUE TO ; OPERATE BUT IN A DEGRADED MODE. ; ; VERSION: 2.00 ; DATE: DECEMBER 5, 1979 ; . INITIAL VERSION OF PROGRAM. ; ;----------------------------------------------------------------------- MACLIB DISKDEF MACLIB Z80S VERSION EQU 20 ;CP/M VERSION NUMBER ALTOSV EQU 0 ;ALTOS VERSION NUMBER TRUE EQU 0FFFFH ; FALSE EQU 00000H ; ;----------------------------------------------------------------------- ; ; THE FOLLOWING FIELDS ARE USER MODIFIABLE ; ;----------------------------------------------------------------------- MSIZE EQU 32 ; DMA EQU TRUE ; HARDSK EQU TRUE ; ;----------------------------------------------------------------------- ; ; THE FOLLOWING CONSTANTS APPLY TO THE RELOCATION OF BIOS ; ;----------------------------------------------------------------------- RELOC EQU TRUE ; RAM$TOP EQU 1D00H ;TOP ADDRESS+1 BIOS EQU RAM$TOP-0600H ;BASIC INPUT/OUTPUT BDOS EQU BIOS-0E00H ;BASE OF THE BDOS ORG BIOS BUFF EQU 080H ;DEFAULT BUFFER RETRY EQU 10 ;MAX RETRIES ON DISK ; ; JUMP VECTOR FOR INDIVIDUAL SUBROUTINES ; ;----------------------------------------------------------------------- jmp boot ;cold start wboote: jmp wboot ;warm start jmp const ;console status jmp conin ;console character in jmp conout ;console character out jmp list ;list character out jmp punch ;punch character out jmp reader ;reader character out jmp home ;move head to home position jmp seldsk ;select disk jmp settrk ;set track number jmp setsec ;set sector number jmp setdma ;set dma address jmp read ;read disk jmp write ;write disk jmp listst ;return list status jmp sectran ;sector translate PAGE ;----------------------------------------------------------------------- ; ; FIXED TABLES FOR TWO DRIVE MINIMAL STANDARD SYSTEM ; ; THE LOCATION OF THE FOLLOWING TABLES MUST NOT BE ; CHANGED AS EXTERNAL PROGRAMS RELY ON THEIR ; POSITION IN THIS PROGRAM. ; ;----------------------------------------------------------------------- TRKM: DB 000H,000H,000H,000H ;TRACK REGISTERS SELM: DB 004H,008H,010H,020H ;DENSITY MASKS UPDATED BY SETUP MODM: DB 000H,000H,000H,000H ;MODE MASKS UPDATED BY SETUP PTR1: DB 047H,00DH ;9600 BAUD SETUP FOR PRINTER 1 PTR2: DB 047H,00DH ;9600 BAUD SETUP FOR AUXILLIARY PORT DPBASE: ;THESE BLOCKS ARE UPDATED BY SETUP ; DISK PARAMETER HEADER FOR DISK 00 (A:) DW XLT00,0000H DW 0000H,0000H DW DIRBF,SDBLK DW CHK00,ALL00 XLT00: db 01,07,13,19,25,05,11,17,23,03,09,15,21 db 02,08,14,20,26,06,12,18,24,04,10,16,22 XLT01: DB 01,02,03,04,05,06,07,08,09,10,11,12 DB 13,14,15,16,17,18,19,20,21,22,23,24 DB 25,26,27,28,29,30,31,32,33,34,35,36 DB 37,38,39,40,41,42,43,44,45,46,47,48 ;----------------------------------------------------------------------- ; ; DISK PARAMETER BLOCKS ; ;----------------------------------------------------------------------- SDBLK: ;DISK PARAMETER BLOCK FOR SINGLE DENSITY dw 26 ;sectors per track db 3 ;block shift factor db 7 ;block mask db 0 ;null mask dw 242 ;disk size-1 dw 63 ;directory max db 192 ;alloc 0 db 0 ;alloc 1 dw 16 ;check size dw 2 ;track offset DDBLK: DW 48 ;SECTORS PER TRACK DB 4 ;BLOCK SHIFT FACTOR DB 15 ;BLOCK MASK DB 0 ;EXTENT MASK DW 224 ;DISK SIZE-1 DW 95 ;DIRECTORY MAX DB 192 ;ALLOC 0 DB 0 ;ALLOC 1 DW 24 ;CHECK SIZE DW 2 ;TRACK OFFSET MPARMS: DW 0 ;MISC. PARAMETERS ; ; 0100H = DOUBLE HEADED FLOPPY DRIVES ; 0200H = CENTRONICS PRINTER IS LIST DEVICE ; ;----------------------------------------------------------------------- ; ; END OF FIXED LOCATION DEPENDENT TABLES ;----------------------------------------------------------------------- PAGE ; COLD BOOT ROUTINE ; BOOT: ;simplest case is to just perform parameter initialization ; INTERRUPT VECTOR AND ROUTINE WBOOT: ;SIMPLEST CASE IS TO DO A COLD BOOT gocpm: DI MVI A,INTERUPT SHR 8 STAI MVI A,INTERUPT AND 0FFH OUT 00AH EI RET ; CONST: ;console status, return 0ffh if character ready, 00h if not XRA A ;CHECK STATUS OUT 01DH ; IN 01DH ; ANI 00000001B ;CHARACTER WAITING ?? RZ ;NO, RETURN MVI A,0FFH ;RETURN ALL FOXES ret CONIN: ;console character into register a CALL CONST ;CHARACTER WAITING ?? JZ CONIN ;NOT YET.... IN 01CH ;READ CHARACTER IN ANI 07FH ;MAKE SURE ITS ASCII ret CONOUT: ;console character output from register c MVI A,010H ;RESET INT BIT OUT 01DH ; IN 01DH ;GET STATUS ANI 00001100B ;TXE AND DTR CPI 00001100B ;READY ?? JNZ CONOUT ;NO, WAIT HERE MOV A,C ;Get to accumulator OUT 01CH ;WRITE IT ONTO CONSOLE ret LIST: ;list character from register c MVI A,010H ;RESET INT BIT OUT 01FH ; IN 01FH ;GET STATUS ANI 00001100B ;TXE AND DTR CPI 00001100B ;READY ?? JNZ LIST ;NO, WAIT HERE MOV A,C ;Get to accumulator OUT 01EH ;WRITE IT ONTO PRINTER ret ;RETURN TO CALLER LISTST: ;return list status (0 if not ready, 1 if ready) xra a ;0 is always ok to return ret PUNCH: ;punch character from register c ret ;null subroutine READER: ;read character into register a from reader device mvi a,1ah ;enter end of file for now (replace later) ret PAGE ;----------------------------------------------------------------------- ; ; THESE ARE THE DISK I/O ROUTINES. ; THESE ROUTINES WILL BE USED BY THE BDOS DURING ; THE LOAD OF THE FULL CBIOS. FOLLOWING THE SUCCESSFUL ; LOAD THEY WILL NO LONGER BE USED. ; ;----------------------------------------------------------------------- HOME: ;move to the track 00 position of current drive CALL POINT ;POINT TO TRACK REGISTER MVI M,000H ;SET TO TRACK ZERO MVI A,00AH ;HOME COMMAND OUT 004H ;DO IT WT1: JR WT1 ;WAIT HERE UNTIL FINISHED ret ;RETURN TO CALLER SELDSK: ;select disk given by register C CALL WBOOT lxi h,0000h ;error return code mov a,c ; ORA A ;MUST BE ONLY 0 RNZ ;INVALID FOR LOADER. STA DISKNO ;UPDATE DISK NUMBER CALL POINT ; MOV A,M ;LOAD LAST TRACK NUMBER OUT 005H ;RESETUP 1791 LXI D,004H ;POINT TO DENSITY REGISTER DAD D ; MOV A,M ;PICKUP MASK OUT 008H ;WITHE IT OUT TO SELECT DRIVE ; compute proper disk parameter header address LXI H,DPBASE ;ONLY ONE SO ITS EASY.... ret SETTRK: ;set track given by register c CALL POINT ;POINT TO LAST TRACK REGISTER mov a,c ; CMP M ;SAME TRACK AS LAST TIME ?? RZ ;YES, NO NEED TO SEEK MOV M,A ; OUT 007H ; MVI A,01AH ;SEEK TO CORRECT TRACK OUT 004H ;DO IT.... STWT: JR STWT ;WAIT FOR SEEK TO COMPLETE ret SETSEC: ;set sector given by register c mov a,c ;WRITE SECTOR OUT OUT 006H ; ret SECTRAN: ;translate the sector given by BC using the ;translate table given by DE xchg ;HL=.trans dad b ;HL=.trans(sector) mov l,m ;L = trans(sector) mvi h,0 ;HL= trans(sector) ret ;with value in HL SETDMA: ;set dma address given by registers b and c mov l,c ;low order address mov h,b ;high order address shld dmaad ;save the address ret READ: ;perform read operation (usually this is similar to write ; so we will allow space to set up read command, then use ; common code in write) MVI A,08CH ;READ COMMAND CODE MVI B,001H ;DMA READ CODE MVI C,09FH ;READ STATUS MASK jmp waitio ;to perform the actual i/o ORG (($+0A2H) AND 0FF00H)+5EH INTERUPT: DW IRTN IRTN: POP H ;PICKUP PC INX H ;BUMP PAST JR $ INX H ; PUSH H ;PUT IT BACK FOR RETI EI ; RETI ; WRITE: ;perform a write operation MVI A,0ACH ;WRITE COMMAND CODE MVI B,005H ;DMA WRITE CODE MVI C,0FFH ;WRITE STATUS MASK waitio: ;enter here from read and write to perform the actual i/o ; operation. return a 00h in register a if the operation completes ; properly, and 01h if an error occurs during the read or write PUSH PSW ;SAVE I/O COMMAND CODE IN 008H ;IS HEAD LOADED ?? ANI 00000010B ;CHECK MVI D,0FBH ;ASSUME YES JNZ $+3+2 ;VERIFY ASSUMPTION MVI D,0FFH ;ITS NOT, LEAVE HEAD LOAD BIT IN COMMAND POP PSW ;RESTORE COMMAND ANA D ;RESET HEAD LOAD BASED ON PREVIOUS TEST IF DMA ;GENERATE DMA SUPPORT PUSH PSW ;SAVE COMMAND PUSH B ;SAVE REST MOV A,B ; STA DMALST3 ;SAVE READ/WRITE CODE BYTE LXI B,01100H ;17 BYTES OF DATA AND PORT ZERO LXI H,DMALIST ; OUTIR ;WRITE IT OUT POP B ; POP PSW ; ENDIF ; PUSH B ;SAVE STATUS MASK IF NOT DMA ;NON DMA SOFTWARE PUSH PSW ;SAVE PSW MOV A,B ;GET DMA I/O COMMAND (001 OR 005) ANI 00000100B ;REMOVE ALL BUT TEST BIT RRC ; RRC ; LHLD LOWSTR ;LOW MEMORY INI/RETN ORA H ;MAKE INTO AN OTI IF NECESSARY MOV H,A ; SHLD 066H ;SAVE AT NMI LOCATION LHLD LOWSTR+2 ; SHLD 066H+2 ; POP PSW ;RESTORE PSW LHLD DMAAD ;POINT TO RECORD AREA MVI C,007H ;PORT ADDRESS FOR I/O ENDIF ;END NON DMA SOFTWARE OUT 004H ;PERFORM COMMAND RDLP: JR RDLP ;WAIT HERE IN 004H ;READ STATUS POP B ; ANA C ;IS STATUS OK ?? RZ ;YES, RETURN OK mvi a,1 ;error condition ret ;RETURN IN ERROR POINT: LHLD DISKNO ;CURRENT DRIVE MVI H,000H ; LXI D,TRKM ; DAD D ; RET ;POINT TO CURRENT TRACK REGISTER MSPRT: MOV A,M ; ORA A ;END OF MESSAGE ?? RZ ;YES INX H ; MOV C,A ; CALL CONOUT ; JMP MSPRT ; PAGE ;----------------------------------------------------------------------- ; ; CONSTANTS AND WORK AREAS ; ;----------------------------------------------------------------------- DISKNO: DS 1 ;DISK NUMBER 0-15 TRACK: DS 1 ;TRACK NUMBER SECTOR: DS 1 ; IF DMA ;DMA SUPPORT SOFTWARE DMALIST:DB 0C3H,07DH ; DMAAD: DS 2 ;DIRECT MEMORY ADDRESS DW 128-1 ;LENGTH FOR I/O DB 014H,028H,085H,007H,08AH,0CFH,001H,0CFH DMALST3:DS 1 ;001=READ, 005=WRITE DB 0CFH,087H ; ENDIF ; IF NOT DMA ;NON DMA SUPPORT SOFTWARE DMAAD: DS 2 ;DIRECT MEMORY ADDRESS LOWSTR: INI ; RETN ; ENDIF ; MSG: DB 00DH,00AH IF RELOC MSZ: DB '00' ENDIF IF NOT RELOC MSZ: DB MSIZE/10+'0',MSIZE MOD 10 + '0' ENDIF DB 00DH,00AH,000H NOMSG: DB 00DH,00AH DB 'CBIOS00.COM NOT FOUND ON DISK, CORRECT AND RETRY ' DB 00DH,00AH,000H LDRSIZ EQU $-BIOS ;LOADER SIZE IN BYTES LDRPAG EQU (LDRSIZ+255)/256;LOADER SIZE IN PAGES ;----------------------------------------------------------------------- ; ; THE remainder of the CBIOS is reserved uninitialized ; data area, and does not need to be a part of the ; system memory image (the space must be available, ; however, between "begdat" and "enddat"). ; ;----------------------------------------------------------------------- begdat equ $ ;beginning of data area dirbf: ds 128 ;scratch directory area all00: ds 31 ;allocation vector 0 chk00: ds 16 ;check vector 0 enddat equ $ ;end of data area datsiz equ $-begdat;size of data area end