TITLE 'DOUBLE DENSITY MYDOS3 SYSTEM DISK BUILDER' ; ; Copyright 1984, Charles Marslett, Wordmark Systems ; ; Permission is granted by the author for any use whatsoever of this ; code, so long as this notice remains in the source code, and so ; long as the source to this routine, however modified or unmodified, ; is made available for a nominal cost. ; ; ; Some important absolute addresses ; CIOV = $E456 ;CIO ENTRY VECTOR ; MENUP = $02E0 ;THE RUN ENTRY POINT OF "MDUP.OBJ" ; ORIGIN = $4800 ;GOTTA BE BIG ENOUGH TO NOT HIT EITHER COPY OF MYDOS ; ZCTR = $FA ;A GENERAL PURPOSE COUNTER BPTR = $FC ;A GENERAL PURPOSE POINTER ZPTR = $FE ;AND ANOTHER GENERAL PURPOSE POINTER ; ; Define the fields of IOCB $10 that I use ; ORG $0351 DS 1 ICMD DS 1 DS 1 IBUF DS 4 ILEN DS 2 IAUX1 DS 1 IAUX2 DS 1 ; ; The BUILD program itself -- loads MDOS.OBJ and MDUP.OBJ into memory above ; itself, then relocates the code down over the previous version of MYDOS ; that we are running with and starts it up. This is how we create a new ; version of MYDOS. ; ORG ORIGIN ; START LDX #LOW[SIGNON] LDY #HIGH[SIGNON] ;LOG ONTO THE SCREEN JSR DMSG ; LDA #$C0 STA BPTR+1 ;POINT BPTR AT $C000 LDY #0 STY BPTR LDA #$FF STA SAVC LDX #$10 CLRC STA (BPTR),Y INY BNE CLRC INC BPTR+1 DEX BNE CLRC ; LDA #HIGH[BUFFER] STA BPTR+1 ;POINT BPTR AT "BUFFER" LDA #LOW[BUFFER] STA BPTR LDX #$20 LDA #0 MVLP1 STA (BPTR),Y ;FILL THE 8K BUFFER WITH $00 BYTES INY BNE MVLP1 INC BPTR+1 DEX BNE MVLP1 ; ; COPY NEW DOS CODE FROM FILE "MDOS.OBJ" ; LDX #LOW[MSG01] LDY #HIGH[MSG01] JSR DMSG ;ANNOUNCE WE ARE READING "D:MDOS.OBJ" LDY #LOW[DOSFIL] LDA #HIGH[DOSFIL] JSR LOADBF ;LOAD CONTENTS OF "MDOS.OBJ" ; ; COPY NEW DOS AND DUP CODE FROM FILE "MDUP.OBJ" ; LDX #LOW[MSG02] LDY #HIGH[MSG02] JSR DMSG ;ANNOUNCE WE ARE READING "D:MDUP.OBJ" LDY #LOW[DUPFIL] LDA #HIGH[DUPFIL] JSR LOADBF ;LOAD CONTENTS OF "MDUP.OBJ" ; ; MOVE BUFFER DOWN TO LOW MEMORY ; LDX #LOW[MSG03] LDY #HIGH[MSG03] JSR DMSG ;ANNOUNCE WE ARE RELOCATING DOS AND DUP CODE LDA #$07 STA ZPTR+1 LDA #$00 STA ZPTR ;SET DESTINATION POINTER TO $0700 LDA #HIGH[BUFFER] STA BPTR+1 LDA #LOW[BUFFER] STA BPTR ;SET SOURCE POINTER TO "BUFFER" ; LDY #0 MVLP2 LDA (BPTR),Y STA (ZPTR),Y ;COPY 256 BYTES AT A TIME UNTIL WE INY ;ARE ABOUT TO OVERWRITE BUILD ITSELF BNE MVLP2 ;(THIS IS TOO MUCH, I HOPE, BUT IT WORKS) INC BPTR+1 INC ZPTR+1 LDA ZPTR+1 CMP #HIGH[START] BNE MVLP2 ; ; REINITIALIZE THE SYSTEM ; LDX #LOW[MSG04] LDY #HIGH[MSG04] JSR WFSTR ;ANNOUNCE STARTUP AND WAIT FOR A KEY ; JSR DOSINI ;REINITIALIZE THE NEW MYDOS ; LDX #0 LDA #3 STA ICMD-16 LDA #$2C STA IAUX1-16 LDA #LOW[EC] STA IBUF-16 LDA #HIGH[EC] STA IBUF+1-16 JSR CIOV ;REOPEN THE KEYBOARD/SCREEN "E:" DEVICE ; LDX #LOW[MSG05] LDY #HIGH[MSG05] JSR WFSTR ;ANNOUNCE WE ARE READY TO RUN THE NEW MYDOS ; JMP (MENUP) ;ENTER BACK AT MENU (USE "H" TO SAVE NEW DOS) ; ; ; LOAD CONTENTS OF OBJECT FILE INTO BUFFER ; LOADBF STY IBUF STA IBUF+1 LDA #$FF STA MINAD STA MINAD+1 ;SET LOW ADDRESS TO $FFFF LDA #3 STA ICMD LDA #4 STA IAUX1 LDA #0 STA MAXAD ;SET HIGH ADDRESS TO $0000 STA MAXAD+1 STA IAUX2 LDX #$10 JSR CIOV ;OPEN D:MDOS.OBJ OR D:MDUP.OBJ BPL GOTFIL LDX #LOW[NOFIL] LDY #HIGH[NOFIL] JSR DMSG ;REPORT IT IF WE CANNOT OPEN THE FILE JMP ($000A) ; GOTFIL LDA #7 ;ELSE, STA ICMD ;CHANGE COMMAND TO READ LDA #LOW[BUFAD] STA IBUF LDA #HIGH[BUFAD] ;BUFFER ADDRESS TO THAT OF LOCAL BUF. STA IBUF+1 LDA #2 STA ILEN LDA #0 STA ILEN+1 ;LENGTH TO 2 BYTES LDX #$10 JSR CIOV ;READ HEADER BMI INVHDR ;IF ERROR, REPORT IT LDA BUFAD AND BUFAD+1 CMP #$FF ;ELSE, VALID HEADER? BPL RDNXTB INVHDR LDX #LOW[NOHDR] LDY #HIGH[NOHDR] JSR DMSG ;IF NOT, REPORT THAT ERROR JMP ($000A) ; RDNXTB LDA #LOW[BUFAD] ;READ THE NEXT WORD PAIR (START & END ADDR) STA IBUF LDA #HIGH[BUFAD] STA IBUF+1 LDA #4 STA ILEN ;SET LENGTH TO 4 BYTES LDA #0 STA ILEN+1 LDX #$10 JSR CIOV ;READ START/END ADDRESSES BPL RDDATA ;IF NO ERROR, LOAD THE DATA CPY #$88 ;ELSE, IS IT EOF? BNE ABORT ;IF NOT EOF, REPORT THE ERROR JMP MOVER ;IF EOF, WE HAVE LOADED IT ALL, RETURN NORMALLY ; RDDATA LDA BUFAD+2 LDY BUFAD+3 CPY MAXAD+1 BCC NOTMAX ;IF THIS BLOCK SETS A NEW HIGH ADDRESS LOADED BNE NEWMAX CMP MAXAD BCC NOTMAX NEWMAX STY MAXAD+1 ;UPDATE THE HIGH WATER MARK STA MAXAD NOTMAX SEC SBC BUFAD STA ZCTR TYA SBC BUFAD+1 STA ZCTR+1 INC ZCTR BNE LENOK INC ZCTR+1 LENOK JSR DEBUG1 LDY BUFAD+1 LDA BUFAD CPY MINAD+1 ;AND IF IT SETS A NEW LOW ADDRESS LOADED BCC NEWMIN BNE NOTMIN CMP MINAD BCS NOTMIN ;UPDATE THE LOW WATER MARK NEWMIN CPY #$03 BCC NOTMIN STY MINAD+1 STA MINAD NOTMIN CPY #$07 BCC DONTMV CPY #$C0 ;SKIP THE INDIRECT BUFFER AND MOVE BCS DONTMV ;IF THE ADDR <0700 OR >BFFF ADC #LOW[BUFFER-$700] PHA TYA ADC #HIGH[BUFFER-$700] TAY PLA DONTMV STA BPTR STY BPTR+1 JSR DEBUG2 LDA #0 STA ILEN STA ILEN+1 ;READ ONE BYTE AT A TIME GETNB LDX #$10 JSR CIOV BPL STBYTE ;AND IF NO ERROR, STORE IT ABORT LDX #LOW[ABORTED] LDY #HIGH[ABORTED] JSR DMSG ;REAL I/O ERROR JMP ($000A) ;EXIT TO DOS ; STBYTE LDY BPTR BNE STBY0 LDY BPTR+1 ;TEST FOR BUFFER POINTER BEING STILL VALID CPY #$C0 BNE STBY0 STA SAVC BEQ STBY3 STBY0 LDY #0 STA (BPTR),Y ;ALL OK, STORE THE BYTE JUST READ STBY3 INC BPTR BNE STBT1 INC BPTR+1 STBT1 LDA ZCTR BNE STBT2 ;INCREMENT THE MEMORY POINTER DEC ZCTR+1 STBT2 DEC ZCTR LDA ZCTR ORA ZCTR+1 ;DECREMENT THE BYTE COUNTER BNE GETNB ;IF STILL IN THE BLOCK, READ THE NEXT BYTE JMP RDNXTB ;ELSE, EXAMINE THE NEXT BLOCK ; MOVER LDA #12 ;DONE WITH THE LOAD, STA ICMD LDX #$10 JSR CIOV ;CLOSE LOAD FILE JSR PSTR DB '(',0 LDA MINAD+1 JSR PHEX ;REPORT THE LOW AND HIGH WATER MARKS LDA MINAD JSR PHEX JSR PSTR DB '-',0 LDA MAXAD+1 JSR PHEX LDA MAXAD JSR PHEX LDX #LOW[LOADED] LDY #HIGH[LOADED] JSR DMSG RTS ;AND RETURN TO THE MAIN LINE CODE ; ; PROGRAM FILE (NEW FMS) ; DOSFIL DB 'D:MDOS.OBJ',$9B ; ; PROGRAM FILE (NEW UTILITY PROGRAM) ; DUPFIL DB 'D:MDUP.OBJ',$9B ; ; CONSOLE KEYBOARD/DISPLAY ; EC DB 'E:',$9B ; ; DISPLAY A MESSAGE AND WAIT FOR "START" ; WFSTR JSR DMSG ;NESTED CALL TO DISPLAY THE MESSAGE LDA #8 STA $D01F WFSTRT LDA $D01F ;READ CONSOLE SWITCHES AND #1 BNE WFSTRT ;WAIT UNTIL START IS DEPRESSED RTS ; ; DISPLAY A MESSAGE TO THE OPERATOR ; DMSG STX ZPTR STY ZPTR+1 LDA #0 STA ZCTR MSGLP LDY ZCTR LDA (ZPTR),Y BEQ DXIT JSR BYTOUT INC ZCTR BNE MSGLP ; DXIT RTS ; CODE DB '0123456789ABCDEF' ; ; DISPLAY A 4 DIGIT HEX NUMBER ON THE SCREEN ; PHEX PHA LSR A LSR A LSR A LSR A TAX LDA CODE,X JSR BYTOUT PLA AND #$0F TAX LDA CODE,X ; BYTOUT LDX #11 STX ICMD-$10 LDX #0 STX ILEN-$10 STX ILEN-$10+1 JSR CIOV RTS ; PSTR PLA STA ZPTR PLA STA ZPTR+1 PLOOP INC ZPTR BNE POUT INC ZPTR+1 POUT LDX #0 LDA (ZPTR,X) BEQ PEXIT JSR BYTOUT JMP PLOOP ; PEXIT LDA ZPTR+1 PHA LDA ZPTR PHA RTS ; ; REPORT THE HIGH AND LOW BUFFER LIMITS ; DEBUG1 JSR PSTR DB '(',0 LDA BUFAD+1 JSR PHEX LDA BUFAD JSR PHEX JSR PSTR DB '-',0 LDA BUFAD+3 JSR PHEX LDA BUFAD+2 JSR PHEX RTS ; DEBUG2 JSR PSTR DB ')' DB $1E,$1E,$1E,$1E,$1E DB $1E,$1E,$1E,$1E,$1E DB $1E,0 RTS ; ; ROUTINE TO REINITIALIZE DOS 2.0 ; DOSINI LDA $704 STA $00C LDA $704+1 STA $00C+1 JMP ($00C) ;==REINITIALIZE ENTIRE DOS/DUP ; ; MESSAGES TO OPERATOR ; SIGNON DC $9B,$9B,' ' DC 'M','Y','D','O','S','3',' ','d','o','u','b','l','e' DC ' ','d','e','n','s','i','t','y' DC ' ','A','T','A','R','I',' ','O','S',' ',$9B DB ' ' DC ' ',' ',' ',' ',' ',' ','s','y','s','t','e','m' DC ' ','d','i','s','k',' ','b','u','i','l','d','e','r' DC ' ',' ',' ',' ',' ',' ',' ',$9B,$9B DB 0 ; MSG01 DB 'LOADING MDOS.OBJ',0 MSG02 DB 'LOADING MDUP.OBJ',0 LOADED DB $1E,$1E,$1E,$1E,$1E DB $1E,$1E,$1E,$1E,$1E DB $1E,$1E,$1E,$1E,$1E DB $1E,$1E,$1E,$1E,$1E DB $1E,$1E,'ED',$FE,$9B,0 MSG03 DB 'Moving DOS/DUP into place',$9B,0 MSG04 DB 'PRESS ' DC 'S','T','A','R','T' DB ' TO INITIALIZE NEW DOS',$9B,0 MSG05 DB 'PRESS ' DC 'S','T','A','R','T' DB ' TO ENTER NEW DOS.',$9B,0 ; NOFIL DB 'Cannot open Object File',$9B,0 NOHDR DB 'Invalid Header in Object File',$9B,0 ABORTED DB 'I/O Error, load aborted',$9B,0 ; ; BUFFER FOR PATCHING A RUNNING DOS ; MAXAD DS 2 MINAD DS 2 SAVC DS 1 BUFAD DS 6 ;FOR ADDRESSES BUFFER DS START-$0700 ; ; EXECUTION FORCED, LOAD RUN ADDRESS ; ; ORG $02E0 ; DW START ;run address ; END START