Terminal program for MailStation devices
1; vim:syntax=z8a:ts=8
2;
3; msTERM
4; interrupt service routine
5;
6; Copyright (c) 2019 joshua stein <jcs@jcs.org>
7;
8; Permission to use, copy, modify, and distribute this software for any
9; purpose with or without fee is hereby granted, provided that the above
10; copyright notice and this permission notice appear in all copies.
11;
12; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19;
20
21 .module isr
22
23 .include "mailstation.inc"
24 .globl _modem_isr
25
26 .equ isrjump, #0xf7
27 .equ isrjumptable, #0xf800
28
29 ; we're going to put 0xf7 at 0xf800 - 0xf8ff and then put 0xf8 in the
30 ; 'i' register. when an interrupt happens in interrupt mode 2, some
31 ; garbage byte will be on the bus and form an address 0xf800+garbage.
32 ; the cpu will then read that address+1 which we know will contain
33 ; 0xf7f7, and then jump to 0xf7f7, which we contain our own code,
34 ; which will just be a 'jp isr' to our real ISR
35
36 .area _CODE
37
38_patch_isr::
39 di
40
41 ; spray isrjump from isrjumptable to (isrjumptable + 0xff + 1)
42 ld hl, #isrjumptable
43 ld a, #isrjump
44 ld (hl), a
45 ld de, #isrjumptable + 1
46 ld bc, #0x0100
47 ldir ; ld (de), (hl); dec bc until 0
48
49 ; put our jump at isrjump+isrjump
50 ld h, #isrjump
51 ld l, #isrjump
52 ld (hl), #0xc3 ; jp
53 inc hl
54 ex de, hl
55 ld hl, #isr
56 ld a, h
57 ld b, l
58 ex de, hl
59 ld (hl), b ; lower address of isr
60 inc hl
61 ld (hl), a ; upper address of isr
62
63 ld hl, #isrjumptable
64 ld a, h
65 ld i, a ; interrupts will now be #0xf800 + rand
66 im 2 ; enable interrupt mode 2
67
68 xor a ; clear interrupt mask
69 set 7, a ; allow interrupt 7 for power button
70 ;set 6, a ; 6 for modem
71 ;set 5, a ; 5 for RTC
72 set 2, a ; 2 for keyboard
73 set 1, a ; 1 for keyboard
74 ld hl, (p3shadow)
75 ld (hl), a ; store this mask in p3shadow
76 out (0x3), a
77 ei ; here we go!
78 ret
79
80isr:
81 push af
82 push bc
83 push de
84 push hl
85 push ix
86 push iy
87 in a, (0x3)
88 bit 7, a ; power button
89 jp nz, 0x1940
90 bit 6, a ; modem
91 jp nz, isr_6
92 in a, (0x3) ; why read again? factory isr does
93 bit 1, a ; keyboard scan, 64hz
94 jp nz, 0x18d4 ; use factory handler
95 bit 2, a ; keyboard when button pressed
96 jp nz, 0x18e7 ; use factory handler
97 xor a ; any other interrupt, just ignore
98 out (0x3), a
99 jp isrout
100isr_7:
101 ld hl, (p3shadow)
102 ld a, (hl)
103 res 7, a
104 out (0x3), a ; reset interrupt
105 ld a, (hl)
106 out (0x3), a ; set mask back to p3shadow
107 call 0x3b19 ; default power button handler
108 jp isrout
109isr_6:
110 ld hl, (p3shadow)
111 ld a, (hl)
112 res 6, a
113 out (0x3), a ; reset interrupt
114 ld a, (hl)
115 out (0x3), a ; set mask back to p3shadow
116 call _modem_isr
117 jp isrout
118isrout:
119 pop iy
120 pop ix
121 pop hl
122 pop de
123 pop bc
124 pop af
125 ei
126 reti