; SAVE#D:BUILD.M65 ; .OPT NO LIST .OPT NO EJECT .TITLE "MYDOS 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 code of this routine, ; however modified or ; unmodified, is made available ; for a nominal cost. ; ; ; Some important absolute ; addresses ; CH = $02FC ; KEY PRESS SHADOW REGISTER ; 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 BPTR = $FC ZPTR = $FE ; GENERAL PURPOSE POINTERS ; ; ; Define the fields of IOCB ; #10 that I use ; *= $0351 *= *+1 ICMD *= *+1 *= *+1 IBUF *= *+4 ILEN *= *+2 IAUX1 *= *+1 IAUX2 *= *+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 ; *= ORIGIN ; START LDX # 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 # >BUFFER STA BPTR+1 LDA # MSG01 JSR DMSG ; ANNOUNCE WE ARE READING ; "D:MDOS.OBJ" ; LDY # DOSFIL JSR LOADBF ; LOAD CONTENTS OF "MDOS.OBJ" ; ; ; COPY NEW DOS AND DUP CODE FROM ; FILE "MDUP.OBJ" ; LDX # MSG02 JSR DMSG ; ANNOUNCE WE ARE READING ; "D:MDUP.OBJ" ; LDY # DUPFIL JSR LOADBF ; LOAD CONTENTS OF "MDUP.OBJ" ; ; MOVE BUFFER DOWN TO LOW MEMORY ; LDX # 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 # >BUFFER STA BPTR+1 LDA # START BNE MVLP2 ; COPY 256 BYTES AT A TIME UNTIL ; WE ARE ABOUT TO OVERWRITE ; 'BUILD' ITSELF ; (THIS IS TOO MUCH, I HOPE, ; BUT IT WORKS) ; ; REINITIALIZE THE SYSTEM ; ; LDX # 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 # EC STA IBUF+1-16 JSR CIOV ; REOPEN THE KEYBOARD/SCREEN ; "E:" DEVICE ; ; LDX # MSG05 JSR WFSTR ; ANNOUNCE WE ARE READY TO RUN ; THE NEW MYDOS LDY #$00 LDX #$00 PS1 INY BNE PS1 INX BNE PS1 JMP ($0A) ; ENTER NEW MYDOS AT ITS' MENU ; SCREEN, (USE 'H' TO WRITE OUT ; NEW DOS AFTER FORMATTING A ; NEW DISK) ; ;* ;* ;* ;* ; CODE MOVING ROUTINES ; REFERENCED ABOVE ; ; ; ; 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 ; OPEN STA ICMD LDA #4 ; FOR READ STA IAUX1 LDA #0 STA MAXAD STA MAXAD+1 STA IAUX2 ; SET HIGH ADDRESS TO $0000 ; LDX #$10 ; IOCB #10 JSR CIOV ; OPEN D:MDOS.OBJ OR D:MDUP.OBJ ; BPL GOTFIL ; BRANCH GOOD ; LDX # NOFIL JSR DMSG ; REPORT IT IF WE CANNOT OPEN ; THE FILE, ; WAIT LDA #$FF ; WAIT FOR KEY STA CH ; PRESS SO USER LDA CH ; CAN READ CMP #$FF ; MESSAGE BEQ WAIT JMP ($0A) ; QUIT BY ; JUMPING THRU DOSVEC TO OLD DOS ; ; GOTFIL LDA #7 ; CHANGE COMMAND STA ICMD ; TO GET BINARY ; ; RECORD LDA # BUFAD STA IBUF+1 ; BUFFER ADDRESS TO THAT OF ; LOCAL BUFFFER ; LDA #2 STA ILEN LDA #0 STA ILEN+1 ; LENGTH TO GET = 2 BYTES ; LDX #$10 ; STILL IOCB #10 JSR CIOV ; READ HEADER BMI INVHDR ; BR ON ERROR LDA BUFAD AND BUFAD+1 CMP #$FF ; 2 FFs? BPL RDNXTB ; BR IF YES ; INVHDR LDX # NOHDR ; BINARY JSR DMSG ; FILE SO SAY SO JMP WAIT ; AND THEN QUIT ; ; ; RDNXTB LDA # BUFAD STA IBUF+1 ; READ THE NEXT WORD PAIR OF ; BYTES - (START & END ADDR) ; LDA #4 STA ILEN LDA #0 STA ILEN+1 ; SET LENGTH TO GET = 4 BYTES ; LDX #$10 ; STILL IOCB #10 JSR CIOV ; DO IT BPL RDDATA ; BR IF GOOD CPY #$88 ; BAD, EOF? BNE ABORT ; BR NO EOF JMP MOVER ; YES, EOF, WE ; HAVE LOADED IT ALL, RETURN ; NORMALLY - ALL GOOD ; ; RDDATA LDA BUFAD+2 LDY BUFAD+3 CPY MAXAD+1 BCC NOTMAX BNE NEWMAX CMP MAXAD BCC NOTMAX NEWMAX STY MAXAD+1 STA MAXAD ; IF THIS BLOCK SETS A NEW HIGH ; ADDRESS LOADED, THEN UPDATE ; THE NEW HIGH WATER MARK ; 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 BCC NEWMIN BNE NOTMIN CMP MINAD BCS NOTMIN NEWMIN CPY #$03 BCC NOTMIN STY MINAD+1 STA MINAD ; AND IF IT SETS A NEW LOW ; ADDRESS LOADED, UPDATE THE ; THE NEW LOW WATER MARK ; NOTMIN CPY #$07 BCC DONTMV CPY #$C0 BCS DONTMV ; SKIP THE INDIRECT BUFFER AND ; MOVE IF THE ADDR <0700 OR ; >BFFF ; ADC # BUFFER-$0700 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 ; GOOD? STORE IT ; ABORT LDX # ABORTED JSR DMSG ;REAL I/O ERROR JMP WAIT ; EXIT TO DOS ; STBYTE LDY BPTR BNE STBY0 LDY BPTR+1 ; TEST FOR CPY #$C0 ; BUFFER POINTER BNE STBY0 ; BEING STILL STA SAVC ; VALID BEQ STBY3 STBY0 LDY #0 ; PUT BYTE JUST STA (BPTR),Y ; READ STBY3 INC BPTR ; INCREMENT THE BNE STBT1 ; MEMORY INC BPTR+1 ; POINTER STBT1 LDA ZCTR BNE STBT2 DEC ZCTR+1 ; DEC BYTE CNTR STBT2 DEC ZCTR ; LDA ZCTR ORA ZCTR+1 ; IF STILL IN- BNE GETNB ; SIDE THE ; BLOCK, READ THE NEXT BYTE ; JMP RDNXTB ; OUTSIDE - GET ; THE NEXT BLOCK READ IN ; ; MOVER LDA #12 ; DONE WITH THE STA ICMD ; LOAD SO CLOSE LDX #$10 ; LOAD FILE JSR CIOV ; GO DO IT JSR PSTR .BYTE "(",0 ; PUT STRING LDA MINAD+1 JSR PHEX ; REPORT THE LOW LDA MINAD ; WATER ADDRESS JSR PHEX ; MARKS JSR PSTR .BYTE "-",0 ; PUT STRING LDA MAXAD+1 JSR PHEX ; REPORT THE LDA MAXAD ; HIGH WATER JSR PHEX ; ADDRESS MARKS ; LDX # LOADED ; LOADED JSR DMSG ; MESSAGE RTS ; AND RETURN TO THE MAIN LINE ; CODE ;* ;* ;* ; STABLE LABLES ; ; ; DOSFIL .BYTE "D:MDOS.OBJ",$9B ; ; DUPFIL .BYTE "D:MDUP.OBJ",$9B ; ; CONSOLE KEYBOARD/DISPLAY ; IN OTHER WORDS - THE E: DEVICE ; USED IN 'OPEN' IOCB COMMAND ; ; EC .BYTE "E:",$9B ; ; ;** SUBROUTINES ; ; DISPLAY A MESSAGE AND WAIT ; FOR A "START" PRESS ; WFSTR JSR DMSG ; DISPLAY A ; ; MESSAGE ; WFSTRT LDA #7 ; NO KEY PRESSED STA $D01F ; CONSOL LDA $D01F ; READ CONSOLE CMP #6 ; START KEY BNE WFSTRT ; LOOP UNTIL ; START IS PRESSED ; WFSTRT1 LDA #7 ; NO KEY PRESSED STA $D01F ; CONSOL LDA $D01F ; READ CONSOLE CMP #7 ; NO KEY PRESSED BNE WFSTRT1 ; LOOP UNTIL ; ; START IS RELEASED RTS ; ; ; DISPLAYS 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 .BYTE "0123456789ABCDEF" ; ; ; DISPLAY A 4 DIGIT HEX NUMBER ; ON THE SCREEN ; PHEX PHA LSR A ; GET HIGH LSR A ; NIBBLE VALUE LSR A LSR A ; IN X FOR TAX ; OFFSET LOAD OF LDA CODE,X ; REGISTER A JSR BYTOUT ; PUT TO E: PLA ; RESTORE BYTE AND #$0F ; LOW NIBBLE TAX ; SAME AS THE LDA CODE,X ; FIRST ; BYTOUT LDX #11 STX ICMD-$10 LDX #0 STX ILEN-$10 STX ILEN-$10+1 JSR CIOV RTS ; ; PRINTS MESSAGE TO IOCB #0, ; E:, BY USING STACKED ADDRESS ; FROM SUBROUTINE CALL AND ; ALSO RETURNING TO ADDRESS ; IMMEADIATELY AFTER MESSAGE ; CODE ; PSTR PLA ; GET ADDRESS OF STA ZPTR ; MESSAGE INTO PLA ; ZERO PAGE STA ZPTR+1 ; LOCATIONS PLOOP INC ZPTR ; BUMP POINTER BNE POUT ; FOR NEXT BYTE INC ZPTR+1 ; TO PUT AND TO ; CORRECT FOR SUBROUTINE CALL ; POUT LDX #0 ; IOCB #0 = E: LDA (ZPTR,X) ; GET BYTE BEQ PEXIT ; ZERO = QUIT JSR BYTOUT ; PUT IT JMP PLOOP ; GET ANOTHER ; PEXIT LDA ZPTR+1 ; DONE PRINTING PHA ; SO PUSH RETURN LDA ZPTR ; ADDRESS ONTO PHA ; STACK AND RTS ; RUN CODE JUST ; AFTER MESSAGE CODE ; ; ; REPORT THE HIGH AND LOW BUFFER ; LIMITS ; DEBUG1 JSR PSTR .BYTE "(",0 LDA BUFAD+1 JSR PHEX LDA BUFAD JSR PHEX JSR PSTR .BYTE "-",0 LDA BUFAD+3 JSR PHEX LDA BUFAD+2 JSR PHEX RTS ; DEBUG2 JSR PSTR .BYTE ")" .BYTE $1E,$1E,$1E,$1E,$1E .BYTE $1E,$1E,$1E,$1E,$1E .BYTE $1E,0 RTS ; ; ROUTINE TO REINITIALIZE ; DOS 2.0 ; DOSINI LDA $0704 STA $0C LDA $0704+1 STA $0C+1 JMP ($0C) ;==REINITIALIZE ; ENTIRE NEW DOS/DUP SYSTEM!!! ; ; ; ; MESSAGES TO OPERATOR ; SIGNON .BYTE $7D,$9B,$9B,$9B .BYTE +$80," MYDOS3 do" .BYTE +$80,"uble densit" .BYTE +$80,"y ATARI OS " .BYTE $9B .BYTE +$80," syst" .BYTE +$80,"em disk bui" .BYTE +$80,"lder " .BYTE $9B,$9B,0 ; MSG01 .BYTE "LOADING MDOS.OBJ",$9B .BYTE 0 ; MSG02 .BYTE "LOADING MDUP.OBJ",$9B .BYTE 0 ; LOADED .BYTE $FE,$1E,$1E,$1E,$1E .BYTE $1E,$1E,$1E,$1E,$1E .BYTE $1E,$1E,$1E,$1E,$1E .BYTE $1E,$1E,$1E,$1E,$1E .BYTE $1E,$1E,$1E,$1E,$1E .BYTE $1E,$1E,$1E,$1E,$1E .BYTE "LOADED",$FE,$9B,0 ; MSG03 .BYTE "Moving DOS/DU" .BYTE "P into place",$9B,0 ; MSG04 .BYTE "PRESS " .BYTE +$80,"START" .BYTE " TO INITIALIZ" .BYTE "E NEW DOS",$9B,0 ; MSG05 .BYTE "PRESS " .BYTE +$80,"START" .BYTE " TO ENTER NEW DOS" .BYTE $9B,0 ; NOFIL .BYTE "Cannot open " .BYTE "Object File",$9B,0 ; NOHDR .BYTE "Invalid Header in" .BYTE " Object File",$9B,0 ; ABORTED .BYTE "I/O Error, " .BYTE "load aborted",$9B,0 ; ; ;** VARIOUS VARIABLES ; MAXAD *= *+2 MINAD *= *+2 SAVC *= *+1 BUFAD *= *+6 BUFFER *= *+START-$0700 ; ; LOAD ATARIDOS RUN ADDRESS ; *= $02E0 .WORD START ;run address ;