--- title: "Multitasking on the 2068" type: "article" slug: "multitasking-on-the-2068" url: "http://localhost/article/multitasking-on-the-2068/" markdown_url: "http://localhost/article/multitasking-on-the-2068.md" published_at: "2022-10-07T12:26:58+00:00" modified_at: "2026-07-23T14:35:57+00:00" featured_image: url: "http://localhost/wp-content/uploads/2022/04/20230809-041332.jpg" excerpt: "After playing with a QL and seeing its clock run independently of every thing else, I decided to try the same thing on the TS2068 using the IM 2 interrupt mode. Here is the results of that attempt. Very simply, it prints a digital clock to the upper right hand corner of the screen while…" category: - name: "SMUG Bytes" slug: "smug-bytes" taxonomy: "category" url: "http://localhost/category/periodicals/smug-bytes/" post_tag: - name: "Best of Timex/Sinclair 2068 Articles and Documents" slug: "ts2068best" taxonomy: "post_tag" url: "http://localhost/tag/ts2068best/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" - name: "Type-in program" slug: "type-in-program" taxonomy: "post_tag" url: "http://localhost/tag/type-in-program/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" indiv: - name: "Lloyd Dreger" slug: "lloyd-dreger" taxonomy: "indiv" url: "http://localhost/indiv/lloyd-dreger/" publication_r: id: 37935 title: "SMUG Bytes" type: "periodical" url: "http://localhost/periodical/smug-bytes/" authors: "Lloyd Dreger" authors_r: - name: "Lloyd Dreger" slug: "lloyd-dreger" taxonomy: "indiv" url: "http://localhost/indiv/lloyd-dreger/" volume: "6" issue: "2" issues_articles: - id: 39717 title: "SMUG Bytes v6 n2" type: "issue" url: "http://localhost/issue/smug-bytes-v6-n2/" pages: "3-5" pubdate: "February 1989" related_articles: - id: 46436 title: "Multitasking on the 2068 (Part 2)" type: "article" url: "http://localhost/article/multitasking-on-the-2068-part-2/" archive_link: false --- # Multitasking on the 2068 After playing with a QL and seeing its clock run independently of every thing else, I decided to try the same thing on the TS2068 using the IM 2 interrupt mode. Here is the results of that attempt. Very simply, it prints a digital clock to the upper right hand corner of the screen while other programs are running. For a clock to really work, it should be what we call transparent, i. e., work under all situations. This is almost true on the TS2068 but some situations will cause the program to crash. The main reason is that the clock can’t have its own window and must share with the main screen. This messes up editing and listing basic programs while the clock is running. we can, however, keep it running without printing to the screen with a few pokes to the code and repoke when we want to print the clock again. The use of the IM 2 mode is fully discussed in my book, “[ADVANCED 2068 MACHINE CODE–VOLUME 1](http://localhost/book/advanced-machine-code-programming-on-the-2068/)” and is not a subject easily understood. However, let it suffice to say that the program uses the space from 64800 up to the UDG area of high memory-don’t overwrite it with code from any other program. It can be relocated if some precautions are taken. Contrary to some advice you may have read, to initiate the IM 2 mode you need 257 bytes of memory starting at a page boundary (L = 0). These must be loaded with the same high byte address of the jump address. Selecting this at 65024 and writing in 253’s with I loaded with 254, causes the interrupt to jump to address 253/253 (65021) which is just 3 bytes below the start of the 253 code talked about above and just enough room for a JP instruction. I have found out that with Aerco Disks activated, (OUT 244,1), the IM 2 mode sometimes crashes–which means that the CPU isn’t necessarily putting a 255 on that data bus. Other peripherals may do the same thing. A word to the wise… The operating procedure of the actual clock routine will setup a print line with the proper CODE characters and then use a RST 16 to print them to the screen. The clock doesn’t rely on the frames counter but the command BEEP, LPRINT, LLIST, COPY. SAVE, CAT, LOAD, MERGE, VERIFY. MOVE, ERASE, and repeat DELETE do what is called a DI (disable interrupts) which means no interrupts allowed until they are finished. This means the clock would not be updated every 1/60th of a second and so would run slow. That time can be considerable when saving, loading or verifying using tape. Here is the code given in decimal so you can enter it with a for/next loop from BASIC. #### The Stop Clock Routine ``` 64800 229 STOP PUSH HL 64801 62,63 LD A,63 ; VALUE FOR I REGISTER RETURN 64803 237,86 IM 1 64805 237,71 LD I,A 64807 225 POP HL 64808 201 RET ``` #### The Start Clock Routine ``` 64809 243 START DI 64810 229 PUSH HL ; SO WE CAN GET BACK TO BASIC 64811 62,254 LD A,254 68413 237,71 LD I,A ; SET INTERRUPT REGISTER 68415 30,0,254 LD HL,65024 ; SETUP INTERRUPT TABLE 64818 69 LD B,L 64819 61 DEC A 64820 119 TBLP LD (HL),A 64821 35 INC HL 64822 16,252 DJNZ TBLP 64824 0 NOP ; CORRECTION FROM PART 2 ARTICLE 64825 119 LD (HL),A 64826 237,94 IM 2 64828 225 EI 64830 201 RET ``` #### The Clock Routine ``` 64831 22 DATA DEFB 22 ; At the 1st 13 bytes are data 64832 0,24 DEFW #1800 ; 0,24 of which the 1st 64834 48 DEFB 48 ; "0" HIHR BYTE 11 will be 64835 48 DEFB 48 ; "0" LOHR BYTE printed 64836 58 DEFB 58 ; ":" COLON BETWEEN HR & MIN 64837 48 DEFB 48 ; "0" HIMIN BYTE 64838 48 DEFB 48 ; "0" LOMIN BYTE 64839 58 DEFB 58 ; ":" COLON BETWEEN MIN & SEC 64840 48 DEFB 48 ; "0" HISEC BYTE 64841 48 DEFB 40 ; "0" LOSEC BYTE 64842 255 DEFB 255 ; END OF PRINT MARKER 64843 60 FRACT DEFB 60 ; FRACTION PART OF SEC CALL HERE 64844 243 CLOCK DI 64845 197 PUSH BC 64846 213 PUSH DE 64847 229 PUSH HL 64848 245 PUSH BC ; PUSH ALL REGISTERS 64849 8 EX AF,AF' 64850 245 PUSH AF 64851 217 EXX 64851 197 PUSH BC 64852 213 PUSH DE 64854 229 PUSH HL 64855 42,136,92 LD HL,(SPOS) ; WE MUST SAVE TOP SCREEN 64858 229 PUSH HL ; AS WELL 64859 42,132,92 LD HL,(DFCC) 64862 229 PUSH HL 64863 58,60,92 LD A,(TVFLAG) 64866 245 PUSH AF 64867 203,135 RES 1,A ; MAKE SURE WE PRINT IN TOP SCR 64869 50,60,92 LD (TVFLAG),A 64872 33,75,253 LD HL,FRACT ; POINT HL AT FRACT ADDR 64875 53 DEC (HL) ; TICK FRACTION OF SEC 64876 32,71 JR NZ, PRINT ; READY TO PRINT IF <>0 64878 54,60 LD (HL),60 ; RESET FRACTION 64880 43 DEC HL ; SKIP THE END MARKER 64881 43 DEC HL ; AT LOSEC 64882 52 INC (HL) ; TICK LOSEC 64883 126 LD A,(HL) 64884 254,58 CP 58 ; IS COUNT TO "10"? 64886 32,61 JR NZ,PRINT ; READY TO PRINT IF NOT 64888 54,48 LD (HL),48 ; RESET LOSEC 64890 43 DEC HL ; TO HISEC 64891 52 INC (HL) ; TICK HISEC 64892 126 LD A,(HL) 64893 254,54 CP 54 ; IS COUNT TO "6"? 64895 32,52 JR NZ,PRINT ; READY TO PRINT IF NOT 64897 54,48 LD (HL),48 ; RESET HISEC 64899 43 DEC HL ; SKIP ":" 64900 43 DEC HL ; TO LOMIN 64901 52 INC (HL) ; TICK LOMIN 64902 126 LD A,(HL) 64903 254,58 CP 58 ; IS COUNT TO "10"? 64905 32,42 JR NZ,PRINT ; READY TO PRINT IF NOT 64907 54,48 LD (HL),48 ; RESET LOMIN 64909 43 DEC HL ; TO HIMIN 64910 52 INC (HL) ; TICK HIMIN 64911 126 LD A,(HL) 64912 254,54 CP 54 ; IS COUNT TO "6"? 64914 32,33 JR NZ,PRINT ; READY TO PRINT IF NOT 64916 54,48 LD (HL),48 ; RESET HIMIN 64918 43 DEC HL ; SKIP COLON AGAIN 64919 43 DEC HL ; TO LOHR 64920 52 INC (HL) ; TICK LOHR 64921 126 LD A,(HL) 64922 254,52 CP 52 ; IS COUNT TO "4"? 64924 40,11 JR Z,TEST ; JUMP TO SEE IF NEW DAY 64926 126 RETURN LD A,(HL) 64927 254,58 CP 58 ; IS COUNT TO "10"? 64929 32,18 JR NZ,PRINT ; READY TO PRINT IF NOT 64931 54,48 LD (HL),48 ; RESET LOHR 64933 43 DEC HL ; TO HIHR 64934 52 INC (HL) ; TICK HIHR 64935 24,12 JR PRINT ; READY TO PRINT 64937 42 TEST DEC HL ; TO HIHR 64938 126 LD A,(HL) 64939 35 INC HL ; BACK TO LOHR 64940 254,50 CP 50 ; IS HIHR COUNT TO "2"? 64942 32,238 JR NZ,RETURN ; RETURN TO MAIN IF NOT 64944 54,48 LD (HL),48 ; RESET LOHR AS NEW DAY 64946 43 DEC HL ; TO HIHR 64947 54,48 LD (HL),48 ; RESET HIHR 64949 32,63,253 PRINT LD HL,DATA 64952 126 LD A,(HL) 64953 254,255 CP 255 ; IS CHR END MARKER? 64955 40,4 JR Z,DONE ; FINISHED WITH PRINT 64957 215 RST 16 ; PRINT 10 64958 35 INC HL ; TO NEXT CHR 64959 24,247 JR NEXT ; REPEAT 64961 241 DONE POP AF ; RESTORE SAVED SYSTEM VARS 64962 50,60,92 LD (TVFLAG),A 64965 225 POP HL 64966 32,132,92 LD (DFCC),HL 64969 225 POP HL 64970 34,136,92 LD (SPOS),HL ; AT THIS POINT WE COULD CALL ; OTHER ROUTINE TO DO ; SOMETHING ELSE BEFORE ; RETURNING IF WE LIKED 64973 225 POP HL ; RESTORE ALL REGISTERS 64974 209 POP DE 64975 193 POP BC 64976 217 EXX 64977 241 POP AF 64978 8 EX AF,AF' 64979 241 POP AF ; OP CODE TYPO CORRECTED. 64980 225 POP HL 64981 209 POP DE 64982 193 POP BC 64983 206,60,0 CALL 56 ; NOW DO THE REGULAR INTERRUPT 64986 251 EI 64987 237,77 RETI ``` Note I have indicated where to call another routine if you desire to do something else before returning. Put it in there with a call as you have all the registers still pushed. But remember you are still in DI mode. The EI at 64986 isn’t necessary as there is an EI at the end of the regular interrupt routine. It’s there so no one would say he didn’t do it. For the basic program see next month’s This SMUG Bytes. article has to be continued