Sunday, December 12, 2021

Avengers! Disassemble!

 

Disassembler, disassemble yourself!

So, I thought it would be a good exercise to write a disassembler for the RIBBBIT65.  My plan is to integrate this into the CoreROM, but I have a few fixes and tweaks I want to do first.  As it is now, this starts as $1000 and references some constants and code in the CoreROM (e.g. CIOH), so, unfortunately, this won't really output anything without that, but you could stuff your own output routines in there if you were so inclined.  

...and, yes, I realize there's a bunch of stuff in here that's redundant... and some hard-coded addresses (rather than constants)... but I thought it might be nice to get something out there.

Originally, I had written this with its own "private" buffer, that it would then copy to the CIOH output buffer, but then I realized that was dumb, and just made this write directly to the CIOH output buffer.  Unfortunately, there are still some vestiges of the "private buffer" business in here (constants and such).

Anyway... here it is.

; START BNW CONSTANTS
DBUTIL0 = $50
DBUTIL1 = $51
DBUTIL2 = $52
DBUTIL3 = $53
DBUTIL4 = $54
VWMSGSYS = $0090  ; System Message Vector
VWMSGPRG = $0092  ; Program Message Vector
VWMSGSPC = $0094  ; Special Message Vector
DBCPBTERM = $6237  ; Current Peripheral Buffer Terminate Value
CBSERBRDM = $6238  ; Serial Baud Rate Delay MultiplierDFCLCDLB0 = $6d00  ; Character LCD Line Buffer 0
DFCLCDLB1 = $6d30  ; Character LCD Line Buffer 1
DFCLCDLB2 = $6d60  ; Character LCD Line Buffer 2
DFCLCDLB3 = $6d90  ; Character LCD Line Buffer 3
DFCLCDLB4 = $6dc0  ; Character LCD Line Buffer 4
pfciohobufappendbytestart = $b264 ;EXPR(45668=0xb264) ABS 
pfsetcurpstart = $b1c0 ; EXPR(45504=0xb1c0) ABS 
pfciohstdentry = $b27f ; EXPR(45695=0xb27f) ABS 
pfciohobufinitstart = $b23d ; EXPR(45629=0xb23d) ABS 
; END BNW CONSTANTS


VWLDASMSTARTVEC = $b0   ; Vector to beginning of space to disassemble
VWLDASMENDVEC = $b2     ; Vector to end of space to disassemble
VWLDASMCUROCVEC = $b4   ; Vector to the current "working" OpCode
DBLDASMOBWP = $ba       ; Output Buffer Write Pointer (offset)
DBLDASMOBRP = $bb       ; Output Buffer Read Pointer (offset)
DBLDASMOCVINCCNT = $bc  ; Number of times to increment VWLDASMCUROCVEC
DBLDASMDONEFLG = $bd    ; Done Flag -- Anything other than $00 means done
DBLDASOCWRKCPY = $be    ; Working copy of the current OpCode





DBBTHSRC = $21
;DWBTHRES = $22
DWBTHRES = $72
PFBYTETOASCII = $e14f

;BTHRESL EXPR(115=0x73) EQU 
;BTHRESH EXPR(114=0x72) EQU

    .org $1000
pfbdasmentry:

    ;;;; Tell the CLCD we're streaking
    lda #<$c200 ; dfr65msg001 ; $c200 ; dfr65msg001
    sta $0090 ; VWMSGSYS ; $0090 ; VWMSGSYS
    lda #>$c200 ; dfr65msg001 ; $c200 ; dfr65msg001
    sta $0090 + 1 ; VWMSGSYS + 1 ; $0090 + 1 ; VWMSGSYS + 1
    lda #pfbdasmclcdmsg ; twmesg   ;;;;   <<<======LOCAL MESSAGE
    sta $0092 + 1 ; VWMSGPRG + 1 ; $0092 + 1 ; VWMSGPRG + 1
    jsr $ce17 ; pflcd162spmsgtobufstart ; $ce17 ; pflcd162spmsgtobufstart
    jsr $bd00 ; pfclcd162l1bufstart ; $bd00 ; pfclcd162l1bufstart
    
    
    ;; INITIALIZE THE THINGS
    lda #$00
    sta DBLDASMDONEFLG
    clc
    lda VWLDASMSTARTVEC
    sta VWLDASMCUROCVEC
    lda VWLDASMSTARTVEC + 1
    sta VWLDASMCUROCVEC + 1
    
    jsr pfbdasmserportinit
    
