; ************************ ; FALCON MONITOR 6.1 /9000 ; ************************ ; 29.11.2012 kompilace betaverze 6.1.02 ; 29.11.2012 opravena syntaxtická chyba XCGH ma XCHG ; 29.11.2012 doplněn fiktivní byte XX do funkcí FIND/REPLACE ; 20.12.2012 opravena chyba vyhodnocení CY u trasování ; 20.12.2012 opravena chyba ukončení trasování při zpracování ; podmíněných instrukcí CALL ; 22.12.2013 opravena chyba délky souboru MGF ; 22.12.2013 kompilace verze 6.1.03 s upraveným init textem ; 05.01.2014 odstraněna slepá procedura "cmdexp" ; drobné sémantické opravy beze změny kódu ; 05.01.2014 doplněn příkaz G ; 05.01.2014 kompilace verze 6.1.04 ; opravit divný formát výpisu u TRACE ; ******************* ; vazba na původní OS ; ******************* autstrt .equ 7ffbh ; adresa STACKu pro autostart coldrst .equ 8000h ; studený start systému os_err .equ 804ch ; vstup do os s výpisem hlášení os_ret .equ 805ah ; vstup do os bez výpisu hlášení hex1 .equ 80dfh ; zformování nibble z ASCII txt pairin .equ 80f7h ; zformování byte z ASCII txt adrin .equ 8109h ; zformování word z ASCII txt clrbuf .equ 8113h ; vymazání buferu dial. řádku prevo1 .equ 8125h ; převod byte na ASCII txt nibasc .equ 8131h ; převod nibble na ASCII txt prev21 .equ 8137h ; presekvence prevo2 prevo2 .equ 813bh ; převod byte do paměti at HL radr .equ 814bh ; načtení adresy s testem txthead .equ 81d8h ; načte 8 znaků jména souboru prteol .equ 84feh ; tisk EOL prtout .equ 8500h ; tisk znaku vč. CTRL kódů prtdir .equ 8542h ; tisk znaku natvrdo inkey .equ 89c0h ; test klávesnice decpar .equ 8a54h ; načtení BCD čísla setsped .equ 8b44h ; nastavení 8251/8253 dle HL (mgffreq) ldbyte .equ 8b6ch ; načtení byte z MGF ld_blk .equ 8badh ; load souboru enter .equ 8beeh ; editace dial. řádku romin .equ 8c00h ; přenos byte z ROMPACKu warmrst .equ 8c40h ; vstup do smycky monitoru t_stop .equ 8c74h ; test STOP klávesy svbyte .equ 8d7eh ; zápis byte na MGF ostext .equ 8e48h ; vypíše text OS (hlášení) bindec .equ 8e73h ; konverze bin>dec savblk .equ 8eb4h ; zapíše soubor na MGF ovrspc .equ 8fb1h ; přeskočí mezery at HL txtbuf .equ 0c030h ; editační buffer prtpos .equ 0c03eh ; pozice tisku curch .equ 0c072h ; kurzor v buferu dial. řádku mess .equ 0c074h ; adresa chybového hlášení dialln .equ 0c078h ; adresa edit. buferu syscmd .equ 0c07eh ; tabulka systémových příkazů ramvct .equ 0c0f0h ; vektor pro MG/terminál findnr .equ 0c1b0h ; číslo hledaného souboru findtp .equ 0c1b1h ; typ hledaného souboru filedat .equ 0c1b2h ; údaje o souboru erasatr .equ 0c1f1h ; atribut vymazání paměti mgffreq .equ 0c1feh ; rychlost nahrávání MGF .org 9000h ; ************ ; inicializace ; ************ call prtstg .db 1ch,0dh,"FALCON MONITOR 9000 v6.1.04" .db " (C) 2013",0dh,8dh lxi h,newcmd-1 shld syscmd jmp warmrst ; ******************** ; porovná HL versus DE ; ******************** hlvsde: mov a,h cmp d rnz mov a,l cmp e ret ; *********************** ; rutiny pro výstup znaku ; *********************** prtstg: xthl call prttxt xthl ret ; *********************** prttxz: call prtout prttxt: mov a,m inx h ana a jp prttxz ani 7fh jmp prtout ; *********************** condcr: lda prtpos ani 3fh rz jmp prteol ; *********************** wrdasc: mov a,h call bytasc mov a,l ; *********************** bytasc: push b call prevo1 pop b ret ; *********************** adrout: call wrdasc jmp prtspc ; *********************** bytout: call bytasc jmp prtspc ; *********************** prt3sp: call prtspc prt2sp: call prtspc prtspc: mvi a,' ' jmp prtout ; *********************** bytbit: push psw call bytout pop psw ; *********************** bitasc: mvi c,8 bitasl: ral push psw mvi a,18h ral call prtout pop psw dcr c jnz bitasl ret ; *********************** insadd: mvi a,'>' insadr: push psw push d call clrbuf pop d pop psw lhld txtbuf mov m,a inx h mov a,d call prevo2 inx h mvi a,6 call prev21 jmp os_ret ; ************************************** ; načtení potenciální adresy z ASCII txt ; výstup: C = 1 nenásleduje adresa ; ************************************** tstadr: call skpspc call hex1 rc jmp radr ; ********************************************** ; načte povinný byte s vynecháním úvodních mezer ; ********************************************** kmplbt: call skpspc jmp rbyte ; ************************************** ; načtení potenciálního byte z ASCII txt ; výstup: C = 1 nenásleduje byte ; ************************************** tstbyt: call skpspc call hex1 rc ; ************************ ; načtení byte s kontrolou ; ************************ rbyte: push b lhld curch call pairin shld curch pop b rnc lxi h,82b0h ; Error in data shld mess jmp os_err ; ***************************** ; ovládací struktura k výpisům ; stisk SHIFT pozastavuje výpis ; stisk STOP vrací CY = 0 ; 10 byte ; ***************************** moneol: in 0f5h ral ral rnc ral jnc moneol call prteol stc ret ; *************** ; 2 komplement HL ; *************** hl2cpl: mov a,h cma mov h,a mov a,l cma mov l,a inx h ret ; ******************* ; test vyššího nibble ; ******************* testhi: rrc rrc rrc rrc ani 0fh ret ; ************************ ; přeskočí mezery v buferu ; ************************ skpspc: lhld curch call ovrspc shld curch ret ; *********************************** ; načtení dvou parametrů z txt buferu ; výstupy: HL = 1. parametr ; BC = 2. par. minus 1. par. ; *********************************** gt2par: call radr push d call skpspc call radr pop h push h call hl2cpl dad d mov b,h mov c,l pop h inx b ret ; *********************************** ; načtení tří parametrů z txt buferu ; výstupy: HL = 1. parametr ; BC = 2. par. minus 1. par. ; DE = 3. parametr ; *********************************** gt3par: call gt2par ; ************************************************* ; načte povinnou adresu s vynecháním úvodních mezer ; ************************************************* mstadr: push b push h call skpspc call radr pop h pop b ret ; ******************** ; vytiskne text TOTAL: ; ******************** prttot: call prtstg .db "TOTAL:",' '+80h ret ; ******** ; příkaz > ; ******** cmdsub: lxi h,82b0h ; Error in data shld mess call radr cmdsul: call ovrspc cpi 0dh jz insadd cpi 34 jz cmdsqu call pairin jc os_err stax d inx d jmp cmdsul cmdsqu: inx h cmdsqn: mov a,m cpi 0dh inx h jz insadd cpi 34 jz cmdsul stax d inx d jmp cmdsqn ; ******** ; příkaz % ; ******** cmdpro: call radr xchg cmdprl: shld ROMstr call romin ROMstr: .dw 0 ROMlen: .dw 7 RAMdst: .dw ROMbuf mvi a,'%' call prtout lhld ROMstr call adrout lxi h,ROMbuf call mshowi call moneol jnc cmdend lhld ROMstr lxi d,8 dad d jmp cmdprl ROMbuf: .fill 8,0 ; ******** ; příkaz + ; ******** cmdpls: call gt2par dad h dad b dcx h cmdplc: call condcr call prttot lstadr: call wrdasc jmp cmdend ; ******** ; příkaz - ; ******** cmdmns: call gt2par mov h,b mov l,c dcx h call hl2cpl jmp cmdplc ; ******** ; příkaz @ ; ******** cmdzav: call radr xchg cmdzal: mvi a,'>' call prtout call adrout mov a,m inx h call bytbit call moneol jc cmdzal jmp cmdend ; ******** ; příkaz A ; ******** cmd_a: call radr xchg cmd_al: mvi a,'>' call prtout call adrout mvi c,40 cmd_an: mov a,m inx h push h call prtdir pop h dcr c jnz cmd_an call moneol jnc cmdend jmp cmd_al ; ********** ; příkaz CMP ; ********** cmdcmp: call setcnt call gt3par cmdcml: ldax d cmp m stc cmc cnz nmatch jc escape inx d inx h dcx b mov a,b ora c jnz cmdcml zaver: call prtdif jmp cmdend ; ************************************* ; společné rutiny vyhledávacích příkazů ; ************************************* prtdif: call condcr call prtstg .db "DIFFERENT:",' '+80h lhld count jmp wrdasc setcnt: mvi a,1 ; nastavení count sta vypis ; a vypis lxi h,0 shld count lhld curch mov a,m cpi 'L' rnz xra a sta vypis inx h shld curch jmp skpspc mtchcm: push h lhld count inx h shld count pop h lda vypis ana a ret nmatch: call mtchcm rz call adrout mov a,m call bytout mvi a,'-' call prtout call prtspc xchg mov a,m call bytout call adrout xchg call prteol matchw: in 0f5h ral ral cmc rc ral jnc matchw ana a ret escape: call prtesc jmp cmdend prtesc: call condcr call prtstg .db "STOPPED.",'.'+80h ret vypis: .db 1 count: .dw 0 ; *********** ; příkaz SAVE ; *********** cmdsav: call setvct call decpar jc os_err lhld curch dcx h shld curch sta filedat call kmplbt sta filedat+1 call skpspc call gt2par dcx b shld filedat+2 mov h,b mov l,c shld filedat+4 call skpspc call txthead call mginfo lxi h,cmdsvt shld mess call ostext call savblk call prteol jmp os_err cmdsvt: .db "++ RECORDING ++",0dh ; *********** ; příkaz FILE ; *********** cmdfaj: call mginfo jmp cmdend mginfo: call prtstg .db " NR:",' '+80h lda filedat call bindec call bytasc call prtstg .db 0dh,"TYPE:",' '+80h lda filedat+1 call bytasc call prtstg .db 0dh,"FROM:",' '+80h lhld filedat+2 call wrdasc call prtstg .db 0dh," LEN:",' '+80h lhld filedat+4 inx h call wrdasc call prtstg .db 0dh,"NAME:",' '+80h lxi h,filedat+6 call prt8as jmp prteol ; ********* ; příkaz IN ; ********* cmdin: call rbyte sta cmdpon+1 call cmdpoc jmp cmdend ; *********** ; příkaz JUMP ; *********** cmdjmp: call radr xchg shld cmdjmv+1 call reg_ld cmdjmv: call 8000h call reg_sv jmp cmdend reg_ld: lhld regpsw push h pop psw lhld reg_bc mov b,h mov c,l lhld reg_de xchg lhld reg_hl ret reg_sv: shld reg_hl lxi h,0 dad sp shld reg_sp push psw pop h shld regpsw xchg shld reg_de mov h,b mov l,c shld reg_bc ret ; ******** ; příkaz M ; ******** cmd_m: call radr xchg cmd_ml: call mshow call moneol jc cmd_ml cmdend: call condcr call prteol call clrbuf jmp os_ret ; ******** ; příkaz N ; ******** cmd_n: call radr mov a,e ani 0c0h ori 30h mov e,a xchg cmd_nl: call mshow call moneol jnc cmdend call mshow call moneol jnc cmdend lxi d,48 dad d jmp cmd_nl ; ************************************* ; podpůrná rutina paměťových prohlížečů ; v HL je vstup adresy pro zobr. 8 byte ; ************************************* mshow: mvi a,'>' call prtout call adrout mshowi: push h mvi c,8 mshow1: mov a,c ani 3 cz prtspc mov a,m inx h call bytout dcr c jnz mshow1 call prtspc pop h call prt8as push d call prt2sp pop d mov a,d call nibasc mov a,e jmp bytasc prt8as: mvi c,8 lxi d,0 mshow2: mov a,m add e mov e,a jnc mshow3 inr d mshow3: mov a,m inx h push h call prtdir pop h dcr c jnz mshow2 ret ; ********** ; příkaz OUT ; ********** cmdout: call rbyte sta cmdouw+1 cmdoun: call tstbyt jc cmdend cmdouw: out 0ffh jmp cmdoun ; *********** ; příkaz PORT ; *********** cmdpor: call rbyte sta cmdpon+1 lhld prtpos cmdpol: push h call cmdpoc in 0f5h ral ral pop h jnc cmdend shld prtpos jmp cmdpol cmdpoc: call prtstg .db "PORT",' '+80h lda cmdpon+1 call bytasc call prtstg .db ':',' '+80h cmdpon: in 0 jmp bytbit ; *********** ; příkaz QUIT ; *********** cmdqui: xra a sta erasatr jmp coldrst ; ******** ; příkaz / ; ******** cmdsrg: lxi b,cmd_r push b call tstbyt rc sta regpsw+1 call tstadr rc xchg shld reg_hl call tstadr rc xchg shld reg_de call tstadr rc xchg shld reg_bc call skpspc mov a,m cpi 0dh rz xchg mvi b,8 setflg: ldax d inx d cpi '0' jc asmerd ; error in data cpi '2' jnc asmerd rar mov a,c ral mov c,a dcr b jnz setflg sta regpsw cmd_r: call rgprn1 call rgprn2 jmp cmdend reg_bc: .dw 0 ; reg. BC reg_de: .dw 0 ; reg. DE reg_hl: .dw 0 ; reg. HL reg_sp: .dw 0 ; reg. SP regpsw: .dw 0 ; reg. PSW reg_pc: .dw 0 ; reg. PC rgprn1: call prtstg .db " A HL DE BC SZ.A.P.C SP",8dh ret rgprn2: mvi a,'/' call prtout lda regpsw+1 call bytout lhld reg_hl call adrout lhld reg_de call adrout lhld reg_bc call adrout lda regpsw call bitasc call prtspc lhld reg_sp call adrout jmp condcr ; *********** ; příkaz SCAN ; *********** cmdscn: call radr lhld prtpos cmdscl: push d push h xchg call mshow pop h in 0f5h ral ral jnc cmdend shld prtpos pop d jmp cmdscl ; ************ ; příkaz STACK ; ************ cmdstk: call prtstg .db "SP",'='+80h lxi h,0 dad sp call wrdasc jmp cmdend ; ********** ; příkaz SUM ; ********** cmdsum: call gt2par xra a mov d,a mov e,a push psw cmdsu1: pop psw add m jnc cmdsu2 inx d cmdsu2: inx h dcx b push psw mov a,b ora c jnz cmdsu1 call prttot xchg call wrdasc pop psw call bytasc jmp cmdend ; ************ ; příkaz TURBO ; ************ cmdtrb: lhld curch mov a,m cpi 0dh jz cmdtrp cpi 'N' jnz cmdtrs lxi h,06abh jmp cmdtrx cmdtrs: call radr xchg cmdtrx: shld mgffreq cmdtrp: call prtstg .db "MGF SPPED:",' '+80h lhld mgffreq call wrdasc jmp cmdend ; ******** ; příkaz D ; ******** cmddis: call radr xchg cmddil: call disone call moneol jc cmddil jmp cmdend ; ********************************* ; výpis instrukce i8080 ve formátu ; .adr byte1 [byte2] [byte3] opcode ; vstup: HL ; výstup: aktualizovaný HL ; ********************************* disone: mvi a,'.' ; prefix . call prtout call adrout ; adresa call prtspc push h ; určit počet byte call fnclen pop h push h dcr e jz dis1by dcr e jz dis2by call onebyt ; 3 bytová instr. call twobyt pop h call mnemo mov e,m inx h mov d,m inx h xchg call wrdasc xchg ret dis2by: call twobyt ; 2 bytová instr. call prt3sp pop h call mnemo mov a,m inx h jmp bytasc dis1by: call onebyt ; 1 bytová instr. call prt3sp call prt3sp pop h ; ********************************** ; výpis symbolického jména instrukce ; ********************************** mnemo: call prtspc ; tisk mnemo mov c,m inx h lxi d,tabop1 call search ldax d ; první znak ani 7fh cpi 20h jnc prtupy ; je std > tisk mov c,a ; je token inx d push d ; pak dekompilace lxi d,tabop2 call search ldax d ani 7fh call prtupy pop d jmp prtupt ; ******************************** ; tisk znaku do výskytu +80h ; vstup: DE - ukazatel na bufer ; výstup: B - poslední platný znak ; - neplést s prttxt ; ******************************** prtupy: mov b,a call prtout inx d prtupt: ldax d ana a jp prtupy mov a,b ; pokud není poslední cpi ',' ; znak čárka, přidá SPC cnz prtspc ret ; ********************************* ; pomocné procedury pro výpis bytes ; ********************************* twobyt: call onebyt onebyt: mov a,m ; tisk byte inx h jmp bytout ; ******************************** ; podle hodoty v reg. C najde text ; vstup: reg. C - pořadí ; reg. DE - adresa tabulky ; výstup: reg. DE - adresa textu ; ******************************** search: mov a,c ; nalézt instrukci ana a rz searlo: call fndbig dcr c jmp search ; ******************************* ; najede v textu na znak >80h ; vstup: reg. DE - adresa textu ; výstup: reg. DE po aktualizaci ; ******************************* fndbig: inx d ldax d ana a jp fndbig ret ; ************************************** ; vyhledání stringu v tabulce ; vstup: DE - tabulka stringů ; HL - ukazatel na hledaný string ; B - počet platných položek ; ************************************** recogn: push h ldax d ; přímý test 1. byte reccmn: cmp m jz recsek ani 7fh ; mask. test 1. byte cmp m jnz recnot recsek: inx d inx h ldax d ana a jp recnox pop psw ; nalezeno ana a mov a,b ret recnox: cmp m jz recsek recnot: pop h call fndbig dcr b jnz recogn stc ret ; nenalezeno ; **************************************** ; výpočet délky instrukce i8080 ; vstup: reg. HL - ukaz. na operační kód ; výstup: reg. E - hodnota 1/2/3 ; délka: 42 byte ; **************************************** fnclen: mov d,m lxi h,fnclnt fncle1: mov e,m inx h fncle2: mov a,m cmp e rz jc fncle1 ana d inx h cmp m inx h rz jmp fncle2 fnclnt: .db 3 .db 0ffh,0c3h,0ffh,0cdh .db 0c7h,0c4h,0c7h,0c2h .db 0e7h,022h,0cfh,001h .db 2 .db 0f7h,0d3h,0c7h,0c6h .db 0c7h,006h .db 1,1 ; ******** ; příkaz . ; ******** cmdasm: call radr push d call skpspc lxi d,tabop2 mvi b,mxtoken+1 call recogn jc ntoken cma ; instrukce s token adi 82h+mxtoken push psw call ovrspc pop psw dcx h mov m,a ntoken: lxi d,tabop1 mvi b,0 call recogn pop d jc asmerr cma inr a mov c,a cpi 0f4h ; ošetření CP<>CPI jnz ncodf4 mov a,m cpi 'I' jnz ncodf4 mvi c,0feh inx h ncodf4: mov a,c stax d ; zjistit délku instr. push d push h xchg call fnclen mov a,e pop h pop d inx d ; rozcestník dle délky dcr a jz asmnxt dcr a jz asm2bt asm3bt: push d ; instrukce 3 byte call ovrspc call adrin pop h jc asmerd mov m,e inx h mov m,d inx h xchg jmp asmnxt asm2bt: call ovrspc ; instrukce 2 byte call pairin jc asmerd stax d inx d asmnxt: mvi a,'.' ; příprava další adresy jmp insadr asmerd: lxi h,82b0h ; Error in data jmp asmer2 asmerr: lxi h,asmert ; Invalid OP code asmer2: shld mess jmp os_err asmert: .db "++ No valid OP code ++",0dh ; *********** ; příkaz SWAP ; *********** cmdswp: call gt3par cmdswl: mov a,m push psw ldax d mov m,a pop psw stax d inx h inx d dcx b mov a,b ora c jnz cmdswl jmp cmdend ; ************ ; příkaz BLOCK ; ************ cmdblk: call gt2par push b push h lhld curch call ovrspc lxi d,operac-4 cmdblf: inx d inx d inx d inx d ldax d ana a jz blkerr cmp m jnz cmdblf inx h inx d ldax d sta opplac inx d ldax d sta opplac+1 inx d ldax d sta opplac+2 shld curch call tstbyt mvi e,0 jc cmdble mov e,a cmdble: pop h pop b cmdbll: mov a,m opplac: nop nop nop mov m,a inx h dcx b mov a,b ora c jnz cmdbll jmp cmdend operac: .db 'A' ana e nop nop .db 'O' ora e nop nop .db 'X' xra e nop nop .db '+' add e nop nop .db '-' sub e nop nop .db 'M' call blkmir .db 'L' rlc nop nop .db 'R' rrc nop nop .db 0 blkmir: mvi d,8 mirlop: mov a,m ral mov m,a mov a,e rar mov e,a dcr d jnz mirlop ret blkerr: pop h pop b lxi h,blkert jmp asmer2 blkert: .db "++ Invalid fnc ++",0dh ; *********** ; příkaz FILL ; *********** cmdfil: call gt2par xchg call skpspc push h cmdfre: pop h push h shld curch call rbyte jmp cmdf2b cmdflo: call tstbyt jc cmdfre cmdf2b: stax d inx d dcx b mov a,b ora c jnz cmdflo pop psw jmp cmdend ; *********** ; příkaz FIND ; *********** cmdfin: call setcnt call gt2par xchg call skpspc cmdfia: push h push d cmdfio: call gt_byt jc cmdfod ; neplatný byte (0dh) => nalezeno jz cmdfxx ; byte XX - přeskočit test xchg cmp m xchg cmdfxx: inx d jz cmdfio cmfnnx: pop d pop h shld curch inx d dcx b mov a,b ora c jnz cmdfia lhld count jmp cmdplc cmdfod: call mtchcm ; výskyt nalezen jz cmfnnx pop h ; defacto DE push h call adrout call prtspc call matchw jc escape jmp cmfnnx ; *********** ; příkaz WAIT ; *********** cmdwai: call rbyte sta cmdwal+1 call kmplbt sta cmdwam+1 call kmplbt sta cmdwau+1 cmdwal: in 0 mov b,a cmdwam: ani 0 cmdwau: cpi 0 jz cmdwax in 0f5h ral ral jc cmdwal jmp escape ; stopped cmdwax: call prtstg .db "PORT",' '+80h lda cmdwal+1 call bytasc call prtstg .db ':',' '+80h mov a,b call bytbit jmp cmdend ; *********** ; příkaz COPY ; *********** cmdcpy: call gt3par call hlvsde jnc cmdcp2 dad b xchg dad b xchg cmdcp1: dcx d dcx h mov a,m stax d dcx b mov a,b ora c jnz cmdcp1 jmp cmdend cmdcp2: mov a,m stax d inx h inx d dcx b mov a,b ora c jnz cmdcp2 jmp cmdend ; ************* ; příkaz VERIFY ; ************* cmdvrf: lxi h,0 shld count call getfnr jc os_err call kmplbt sta findtp lxi h,ramvct lxi d,myrout mvi m,0c3h inx h mov m,e inx h mov m,d call ld_blk jmp cmdend ; oblužná rutina komparace myrout: pop psw mvi b,0 myrou1: call ldbyte jnc myrou2 pop b jmp setvct myrou2: mov c,a add b mov b,a mov a,c cmp m cnz myroue inx h mov a,d ora e dcx d jnz myrou1 call ldbyte xra b push psw call prtdif call condcr call setvct pop psw ret myroue: call mtchcm lda prtpos ani 3fh cpi 43 rnc mvi a,'!' call prtout jmp adrout ; ************ ; příkaz CHECK ; ************ cmdchc: call getfnr jc os_err xra a jmp cmdlac ; *********** ; příkaz LOAD ; *********** cmdlad: call getfnr jc os_err call kmplbt cmdlac: sta findtp call tstadr jc cmdldw lxi h,ramvct mvi m,21h inx h mov m,e inx h mov m,d inx h mvi m,0c9h cmdldw: call ld_blk call setvct jmp cmdend getfnr: call decpar lhld curch dcx h shld curch rc sta findnr ana a setvct: mvi a,0c9h sta ramvct ret ; *********** ; příkaz HACK ; *********** ; pozor! zavaděče přepisují bufer klávesnice, ; proto je nutno předčíst data do vlastního buferu cmdhck: call getfnr ; číslo souboru jc os_err mvi a,'?' ; typ souboru sta findtp call skpspc call radr ; načíst HACK xchg shld myhack ; uložit HACK adresu mvi b,0 lxi d,myhack+3 ; načíst a uložit HACK bytes hcknxt: call tstbyt jc restrt stax d inx d inr b mov a,b cpi 7 jc hcknxt restrt: mov a,b ; uložit počet HACK bytes sta myhack+2 lxi h,0 ; přesun STACKu dad sp shld mystck lxi sp,mystck call ld_blk ; natáhnout zavaděč xra a sta erasatr ; deaktivovat ochranu lhld myhack ; spustit HACK lxi d,myhack+2 ldax d mov b,a nxtwrt: mov a,b ana a jz spust inx d ldax d mov m,a inx h dcr b jmp nxtwrt spust: lxi sp,7fffh ; obnovit STACK lhld autstrt pchl ; autostart .fill 40,0 ; záložní STACK mystck: .dw 0 myhack: .dw 0 ; adresa .fill 8,0 ; data ; ************** ; příkaz REPLACE ; ************** cmdrep: call setcnt ; načíst adresy od / do call gt2par ; a uložit ukazatele na stringy push b push h lhld curch shld cmdrfn call gt_byt lxi h,cmdtt1 jc cmdert cmdre1: call gt_byt jnc cmdre1 call skpspc mov a,m inx h shld curch shld cmdrrp cpi '>' lxi h,cmdtt2 jnz cmdert call gt_byt lxi h,cmdtt3 jc cmdert pop d pop b lhld cmdrfn ; tělo hledací rutiny cmdre2: shld curch push h push d cmdre3: call gt_byt jc cmdre5 ; chybný byte jz cmdxx1 ; byte XX - přeskočit test xchg cmp m xchg cmdxx1: inx d jz cmdre3 cmdre4: pop d pop h inx d dcx b mov a,b ora c jnz cmdre2 lhld count jmp cmdplc cmdre5: pop d ; výskyt nalezen push d ; tělo nahrazující rutiny lhld cmdrrp shld curch cmdre6: call gt_byt jc cmdre7 ; chybný byte jz cmdxx2 ; byte XX - přeskočit zápis stax d cmdxx2: inx d jmp cmdre6 cmdre7: call mtchcm ; inc(count) + test "vypis" jz cmdre4 pop h ; defacto DE push h call adrout call prtspc call matchw jc escape jmp cmdre4 cmdert: pop psw pop psw shld mess jmp os_err ; načtení potenciálního byte a nastavení příznaků gt_byt: call tstbyt jc gt_by2 push b mov b,a mvi a,1 ana a mov a,b pop b ret gt_by2: call gt_by3 rc gt_by3: mov a,m cpi 'X' stc rnz inx h shld curch ; CY=0/Z=0 - platný byte xra a ; CY=0/Z=1 - byte XX ret ; CY=1 - chyba cmdtt1: .db "++ Wanted data error ++",0dh cmdtt2: .db "++ Delimiter error ++",0dh cmdtt3: .db "++ Replace data error ++",0dh cmdrfn: .dw 0 ; ukaz. na hledaný string cmdrrp: .dw 0 ; ukaz. na nový string ; ************ ; příkaz TRACE ; ************ cmdtrc: call radr xchg shld reg_pc lxi h,0 dad sp shld reg_sp lxi sp,mystck tracel: lxi h,0c280h shld 0c03eh ;call prteol lxi h,0 ; smycka trasování shld instr+1 ; 2. a 3. byte instrukce neplatný lhld reg_pc push h call disone call prteol pop h mov a,m ; ošetření výjimek emulace cpi 76h ; HLT jnz n_hlt xra a sta instr jmp inshlt n_hlt: cpi 0c9h ; RET jz trcend cpi 0c3h ; JMP jz emujmp cpi 0e9h ; PCHL jnz n_pchl xra a sta instr lhld reg_hl shld reg_pc jmp inshlt n_pchl: ani 0c7h ; Rx/RNx cpi 0c0h jz trcend cpi 0c2h ; Jx/JNx jz emujmp trccom: call fnclen ; určit délku aktuální instrukce lhld reg_pc lxi b,instr ; nakopírovat 1-3 byte instrukce tracec: mov a,m stax b inx h inx b dcr e jnz tracec shld reg_pc inshlt: lhld regpsw ; připravit trasovací registry push h pop psw lhld reg_bc push h pop b lhld reg_de xchg lxi h,0 jnc CYWAS0 dad sp stc jmp CYWAS1 CYWAS0: dad sp stc cmc CYWAS1: shld mystck lhld reg_sp sphl lhld reg_hl instr: nop ; emulace instrukce nop nop shld reg_hl ; a uschovat trasovací registry tradon: lxi h,0 jnc CWAS0 ; pozor! dad ruší CY dad sp stc jmp CWAS1 CWAS0: dad sp stc cmc CWAS1: shld reg_sp lhld mystck sphl xchg shld reg_de push b pop h shld reg_bc push psw pop h shld regpsw call rgprn1 ; výpis registrů po 1 kroku call rgprn2 trcwai: call matchw ; čekání na klávesnici jc trcend call inkey jnc trcwai jmp tracel trcend: lxi sp,7fffh ; konec trasování jmp cmdend emujmp: mov a,m ; emulace skokových instrukcí inx h sta instr mov a,m inx h sta sucjmp+1 mov a,m inx h sta sucjmp+2 shld reg_pc lxi h,my_jmp shld instr+1 jmp inshlt my_jmp: shld reg_hl ; emulace úspěšného skoku JMP sucjmp: lxi h,0 shld reg_pc jmp tradon ; *********************************************** ; příkaz pro prohlížení paměti v grafickém režimu ; *********************************************** cmdg: lhld curch mov a,m lxi d,vertic cpi 'V' jz cmd_gp lxi d,horizn cpi 'H' jnz cmd_gd cmd_gp: inx h cmd_gd: shld curch xchg shld cmd_gv+1 call mstadr call tstbyt jc cmdpar ; test na rozsah 1..43 cpi 2ch jnc asmerr sta ghpar+1 sta gvpar+1 cmdpar: xchg cmd_gl: call adrout cmd_gv: call 0 call moneol jc cmd_gl jmp cmdend horizn: xchg ; DE = zdroj lhld prtpos lxi b,(-10)*64 dad b ; HL = videoram mvi c,9 ; 9 pixelů pod sebou ghpar: mvi b,2 ; počet bajtů vedle sebe push h ghline: ldax d mov m,a inx d inx h dcr b jnz ghline pop h push b lxi b,64 dad b pop b dcr c jnz ghpar xchg ret vertic: xchg ; DE = zdroj lhld prtpos lxi b,(-10)*64 dad b ; HL = videoram gvpar: mvi b,2 ; počet bajtů vedle sebe gvrow: mvi c,9 ; 9 pixelů pod sebou gvcol: ldax d mov m,a inx d push b lxi b,64 dad b pop b dcr c jnz gvcol push b lxi b,(-9)*64+1 dad b pop b dcr b jnz gvrow xchg ret ; ***************** ; systémové příkazy ; ***************** newcmd: .db '%',0 ; * .dw cmdpro .db '/',0 ; * .dw cmdsrg .db '.',0 ; * .dw cmdasm .db '+',0 ; * .dw cmdpls .db '-',0 ; * .dw cmdmns .db '>',0 ; * .dw cmdsub .db '@',0 ; * .dw cmdzav .db 'A',0 ; * .dw cmd_a .db "BLOCK",0 ; * .dw cmdblk .db "CHECK",0 ; * .dw cmdchc .db "COPY",0 ; * .dw cmdcpy .db "CMP",0 ; * .dw cmdcmp .db "FILL",0 ; * .dw cmdfil .db "FIND",0 ; * .dw cmdfin .db 'D',0 ; * .dw cmddis .db "FILE",0 ; * .dw cmdfaj .db "G",0 ; * .dw cmdg .db "HACK",0 ; * .dw cmdhck .db "IN",0 ; * .dw cmdin .db "JUMP",0 ; * .dw cmdjmp .db "LOAD",0 ; * .dw cmdlad .db 'M',0 ; * .dw cmd_m .db 'N',0 ; * .dw cmd_n .db "OUT",0 ; * .dw cmdout .db "PORT",0 ; * .dw cmdpor .db "QUIT",0 ; * .dw cmdqui .db "REPLACE",0 ; * .dw cmdrep .db "SAVE",0 ; * .dw cmdsav .db "SCAN",0 ; * .dw cmdscn .db "STACK",0 ; * .dw cmdstk .db "SUM",0 ; * .dw cmdsum .db "SWAP",0 ; * .dw cmdswp .db "TRACE",0 ; * .dw cmdtrc .db "TURBO",0 ; * .dw cmdtrb .db "VERIFY",0 ; * .dw cmdvrf .db "WAIT",0 ; * .dw cmdwai .db 0ffh .include "opcode.a85" .end