DOUBLE DRAGON
Here's a short and simple program which enables you to run more than one program at once on your Dragon. Or more precisely, Task Swapper turns an unexpanded Dragon 64 into two separate Dragon 32's. You can therefore develop and RUN two BASIC programs simultaneously. Or perhaps run BASIC on one virtual machine whilst at the same time using ALLDREAM or playing a game of ESCAPE on the other.
To change between the tasks just press SHIFT and SPACE. You can do this at any time; you do not need to be at the command prompt. The active and inactive tasks are then swapped and you can continue from where you left off in the other task. You can also press SHIFT+O to overwrite the inactive task with the active task, thereby saving your position in an adventure game or making a back-up copy of a program which you are working on. You can also use this facility to bring a crashed task back into use.
To install the Task Swapper program simply enter, save and then RUN the BASIC loader given below. You then have two identical virtual machines, and can continue and switch between them as you please. But what architectures do you now have? Well, both machines must share the IO registers, use a new IRQ handler, and lose the 330 bytes of memory occupied by Task Swapper. But apart from these restrictions the illusion of two separate machines is complete.
In practice this means that if you run BASIC on both virtual machines then you should have no problems at all. However, you must not attempt to access the upper 32K of RAM, or CLEAR/POKE above address $7EB5. It's also wise to avoid switching tasks in the middle of IO operations such as printing.
For machine code programs the issue of compatibility with Task Swapper is more complicated. In theory they should work just as well. However, the lack of a protection mechanism in the 6809 means that Task Swapper cannot prevent other programs from taking over the IRQ. And if this happens then the inactive task will become inaccessible (though sometimes pressing RESET may reinstate Task Swapper). Most commercial games will indeed monopolise the IRQ, and only trial and error can reveal which programs are compatible.
Some machine code programs also use non-standard base addresses for the graphics screen and so will not be restored correctly when swapped back into main memory. For such programs simply press SHIFT+G to scroll the screen up, or SHIFT+W to scroll down. You only need to do this once, as addresses $BA:$BB are updated accordingly. Semigraphics and obscure graphics modes aren't supported at all.
To avoid conflicts with machine code programs Task Swapper may be relocated if necessary. It can happily live anywhere in RAM but must begin on an even byte boundary. I've not tested Task Swapper under Dragon DOS, but it may work. I'd guess that it would be prudent to access disks from just one of the tasks, or perhaps modify Task Swapper so that the DOS workspace isn't swapped.
Code: Select all
100 'Dragon 64 Task Swapper by Sarah
110 CLEAR 200,&H7EB5: L=&H7EB6
120 READ A$: FOR I=1 TO 66 STEP 2: V=VAL("&H"+MID$(A$,I,2)): T=T+V
130 POKE L,V: L=L+1: NEXT: IF L<32768 THEN 120
140 IF T=37631 THEN EXEC &H7EB6 ELSE ?"Error In Data"
200 DATA 338C5E11B3010D260D39000000000000010000000000BE010DAF8D00F8FF010D33
210 DATA 8D011B9E72AF8D011EDF728680347E340210EF8CD48D0C3BEC81EDC11183FF0025
220 DATA F6391A10B7FFDF9E8ACE80008DED308CAD33898000308901008DE0B7FFDE396A8C
230 DATA AC26378EFF008605A78CA2E602867FA702A684E7028548260C10EF8C8A8DC2F6FF
240 DATA 22E78C8D855026060ABA0ABA2008854426090CBA0CBA1700892075856026711A10
250 DATA 10EF8DFF62328DFF67B7FFDF308DFF4BAF8DFF559E8A108E80008D5E30890100CC
260 DATA 8000ED8DFF428D51B7FFDEA68DFF403402F6FF22E78DFF37BDA93AA6E481B0251B
270 DATA CEFFC081C0250EA74581D0250C81E02506A7432004A743A7418D243502B7FF22AE
280 DATA 8DFF0110EE8DFEFAAF8DFEF67E0000EC84EEA4EDA1EF81AC8DFEEB25F239DCBA44
290 DATA 8EFFC64424063001A7802004A78430028CFFD425EE3912308DFF1DBF010D7E0000
Code: Select all
7EB6
7EB6 * TASK SWAPPER BY SARAH
7EB6 * 15/4/94
7EB6
7EB6 *CHECK IF ALREADY INSTALLED
7EB6 338C5E @START LEAU IRQ,PC
7EB9 11B3010D CMPU $10D
7EBD 260D BNE INSTAL
7EBF 39 RTS
7EC0
7EC0 *S REGISTER SWAP SPACE+STACK ETC
7EC0 0000 SREG FDB 0
7EC2 0000 SREG2 FDB 0
7EC4 0000 END FDB 0
7EC6 01 IRQCNT FCC 1
7EC7 00000000 STACK FDB 0,0
7ECB 00 FF22 FCC 0
7ECC
7ECC *INSTALL NEW IRQ HANDLER
7ECC BE010D INSTAL LDX $10D
7ECF AF8D00F8 STX IRQJMP+1,PC
7ED3 FF010D STU $10D
7ED6
7ED6 *INSTALL NEW RESET HANDLER
7ED6 338D011B LEAU RESET,PC
7EDA 9E72 LDX 114
7EDC AF8D011E STX RESJMP+1,PC
7EE0 DF72 STU 114
7EE2
7EE2 *FORK AND RETURN
7EE2 8680 LDA #$80
7EE4 347E PSHS U,Y,X,DP,D
7EE6 3402 PSHS A
7EE8 10EF8CD4 STS SREG,PC
7EEC 8D0C BSR DUP
7EEE 3B RTI
7EEF
7EEF *COPY LOOP
7EEF EC81 CPLOOP LDD ,X++
7EF1 EDC1 STD ,U++
7EF3 1183FF00 COPY CMPU #$FF00
7EF7 25F6 BLO CPLOOP
7EF9 39 RTS
7EFA
7EFA *COPY MEM TO EXTENDED MEMORY
7EFA 1A10 DUP ORCC #$10
7EFC B7FFDF STA $FFDF
7EFF 9E8A LDX $8A
7F01 CE8000 LDU #$8000
7F04 8DED BSR COPY
7F06 308CAD LEAX @START,PC
7F09 33898000 LEAU $8000,X
7F0D 30890100 LEAX $100,X
7F11 8DE0 BSR COPY
7F13 B7FFDE STA $FFDE
7F16 39 RTS
7F17
7F17 *NEW IRQ HANDLER
7F17 *TIME TO READ KEYBOARD YET?
7F17 6A8CAC IRQ DEC IRQCNT,PC
7F1A 2637 BNE IRQJP2
7F1C
7F1C *READ KEYBOARD
7F1C 8EFF00 LDX #$FF00
7F1F 8605 LDA #5
7F21 A78CA2 STA IRQCNT,PC
7F24 E602 LDB 2,X
7F26 867F LDA #255-128
7F28 A702 STA 2,X
7F2A A684 LDA ,X
7F2C E702 STB 2,X
7F2E
7F2E *CHECK FOR SHIFT+O
7F2E 8548 BITA #64+8
7F30 260C BNE NOVER
7F32 10EF8C8A STS SREG,PC
7F36 8DC2 BSR DUP ;OVERWRITE OTHER TASK
7F38 F6FF22 LDB $FF22
7F3B E78C8D STB FF22,PC
7F3E
7F3E *CHECK FOR SHIFT+W
7F3E 8550 NOVER BITA #64+16
7F40 2606 BNE NDOWN
7F42 0ABA DEC $BA
7F44 0ABA DEC $BA
7F46 2008 BRA CHGBAS
7F48
7F48 *CHECK FOR SHIFT+G
7F48 8544 NDOWN BITA #64+4
7F4A 2609 BNE NUP
7F4C 0CBA INC $BA
7F4E 0CBA INC $BA
7F50 170089 CHGBAS LBSR GBASE
7F53 2075 IRQJP2 BRA IRQJMP
7F55
7F55 *CHECK FOR SHIFT+SPACE
7F55 8560 NUP BITA #64+32
7F57 2671 BNE IRQJMP
7F59
7F59 *PREPARE TO SWAP TASKS
7F59 1A10 ORCC #$10 ;NO MORE IRQS
7F5B 10EF8DFF62 STS SREG2,PC ;REMEMBER STACK
7F60 328DFF67 LEAS STACK+4,PC ;TEMP STACK
7F64
7F64 *SWAP THE TASKS
7F64 B7FFDF STA $FFDF
7F67 308DFF4B LEAX @START,PC
7F6B AF8DFF55 STX END,PC
7F6F 9E8A LDX $8A
7F71 108E8000 LDY #$8000
7F75 8D5E BSR SWAP
7F77 30890100 LEAX $100,X
7F7B CC8000 LDD #$8000
7F7E ED8DFF42 STD END,PC
7F82 8D51 BSR SWAP
7F84 B7FFDE STA $FFDE
7F87
7F87 *SWAP THE DISPLAY MODE
7F87 A68DFF40 LDA FF22,PC
7F8B 3402 PSHS A
7F8D F6FF22 LDB $FF22
7F90 E78DFF37 STB FF22,PC
7F94 BDA93A JSR 43322
7F97 A6E4 LDA ,S
7F99 81B0 CMPA #$B0
7F9B 251B BLO TEXT
7F9D
7F9D *SET GRAPHIC RESOLUTION
7F9D CEFFC0 LDU #$FFC0
7FA0 81C0 CMPA #$C0
7FA2 250E BLO X11
7FA4 A745 STA 5,U
7FA6 81D0 CMPA #$D0
7FA8 250C BLO XXX
7FAA 81E0 CMPA #$E0
7FAC 2506 BLO XX1
7FAE A743 STA 3,U
7FB0 2004 BRA XXX
7FB2 A743 X11 STA 3,U
7FB4 A741 XX1 STA 1,U
7FB6
7FB6 *SET BASE ADDRESS
7FB6 8D24 XXX BSR GBASE
7FB8
7FB8 *SET VDG REGISTER
7FB8 3502 TEXT PULS A
7FBA B7FF22 STA $FF22
7FBD
7FBD *SWAP STACK POINTERS
7FBD AE8DFF01 LDX SREG2,PC
7FC1 10EE8DFEFA LDS SREG,PC
7FC6 AF8DFEF6 STX SREG,PC
7FCA
7FCA *CONTINUE EXISTING IRQ HANDLER
7FCA 7E0000 IRQJMP JMP >0
7FCD
7FCD *MEM AND EXTENDED MEM SWAP LOOP
7FCD EC84 SWLOOP LDD ,X
7FCF EEA4 LDU ,Y
7FD1 EDA1 STD ,Y++
7FD3 EF81 STU ,X++
7FD5 AC8DFEEB SWAP CMPX END,PC
7FD9 25F2 BLO SWLOOP
7FDB 39 RTS
7FDC
7FDC *SET SCREEN BASE ADDR. FROM $BA
7FDC DCBA GBASE LDD $BA
7FDE 44 LSRA
7FDF 8EFFC6 LDX #$FFC6
7FE2 44 SETADR LSRA
7FE3 2406 BCC SET0
7FE5 3001 LEAX 1,X
7FE7 A780 STA ,X+
7FE9 2004 BRA TSTEND
7FEB A784 SET0 STA ,X
7FED 3002 LEAX 2,X
7FEF 8CFFD4 TSTEND CMPX #$FFD4
7FF2 25EE BLO SETADR
7FF4 39 RTS
7FF5
7FF5 *NEW RESET HANDLER
7FF5 12 RESET NOP
7FF6 308DFF1D LEAX IRQ,PC ; ENSURE IRQ SET
7FFA BF010D STX $10D
7FFD 7E0000 RESJMP JMP >0
8000