⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.mas

📁 采用QT设计的S08仿真器程序 带源代码 使用串口方式,成本很低
💻 MAS
字号:
;----------------------------------------------------------------------------;
; MAIN.MAS              Programa principal                                   ;
; ========                                                                   ;
;----------------------------------------------------------------------------;
;                       Programado por Ing.Gabriel Dubatti (c)2005-2006      ;
;                       info@ingdubatti.com.ar                               ;
;                       www.ingdubatti.com.ar                                ;
;----------------------------------------------------------------------------;


;**** OJO: no colocar nada antes de esta etiqueta ****
;Entra directamente desde el modulo RESET
;=============================================================================
; StartMain:
;   F.bus deseado = 4 MHz o 3.225MHz (segun switch: BUSFREC4MHZ)
;=============================================================================
StartMain: 
$SETNOT CALIBRATE 	                ;normal operation
;$SET CALIBRATE						;test oscillator 

$IF CALIBRATE
;TEST de oscilador: genera cuadrada en PA.0 de frec. bus / 100 => 40.000 KHz
;                                                            o => 32.225 KHz
   while(1){
       bset 0,PORTA                ;clock up
       nsa                         ;igual bra loop
       lda #!12                    ;
       do{                         ;
       }while( --a != 0 )          ;
       nop                         ;ajusta demora a 50 ciclos
       sta COPCTL                  ;reset COP (4 ciclos)

       bclr 0,PORTA                ;clock down
       lda #!13                    ;
       do{                         ;
       }while( --a != 0 )          ;
       nop                         ;
       nop                         ;ajusta demora a 50 ciclos
   }                               ;
   
$ELSEIF
;===========================================================
    while(1){
        bsr RXByte                  ;espera un comando desde la puerta serie
        if( a == #$80 ){            ;
            jsr DoCmdLoadRAM        ;OPTIMIZA [80] = LOAD RAM
            continue                ;
        }                           ;
        if( a >=0 ){                ;los comandos $80...$FF no hacen eco
            bsr TXByte              ;$00..$7F: HACE ECO
        }                           ;
        ldhx #Comandos              ;busca el comando en la tabla y lo ejecuta
        while(1){                   ;
            if( a == ,x ){          ;encontro el comando?
                psha                ;salva el comando
                lda 1,x             ;carga direccion de la rutina (parte alta)
                ldx 2,x             ;y parte baja
                psha                ;
                pulh                ;
                jsr ,x              ;procesa el comando
                pula                ;comandos $80..$FF: NO retornan CR+LF
                if( a >= 0 ){       ;comandos $00..$7F: RETORNAN CR+LF
                    lda #!13        ;envia [CR]+[LF]
                    bsr TXByte      ;
                    lda #!10        ;
                    bsr TXByte      ;
                }                   ;
                break               ;
            }                       ;
            aix #3                  ;prueba con el siguiente
            if( ,x == 0 ){          ;fin de la tabla?
                lda #'?'            ;comando desconocido: envia "?"
                bsr TXByte          ;
                break               ;
            }                       ;
        }                           ;
    }                               ;
$ENDIF

;==============================================================================
; TXByte:
;  Transmite un byte por la puerta serie simulada a 115200 (como caracter)
;
;  REQUIERE BUS de 4 MHZ. (delay= 35 ciclos x bit, error= 0.8%)
;  o        BUS de 3.225MHZ (delay= 28 ciclos x bit)
;
; Requiere:
;       A= byte a enviar. (MANTIENE A,X,H)
;==============================================================================
TxByte:
;;    sei                             ;TAPA INTS (para no arruinar tiempos)
;;    sta     COPCTL                  ;reset COP
    bclr    PA_B_TX,PORTA           ;TX=0 (START)
    psha                            ;mantiene A y X
    pshx
    ldx     #!10                    ;X=numero de bits a enviar
    do{

$IF BUSFREC4MHZ
        nsa                         ;para 4MHZ: delay= 20 (+ 15= 35)
        nsa                         ;
        nsa                         ;
        nsa                         ;
        nsa                         ;
        nsa                         ;
        nop                         ;
        nop                         ;
$ELSEIF
        nsa                         ;para 3.225MHZ: delay= 13 (+ 15= 28)
        nsa                         ;
        nsa                         ;
        nsa                         ;
        nop                         ;
$ENDIF

        sec                         ;CY=1 (STOP)
        rora                        ;envia bits 0,1,2... al carry
        if( cy == 1 ){              ;hace TX= CY
            bset PA_B_TX,PORTA      ;TX=1
        }else{
            bclr PA_B_TX,PORTA      ;TX=0
            brn $                   ;delay de 3 ciclos (igual al branch del else)
        }
    }while( --x != 0 )
    pulx
    pula
;;    cli                             ;DESTAPA INTS
;;    sta     COPCTL                  ;reset COP
    rts

;==============================================================================
; RXByte:
;  Espera y RECIBE un byte por la puerta serie a 115200.
;
;  REQUIERE BUS de 4 MHZ. (delay= 35 ciclos x bit, error= 0.8%)
;  o        BUS de 3.225MHZ (delay= 28 ciclos x bit)
;
;  Espera INFINITA por el START.
;
; Requiere:
;       OUT: A= byte recibido. (MANTIENE H,X)
;==============================================================================
RXByte:
    pshx                            ;salva X