;;;; HERE BEGINS THE BIG OUTER LOOP
pfbdasmmainlooptop:

    ;; Save a working copy of the current OpCode
    ldy #$00                  ; Copy the Current OC Vector to "Working Copy"
    lda (VWLDASMCUROCVEC),y
    sta DBLDASOCWRKCPY
    
    ; Initialize the things
    lda #$00
    sta DBLDASMOBWP       ; Output Buffer Write Pointer (offset)
    sta DBLDASMOBRP       ; Output Buffer Read Pointer (offset)
    
    ; Clear the Output Buffer
    jsr pfciohobufinitstart

    ; Call the POC Disassembler
    jsr pfpocdasmentry
    
    ; Write the Serial Buffer out to the port
    jsr pfbdasmserportwrite
    
    ;;; Increment the "Current OpCode Vector" the correct number of 
    ;;; times for the "length" of the OpCode
    jsr pfbdasmcurocvecincstart

    lda DBLDASMDONEFLG        ; Get the "DONE" flag
    cmp #$00                  ; $00 == Keep going
    bne pfbdasmexit           ; Bail out if != 0
    
    jmp pfbdasmmainlooptop
    
pfbdasmexit:
    rts
    
    
    
    
    
;;;;;; INITIALIZE THE SERIAL PORT
pfbdasmserportinit:
    ; preserve the registers
    pha
    txa
    pha
    tya
    pha
    ; Initialize the SIO4 device
    ;; Set baud rate write delay
    lda #$08
    sta CBSERBRDM ; CBSERBRDM
    ;; Set terminate character
    lda #$00
    sta DBCPBTERM ; DBCPBTERM
    ;lda #$04 ;;; 
    lda #$05
    jsr pfsetcurpstart
    lda #$10
    jsr pfciohstdentry
    ;restore the registers
    pla
    tay
    pla
    tax
    pla
    rts


;;;;;; WRITE TO THE SERIAL PORT
pfbdasmserportwrite:
    ;;;; START WRITE TO SERIAL PORT MAYBE
    ; Preserve the registers
    pha
    tya
    pha
    txa
    pha
    
    ;lda #$04 ;;;;
    lda #$05
    jsr pfsetcurpstart
    lda #$62
    jsr pfciohstdentry
        
    ;;;; END WRITE TO SERIAL PORT MAYBE
    ; Restore the registers
    pla
    tax
    pla
    tay
    pla
    rts

;;;;;;;;NEW INCREMENT CURRENT OPCODE VECTOR
pfbdasmcurocvecincstart:
    pha
    txa
    pha
    tya
    pha
    
    ldy DBLDASOCWRKCPY
    lda dfopcdarglut,y
    sta DBUTIL3 ; TMP copy of OpCode length
    ; Get the c lsb
    lda VWLDASMCUROCVEC
    ; eor with $ff to see how many steps til carry
    eor #$ff
    sta DBUTIL4 ; tmp holding spot for "steps til carry"
    lda DBUTIL4
    cmp DBUTIL3 ; compare with opcode length
    bcs pfbdasmcurocvecincinclsbonly ; no carry expected
    lda DBUTIL3 ; Opcode Length
    sbc DBUTIL4 ; tmp holding spot for "steps til carry"
    sta VWLDASMCUROCVEC
    clc
    lda VWLDASMCUROCVEC + 1
    adc #$01
    sta VWLDASMCUROCVEC + 1
    jmp pfbdasmcurocvecinccheckgt
    nop
    
pfbdasmcurocvecincinclsbonly:
    clc
    lda VWLDASMCUROCVEC
    adc DBUTIL3
    sta VWLDASMCUROCVEC
    nop
  
pfbdasmcurocvecinccheckgt:
    lda VWLDASMCUROCVEC + 1  ; 80
    cmp VWLDASMENDVEC + 1  ; 80
    beq pfbdasmcurocvecincchecklsbgt
    bmi pfbdasmcurocvecincdonedone
    bpl pfbdasmcurocvecincoverflow
pfbdasmcurocvecincchecklsbgt:
    lda VWLDASMCUROCVEC
    cmp VWLDASMENDVEC
    bmi pfbdasmcurocvecincdonedone
    nop

