MTOS MultiTasking Operation System



The MTOS is a set of programs that uses a program called "Split Personality" from Nibble magazine. Most of the code in Split Personality is intact. We've added the ability to add more banks to the system with a Ramworks III card, added cross bank transfer ability, interrupt handler for multitasking (auto-switching), interrupt enabler, and a Z80 programmable interrupt generator.

Download the DSK. This is an old version of the code without the interrupt code, no PRODOS compatibility.

I've helped beta-test and improve the code for an apple II "multitasker". It interests me for use on my robot. Wozbot currently multitasks several programs in his memory. The MTOS system stores different programs (along with the STACK for that process) in different banks of auxillary memory. The 6502 processor has a 64k address range (16bit address). To add more memory to the computer, companies "bank switched RAM". RAM is stuck on an interface card. It is switched out in chunks into the address space of the 6502. The Apple lets you switch different parts out at different times. You can switch the stack/Language Card (upper 16k), page zero and 1 (zero page and the stack), and page 2 to DFFF (the area between the stack and $C000, which is the beginning of the "softswitches" and other Apple II I/O area. Here is an article that will give you better idea how the Softswitches work. THe MTOS works by running a program for a short time, a mouse card interrupt occurs. The interrupt triggers the switching code. The code saves the processor status, program counter, stack pointer, etc (all 6502 registers). It then switches in the next bank of Auxillary memory. The control is passed to the switching code in the selected bank. The code loads the processor status for that task, and runs the task. Another interrupt occurs, and the code switches to the next task. COMING SOON: Memory map animations of how the transfer between banks occurs. RJ The Setup program gets loaded into $8200. It then copies data around the banks as mentioned and described below.

A small BASIC program is used to add more active banks. Up to 16 banks can be used with a RAMWORKS III card.

Once the banks are setup, you POKE the number of the bank you want to get to and CALL768. Split Pers determines if you are in Aux or MAIN. If in AUX, it switches to MAIN. If in MAIN, it switches to the bank you POKED.

No automation of program loading has been made. You must go into each bank seperately and load the appropriate BASIC/Assembly files.

You must also BLOAD the interrupt handler into any bank you wish to multitask.

Once all the interrupt handlers are installed, interrupts are turnedON. I wrote a small driver for my Z80 computer that sets the interrupt interval and turns them ON.

The Apple II will begin multitasking. Needed is screen output for aux banks higher than AUX0. We could add code into MAIN RAM to copy from AUX the screen data and store it in MAIN RAM screen area. This would be slow. How about a RAM card that allows you to display text from any bank?


Step 1:
a)Set to read/write all main memory.
b)Set to Read ROM/Write RAM
---c)Copy ROM to upper 16k main RAM
---d)Copy $00-$1FF (zero pg, stack) to $8000-$81FF
---e)Load Split Pers to $300

Step 2:
a)Set to read $200-$BFFF main memory.
b)Set to write $200-$BFFF Aux memory
---c)Copy $200-$BFFF from main to aux memory

Step 3:
a)Set to READ/WRITE Aux. $0-$1ff and upper 16k.
b)Set to Read ROM/WRITE RAM
---c)Copy ROM into Aux RAM top 16k

