#include "asm86.h" #include "ti86asm.inc" CurPos = _textShadow+42 IZFlag = _textShadow+43 IZData = _textShadow+47 SaveAddress = _textShadow+48 .org _asm_exec_ram ld a,$0D ;since only ROM disassembly, we can out (6),a ;copy the needed function calls into ;$8000-$BFFF, and add $4000 to all ;of our calls. no page storage needed ;this way set shiftALock,(IY+shiftflags) ;uses _getkey, so set alpha status set shiftAlpha,(IY+shiftflags) ;as locked for key interpretation call _runindicoff+$4000 call _clrLCD+$4000 ld hl,$0000 ld (_curRow),hl set textInverse,(IY+textflags) ld hl,TitleStr call _puts+$4000 res textInverse,(IY+textflags) ChangeStuff: call MinorLCD ;clear only the last 6 lines of LCD ld hl,$0000 EnterAddressLoop: ld de,$1000 ;enter an address to go to ld (_penCol),de ;this is something that is REALLY call DispAddress ;lacking in your version (no offense) EnterAddress: push hl call _getkey+$4000 pop hl or a jr z,EnterAddress cp kLeft jp z,RomPageDec cp kRight jp z,RomPageInc cp kExit jp z,ExitEverything cp kEnter jr z,Goobernate ;don't try to make sense out of some ;of these labels... cp kCapZ jr nc,EnterAddress sub kCapA jr c,EnterAddress push hl ld hl,ConvertTable ld d,0 ld e,a add hl,de ld a,(hl) cp $FF jr z,EnterAddress ld d,0 ld e,a pop hl add hl,hl add hl,hl add hl,hl add hl,hl add hl,de jr EnterAddressLoop RomPageDec: in a,(5) dec a and %00001111 out (5),a jr ChangeStuff RomPageInc: in a,(5) inc a and %00001111 out (5),a jr ChangeStuff Goobernate: push hl pop ix ;ld ix,hl DisplayScreen: ld (SaveAddress),ix call MinorLCD ld hl,$1000 ld (_penCol),hl ld (IZFlag+2),hl ;put a zero-terminater at the end of ;the IZString (IZFlag). This contains ;"HL", "IX", or "IY". ld b,8 ;8 lines of disassembly Loop: push bc push ix pop hl call DispAddress ld a,$1E ld (CurPos),a ;set X coordinate to disassembly ;location. it will be changed and ;restored as the actual byte numbers ;are displayed to the left of it ld a,$46 ld (_penCol),a ld hl,'L'*256+'H' ;set IZString to "HL" ld (IZFlag),hl xor a ld (IZData),a ;set IZData to 0 - IZData is the plus ;number, i.e., IX+$02 - $02 is IZData call PutByte ;this is the main function. see more ;details later in the program ld hl,Table1 ;set the table to Table1 cp $DD ;see if byte is DD jr nz,NotDD ld hl,'X'*256+'I' ;if so, set IZString to "IX" jr IZCommon ;and jump to the IZ Handling ;IZ = common to both IX and IY NotDD: cp $76 ;see if command is halt. this instruc jr nz,Not76 ;does not fit in with the pattern of ld hl,Table8 ;naming schemes jr NonConformist+3 Not76: cp $FD ;see if bytes is $FD and if so load jr nz,NotFD ;"IY" into IZFlag ld hl,'Y'*256+'I' IZCommon: ld (IZFlag),hl ld hl,Table1 ;set table pointer to Table1 call PutByte ;get the next byte ld c,a ;these AND commands see if the IZ and %00000111 ;has a +$xx in it cp $06 jr z,IZOffset ld a,c and %11111000 cp $70 jr z,IZOffset ld a,c and %11111110 cp $34 jr z,IZOffset ld a,c cp $CB jr z,IZOffset jr NotFD ;if not, continue on IZOffset: push bc ;otherwise, get the offset call PutByte pop bc ld (IZData),a ;and load it into IZData instead of 0 ld a,c ;now get back the actual op code NotFD: cp $CB ;special handling for $CB ops jr z,ItsCB cp $ED ;special handling for $ED ops jr z,ItsED cp $40 ;if $40<=opcode<$C0, the opcode uses jr c,NonConformist ;standard ,A ,B ,C ... naming cp $C0 jr c,Conformist sub $80 jr NonConformist ItsED: call PutByte ;get the new opcode... sub $40 cp $3C jr c,ItsEDOK sub $24 ;there is a gap in the table to save ;space where there were no commands ItsEDOK: ld hl,Table3 ;point to table 3 jr NonConformist ItsCB: call PutByte ;get opcode... ld hl,Table2 ;point to table2 jr Commons ;go to "common" area, for either ;conforming opcodes or CB opcodes Conformist: sub $40 ld hl,Table0 Commons: push af and %11111000 rra \ rra \ rra call GetTable ;this gets the opcode translation call DispString pop af and %00000111 ld hl,Table9 ;this gets the ,A ,B ,C ... translate NonConformist: call GetTable call DispString ld hl,_penCol ld (hl),$00 inc hl ld a,$06 add a,(hl) ld (hl),a pop bc dec b jp nz,Loop WaitkeyLoop: call _getkey+$4000 cp kUp jr z,ScrollUp cp kDown jr z,ScrollDown cp kExit jr z,ExitEverything call ScrollDowny jp ChangeStuff ScrollDown: call ScrollDowny jp DisplayScreen ScrollDowny: ;the program uses a "stack" to keep track of ld hl,Stack+$1800-1-3 ;where you've been. this is how the UP key ld de,Stack+$1800-1-0 ;works - essentially a BACK feature ld bc,$1800-3 lddr ld hl,(SaveAddress) in a,(5) ld (Stack),a ld (Stack+1),hl ret ScrollUp: ld a,(Stack) out (5),a ld ix,(Stack+1) ld hl,Stack+3 ld de,Stack ld bc,$1800-3 ldir jp DisplayScreen ExitEverything: res shiftALock,(IY+shiftflags) res shiftAlpha,(IY+shiftflags) ld a,$0D ;I dunno if this is necessary out (5),a ;but I put it there anyway - call _clrScrn ;it allows this back into normal rom ret DispString: ld a,(hl) inc hl or a ret z cp '!' ;a ! in a string in the table shows jr nz,NotRel ;that we need a relative address show push hl call PutByte push ix pop hl ld e,a ld d,$00 cp $80 jr c,Positive ld d,$FF Positive: add hl,de ld a,'$' call Prot_vputmap call DispHexHL pop hl jr DispString NotRel: cp '#' ;# indicates a byte value to show jr nz,NotByte ld a,'$' call Prot_vputmap call PutByte call DispHexA jr DispString NotByte: cp '%' ;% indicates a word value to show jr nz,NotWord push hl ld a,'$' call Prot_vputmap call PutByte ld l,a call PutByte ld h,a call DispHexHL pop hl jr DispString NotWord: cp '@' ;@ indicates that HL, IX, or IY needs ;to be displayed according to the ;calculations done in the main part jr nz,NotOffset push hl ld hl,IZFlag call _vputs+$4000 pop hl ld a,(IZData) or a jr z,DispString ld c,'+' cp $80 jr c,IZPositive ld c,'-' neg IZPositive: push af ld a,c call Prot_vputmap ld a,'$' call Prot_vputmap pop af call DispHexA jr DispString NotOffset: cp $80 ;if a value is greater than $80, it ;indicates further compression jr c,NotCompressed sub $80 push hl ld hl,Table6 ;this table is a compression table call GetTable call _vputs+$4000 pop hl jp DispString NotCompressed: call Prot_vputmap jp DispString GetTable: ;another driving force of the prog, ;this does a look-up in a table of ;null-terminated strings or a ret z ld b,a GetTableLoop: ld a,(hl) inc hl or a jr nz,GetTableLoop djnz GetTableLoop ret DispAddress: ;displays address with ROM page in a,(5) call DispDigit ld a,':' call Prot_vputmap ; ld de,$8000 ; push hl ; or a ; sbc hl,de ; pop hl ; jr c,DispHexHL ; sbc hl,de DispHexHL: ld a,h call DispHexA ld a,l call DispHexA ret DispHexA: push hl push af and 11110000b rra rra rra rra call DispDigit pop af push af and 00001111b call DispDigit pop af pop hl ret DispDigit: add a,'0' cp '9'+1 jr c,DispDigitOK add a,'A'-'9'-1 DispDigitOK: Prot_vputmap: push ix call _vputmap+$4000 pop ix ret PutByte: ;this gets & displays a byte ld a,(ix) ;ix is current mem location ld c,a ;store this value ld a,(_penCol) ;switch the menu x value push af ld a,(CurPos) ld (_penCol),a ld a,c call DispHexA ;diplay the byte ld a,(_penCol) ;switch the menu x value back ld (CurPos),a pop af ld (_penCol),a ld a,c ;reload the loaded byte inc ix ;increase mem pointer ret ;! = $relative address ;@ = HL,IX(+$xx),IY(+$xx) ;# = $xx ;$ = $xxxx ;hope you can't make sense of much of this - it's compressed! Table0: .db "€B,",0 .db "€C,",0 .db "€D,",0 .db "€E,",0 .db "€H,",0 .db "€L,",0 .db "€(@™",0 .db "€A,",0 .db "„A,",0 .db "…A,",0 .db "†",0 .db "‡A,",0 .db "AND ",0 .db "Ÿ",0 .db "OR ",0 .db "CP ",0 Table1: .db "NOP",0 .db "€”,%",0 .db "€(”™A",0 .db "ˆ”",0 .db "ˆB",0 .db "‰B",0 .db "€B,#",0 .db " CA",0 .db "EX —,—",39,0 .db "„@,”",0 .db "€A˜”)",0 .db "‰”",0 .db "ˆC",0 .db "‰C",0 .db "€C,#",0 .db "‘CA",0 .db "DJ› !",0 .db "€•,%",0 .db "€(•™A",0 .db "ˆ•",0 .db "ˆD",0 .db "‰D",0 .db "€D,#",0 .db " A",0 .db "Š!",0 .db "„@,•",0 .db "€A˜•)",0 .db "‰•",0 .db "ˆE",0 .db "‰E",0 .db "€E,#",0 .db "‘A",0 .db "Š›,!",0 .db "€@,%",0 .db "€(%™@",0 .db "ˆ@",0 .db "ˆH",0 .db "‰H",0 .db "€H,#",0 .db "DAA",0 .db "ŠZ,!",0 .db "„@,@",0 .db "€@˜%)",0 .db "‰@",0 .db "ˆL",0 .db "‰L",0 .db "€L,#",0 .db "CPL",0 .db "Šœ,!",0 .db "€–,%",0 .db "€(%™A",0 .db "ˆ–",0 .db "ˆ(@)",0 .db "‰(@)",0 .db "€(@™#",0 .db "SCF",0 .db "ŠC,!",0 .db "„@,–",0 .db "€A˜%)",0 .db "‰–",0 .db "ˆA",0 .db "‰A",0 .db "€A,#",0 .db "CCF",0 .db "Ž ›",0 .db "‘”",0 .db "‹›,%",0 .db "‹%",0 .db "Œ›,%",0 .db "’”",0 .db "„A,#",0 .db "00",0 .db "Ž Z",0 .db "Ž",0 .db "‹Z,%",0 .db 0 .db "ŒZ,%",0 .db "Œ%",0 .db "…A,#",0 .db "08",0 .db "Ž œ",0 .db "‘•",0 .db "‹œ,%",0 .db "#™A",0 .db "Œœ,%",0 .db "’•",0 .db "†#",0 .db "10",0 .db "Ž C",0 .db "EXX",0 .db "‹C,%",0 .db "A˜#)",0 .db "ŒC,%",0 .db 0 .db "‡A,#",0 .db "18",0 .db "Ž PO",0 .db "‘@",0 .db "‹PO,%",0 .db "EX (–™@",0 .db "ŒPO,%",0 .db "’@",0 .db "AND #",0 .db "20",0 .db "Ž PE",0 .db "‹(@)",0 .db "‹PE,%",0 .db "EX •,@",0 .db "ŒPE,%",0 .db 0 .db "Ÿ#",0 .db "28",0 .db "Ž P",0 .db "‘—",0 .db "‹P,%",0 .db "DI",0 .db "ŒP,%",0 .db "’—",0 .db "OR #",0 .db "30",0 .db "Ž M",0 .db "€–,@",0 .db "‹M,%",0 .db "EI",0 .db "ŒM,%",0 .db 0 .db "CP #",0 .db "38",0 Table2: .db " C ",0 .db "‘C ",0 .db "  ",0 .db "‘ ",0 .db "SLA ",0 .db "SRA ",0 .db "SL1 ",0 .db "S  ",0 .db "0,",0 .db "1,",0 .db "2,",0 .db "3,",0 .db "4,",0 .db "5,",0 .db "6,",0 .db "7,",0 .db "‚0,",0 .db "‚1,",0 .db "‚2,",0 .db "‚3,",0 .db "‚4,",0 .db "‚5,",0 .db "‚6,",0 .db "‚7,",0 .db "ƒ0,",0 .db "ƒ1,",0 .db "ƒ2,",0 .db "ƒ3,",0 .db "ƒ4,",0 .db "ƒ5,",0 .db "ƒ6,",0 .db "ƒ7,",0 Table3: .db "B˜š",0 .db "C™B",0 .db "‡@,”",0 .db "€(%™”",0 .db "NEG",0 .db "ŽN",0 .db "“0",0 .db "€I,A",0 .db "C˜š",0 .db "C™C",0 .db "…@,”",0 .db "€”˜%)",0 .db 0 .db "ŽI",0 .db 0 .db "€R,A",0 .db "D˜š",0 .db "C™D",0 .db "‡@,•",0 .db "€(%™•",0 .db 0 .db 0 .db "“1",0 .db "€A,I",0 .db "E˜š",0 .db "C™E",0 .db "…@,•",0 .db "€•˜%)",0 .db 0 .db 0 .db "“2",0 .db "€A,R",0 .db "H˜š",0 .db "C™H",0 .db "‡@,@",0 .db 0 .db 0 .db 0 .db 0 .db "‘D",0 .db "L˜š",0 .db "C™L",0 .db "…@,@",0 .db 0 .db 0 .db 0 .db 0 .db " D",0 .db 0 .db 0 .db "‡@,–",0 .db "€(%™–",0 .db 0 .db 0 .db 0 .db 0 .db "A˜š",0 .db "C™A",0 .db "…@,–",0 .db "€–˜%)",0 .db "LDI",0 .db "CPI",0 .db "INI",0 .db "OUTI",0 .db 0 .db 0 .db 0 .db 0 .db "LDD",0 .db "CPD",0 .db "IND",0 .db "OUTD",0 .db 0 .db 0 .db 0 .db 0 .db "LD",0 .db "CP",0 .db "IN",0 .db "OT",0 .db 0 .db 0 .db 0 .db 0 .db "LDž",0 .db "CPž",0 .db "INž",0 .db "OTž",0 Table6: .db "LD ",0 ;€ 128 .db "BIT ",0 ; 129 .db "RES ",0 ;‚ 130 .db "SET ",0 ;ƒ 131 .db "ADD ",0 ;„ 132 .db "ADC ",0 ;… 133 .db "SUB ",0 ;† 134 .db "SBC ",0 ;‡ 135 .db "INC ",0 ;ˆ 136 .db "DEC ",0 ;ˆ 137 .db "JR ",0 ;Š 138 .db "JP ",0 ;‹ 139 .db "CALL ",0 ;Œ 140 .db "RST $",0 ; 141 .db "RET",0 ;Ž 142 .db "OUT (",0 ; 143 .db "IN ",0 ; 144 .db "POP ",0 ;‘ 145 .db "PUSH ",0 ;’ 146 .db "IM ",0 ;“ 147 .db "BC",0 ;” 148 .db "DE",0 ;• 149 .db "SP",0 ;– 150 .db "AF",0 ;— 151 .db ",(",0 ;˜ 152 .db "),",0 ;™ 153 .db "C)",0 ;š 154 .db "NZ",0 ;› 155 .db "NC",0 ;œ 156 .db "IR",0 ; 157 .db "DR",0 ;ž 158 .db "XOR ",0 ;Ÿ 159 .db "RL",0 ;  160 .db "RR",0 ;‘ 161 Table8: .db "HALT",0 Table9: .db "B",0 .db "C",0 .db "D",0 .db "E",0 .db "H",0 .db "L",0 .db "(@)",0 .db "A",0 ;logic used for DD and FD ;DD = use IX not @ ;FD = use IY not @ ;use addition/subtraction if: ; opcode & %00000111 = $06 ; or opcode & %11111000 = $70 ; or opcode & %11111110 = $34 ; or opcode & %11111111 = $CB TitleStr: ;123456789012345678901 .db " Disasm86 - v1.0.2 " .db " (C) 1998 Kirk Meyer ",0 MinorLCD: ld hl,$FD00 ld de,$FD01 ld bc,$03FF ld (hl),$00 ldir ret ConvertTable: .db $0A,$0B,$0C,$0D,$0E .db $0F,$FF,$FF,$FF,$FF .db $FF,$07,$08,$09,$FF .db $FF,$04,$05,$06,$FF .db $01,$02,$03,$FF .db $00 Stack: ;sorry, I got lazy with commenting toward the end here .end