📄 main.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 + -