Step 4:
a)Set to read $200-$BFFF main memory.
b)Set to READ/Write Aux memory $00-$1FF and top 16k
---c)Copy $8000-$81FF from main to aux memory $00-$1FF (see step1)
TEMP EQU $0000 STARTSOU EQU $3C ENDSOU EQU $3E DEST EQU $42 STATUS EQU $48 BANK EQU $3CE APPLEID EQU $3CF RDMAINRM EQU $C002 WRMAINRM EQU $C004 SETSTDZP EQU $C008 SETALTZP EQU $C009 READRAM EQU $C080 RROMWRAM EQU $C081 READROM EQU $C082 RDWRTLC EQU $C083 AUXMOVE EQU $C311 IDBYTE EQU $FBB3 HOME EQU $FC58 COUT EQU $FDED MOVE EQU $FE2C BELL EQU $FF3A SAVE EQU $FF4A * *************************** * ORG $8200 * * *THE FIRST SECTION OF THIS PROGRAM IS A *CONTROLLING CODE THAT CALLS SUBROUTINES TO DO ALMOST *EVERYTHING. THIS SHOULD MAKE THE CODE EASY TO FOLLOW *AND MODIFY * ***************************** * CLI ; CLEAR INTERRUPTS CLD ; CLEAR DECIMAL MODE CLC ; CLEAR CARRY JSR SAVE ; AND SAVE REGISTER VALUES SEI ;DISABLE INTERRUPTS- WITH THE SOFT ;SWITCHES TO BE HIT THEY COULD BE ;FATAL JSR NORMAL ;INITIALIZE RAM STATUS TO KNOWN ;SETTINGS TO READ/WRITE ROM UPPER ;16K AND MAIN RAM NOP NOP NOP * ;JSR CKMEMSIZ MAKE SURE WE HAVE EXPANDED RAM JSR ZPSETUP ;DO VECTORS. ETC BEFORE ZPPISAVE JSR ZPP1SAVE ;SAVE A "VIRGIN" COPY OF THE ZERO ;PAGE AND 6502'S STACK (PAGE ONE) JSR INSTALSW ;PUT RAM GATE IN AT $300 JSR LCLOAD ;COPY ROM TO LANGUAGE CARD NOP NOP NOP * ;JSR CKBIGMEM HOOK IN HERE TO LOOK FOR A BIG ;MEMORY RAM CARD USING THE IIE'S ;RENDUNDANT RAM STRUCTURE. THE ;EXAMPLE SUPPLIED HERE IS FOR AN ;APPLIED ENGINEERING MEMORYMASTER DOBANK2 LDA #$02 ;BEGIN SETUP OF THE 2ND 64K BANK STA BANK ;BY PUTTING AN ID BYTE (03CE) JSR MAINLOAD ;IN PLACE AND COPYING THE $200 ;TO $BFFF DATA TO ALT. THIS WILL ;INCLUDE THE RAM GATE SWITCH. ;DOS VECTORS, LOADED APPLESOFT/BINARY ;PROGRAMS, DOS, ETC STA SETALTZP ;SWITCH ON TOP 16K, ZP AND PG1 JSR LCLOAD ;AND DO LC LOAD IN THAT RAM STA SETSTDZP ;THEN TURN THE ROM BACK ON JSR ZPP1COPY ;COPY NORMAL PAGE 0 AND 1 INTO ;WHATEVER ALTERNATE RAM AVAILABLE * +-----------------------------------------+ * | SPECIAL NOTE | * | AT THIS POINT WE ARE | * | ALMOST FINISHED FOR A NORMAL 128K | * | EXPANDED RAM IIE SO ANY LARGE MEMORY | * | CARDS THAT WERE FOUND IN CKBIGMEM | * | ABOVE THAT NEED ATTENTION MUYST NOW BE | * | HANDLED . THE EXAMPLE GIVE IS FOR AN | * | AE MEMORY MASTER (192K)--SUBSITTUE | * | ROUTINES FOR THE SPECIFIC CARD OF | * | YOUR CHOICE HERE. IN CKBIGMEM AND IN | * | THE SECTION NOW TITLED MEMASTER | * +-----------------------------------------+ LDA APPLEID ;IS THIS A MEMORY MASTER IIE? CMP #$81 ;IF SO WE DO 2ND ALT 64K BANK BEQ MEMASTER ;COPYING STUFF END LDA #$01 ;PUT A "1" IN THE MAIN RAM'S STA BANK ;BANK IDENTIFICATION BYTE JSR HOME ;NEATEN THINGS UP A LITTLE JMP $3D0 ;AND EXIT TO APPLESOFT MEMASTER STA $C05E ;SWITCH TO 2ND ALTERNATE 64K RAM STA $C05F LDA #$03 ;PUT A THREE IN THE 3RD BANKS STA BANK ;ID BYTE WHEN THE $200-$BFFF JSR MAINLOAD ;RANGE IS COPIED STA SETALTZP ;REPEAT LOADING OF TOP 16K WITH JSR LCLOAD ;APPLESOFT AND MONITOR BUT IN THE STA SETSTDZP ;MEMORYMASTER'S 2ND ALT 64K BANK JSR ZPP1COPY ;ZEROPG AND PG1 COPY STA $C05E ;HITMEMORY MASTER SWITCHES AGAIN STA $C05F ;TO RETURN TO BANK #2 JSR END ;NOW EXIT * END OF GENERAL CONTROLLING PROGRAM * FOLLOWING ARE SUBROUTINES CALLED FROM ABOVE * APPLE ID AND SPLIT PERS ARE ACCESSED NORMAL STA WRMAINRM ;WRITEMOTHER RAM STA RDMAINRM ;READ MOTHER RAM LDA READROM ;READ ROM IN LC/WRITE PROTECT RAM STA SETSTDZP ;MAKE ANY ALT. RAM UNAVAILABLE JSR MSGOUT ;CLEAR THE SCREEN AND HEX 8D04 ;TURN ON 80 COL CARD ASC "PR#3" HEX 8D00 ;MAKE SURE I/O VECTORS INSTALLED JSR INTRO ;GIVE CREDITS RTS * CKMEMSIZ JSR MSGOUT ;LOAD THE APPLEID PGM HEX 8D04 ASC "BLOAD APPLE.ID" HEX 8D00 JSR $D24 ;CALL THE PROGRAM LDA APPLEID ;USE APPLE'S OWN ROUTINE TO SEE CMP #$80 ;IF WE HAVE EXPANDED RAM BNE NORAM ;IF NOT GOTO BAD NEWS CENTRAL JSR HOME ;CLEAR THE SCREEN JSR MSGOUT ;IF SO NOTIFY THAT PROCESS IS ON ASC "EXPANDED RAM AVAILABLE--SETUP IN PROGRESS" HEX 8D00 RTS NORAM JSR HOME ;CLEAR SCREEN JSR MSGOUT ;NO EXTRA RAM- GIVE 'EM HEX 8D ;BAD NEWS ASC "THE APPLE MACHINE IDENTIFICATION" HEX 8D ASC "PROGRAM HAS NOT FOUND THEIS COMPUTER" HEX 8D ASC "TO BE EQUIPPED WITH EXPANDED RAM." HEX 8D8D8D ASC "SETUP IS TERMINATED" HEX 8D8D00 JSR NORMAL JSR BELL JMP $3D0 ;EXIT VIA DOS ZPSETUP LDA #$FF ;SIGNAL IMMEDIATE MODE WITH $FF STA $76 ;IN CURLIN+1 LDA $49 ;GET STACK POINTER FOR ALT RAM USE STA $101 ;AND INITIALIZE STACKPOINTER VALUE ;<- ADD NEEDED ZEROPAGE STUFF HERE RTS ;AND RETURN LCLOAD ;SET TO READ ROM/WRITE RAM ;IN LC AREA--IF ALTZP IS ON ;THIS GIVES THE TOP OF AN ;ALTERNATE 64K BANK INSTEAD LDA RROMWRAM ;SET TOP 16K TO READ ROM AND LDA RROMWRAM ; WRITE RAM FOR COPY TRANSFER ;2 LDA'S REQUIRED (NOT IN MANUAL) LDY #$00 ;SET UP THE $D000 STARTING LDA #$D0 ;ADDRESS IN DEST AND STA DEST+1 ;LEAVE Y HOLDING #$00 STY DEST LCLOOP LDA (DEST),Y ;USE POST INDEXED INDIRECT STA (DEST),Y ;ADDRESSING TO CREAT A VERY DEY ;F-A-S-T BNE LCLOOP ;ROUTINE TO COPY AN IMAGE OF INC DEST+1 ;APPLESOFT AND THE MONITOR BNE LCLOOP ;FROM FROM TO AVAILABLE RAM LDA READROM ;WHEN FINISHED RESET ROM RTS ;AND RETURN INSTALSW JSR MSGOUT ;PRINT RETURN ($8D) AND CTL-D HEX 8D04 ;TO GETT UNCLE DOS'S ATTENTION ASC "BLOAD SPLIT.PERS" HEX 8D00 ;PRINT RETURN, MARK MESSAGE END RTS ;ALL DONE--CONTINUE ZPP1SAVE LDA #$00 ;MOVE PAGE ZERO AND PAGE 1 STA DEST ;TO $8000 TO $81FF LDA #$80 ;USING THE APPLE'S BUILT IN STA DEST+1 ;MOVE ROUTINE AT $FE2C LDA #$00 STA STARTSOU STA STARTSOU+1 LDA #$FF STA ENDSOU LDA #$01 STA ENDSOU+1 JSR MOVE LDX $49 ;GET STACK POINTER SAVED AT $101 INX ;IT WILL BE INCREMENTED BEFORE THE LDA STATUS ;STATUS BYTE IS PULLED ON TO IT SO STA $8100,X ;PUT THE STATUS BYTE WHERE NEEDED ;NOTE : CAN'T BE DONE IN ZPSETUP RTS ZPP1COPY STA SETALTZP ;TURN ON AUX TOP 16 + PG0-1 LDX #$00 ;BUILD A COUPLE OF SIMPLE PUTZPG LDA $8000,X ;LOOPS TO TAKE THE PAGES STA $00,X ;STORED AT $8000-$81FF AND DEX ;PUT THEN IN ALT RAM PG 0-1 BNE PUTZPG ;--EASIER TO DO THIS THAN PUTPG1 LDA $8100,X ;SET UP "MOVE" ROUTINE STA $100,X DEX BNE PUTPG1 LDA READROM STA SETSTDZP RTS MAINLOAD LDA #$00 ;AUXMOVE IS SET UP MUCH LIKE STA DEST ;THE MOVE ROUTINE STA STARTSOU LDA #$02 STA DEST+1 STA STARTSOU+1 LDA #$FF STA ENDSOU LDA #$BF STA ENDSOU+1 SEC ;SIGNAL MAIN TO AUX MOVE JSR AUXMOVE ;PROVIDED BY APPLE AT $C311 RTS * +-----------------------------------------+ * | NOTE: THE CODE IN CKBIGMEM BELOW | * | IS FOR EXAMPLE. CODE IN THIS | * | AREA MUST BE SPECIFIC FOR A GIVEN | * | TYPE OF RAM CARD IN CONSIDERATION | * | OF ITS SIZE, SWITCHING PROCEDURE | * | AND RAM ARCHITECTURE. THE CODE | * | HERE IS FOR AN A.E. MEMORY MASTER. | * +-----------------------------------------+ CKBIGMEM LDA RDWRTLC ;MAKE SURE WE READ AND WRITE LDA RDWRTLC ;THE LC (UPPER 16K) AREA STA SETALTZP ;IN THE ALTERNATE RAM LDA IDBYTE ;GET A BYTE TO TEST STA $C05E ;THESE INSTRUCTION ARE THE SWITCH STA $C05F ;TO CHANGE MEMORY ALT 64K CMP IDBYTE ;IS IT THE SAME AS BEFORE WE HIT ;THE MEMORY MASTER ALTERNATE RAM ;BANK SWITCH SEQUENCE? BNE PREPLUS ;IF NET WE HAVE ADDITIONAL BANK ;BUT IF SO WE STILL DON'T KNOW SO INC IDBYTE ;WE CHANGE THE IDBYTE AND THEN STA $C05E ;WE HIT THE MEMORY MASTER BANK STA $C05F ;SWITCH SEQUENCE. IF OUR COMPARISON CMP IDBYTE ;SAYS ACC=IDBYTE WE HAVE AN EXTRA ;BANK TO SETUP. IF NOT WE GIVE STA SETSTDZP ;UP, TURN OFF THE ALT. UPPER RAM LDA READROM ;AND SELECT ROM, LEAVING $80 IN RTS ;THE APPLEID WHEN WE RETURN PREPLUS STA $C05E ;AESTHETIC CONSIDERATION-IT DOESN'T STA $C05F ;REALLY MATTER WHICH IS "2" OR "3" PLUSBANK STA IDBYTE ;CORRECT IDBYTE LDA READROM ;READ ROM AND TURN OFF STA SETSTDZP ;THE ALTERNATE RAM LDA #$81 STA APPLEID ;SET APPLEID BYTE TO HOLD $81 RTS * * *THE ANDY HERTZFELD STRING PRINTING ROUTINE FROM *CALL - A.P.P.L.E * MSGOUT PLA ;FETCH THE RETURN ADDRESSES STA TEMP ;FROM THE 6502'S STACK PLA ;AND SAVE THEM WHERE WE CAN STA TEMP+1 ;GET TO THEM LATER LDY #0 ;CLEAR THE STRING INDEX AND LOOP INC TEMP ;INCREMENT RETURN ADDRESS FOR BNE SKIPADD ;EACH CHR+HI BYTE IF TEMP=0 INC TEMP+1 ;FOR "BOUNDARY" CROSSINGS SKIPADD LDA (TEMP),Y ;GET THE NEXST CHAR FOR PRINTING BEQ MSGRTS ;AND IF CHR=0 WE EXIT ORA #$80 ;TURN ON HIGH BIT FOR COUT JSR COUT ;AND PRINT VIA MONITOR ROUTINE JMP LOOP ;GO BACK FOR NEXT CHARACTER MSGRTS LDA TEMP+1 ;EXITING SO RECOVER THE PHA ;ADJUSTED RETURN ADDRESS LDA TEMP ;AND PUT IT ON THE STACK PHA ;FOR RETURN PAST END OF STRING RTS ;TO NEXT PROGRAM INSTRUCTION * * INTRO JSR BELL ;TOOT THE HORN JSR HOME ; AND CLEAR THE SCREEN JSR MSGOUT ;GIVE CRIDIT WHERE HEX 8D ;CREDIT IS DUE ASC "APPLE SPLIT PERSONALITY" HEX 8D ASC "BY JOHN A. OAKEY" HEX 8D ASC "COPYRIGHT (C)1986" HEX 8D ASC "BY MICROSPARC, INC." HEX 8D ASC "CONCORD, MA 01742" HEX 8D8D8D ASC "TWO MOMENTS PLEASE." HEX 8D8D00606F616B6579 ORG $2000 BankSel EQU $C073 MaxMem EQU 16 ;Maximum desired, 3 megabytes in this example *Write bank number to each bank STA $C009 ;Store in alternate zero page LDY #$7F ;Valid banks range $00 to $7F FindBanks STY BankSel ;Go through each bank STY $00 ;Store the bank number TYA EOR #$FF STA $01 ;Second self-check DEY BPL FindBanks *Read them back to find valid banks and save in table LDA #$00 TAY TAX FindThem STY BankSel ;Search through all banks STA BankSel+3 CPY $00 BNE NotOne ;Check bank number TYA EOR #$FF CMP $01 ;Check second double-check BNE NotOne INX TYA ;Found valid bank-save in table STA BankTbl,X CPX #MaxMem ;Found all banks to be used BCS Done NotOne INY ;Go through all valid bank ranges BPL FindThem *Ending routine Done LDA #$00 ;Reset to video bank STA BankSel STA $C008 STX BankTbl ;Size of Ram card LDA #$FF STA BankTbl+1,X ;Mark end of table RTS BankTbl DS MaxMem+2