Rudimentary Interrupts

Added first pass of interrupt handling. SOF interrupt for Channel A is working in this test.
This commit is contained in:
Peter Weingartner 2021-09-17 21:40:55 -04:00
parent ac4f09f048
commit b172a7e086
16 changed files with 5122 additions and 5993 deletions

View file

@ -30,10 +30,10 @@ fatfs:
$(MAKE) --directory=fatfs
snd:
$(MAKE) --directory=snd
$(MAKE) --directory=snd
foenixmcp.s68: foenixmcp.o log.o ring_buffer.o $(cpu) dev fatfs snd
$(CC) $(CFLAGS) -o foenixmcp.s68 foenixmcp.o log.o ring_buffer.o $(cpu_c_obj) $(dev_c_obj) $(fat_c_obj) $(snd_c_obj)
foenixmcp.s68: foenixmcp.o log.o ring_buffer.o interrupt.o $(cpu) dev fatfs snd
$(CC) $(CFLAGS) -o foenixmcp.s68 foenixmcp.o log.o ring_buffer.o interrupt.o $(cpu_c_obj) $(dev_c_obj) $(fat_c_obj) $(snd_c_obj)
%.o: %.c $(DEPS)
$(CC) -S -c -o $@ $< $(CFLAGS)
@ -41,6 +41,6 @@ foenixmcp.s68: foenixmcp.o log.o ring_buffer.o $(cpu) dev fatfs snd
.PHONEY: clean
clean:
$(RM) *.s68 *.o
$(RM) *.s68 *.o *.asm
$(MAKE) --directory=$(cpu) clean
$(MAKE) --directory=dev clean

View file

@ -4,9 +4,51 @@
public _text_init
cnop 0,4
_text_init
movem.l l4,-(a7)
movem.l l8,-(a7)
lea l1,a2
lea 46+l1,a3
moveq #0,d2
bra l5
l4
move.l d2,d0
lsl.l #1,d0
lea _fg_color_lut,a0
add.l d0,a0
move.l d2,d0
lsl.l #1,d0
move.l #13026304,a1
move.w (a0),(0,a1,d0.l)
move.l d2,d0
lsl.l #1,d0
lea _fg_color_lut,a0
add.l d0,a0
move.l d2,d0
lsl.l #1,d0
move.l #13288448,a1
move.w (a0),(0,a1,d0.l)
move.l d2,d0
lsl.l #1,d0
lea _bg_color_lut,a0
add.l d0,a0
move.l d2,d0
lsl.l #1,d0
move.l #13026368,a1
move.w (a0),(0,a1,d0.l)
move.l d2,d0
lsl.l #1,d0
lea _bg_color_lut,a0
add.l d0,a0
move.l d2,d0
lsl.l #1,d0
move.l #13288512,a1
move.w (a0),(0,a1,d0.l)
l7
addq.l #1,d2
l5
moveq #32,d0
cmp.l d2,d0
bgt l4
l6
move.l #12845056,(a2)
move.l #12976128,(4,a2)
move.l #13008896,(8,a2)
@ -16,6 +58,11 @@ _text_init
move.l (a2),a0
moveq #1,d0
move.l d0,(a0)
move.l (20,a2),a0
move.l #1056769,(a0)
move.l (20,a2),a0
moveq #64,d0
move.l d0,(4,a0)
move.l #0,-(a7)
jsr _text_setsizes
move.l #0,-(a7)
@ -37,6 +84,10 @@ _text_init
move.l (a3),a0
moveq #1,d0
move.l d0,(a0)
move.l (20,a3),a0
move.l #1056768,(a0)
move.l (20,a3),a0
move.l #4194304,(4,a0)
move.l #1,-(a7)
jsr _text_setsizes
move.l #0,-(a7)
@ -52,23 +103,23 @@ _text_init
moveq #0,d0
add.w #64,a7
l2
l4 reg a2/a3
movem.l (a7)+,a2/a3
l6 equ 8
l8 reg a2/a3/d2
movem.l (a7)+,a2/a3/d2
l10 equ 12
rts
opt o+,ol+,op+,oc+,ot+,oj+,ob+,om+
public _text_set_cursor
cnop 0,4
_text_set_cursor
movem.l l11,-(a7)
move.w (22+l13,a7),d6
move.w (18+l13,a7),d5
move.b (15+l13,a7),d4
move.w (10+l13,a7),d3
move.w (6+l13,a7),d2
movem.l l15,-(a7)
move.w (22+l17,a7),d6
move.w (18+l17,a7),d5
move.b (15+l17,a7),d4
move.w (10+l17,a7),d3
move.w (6+l17,a7),d2
cmp.w #2,d2
bge l10
l9
bge l14
l13
move.w d2,d0
ext.l d0
moveq #46,d1
@ -113,24 +164,24 @@ l9
or.l d1,d0
move.l (12,a1),a0
move.l d0,(a0)
l10
l7
l11 reg d2/d3/d4/d5/d6/d7
l14
l11
l15 reg d2/d3/d4/d5/d6/d7
movem.l (a7)+,d2/d3/d4/d5/d6/d7
l13 equ 24
l17 equ 24
rts
; stacksize=28
opt o+,ol+,op+,oc+,ot+,oj+,ob+,om+
public _text_set_xy
cnop 0,4
_text_set_xy
movem.l l22,-(a7)
move.w (6+l24,a7),d5
move.w (10+l24,a7),d3
move.w (14+l24,a7),d2
movem.l l26,-(a7)
move.w (6+l28,a7),d5
move.w (10+l28,a7),d3
move.w (14+l28,a7),d2
cmp.w #2,d5
bge l17
l16
bge l21
l20
move.w d5,d0
ext.l d0
moveq #46,d1
@ -153,18 +204,18 @@ l16
move.w (28,a2),d1
ext.l d1
cmp.l d0,d1
bgt l19
l18
bgt l23
l22
moveq #0,d3
addq.w #1,d2
l19
l23
moveq #0,d0
move.w d2,d0
move.w (30,a2),d1
ext.l d1
cmp.l d0,d1
bgt l21
l20
bgt l25
l24
move.w (30,a2),d0
subq.w #1,d0
move.w d0,d2
@ -173,7 +224,7 @@ l20
move.l d0,-(a7)
jsr _text_scroll
addq.w #4,a7
l21
l25
move.w d3,(32,a2)
move.w d2,(34,a2)
moveq #0,d0
@ -195,25 +246,25 @@ l21
move.l (8,a2),a0
add.w d4,a0
move.l a0,(40,a2)
l17
l14
l22 reg a2/d2/d3/d4/d5/d6/d7
l21
l18
l26 reg a2/d2/d3/d4/d5/d6/d7
movem.l (a7)+,a2/d2/d3/d4/d5/d6/d7
l24 equ 28
l28 equ 28
rts
opt o+,ol+,op+,oc+,ot+,oj+,ob+,om+
public _text_setsizes
cnop 0,4
_text_setsizes
sub.w #20,a7
movem.l l41,-(a7)
cmp.w #2,(26+l43,a7)
bge l28
l27
movem.l l45,-(a7)
cmp.w #2,(26+l47,a7)
bge l32
l31
moveq #0,d2
moveq #0,d5
moveq #0,d6
move.w (26+l43,a7),d0
move.w (26+l47,a7),d0
ext.l d0
moveq #46,d1
move.l d2,-(a7)
@ -248,60 +299,60 @@ l27
move.w d0,d6
move.w d6,d0
sub.w #0,d0
beq l30
beq l34
subq.w #1,d0
beq l31
beq l35
subq.w #1,d0
beq l32
beq l36
subq.w #1,d0
beq l33
bra l34
l30
beq l37
bra l38
l34
move.w #80,(24,a2)
move.w #60,(26,a2)
bra l29
l31
bra l33
l35
move.w #100,(24,a2)
move.w #75,(26,a2)
bra l29
l32
bra l33
l36
move.w #128,(24,a2)
move.w #96,(26,a2)
bra l29
l33
bra l33
l37
move.w #80,(24,a2)
move.w #50,(26,a2)
bra l29
l34
l29
bra l33
l38
l33
tst.w d5
beq l36
beq l40
lea (24,a2),a0
move.w (a0),d0
ext.l d0
move.l d0,d1
bge l44
bge l48
addq.l #1,d1
l44:
l48:
asr.l #1,d1
move.w d1,(a0)
lea (26,a2),a0
move.w (a0),d0
ext.l d0
move.l d0,d1
bge l45
bge l49
addq.l #1,d1
l45:
l49:
asr.l #1,d1
move.w d1,(a0)
l36
l40
move.w (26,a2),(30,a2)
move.w (24,a2),(28,a2)
move.w d2,d0
and.b #1,d0
and.w #255,d0
and.l #65535,d0
beq l38
beq l42
move.w d2,d0
and.w #16128,d0
and.l #65535,d0
@ -311,52 +362,52 @@ l36
and.l d2,d0
moveq #16,d1
lsr.l d1,d0
move.w d0,(14+l43,a7)
move.w d0,(14+l47,a7)
move.w d7,d0
ext.l d0
tst.l d0
bge l46
bge l50
addq.l #3,d0
l46:
l50:
asr.l #2,d0
move.w d0,d3
move.w (14+l43,a7),d0
move.w (14+l47,a7),d0
ext.l d0
tst.l d0
bge l47
bge l51
addq.l #3,d0
l47:
l51:
asr.l #2,d0
move.w d0,d4
tst.w d5
beq l40
beq l44
move.w d3,d0
ext.l d0
move.l d0,d1
bge l48
bge l52
addq.l #1,d1
l48:
l52:
asr.l #1,d1
move.w d1,d3
move.w d4,d0
ext.l d0
move.l d0,d1
bge l49
bge l53
addq.l #1,d1
l49:
l53:
asr.l #1,d1
move.w d1,d4
l40
l44
lea (28,a2),a0
sub.w d3,(a0)
lea (30,a2),a0
sub.w d4,(a0)
l38
l28
l25
l41 reg a2/d2/d3/d4/d5/d6/d7
l42
l32
l29
l45 reg a2/d2/d3/d4/d5/d6/d7
movem.l (a7)+,a2/d2/d3/d4/d5/d6/d7
l43 equ 28
l47 equ 28
add.w #20,a7
rts
; stacksize=56
@ -364,13 +415,13 @@ l43 equ 28
public _text_set_color
cnop 0,4
_text_set_color
movem.l l54,-(a7)
move.w (14+l56,a7),d4
move.w (10+l56,a7),d3
move.w (6+l56,a7),d2
movem.l l58,-(a7)
move.w (14+l60,a7),d4
move.w (10+l60,a7),d3
move.w (6+l60,a7),d2
cmp.w #2,d2
bge l53
l52
bge l57
l56
move.w d2,d0
ext.l d0
moveq #46,d1
@ -398,22 +449,22 @@ l52
and.l #15,d1
or.l d1,d0
move.b d0,(44,a1)
l53
l50
l54 reg d2/d3/d4/d5/d6
l57
l54
l58 reg d2/d3/d4/d5/d6
movem.l (a7)+,d2/d3/d4/d5/d6
l56 equ 20
l60 equ 20
rts
; stacksize=20
opt o+,ol+,op+,oc+,ot+,oj+,ob+,om+
public _text_clear
cnop 0,4
_text_clear
movem.l l65,-(a7)
move.w (6+l67,a7),d3
movem.l l69,-(a7)
move.w (6+l71,a7),d3
cmp.w #2,d3
bge l60
l59
bge l64
l63
move.w d3,d0
ext.l d0
moveq #46,d1
@ -432,15 +483,15 @@ l59
add.l d0,a0
move.l a0,a2
moveq #0,d2
bra l62
l61
bra l66
l65
move.l (4,a2),a0
move.b #32,(0,a0,d2.l)
move.l (8,a2),a1
move.b (44,a2),(0,a1,d2.l)
l64
l68
addq.l #1,d2
l62
l66
move.w (24,a2),d0
ext.l d0
move.w (26,a2),d1
@ -457,13 +508,13 @@ l62
clr.w d4
add.l d4,d0
cmp.l d2,d0
bgt l61
l63
l60
l57
l65 reg a2/d2/d3/d4/d5
bgt l65
l67
l64
l61
l69 reg a2/d2/d3/d4/d5
movem.l (a7)+,a2/d2/d3/d4/d5
l67 equ 20
l71 equ 20
rts
; stacksize=20
opt o+,ol+,op+,oc+,ot+,oj+,ob+,om+
@ -471,11 +522,11 @@ l67 equ 20
cnop 0,4
_text_scroll
sub.w #28,a7
movem.l l84,-(a7)
cmp.w #2,(34+l86,a7)
bge l71
l70
move.w (34+l86,a7),d0
movem.l l88,-(a7)
cmp.w #2,(34+l90,a7)
bge l75
l74
move.w (34+l90,a7),d0
ext.l d0
moveq #46,d1
move.l d2,-(a7)
@ -497,8 +548,8 @@ l70
add.l d0,a0
move.l a0,a6
moveq #0,d3
bra l73
l72
bra l77
l76
move.w d3,d0
muls.w (24,a6),d0
move.w d0,d4
@ -515,8 +566,8 @@ l72
move.l (8,a6),a5
add.w d5,a5
moveq #0,d2
bra l77
l76
bra l81
l80
move.l a4,a0
addq.l #2,a4
move.l a2,a1
@ -527,56 +578,56 @@ l76
move.l a3,a1
addq.l #2,a3
move.w (a0),(a1)
l79
addq.w #2,d2
l77
cmp.w (24,a6),d2
blt l76
l78
l75
addq.w #1,d3
l73
move.w d3,d0
ext.l d0
move.w (30,a6),d1
ext.l d1
subq.l #1,d1
cmp.l d0,d1
bgt l72
l74
move.w (30,a6),d0
subq.w #1,d0
muls.w (24,a6),d0
move.w d0,d7
move.l (4,a6),a1
add.w d7,a1
move.l a1,(10+l86,a7)
move.l (8,a6),a1
add.w d7,a1
move.l a1,(14+l86,a7)
move.b (44,a6),d6
moveq #0,d2
bra l81
l80
move.l (10+l86,a7),a0
addq.l #2,(10+l86,a7)
move.w #32,(a0)
move.l (14+l86,a7),a0
addq.l #2,(14+l86,a7)
moveq #0,d0
move.b d6,d0
move.w d0,(a0)
l83
addq.w #2,d2
l81
cmp.w (24,a6),d2
blt l80
l82
l71
l68
l84 reg a2/a3/a4/a5/a6/d2/d3/d4/d5/d6/d7
l79
addq.w #1,d3
l77
move.w d3,d0
ext.l d0
move.w (30,a6),d1
ext.l d1
subq.l #1,d1
cmp.l d0,d1
bgt l76
l78
move.w (30,a6),d0
subq.w #1,d0
muls.w (24,a6),d0
move.w d0,d7
move.l (4,a6),a1
add.w d7,a1
move.l a1,(10+l90,a7)
move.l (8,a6),a1
add.w d7,a1
move.l a1,(14+l90,a7)
move.b (44,a6),d6
moveq #0,d2
bra l85
l84
move.l (10+l90,a7),a0
addq.l #2,(10+l90,a7)
move.w #32,(a0)
move.l (14+l90,a7),a0
addq.l #2,(14+l90,a7)
moveq #0,d0
move.b d6,d0
move.w d0,(a0)
l87
addq.w #2,d2
l85
cmp.w (24,a6),d2
blt l84
l86
l75
l72
l88 reg a2/a3/a4/a5/a6/d2/d3/d4/d5/d6/d7
movem.l (a7)+,a2/a3/a4/a5/a6/d2/d3/d4/d5/d6/d7
l86 equ 44
l90 equ 44
add.w #28,a7
rts
; stacksize=80
@ -584,12 +635,12 @@ l86 equ 44
public _text_put_raw
cnop 0,4
_text_put_raw
movem.l l95,-(a7)
move.b (11+l97,a7),d3
move.w (6+l97,a7),d2
movem.l l99,-(a7)
move.b (11+l101,a7),d3
move.w (6+l101,a7),d2
cmp.w #2,d2
bge l90
l89
bge l94
l93
move.w d2,d0
ext.l d0
moveq #46,d1
@ -609,11 +660,11 @@ l89
move.l a0,a3
move.b d3,d0
sub.b #10,d0
beq l92
beq l96
subq.b #3,d0
beq l93
bra l94
l92
beq l97
bra l98
l96
move.w (34,a3),d0
ext.l d0
addq.l #1,d0
@ -624,10 +675,10 @@ l92
move.l d0,-(a7)
jsr _text_set_xy
add.w #12,a7
bra l91
l93
bra l91
l94
bra l95
l97
bra l95
l98
lea (36,a3),a0
move.l (a0),a1
addq.l #1,(a0)
@ -648,26 +699,96 @@ l94
move.l d0,-(a7)
jsr _text_set_xy
add.w #12,a7
l95
l94
l91
l90
l87
l95 reg a2/a3/d2/d3/d4/d5
l99 reg a2/a3/d2/d3/d4/d5
movem.l (a7)+,a2/a3/d2/d3/d4/d5
l97 equ 24
l101 equ 24
rts
opt o+,ol+,op+,oc+,ot+,oj+,ob+,om+
public _text_put_ansi
cnop 0,4
_text_put_ansi
movem.l l102,-(a7)
move.w (6+l104,a7),d0
l100
l101
l98
l102 reg
l104 equ 0
movem.l l106,-(a7)
move.w (6+l108,a7),d0
l104
l105
l102
l106 reg
l108 equ 0
rts
; stacksize=0
public _fg_color_lut
cnop 0,4
_fg_color_lut
dc.w 0
dc.w 65280
dc.w 0
dc.w 65408
dc.w 32768
dc.w 65280
dc.w 128
dc.w 65280
dc.w 32768
dc.w 65408
dc.w 32896
dc.w 65280
dc.w 128
dc.w 65408
dc.w 32896
dc.w 65408
dc.w 17664
dc.w 65535
dc.w 17683
dc.w 65419
dc.w 0
dc.w 65312
dc.w 8192
dc.w 65280
dc.w 32
dc.w 65280
dc.w 8224
dc.w 65312
dc.w 16448
dc.w 65344
dc.w 65535
dc.w 65535
public _bg_color_lut
cnop 0,4
_bg_color_lut
dc.w 0
dc.w 65280
dc.w 0
dc.w 65408
dc.w 32768
dc.w 65280
dc.w 128
dc.w 65280
dc.w 8192
dc.w 65312
dc.w 8224
dc.w 65280
dc.w 32
dc.w 65312
dc.w 8224
dc.w 65312
dc.w 26910
dc.w 65490
dc.w 17683
dc.w 65419
dc.w 0
dc.w 65312
dc.w 8192
dc.w 65280
dc.w 32
dc.w 65280
dc.w 4112
dc.w 65296
dc.w 16448
dc.w 65344
dc.w 65535
dc.w 65535
section "BSS",bss
cnop 0,4
l1

