grx0644@uoft02.utoledo.edu (12/01/90)
I wrote an assembly program for my c128. Its a simple program that writes the time on the screen in the upper left hand corner. To be useful, it is started by a sys statement and returns basic when finished. It uses the cassette buffer as its home. I want to have the C128 to execute this program as part of the C128's normal routine so I don't have to keep sending a sys command. is there a way to patch something the normal operating routine that will cause the computer to JSR to my routine and then RTS back to what ever it was doing, without interupting any basic programs that may be executing at the same time? I am new to assembly so if anyone know the answer, please, I beg you, in every day terms!!! :) Thanks in advance Tony. PS. If anyone wants the basic prg that sets the clock and the ml program that is the clock, the are uploaded to my account and I can send them out uuencoded!!
slobasso@raven.calpoly.edu) (I don't know ;-) (12/02/90)
In article grx0644@uoft02.utoledo.edu writes: |I wrote an assembly program for my c128. Its a simple program that writes the |time on the screen in the upper left hand corner. To be useful, it is started |by a sys statement and returns basic when finished. It uses the cassette buffer |as its home. I want to have the C128 to execute this program as part of the |C128's normal routine so I don't have to keep sending a sys command. is there |a way to patch something the normal operating routine that will cause the |computer to JSR to my routine and then RTS back to what ever it was doing, |without interupting any basic programs that may be executing at the same time? The best way to do this is to make a ML program run while other things run is to link it into an interrrupt. I use the IRQ RAM vector. $0314-0315 When your program is done rather than returning (rts) you just jmp to where the Vector usually points. here's a sample that changes the border color of the 40col screen . 01800 78 SEI ;these 7 lines set up the interrupt vector . 01801 A9 0D LDA #$0D ;LSB of address . 01803 8D 14 03 STA $0314 . 01806 A9 18 LDA #$18 ;MSB of address . 01803 8D 15 03 STA $0315 . 0180B 58 CLI . 0180C 60 RTS ; note that the program starts at the address used above . 0180D CE 20 D0 DEC $D020 ;this is your actual program, it finishes by . 01810 4C 65 FA JMP $FA65 ;jumping to FA65 (EA31 for the C64) this program will run while a basic or ML program is running w/o interrupting it. Try to have the program as small as possible since it is executed very often. For instance a clock need only be updated once every second. I think that the interrupt will get called 60 times a second. -- --- | I took a course in speed reading and was Steve LoBasso | able to read War and Peace in twenty minutes. slobasso@polyslo.CalPoly.EDU | It's about Russia. ucbvax!voder!polyslo!slobasso | -- Woody Allen
hh2x@vax5.cit.cornell.edu (12/02/90)
In article <1990Nov30.161424.2348@uoft02.utoledo.edu>, grx0644@uoft02.utoledo.edu writes: > I wrote an assembly program for my c128. Its a simple program that writes the > time on the screen in the upper left hand corner. To be useful, it is started > by a sys statement and returns basic when finished. It uses the cassette buff
sd05@terre.DMI.USherb.CA (Sylvain Tremblay / Eric Trepanier) (12/03/90)
In article <1990Nov30.161424.2348@uoft02.utoledo.edu> grx0644@uoft02.utoledo.edu writes: >I wrote an assembly program for my c128. Its a simple program that writes the >time on the screen in the upper left hand corner. To be useful, it is started >by a sys statement and returns basic when finished.It uses the cassette buffer >as its home. I want to have the C128 to execute this program as part of the >C128's normal routine so I don't have to keep sending a sys command. is there >a way to patch something the normal operating routine that will cause the >computer to JSR to my routine and then RTS back to what ever it was doing, >without interupting any basic programs that may be executing at the same time? >I am new to assembly so if anyone know the answer, please, I beg you, in every >day terms!!! :) >Thanks in advance >Tony. What you must do is an interrupt service routine. The 6502 processor is interrupted every 1/60th second to perform some housekeeping chores, such as scanning the keyboard for a key, displaying any new characters, and so on... When the "interruption" occurs, the current processor's volatil state (Acc, Xreg, Yreg, Processor Status, MMU cfg, ...) is saved on the stack, and then the 8502 jumps through an indirect vector to its interrupt service routine. When it is done, it exits via a RTI (ReTurn from Interrupt) instead of a RTS. It is possible to have a custom routine executed as part of the normal interrupt sequence by making the indirect vector point to your own routine, instead of the Kernal's. Once your routine is executed, you should JMP to the remainder of the Kernal's interrupt service routine, or else the 8502 will not scan the keyboard anymore, and the computer will appear to be locked (crashed). It is important to disable interruptions (with a SEI, SEt Interrupt disable bit) while you are modifying the indirect vector. If you don't, an interruption might occur just after you modify the low byte, but before you modify the high byte. This would cause the 8502 to jump to an invalid address, and thus, probably crash. This is what your code should look like: InitClk: sei ; disable interruptions lda IIRQ ; get interrupt vector value, low byte sta JumpIRQ+1 ; and store at end of custom interrupt routine lda IIRQ+1 ; get interrupt vector value, high byte sta JumpIRQ+2 ; and store at end of custom interrupt routine lda #<Clock ; get low byte of custom interrupt routine sta IIRQ ; and store in interrupt vector, low byte lda #>Clock ; get high byte of custom interrupt routine sta IIRQ+1 ; and store at end of custom interrupt routine cli ; reenable interruptions rts ; exit from clock initialisation routine Clock: ... ; Clock interrupt service routine JumpIRQ: jmp $FFFF ; Jump to the remainder of the IRQ routine When you want to initialize the clock, just do a SYS to InitClk. And, provided that your clock service routine is ok, it should run continuously, without disturbing any basic program. You should probably have a clock disable routine which would restore the interrupt vector (IIRQ = $0314) back to its original value. One thing you must keep in mind is that you CANNOT fiddle with the VDC while you're in your interrupt routine. This is a more delicate subject and would require that you know exactly how the VDC works, and I'm not sure you do. This means that your clock can only work in 40 columns mode. It could be made to work in 80 columns mode too, but it would require a lot more work on your part. Stick with to 40 column clock first. If you can do it, then try doing it in 80 column. Well I hope that this short letter gives you a hint. Interrupts are the most powerful and intersting aspects of machine language programming. If you learn to master them, you make your C128 do great things, like a mouse driver or background jobs, or so on... There is a book by Jim Butterfield that I highly recommend to any novice or intermediate machine language programmers, it is called: Machine Language For The Commodore 64, 128 And Other Commodore Computers Its publisher's address is: A Brady Book, Published by Prentice Hall Press, New York, New York 10023 This book is an excellent ml tutorial which covers every aspects of machine language programming on the C128. Eric Trepanier -- +-----------------------------------------------------------------///------+ | Sylvain Tremblay INTERNET: sd05@terre.USherb.CA __ /// /| | | Eric Trepanier CIS: 71640,666 \\\/// # | | | Sherbrooke, Qc, Can TEL: (819) 820-0976 \XX/ _|_ |
treesh@vangogh.helios.nd.edu (12/04/90)
What you need to do is use whats called an IRQ splice. I dont know exactaly how this is done on the C128, but I would guess its not that hard. If its anything like its done on the 64, you will need to make one small modification to the end of your ML routine, insteat of having it RTS, you will have it JMP to a locations somplace in the Kernal ROM. You will then alter an IRQ vector, so that it now points to your ML, and when your ML is done it will jump to the place in ROM to where it normally would have gone if you had not alterd the vector in the first place. IRQ's are jumpped to 60 times a second on the 64, and are for all pracitcal pourposes transparrent to BASIC. ctfm
md3b+@andrew.cmu.edu (Matthew Donald Drown) (12/07/90)
I haven't done this in a couple years, I have an Amiga now, but for some help. To set up an IRQ you must set the address you want to be jumped to, in lo-byte, hi-byte format. Then your code must end with a JMP $ea31. That should be it. A simle prog that keeps the screen black no matter what you do would be: Begin: sei lda #<irqthingy ldx #>irqthingy sta $0314 stx $0315 cli rts IrqThingy: lda #$00 sta $d020 jmp $ea31 That should do, more advanced stuff is stopping the interupt at certain screen spots. Not much harder, but get this part working first. -Matt (BTW, was anyone on QLink 2 years ago? And if so do you remember a guy called Nemesis? That's me, I wrote a demo maker for people.)