braner@batcomputer.TN.CORNELL.EDU (braner) (11/03/86)
[] /* * Program to code ST screens in a text file. * By Moshe Braner, 861103. * * Run once, it stays in RAM and is activated by Alt-Help. * * This version written for the Megamax C compiler. */ #include <osbind.h> /* register assignments: */ #define REPN D3 #define INDEX D4 #define REP D5 #define ROW D6 #define OUTN D7 #define OLD A2 #define COL A3 #define PHYS A4 #define COLS A5 #define VAR A6 #define BUF A6 #define SP A7 /* non-register variables: */ #define HAND -2 #define ROWS -4 #define RES -6 #define LINEN -8 #define CHKSUM -12 /* long! */ #define DTA -60 /* 44 bytes */ extern dump(); asm { dump: MOVE.W #1,0x4EE MOVEM.L A6-A0/D7-D0,-(SP) LEA vars+60(PC),VAR MOVE.B 0xFF8260,D0 /* video resolution */ AND.L #0x00000003,D0 MOVE.L D0,CHKSUM(VAR) MOVE.W D0,RES(VAR) ADD.W #0x30,D0 MOVE.B D0,(BUF) /* output resolution (1 byte) */ LEA dumpname+8(PC),A0 MOVE.B D0,(A0) /* modify file name */ PEA DTA(VAR) /* check for last file name used */ MOVE.W #0x1A,-(SP) /* SETDTA */ TRAP #1 ADDQ.L #6,SP chkname: CLR.W -(SP) /* attribute 0 = normal files */ PEA dumpname(PC) MOVE.W #0x4E,-(SP) /* SFIRST */ TRAP #1 ADDQ.L #8,SP TST D0 BNE.S okname /* not found - use it */ LEA dumpname+4(PC),A0 CMPI.B #0x5A,(A0) /* was 'A' - up to 'Z' ? */ BLT.S incname MOVE.B #0x41,(A0) /* back to 'A' */ BRA.S okname incname: ADDQ.B #1,(A0) BRA.S chkname okname: CLR.W -(SP) /* attribute 0 = r/w file */ PEA dumpname(PC) MOVE.W #0x3C,-(SP) /* CREATE */ TRAP #1 ADDQ.L #8,SP TST D0 /* any errors? */ BMI cleanup /* - then skip */ MOVE.W D0,HAND(VAR) /* file handle */ MOVE.W #2,-(SP) /* PHYSBASE */ TRAP #14 ADDQ.L #2,SP MOVE.L D0,PHYS /* video RAM */ MOVEQ #1,OUTN /* output char counter */ MOVE.W #1,LINEN(VAR) /* line length counter */ MOVE.L #0xFF8240,A0 /* palette */ MOVE.W #15,D2 palette: /* output palette (48 bytes) */ CLR.L D0 MOVE.W (A0)+,D0 ADD.L D0,CHKSUM(VAR) BSR codeuniq DBF D2,palette LEA consts,A0 /* read constants from table */ MOVE.W RES(VAR),D0 ADD.W D0,D0 MOVE.W 0(A0,D0),ROW MOVE.W ROW,ROWS(VAR) MOVE.W 6(A0,D0),COLS MOVE.W #0,COL /* set up for coding */ SUBQ.W #1,ROW CLR.W REP CLR.W INDEX BSR nextw MOVE.W D0,OLD BRA.S comp2 comp1: /* compress the picture */ MOVE.W COL,D0 CMP.W COLS,D0 BGE.S endloop MOVE.W ROWS(VAR),ROW MOVE.W COL,INDEX comp2: BSR nextw CMP.W OLD,D0 BNE.S notrep TST.W REP BNE.S oldrep SEQ REP MOVEQ #1,REPN oldrep: CMP.W #127,REPN BLT.S loop1 notrep: EXG D0,OLD TST.W REP BEQ.S uniq CLR.W REP BSR coderep BRA.S loop uniq: BSR codeuniq loop: BNE.S close /* error writing file */ loop1: ADDQ.W #1,REPN DBF ROW,comp2 ADDQ.W #1,COL BRA comp1 endloop: TST.W REP /* in middle of repetition? */ BEQ.S done MOVE.W OLD,D0 /* then go finish it... */ BSR coderep done: MOVE.W CHKSUM(VAR),D0 /* append coded checksum */ BSR codeuniq MOVE.L CHKSUM(VAR),D0 BSR codeuniq BSR crlf /* end last line */ BSR save /* save to disk */ close: MOVE.W HAND(VAR),-(SP) MOVE.W #0x3E,-(SP) /* CLOSE file */ TRAP #1 ADDQ.L #4,SP cleanup: MOVEM.L (SP)+,D0-D7/A0-A6 MOVE.W #0xFFFF,0x4EE /* ADDQ.L #4,SP ROM does it, so me too? */ RTS /* return to interrupt handler */ coderep: MOVE.W D0,D1 MOVE.W REPN,D0 LSR.W #2,D0 ORI.W #0x40,D0 BSR notz LSL.W #4,REPN MOVE.W D1,D0 LSR.W #6,D0 LSR.W #6,D0 OR.W REPN,D0 BRA.S code1 codeuniq: MOVE.W D0,D1 LSR.W #6,D0 LSR.W #6,D0 code1: BSR outbyte MOVE.W D1,D0 LSR.W #6,D0 BSR outbyte MOVE.W D1,D0 BSR outbyte CMP.W #4600,OUTN /* buffer almost full? */ BLT.S nosave save: /* save to disk */ MOVE.L BUF,-(SP) EXT.L OUTN MOVE.L OUTN,-(SP) MOVE.W HAND(VAR),-(SP) MOVE.W #0x40,-(SP) /* WRITE to file */ TRAP #1 ADDA #12,SP CMP.W OUTN,D0 BNE.S error /* retain error code */ CLR.W OUTN nosave: CLR.W D0 /* no error */ error: RTS nextw: /* read 2 bytes from screen */ CLR.L D0 MOVE.B 0(PHYS,INDEX),D0 ADD.W COLS,INDEX LSL.W #8,D0 MOVE.B 0(PHYS,INDEX),D0 ADD.W COLS,INDEX ADD.L D0,CHKSUM(VAR) RTS outbyte: /* put byte in buffer */ AND.W #0x3F,D0 BEQ.S zzz ADD.W #0x20,D0 /* offset by ' ' */ BRA.S notz zzz: MOVE.W #0x7A,D0 /* but avoid ' ' itself */ notz: MOVE.B D0,0(BUF,OUTN) ADDQ.W #1,OUTN ADDQ.W #1,LINEN(VAR) CMPI.W #64,LINEN(VAR) /* line long enough? */ BLT.S nocrlf crlf: MOVE.B #0x0D,0(BUF,OUTN) /* then append cr-lf */ MOVE.B #0x0A,1(BUF,OUTN) ADDQ.W #2,OUTN CLR.W LINEN(VAR) nocrlf: RTS dumpname: /* filename: "DUMPA.CSn" - will be changed */ DC.B 0x44,0x55,0x4D,0x50,0x41,0x2E,0x43,0x53,0x6E,0x00 consts: /* rows/2-1, columns */ DC.W 99,99,199,160,160,80 vars: /* 60-byte variable space, */ /* then 4608-byte output buffer */ } char dummy[4668]; /* ensure enough space in SBRK */ extern poke_it(); /* put our vector for screen dump */ asm { poke_it: LEA dump,A0 MOVE.L #0x000502,A1 MOVE.L A0,(A1) RTS } char *text[] = { "\033E\r\n", "\t+--------------------------+\r\n", "\t| SCREEN DUMP PROGRAM |\r\n", "\t| (Compressed format) |\r\n", "\t| for |\r\n", "\t| Atari ST with TOS in ROM |\r\n", "\t| by Moshe Braner, 8610 |\r\n", "\t+--------------------------+\r\n", "\r\n", "\tProgram installed. Hit any key.\r\n", "\r\n", "\t(Later: press Alt-Help for a screen dump.\r\n", "\t Dumps into files DUMPA.CSn, DUMPB.CSn, ...\r\n", "\t where n = 0, 1 or 2 for lo, med or hi res.)\r\n", "\r\n\n", "" }; main() { register char c; register char *cp; register char **cpp; Supexec(&poke_it); /* mess with vector */ cpp = &text[0]; /* print message */ while (*(cp=*cpp++)) while (c=*cp++) Bconout(2, c); Bconin(2); /* wait for keypress */ Ptermres((long)6000, 0); /* stay resident */ } - Moshe Braner, Cornell U.