diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/usart.spec.ts | 43 | ||||
| -rw-r--r-- | src/usart.ts | 13 |
2 files changed, 56 insertions, 0 deletions
diff --git a/src/usart.spec.ts b/src/usart.spec.ts index f0dacc4..dadfc78 100644 --- a/src/usart.spec.ts +++ b/src/usart.spec.ts @@ -113,4 +113,47 @@ describe('USART', () => { expect(cpu.data[0xc0]).toEqual(0x40 | 0x20); // UCSR0A: TXC | UDRE }); }); + + describe('onLineTransmit', () => { + it('should call onLineTransmit with the current line buffer after every newline', () => { + const cpu = new CPU(new Uint16Array(1024)); + const usart = new AVRUSART(cpu, usart0Config, FREQ_16MHZ); + usart.onLineTransmit = jest.fn(); + cpu.writeData(0xc1, 0x8); // UCSR0B <- TXEN + cpu.writeData(0xc6, 0x48); // 'H' + cpu.writeData(0xc6, 0x65); // 'e' + cpu.writeData(0xc6, 0x6c); // 'l' + cpu.writeData(0xc6, 0x6c); // 'l' + cpu.writeData(0xc6, 0x6f); // 'o' + cpu.writeData(0xc6, 0xa); // '\n' + expect(usart.onLineTransmit).toHaveBeenCalledWith('Hello'); + }); + + it('should not call onLineTransmit if no newline was received', () => { + const cpu = new CPU(new Uint16Array(1024)); + const usart = new AVRUSART(cpu, usart0Config, FREQ_16MHZ); + usart.onLineTransmit = jest.fn(); + cpu.writeData(0xc1, 0x8); // UCSR0B <- TXEN + cpu.writeData(0xc6, 0x48); // 'H' + cpu.writeData(0xc6, 0x69); // 'i' + expect(usart.onLineTransmit).not.toHaveBeenCalled(); + }); + + it('should clear the line buffer after each call to onLineTransmit', () => { + const cpu = new CPU(new Uint16Array(1024)); + const usart = new AVRUSART(cpu, usart0Config, FREQ_16MHZ); + usart.onLineTransmit = jest.fn(); + cpu.writeData(0xc1, 0x8); // UCSR0B <- TXEN + cpu.writeData(0xc6, 0x48); // 'H' + cpu.writeData(0xc6, 0x69); // 'i' + cpu.writeData(0xc6, 0xa); // '\n' + cpu.writeData(0xc6, 0x74); // 't' + cpu.writeData(0xc6, 0x68); // 'h' + cpu.writeData(0xc6, 0x65); // 'e' + cpu.writeData(0xc6, 0x72); // 'r' + cpu.writeData(0xc6, 0x65); // 'e' + cpu.writeData(0xc6, 0xa); // '\n' + expect(usart.onLineTransmit).toHaveBeenCalledWith('there'); + }); + }); }); diff --git a/src/usart.ts b/src/usart.ts index da5cee0..8d5691c 100644 --- a/src/usart.ts +++ b/src/usart.ts @@ -28,6 +28,7 @@ export const usart0Config: USARTConfig = { }; export type USARTTransmitCallback = (value: u8) => void; +export type USARTLineTransmitCallback = (value: string) => void; // Register bits const UCSRA_RXC = 0x80; // USART Receive Complete @@ -57,6 +58,9 @@ const UCSRC_UCPOL = 0x1; // Clock Polarity export class AVRUSART { public onByteTransmit: USARTTransmitCallback | null = null; + public onLineTransmit: USARTLineTransmitCallback | null = null; + + private lineBuffer: string = ''; constructor(private cpu: CPU, private config: USARTConfig, private freqMHz: number) { this.cpu.writeHooks[config.UCSRA] = (value) => { @@ -73,6 +77,15 @@ export class AVRUSART { if (this.onByteTransmit) { this.onByteTransmit(value); } + if (this.onLineTransmit) { + const ch = String.fromCharCode(value); + if (ch === '\n') { + this.onLineTransmit(this.lineBuffer); + this.lineBuffer = ''; + } else { + this.lineBuffer += ch; + } + } this.cpu.data[config.UCSRA] |= UCSRA_UDRE | UCSRA_TXC; }; } |
