; ; Monitor: state driven monitor program for examining and modifying ; registers, data, i/o and eeprom. ; ; Command summary: ; ; cmd in out Action ; --- --- --- ------ ; a xx Sets low address to read ; A xx Sets high address to read ; r dd Outputs byte 'dd' at 'xx' ; w xx writes a byte at xx ;----- Helper commands -------- Remove --------------- ; e dd r/w eeprom ; E xx ; i dd r/w i/o ; I xx ; ; ; Since all memory (registers, I/O and Sram) are mapped linearly through ; the Z register, the above will do, although reading and writing the eeprom ; is tricky. (Does this work on the 1200?) ; ; Register Usage: ; M_Flags - all state information ; M_Temp - Temp storage for reading/writing nibbles. ; ; This code has been optimised for code density and minimal register usage, ; not speed. EEPROM stuff can be removed once a host application is written ; that can access the EEPROM via the I/O registers via the regular read and ; write commands. ; .equ M_Command = 0 ; Monitor states (M_State) .equ M_hnibble = 1 .equ M_lnibble = 2 .equ M_write = 3 ; Data byte destination flags .equ M_addl = 4 .equ M_addh = 5 .equ M_ewrite= 6 .equ M_Iwrite= 7 .cseg monitor: tst M_Flags ; Initial condition is no bits set. breq mo_prompt rcall GetChar ; always read a char in these states mov TxByte, RxByte rcall putchar ; remove echo when host driver built sbrc M_Flags, M_command rjmp mo_command sbrc M_Flags, M_hnibble rjmp mo_hnibble sbrc M_Flags, M_lnibble rjmp mo_lnibble mo_err: ldi TxByte, '?' rcall putchar rjmp mo_prompt ; ; Print friendly prompt before waiting for next command. ; mo_prompt: ldi TxByte, 0x0D ; Print prompt, switch to command mode rcall putchar ldi TxByte, '>' rcall putchar ; reset to command mode, reset cmd-in-prog flags ldi M_Flags, 1< 'A' subi RxByte, 'A' - 10 ; sub 'A', add 10 mo_hn1: swap RxByte mov M_Temp, RxByte cbr M_Flags, 1< 'A' subi RxByte, 'A' - 10 ; sub 'A', add 10 mo_ln1: add M_Temp, RxByte brcs mo_err ; overflow if not ascii hex sbrc M_Flags, M_Addl ; Low Address mov ZL, M_Temp sbrc M_Flags, M_addh ; High Address mov ZH, M_Temp sbrc M_Flags, M_Write ; Write memory space st Z, M_Temp sbrs M_Flags, M_EWrite ; Write EEProm space rjmp mo_ln3 ; had to be one of the above. mo_ln2: sbic EECR, EEWE ; Make sure EEPROM is ready rjmp mo_ln2 out EEAR, ZL out EEDR, M_Temp sbi EECR, EEWE mo_ln3: sbrs M_Flags, M_IWrite rjmp mo_ln4 clt rcall io_rw brts mo_err ; special case if I/O address bad mo_ln4: rjmp mo_prompt ; ; Parse out command and switch modes as needed. ; mo_command: cpi RxByte, 'r' ; Read a byte brne m1 ld M_Temp, Z rjmp PutHexByte m1: cpi RxByte, 'w' ; Write a byte brne m2 ldi M_Flags, 1<> out EEAR, ZL ; Should check to make sure no write in progress sbi EECR, EERE ; Flag a read operation in M_Temp, EEDR rjmp PutHexByte m5: cpi RxByte, 'E' ; Write eeprom byte brne m6 ldi M_Flags, 1< '9' brlt ph1 ; subi '9' and add 'A' subi TxByte, ('9' + 1 - 'A') ph1: rjmp putchar ; ; io_rw ; ; Hack since the 1200 doesn't seem to read I/O via the Z reg ; ; PARAMETERS: ; ZL = Address to read/write ; M_Temp = Data read or to be written ; T = read bit (1=r, 0=w) ; ; RETURNS ; T bit 0 if Ok, 1 if error (unrecognized I/O address) ; io_rw: cpi ZL, ACSR brne io1 brtc io0a in M_Temp, ACSR rjmp io_ret io0a: out ACSR, M_Temp rjmp io_ret io1: cpi ZL, PIND brne io2 brtc io2 ; read only in M_Temp, PIND rjmp io_ret io2: cpi ZL, DDRD brne io3 brtc io2a in M_Temp, DDRD rjmp io_ret io2a: out DDRD, M_Temp rjmp io_ret io3: cpi ZL, PORTD brne io4 brtc io3a in M_Temp, PORTD rjmp io_ret io3a: out PORTD, M_Temp rjmp io_ret io4: cpi ZL, PINB ; read only brne io5 brtc io5 in M_Temp, PINB rjmp io_ret io5: cpi ZL, DDRB brne io6 brtc io5a in M_Temp, DDRB rjmp io_ret io5a: out DDRB, M_Temp rjmp io_ret io6: cpi ZL, PORTB brne io7 brtc io6a in M_Temp, PORTB rjmp io_ret io6a: out PORTB, M_Temp rjmp io_ret io7: io10: cpi ZL, WDTCR brne io11 brtc io10a in M_Temp, WDTCR rjmp io_ret io10a: out WDTCR, M_Temp rjmp io_ret io11: cpi ZL, TCNT0 brne io12 brtc io11a in M_Temp, TCNT0 rjmp io_ret io11a: out TCNT0, M_Temp rjmp io_ret io12: cpi ZL, MCUCR brne io13 brtc io12a in M_Temp, MCUCR rjmp io_ret io12a: out MCUCR, M_Temp rjmp io_ret io13: cpi ZL, TIFR brne io14 brtc io13a in M_Temp, TIFR rjmp io_ret io13a: out TIFR, M_Temp rjmp io_ret io14: cpi ZL, GIMSK brne io15 brtc io14a in M_Temp, GIMSK rjmp io_ret io14a: out GIMSK, M_Temp rjmp io_ret io15: cpi ZL, SREG brne io16 brtc io15a in M_Temp, SREG rjmp io_ret io15a: out SREG, M_Temp io_ret: clt ; T = 0 Ok ret io16: set ; T = 1 Error, bad io address ret