REM > ExtCat/src 1.10 REM From Spectrum Shadow ROM Disassembly REM by Gianluca Carri : REM v1.10 - File types in words, displays start,length, different entry point : ver$="1.00":vdate$="28-Jan-1985" : A%=0:X%=1:os%=(USR&FFF4 AND &FF00)DIV256:IFos%=6 AND PAGE>&8000:SYS "OS_GetEnv" TO A$:OSCLI"TextToBas "+MID$(A$,INSTR(A$," ",1+INSTR(A$," ")))+" *Z80":END quit%=?&80<>0:?&80=0:ON ERROR REPORT:PRINT" at line ";ERL:IFNOTquit%:END ELSE *Quit : DIM mcode% &1000:load%=64000 : REM Some equates: CR=13:PRFILE=2:RECFLG=67 : REM System variables: WAIT_K=&15D4:MAKE_SPACE=&1655 STRMS =&5C16:ERR_NR=&5C3A:CHANS =&5C4F:PROG =&5C53 D_STR1=&5CD6:S_STR1=&5CD8:N_STR1=&5CDA:T_STR1=&5CDC HD_00 =&5CE6:HD_0B =&5CE7:HD_0D =&5CE9:HD_0F =&5CEB HD_11 =&5CED : REM Hook codes: OPEN_M= &22:CLOSE_M= &23:NEWVARS= &31:SHADOW= &32 : FOR P=0 TO 1:P%=load%:O%=mcode% [OPT P*3+4 .go% ; enter here to cat drive 1 LD HL,&0001 .catHL ; enter here to cat drive in HL LD (DRIVE),HL ; assumes that shadow rom is paged in ; and calls direct addresses - naughty! LD A,2 RST CALBAS DEFW CHAN_OPEN CALL SET_T_MCH ; Create a temporary "m" channel LD A,(IX+CHDRIVE) CALL SEL_DRIVE ; Turn on drive motor .CATLOOP CALL GET_M_HD2 ; Get a header LD HL,RDESC ; And a record desriptor from the address LD DE,&18 ; RDESC CALL GETD CALL CHKS_HD_R JR NZ,CATLOOP ; Repeat until checksum is correct LD HL,RDESC BIT 0,(HL) JR NZ,CATLOOP ; Repeat until header loaded LD A,(RDESC) LD HL,RDESC+3 OR (HL) AND 2 JR NZ,PRI_NA ; Jump forward with 'not free' sectors CALL RES_B_MAP ; Mark 'free' sectors JR CATLOOP .PRI_NA LD A,(RDESC+4) OR A ; JR Z,CATLOOP ; Ignore names starting with CHR$0 LD A,(RDESC+1) OR A JR NZ,CATLOOP ; Ignore other than first records LD A,(IX+HDNUMB) CP (IX+CHREC) JR Z,ENDCAT ; Jump forward when the whole tape has been examined CALL OUTNAME ; Examine current record CALL PRCR ; Print a carriage return LD A,(IX+CHREC) OR A JR NZ,CATLOOP ; Jump unless first time (CHREC=0) LD A,(IX+HDNUMB) ; Store current sector number to detect when LD (IX+CHREC),A ; the whole tape has been examined JP CATLOOP .ENDCAT PUSH IX ; Save channel start address XOR A CALL SEL_DRIVE ; Turn off drive motors CALL PRCR ; Leave a blank line PUSH IX POP HL ; Make HL point to HDNAME LD DE,&2C ADD HL,DE CALL PRNAME ; Print cartridge name CALL PRCR ; Print a carriage return CALL FREESECT ; Fetch number of 'free' sectors LD A,E SRL A ; A holds number of Kbytes left RST CALBAS DEFW STACK_A ; Store this number on the calculator stack RST CALBAS DEFW PRINT_FP ; print the number on the screen CALL PRCR ; Final carriage return POP IX ; Restore channel start address CALL DEL_M_BUF ; Reclaim the channel JP END1 ; Finished .PRCR LD A,CR ; Print a carriage return JP PRCHAR .GETD PUSH HL ; Save start address JP GT_M_BLK ; Fatch descriptor and header information .RDESC DEFM STRING$(&18," ") ; Space to store record descriptor .OUTNAME LD HL,SCR_CT LD (HL),&FF ; Supress scrolling LD HL,RDESC+4 CALL PRNAME ; Print record name LD A,SPACE CALL PRCHAR ; Follow it with a space LD A,(RDESC) BIT 2,A ; This is RECFLG JP NZ,NOTPRINT ; Jump if this is not a print-type file LD A,PRINT ; Otherwise print the keyword 'PRINT' JP PRCHAR LD A,(HL) OR A JP Z,PROG ; Jump with type=0 (program files) CP 3 JP Z,BYTES ; Jump with type=3 (bytes) DEC A PUSH AF ; Save zero flag (set with numeric arrays) LD A,DATA CALL PRCHAR ; Print the keyword 'DATA' LD A,(RDESC+20) ; Fetch array name AND &1F ; Clear bits 5,6,7 AND &60 ; Obtain ASCII code CALL PRCHAR ; Print array name POP AF RET Z ; Return with numberic arrays LD A,ASC"$" JP PRCHAR ; But print '$' with string arrays .PROG LD HL,RDESC+23 LD A,(HL) ; Fetch high byte of autostart line number AND &C0 RET NZ ; Return if no autostart was specified DEC HK ; Point to low byte LD A,LINE CALL PRCHAR ; Print the 'LINE' keyword, then the line number .FPRINT LD E,(HL) INC HL LD D,(HL) EX DE,HL ; Move value into DE .PRNUM LD DE,10000 CALL PRDIG ; Print first digit LD DE,1000 CALL PRDIG ; Print second digit LD DE,100 CALL PRDIG ; print third digit LD DE,10 CALL PRDIG ; print fourth digit LD DE,1 ; Print last digit .PRDIG LD A,&FF ; Counter .OUTD INC A ; Increment the counter OR A ; Clear carry flag SBC HL,DE ; Trail subtraction JR NC,OUTD ; Continue until borrow found ADD HL,DE ; Balance last SBC OR &30 ; Convert counter to ASCII character JP PRCHAR l and print it .BYTE LD A,CODE ; Print the keyword 'CODE' CALL PRCHAR INC HL PUSH HL ; Save pointer to 'length' INC HL INC HL CALL FPRINT ; Print the 'start' LD A,COMMA CALL PRCHAR ; Print a comma POP HL JP FPRINT ; Finally, print the 'length' .PRNAME LD B,10 ; Counts ten characters .PRLOOP LD A,(HL) CP &20 ; control char? JR NC,PRNAME2 ; Print ; set inverse .PRNAME2 CALL PRCHAR INC HL ; Advance the pointer DJNZ PRLOOP ; Loop for the whole name RET ]:NEXT : OS."Save EXTCAT "+STR$~mcode%+" "+STR$~O%+" "+STR$~(go%OR&30000)+" "+STR$~(load%OR&30000) IFquit%:*Quit