It's fun to read how much of my initial ideas have died a horrible death in the last few months
Timendus wrote:no wiki, no publicity
http://vera.timendus.com/
- Investigating the possible use of C in z80 calc programming
Haven't written a single line of C for the kernel, all die hard assembly
- Support multitasking (I know it can be done, so who knows, with the right tools
)
Well, multitasking hasn't really been abandoned, only pushed away to the VM... but still...
(You could argue that the demo below has a bit of multitasking going on though
)
- "Compatibility" with Ti-OS in the sense that it should be able to communicate with normal calcs through the link port and transfer files
Okay, perhaps this one could still happen in userspace, but it's not very likely.
Anyway, that's not why I'm necroposting
We've got the interrupts and power on/off tamed
Note that the timer animation in the top right corner and the "Power on"/"Power off" messages are triggered by the kernel through callback handlers (this is a "userspace application" in that sense which only uses the kernel interrupt routines and doesn't have to do any interrupt voodoo magic itself, only it has been compiled into the kernel as a test so it's not a "stand alone" app in the usual sense).
Using interrupt callbacks means that the main loop which is waiting for the user pressing Enter is not handling the animation, and is not handling the power downs. You can turn the calculator off by simply pressing the ON key once (and back on by pressing the key again) and this is handled in the im 1 interrupt handler. So you should be able to turn your calculator off during assembly applications by default. And even though it doesn't get screenshotted by PTI, when the console says "Power off", the emulator actually goes off
Oh, and you can also register a callback handler for link port interrupts, but that hasn't been tested yet
For those who are interested; here's the full source of the test "application", I've added a few comments to clarify how it works:
Code: Select all
;; === TEST_INTERRUPTHOOKS ===
;; Test adding custom application interrupt handlers
;;
;; Warning:
;; Screws up two bytes at $8000
#ifdef TEST_INTERRUPTHOOKS
; Initialize the animation variables
ld a,%00111111 ; "sprite"
ld ($8000),a
xor a ; delay counter
ld ($8001),a
; Output "Showing interrupts\nPress Enter to stop"
ld hl,test_int_str1
call console_printstr
; Set up timer interrupt callback handler
ld hl,test_int_timerhandler
call interrupt_register_timerhandler
; Set up power on callback handler
ld hl,test_int_onhandler
call interrupt_register_poweronhandler
; Set up power off callback handler
ld hl,test_int_offhandler
call interrupt_register_poweroffhandler
; Here's our excuse for a "main loop" :)
call keyboard_waitkey ; blocking waitkey routine
; Exit from "main loop", clean callback handlers
call interrupt_clear_handlers
; Jump to exit
jp test_int_done
; Timer interrupt callback handler
test_int_timerhandler:
; Execute only once every 20 calls
ld a,($8001)
inc a
cp 20
ld ($8001),a
ret nz
xor a
ld ($8001),a
; Update animation directly on the LCD
call display_lcd_delay
ld a,1
out (LCDCTRL),a
call display_lcd_delay
ld a,$80
out (LCDCTRL),a
call display_lcd_delay
ld a,$2B
out (LCDCTRL),a
call display_lcd_delay
ld a,($8000)
out (LCDDATA),a
; Rotate the "sprite"
rrca
ld ($8000),a
; Done
ret
; Power on callback handler
test_int_onhandler:
; Output "\nPower on"
ld hl,test_int_str2
call console_printstr
ret
; Power off callback handler
test_int_offhandler:
; Output "\nPower off"
ld hl,test_int_str3
call console_printstr
ret
test_int_done:
#endif
...
#ifdef TEST_INTERRUPTHOOKS
test_int_str1:
.db "Showing interrupts\nPress Enter to stop",0
test_int_str2:
.db "\nPower on",0
test_int_str3:
.db "\nPower off",0
#endif