View file

@ -33,14 +33,63 @@ typedef struct s_text_channel {
static t_text_channel text_channel[MAX_TEXT_CHANNELS];
// 0xHHLL, 0xHHLL
// 0xGGBB, 0xAARR
const unsigned short fg_color_lut [32] = {
0x0000, 0xFF00, // Black (transparent)
0x0000, 0xFF80, // Mid-Tone Red
0x8000, 0xFF00, // Mid-Tone Green
0x0080, 0xFF00, // Mid-Tone Blue
0x8000, 0xFF80, // Mid-Tone Yellow
0x8080, 0xFF00, // Mid-Tone Cian
0x0080, 0xFF80, // Mid-Tone Purple
0x8080, 0xFF80, // 50% Grey
0x4500, 0xFFFF, // Orange? Brown?
0x4513, 0xFF8B, // Orange? Brown?
0x0000, 0xFF20, // 12.5% Red
0x2000, 0xFF00, // 12.5% Green
0x0020, 0xFF00, // 12.5% Blue
0x2020, 0xFF20, // 12.5% Grey
0x4040, 0xFF40, // 25% Grey
0xFFFF, 0xFFFF // 100% Grey = White
};
const unsigned short bg_color_lut [32] = {
0x0000, 0xFF00, // Black (transparent)
0x0000, 0xFF80, // Mid-Tone Red
0x8000, 0xFF00, // Mid-Tone Green
0x0080, 0xFF00, // Mid-Tone Blue
0x2000, 0xFF20, // 12.5% Yellow
0x2020, 0xFF00, // 12.5% Cian
0x0020, 0xFF20, // 12.5% Purple
0x2020, 0xFF20, // 12.5% Grey
0x691E, 0xFFD2, // Orange? Brown?
0x4513, 0xFF8B, // Orange? Brown?
0x0000, 0xFF20, // 12.5% Red
0x2000, 0xFF00, // 12.5% Green
0x0020, 0xFF00, // 12.5% Blue
0x1010, 0xFF10, // 6.25% Grey
0x4040, 0xFF40, // 25% Grey
0xFFFF, 0xFFFF // 100% Grey = White
};
/*
* Initialize the text screen driver
*/
int text_init() {
int x;
int i, x;
p_text_channel chan_a = &text_channel[0];
p_text_channel chan_b = &text_channel[1];
// Init CLUT for the Color Memory
for (i = 0; i<32; i++) {
FG_CLUT_A[i] = fg_color_lut[i];
FG_CLUT_B[i] = fg_color_lut[i];
BG_CLUT_A[i] = bg_color_lut[i];
BG_CLUT_B[i] = bg_color_lut[i];
}
/* TODO: initialize everything... only do a screen if it's present */
chan_a->master_control = MasterControlReg_A;
@ -50,9 +99,12 @@ int text_init() {
chan_a->cursor_position = CursorControlReg_H_A;
chan_a->border_control = BorderControlReg_L_A;
*chan_a->master_control = VKY3_MCR_TEXT_EN; /* Set to text only mode: 640x480 */
*chan_a->master_control = 1; /* Set to text only mode: 640x480 */
// *chan_a->border_control = 0; /* Set to no border */
chan_a->border_control[0] = 0x00102001; // Enable
chan_a->border_control[1] = 0x00000040; //Dark Blue
text_setsizes(0);
text_set_color(0, 15, 0);
text_clear(0);
@ -65,8 +117,10 @@ int text_init() {
chan_b->cursor_position = CursorControlReg_H_B;
chan_b->border_control = BorderControlReg_L_B;
*chan_b->master_control = VKY3_MCR_TEXT_EN; /* Set to text only mode: 640x480 */
// *chan_b->border_control = 0; /* Set to no border */
*chan_b->master_control = 1; /* Set to text only mode: 640x480 */
chan_b->border_control[0] = 0x00102000; // Enable
chan_b->border_control[1] = 0x00400000; //Dark Red
text_setsizes(1);
text_set_color(1, 15, 0);

View file

@ -129,7 +129,7 @@ _uart_init
addq.w #8,a7
move.l a2,d0
beq l29
move.l #12,-(a7)
move.l #1,-(a7)
move.w d2,d0
ext.l d0
move.l d0,-(a7)

View file

@ -66,7 +66,7 @@ void uart_init(short uart) {
DEBUG("uart_init");
if (uart_base) {
/* Default to 9600 bps */
uart_setbps(uart, UART_9600);
uart_setbps(uart, UART_115200);
/* Set: no parity, 1 stop bit, 8 data bits */
uart_setlcr(uart, LCR_PARITY_NONE | LCR_STOPBIT_1 | LCR_DATABITS_8);

View file

@ -15,6 +15,7 @@
/* Definitions of physical drive number for each drive */
#define DEV_SDC 0 /* Example: Map Ramdisk to physical drive 0 */
#define DEV_HDC 2
/*-----------------------------------------------------------------------*/

View file

@ -166,12 +166,12 @@
/ Drive/Volume Configurations
/---------------------------------------------------------------------------*/
#define FF_VOLUMES 1
#define FF_VOLUMES 3
/* Number of volumes (logical drives) to be used. (1-10) */
#define FF_STR_VOLUME_ID 0
#define FF_VOLUME_STRS "SDC"
// #define FF_VOLUME_STRS "012"
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each

File diff suppressed because it is too large Load diff

View file

@ -4,6 +4,7 @@
#include <string.h>
#include "sys_general.h"
#include "interrupt.h"
#include "gabe_reg.h"
#include "superio.h"
#include "syscalls.h"
@ -16,6 +17,7 @@
#include "dev/sdc.h"
#include "dev/uart.h"
#include "snd/codec.h"
#include "snd/psg.h"
#include "snd/sid.h"
#include "fatfs/ff.h"
#include "log.h"
@ -80,6 +82,9 @@ void initialize() {
text_init(); // Initialize the text channels
DEBUG("Foenix/MCP starting up...");
/* Initialize the interrupt system */
int_init();
/* Set the power LED to purple */
*RGB_LED_L = 0x00FF;
*RGB_LED_H = 0x00FF;
@ -94,7 +99,7 @@ void initialize() {
init_codec();
/* Initialize the SID chips */
sid_init();
sid_init_all();
/* Play the SID test bong on the Gideon SID implementation */
sid_test_internal();
@ -142,6 +147,9 @@ void initialize() {
} else {
DEBUG("SDC initialized.");
}
/* Enable all interrupts */
int_enable_all();
}
void print(short channel, char * message) {
@ -225,12 +233,12 @@ FILINFO my_file;
FATFS my_fs;
char line[255];
short dos_cmd_dir(short screen) {
short dos_cmd_dir(short screen, char * path) {
FRESULT fres;
TRACE("dos_cmd_dir");
fres = f_mount(&my_fs, "0:", 0);
fres = f_mount(&my_fs, path, 0);
TRACE("f_mount");
if (fres == FR_OK) {
fres = f_opendir(&my_dir, "/");
@ -317,6 +325,36 @@ void uart_send(short uart, char * message) {
}
}
void uart_test_send(short uart) {
while (1) {
uart_send(uart, 'a');
}
}
static long g_sof_counter = 0;
/*
* Interrupt handler for Channel A's Start of Frame
*/
void int_sof_a() {
g_sof_counter++;
long counter_mod = g_sof_counter % 60;
if (counter_mod == 0) {
/* Set the power LED to red */
*RGB_LED_L = 0x00FF;
*RGB_LED_H = 0x0000;
} else if (counter_mod == 30) {
/* Set the power LED to blue */
*RGB_LED_L = 0x0000;
*RGB_LED_H = 0x00FF;
}
/* Acknowledge the interrupt before leaving */
int_ack(SOF_A_INT00);
}
int main(int argc, char * argv[]) {
short result;
@ -325,24 +363,21 @@ int main(int argc, char * argv[]) {
print(CDEV_CONSOLE, "Foenix/MCP\n\nText Channel A\n");
print(CDEV_EVID, "Foenix/MCP\n\nText Channel B\n");
// Try to get the MBR of the HDD
// test_get_mbr(CDEV_EVID, BDEV_HDD);
// uart_test_send(0);
// print(1, "\nSDC directory:\n");
// dos_cmd_dir(1);
/* Register a handler for the SOF interrupt and enable it */
int_register(0x00, int_sof_a);
int_enable(0x00);
// Try the A2560K built in keybaord
// try_mo(1);
// dos_cmd_dir(0, "2:");
// lpt_initialize();
//
// result = lpt_write((p_channel)0, "Hello\n", 5);
// if (result) {
// print(CDEV_CONSOLE, "\nError printing.\n");
// } else {
// print(CDEV_CONSOLE, "\nPrinting success.\n");
// while (1) {
// text_set_xy(0, 40, 0);
// print_hex_16(0, g_sof_counter);
// }
try_mo(0);
DEBUG("Stopping.");
/* Infinite loop... */

File diff suppressed because it is too large Load diff

200
src/interrupt.c Normal file
View file

@ -0,0 +1,200 @@
/*
* Definitions for the interrupt controls
*/
#include "interrupt.h"
#define MAX_HANDLERS 48
static p_int_handler g_int_handler[MAX_HANDLERS];
/*
* Return the group number for the interrupt number
*
* For the m68000 machines, this will just be the high nibble of the number
*/
unsigned short int_group(unsigned short n) {
return ((n >> 4) & 0x0f);
}
/*
* Return the mask bit for the interrupt number
*
* For the m68000 machines, this will just be the bit corresponding to the lower nibble
*/
unsigned short int_mask(unsigned short n) {
return (1 << (n & 0x0f));
}
/*
* Initialize the interrupt registers
*/
void int_init() {
int i;
for (i = 0; i < MAX_HANDLERS; i++) {
g_int_handler[i] = 0;
}
// At Reset, all of those already have those values
// the Pol are @ 0x0000 and normally pending are reseted, but it is not impossible that some might be triggered during init
*EDGE_GRP0 = 0xFFFF;
*EDGE_GRP1 = 0xFFFF;
*EDGE_GRP2 = 0xFFFF;
*MASK_GRP0 = 0xFFFF;
*MASK_GRP1 = 0xFFFF;
*MASK_GRP2 = 0xFFFF;
}
/*
* Disable an interrupt by masking it
*
* Interrupt number is made by the group number and number within the group.
* For instance, the RTC interrupt would be 0x1F and the Channel A SOF interrupt would be 0x00.
*
* Inputs:
* n = the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
*/
void int_disable(unsigned short n) {
/* Find the group (the relevant interrupt mask register) for the interrupt */
unsigned short group = int_group(n);
/* Find the mask for the interrupt */
unsigned short mask = int_mask(n);
/* Set the mask bit for the interrupt in the correct MASK register */
MASK_GRP0[group] |= mask;
}
/*
* Enable an interrupt
*
* Interrupt number is made by the group number and number within the group.
* For instance, the RTC interrupt would be 0x1F and the Channel A SOF interrupt would be 0x00.
* And interrupt number of 0xFF specifies that all interrupts should be disabled.
*
* Inputs:
* n = the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
*/
void int_enable(unsigned short n) {
/* Find the group (the relevant interrupt mask register) for the interrupt */
unsigned short group = int_group(n);
/* Find the mask for the interrupt */
unsigned short mask = int_mask(n);
/* Clear the mask bit for the interrupt in the correct MASK register */
MASK_GRP0[group] &= ~mask;
}
/*
* Register a handler for a given interrupt.
*
* Inputs:
* n = the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
* handler = pointer to the interrupt handler to register
*
* Returns:
* the pointer to the previous interrupt handler
*/
p_int_handler int_register(unsigned short n, p_int_handler handler) {
if (n < MAX_HANDLERS) {
p_int_handler old_handler = g_int_handler[n];
g_int_handler[n] = handler;
return old_handler;
} else {
return 0;
}
}
/*
* Return true (non-zero) if an interrupt is pending for the given interrupt
*
* Inputs:
* n = the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
*
* Returns:
* non-zero if interrupt n is pending, 0 if not
*/
short int_pending(unsigned short n) {
/* Find the group (the relevant interrupt mask register) for the interrupt */
unsigned short group = int_group(n);
/* Find the mask for the interrupt */
unsigned short mask = int_mask(n);
/* Set the mask bit for the interrupt in the correct MASK register */
return (PENDING_GRP0[group] & mask);
}
/*
* Acknowledge an interrupt (clear out its pending flag)
*
* Inputs:
* n = the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
*/
void int_ack(unsigned short n) {
/* Find the group (the relevant interrupt mask register) for the interrupt */
unsigned short group = int_group(n);
/* Find the mask for the interrupt */
unsigned short mask = int_mask(n);
/* Set the mask bit for the interrupt in the correct MASK register */
PENDING_GRP0[group] |= mask;
}
/*
* Interrupt dispatcher for Vicky Channel A interrupts (0 - 7)
*/
void int_vicky_channel_a() {
unsigned short n;
unsigned short mask = 1;
unsigned short pending = *PENDING_GRP0 & 0xff;
if (pending != 0) {
for (n = 0; n < 8; n++) {
if (pending & mask) {
p_int_handler handler = g_int_handler[n];
if (handler) {
/* If we got a handler, call it */
handler();
/* And acknowledge the interrupt */
int_ack(n);
}
}
// Compute the next mask
mask = mask << 1;
}
}
}
/*
* Interrupt dispatcher for Vicky Channel B interrupts (8 - 15)
*/
void int_vicky_channel_b() {
unsigned short n;
unsigned short mask = 1;
unsigned short pending = (*PENDING_GRP0 >> 8) & 0xff;
if (pending != 0) {
for (n = 8; n < 16; n++) {
if (pending & mask) {
p_int_handler handler = g_int_handler[n];
if (handler) {
/* If we got a handler, call it */
handler();
/* And acknowledge the interrupt */
int_ack(n);
}
}
// Compute the next mask
mask = mask << 1;
}
}
}

176
src/interrupt.h Normal file
View file

@ -0,0 +1,176 @@
/*
* Declarations for the interrupt system
*/
#ifndef __INTERRUPT_H
#define __INTERRUPT_H
/* Type declaration for an interrupt handler */
typedef void (*p_int_handler)();
/*
* Interrupt control registers
*/
#define PENDING_GRP0 ((volatile unsigned short *)0x00C00100)
#define PENDING_GRP1 ((volatile unsigned short *)0x00C00102)
#define PENDING_GRP2 ((volatile unsigned short *)0x00C00104)
#define POL_GRP0 ((volatile unsigned short *)0x00C00108)
#define POL_GRP1 ((volatile unsigned short *)0x00C0010A)
#define POL_GRP2 ((volatile unsigned short *)0x00C0010C)
#define EDGE_GRP0 ((volatile unsigned short *)0x00C00110)
#define EDGE_GRP1 ((volatile unsigned short *)0x00C00112)
#define EDGE_GRP2 ((volatile unsigned short *)0x00C00114)
#define MASK_GRP0 ((volatile unsigned short *)0x00C00118)
#define MASK_GRP1 ((volatile unsigned short *)0x00C0011A)
#define MASK_GRP2 ((volatile unsigned short *)0x00C0011C)
/*
* For A2560K: $00C00100..$00C001FF - Interrupt Controllers
*/
/*
* Interrupt Reg0 - 16bits - GROUP0 (GRP0)
*/
/* Video Related Interrupts - Text Channel */
#define SOF_A_INT00 0x0001 /* Interrupt 0x00: Start of Frame Channel A */
#define SOL_A_INT01 0x0002 /* Interrupt 0x01: Start of Line Channel A */
#define VICKY_A_INT02 0x0004 /* Interrupt 0x02: Channel A */
#define VICKY_A_INT03 0x0008 /* Interrupt 0x03: Channel A */
#define VICKY_A_INT04 0x0010 /* Interrupt 0x04: Channel A */
#define VICKY_A_INT05 0x0020 /* Interrupt 0x05: Channel A */
#define RESERVED0 0x0040
#define VICKY_A_DAC_HP07 0x0080 /* Interrupt 0x06: */
/* Video Related Interrupts - Graphic Channel */
#define SOF_B_INT08 0x0100 /* Interrupt 0x08: Start of Line Channel B */
#define SOL_B_INT09 0x0200 /* Interrupt 0x09: Start of Line Channel B */
#define VICKY_B_INT0A 0x0400 /* Interrupt 0x0A: Channel B */
#define VICKY_B_INT0B 0x0800 /* Interrupt 0x0B: Channel B */
#define VICKY_B_INT0C 0x1000 /* Interrupt 0x0C: Channel B */
#define VICKY_B_INT0D 0x2000 /* Interrupt 0x0D: Channel B */
#define RESERVED1 0x4000
#define VICKY_B_DAC_HP_INT0F 0x8000 /* Interrupt 0x0F: Channel B */
/*
* Interrupt Reg1 - 16bits GROUP1 (GRP1)
*/
/* SuperIO */
#define SPIO_KBD_INT10 0x0001 // Interrupt 0x10: Super IO Keyboard
#define A2560K_KBD_INT11 0x0002 // Interrupt 0x11: This is the A2560K Internal Keyboard and also the U KBD Interrupt
#define SPIO_MOUSE_INT12 0x0004 // Interrupt 0x12: Super IO Mouse
#define SPIO_COM1_INT13 0x0008 // Interrupt 0x13: Super IO COM1
#define SPIO_COM2_INT14 0x0010 // Interrupt 0x14: Super IO COM2
#define SPIO_LPT1_INT15 0x0020 // Interrupt 0x15: Super IO LPT1
#define SPIO_FDC_INT16 0x0040 // Interrupt 0x16: Super IO Floppy Disk Controller
#define SPIO_MPU401_INT17 0x0080 // Interrupt 0x17: Super IO MPU401 (MIDI)
/* Timers */
#define TIMER0_INT18 0x0100 // Interrupt 0x18: Timer0 Clocked with CPU Clock
#define TIMER1_INT19 0x0200 // Interrupt 0x19: Timer1 Clocked with CPU Clock
#define TIMER2_INT1A 0x0400 // Interrupt 0x1A: Timer2 Clocked with CPU Clock
#define TIMER3_INT1B 0x0800 // Interrupt 0x1B: Timer3 Clocked with SOF Channel A
#define TIMER4_INT1C 0x1000 // Interrupt 0x1C: Timer4 Clocked with SOF Channel B
#define RESERVED3 0x2000 // No interrupt - Reserved
#define RESERVED4 0x4000 // No Interrupt - Reserved
#define RTC_INT1F 0x8000 // Interrupt 0x1F: RTC
/*
* Interrupt Reg2 - 16bits GROUP2 (GRP2)
*/
/* Mostly Music / Sound Related Interrupts */
#define IDE_INT20 0x0001 // IDE HDD Generated Interrupt
#define SDCARD_INS_INT21 0x0002 // SDCard Insert Interrupt
#define SD_INT22 0x0004 // SDCard Controller Interrupt
#define INT_OPM_INT23 0x0008 // Internal OPM Interrupt
#define EXT_OPN2_INT24 0x0010 // External OPN2 Interrupt
#define EXT_OPL3_INT25 0x0020 // External OPL3 Interrupt
#define RESERVED5 0x0040 // No interrupt - Reserved
#define RESERVED6 0x0080 // No interrupt - Reserved
#define BEATRIX_INT28 0x0100 // Beatrix Interrupt 0
#define BEATRIX_INT29 0x0200 // Beatrix Interrupt 1
#define BEATRIX_INT2A 0x0400 // Beatrix Interrupt 2
#define BEATRIX_INT2B 0x0800 // Beatrix Interrupt 3
#define RESERVED7 0x1000 // No Interrupt - Reserved
#define DAC1_PB_INT2D 0x2000 // DAC1 Playback Done Interrupt (48K)
#define RESERVED8 0x4000 // No Interrupt - Reserved
#define DAC0_PB_INT2F 0x8000 // DAC0 Playback Done Interrupt (44.1K)
/*
* Initialize the interrupt registers
*/
extern void int_init();
/*
* Enable all interrupts
*
* NOTE: this is actually provided in the low level assembly
*/
extern void int_enable_all();
/*
* Disable all interrupts
*
* NOTE: this is actually provided in the low level assembly
*/
extern void int_disable_all();
/*
* Disable an interrupt by masking it
*
* Inputs:
* n = the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
*/
extern void int_disable(unsigned short n);
/*
* Enable an interrupt
*
* Inputs:
* n = the number of the interrupt
*/
extern void int_enable(unsigned short n);
/*
* Register a handler for a given interrupt.
*
* Inputs:
* n = the number of the interrupt
* handler = pointer to the interrupt handler to register
*
* Returns:
* the pointer to the previous interrupt handler
*/
extern p_int_handler int_register(unsigned short n, p_int_handler handler);
/*
* Return true (non-zero) if an interrupt is pending for the given interrupt
*
* Inputs:
* n = the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
*
* Returns:
* non-zero if interrupt n is pending, 0 if not
*/
extern short int_pending(unsigned short n);
/*
* Acknowledge an interrupt (clear out its pending flag)
*
* Inputs:
* n = the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
*/
extern void int_ack(unsigned short n);
#endif

View file

@ -1,44 +0,0 @@
idnt "log.c"
opt o+,ol+,op+,oc+,ot+,oj+,ob+,om+
section "CODE",code
public _DEBUG
cnop 0,4
_DEBUG
movem.l l7,-(a7)
move.l (4+l9,a7),a2
moveq #0,d2
bra l4
l3
lea (a2,d2.l),a0
move.b (a0),d0
ext.w d0
ext.l d0
move.l d0,-(a7)
move.l #0,-(a7)
jsr _text_put_raw
addq.w #8,a7
l6
addq.l #1,d2
l4
move.l a2,a0
inline
move.l a0,d0
.l1
tst.b (a0)+
bne .l1
sub.l a0,d0
not.l d0
einline
cmp.l d2,d0
bhi l3
l5
move.l #10,-(a7)
move.l #0,-(a7)
jsr _text_put_raw
addq.w #8,a7
l1
l7 reg a2/d2
movem.l (a7)+,a2/d2
l9 equ 8
rts
public _text_put_raw

View file

@ -1,6 +1,8 @@
xref ___main
xdef _syscall
xdef ___exit
xdef _int_enable_all
xdef _int_disable_all
section "vectors",code
@ -29,8 +31,8 @@
dc.l not_impl ; 22 - Reserved
dc.l not_impl ; 23 - Reserved
dc.l not_impl ; 24 - Spurious Interrupt
dc.l not_impl ; 25 - Level 1 Interrupt Autovector
dc.l not_impl ; 26 - Level 2 Interrupt Autovector
dc.l autovec1 ; 25 - Level 1 Interrupt Autovector
dc.l autovec2 ; 26 - Level 2 Interrupt Autovector
dc.l not_impl ; 27 - Level 3 Interrupt Autovector
dc.l not_impl ; 28 - Level 4 Interrupt Autovector
dc.l not_impl ; 29 - Level 5 Interrupt Autovector
@ -52,12 +54,14 @@
dc.l h_trap_13 ; 45 - TRAP #13
dc.l not_impl ; 46 - TRAP #14
dc.l not_impl ; 47 - TRAP #15
; TODO: make room for reserved and User Interrupt Vectors
code
coldboot: lea ___STACK,sp
bsr _int_disable_all
lea ___BSSSTART,a0
move.l #___BSSSIZE,d0
beq callmain
@ -77,11 +81,39 @@ callmain: jsr ___main ; call __main to transfer to the C code
___exit:
bra ___exit
;
; Autovector #1: Used by VICKY III Channel B interrupts
;
autovec1: movem.l d0-d7/a0-a6,-(a7)
jsr _int_vicky_channel_b ; Call the dispatcher for Channel B interrupts
movem.l (a7)+,d0-d7/a0-a6
rte
;
; Autovector #1: Used by VICKY III Channel A interrupts
;
autovec2: movem.l d0-d7/a0-a6,-(a7)
jsr _int_vicky_channel_a ; Call the dispatcher for Channel A interrupts
movem.l (a7)+,d0-d7/a0-a6
rte
;
; Unimplemented Exception Handler -- just return
;
not_impl: rte
;
; Enable all interrupts
;
_int_enable_all: andi.w #$F8FF,SR
rts
;
; Disable all interrupts
;
_int_disable_all: ori.w #$0700,SR
rts
;
; Function to make a system call based on the number of the system function:
; int32_t syscall(int32_t number, int32_t p0, int32_t p1, int32_t p2, int32_t p3, int32_t p4, int32_t p5)
@ -105,7 +137,7 @@ _syscall:
;
; TRAP#13 handler... transfer control to the C dispatcher
;
h_trap_13:
h_trap_13:
move.l d7,-(sp) ; Push the parameters to the stack for the C call
move.l d6,-(sp)
move.l d5,-(sp)

File diff suppressed because it is too large Load diff

View file

@ -1,125 +0,0 @@
idnt "ring_buffer.c"
opt o+,ol+,op+,oc+,ot+,oj+,ob+,om+
section "CODE",code
public _rb_word_init
cnop 0,4
_rb_word_init
movem.l l3,-(a7)
move.l (4+l5,a7),a1
move.w #0,(256,a1)
move.w #0,(258,a1)
l1
l3 reg
l5 equ 0
rts
; stacksize=0
opt o+,ol+,op+,oc+,ot+,oj+,ob+,om+
public _rb_word_full
cnop 0,4
_rb_word_full
movem.l l11,-(a7)
move.l (4+l13,a7),a1
moveq #0,d0
move.w (256,a1),d0
addq.l #1,d0
moveq #0,d1
move.w (258,a1),d1
cmp.l d0,d1
beq l8
l10
moveq #0,d0
bra l9
l8
moveq #1,d0
l9
l6
l11 reg
l13 equ 0
rts
; stacksize=0
opt o+,ol+,op+,oc+,ot+,oj+,ob+,om+
public _rb_word_empty
cnop 0,4
_rb_word_empty
movem.l l19,-(a7)
move.l (4+l21,a7),a2
move.w (256,a2),d0
cmp.w (258,a2),d0
beq l16
l18
moveq #0,d0
bra l17
l16
moveq #1,d0
l17
l14
l19 reg a2
movem.l (a7)+,a2
l21 equ 4
rts
; stacksize=4
opt o+,ol+,op+,oc+,ot+,oj+,ob+,om+
public _rb_word_put
cnop 0,4
_rb_word_put
movem.l l28,-(a7)
move.w (10+l30,a7),d2
move.l (4+l30,a7),a2
move.l a2,-(a7)
jsr _rb_word_full
addq.w #4,a7
tst.w d0
bne l25
l24
lea (256,a2),a0
move.w (a0),d0
addq.w #1,(a0)
and.l #65535,d0
lsl.l #1,d0
move.w d2,(0,a2,d0.l)
cmp.w #128,(256,a2)
bcs l27
l26
move.w #0,(256,a2)
l27
l25
l22
l28 reg a2/d2
movem.l (a7)+,a2/d2
l30 equ 8
rts
; stacksize=16
opt o+,ol+,op+,oc+,ot+,oj+,ob+,om+
public _rb_word_get
cnop 0,4
_rb_word_get
movem.l l38,-(a7)
move.l (4+l40,a7),a2
move.l a2,-(a7)
jsr _rb_word_empty
addq.w #4,a7
tst.w d0
bne l34
l33
lea (258,a2),a0
move.w (a0),d0
addq.w #1,(a0)
and.l #65535,d0
lsl.l #1,d0
move.w (0,a2,d0.l),d2
cmp.w #128,(258,a2)
bcs l36
l35
move.w #0,(258,a2)
l36
move.w d2,d0
bra l31
l34
moveq #0,d0
l37
l31
l38 reg a2/d2
movem.l (a7)+,a2/d2
l40 equ 8
rts
; stacksize=20