pfbdasmcurocvecincoverflow:
    lda #$ff
    sta DBLDASMDONEFLG
    nop

pfbdasmcurocvecincdonedone:    
    pla
    tay
    pla
    tax
    pla
    rts
    nop
    nop
    nop
    nop
;;;;;;;;;;END NEW INCREMENT CURRENT OPCODE VECTOR

;;;;;;; START "PROOF OF CONCEPT" DISASSEMBLER
    ;.org $1800
pfpocdasmentry:
    ;  Preserve the registers
    pha
    txa
    pha
    tya
    pha 
    
    ldy #$00
    lda (VWLDASMCUROCVEC),y  ; Load the OpCode at the "Current OpCode Vector"
    sta $0600                ; Store the OpCode in $0600
    tay                      ; Move the OpcCode to rY
    lda dfopcdmnemlut,y      ; Load the Mnemonic Offset from the lookup table
    sta $0601                ; Store the Mnemonic Offset in $0601
    lda dfopcdarglut,y       ; Load the Arg Count from the lookup table
    sta $0602                ; Store the Arg Count in $0602
    lda #$00                 ; Set the "Working Arg" to #$00
    sta $0603                ; Store the "Working Arg" to $0603
    lda #$00
    sta $0604                ; Out Buff Offset
        
    ;; We're going to put an output string in RAM, starting at $06010
    ;; First, post the current address
    lda VWLDASMCUROCVEC + 1
    jsr PFBYTETOASCII
    lda DWBTHRES ; 72
    jsr pfciohobufappendbytestart
    lda DWBTHRES + 1 ; 73
    jsr pfciohobufappendbytestart
    
    lda VWLDASMCUROCVEC + 0
    jsr PFBYTETOASCII
    lda DWBTHRES ; 72
    jsr pfciohobufappendbytestart
    lda DWBTHRES + 1 ; 73
    jsr pfciohobufappendbytestart
    
    lda #$3a ; ":"
    jsr pfciohobufappendbytestart
    lda #$20 ; " "
    jsr pfciohobufappendbytestart
    
    ;; Second, copy the Nmemonic
    lda $0601
    tay
    lda dfmnemreflut,y
    jsr pfciohobufappendbytestart
    iny
    lda dfmnemreflut,y
    jsr pfciohobufappendbytestart
    iny
    lda dfmnemreflut,y
    jsr pfciohobufappendbytestart
    ;;
    ;; We would put a decoration here if appropriate
    ;;
    ;; Add a space
    lda #$20
    jsr pfciohobufappendbytestart
    
    ;;
    ;; Convert the OpCode to ASCII Hex
    ldy #$00
    lda (VWLDASMCUROCVEC),y
    sta DBBTHSRC
    jsr PFBYTETOASCII
    lda DWBTHRES ; 72
    jsr pfciohobufappendbytestart
    lda DWBTHRES + 1 ; 73
    jsr pfciohobufappendbytestart
    ;;
    ;; Add a space
    lda #$20
    jsr pfciohobufappendbytestart

    ldy #$01 
pfpocdasmarglooptop:
    cpy $0602 ; If we're already at the "length" value, dump out.
    beq pfpocdasmdone
    
    ;; FIRST ARG
    lda (VWLDASMCUROCVEC),y
    sta DBBTHSRC
    jsr PFBYTETOASCII
    lda DWBTHRES ; 72
    jsr pfciohobufappendbytestart
    lda DWBTHRES + 1 ; 73
    jsr pfciohobufappendbytestart
    lda #$20
    jsr pfciohobufappendbytestart
    
    ;; SECOND ARG
    iny
    cpy $0602 ; If we're already at the "length" value, dump out.
    beq pfpocdasmdone
    lda (VWLDASMCUROCVEC),y
    sta DBBTHSRC
    jsr PFBYTETOASCII
    lda DWBTHRES ; 72
    jsr pfciohobufappendbytestart
    lda DWBTHRES + 1 ; 73
    jsr pfciohobufappendbytestart
    lda #$20
    jsr pfciohobufappendbytestart
    
    ;; THIRD ARG
    iny
    cpy $0602 ; If we're already at the "length" value, dump out.
    beq pfpocdasmdone
    lda (VWLDASMCUROCVEC),y
    sta DBBTHSRC
    jsr PFBYTETOASCII
    lda DWBTHRES ; 72
    jsr pfciohobufappendbytestart
    lda DWBTHRES + 1 ; 73
    jsr pfciohobufappendbytestart
    lda #$20
    jsr pfciohobufappendbytestart
    
