; CP/NET BOOTING LOADER ; ; 1982.8.27. VER.1.0 ; ; EQUATIONS OF DATA ; TOP EQU 0 ;MEMORY TOP ; ; EQUATIONS OF CP/NET FUNCTION ; COPEN EQU 15 ;OPEN FILE CREAD EQU 20 ;READ ONE SECTOR CSTUSC EQU 32 ;SET USER CODE CLOGIN EQU 64 ;LOG IN ; ; EQUATIONS OF CODE & DATA ; SOH EQU 01H ;START OF HEADER STX EQU 02H ;START OF DATA ETX EQU 03H ;END OF DATA EOT EQU 04H ;END OF TRANSMISSION ENQ EQU 05H ;ENQUIRE ACK EQU 06H ;ACKNOWLEDGE ACKS EQU 07H ;SECOND ACKNOWLEDGE LF EQU 0AH ;LINE FEED CR EQU 0DH ;CARRIAGRE RETURN NAK EQU 15H ;NEGATIVE ACKNOWLEDGE ; TMORTY EQU 100 ;TIME OUT RETRY COUNT MAXRTY EQU 10 ;SEND MESSAGE RETRY COUNT ; ; EQUATIONS OF INPUT OUTPUT PORT & ADDRESS ; COMPRT EQU 0C4H ;COMMUNICATION PORT STATI EQU COMPRT ;INPUT STATUS DPRTI EQU COMPRT+1 ;DATA PORT MSKI EQU 01H ;INPUT READY BIT ; STATO EQU COMPRT ;OUTPUT STATUS DPRTO EQU COMPRT+1 ;DATA PORT MSKO EQU 80H ;OUTPUT READY BIT ; ; CRTBF EQU 0F800H ;VRAM AREA CPORT EQU 40H ;PORT FOR BELL ON ; ; SUBTTL BOOTER PART ; ; SYSTEM PAGE ; 2B:NDOS TOP ; 2B:SNIOS TOP ; 2B:BDOS TOP ; 2B:BIOS TOP ; 2B:LENGTH ; ; ; ENTRY POINT & PARAMETERS ; NBOOT: JMP START ; ; ID CODE FOR PATCH ; MSTID: DB 0 ;MASTER ID CODE SLVID: DB 20H ;SLAVE ID CODE ; ; FCB FOR SYSTEM LOAD ; FCB: DB 2 ;MASTER DISK NUMBER +1 DB 'CPNETPC SYS' ;SYSTEM FILE NAME DB 0,0 ;EXTENT & CURRENT RECODE ; ; PASS WORD ; PASSWD: DB 'PASSWORD' ;DEFAULT PASS WORD ; ; START: LXI SP,STACK CALL LOGIN ;LOG IN CALL SETUSR ;SET USER CODE TO ZERO CALL OPEN ;OPEN SYSTEM FILE LXI H,PARAMT SHLD DMAADD ;SET DMA ADDRESS TO WORK CALL READ ;READ PARAMETER PAGE LHLD PARAMT SHLD DMAADD ;GET LOADING TOP LXI D,3 DAD D SHLD NDOSPT ;SAVE NDOS COLD START ENTRY LHLD PARAMT+2 DAD D DAD D SHLD SNIOSP ;GET SNIOS ENTRY FOR CONFIGRATION TABLE LHLD PARAMT+4 DAD D DAD D SHLD BDOSPT ;GET BDOS ENTRY LHLD PARAMT+6 SHLD BIOSPT ;BIOS COLD START POINT LHLD PARAMT+8 ;GET SYSTEM LENGTH DAD H MOV A,H ;GET COUNT LOOP: ;SECTOR READ LOOP PUSH PSW ;SAVE COUNT CALL READ ;READ ONE SECTOR LHLD DMAADD LXI D,128 DAD D SHLD DMAADD ;TO NEXT DMA ADDRESS POP PSW DCR A JNZ LOOP ;TO NEXT SECTOR MVI A,0C3H STA TOP STA TOP+5 ;SET JUMP INSTRUCTIONS LHLD BDOSPT SHLD TOP+6 ;SET BDOS ENTRY LHLD BIOSPT INX H INX H INX H SHLD TOP+1 ;SET WARM BOOT VECTOR LXI H,LOOPEN PUSH H LHLD SNIOSP ;GET ROUTINE POINT FOR CONFIGRATION TABLE PUSH H LHLD NDOSPT MOV B,H MOV C,L ;GET NDOS TOP LHLD BIOSPT PCHL ;TO BIOS INITIALIZE ROUTINE ; LOOPEN: INX H LDA SLVID MOV M,A ;SET SLAVE ID LXI D,40 DAD D MOV M,A ;SLAVE ID FOR LIST OUT LHLD NDOSPT PCHL ;TO NDOS COLD START POINT ; ; OPEN FILE ; OPEN: XRA A STA FCB+12 ;CLEAR EXTENT STA FCB+13 ;CLEAR CURRENT RECODE CALL STFCBP ;SET FCB POINT LXI H,FCB MVI B,13 CALL MCPYTO ;SET FCB DATA MVI C,COPEN CALL LINK ;LINK WITH MATSER CALL GTRPA ;GET RETURN PARAMETER INR A MVI A,'O' JZ LOADER ;OPEN ERROR RET ; ; READ ONE SECTNR ; READ: CALL STFCBP CALL STEXCR ;SET EXTENT & CURRENT RECODE MVI C,CREAD CALL LINK CALL RSEXCR ;RESTORE EXTENT & CURRENT RECODE LHLD DMAADD ;DMA POINT MVI B,128 CALL MCPYFR ;GET DAMA CALL GTRPA ;GET RETURN PARAMETER ORA A MVI A,'D' JNZ LOADER ;READ DATA ERROR RET ; ; LINK WITH MASTER ; INPUT ; C:FUNCTION ; LINK: LXI H,MSGTOP MVI M,0 ;TO SEND INX H LDA MSTID MOV M,A INX H LDA SLVID MOV M,A ;SET SLAVE ID INX H MOV M,C ;SET FCUNTION INX H XCHG LHLD MCRPNT ;DATA POINT XRA A SUB E MOV C,A MVI A,0 SBB D MOV B,A DAD B ;GET LENGTH DCX H DCX H XCHG MOV M,E ;SET SIZE LXI B,MSGTOP CALL SNDMSG INR A MVI A,'S' JZ LOADER ;SEND ERROR LXI B,MSGTOP CALL RCVMSG INR A MVI A,'R' JZ LOADER ;RECEIVE ERROR LXI H,MSGDAT SHLD MCRPNT ;INITIALIZE POINTER RET ; ; RESTORE EXTENT & CURRENT RECORD ; RSEXCR: LHLD MCRPNT MOV A,M STA FCB+12 ;SET EXTENT INX H MOV A,M STA FCB+13 ;SET CURRENT RECODE INX H SHLD MCRPNT RET ; ; GET RETURN PARAMETER ; OUTPUT ; A:ONE BYTE PARAMETER SAME WITH L ; GTRPA: LHLD MCRPNT MOV A,M ;GET PARAMETER RET ; ; SET EXTENT & CURRENT RECODE ; STEXCR: LHLD MCRPNT LDA FCB+12 ;GET EXTENT MOV M,A INX H LDA FCB+13 ;GET CURRENT RECODE MOV M,A INX H SHLD MCRPNT RET ; ; SET FCB POINT ; STFCBP: LXI H,MSGDAT LXI D,FCB MOV M,E INX H MOV M,D ;SET FCB POINT INX H SHLD MCRPNT ;SET POINTER RET ; ; MESSAGE COPY FROM MESSAGE BUFFER ; INPUT ; B:COUNT ; HL:DESTINATION ; MCPYFR: XCHG LHLD MCRPNT ;GET MESSAGE BUFFER POINT MOV A,M ;COPY DATA STAX D INX D INX H DCR B JNZ $-5 ;TO NEXT BYTE SHLD MCRPNT ;SAVE NEXT POINT RET ; ; MESSAGE COPY TO MESSAGE BUFFER ; INPUT ; B:COUNT ; HL:SOURCE POINT ; MCPYTO: XCHG LHLD MCRPNT ;GET MESSAGE POINT LDAX D ;COPY DATA MOV M,A INX D INX H DCR B JNZ $-5 SHLD MCRPNT ;SAVE NEXT POINT RET ; ; LOGIN ; LOGIN: LXI H,MSGDAT SHLD MCRPNT ;SET POINTER TO TOP LXI H,PASSWD MVI B,8 CALL MCPYTO ;SET PASSWORD MVI C,CLOGIN CALL LINK CALL GTRPA ;GET RESULT ORA A MVI A,'L' JNZ LOADER ;LOGIN ERROR RET ; ; SET USER CODE TO ZERO ; SETUSR: LXI H,MSGDAT MVI M,0 ;SET USER CODE ZERO INX H SHLD MCRPNT ;SET DATA POINTER MVI C,CSTUSC JMP LINK ; ; LOAD ERROR ; INPUT ; A:ERROR CODE ; LOADER: LXI D,CBOTER ;ERROR COMMENT POINT JMP FTEROR ; ; SUBTTL COMMUNICATION PART ; ; FATAL ERROR END STOP ; INPUT ; DE:ERROR STRING POINTER ; A:ERROR CODE ; FTEROR: DI MOV C,A LXI H,CRTBF+50 INX H INX D LDAX D MOV M,A ORA A JNZ $-5 ;TO NEXT CODE MOV M,C ;SET ERROR CODE MVI A,20H OUT CPORT ;BELL ON JMP $ ; ; SEND MESSAGE ON NETWORK ; INPUT ; BC:MESSAGE ADDRESS ; SNDMSG: MOV H,B MOV L,C SHLD MSGADR ;SAVE MESSAGE ADDRESS SNDMSR: ;RETRY LOOP MVI A,MAXRTY STA RTYCNT ;INITIALIE RETRY COUNT SEND: CALL NTRSET ;RESET BUFFER SENDS: LHLD MSGADR ;GET MESSAGE TOP MVI D,TMORTY ;TIME OUT RETRY COUNT SENDWT: ;ENQUIRE RESPONSE WAIT LOOP MVI C,ENQ CALL CHROUT ;SEND ENQUIRE TO MASTER CALL CHARIN ;WAIT RESPONSE JNC SENDGT ;GET RESPONSE DCR D ;TIME OVER JNZ SENDWT ;SEND ENQUIRE ONCE MORE JMP CHINTO ;TIME OVER FOR LINK ; SENDGT: ;GET RESPONSE CPI ENQ ;CHECK SEND - SEND MODE JZ SNDRCV ;CRASH SEND SO TO PASS RECEIVE MODE CALL GETAK0 ;GET RESPONSE OF ENQ MVI C,SOH MVI E,5 ;HEADER LENGTH COUNT CALL MSGOUT ;SEND SOH,FMT,DID,SID,FNC,SIZ XRA A SUB D MOV C,A CALL NETOUT ;SEND HCS (HEADER CHECK SUM) CALL CHARIW ;GET RESPONSE JC GETATS ;TIME OVER CPI ACK JNZ $+9 ;NORMAL MODE CALL CHARIW ;MAYBE BUFFER LEFT ACK, SO IGNORE JC GETATS ;TIME OVER SUI ACKS JNZ GETATS ;MISS MATCH OF RESPONSE DCX H MOV E,M INX H INR E MVI C,STX CALL MSGOUT ;SEND STX,DB0,DB1,.... MVI C,ETX CALL NETOUT ;SEND ETX XRA A SUB D MOV C,A CALL NETOUT ;SEND DATA CHECK SUM MVI C,EOT CALL CHROUT ;SEND END OF TRNASMISSION CALL GETAKS ;********NEED CALL ******* FOR ERROR RETRY RET ; ; PASS RECEIVE FOR SEND & SEND MODE ; SNDRCV: CALL NTRSET ;CLEAR CURRENT BUFFER MVI D,TMORTY SNDRCW: ;WAIT FOR ANOTHER ENQ CALL CHARIN JNC SNDRCG ;GET DATA DCR D ;TIME OVER JNZ SNDRCW ;WAIT JMP SEND ;MAYBE MISS LINK, SO TO SEND ; SNDRCG: ;GET DATA CPI ENQ JNZ SEND ;MAYBE MISS LINK LXI H,SNDRCV PUSH H ;SAVE RETRY LOOP CALL SNDACK ;SEND ACKNOWLEDGE CALL CHARIW RC ;NO RESPONSE, SO RETRY CPI SOH RNZ LXI H,DHEADR ;DUMMY HEADER BUFFER MOV D,A MVI E,5 CALL MSGIN ;GET HEADER CNC NETIN ;GET CHECK SUM RC ;TIME OUT RETRY JNZ SNDNAK ;CHECK SUM ERROR CALL SNDAKS ;SEND RESPONSE CALL CHARIW RC CPI STX ;CHECK START OF TEXT RNZ ;RETRY MOV D,A ;INITIALIZE CHECK SUM DCX H MOV E,M INR E INR E ;GET COUNT FOR READ SNDRCL: ;DATA PASS RECEIVE LOOP CALL NETIN ;GET ONE DATA RC ;TIME OUT RETRY DCR E JNZ SNDRCL ;TO NEXT DATA CPI ETX RNZ ;MISS MATCH OF END CODE CALL NETIN ;GET CHECK SUM RC CALL CHARIN RC CPI EOT ;END OF TRANSMISSION RNZ MOV A,D ORA A JNZ SNDNAK ;CHECK SUM ERROR CALL SNDAKS POP H JMP SENDS ; ; GET ACKNOWLEDGE ; OVERRIDING RETURN WHEN ERROR ; GETAK0: ;CHECK ACKNOWLEDGE SUI ACK RZ SNDRTY: POP H ;DISCARD RETURN ADDRESS GETATS: ;TIME OVER RETRY LXI H,RTYCNT DCR M JNZ SEND ;SEND AGAIN CHINTO: ;CHARACTER IN TIME OUT MVI A,-1 RET ; GETAKS: ;GET SECOND ACKNOWLEDGE CALL CHARIW JC SNDRTY ;TIME OUT SUI ACKS RZ ;OK JMP SNDRTY ;RETRY ; ; RECEIVE MESSAGE FROM NETWORK ; INPUT ; BC:MESSAGE ADDRESS ; RCVMSG: MOV H,B MOV L,C SHLD MSGADR ;SAVE MESSAGE ADDRESS RCVMSR: MVI A,MAXRTY STA RTYCNT ;INITIALIZE RETRY COUNT RECALL: CALL RECEIV LXI H,RTYCNT ;RETURN FROM RECEIV IS ERROR DCR M JNZ RECALL ;RETRY RCVTOT: ;TIME OUT MVI A,-1 RET ; ; RECEIVE BODDY ; RETURN OVERRIDING WHEN OK ; SIMPLE RETURN IS ERROR ; RECEIV: LHLD MSGADR ;GET MESSAGE ADDRESS MVI D,TMORTY CALL NTRSET ;RESET INPUT BUFFER RCVFST: ;RECEIVE FIRST CHARACTER LOOP CALL CHARIN JNC RCVGFS ;GET FIRST CHARACTER DCR D ;TIME OVER JNZ RCVFST ;RETRY POP H JMP RCVTOT ;SET TIME OVER ERROR FLAG & RETRY ; RCVGFS: ;GET FIRST CHARACTER CPI ENQ JNZ RECEIV ;NOT ENQUIRE SO RETRY CALL SNDACK ;RESPONSE TO MASTER CALL CHARIW RC ;RETURN TO RECEIVE RETRY CPI SOH RNZ ;NOT START OF HEADER MOV D,A ;START OF HEADER MVI E,5 ;LENGTH OF HEADER CALL MSGIN ;GET HEADER BLOCK CNC NETIN ;GET HCS (HEADER CHECK SUM) RC ;TIME OVER RETRY JNZ SNDNAK ;CHECK SUM ERROR CALL SNDAKS ;SEND RESPONSE CALL CHARIW ;WAIT DATA TOP RC CPI STX RNZ ;NOT START OF TEXT MOV D,A ;START OF TEXT DCX H MOV E,M ;GET SIZE INX H INR E ;MAKE READ COUNT FOR DATA BLOCK CALL MSGIN ;RECEIVE DATA RC CALL CHARIN ;GET END CODE OF DATA BLOCK RC CPI ETX RNZ ;NOT END OF TEXT SO RETRY ADD D MOV D,A CALL NETIN ;GET HEADER CHECK SUM RC CALL CHARIN ;GET LAST CODE RC CPI EOT RNZ ;NOT END OF TRANSMIT SO ERROR MOV A,D ORA A JNZ SNDNAK ;CHECK SUM ERROR POP H ;OK ALL PACKETTE IS RECEIVED LHLD MSGADR INX H LDA SLVID ;GET SLAVE ID SUB M ;CHECK SID JZ $+5 MVI A,-1 ;SID ERROR PUSH PSW CALL SNDAKS ;SEND ACKNOWLEDGE POP PSW RET ; ; ROUTINES TO SEND RESPONSE CODES ; SNDACK: ;SEND ACKNOWLEDGE MVI C,ACK JMP CHROUT ; SNDAKS: ;SEND SECOND ACKNOWLEDGE MVI C,ACKS JMP CHROUT ; SNDNAK: ;SEND NEGATIVE ACKNOWLEDGE MVI C,NAK JMP CHROUT ; ; NETWORK ERROR RECOVER ROUTINE RESET COMMUNICATION INTERFACE ; NTRSET: MVI A,080H OUT STATO ;RESET RET ; ; NETWORK OUTPUT DATA ; INPUT ; C:OUTPUT DATA ; D:CHECK SUM ; NETOUT: MOV A,D ADD C MOV D,A ;MAKE CHECK SUM CHROUT: IN STATO ANI MSKO ;GET OUTPUT READY MODE JNZ CHROUT ;NOT READY MOV A,C OUT DPRTO ;OUT DATA RET ; ; INPUT FROM NETWORK ; OUTPUT ; A:DATA ; CF:ON TIME OVER OFF GET DATA ; CHARIW: ;LONG WAIT MVI B,0 JMP CHARIM ; CHARIN: MVI B,10 ;10 MS = 192 CH / 192K BAUD CHARIM: ;WAIT LOOP MVI C,5AH ;1 MS WAIT VALUE CHARIL: ;1 MS WAIT LOOP IN STATI ANI MSKI JZ CHARIG ;READY DCR C JNZ CHARIL ;WAIT OF 1 MS DCR B JNZ CHARIM ;WAIT STC ;TIME OVER RETURN RET ; CHARIG: IN DPRTI ;GET DATA RET ; ; MESSAGE INPUT ; INPUT ; HL:DESTINATION ADDRESS ; E:INPUT COUNT ; MSGIN: CALL NETIN RC ;TIME OUT MOV M,A ;GET DATA INX H DCR E JNZ MSGIN ;TO NEXT BYTE RET ; ; NETWORK INPUT ; INPUT ; D:CHECK SUM ; OUTPUT ; A:DATA ; NETIN: CALL CHARIN ;RECEIVE BYTE IN BINARY MODE RC MOV B,A ADD D ;MAKE CHECK SUM MOV D,A ORA A ;OFF CARRY FLAG MOV A,B RET ; ; MESSAGE OUT ; INPUT ; HL:SOURCE ADDRESS ; E:COUNT OF OUTPUT DATA ; C:PREAMBLE CODE ; MSGOUT: MVI D,0 ;CLEAR CHECK SUM CALL NETOUT ;OUT PREAMBLE CODE MSGOTL: ;OUT LOOP MOV C,M ;GET CODE INX H CALL NETOUT ;OUT DATA DCR E JNZ MSGOTL ;TO NEXT DATA RET ; ; CBOTER: DB ' LOAD ERROR ',0 ; ; WORKING AREA ; FOR BOOT ; DMAADD: DS 2 ;DMA ADDRESS NDOSPT: DS 2 ;NDOS COLD START POINT SNIOSP: DS 2 ;SNIOS ENTRY FOR CONFIGRATION TABLE BDOSPT: DS 2 ;BDOS ENTRY POINT BIOSPT: DS 2 ;BIOS COLD START POINT ; MCRPNT: DS 2 ;MESSAGE POINTER ; ; MESSAGE AREA ; MSGTOP: DS 5 ;HEADER MSGDAT: DS 2 ;DATA PARAMT: DS 128 ;DATA OF ONE SECTOR DS 1 ; DS 64 STACK: ; ; DATA AREA FOR SEND & RECEIVE ; MSGADR: DS 2 ;MESSSAGE ADDRESS BUFFER DHEADR: DS 5 ;DUMMY HEADER BUFFER RTYCNT: DB 0 ;RETRY COUNT ; ; END