PAGE ; B o o t C P / M f r o m d i s k. ; ; The CBOOT entry point gets control from the cold start ; loader and is responsible for the basic system initial- ; ization. This includes outputting a sign-on message and ; initializing the following page zero locations: ; ; 0 .. 3FF = Interrupt traps ; 380..383 = Irupt 224 for BDOS entry. ; 400..40F = (reserved for debuggers) ; ; Register CL must contain the selected drive, which is ; zero to select the A drive. The exit address is to ; the CCP routine. ; ; The WBOOT entry point gets control when a warm start ; occurs, a ^C from the console, a jump to BDOS (function ; 0), or a jump to location zero. The WBOOT routine does ; only a flush call to the deblocker. ; ; Entry CS= set by far jump. ; 40: (Set by BOOT) Board switch options. ; Exit to CCP or LDCPM ; (0:08) = Banger parameters ; (0:0A) = Board switch options. ; CCP+8 is MFORM M! command line. ; Cold boot exit is to CCP and Warm boot exit ; is to CCP+6 to skip "auto-vector". ; ; Disk layout Definition. ; Cylinder 0 Head 0 ; 0 thru 3 Boot program ; 4 thru 23 Reserved for CBIOS ; 24 Group header of LOADER.CMD ; 25 RESTART code loaded at FFF8:0080 ; ; 256 byte sectors -- Cylinder 1 Head 0: ; 0 thru 3 LDCPM ; 4 thru 17 LDBDOS ; 18 thru 25 **Reserved for CP/M expansion** ; ; 512 byte sectors -- Cylinder 1 Head 0: ; 0 thru 3 CCP ; 4 thru 11 BDOS ; 12 thru 15 **Reserved for CP/M expansion** ; ; 1024 byte sectors -- Cylinder 1 Head 0: ; 0 thru 1 CCP ; 2 thru 5,7 BDOS ; 6 **Reserved for CP/M expansion** space 4 ; WarmStart entry point. ; Called whenever BDOS function 0 is done. WBOOT: CALL HOME ;insure flush & position JMP CCP+6 ;skip "auto-vector" space 4,10 ; Interrupt trap. ITRAP: CLI ;disable further Irupts MOV AX,CS MOV DS,AX LD BX,#ITRAPM CALL PRINT ITRAP9: HLT ;hard stop JMP ITRAP9 ITRAPM: DB CR,LF,BELCHR DB 'Wild Interrupt!' DB EOS space 4,10 ; Cold Start. CBOOT: proc MOV AX,CS ;Get code segment MOV ES,AX MOV SS,AX LD SP,#STACKP ;top of system space (temp. stack) CLD ;clear direction to forward XOR CX,CX MOV DS,CX LD BL,OPTS ;fetch board option switches MOV DS,AX STO BL,OPT_SW STO AX,DMASEG STO AX,BUFSEG ld ax,#sysend mov es,ax sto es,mrt+1 ld bx,#0 sizelp $es ld cl,[bx] $es stob #0,[bx] $es ld ch,[bx] $es sto cl,[bx] mov ax,es inc ax mov es,ax or ax,ax jz sizel1 or ch,ch jz sizelp sizel1 mov ax,es sub ax,#sysend+1 sto ax,mrt+3 mov ax,cs mov es,ax .hdrv IF HDRIVE ;size M-DRIVE/H board LD CL,#0FFH ; LD BX,#0FFF0H ;Use top of M-DRIVE/H board MSIZLP: ADD CL,#08 ;8 sectors per board MOV AL,CL CALL SET ;Go set M-DRIVE/H board INB HDATA ;get a byte MOV AH,AL ;Save the byte MOV AL,CL ;Get current count CALL SET XOR AL,AL ;CLEAR A OUTB HDATA ;out to memory drive MOV AL,CL ;Get Highest byte for set CALL SET ; INB HDATA ;Try and get a 0 CMP AL,#0 ;Was it 0 JNE SETDPB ;If so then done MOV AL,CL CALL SET MOV AL,AH ;Get saved byte OUTB HDATA ;And restore it CMP CL,#64-1 ;Max 8 boards (8*8=64) JNE MSIZLP ;And try for next board ADD CL,#8 ;For special case of 8 boards ; SETDPB: MOV AL,CL ;CL has # Sectors/track AND AL,#0111_1000B ; CMP AL,#8 ;There is one board JL NOBORD ;Table is OK JE SZDONE ;Else one board LD AH,#0 ; STO AX,DPBHMD+1 ;Set #sectors/track MOV CH,CL ;Save CL LD CL,#3 ;Shift 3 bits SHR AL,CL ; LD DX,#254 ;DSM is (# boards * 254) -1 MUL DX ; DEC AX ; and -1 STO AX,DPBHMD+6 ;Set DSM CMP CH,#32 ;If big M-DRIVE JL SETEXM ;if not go set EXM STO #256-1,DPBHMD+8 ;Set #dir entries STO #REV (0F000H),DPBHMD+10 ;Set reserved blocks SETEXM: STOB #0,DPBHMD+5 ;Set EXM to 0 JMP SZDONE NOBORD: LD AL,#0 ;Set no M drive STO AL,DSKMSK+('M'-'A') ; STO AL,DPBHMD+1 ;Set 0 SPT if no M drive SZDONE: .hdrv ENDIF .i1 IF INTER1 LD BL,OPT_SW CMP BL,#0 JNZ CBOOT3 ;If Interfacer 1 not selected LD SI,#J.I1ORG LD DI,#J.CST LD CX,#JLI1ORG REP MOVSB LD AX,#LISTST-J.LST-3 STO AX,J.LST+1 JMP CBOOTX CBOOT3: .i1 ENDIF .b IF BANG LD BL,OPT_SW CMP BL,#1 JNE CBOOT4 ;if BitBanger not selected LD SI,# J.BANG LD DI,# J.CST LD CX,# JLBANG REP MOVSB .ldr IF @LDR CALL BAUD ;get terminal speed PUSH DS LD BX,TICK-1 LD CX,#ZSEG MOV DS,CX STO BX,TICKH ;pass Banger parameters POP DS .ldr else PUSH DS LD CX,#ZSEG MOV DS,CX LD BX,TICKH POP DS STO BX,TICK-1 .ldr endif JMP CBOOTX CBOOT4: .b ENDIF .s IF SMORG LD BL,OPT_SW CMP BL,#2 JNZ CBOOT5 ;If System support not selected LD SI,# J.SMORG LD DI,# J.CST LD CX,# JLSMORG REP MOVSB LD AX,#I3LST-J.LST-3 STO AX,J.LST+1 .ldr IF @LDR CALL STINIT ;Initialize System Support CALL SINTDIS ;Initialize 8259a's mask all interupts CALL I3INIT ;INITIALIZE I/O 3 FOR LIST .ldr endif JMP CBOOTX CBOOT5: .s ENDIF .i3 IF INTER3 LD BL,OPT_SW CMP BL,#3 JNZ CBOOT6 ;If Interfacer 3 not selected LD SI,# J.I3ORG LD DI,# J.CST LD CX,# JLI3ORG REP MOVSB LD AX,# I3LST-J.LST-3 STO AX,J.LST+1 .ldr IF @LDR CALL I3INIT ;Initialize Interfacer 3 .ldr endif ; JMP CBOOTX CBOOT6: .i3 ENDIF CBOOTX: .ldr IF @LDR LD CX,#ZSEG MOV DS,CX ;Need to move to absolute low RAM STO #BDOSE,STRAP ;set BIOS interrupt vector MOV AX,CS STO AX,STRPSG ;BDOS code segment same as ours MOV DS,AX ;restore DataSeg LD BX,#SIGNON CALL PRINT ;display signon CALL BCPM ;load LOADER.CMD XOR CX,CX ;default drive JMP CCP+3 .ldr else ;Full BIOS coldstart tasks XOR AX,AX ;AX = 0 STO AL,IOBYTE MOV DS,AX ;Need to move to absolute low RAM MOV ES,AX STO #ITRAP,0 STO CS,2 LD DI,# 4 LD SI,# 0 LD CX,# 2*(256-1) REP ;propagate Trap to all 256 vectors MOVS STO #BDOSE,STRAP ;set BIOS interrupt vector MOV AX,CS MOV DS,AX ;restore segment regs MOV ES,AX ;Print signon messages mdrive size and memory size LD BX,#BEGIN CALL PRINT IF HDRIVE LD BX,#CRLF CALL PRINT ;Print some crlf's LD AX,DPBHMD+1 ;Get sectors per track CMP AX,#0 ;See if there is an MDRIVE JE NOMDRV ;If no mdrive LD CX,#64 MUL CX ;* 64 to make K message LD BX,#10 ;Base for conversion routine CALL PUTN ;Print and convert to ASCII LD BX,#KMESG ;And print rest of message CALL PRINT ; JMP PMEM NOMDRV: LD BX,#NOMDMS ;Print no memory drive message CALL PRINT ENDIF ; PMEM: LD BX,#MEMMSG ;Memory message CALL PRINT LD AX,MRT+3 ADD AX,#SYSEND+1 LD BX,#MEGMSG ; CMP AX,#0H ;Special case of 1 meg JE PMEM1 ;If one megabyte LD CX,#6 ;6 bits is 1k SHR AX,CL LD BX,#10 ;Base for conversion CALL PUTN ;Convert to ASCII and print LD BX,#PRNTK ; PMEM1: CALL PRINT LD BX,#CRLF CALL PRINT XOR CX,CX ;CX = 0 JMP CCP ;Enter Console Command Processor and ;execute anything in auto-vector. BEGIN: DB CLRSCR,0 ;SEND CLEAR SCREEN KMESG: DB 'K M-DRIVE/H Active' CRLF: DB 0AH,0DH,0AH,0DH,0 MEMMSG: DB 'Total Memory: ',0 PRNTK: DB 'K',0 MEGMSG: DB '1 MEGABYTE',0 NOMDMS: DB 'NO M-DRIVE/H Active',0AH,0DH,0 .ldr endif .i1 if inter1 j.i1org: loc j.cst jmp const jmp conin jmp conout jmp list jmp punch jmp reader loc *o jli1org equ *-j.i1org endif .b IF BANG J.BANG: LOC J.CST JMP KONST JMP KONIN JMP KONOUT LOC *O JLBANG = *-J.BANG .b ENDIF .s IF SMORG J.SMORG: LOC J.CST JMP sCONST JMP sCONIN JMP sCONOUT JMP I3LIST LOC *O JLSMORG = *-J.SMORG .s ENDIF .i3 IF INTER3 J.I3ORG: LOC J.CST JMP I3CONST JMP I3CONIN JMP I3CONOUT JMP I3LIST LOC *O JLI3ORG = *-J.I3ORG .i3 ENDIF SPACE 4,10 ; Boot CPM from disk ; ; Exit A = 0, load sucessful. ; Z bit = 1, load successful. .ldr IF @LDR BCPM: proc :0: LD CL,#'A'-'A' ;Select Disk 'A' LD DX,#0 ;Force disk type determination CALL SELDSK TEST BX,BX JZ :E ;If drive not selectable LD AL,SEKTYP ;Get disk type RCR AL ;Remove sided bit DEC AL JS :E ;If invalid boot type LD CH,#0 ; MOV CL,AL LD BX,#BSECT ;Boot sector table ADD BX,CX LD AL,[BX] ;Get number of sectors STO AL,NUMSEC STO #CCP,DMAADR ;Set destination address MOV AX,CS ;Set segment address = our CS STO AX,DMASEG LD AL,SEKTYP AND AL,#1 ;Mask sided bit ADD AL,#1 LD BH,#0 MOV BL,AL STO BX,SEKTRK ;Set track LD AL,#0 ;Set boot sector STO AL,SAVSEC CALL SETACT ;Move SEK to ACT LD AL,#F.RDAT+040h ;Read data CALL FINAL JNZ :E ;If read erros LD AL,#1 STO AL,NUMSEC XOR AL,AL ;Clear error indicator RET :E: LD BX,#:M CALL PRINT LD CX,#500 CALL DELAY ;Delay 500 milli-seconds OR AL,#1 ;Set error indicator JMP :0 ;try endlessly :M: DB CR,LF,BELCHR DB 'Can''t read Loader!' DB EOS N$DOSL = high (L$CCP+L$DOS+255) BSECT: DB N$DOSL*256/256 ;MFM 256 byte sectors DB N$DOSL*256/512 ;MFM 512 byte sectors DB N$DOSL*256/1024 ;MFM 1024 byte sectors IF HARD db n$dosl*256/1024 ; gbc10, gbc20, gbc26 ENDIF NUMSEC: DB 1 ;xfer length SIGNON: db cr,lf db 'CP/M 86 ' db vers/10+'0','.',vers mod 10 + '0' db cbiosv+'@' db cbiosh+'@' db cbiosm+'@' if gbc10 db '10' endif if gbc20 db '20' endif if gbc26 db '26' endif db cr,lf db 'Copyright (C) Digital Research,',cr,lf db ' (C) Sorcim, ',cr,lf db ' (C) G & G Engineering and',CR,LF db ' (C) CompuPro',cr,lf db CR,LF,CR,LF,LF db 'Loading CPM.SYS' db CR,LF,0 space 4,10 .ldr ENDIF