;********************************************************************** ;* Filename: main.asm ;* Project: EPROM emulator ;* Date: 05 June 2005 ;* Version: 0.1 ;* Author: Philip Pemberton ;* ;* Main program loop for EPROM emulator. ;********************************************************************** include "config.inc" ; Device configuration ;********************************************************************** ;** HEADERS ;********************************************************************** include "pins.inc" ; Pin definitions include "mac_table.inc" ; Table handling defines / macros ;********************************************************************** ;** CONSTANTS ;********************************************************************** lbank equ 0 ;register bank for the local state of this module lbankadr equ bankadr(lbank) ;address within local state register bank ;********************************************************************** ;** RAM VARIABLES ;********************************************************************** ; Global state. defram gbankadr ; Local state defram lbankadr flags res 1 ; Flags sTemp1 res 1 ; Subroutine temporary variable #1 sTemp2 res 1 ; Subroutine temporary variable #2 temp res 1 ; Temporary storage loop res 1 ; Loop variable chkAcc res 1 ; Checksum accumulator #define flag_Running flags, 0 extern addr_High, addr_Low ;********************************************************************** ;** MACROS ;********************************************************************** ;********************************************************************** ;** PROGRAM ENTRY POINT (AFTER SETUP) ;********************************************************************** .main CODE ; Code segment for ;---------------------------------- ; Subroutine: main_Run ; Inputs: ; None ; Outputs: ; None ; Function: ; Main program loop ; glbsub main_Run dbankif lbankadr ; Select RAM bank cmd_loop: gcall uart_Get ; Get the command byte dbankif lbankadr movwf temp ; Save the command byte movwf chkAcc ; Initialise checksum xorlw 0x00 ; =0x00 (NOP)? skpnz goto cmd_loop movf temp, W ; Get command byte xorlw 'D' ; 'D' ==> Debug skpnz goto cmd_Debug movf temp, W ; Get command byte xorlw 'G' ; 'G' ==> Get hardware ID string skpnz goto cmd_GetID movf temp, W ; Get command byte xorlw 'M' ; 'M' ==> Set Mode skpnz goto cmd_SetMode movf temp, W ; Get command byte xorlw 'V' ; 'V' ==> Version Request skpnz goto cmd_Version movf temp, W ; Get command byte xorlw 'W' ; 'W' ==> Write Block skpnz goto cmd_WriteBlock goto error_BadCmd ; Bad/unrecognised command leave ;********************************************************************** ;** COMMAND HANDLERS ;********************************************************************** ;---------------------------------------------------------------------- ; 'D': Debug command cmd_Debug: gcall addr_Reset movlw 0x08 dbankif lbankadr movwf loop dbug_loop: gcall ram_Read dbankif lbankadr movwf temp swapf temp, W call toHex gcall uart_Put dbankif lbankadr movf temp, W call toHex gcall uart_Put movlw " " gcall uart_Put gcall addr_Inc dbankif lbankadr decfsz loop, F goto dbug_loop goto cmd_loop ;---------------------------------------------------------------------- ; 'G': Get hardware ID string cmd_GetID: gcall uart_Get ; Get checksum byte dbankif lbankadr addwf chkAcc, F ; Add to checksum accumulator skpz ; Chksum ACC = 0? goto error_Checksum ; If not, then checksum error movlw 0x00 ; E00: No errors. gcall uart_Put clrf loop ; Clear loopvar id_print_loop: LoadTblOfs table_IDString ; Set up table to read ID str. movf loop, W ; Loopvar ==> W gcall table_Get ; Get the table byte iorlw 0x00 ; Update flags skpnz ; If byte = 0 then end of string goto id_print_end ; byte = 0 so end gcall uart_Put ; byte != 0 so send incf loop, F ; Loop++ goto id_print_loop ; Keep going id_print_end: movlw 0x00 ; Terminating null gcall uart_Put goto cmd_loop ; Back to the command loop ;---------------------------------------------------------------------- ; 'M': Set Mode cmd_SetMode: gcall uart_Get ; Get mode byte dbankif lbankadr movwf sTemp1 addwf chkAcc, F ; Update checksum gcall uart_Get ; Get device ID byte dbankif lbankadr movwf sTemp2 addwf chkAcc, F ; Update checksum gcall uart_Get ; Get checksum byte dbankif lbankadr addwf chkAcc, F ; Add to checksum accumulator skpz ; Chksum ACC = 0? goto error_Checksum ; If not, then checksum error movf sTemp2, W ; What type of ROM? xorlw 0x00 ; 00: 2764? skpnz goto setmode_rt_2764 ; 2764 selected movf sTemp2, W ; What type of ROM? xorlw 0x01 ; 01: 27128? skpnz goto setmode_rt_27128 ; 27128 selected movf sTemp2, W ; What type of ROM? xorlw 0x02 ; 02: 27256? skpnz goto setmode_rt_27256 ; 27256 selected movf sTemp2, W ; What type of ROM? xorlw 0x03 ; 03: 27256? skpnz goto setmode_rt_27512 ; 27512 selected goto error_InvalidDevice ; Invalid device code setmode_rt_2764: ; 2764 or ... setmode_rt_27128: ; ... 27128 dbankif SELA_PORT bsf SELA dbankif SELB_PORT bsf SELB goto setmode_rt_end setmode_rt_27256: dbankif SELA_PORT bsf SELA dbankif SELB_PORT bcf SELB goto setmode_rt_end setmode_rt_27512: dbankif SELA_PORT bcf SELA dbankif SELB_PORT bcf SELB goto setmode_rt_end setmode_rt_end: dbankif lbankadr movf sTemp1, W ; Run mode? skpz goto setmode_run ; Yes. bcf flag_Running ; No. Clear "Running" flag dbankif ADRL_TRIS clrf ADRL_TRIS ; ADRL => output mode dbankif DATA_TRIS clrf DATA_TRIS ; DATA => output mode dbankif nAHOE_PORT bcf nAHOE ; Enable ADRH buffer dbankif nREAD_PORT bsf nREAD ; Disable RAM reads dbankif RESET_PORT bsf RESET ; Reset the target dbankif nRUN_PORT bsf nRUN ; Load mode on goto setmode_r_end setmode_run: dbankif lbankadr bsf flag_Running ; Set "Running" flag dbankif ADRL_TRIS movlw 0xFF movwf ADRL_TRIS ; Tristate ADRL dbankif DATA_TRIS movwf DATA_TRIS ; Tristate DATA dbankif nAHOE_PORT ; Disable ADRH buffer bsf nAHOE dbankif nREAD_PORT bcf nREAD ; Enable RAM reads dbankif nRUN_PORT bcf nRUN ; Run mode on dbankif RESET_PORT bcf RESET ; Run the target setmode_r_end: movlw 0x00 gcall uart_Put goto cmd_loop ; Back to the command loop ;---------------------------------------------------------------------- ; 'V': Version Request cmd_Version: gcall uart_Get ; Get checksum byte addwf chkAcc, F ; Add to checksum accumulator skpz ; Chksum ACC = 0? goto error_Checksum ; If not, then checksum error movlw 0x00 ; E00: No error gcall uart_Put movlw MAJOR_VER ; Major version gcall uart_Put movlw MINOR_VER ; Minor version gcall uart_Put movlw HARDWARE_ID ; Hardware ID gcall uart_Put goto cmd_loop ; Back to the command loop ;---------------------------------------------------------------------- ; 'W': Write Block cmd_WriteBlock: btfsc flag_Running ; Target in run mode? goto error_Running ; Yes, we can't load in Run mode gcall uart_Get ; Get high address dbankif gbankadr movwf addr_High dbankif lbankadr addwf chkAcc, F ; Add to checksum accumulator gcall uart_Get ; Get low address dbankif gbankadr movwf addr_Low dbankif lbankadr addwf chkAcc, F ; Add to checksum accumulator gcall addr_Update ; Load the address into the buffers gcall uart_Get ; Get byte count dbankif lbankadr movwf loop addwf chkAcc, F ; Add to checksum accumulator gcall uart_Get ; Get first data byte dbankif lbankadr addwf chkAcc, F ; Add to checksum accumulator gcall ram_Write ; Write to RAM gcall addr_Inc ; Increment address write_loop: gcall uart_Get ; Get data byte dbankif lbankadr addwf chkAcc, F ; Add to checksum accumulator gcall ram_Write ; Write to RAM gcall addr_Inc ; Increment address decfsz loop, F ; Decrement loop counter goto write_loop ; If >0 then keep going gcall uart_Get ; Get checksum byte dbankif lbankadr addwf chkAcc, F ; Add to checksum accumulator skpz ; Chksum ACC = 0? goto error_Checksum ; If not, then checksum error movlw 0x00 ; E00: No error gcall uart_Put goto cmd_loop ;********************************************************************** ;** ERROR HANDLERS ;********************************************************************** ;---------------------------------------------------------------------- ; E01: Checksum error error_Checksum: movlw 0x01 gcall uart_Put goto cmd_loop ; Back to the command loop ;---------------------------------------------------------------------- ; E02: Bad command error_BadCmd: movlw 0x02 gcall uart_Put goto cmd_loop ; Back to the command loop ;---------------------------------------------------------------------- ; E03: Invalid mode error_InvalidMode: movlw 0x03 gcall uart_Put goto cmd_loop ; Back to the command loop ;---------------------------------------------------------------------- ; E04: Invalid device code error_InvalidDevice: movlw 0x04 gcall uart_Put goto cmd_loop ; Back to the command loop ;---------------------------------------------------------------------- ; E05: Can't access RAM in RUN mode error_Running: movlw 0x05 gcall uart_Put goto cmd_loop ; Back to the command loop ;********************************************************************** ;** SUBROUTINES ;********************************************************************** ;---------------------------------- ; Subroutine: toHex ; Inputs: ; W = Data nibble ; Outputs: ; W = Hex ASCII version of data nibble ; Function: ; Converts a data nibble into its hexadecimal representation. ; locsub toHex andlw 0x0F ; Mask off low nibble movwf sTemp1 ; Save data nibble LoadTblOfs table_Hex ; Load the table offset movf sTemp1, W ; Data nibble => W gcall table_Get ; Get the byte from the table leave ; Exit with W = ascii of nibble ;********************************************************************** ;** DATA TABLES ;********************************************************************** table_IDString: ; ID string dt "512kbit EPROM emulator",0 table_Hex: ; Hex->Asc conversion table dt "0123456789ABCDEF" END