;---------------------------------------------------------------------------- ; Z80 Debugger v1.1b, (C) LopSoft Research, 2005. ;---------------------------------------------------------------------------- org 0E000h display = 3C00h ;Display memory keyboard = 3800h ;Keyboard map nmi = 0066h restart = 06CCh ;Csak az attekinthetoseg miatt a display sorcimek ROW.0 = display + 0 * 64 ROW.1 = display + 1 * 64 ROW.2 = display + 2 * 64 ROW.3 = display + 3 * 64 ROW.4 = display + 4 * 64 ROW.5 = display + 5 * 64 ROW.6 = display + 6 * 64 ROW.7 = display + 7 * 64 ROW.8 = display + 8 * 64 ROW.9 = display + 9 * 64 ROW.10 = display + 10 * 64 ROW.11 = display + 11 * 64 ROW.12 = display + 12 * 64 ROW.13 = display + 13 * 64 ROW.14 = display + 14 * 64 ROW.15 = display + 15 * 64 ;billentyu kodok key.up = 10h key.down = 11h key.left = 12h key.right = 13h key.enter = 0Dh key.clr = 0Eh key.break = 0Fh start: ld a,0C3h ;JP ld hl,break ;NMI break address ld (41A6h),a ld (41A7h),hl ld hl,trap.rst ;Trap address RST 56-hoz ld (4012h),a ld (4013h),hl ld hl,init_msg ;Disp.re bejelentkezo szoveg @loop: ld a,(hl) ;Copy 00h-ig or a jp z,@1 call 0033h inc hl jr @loop @1: ld a,(nmi) ;Debug eprom? cp 31h jp nz,restart ;Igen, kilep, majd NMI-vel lehet ;visszalepni ;---------------------------------------------------------------------------- ;NMI - programfutas megszakitasa ;---------------------------------------------------------------------------- break: inc sp ;NMI-bol CALL-al jon ide. Nem oda, inc sp ;hanem az NMI-t kivalto cimre kell ;majd visszaterni push af ;save AF ld a,(debug_on) ;break rutin aktiv? or a jp nz,break.exit ;igen, megegyszer nem inditja el xor a ;NMI flag, nem kell cimkorrekcio jr break.common ;---------------------------------------------------------------------------- ;Breakpoint - program megszakitas RST 38h-val ;---------------------------------------------------------------------------- trap.rst: push af ;Save AF ld a,-1 ;PC korrekcio kell, mert RST utani ;cimre mutat break.common: ld (brk.correct),a ld a,-1 ;"Debugger on" flag ld (debug_on),a ;nem volt, most aktiv lesz inc a ld (4022h),a ;cursor off ld (reg.bc),bc ;osszes reg mentese ld (reg.de),de ld (reg.hl),hl pop hl ;Get AF ld (reg.af),hl pop hl ;PC cime megszakitaskor ld (reg.pc),hl ld (reg.sp),sp ex af,af' ;masodlagos reg.keszlet push af pop hl ld (reg.af1),hl exx ld (reg.bc1),bc ld (reg.de1),de ld (reg.hl1),hl ld (reg.ix),ix ld (reg.iy),iy ld a,i ld h,a ld a,r ld l,a ld (reg.ir),hl ld sp,dspbuff ;sajat stack call restore.brk ;brk adatok visszaallitasa ld hl,0 ;trace brk torlese ld (breakpoints+18),hl call main ;ok, belepes a debugger-be call store.brk ;brk pontok beallitasa ld hl,(reg.af1) ;masodlagos regiszterek vissza push hl pop af ex af,af' ld bc,(reg.bc1) ld de,(reg.de1) ld hl,(reg.hl1) exx ld sp,(reg.sp) ld hl,(reg.pc) push hl ld hl,(reg.af) push hl ld bc,(reg.bc) ld de,(reg.de) ld hl,(reg.hl) ld ix,(reg.ix) ld iy,(reg.iy) xor a ;"Debugger on" flag torlese ld (debug_on),a break.exit: pop af ret ;---------------------------------------------------------------------------- ;Breakpoint-ok beallitasa ;---------------------------------------------------------------------------- store.brk: ld hl,breakpoints ;Tablazat kezdete ld ix,brk.data ;Eredeti kodnak buffer ld b,10 ;Max 9+1 brk. van @1: ld e,(hl) ;Get Brk address inc hl ld d,(hl) inc hl ld a,d ;Addr = 0? or e jr z,@2 ;Igen, nincs brk. beallitva ex de,hl ld a,(hl) ;Eredeti kod ld (ix+0),a ; mentese ld (hl),255 ;RST 38h a helyere ex de,hl @2: inc ix ;next djnz @1 ret ;---------------------------------------------------------------------------- ;Breakpoint kodok torlese, eredeti visszaallitasa ;---------------------------------------------------------------------------- restore.brk: ld hl,breakpoints ;Brk cim tablazat ld ix,brk.data ;Eredeti kodok ld b,10 ;9+1 brk van. @1: ld e,(hl) ;Get addr inc hl ld d,(hl) inc hl ld a,d ;Addr = 0? or e jr z,@2 ld a,(ix+0) ;Restore orig. code ld (de),a @2: inc ix ;next djnz @1 ld a,(brk.correct) ;Brk RST-vel? or a ret z ;Nem, NMI, ok ld hl,(reg.pc) ;RST, a kovetkezo cimre mutatna, dec hl ;vissza kell lepni egyet ld (reg.pc),hl ret ;---------------------------------------------------------------------------- ; Main loop rutin ;---------------------------------------------------------------------------- main: ld de,dspbuff ;Main display mentese buffer-be ld hl,display ld bc,1024 ldir ld hl,display ;Kepernyotorles ld de,display+1 ld bc,1023 ld (hl),' ' ldir ld hl,(reg.pc) ;hol allt meg ld (asm.addr),hl ;Asm lista PC-re all @1: call view.regs ;Regiszterek disp.re call view.stack ;Stack tartalom call view.flags ;Flag-ek call view.ndx ;(BC),(DE),(HL) call view.dump ;Dump disp.re call view.brk ;Breakpoint lista call draw.lines ;Kreretek call view.asm ;ASM lista disp.re, mozgas benne ;ha mas bill. akkor lep ki es ;annak a kodjaval ter vissza call key.exec ;Bill. funkciok vegrehajtasa cp 'G' ;Go key? jr nz,@1 ;nem, refresh @2: xor a ;run, de elobb az osszes bill.t ld hl,3880h ;fel kell engedni, ne kavarjon be @3: or (hl) rrc l jr nc,@3 ;oszes sort beolvasta? or a jr nz,@2 ;van lenyomott bill? ld de,display ;Main screen visszaallitasa ld hl,dspbuff ld bc,1024 ldir ret ;--------------------------------------------------------------------------- ; L - command: load - file betoltese magnorol ; ; Keri a file nevet, ha nem cas, vagy nem talalja, error ; A dump ablakot hasznalja ;--------------------------------------------------------------------------- load: ld hl,ROW.12 ;Dump ablak cime ld de,10 ;54 ch. szeles, a kov. sorig 10 ch. ld c,4 ;4 sor magas @1: ld b,54 @2: ld (hl),' ' ;Torles inc hl djnz @2 add hl,de ;next line dec c jr nz,@1 ld de,file.msg ;'FILE: ' disp.re ld hl,ROW.12 call print ;dump ablak 1. soraba push hl pop de ld b,6 ;max 6 ch. a filenev @3: call getkey ;bill.re var villogo cursorral cp key.left ;elozo ch. torlese jr z,@4 cp key.enter jr z,@5 cp '0' ;break v. clr key? ret c ;igen, kilep cp '9'+1 jr c,@6 ;ok, szam cp 'A' jr c,@3 cp 'Z'+1 ;ha nem betu, ujat ker jr nc,@3 @6: inc b ;6 ch. megvolt? dec b jr z,@3 ;igen, ey mar sok lenne ld (hl),a ;disp.re inc hl ;ok, next dec b jr @3 ;utolso ch. torlese @4: ld a,b ;cursor? cp 6 jr z,@3 ;elso poz. nincs mit torolni dec hl inc b ld (hl),' ' ;egyet vissyalepett es torli az jr @3 ;utolso ch.t ;betoltes @5: ex de,hl ;HL a file nev elejen call 0293h ;Szintbeallitas olvasashoz call 0235h ;1 byte beolvasasa cp 55h ;header jr nz,@err0 ld b,6 ;file nev hoszza @7: ld a,(hl) ;disp.rol olvassa vissza cp ' ' ;vege? jr z,@begin ;igen, ok a nev, johet a file call 0235h ;nev szalagrol cp (hl) ;stimmel? jr nz,@err1 ;nem, leall inc hl djnz @7 @begin: ld de,loading.msg ;'LOADING' disp.re call print.l2 ;dump ablak 2.sora ld hl,ROW.15 ;legalso sorba a futo csik elso ld b,8 ;fazisa: 8 ch. szeles lesz @8: ld (hl),255 inc hl djnz @8 ld a,64 ;csak 64 byte-onkent lepked majd ld (column),a @9: call @shift ;futtatja a csikot, ha kell es ;beolvas egy karaktert cp 78h ;End of File? jr z,@eof ;igen, mar csak a startcim van hatra cp 3Ch ;Block header? jr nz,@9 ;nem, tovabb keres call @shift ;Blokkhossz beolvasasa ld b,a call @addr ;hova toltse? @10: call @shift ;Blokk betoltese ld (hl),a inc hl djnz @10 call @shift ;checksum, nem foglalkozok vele jr @9 ;kov. blokkra @eof: call @addr ;start cim beolv. ld (asm.addr),hl ;ASM ablak es PC oda all ld (reg.pc),hl ret ;HL-be beolvas egy cimet @addr: call @shift ld l,a call @shift ld h,a ret @err0: ld de,error0.msg ;Wrong file jr @err @err1: ld de,error1.msg ;File not found @err: call print.l2 jp getkey ;Var egy bill-re es kilep load-bol ;egy karakter beolvasasa magnorol, es a status csik leptetese, ha kell @shift: ld a,(column) ;statust kell shiftelni? dec a ld (column),a jr nz,@12 ;meg nem, csak beolvasas ld a,64 ;restart counter ld (column),a ld ix,ROW.15 + 53 ;also sor vegere all (dump ablakban) push bc ld c,(ix+0) ;save last ch. ld b,53 @11: dec ix ;a sor jobbra megy ld a,(ix+0) ld (ix+1),a djnz @11 ld (ix+0),c ;first ch. <- last ch. pop bc @12: call 0235h ;ch magnorol ret print.l2: ld hl,ROW.13 ;dump ablak 2. sora print: ld a,(de) ;szoveg disp.re 00h-ig or a ret z ld (hl),a inc de inc hl jr print ;---------------------------------------------------------------------------- ;DE kiiratasa (HL)-re hexaban ;---------------------------------------------------------------------------- hexw: ld a,d call hex ld a,e ;---------------------------------------------------------------------------- ;A kiiratasa (HL)-re hexaban ;---------------------------------------------------------------------------- hex: push af rlca ;Felso 4 bit rlca rlca rlca call @@1 ;Atalakitas hexara ;s kiiras pop af ;Eredeti byte @@1: and 0Fh ;Also 4 bit marad cp 10 ;szam? jr c,@@2 ;Igen, +30h add a,7 ;30h+10 es 41h kozti kulonbseg @@2: add a,'0' ;Ascii ld (hl),a inc hl ret ;------------------------------------------------------------------------- ; Regiszterek kiirasa a display-re ;------------------------------------------------------------------------- view.regs: push bc push hl push ix ld ix,reg.name ;Regiszternevek ld iy,registers ;Regiszter ertekek ld b,6 ;6 reg. ld hl,ROW.0+46 ;row:0 col:46 call @@1 ;Kiiratas (af,bc,de,hl,sp,ix) ld b,6 ;masik 6 reg. melle ld hl,ROW.0+56 ;(af',bc',de',hl',ir,iy) call @@1 ld b,1 ;PC kulon ablakba kerul ld hl,ROW.0+37 call @@1 pop ix pop hl pop bc ret @@1: call @@2 ;Reg. nev masolasa disp.re call @@2 ;(3 karakter) call @@2 ld (hl),':' ;elvalaszto kettospont inc hl ld e,(iy+0) ;reg. ertek DE-be inc iy ld d,(iy+0) inc iy call hexw ;display-re ld de,64-8 ;kovetkezo sor (vissza 8 kar.) add hl,de djnz @@1 ret @@2: ld a,(ix+0) ;1 karakter masolasa display-re ld (hl),a inc ix inc hl ret ;------------------------------------------------------------------------- ; Stack kiirasa a display-re ;------------------------------------------------------------------------- view.stack: ld hl,ROW.15+56 ;row:15 col:56 ld ix,(reg.sp) ;stack cime ld b,4 ;a stack 4 felso szava ld c,'0' ;'+00'-tol indul @@1: ld (hl),'+' ;egy sor kiirasa inc hl ld (hl),'0' inc hl ld (hl),c inc hl ld (hl),':' inc hl ld e,(ix+0) ;stack adat elo DE-be ld d,(ix+1) inc ix ;kovetkezo elemre all inc ix inc c ;'+0n' novelese 2-vel inc c call hexw ;display-re ld de,-64-8 ;egy sort fel (es balra 8 kar.) add hl,de djnz @@1 ret ;------------------------------------------------------------------------- ; Flag-ek kiirasa a display-re ;------------------------------------------------------------------------- view.flags: ld a,(reg.af) ;Flag-ek B-be ld b,a ld hl,ROW.7+46 ;row:7 col:46 ld ix,flag.name ;Falg nevek call @2out ;S, Z rlc b ;nem hasznalt call @out ;H rlc b ;nem hasznalt ld hl,ROW.7+52 ;row:7 col:52 call @out ;P @2out: call @out ; (N, C) @out: ld a,(ix+0) ;Falg neve display-re inc ix ld (hl),a inc hl ld (hl),':' inc hl ld a,'0' ;Flag ertek A-ba ('0' v '1') rlc b adc a,0 ld (hl),a ;disp.re ld de,62 add hl,de ret ;------------------------------------------------------------------------- ; reg.indexek kiirasa disp.re ;------------------------------------------------------------------------- view.ndx: ld hl,ROW.7+56 ;row:7 col:56 ld ix,reg.bc ;BC-re all ld iy,reg.name+3 call @1 ;(BC) call @1 ;(DE) ;(HL) @1: ld (hl),'(' ;'(' inc hl call @2 ;2ch. reg. nev call @2 inc iy ;skip space ld (hl),')' ;')' inc hl inc hl ;' :' ld (hl),':' inc hl ld e,(ix+0) ;Regiszter elo ld d,(ix+1) inc ix ;kov.re all inc ix ld a,d ;test display memory area and 0FCh cp 3Ch jr nz,@3 ;nem dspmem ex de,hl ;ha igen, akkor a bufferbol kell ld bc,dspbuff-3C00h ;kiolvasni az adatot add hl,bc ex de,hl @3: ld a,(de) ;adat disp-re call hex ld de,56 ;next line add hl,de ret @2: ld a,(iy+0) ;1ch copy disp.re inc iy ld (hl),a inc hl ret ;------------------------------------------------------------------------- ; Dump lista kiirasa a display-re (4x16 byte) ;------------------------------------------------------------------------- view.dump: push bc push de push hl ld hl,ROW.12 ;row:12 col:0 ld de,(dump.addr) ;mem cim call @line ;1 sor call @line call @line call @line pop hl pop de pop bc ret @line: call hexw ;cim kiirasa ld (hl),':' inc hl ld (hl),' ' inc hl ld b,16 ;16 byte @loop: push de ;disp mem corr. ld a,d ;test display memory area and 0FCh cp 3Ch ld a,(de) jr nz,@1 ;nem dspmem push bc ex de,hl ;ha igen, akkor a bufferbol kell ld bc,dspbuff-3C00h ;kiolvasni az adatot add hl,bc ex de,hl pop bc ld a,(de) ;byte bufferbol @1: pop de call hex ld (hl),' ' inc hl inc de djnz @loop ld bc,64-54 ;kov. sor elejere all add hl,bc ret ;------------------------------------------------------------------------- ;az elvalaszto vonalak rajzolasa ;------------------------------------------------------------------------- draw.lines: ld hl,ROW.11 ;row:11 col:0 ld b,64 ;teljes sor call hline ;(horizontal line) ld hl,ROW.6+46 ;row:6 col:46 ld b,18 ;18 kar. call hline ld hl,ROW.1+37 ;row:1 col:37 ld b,8 call hline ld de,64 ;vline soremeles ld hl,ROW.0+45 ;row:0 col:45 ld b,11 ;11 sor call vline ;(vertical line) ld hl,ROW.2+36 ;row:2 col:36 ld b,9 call vline ld a,0CEh ;a vonalak talalkozasa ld (ROW.11+36),a ld (ROW.11+45),a ld a,0ECh ld (ROW.11+54),a ld a,0EAh ld (ROW.0+36),a ld (ROW.1+36),a ld a,0EEh ld (ROW.1+45),a ld hl,ROW.12+54 ;row:12 col:54 ld b,4 ;4 sor vline: ld (hl),0EAh ;fuggoleges vonal add hl,de djnz vline ret hline: ld (hl),0CCh inc hl djnz hline ret ;------------------------------------------------------------------------- ; breakpoint lista kiirasa ;------------------------------------------------------------------------- view.brk: ld hl,ROW.2+37 ld ix,breakpoints ld bc,0931h ;9 lines, '1' @1: push hl ;save crs pos. ld (hl),'B' ;'Bn :' inc hl ld (hl),c inc hl inc hl ld (hl),':' inc hl inc c ;Kov. sorszam ld e,(ix+0) ;Brk. addr? ld d,(ix+1) ld a,d or e jr nz,@2 ;0? ld (hl),'-' ;igen, '----' inc hl ld (hl),'-' inc hl ld (hl),'-' inc hl ld (hl),'-' jr @3 @2: call hexw ;ok, cim kiirasa @3: inc ix inc ix pop hl ld de,64 ;next line add hl,de djnz @1 ret ;------------------------------------------------------------------------- ; ASM lista kiirasa a display-re (1 elozo + 10 kov. sor) ;------------------------------------------------------------------------- view.asm: call prev.addr ;megkeresi az elozo utasitas cimet ld (address),hl ld hl,ROW.0 ;row:0 col:0 ld b,11 ;11 sor lesz @@1: push bc push hl call @@2 ;1 utasitas dekodolasa pop de push de ld bc,35 ;35 karaktert masol disp.re ld hl,buffer ldir pop hl ld bc,64 ;next line add hl,bc pop bc djnz @@1 @1: ld hl,ROW.1 ;Cursor a lista 2.soraba call getkey jr z,@1 cp key.up jr z,@up cp key.down jr z,@down cp key.left jr z,@pgup cp key.right jr z,@pgdn ret @up: call prev.addr ;elozo ut. cime ld (asm.addr),hl ;majd ebbol indul ki jr view.asm @down: ld hl,(asm.addr) ;egy sort megy le ld (address),hl call decode @pgdn: ld hl,(address) ;itt a lista vegen allt ld (asm.addr),hl jr view.asm @pgup: ld b,10 @2: push bc call prev.addr ld (asm.addr),hl pop bc djnz @2 jr view.asm @@2: ld hl,(address) ;ut. cime push hl call decode pop de ;cim elo push de call find.brk ;breakpoint keresese jr nc,@@3 ;nincs ld a,'B' ;'B' a sor elejere, ha van brk. ld (buffer),a @@3: pop de ;PC is itt all? ld a,(reg.pc+1) sub d ret nz ld a,(reg.pc) sub e ret nz ld a,'>' ;igen, '>' jelzi ld (buffer+1),a ret ;DE cim keresese breakpoints tablazatban (C=1 ha van) find.brk: ld b,10 ;9+1 brk van push hl ld hl,breakpoints+19 @@1: ld a,d ;cim egyezik? sub (hl) dec hl jr nz,@@2 ;nem, tovabb ld a,e sub (hl) jr nz,@@2 ld a,d or e jr z,@@2 pop hl scf ;C <- 1, found ret @@2: dec hl djnz @@1 or a pop hl ret ;---------------------------------- ;Elozo utasitas cimenek megkeresese ;---------------------------------- prev.addr: ld hl,(asm.addr) ;A lista baziscime ld a,l ;visszalep 16 byte-ot sub 16 ld l,a ld a,h sbc a,0 ld h,a ld b,4 ;4 proba lesz @2: push bc push hl ld (address),hl @3: ld hl,(address) push hl call decode ld hl,(asm.addr) ld de,(address) call 1C90h ;compare DE,HL jr z,@4 ;match, ok megvan pop hl jr nc,@3 ;tulfutott? pop hl ;igen, a keresesi cim novelese inc hl pop bc ;4 kiserlet megvolt? djnz @2 ld hl,(asm.addr) ;elmeletileg ide csak ritkan dec hl ;fog eljutni.. nincs talalat, ret ;1 byte-ot lep vissza. @4: pop hl pop bc pop bc ret ;--------------------------------------- ;billentyuzet lekerdezes ;--------------------------------------- kbdread: call toggle.scr ;toggle screen, ha shift ld hl,3880h ;rasztersor elejet fogja cimezni ld de,kbdbuffer-1 ;bill. elozo allapota ld c,'@'-8 ;elso sor call @1 ;test @..G call @1 ;test H..O call @1 ;test P..W call @1 ;test X..Z ld c,'0'-8 ;szamok jonnek call @1 ;test 0..7 call @1 ;test 8.. ld c,13-8 ;cr.. call @1 ;test control keys xor a ;no key, exit ret @1: ld a,c ;key code correction add a,8 ld c,a rlc l ;next raster inc de ;next buffer ld a,(de) ;get old state ld b,a ;save ld a,(hl) ;get kbd state ld (de),a ;save new state xor b ;valtozas ? and (hl) ;lenyomas? ret z ;nem, kesz @2: rrca ;search correct keycode jr c,@3 inc c jr @2 @3: pop hl ;clear stack ld a,c ;get keycode cp 14h ;space? ret nz ;no, ready ld a,' ' ;spc code or a ret ;------------------------------------------------ ;shift-re toggle screen, amig nyomva van ;------------------------------------------------ toggle.scr: ld a,(3880h) ;shift key raster line rrca ret nc ;nincs, ret call swap.scr ;display swap @1: ld a,(3880h) rrca jr c,@1 ;------------------------------------------------ ;swap.scr - felcsereli a ket kepernyo tartalmat ;------------------------------------------------ swap.scr: ld bc,1024 ;dsp. length ld de,dspbuff ;dsp. buffer ld hl,display ;main display @1: ld a,(de) ;swap bytes ex af,af' ld a,(hl) ld (de),a ex af,af' ld (hl),a inc de ;next pos inc hl dec bc ;counter down ld a,b or c jr nz,@1 ret ;------------------------------------------------ ;getkey - egy bill.re var, kozben villog a cursor ; HL display address ;------------------------------------------------ getkey: push bc push de push hl @loop: ld d,(hl) ;get char ld (hl),8Fh ;cursor char ld bc,300 ;rovidebb varakozas call @1 ld (hl),d ;orig. char jr nz,@exit ld bc,650 ;hosszabb varakozas call @1 jr z,@loop @exit: pop hl pop de pop bc ret @1: push de ;BC ideig vagy bill. lenyomasig var push hl @2: push bc call kbdread pop bc jr nz,@3 dec bc ld a,b or c jr nz,@2 @3: pop hl pop de ret ;--------------------------------------------------------------------------- ;hexedit - edit A (2 or 4) width hex area ; ;input: - HL display address, D or DE old data ;output: - D or DE new data, A exit key ; ;keys: left - exit when crs in first pos, or move crs left ; right - exit when crs in last pos, or move crs right ; up,down,enter - exit with new data ; crl, break - exit without changes ;--------------------------------------------------------------------------- hexedit: push de ;save old data push bc push hl ld b,0 ;crs = 0 ld c,a @loop: call getkey cp key.enter ;Enter jr z,@exit cp key.up ;Up jr z,@exit cp key.down ;Down jr z,@exit cp key.clr ;CLR jr z,@quit cp key.break ;Break jr nz,@main @quit: pop hl ;restore input state push hl ;restore display push af ld a,d ;original data call hex ld a,c ;width 2 or 4? cp 3 jr c,@quit1 ld a,e ;width 4 call hex @quit1: pop af pop hl pop bc pop de scf ;'break' flag ret @exit: pop hl ;restore data begin push hl ld b,4 ;convert display data to DE push af @1: ld a,(hl) ;egy karakter ascii -> hex sub '0' cp 10 jr c,@2 sub 7 @2: ex de,hl ;SHL DE,4 add hl,hl add hl,hl add hl,hl add hl,hl ex de,hl and 15 ;+ value or e ld e,a ;store inc hl djnz @1 pop af pop hl pop bc inc sp inc sp or a ret @main: cp key.left ;left key jr z,@left cp key.right ;right key jr z,@right cp '0' jr c,@loop ;Csak hex karakterekkel foglalkozik cp 'F'+1 jr nc,@loop cp '9'+1 jr c,@3 cp 'A' jr c,@loop @3: ld (hl),a ;Disp.re @right: inc hl ;kov. karakterre inc b ;cursor ld a,b cp c ;mezo vege? ld a,key.right ;last key jr z,@exit ;ha igen, kilep jr @loop @left: ld a,b ;cursor or a ld a,key.left ;last key jr z,@exit ;elso kar.en allt, kilep dec hl ;egyet balra dec b jr @loop ;--------------------------------------------------------------------------- ; execute key functions ;--------------------------------------------------------------------------- key.exec: cp key.enter ;Enter? jp z,exec ;execute (same as E) cp 'A' ;asm addr jr z,edit.asm cp 'D' ;Dump window? jr z,edit.dump cp 'B' ;Toggle breakpoint jp z,toggle.brk cp 'N' ;new pc jp z,new.pc cp 'P' ;goto pc jp z,goto.pc cp 'R' ;reg. edit jp z,reg.edit cp 'F' ;flag edit jp z,flag.edit cp 'T' ;trap jp z,trap cp 'E' ;execute jp z,exec cp 'U' jp z,go.break cp 'L' ;load file jp z,load cp '1' ;1-9 goto brk addr. ret c cp '9'+1 ret nc jp goto.brk ;---------------------------------------------------------------------------- ;U - A cursor cimig futtatja a programot ;---------------------------------------------------------------------------- go.break: ld hl,(asm.addr) ;Cursor poz. cime ld (breakpoints+18),hl ;a +1 brkpont lesz a megsz. ld a,'G' ;Go command! ret ;---------------------------------------------------------------------------- ;A - Asm lista cimbevitel ;---------------------------------------------------------------------------- edit.asm: ld hl,ROW.1+2 ;row:1, col:2 ld de,(asm.addr) ;get current address ld a,4 ;4 ch width call hexedit ;edit address ld a,' ' ;unused key ret c ;break input ld (asm.addr),de ;store new value ret ;---------------------------------------------------------------------------- ;D - Dump szerkesztese ;---------------------------------------------------------------------------- edit.dump.up: ld hl,(dump.addr) ;egy sorral feljebb lep sbc hl,bc dump.refresh: ld (dump.addr),hl ;store new address call view.dump ;refresh window ;belepes itt edit.dump: ld hl,ROW.12 ;dump window address ld de,(dump.addr) ;get address for edit ld a,4 ;4 ch width call hexedit ;edit address jr c,@1 ;break? not change ld (dump.addr),de ;store new address ld bc,16 ;16 byte egy sor cp key.up jr z,edit.dump.up ;egy sorral feljebb lep cp key.down jr nz,@1 ld hl,(dump.addr) ;egy sorral lejebb lep add hl,bc jr dump.refresh ;refresh address and window @1: cp key.break ;break? jr z,@2 ;ok, edit data (skip address) cp key.enter ;Enter? ret z ;ok, exit @2: ld hl,ROW.12+6 ;Adatmezo cime a disp.en ld ix,(dump.addr) ;mem address ld bc,0000h ;cursor pos (0,0) ;adatmezo szerkesztese dump: call view.dump ;refresh window push ix ;disp.mem? pop de push de pop iy ld a,d ;test display memory area and 0FCh cp 3Ch jr nz,@0 ;nem dspmem push bc ex de,hl ;ha igen, akkor a bufferbol kell ld bc,dspbuff-3C00h ;kiolvasni az adatot add hl,bc ex de,hl pop bc push de pop iy @0: ld d,(iy+0) ;get data ld a,2 ;2 ch width call hexedit ;edit data jr c,@1 ;brk / clear? ld e,a ;save key ld (iy+0),d ;store data ld a,(iy+0) ;be tudta irni? cp d jr nz,dump ;nem, nem ram, nem mozdul el ld a,e ;restore last key @1: cp key.break ;break? jr z,edit.dump ;igen, vissza a cim szerk.re cp key.up ;bill? ret c ;enter, clr: exit jr z,dump.up cp key.left jr z,dump.left ;left jr c,dump.down ;down cp key.right jr nz,dump inc c ;crs jobbra inc hl ;dsp. addr +3 ch. inc hl inc hl inc ix ;mem +3 ch ld a,c ;crs? cp 16 ;end of line? jr c,dump ;nem, ok ld c,0 ;crs sor elejere ld a,l ;disp. addr. sor elejere and 0C0h or 6 ld l,a ld de,-16 ;mem addr. sor elejere add ix,de dump.down: inc b ;crs down ld de,16 ;next line add ix,de ;(memptr) ld a,b ;out of window? cp 4 jr c,@1 ;nem, ok dec b ;crs vissza ld de,16 ;scroll window call dump.scroll ;calc. addr jr dump @1: ld de,64 ;csak a disp. addr. megy lejebb add hl,de jr dump dump.up: dec b ;crs fel jp p,@1 ;ablakban? igen -> inc b ;restore crs ld de,-16 ;scroll window call dump.scroll ;window addr jr @2 @1: ld de,-64 ;dsp ptr up add hl,de ld de,-16 ;memptr up @2: add ix,de jp dump dump.left: dec hl ;dsp ptr 3ch left dec hl dec hl dec ix ;memptr left dec c ;crs left jp p,dump ;ablakban? i -> ld c,15 ;crs sor vegere ld a,l ;dsp ptr sor vegere and 0C0h or 51 ld l,a ld de,16 ;memptr sor vege add ix,de jr dump.up ;scroll up dump.scroll: push hl ;scroll window ld hl,(dump.addr) add hl,de ld (dump.addr),hl pop hl ret toggle.brk: ld de,(asm.addr) ;Cursor addr ld ix,breakpoints ;Search ld b,9 ;9 brk @1: ld a,(ix+1) ;match? sub d jr nz,@2 ld a,(ix+0) sub e jr nz,@2 ld (ix+0),0 ;igen, delete brk ld (ix+1),0 ret @2: inc ix ;next inc ix djnz @1 ;nincs a tablaban, keres egy ures helyet ld ix,breakpoints ;table begin ld b,9 @3: ld a,(ix+0) ;ures? or (ix+1) jr nz,@4 ;nem, -> ld (ix+0),e ;store address ld (ix+1),d ret @4: inc ix ;next inc ix djnz @3 ret ;Table full ;---------------------------------------------------------------------------- ;1..9 - Go to brk address ;---------------------------------------------------------------------------- goto.brk: sub '1' ;convert to index add a,a ld e,a ld d,0 ;DE: index ld hl,breakpoints add hl,de ld e,(hl) ;get brk address inc hl ld d,(hl) ld a,d or e ret z ;empty? ld (asm.addr),de ;store new address ret ;---------------------------------------------------------------------------- ;N - new PC ;---------------------------------------------------------------------------- new.pc: ld hl,(asm.addr) ;PC <- Asm addr ld (reg.pc),hl ret ;---------------------------------------------------------------------------- ;P - go to PC addr ;---------------------------------------------------------------------------- goto.pc: ld hl,(reg.pc) ;Asm addr <- PC ld (asm.addr),hl ret ;---------------------------------------------------------------------------- ;R - Edit registers ;---------------------------------------------------------------------------- reg.edit: ld hl,ROW.0+50 ;row:0, col:50 ld ix,registers ;register array ld bc,0000h ;crs (0,0) reg.loop: call view.regs ;refresh ld e,(ix+0) ;get current reg. value ld d,(ix+1) ld a,4 ;4ch width call hexedit ;edit jr c,@1 ;break? ld (ix+0),e ;store new value ld (ix+1),d @1: cp key.enter ;enter: exit ret z cp key.clr ;clr: exit ret z cp key.up ;up? jr z,reg.up cp key.down ;down? jr z,reg.down cp key.break ;break? jr z,reg.tab cp key.left ;left jr z,reg.up cp key.right ;right jr nz,reg.loop reg.down: inc b ;next reg. inc ix inc ix ld de,64 ;crs down add hl,de ld a,b ;end of table? cp 6 jr c,reg.loop ld hl,ROW.0+50 ;first row ld de,-12 ;up 6 regs ld b,0 ;crs = 0 reg.set: ld a,l ;select side add a,c ld l,a add ix,de jr reg.loop reg.up: dec ix ;prev reg. dec ix ld de,-64 ;crs up add hl,de dec b jp p,reg.loop ;top? ld hl,ROW.5+50 ;last row ld de,12 ;down 6 regs. ld b,5 ;set crs jr reg.set reg.tab: ld (ix+0),e ;store new value ld (ix+1),d ld a,l ;switch side xor 14 ld l,a ld a,c ;set side xor 10 ld c,a ld de,-12 ;set reg. index jr z,@1 ld de,12 @1: add ix,de jr reg.loop ;---------------------------------------------------------------------------- ;F - Edit flags ;---------------------------------------------------------------------------- flag.edit: ld hl,ROW.7+48 ;A flag ertekekre all ra ld b,0 ;crs flag.loop: call getkey ;bill. cp key.clr ;clr/berak: exit ret z cp key.break ret z cp key.enter ;enter: read flags, exit jr z,flag.get cp key.left jr z,flag.up ;up/left: prev. flag cp key.right jr z,flag.down ;down/right: next flag cp key.up jr z,flag.up cp key.down jr z,flag.down cp '0' ;0/1 set jr z,@1 cp '1' jr nz,flag.loop @1: ld (hl),a ;disp.re flag.down: ld de,64 ;next row add hl,de inc b ld a,b cp 3 jr z,@1 ;next column cp 6 jr nz,flag.loop jr flag.edit ;first flag @1: ld hl,ROW.7+54 jr flag.loop flag.up: ld de,-64 ;prev. row add hl,de dec b jp m,@1 ld a,b cp 2 jr nz,flag.loop ld hl,ROW.9+48 jr flag.loop @1: ld hl,ROW.9+54 ;last flag ld b,5 jr flag.loop flag.get: ld a,(ROW.7+48) ;flag-ek visszaolvasasa call @1 ;disp.rol ld a,(ROW.8+48) call @1 xor a call @1 ld a,(ROW.9+48) call @1 xor a call @1 ld a,(ROW.7+54) call @1 ld a,(ROW.8+54) call @1 ld a,(ROW.9+54) call @1 ld a,(reg.af) and 28h or b ld (reg.af),a ret @1: rrca ;store value to B rl b ret ;---------------------------------------------------------------------------- ;E or Enter - Execute ;T - Trap ;---------------------------------------------------------------------------- exec: ld a,255 ;trap mode flag jr trap@1 trap: xor a @1: ld (trap.mode),a call jmp.test ;ugro utasitas? ha igen, vegrehajtja jp nc,goto.pc ;ok, ready, asm addr refresh ld hl,0 ;fill opcode buffer with NOP's ld (opcode+0),hl ld (opcode+2),hl ld hl,(reg.pc) ;utasitas hosszanak meghatarozasa ld (address),hl call decode ld hl,(address) ;length := new addr - old addr ld de,(reg.pc) or a sbc hl,de ld (trap.length),hl ld b,l ;utasitas hossza ld hl,(reg.pc) ;utasitas masolasa a vegrehajtashoz ld de,opcode @2: ld a,(hl) ld (de),a inc hl inc de djnz @2 call test.swap ;utasitas ir/olvas mem-et? push af call c,swap.scr ;"smart" screen swap ;visszaallitja az osszes eredeti regisztert, kiveve PC, ;majd vegrehajtja itt az utasitast. ;utana elmenti az uj reg. ertekeket ld (main.sp),sp ld a,(reg.ir+1) ;csak I reg. vissza, R nem erdekes ld i,a ld hl,(reg.af1) ;masodlagos regiszterek vissza push hl pop af ex af,af' ld bc,(reg.bc1) ld de,(reg.de1) ld hl,(reg.hl1) exx ld sp,(reg.sp) ld hl,(reg.af) push hl ld bc,(reg.bc) ld de,(reg.de) ld hl,(reg.hl) ld ix,(reg.ix) ld iy,(reg.iy) pop af opcode: dw 0,0 push af ;save AF ld (reg.bc),bc ;osszes reg mentese ld (reg.de),de ld (reg.hl),hl pop hl ld (reg.af),hl ld (reg.sp),sp ld sp,(main.sp) ex af,af' ;masodlagos reg.keszlet push af pop hl ld (reg.af1),hl exx ld (reg.bc1),bc ld (reg.de1),de ld (reg.hl1),hl ld (reg.ix),ix ld (reg.iy),iy ld a,i ld h,a ld a,r ld l,a ld (reg.ir),hl ;itt kesz ld hl,(reg.pc) ;uj PC szamolasa ld de,(trap.length) add hl,de ld (reg.pc),hl ld (asm.addr),hl ;asm is koveti pop af call c,swap.scr ;"smart" screen swap ret ;---------------------------------------------------------------------------- ;ugro utasitasok vegrehajtasa ;---------------------------------------------------------------------------- jmp.DD: ld a,(ix+1) cp 0E9h ;jp (ix/iy) ? scf ret nz ;nem, vissza jmp.ED: ld (reg.pc),hl or a ret jmp.ret: ld hl,(reg.sp) ld e,(hl) inc hl ld d,(hl) inc hl ld (reg.sp),hl ld (reg.pc),de or a ret jmp.test: ld ix,(reg.pc) ;get PC ld a,(ix+0) ;get opcode ld c,a ld hl,(reg.ix) ;eloszor jp (hl,ix,iy) test cp 0DDh ;ehhez mindig a megfelelo reg.et jr z,jmp.DD ;adja tovabb ld hl,(reg.iy) cp 0FDh jr z,jmp.DD ld hl,(reg.hl) cp 0E9h jr z,jmp.ED cp 0C9h ;RET ? jr z,jmp.ret cp 0C3h ;JP ? jr z,jmp.C3 cp 0CDh ;CALL ? jr z,jmp.CD cp 0EDh ;ED prefixxel csak a RETI/RETN van jr nz,@1 ld a,(ix+1) and 0F7h cp 45h ;RETI/RETN? jr z,jmp.RET scf ret @1: and 0C7h ;felteteles ugrasok? cp 0C2h ;jp cc? jr z,jmp.C2 cp 0C4h ;call cc? jr z,jmp.C4 cp 0C0h ;ret cc? jr z,jmp.C0 cp 0C7h ;rst nn? jr z,jmp.C7 jr jmp.rel ;relative? ;------------------------------------- ;JP cc,addr ;------------------------------------- jmp.C2: call test.cond ;utasitast vegre kell hajtani? jr z,jmp.C3 ;igen, jump skip: ld hl,(reg.pc) inc hl @3: inc hl @2: inc hl @1: ld (reg.pc),hl or a ret ;------------------------------------- ;JP addr ;------------------------------------- jmp.C3: ld l,(ix+1) ;get address ld h,(ix+2) jr skip@1 ;store new PC ;------------------------------------- ;CALL cc,addr ;------------------------------------- jmp.C4: call test.cond ;utasitast vegre kell hajtani? jr nz,skip ;nem, skip ;------------------------------------- ;CALL addr / RST nn ;------------------------------------- jmp.CD: ld a,(trap.mode) ;trap or execute? or a scf ret nz ;execute, exit ld de,(reg.pc) ;call instr. 3 bytes length inc de inc de inc de call push.addr ;push return address jr jmp.C3 ;now... jump push.addr: ld hl,(reg.sp) ;get stack ptr dec hl ld (hl),d ;push ret address dec hl ld (hl),e ld (reg.sp),hl ;store new sp ret test.cond: ld a,c ;get opcode and 38h ;mask 'cc' or 0C2h ;JP cc ! ld (@1),a ;store opcode call get.flag ;setting flags ld a,0 ;Z=1, ha vegrehajtva @1: db 0 dw @2 dec a @2: or a ret ;------------------------------------- ;RET cc ;------------------------------------- jmp.C0: call test.cond ;utasitast vegre kell hajtani? jp z,jmp.ret ;igen, RET ld hl,(reg.pc) ;skip 1 byte instruction jr skip@2 jmp.C7: ld a,(trap.mode) ;rst or a scf ;execute? ret nz ;igen, kilep ld de,(reg.pc) ;vegrehajtja inc de call push.addr ;push return address ld a,c ;get opcode and 38h ;mask address ld l,a ld h,0 jr skip@1 ;relativ ugrasok jmp.rel: ld a,c ;get opcode cp 10h ;djnz jr z,jmp.djnz cp 18h ;jr jr z,jmp.jr and 0E7h cp 20h jr z,jmp.jrcc ;jr cc scf ret jmp.djnz: ld a,(reg.bc+1) ;DEC B dec a ld (reg.bc+1),a jr nz,jmp.jr ;B <> 0, jump jmp.jskip: ld hl,(reg.pc) ;skip 2 bytes jp skip@3 jmp.jr: ld e,(ix+1) ;offset ld a,e ;D[7..0] <- offset[7] rlc a ld a,0 sbc a,0 ld d,a ld hl,(reg.pc) ;calc new pc inc hl inc hl add hl,de ld (reg.pc),hl or a ret jmp.jrcc: ld a,c ;get opcode ld (@1),a call get.flag ;setting flags @1: jr jmp.jr jr jmp.jskip get.flag: ld hl,(reg.af) ;flag-ek beallitasa push hl pop af ret ;--------------------------------------------------------------------------- ;"smart" display swapping ; ;csak akkor valt kepet, ha az utasitas ir/olvas mem-et ;--------------------------------------------------------------------------- test.swap: ld ix,opcode ;get opcode ld a,(ix+0) cp 0EDh ;ED-re mindig valt jr z,swap cp 0CBh ;CB-nel, csak a (HL) cimzes van jr z,test.CB cp 0DDh ;IX/IY prefixnel mindig, index jr z,swap ;miatt nem lehet tudni, hogy kell-e cp 0FDh jr z,swap bit 7,a ;select... jr z,test.low bit 6,a jr z,test.hl ;aritm/log-n'l csak ha (hl) cimzes van cp 0CDh ;call mindig jr z,swap and 0C7h cp 0C4h ;call 'cc' mindig jr z,swap cp 0C7h ;rst mindig jr z,swap noswap: or a ret test.low: bit 6,a ;ld r,r ? jr z,@1 and 0F8h cp 70h ;ld (hl) mindig jr z,swap jr test.HL ;csak ha (hl) @1: cp 34h ;inc / dec / ld (hl) jr z,swap cp 35h jr z,swap cp 36h jr z,swap and 7 ;mem cimzes? cp 2 jr z,swap jr noswap test.CB: ld a,(ix+1) test.HL: and 7 cp 6 jr nz,noswap swap: scf ret ;--------------------------------------------------------------------------- ;decode - 1 utasitas visszaforditasa buffer-be ;--------------------------------------------------------------------------- decode: ld hl,buffer ;disp.buffer torlese ld b,35 @1: ld (hl),' ' inc hl djnz @1 ld a,2 ;cursour elso poz.ba ld (column),a call disasm ;1 komplett ut. visszaforditasa jp next.addr ;cim korrekcio ;--------------------------------------------------------------------------- ;disasm - egy utasitas dekodolasa ;--------------------------------------------------------------------------- disasm: ld hl,(address) call print.addr ;cim es elso adatbyte outputra ;ndx.restart - ix,iy prefix restart ndx.restart: ld a,(hl) ;utasitas ld c,a ;save, vegig C-ben a kod rla jp c,upper.half ;80-FF? --> rla jp nc,lower.40 ;00-3F? --> ld a,c cp 76h ;Halt? jr nz,mnem.LDrr ;nem, LOAD r,r ld hl,txt.HALT ;operand nelkuli utasitasok print.no.op: call tab.txt jp printstr ;--------------------------------------------------------------------------- ;LD r,r - 76 (HALT) mar kizarva / LD (HL),(HL) / ;--------------------------------------------------------------------------- mnem.LDrr: call test.ndx.offs ;Index prefix volt? call tab.pr.LD ;print LD call get.target ;get target register to A call print.8bitreg ;Print target register call print.comma ;syntax ld a,c ;Get opcode print.8bitreg: push bc ;save opcode ld b,0 and 7 ld c,a ;reg.offset ld hl,txt.reg8 ;reg chr table add hl,bc ;index pop bc ld a,(hl) ;Register cp ' ' ;(HL) = ' ' jp z,print.ndx ;(HL) v. (IX/IY+dd) jp chrout ;nem, proc reg. ;---------------------------------------------------------------------------- ;16 bites cim outputra ([0]AAAAh) print.addr16: call zj.left ;bal zarojel '(' call print.data16 ;16 bit data, ha kell bevezeto 0-val jr zj.right ;job zarojel ')' ;8 bites cim outputra (I/O) print.addr8: call zj.left ;mint .addr16 call print.data8 jr zj.right ;16 bites reg index outputra (BC),(DE)..(SP) print.ndx16: call zj.left ;'(' call print.reg16 ;'BC..SP' zj.right: ld a,')' jp chrout zj.left: ld a,'(' jp chrout ;---------------------------------------------------------------------------- ;LD mnemonic outputra tab.pr.LD: call tab.txt print.LD: ld hl,txt.LD call printstr jp tab.operand ;--------------------------------------------------------------------------- ;lower.40 - also 40h utasitas dekodolasa (00-3F) ;--------------------------------------------------------------------------- lower.40: ld a,c ;Get opcode and 0F7h cp 34h ;csak inc/dec (ix/iy) van call nc,test.ndx.offs ;index prefix volt? ld hl,jump.tbl1 jp jp.from.table ;ut. elosztasa also 3 bit szerint ;Codes: 00 08 10 18 20 28 30 38 ;------------------------------ low.0.8: or a ;NOP ? jr nz,@1 ;nem, -> ld hl,txt.NOP ;NOP disp.re, nincs operand jp print.no.op @1: cp 08h ;EX AF,AF' ? jr nz,@2 ;nem, -> call tab.txt ;pozicionalas ld hl,txt.EX ;'EX' disp.re call printstr ld hl,txt.AF_AF ;tab, af,af' disp.re call tab.operand jp printstr ;relativ ugrasok: djnz, jr, jr xx @2: call get.data8 ;get offset ld hl,txt.JR ;JR a legtobb ld a,c ;get opcode cp 19h ;djnz v. jr? jr nc,@4 ;nem, -> jr xx,offset cp 11h ;djnz? jr nc,@3 ;nem, jr offset ld hl,txt.DJNZ ;change JR mnemonic to DJNZ @3: call printstr ;JR v. DJNZ disp.re call tab.operand ;offset poz.ba jr @5 ;print offset ;jr flag,offset @4: call print.mnemonic ;disp. JR call get.target ;get flag from opcode and 3 ;NZ,Z,NC,C maradhat call print.cond ;disp.re call print.comma ;',' ;relativ cim disp.re @5: ld hl,(address) ;get address inc hl ;address correction ld a,(data.H) ;get offset ld c,a rla ;sign -> 00 v. FF ld a,0 sbc a,0 ld b,a add hl,bc ;jump address push hl ld a,h call leading.zero ;bevezeto 0, ha kell pop hl call print.hexw ;address disp.re jp print.hexchar ;'h' ;Codes: 01 09 11 19 21 29 31 39 ;------------------------------ low.1.9: and 8 ;LD rr,dddd ? jr nz,@1 ;nem, -> call get.data16 ;16 bites adat elo call print.LD ;'LD' disp.re call print.reg16 ;target reg disp.re jp print.lddata16 ;',dddd' disp.re @1: call tab.txt ;ADD hl,rr 1 byte length xor a ;ADD code call print.aritm.A ;disp.re ld hl,txt.HL call printstr ;target reg: HL v. IX/IY call print.comma ;',' jp print.reg16 ;source reg (BC..SP) ;Codes: 02 0A 12 1A 22 2A 32 3A ;------------------------------ low.2.A: cp 22h ;LD (rr),a / LD a,(rr) ? jr nc,@2 ;nem, -> call tab.pr.LD ;1 byte length, disp: LD ld a,c ;get opcode and 8 ;direction jr z,@1 ;LD (rr),A? igen, -> call print.A.comma ;disp: 'A,' jp print.ndx16 ;(rr) disp.re @1: call print.ndx16 ;forditva: (rr) call print.comma ;',' jp print.A.reg ;'A' @2: call get.data16 ;16 bit adat elo call print.LD ;'LD' ld a,c ;get opcode bit 3,a ;direction jr z,@5 ;(nn),operand? -> bit 4,a ;operand HL? jr nz,@3 ;nem, -> ld hl,txt.HL ;'HL' disp.re call printstr jr @4 @3: call print.A.reg ;'A' disp.re @4: call print.comma ;',' jp print.addr16 ;'(aaaaH)' @5: call print.addr16 ;forditva '(aaaaH),' call print.comma ld a,c ;get opcode bit 4,a ;HL? jp nz,print.A.reg ;nem, 'A' disp.re / exit ld hl,txt.HL ;egyebkent 'HL' jp printstr ;Codes: 02 0A 12 1A 22 2A 32 3A ;------------------------------ ;INC rr / DEC rr ;------------------------------ low.3.B: call tab.txt ;1 byte length ld hl,txt.INC ld a,c ;get opcode bit 3,a ;INC? jr nz,@1 ;nem, -> ld hl,txt.INC jr @2 @1: ld hl,txt.DEC @2: call printstr ;ut. disp.re ld hl,txt.reg16 ;BC..SP jp print.regs ;disp ;------------------------------ ;INC r ;------------------------------ low.4.C: call tab.txt ld hl,txt.INC jr low.45.common ;------------------------------ ;DEC r ;------------------------------ low.5.D: call tab.txt ld hl,txt.DEC low.45.common: call print.mnemonic print.reg8: call get.target ;get target reg jp print.8bitreg ;disp.re ;------------------------------ ;LD r8,d8 ;------------------------------ low.6.E: call get.data8 ;get 8 bit data call print.LD ;'LD' call print.reg8 ;target reg jp source.data8 ;',ddH' ;------------------------------ ;Rotate A, daa, cpl, scf, ccf ;------------------------------ low.7.F: call tab.txt ;1 byte length call get.target ;select ld hl,txt.onebyte ;ut. nevek rla ;*4 rla ld b,4 ;length jp strcopy ;disp.re ;------------------------------ ; target A[0..3] -ba ;------------------------------ get.target: ld a,c ;utasitas kod mask.reg: and 38h ;target reg. mask rra ;>> 0..2 bitre rra rra ret ;---------------------------------------------------------------------------- ;felso 80h kod dekodolasa (80h-FFh) ;---------------------------------------------------------------------------- upper.half: rla ;80-BF? aritm/log ut? jr c,select.upper40 ;nem, C0-FF -> ;ADD, ADC, SUB, SBC, AND, XOR, OR, CP ;------------------------------------ call test.ndx.offs ;index prefix volt? call tab.txt call print.aritm ;disp.re utasitas ld a,c ;get opcode jp print.8bitreg ;source reg disp.re ;HL string begin, A string offset, B length -> disp.re strcopy: ld c,a ;offset ld a,b ;save length ld b,0 ;->16 bit add hl,bc ;string index ld b,a ;restore length @loop: ld a,(hl) ;print call chrout inc hl djnz @loop ret ;Aritmetikai es logikai utasitasok neve disp.re print.aritm: call get.target ;Ut.? print.aritm.A: ld b,3 ;Text length ld hl,txt.aritm ;String begin push bc ;save opcode ld c,a ;*3 rla add a,c call strcopy ;ut. disp.re pop bc ;restore opcode call tab.operand ;tab ld a,c ;get opcode and 0BFh ;90-97, A0-BF es 80h alatt cp 080h ;nem kell 'A,' ret c cp 0A0h ret nc cp 090h jp c,print.A.comma cp 098h ret c jp print.A.comma ;'A,' disp.re select.upper40: ld hl,jump.tbl2 ;jump tablabol ugras, input: C - opcode, also 3 bit szerint jp.from.table: ld a,c ;get opcode and 7 ;csak also 3 bit ld e,a ;*3 (jp aaaa) rla add a,e ld e,a ld d,0 ;index add hl,de inc hl ;jp code-ot atlepi ld e,(hl) ;address -> DE inc hl ld d,(hl) push de ;jump address ld a,c ;get opcode ret ;jump ;--------------------------------- ;RET cc ;--------------------------------- high.0.8: ld hl,txt.RET ;'RET' disp.re call print.no.op jp get.cond ;feltetel disp.re ;--------------------------------- ;POP / vegyes ;--------------------------------- high.1.9: ld hl,txt.POP bit 3,a ;pop? jr nz,oneb.9 ;nem, -> push.pop: call print.no.op ;disp.re PUSH v. POP ld hl,txt.regs ;BC..AF jp print.regs ;disp.re oneb.9: cp 0D9h ;EXX? ld hl,txt.RET jp c,print.no.op ;nem, C9, RET ld hl,txt.EXX jp z,print.no.op ;ok, EXX call tab.txt ld a,c ;get opcode cp 0E9h ;JP (HL) ? jr nz,ld.sphl ;nem, ld sp,hl ld hl,txt.JP ;'JP' disp.re call printstr call tab.operand jp print.ndx ;(HL) v (IX) (IY) ld.sphl: ld hl,txt.LD ;'LD' call printstr ld hl,txt.SP_ ;'SP,' call tab.operand call printstr ld hl,txt.HL ;'HL' jp printstr ;---------------------------------- ; CALL cc,aaaa ;---------------------------------- high.4.C: call get.data16 ld hl,txt.CALL jr high.24 ;---------------------------------- ; JP cc,aaaa ;---------------------------------- high.2.A: call get.data16 ;get address ld hl,txt.JP ;'JP' high.24: call printstr ;disp.re JP v. CALL call get.cond ;cc print.lddata16: call print.comma ; ',dddd' print.data16: ld hl,(data.W) ld a,h call leading.zero ;bevezeto nulla hex-addr.hez call print.hexw ;print address jr print.hexchar ;'h' ;bevezeto nulla hex-hez, ha betuvel kezdodne leading.zero: cp 0A0h ; >= 'A0'? ret c ;nem, nem kell nulla ele ld a,'0' jp chrout source.data8: call print.comma ;',ddH' print.data8: ld a,(data.H) print.hex.A: push af call leading.zero pop af print.hex.H: call print.hex print.hexchar: ld a,'h' jp chrout ;----------------------------------- ; PUSH rr / CALL, prefixek ;----------------------------------- high.5.D: ld hl,txt.PUSH ;push? bit 3,a jp z,push.pop ;igen, -> cp 0CDh ;CALL aaaa ? jp z,high.CD cp 0EDh ;ED prefix? jp nz,high.NDX ;nem, -> call get.new.code ;uj opkod kell ld a,c ;x4 vegu kod csak 1 van cp 44h ;NEG? ld hl,txt.NEG jp z,print.no.op ;igen, ey mar kiszurve and 0F7h ;RLD/RRD? cp 67h jr z,ED.RLD cp 45h ;RETN/RETI? jr z,ED.RETI and 0E7h cp 0A0h ;Blokk utasitasok jr z,ED.LDI cp 0A1h jr z,ED.CPI cp 0A2h jp z,ED.INI cp 0A3h jp z,ED.OUTI cp 047h ;I,R regs move? jp z,ED.IRreg cp 046h ;IM n? jr z,ED.IM and 0C7h cp 43h jp z,ED.LDr16 ;LD r16 <-> (addr) ld a,c and 0CFh cp 42h ;SBC HL,r16? jp z,ED.SBCr16 cp 4ah ;ADC HL,r16? jp z,ED.ADCr16 and 0C7h cp 40h ;IN r,(C)? jp z,ED.IN cp 41h ;OUT (C),a jp z,ED.OUT jp tab.txt ;--------------------------------- ;IM n ;--------------------------------- ED.IM: ld hl,txt.IM call print.no.op call tab.operand ld a,'0' bit 4,c jr z,@1 inc a bit 3,c jr z,@1 inc a @1: jp chrout ;--------------------------------- ;RLD / RRD ;--------------------------------- ED.RLD: ld hl,txt.RRD bit 3,c jp z,print.no.op ld hl,txt.RLD jp print.no.op ;--------------------------------- ;RLD / RRD ;--------------------------------- ED.RETI: ld hl,txt.RETN bit 3,c jp z,print.no.op ld hl,txt.RETI jp print.no.op ;--------------------------------- ; Blokk utasitasok ;--------------------------------- ED.LDI: ld hl,txt.LD ;LDdr jr block.dir ED.CPI: ld hl,txt.CP ;CPdr block.dir: call print.no.op ld a,'D' bit 3,c ;increment? jr z,@1 jr @2 @1: ld a,'I' @2: call chrout bit 4,c ;repeat? ret z ld a,'R' jp chrout ED.INI: ld hl,txt.IN ;INdr jr block.dir ED.OUTI: ld hl,txt.OUT ;OUTd v. OTdr bit 4,c jr z,block.dir ;OUTd -> ld hl,txt.OT jr block.dir ;---------------------------------- ;I,R reg. mozgato utasitasok ;---------------------------------- ED.IRreg: call tab.pr.LD ;'LD' ld a,'A' bit 4,c ;target A? jr z,@1 ;nem -> call chrout ;'A,' call print.comma @1: ld a,'I' ;select I or R reg bit 3,c jr z,@2 ld a,'R' @2: call chrout bit 4,c ;A,r ? ret nz ;ok, kesz call print.comma ;',A' jp print.A.reg ;------------------------------------- ;LD r16,(addr) / LD (addr),r16 ;------------------------------------- ED.LDr16: call get.data16 ;get address call print.LD ;'LD' bit 3,c ;direction jr nz,@1 call print.addr16 ;'(addr),r16' call print.comma jp print.reg16 @1: call print.reg16 ;'r16,(addr)' call print.comma jp print.addr16 ;------------------------------------- ;SBC / ADC HL,r16 ;------------------------------------- ED.SBCr16: ld hl,txt.SBC jr ED.ADCr16@1 ED.ADCr16: ld hl,txt.ADC @1: push hl call tab.txt ;2 byte command pop hl call print.mnemonic ;ADC/SBC ld hl,txt.HL ;'HL,' call printstr call print.comma call ED.getreg ;get source register ld hl,txt.reg16 jp print.2chr ;2ch reg disp.re ED.getreg: ld a,c ;a 40h eltolast korrigalni kell and 70h rra rra rra sub 8 ret ;------------------------------------- ;IN / OUT w. (C) ;------------------------------------- ED.IN: ld hl,txt.IN jr ED.OUT@1 ED.OUT: ld hl,txt.OUT @1: call print.no.op ;IN / OUT disp.re call tab.operand ld hl,txt.reg.C ;(C) bit 0,c ;direction jr nz,@2 call ED.getreg ;target reg call print.reg8 ;disp.re call print.comma ;',' ld hl,txt.reg.C ;'(C)' @2: call printstr bit 0,c ;direction? ret z ;ready call print.comma ;',r8' call ED.getreg jp print.reg8 ;------------------------------------ ; DD / FD prefix ;------------------------------------ high.NDX: ld h,'X' ;IX / IY select ld l,'I' bit 5,a jr z,@1 inc h @1: call @2 ;replace HL with IX or IY call next.addr ;skip prefix call print.data ;display code call ndx.restart ;restart disasm ld hl,4C48h ;'HL', restore HL reg. @2: ld (txt.regs + 4),hl ld (txt.reg16 + 4),hl ld a,h or 80h ld h,a ld (txt.HL),hl ret ;(index+dd) ? - ha igen, offsetet is beolvassa test.ndx.offs: ld a,(txt.HL) ;HL v. IX/IY? (volt prefix?) cp 'I' ret nz ;Nem, ok call next.addr ;Utasitas kodot atlepi ld a,(hl) ;Offset ld (data.L),a ;Store jp print.hex ;Offset data is otputra ;CALL aaaa high.CD: scf ;data width switch push af ld hl,txt.CALL jp decode.addr ;----------------------------------------- ; Aritm/logikai utasitasok, direkt adattal ;----------------------------------------- high.6.E: call get.data8 ;get data call print.aritm ;disp.re utasitas jp print.data8 ;disp.re adat ;----------------------------------------- ;RST nn ;----------------------------------------- high.7.F: ld hl,txt.RST ;'RST' disp.re call print.no.op call tab.operand ld a,c ;get opcode and 38h ;mask address jp print.hex.H ;disp. nnH ;----------------------------------------- ;Maradek vegyes ;----------------------------------------- high.3.B: cp 0CBh ;CB prefix? jp z,CB.prefix cp 0FBh ;EI? jr nz,@1 ld hl,txt.EI jp print.no.op @1: cp 0F3h ;DI? jr nz,@2 ld hl,txt.DI jp print.no.op @2: cp 0E3h ;EX? jr c,@4 push af ;save EX (SP),HL flag ld hl,txt.EX call print.no.op call tab.operand ;'EX' ld hl,txt.reg.SP ;'(SP),' pop af ;get switch jr nz,@3 call printstr ;disp.re ld hl,txt.HL ;'HL' jp printstr @3: ld hl,txt.DE_HL ;EX DE,HL jp printstr @4: cp 0D3h ;C3? (jp addr)? ld hl,txt.JP push af ;save data width switch jr nc,decode.addr@1 decode.addr: call get.data16 ;16 bit width operand jr @2 @1: call get.data8 ;8 bit width operand @2: pop af jr c,@4 jr nz,@3 ;-> IN ld hl,txt.OUT call print.mnemonic ;OUT (nn),A call print.addr8 call print.comma jp print.A.reg @3: ld hl,txt.IN call print.mnemonic ;IN A,(nn) call print.A.reg call print.comma jp print.addr8 @4: call print.mnemonic ;JP / CALL addr jp print.data16 CB.prefix: ld a,(txt.HL) ;index prefix volt? cp 'I' jr nz,@1 ;nem, ok. call get.new.code ;FD CB offset code ! ld a,c ;store offset ld (data.L),a @1: call get.new.code ;get CB code call tab.txt ;ok, nincs tobb byte ld a,c ;get opcode ld e,c ;save reg ld b,3 ;txt width cp 40h jr nc,@2 ;rotate? nem call mask.reg ;get target reg from a call mul.3 ld hl,txt.rotate ;disp.re utasitas call strcopy call tab.operand jr @3 ;disp.re reg. @2: rlca ;bit utasitasok rlca and 3 ;felso ket bittel select dec a ;correct 40h offset call mul.3 ld hl,txt.bits ;disp.re utasitas call strcopy call tab.operand ld a,e ;get opcode call mask.reg ;get target reg from a add a,'0' ;bit nr. call chrout call print.comma ;',' @3: ld a,e ;disp.re reg. jp print.8bitreg mul.3: ld c,a ;A := A * 3 rla rla sub c ret get.new.code: call next.addr ;kov. cim ld a,(hl) ;get opcode ld c,a ;save jp print.hex ;disp. code next.addr: ld hl,(address) ;increment main address inc hl ld (address),hl ret ;16 bites adat elo get.data16: push hl call next.addr ld e,(hl) ld a,e ld (data.L),a call print.hex jr get.data8@1 get.data8: push hl @1: call next.addr ld d,(hl) ld a,d ld (data.H),a call print.hex call tab.txt pop hl ret get.cond: call tab.operand call get.target ;(A - index) : NZ,Z,NC,C,PO,PE,P,M print.cond: rla ld hl,txt.cond ;2 karakter disp.re: (HL) - String begin, A: offset ; ;Ha masodik chr space, nem irja ki print.2chr: ld b,0 ;A -> BC offset ld c,a add hl,bc ;index ld a,(hl) call chrout inc hl ld a,(hl) cp ' ' ret z jp chrout print.regs: call tab.operand jr print.r16woStr ;16 bites reg neve displayre: input C (opcode), C: xxRR xxxx print.reg16: ld hl,txt.reg16 ;Reg16 string begin print.r16woStr: ld a,c and 30h ;mask register rra ;reg # -> offset rra rra jr print.2chr ;a text pozicioba all tab.txt: ld b,16 jr _tab print.mnemonic: call printstr ;utasitas outputra, operand-ra all tab.operand: ld b,22 jr _tab ;tab - B poziciora all _tab: ld a,(column) sub b jr c,@1 ld a,-1 @1: neg ld b,a @2: ld a,' ' call chrout djnz @2 ret ;(HL) vagy (IX+dd) disp.re print.ndx: ld a,'(' ;'(' call chrout ld hl,txt.HL ;reg disp.re call printstr ld a,c cp 0E9h ;JP (HL)? jr z,@1 ;igen, nincs offset ld a,(txt.HL) ;prefix volt? cp 'I' jr nz,@1 ;nem, nincs offset ld a,'+' ;'+' call chrout ld a,(data.L) ;offset call print.hex.A @1: jp zj.right ;')' ;printstr - print string (HL)-rol, az utolso karakter bit7 = 1 printstr: ld a,(hl) or a jp m,chrout call chrout inc hl jr printstr print.A.reg: ld a,'A' chrout: and 7Fh push hl push af ld hl,buffer ld a,(column) add a,l ld l,a ld a,h adc a,0 ld h,a pop af ld (hl),a ld a,(column) inc a cp 35 jr nc,@1 ld (column),a @1: pop hl ret print.A.comma: call print.A.reg ;'A,' print.comma: ld a,',' jr chrout ;------------------------------------------------------------ ;print.addr - HL,' ',(HL) outputra: 'cim',' ','elso adatbyte' ;------------------------------------------------------------ print.addr: call print.hexw ld a,' ' call chrout print.data: ld a,(hl) jr print.hex ;-------------------------------------------- ;HL hexaban outputra ;-------------------------------------------- print.hexw: ld a,h call print.hex ld a,l ;-------------------------------------------- ;A hexaban outputra ;-------------------------------------------- print.hex: push af ;hex rra rra rra rra call @@1 pop af @@1: and 15 add a,'0' cp '0'+10 jr c,@@2 add a,7 @@2: jp chrout ;------------------------------------------------- ;get.addr - (HL)-rol DE-be konvertalja a hex cimet ;------------------------------------------------- get.addr: push bc ld de,0 ld b,d @@1: ld a,(hl) inc hl cp '0' jr c,@@3 ex de,hl add hl,hl add hl,hl add hl,hl add hl,hl cp 'A' jr c,@@2 add a,9 @@2: and 15 ld c,a add hl,bc ex de,hl jr @@1 @@3: pop bc ret jump.tbl1: jp low.0.8 jp low.1.9 jp low.2.A jp low.3.B jp low.4.C jp low.5.D jp low.6.E jp low.7.F jump.tbl2: jp high.0.8 jp high.1.9 jp high.2.A jp high.3.B jp high.4.C jp high.5.D jp high.6.E jp high.7.F txt.reg8: db 'BCDEHL A' txt.regs: db 'BCDEHLAF' txt.reg16: db 'BCDEHLSP' txt.cond: db 'NZZ NCC POPEP M ' txt.aritm: db 'ADD','ADC','SUB','SBC','AND','XOR','OR ','CP ' txt.rotate: db 'RLC','RRC','RL ','RR ','SLA','SRA','SLL','SRL' txt.bits: db 'BIT','RES','SET' txt.onebyte: db 'RLCA','RRCA','RLA ','RRA ' db 'DAA ','CPL ','SCF ','CCF ' txt.HL: db 'H',0CCh txt.SP_: db 'SP',0ACh txt.AF_AF: db 'AF,AF',0A7h txt.DE_HL: db 'DE,H',0CCh txt.reg.SP: db '(SP)',0ACh txt.reg.C: db '(C',0A9h txt.NOP: db 'NO',0D0h txt.HALT: db 'HAL',0D4h txt.LD: db 'L',0C4h txt.JP: db 'J',0D0h txt.JR: db 'J',0D2h txt.DJNZ: db 'DJN',0DAh txt.INC: db 'IN',0C3h txt.DEC: db 'DE',0C3h txt.EX: db 'E',0D8h txt.EXX: db 'EX',0D8h txt.PUSH: db 'PUS',0C8H txt.POP: db 'PO',0D0h txt.CALL: db 'CAL',0CCh txt.RET: db 'RE',0D4h txt.RST: db 'RS',0D4h txt.EI: db 'E',0C9h txt.DI: db 'D',0C9h txt.IN: db 'I',0CEh txt.OUT: db 'OU',0D4h txt.NEG: db 'NE',0C7h txt.RRD: db 'RR',0C4h txt.RLD: db 'RL',0C4h txt.RETN: db 'RET',0CEh txt.RETI: db 'RET',0C9h txt.CP: db 'C',0D0h txt.OT: db 'O',0D4h txt.SBC: db 'SB',0C3h txt.ADC: db 'AD',0C3h txt.IM: db 'I',0CDh txt.END: db 'END',08Dh txt.ORG: db 'OR',0C7h column: db 0 buffer: ds 35 data.W: data.L: db 0 data.H: db 0 address: dw 0 ;--------------------------------------------------------------------------- debug_on: db 0 ;debugger aktiv? op_length: db 0 registers: ;megszakitaskori reg.ertekek reg.af: dw 0 reg.bc: dw 0 reg.de: dw 0 reg.hl: dw 0 reg.sp: dw 0 reg.ix: dw 0 reg.af1: dw 0 reg.bc1: dw 0 reg.de1: dw 0 reg.hl1: dw 0 reg.ir: dw 0 reg.iy: dw 0 reg.pc: dw 0 asm.addr: dw 0 ;assembler lista cime dump.addr: dw 0 ;dump lista cime trap.mode: db 0 ;00 trap, FF execute trap.length: dw 0 ;trap utasitas hossza main.sp: dw 0 ;sajat SP temp buffer brk.correct: db 0 ;brk point pc correction flag breakpoints: dw 0,0,0,0,0,0,0,0,0,0 ;10 breakpoint brk.data: db 0,0,0,0,0,0,0,0,0,0 kbdbuffer: db 0,0,0,0,0,0,0,0 ;kbd status reg.name: db 'AF BC DE HL SP IX AF',27h,'BC',27h,'DE',27h,'HL',27h,'IR IY PC ' flag.name: db 'SZHPNC' file.msg: db 'FILE: ',0 search.msg: db 'SEARCHING',0 loading.msg: db 'LOADING ',0 error0.msg: db 'WRONG FILE',0 error1.msg: db 'FILE NOT FOUND',0 init_msg: db 'Z80 Debugger v1.1b, (C) LopSoft Research, 2005.',13,10,0 ds 64 dspbuff: end start