pfpocdasmdone:
    lda #$0d
    jsr pfciohobufappendbytestart
    lda #$0a
    jsr pfciohobufappendbytestart
    lda #$00
    jsr pfciohobufappendbytestart
    lda #$ea
    jsr pfciohobufappendbytestart
    ; Restore the registers
    pla
    tay
    pla
    tax
    pla
    
    rts
    
;;;;;;; END "PROOF OF CONCEPT" DISASSEMBLER

pfbdasmclcdmsg:
    ;.asciiz "P: R65 DisASM"
    .asciiz "P: R65 CrapDASM"
    
    .byte $00,$00,$00,$00, $00,$00,$00,$00, $00,$00,$00,$00, $00,$00,$00,$00
    .asciiz "DEADBEEFdeadbeef"




; Lookup Tabels:  
;   Opcode to Mnemonic Lookup (dfopcdmnemlut)
;   Opcode to Arg Count Lookup
;   Mnemonic Reference (dfmnemreflut)

    .org $2000


;;;;; MNEMONIC BY OPCODE LOOKUP TABLE
; OpCodes are one byte each.
; OpCode is offset from start of table
; Value at offset is offset from start of dfmnemreflut containinf the Mnemonic
dfopcdmnemlut:
    .byte $30,$84,$f0,$f0,$f0,$84,$08,$f0,$d0,$84,$08,$f0,$f0,$84,$08,$f0
    .byte $10,$84,$f0,$f0,$f0,$84,$08,$f0,$48,$84,$f0,$f0,$f0,$84,$08,$f0
    .byte $6c,$04,$f0,$f0,$0c,$04,$a8,$f0,$d4,$04,$a8,$f0,$0c,$04,$a8,$f0
    .byte $f0,$04,$f0,$f0,$f0,$04,$a8,$f0,$4c,$04,$f0,$f0,$f0,$04,$a8,$f0
    .byte $b0,$44,$f0,$f0,$f0,$44,$7c,$f0,$c8,$44,$7c,$f0,$68,$44,$7c,$f0
    .byte $18,$44,$f0,$f0,$f0,$44,$7c,$f0,$50,$44,$f0,$f0,$f0,$44,$7c,$f0
    .byte $b4,$00,$f0,$f0,$f0,$00,$ac,$f0,$cc,$00,$ac,$f0,$68,$00,$ac,$f0
    .byte $1c,$00,$f0,$f0,$f0,$00,$ac,$f0,$54,$00,$f0,$f0,$f0,$00,$ac,$f0
    .byte $f0,$bc,$f0,$f0,$dc,$bc,$d8,$f0,$a0,$f0,$8c,$f0,$dc,$bc,$d8,$f0
    .byte $20,$bc,$f0,$f0,$dc,$bc,$d8,$f0,$9c,$bc,$c0,$f0,$f0,$bc,$f0,$f0
    .byte $78,$70,$74,$f0,$78,$70,$74,$f0,$98,$70,$88,$f0,$78,$70,$74,$f0
    .byte $24,$70,$f0,$f0,$78,$70,$74,$f0,$58,$f0,$c4,$f0,$78,$70,$74,$f0
    .byte $3c,$34,$f0,$f0,$3c,$34,$40,$f0,$a4,$34,$90,$f0,$f0,$34,$40,$f0
    .byte $28,$34,$f0,$f0,$f0,$34,$40,$f0,$5c,$34,$f0,$f0,$f0,$34,$40,$f0
    .byte $38,$b8,$f0,$f0,$38,$b8,$64,$f0,$94,$b8,$80,$f0,$f0,$b8,$64,$f0
    .byte $2c,$b8,$f0,$f0,$f0,$b8,$64,$f0,$60,$b8,$f0,$f0,$f0,$b8,$64,$f0

