*bump* So, with the following code, a lot of the problems are ameliorated, but for example in the speed test program, the transmitter will reliably eventually get stuck with the interrupt disabled. I can't imagine how that's possible.


Code:
#endif ;cn2_installerinflash
    ld a,%00001000                        ;Acknowledge and disable                    ;2
    out (3),a                                                                        ;2
    ld a,%00001010                        ;Set 1st timer active                        ;2
    out (3),a                                                                        ;2
    ld a,%00000000                        ;Fastest frequency, ~560hz                    ;2
    out (4),a                                                                        ;2
Cn2_NextTickLoop:
    in a,(4)                                                                        ;2
    and %00000010                                                                    ;2
    jr z,Cn2_NextTickLoop                                                            ;2
    ld a,%00001000                        ;Acknowledge and disable                    ;2
    out (3),a                                                                        ;2
    ld a,%00001010                        ;Set 1st timer active                        ;2
    out (3),a                                                                        ;2
    ld a,%00000110                        ;Slowest frequency, ~110hz                    ;2
    out (4),a                                                                        ;2
    exx                                                                                ;1
    ex af,af'                                                                        ;1
    ei                                                                                ;1
    reti                                ;-1-8- -1-9- -9- -4-2- 55 bytes total now    ;1
Cn2_Caller_RoutineDone:


Edit: @Calc84: Just to be clear, your code chunk is meant to go at the beginning of the particular routine to be protected, correct? And its output can be pushed and popped around the protected routine and used to re-enable interrupts at the end?
My code had an error, it should be fixed here:

Code:
   ;Push a zero byte to the stack and pop it
   xor a
   push af
   pop af
   ld a,i
   jp pe,interrupts_on
   ;See if an interrupt triggered. If so, the byte on the stack will not be 0 anymore
   ;unless this code is executing from $0000-$00FF area, which would only happen if you are writing an OS
   dec sp
   dec sp
   pop af
   or a
   jr z,interrupts_off
   ;If interrupts were on, set A to $FF so the increase will set parity even
   ld a,$FF
interrupts_off:
   ;Set parity odd
   inc a
interrupts_on:


Its output is the corrected LD A,I parity flag.
Ah, gotcha, thanks for that. If this works, then hopefully I'll be able to remove my workaround in the CALCnet2.2 interrupt stub, which should speed things back up slightly. I'll let you know how it works out (and if I have the patience to find all the DCS routines that have interrupt protection. :/

Edit: Huzzah! I made three copies of that routine, one on each page, and called it from all the relevant routines instead of doing ld a,i or ld a,r. It ended up costing me about 16 bytes on each page:

Page 0 is 16121 bytes long (263 bytes to spare)
Page 1 is 16335 bytes long (49 bytes to spare)
Page 2 is 16062 bytes long (322 bytes to spare)

It seems to work perfectly, even with my original synchronization fix that Benryves helped me design removed. I ran the speed tester for about 20 minutes with no freeze, whereas previously it would freeze within 30 seconds at most.
I actually made a mistake in that code, for some reason I thought that INC would affect parity instead of overflow. This, however, should work and is more optimized:

Code:
   xor a
   push af
   pop af
   ld a,i
   jp pe,interrupt_check_end
   dec sp
   dec sp
   pop af
   add a,a
   jr z,interrupt_check_end
   xor a
interrupt_check_end:
I'll try that as well, but oddly enough your previous code worked fine for me. I appreciate that that's more optimized though. Smile Because of your help we're definitely on-track for a release of Doors CS 7.1 Beta 1 this evening.
*bump* Calc84, when I switched to your latest version of the code, it seems to no longer work. Sad Is it possible that the broken version was always forcing interrupts to be detected enabled, thus why it seemed functional? Can you think of any reason why this latest code would not function, or should I try to explore what it is or if it's something in my own code?
Might I see your code for it? (since I think you told me you turned it into a routine)
calc84maniac wrote:
Might I see your code for it? (since I think you told me you turned it into a routine)
Here it be:


Code:
iCheckInts0:
;Push a zero byte to the stack and pop it
   xor a
   push af
      pop af
   ld a,i
   ret pe
   ;See if an interrupt triggered. If so, the byte on the stack will not be 0 anymore
   dec sp
   dec sp
   pop af
   add a,a
   ret z
   xor a
   ret
Hmm, I don't see what would be going wrong. It should work in theory...
calc84maniac wrote:
Hmm, I don't see what would be going wrong. It should work in theory...
Can you think of any ways to force it to enter the second part in an emulator and verify what's happening? Actually, that's a stupid question, I can just omit the ld a,i and the ret pe. I'll tell you what I discover.
Removing that part definitely should fail in most cases. If LD A,I returns PE, you can be sure that interrupts are enabled. If it returns PO, it means interrupts were disabled during execution of that instruction. Unfortunately, if an interrupt is requested during LD A,I execution, it will return PO even though interrupts were enabled before that instruction.

So if you remove the RET PE, it should be returning whether an interrupt was taken somewhere between POP AF and DEC SP, which means it will return PO most of the time.
Definitely, but if I were to do something like halt after the pop af with an interrupt definitely enabled, I could reluably check that latter code. Nevertheless, you confirmed that you have already done so.
I've confirmed that something's still off, unfortunately. Sad I loaded DCS7 onto a pair of TI-83+s, ran SpeedTest, and the interrupt seemed to repeatedly stop running about 30-40 seconds in. I edited Doors CS to change instances of "ret po \ ei \ ret" to simply "ei \ ret", and re-did my tests, and lo, no stoppage of execution. I'm very stumped. Sad I wish there was an emulator that emulated the behavior so I could see what's happening.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 2 of 2
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement