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