;;;;; ARGUMENT COUNT BY OPCODE LOOKUP TABLE
; OpCodes are one byte each.
; OpCode is offset from start of table
; Value at offset is number of additional bytes to read for this OpCode
dfopcdarglut:
    .byte $01,$02,$00,$00,$00,$02,$02,$00,$01,$02,$01,$00,$00,$03,$03,$00
    .byte $02,$02,$00,$00,$00,$02,$02,$00,$01,$03,$00,$00,$00,$03,$03,$00
    .byte $03,$02,$00,$00,$02,$03,$02,$00,$01,$02,$01,$00,$03,$03,$03,$00
    .byte $00,$02,$00,$00,$00,$02,$02,$00,$01,$03,$00,$00,$00,$03,$03,$00
    .byte $01,$02,$00,$00,$00,$02,$02,$00,$01,$02,$01,$00,$03,$04,$03,$00
    .byte $02,$02,$00,$00,$00,$02,$02,$00,$01,$03,$00,$00,$00,$03,$03,$00
    .byte $01,$02,$00,$00,$00,$02,$02,$00,$01,$02,$01,$00,$03,$03,$03,$00
    .byte $02,$02,$00,$00,$00,$02,$02,$00,$01,$03,$00,$00,$00,$03,$03,$00
    .byte $00,$02,$00,$00,$02,$02,$02,$00,$01,$00,$01,$00,$03,$03,$03,$00
    .byte $02,$02,$00,$00,$02,$02,$02,$00,$01,$03,$01,$00,$00,$03,$00,$00
    .byte $02,$02,$02,$00,$02,$02,$02,$00,$01,$02,$01,$00,$03,$03,$03,$00
    .byte $02,$02,$00,$00,$02,$02,$02,$00,$01,$00,$01,$00,$03,$03,$03,$00
    .byte $02,$02,$00,$00,$02,$03,$02,$00,$01,$02,$01,$00,$00,$03,$03,$00
    .byte $02,$02,$00,$00,$00,$02,$02,$00,$01,$03,$00,$00,$00,$03,$04,$00
    .byte $02,$02,$00,$00,$02,$02,$02,$00,$01,$02,$01,$00,$00,$03,$03,$00
    .byte $02,$02,$00,$00,$00,$02,$02,$00,$01,$03,$00,$00,$00,$03,$03,$00

;;;;; MNEMONIC TEXT LOOKUP TABLE
; Mnemonics are all 4 bytes long - 3 character and a NUL ($00) terminator
dfmnemreflut:
    .byte $41,$44,$43,$00,$41,$4e,$44,$00,$41,$53,$4c,$00,$42,$49,$54,$00
    .byte $42,$50,$4c,$00,$42,$4d,$49,$00,$42,$56,$43,$00,$42,$56,$53,$00
    .byte $42,$43,$43,$00,$42,$43,$53,$00,$42,$4e,$45,$00,$42,$45,$51,$00
    .byte $42,$52,$4b,$00,$43,$4d,$50,$00,$43,$50,$58,$00,$43,$50,$59,$00
    .byte $44,$45,$43,$00,$45,$4f,$52,$00,$43,$4c,$43,$00,$53,$45,$43,$00
    .byte $43,$4c,$49,$00,$53,$45,$49,$00,$43,$4c,$56,$00,$43,$4c,$44,$00
    .byte $53,$45,$44,$00,$49,$4e,$43,$00,$4a,$4d,$50,$00,$4a,$53,$52,$00
    .byte $4c,$44,$41,$00,$4c,$44,$58,$00,$4c,$44,$59,$00,$4c,$53,$52,$00
    .byte $4e,$4f,$50,$00,$4f,$52,$41,$00,$54,$41,$58,$00,$54,$58,$41,$00
    .byte $44,$45,$58,$00,$49,$4e,$58,$00,$54,$41,$59,$00,$54,$59,$41,$00
    .byte $44,$45,$59,$00,$49,$4e,$59,$00,$52,$4f,$4c,$00,$52,$4f,$52,$00
    .byte $52,$54,$49,$00,$52,$54,$53,$00,$53,$42,$43,$00,$53,$54,$41,$00
    .byte $54,$58,$53,$00,$54,$53,$58,$00,$50,$48,$41,$00,$50,$4c,$41,$00
    .byte $50,$48,$50,$00,$50,$4c,$50,$00,$53,$54,$58,$00,$53,$54,$59,$00
    .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
    .byte $3f,$3f,$3f,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00


...and that's all I have to say about that.

No comments:

Post a Comment

RMVOD r0.9.3 is here!

 Hi folks!   Well, TV Series Playlists are here, as well as some fixes to Recommendations.  Here are the release notes: RIBBBITmedia Video O...