Multitasking on the 2068

Authors

Publication

Pub Details

Date

Pages

BASIC Terms

See all articles from SMUG Bytes v6 n2

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” 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

Products

 

Media

 

Image Gallery

Source Code

Scroll to Top