@@ -5,6 +5,25 @@ import { avrInstruction } from '../cpu/instruction';
55
66const FREQ_16MHZ = 16e6 ;
77
8+ // CPU registers
9+ const R16 = 16 ;
10+ const R17 = 17 ;
11+ const SREG = 95 ;
12+
13+ // TWI Registers
14+ const TWBR = 0xb8 ;
15+ const TWSR = 0xb9 ;
16+ const TWDR = 0xbb ;
17+ const TWCR = 0xbc ;
18+
19+ // Register bit names
20+ const TWIE = 1 ;
21+ const TWEN = 4 ;
22+ const TWSTO = 0x10 ;
23+ const TWSTA = 0x20 ;
24+ const TWEA = 0x40 ;
25+ const TWINT = 0x80 ;
26+
827function asmProgram ( source : string ) {
928 const { bytes, errors, lines } = assemble ( source ) ;
1029 if ( errors . length ) {
@@ -16,8 +35,8 @@ function asmProgram(source: string) {
1635function runInstructions ( cpu : CPU , twi : AVRTWI , count : number ) {
1736 for ( let i = 0 ; i < count ; i ++ ) {
1837 if ( cpu . progMem [ cpu . pc ] === 0x9598 ) {
19- console . log ( cpu . data [ 0xbc ] . toString ( 16 ) ) ;
20- console . log ( cpu . data [ 16 ] ) ;
38+ console . log ( cpu . data [ TWCR ] . toString ( 16 ) ) ;
39+ console . log ( cpu . data [ R16 ] ) ;
2140 throw new Error ( 'BREAK instruction encountered' ) ;
2241 }
2342 avrInstruction ( cpu ) ;
@@ -26,43 +45,39 @@ function runInstructions(cpu: CPU, twi: AVRTWI, count: number) {
2645}
2746
2847describe ( 'TWI' , ( ) => {
29- const TWINT = 7 ;
30- const TWSTA = 5 ;
31- const TWEN = 2 ;
32-
3348 it ( 'should correctly calculate the sclFrequency from TWBR' , ( ) => {
3449 const cpu = new CPU ( new Uint16Array ( 1024 ) ) ;
3550 const twi = new AVRTWI ( cpu , twiConfig , FREQ_16MHZ ) ;
36- cpu . writeData ( 0xb8 , 0x48 ) ; // TWBR <- 0x48
37- cpu . writeData ( 0xb9 , 0 ) ; // TWSR <- 0 ( prescaler: 1)
51+ cpu . writeData ( TWBR , 0x48 ) ;
52+ cpu . writeData ( TWSR , 0 ) ; // prescaler: 1
3853 expect ( twi . sclFrequency ) . toEqual ( 100000 ) ;
3954 } ) ;
4055
4156 it ( 'should take the prescaler into consideration when calculating sclFrequency' , ( ) => {
4257 const cpu = new CPU ( new Uint16Array ( 1024 ) ) ;
4358 const twi = new AVRTWI ( cpu , twiConfig , FREQ_16MHZ ) ;
44- cpu . writeData ( 0xb8 , 0x03 ) ; // TWBR <- 0x03
45- cpu . writeData ( 0xb9 , 0x01 ) ; // TWSR <- 1 ( prescaler: 4)
59+ cpu . writeData ( TWBR , 0x03 ) ;
60+ cpu . writeData ( TWSR , 0x01 ) ; // prescaler: 4
4661 expect ( twi . sclFrequency ) . toEqual ( 400000 ) ;
4762 } ) ;
4863
4964 it ( 'should trigger data an interrupt if TWINT is set' , ( ) => {
5065 const cpu = new CPU ( new Uint16Array ( 1024 ) ) ;
5166 const twi = new AVRTWI ( cpu , twiConfig , FREQ_16MHZ ) ;
52- cpu . writeData ( 0xbc , 0x81 ) ; // TWCR <- TWINT | TWIE
53- cpu . data [ 95 ] = 0x80 ; // SREG: I-------
67+ cpu . writeData ( TWCR , TWINT | TWIE ) ;
68+ cpu . data [ SREG ] = 0x80 ; // SREG: I-------
5469 twi . tick ( ) ;
5570 expect ( cpu . pc ) . toEqual ( 0x30 ) ; // 2-wire Serial Interface Vector
5671 expect ( cpu . cycles ) . toEqual ( 2 ) ;
57- expect ( cpu . data [ 0xbc ] & 0x80 ) . toEqual ( 0 ) ; // UCSR0A should clear TWINT
72+ expect ( cpu . data [ TWCR ] & TWINT ) . toEqual ( 0 ) ;
5873 } ) ;
5974
6075 describe ( 'Master mode' , ( ) => {
6176 it ( 'should call the startEvent handler when TWSTA bit is written 1' , ( ) => {
6277 const cpu = new CPU ( new Uint16Array ( 1024 ) ) ;
6378 const twi = new AVRTWI ( cpu , twiConfig , FREQ_16MHZ ) ;
6479 jest . spyOn ( twi . eventHandler , 'start' ) ;
65- cpu . writeData ( 0xbc , ( 1 << TWINT ) | ( 1 << TWSTA ) | ( 1 << TWEN ) ) ;
80+ cpu . writeData ( TWCR , TWINT | TWSTA | TWEN ) ;
6681 twi . tick ( ) ;
6782 expect ( twi . eventHandler . start ) . toHaveBeenCalledWith ( false ) ;
6883 } ) ;
@@ -72,15 +87,15 @@ describe('TWI', () => {
7287 // https://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf
7388 const { program } = asmProgram ( `
7489 ; register addresses
75- _REPLACE TWSR, 0xb9
76- _REPLACE TWDR, 0xbb
77- _REPLACE TWCR, 0xbc
90+ _REPLACE TWSR, ${ TWSR }
91+ _REPLACE TWDR, ${ TWDR }
92+ _REPLACE TWCR, ${ TWCR }
7893
7994 ; TWCR bits
80- _REPLACE TWEN, 0x04
81- _REPLACE TWSTO, 0x10
82- _REPLACE TWSTA, 0x20
83- _REPLACE TWINT, 0x80
95+ _REPLACE TWEN, ${ TWEN }
96+ _REPLACE TWSTO, ${ TWSTO }
97+ _REPLACE TWSTA, ${ TWSTA }
98+ _REPLACE TWINT, ${ TWINT }
8499
85100 ; TWSR states
86101 _REPLACE START, 0x8 ; TWI start
@@ -209,22 +224,22 @@ describe('TWI', () => {
209224
210225 // Step 5: wait for the assembly code to indicate success by settings r17 to 0x42
211226 runInstructions ( cpu , twi , 16 ) ;
212- expect ( cpu . data [ 17 ] ) . toEqual ( 0x42 ) ;
227+ expect ( cpu . data [ R17 ] ) . toEqual ( 0x42 ) ;
213228 } ) ;
214229
215230 it ( 'should successfully receive a byte from a slave' , ( ) => {
216231 const { program } = asmProgram ( `
217232 ; register addresses
218- _REPLACE TWSR, 0xb9
219- _REPLACE TWDR, 0xbb
220- _REPLACE TWCR, 0xbc
233+ _REPLACE TWSR, ${ TWSR }
234+ _REPLACE TWDR, ${ TWDR }
235+ _REPLACE TWCR, ${ TWCR }
221236
222237 ; TWCR bits
223- _REPLACE TWEN, 0x04
224- _REPLACE TWSTO, 0x10
225- _REPLACE TWSTA, 0x20
226- _REPLACE TWEA, 0x40
227- _REPLACE TWINT, 0x80
238+ _REPLACE TWEN, ${ TWEN }
239+ _REPLACE TWSTO, ${ TWSTO }
240+ _REPLACE TWSTA, ${ TWSTA }
241+ _REPLACE TWEA, ${ TWEA }
242+ _REPLACE TWINT, ${ TWINT }
228243
229244 ; TWSR states
230245 _REPLACE START, 0x8 ; TWI start
@@ -384,7 +399,7 @@ describe('TWI', () => {
384399
385400 // Step 6: wait for the assembly code to indicate success by settings r17 to 0x42
386401 runInstructions ( cpu , twi , 16 ) ;
387- expect ( cpu . data [ 17 ] ) . toEqual ( 0x42 ) ;
402+ expect ( cpu . data [ R17 ] ) . toEqual ( 0x42 ) ;
388403 } ) ;
389404 } ) ;
390405} ) ;
0 commit comments