source: avrstuff/CPC stuff/cpc_serial_2313/code/main.asm@ 53d1ddc

main
Last change on this file since 53d1ddc was 53d1ddc, checked in by Adrien Destugues <pulkomandy@…>, 14 years ago

Now it is possible to assemble the code (with AVRA)

git-svn-id: svn://pulkomandy.tk/avrstuff@27 c6672c3c-f6b6-47f9-9001-1fd6b12fecbe

  • Property mode set to 100644
File size: 3.0 KB
Line 
1; ---------------------------------------------------------------
2; Copyright 2010, Adrien Destugues <pulkomandy@pulkomandy.ath.cx>
3; Distributed under the terms of the MIT Licence
4.INCLUDE "2313def.inc"
5
6; Firmware for µSerial expansion board
7
8.EQU ALL_OUT = 255
9.EQU ALL_IN = 0
10
11.EQU DATADIR = DDRB
12.EQU DATAOUT = PORTB
13.EQU DATAIN = PINB
14
15.EQU CTRLIN = PIND
16.EQU A0 = PIND4
17
18.EQU curregbak = SRAM_START
19
20.CSEG
21; Vectors
22; reset
23 RJMP init
24; int0
25 RJMP cpc_write
26; int1
27 RJMP cpc_read
28; ...
29
30; Interrupt vectors for external INT pins (read and write).
31; we have to react very quick.
32; A read operation for the CPC lasts 3 clock cycles at 4MHz, that's 15
33; AVR cycles. But the interrupt latency is as follow :
34; Lowlevel detection ; 2 cycles
35; End of running instruction ; up to 2 cycles
36; Save PC ; 4 cycles
37;Vector RJMP ; 2 cycles
38 ; TOTAL => 10 cycles
39
40; --- READ INTERRUPT ---
41cpc_read:
42; That means we only have 5 cycles left to output the value on the BUS!
43; We have no time to do anything, so we assume that X is already pointing at
44; the right place and we just OUT it to the data port. We have no time for
45; PUSHing and loading it, anyway.
46
47; Note you can read from either port and get the same result. Two reasons to
48; that : you can already access all the registers and part of the SRAM,
49; and there's no time to do something more clever.
50
51; There is no time to push/pop regs, so we just use X as is. R27 is part of X.
52
53; We assume X (R26:R27) points to the current reg
54; So we can load it and react fast enough to the interrupt
55 LDI R16,ALL_OUT ; 1 ; peut être économisé si on sacrifie un reg
56 OUT DATADIR,R0 ; 1
57 LD R27,X ; 2 cycles ; peut être économisé si un reg. contient
58 ; déjà la valeur à envoyer
59 ; (mais qui l'update ?)
60 OUT DATAOUT, R27 ; 1 cycle
61
62; Here data is sent, the CPC read operation is handled.
63; We now wait for the end of the read cycle.
64; This is not the end of the time-constrained nightmare, however :
65; In the worst case, the CPC can do another OUT or IN right after,
66; so we don't have an infinite number of cycles to handle the interrupt.
67; it is much more relaxed, as we have 12 CPC cycles = 60 AVR cycles free.
68
69; Restore R27
70 LDI R27,curregbak
71 LD R27,X
72
73; release the bus
74 LDI R16,ALL_IN
75 OUT DATADIR, R16
76
77; Restore R27 to selected reg. (we erased it to do the OUT)
78 RETI
79
80
81; --- WRITE INTERRUPT ---
82cpc_write:
83; The timing is a bit less constraining here.
84 PUSH R0
85 IN R0,DATAIN
86; we also need to know A0 state...
87 SBIS CTRLIN,A0
88 ; This was actually a reg select operation!
89 ; Jump to the proper code
90 RJMP regSel
91; We have read the CPC data. End of the heavy-constraint area
92
93; Register write
94 ST X,R0 ; Normal register write
95 RJMP intEnd
96
97regSel:
98 LDI R27,curregbak
99 ST X,R0
100 MOV R27,R0
101
102intEnd:
103 POP R0
104 RETI
105
106
107; --- RESET VECTOR ---
108; Here we perform the hardware initialization.
109; At a bare minimum :
110; * Set up the INT0 and INT1 so the CPC can do the rest of the setup itself
111init:
112 RJMP init
Note: See TracBrowser for help on using the repository browser.