;;  sei                             ;TAPA INTS (para medir los bits)
    do{
;;      sta     COPCTL              ;reset COP
    }while( PORTA.PA_B_RX == 1 )    ;espera el START

$IF BUSFREC4MHZ
    ldx #!16                        ;espera tiempo de 1+1/2 bit= 52.5 ciclos
$ELSEIF
    ldx #!13                        ;espera tiempo de 1+1/2 bit= 42 ciclos
$ENDIF

    do{
    }while( --x != 0 )
    lda #$80                        ;detecta RX completa (8bits)
    while(1){
        if( PORTA.PA_B_RX == 0 ){   ;CY=DATA BIT
        }
        rora
        if( cy == 1 ){              ;ya leyo los 8 (ignora el STOP)
;;          cli                     ;DESTAPA INTS
            pulx                    ;mantiene X
;;          sta COPCTL              ;reset COP
            rts
        }

$IF BUSFREC4MHZ
        ldx #!7                     ;espera tiempo de 1 bit= 35 ciclos
                                    ;2+7x3= 23
$ELSEIF
        nop                         ;espera tiempo de 1 bit= 28 ciclos
        nop                         ;
        ldx #!4                     ;4+12=  16
$ENDIF
        do{
        }while( --x != 0 )          ;
    }                               ;leer otro bit (23/16 +12 = 35/28 ciclos)

;====================================================================
; TXHexByte:
;   Envia un byte por la puerta serie como 2 caracteres HEXADECIMALES
; Requiere A= byte a convertir
; Mantiene A,X,H
;====================================================================
TXHexByte:                          ;A= BYTE a transmitir
    bsr TXHiNibble                  ;envia nibble alto
TXHiNibble:
    nsa                             ;intercambia nibble alto y bajo
TXLowNibble:
    psha                            ;salva A
    and     #$0f                    ;filtra el nibble bajo
    add     #'0'                    ;pasa a ASCII
    if( a > #'9' ){
        add #{'A'-'9'-1}            ;corrige letras A-F
    }
    bsr TXByte                      ;envia A a la puerta serie
    pula                            ;recupera A
    rts

;===========================================================
; Tabla de Comandos aceptados por la puerta serie
; Los comandos $00..$7F RETORNAN eco y CR+LF al finalizar
; Los comandos $80..$FF NO retornan eco NI cr+lf al finalizar
;===========================================================
Comandos:
;este comando lo optimiza para que no tenga que esperar la PC
;   db $80                          ;[80] => LOAD 16 bytes en RAM
;   dw DoCmdLoadRAM                 ;       (en la direccion dada)
    db $90                          ;[90] => ver contenido de la direccion dada
    dw DoCmdDumpMEM                 ;       (16 bytes)

    db $AA                          ;[AA] => EXEC en RAM
    dw DoCmdEXECRAM                 ;   BRKPOINT=0080 / PC=0082
                                    ;   hace GO y espera que pare, retorna A

    db 'W'                          ;W => modifica el contenido de la direccion
    dw DoCmdWriteDIR                ;     dada
    db 'D'                          ;D => ver contenido de la direccion pedida
    dw DoCmdDumpDIR                 ;

    db 'w'                          ;w => grabar el byte dado en ++HX
    dw DoCmdWriteHX                 ;

    db 'R'                          ;R => RESET CPU
    dw DoCmdReset                   ;

    db 'h'                          ;h => HARD SYNC (con RESET, max delay)
    dw DoCmdHardSYNC                ;
    db 'S'                          ;S => SOFT SYNC (sin RESET, max delay)
    dw DoCmdSoftSYNC                ;
    db 'q'                          ;q => QUICK SOFT SYNC (sin RESET, min delay)
    dw DoCmdQuickSYNC               ;

    db 'a'                          ;a => Entra a modo background activo
    dw DoCmdBackDebug               ;

    db 'g'                          ;g => GO
    dw DoCmdGO                      ;Ejecutar codigo desde el PC

    db 't'                          ;t => TRACE
    dw DoCmdTrace                   ;Ejecutar una instruccion desde el PC

    db 's'                          ;s => LEE STATUS
    dw DoCmdREADSTATUS              ;

    db 'c'                          ;c => Selecciona clock alterno / resync
    dw DoCmdClockAlt                ;
    db 'C'                          ;C => Selecciona clock f.bus / resync
    dw DoCmdClockBUS                ;

    db 'b'                          ;b => Breakpoint activado
    dw DoCmdBRKON                   ;
    db 'B'                          ;B => Breakpoint desactivado
    dw DoCmdBRKOFF                  ;

    db 'f'                          ;f => FTS activado (modo FORCE)
    dw DoCmdFTSON                   ;
    db 'F'                          ;F => FTS desactivado (modo TAG)
    dw DoCmdFTSOFF                  ;

    db 'r'                          ;r => ver registros y breakpoint
    dw DoCmdDumpReg                 ;

    db 'd'                          ;d => ver contenido segun HX (16 bytes)
    dw DoCmdDumpHX                  ;

    db 'm'                          ;m => modificar registro / breakpoint
    dw DoCmdModifReg                ;

    db 'v'                          ;v => version del POD
    dw DoCmdVersion                 ;

    db !13                          ;CR => OK
    dw DoCmdOK                      ;
    db !10                          ;LF => OK
    dw DoCmdOK                      ;

    db 0                            ;fin de la tabla


;===========================================================
VECTOR_VOID:                        ;
    rti                             ;

    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -