**************************************************************************** * * RAM-based Console-Device text- and binary file viewer. * RAM-based virtual screen picture/image viewer. * ** THIS IS THE SPEICIAL VERSION, 4.4-LE - REAL "LINE EDIT" IMPLEMENTED!!!!! * * * Copyright 1992 - 1999 Jörg van de Loo * Hövel 15 * 47559 Kranenburg * Germany * * No e-mail address ( - released to the public!). * * -13.06.1992, 22:58:59- V1.0 - Text viewer (PowerPacker (© Nico François) support) * -14.06.1992 23:55:43- V2.0 - Text and picture viewer (thanks to Holger Gzella for picture decoding) * -24.09.1992, 14:47:32- V3.0 - Text, picture and binary files viewer * ... * -04.04.1993, 23:07:01- V3.6 - Rewritten for OS 3 (mainly, console handling...) * -18.06.1994, 21:05:22- V3.7 - Up from this version 100% OS 3 compatible, also brush support * (complete re-work of picture decoding) * -24.06.1994, 15:33:28- V3.8 * -26.06.1994, 01:54:47- V3.9 * -28.06.1994, 14:42:19- V3.A * -30.06.1994, 00:23:00- V3.B - Bug fixed version * -08.01.1995, 22:04:00- V3.BA - better Monitor handling plus ACBM files viewer - * pure sentimental - want to see old Amiga Basic used * pictures. * Now Viewer supports also a masking plane .... * -15.05.1996, 12:45:47- V3.C1 - FinalCopy-II and IFF-Text ASCII extracting support * -25.05.1996, 16:03:25- V3.D3 - Pweeh, string search routine implemented.... * I crashed my system totally with lost of the source * because I forgot to give DisplayBeep() a parameter (NULL). * With MasterSekaV1.71 I recovered the lost source. * -23.08.1997, 21:22:54- V3.D38 - Viewer can now display 8bit images 100% correctly on a CyberGrafX (41.2+) screen * -28.12.1997, 23:03:31- V3.D39 - After heavy request AutoRequester now supports keys (AMIGA-V, AMIGA-B) * -19.02.1998, 09:53:16- V3.D3A - Viewer is now compatible (97%) to the Picasso96 software package * and to other alien gfx-board software packages (I hope so). * -18.10.1998, 21:44:21- V3.D3B - Viewer is now able to display 24 bit images on my gfx-card (CyberVision3D) * -09.04.1999, 22:26:29- V3.E00 - Conversion from HAM8 to 24 bit added (Picasso96 now 100% compatible to Viewer!!!) * -23.04.1999, 20:04:31- V3.ED0 - HAM6 to 24 bit tune-up implemented (removed code for HAM6 to 16 bit - too less brillance) * -01.05.1999, 23:31:48- V3.EDE - Removed bug that caused machine to crash upon displaying non-super bitmap images * on native AMIGAs and which was introduced with the code to display HAM8 images on * a 24 bit screen (set two `bne´ to wrong labels where one lead to an invalid stack) * -12.08.1999, 19:47:20- V4.0 - Added function to play either compressed or uncompressed 8SVX mono sound files from * fast memory. * -19.11.1999, 15:32:17- V4.4 - Added support for 9 to 16 bitplane images (versions 4.1 - 4.3 extremly faulty) * * * * * Simple Text-, Binary- and Image-file viewer for the Amiga Operation System. * * This material is released "as it", no warranties are made! * * The program-code is position independent and resident capable. * It requires kickstart 1.2 or higher and an Amiga Custom-Chip-Set (due * some code which can be easily rewritten for non based Amiga Custom Chip * Set computers). AA- (AGA) resolution support added for pic-viewer of V3.7. * * Tested successfully under SegTracker, Enforcer, Mungwall, IOTorture in * many circumstances. * * The executeable based on this source may freely distributed so long the * copyright notice is unmodified - known as FreeWare. * * The source-code may improved by anyone who wants to do it - in this case * please read the "PRG-ShouldRead" file first - for the agreements. * * This source-code may enclosed to _ANY_ assembler package (also in * modified form) for an example "how to code in 680x0 assembler", but the * copyright notice must be at least unaltered. * * * Noone can say: Copyright "Whose name" - I'm (J.v.d.Loo) the copyright holder! * * * This program was written using HiSoft's Devpac Amiga 3 assembler - * without its special advantages. * * * If anyone takes money for this source-code, object-file or enclosed | * documentation and someone tells me - the fellow who took the money will | * meet me - more than 6 foots tall, more than 200 pounds - and what's very | * dangerous - carrier of the stinking sock - but my Master told me to take | * off my shoes only in an emergency - the smell is not the worst - he said | * - but the burning eyes... | * * * NOTES: * This source file can be assembled unmodified at least with: * HiSoft's Devpac Amiga Assembler 3 (commercial) [fast assembler] * Samu Noujua's SNMA Assembler 1.99 (freeware) [fast assembler] * Frank Wille's PhxAss Assembler 4.18 (shareware) [medium assembler/ fast linker] * * For the Macro-System's Draco computer you have to remove all lines which * are accessing the hardware directly. * * List of what to do... * Printer status should be tested via parallel/and or serial devices, * using QUERY-command. * Picture display routine must first open the screen, then a window. * 'Blit' the image to the window rastport instead of screen's bitmap. * May replace code for scrolling SuperBitMaps through 'Blits' because * the most 3rd graphic board software doesn't support changes of View * dx/dy, or they don't support custom bitmaps and then the image * screen's bitmap is only as tall as the standard monitor resolution. * Status of left- and right mousebuttons can be easily checked via * IDCMPs of the (added) image window. * The other code is system-conform (I hope...). IFD __G2 OUTPUT RAM:Viewer ; Child's name when using Devpac MACHINE MC68000 ; Processor selection ENDC * OPT D+ include exec/types.i include exec/memory.i include exec/ports.i include exec/lists.i include exec/devices.i include exec/execbase.i include graphics/gfx.i include graphics/text.i include graphics/rastport.i include graphics/gfxbase.i include graphics/graphics_lib.i include intuition/intuition.i include intuition/screens.i include intuition/intuitionbase.i include intuition/intuition_lib.i include dos/dos.i include devices/audio.i *********************************** * * Define needed constants and arrays * STRUCTURE _Table,68 ; Begin at offset 68 (end of table used by startup-code) ULONG _dummy000 ; Only to make "FIB" staying on a through eight * divisible address - you may use "ALIGNLONG" * MACRO instead... STRUCT _FIB,272 ; FileInfoBlock STRUCT _NewScreen,ens_SIZEOF ; Screen's structure STRUCT _StdTags,56 ; Screen's taglist (up from OS 2.0) STRUCT _WindowRecord,nw_SIZEOF ; Window's structure STRUCT _ErrWindowStruc,nw_SIZEOF ; Ditto STRUCT _Gad1,gg_SIZEOF STRUCT _Gad2,gg_SIZEOF STRUCT _GTxt1,it_SIZEOF STRUCT _GTxt2,it_SIZEOF STRUCT _Gad3,gg_SIZEOF ; Audio Hit Gadget, no text STRUCT _ArpReqStruc,32 ; Only 26 bytes are needed STRUCT _UserFontStruc,8 ; Font-record ALIGNLONG ULONG _RealIWidth ; No boundary ULONG _ImageWidth ; 16 bit boundary * BMHD-settings follow..... - used for picture UWORD _Width ; May be taller than displayable... (64 bit boundary) UWORD _Height ; ditto UWORD _XPos UWORD _YPos UBYTE _Depth UBYTE _Masking UBYTE _Compresstyp UBYTE _BMHDFlags ; Was before ks 3.0 unused (bmhd_pad) UWORD _TransColour UBYTE _XAspect UBYTE _YAspect UWORD _PlaneWidth ; Visible size UWORD _PlaneHeight ; ditto UWORD _Dummy ; Strictly for longword adjustment ULONG _ViewPortMod STRUCT _Colourmap,1024 ; Max. room for 256 colours ULONG _TypeOfMem ; Which memory type used for bitmap allocation? (~0 = CHIP, 0 = ANY) LONG _ViewPortShare ; Can we change through RasInfo the visible part of an image ( 0=yes,1=yes,-1=no) ULONG _HAMSet ; Depth of image in case image is HAM encoded UWORD _OldY ; Used only for ks lower than v36 UWORD _OldX ; Used only for ks lower than v36 UWORD _BgPen ; Colour-index for background of window's title STRUCT _DisplayInfo,dis_SIZEOF ; Buffer for DisplayInfoData ALIGNLONG ; <- EXEC/EXEC_TYPES.I APTR _GfxBase APTR _IntuitionBase APTR _ReqToolsBase APTR _ArpBase APTR _CyberGfxBase APTR _ScreenPtr APTR _ReqPtr ; ReqTools requester record ULONG _argError ; Not zero upon argument error ULONG _LinesInFile ; Number of lines in file ULONG _UPFSize ; Uncompressed file size ULONG _IncSize ; Increased uncompressed file size ULONG _Line ; Current line where cursor stays ULONG _PageWidth UWORD _StdPageSize ; Std. scrollwidth for console in lines ALIGNLONG APTR _ErrWindowPtr ; Intuition window record APTR _DecrunchAddr ; Address decrunched file APTR _StdprWindowPtr ; Old pointer for system requesters APTR _PtrToWTitle ; Pointer to window's title text APTR _UserProject ; Info-file (for icon.library) APTR _WindowPtr ; Intuition window record APTR _IAddr ; Window's object that raised message STRUCT _WindowTitle,148 ; Room for window's title (title is * changed each time a new file is loaded) LABEL _WriteIo ; Startaddress for console-write message STRUCT _Msg,20 ; Message length, 20 byte STRUCT _Io,12 ; Console-write IO, 12 bytes STRUCT _WriteReq,16 ; Console-write request, 16 bytes STRUCT _WriteReply,34 ; ReplyPort for Console-write STRUCT _ReadIo,48 ; Console-read message including IO and REQ STRUCT _ReadReply,34 ; Console-read reply port ALIGNLONG APTR _TextPtr ; Address file in memory APTR _BufferSize ; Allocated size LONG _FileSize ; File's real size BPTR _LockSave ; Key to file (closed) BPTR _FileHandle ; Handle (closed) APTR _UserFontPtr ; Font record (perhaps opened) APTR _OldFontPtr ; System's default font APTR _SearchStrPtr ; Pointer to search address (from where to continue) ULONG _SearchStrLen ; Length of search string ULONG _CharBuffer ; Read char of IO-request to build complete search string STRUCT _IOReqString,256 ; Buffer which contains search string STRUCT _IOInlineBuf,64 ; Buffer for converting IO-status report to ascii APTR arg_1 ; Shell arguments.... APTR arg_2 APTR arg_3 STRUCT WB_arg_1,60 ; WBench arguments (tooltypes) (max.: 14!!!) BPTR lock_1 ; Overgiven files (Workbench, -the trick APTR file_1 ; with the shift...) * BPTR lock_2 * APTR file_2 * BPTR lock_3 * APTR file_3 STRUCT _Drive,256 ; Buffer for volume's/directory's name STRUCT _File,108 ; The filename itself STRUCT _FileName,364 ; Merged name in dos-convention STRUCT _UserFontBuf,108 ; Into this buffer the name of the font * the user want to use is copied from the * tooltypes - so that we can modify it STRUCT _ConBuffer,256 ; Buffer for console commands APTR _SourceFileSize ; Same as FileSize (used by picture) APTR _SourceFilePtr ; Same as TextPtr + 2 (used by picture) APTR _RGB24Ptr ULONG _RGB24Size APTR _Bitplane ; Address decompressed ILBM file (chip mem) ULONG _AllPlaneSize ; Size of all planes (connected bitplanes) STRUCT _BitmapStruc,bm_SIZEOF+(4*16) ; Screen's or image's bitmap (for safety, 24 bit depth) ULONG _CMapNumEntries ; Colourmap entries (max. 256) APTR _RGB32Values ; Pointer to 32Bit colours of ILBM-file STRUCT _RGB32Colours,((256*3)+2)*4 ; Room for 256 32Bit colours (see LoadRGB32()) UWORD _RMB ; State of right mouse button UWORD _Max ; Local used (haven't got enough unused registers) UWORD _MouseID ; Saved mouse event UWORD _PageSize ; Number of lines of one page UWORD _XOffset ; X and Y offset for console window, UWORD _YOffset ; specified in ToolType UBYTE _NoLineFlag ; Flag, if it is non-zero, the lines are * not counted, e.g. when restoring window * contents UBYTE _NoWarnFlag ; When this flag is set, displaying * warnings is supressed UBYTE _NoCheckPrtFlag ; When this is set, the printer is not checked UBYTE _WrapFlag ; When this is set, make a word wrap when * the contents of one line do not fit in window UBYTE _PageSizeFlag ; When this flag is set, the user has got defined the * scrollwidth UBYTE _ReqFlag ; Indicates which requester is used, * 0 == no requester opened till now * 1 == ReqTools * 2 == Arp * -1 == bad luck, ReqTools nor Arp could be opened UBYTE _LoadFlag ; Indicates loading or saving, 0 == saving UBYTE _BlitFlag ; Local used, means blit image to screen UBYTE _SuperBitMap ; Local used, means screen uses a superbitmap UBYTE _RIChanged ; Local used, RasInfo is changed, so call * MakeScreen() and RetinkDisplay() ALIGNLONG APTR _AudioBuffer ; Address audio datas in Chip-Mem ULONG _AudioBufferSize ; How tall is that buffer? ULONG _AudioPeriod ; How many samples per second? APTR _VHDRPtr APTR _BODYPtr ULONG _BODYSize APTR _IOAudio UBYTE _AudGadget LABEL _TableSize ; Pweeh, size of the defined constants and * arrays, is automatically allocated when * this program is started (done by startup-code) * ** Include the startup-code * include RAD:include/startup.easy ; Simple but effective startup-code * - perhaps you should change directory... * ** RAW-key equates.... * CRSR_UP equ $4C ; Page Up CRSR_DN equ $4D ; Page down CRSR_BK equ $4E ; one line back CRSR_FD equ $4F ; one line further L_Key equ $28 ; load new E_Key equ $12 ; enlarge window H_Key equ $25 ; help page I_Key equ $17 ; info A_Key equ $20 ; about page T_Key equ $14 ; top of file B_Key equ $35 ; bottom of file W_Key equ $11 ; window contents to prt P_Key equ $19 ; print file to prt F_Key equ $23 ; print file to file C_Key equ $33 ; window contents to file PG_UP equ $3F ; page up PG_DN equ $1F ; page down RETURN equ $44 ; one line down ENTER equ $43 ; one line down HOME equ $3D ; top of file END equ $1D ; button of file R_SHIFT equ $61 ; one line back (step) R_Key equ $13 ; refresh Window S_Key equ $21 ; Search (find) N_Key equ $36 ; Next search (find) PrtSc equ $5D ; print screen to prt HELP_Key equ $5F ; Display title * - ReqTools IFND _LVOrtAllocRequestA _LVOrtAllocRequestA EQU -30 ENDC IFND _LVOrtFreeRequestA _LVOrtFreeRequestA EQU -36 ENDC IFND _LVOrtChangeReqAttrA _LVOrtChangeReqAttrA EQU -48 ENDC IFND _LVOrtFileRequestA _LVOrtFileRequestA EQU -54 ENDC * - Arp IFND _LVOArpFileRequest _LVOArpFileRequest EQU -294 ENDC * - DiskFont IFND _LVOOpenDiskFont _LVOOpenDiskFont EQU -30 ENDC * - CyberGraphics IFND _LVOWritePixelArray _LVOWritePixelArray EQU -126 ENDC IFND RECTFMT_RGB RECTFMT_RGB EQU 0 ENDC ************************************************************* * * This subroutine parses the Shell arguments. * Inputs: none (routine uses global constants). * Result: ErrorCode placed in "_argError", see "EQU's" below. * * Remarks: Only three arguments are parsed (if available). * ed_QuoteNotAllowed EQU 1 ; Possible errorcodes ed_MissingEndQuote EQU 10 ; stored in "_argError" _getArg movea.l _argv(A5),A0 lea arg_1(A5),A1 moveq #0,D2 bra.s _getArg1.1 _getArg.1 addq.b #4,D2 cmpi.b #12,D2 ; 3 args * à 4 bytes = 12 beq.s _argEnd cmpi.b #' ',(A0) beq.s _skipUnused _getArg1.1 cmpi.b #10,(A0) beq.s _argEnd _getArg.2 cmpi.b #'"',(A0) beq.s _inQuotes _noQuotes move.l A0,(A1,D2.w) _stdLoop cmpi.b #'"',(A0) beq.s _argError.1 cmpi.b #10,(A0) beq.s _noMoreArg cmpi.b #' ',(A0) beq.s _nextArgument addq.l #1,A0 bra.s _stdLoop _nextArgument clr.b (A0)+ bra.s _getArg.1 _inQuotes addq.l #1,A0 move.l A0,(A1,D2.w) _quoteLoop cmpi.b #10,(A0) beq.s _argError.2 cmpi.b #'"',(A0) beq.s _nextArgument addq.l #1,A0 bra.s _quoteLoop _noMoreArg clr.b (A0) 1$ addq.b #4,D2 cmpi.b #12,D2 ; max: 3 arguments beq.s _argEnd clr.l (A1,D2.w) bra.s 1$ _argEnd rts ; back _skipUnused addq.l #1,A0 cmpi.b #' ',(A0) beq.s _skipUnused bra.s _getArg1.1 _argError.1 moveq #ed_QuoteNotAllowed,D0 bsr.s _setArgError subq.b #4,D2 bra.s _noMoreArg _argError.2 moveq #ed_MissingEndQuote,D0 bsr.s _setArgError subq.b #4,D2 bra.s _noMoreArg _setArgError move.l D0,_argError(A5) rts ****************************************************************************** * * Routine to parse from Workbench overgiven files. * Inpts: D0 - how many arguments (files) allowed to store * D1 - how many arguments are there?, * A0 - pointer to sm_ArgList (global - startup-code -> WBench-message), * A1 - address array for lock of file and filename, - * - array must look like this: * BPTR Lock * APTR File (string pointer) * BPTR Lock * APTR File (string pointer) * ... and so on * Results: none * _GetWBFiles subq.l #1,D1 beq.s 3$ bcs.s 3$ addq.l #4,A0 bra.s 2$ 1$ addq.l #4,A0 move.l (A0),(A1)+ ; Lock addq.l #4,A0 move.l (A0),(A1)+ ; Filename subq.l #1,D1 ; argc -1 beq.s 3$ 2$ dbf D0,1$ 3$ rts **************************************************** * * Subroutine to set the returncode for this program, * use Shell-command why to investigate the error. * * Inputs: D0 - errorcode * Results: none * _SetError move.l D0,_errno(A5) _setError4Task movea.l _SysBase(A5),A0 movea.l 276(A0),A0 ; ThisTask move.l D0,pr_Result2(A0) rts ****************************************** * * Entry point, called out of startup-code. * _main ; Startup-Code enters here... bsr.w _InitStandard ; Init windows tst.l _WBenchMsg(A5) bne.s .GetWBArgs ; If we are started from workbench bsr.w _getArg ; otherwise parse Shell arguments bra.s .argsOk .GetWBArgs tst.l _argc(A5) ; Any file given (from WB)? beq.s 0$ moveq #1,D0 ; Max. allowed number of arguments! move.l _argc(A5),D1 ; Number of arguments stored (WB) movea.l _argv(A5),A0 ; sm_ArgList pointer lea lock_1(A5),A1 ; Address buffer bsr.s _GetWBFiles ; Call subroutine to parse files 0$ moveq #13,D0 ; 14 Entries tst.l _ToolTypesArray(A5) beq.s .argsOk movea.l _ToolTypesArray(A5),A0 ; Pointer to ToolTypeArray lea WB_arg_1(A5),A1 ; Address first WB-Text 1$ tst.l (A0) beq.s .argsOk ; If no more texts are set... move.l (A0)+,(A1)+ ; WB-Arg-Text -> Arg[1..] a.s.o. dbf D0,1$ .argsOk move.l #20,_errno(A5) bsr.w _SetPrefs ; See there bsr.w _OpenROMLibs ; Open libraries tst.l _WBenchMsg(A5) ; WB-start? beq.s 4$ ; No? - then it was a Shell-start bsr.w _SetDirection ; Get user datas bsr.w _CheckWarning bsr.w _CheckExecute ; Execute (if a specification) a command 4$ bsr.w _SetWindow ; Set window limits bsr.w _CheckWrap ; Check Word-Wrap (ToolTypes) move.l #100,_errno(A5) bsr.w _OpenWindow tst.l D0 beq.w _Out_02 ; Don't bomb ********************************************** * * Open console device for reading and writing. * move.l #80,_errno(A5) movea.l _SysBase(A5),A6 ; Make ReadReplyPort lea _ReadReply(A5),A0 move.l _OwnTask(A5),MP_SIGTASK(A0) ; Task to be signalled lea MP_MSGLIST(A0),A0 ; Console-read reply port NEWLIST A0 lea _WriteReply(A5),A0 ; Make WriteReplyPort lea MP_MSGLIST(A0),A0 ; Console-read reply port NEWLIST A0 lea _ReadIo(A5),A1 move.l _WindowPtr(A5),IO_DATA(A1) move.l #wd_SIZEOF,IO_LENGTH(A1) moveq #0,D0 ; Unit moveq #0,D1 ; Flags lea _DeviceName(pc),A0 jsr _LVOOpenDevice(A6) ; Open console device tst.l D0 beq.s .ConsoleIsOpen lea _ErrorOpenDevTxt(pc),A0 ; else... bsr.w _DisplayError bra.w _Out_01 .ConsoleIsOpen lea _ReadIo(A5),A0 ; ReadIo<->WriteIo lea _WriteIo(A5),A1 move.l IO_DEVICE(A0),IO_DEVICE(A1) ; Device move.l IO_UNIT(A0),IO_UNIT(A1) ; Unit lea _ReadReply(A5),A2 move.l A2,MN_REPLYPORT(A0) lea _WriteReply(A5),A2 move.l A2,MN_REPLYPORT(A1) clr.l _errno(A5) *********************** * * Some useful stuff.... * bsr.w _CursorOff ; Cursor invisible bsr.w _SetPtr4Req ; Twist pointer for system-requesters bsr.w _SetScrollWidth ; Seek and set scrollwidth bsr.w _SetPageWidthAndLen ; Seek and set page sizes lea _ConBuffer(A5),A0 ; Address buffer move.w #$9B48,(A0) ; Cursor Home moveq #2,D0 ; 2 chars for output bsr.w _ConOut_Rel ; Write down to console... tst.l arg_1(A5) ; Any file placed? bne.w _CLILoad ; Yes.. tst.l file_1(A5) ; Or is there a file? bne.w _WBLoad ; Yes... * Otherwise.... _InitRequester bsr.w OpenReq ; Open for requests needed libraries tst.b _ReqFlag(A5) ; ReqTools or Arp opened? bmi.w _End_1 ; No, bad luck _NextTry st.b _LoadFlag(A5) ; We want to load... bsr.w _GetFile ; Build request and get file cmpi.l #-1,D0 ; Hard error? beq.w _End_1 ; Ok, finish immediately tst.l D0 ; No file? beq.s _NoFileChosen ; Too bad bsr.w _ReadFile ; Read that file tst.l D0 ; Any error? beq.s _Loop ; Yes... * ** Now we check the file. If it returns to this point all went ok. ** We check for ascii files, binary files, PP20 files, ILBM files. * bsr.w _CheckFile bsr.w _IgnoreSettings ; ANSI-Filter bsr.w _SetViewerPrefs ; Preferences bra.w _FirstPage ; Display first page _NoFileChosen lea _NoFileMsg(pc),A0 bsr.w _DisplayError tst.l D0 ; User said: "Cancle" loading beq.w _End ; If so, terminate... *********************************************** * * Main routine, is waiting until an event occurs. * _Loop clr.b _NoLineFlag(A5) ; Allow line counting bsr.w _ComLine ; Make window-title .noComLine bsr.w _SetActionWait ; Allow intuition to send us RAW-key messages tst.l _TextPtr(A5) ; Any text to display? beq.s .NoNextTxt ; If not tst.b _AudGadget(A5) bne.s .NoNextTxt tst.w _MouseID(A5) ; This inidicates if a mousebutton * was already touched, if it was touched, bne.w .MouseWasTouched ; we have to jump to an other routine... .NoNextTxt move.l A2,-(sp) movea.l _WindowPtr(A5),A2 movea.l wd_UserPort(A2),A2 movea.l A2,A0 movea.l _SysBase(A5),A6 jsr _LVOWaitPort(A6) ; Wait until a message has reached us movea.l A2,A0 jsr _LVOGetMsg(A6) movea.l D0,A1 movea.l D0,A2 jsr _LVOReplyMsg(A6) move.l 20(A2),D0 ; im_Class move.w 24(A2),D1 ; im_Code move.l 28(A2),_IAddr(A5) movea.l (sp)+,A2 * ** Some notes at this point: normally you should remember the received things i.e. ** im_Class, im_Code, im_IAddress and so on into private constants and _THEN_ ** reply the message to avoid conflicts with intuition. Because intuition does ** only send us (at most) each 1/10 second a message - and this is assembler - ** _AND_ we awoke yet (running task) it's not too critical to save the message ** things not - _BUT_ - if intuition is rewritten for (may be) Kickstart 41/42 ** and it's then a lot faster, the replying without saving will cause BIG trouble. * cmpi.l #$8,D0 ; MouseButtons? beq.s 4$ ; Startup for mouse-buttons!!!! cmpi.l #$40,D0 beq.s 3$ bsr.w _SetNILWait ; Tell intuition we don't want to have message * for now, do it via a PA_IGNORE flag which * blocks messages for our window clr.w _MouseID(A5) ; Erase ID movem.l D0-D1,-(sp) 1$ movea.l _WindowPtr(A5),A0 movea.l wd_UserPort(A0),A0 jsr _LVOGetMsg(A6) ; Ignore following messages until tst.l D0 ; flag is active... beq.s 2$ movea.l D0,A1 jsr _LVOReplyMsg(A6) ; Free message bra.s 1$ 2$ movem.l (sp)+,D0-D1 cmpi.l #$200,D0 ; CLOSEWINDOW ? beq.w _End ; If so... cmpi.l #$400,D0 ; RAWKEY? beq.w _RawKey ; If so... 3$ cmpi.l #$40,D0 ; Gadget up ? bne.w _Loop movea.l _IAddr(A5),A0 cmpi.w #3,gg_GadgetID(A0) ; Gadget id = 3? bne.w _Loop bra.w _AudioHit * ** If the first time a mousebutton was clicked, we are at this point. * 4$ tst.b _AudGadget(A5) bne.w _Loop move.w D1,_MouseID(A5) cmpi.w #$69,D1 ; Right one? bne.s .LeftOne move.w D1,_MouseID(A5) .RO1 move.w #CRSR_FD,D1 bra.s _RawKey .LeftOne cmpi.w #$68,D1 ; Left one? bne.s .NotValid ; Not a valid message... move.w D1,_MouseID(A5) .LO1 move.w #CRSR_BK,D1 bra.s _RawKey .NotValid clr.w _MouseID(A5) bra.w _Loop * ** A mouse-button was clicked a while ago, we have now to check if the mousebutton ** was released. * .MouseWasTouched move.l A2,-(sp) movea.l _WindowPtr(A5),A0 movea.l wd_UserPort(A0),A0 movea.l _SysBase(A5),A6 jsr _LVOGetMsg(A6) ; Do we have a message? tst.l D0 beq.s .further ; No, just do it like a mousebutton was clicked movea.l D0,A1 movea.l D0,A2 jsr _LVOReplyMsg(A6) cmpi.l #$8,im_Class(A2) ; MouseButtons? | SEE NOTES ABOUT bne.s .further ; see above | MESSAGES A PIECE cmpi.w #$68+$80,im_Code(A2) ; Left one released? | FURTHER ABOVE.... beq.s .EndMouse cmpi.w #$69+$80,im_Code(A2) ; or right one released? bne.s .further .EndMouse movea.l (sp)+,A2 clr.w _MouseID(A5) ; Clear ID (code), indicates that no mouse- bra.w _Loop ; button is held down .further movea.l (sp)+,A2 cmpi.w #$68,_MouseID(A5) ; Left mousebutton? beq.s .LO1 bra.s .RO1 ; else it was the right one! * ** Startup for console action * _RawKey lea _ConBuffer(A5),A0 ; Buffer move.w D1,(A0) ; Store there the raw-key bra.w _ConsoleEvent ; just go ahead ********************** * * Our end has come.... * _End_1 lea _NoReqTxt(pc),A0 ; Fail with message (couldn't open file- bsr.w _DisplayError ; requester) _End movea.l 4.w,A6 suba.l A1,A1 jsr _LVOFindTask(A6) movea.l D0,A0 movea.l pr_ReturnAddr(A0),A0 ; Program's exit address subq.l #8,A0 movea.l (A0),A5 ; Restore basetable pointer movea.l _OwnTask(A5),A0 ; Restore pointer for system-requesters move.l _StdprWindowPtr(A5),184(A0) tst.l _UserProject(A5) ; .info-file there? beq.s 0$ movea.l _IconBase(A5),A6 movea.l _UserProject(A5),A0 jsr _LVOFreeDiskObject(A6) ; Free the info-file resources 0$ movea.l _SysBase(A5),A6 lea _ReqToolsBase(A5),A2 ; ReqTools-library open? tst.l (A2) beq.s 1$ ; No movea.l A6,A4 ; Save Exec movea.l (A2),A6 ; ReqTools-Base movea.l _ReqPtr(A5),A1 ; File-requester-record jsr _LVOrtFreeRequestA(A6) ; Free it movea.l A6,A1 ; ReqTools-Base A1 movea.l A4,A6 ; Exec jsr _LVOCloseLibrary(A6) 1$ tst.l _ArpBase(A5) ; Arp-Library open? beq.s 2$ ; No movea.l _ArpBase(A5),A1 jsr _LVOCloseLibrary(A6) 2$ tst.l _CyberGfxBase(A5) beq.s 3$ movea.l _CyberGfxBase(A5),A1 jsr _LVOCloseLibrary(A6) 3$ move.l _BufferSize(A5),D0 ; Something allocated? beq.s 4$ ; No movea.l _TextPtr(A5),A1 ; Else jsr _LVOFreeMem(A6) ; free it 4$ bsr.w _FreeAudio movea.l _SysBase(A5),A6 lea _ReadIo(A5),A1 jsr _LVOCloseDevice(A6) ; Close console-device _Out_01 bsr.w _CloseWindow ; Close main-window _Out_02 bsr.w _CloseROMLibs ; Close 'em rts ; Back into startup-code ******************************************** * * One routine with a few entries to call.... * * It will write down to the console-window * the overgiven text. * _ConOut ; Write down 1 char, the char is in the "_ConBuffer" movea.l _SysBase(A5),A6 lea _WriteIo(A5),A1 ; Io-structure for writing move.l #1,IO_LENGTH(A1) ; 1 char for output _ContConOut ; Write down x-chars, the chars are in the "_ConBuffer" move.w #CMD_WRITE,IO_COMMAND(A1) ; Command = Write lea _ConBuffer(A5),A0 ; Address char _ContConOut_01 ; Check first for tab-width (take 1 tab as 8 blanks) bsr.s _CheckTAB _ContConOut_02 ; Just do it (writing) move.l A0,IO_DATA(A1) ; Address string movea.l _SysBase(A5),A6 jsr _LVODoIO(A6) ; Do it, but wait until done lea _ConBuffer(A5),A0 rts _ConOut_Rel ; Relative length, rigid address (number of chars in D0) lea _WriteIo(A5),A1 move.l D0,IO_LENGTH(A1) bra.s _ContConOut _ConOut_Reloc ; Relative length, relative address (number of chars in D0, * address string in A0) movea.l _SysBase(A5),A6 lea _WriteIo(A5),A1 move.l D0,IO_LENGTH(A1) move.w #CMD_WRITE,IO_COMMAND(A1) ; Command = Write bra.s _ContConOut_01 ***************************************************** * * Compute length for one line, take 1 tab as 8 blanks. * _CheckTAB tst.b _WrapFlag(A5) ; Word Warp allowed? bne.w .CT_End ; If so... tst.l _PageWidth(A5) beq.w .CT_End movem.l D0-D3/A0-A2,-(sp) move.l _PageWidth(A5),D3 ; Number of Displayable columns addq.w #1,D3 move.l D0,D2 ; Number of chars to print down movea.l A0,A2 ; Address string .CT_Next movea.l A2,A0 ; Current string moveq #0,D0 ; Number of Chars moveq #0,D1 ; Number of columns .CT_Search addq.w #1,D0 ; Number of chars plus 1 addq.w #1,D1 ; Number of columns plus 1 cmp.l D1,D3 ; Compare width maximum of possible * displayable columns bls.s .CT_Store cmpi.b #10,(A2) ; LineFeed beq.s .CT_Store cmpi.b #9,(A2) ; TAB beq.s .CT_AddTAB cmpi.b #27,(A2) ; ESC beq.s .CT_IgnoreESC addq.l #1,A2 subq.w #1,D2 ; Number of chars minus 1 beq.s .CT_Store bra.s .CT_Search .CT_Store lea _WriteIo(A5),A1 ; Io-structure for writing move.w #CMD_WRITE,IO_COMMAND(A1) ; Command = Write move.l D0,IO_LENGTH(A1) ; Chars for output move.l A0,IO_DATA(A1) ; Address string movea.l _SysBase(A5),A6 jsr _LVODoIO(A6) ; Do it, but wait until done tst.w D2 beq.s .CT_End_1 moveq #-1,D0 1$ subq.w #1,D2 beq.s .CT_End_1 cmpi.b #10,(A2)+ ; LineFeed dbeq D0,1$ bra.s .CT_Next .CT_AddTAB addq.w #7,D1 andi.w #-8,D1 addq.l #1,A2 subq.w #1,D2 beq.s .CT_Store bra.s .CT_Search .CT_IgnoreESC subq.w #1,D1 addq.l #4,A2 ; Ignore 4 chars (currently no real length addq.w #3,D0 ; checking (Sequencer) is done...) subq.w #4,D2 beq.s .CT_Store bcs.s 2$ bra.s .CT_Search 2$ subq.l #1,A2 subq.w #1,D0 addq.w #1,D2 bcs.s 2$ bra.s .CT_Store .CT_End_1 movem.l (sp)+,D0-D3/A0-A2 .CT_End rts *********************************************** * * Read from console-window - but don't wait for * the result. * * Inputs: D0 - number of chars to read * Results: Chars in gloabal "_ConBuffer" * _QueueRead lea _ReadIo(A5),A1 move.l D0,IO_LENGTH(A1) ; Number of chars to read move.l A0,IO_DATA(A1) move.w #CMD_READ,IO_COMMAND(A1) ; Command READ movea.l _SysBase(A5),A6 jmp _LVOSendIO(A6) ; Send command _GetConMsg moveq #20,D0 lea _ConBuffer(A5),A0 bsr.s _QueueRead ; Get the message movea.l _SysBase(A5),A6 lea _ReadReply(A5),A0 jmp _LVOGetMsg(A6) ************************************************************ * * Open graphic and intuition libraries, * required version is 33 (ks 1.2). * * Inputs: None * Result: GfxBase and IntuitionBase * (NULL not possible!!! - noone works with a ks. lower 33!!!) * At the moment I know only one person who got a ks. lower than 33, 32, * OS1.1 PAL - Amiga 1000, the machine with the WOM; no, he doesn't sells it... * _OpenROMLibs movea.l _SysBase(A5),A6 lea _IntuitionName(pc),A1 moveq #33,D0 jsr _LVOOpenLibrary(A6) move.l D0,_IntuitionBase(A5) moveq #33,D0 lea _GfxName(pc),A1 jsr _LVOOpenLibrary(A6) move.l D0,_GfxBase(A5) rts **************************************** * * Close graphic and intuition libraries. * * Inputs: None * Results: None * _CloseROMLibs movea.l _SysBase(A5),A6 movea.l _IntuitionBase(A5),A1 jsr _LVOCloseLibrary(A6) movea.l _GfxBase(A5),A1 jmp _LVOCloseLibrary(A6) ******************************************* * * Open main window which is used as console * window. * * We take from the tooltypes (if wb-start) * the specified X- and Y-offset for our * window and of course the font the user * specified (in tooltypes) for this window. * * Inputs: None * Results: _UserFontPtr (may be NULL) * _WindowPtr (may be NULL) * _OpenWindow lea WB_arg_1(A5),A0 .NextTType tst.l (A0) ; Argument there? beq.s _NoOffsetDeclared ; No movea.l (A0)+,A1 ; Address overgiven string lea _OffsetSpecName(pc),A2 ; Address string to compare moveq #12,D0 ; 13 chars to compare .CheckTType cmpm.b (A1)+,(A2)+ ; Compare strings bne.s .NextTType ; "WINDOWOFFSET=" dbf D0,.CheckTType movea.l A1,A0 ; Pointer to following string moveq #0,D0 move.b (A0),D0 lsl.w #8,D0 move.b 1(A0),D0 lsl.l #8,D0 move.b 2(A0),D0 lsl.l #8,D0 move.b 3(A0),D0 cmpi.l #'AUTO',D0 ; Auto adjustment? bne.s .Value tst.b 4(A0) bne.s .Value movea.l _IntuitionBase(A5),A1 movea.l ib_ActiveScreen(A1),A1 moveq #0,D0 move.b sc_BarHeight(A1),D0 addq.w #1,D0 move.w D0,_YOffset(A5) bra.s _NoOffsetDeclared ; ...altough it is... .Value moveq #0,D0 ; No mask bsr.w _StrToLong tst.l D1 bmi.s _NoOffsetDeclared ; Upon error .XOffsetGot move.w D0,_XOffset(A5) ; Save X-Offset moveq #0,D0 ; No mask bsr.w _StrToLong tst.l D1 bmi.s _NoOffsetDeclared ; Upon error .YOffsetGot move.w D0,_YOffset(A5) ; Save Y-Offset * ** Look for the font... * _NoOffsetDeclared lea WB_arg_1(A5),A0 .NextTType tst.l (A0) ; Argument there? beq.w _NoFontDeclared ; No movea.l (A0)+,A1 ; Address overgiven string lea _FontSpecName(pc),A2 ; Address string to compare moveq #4,D0 ; 5 chars to compare .CheckTType cmpm.b (A1)+,(A2)+ ; Compare strings bne.s .NextTType ; "FONT=" dbf D0,.CheckTType movea.l A1,A0 ; Pointer to following string lea _UserFontBuf(A5),A1 ; Our private buffer tst.b (A0) ; End of user's string? beq.w _NoFontDeclared 1$ move.b (A0)+,(A1)+ ; Copy font's name beq.w _NoFontDeclared ; If an interrupted end... cmpi.b #',',(A0) ; Comma = number follows! bne.s 1$ move.b #'.',(A1)+ ; Add string ".font" to font's name move.b #'f',(A1)+ move.b #'o',(A1)+ move.b #'n',(A1)+ move.b #'t',(A1)+ clr.b (A1) moveq #0,D0 ; No mask bsr.w _StrToLong cmpi.l #-1,D1 beq.s _NoFontDeclared _OpenUserFont lea _UserFontStruc(A5),A0 ; FontAttr-record move.w D0,4(A0) ; Save height of font move.b #$40|1,7(A0) ; Designed and ROM-Font (on first try) lea _UserFontBuf(A5),A1 ; Buffer with font's name move.l A1,(A0) ; Set name in FontAttr-record movea.l _GfxBase(A5),A6 jsr _LVOOpenFont(A6) ; Try to open the font tst.l D0 ; Font opened? beq.s .OpenDiskFont ; If not... movea.l D0,A1 ; TextFont lea _UserFontStruc(A5),A0 ; FontAttr-record move.w 4(A0),D1 ; Get height of font cmp.w 20(A1),D1 ; Height of opened font same as... beq.s _GotFont ; Of course... movea.l _GfxBase(A5),A6 ; Otherwise close jsr _LVOCloseFont(A6) ; opened font (got not the right height) .OpenDiskFont lea _DiskFontName(pc),A1 ; "diskfont.library" moveq #33,D0 movea.l _SysBase(A5),A6 jsr _LVOOpenLibrary(A6) ; Open the library tst.l D0 beq.s _NoFontDeclared ; Damned! movea.l D0,A6 ; DiskfontBase lea _UserFontStruc(A5),A0 ; Addr. FontAttr-record move.b #$40|2,7(A0) ; Designed and DISK-Font! jsr _LVOOpenDiskFont(A6) ; Load the disk-resident-font tst.l D0 ; Got font? beq.s 1$ ; No... move.l D0,D2 ; Save font-pointer movea.l A6,A1 ; DiskFontBase movea.l _SysBase(A5),A6 jsr _LVOCloseLibrary(A6) ; Close "diskfont.library" move.l D2,D0 ; Font-pointer bra.s _GotFont 1$ movea.l A6,A1 ; DiskfontBase movea.l _SysBase(A5),A6 jsr _LVOCloseLibrary(A6) bra.s _NoFontDeclared ; Error exit _GotFont move.l D0,_UserFontPtr(A5) ; Save font-pointer * ** Attempt to open the window with (if) overgiven X- and Y-Offsets ** and (if) user specified font. * _NoFontDeclared movea.l _SysBase(A5),A6 jsr _LVOForbid(A6) movea.l _IntuitionBase(A5),A6 move.l ib_ActiveScreen(A6),_ScreenPtr(A5) ; Get active screen lea _WindowRecord(A5),A0 ; Window-record move.l _ScreenPtr(A5),nw_Screen(A0) ; On this screen our window should appear movea.l _ScreenPtr(A5),A1 ; Address screen-record move.w _XOffset(A5),D0 beq.s 0$ add.w D0,(A0) ; Set left edge of window 0$ move.w _YOffset(A5),D0 beq.s 1$ add.w D0,nw_TopEdge(A0) ; Set top edge of window 1$ tst.w nw_Width(A0) bne.s 2$ move.w sc_Width(A1),nw_Width(A0) 2$ tst.w nw_Height(A0) bne.s 3$ move.w sc_Height(A1),nw_Height(A0) 3$ move.w _XOffset(A5),D0 beq.s 4$ sub.w D0,nw_Width(A0) 4$ move.w _YOffset(A5),D0 beq.s 5$ sub.w D0,nw_Height(A0) 5$ jsr _LVOOpenWindow(A6) ; Open the window move.l D0,-(sp) movea.l _SysBase(A5),A6 jsr _LVOPermit(A6) move.l (sp)+,D0 move.l D0,_WindowPtr(A5) ; Save window pointer beq.w 7$ movem.l D0/A2-A3,-(sp) movea.l D0,A3 ; Window movea.l wd_BorderRPort(A3),A2 ; RastPort of titlebar movea.l _IntuitionBase(A5),A6 cmpi.w #35,LIB_VERSION(A6) ; Kickstart 2.x or higher? bls.s .Read ; No... movea.l wd_WScreen(A3),A0 ; Window's screen jsr _LVOGetScreenDrawInfo(A6) ; Get drawing infos tst.l D0 beq.s .Read movea.l D0,A1 ; DrawInfos movea.l dri_Pens(A1),A0 ; Pointer to pen-array move.w 5*2(A0),D0 ; Get fillpen (aktive window's bar background) move.l D0,-(sp) movea.l wd_WScreen(A3),A0 ; Window's screen jsr _LVOFreeScreenDrawInfo(A6) move.l (sp)+,D0 movea.l _GfxBase(A5),A6 ; Restore Base bra.s .SavePen .Read movea.l A2,A1 moveq #28,D0 ; X moveq #1,D1 ; Y (room of first vertical pixel) movea.l _GfxBase(A5),A6 jsr _LVOReadPixel(A6) ; Get title bar's background colour .SavePen move.w D0,_BgPen(A5) ; Save colour * ** Now we have to set the font for the title bar, it's the same like the screen's ** default font! * movea.l wd_WScreen(A3),A0 ; The window our screen appears on lea sc_RastPort(A0),A0 ; Screen's rastport movea.l rp_Font(A0),A0 ; Default font movea.l A2,A1 ; Window's title bar rastport jsr _LVOSetFont(A6) ; Set font (there isn't one - til now!) movem.l (sp)+,D0/A2-A3 tst.l _UserFontPtr(A5) ; Font opened? beq.s 6$ move.l D0,-(sp) movea.l _WindowPtr(A5),A1 movea.l wd_RPort(A1),A1 ; RastPort move.l rp_Font(A1),_OldFontPtr(A5) ; Save old font for later movea.l _UserFontPtr(A5),A0 jsr _LVOSetFont(A6) ; Set font the user want move.l (sp)+,D0 6$ movea.l _WindowPtr(A5),A1 movea.l wd_RPort(A1),A1 ; RastPort cmpi.b #1,rp_Mask(A1) ; Only one bitplane? beq.s .okBP ; Yes... move.b #%11,rp_Mask(A1) ; Max. 2 bitplanes for Gfx-output! * At the moment (ks 3.0) it's not supported, may be ks 3.1 will support it. * If this cause trouble with your 3rd party graphic board, remove the lines. .okBP rts 7$ tst.l _UserFontPtr(A5) beq.s 8$ movea.l _UserFontPtr(A5),A1 movea.l _GfxBase(A5),A6 jsr _LVOCloseFont(A6) 8$ moveq #0,D0 lea _WindowRecord(A5),A0 move.w nw_Height(A0),D0 move.l D0,-(sp) move.w nw_Width(A0),D0 move.l D0,-(sp) move.w nw_TopEdge(A0),D0 move.l D0,-(sp) move.w (A0),D0 ; LeftEdge move.l D0,-(sp) pea _ErrorOpenWindowTxt(pc) bsr.w _FmtDisplay lea 20(sp),sp ; Restore stack moveq #0,D0 rts ******************************************* * * Close the main window. * If a font was opened for this window, * the system-default font is first set * to the window (restored), then the opened * font is closed and after that, the window * is closed. * * Inputs: None * Results: None * _CloseWindow tst.l _UserFontPtr(A5) beq.s 1$ movea.l _GfxBase(A5),A6 movea.l _WindowPtr(A5),A1 move.l wd_RPort(A1),A1 movea.l _OldFontPtr(A5),A0 jsr _LVOSetFont(A6) movea.l _UserFontPtr(A5),A1 jsr _LVOCloseFont(A6) 1$ movea.l _IntuitionBase(A5),A6 movea.l _WindowPtr(A5),A0 jmp _LVOCloseWindow(A6) ************************************* * * Short subroutine to set window's name * pc-relative. * * Inputs: None * Results: None * _SetPrefs lea _WindowRecord(A5),A0 lea _WindowName(pc),A1 move.l A1,nw_Title(A0) rts ***************************************** * * Main routine calls this one. * This one will jump to the routine which * belongs to the key. * * Inputs: A0 - "_ConBuffer" * Key in "_ConBuffer" * Results: None * Notes: Never call it via "bsr" or "jsr"! * _ConsoleEvent cmpi.w #L_Key,(A0) beq.w _LoadNew cmpi.w #E_Key,(A0) beq.w _EnlargeWindow cmpi.w #H_Key,(A0) beq.w _DisplayHelp cmpi.w #I_Key,(A0) beq.w _Info cmpi.w #A_Key,(A0) beq.w _About tst.l _TextPtr(A5) beq.w _Loop move.w (A0),D0 cmpi.b #CRSR_UP,D0 beq.w _PageUp cmpi.b #CRSR_DN,D0 beq.w _PageDown cmpi.b #CRSR_FD,D0 beq.w _OneLineUp cmpi.b #CRSR_BK,D0 beq.w _OneLineDown cmpi.b #T_Key,D0 beq.w _Top cmpi.b #B_Key,D0 beq.w _Bottom cmpi.b #RETURN,D0 beq.w _OneLineDown cmpi.b #ENTER,D0 beq.w _OneLineDown cmpi.b #HOME,D0 beq.w _Top cmpi.b #END,D0 beq.w _Bottom cmpi.b #PG_UP,D0 beq.w _PageUp_01 cmpi.b #PG_DN,D0 beq.w _PageDown_01 cmpi.b #R_SHIFT,D0 beq.w _OneLineUp cmpi.b #W_Key,D0 beq.w _WindowContentsPrt cmpi.b #PrtSc,D0 beq.w _WindowContentsPrt cmpi.b #C_Key,D0 beq.w _WindowContensFile cmpi.b #P_Key,D0 beq.w _Print2Prt cmpi.b #F_Key,D0 beq.s _Print2File cmpi.b #R_Key,D0 beq.w _RestorePage cmpi.w #S_Key,D0 beq.w _SearchSequence cmpi.w #N_Key,D0 beq.w _ContinueSearch cmpi.b #HELP_Key,D0 bsr.s _DisplayTitle bra.w _Loop ************************************************** * * Allow counting lines and create new window-title. * * Inputs: none * Results: none * _DisplayTitle clr.b _NoLineFlag(A5) ; Allow to count lines bsr.w _ComLine ; Create (modify) window-title rts ************************************** * * Set prefs to display the ascii-text, * set up registers. * * Inputs: none * Results: A3 - textstart, A2 - textend * _SetViewerPrefs movea.l _TextPtr(A5),A4 ; Current text-position addq.l #2,A4 ; Overread #$200A movea.l A4,A3 ; Textstart A3 movea.l A4,A2 ; ^ A2 move.l _FileSize(A5),D0 ; Length file add.l D0,A2 ; = textend addq.l #3,A2 ; + #$0200A + 1 byte behind source move.b #10,(A2) ; = textend move.l A3,D5 move.l A3,D6 rts ************************************* * * Print that ascii-text-file to file. * * Inputs: none * Reslts: none * _Print2File clr.b _LoadFlag(A5) ; Set save-flag tst.b _ReqFlag(A5) bne.s 1$ ; Requester already opened? bsr.w OpenReq ; No... 1$ bsr.w _GetFile ; Get filename cmpi.l #-1,D0 ; Hard error? beq.w _CantPrint ; If so... tst.l D0 ; No file? bne.s _PrintFileTO ; If so... bra.w _Loop ; ...and back * ** Ok, do further... * _PrintFileTO lea _PrintFileTxt(pc),A0 bsr.w _DisplayError tst.l D0 ; User cancelled? beq.s _DoNotPrint ; ..then do not write down the file lea _FileName(A5),A0 movea.l A3,A1 ; Textstart move.l _FileSize(A5),D0 ; Length file bsr.w _PrintFile ; Write down the file bra.w _Loop ; ...and end *************************************** * * Write down window contents to a file. * * Inputs: none * Reslts: none * _WindowContensFile clr.b _LoadFlag(A5) ; Indicate loading tst.b _ReqFlag(A5) bne.s 1$ ; Requester already opened? bsr.w OpenReq ; No... 1$ bsr.w _GetFile ; Get filename cmpi.l #-1,D0 ; Hard error? beq.s _CantPrint ; If so... tst.l D0 ; No file? bne.s _PrintFileTO_01 ; If so... bra.w _Loop * ** Further.... * _PrintFileTO_01 lea _PrintContentsTxt(pc),A0 bsr.w _DisplayError tst.l D0 ; Right mosebutton? beq.s _DoNotPrint ; Then do not write movea.l D6,A1 ; Current address (current line D6) movea.l A1,A0 move.w _PageSize(A5),D1 ; Number of lines of one page addq.w #2,D1 ; plus one line and one for linefeed moveq #0,D0 ; Counter 1$ cmpa.l A2,A0 ; Textend == current textposition? bge.s 2$ ; If so, error addq.w #1,D0 cmpi.b #10,(A0)+ ; Search for linefeed bne.s 1$ dbf D1,1$ ; Lines of one page 2$ lea _FileName(A5),A0 ; The filename bsr.w _PrintFile ; Write down file bra.w _Loop ; back to main ******************************* * * Print window contents to PRT: * * Inputs: none * Reslts: none * _WindowContentsPrt lea _FileName(A5),A0 move.l #'PRT:',(A0)+ clr.b (A0) bsr.s _CheckPrinter ; Check if printer is turned off or so... bra.s _PrintFileTO_01 * ** Error handling.... * _DoNotPrint lea _PrintCancelTxt(pc),A0 bsr.w _DisplayError bra.w _Loop _CantPrint bra.w _End ************************** * * Print whole file to PRT: * * Inputs: none * Reslts: none * _Print2Prt lea _FileName(A5),A0 move.l #'PRT:',(A0)+ clr.b (A0) bsr.s _CheckPrinter bra.w _PrintFileTO **************************************** * * Check printer: uses direct CIA-access. * Works only 100% correctly with Epson- * printers. * * Inputs: none * Reslts: none * Notes: Checking can be disabled * _CheckPrinter tst.b _NoCheckPrtFlag(A5) ; Allowed to check? bne.s 1$ move.b $BFD000,D0 ; CIA PRA cmpi.b #255,D0 beq.s .PrinterOFF cmpi.b #253,D0 beq.s .NotOneLine cmpi.b #255,D0 bne.s .PrinterOFF 1$ rts .PrinterOFF lea _PrinterOFFTxt(pc),A0 bsr.w _DisplayError addq.l #4,sp bra.w _Loop .NotOneLine lea _NotOnelineTxt(pc),A0 bsr.w _DisplayError addq.l #4,sp bra.w _Loop ********************* * * How to explain....? * _PageUp move.w _PageSize(A5),D7 ; ditto bra.w _LinesUp _PageUp_01 move.w _StdPageSize(A5),D7 ; Set scrollwidth addq.w #1,D7 ; We can display one line more bra.w _OnePageUp _PageDown move.w _PageSize(A5),D7 ; see above bra.w _LinesDown _PageDown_01 move.w _StdPageSize(A5),D7 ; see above addq.w #1,D7 ; We can display one line more bra.w _OnePageDown _OneLineUp moveq #0,D7 ; 1 line! bra.w _LinesUp _OneLineDown moveq #0,D7 ; ditto bra.w _LinesDown _RestorePage bsr.w _SetPageWidthAndLen _RestorePage_1 bsr.w _RestoreCurrentPage bra.w _Loop **************************************************** * * Load from Shell overgiven file and set scrollwidth. * * Inputs: none * Reslts: none * _CLILoad tst.l arg_2(A5) ; 2. argument empty? beq.s 1$ ; If so... movea.l arg_2(A5),A0 * ** Convert chars of second argument to uppercase. ** 2. argument should look like this: 1> viewer scrollwidth=11 ** ¯¯¯¯¯¯¯¯¯¯¯¯¯¯ * 2$ tst.b (A0) beq.s 4$ cmpi.b #'@',(A0) bls.s 3$ cmpi.b #'z',(A0) bhi.s 3$ bclr #5,(A0) 3$ addq.l #1,A0 bra.s 2$ 4$ lea arg_2(A5),A0 clr.l 4(A0) ; Clear next argument bsr.w _SetScrollWidth_01 ; Get scrollwidth 1$ movea.l arg_1(A5),A0 ; Address 1. argument (filename) lea _FileName(A5),A1 ; Address buffer for filename _StoreArgName move.b (A0)+,(A1)+ ; Copy argument tst.b -1(A0) bne.s _StoreArgName bra.s _ReadIn ******************************************* * * Startup to load workbench overgiven file. * * Inputs: none * Results: none * _WBLoad tst.l lock_1(A5) ; Lock to dir? beq.s 1$ ; No... move.l lock_1(A5),D1 movea.l _DOSBase(A5),A6 jsr _LVOCurrentDir(A6) ; else set as current directory 1$ tst.l file_1(A5) beq.w _InitRequester movea.l file_1(A5),A0 ; Address name from file lea _FileName(A5),A1 bra.s _StoreArgName ***************************************** * * Build requester, check file, read file. * * Inputs: none * Results: none * _LoadNew st.b _LoadFlag(A5) ; Flag == load tst.b _ReqFlag(A5) bne.s 1$ ; Requester already opened? bsr.w OpenReq ; No... 1$ bsr.w _GetFile ; Get filename tst.l D0 bmi.w _End_1 ; Hard error? tst.l D0 beq.w _Loop ; No file? _ReadIn bsr.w _FreeAudio bsr.w _ReadFile ; Read file in tst.l D0 ; Error? beq.w _Loop ; If so... bsr.w _ClearWindow ; Erase window contents bsr.w _CheckFile ; Check if ASCII, PP-crunched or IFF-screen bsr.w _IgnoreSettings ; ANSI-filter * bsr.w _SetViewerPrefs ; Set up ascii-file to display bra.w _FirstPage ; Display first page ********************************************* * * Display first page of ascii-text in window. * * Inputs: none * Results: none * _Top bra.w _FirstPage ; Display first page ********************************************* * * Display last page of ascii-text in window. * * Inputs: none * Results: none * _Bottom bra.w _LastPage ********************************************** * * Page up - clear window and write down string * * Inputs: D5 == Address of last char in window (or NULL) * D6 == Address of 1. char in window * D7 == Number of lines to scroll (display) * A2 == Address last char of text * A3 == Address first char of text * A4 == used * Results: * D5 == Address of last char in window * D6 == Address of 1. char in window * _OnePageUp movea.l D6,A4 movea.l A4,A0 subq.l #4,A0 ; Any chars to display? cmpa.l A3,A0 bls.w _Loop ; If not... bsr.w _ClearWindow moveq #0,D2 ; Number of chars! 0$ cmpa.l A3,A4 ; A3 == lowest address, A4 == current address, does it fit? bls.s 6$ ; If not... 1$ moveq #0,D0 ; Counter for number of chars 2$ addq.w #1,D0 ; Else counter for number of chars plus 1 subq.l #1,A4 cmpi.b #10,(A4) ; Next line? bne.s 2$ add.w D0,D2 3$ tst.b _NoLineFlag(A5) ; Counting lines allowed? bne.s 4$ ; No... subq.l #1,_Line(A5) 4$ move.l A4,D6 ; Remember startaddress of string in D6 as next pointer * for LinesUp-routine movea.l D5,A0 ; Address last char in window 5$ cmpi.b #10,-(A0) ; Find LineFeed bne.s 5$ move.l A0,D5 ; New address last char in window dbf D7,0$ move.l D2,-(sp) lea _ConBuffer(A5),A0 ; Address buffer move.w #$9B48,(A0) ; Cursor Home moveq #2,D0 ; 2 chars for output bsr.w _ConOut_Rel ; Output move.l (sp)+,D0 movea.l A4,A0 addq.l #1,A0 subq.w #1,D0 bsr.w _ConOut_Reloc ; Print down those lines bra.w _Loop 6$ bsr.w _RestoreCurrentPage bra.w _Loop *********************************************** * * Number of lines to scroll up.... * * Inputs: D5 == Address of last char in window (or NULL) * D6 == Address of 1. char in window * D7 == Number of lines to scroll (display) * A2 == Address last char of text * A3 == Address first char of text * A4 == used * Results: * D5 == Address of last char in window * D6 == Address of 1. char in window * _LinesUp movea.l D6,A4 ; Last address from LinesDown as current address for us 0$ cmpa.l A3,A4 ; A3 == lowest address, A4 == current address, does it fit? bls.w _Loop ; If not... lea _ConBuffer(A5),A0 ; Address buffer move.w #$9B48,(A0)+ ; Cursor Home move.l #$9B314100,(A0) ; Scroll 1 line up moveq #5,D0 ; 5 chars for output bsr.w _ConOut_Rel ; Output 1$ moveq #0,D0 ; Counter for number of chars 2$ addq.w #1,D0 ; Else counter for number of chars plus 1 subq.l #1,A4 cmpi.b #10,(A4) bne.s 2$ 3$ tst.b _NoLineFlag(A5) ; Counting lines allowed? bne.s 4$ ; No... subq.l #1,_Line(A5) 4$ movea.l A4,A0 addq.l #1,A0 subq.w #1,D0 bsr.w _ConOut_Reloc ; Print down the line move.l A4,D6 ; Remember startaddress of string in D6 as next pointer * for LinesUp-routine movea.l D5,A0 ; Address last char in window 5$ cmpi.b #10,-(A0) ; Find LineFeed bne.s 5$ move.l A0,D5 ; New address last char in window dbf D7,0$ bra.w _Loop ******************************************************************* * * Scroll down one complete page an write to freed room the strings. * * Inputs: D5 == Address of last char in window (or NULL) * D6 == Address of 1. char in window * D7 == Number of lines to scroll (display) * A2 == Address last char of text * A3 == Address first char of text * A4 == used * Results: * D5 == Address of last char in window * D6 == Address of 1. char in window * _OnePageDown movea.l D5,A4 ; Last address char in window movea.l A4,A0 addq.l #2,A0 ; At least a few bytes to display? cmpa.l A2,A0 ; Does it fit? bge.w _Loop bsr.w _ClearWindow addq.l #1,A4 ; Ignore introducing LineFeed lea _ConBuffer(A5),A0 move.w #$9B48,(A0) moveq #2,D0 bsr.w _ConOut_Rel bra.s _Lines_Down ************************************************************** * * Scroll down and print contents, number of lines: ScrollWidth. * * Inputs: D5 == Address of last char in window (or NULL) * D6 == Address of 1. char in window * D7 == Number of lines to scroll (display) * A2 == Address last char of text * A3 == Address first char of text * A4 == used * Results: * D5 == Address of last char in window * D6 == Address of 1. char in window * _LinesDown movea.l D5,A4 ; Last address char in window cmpa.l A2,A4 ; Does it fit? bge.w _Loop lea _ConBuffer(A5),A0 move.l #$9B393939,(A0)+ ; Cursor End of Display move.b #$48,(A0) ; 999H moveq #5,D0 bsr.w _ConOut_Rel _Lines_Down movea.l A4,A0 moveq #0,D0 ; Counter for number of chars 1$ cmpa.l A2,A4 ; A2 == highest address, A4 == current bge.w _Loop addq.w #1,D0 ; Counter for chars plus 1 addq.l #1,A4 cmpi.b #10,(A4) ; LineFeed? bne.s 1$ ; If not, do it further bsr.w _ConOut_Reloc ; Print down one line move.l A4,D5 ; Last char address in window movea.l D6,A0 ; First char in window 2$ addq.l #1,A0 cmpi.b #10,(A0) ; LineFeed (next line)? bne.s 2$ move.l A0,D6 ; New address (first char in window) tst.b _NoLineFlag(A5) ; Allowed to count lines? bne.s 3$ ; No... addq.l #1,_Line(A5) 3$ dbf D7,_Lines_Down ; Number of lines bra.w _Loop ********************************* * * Restore current window contents * * Inputs: D5 == Address of last char in window (or NULL) * D6 == Address of 1. char in window * A2 == Address last char of text * A3 == Address first char of text * A4 == used * Results: * D5 == Address of last char in window * D6 == Address of 1. char in window * _RestoreCurrentPage tst.l _BufferSize(A5) ; Any datas to display out there? beq.s 2$ ; If not... move.l D6,D5 ; Last address == current addq.l #1,D5 ; Ignore introducing linefeed move.w _StdPageSize(A5),D7 addq.w #1,D7 movea.l D5,A4 ; Last address char in window cmpa.l A2,A4 ; Does it fit? bge.s 2$ lea _ConBuffer(A5),A0 ; Address buffer move.l #$1B5B306D,(A0)+ ; Reset display move.l #$9B639B48,(A0)+ ; Reset console and Cursor Home move.l #$9B4A9B48,(A0) ; Erase to end of display Cursor Home moveq #12,D0 ; 12 chars for output bsr.w _ConOut_Rel ; Output 0$ movea.l A4,A0 moveq #0,D0 ; Counter for number of chars 1$ cmpa.l A2,A4 ; A2 == highest address, A4 == current bge.s 2$ addq.w #1,D0 ; Counter for chars plus 1 addq.l #1,A4 cmpi.b #10,(A4) ; LineFeed? bne.s 1$ ; If not, do it further bsr.w _ConOut_Reloc ; Print down one line move.l A4,D5 ; Last char address in window dbf D7,0$ ; Number of lines 2$ rts *************************************** * * Display first page of ascii-text-file * * Inputs: D5 == Address of last char in window (or NULL) * D6 == Address of 1. char in window * A2 == Address last char of text * A3 == Address first char of text * A4 == used * Results: * D5 == Address of last char in window * D6 == Address of 1. char in window * _FirstPage bsr.w _SetViewerPrefs ; Prefs == as on start! moveq #0,D7 move.w _StdPageSize(A5),D7 addq.w #1,D7 move.l D7,_Line(A5) ; == number of lines that "are" displayed"!?" movea.l D5,A4 ; Last address char in window cmpa.l A2,A4 ; Does it fit? bge.w _Loop lea _ConBuffer(A5),A0 ; Address buffer move.l #$1B5B306D,(A0)+ ; Reset display move.l #$9B639B48,(A0)+ ; Reset and Cursor Home move.l #$9B4A9B48,(A0) ; Erase to end of display + Cursor Home moveq #12,D0 ; 12 chars for output bsr.w _ConOut_Rel ; Output 0$ movea.l A4,A0 moveq #0,D0 ; Counter for number of chars 1$ cmpa.l A2,A4 ; A2 == highest address, A4 == current bge.w _Loop addq.w #1,D0 ; Counter for chars plus 1 addq.l #1,A4 cmpi.b #10,(A4) ; LineFeed? bne.s 1$ ; If not, do it further bsr.w _ConOut_Reloc ; Print down one line move.l A4,D5 ; Last char's address in window dbf D7,0$ ; Number of lines bra.w _Loop ************************************** * * Display last page of ascii-text-file * * Inputs: D5 == Address of last char in window (or NULL) * D6 == Address of 1. char in window * A2 == Address last char of text * A3 == Address first char of text * A4 == used * Results: * D5 == Address of last char in window * D6 == Address of 1. char in window * _LastPage move.l A2,D5 ; Highest address as current for LinesDown move.l D5,D6 ; Highest address as current for us! lea _ConBuffer(A5),A0 ; Address buffer move.l #$1B5B306D,(A0)+ ; Reset display move.l #$9B639B48,(A0)+ ; Reset console and Cursor Home move.w #$9B4A,(A0) ; Erase to end of display + Cursor Home moveq #10,D0 ; 10 chars for output bsr.w _ConOut_Rel ; Output move.w _StdPageSize(A5),D7 ; Number of scrolls addq.w #1,D7 ; Plus 1 movea.l D6,A4 0$ cmpa.l A3,A4 ; A3 == lowest address, A4 == current address, does it fit? bls.w _Loop ; If not... lea _ConBuffer(A5),A0 ; Address buffer move.w #$9B48,(A0)+ ; Cursor Home move.l #$9B314100,(A0) ; Scroll 1 line up moveq #5,D0 ; 5 chars for output bsr.w _ConOut_Rel ; Output 1$ moveq #0,D0 ; Counter for number of chars 2$ addq.w #1,D0 ; Counter for number of chars plus 1 subq.l #1,A4 ; Next char cmpi.b #10,(A4) ; Next line? bne.s 2$ movea.l A4,A0 addq.l #1,A0 subq.w #1,D0 bsr.w _ConOut_Reloc ; Print down the line move.l A4,D6 ; Remember startaddress of string in D6 as next pointer * for LinesUp-routine dbf D7,0$ move.l _LinesInFile(A5),D0 ; How many lines in file? addq.l #1,D0 move.l D0,_Line(A5) ; = lines bra.w _Loop ************************ * * Make cursor invisible. * * Inputs: none * Results: none * _CursorOff clr.l -(sp) movea.l sp,A0 move.b #$9B,(A0) move.b #'0',1(A0) move.b #' ',2(A0) move.b #'p',3(A0) moveq #4,D0 bsr.w _ConOut_Reloc ; Output addq.l #4,sp rts _CursorOn clr.l -(sp) movea.l sp,A0 move.b #$9B,(A0) move.b #' ',1(A0) move.b #'p',2(A0) moveq #3,D0 bsr.w _ConOut_Reloc ; Output addq.l #4,sp rts **************************************************************** * * Twist pointer for system-requester so that system-requesters * which mean us, will appear on our window; must be done because * any other screen as the Workbench's one can be used by Viewer. * * Inputs: none * Results: none * _SetPtr4Req movea.l _OwnTask(A5),A0 move.l pr_WindowPtr(A0),_StdprWindowPtr(A5) ; Save default pointer move.l _WindowPtr(A5),pr_WindowPtr(A0) ; Twist rts *********************************************** * * Find in tooltypes a string which tells us to make a * word warp when the contents of one line do not fit * in one line (window limits) * * Inputs: none * Results: none * _CheckWrap lea WB_arg_1(A5),A0 1$ tst.l (A0) ; Any argument? beq.s 4$ movea.l (A0)+,A1 lea _WrapDef(pc),A2 ; String to compare moveq #7,D0 2$ cmpm.b (A1)+,(A2)+ bne.s 1$ dbf D0,2$ st.b _WrapFlag(A5) ; Set flag 4$ rts ************************************************* * * Get window limits out of tooltypes, * (EXTENTWINDOW=,) * * Inputs: (GetNextArg() - pointer to string in A0 * Results: none * _SetWindow ; Only if WB-start!!! lea WB_arg_1(A5),A0 _GetNextArg ; this one for the Shell 1$ tst.l (A0) ; Argument there? beq.s .EndSetWindow ; No movea.l (A0)+,A1 ; Address overgiven string lea _WindowDef(pc),A2 ; Address string to compare moveq #12,D0 ; 13 chars to compare 3$ cmpm.b (A1)+,(A2)+ ; Compare strings bne.s 1$ ; "EXTENTWINDOW=" dbf D0,3$ moveq #0,D0 ; Fill up (no mask) movea.l A1,A0 ; A0 string (contains value) bsr.w _StrToLong tst.l D1 ; Error? bmi.s .EndSetWindow .SetWidth lea _WindowRecord(A5),A3 ; Address window-record move.w D0,nw_Width(A3) ; Set width moveq #0,D0 ; No mask * String to convert already in A0 bsr.w _StrToLong tst.l D1 bmi.s .EndSetWindow .SetHeight lea _WindowRecord(A5),A3 ; Window-record move.w D0,nw_Height(A3) ; Set height .EndSetWindow rts ********************************************************* * * Set scrollwidth, user has to specify it on his own, * tooltyes or Shell. * * Inputs: (SetScrollWidth_01() - only Shell: A0 - string) * Results: none * _SetScrollWidth ; Only available from Workbench lea WB_arg_1(A5),A0 ; Address constant of 1. argument _SetScrollWidth_01 ; Jumpmark for Shell use tst.l (A0) ; Address 1. argument there? beq.s 1$ movea.l (A0)+,A1 ; Out of it address 1. argument lea _PageDef(pc),A2 moveq #11,D0 ; 12 loops 2$ cmpm.b (A1)+,(A2)+ ; Compare char for char bne.s _SetScrollWidth_01 ; "SCROLLWIDTH=" dbf D0,2$ moveq #0,D0 ; No mask movea.l A1,A0 ; Text into A0 bsr.w _StrToLong ; Get value cmpi.l #-1,D1 ; On error beq.s 1$ subq.w #1,D0 ; Because scrolling can be done once more! move.w D0,_PageSize(A5) ; Set length to scroll st.b _PageSizeFlag(A5) ; Set flag 1$ rts **************************************************** * * Get from and only! from Workbench overgiven file, * may be specified in the defaulttool of the project- * icon of a file. * * Inputs: none * Results: none * _SetDirection tst.l _argc(A5) ; Any argument? beq.s 2$ ; If not... move.l lock_1(A5),D1 ; Get the lock to the file beq.s 3$ movea.l _DOSBase(A5),A6 jsr _LVOCurrentDir(A6) ; Change current directory to project's one 3$ tst.l file_1(A5) ; No file? beq.s 2$ movea.l file_1(A5),A0 ; Name of file tst.l _IconBase(A5) beq.s 2$ movea.l _IconBase(A5),A6 jsr _LVOGetDiskObject(A6) ; Load ".info"-file move.l D0,_UserProject(A5) ; Save its handle movea.l D0,A0 ; Pointer to entries A0 tst.l D0 beq.s 2$ ; Upon error movea.l do_ToolTypes(A0),A0 ; Get those tooltype-pointer move.l A0,_ToolTypesArray(A5) moveq #14,D0 ; Allow 15 entries to be stored lea WB_arg_1(A5),A1 ; Address for 1. argument 1$ move.l (A0)+,(A1)+ ; Save these pointers beq.s 2$ ; Last pointer? dbf D0,1$ ; No... 2$ rts ************************************************* * * Get page width and length in lines. Do it via a * console status report. * * Maximums for now: * 999 lines and 999 columns. * The console will report if we set the limits to * 999 the maximum which is displayable, e.g. * 20;78R - mean 20 lines and 78 columns. * * Inputs: none * Results: none * _SetPageWidthAndLen movem.l D0-D7/A0-A6,-(sp) .GetConReport lea _ConBuffer(A5),A0 move.l #$9B39393B,(A0)+ ; Move Cursor 99; [ NOTEZ-BIEN: We cannot use 999 * here - due to the below menitioned bug! ] move.l #$39393948,(A0)+ ; 999H - here it works... moveq #8,D0 bsr.w _ConOut_Rel lea _ConBuffer(A5),A0 move.l #$9B393939,(A0)+ ; Because of a bug in the con-routines move.b #'B',(A0) ; we have to set the cursor as single CSI moveq #5,D0 ; to end of the display (999B bsr.w _ConOut_Rel lea _ConBuffer(A5),A0 move.l #$9B366E00,(A0)+ ; Console Device Status Report * 6n moveq #3,D0 ; 3 chars bsr.w _ConOut_Rel ; Output lea _ConBuffer(A5),A0 moveq #20,D0 .ClearIt clr.b (A0)+ dbf D0,.ClearIt 1$ bsr.w _GetConMsg ; Get the message from the console-device tst.l D0 ; Message? beq.s 1$ movea.l D0,A1 jsr _LVOReplyMsg(A6) lea _ConBuffer(A5),A0 addq.l #1,A0 move.l A0,D2 move.l _stdout(A5),D1 beq.s 8$ moveq #7,D3 movea.l _DOSBase(A5),A6 ; Print message to Shell-window jsr _LVOWrite(A6) 8$ lea _ConBuffer(A5),A0 addq.l #1,A0 ; Overread CSI moveq #0,D0 ; No mask bsr.w _StrToLong ; Get value cmpi.l #-1,D1 ; Error ? bne.s 2$ cmpi.b #';',-1(A0) ; Last char the semicolon? beq.s 2$ ; If so, it is ok bra.w .GetConReport ; Upon error 2$ subq.w #2,D0 ; Minus 2 = scrollwidth move.w D0,_StdPageSize(A5) ; Standard scrollwidth tst.b _PageSizeFlag(A5) ; Already defined (ToolTypes)? bne.s 3$ ; If so... move.w D0,_PageSize(A5) ; Else save it 3$ * ** Get count which stays after the semicolon ** (returned by the status-report) * moveq #0,D0 ; No mask bsr.w _StrToLong ; Get value cmpi.l #-1,D1 ; Error ? bne.s 4$ cmpi.b #'R',-1(A0) ; Last char the 'R'? beq.s 4$ ; If so, it is ok bra.w .GetConReport ; Else get new 4$ subq.w #1,D0 move.l D0,_PageWidth(A5) ; Set max. length lea _IOInlineBuf(A5),A0 move.b #10,(A0)+ move.l _PageWidth(A5),D0 bsr.w _comdec move.b #10,(A0)+ clr.b (A0) lea _IOInlineBuf(A5),A0 move.l _stdout(A5),D1 beq.s 6$ move.l A0,D2 moveq #-1,D3 7$ tst.b (A0)+ dbeq D3,7$ not.l D3 movea.l _DOSBase(A5),A6 jsr _LVOWrite(A6) ; Print down settings to Shell-window 6$ movem.l (sp)+,D0-D7/A0-A6 5$ rts ******************************************************************** * * Open and init a filerequester, only Arp and ReqTools supported yet. * * * Inputs: none * Results: Gloabal Flag ("_ReqFlag), indicates which requester is used, * 1 ReqTools * 2 Arp * -1 failed to open (hard error) * OpenReq tst.l _ReqPtr(A5) bne.s 1$ movea.l _SysBase(A5),A6 moveq #37,D0 lea _ReqToolsName(pc),A1 jsr _LVOOpenLibrary(A6) move.l D0,_ReqToolsBase(A5) beq.s _ArpReq ; If it failed... movea.l _ReqToolsBase(A5),A6 ; else moveq #0,D0 ; Must be NULL for the moment suba.l A0,A0 ; (Tags) ditto jsr _LVOrtAllocRequestA(A6) ; Allocate structure move.l D0,_ReqPtr(A5) beq.s .noReqToolsReq ; Upon error 1$ move.b #1,_ReqFlag(A5) ; Say: ok reqtools rts .noReqToolsReq movea.l A6,A1 movea.l _SysBase(A5),A6 jsr _LVOCloseLibrary(A6) clr.l _ReqToolsBase(A5) ; Important!!! _ArpReq tst.l _ArpBase(A5) bne.s 2$ movea.l _SysBase(A5),A6 moveq #39,D0 lea _ArpName(pc),A1 jsr _LVOOpenLibrary(A6) move.l D0,_ArpBase(A5) beq.s .NoArp ; Hard error, failed to open any requester! bsr.s _InitReq ; Init Arp-structure 2$ move.b #2,_ReqFlag(A5) ; Flag for Ok Arp rts .NoArp move.b #-1,_ReqFlag(A5) ; Say: damned, failed to open rts ********************************** * * Display ReqTools file-requester. * * Inputs: none * Results: none * _ReqLoad movem.l A2-A3,-(sp) suba.l A0,A0 ; TAG-list movea.l _ReqPtr(A5),A1 ; ReqTools-structure lea _File(A5),A2 ; Buffer for filename tst.b _LoadFlag(A5) ; Shall we load? bne.s 3$ ; No, save! lea _SaveTitle(pc),A3 ; Save-string (title-text) bra.s 2$ 3$ lea _AWTitle(pc),A3 ; Window-title == load 2$ movea.l _ReqToolsBase(A5),A6 jsr _LVOrtFileRequestA(A6) tst.l D0 beq.s 4$ ; No file was chosen! lea _Drive(A5),A1 ; Address buffer for directory movea.l _ReqPtr(A5),A0 ; Address Requester-structure movea.l 16(A0),A0 ; rtfi_Dir(A0),A0! - pointer to directory 1$ move.b (A0)+,(A1)+ ; Copy drive-name tst.b -1(A0) ; Copy also NULL-byte bne.s 1$ moveq #1,D0 ; Signal ok 4$ movem.l (sp)+,A2-A3 rts ************************************ * * Initialize Arp-requester structure. * * Inputs: none * Results: none * _InitReq lea _ArpReqStruc(A5),A0 ; Address structure lea _AWTitle(pc),A1 ; Address title for requester move.l A1,(A0) lea _File(A5),A1 ; Address buffer for name move.l A1,4(A0) lea _Drive(A5),A1 ; Address buffer for directory move.l A1,8(A0) move.b #':',_Drive(A5) ; Say current directory rts ***************************** * * Display Arp-file-requester. * * Inputs: none * Results: none * _ArpLoad movem.l D2-D7/A2-A6,-(sp) ; <-I don't trust Arp lea _ArpReqStruc(A5),A0 ; Address structure tst.b _LoadFlag(A5) ; Shall we load a file? bne.s 1$ ; Yes... lea _SaveTitle(pc),A1 ; Otherwise set saving-title move.l A1,(A0) bra.s 2$ 1$ lea _AWTitle(pc),A1 ; Title (Load) move.l A1,(A0) 2$ movea.l _ArpBase(A5),A6 lea _ArpReqStruc(A5),A0 ; Structure of requester jsr _LVOArpFileRequest(A6) movem.l (sp)+,D2-D7/A2-A6 rts *************************************************** * * Merge volume's/directory's name with file's name. * * Inputs: none * Results: none * _GetFileName move.l A2,-(sp) lea _Drive(A5),A0 lea _File(A5),A1 lea _FileName(A5),A2 1$ tst.b (A0) beq.s 2$ move.b (A0)+,(A2)+ bra.s 1$ 2$ tst.b -1(A0) beq.s 3$ cmpi.b #':',-1(A0) beq.s 3$ cmpi.b #'/',-1(A0) beq.s 3$ move.b #'/',(A2)+ 3$ move.b (A1)+,(A2)+ tst.b -1(A1) bne.s 3$ movea.l (sp)+,A2 rts *********************************** * * Startup to display filerequester. * * Inputs: none * Results: D0 == NULL upon error * *------------------------------------------------------ _GetFile cmpi.b #-1,_ReqFlag(A5) ; No requester at all? beq.s .NoReqAtAll cmpi.b #1,_ReqFlag(A5) ; ReqTools-Load-routine? bne.s .ArpMustLoad ; No, Arp bsr.w _ReqLoad ; else ReqTools-file-requester tst.l D0 ; Ok? beq.s .NoFileGet ; No, no file selected! bsr.s _GetFileName ; Combinate filename in dos-convention moveq #$11,D0 ; Return ok rts .ArpMustLoad bsr.w _ArpLoad ; Arp-file-requester tst.l D0 ; No file? beq.s .NoFileGet bsr.s _GetFileName ; Combinate filename in dos-convention moveq #$11,D0 ; Return ok. rts .NoReqAtAll moveq #-1,D0 ; Damned, no requester at all! rts .NoFileGet ; No file was selected rts *************************************************************** * * Complex routine which loads a file, sets up needed parameters. * * Inputs: none * Results: D0 - NULL upon error * _ReadFile movea.l _SysBase(A5),A6 movea.l _TextPtr(A5),A1 move.l _BufferSize(A5),D0 beq.s 1$ jsr _LVOFreeMem(A6) ; Free last pointed text clr.l _BufferSize(A5) clr.l _TextPtr(A5) clr.l _Line(A5) clr.l _SearchStrPtr(A5) ; Don't access what isn't valid.... clr.l _SearchStrLen(A5) 1$ movea.l _DOSBase(A5),A6 lea _FileName(A5),A0 move.l A0,D1 moveq #ACCESS_READ,D2 ; Mode: READ jsr _LVOLock(A6) move.l D0,_LockSave(A5) ; Save lock of file beq.w .LockErr move.l _LockSave(A5),D1 ; The key to the file lea _FIB(A5),A0 ; Address FileInfoBlock move.l A0,D2 ; into D2 jsr _LVOExamine(A6) ; Get file's status lea _FIB(A5),A0 ; Address FileInfoBlock tst.l (A0) ; Was function Examine successful? beq.w .ExamineErr ; No, oh boy move.l _LockSave(A5),D1 ; Key to D1 jsr _LVOUnLock(A6) ; Free key lea _FIB(A5),A0 ; Address FileInfoBlock tst.l 4(A0) ; Dir or file? bpl.w .ItsADir ; Too bad, it's a dir move.l 124(A0),_FileSize(A5) ; Get size in bytes of file move.l 124(A0),D0 ; also into D0 beq.w .FileEmpty ; If the file is empty addq.l #8,D0 ; else filelength plus 8 bytes bsr.w _MakeCountEven ; Align count move.l D0,_BufferSize(A5) ; Save extended count movea.l _SysBase(A5),A6 move.l #MEMF_PUBLIC|MEMF_CLEAR,D1 jsr _LVOAllocMem(A6) ; Mem demand move.l D0,_TextPtr(A5) ; Save address allocated memory beq.w .AllocError ; Upon error... movea.l _DOSBase(A5),A6 lea _FileName(A5),A0 ; Address string (file's name) move.l A0,D1 ; into D1 move.l #MODE_OLDFILE,D2 ; Mode = OLD jsr _LVOOpen(A6) ; Open file move.l D0,_FileHandle(A5) ; Save handle beq.s .FileOpenErr ; Upon error move.l _FileHandle(A5),D1 movea.l _TextPtr(A5),A0 ; Address buffer for file to read in move.w #$200A,(A0)+ ; Write first a Blank and a LineFeed move.l A0,D2 ; Current address into D2 move.l _FileSize(A5),D3 ; Length file jsr _LVORead(A6) ; Read file into buffer tst.l D0 bmi.s .ReadError ; Upon error bsr.s .CloseFile ; Close file movea.l _TextPtr(A5),A0 move.l _FileSize(A5),D0 cmpi.b #10,1(A0,D0.l) beq.s .ok move.b #10,2(A0,D0.l) ; LineFeed (end) .ok moveq #$11,D0 ; Say ok rts ; and back .ReadError movea.l _DOSBase(A5),A6 ; - Because of bug in DOS v39 * we have to restore DOSBase.... jsr _LVOIoErr(A6) ; Get the error bsr.w _SetError ; Set the error bsr.s .CloseFile ; Close file bsr.w _FreeFile ; Free allocated memory lea _ReadErrTxt(pc),A0 ; Errorstring bsr.w _DisplayError ; Tell user... moveq #0,D0 rts .CloseFile move.l A6,-(sp) movea.l _DOSBase(A5),A6 move.l _FileHandle(A5),D1 jsr _LVOClose(A6) movea.l (sp)+,A6 rts .FileOpenErr jsr _LVOIoErr(A6) ; Get the error bsr.w _SetError ; and set it bsr.w _FreeFile ; Free memory lea _OpenFileErrTxt(pc),A0 ; Errorstring bsr.w _DisplayError ; Tell user... moveq #0,D0 rts .AllocError movea.l _DOSBase(A5),A6 ; Get errorcode (103) jsr _LVOIoErr(A6) bsr.w _SetError ; Set the errorcode lea _AllocErrTxt(pc),A0 ; Errorstring bsr.w _DisplayError ; Tell user... moveq #0,D0 rts .FileEmpty lea _EmptyTxt(pc),A0 ; Errorstring bsr.w _DisplayError ; Tell user... moveq #0,D0 rts .ItsADir lea _DirTxt(pc),A0 ; Errorstring bsr.w _DisplayError ; Tell user... tst.l D0 beq.s 3$ ; If user said abort... bsr.w OpenReq ; Initialize requester (Arp or Reqtools) cmpi.b #-1,_ReqFlag(A5) ; No requester at all? beq.s 3$ ; If so... lea _FileName(A5),A0 ; Name of directory move.l A0,D1 moveq #ACCESS_READ,D2 ; Mode: Read movea.l _DOSBase(A5),A6 jsr _LVOLock(A6) ; Lock Directory move.l D0,D2 ; Lock into D2 beq.s 3$ ; If we can't get lock * move.l D0,D0 ; Lock lea _Drive(A5),A0 ; Buffer for name from Lock lea _FIB(A5),A1 ; FileInfoBlock bsr.w _GetNameFromLock ; Get complete name of Lock, e.g. "DF0:pics/brushes/" move.l D2,D1 ; Lock movea.l _DOSBase(A5),A6 jsr _LVOUnLock(A6) ; Free Lock cmpi.b #1,_ReqFlag(A5) ; Reqtools-requester? bne.s 2$ ; If not, it must be arp (for now) clr.l -(sp) ; Local TagItems.... clr.l -(sp) ; TAG_DONE clr.l -(sp) ; ti_DATA (pointer to directory string) clr.l -(sp) ; ti_TAG (RTFI_Dir) movea.l sp,A0 ; As TagList... move.l #$80000000+50,(A0) ; Tell: change directory (RTFI_Dir) lea _Drive(A5),A1 ; Address new directory string move.l A1,4(A0) ; as pointer for ReqTools movea.l _ReqPtr(A5),A1 ; Reqtools-Requester-Record movea.l _ReqToolsBase(A5),A6 jsr _LVOrtChangeReqAttrA(A6) ; Change directory to overgiven one lea 16(sp),sp ; Correct stack 2$ st.b _LoadFlag(A5) ; Tell: we're going to "load" a file bsr.w _GetFile ; Get filename (display requester) tst.l D0 ; Nothing picked? beq.s 3$ ; Hard error not possible, only "no file chosen" bra.w _ReadFile ; Again, try to load the file... 3$ moveq #0,D0 ; Tell, didn't fit to read file rts .ExamineErr ; Should never occur jsr _LVOIoErr(A6) bsr.w _SetError move.l _LockSave(A5),D1 ; Key jsr _LVOUnLock(A6) ; We allow other people to modify that file... lea _ExamineErrTxt(pc),A0 bsr.w _DisplayError moveq #0,D0 rts .LockErr jsr _LVOIoErr(A6) bsr.w _SetError lea _LockErrTxt(pc),A0 bsr.w _DisplayError * ** Now we do something smart.... * ** When the user calls us directly from CLI/Shell with the path and file and ** the file he/she wants to displayed can't be locked because he/she entered ** an invalid path or filename, we search as long as the path is valid, example: * ** 1> viewer hd2:dtp/pictures/btush/aga/lamp.bsh <- incorrect ** was chosen by the user, but the valid name is: ** 1> viewer hd2:dtp/pictures/brush/aga/lamp.bsh <- correct * ** The only thing we now have to do is to search backward if the string is valid, i.e. ** if the directory can be locked: * ** (--------) "hd2:dtp/pictures/btush/aga/lamp.bsh" - caused the lock-error ** (1st loop) "hd2:dtp/pictures/btush/aga/" - isn't still valid ** (2nd loop) "hd2:dtp/pictures/btush/" - isn't still valid ** (3rd loop) "hd2:dtp/pictures/" - valid!!! * ** Now we copy this valid string into the buffer for the "_Drive" and depending ** of the requester-modules (ReqTools/Arp) we setup the necessary things. ** That's all! * * Let's say the the volume isn't available (e.g. "DF7:"), then it makes no sense * to execute the following routine (if we can't access the disk, we can't access * the directories...). move.l _errno(A5),D0 ; Get current IoErr-errornumber cmpi.l #ERROR_DEVICE_NOT_MOUNTED,D0 beq.w .NotFound cmpi.l #ERROR_NOT_A_DOS_DISK,D0 beq.w .NotFound cmpi.l #ERROR_NO_DISK,D0 beq.w .NotFound cmpi.l #ERROR_OBJECT_IN_USE,D0 ; Does somebody format the drive? beq.w .NotFound .FindValidDir lea _FileName(A5),A0 ; Address string of filename movea.l A0,A1 ; Startaddress of string also in A1 moveq #-1,D0 ; Dummy-counter .FindStrEnd tst.b (A0)+ ; Find string end dbeq D0,.FindStrEnd subq.l #1,A0 ; Pointer to NULL-byte (terminator) of string .Find cmpa.l A0,A1 ; Original same as decreased address?, i.e. beq.w .NotFound ; stringstart found - then no trailing was found cmpi.b #':',(A0) ; Else... beq.s .Found cmpi.b #'/',(A0) beq.s .Found subq.l #1,A0 dbf D0,.Find ; So long not found... .Found move.b (A0),D1 ; Remember last valid char clr.b (A0) ; Last valid char is the ":" or the "/", so * terminate string (_FileName), i.e. replace ":" * or "/" through NULL-byte - otherwise at next loop * we found the same char (never ending loop) * "Viewer Hang Up" move.l A2,-(sp) lea _Drive(A5),A2 ; Stringbuffer for volume/directory .Cpy cmpa.l A1,A0 ; Copy all chars until we reach the right address beq.s .Done move.b (A1)+,(A2)+ dbf D0,.Cpy .Done move.b D1,(A2)+ ; Copy also remembered trailing clr.b (A2) ; Terminate new string movea.l (sp)+,A2 lea _Drive(A5),A0 move.l A0,D1 moveq #ACCESS_READ,D2 movea.l _DOSBase(A5),A6 jsr _LVOLock(A6) ; Can we lock the directory (or volume) move.l D0,D1 beq.s .FindValidDir ; If not, try again... jsr _LVOUnLock(A6) ; Else give back not more needed lock bsr.w OpenReq ; Initialize requester (Arp or Reqtools) cmpi.b #-1,_ReqFlag(A5) ; No requester at all? beq.s .NotFound ; If so... cmpi.b #1,_ReqFlag(A5) ; Reqtools-requester? bne.s .NotFound ; If not, it must be arp (for now) clr.l -(sp) ; Local TagItems.... clr.l -(sp) ; TAG_DONE clr.l -(sp) ; ti_DATA (pointer to directory string) clr.l -(sp) ; ti_TAG (RTFI_Dir) movea.l sp,A0 ; As TagList... move.l #$80000000+50,(A0) ; Tell: change directory (RTFI_Dir) lea _Drive(A5),A1 ; Address new directory string move.l A1,4(A0) ; as pointer for ReqTools movea.l _ReqPtr(A5),A1 ; Reqtools-Requester-Record movea.l _ReqToolsBase(A5),A6 jsr _LVOrtChangeReqAttrA(A6) ; Change directory to overgiven one lea 16(sp),sp ; Correct stack .NotFound moveq #0,D0 ; Indicates no file was loaded... rts *************************************************************** * * * Inputs: D0 - Lock of directory * A0 - buffer for name of merged volume/directory name * A1 - buffer for FileInfoBlock (272 byte here) * _GetNameFromLock movem.l D2/D6-D7/A3-A4,-(sp) movea.l _DOSBase(A5),A6 move.l D0,D6 ; Lock beq.s .ErrorEnd move.l A0,A3 ; Buffer move.l A1,A4 ; FIB moveq #1,D7 ; Counter move.l D6,-(sp) ; Lock onto stack .Parent move.l D6,D1 ; Lock jsr _LVOParentDir(A6) tst.l D0 ; Previous dir beq.s .Volume ; Home-directory e.g. DF0 move.l D0,-(sp) ; Lock passed onto stack addq.l #1,D7 ; 1 more Lock move.l D0,D6 ; Save this Lock bra.s .Parent ; So long home-directory not found... .Volume move.l (sp)+,D1 ; Lock bsr.s .ExamineDir ; Get those infos bsr.s .CopyName ; Copy volume's name move.b #':',-1(A3) ; Set colon subq.l #1,D7 ; 1 less argument beq.s .FoundThem ; If all... .Drawer move.l (sp)+,D1 ; Lock bsr.s .ExamineDir ; Get the infos bsr.s .CopyName ; Copy drawer's name move.b #'/',-1(A3) ; Set trailing subq.l #1,D7 ; 1 less argument beq.s .FoundThem bra.s .Drawer .FoundThem clr.b (A3) moveq #0,D0 ; Indicates no error .end movem.l (sp)+,D2/D6-D7/A3-A4 rts .ErrorEnd moveq #-1,D0 bra.s .end .ExamineDir move.l A4,D2 ; FIB jmp _LVOExamine(A6) .CopyName move.l A4,A0 ; FIB addq.l #8,A0 ; Lock .CopyIt move.b (A0)+,(A3)+ bne.s .CopyIt rts ************************ * * Free allocated data... * * Inputs: none * Results: none _FreeFile move.l A6,-(sp) movea.l _SysBase(A5),A6 movea.l _TextPtr(A5),A1 move.l _BufferSize(A5),D0 jsr _LVOFreeMem(A6) clr.l _BufferSize(A5) ; Important!!! clr.l _TextPtr(A5) ; Important!!! clr.l _SearchStrPtr(A5) clr.l _SearchStrLen(A5) movea.l (sp)+,A6 rts ****************************************** * * File is an object module or a binary file. * Called out of "CheckFile() * * Inputs: none * Results: none * *------------------------------------------------------ _WrongFileType tst.b _NoWarnFlag(A5) bne.s 1$ bsr.w _GetConvertedSize move.l D0,-(sp) pea _ObjectFileTxt(pc) ; Display the error bsr.w _FmtDisplay addq.l #8,sp tst.l D0 ; Right mouse button? beq.s 0$ ; Yes 1$ bra.w _ConvertBinary 0$ addq.l #4,sp ; Remove "bsr" bsr.s _FreeFile bra.w _Loop _BinaryFile tst.b _NoWarnFlag(A5) bne.s 1$ bsr.w _GetConvertedSize move.l D0,-(sp) pea _BinaryFileTxt(pc) bsr.w _FmtDisplay addq.l #8,sp tst.l D0 ; Right mouse button? beq.s 0$ ; Yes 1$ bra.w _ConvertBinary 0$ addq.l #4,sp ; Remove "bsr" bsr.s _FreeFile bra.w _Loop ********************************************** * * Check if the file is an ascii-text file, * a powerpacker.library packed ascii-textfile, * a picture, * a powerpacker.library packed picture or -what is * not truely displayable * an object file, * a binary file (like ANIMs). * * Inputs: none * Results: none * _CheckFile movea.l _TextPtr(A5),A0 ; Source in memory addq.l #2,A0 ; Overread #$200A cmpi.l #'PP20',(A0) ; PowerPacker.library packed? beq.w _Decrunch cmpi.l #$000003F3,(A0) ; Hunk header? beq.s _WrongFileType ; If so ... cmpi.l #'CAT ',(A0) beq.w _LoadFCFile cmpi.l #'LIST',(A0) beq.w _LoadFCFile cmpi.l #'FORM',(A0) ; IFF-file? bne.s _CheckFile_1 ; If not... cmpi.l #'ILBM',8(A0) ; Picture? beq.w _LoadScreen ; If so... cmpi.l #'ACBM',8(A0) ; Picture? beq.w _LoadScreen ; If so... cmpi.l #'SWRT',8(A0) ; FinalCopy document? beq.w _LoadFCFile cmpi.l #'FTXT',8(A0) ; IFF-text document? beq.w _LoadFCFile cmpi.l #'WOWO',8(A0) ; WordWoorth text document? beq.w _LoadFCFile cmpi.l #'8SVX',8(A0) ; Audio file? beq.w _LoadAudio * ** Test if file contains binary datas... * _CheckFile_1 move.l #255,D0 ; Counter move.l _FileSize(A5),D1 ; Old filelength cmp.l D0,D1 ; Compare ble.s SetLittleFileSize ; Smaller than 256! bra.s Test_If_Binary ; Else test 256 bytes SetLittleFileSize: move.b D1,D0 ; As much bytes file is large (smaller than 256) subq.b #1,D0 ; Minus 1 - because of DBF Test_If_Binary move.b (A0),D1 cmpi.b #$9B,D1 beq.s .Ok cmpi.b #127,D1 bls.s .Ok1 cmpi.b #159,D1 bls.w _BinaryFile bra.s .Ok .Ok1 cmpi.b #31,D1 bhi.s .Ok cmpi.b #6,D1 bls.w _BinaryFile .Ok2 cmpi.b #15,D1 beq.w .Ok cmpi.b #16,D1 beq.w .Ok cmpi.b #27,D1 beq.s .Ok bhi.w _BinaryFile cmpi.b #15,D1 bhi.w _BinaryFile .Ok addq.l #1,A0 ; One char further dbf D0,Test_If_Binary ; All bytes tested? rts ******************************************* * * Decrunch startup for PP20 crunched files. * * Inputs: none * Results: none * _Decrunch movea.l _TextPtr(A5),A0 ; Source addq.l #2,A0 ; Overread #$200A move.l _FileSize(A5),D0 ; Length file lea -4(A0,D0.l),A0 ; Pointer to last longword of crunched file move.l (A0),D0 ; Only upper 24 bits are intresting lsr.l #8,D0 ; Skip crunch-info move.l D0,_UPFSize(A5) ; UnPackedFileSize addi.l #12,D0 ; Plus 8 bytes :-) Nico François * plus 4 :-) Jörg van de Loo bsr.w _MakeCountEven ; Align size move.l D0,_IncSize(A5) ; Increased file size tst.b _NoWarnFlag(A5) ; Allowed to display warning? bne.s 1$ move.l _UPFSize(A5),D0 ; Length file move.l D0,-(sp) pea _PPCrunchTxt(pc) ; Tell user bsr.w _FmtDisplay addq.l #8,sp tst.l D0 ; Right mousebtton? beq.w _BinaryFile ; If so... 1$ move.l _IncSize(A5),D0 move.l #MEMF_PUBLIC|MEMF_CLEAR,D1 movea.l _SysBase(A5),A6 jsr _LVOAllocMem(A6) move.l D0,_DecrunchAddr(A5) ; Buffer for decrunched datas beq.s .DecrunchError movea.l _TextPtr(A5),A0 ; = Decrunch address addq.l #2,A0 ; Overread #$200A move.l _FileSize(A5),D0 ; Length crunched file movea.l _DecrunchAddr(A5),A1 ; Address for uncrunched file move.w #$200A,(A1)+ ; (but write down Blank and LineFeed as first * entries, important for the ascii-text-viewer). bsr.s _PPDecrunch ; Decrunch datas movea.l _DecrunchAddr(A5),A0 move.l _UPFSize(A5),D0 cmpi.b #10,1(A0,D0.l) beq.s .CrunchOk move.b #10,2(A0,D0.l) ; Write LineFeed at end of uncrunched file .CrunchOk bsr.w _FreeFile ; Free not needed thing move.l _DecrunchAddr(A5),_TextPtr(A5) ; Copy pointer move.l _IncSize(A5),_BufferSize(A5) ; Copy size move.l _UPFSize(A5),_FileSize(A5) ; Copy size bra.w _CheckFile ; Check unpacked file .DecrunchError lea _DecrunchErrTxt(pc),A0 bsr.w _DisplayError bsr.w _FreeFile ; see above addq.l #4,sp ; Remove "bsr" CheckFile bra.w _Loop *********************************** * * Copyright Nico François * _PPDecrunch movem.l D1-D3/D5-D7/A2-A3,-(sp) bsr.s .PowerPackerDecruncher movem.l (sp)+,D1-D3/D5-D7/A2-A3 rts .PowerPackerDecruncher lea 4(A0),A3 lea 0(A0,D0.l),A0 movea.l A1,A2 moveq #3,D6 moveq #7,D7 moveq #1,D5 movea.l A2,A1 move.l -(A0),D1 tst.b D1 beq.s 1$ bsr.s 5$ subq.b #1,D1 lsr.l D1,D5 1$ lsr.l #8,D1 add.l D1,A2 2$ bsr.s 5$ bcs.s 12$ moveq #0,D2 3$ moveq #1,D0 bsr.s 8$ add.w D1,D2 cmp.w D6,D1 beq.s 3$ 4$ moveq #7,D0 bsr.s 8$ move.b D1,-(A2) dbf D2,4$ cmp.l A2,A1 bcs.s 12$ rts 5$ lsr.l #1,D5 beq.s 6$ rts 6$ move.l -(A0),D5 roxr.l #1,D5 rts 7$ subq.w #1,D0 8$ moveq #0,D1 9$ lsr.l #1,D5 beq.s 11$ 10$ roxl.l #1,D1 dbf D0,9$ rts 11$ move.l -(A0),D5 roxr.l #1,D5 bra.s 10$ 12$ moveq #1,D0 bsr.s 8$ moveq #0,D0 move.b 0(A3,D1.w),D0 move.w D1,D2 cmp.w D6,D2 bne.s 15$ bsr.s 5$ bcs.s 13$ moveq #7,D0 13$ bsr.s 7$ move.w D1,D3 14$ moveq #2,D0 bsr.s 8$ add.w D1,D2 cmp.w D7,D1 beq.s 14$ bra.s 16$ 15$ bsr.s 7$ move.w D1,D3 16$ addq.w #1,D2 17$ move.b 0(A2,D3.w),-(A2) dbf D2,17$ cmpa.l A2,A1 bcs.s 2$ rts *********************************************** * * Attempt to find a display ID which does match * with the settings of the computed image. * * Needed for the Picasso96 software package. * * Should also works with other by me unknown * 3rd party software packages. * _GetMode movem.l D2-D3/D5-D7/A2,-(sp) moveq #0,D5 move.b D0,D5 cmpi.w #1360,_Width(A5) ; Maximum widtn for a 24 bit display (CV3D) bls.s 1$ cmpi.b #16,D5 ; If not 24 bitplanes deep bls.s 1$ moveq #16,D5 ; Else, force screen from 24 to 16 bitplanes 1$ moveq #0,D7 ; Error code or Monitor ID movea.l _SysBase(A5),A6 move.l #128,D0 ; Buffer for DimensionInfo (di) move.l #MEMF_CLEAR,D1 jsr _LVOAllocMem(A6) tst.l D0 beq.w .end movea.l D0,A2 ; DimensionInfo movea.l _GfxBase(A5),A6 moveq #INVALID_ID,D6 ; Get really first ID! cmpi.b #7,D5 bhi.s .loop moveq #8,D5 ; Less than 8 bitplanes -> now 8 bitplanes! .loop move.l D6,D0 ; Last monitor ID jsr _LVONextDisplayInfo(A6) cmpi.l #INVALID_ID,D0 ; End of monitor ID list? beq.s .notfound move.l D0,D6 ; Monitor ID andi.l #$FFF00000,D0 ; Only non native AMIGA modes allowed! beq.s .loop cmpi.l #$FFF00000,D0 ; Test monitor? - ignore! beq.s .loop suba.l A0,A0 ; handle = 0 movea.l A2,A1 ; di move.l #128,D0 ; size of buffer move.l #DTAG_DIMS,D1 ; TAG move.l D6,D2 ; Monitor ID jsr _LVOGetDisplayInfoData(A6) tst.l D0 beq.s .loop ; If it failed... * cmpi.w #15,dim_MaxDepth(A2) ; Ignore 15bit modes! * beq.s .loop cmp.w #16,D5 ; More than 16 bitplanes? bls.s .normalDepthCheck ; If not, a normal depth check cmp.w #23,dim_MaxDepth(A2) ; Can we display 24 bitplanes at a time with this monitor? bls.s .loop ; No... bra.s .dimCheck ; Yes... .normalDepthCheck cmp.w dim_MaxDepth(A2),D5 ; Right depth? bne.s .loop ; If not... .dimCheck lea dim_Nominal(A2),A0 ; Get dimension of monitor move.w ra_MaxX(A0),D0 ; Last X-position of monitor (e.g. 639) move.w ra_MaxY(A0),D1 ; Last Y-position of monitor (e.g. 479) addq.w #1,D0 ; e.g. == 640 addq.w #1,D1 ; e.g. == 480 move.w _PlaneWidth(A5),D2 ; e.g. 640 move.w _PlaneHeight(A5),D3 ; e.g. 480 cmp.w D0,D2 bne.s .loop cmp.w D1,D3 bne.s .loop move.l D6,D7 ; Found ID! * Now figure out if this monitor supports changes of RasInfo, * set ViewPortShare by default to no (#-1)! * Completey removed because Picasso96 1.4x supports now changing of View^dx/dy moveq #0,D0 ; Must be set to minus 1 if the check should work!!! move.l D0,_ViewPortShare(A5) * suba.l A0,A0 ; handle = 0 * movea.l A2,A1 ; Now MonitorInfo!!! * move.l #128,D0 ; size of buffer * move.l #DTAG_MNTR,D1 ; TAG * move.l D6,D2 ; Monitor ID * jsr _LVOGetDisplayInfoData(A6) * tst.l D0 * beq.s .freeDI * move.l mtr_Compatibility(A2),_ViewPortShare(A5) * bra.s .freeDI .notfound * moveq #0,D7 ; No ID! * move.l D7,_ViewPortShare(A5) ; Reset .freeDI movea.l _SysBase(A5),A6 movea.l A2,A1 move.l #128,D0 jsr _LVOFreeMem(A6) .end move.l D7,D0 movem.l (sp)+,D2-D3/D5-D7/A2 rts ; Return ID in D0 or zero for not found * (only foreign modes will be returned) ************************************************ * * Display picture or image... * * Inputs: none * Results: none * _LoadScreen tst.b _NoWarnFlag(A5) bne.s 0$ cmpi.l #'ACBM',8(A0) ; ACBM-file? bne.s .IFF_ILBM ; if not, must be ILBM-file lea _ACBMTxt(pc),A0 bsr.w _DisplayError tst.l D0 ; User cancelled? beq.w _BinaryFile ; If so, don't display bra.s 0$ .IFF_ILBM lea _ILBMTxt(pc),A0 bsr.w _DisplayError tst.l D0 ; User cancelled? beq.w _BinaryFile ; If so, don't display 0$ movea.l _TextPtr(A5),A0 ; Source in memory addq.l #2,A0 ; Overread #$200A move.l A0,_SourceFilePtr(A5) ; Copy pointer and size move.l _FileSize(A5),_SourceFileSize(A5) bsr.w _Convert ; Decrunch image move.l D0,-(sp) ; Save returncode movea.l _SysBase(A5),A6 movea.l _TextPtr(A5),A1 move.l _BufferSize(A5),D0 ; Free old datas jsr _LVOFreeMem(A6) clr.l _TextPtr(A5) ; Important!!! clr.l _BufferSize(A5) clr.l _SearchStrPtr(A5) clr.l _SearchStrLen(A5) move.l (sp)+,D0 ; Get return code cmpi.l #1,D0 ; 1 means all ok. bne.w 2$ moveq #0,D0 move.b _Depth(A5),D0 move.l _ViewPortMod(A5),D1 andi.l #HAM_KEY,D1 ; HAM6 or HAM8? beq.s .noham ; If not... .ham moveq #0,D1 move.b _Depth(A5),D1 move.l D1,_HAMSet(A5) move.b #24,_Depth(A5) ; Always use a 24 bit depth screen for HAM modes moveq #1,D1 ; Initial val subq.b #2,D0 ; 8 to 6 or 6 to 4 lsl.w D0,D1 ; HAM8: 1 << 6 = 64 or HAM6: 1 << 4 = 16 lsl.l D0,D1 ; Perform 64 * 64 * 64 or lsl.l D0,D1 ; 16 * 16 * 16 bra.s .giveMsg ; Done for HAM .noham clr.l _HAMSet(A5) moveq #1,D1 lsl.l D0,D1 ; 1 << x = number of colours used .giveMsg tst.b _NoWarnFlag(A5) bne.s .DontWrite move.l _AllPlaneSize(A5),D0 ; Allocated size (in bytes) move.l D0,-(sp) move.l D1,-(sp) ; Number of colours move.w _Height(A5),D0 ; Height of image move.l D0,-(sp) move.l _RealIWidth(A5),D0 ; Width of image (no boundary) move.l D0,-(sp) move.w _Height(A5),D0 ; Number of rows used by bitmap move.l D0,-(sp) move.w _Width(A5),D0 ; Width in pixels of bitmap move.l D0,-(sp) move.w _PlaneHeight(A5),D0 ; Original screen's height move.l D0,-(sp) move.w _PlaneWidth(A5),D0 ; Original screen's width move.l D0,-(sp) pea _ImageInfoTxt(pc) bsr.w _FmtDisplay lea 9*4(sp),sp tst.l D0 beq.w 2$ .DontWrite clr.b _BlitFlag(A5) ; Reset flags, important!!! clr.b _SuperBitMap(A5) moveq #0,D0 move.l D0,_ViewPortShare(A5) * ** If we're in OS3(+) we ask the system for the proberty ViewPort ModeID! * movea.l _GfxBase(A5),A6 cmpi.w #38,LIB_VERSION(A6) bls.w .stdcheck tst.l _TypeOfMem(A5) ; TypeOfMem set up by routine _Convert(), if it is zero * the bitplanes for the image where forces to public (FAST) * memory, since an alien gfx board software created the window's bitmap bne.w .stdcheck bsr.w _CheckEHB clr.l -(sp) ; Assumption: 3rd party GFX device clr.l -(sp) clr.l -(sp) clr.l -(sp) clr.l -(sp) clr.l -(sp) clr.l -(sp) movea.l sp,A0 moveq #0,D1 move.l D1,D2 move.w _PlaneHeight(A5),D1 ; Screen's dimension (not bitmap !!!) move.w _PlaneWidth(A5),D2 * ** Make a 4 to 3 aspect ratio so that any 3rd party device can handle it... * lsl.l #2,D1 ; * 4 divu.w #3,D1 ; / 3 cmp.w D1,D2 ; Range check... bhi.s .align0 andi.l #$FFFF,D1 move.w D1,D2 ; New Width .align0 cmpi.w #360,D2 ; Following are resolutions which can be used bhi.s .align1 ; for 8 bitplane images, the other do only move.w #320,D2 ; support 15/16 and 24/32 bit resolutions... move.w #240,D1 bra.s .dimset .align1 cmpi.w #768,D2 bhi.s .align2 move.w #640,D2 move.w #480,D1 bra.s .dimset .align2 cmpi.w #896,D2 bhi.s .align3 move.w #800,D2 move.w #600,D1 bra.s .dimset .align3 move.w #1024,D2 ; Default... move.w #768,D1 .dimset move.w D2,_PlaneWidth(A5) move.w D1,_PlaneHeight(A5) moveq #0,D0 move.b _Depth(A5),D0 cmpi.b #14,D0 ; Force a 9-14 bitplane display to 15 bit bhi.s .depthok cmpi.b #8,D0 bls.s .depthok moveq #15,D0 bra.s .startscan .depthok cmpi.b #16,D0 bls.s .startscan cmpi.w #1360,_Width(A5) bls.s .startscan moveq #16,D0 .startscan movem.l D0-D2,-(sp) move.l #BIDTAG_NominalWidth,(A0) move.w D2,4(A0) move.l #BIDTAG_NominalHeight,6(A0) move.w D1,10(A0) move.l #BIDTAG_Depth,12(A0) move.b D0,14(A0) clr.l 16(A0) ; TAG_Done movea.l _GfxBase(A5),A6 jsr _LVOBestModeIDA(A6) move.l D0,_ViewPortMod(A5) ; Save 3rd party GFX device View Mode ID (only CyberGraphX) andi.l #$FFF00000,D0 ; Only foreign modes! beq.s .getModeID cmpi.l #$FFF00000,D0 ; Do not use a test monitor! bne.s .modeok .getModeID move.l (sp),D0 ; Depth bsr.w _GetMode ; Find monitor id that suits... move.l D0,_ViewPortMod(A5) bne.s .modeok ; If found movem.l (sp)+,D0-D2 cmpi.b #15,D0 ; 15 bit? bne.s .wrongMode ; No moveq #16,D0 ; Try 16 bit instead of 15 bra.s .startscan .wrongMode lea _ErrorInvalidIDTxt(pc),A0 bsr.w _DisplayError lea 7*4(sp),sp bra.w 2$ .modeok movem.l (sp)+,D0-D2 lea 7*4(sp),sp bsr.w _BrightenColours ; Adjust the colours, e.g.: native AA = 8 bits per pen, 3rd party e.g. only 6 bra.s .ViewModeSet .stdcheck move.l _ViewPortMod(A5),D0 ; ViewModes movea.l _SysBase(A5),A6 cmpi.w #35,LIB_VERSION(A6) bls.s .StdChipSet movea.l _GfxBase(A5),A6 jsr _LVOModeNotAvailable(A6) tst.l D0 beq.s .ViewModeSet move.l _ViewPortMod(A5),D0 ; Take as std-chip-set because Monitor isn't installed .StdChipSet andi.l #$FFFF,D0 ; Clear upper 16 bits because move.l D0,_ViewPortMod(A5) ; OS 1.x doesn't cares about Monitors! bsr.w _DefaultMonitor ; Choose screen-mode depending on video system... .ViewModeSet lea _NewScreen(A5),A0 ; Init screen-record clr.l (A0)+ move.w _PlaneWidth(A5),(A0)+ move.w _PlaneHeight(A5),(A0)+ moveq #0,D0 move.b _Depth(A5),D0 tst.l _TypeOfMem(A5) bne.s .storeDepth cmpi.b #16,D0 bls.s .storeDepth cmp.w #1360,_Width(A5) bls.s .storeDepth moveq #16,D0 ; Reduce 24 bit to 16 .storeDepth move.w D0,(A0)+ move.b #-1,(A0)+ move.b #-1,(A0)+ move.l _ViewPortMod(A5),D0 move.w D0,(A0)+ move.w #NS_EXTENDED|CUSTOMSCREEN|CUSTOMBITMAP|SCREENQUIET,D1 move.w D1,(A0)+ clr.l (A0)+ ; Font lea _ScreenName(pc),A1 move.l A1,(A0)+ clr.l (A0)+ ; Gadgets lea _BitmapStruc(A5),A1 ; Set bitmap as screen's bitmap move.l A1,(A0)+ lea _StdTags(A5),A1 ; Init tag-list for screen move.l A1,(A0)+ move.l #SA_DisplayID,(A1)+ move.l _ViewPortMod(A5),D0 tst.l _TypeOfMem(A5) ; Check if bitplanes forced to FAST-RAM - then * the monitor ID isn't (shouldn't be) a normal AMIGA view mode beq.s .Set btst.l #12,D0 ; An ECS or AA monitor? bne.s .ECS_AA ; if so... andi.l #$FFFF,D0 ; else mask out unused bytes bra.s .Set .ECS_AA cmpi.l #$5FFFF,D0 ; Highest possible OS1 and! OS2 monitor ID bhi.s .NewAAMode ; We do have an AA display mode - so * check if we have the "AA-chip-set" bra.s .Set ; We have only to open a standard or ECS display * ** AA monitor used for displaying, do we have the right chip-set? ** NOTE: I check here the hardware but for the sakeness of completeness the info-data- ** base of the monitor itselfs must be examined. * .NewAAMode movea.l _SysBase(A5),A6 cmpi.w #38,LIB_VERSION(A6) ; OS3.x or greater? bls.s .MustEraseDbl ; If not... movea.l _GfxBase(A5),A6 move.b gb_ChipRevBits0(A6),D1 ; AA custom chip-set enabled? andi.b #GFXF_AA_ALICE|GFXF_AA_LISA,D1 bne.s .Set ; If enabled... .MustEraseDbl andi.l #$FFFF,D0 ; else take as default monitor .Set tst.l D0 bne.s .gotMID bsr.w _DefaultMonitor .gotMID move.l D0,(A1)+ ; Set DisplayID clr.l (A1) clr.b _BlitFlag(A5) ; Erase flag move.w _Height(A5),D0 move.w _PlaneHeight(A5),D1 cmp.w D0,D1 slt.b _SuperBitMap(A5) ; Bitmap taller than screen? - see there shi.b _BlitFlag(A5) ; Displaying a brush? move.w _Width(A5),D0 move.w _PlaneWidth(A5),D1 tst.l _TypeOfMem(A5) ; Foreign display HW used to display image? beq.s .widthSetOk ; If so, addi.w #63,D1 ; otherwise care about the BURST-Fetch-mode andi.w #-64,D1 ; so we have to correct this value .widthSetOk tst.b _SuperBitMap(A5) ; Already dimension for a superbitmap? bne.s 1$ ; If so, skip next cmp.w D0,D1 ; Check for superbitmap slt.b _SuperBitMap(A5) ; Set flag when encountered 1$ tst.b _BlitFlag(A5) ; Already a brush encountered? bne.s .MustSet ; If so... cmp.w D0,D1 shi.b _BlitFlag(A5) ; Encountered now tst.b _BlitFlag(A5) ; Do we display a brush? bne.s .MustSet ; If so... bra.s .CheckDevice ; Normal fullscreen image either with a superbitmap or without .MustSet lea _NewScreen(A5),A0 move.w #NS_EXTENDED|CUSTOMSCREEN|SCREENQUIET,ns_Type(A0) ; No custom bitmap used when displaying brushes! .CheckDevice tst.l _TypeOfMem(A5) ; If the bitplanes have been forced to public memory * I assume that a 3rd party GFX software driver is installed, * this means we cannot use the system function to set the view * since AMIGA 3rd party GFX boards are originally from the PC * and PCs don't support overscan!!! beq.s .3rdParty bsr.w _SetView ; See there... (only for real AMIGA monitors/screens) bra.s .ScreenSet .3rdParty lea _NewScreen(A5),A0 move.w #NS_EXTENDED|CUSTOMSCREEN|SCREENQUIET,ns_Type(A0) ; No custom bitmap! clr.l ns_CustomBitMap(A0) tst.b _SuperBitMap(A5) ; Do we have a super bitmap? beq.s .ScreenSet lea _StdTags(A5),A0 ; Taglist for screen, SA_DisplayID already set move.l #SA_AutoScroll,8(A0) move.l #0,12(A0) ; FALSE move.l #SA_Type,16(A0) move.l #CUSTOMSCREEN,20(A0) move.l #SA_Width,24(A0) move.l _ImageWidth(A5),28(A0) ; How tall must be the screen's bitmap (without alignments) move.l #SA_Height,32(A0) clr.w 36(A0) ; Clear upper word of longword move.w _Height(A5),38(A0) clr.l 40(A0) ; TAG_DONE .ScreenSet lea _NewScreen(A5),A0 movea.l _IntuitionBase(A5),A6 jsr _LVOOpenScreen(A6) tst.l D0 bne.s .OkScreen ; Screen is open... lea _ErrorOpeningScreen(pc),A0 bsr.w _DisplayError bra.w 2$ .OkScreen move.l D0,D2 ; ScreenPtr movea.l D0,A0 lea sc_ViewPort(A0),A0 ; Get screen's viewport lea _Colourmap(A5),A1 ; Get screen's colourmap move.l _CMapNumEntries(A5),D0 ; Number of colours (max 256) movea.l _GfxBase(A5),A6 cmpi.w #38,LIB_VERSION(A6) bhi.s .set32Bit ; Running an AGA machine! jsr _LVOLoadRGB4(A6) ; Else use old colour-set function bra.s .ColoursSet .set32Bit tst.l _TypeOfMem(A5) bne.s .modifyCM32 * ** Following only for displays with more than 8 bitplanes * cmpi.b #8,_Depth(A5) bls.s .modifyCM32 move.l D2,-(sp) movea.l D2,A2 lea sc_ViewPort(A2),A0 moveq #0,D0 move.l D0,D1 move.l D0,D2 move.l D0,D3 jsr _LVOSetRGB32(A6) ; Colour zero of ViewPort to black lea sc_RastPort(A2),A1 moveq #0,D0 jsr _LVOSetAPen(A6) ; Use Rastport's pen zero lea sc_RastPort(A2),A1 moveq #0,D0 moveq #0,D1 move.w sc_Width(A2),D2 subq.w #1,D2 move.w sc_Height(A2),D3 subq.w #1,D3 jsr _LVORectFill(A6) ; Flood Screen with pen zero (black background) move.l (sp)+,D2 bra.s .ColoursSet .modifyCM32 lea _RGB32Colours(A5),A1 ; RGB32 Colourtable jsr _LVOLoadRGB32(A6) ; Load them .ColoursSet tst.l _TypeOfMem(A5) ; Since the most 3rd party GFX board drivers don't support beq.s .blit ; custom BitMaps we have to copy the bitplanes manually... tst.b _BlitFlag(A5) ; Do we have to blit an image to the screen? beq.w .noneedblit ; No... .blit movem.l D2-D7/A2,-(sp) .loop movea.l _IntuitionBase(A5),A6 move.l ib_FirstScreen(A6),D0 cmp.l D2,D0 beq.s .startblit movea.l _DOSBase(A5),A6 moveq #1,D1 jsr _LVODelay(A6) bra.s .loop .startblit tst.l _HAMSet(A5) bne.s .convertHAM lea _BitmapStruc(A5),A0 ; Image's bitmap cmpi.b #24,bm_Depth(A0) bne.s .check16bit movea.l D2,A1 ; Screen A1 lea sc_RastPort(A1),A1 bsr.w _PlanarBMtoRGB24 tst.l D0 bne.w .none bra.s .realstartblit .convertHAM tst.l _TypeOfMem(A5) ; HAM and no gfx-board? bne.s .realstartblit lea _BitmapStruc(A5),A0 ; Image's bitmap movea.l D2,A1 ; Screen A1 lea sc_RastPort(A1),A1 bsr.w _HAMtoRGB24 tst.l D0 bne.w .none .check16bit cmpi.b #8,bm_Depth(A0) bls.s .realstartblit cmpi.b #16,bm_Depth(A0) bhi.s .realstartblit movea.l D2,A1 ; Screen A1 lea sc_RastPort(A1),A1 bsr.w _CLUTtoRGB16 tst.l D0 bne.w .none .realstartblit lea _BitmapStruc(A5),A0 ; Image's bitmap movea.l D2,A1 ; Screen A1 movea.l A1,A2 lea sc_RastPort(A1),A1 ; Screen's RastPort movea.l rp_BitMap(A1),A1 moveq #0,D0 move.l D0,D1 moveq #0,D2 move.w sc_Width(A2),D2 ; Screen's dimensions lsr.w #1,D2 ; Half moveq #0,D7 move.l _RealIWidth(A5),D7 ; Image's width lsr.w #1,D7 ; Half sub.w D7,D2 ; == X-Offset for image move.w sc_Height(A2),D3 lsr.w #1,D3 ; Half move.w _Height(A5),D7 lsr.w #1,D7 ; Half sub.w D7,D3 ; Y-Offset for image move.l _RealIWidth(A5),D4 ; Image's width move.w _Height(A5),D5 ; Image's height * ** Because a blit must be friendly, we now check the bounds * tst.w D2 bpl.s .XOk moveq #0,D2 .XOk tst.w D3 bpl.s .YOk moveq #0,D3 .YOk move.w D4,D7 add.w D2,D7 cmp.w sc_Width(A2),D7 bls.s .WOk move.w sc_Width(A2),D7 addq.w #1,D7 move.w D4,D6 add.w D2,D6 sub.w D7,D6 sub.w D6,D4 .WOk move.w D5,D7 add.w D3,D7 cmp.w sc_Height(A2),D7 bls.s .doblit move.w sc_Height(A2),D7 addq.w #1,D7 move.w D5,D6 ; e.g. 832 add.w D3,D6 ; e.g. 0 sub.w D7,D6 ; 800 from 832 = 32 sub.w D6,D5 ; 832 - 32 = 800 .doblit move.b #$C0,D6 ; Minterm == blit all move.l #$FF,D7 ; Only byte treated... suba.l A2,A2 movem.l D0-D1/A0-A1,-(sp) movea.l _GfxBase(A5),A6 jsr _LVOWaitBlit(A6) movem.l (sp)+,D0-D1/A0-A1 jsr _LVOBltBitMap(A6) ; Blit the image to the display (only first 8 bitplanes... shit...) .none movem.l (sp)+,D2-D7/A2 .noneedblit movem.l D2-D7/A2-A4,-(sp) movea.l D2,A4 ; Screen lea sc_ViewPort(A4),A3 ; Screen's ViewPort movea.l vp_RasInfo(A3),A3 ; Screen's RasInfo move.w _PlaneWidth(A5),D2 ; Visible size (screen) move.w _PlaneHeight(A5),D3 ; Visible size (screen) move.l _RealIWidth(A5),D4 ; Whole size (bitmap) move.w _Height(A5),D5 ; Whole size (bitmap) move.w D2,D6 ; Current Width move.w D3,D7 ; Current Height .Wait clr.b _RIChanged(A5) ; Important tst.b _SuperBitMap(A5) ; Do we have a superbitmap? beq.w .PureWait ; No, wait only move.w sc_MouseX(A4),D0 ; Mouse-x-position on screen move.w sc_MouseY(A4),D1 ; Mouse-y-position on screen move.w $DFF016.l,_RMB(A5) ; Right mouse button state addq.w #1,D0 ; Important! addq.w #1,D1 ; Important! * ** When the mouse hits the limits of the screen, we scroll the bitmap ** to the direction where the mouse hits the screen limits, so we display ** the normally invisible parts. * .ScrollRight cmp.w D0,D2 ; MouseX + 1 same as screenwidth (not bitmap!) bhi.s .ScrollDown ; If not, mouse not at border... cmp.w D4,D6 ; Right border reached ? (max == current ?) bge.s .ScrollDown ; - then not at the border of the bitmap... st.b _RIChanged(A5) ; Else indicate: Must "Rethink Display" after this action btst #2,_RMB(A5) ; Right mouse button? beq.s .SR16 ; - then move faster... .SR1 addq.w #1,D6 ; One more pixel (right side) + 1 to display addq.w #1,ri_RxOffset(A3) ; Change offset so the hidden pixel can be displayed bra.s .ScrollDown ; Check for down scrolling .SR16 move.w D6,_Max(A5) ; RMB - maximum visible (_Max(A5) is only a dummy - * haven't got enought registers.... addi.w #16,_Max(A5) ; plus 16 pixels cmp.w _Max(A5),D4 ; In range? - does it fit? blt.s .SR1 ; If not... addi.w #16,D6 ; Else 16 pixels more to display addi.w #16,ri_RxOffset(A3) ; Change offset (X) so those hidden 16 pixels can * ; be displayed .ScrollDown cmp.w D1,D3 ; MouseY + 1 same as bottom of screen (not bitmap!) bhi.s .ScrollLeft ; If not, screen border not touched... cmp.w D5,D7 ; max == current ? bge.s .ScrollLeft st.b _RIChanged(A5) btst #2,_RMB(A5) beq.s .SD16 .SD1 addq.w #1,D7 addq.w #1,ri_RyOffset(A3) bra.s .ScrollLeft .SD16 move.w D7,_Max(A5) addi.w #16,_Max(A5) cmp.w _Max(A5),D5 blt.s .SD1 addi.w #16,D7 addi.w #16,ri_RyOffset(A3) .ScrollLeft tst.w sc_MouseX(A4) ; Top of screen touched with mouse? bne.s .ScrollUp cmp.w D2,D6 ; std == current ? bls.s .ScrollUp st.b _RIChanged(A5) btst #2,_RMB(A5) beq.s .SL16 .SL1 subq.w #1,D6 subq.w #1,ri_RxOffset(A3) bra.s .ScrollUp .SL16 move.w D6,_Max(A5) subi.w #16,_Max(A5) cmp.w _Max(A5),D2 bhi.s .SL1 subi.w #16,D6 subi.w #16,ri_RxOffset(A3) .ScrollUp tst.w sc_MouseY(A4) ; Left border touched with mouse? bne.s .Check cmp.w D3,D7 ; std == current ? bls.s .Check st.b _RIChanged(A5) btst #2,_RMB(A5) beq.s .SU16 .SU1 subq.w #1,D7 subq.w #1,ri_RyOffset(A3) bra.s .Check .SU16 move.w D7,_Max(A5) subi.w #16,_Max(A5) cmp.w _Max(A5),D3 bhi.s .SU1 subi.w #16,D7 subi.w #16,ri_RyOffset(A3) .Check tst.b _RIChanged(A5) ; RasInfo changed? beq.s .PureWait ; No, wait only tst.l _ViewPortShare(A5) ; Assumption: If we can share the ViewPort we bmi.s .mustblit ; can also change the RasInfo-offsets! * Called under OS1.x, 2.x and OS3.x when a native Amiga monitor is available. * CyberGraphX will also end here... movea.l _IntuitionBase(A5),A6 movea.l A4,A0 ; Screen jsr _LVOMakeScreen(A6) ; Move screen contents jsr _LVORethinkDisplay(A6) ; and make them visible bra.s .CheckLMB .mustblit ; This is only for alien gfx-board software packages... (Picasso96) movem.l D2-D7/A2,-(sp) ; » We have to blit the non visible part * into the display lea _BitmapStruc(A5),A0 ; Image's bitmap lea sc_RastPort(A4),A1 ; Screen's RastPort movea.l rp_BitMap(A1),A1 ; Screen's BitMap suba.l A2,A2 ; No Temp move.w D6,D0 ; Last displayable pixel X move.w D7,D1 ; Last displayable pixel Y moveq #0,D2 ; DestX moveq #0,D3 ; DestY move.w _PlaneWidth(A5),D4 ; Width move.w _PlaneHeight(A5),D5 ; Height sub.w D4,D0 ; = SrcX sub.w D5,D1 ; = SrcY move.b #$C0,D6 ; Cooky cut move.b #$FF,D7 ; All planes movem.l D0-D1/A0-A1,-(sp) movea.l _GfxBase(A5),A6 jsr _LVOWaitBlit(A6) movem.l (sp)+,D0-D1/A0-A1 jsr _LVOBltBitMap(A6) jsr _LVOWaitBlit(A6) movem.l (sp)+,D2-D7/A2 bra.s .CheckLMB .PureWait moveq #4,D1 ; Wait 4/50 or 4/60 seconds movea.l _DOSBase(A5),A6 jsr _LVODelay(A6) .CheckLMB btst #6,$BFE001 ; Left mouse button? bne.w .Wait movem.l (sp)+,D2-D7/A2-A4 movea.l D2,A0 ; Screen movea.l _IntuitionBase(A5),A6 jsr _LVOCloseScreen(A6) bsr.w _RestoreView ; See there 2$ tst.l _Bitplane(A5) ; Bitplane allocated? beq.s 3$ movea.l _Bitplane(A5),A1 move.l _AllPlaneSize(A5),D0 clr.l _AllPlaneSize(A5) clr.l _Bitplane(A5) movea.l _SysBase(A5),A6 jsr _LVOFreeMem(A6) ; Free bitplanes 3$ movea.l _IntuitionBase(A5),A6 movea.l _WindowPtr(A5),A0 jsr _LVOActivateWindow(A6) ; Activate our window addq.l #4,sp bra.w _LoadNew ; Display requester ************************************************************************ * ** Subroutines to set correct view for overscan pictures of ks lower v36. * _SetView movem.l D0-D1/A0-A1/A6,-(sp) movea.l _IntuitionBase(A5),A6 cmpi.w #35,LIB_VERSION(A6) ; Lower V36? bhi.s .OSOScanSet jsr _LVOViewAddress(A6) ; Get view movea.l D0,A0 move.w v_DyOffset(A0),_OldY(A5) ; Save old offset move.w v_DxOffset(A0),_OldX(A5) cmpi.w #320,_PlaneWidth(A5) ; Lower than 320? bls.s 1$ ; No overscan! cmpi.w #352,_PlaneWidth(A5) ; If it fits, we have bls.s 2$ ; an overscan-screen cmpi.w #640,_PlaneWidth(A5) ; Lower than 640? bls.s 1$ ; No overscan! bra.s 2$ ; Else we have an overscan-screen 1$ cmpi.w #256,_PlaneHeight(A5) ; Lower than 256? bls.s .NoOScan ; No overscan! cmpi.w #290,_PlaneHeight(A5) ; If it fits, we have bls.s 2$ ; an overscan-screen cmpi.w #512,_PlaneHeight(A5) ; Lower than 512? bls.s .NoOScan ; No overscan! 2$ ; We have an overscan screen! move.w #30,v_DyOffset(A0) ; Change dyOffset move.w #112,v_DxOffset(A0) ; Change dxOffset jsr _LVORethinkDisplay(A6) ; Make display .NoOScan movem.l (sp)+,D0-D1/A0-A1/A6 rts * Let the system do the work (up from OS2.0)... .OSOScanSet lea _StdTags(A5),A0 movea.l 4(A0),A0 ; MonitorID clr.l -(sp) ; Make room for rectangle - see gfx.i clr.l -(sp) movea.l sp,A1 ; Rectangle moveq #OSCAN_STANDARD,D0 ; The simply - may improve on your own... jsr _LVOQueryOverscan(A6) ; Give me informations... tst.l D0 ; Failed? beq.s .NoOScan movea.l sp,A0 ; Rectangle lea _NewScreen(A5),A1 move.w (A0),(A1) ; ( ra_MinX(A0),ns_LeftEdge(A1) ) move.w ra_MinY(A0),ns_TopEdge(A1) addq.l #8,sp bra.s .NoOScan ; Set... _RestoreView movem.l D0-D1/A0-A1/A6,-(sp) movea.l _IntuitionBase(A5),A6 cmpi.w #35,LIB_VERSION(A6) ; Ks 1.3 including Headly-Monitor? bhi.s .NotNeeded ; At least Kickstart 2.0 ßeta... jsr _LVOViewAddress(A6) ; Get old offsets movea.l D0,A0 move.w _OldY(A5),v_DyOffset(A0); Restore them move.w _OldX(A5),v_DxOffset(A0) jsr _LVORethinkDisplay(A6) .NotNeeded movem.l (sp)+,D0-D1/A0-A1/A6 rts ************************************************************************ * ** Running OS 1.x or the required mode is not available (up from OS 2.x) * * Video Overscan taken as limit to check against... * _DefaultMonitor moveq #0,D0 cmpi.w #362,_PlaneWidth(A5) ; Los-Res maximum? bhi.s .MinMedRes ; If taller, at least Med-Res bra.s .CheckILace .MinMedRes ori.w #V_HIRES,D0 ; Set Hires key .CheckILace cmpi.w #283,_PlaneHeight(A5) ; Maximum for PAL non-interlace bhi.s .ItsInterlace ; else we have to set interlace-bit bra.s .CheckNTSC .ItsInterlace ori.w #V_LACE,D0 ; Set LACE-key .CheckNTSC movea.l _GfxBase(A5),A6 move.w gb_DisplayFlags(A6),D1 btst #2,D1 ; PAL or NTSC ($4 means PAL)? bne.s .VMSet ; was PAL btst #2,D0 ; else NTSC - check for interlace ($4 means V_LACE) bne.s .VMSet ; Since already set cmpi.w #241,_PlaneHeight(A5) ; Maximum for NTSC non-lace bls.s .VMSet ori.w #V_LACE,D0 .VMSet move.l _ViewPortMod(A5),D1 btst #11,D1 ; HAM-Key? (HAM or HAM8?) beq.s .SetDim ; No HAM, else ori.w #V_HAM,D0 ; set HAM-Key .SetDim move.l D0,_ViewPortMod(A5) ; Save new ViewModes move.w gb_DisplayFlags(A6),D1 andi.w #V_HIRES,D0 bne.s .Hires cmpi.w #362,_PlaneWidth(A5) ; We have a Lores display bls.s .checkDimHeight move.w #362,_PlaneWidth(A5) bra.s .checkDimHeight .Hires cmpi.w #724,_PlaneWidth(A5) ; We have a Medres or Hires display bls.s .checkDimHeight move.w #724,_PlaneWidth(A5) .checkDimHeight move.l _ViewPortMod(A5),D0 andi.w #V_LACE,D0 ; Check for interlace bne.s .Interlace btst #2,D1 ; Check display against NTSC / PAL bne.s .noILacePAL cmpi.w #241,_PlaneHeight(A5) ; Non interlace NTSC display bls.s .done move.w #241,_PlaneHeight(A5) bra.s .done .noILacePAL cmpi.w #283,_PlaneHeight(A5) ; Non interlace PAL display bls.s .done move.w #283,_PlaneHeight(A5) bra.s .done .Interlace btst #2,D1 ; Check Display against NTSC / PAL bne.s .ILacePAL cmpi.w #482,_PlaneHeight(A5) ; Interlace NTSC display bls.s .done move.w #482,_PlaneHeight(A5) bra.s .done .ILacePAL cmpi.w #566,_PlaneHeight(A5) ; Interlace PAL display bls.s .done move.w #566,_PlaneHeight(A5) .done rts ************************************************************************* * ** Convert a AMIGA BitMap-Structure with 24 bitplanes to the RGB values a ** 3rd party gfx-board support. ** This routines needs a 68020 CPU. ** This routine has been designed as a hack (late after midnight) and so ** it looks really dirty. Sorry for that. * OPT P=68020 _PlanarBMtoRGB24 * A0 - bitmap, A1 Rastport movem.l D2-D7/A2-A6,-(sp) movea.l A0,A3 ; Bitmap movea.l A1,A2 ; RastPort tst.l _CyberGfxBase(A5) bne.s .start movea.l _SysBase(A5),A6 lea _CyberGfxName(pc),A1 moveq #40,D0 jsr _LVOOpenLibrary(A6) move.l D0,_CyberGfxBase(A5) beq.w .endall .start OPT OW- move.w bm_BytesPerRow(A3),D0 mulu.w #24,D0 move.l D0,D3 move.l D0,_RGB24Size(A5) move.l #MEMF_PUBLIC|MEMF_CLEAR,D1 movea.l _SysBase(A5),A6 jsr _LVOAllocMem(A6) move.l D0,_RGB24Ptr(A5) beq.w .endall OPT OW+ move.l _CyberGfxBase(A5),D1 move.l _ImageWidth(A5),D2 move.l A5,-(sp) lea -48(sp),sp ; Mixed buffer movea.l sp,A5 move.l D0,24(A5) ; Data buffer move.l D1,28(A5) ; CyberGfxBase move.l D2,32(A5) ; ImageWidth move.l A2,36(A5) ; RastPort move.l D3,44(A5) ; Size of one 24 bit RGB row movea.l D0,A4 ; RGB24 OPT OW- moveq #0,D3 ; Line moveq #0,D4 ; Bytes per row move.w bm_BytesPerRow(A3),D4 ; As it tells moveq #0,D7 ; Offset (X) in planar bitmap moveq #0,D6 ; Pixel per line OPT OW+ .nextpixel ; Read eight pixel (one byte) of each bitplane * moveq #23,D0 ; For 24 bit-planes * lea 8(A3),A0 ; 1st plane ptr * movea.l A5,A2 ; Mixed buffer *.getB * movea.l (A0)+,A1 * move.b 0(A1,D7.l),(A2)+ ; Read eight pixel (one byte) of each bitplane * subq.w #1,D0 * bcc.s .getB ; For 24 bitplanes * movem.l D3-D4/D6-D7/A3-A5,-(sp) * movea.l A5,A0 * movem.l (A0)+,D1-D6 * ** Replaces above, consider yourself what's faster. Read eight pixel (one byte) of each bitplane * movem.l D3-D4/D6-D7/A3-A5,-(sp) ; Replacement start OPT OW- lea bm_Planes(A3),A0 ; 1st plane ptr moveq #8,D0 move.b ([0,A0],D7.l),D1 ; Read 8 pixel of bit-plane 0 lsl.w D0,D1 move.b ([4,A0],D7.l),D1 ; Read 8 pixel of bit-plane 1 lsl.l D0,D1 move.b ([8,A0],D7.l),D1 ; Read 8 pixel of bit-plane 2 lsl.l D0,D1 move.b ([12,A0],D7.l),D1 ; Read 8 pixel of bit-plane 3 move.b ([16,A0],D7.l),D2 ; Read 8 pixel of bit-plane 4 lsl.w D0,D2 move.b ([20,A0],D7.l),D2 ; Read 8 pixel of bit-plane 5 lsl.l D0,D2 move.b ([24,A0],D7.l),D2 ; Read 8 pixel of bit-plane 6 lsl.l D0,D2 move.b ([28,A0],D7.l),D2 ; Read 8 pixel of bit-plane 7 move.b ([32,A0],D7.l),D3 ; Read 8 pixel of bit-plane 8 lsl.w D0,D3 move.b ([36,A0],D7.l),D3 ; Read 8 pixel of bit-plane 9 lsl.l D0,D3 move.b ([40,A0],D7.l),D3 ; Read 8 pixel of bit-plane 10 lsl.l D0,D3 move.b ([44,A0],D7.l),D3 ; Read 8 pixel of bit-plane 11 move.b ([48,A0],D7.l),D4 ; Read 8 pixel of bit-plane 12 lsl.w D0,D4 move.b ([52,A0],D7.l),D4 ; Read 8 pixel of bit-plane 13 lsl.l D0,D4 move.b ([56,A0],D7.l),D4 ; Read 8 pixel of bit-plane 14 lsl.l D0,D4 move.b ([60,A0],D7.l),D4 ; Read 8 pixel of bit-plane 15 move.b ([64,A0],D7.l),D5 ; Read 8 pixel of bit-plane 16 lsl.w D0,D5 move.b ([68,A0],D7.l),D5 ; Read 8 pixel of bit-plane 17 lsl.l D0,D5 move.b ([72,A0],D7.l),D5 ; Read 8 pixel of bit-plane 18 lsl.l D0,D5 move.b ([76,A0],D7.l),D5 ; Read 8 pixel of bit-plane 19 move.b ([80,A0],D7.l),D6 ; Read 8 pixel of bit-plane 20 lsl.w D0,D6 move.b ([84,A0],D7.l),D6 ; Read 8 pixel of bit-plane 21 lsl.l D0,D6 move.b ([88,A0],D7.l),D6 ; Read 8 pixel of bit-plane 22 lsl.l D0,D6 move.b ([92,A0],D7.l),D6 ; Read 8 pixel of bit-plane 23 OPT OW+ ; Replacement end * ** Registers (D1-D6) filled with 24 bytes each holding 8 pixel * .getColour movea.l A4,A0 ; RGB24 buffer move.l D1,A1 move.l D2,A2 move.l D3,A3 move.l D4,A4 move.l D5,A5 move.l D6,A6 move.l #$80808080,D0 and.l D0,D1 ; bit 0 of plane 0,1,2,3 and.l D0,D2 ; bit 0 of plane 4,5,6,7 and.l D0,D3 ; bit 0 of plane 8,9,10,11 and.l D0,D4 ; bit 0 of plane 12,13,14,15 and.l D0,D5 ; bit 0 of plane 16,17,18,19 and.l D0,D6 ; bit 0 of plane 20,21,22,23 moveq #-34,D0 ; See 'Counting ...' below for explain move.l D0,-(sp) .GetPixelColour * Get the red bits (8 per gun) (24 bit) * Original R0 pixel 0 bit 31 , R1 pixel 0 bit 23 , R2 pixel 0 bit 15, R3 pixel 0 bit 0 in D1.L move.b D1,D0 ; R3 pixel 0 in D0.b lsr.w #8,D1 ; Get R2 pixel 0 on byte position in D1.b lsr.b #4,D0 ; R3 pixel 0 on position 3 lsr.b #5,D1 ; R2 pixel 0 on position 2 or.b D0,D1 move.b D1,D7 ; Half lower nibble in D7 (bits 3 and 2) swap.w D1 ; Original R0 pixel 0, R1 pixel 0, R2 pixel 0, R3 pixel 0 in D1.L * R0 pixel 0 and R1 pixel 0 in D1.w move.b D1,D0 ; R1 pixel 0 in D0 lsr.w #8,D1 ; Get R0 pixel 0 on byte position lsr.b #6,D0 ; R1 pixel 0 on position 1 lsr.b #7,D1 ; R0 pixel 0 on position 0 or.b D0,D1 or.b D1,D7 ; R3 R2 R1 R0 * -------------------- * Original R4 pixel 0 bit 31 , R5 pixel 0 bit 23 , R6 pixel 0 bit 15, R7 pixel 0 bit 0 in D2.L move.b D2,D0 ; R7 pixel 0 in D0 lsr.w #8,D2 ; Get R6 pixel 0 on byte position * lsr.b #0,D0 ; R7 pixel 0 on position 7 lsr.b #1,D2 ; R6 pixel 0 on position 6 or.b D0,D2 or.b D2,D7 ; R7 R6 nn nn R3, R2, R1, R0 swap.w D2 ; Original R4 pixel 0, R5 pixel 0 in D2.L * R4 pixel 0, R5 pixel 0 in D2.w move.b D2,D0 ; R5 pixel 0 in D0 lsr.w #8,D2 ; Get R4 pixel 0 on byte position lsr.b #2,D0 ; R5 pixel 0 on position 5 lsr.b #3,D2 ; R4 pixel 0 on position 4 or.b D0,D2 or.b D2,D7 ; R0, R1, R2, R3, R4, R1 nn nn move.b D7,(A0)+ ; Store red value * ------------------------------------------------------------------- * Get the green bits (8 ber gun) (24 bit) move.b D3,D0 ; G3 pixel 0 in D0 lsr.w #8,D3 ; Get G2 pixel 0 on byte position lsr.b #4,D0 ; G3 pixel 0 on position 3 lsr.b #5,D3 ; G2 pixel 0 on position 2 or.b D0,D3 move.b D3,D7 ; nn nn nn nn G3 G2 nn nn swap.w D3 ; Original G0 pixel 0, G1 pixel 0, G2 pixel 0, G3 pixel 0 * now G0 pixel 0, G1 pixel 0 in D3.w move.b D3,D0 ; G1 pixel 0 in D0 lsr.w #8,D3 ; Get G0 pixel 0 on byte position lsr.b #6,D0 ; G1 pixel 0 on position 1 lsr.b #7,D3 ; G0 pixel 0 on position 0 or.b D0,D3 or.b D3,D7 ; nn nn nn nn G3 G2 G1 G0 * ------------------- move.b D4,D0 ; G7 pixel 0 in D0 lsr.w #8,D4 ; Get G6 pixel 0 on byte position * lsr.b #0,D0 ; G7 pixel 0 on position 7 lsr.b #1,D4 ; G6 pixel 0 on position 6 or.b D0,D4 or.b D4,D7 ; G7 G6 nn nn G3 G2 G1 G0 swap.w D4 ; Original G4 pixel 0, G5 pixel 0, G6 pixel 0, G7 pixel 0 * now G4 pixel 0, G5 pixel 0 in D4.w move.b D4,D0 ; G5 pixel 0 in D0 lsr.w #8,D4 ; Get G4 pixel 0 on byte position lsr.b #2,D0 ; G5 pixel 0 on position 5 lsr.b #3,D4 ; G4 pixel 0 on position 4 or.b D0,D4 or.b D4,D7 ; G7 G6 G5 G4 G3 G2 G1 G0 move.b D7,(A0)+ ; Store green value * ------------------------------------------------------------------- * Get the blue bits (8 ber gun) (24 bit) move.b D5,D0 ; B3 pixel 0 in D0 lsr.w #8,D5 ; Get B2 pixel 0 on byte position lsr.b #4,D0 ; B3 pixel 0 on position 3 lsr.b #5,D5 ; B2 pixel 0 on position 2 or.b D0,D5 move.b D5,D7 ; nn nn nn nn B3 B2 nn nn swap.w D5 ; Original B0 pixel 0, B1 pixel 0, B2 pixel 0, B3 pixel 0 * now B0 pixel 0, B1 pixel 0 in D5.w move.b D5,D0 ; B1 pixel 0 in D0 lsr.w #8,D5 ; Get B0 pixel 0 on byte position lsr.b #6,D0 ; B1 pixel 0 on position 1 lsr.b #7,D5 ; B0 pixel 0 on position 0 or.b D0,D5 or.b D5,D7 ; nn nn nn nn B3 B2 B1 B0 * ------------------- move.b D6,D0 ; B7 pixel 0 in D0 lsr.w #8,D6 ; Get B6 pixel 0 on byte position * lsr.b #0,D0 ; B7 pixel 0 on position 7 lsr.b #1,D6 ; B6 pixel 0 on position 6 or.b D0,D6 or.b D6,D7 ; B7 B6 nn nn B3 B2 B1 B0 swap.w D6 ; Original B4 pixel 0, B5 pixel 0, B6 pixel 0, B7 pixel 0 * now B4 pixel 0, B5 pixel 0 in D6.w move.b D6,D0 ; B5 pixel 0 in D0 lsr.w #8,D6 ; Get B4 pixel 0 on byte position lsr.b #2,D0 ; B5 pixel 0 on position 5 lsr.b #3,D6 ; B4 pixel 0 on position 4 or.b D0,D6 or.b D6,D7 ; B7 B6 B5 B4 B3 B2 B1 B0 move.b D7,(A0)+ ; Store blue value * ------------------------------------------------------------------- * Repeat GetPixelColour until a complete byte (8 pixel) is worked out... move.l (sp)+,D0 move.l A1,D1 move.l A2,D2 move.l A3,D3 move.l A4,D4 move.l A5,D5 move.l A6,D6 .thejump addi.l #36,D0 move.l D0,-(sp) jmp (pc,D0.w) ; An opcode for 32 bit CPUs only .mask1 ; Counting 2 :: (-34) = (+2 - +36 = -34) -> 1st offset to PC to reach this (.mask1) move.l #$40404040,D0 ; -- Each mask has got 15 instruction surrounded by 36 bytes code and.l D0,D1 ; bit 1 of plane 0,1,2,3 and.l D0,D2 ; bit 1 of plane 4,5,6,7 and.l D0,D3 ; bit 1 of plane 8,9,10,11 and.l D0,D4 ; bit 1 of plane 12,13,14,15 and.l D0,D5 ; bit 1 of plane 16,17,18,19 and.l D0,D6 ; bit 1 of plane 20,21,22,23 moveq #1,D0 lsl.l D0,D1 lsl.l D0,D2 lsl.l D0,D3 lsl.l D0,D4 lsl.l D0,D5 lsl.l D0,D6 bra.w .GetPixelColour .mask2 move.l #$20202020,D0 and.l D0,D1 ; bit 2 of plane 0,1,2,3 and.l D0,D2 ; bit 2 of plane 4,5,6,7 and.l D0,D3 ; bit 2 of plane 8,9,10,11 and.l D0,D4 ; bit 2 of plane 12,13,14,15 and.l D0,D5 ; bit 2 of plane 16,17,18,19 and.l D0,D6 ; bit 2 of plane 20,21,22,23 moveq #2,D0 lsl.l D0,D1 lsl.l D0,D2 lsl.l D0,D3 lsl.l D0,D4 lsl.l D0,D5 lsl.l D0,D6 bra.w .GetPixelColour .mask3 move.l #$10101010,D0 and.l D0,D1 ; bit 3 of plane 0,1,2,3 and.l D0,D2 ; bit 3 of plane 4,5,6,7 and.l D0,D3 ; bit 3 of plane 8,9,10,11 and.l D0,D4 ; bit 3 of plane 12,13,14,15 and.l D0,D5 ; bit 3 of plane 16,17,18,19 and.l D0,D6 ; bit 3 of plane 20,21,22,23 moveq #3,D0 lsl.l D0,D1 lsl.l D0,D2 lsl.l D0,D3 lsl.l D0,D4 lsl.l D0,D5 lsl.l D0,D6 bra.w .GetPixelColour .mask4 move.l #$08080808,D0 and.l D0,D1 ; bit 4 of plane 0,1,2,3 and.l D0,D2 ; bit 4 of plane 4,5,6,7 and.l D0,D3 ; bit 4 of plane 8,9,10,11 and.l D0,D4 ; bit 4 of plane 12,13,14,15 and.l D0,D5 ; bit 4 of plane 16,17,18,19 and.l D0,D6 ; bit 4 of plane 20,21,22,23 moveq #4,D0 lsl.l D0,D1 lsl.l D0,D2 lsl.l D0,D3 lsl.l D0,D4 lsl.l D0,D5 lsl.l D0,D6 bra.w .GetPixelColour .mask5 move.l #$04040404,D0 and.l D0,D1 ; bit 5 of plane 0,1,2,3 and.l D0,D2 ; bit 5 of plane 4,5,6,7 and.l D0,D3 ; bit 5 of plane 8,9,10,11 and.l D0,D4 ; bit 5 of plane 12,13,14,15 and.l D0,D5 ; bit 5 of plane 16,17,18,19 and.l D0,D6 ; bit 5 of plane 20,21,22,23 moveq #5,D0 lsl.l D0,D1 lsl.l D0,D2 lsl.l D0,D3 lsl.l D0,D4 lsl.l D0,D5 lsl.l D0,D6 bra.w .GetPixelColour .mask6 move.l #$02020202,D0 and.l D0,D1 ; bit 6 of plane 0,1,2,3 and.l D0,D2 ; bit 6 of plane 4,5,6,7 and.l D0,D3 ; bit 6 of plane 8,9,10,11 and.l D0,D4 ; bit 6 of plane 12,13,14,15 and.l D0,D5 ; bit 6 of plane 16,17,18,19 and.l D0,D6 ; bit 6 of plane 20,21,22,23 moveq #6,D0 lsl.l D0,D1 lsl.l D0,D2 lsl.l D0,D3 lsl.l D0,D4 lsl.l D0,D5 lsl.l D0,D6 bra.w .GetPixelColour .mask7 move.l #$01010101,D0 and.l D0,D1 ; bit 7 of plane 0,1,2,3 and.l D0,D2 ; bit 7 of plane 4,5,6,7 and.l D0,D3 ; bit 7 of plane 8,9,10,11 and.l D0,D4 ; bit 7 of plane 12,13,14,15 and.l D0,D5 ; bit 7 of plane 16,17,18,19 and.l D0,D6 ; bit 7 of plane 20,21,22,23 moveq #7,D0 lsl.l D0,D1 lsl.l D0,D2 lsl.l D0,D3 lsl.l D0,D4 lsl.l D0,D5 lsl.l D0,D6 bra.w .GetPixelColour .mask8 ; Does not exist!!! move.l (sp)+,D0 ; - so, continue... movem.l (sp)+,D3-D4/D6-D7/A3-A5 addq.l #1,D7 ; Worked out 8 pixel lea 24(A4),A4 ; Increase RGB24 buffer addq.w #1,D6 ; New byte (8 pixel) cmp.w D6,D4 ; End of line? bne.w .nextpixel ; If no new line movem.l D3-D4/D7,-(sp) * WritePixelArray( SrcRect [pointer to src datas A0] * SrcX X position D0 * SrcY Y position D1 * SrcMod bytes per row in source rectangle D2 * RastPort A1 * DestX D3 * DestY D4 * SizeX D5 * SizeY D6 * SrcFmt RECTFMT_RGB ) OPT OW- movea.l 24(A5),A0 ; Datas moveq #0,D0 moveq #0,D1 moveq #0,D2 move.l 44(A5),D2 movea.l 36(A5),A1 ; RastPort move.l D3,D4 ; DestY moveq #0,D3 ; DestX move.l 32(A5),D5 ; Width move.w #1,D6 ; Height moveq #RECTFMT_RGB,D7 movea.l 28(A5),A6 jsr _LVOWritePixelArray(A6) OPT OW+ movem.l (sp)+,D3-D4/D7 move.l 24(A5),A4 ; RGB24 buffer moveq #0,D6 ; New X position (starting at zero) addq.w #1,D3 ; Increase line number cmp.w bm_Rows(A3),D3 ; Already done for all lines? bne.w .nextpixel lea 48(sp),sp movea.l (sp)+,A5 move.l _RGB24Ptr(A5),A1 move.l _RGB24Size(A5),D0 movea.l _SysBase(A5),A6 jsr _LVOFreeMem(A6) moveq #-1,D0 .endall movem.l (sp)+,D2-D7/A2-A6 rts _PlanarBMtoRGB24end OPT P=68000 ***************************************************** * ** Same as above only for 6/8 bitplanes (HAM encoded) * OPT P=68020 _HAMtoRGB24 * A0 - bitmap, A1 Rastport movem.l D2-D7/A2-A6,-(sp) movea.l A0,A3 ; Bitmap movea.l A1,A2 ; RastPort tst.l _CyberGfxBase(A5) bne.s .start movea.l _SysBase(A5),A6 lea _CyberGfxName(pc),A1 moveq #40,D0 jsr _LVOOpenLibrary(A6) move.l D0,_CyberGfxBase(A5) beq.w .endall .start OPT OW- move.w bm_BytesPerRow(A3),D0 mulu.w #24,D0 move.l D0,D3 addq.l #8,D0 ; For one black RGB pixel (mem-allocation boundary = 8 - thus use 8 instead of 3) at left of image move.l D0,_RGB24Size(A5) move.l #MEMF_PUBLIC|MEMF_CLEAR,D1 movea.l _SysBase(A5),A6 jsr _LVOAllocMem(A6) move.l D0,_RGB24Ptr(A5) ; Buffer for RGB24 format beq.w .endall OPT OW+ move.l _CyberGfxBase(A5),D1 move.l _ImageWidth(A5),D2 lea _RGB32Colours(A5),A0 move.l A0,D4 addq.l #4,D4 ; Pointer to colours (RGB) for index 0 move.l _HAMSet(A5),D5 move.l A5,-(sp) lea -56(sp),sp ; Mixed buffer movea.l sp,A5 addq.l #8,D0 ; Ignore the black pixel move.l D0,24(A5) ; Data buffer move.l D1,28(A5) ; CyberGfxBase move.l D2,32(A5) ; ImageWidth move.l A2,36(A5) ; RastPort move.l D3,44(A5) ; Size of one 24 bit RGB row move.l D4,48(A5) ; RGB32Colours move.l D5,52(A5) ; HAM indicator (HAM6/HAM8) movea.l D0,A4 ; Data OPT OW- moveq #0,D3 ; Line moveq #0,D4 ; Bytes per row move.w bm_BytesPerRow(A3),D4 ; As it tells moveq #0,D5 ; Offset (X) in planar bitmap moveq #0,D6 ; Pixel per line OPT OW+ .nextpixel move.l 52(A5),D0 ; For `n´ bit-planes subq.w #1,D0 lea 8(A3),A0 ; 1st plane ptr movea.l A5,A2 ; Mixed buffer .getB movea.l (A0)+,A1 move.b 0(A1,D5.l),(A2)+ ; Read eight pixel (one byte) of each bitplane subq.w #1,D0 bcc.s .getB ; For `n´ bitplanes cmpi.l #7,52(A5) ; HAM6 ? bhi.s .doconvert clr.b (A2)+ ; HAM6 has got 2 bits less than HAM8 clr.b (A2)+ .doconvert movem.l D3-D6/A3-A5,-(sp) bsr.s .getC movem.l (sp)+,D3-D6/A3-A5 addq.l #1,D5 ; Worked out 8 pixel lea 24(A4),A4 ; Increase RGB24 buffer addq.w #1,D6 ; New byte (8 pixel) cmp.w D6,D4 ; End of line? bne.s .nextpixel ; If no new line movem.l D3-D5,-(sp) * WritePixelArray( SrcRect [pointer to src datas A0] * SrcX X position D0 * SrcY Y position D1 * SrcMod bytes per row in source rectangle D2 * RastPort A1 * DestX D3 * DestY D4 * SizeX D5 * SizeY D6 * SrcFmt RECTFMT_RGB ) OPT OW- movea.l 24(A5),A0 ; Datas moveq #0,D0 moveq #0,D1 moveq #0,D2 move.l 44(A5),D2 movea.l 36(A5),A1 ; RastPort move.l D3,D4 ; DestY moveq #0,D3 ; DestX move.l 32(A5),D5 ; Width move.w #1,D6 ; Height moveq #RECTFMT_RGB,D7 movea.l 28(A5),A6 jsr _LVOWritePixelArray(A6) OPT OW+ movem.l (sp)+,D3-D5 move.l 24(A5),A4 ; RGB24 buffer moveq #0,D6 ; New X position (starting at zero) addq.w #1,D3 ; Increase line number cmp.w bm_Rows(A3),D3 ; Already done for all lines? bne.s .nextpixel lea 56(sp),sp movea.l (sp)+,A5 move.l _RGB24Ptr(A5),A1 move.l _RGB24Size(A5),D0 movea.l _SysBase(A5),A6 jsr _LVOFreeMem(A6) moveq #-1,D0 .endall movem.l (sp)+,D2-D7/A2-A6 rts * ** Buffer filled with 24 bytes which hold 8 pixel * .getC movea.l A5,A0 ; Mixed buffer move.l (A0)+,D1 ; 4 bytes (plane0 pixel 0-7, plane1 pixel 0-7 and so on move.l (A0)+,D2 moveq #0,D3 movea.l A4,A0 ; RGB24 buffer movea.l 48(A5),A3 ; Index colour table move.l D1,A1 move.l D2,A2 move.l #$80808080,D0 and.l D0,D1 ; bit 0 of plane 0,1,2,3 and.l D0,D2 ; bit 0 of plane 4,5,6,7 moveq #-14,D0 ; See 'Counting ...' below for explantion move.l D0,-(sp) .GetPixelColour * Original D1 pixel-0 bit 0 , P1 pixel-0 0 bit 1, P2 pixel-0 bit 2, P3 pixel-0 bit 4 move.b D1,D0 ; P3 pixel 0 in D0.b lsr.w #8,D1 ; Get P2 pixel 0 on byte position in D1.b lsr.b #4,D0 ; P3 pixel 0 on position 3 lsr.b #5,D1 ; P2 pixel 0 on position 2 or.b D0,D1 move.b D1,D7 ; Half lower nibble in D7 (bits 3 and 2) swap.w D1 ; Original P2 pixel 0, P3 pixel 0, P0 pixel 0, P1 pixel 0 * P0 pixel 0 and P1 pixel 0 in D1.w move.b D1,D0 ; P1 pixel 0 in D0 lsr.w #8,D1 ; Get P1 pixel 0 on byte position lsr.b #6,D0 ; P1 pixel 0 on position 1 lsr.b #7,D1 ; P0 pixel 0 on position 0 or.b D0,D1 or.b D1,D7 ; P3 P2 P1 P0 * -------------------- * Original P4 pixel 0 bit 4, P5 pixel 0 bit 5 , P6 pixel 0 bit 6, P7 pixel 0 bit 7 move.b D2,D0 ; P7 pixel 0 in D0 lsr.w #8,D2 ; Get P6 pixel 0 on byte position * lsr.b #0,D0 ; P7 pixel 0 on position 7 lsr.b #1,D2 ; P6 pixel 0 on position 6 or.b D0,D2 or.b D2,D7 ; P7 P6 nn nn P3, P2, P1, P0 swap.w D2 ; Original P6 pixel 0, P7 pixel 0 * P6 pixel 0, P7 pixel 0 in D2.w move.b D2,D0 ; P4 pixel 0 in D0 lsr.w #8,D2 ; Get P5 pixel 0 on byte position lsr.b #2,D0 ; P4 pixel 0 on position 5 lsr.b #3,D2 ; P5 pixel 0 on position 4 or.b D0,D2 or.b D2,D7 ; P7, P6, P5, P4, P3, P2 P1 P0 cmpi.l #7,52(A5) ; HAMSet equal to HAM8? bhi.s .checkham8 cmpi.b #15,D7 ; Index = 15? (HAM6 used) bls.s .storeHAM6 ; If index lower or equal 15 store unmodified index bra.s .modifyHAM6 ; Else compute modified index .checkham8 cmpi.b #63,D7 ; Index = 63? (HAM8 used) bls.s .store ; If index lower or equal 63 store unmodified index .modify ; Modifiy new pixel by last stored move.b -3(A0),(A0)+ ; Get red and take over move.b -3(A0),(A0)+ ; Get green and take over move.b -3(A0),(A0)+ ; Get blue and take over move.w D7,D6 ; Index andi.w #63,D7 ; Without H(old)A(nd)M(odified) bits lsl.b #2,D7 ; 6-bit value to an 8 bit one andi.w #192,D6 ; Only H(old)A(nd)M(odified) bits lsr.w #6,D6 ; into lowest bit positions jmp (pc,D6.w*2) ; Calls one of the three `bra.s´ below bra.s .modifyblue bra.s .modifyred bra.s .modifygreen .modifyblue move.b D7,-1(A0) bra.s .repeat .modifygreen move.b D7,-2(A0) bra.s .repeat .modifyred move.b D7,-3(A0) bra.s .repeat .modifyHAM6 move.b -3(A0),(A0)+ ; Get red move.b -3(A0),(A0)+ ; Get green move.b -3(A0),(A0)+ ; Get blue move.w D7,D6 andi.w #15,D7 ; Without H(old)A(nd)M(odified) bits move.b D7,D5 ; Save result lsl.b #4,D5 ; Low nibble to high nibble or.b D5,D7 ; Make new value andi.w #48,D6 ; Only H(old)A(nd)M(odified) bits lsr.w #4,D6 ; into lowest bit positions jmp (pc,D6.w*2) bra.s .modifyblue bra.s .modifyred bra.s .modifygreen .storeHAM6 andi.w #15,D7 move.w D7,D3 ; INDEX to colour value lsl.w #3,D3 ; INDEX * 8 move.w D7,D4 lsl.w #2,D4 ; INDEX * 4 add.w D4,D3 ; == mulu 12 D3 (12 bytes per RGB gun used by OS3 structure) lea 0(A3,D3.w),A4 ; Colour values (longwords) move.b (A4),(A0)+ ; Get only most significant byte move.b 4(A4),(A0)+ ; the same... move.b 8(A4),(A0)+ ; and again bra.s .repeat .store andi.w #63,D7 move.w D7,D3 ; INDEX to colour value lsl.w #3,D3 ; INDEX * 8 move.w D7,D4 lsl.w #2,D4 ; INDEX * 4 add.w D4,D3 ; == mulu 12 D3 lea 0(A3,D3.w),A4 ; Colour values (longwords) move.b (A4),(A0)+ ; See above move.b 4(A4),(A0)+ move.b 8(A4),(A0)+ * Repeat GetPixelColour until a complete byte (8 pixel) is worked out... .repeat move.l (sp)+,D0 move.l A1,D1 move.l A2,D2 .thejump addi.l #20,D0 move.l D0,-(sp) jmp (pc,D0.w) ; Call one of the masks below depending on value in D0 .end move.l (sp)+,D0 ; Counting 2 rts ; Counting 4 .mask1 ; Counting 6 :: (-14) = (+6 - +20 = -14) -> 1st offset to PC to reach this (.mask1) move.l #$40404040,D0 ; -- Each mask has got 15 instruction surrounded by 20 bytes code and.l D0,D1 ; bit 1 of plane 0,1,2,3 and.l D0,D2 ; bit 1 of plane 4,5,6,7 moveq #1,D0 lsl.l D0,D1 lsl.l D0,D2 bra.w .GetPixelColour .mask2 ; 26 move.l #$20202020,D0 and.l D0,D1 ; bit 2 of plane 0,1,2,3 and.l D0,D2 ; bit 2 of plane 4,5,6,7 moveq #2,D0 lsl.l D0,D1 lsl.l D0,D2 bra.w .GetPixelColour .mask3 ; 46 move.l #$10101010,D0 and.l D0,D1 ; bit 3 of plane 0,1,2,3 and.l D0,D2 ; bit 3 of plane 4,5,6,7 moveq #3,D0 lsl.l D0,D1 lsl.l D0,D2 bra.w .GetPixelColour .mask4 ; 66 move.l #$08080808,D0 and.l D0,D1 ; bit 4 of plane 0,1,2,3 and.l D0,D2 ; bit 4 of plane 4,5,6,7 moveq #4,D0 lsl.l D0,D1 lsl.l D0,D2 bra.w .GetPixelColour .mask5 ; 86 move.l #$04040404,D0 and.l D0,D1 ; bit 5 of plane 0,1,2,3 and.l D0,D2 ; bit 5 of plane 4,5,6,7 moveq #5,D0 lsl.l D0,D1 lsl.l D0,D2 bra.w .GetPixelColour .mask6 move.l #$02020202,D0 and.l D0,D1 ; bit 6 of plane 0,1,2,3 and.l D0,D2 ; bit 6 of plane 4,5,6,7 moveq #6,D0 lsl.l D0,D1 lsl.l D0,D2 bra.w .GetPixelColour .mask7 move.l #$01010101,D0 and.l D0,D1 ; bit 7 of plane 0,1,2,3 and.l D0,D2 ; bit 7 of plane 4,5,6,7 moveq #7,D0 lsl.l D0,D1 lsl.l D0,D2 bra.w .GetPixelColour .mask8 ; Does not exists!!! bra.w .end _HAMtoRGB24end OPT P=68000 ***************************************************** * ** Same as above only for more than 9 and less than 17 bitplanes (not HAM) encoded * OPT P=68020 _CLUTtoRGB16 * A0 - bitmap, A1 Rastport movem.l D2-D7/A2-A6,-(sp) movea.l A0,A3 ; Bitmap movea.l A1,A2 ; RastPort tst.l _CyberGfxBase(A5) bne.s .start movea.l _SysBase(A5),A6 lea _CyberGfxName(pc),A1 moveq #40,D0 jsr _LVOOpenLibrary(A6) move.l D0,_CyberGfxBase(A5) beq.w .endall .start OPT OW- move.w bm_BytesPerRow(A3),D0 ; CLUT (9-16 bits) become to a RGB (24 bit) gun, which is written to a 16 bit display mulu.w #24,D0 move.l D0,D3 move.l D0,_RGB24Size(A5) move.l #MEMF_PUBLIC|MEMF_CLEAR,D1 movea.l _SysBase(A5),A6 jsr _LVOAllocMem(A6) move.l D0,_RGB24Ptr(A5) ; Buffer for RGB24 format beq.w .endall OPT OW+ move.l _CyberGfxBase(A5),D1 move.l _ImageWidth(A5),D2 move.l _RGB32Values(A5),D4 move.l A5,-(sp) lea -56(sp),sp ; Mixed buffer movea.l sp,A5 * move.l D0,24(A5) ; Data buffer * move.l D1,28(A5) ; CyberGfxBase * move.l D2,32(A5) ; ImageWidth * move.l A2,36(A5) ; RastPort * move.l D3,44(A5) ; Size of one 24 bit RGB row * move.l D4,48(A5) ; RGB32Values move.l D0,32(A5) ; Data buffer move.l D1,36(A5) ; CyberGfxBase move.l D2,40(A5) ; ImageWidth move.l A2,44(A5) ; RastPort move.l D3,48(A5) ; Size of one 24 bit RGB row move.l D4,52(A5) ; RGB32Values movea.l D0,A4 ; Data OPT OW- moveq #0,D3 ; Line moveq #0,D4 ; Bytes per row move.w bm_BytesPerRow(A3),D4 ; As it tells moveq #0,D5 ; Offset (X) in planar bitmap moveq #0,D6 ; Pixel per line OPT OW+ .nextpixel moveq #15,D0 ; For 16 bit-planes lea 8(A3),A0 ; 1st plane ptr movea.l A5,A2 ; Mixed buffer .getB move.l (A0)+,D1 bne.s .exists move.b D1,(A2)+ ; No data (e.g. 13 bitplanes and bitplane 14/15/16 encountered) bra.s .further .exists movea.l D1,A1 move.b 0(A1,D5.l),(A2)+ ; Read eight pixel (one byte) of each bitplane .further subq.w #1,D0 bcc.s .getB ; For `n´ bitplanes .doconvert movem.l D3-D6/A3-A5,-(sp) bsr.s .getC movem.l (sp)+,D3-D6/A3-A5 addq.l #1,D5 ; Worked out 8 pixel lea 24(A4),A4 ; Increase RGB24 buffer addq.w #1,D6 ; New byte (8 pixel) cmp.w D6,D4 ; End of line? bne.s .nextpixel ; If no new line movem.l D3-D5,-(sp) * WritePixelArray( SrcRect [pointer to src datas A0] * SrcX X position D0 * SrcY Y position D1 * SrcMod bytes per row in source rectangle D2 * RastPort A1 * DestX D3 * DestY D4 * SizeX D5 * SizeY D6 * SrcFmt RECTFMT_RGB ) OPT OW- movea.l 32(A5),A0 ; Datas moveq #0,D0 moveq #0,D1 moveq #0,D2 move.l 48(A5),D2 movea.l 44(A5),A1 ; RastPort move.l D3,D4 ; DestY moveq #0,D3 ; DestX move.l 40(A5),D5 ; Width move.w #1,D6 ; Height moveq #RECTFMT_RGB,D7 movea.l 36(A5),A6 jsr _LVOWritePixelArray(A6) OPT OW+ movem.l (sp)+,D3-D5 move.l 32(A5),A4 ; RGB24 buffer moveq #0,D6 ; New X position (starting at zero) addq.w #1,D3 ; Increase line number cmp.w bm_Rows(A3),D3 ; Already done for all lines? bne.s .nextpixel lea 56(sp),sp movea.l (sp)+,A5 move.l _RGB24Ptr(A5),A1 move.l _RGB24Size(A5),D0 movea.l _SysBase(A5),A6 jsr _LVOFreeMem(A6) moveq #-1,D0 .endall movem.l (sp)+,D2-D7/A2-A6 rts * ** Buffer filled with 24 bytes which hold 8 pixel * .getC movea.l A5,A0 ; Mixed buffer move.l 52(A5),A5 ; RGB32Values movem.l (A0)+,D1-D4 ; 8 bytes (plane0 pixel 0-15, plane1 pixel 0-15 and so on movea.l A4,A0 ; RGB24 buffer move.l D1,A1 move.l D2,A2 move.l D3,A3 move.l D4,A4 move.l #$80808080,D0 and.l D0,D1 ; bit 0 of plane 0,1,2,3 and.l D0,D2 ; bit 0 of plane 4,5,6,7 and.l D0,D3 ; bit 0 of plane 8,9,10,11 and.l D0,D4 ; bit 0 of plane 12,13,14,15 moveq #-22,D0 ; See 'Counting ...' below for explantion move.l D0,-(sp) .GetPixelColour moveq #0,D7 move.l D7,D5 * Original D1 pixel-0 bit 0 , P1 pixel-0 bit 1, P2 pixel-0 bit 2, P3 pixel-0 bit 4 move.b D1,D0 ; P3 pixel 0 in D0.b lsr.w #8,D1 ; Get P2 pixel 0 on byte position in D1.b lsr.b #4,D0 ; P3 pixel 0 on position 3 lsr.b #5,D1 ; P2 pixel 0 on position 2 or.b D0,D1 move.b D1,D7 ; Half lower nibble in D7 (bits 3 and 2) swap.w D1 ; Original P2 pixel 0, P3 pixel 0, P0 pixel 0, P1 pixel 0 * P0 pixel 0 and P1 pixel 0 in D1.w move.b D1,D0 ; P1 pixel 0 in D0 lsr.w #8,D1 ; Get P1 pixel 0 on byte position lsr.b #6,D0 ; P1 pixel 0 on position 1 lsr.b #7,D1 ; P0 pixel 0 on position 0 or.b D0,D1 or.b D1,D7 ; P3 P2 P1 P0 * -------------------- * Original P4 pixel 0 bit 4, P5 pixel 0 bit 5 , P6 pixel 0 bit 6, P7 pixel 0 bit 7 move.b D2,D0 ; P7 pixel 0 in D0 lsr.w #8,D2 ; Get P6 pixel 0 on byte position * lsr.b #0,D0 ; P7 pixel 0 on position 7 lsr.b #1,D2 ; P6 pixel 0 on position 6 or.b D0,D2 or.b D2,D7 ; P7 P6 nn nn P3, P2, P1, P0 swap.w D2 ; Original P6 pixel 0, P7 pixel 0 * P6 pixel 0, P7 pixel 0 in D2.w move.b D2,D0 ; P4 pixel 0 in D0 lsr.w #8,D2 ; Get P5 pixel 0 on byte position lsr.b #2,D0 ; P4 pixel 0 on position 5 lsr.b #3,D2 ; P5 pixel 0 on position 4 or.b D0,D2 or.b D2,D7 ; P7, P6, P5, P4, P3, P2 P1 P0 * -------------------- move.b D3,D0 ; P3 pixel 0 in D0.b lsr.w #8,D3 ; Get P2 pixel 0 on byte position in D1.b lsr.b #4,D0 ; P3 pixel 0 on position 3 lsr.b #5,D3 ; P2 pixel 0 on position 2 or.b D0,D3 move.b D3,D5 ; Half lower nibble in D7 (bits 3 and 2) swap.w D3 ; Original P2 pixel 0, P3 pixel 0, P0 pixel 0, P1 pixel 0 * P0 pixel 0 and P1 pixel 0 in D1.w move.b D3,D0 ; P1 pixel 0 in D0 lsr.w #8,D3 ; Get P1 pixel 0 on byte position lsr.b #6,D0 ; P1 pixel 0 on position 1 lsr.b #7,D3 ; P0 pixel 0 on position 0 or.b D0,D3 or.b D3,D5 ; P3 P2 P1 P0 * -------------------- * Original P4 pixel 0 bit 4, P5 pixel 0 bit 5 , P6 pixel 0 bit 6, P7 pixel 0 bit 7 move.b D4,D0 ; P7 pixel 0 in D0 lsr.w #8,D4 ; Get P6 pixel 0 on byte position * lsr.b #0,D0 ; P7 pixel 0 on position 7 lsr.b #1,D4 ; P6 pixel 0 on position 6 or.b D0,D4 or.b D4,D5 ; P7 P6 nn nn P3, P2, P1, P0 swap.w D4 ; Original P6 pixel 0, P7 pixel 0 * P6 pixel 0, P7 pixel 0 in D2.w move.b D4,D0 ; P4 pixel 0 in D0 lsr.w #8,D4 ; Get P5 pixel 0 on byte position lsr.b #2,D0 ; P4 pixel 0 on position 5 lsr.b #3,D4 ; P5 pixel 0 on position 4 or.b D0,D4 or.b D4,D5 ; P7, P6, P5, P4, P3, P2 P1 P0 lsl.w #8,D5 or.w D5,D7 .store move.w D7,D5 ; INDEX add.l D5,D5 ; Index * 2 add.l D5,D7 ; = Index * 3 move.b 0(A5,D7.l),(A0)+ ; Colour value R move.b 1(A5,D7.l),(A0)+ ; Colour value G move.b 2(A5,D7.l),(A0)+ ; Colour value B * Repeat GetPixelColour until a complete byte (8 pixel) is worked out... .repeat move.l (sp)+,D0 move.l A1,D1 move.l A2,D2 move.l A3,D3 move.l A4,D4 .thejump addi.l #28,D0 move.l D0,-(sp) jmp (pc,D0.w) ; Call one of the masks below depending on value in D0 .end move.l (sp)+,D0 ; Counting 2 rts ; Counting 4 .mask1 ; Counting 6 :: (-22) = (+6 - +28 = -22) -> 1st offset to PC to reach this (.mask1) move.l #$40404040,D0 ; -- Each mask has got 19 instruction surrounded by 28 bytes code and.l D0,D1 ; bit 1 of plane 0,1,2,3 and.l D0,D2 ; bit 1 of plane 4,5,6,7 and.l D0,D3 and.l D0,D4 moveq #1,D0 lsl.l D0,D1 lsl.l D0,D2 lsl.l D0,D3 lsl.l D0,D4 bra.w .GetPixelColour .mask2 ; 26 move.l #$20202020,D0 and.l D0,D1 ; bit 2 of plane 0,1,2,3 and.l D0,D2 ; bit 2 of plane 4,5,6,7 and.l D0,D3 ; bit 2 of plane 4,5,6,7 and.l D0,D4 ; bit 2 of plane 4,5,6,7 moveq #2,D0 lsl.l D0,D1 lsl.l D0,D2 lsl.l D0,D3 lsl.l D0,D4 bra.w .GetPixelColour .mask3 ; 46 move.l #$10101010,D0 and.l D0,D1 ; bit 3 of plane 0,1,2,3 and.l D0,D2 ; bit 3 of plane 4,5,6,7 and.l D0,D3 ; bit 3 of plane 4,5,6,7 and.l D0,D4 ; bit 3 of plane 4,5,6,7 moveq #3,D0 lsl.l D0,D1 lsl.l D0,D2 lsl.l D0,D3 lsl.l D0,D4 bra.w .GetPixelColour .mask4 ; 66 move.l #$08080808,D0 and.l D0,D1 ; bit 4 of plane 0,1,2,3 and.l D0,D2 ; bit 4 of plane 4,5,6,7 and.l D0,D3 ; bit 4 of plane 4,5,6,7 and.l D0,D4 ; bit 4 of plane 4,5,6,7 moveq #4,D0 lsl.l D0,D1 lsl.l D0,D2 lsl.l D0,D3 lsl.l D0,D4 bra.w .GetPixelColour .mask5 ; 86 move.l #$04040404,D0 and.l D0,D1 ; bit 5 of plane 0,1,2,3 and.l D0,D2 ; bit 5 of plane 4,5,6,7 and.l D0,D3 ; bit 5 of plane 4,5,6,7 and.l D0,D4 ; bit 5 of plane 4,5,6,7 moveq #5,D0 lsl.l D0,D1 lsl.l D0,D2 lsl.l D0,D3 lsl.l D0,D4 bra.w .GetPixelColour .mask6 move.l #$02020202,D0 and.l D0,D1 ; bit 6 of plane 0,1,2,3 and.l D0,D2 ; bit 6 of plane 4,5,6,7 and.l D0,D3 ; bit 6 of plane 4,5,6,7 and.l D0,D4 ; bit 6 of plane 4,5,6,7 moveq #6,D0 lsl.l D0,D1 lsl.l D0,D2 lsl.l D0,D3 lsl.l D0,D4 bra.w .GetPixelColour .mask7 move.l #$01010101,D0 and.l D0,D1 ; bit 7 of plane 0,1,2,3 and.l D0,D2 ; bit 7 of plane 4,5,6,7 and.l D0,D3 ; bit 7 of plane 4,5,6,7 and.l D0,D4 ; bit 7 of plane 4,5,6,7 moveq #7,D0 lsl.l D0,D1 lsl.l D0,D2 lsl.l D0,D3 lsl.l D0,D4 bra.w .GetPixelColour .mask8 ; Does not exists!!! bra.w .end _CLUT16oRGB16end OPT P=68000 *********************************** * ONIX 02.10.'91 * * MakeCounteven * * Inputs: D0 - value * Results: D0 - value * _MakeCountEven addq.l #7,D0 andi.l #-8,D0 rts ******************************** * * Filter ANSI-escape code. * * Inputs: none * Results: none * _IgnoreSettings movea.l _TextPtr(A5),A0 ; Address file in memory addq.l #2,A0 ; Overread #$200A move.l _FileSize(A5),D0 ; Length of this file moveq #0,D1 ; Amount lines 1$ subq.l #1,D0 ; Length -1 bmi.s .done cmpi.b #10,(A0)+ ; LineFeed? beq.s 6$ ; If so... cmpi.b #12,-1(A0) ; ANSI-sequence? beq.s 5$ ; If so... cmpi.b #13,-1(A0) ; LineFeed? beq.s 5$ ; If not... 2$ cmpi.b #31,-1(A0) bhi.s 1$ cmpi.b #27,-1(A0) beq.s 1$ cmpi.b #8,-1(A0) bls.s 3$ bra.s 1$ 3$ move.b #' ',-1(A0) bra.s 1$ .done move.l D1,_LinesInFile(A5) ; Lines in file bra.s _SetTitle 5$ move.b #10,-1(A0) ; LineFeed instead of ANSI! 6$ addq.l #1,D1 bra.s 1$ ************************************ * * Make title for main-window * * Inputs: none * Results: none * _SetTitle move.l A2,-(sp) lea _WindowTitle(A5),A2 ; Address buffer lea _FIB(A5),A0 ; Address FileInfoBlock addq.l #8,A0 ; Get the name of the file 1$ move.b (A0)+,(A2)+ ; Copy the file's name tst.b (A0) bne.s 1$ move.b #' ',(A2)+ ; Write Blank move.b #'(',(A2)+ movea.l A2,A0 ; Address buffer move.l _LinesInFile(A5),D0 ; Number of lines in file bsr.w _comdec ; Convert count into ascii move.b #' ',(A0)+ ; Write String ' Lines) Current line: ' move.b #'L',(A0)+ move.b #'i',(A0)+ move.b #'n',(A0)+ move.b #'e',(A0)+ move.b #'s',(A0)+ move.b #')',(A0)+ move.b #' ',(A0)+ move.b #' ',(A0)+ move.b #'C',(A0)+ move.b #'u',(A0)+ move.b #'r',(A0)+ move.b #'r',(A0)+ move.b #'e',(A0)+ move.b #'n',(A0)+ move.b #'t',(A0)+ move.b #' ',(A0)+ move.b #'l',(A0)+ move.b #'i',(A0)+ move.b #'n',(A0)+ move.b #'e',(A0)+ move.b #':',(A0)+ move.b #' ',(A0)+ move.l A0,_PtrToWTitle(A5) ; Remember current buffer address movea.l _IntuitionBase(A5),A6 movea.l _WindowPtr(A5),A0 lea _WindowTitle(A5),A1 ; Address new window title lea _WindowName(pc),A2 ; Address new screen title jsr _LVOSetWindowTitles(A6) ; Set window and screen title movea.l (sp)+,A2 rts _ComLine tst.l _TextPtr(A5) ; File in memory? beq.w 2$ ; No... tst.b _AudGadget(A5) ; We make a sound audible, thus no text and lines! bne.w 2$ move.l A2,-(sp) movea.l _PtrToWTitle(A5),A0 ; Save current buffer address for later move.l _Line(A5),D0 ; Current line bsr.w _comdec move.b #' ',(A0)+ ; Write blanks... move.b #' ',(A0)+ move.b #' ',(A0)+ move.b #' ',(A0)+ move.b #' ',(A0)+ move.b #' ',(A0)+ move.b #' ',(A0)+ clr.b (A0) ; End of window-title movea.l _GfxBase(A5),A6 movea.l _WindowPtr(A5),A0 movea.l wd_BorderRPort(A0),A2 ; RastPort move.w _BgPen(A5),D0 ; Backgroundcolour of window's titel bar movea.l A2,A1 jsr _LVOSetBPen(A6) moveq #1,D0 ; Foregroundcolour movea.l A2,A1 jsr _LVOSetAPen(A6) movea.l rp_BitMap(A2),A0 ; Bitmap for the title cmpi.b #1,bm_Depth(A0) ; Only one bitplane used? bne.s .normal ; No, more. moveq #0,D0 ; Because of the inversed title bar movea.l A2,A1 jsr _LVOSetAPen(A6) .normal move.b #RP_JAM2,D0 movea.l A2,A1 jsr _LVOSetDrMd(A6) moveq #30,D0 ; X moveq #1,D1 ; Y movea.l A2,A1 add.w 62(A2),D1 ; TxBaseLine jsr _LVOMove(A6) lea _WindowTitle(A5),A0 moveq #-1,D0 1$ tst.b (A0)+ dbeq D0,1$ not.l D0 lea _WindowTitle(A5),A0 movea.l A2,A1 jsr _LVOText(A6) movea.l (sp)+,A2 2$ rts ********************************************** * * Size window to maximum "!?!?|?" . * * Inputs: none * Results: none * _EnlargeWindow movem.l D0-D3/A0-A2/A6,-(sp) movea.l _IntuitionBase(A5),A6 movea.l _WindowPtr(A5),A0 movea.l A0,A2 lea _WindowRecord(A5),A1 move.w wd_LeftEdge(A0),D0 move.w wd_TopEdge(A0),D1 neg.w D0 ; Place it to 0, neg.w D1 ; 0 add.w (A1),D0 ; leftEdge add.w nw_TopEdge(A1),D1 ; topEdge jsr _LVOMoveWindow(A6) ; Move window to 0,0 or to user specified X- and Y-position bsr.s 1$ ; Wait for intuition timer tick movea.l A2,A0 ; Intuition-Engage-Window-Record move.w wd_Width(A0),D2 ; Current window-width move.w wd_Height(A0),D3 ; Current window-height lea _WindowRecord(A5),A1 ; Address window-record move.w nw_Width(A1),D0 ; User's width move.w nw_Height(A1),D1 ; Users's height sub.w D2,D0 ; Substract sub.w D3,D1 jsr _LVOSizeWindow(A6) ; Enlarge? window movem.l (sp)+,D0-D3/A0-A2/A6 bsr.s 1$ ; Wait bsr.w _SetPageWidthAndLen bsr.w _RestoreCurrentPage bra.w _Loop 1$ movem.l D0-D3/A0-A3/A6,-(sp) moveq #6,D1 ; 6/60 seconds = 1/10 second == int. timer tick movea.l _DOSBase(A5),A6 jsr _LVODelay(A6) movem.l (sp)+,D0-D3/A0-A3/A6 rts ******************************************************************* * * Format text, display that text in a window, get Gadget-status and * return. * * Inputs: Stack - reverse arguments on stack * Results: D0 = NULL = FALSE , D0 ~NULL = OK * IFD __G2 OPT OW- ; Devpac: Don't display optimisation warnings ENDC _FmtDisplay STRUCTURE printfBuf,0 STRUCT _Cnt,4 ; Counter for number of chars STRUCT _Buffer,512 ; Room for max. 511 chars LABEL _Args ; Dynamic wide LABEL _pfbso .printf movem.l D2-D6/A2-A3,-(sp) movea.l 32(sp),A0 ; Pointer to the string which should be formatted moveq #-1,D1 ; Dummy-counter moveq #0,D0 ; Counter for arguments 0$ cmpi.b #'%',(A0) ; Argument? bne.s .NoArg ; No... addq.w #1,D0 ; Argument +1 .NoArg tst.b (A0)+ ; End of string? dbeq D1,0$ ; If not lsl.l #2,D0 ; * 4 == longwords addi.l #_pfbso,D0 ; 4 bytes count, plus buffer addq.l #7,D0 andi.l #-8,D0 ; Align size move.l D0,D5 ; Save size move.l #MEMF_PUBLIC|MEMF_CLEAR,D1 movea.l _SysBase(A5),A6 jsr _LVOAllocMem(A6) move.l D0,D4 ; Address table beq.s 3$ ; Upon error movea.l 32(sp),A0 ; Pointer to string lea 36(sp),A1 ; Pointer to 1. argument movea.l D4,A2 ; Address table lea _Args(A2),A2 ; Address arguments-buffer (up from 516) moveq #-1,D1 ; Dummy-counter bra.s 1$ * -- ############# -- * .skip addq.l #2,A0 ; Overread both %-chars subq.w #2,D1 ; 2 chars less in text bmi.s 3$ ; Upon error * --- Here we start! --- * 1$ cmpi.b #'%',(A0) ; Argument? bne.s 2$ ; No cmpi.b #'%',1(A0) ; or only to display %-char? beq.s .skip ; If so, overread both %-chars addq.l #1,A0 ; Else only one %-char subq.w #1,D1 ; Counter -1 .getType cmpi.b #'b',(A0) ; Argument = BCPL? beq.s .typeFound ; If so cmpi.b #'d',(A0) ; Decimal? beq.s .typeFound.1 cmpi.b #'x',(A0) ; Sedicimal? beq.s .typeFound.1 cmpi.b #'s',(A0) ; String? beq.s .typeFound cmpi.b #'c',(A0) ; One char? beq.s .typeFound.1 * ** Because an argument can look like this: '%-08ld' we only search for the ** valid description of the argument, here 'd' in a loop. * tst.b (A0)+ ; Search further dbeq D1,.getType bra.s 3$ ; Upon error, string without end of argument .typeFound.1 cmpi.b #'l',-1(A0) ; Longword? beq.s .typeFound ; then the other routine move.l (A1),D0 ; Get argument (ever longword) move.w D0,(A2)+ ; write down for Exec only a word addq.l #4,A1 ; Pointer to following argument bra.s 2$ ; and do it normal .typeFound move.l (A1),(A2)+ ; Argument-contents into buffer addq.l #4,A1 ; see above 2$ tst.b (A0)+ ; Search for NULL-byte dbeq D1,1$ bra.s .FmtString ; == End of string, now format string 3$ moveq #0,D6 ; Return error .printf_end tst.l D4 ; Address table? beq.s 4$ movea.l D4,A1 ; Address table move.l D5,D0 ; Size table movea.l _SysBase(A5),A6 jsr _LVOFreeMem(A6) ; Free table 4$ move.l D6,D0 movem.l (sp)+,D2-D6/A2-A3 rts .FmtString movea.l 32(sp),A0 ; Pointer to unformatted string movea.l D4,A3 ; Address table lea _Args(A3),A1 ; Address arguments-buffer lea .Hook(pc),A2 ; Call-Back-Routine * movea.l A3,A3 ; Address table already in A3 movea.l _SysBase(A5),A6 ; Base Exec jsr _LVORawDoFmt(A6) ; Format the string movea.l D4,A1 lea _Buffer(A1),A0 ; Address formatted text in buffer move.l _Cnt(A1),D0 ; Size of text beq.s .okEnd ; If zero bsr.s _DisplayError ; else print text to window move.l D0,D6 .okEnd bra.s .printf_end .Hook * D0 == char, returned by RawDoFmt() * A3 == Pointer to table, returned by RawDoFmt() movem.l D1/A0,-(sp) lea _Buffer(A3),A0 ; Buffer for formatted text move.l _Cnt(A3),D1 ; Number of chars that are in buffer move.b D0,0(A0,D1.w) ; Store current addq.l #1,_Cnt(A3) ; Counter plus 1 cmpi.l #510,D1 ; 511 chars in buffer? bls.s .ok ; If ok. subq.l #1,_Cnt(A3) ; One too far clr.b 0(A0,D1.w) ; Clear byte .ok movem.l (sp)+,D1/A0 rts IFD __G2 OPT OW+ ENDC ****************************************************************** * * Open in the middle of a screen a window where we will display * a text. * * * Inputs: A0 - text * Results: D0 - NULL == ABORT, else OK _DisplayError movem.l D1-D4/A0-A4,-(sp) movea.l A0,A4 ; Save text for later lea _ErrWindowStruc(A5),A0 tst.l _ScreenPtr(A5) bne.s .GotScreen movea.l _IntuitionBase(A5),A1 movea.l ib_ActiveScreen(A1),A1 .GotScreen movea.l _ScreenPtr(A5),A1 move.l A1,nw_Screen(A0) ; ScreenPtr->WindowRecord * Center window on screen. move.w sc_Width(A1),D0 ; Width of screen subi.w #320,D0 ; Width of ErrorWindow lsr.w #1,D0 ; Half move.w D0,(A0) ; == leftEdge move.w sc_Height(A1),D0 ; Height of screen subi.w #100,D0 ; Height of ErrorWindow lsr.w #1,D0 ; Half move.w D0,nw_TopEdge(A0) ; == topEdge * Open the window. clr.l nw_FirstGadget(A0) movea.l _IntuitionBase(A5),A6 jsr _LVOOpenWindow(A6) move.l D0,_ErrWindowPtr(A5) beq.w .NoErrWindow ; Upon error movea.l D0,A0 ; Window movea.l wd_RPort(A0),A3 ; ^RastPortPtr bsr.w _InitGadgets ; Init gadgets lea _Gad1(A5),A1 ; First gadget moveq #0,D0 ; Begin with number zero moveq #-1,D1 ; All gadgets moveq #0,D2 movea.l D2,A2 ; No requester jsr _LVOAddGList(A6) ; Set gadgets to window lea _Gad1(A5),A0 ; Gadgets movea.l _ErrWindowPtr(A5),A1 ; Window moveq #0,D2 movea.l D2,A2 ; No requester jsr _LVORefreshGList(A6) ; Draw gadgets * Set pens. moveq #1,D0 ; 1. foregroundcolour movea.l A3,A1 ; RastPort movea.l _GfxBase(A5),A6 jsr _LVOSetAPen(A6) ; Set text-pen * Fill background of window with 1. foreground colour. movea.l _ErrWindowPtr(A5),A0 movea.l A3,A1 ; RastPort move.w #0,D0 ; leftEdge move.w #0,D1 ; topEdge move.w #319,D2 ; width move.w #79,D3 ; height moveq #0,D4 move.b wd_BorderLeft(A0),D4 add.w D4,D0 addq.w #1,D0 move.b wd_BorderRight(A0),D4 sub.w D4,D2 subq.w #1,D2 move.b wd_BorderTop(A0),D4 add.w D4,D1 addq.w #1,D1 move.b wd_BorderBottom(A0),D4 sub.w D4,D3 subq.w #1,D3 movem.l D0/D2,-(sp) ; Save coordinates jsr _LVORectFill(A6) ; Draw rectangle move.w #2,D0 ; 2. Foregroundcolour movea.l A3,A1 ; RastPort jsr _LVOSetAPen(A6) ; Set text-pen movea.l A3,A1 ; RastPort move.w #RP_JAM1,D0 jsr _LVOSetDrMd(A6) movem.l (sp)+,D0/D2 ; Get coordinates * D0 contains X-Offset moveq #76,D1 ; Y-Offset movea.l A3,A1 jsr _LVOMove(A6) move.l D2,D0 ; D2 == X-Offset - to D0 moveq #76,D1 ; Y-Offset movea.l A3,A1 jsr _LVODraw(A6) moveq #0,D0 ; X-, Y-offsets = 0 move.l D0,D1 move.b (A4)+,D1 ; Y-Offset out of text movea.l A3,A1 ; RastPortPtr jsr _LVOMove(A6) ; Set Gfx-cursor move.l A4,-(sp) ; Text moveq #0,D0 move.w rp_TxHeight(A3),D0 addq.w #2,D0 ; Spacing sub.w rp_TxBaseline(A3),D0 move.l D0,-(sp) move.l _ErrWindowPtr(A5),-(sp) ; Window bsr.w _CenterPage ; CenterText (struct Window *, ULONG Spacing, char *) lea 12(sp),sp ; Restore stack .Wait movea.l _ErrWindowPtr(A5),A0 ; WindowPointer movea.l wd_UserPort(A0),A0 ; MsgPort movea.l A0,A3 ; save it movea.l _SysBase(A5),A6 jsr _LVOWaitPort(A6) ; Sleep movea.l A3,A0 ; MsgPort jsr _LVOGetMsg(A6) ; Get the message tst.l D0 beq.s .Wait movea.l D0,A1 ; into A1 movea.l A1,A2 move.l im_Class(A2),D2 move.w im_Code(A2),D3 swap D3 move.w im_Qualifier(A2),D3 jsr _LVOReplyMsg(A6) cmpi.l #$40,D2 ; GadgetUp? beq.s .Gadget btst.l #6,D3 ; Left AMIGA (Commodore) key? beq.s .Wait ; If not... swap D3 cmpi.b #53,D3 beq.s .KeyB cmpi.b #52,D3 beq.s .KeyV bra.s .Wait .KeyB moveq #0,D3 bra.s .EndDisplayError .KeyV moveq #1,D3 bra.s .EndDisplayError .Gadget tst.l im_IAddress(A2) beq.s .Wait ; No gadget? movea.l im_IAddress(A2),A0 ; Get gadget's address move.w gg_GadgetID(A0),D3 ; Get my ID .EndDisplayError movea.l _ErrWindowPtr(A5),A0 movea.l _IntuitionBase(A5),A6 jsr _LVOCloseWindow(A6) move.w D3,D0 ; im_Code (gadget's ID) cmpi.w #1,D0 ; Left gadget (OK) ? beq.s .NoErrWindow ; If so... moveq #0,D0 ; It was the right one .NoErrWindow movem.l (sp)+,D1-D4/A0-A4 rts * * void CenterPage( struct Window *Window, ULONG Spacing, STRPTR TextPage ); * _CenterPage movem.l D2-D3/A2-A3,-(sp) movea.l _GfxBase(A5),A6 movea.l 20(sp),A0 ; Window movea.l 50(A0),A3 ; RastPort moveq #0,D3 move.l 24(A0),D0 ; Window flags btst.l #10,D0 ; gimme zero zero ? bne.s 0$ ; if gzz move.w 8(A0),D3 ; Window-width lsr.w #1,D3 ; == half window width bra.s 1$ 0$ move.w 112(A0),D3 ; gzzWidth lsr.w #1,D3 ; == half window width 1$ movea.l 28(sp),A2 ; Text 2$ movea.l A2,A0 moveq #-1,D2 ; Counter 3$ tst.b (A0) ; End? beq.s 4$ cmpi.b #10,(A0)+ ; Search for line-end dbeq D2,3$ move.l A0,-(sp) ; Save pointer to next line not.l D2 ; Compute length move.l D2,D0 ; Length in number of chars movea.l A3,A1 ; RastPort movea.l A2,A0 ; Text jsr _LVOTextLength(A6) move.l D0,D1 ; Length in pixels lsr.w #1,D1 ; == half length move.l D3,D0 ; Half window-width sub.w D1,D0 ; minus half text-width == X-offset for 1. char move.w 38(A3),D1 ; Current Y add.w 62(A3),D1 ; plus rp_TxBaseline movea.l A3,A1 ; RastPort jsr _LVOMove(A6) movea.l (sp)+,A0 ; Get pointer to next line exg.l A0,A2 ; A0 == now old position, A2 new position of text move.l D2,D0 ; TextLength in number of chars movea.l A3,A1 ; RastPort jsr _LVOText(A6) move.w 38(A3),D1 ; Current Y-Offset move.l 24(sp),D0 ; Spacing (user's Y-offset) add.w D0,D1 ; Next line offset (Y) move.w 36(A3),D0 ; Current X-Offset movea.l A3,A1 ; RastPort jsr _LVOMove(A6) bra.s 2$ 4$ movem.l (sp)+,D2-D3/A2-A3 rts *************************************** * * Convert long-value into ascii-string. * * Inputs: D0 - value (ulong), A0 - buffer * Result: none * _comdec movem.l D2/A2,-(sp) move.l D0,D2 lea _Divutable(pc),A2 movea.l A0,A1 moveq #9,D0 1$ moveq #48,D1 2$ addq.b #1,D1 sub.l (A2),D2 bcc.s 2$ subq.b #1,D1 add.l (A2)+,D2 cmpi.b #'0',D1 bne.s 3$ cmpi.b #0,D0 beq.s 3$ cmpa.l A1,A0 bne.s 3$ dbf D0,1$ 3$ move.b D1,(A0)+ 4$ dbf D0,1$ clr.b (A0) movem.l (sp)+,D2/A2 rts ************************************************************* * * Print file to ???. * * Inputs: D0 - length datas, A0 - filename, A1 - startaddress * Results: none * Note: The datas are not stored in once to the device (PRT:/DFx:) * because when a disk-error occurs, we get the chance to terminate * saving/printing earlier, which in fact will not destroy the whole * disk as it is possible under OS1.x . _PrintFile movem.l D2-D5/A2,-(sp) move.l D0,D5 ; Save length movea.l A1,A2 ; Save address datas move.l A0,D1 ; Name move.l #MODE_NEWFILE,D2 ; Mode: New movea.l _DOSBase(A5),A6 jsr _LVOOpen(A6) move.l D0,D4 ; FileHandle beq.s .PrintOpenError 3$ subi.l #4096,D5 ; Length -4096 bytes bcs.s 1$ ; If there aren't at least 4096 chars to store move.l #4096,D3 ; Number of chars to write: 4096 bra.s 2$ ; Go and write these chars... 1$ addi.l #4096,D5 ; Add these - now D5 contains again the rest to store move.l D5,D3 ; Number of chars to store moveq #0,D5 ; Indicates: no chars anymore for next loop 2$ move.l D4,D1 ; FileHandle move.l A2,D2 ; Address jsr _LVOWrite(A6) tst.l D0 bmi.s .WriteError lea 4096(A2),A2 ; Increase address by 4096 bytes tst.l D5 ; Rest there? bne.s 3$ ; If there... move.l D4,D1 ; FileHandle jsr _LVOClose(A6) ; Close file/prt: or something like that .PrintFileEnd movem.l (sp)+,D2-D5/A2 rts .PrintOpenError jsr _LVOIoErr(A6) bsr.w _SetError lea _OpenPrintErrTxt(pc),A0 bsr.w _DisplayError bra.s .PrintFileEnd .WriteError movea.l _DOSBase(A5),A6 ; - Because of a bug in DOS v39 * we have to restore DOSBase.... jsr _LVOIoErr(A6) bsr.w _SetError move.l D4,D1 jsr _LVOClose(A6) lea _WriteErrTxt(pc),A0 bsr.w _DisplayError bra.s .PrintFileEnd ************************ * * Erase window contents. * * Inputs: none * Results: none * _ClearWindow lea _ConBuffer(A5),A0 move.l #$9B489B4A,(A0) ; Cursor Home & erase to end of display moveq #4,D0 bra.w _ConOut_Rel ***************************************************************** * * Search for overgiven string.... * * Will use the console.device as input stream and also for output. * Searching is done only forward and also case insensitive. * _SearchSequence movem.l D2-D4/A2-A4,-(sp) move.l #$200,D0 movea.l _WindowPtr(A5),A0 movea.l _IntuitionBase(A5),A6 jsr _LVOModifyIDCMP(A6) bsr.s _ClearWindow tst.l _TextPtr(A5) beq.s .end lea _ConBuffer(A5),A0 move.w #$9B48,(A0) ; Cursor Home moveq #2,D0 bsr.w _ConOut_Rel lea _SearchText(pc),A0 lea _SearchTextEnd(pc),A1 ; Address end of help-text suba.l A0,A1 ; == length text move.l A1,D0 ; into D0 bsr.w _ConOut_Reloc ; Output bsr.w _CursorOn lea _IOReqString(A5),A3 ; Buffer to store the complete string the user enters moveq #0,D3 ; Amount of already stored chars moveq #0,D4 ; Position in textbuffer movea.l A3,A0 ; Clear IOReqString move.w #256-1,D0 .clear clr.b (A0)+ subq.w #1,D0 bcc.s .clear lea _CharBuffer(A5),A0 ; At least, two chars wide (only for console reading) clr.l (A0) ; Indicator: Nothing entered! .loop moveq #2,D0 lea _CharBuffer(A5),A0 lea _ReadIo(A5),A1 move.l D0,IO_LENGTH(A1) ; Number of chars to read move.l A0,IO_DATA(A1) move.b #IOF_QUICK,IO_FLAGS(A1) move.w #CMD_READ,IO_COMMAND(A1) ; Command READ movea.l _SysBase(A5),A6 jsr _LVODoIO(A6) ; Send command lea _CharBuffer(A5),A0 ; Get the chars tst.b (A0) ; Too bad, no char beq.s .loop lea _CharBuffer(A5),A0 ; Get address of buffer move.b (A0),D0 ; Get the char (or sequencer ($9B)) move.b 1(A0),D1 ; When D0 sequencer, D1 keycode clr.l (A0) ; Indicator: No char stored! bra.s .SetString ; Parse that char... * ------ finish (not found) ------ * .end bsr.w _CursorOff move.l #$8|$200|$400,D0 movea.l _WindowPtr(A5),A0 movea.l _IntuitionBase(A5),A6 jsr _LVOModifyIDCMP(A6) movem.l (sp)+,D2-D4/A2-A4 bsr.w _RestoreCurrentPage bra.w _Loop *********************************** * * React to read char * * INPUTS: D0 - char * or D0 - sequence ($9B) * then D1 - char .SetString cmpi.b #13,D0 ; Carridge return? beq.w .done cmpi.b #8,D0 ; Backspace beq.s .BackSpace cmpi.b #$7F,D0 ; DEL beq.s .Delete cmpi.b #$9B,D0 ; (sequence) beq.w .Sequencer cmpi.b #$1B,D0 ; ESC beq.w .Escape * ############ -------- Any other char -------- * cmpi.b #255,D3 ; Maximum editable chars beq.w .loop move.b D0,D2 ; The char bsr.w _InsertChar ; Store char (D2) to TextBuffer bsr.w _PrintChar bra.w .loop ; and normal... * ############ -------- Delete last character -------- * .BackSpace tst.l D3 ; At least one char stored? beq.w .loop tst.l D4 beq.w .loop cmpi.b #9,-1(A3,D4.l) bne.s .donormal moveq #0,D2 bsr.w _MoveTAB bsr.w _RemChar bra.s .delete ; <- see there... * ------------------------------ * .donormal lea _ConBuffer(A5),A0 move.w #$9B44,(A0) ; D moveq #2,D0 bsr.w _ConOut_Rel subq.l #1,D4 bsr.w _RemChar bra.s .delete ; <- see there... * ############ ------ Delete current character ------ * .Delete tst.l D3 beq.w .loop cmp.l D3,D4 beq.w .loop bsr.w _RemChar .delete tst.l D4 beq.s .dprint ; Start of line (first char) lea _ConBuffer(A5),A0 move.w #$9B44,(A0) ; D moveq #2,D0 bsr.w _ConOut_Rel .dprint bsr.w _PrintChar cmp.l D3,D4 bne.s .chardeleted lea _ConBuffer(A5),A0 move.w #$9B50,(A0) ; 1D moveq #2,D0 bsr.w _ConOut_Rel .chardeleted bra.w .loop * ############ ------ Cursor keys or something like that picked... ------ * .Sequencer ; D0=$9B, D1=xx, * where xx is: * HELP $3F * CursorLeft $44 * CursorRight $43 * CursorUp $41 * CursorDown $42 tst.l D3 beq.w .loop cmpi.b #$44,D1 beq.s .left .right cmp.w D3,D4 beq.w .loop moveq #~0,D2 cmpi.b #9,0(A3,D4.l) bne.s .charright bsr.w _MoveTAB bra.w .loop .charright addq.l #1,D4 lea _ConBuffer(A5),A0 move.w #$9B43,(A0) ; C moveq #2,D0 bsr.w _ConOut_Rel bra.w .loop * ------------------------------ * .left tst.w D4 beq.w .loop moveq #0,D2 cmpi.b #9,-1(A3,D4.l) bne.s .charleft bsr.w _MoveTAB bra.w .loop .charleft subq.l #1,D4 lea _ConBuffer(A5),A0 move.w #$9B44,(A0) ; D moveq #2,D0 bsr.w _ConOut_Rel bra.w .loop * ############ ------- Escape key pressed... -------- * .Escape cmpi.b #255,D3 ; Maximum editable chars beq.w .loop move.b #'·',D2 bsr.w _InsertChar bsr.w _PrintChar bra.w .loop * ############ ------- Carridge Return - string complete! ------- * .done tst.l D3 ; If user cancled entering beq.w .end clr.b (A3,D3.l) ; Terminator bsr.w _CursorOff * ------- Replace '·' (synonym for escape) through escape character ------- * lea _IOReqString(A5),A0 ; Buffer with chars... .escapeSearch tst.b (A0) beq.s .searchStart cmpi.b #'·',(A0)+ bne.s .escapeSearch move.b #27,-1(A0) bra.s .escapeSearch * -------- Search for the overgiven string --------- * .searchStart lea _IOReqString(A5),A2 ; Buffer with chars... movea.l _TextPtr(A5),A3 ; Text start addq.l #2,A3 ; Overread #$200A movea.l A3,A4 adda.l _BufferSize(A5),A4 ; Size of chars of text subq.l #4,A4 ; Ignore introducing ($200A) and terminator .search move.l D3,-(sp) move.l A2,-(sp) move.l A3,-(sp) bsr.w _strincmp ; Compare case insensitive strings lea 12(sp),sp tst.l D0 beq.s .found ; D0 = 0 means ok. addq.l #1,A3 ; Else, next char cmpa.l A3,A4 ; Check against limit bls.s .notfound ; If out of limit bra.s .search ; Else, search .found move.l A3,D0 ; Found text addq.l #1,D0 ; No trouble shooting.... move.l D0,_SearchStrPtr(A5) ; There where we can continue if user said "search next" move.l D3,_SearchStrLen(A5) ; Remember length of string to search for * -------- Search for linestart -------- * movea.l _TextPtr(A5),A0 addq.l #2,A0 ; Overread #$200A .searchLF cmpi.b #10,(A3) ; LineFeed (line start) beq.s .foundLineStart cmpa.l A0,A3 ; Does it fit? bls.s .notfound subq.l #1,A3 ; Else one less char... bra.s .searchLF .foundLineStart move.l #$8|$200|$400,D0 movea.l _WindowPtr(A5),A0 movea.l _IntuitionBase(A5),A6 jsr _LVOModifyIDCMP(A6) move.l A3,D0 movem.l (sp)+,D2-D4/A2-A4 move.l D0,-(sp) bsr.w _GetCurrentLine ; Compute the line (last one in window) move.l (sp)+,D6 ; First char in window bsr.w _RestoreCurrentPage bra.w _Loop * ############ ------- Couldn't find the string... ------- * .notfound suba.l A0,A0 movea.l _IntuitionBase(A5),A6 jsr _LVODisplayBeep(A6) clr.l _SearchStrPtr(A5) clr.l _SearchStrLen(A5) bra.w .end **************************************************************** * * Move a char which is a tabulator - to the left or to the right * * D2 - indicator: zero = leftmove, unequal zero = move right * _MoveTAB lea _ConBuffer(A5),A0 ; Buffer for created string move.b #$9B,(A0) ; lea _IOReqString(A5),A1 ; Buffer with chars moveq #12,D0 ; Initial column offset, here "Search for: " <- 12 chars * For a real editor replace 12 through 0, 'cause of line start... tst.b D2 beq.s .leftsetup ; ...because left move cursor .rightsetup move.l A0,-(sp) lea 0(A3,D4.l),A0 bra.s .searchtab .leftsetup move.l A0,-(sp) lea -1(A3,D4.l),A0 .searchtab cmpa.l A0,A1 ; Last char before tab? beq.s .gottab ; If found addq.w #1,D0 ; Else counter for chars plus 1 cmpi.b #9,(A1) ; A tab? bne.s .next1 ; If not... addq.w #7,D0 ; Else calc position (every time divisible through 8) andi.w #-8,D0 .next1 addq.l #1,A1 ; Get next char('s position(address)) bra.s .searchtab ; And search further .gottab ; Current position in D0 before tab movea.l (sp)+,A0 tst.b D2 bne.s .rightmove .leftmove move.b #'D',D2 move.l D0,D1 addq.l #8,D1 ; Add a char (1) and make width divisible by 8 (7) andi.l #-8,D1 sub.l D0,D1 ; Number of space to move left subq.l #1,D4 bra.s .write .rightmove move.b #'C',D2 move.l D0,D1 addq.l #8,D1 ; Add a char (the tab) and make width divisible by 8 (7) andi.l #-8,D1 sub.l D0,D1 addq.l #1,D4 .write addi.b #'0',D1 ; Convert it into ASCII move.b D1,1(A0) ; Into ConBuffer move.b D2,2(A0) ; nD = cursor n positions backward moveq #3,D0 ; Three chars for output bsr.w _ConOut_Rel ; Output! rts ************************************************** * * Print yet entered char to window. * * INPUTS: D3 - amount of chars in TextBuffer * D4 - current BufPosition * _PrintChar cmp.l D3,D4 bne.s .givestring tst.l D3 beq.s .erase lea -1(A3,D3),A0 ; Address string (including new charcter) moveq #1,D0 bsr.w _ConOut_Reloc rts .givestring lea _ConBuffer(A5),A0 move.w #$9B4B,(A0) ; K [erase to end of line] moveq #2,D0 bsr.w _ConOut_Rel lea -1(A3,D4),A0 ; Address string (including new charcter) move.l D3,D0 ; Length move.l D4,D1 ; - minus current position addq.l #1,D0 bsr.w _ConOut_Reloc ; Print rest of string * Because the cursor is at end of line, we have to move it to current BufPosition... move.l D4,-(sp) move.l D3,D4 ; End of line = current BufPosition .loopmove moveq #0,D2 ; Indicator: left move cmpi.b #9,-1(A3,D4.l) ; A tab? bne.s .moveleft ; If not... bsr.w _MoveTAB ; Else, move it as tab... bra.s .movedone ; done (for this time) .moveleft subq.l #1,D4 ; BufPosition minus 1 lea _ConBuffer(A5),A0 move.l #$9B314400,(A0) ; 1D moveq #3,D0 bsr.w _ConOut_Rel ; Move cursor 1 position left .movedone move.l (sp),D0 ; Get original BufPosition cmp.l D0,D4 ; reached? bne.s .loopmove ; If not addq.l #4,sp .done rts .erase lea _ConBuffer(A5),A0 move.w #$9B50,(A0) ; 1D moveq #2,D0 bsr.w _ConOut_Rel rts ******************************* * * Insert a char in text buffer * * INPUTS: D2 - the char to store * D3 - amount of currently stored chars * D4 - currently used BufPosition * RESULTS: D3 - increased by one * D4 - increased by one _InsertChar cmp.l D3,D4 beq.s .atend ; It's currently the last char... lea 0(A3,D4.l),A0 ; Source lea 1(A3,D4.l),A1 ; Destination move.l D3,D0 sub.l D4,D0 bsr.s _DupCopy ; Free room at current position in textbuffer move.b D2,0(A3,D4.l) ; and store there the char addq.l #1,D3 addq.l #1,D4 rts .atend ; Insert char at last position move.b D2,0(A3,D4.l) clr.b 1(A3,D4.l) ; Terminator addq.l #1,D3 addq.l #1,D4 rts ***************************************************** * * Because Exec function CopyMem() cannot be used when * "ascended overlay copying" is required, * we have to make an own, which copies "reverse" the * datas. * * Inputs: A0/A1/D0 - source/destination/size * _DupCopy subq.l #1,D0 .loop move.b 0(A0,D0.l),0(A1,D0.l) subq.l #1,D0 bcc.s .loop rts ****************************************************************** * * Remove char in text buffer which currently stays on BufPosition * * INPUTS: D3 - currently amount of char in buffer (old length) * D4 - current buffers poisition (BufPosition) * REULTS: char on BufPosition removed * D3 - decreased by one (char removed) * NOTES: D4 unchanged... * _RemChar subq.l #1,D3 ; New size move.l D3,D0 ; Amount chars in buffer move.l D4,D1 ; Buffers position sub.l D1,D0 ; Number of bytes behind BufPosition beq.s .endchar bmi.s .endchar lea 1(A3,D4.l),A0 ; Source lea 0(A3,D4.l),A1 ; Destination movea.l _SysBase(A5),A6 jsr _LVOCopyMem(A6) .endchar clr.b 0(A3,D3.l) rts **************************************************************** * * Compare case insensitive string1 and string2 with width-limit. * * Input: string1, string2, num-chars (stackargs) * Result: D0 = FALSE (0L) if strings are the same. * _strincmp ;cargs string1.l,string2.l, num-chars.l move.l D2,-(sp) movea.l 8(sp),A0 movea.l 12(sp),A1 move.l 16(sp),D2 andi.l #$FFFF,D2 subq.w #1,D2 .start move.b (A0)+,D0 bsr.s _UpperCase move.b D0,D1 move.b (A1)+,D0 bsr.s _UpperCase tst.b D0 bne.s .tst tst.b D1 beq.s .same .tst cmp.b D0,D1 bne.s .differ dbf D2,.start .same move.l (sp)+,D2 moveq #0,D0 rts .differ move.l (sp)+,D2 moveq #-1,D0 rts ********************************************* * * Change char in D0 to uppercase if possible. * Supports all ASCII-one characters! * * Returns char in D0 * _UpperCase tst.b D0 beq.s .back cmpi.b #96,D0 bls.s .back cmpi.b #122,D0 bls.s .change cmpi.b #255,D0 beq.s .back cmpi.b #223,D0 bhi.s .change rts .change andi.b #$DF,D0 .back rts ************************************************* * * If the N-key is pressed, we are at this point. * Same as SearchSequence() but without any * input()... * _ContinueSearch movem.l D2/A2-A4,-(sp) move.l #$200,D0 movea.l _WindowPtr(A5),A0 movea.l _IntuitionBase(A5),A6 jsr _LVOModifyIDCMP(A6) tst.l _TextPtr(A5) ; Any text to examine? beq.w .end lea _IOReqString(A5),A0 ; Any search string given? tst.b (A0) beq.w .end move.l _SearchStrLen(A5),D2 ; Length of search string set? beq.w .end tst.l _SearchStrPtr(A5) ; An address remembered? beq.s .end lea _IOReqString(A5),A2 ; String to search for.... movea.l _SearchStrPtr(A5),A3 ; Address from where to search movea.l _TextPtr(A5),A4 ; Address text-start addq.l #2,A4 ; Overread #$200A adda.l _BufferSize(A5),A4 ; = end of text subq.l #4,A4 .search move.l D2,-(sp) move.l A2,-(sp) move.l A3,-(sp) bsr.w _strincmp lea 12(sp),sp tst.l D0 beq.s .found cmpa.l A3,A4 bls.s .notfound addq.l #1,A3 bra.s .search .found move.l A3,D0 addq.l #1,D0 move.l D0,_SearchStrPtr(A5) ; Remember address where we found string (plus 1 byte) move.l D2,_SearchStrLen(A5) movea.l _TextPtr(A5),A0 ; Address text-start addq.l #2,A0 ; Overread #$200A .searchLF cmpi.b #10,(A3) beq.s .foundLineStart cmpa.l A0,A3 ; Does it fit? bls.s .notfound subq.l #1,A3 ; Else one less char... bra.s .searchLF .foundLineStart move.l A3,D0 movem.l (sp)+,D2/A2-A4 move.l D0,-(sp) bsr.s _GetCurrentLine move.l #$8|$200|$400,D0 movea.l _WindowPtr(A5),A0 movea.l _IntuitionBase(A5),A6 jsr _LVOModifyIDCMP(A6) move.l (sp)+,D6 ; First char in window bsr.w _RestoreCurrentPage bra.w _Loop .notfound suba.l A0,A0 movea.l _IntuitionBase(A5),A6 jsr _LVODisplayBeep(A6) .end move.l #$8|$200|$400,D0 movea.l _WindowPtr(A5),A0 movea.l _IntuitionBase(A5),A6 jsr _LVOModifyIDCMP(A6) movem.l (sp)+,D2/A2-A4 bsr.w _RestoreCurrentPage bra.w _Loop ****************************************** * * Compute current line. * * Input: D0 - address within text buffer. * _GetCurrentLine movea.l _TextPtr(A5),A0 move.l D0,A1 moveq #0,D1 .cmp cmpi.b #10,(A0) beq.s .add .tst cmpa.l A0,A1 beq.s .found .next addq.l #1,A0 bra.s .cmp .add addq.l #1,D1 bra.s .tst .found moveq #0,D0 move.w _StdPageSize(A5),D0 ; Amount of lines in window add.l D0,D1 move.l D1,_Line(A5) rts *************************** * * Display commands summary. * * Inputs: none * Results: none * _DisplayHelp bsr.w _SetActionWait ; See there bsr.w _ClearWindow lea _HelpText(pc),A0 ; Address help-text lea _HelpTextEnd(pc),A1 ; Address end of help-text suba.l A0,A1 ; == length text move.l A1,D0 ; into D0 bsr.w _ConOut_Reloc ; Output move.l A2,-(sp) 1$ movea.l _SysBase(A5),A6 movea.l _WindowPtr(A5),A2 movea.l wd_UserPort(A2),A2 movea.l A2,A0 jsr _LVOWaitPort(A6) movea.l A2,A0 jsr _LVOGetMsg(A6) movea.l D0,A1 movea.l D0,A2 jsr _LVOReplyMsg(A6) cmpi.w #H_Key+$80,im_Code(A2) ; H-key released? bne.s 1$ movea.l _WindowPtr(A5),A2 movea.l wd_UserPort(A2),A2 movea.l A2,A0 jsr _LVOWaitPort(A6) ; Wait for any event movea.l A2,A0 jsr _LVOGetMsg(A6) movea.l D0,A1 jsr _LVOReplyMsg(A6) movea.l (sp)+,A2 tst.l _TextPtr(A5) ; Any text there? beq.s 2$ ; If not bsr.w _RestoreCurrentPage ; Else restore the page 2$ bra.w _Loop ************************** * * Display the standard.... * * Inputs: none * Results: none * _About lea _AboutTxt(pc),A0 ; I like this... bsr.w _DisplayError bra.w _Loop **************************************** * * Display informations about program.... * * Inputs: none * Results: none * _Info move.l #_TableSize,D0 ; Size BSS addq.l #7,D0 andi.l #-8,D0 ; Aligned size move.l D0,-(sp) lea _startup(pc),A0 ; Code start subq.l #4,A0 ; Next hunk... movea.l (A0),A0 ; BPTR next hunk adda.l A0,A0 adda.l A0,A0 ; == APTR next hunk move.l -4(A0),D0 ; Size next hunk subq.l #8,D0 ; Ignore hunk-header (8 bytes) move.l D0,-(sp) ; Size datas-chip lea _Divutable(pc),A0 ; Start datas lea _EndDatas(pc),A1 ; End datas sub.l A0,A1 ; == size datas move.l A1,D0 addq.l #3,D0 andi.l #-4,D0 ; Aligned size (longword) move.l D0,-(sp) lea _startup(pc),A0 ; Entry point of program lea _Divutable(pc),A1 ; End of code suba.l A0,A1 ; == size of code move.l A1,-(sp) pea _InfoTxt(pc) ; Text... bsr.w _FmtDisplay lea 20(sp),sp ; Restore stack bra.w _Loop ************************* * * Allow messages for now. * * Inputs: none * Results: none * _SetActionWait move.l A0,-(sp) movea.l _WindowPtr(A5),A0 movea.l wd_UserPort(A0),A0 clr.b MP_FLAGS(A0) movea.l (sp)+,A0 rts *********************************** * * Do not allow any message for now. * * Inputs: none * Results: none * _SetNILWait move.l A0,-(sp) movea.l _WindowPtr(A5),A0 movea.l wd_UserPort(A0),A0 move.b #PA_IGNORE,MP_FLAGS(A0) movea.l (sp)+,A0 rts ******************************************** * * Check for user specification in tooltypes. * * Inputs: none * Results: none * _CheckWarning lea WB_arg_1(A5),A0 ; Address constant of 1. argument 1$ tst.l (A0) ; Address 1. argument there? beq.s 3$ movea.l (A0)+,A1 ; Out of it address 1. argument lea _NoWarningName(pc),A2 ; "NOWARN",0 moveq #6,D0 ; 7 loops 2$ cmpm.b (A1)+,(A2)+ ; Compare char for char bne.s 1$ ; "NOWARN" dbf D0,2$ st.b _NoWarnFlag(A5) 3$ lea WB_arg_1(A5),A0 ; Address constant of 1. argument 4$ tst.l (A0) ; Address 1. argument there? beq.s 6$ movea.l (A0)+,A1 ; Out of it address 1. argument lea _NoCheckPrinterTxt(pc),A2 ; "NOPRTCHECK",0 moveq #10,D0 ; 11 loops 5$ cmpm.b (A1)+,(A2)+ ; Compare char for char bne.s 4$ dbf D0,5$ st.b _NoCheckPrtFlag(A5) 6$ rts ************************************************* * * Check for user specification in tooltypes. * If specification was made, execute the command. * Inputs: none * Results: none * _CheckExecute lea WB_arg_1(A5),A0 .NextTType tst.l (A0) ; Argument there? beq.s .EndExecute ; No movea.l (A0)+,A1 ; Address overgiven string lea _ExecuteTxt(pc),A2 ; Address string to compare moveq #7,D0 ; 8 chars to compare .CheckTType cmpm.b (A1)+,(A2)+ ; Compare strings bne.s .NextTType ; "EXECUTE=" dbf D0,.CheckTType movea.l A1,A0 ; Pointer to following string moveq #0,D4 lea _ConBuffer(A5),A1 1$ move.b (A0)+,(A1)+ bne.s 1$ move.l _stdout(A5),D3 bne.s 2$ lea _NilName(pc),A0 move.l A0,D1 move.l #MODE_NEWFILE,D2 movea.l _DOSBase(A5),A6 jsr _LVOOpen(A6) move.l D0,D4 beq.s .EndExecute move.l D4,D3 2$ lea _ConBuffer(A5),A0 move.l A0,D1 moveq #0,D2 movea.l _DOSBase(A5),A6 jsr _LVOExecute(A6) tst.l D4 beq.s .EndExecute move.l D4,D1 jsr _LVOClose(A6) .EndExecute rts ********************************** * * Init gadgets for "DisplayError". * Do it position independent. * * Inputs: None * Results: None * _InitGadgets movem.l D0-D2/A0-A4/A6,-(sp) BoolGadFlags EQU GADGIMMEDIATE|RELVERIFY lea _Gad1(A5),A0 move.w #20,gg_LeftEdge(A0) move.w #78,gg_TopEdge(A0) move.w #74,gg_Width(A0) move.w #19,gg_Height(A0) move.w #GADGHIMAGE|GADGIMAGE,gg_Flags(A0) move.w #BoolGadFlags,gg_Activation(A0) move.w #BOOLGADGET,gg_GadgetType(A0) move.w #1,gg_GadgetID(A0) lea _Gad2(A5),A1 moveq #gg_SIZEOF,D0 bra.s 2$ 1$ move.b (A0)+,(A1)+ 2$ dbf D0,1$ lea _Gad2(A5),A0 clr.l (A0) ; No next gadget! - otherwise on second * initializing it would point to itself!!! move.w #226,gg_LeftEdge(A0) move.w #2,gg_GadgetID(A0) lea _GTxt1(A5),A0 move.b #1,(A0) ; DetailPen lea _GTxt2(A5),A0 move.b #1,(A0) ; DetailPen lea _Image.1(pc),A0 lea _Image.2(pc),A1 lea _Gad1(A5),A2 lea _Gad2(A5),A3 move.l A3,(A2) move.l A0,gg_GadgetRender(A2) move.l A1,gg_SelectRender(A2) lea _GTxt1(A5),A4 move.l A4,gg_GadgetText(A2) move.l A0,gg_GadgetRender(A3) move.l A1,gg_SelectRender(A3) lea _GTxt2(A5),A4 move.l A4,gg_GadgetText(A3) lea _GTxt1(A5),A0 lea _GStr1(pc),A1 move.l A1,it_IText(A0) lea _GTxt2(A5),A0 lea _GStr2(pc),A1 move.l A1,it_IText(A0) lea _startup(pc),A0 ; First instruction of Viewer (startup-code) subq.l #4,A0 ; Pointer to BPTR next hunk movea.l (A0),A0 ; BPTR NextHunk adda.l A0,A0 adda.l A0,A0 ; APTR NextHunk addq.l #4,A0 ; Section Chip (_Gad.1, size 190 bytes) movea.l A0,A1 lea 190(A1),A1 ; _Gad.2 lea _Image.1(pc),A2 lea _Image.2(pc),A3 move.l A0,ig_ImageData(A2) move.l A1,ig_ImageData(A3) bsr.s _CenterGadTxt movem.l (sp)+,D0-D2/A0-A4/A6 rts _CenterGadTxt lea _Gad1(A5),A2 ; First-Gadget bra.s .set .NextGadget tst.l (A2) ; Next gadget? beq.w .NoNext movea.l (A2),A2 .set move.w gg_GadgetType(A2),D0 btst #0,D0 ; BoolGadget ? beq.s .NextGadget ; If not tst.l gg_GadgetText(A2) ; Intuition-text-structure? beq.s .NextGadget movea.l gg_GadgetText(A2),A0 movea.l A0,A3 ; Save Intuition-text-structure tst.l it_IText(A0) ; Any Text placed? beq.s .NextGadget movea.l it_IText(A0),A0 ; Pointer to string movea.l A0,A1 moveq #-1,D0 .getChars tst.b (A1)+ dbeq D0,.getChars not.l D0 ; Length in chars of string movea.l _ErrWindowPtr(A5),A1 ; Window movea.l wd_WScreen(A1),A1 ; Screen's lea sc_RastPort(A1),A1 ; RastPort!!! <- default font!!! movea.l _GfxBase(A5),A6 jsr _LVOTextLength(A6) ; Get stringlength in pixel move.w gg_Width(A2),D1 ; Width of gadget lsr.w #1,D0 ; Half textlength lsr.w #1,D1 ; Half gadget width sub.w D0,D1 ; Offset 1. char move.w D1,it_LeftEdge(A3) ; Store it in IntuiText-structure moveq #0,D2 ; Flags movea.l _ErrWindowPtr(A5),A0 ; Window movea.l wd_WScreen(A0),A0 ; Get screen's lea sc_RastPort(A0),A0 ; rastport - not window's one, because * the default-font is used for a gadget-text move.w rp_TxHeight(A0),D0 ; Height in pixel of font btst #0,D0 ; Font-height even (8, 10, 12 a.s.o.)? bne.s 2$ 1$ move.b #1,D2 2$ move.w #19,D1 ; Height gadget lsr.w #1,D0 ; Half lsr.w #1,D1 ; Half sub.w D0,D1 ; Y-offset font add.w D2,D1 ; Add (may be NULL) for even font-sizes move.w D1,it_TopEdge(A3) ; Set Top-Offset bra.w .NextGadget .NoNext rts *************** * * Init windows. * * Inputs: none * Results: none * _InitStandard lea _WindowRecord(A5),A0 move.b #1,nw_DetailPen(A0) move.b #3,nw_BlockPen(A0) move.l #$8|$40|$200|$400,nw_IDCMPFlags(A0) move.l #1|2|4|8|$10|$400|$1000|$10000,nw_Flags(A0) move.w #240,nw_MinWidth(A0) move.w #70,nw_MinHeight(A0) moveq #-1,D0 move.w D0,nw_MaxWidth(A0) move.w D0,nw_MaxHeight(A0) move.w #CUSTOMSCREEN,nw_Type(A0) lea _ErrWindowStruc(A5),A0 move.w #320,nw_Width(A0) move.w #100,nw_Height(A0) move.b #-1,nw_DetailPen(A0) move.b #-1,nw_BlockPen(A0) move.l #$40|$400,nw_IDCMPFlags(A0) move.l #$1000|$10000,nw_Flags(A0) move.w #320,nw_MinWidth(A0) move.w #100,nw_MinHeight(A0) move.w #320,nw_MaxWidth(A0) move.w #100,nw_MaxHeight(A0) move.w #CUSTOMSCREEN,nw_Type(A0) rts **************************************************************************** * * Allocate AudioIO-request * * Inputs: Priority (should be NULL or negative) D0 (byte, word, longword, but signed!) * * Result: APTR IOAudio - pointer to IORequest or zero upon error * * Notes: IOAudio is larger than it seems, so never deallocate it on your own. * IOReq_size EQU 68+4 ; size: divisible by eight MsgPort_size EQU 34+6 ; size: divisible by eight IOAudio_size EQU IOReq_size+MsgPort_size _AllocIOAudioA ; (D0)(Pri) movem.l D2/A3-A4/A6,-(sp) move.l D0,D2 ; Pri moveq #IOAudio_size,D0 ; 68 bytes IOAudio, 34 bytes MsgPort - aligned! move.l #MEMF_PUBLIC|MEMF_CLEAR,D1 movea.l _SysBase(A5),A6 jsr _LVOAllocMem(A6) tst.l D0 beq.w .AllocAudioEnd ; Error no mem movea.l D0,A4 ; IOReq ( *IOAudio) movea.l D0,A3 ; IOAudio lea IOReq_size(A3),A3 ; Skip IOAudio - thus pointer to MessagePort moveq #-1,D0 ; Any signal will do it jsr _LVOAllocSignal(A6) cmpi.l #-1,D0 ; Failed? beq.w .errNoSignal move.b D0,MP_SIGBIT(A3) ; SignalBit suba.l A1,A1 jsr _LVOFindTask(A6) ; Own task move.l D0,MP_SIGTASK(A3) ; Task who is signalled move.b #NT_MSGPORT,LN_TYPE(A3) ; Type = message port lea MP_MSGLIST(A3),A0 NEWLIST A0 ; Set up empty list btst #31,D2 ; A signed long value? bne.s .signed ; If so... btst #15,D2 ; A signed word value? beq.s .setup ; If not... .signed bset #7,D2 ; Make a signed byte .setup move.b D2,LN_PRI(A4) ; Priority of message (IOAudio->io_Message->ln_Pri) move.b #NT_REPLYMSG,LN_TYPE(A4) ; Type = ~message - due to a buck in CheckIO() move.l A3,MN_REPLYPORT(A4) ; Set replyport move.w #ioa_SIZEOF,MN_LENGTH(A4); Length of message lea _Channels(pc),A0 move.l A0,ioa_Data(A4) ; Address channel map move.l #4,ioa_Length(A4) ; Length channel map move.b #ADIOF_NOWAIT,IO_FLAGS(A4) ; Do not wait until channels are unlocked move.w #ADCMD_ALLOCATE,IO_COMMAND(A4) ; Alloc channels upon opening device lea _AudioName(pc),A0 ; Device movea.l A4,A1 ; IOReq moveq #0,D0 ; Unit moveq #0,D1 ; Flags jsr _LVOOpenDevice(A6) tst.l D0 bne.s .errNoDev move.l A4,D0 ; IOAudio .AllocAudioEnd movem.l (sp)+,D2/A3-A4/A6 rts .errNoMem moveq #ERROR_NO_FREE_STORE,D0 bsr.s .SetIoErr moveq #0,D0 bra.s .AllocAudioEnd .errNoSignal move.l #ERROR_NO_MORE_ENTRIES,D0 bsr.s .SetIoErr bsr.s .FreeAudioIOReq moveq #0,D0 bra.s .AllocAudioEnd .errNoDev move.l #ERROR_OBJECT_IN_USE,D0 bsr.s .SetIoErr moveq #0,D0 move.b MP_SIGBIT(A3),D0 jsr _LVOFreeSignal(A6) bsr.s .FreeAudioIOReq moveq #0,D0 bra.s .AllocAudioEnd .FreeAudioIOReq movea.l A4,A1 moveq #IOAudio_size,D0 jmp _LVOFreeMem(A6) .SetIoErr movea.l 276(A6),A0 ; ThisTask(A6) cmpi.b #NT_PROCESS,LN_TYPE(A0) ; Are we a process or task? bne.s .done move.l D0,pr_Result2(A0) ; Set error code in process' error field .done rts ************************************************************************* * * Free through AllocAudioIO() allocated IORequest, MessagePort, Signalbit. * * Inputs: IOAudio A0, APTR * * Results: None * _FreeIOAudioA ; (A0)(IOAudio) movem.l A3-A4/A6,-(sp) move.l A0,D0 beq.s .out movea.l A0,A4 movea.l A0,A3 lea IOReq_size(A3),A3 ; Skip IOAudio tst.l IO_DEVICE(A4) beq.s .NotInProgress movea.l A4,A1 * clr.b LN_TYPE(A4) * Although I set the type of IORequest to zero (as stated in autodocs) CheckIO() will ever hang... * movea.l _SysBase(A5),A6 * jsr _LVOCheckIO(A6) ; A process running? * tst.l D0 ; ~0 == no process * bne.s .NotInProgress movea.l A4,A1 ABORTIO * movea.l A4,A1 * jsr _LVOWaitIO(A6) .NotInProgress moveq #0,D0 move.b MP_SIGBIT(A3),D0 ; Get allocated signal jsr _LVOFreeSignal(A6) ; Free allocated signal movea.l A4,A1 jsr _LVOCloseDevice(A6) ; Close the audio-device movea.l A4,A1 moveq #IOAudio_size,D0 ; Full size (aligned) jsr _LVOFreeMem(A6) ; Free allocated memory .out movem.l (sp)+,A3-A4/A6 rts ******************************************************* * * Move the datas to the audio-channels. * Breaks the current IOAudio-process. * Does not wait until datas are completely worked out. * * Inputs: D0 (ULONG) Length in Bytes * D1 (UWORD) Cycles ( NULL = neverending) * D2 (UWORD) Period * D3 (UWORD) Volume * A0 (APTR) IOAudio * A1 (APTR) AudioDatas (must stay in chip-mem) * * Results: NULL - error - zero IOAudio * _SendIOAudioA ; (D0,D1,D2,D3,A0,A1)(length,cycles,period,volume,IOAudio,audiodata) movem.l D2-D5/A2-A3/A6,-(sp) movea.l A0,A2 ; IOAudio movea.l A1,A3 ; audiodata * D2 ; period * D3 ; volume move.l D0,D4 ; length move.w D1,D5 ; cycles move.l A0,D0 beq.s .failed * ** There seems to be a bug in the audio.device. CheckIO() will here ** return ever that there is a process running, even there isn't one. ** If we _do_ ABORTIO with an afterward WaitIO() (convention!) we wait ** here until world's ruin.... * movea.l A2,A1 movea.l _SysBase(A5),A6 jsr _LVOCheckIO(A6) ; A process running? tst.l D0 ; ~0 == no process bne.s .NotInProgress movea.l A2,A1 ABORTIO .NotInProgress movea.l A2,A1 ; IOAudio move.l A3,ioa_Data(A1) move.l D4,ioa_Length(A1) move.w D2,ioa_Period(A1) move.w D3,ioa_Volume(A1) move.w D5,ioa_Cycles(A1) move.b #ADIOF_PERVOL|ADIOF_SYNCCYCLE|IOF_QUICK,IO_FLAGS(A1) move.w #CMD_WRITE,IO_COMMAND(A1) BEGINIO ; BEGINIO and ABORTIO are MARCOS of "exec/io.i"! move.l A2,D0 .out movem.l (sp)+,D2-D5/A2-A3/A6 rts .failed moveq #0,D0 bra.s .out ******************************************* * ** Make the sound audible * _AudioHit movem.l D2-D7,-(sp) tst.b _AudGadget(A5) beq.w 1$ tst.l _AudioBuffer(A5) beq.w 1$ tst.l _IOAudio(A5) beq.w 1$ movea.l _IOAudio(A5),A0 move.b IO_ERROR(A0),D0 ; Any error? bpl.s .gogo ; No... bsr.w _FreeIOAudioA ; Error, so free device block moveq #-50,D0 ; and allocate a new one bsr.w _AllocIOAudioA ; with the same priority move.l D0,_IOAudio(A5) beq.w .errorPlay ; If we still can't them... .gogo move.l _BODYSize(A5),D0 move.l _AudioBufferSize(A5),D1 cmp.l D0,D1 bls.s 2$ * Normal, one shot sample play, sample size lower or equal to 28 kbyte move.l _BODYSize(A5),D0 moveq #1,D1 move.l _AudioPeriod(A5),D2 moveq #64,D3 movea.l _IOAudio(A5),A0 move.l _AudioBuffer(A5),A1 bsr.w _SendIOAudioA movea.l _IOAudio(A5),A0 tst.b IO_ERROR(A0) bne.w .errorPlay bra.w .done ; Done * Smart, sample size taller than 28 kbyte 2$ movea.l _IOAudio(A5),A0 movea.l MN_REPLYPORT(A0),A0 move.b MP_SIGBIT(A0),D1 ; Get SigBit of IO Request moveq #0,D4 move.b D1,D4 moveq #1,D0 lsl.l D1,D0 ; ... and convert it into a bitmask move.l D0,D7 movea.l _WindowPtr(A5),A0 ; Same for our window movea.l wd_UserPort(A0),A0 move.b MP_SIGBIT(A0),D1 moveq #1,D0 lsl.l D1,D0 or.l D0,D7 ; Combine both mask move.l _BODYSize(A5),D6 ; The size of the whole audio datas moveq #0,D5 ; How many bytes already played moveq #0,D0 ; Refer to chip-ram buffer 0 bsr.w .SetupAudBuffer move.l D0,D2 ; Amount datas to play 3$ tst.l D2 beq.w .done move.l D2,D0 ; Play how many .... moveq #1,D1 ; One cycle move.l _AudioPeriod(A5),D2 ; Period moveq #64,D3 ; Volume move.l _IOAudio(A5),A0 ; Device IO Request block move.l _AudioBuffer(A5),A1 ; Datas bsr.w _SendIOAudioA ; Play them! moveq #1,D0 ; Refer to chip-ram buffer 1 bsr.s .SetupAudBuffer move.l D0,D2 beq.s .done movea.l _IOAudio(A5),A0 tst.b IO_ERROR(A0) ; Error occurred? bne.s .errorPlay movea.l _SysBase(A5),A6 move.l D7,D0 ; Mask jsr _LVOWait(A6) ; Wait for this part to finish moveq #0,D3 btst.l D4,D0 ; Not an audio signal? beq.w 4$ ; If no audio signal! .InJump move.l D2,D0 ; Play how many .... moveq #1,D1 move.l _AudioPeriod(A5),D2 moveq #64,D3 movea.l _IOAudio(A5),A0 move.l _AudioBuffer(A5),A1 lea 14*1024(A1),A1 bsr.w _SendIOAudioA moveq #0,D0 ; Refer to chip-ram buffer 0 bsr.s .SetupAudBuffer move.l D0,D2 movea.l _IOAudio(A5),A0 tst.b IO_ERROR(A0) bne.s .errorPlay movea.l _SysBase(A5),A6 move.l D7,D0 jsr _LVOWait(A6) ; Wait for that part to finish moveq #1,D3 btst.l D4,D0 ; Not an audio signal? beq.s 4$ ; If no audio signal! bra.s 3$ ; Restart (next data block) .errorPlay lea _AudErrTxt(pc),A0 bsr.w _DisplayError bra.s 1$ .done movea.l _SysBase(A5),A6 movea.l _IOAudio(A5),A1 jsr _LVOWaitIO(A6) 1$ movem.l (sp)+,D2-D7 bra.w _Loop * -------- Fill either first or second buffer with audio datas -------- * * D0 = 0, 1st buffer, D0 = 1, second buffer .SetupAudBuffer subi.l #14*1024,D6 ; Try to work out 14 kbyte bcs.s .overload ; If there isn't such a amount movea.l _BODYPtr(A5),A0 ; Pointer to datas (in fast ram/hopefully) add.l D5,A0 ; Fetch datas that aren't worked out yet movea.l _AudioBuffer(A5),A1 ; Chip-ram buffer (28 kbyte) mulu.w #14*1024,D0 ; Two which part we refer (14 kbyte) adda.l D0,A1 move.l #14*1024,D0 ; Size: 14 kbyte to copy movea.l _SysBase(A5),A6 jsr _LVOCopyMemQuick(A6) move.l #14*1024,D0 ; Size to play: 14 kbyte add.l D0,D5 ; Amount datas that worked out already rts .overload add.l #14*1024,D6 ; Get rest of datas movea.l _BODYPtr(A5),A0 add.l D5,A0 movea.l _AudioBuffer(A5),A1 mulu.w #14*1024,D0 ; To which chip-ram buffer we refer ? adda.l D0,A1 move.l D6,D0 movea.l _SysBase(A5),A6 jsr _LVOCopyMem(A6) add.l D6,D5 move.l D6,D0 ; Size to play moveq #0,D6 ; No more datas rts * -------- React to user input (while something is played)-------- * 4$ movea.l _WindowPtr(A5),A0 movea.l wd_UserPort(A0),A0 movea.l _SysBase(A5),A6 jsr _LVOGetMsg(A6) tst.l D0 beq.s 7$ movea.l D0,A1 move.l 20(A1),D0 ; im_Class move.w 24(A1),D1 ; im_Code move.l 28(A1),_IAddr(A5) movem.l D0-D1,-(sp) jsr _LVOReplyMsg(A6) movem.l (sp)+,D0-D1 cmpi.l #$200,D0 ; CLOSEWINDOW ? bne.s 5$ movem.l (sp)+,D2-D7 bsr.s .WaitAction bra.w _End ; If so... 5$ cmpi.l #$40,D0 ; GADGETUP bne.s 6$ movea.l _IAddr(A5),A0 cmpi.w #3,gg_GadgetID(A0) bne.s 7$ bsr.s .WaitAction bra.w 2$ ; Redo from start! 6$ cmpi.l #$400,D0 ; RAWKEY? bne.s 7$ ; If not... cmpi.w #L_Key,D1 bne.s 7$ movem.l (sp)+,D2-D7 bsr.s .WaitAction bra.w _LoadNew 7$ bsr.s .WaitAction tst.l D3 beq.w .InJump ; Jump where we can continue bra.w 3$ * -------- Ignore multiple intuition messages and wait for the IO to complete -------- * .WaitAction movea.l _WindowPtr(A5),A0 movea.l wd_UserPort(A0),A0 movea.l _SysBase(A5),A6 jsr _LVOGetMsg(A6) tst.l D0 beq.s 8$ movea.l D0,A1 jsr _LVOReplyMsg(A6) bra.s .WaitAction 8$ movea.l _IOAudio(A5),A1 jsr _LVOWaitIO(A6) rts ************************************************* * ** Load Audio File * _LoadAudio lea _8SVXTxt(pc),A0 bsr.w _DisplayError tst.l D0 beq.w _BinaryFile bsr.s _GetAudioSettings moveq #-50,D0 bsr.w _AllocIOAudioA move.l D0,_IOAudio(A5) beq.s .error bsr.w _DisplayAudioGadget addq.l #4,sp ; Remove "bsr.w _CheckFile" bra.w _Loop .error bsr.w _FreeAudio bsr.w _FreeFile lea _8SVXErrTxt(pc),A0 bsr.w _DisplayError addq.l #4,sp bra.w _Loop _GetAudioSettings bsr.w _CheckFibDelta tst.l D0 beq.w .error move.l #28*1024,D0 move.l D0,_AudioBufferSize(A5) move.l #MEMF_CLEAR|MEMF_CHIP|MEMF_PUBLIC,D1 movea.l _SysBase(A5),A6 jsr _LVOAllocMem(A6) move.l D0,_AudioBuffer(A5) beq.w .error movea.l _TextPtr(A5),A0 ; Address datas move.l _FileSize(A5),D0 ; Size datas cmpi.w #'FO',(A0) beq.s .startScan addq.l #2,A0 subq.l #2,D0 .startScan lea 12(A0),A0 subi.l #12,D0 move.l #'VHDR',D1 bsr.w .getChunk tst.l D1 beq.s .error .scanBody move.l A0,_VHDRPtr(A5) addq.l #8,_VHDRPtr(A5) move.l #'BODY',D1 bsr.w .getChunk tst.l D1 beq.s .error .gotBody move.l A0,_BODYPtr(A5) addq.l #8,_BODYPtr(A5) move.l 4(A0),_BODYSize(A5) move.l _VHDRPtr(A5),A0 moveq #0,D1 move.w 12(A0),D1 * Hertz to Period, the slow way... move.l #100000000,D0 * move.l D1,D1 ; Hertz moveq #28,D2 mulu.w D2,D1 moveq #-1,D2 .divlong addq.l #1,D2 sub.l D1,D0 bcc.s .divlong move.l D2,_AudioPeriod(A5) move.l _BODYSize(A5),D0 move.l _AudioBufferSize(A5),D1 cmp.l D0,D1 bhi.s .cpy move.l _BODYPtr(A5),A0 move.l _AudioBuffer(A5),A1 move.l #28*1024,D0 movea.l _SysBase(A5),A6 jsr _LVOCopyMemQuick(A6) rts .cpy move.l _BODYPtr(A5),A0 move.l _AudioBuffer(A5),A1 move.l _BODYSize(A5),D0 movea.l _SysBase(A5),A6 jsr _LVOCopyMem(A6) rts .error lea _8SVXErrTxt(pc),A0 bsr.w _DisplayError bsr.w _FreeFile bsr.w _FreeAudio addq.l #8,sp ; Remove "bsr.w _CheckFile" and "bsr.s GetAudioSettings" bra.w _Loop .getChunk cmp.l (A0),D1 beq.s .chunkFound .getNextChunk move.l 4(A0),D2 ; Size of this chunk addq.l #1,D2 andi.l #-2,D2 ; In case it was odd, it's now even addq.l #8,D2 ; Skip chunk name and its size entry sub.l D2,D0 ; A rest left? beq.s .chunkError bmi.s .chunkError lea 0(A0,D2),A0 ; Point to next chunk name cmp.l (A0),D1 ; Compare bne.s .getNextChunk .chunkFound rts .chunkError moveq #0,D1 rts _FindVHDR move.l D0,D2 ; Size file subi.l #12,D2 lea 12(A0),A1 ; Chunk name .restart move.l 4(A1),D1 ; Chunk size addq.l #1,D1 andi.l #-2,D1 ; Even chunk size addq.l #8,D1 ; Chunk name + sizeof(chunk size var) (4 bytes) sub.l D1,D2 beq.s .notfound bmi.s .notfound lea 0(A1,D1),A1 ; Next chunk name cmpi.l #'VHDR',(A1) bne.s .restart .found addq.l #8,A1 bra.s _TestIfFibDeltaComp .notfound lea _8SVXErrTxt(pc),A0 bsr.w _DisplayError bsr.w _FreeFile lea 12(sp),sp ; Remove "bsr.w _CheckFile" and "bsr.s GetAudioSettings" and "bsr.s _CheckFibDelta" bra.w _Loop _FreeAudio tst.l _AudioBuffer(A5) beq.s 1$ movea.l _AudioBuffer(A5),A1 move.l _AudioBufferSize(A5),D0 movea.l _SysBase(A5),A6 jsr _LVOFreeMem(A6) clr.l _AudioBuffer(A5) 1$ move.l _IOAudio(A5),D0 beq.s 2$ movea.l D0,A0 bsr.w _FreeIOAudioA clr.l _IOAudio(A5) 2$ bsr.w _RemoveAudioGadget rts _CheckFibDelta movem.l D2-D4/A2-A4,-(sp) move.l _FileSize(A5),D0 movea.l _TextPtr(A5),A0 addq.l #2,A0 ; Overread subq.l #2,D0 cmpi.l #'FORM',(A0) ; IFF? bne.s _CheckFibEnd cmpi.l #'8SVX',8(A0) ; 8SVX? bne.s _CheckFibEnd cmpi.l #'VHDR',12(A0) ; IFF? bne.w _FindVHDR lea 20(A0),A1 _TestIfFibDeltaComp cmpi.b #1,15(A1) bne.s _CheckFibEndOk bra.s _StartUnpack _CheckFibEnd moveq #0,D0 movem.l (sp)+,D2-D4/A2-A4 rts _CheckFibEndOk moveq #-1,D0 movem.l (sp)+,D2-D4/A2-A4 rts _StartUnpack move.l D0,D1 movea.l A0,A1 moveq #0,D2 1$ subq.l #2,D1 bls.s _CheckFibEnd addq.l #2,D2 cmpi.w #'BO',(A1)+ bne.s 1$ addq.l #6,D2 ; plus 'BODY' text ('DY' plus room for 1 longword) move.l 2(A1),D3 ; Length Body addq.l #6,A1 ; Ignore 'DY' plus length movea.l A0,A2 ; IFF-Header movea.l A1,A3 ; Compressed datas * A2 pointer to IFF header * A3 pointer to compressed datas * D2 length IFF header * D3 length sample (compressed) datas move.l D2,D0 add.l D3,D0 add.l D3,D0 ; Length new IFF-file! (2* D3 !!!) addq.l #3,D0 ; + 7 - 4 = 3 ( because of 2*(n-2) ! ) andi.l #-8,D0 move.l D0,D4 ; New IFF-file length move.l #MEMF_CLEAR|MEMF_PUBLIC,D1 movea.l 4.w,A6 jsr _LVOAllocMem(A6) tst.l D0 beq.s _CheckFibEnd movea.l D0,A4 * A2 pointer to IFF header * A3 pointer to compressed datas * A4 pointer to allocated memory * D2 length IFF header * D3 length sample (compressed) datas * D4 size allocated memory move.l A2,A0 movea.l A4,A1 move.l D2,D0 subq.l #4,D0 ; Minus length of 'BODY' length set jsr _LVOCopyMem(A6) ; Copy IFF-Header add.l D3,4(A4) ; Add double size of datas of FORM-chunk subq.l #4,4(A4) clr.b 35(A4) ; Erase comression sign move.l D3,D0 ; length datas movea.l A3,A0 ; Source datas movea.l A4,A1 add.l D2,A1 ; Destination (pointer right behind IFF header!) move.l D3,D1 add.l D1,D1 ; New length of BODY = length * 2 subq.l #4,D1 ; Because of 2*(n-2) ! move.l D1,-4(A1) ; Set length bsr.s _FibDeltaUnpack ; Unpack datas bsr.w _FreeFile move.l D4,_BufferSize(A5) move.l D2,D0 add.l D3,D0 add.l D3,D0 ; 2 * D3!!!! subq.l #4,D0 move.l D0,_FileSize(A5) move.l A4,_TextPtr(A5) bra.w _CheckFibEndOk ****************************************************************************** * * FibDelatUnpack * * Based on Steve Hayes' DUnpack for his Fibonacci Delta compression algorythm. * * Converted to assembly by Jörg van de Loo * Hövel 15 * 47559 Kranenburg * Germany * _FibDeltaUnpack ; (numdatas,source,destination)(D0,A0,A1) movem.l D2-D5/A2,-(sp) subq.l #2,D0 ; numdatas-2 ( n - 2 ) moveq #0,D1 move.b 1(A0),D1 ; x = source[1] = initial value! addq.l #2,A0 ; source + 2 * movea.l A1,A1 ; destination * ** (rawdatas-2,data,source+2,destination)(D0,D1,A0,A1) * move.l D0,D2 ; maximum datas = add.l D2,D2 ; doubled ( 2*(n-2) ) moveq #0,D3 ; internal counter ( i ) moveq #0,D5 ; Dummy lea __DeltaTable(pc),A2 ; Table of deltas to add to value x bra.s .checkend .next move.l D3,D4 ; counter lsr.l #1,D4 ; counter / 2 move.b 0(A0,D4.l),D5 ; d = source[i] btst #0,D3 ; even or odd, i.e. low nibble or high nibble to affect beq.s .highnibble .lownibble andi.b #15,D5 ; d &= 15 (only low nibble (4 bits)) bra.s .store .highnibble lsr.b #4,D5 ; d / 16 (high nibble (4 bits) on low nibble's position) .store move.b 0(A2,D5.w),D4 ; Delta out of table add.b D4,D1 ; x += Delta move.b D1,0(A1,D3.l) ; write data value (uncompressed now!) addq.l #1,D3 ; i ++ .checkend cmp.l D3,D2 bhi.s .next movem.l (sp)+,D2-D5/A2 move.b D1,D0 ; return x rts __DeltaTable dc.b -34,-21,-13,-8,-5,-3,-2,-1,0,1,2,3,5,8,13,21 ************************************************* * ** Init Audio Hit Gadget * _DisplayAudioGadget movem.l D2/A2-A3,-(sp) lea _Gad3(A5),A2 clr.l (A2) move.w #8,gg_LeftEdge(A2) move.w #6,gg_TopEdge(A2) move.w #45,gg_Width(A2) move.w #28,gg_Height(A2) move.w #GADGHIMAGE|GADGIMAGE,gg_Flags(A2) move.w #BoolGadFlags,gg_Activation(A2) move.w #BOOLGADGET,gg_GadgetType(A2) move.w #3,gg_GadgetID(A2) lea _Image.3(pc),A0 lea _Image.4(pc),A1 move.l A0,gg_GadgetRender(A2) move.l A1,gg_SelectRender(A2) lea _startup(pc),A0 ; First instruction of Viewer (startup-code) subq.l #4,A0 ; Pointer to BPTR next hunk movea.l (A0),A0 ; BPTR NextHunk adda.l A0,A0 adda.l A0,A0 ; APTR NextHunk addq.l #4,A0 ; Section Chip (_Gad.1, size 190 bytes) lea 380(A0),A0 ; Skip both images (each 190 bytes) lea 336(A0),A1 ; Pointer to Select Audio Image lea _Image.3(pc),A2 lea _Image.4(pc),A3 move.l A0,ig_ImageData(A2) move.l A1,ig_ImageData(A3) movea.l _WindowPtr(A5),A0 ; Window movea.l wd_RPort(A0),A3 ; ^RastPortPtr lea _Gad3(A5),A1 ; Audio gadget moveq #0,D0 ; Begin with number zero moveq #-1,D1 ; All gadgets moveq #0,D2 movea.l D2,A2 ; No requester move.l _IntuitionBase(A5),A6 jsr _LVOAddGList(A6) ; Set gadgets to window lea _Gad3(A5),A0 ; Gadgets movea.l _WindowPtr(A5),A1 ; Window moveq #0,D2 movea.l D2,A2 ; No requester jsr _LVORefreshGList(A6) ; Draw gadgets st.b _AudGadget(A5) movem.l (sp)+,D2/A2-A3 rts _RemoveAudioGadget tst.b _AudGadget(A5) beq.s 1$ movea.l _WindowPtr(A5),A0 lea _Gad3(A5),A1 moveq #1,D0 movea.l _IntuitionBase(A5),A6 jsr _LVORemoveGList(A6) clr.b _AudGadget(A5) 1$ rts ******************************************************** * * (C) 1994 J.v.d.Loo * * AA-support routines * * Decompressor and 32 bit gun colour converter * * Taken out of BitMapSaver * * Inputs: none * Results: D0 = 1 when all went ok * * ------------------------------------------------------ * * This is an fully decrompress routine for images of 64bit boundary (modulo). _Convert movem.l D2-D6/A2-A4,-(sp) bsr.w _Init24BitPal ; Grey colour image setup when no palette set... movea.l _WindowPtr(A5),A0 ; Window movea.l wd_RPort(A0),A0 ; Its rastport movea.l rp_BitMap(A0),A0 ; BitMap being used moveq #BMA_FLAGS,D1 ; Ask for flags being used movea.l _GfxBase(A5),A6 cmpi.w #38,LIB_VERSION(A6) ; OS 3 required for this check bls.s .std ; If not available, treat it as the original GFX device * is used... jsr _LVOGetBitMapAttr(A6) andi.l #BMF_STANDARD,D0 ; Standard bitmap or one created by a 3rd graphic device? beq.s .alien .std move.l #MEMF_CHIP,_TypeOfMem(A5) ; BitMap forced to CHIP-RAM (standard AMIGA device) bra.s .doconvert .alien move.l #0,_TypeOfMem(A5) ; BitMap forced to FAST-RAM (3rd party GFX device) .doconvert movea.l _SourceFilePtr(A5),A0 ; Address datas cmpi.l #'FORM',(A0)+ ; IFF ? bne.w .finish_1 addq.l #4,A0 ; Length IFF-file!?!? cmpi.l #'ACBM',(A0) bne.s .check4ILBM addq.l #4,A0 bra.s .okType .check4ILBM cmpi.l #'ILBM',(A0)+ ; Picture? bne.w .finish_1 .okType move.l _SourceFileSize(A5),D4 subi.l #12,D4 ; Length datas - length header .searchChunks subq.l #4,D4 ; Length datas -4 beq.w .finish_1 ; If end reached bmi.w .finish_1 move.l (A0)+,D3 ; Chunk-name cmpi.l #'BMHD',D3 ; Bitmap-header? beq.s .foundBMHD cmpi.l #'CAMG',D3 ; ViewPort-display? beq.w .foundCAMG cmpi.l #'CMAP',D3 ; Colour-map? beq.w .foundCMAP cmpi.l #'BODY',D3 ; Datas? beq.w .foundBODY cmpi.l #'ABIT',D3 ; Amiga Bitplane Datas? beq.w .foundABIT .unknownChunk subq.l #4,D4 ; Datas -4 move.l (A0)+,D0 ; Length of this chunk addq.l #1,D0 andi.l #-2,D0 ; Through 2 divisible sub.l D0,D4 ; Datas minus (over)readed entries lea 0(A0,D0.w),A0 ; New address bra.s .searchChunks .foundBMHD subq.l #4,D4 ; Datas -4 move.l (A0)+,D0 ; Save number entries lea _Width(A5),A1 ; Address data-array moveq #0,D1 move.w (A0),D1 ; Get width move.l D1,_RealIWidth(A5) ; Non aligned width of image addi.l #15,D1 andi.l #-16,D1 move.l D1,_ImageWidth(A5) ; Save dafault width (aligned) addi.l #63,D1 andi.l #-64,D1 ; Set up to BURST-FETCH mode, needed for AGA move.w D1,(A1) ; Save width move.w 2(A0),2(A1) ; Height move.w 4(A0),4(A1) ; X-Position move.w 6(A0),6(A1) ; Y-Position move.b 8(A0),8(A1) ; Depth move.b 9(A0),9(A1) ; Masking-type move.b 10(A0),10(A1) ; compression-mode move.b 11(A0),11(A1) ; Unused move.w 12(A0),12(A1) ; Transparent colour move.b 14(A0),14(A1) ; X-aspect move.b 15(A0),15(A1) ; Y-aspect move.w 16(A0),16(A1) ; Page width move.w 18(A0),18(A1) ; Page height lea (A0,D0.w),A0 ; Overread header sub.l D0,D4 ; Length Datas minus entries bra.w .searchChunks .foundCAMG subq.l #4,D4 ; Datas -4 move.l (A0)+,D0 ; Length addq.l #1,D0 andi.l #-2,D0 ; Through 2 divisible move.l (A0),_ViewPortMod(A5) ; ViewPort mode andi.l #$FFFF9ABD,_ViewPortMod(A5) ; means: * bclr #1,D0 ; no genlocVideo * bclr #6,D0 ; no pfba * bclr #8,D0 ; no genlocAudio * bclr #10,D0 ; no dualpf * bclr #13,D0 ; no vpHide * bclr #14,D0 ; no sprites lea 0(A0,D0.w),A0 ; Skip unused sub.l D0,D4 ; Length datas bra.w .searchChunks .foundCMAP subq.l #4,D4 ; Datas -4 move.l (A0)+,D0 ; Entry length (ever through 2 divisible!!!) move.l D0,-(sp) ; Remember divu.w #3,D0 ; /3 andi.l #$FFFF,D0 move.l D0,_CMapNumEntries(A5) ; = number of words of Colourmap lea _Colourmap(A5),A1 ; Address colour-array move.l A0,_RGB32Values(A5) move.l A0,-(sp) cmpi.l #256*3,D0 bhi.s .getRGB32 .getRGB moveq #0,D1 move.b (A0)+,D1 ; R-value andi.w #$F0,D1 lsl.w #4,D1 ; Clear Half-byte position (G-value) move.b (A0)+,D2 ; G-value andi.w #$F0,D2 ; Mask it out or.w D2,D1 ; Store G-value move.b (A0)+,D2 ; B-value andi.w #$F0,D2 lsr.b #4,D2 ; Half-byte position or.w D2,D1 ; D1 = RGB-word move.w D1,(A1)+ ; Store RGB-word subq.l #1,D0 bgt.s .getRGB .getRGB32 move.l _CMapNumEntries(A5),D0 movea.l _RGB32Values(A5),A0 lea _RGB32Colours(A5),A1 bsr.w _RGBtoRGB32 movea.l (sp)+,A0 move.l (sp)+,D0 addq.l #1,D0 andi.l #-2,D0 sub.l D0,D4 ; Datas minus (over)readed entries lea 0(A0,D0.l),A0 ; New address bra.w .searchChunks .foundBODY cmpi.b #1,_Compresstyp(A5) bhi.w .finish_3 tst.b _Masking(A5) beq.s .go move.b _Masking(A5),D0 btst.l #0,D0 beq.s .go tst.b _NoWarnFlag(A5) bne.s .go movem.l A0-A1,-(sp) lea _WarnMaskingTxt(pc),A0 ; MASKING = DATA of 1st line for all bitplanes + masking line bsr.w _DisplayError ; DATA of 2nd line for all bitplanes + masking line move.l #5,_errno(A5) ; DATA of 3rd line for all bitplanes + masking line movem.l (sp)+,A0-A1 ; ........... and so on .go lea _BitmapStruc(A5),A2 ; Address bitmap-structure moveq #23,D0 addq.l #8,A2 .clear clr.l (A2)+ ; Clear all 24 bitplane pointers subq.w #1,D0 bcc.s .clear lea _BitmapStruc(A5),A2 ; Address bitmap-structure moveq #0,D0 ; Clear it move.w _Width(A5),D0 ; Pixel width lsr.w #3,D0 ; /8 = bytes move.w D0,(A2)+ ; Bytes per row move.w _Height(A5),(A2)+ ; Height graphic move.b _Depth(A5),1(A2) ; Number of bitplanes * ** Allocate needed bitplanes (all in once). ** <- D0 still holds number of bytes per line. * move.l A0,-(sp) ; Save current address movea.l _SysBase(A5),A6 ; Base Exec mulu.w _Height(A5),D0 ; = size of one bitplane move.l D0,D2 ; to D2 moveq #0,D1 ; Clear it move.b _Depth(A5),D1 ; Number of bitplanes * ** For those bug I searched 3 days... - so stupid I'm. ** I use normally images up to 736*566 pixel, that means that one plane is ** 736/8*566 pixel = 52072 bytes large, this size fits in a word, ** so "mulu" #8,Dx did not cause trouble (for 8 bitplanes). ** While testing "BitMapSaver" with an images of 960*724 pixel width, my ** A4000 crashed - no guru but no input was furthermore possible! ** Today I got it. 960/8 = 120 = fits in a word, mulu #724,120 = ? - ** 86880 bytes = longword!!! Until that point all went ok, but after ** mulu.w #8,86880 (8 bitplanes) the value was not as you may expect 695040 ** instead of it 170752 was returned. So the images was loaded to unallocated ** memory, "Amiga hang up". ** The crash occurred each time when DOS-function "Write" was called - and ** because there is a bug in the v39 ROM of the dos.library, I thought this ** was a bug of it, too. ** [( v39 bug: After a read/write error occures and the "Write"-routine returns ** to the program, the baseregister A6 does not contain the DOSBase any more.)] ** But further: ** The mistake I made was to multiply a longword with a word - what is not ** possible with the 68000 instruction "mulu.w". I know this, but I never ** cared in this routine about it.... ** But... here is the solution... * moveq #0,D0 ; Zero !!! bra.s .x1 .mul add.l D2,D0 ; Longword multiply!!! .x1 dbf D1,.mul move.l D0,_AllPlaneSize(A5) ; Save size of all bitplanes move.l _TypeOfMem(A5),D1 ; Set as CHIP or FAST ori.l #MEMF_CLEAR,D1 ; Requirements jsr _LVOAllocMem(A6) ; Mem demand move.l D0,_Bitplane(A5) ; Save memory address beq.w .finish_2 ; If error lea _BitmapStruc(A5),A0 ; Address bitmap-structure moveq #0,D1 ; Clear it move.w (A0),D1 ; Bytes per row mulu.w 2(A0),D1 ; Number bytes of one bitplane moveq #0,D2 move.b 5(A0),D2 ; Number of bitplanes addq.l #8,A0 ; Address constant for first plane movea.l D0,A1 ; Address memory .StoreBPPtr move.l A1,(A0)+ ; Set address of bitplane to constant add.l D1,A1 ; Get next bitplane's memory address subq.b #1,D2 ; Decrease number of bitplanes bne.s .StoreBPPtr ; If not all are set yet... * ** Do it normal. * movea.l (sp)+,A0 ; Get back current address move.l D4,D2 ; Size in bytes of datas moveq #0,D0 ; Initialiize them with NULL for first time move.l D0,D1 move.l D1,D3 move.l D3,D4 move.l D4,D5 ; Linecounter addq.l #4,A0 subq.l #4,D2 lea _BitmapStruc(A5),A2 ; Address bitmap-structure addq.l #8,A2 ; Address pointer to first bitplane move.w _Width(A5),D3 ; Pixelwidth of image lsr.w #3,D3 ; in bytes move.b _Depth(A5),D4 ; Number of planes tst.b _Compresstyp(A5) bne.s .Decompress ; If compressed... movem.l D0-D1/A0-A1,-(sp) tst.b _NoWarnFlag(A5) bne.s .NoWarn.1 lea _WarnUncompressedTxt(pc),A0 bsr.w _DisplayError move.l #5,_errno(A5) .NoWarn.1 movem.l (sp)+,D0-D1/A0-A1 bra.w .StoreUnpacked .Decompress moveq #0,D6 ; Bitplanecounter .Decompressing lsl.w #2,D6 ; Bitplanecounter * 4 = longword adjustment movea.l 0(A2,D6.w),A3 ; Current bitplane lsr.w #2,D6 ; Normal * Instead of the last three lines you can write * movea.l 0(A2,D6.w*4),A3 * if you have a turboboard. move.w D3,D0 ; Bytes per line mulu.w D5,D0 ; mutilply with current line lea 0(A3,D0.l),A3 ; Startoffset to A3 movea.l A3,A4 ; Address plane(x) to A4 move.l _ImageWidth(A5),D0 ; Real pixel width of image lsr.w #3,D0 ; in bytes lea 0(A4,D0.w),A4 ; == End of line .CheckOperation subq.l #1,D2 ; Data counter bmi.w .IncorrectSize moveq #0,D0 move.b (A0)+,D0 cmpi.b #-128,D0 ; #-128 = no operation beq.s .NoOperation cmpi.b #127,D0 bhi.s .StoreNeg ; If negativ (greater #128!) .CopyBytes subq.l #1,D2 bmi.w .IncorrectSize move.b (A0)+,(A3)+ dbf D0,.CopyBytes bra.s .NoOperation .StoreNeg neg.b D0 ; To positive value subq.l #1,D2 bmi.w .IncorrectSize move.b (A0)+,D1 ; Next byte .StoreNegCopy move.b D1,(A3)+ ; Store byte dbf D0,.StoreNegCopy ; While not all .NoOperation tst.l D2 beq.w .finish bmi.s .IncorrectSize cmpa.l A3,A4 ; Position(x),line(x) the same as * ; the end of line(x),plane(x)? bhi.s .CheckOperation addq.w #1,D6 ; Increase planecounter cmp.w D4,D6 ; Last plane? bne.s .Decompressing move.b _Masking(A5),D0 btst.l #0,D0 beq.s .goon bsr.w _IgnoreCompMaskLine .goon addq.w #1,D5 ; Next line lea _BitmapStruc(A5),A1 cmp.w 2(A1),D5 ; Last line? bne.s .Decompress bra.w .finish .StoreUnpacked moveq #0,D6 ; Bitplanecounter .StoreUncompress lsl.w #2,D6 ; Bitplanecounter * 2 = longword adjustment movea.l 0(A2,D6.w),A3 ; Current bitplane lsr.w #2,D6 ; Normal move.w D3,D0 ; Bytes per line mulu.w D5,D0 ; multiply with current line lea 0(A3,D0.l),A3 ; StartOffset to A3 movea.l A3,A4 ; Address plane(x) to A4 move.l _ImageWidth(A5),D0 ; Real pixel width of image lsr.w #3,D0 ; in bytes lea 0(A4,D0.w),A4 ; == End of line * move.w D0,D0 ; Set counter (already done!) bra.s .StoreUncmp_1 ; 'Cause of DBF .StoreUncmp move.b (A0)+,(A3)+ ; Copy byte into bitplane .StoreUncmp_1 dbf D0,.StoreUncmp ; until all are done addq.w #1,D6 ; Increase planecounter cmp.w D4,d6 ; All planes worked out? bne.s .StoreUncompress ; No - so do further move.b _Masking(A5),D0 btst.l #0,D0 beq.s .goon1 bsr.w _IgnoreMaskLine .goon1 addq.w #1,D5 ; Next line lea _BitmapStruc(A5),A1 cmp.w 2(A1),D5 ; Last line? bne.s .StoreUnpacked ; No... bra.s .finish .IncorrectSize lea _IncorrectSizeTxt(pc),A0 bsr.w _DisplayError move.l #20,_errno(A5) movem.l (sp)+,D2-D6/A2-A4 moveq #0,D0 ; Bad IFF-file rts .finish_3 lea _NoByteRunTxt(pc),A0 bsr.w _DisplayError move.l #20,_errno(A5) movem.l (sp)+,D2-D6/A2-A4 moveq #0,D0 ; Unknown compression methode rts .finish_2 lea _AllocBufErrTxt(pc),A0 bsr.w _DisplayError addq.w #4,sp ; Overread "move.l A0,-(sp)" movem.l (sp)+,D2-D6/A2-A4 moveq #-1,D0 ; Error, no mem rts .finish_1 lea _NoIFFFileTxt(pc),A0 bsr.w _DisplayError move.l #20,_errno(A5) movem.l (sp)+,D2-D6/A2-A4 moveq #0,D0 ; Not an IFF-file rts .finish movem.l (sp)+,D2-D6/A2-A4 moveq #1,D0 ; No error rts * ** This is the engine to store the datas of the ABIT-chunk into the ** planar-datas needed for plain Amigas-screens. I ask myself a lot times ** why no demo-coder use this type of data, instead of it they use RAW-datas ** which is the same, but without an IFF-header... * .foundABIT lea _BitmapStruc(A5),A2 ; Address bitmap-structure moveq #0,D0 ; Clear it move.w _Width(A5),D0 ; Pixel width lsr.w #3,D0 ; /8 = bytes move.w D0,(A2)+ ; Bytes per row move.w _Height(A5),(A2)+ ; Height graphic move.b _Depth(A5),1(A2) ; Number of bitplanes * ** Allocate needed bitplanes (all in once). ** <- D0 still holds number of bytes per line. * move.l A0,-(sp) ; Save current address mulu.w _Height(A5),D0 ; = size of one bitplane move.l D0,D2 ; to D2 move.b _Depth(A5),D1 ; Number of bitplanes moveq #0,D0 ; Zero !!! .addsize add.l D2,D0 ; Longword multiply!!! subq.b #1,D1 bne.s .addsize move.l D0,_AllPlaneSize(A5) ; Save size of all bitplanes move.l #MEMF_CHIP|MEMF_CLEAR,D1 ; Requirements movea.l _SysBase(A5),A6 ; Base Exec jsr _LVOAllocMem(A6) ; Mem demand move.l D0,_Bitplane(A5) ; Save memory address beq.s .finish_2 ; If error lea _BitmapStruc(A5),A0 ; Address bitmap-structure move.w (A0),D1 ; Bytes per row mulu.w 2(A0),D1 ; Number bytes of one bitplane move.b 5(A0),D2 ; Number of bitplanes addq.l #8,A0 ; Address constant for first plane movea.l D0,A1 ; Address memory .StoreBAddr move.l A1,(A0)+ ; Set address of bitplane to constant adda.l D1,A1 ; Get next bitplane's memory address subq.b #1,D2 ; Decrease number of bitplanes bne.s .StoreBAddr ; If not all are set yet... movea.l (sp)+,A0 ; Get back current address (source) addq.l #4,A0 ; Overread length entry move.l D4,D2 ; Size in bytes of datas subq.l #8,D2 ; Minus two longword ( ABIT[length] ) lea _BitmapStruc(A5),A2 ; Address bitmap-structure addq.l #8,A2 ; Address pointer to first bitplane moveq #0,D3 move.w _Width(A5),D3 ; Pixelwidth of page (64 bit boundary) lsr.w #3,D3 ; in bytes move.l _ImageWidth(A5),D4 ; Aligned width (16 bit boundary) lsr.l #4,D4 ; in words move.w _Height(A5),D5 ; Number of lines move.b _Depth(A5),D6 ; Number of planes * A0 - original Datas * A2 - BitPlane-Address-Array * D2 - length original Datas * D3 - Pagewidth (boundary 64 bit) in bytes (longword) * D4 - Image width ( boundary 16 bit) * D5 - Height of Image in number of lines * D6 - Depth subq.w #1,D4 ; 'Cause of DBF subq.w #1,D5 ; 'Couse of DBF move.w D4,D1 move.w D5,D0 movea.l (A2)+,A3 ; Out of constant address of bitplane movea.l A3,A4 ; ...also in A4 adda.l D3,A4 ; Next line's address (destination) after comming loop .copyLine move.w (A0)+,(A3)+ ; Store data-word subq.l #2,D2 beq.w .finish bcs.w .IncorrectSize dbf D1,.copyLine ; Store this line... movea.l A4,A3 ; Next line's address into A3 adda.l D3,A4 ; Add bytesize of one line to A4 move.w D4,D1 ; Image width in number of words dbf D0,.copyLine ; Store next line subq.b #1,D6 ; One less bitplane to go... beq.w .finish * One complete Bitplane stored, so do next movea.l (A2)+,A3 ; Next bitplane's address out of constant movea.l A3,A4 ; Address also in A4 adda.l D3,A4 ; Address next line of this Bitplane move.w D5,D0 ; Number of lines move.w D4,D1 ; Image width in number of words bra.s .copyLine ; Store next bitplane * ** These routines are only called if a mask is set for the picture (brush) * _IgnoreMaskLine ; Uncompressed IFF move.l _ImageWidth(A5),D0 lsr.w #3,D0 adda.l D0,A0 sub.l D0,D2 rts _IgnoreCompMaskLine ; Compressed IFF move.l D3,-(sp) move.l _ImageWidth(A5),D3 lsr.w #3,D3 moveq #0,D1 .CheckOperation cmp.w D3,D1 beq.s .out subq.l #1,D2 ; Data counter bmi.s .out moveq #0,D0 move.b (A0)+,D0 cmpi.b #-128,D0 ; #-128 = no operation beq.s .NoOperation cmpi.b #127,D0 bhi.s .StoreNeg ; If negativ (greater #128!) .CopyBytes subq.l #1,D2 bmi.s .out addq.l #1,A0 ; Store byte of mask to nowhere... addq.w #1,D1 dbf D0,.CopyBytes bra.s .NoOperation .StoreNeg neg.b D0 ; To positive value subq.l #1,D2 bmi.s .out addq.l #1,A0 .StoreNegCopy addq.w #1,D1 ; Store byte of mask to nowhere and decrease counter... dbf D0,.StoreNegCopy ; While not all .NoOperation tst.l D2 bmi.s .out bra.s .CheckOperation .out movem.l (sp)+,D3 rts ************************************************************* * * Init the standard palette (RGB32) to one which contains * only grey values, so called Grey Palette. * Since the OS doesn't support 24 bit screens and 3rd party * GFX boards will not allow custom applications to copy * 24 bitplanes into a screen they made via OS functions, * the first 8 bitplanes are treated as they contain only grey * colours (those 8 which we gonna display). * When there is a device that will allow to copy 24 bitplanes * to a screen, Viewer can display it immediately, since * I never stripped the code to support only 8 bitplanes, * although 3rd party graphic board software emulation does! * _Init24BitPal move.l #256,D0 lea _RGB32Colours(A5),A1 move.l D0,D1 swap D1 ; number of colours (1st word) start at colour (2nd word) move.l D1,(A1)+ ; store number of entries in table and * startoffset for colours .GoAhead movem.l D2-D4,-(sp) moveq #0,D1 moveq #0,D2 moveq #0,D3 bra.s .sneek .convert moveq #2,D4 ; 3 loops .storeOneLW * move.b D1,D1 ; the value move.b D1,D3 ; save it andi.b #$F,D3 ; only low nibble move.b D3,D2 ; also in D2 lsl.b #4,D2 ; store it as high nibble add.b D3,D2 ; add low nibble move.b D1,(A1)+ ; save high byte of high word move.b D2,(A1)+ ; save low byte of high word move.b D2,(A1)+ ; save high byte of low word move.b D2,(A1)+ ; save low byte of low word dbf D4,.storeOneLW ; for one colour (R, G, B) addq.b #1,D1 .sneek dbf D0,.convert moveq #0,D0 move.l D0,(A1) ; terminator!!! movem.l (sp)+,D2-D4 rts *************************************************************** * ** Check if the hardware display supports 8 bit per gun as the ** original AMIGA hardware. If not, brighten up the display... * ** Because only simple device for the AMIGA are available (3rd ** party gfx-boards) this routine might not work perfectly since ** those cards don't work proberly in an AMIGA surround due to ** their limits and not implemented AMIGA features: ** only 3 colour sprites, only one sprite, no soft-scrolling ** screens, no overscan, only one hardware screen, incorrect ** bits per gun (a 256 colour display offers only 262144 colour ** palette) where the original double A chip set offers 16.7 million!) ** and a lot more. * _BrightenColours movem.l D0-D2/A0-A1/A6,-(sp) * GetDisplayInfoData( 0, di, sizeof( di), DTAG_DISP, DisplayID) suba.l A0,A0 ; Handle lea _DisplayInfo(A5),A1 ; Buffer moveq #dis_SIZEOF,D0 ; sizeof move.l #DTAG_DISP,D1 ; TAG move.l _ViewPortMod(A5),D2 ; DisplayID movea.l _GfxBase(A5),A6 cmpi.w #38,LIB_VERSION(A6) beq.s .done ; Since we have not AMIGA OS3... jsr _LVOGetDisplayInfoData(A6) tst.l D0 beq.s .done lea _DisplayInfo(A5),A0 move.b RedBits(A0),D0 cmpi.b #7,D0 bls.s .adjust move.b GreenBits(A0),D0 cmpi.b #7,D0 bls.s .adjust move.b BlueBits(A0),D0 cmpi.b #7,D0 bhi.s .done .adjust * AdjustPal32( struct DisplayInfo *, struct RGB32 *) lea _RGB32Colours(A5),A1 bsr.s _AdjustPal32 .done movem.l (sp)+,D0-D2/A0-A1/A6 rts *********************************************************** * ** Adjust (brighten) RGB32 colour table values to supported ** less than 8 bits per gun. * ** This routine was just a quick hack... * ** Only useful when a simple 3rd party graphic device is ** installed, such as for IBM-compatible computers which are ** adapted to the AMIGA system, e.g. Picasso II(+) & IV, ** Picollo, Picollo SD 64, Retina Z2 & Z3, CyberVision 64, ** CyberVision 64 3D etc. . ** Does the GVP (Spectrum) and the Merlin support 8 bit per ** gun also in non 24 bit displays? If you know, tell me. * _AdjustPal32 movem.l D2-D7,-(sp) btst #7,_BMHDFlags(A5) ; Indicates if colourmap of file is bne.s .RGB32 ; stored as 8-bit values (AGA resolution (RGB32)) * ** This one is to convert the original RGB4 values (now RGB32) to values ** which looks on this simple device (3rd party gfx device) the same as ** with the OCS or ECS CHIP SET. * .RGB4 move.b RedBits(A0),D5 ; e.g. 6 moveq #8,D0 sub.b D5,D0 ; 8 - 6 = 2 moveq #16,D5 mulu.w D0,D5 ; = 16 move.b GreenBits(A0),D6 ; e.g. 5 moveq #8,D0 sub.b D6,D0 ; 8 - 5 = 3 moveq #16,D6 mulu.w D0,D6 ; = 24 move.b BlueBits(A0),D7 ; e.g. 4 moveq #8,D0 sub.b D7,D0 ; 8 - 4 = 4 moveq #16,D7 mulu.w D0,D7 ; = 32 bra.s .doit * ** This one to adjust palette to reflect less bits per gun as the AA (AGA) hardware. * .RGB32 moveq #0,D0 move.b RedBits(A0),D0 ; e.g. 6 moveq #32,D1 ; = 32 (256 luminanz / 8 bit per luminanz = 32) mulu.w D0,D1 ; 6 * 32 = 192 move.l #256,D5 sub.w D1,D5 ; 256 - 192 = 64 divu.w D0,D5 ; 64 / 6 = ~10 moveq #0,D0 move.b GreenBits(A0),D0 ; e.g. 5 moveq #32,D1 ; = 32 (256 luminanz / 8 bit per luminanz = 32) mulu.w D0,D1 ; 5 * 32 = 160 move.l #256,D6 sub.w D1,D6 ; 256 - 160 = 96 divu.w D0,D6 ; 96 / 5 = ~19 moveq #0,D0 move.b BlueBits(A0),D0 ; e.g. 4 moveq #32,D1 ; = 32 (256 luminanz / 8 bit per luminanz = 32) mulu.w D0,D1 ; 4 * 32 = 128 move.l #256,D7 sub.w D1,D7 ; 256 - 128 = 128 divu.w D0,D7 ; 128 / 4 = 32 .doit move.l (A1)+,D0 ; Number of colours (1st word, offset colour 2nd word) swap D0 ; D0 = number colours used bra.s .dec .loop move.l D0,-(sp) ; number of colours move.l (A1),D0 ; Colour value (red) (32 bit) moveq #24,D1 ; into lsr.l D1,D0 ; lowest byte add.w D5,D0 .adjred cmpi.w #255,D0 ; Range check bls.s .okred move.l #255,D0 .okred bsr.s .storeNew move.l (A1),D0 ; Colour value (green) (32 bit) moveq #24,D1 ; into lsr.l D1,D0 ; lowest byte add.w D6,D0 .adjgreen cmpi.w #255,D0 ; Range check bls.s .okgreen move.l #255,D0 .okgreen bsr.s .storeNew move.l (A1),D0 ; Colour value (blue) (32 bit) moveq #24,D1 ; into lsr.l D1,D0 ; lowest byte add.w D7,D0 .adjblue cmpi.w #255,D0 ; Range check bls.s .okblue move.l #255,D0 .okblue bsr.s .storeNew move.l (sp)+,D0 .dec subq.w #1,D0 bcc.s .loop movem.l (sp)+,D2-D7 rts .storeNew move.w D0,D1 lsl.w #8,D0 andi.w #$F,D1 ; Only low nible move.b D1,D0 lsl.b #4,D1 or.b D0,D1 move.b D1,D0 lsl.l #8,D0 move.b D1,D0 lsl.l #8,D0 move.b D1,D0 move.l D0,(A1)+ ; Store new computed red value rts ******************************************************** * V39 RGB32 format * * Highest byte of longword contains colour-value, e.g. 237 (0xED). * The rest (lower 3 bytes) containing the low nibble of * the highest byte, here 13, fully: * ED DD DD DD == 0xEDDDDDDD * * Inputs: D0 - number of colours to convert (max. 256) * A0 - RGB source table (like CMAP chunk) * A1 - RGB32 destionation buffer (safety = (256*3+2)*4 bytes large) * Results: RGB32 buffer filled with 32bit RGB values (used by LoadRGB32, SA_Colors32) * D0 == -1L on error (too much colours, max. 256) _RGBtoRGB32 ; (colours, tableRGB, tableRGB32)(D0, A0, A1) andi.l #$1FF,D0 ; max 256 colours cmpi.w #256,D0 bls.s .cok ; if not more colours move.l #256,D0 .cok move.l D0,D1 swap D1 ; number of colours (1st word) start at colour (2nd word) move.l D1,(A1)+ ; store number of entries in table and * startoffset for colours btst #7,_BMHDFlags(A5) ; Full byte used by colour value? bne.s .GoAhead ; If so... cmpi.w #32,D0 ; More than 32 colours? bhi.s .AGA ; Assumption: an AGA-picture where the programmer forgot * to set the bit bsr.s .ModifyColours ; Else take as 4-bit bra.s .GoAhead .AGA bset #7,_BMHDFlags(A5) ; Indicates it's valid .GoAhead movem.l D2-D4,-(sp) moveq #0,D1 moveq #0,D2 moveq #0,D3 bra.s .sneek .convert moveq #2,D4 ; 3 loops .storeOneLW move.b (A0)+,D1 ; get value move.b D1,D3 ; save it andi.b #$F,D3 ; only low nibble move.b D3,D2 ; also in D2 lsl.b #4,D2 ; store it as high nibble add.b D3,D2 ; add low nibble move.b D1,(A1)+ ; save high byte of high word move.b D2,(A1)+ ; save low byte of high word move.b D2,(A1)+ ; save high byte of low word move.b D2,(A1)+ ; save low byte of low word dbf D4,.storeOneLW ; for one colour (R, G, B) .sneek dbf D0,.convert moveq #0,D0 move.l D0,(A1) ; terminator!!! movem.l (sp)+,D2-D4 rts .failed moveq #-1,D0 rts * ** Change 4-bit colour value to 8-bit colour value ( needed for LoadRGB32() ) * .ModifyColours movem.l D0-D2/A0,-(sp) bra.s 2$ 1$ move.b (A0)+,D1 ; Get value andi.b #$F0,D1 ; Ignore unused nibble move.b D1,D2 ; Save result lsr.b #4,D2 ; High nibble to low nibble add.b D2,D1 ; Make new value move.b D1,-1(A0) ; Store new computed value 2$ dbf D0,1$ ; Until all are done movem.l (sp)+,D0-D2/A0 rts ******************************************************** * ** This routine will only be called before the dimension ** and MonitorID grab is fired up! * _CheckEHB movem.l D0-D2/A0-A1,-(sp) move.l _ViewPortMod(A5),D0 ; Original (not modified till now) andi.l #V_EXTRA_HALFBRITE,D0 beq.s .done lea _RGB32Colours(A5),A0 move.l (A0),D0 ; Get color offset and amount colors e.g. 0x00200000 swap D0 ; e.g. 0x00000020 moveq #0,D2 move.w D0,D2 ; Remember amount colors (e.g. 32) add.w D0,D0 ; Double amount of colors (e.g. 64) swap D0 move.l D0,(A0)+ ; Store new amount of colors move.l D2,D0 ; Amount colors (e.g. 32) move.l D0,D1 ; ditto lsl.l #3,D0 ; Amount colors * 8 lsl.w #2,D1 ; Amount colors * 4 add.l D1,D0 ; == amount colors in bytes (e.g. 32) * 12) lea 0(A0,D0.l),A1 ; Destination move.l D2,D0 ; e.g. 32 add.w D0,D0 ; == 64 add.w D2,D0 ; == 96 runs (== 384 bytes of source to touch) bra.s .loopdec .loop move.l (A0)+,D1 lsr.l #1,D1 move.l D1,(A1)+ .loopdec dbf D0,.loop clr.l (A1) .done movem.l (sp)+,D0-D2/A0-A1 rts ************************** * * Convert binary to ascii. * * Inputs: none * Results: none * _ConvertBinary movem.l D2-D7/A2-A4,-(sp) move.l _BufferSize(A5),D2 ; Length allocated buffer move.l _FileSize(A5),D3 ; Real filelength movea.l _TextPtr(A5),A2 ; Adress buffer addq.l #2,A2 ; Skip #$020A bsr.w _GetConvertedSize move.l D0,D4 ; Save new size move.l #MEMF_PUBLIC|MEMF_CLEAR,D1 movea.l _SysBase(A5),A6 jsr _LVOAllocMem(A6) movea.l D0,A4 ; Save new buffer pointer tst.l D0 beq.w .ErrorAlloc ; Upon error movea.l D0,A3 ; Address buffer move.w #$200A,(A3)+ ; Write Blank and LineFeed * A4 - allocated buffer - do not scratch * A3 - allocated buffer - used * A2 - old datas - used * D4 - allocated size - do not scratch * D3 - FileSize - used moveq #0,D7 ; New filesize moveq #-16,D5 ; Linenumber movea.l A3,A0 ; Address buffer 1$ tst.l D3 ; Soruce file end? beq.w .end ; If so... cmpi.l #15,D3 ; Do we have a rest of 4 longwords to convert? bls.w .ARest ; If not... addi.l #16,D5 ; Else add 16 bytes (4 longwords) move.l D5,D0 ; Line number bsr.w _comhex ; Convert count to ascii move.b #':',(A0)+ ; Write colon at end of number move.b #' ',(A0)+ ; Write 2 blanks move.b #' ',(A0)+ addi.l #11,D7 ; New filelength plus 11 bytes move.l (A2),D0 ; Get 1. longword of line to convert bsr.w _comhex ; Convert it to ascii move.b #' ',(A0)+ ; Write Blank addi.l #9,D7 ; New filesize plus 9 move.l 4(A2),D0 ; 2. longword bsr.w _comhex move.b #' ',(A0)+ addi.l #9,D7 move.l 8(A2),D0 ; 3. longword bsr.w _comhex move.b #' ',(A0)+ addi.l #9,D7 move.l 12(A2),D0 ; 4. longword bsr.w _comhex move.b #' ',(A0)+ move.b #' ',(A0)+ move.b #' ',(A0)+ move.b #' ',(A0)+ addi.l #12,D7 subi.l #16,D3 ; Old filesize -16 moveq #15,D0 ; 16 bytes to write 0$ move.b (A2)+,D1 ; Get byte cmpi.b #31,D1 ; Displayable char? bls.s .exchange ; If not cmpi.b #160,D1 ; Displayable char? bhi.s .ok ; If so cmpi.b #127,D1 ; Displayable char bls.s .ok ; If so .exchange move.b #'.',(A0)+ ; Not displayable, exchange through point bra.s 2$ .ok move.b D1,(A0)+ ; Displayable... 2$ dbf D0,0$ ; Number of bytes in one line (16) move.b #10,(A0)+ ; Write LineFeed addi.l #17,D7 ; New filelength +17 bra.w 1$ * ------------ * .ARest ; Less than 16 bytes.... addi.l #16,D5 ; Linenumber move.l D5,D0 ; Convert linenumber (binary) bsr.w _comhex ; into ascii-chars move.b #':',(A0)+ ; Write colon after linenumber move.b #' ',(A0)+ move.b #' ',(A0)+ addi.l #11,D7 ; New filelength +11 bytes movea.l A2,A1 ; Address current offset in source file move.l D3,D5 ; Rest-length of old file .longLoop cmpi.b #3,D5 ; Less than 3 bytes? bls.s .byteWidth subq.l #4,D5 ; Because one longword contains 4 bytes move.l (A1)+,D0 ; Get longword to convert bsr.w _comhex ; into ascii move.b #' ',(A0)+ addi.l #9,D7 ; New filesize plus 9 bra.s .longLoop .byteWidth subq.b #1,D5 ; Old filelength -1 bcs.s .MakeASCII ; When end is reached move.b (A1)+,D0 ; Get byte bsr.w _comhexByte ; and convert it into ascii addq.l #1,D7 ; New filelength +1 bra.s .byteWidth .MakeASCII move.l A0,-(sp) ; Current buffer address moveq #-1,D0 ; Counter 3$ cmpi.b #10,-(A0) ; Find LineFeed of last line dbeq D0,3$ not.l D0 ; Compute length movea.l (sp)+,A0 ; Current buffer address moveq #49,D1 ; At this position we write down the ascii-values sub.b D0,D1 4$ move.b #' ',(A0)+ ; Write as much Blank until we reach position 49 addq.l #1,D7 ; New filelength +1 dbf D1,4$ add.l D3,D7 ; Add rest of old filelength to new filelength move.l D3,D0 ; Rest subq.b #1,D0 ; Because of DBF 5$ move.b (A2)+,D1 ; Get value cmpi.b #31,D1 ; Displayable char? bls.s 6$ cmpi.b #160,D1 ; Displayable char? bhi.s 7$ cmpi.b #127,D1 ; Displayable char? bls.s 7$ 6$ move.b #'.',(A0)+ ; Not displayable! bra.s 8$ 7$ move.b D1,(A0)+ 8$ dbf D0,5$ bra.w .end ; ....finish * --------------- * .end move.b #10,(A0) ; Last char of file should be a LineFeed bsr.w _FreeFile ; Free old file (buffer) move.l A4,_TextPtr(A5) ; New buffer address move.l D4,_BufferSize(A5) ; New buffer size move.l D7,_FileSize(A5) ; New filesize movem.l (sp)+,D2-D7/A2-A4 rts .ErrorAlloc lea _AllocErrTxt(pc),A0 ; Display error bsr.w _DisplayError bsr.w _FreeFile ; Free old file movem.l (sp)+,D2-D7/A2-A4 addq.l #4,sp bra.w _Loop _GetConvertedSize move.l _FileSize(A5),D0 ; Original move.l D0,D1 lsl.l #2,D0 ; *4 lsr.l #2,D1 ; /4 add.l D1,D0 ; == * 4.25 addi.l #76,D0 ; For safety andi.l #-8,D0 ; Align size rts _comhex move.l D2,-(sp) moveq #7,D1 1$ rol.l #4,D0 move.l D0,D2 and.b #$F,D2 addi.b #'0',D2 cmpi.b #'9',D2 bls.s 2$ addq.b #7,D2 2$ move.b D2,(A0)+ dbf D1,1$ move.l (sp)+,D2 rts _comhexByte move.l D2,-(sp) moveq #1,D1 1$ rol.b #4,D0 move.b D0,D2 and.b #$F,D2 addi.b #'0',D2 cmpi.b #'9',D2 bls.s 2$ addq.b #7,D2 2$ move.b D2,(A0)+ dbf D1,1$ move.l (sp)+,D2 rts ****************************************************************************** * * This routine will extract the ASCII-characters of a `known' document. * It will only search for each known-chunk, remember the length of it, and * then it allocates a buffer based on the computed length, and after that, * it will re-scan the file and copy the plain characters into the new allocated * buffer. * * This routine is rather a joke than useful... * _LoadFCFile tst.b _NoWarnFlag(A5) ; Allowed to display warnings? bne.s .doit ; If not... lea _IFFAsciiTxt(pc),A0 ; Else, give out this bsr.w _DisplayError ; message tst.l D0 ; User said ok.? beq.w _BinaryFile ; If not, don't display... .doit movea.l _TextPtr(A5),A0 ; Start of datas addq.l #2,A0 ; Overread $200A ( Blank and LineFeed ) movea.l A0,A1 move.l _BufferSize(A5),D0 ; Get length of buffer subq.l #2,D0 ; Because of Blank and LineFeed ($200A) move.l D0,D1 moveq #0,D4 ; Amount of charcaters cmpi.l #'CAT ',(A0) beq.s .valid cmpi.l #'LIST',(A0) beq.s .valid cmpi.l #'FORM',(A0) ; Check IDs bne.w .errNonStd cmpi.l #'SWRT',8(A0) beq.s .valid cmpi.l #'WOWO',8(A0) beq.s .valid cmpi.l #'FTXT',8(A0) bne.w .errNonStd .valid lea 12(A0),A0 ; Pointer to e.g. "HYPH"-chunk sub.l #12,D0 .ChunkName cmpi.l #8,D0 ; Less than 9 bytes? ble.w .gotLength ; So call second pass move.l (A0),D3 ; Name of chunk move.l 4(A0),D2 ; Length of chunk cmpi.l #'FORM',D3 beq.s .skipType cmpi.l #'CAT ',D3 beq.s .skipType cmpi.l #'LIST',D3 beq.s .skipType cmpi.l #'PROP',D3 bne.s .goon .skipType lea 12(A0),A0 sub.l #12,D0 bra.s .ChunkName .goon addq.l #8,A0 ; Overread chunk-name and its size setting subq.l #8,D0 ; Rest of filelength bmi.w .errIncomplete ; Upon error cmpi.l #'CHRS',D3 ; Characters? beq.s .addLength cmpi.l #'RULE',D3 ; "RULE"-chunk treated as LineFeed beq.s .addLF cmpi.l #'WTXT',D3 ; "WTXT"-chunk treated as text beq.s .addLength addq.l #1,D2 ; Make chunk-size even andi.l #-2,D2 add.l D2,A0 ; Pointer to next chunk sub.l D2,D0 ; Rest of filelength bra.s .ChunkName ; and scan... .addLength ; CHRS-chunk found tst.l D2 ; CHRS-chunk with size zero? bne.s .asciichars ; If size set addq.l #1,D4 ; else size == 0 so set a LineFeed bra.s .next .asciichars add.l D2,D4 ; else add size .next addq.l #1,D2 ; Make chunk-size even andi.l #-2,D2 add.l D2,A0 ; Pointer to next chunk sub.l D2,D0 bra.w .ChunkName .addLF ; RULE-chunk is treated as a LineFeed addq.l #1,D4 ; Size plus 1 addq.l #1,D2 ; Make chunk-size even andi.l #-2,D2 add.l D2,A0 ; Pointer to next chunk sub.l D2,D0 bra.w .ChunkName ***************************** * Parsing done ( first pass ) * Now allocate the buffer and * store the characters. .gotLength move.l _PageWidth(A5),D7 ; Limit for word-wrap move.l D4,D5 ; Size of characters add.l #15,D5 ; Plus 7 and! plus 8 bytes (8-Bytes = $200A at front and $0A * at end of datas ( rest for safety )) andi.l #-8,D5 ; Make size divisible through eight (round it up) movem.l D1/A1,-(sp) ; Remember source and source's size move.l D5,D0 ; Size in bytes move.l #MEMF_CLEAR,D1 movea.l _SysBase(A5),A6 jsr _LVOAllocMem(A6) ; Mem demand movem.l (sp)+,D1/A1 tst.l D0 beq.w .errNoMem ; Upon error movea.l D0,A2 ; Destination movea.l A2,A3 ; Remember move.w #$200A,(A2)+ ; Write first down Blank and LineFeed movea.l A1,A0 ; Source move.l D1,D0 ; Length source lea 12(A0),A0 ; Pointer to first important chunk-name (e.g. HYPH) subi.l #12,D0 moveq #0,D6 ; Amount of chars in line... .checkChunk cmpi.l #8,D0 ; At least 8 bytes? ble.w .done ; else pass 2 ends... move.l (A0),D1 ; Name of chunk move.l 4(A0),D2 ; Length of chunk cmpi.l #'FORM',D1 beq.s .noParseYet cmpi.l #'CAT ',D1 beq.s .noParseYet cmpi.l #'PROP',D1 beq.s .noParseYet cmpi.l #'LIST',D1 bne.s .parse .noParseYet lea 12(A0),A0 ; Overread e.g. FORM####ANHD sub.l #12,D0 ; i.e. point to e.g. DLTA chunk (FORM####ANHDDLTA####) bra.s .checkChunk ; ¯¯¯¯ .parse addq.l #8,A0 ; Overread chunk-name and its size subq.l #8,D0 bmi.w .errIncomplete_1 ; Upon error cmpi.l #'CHRS',D1 ; Characters? beq.s .copyTxt cmpi.l #'RULE',D1 ; Or a ruler which is interpreted as a LineFeed beq.w .SetLF cmpi.l #'WTXT',D1 ; Characters? beq.s .copyTxt addq.l #1,D2 ; Make chunk-size even andi.l #-2,D2 add.l D2,A0 ; Pointer to next chunk sub.l D2,D0 bra.s .checkChunk ; And search again... .copyTxt move.l D2,D1 ; Size of this chunk addq.l #1,D2 ; Make chunk-size even andi.l #-2,D2 tst.l D1 ; Chunk-size == 0? beq.s .OnlyLF ; Interpret as linefeed movea.l A0,A1 ; Source of characters bra.s .cpy .cpyChar cmpi.b #9,(A1) ; Tab? bne.s .store ; ...if not addq.b #7,D6 ; Else, this char [1] (Tab) + [7] andi.b #-8,D6 ; on a position which is divisable by eight * subq.b #1,D6 ; Minus 1, because 2 lines further we add one... .store cmpi.b #$9B,(A1) ; CSI? beq.s .ignoredouble ; Ignore CSI cmpi.b #15,(A1) ; Ignore shift-in etc. beq.s .addLineFeed cmpi.b #16,(A1) beq.s .ignore cmpi.b #17,(A1) beq.s .ignore cmpi.b #18,(A1) beq.s .ignore move.b (A1)+,(A2)+ ; Copy characters cmpi.b #10,-1(A2) ; A new line? beq.s .reset addq.b #1,D6 ; New line length plus 1 cmp.b D7,D6 ; Range limit reached? bls.s .cpy ; If not yet reached... bra.s .findterminator ; Else, split line... .reset moveq #0,D6 bra.s .cpy .addLineFeed addq.l #1,A1 move.b #10,(A2)+ moveq #0,D6 bra.s .cpy .ignoredouble addq.l #1,A1 subq.l #1,D1 subq.l #1,D4 .ignore addq.l #1,A1 subq.l #1,D4 .cpy subq.l #1,D1 ; One less... bcc.s .cpyChar add.l D2,A0 ; Pointer to next chunk sub.l D2,D0 bra.w .checkChunk ; and restart... .OnlyLF ; <- Chunk-size of CHRS-chunk zero!!! move.b #10,(A2)+ ; Add a LineFeed at the end of each line add.l D2,A0 ; Pointer to next chunk sub.l D2,D0 moveq #0,D6 ; No chars in this line at the moment! bra.w .checkChunk ; Restart .SetLF ; <- RULER move.b #10,(A2)+ ; Add a LineFeed at the end of each line addq.l #1,D2 ; Make chunk-size even andi.l #-2,D2 add.l D2,A0 ; Pointer to next chunk sub.l D2,D0 moveq #0,D6 ; No chars in this line at the moment! bra.w .checkChunk ; Restart .findterminator move.l A2,-(sp) subq.l #1,A2 ; Pointer to last stored char moveq #0,D6 ; Chars in next line (this line will be split into two part) .loop subq.l #1,A2 ; One less char addq.b #1,D6 ; Amount of chars in newline plus one cmp.b D7,D6 ; Range checking... bhi.s .err cmpi.b #9,1(A2) ; Tab? beq.s .found ; <- Replace Tab through LineFeed cmpi.b #' ',1(A2) ; Blank bne.s .loop ; If not .found move.b #10,1(A2) ; Replace Blank or Tab through LineFeed movea.l (sp)+,A2 bra.s .cpy .err ; A line without any Blanks or Tabs moveq #0,D6 movea.l (sp)+,A2 bra.s .cpy ***** HELLO ***** .done move.b #10,(A2) ; Write as last char of ascii-file the LineFeed! addq.l #1,D4 bsr.w _FreeFile ; Free old (not more needed datas) move.l A3,_TextPtr(A5) ; Set up source move.l D4,_FileSize(A5) ; Set up source's size (plain ascii-chars) move.l D5,_BufferSize(A5) ; Set up source's size (extended) rts .errNoMem lea _NoFreeStoreTxt(pc),A0 bsr.w _DisplayError bra.w _CheckFile_1 ; Set up as binary .errNonStd lea _NoAsciiDatasTxt(pc),A0 bsr.w _DisplayError bra.w _CheckFile_1 ; Set up as binary .errIncomplete_1 movea.l A3,A1 move.l D4,D0 movea.l _SysBase(A5),A6 jsr _LVOFreeMem(A6) .errIncomplete lea _IncompleteIFFTxt(pc),A0 bsr.w _DisplayError bra.w _CheckFile_1 ; Set up as binary ******************************************************** * * StrToLong( ULONG mask, char *buffer ); * * * Convert an ascii-string into computer internal number. * Converted are: dual, decimal, signed decimal and * hexadecimal ascii-strings. * * Valid terminators for the string-counts are: NULL-byte, * tabulator, LineFeed, Blank (Space) and the comma. * * Introducion for strings: * "#" = decimal (max. 10 chars for count) * "" = decimal (max. 10 chars for count) * "+" = decimal (max. 10 chars for count) * * "-" = signed decimal (max. 10 chars for count) * * "0x" = sedecimal (hexadecimal) (max. 8 chars for count) * "$" = sedecimal (hexadecimal) (max. 8 chars for count) * * "%" = dual (max. 32 chars for count) * * Inputs: D0 - when NULL (zero) the routine is working normal. * - You can put a key-byte (mask) into D0 - the * subroutine is called then directly without * checking introducing arguments, note: in this * case no introducion has to be set in the ascii- * string, eg: D0 contains the "$" char - then * the ascii-string must be pointed to a plain * text, eg. "0003f000" - result here: converted * string to hexadecimal. * A0 - Pointer to the string which should be converted. * Results: Count in D0 * D1 contains -1L on error * A0 points to next argument if no error occured, * otherwise check -1(A0) and (A0) for the error, * it holds the char which caused the error! * * XDEF _StrToLong _StrToLong movem.l D2-D3,-(sp) * ** When called as C-stub, set following two lines. * ;move.l 12(sp),D0 ;move.l 16(sp),A0 move.w D0,D2 ; Save mask moveq #0,D0 ; Count to return move.l D0,D1 ; Local count-buffer tst.w D2 ; Mask set? beq.s .Sneek ; No, do it normal cmpi.b #'$',D2 ; Hexadecimal? beq.w .Hex_01 cmpi.w #'0x',D2 ; Hexadecimal? beq.w .Hex_01 cmpi.b #'#',D2 ; Decimal? beq.w .Dec_01 cmpi.b #' ',D2 ; Decimal? beq.w .Dec_01 cmpi.b #'-',D2 ; Signed decimal? beq.s .SignedDec_01 cmpi.b #'%',D2 ; Dual? beq.w .Dual_01 .Sneek * ** Find chars we have to skip... * cmpi.b #9,(A0) ; Tab-key? beq.s .Skip cmpi.b #' ',(A0) ; Blank? beq.s .Skip cmpi.b #'!',(A0) ; For complex string arguments beq.s .Skip cmpi.b #'|',(A0) ; For complex string arguments beq.s .Skip cmpi.b #',',(A0) ; Comma? beq.s .Skip cmpi.b #';',(A0) ; Semicolon? beq.s .Skip * ** Check if an interrupted end... * tst.b (A0) ; End? beq.w .Error_StringToLong cmpi.b #10,(A0) ; CR (LF)? beq.w .Error_StringToLong * ** Parse argument (string's introducion)... * cmpi.b #'-',(A0) ; Minus-char? beq.s .SignedDec cmpi.b #'+',(A0) ; Plus-char? beq.w .Dec cmpi.b #'$',(A0) ; Hex-char? beq.s .Hex cmpi.b #'%',(A0) ; Dual-char? beq.w .Dual cmpi.b #'#',(A0) ; Sometimes used for decimal introducion beq.w .Dec cmpi.b #'0',(A0) ; Zero-char? bne.w .Dec_01 cmpi.b #'x',1(A0) ; 0x == C-introducion for hex bne.w .Dec_01 addq.l #1,A0 ; Overread '0' of '0x' bra.s .Hex * ----------------------- * .Skip addq.l #1,A0 bra.s .Sneek * ----------------------- * .SignedDec addq.l #1,A0 ; Overread sign .SignedDec_01 moveq #9,D2 ; 10 chars to convert .SDC tst.b (A0) ; End? beq.s .End_SDC cmpi.b #9,(A0) ; Tab-key? beq.s .End_SDC cmpi.b #10,(A0) ; CR (LF)-key? beq.s .End_SDC cmpi.b #' ',(A0) ; Blank-key? beq.s .End_SDC cmpi.b #',',(A0) ; Comma-key? beq.s .End_SDC move.b (A0)+,D1 ; Get char cmpi.b #'0',D1 blt.w .Error_StringToLong cmpi.b #'9',D1 bhi.w .Error_StringToLong subi.b #48,D1 ; Computer intern number move.l D0,D3 ; Save D0 lsl.l #3,D0 ; D0 * 8 add.l D3,D3 ; D3 * 2 add.l D3,D0 ; == mulu.l #10,D0 add.l D1,D0 ; Store new nibble dbf D2,.SDC .End_SDC neg.l D0 bra.w .End_StringToLong * ----------------------- * .Hex addq.l #1,A0 ; Overread introducion .Hex_01 moveq #7,D2 ; 8 chars to convert .HC tst.b (A0) ; End? beq.w .End_StringToLong cmpi.b #9,(A0) ; Tab-key? beq.w .End_StringToLong cmpi.b #10,(A0) ; CR (LF)-key? beq.w .End_StringToLong cmpi.b #' ',(A0) ; Blank-key? beq.w .End_StringToLong cmpi.b #',',(A0) ; Comma-key? beq.w .End_StringToLong move.b (A0)+,D1 ; Get char cmpi.b #'0',D1 ; 0-char? blt.w .Error_StringToLong cmpi.b #'9',D1 ; 9-char bls.s .OkHC bclr.l #5,D1 ; To uppercase cmpi.b #'F',D1 ; F-char bhi.w .Error_StringToLong cmpi.b #'A',D1 ; A-char? blt.w .Error_StringToLong subi.b #55,D1 lsl.l #4,D0 ; Room for nibble or.l D1,D0 ; Store new nibble dbf D2,.HC bra.w .End_StringToLong .OkHC subi.b #48,D1 ; Computer intern number lsl.l #4,D0 ; Room for nibble or.l D1,D0 ; Store new nibble dbf D2,.HC bra.w .End_StringToLong * ----------------------- * .Dec addq.l #1,A0 ; Overread introducion .Dec_01 moveq #9,D2 ; 10 chars to convert .DC tst.b (A0) ; End? beq.w .End_StringToLong cmpi.b #9,(A0) ; Tab-key? beq.s .End_StringToLong cmpi.b #10,(A0) ; CR (LF)-key? beq.s .End_StringToLong cmpi.b #' ',(A0) ; Blank-key? beq.s .End_StringToLong cmpi.b #',',(A0) ; Comma-key? beq.s .End_StringToLong move.b (A0)+,D1 ; Get char cmpi.b #'0',D1 blt.s .Error_StringToLong cmpi.b #'9',D1 bhi.s .Error_StringToLong subi.b #48,D1 ; Computer intern number move.l D0,D3 ; Save D0 lsl.l #3,D0 ; D0 * 8 add.l D3,D3 ; D3 * 2 add.l D3,D0 ; == mulu.l #10,D0 add.l D1,D0 ; Store new nibble dbf D2,.DC bra.s .End_StringToLong * ----------------------- * .Dual addq.l #1,A0 ; Overread '%' .Dual_01 moveq #31,D2 ; 32 chars to convert .DUC tst.b (A0) ; End? beq.s .End_StringToLong cmpi.b #9,(A0) ; Tab-key? beq.s .End_StringToLong cmpi.b #10,(A0) ; CR (LF)-key? beq.s .End_StringToLong cmpi.b #' ',(A0) ; Blank-key? beq.s .End_StringToLong cmpi.b #',',(A0) ; Comma-key? beq.s .End_StringToLong cmpi.b #'.',(A0) ; A dot set between? beq.s .Skip_Dot move.b (A0)+,D1 ; Get char subi.b #48,D1 ; Computer internal number cmpi.b #1,D1 bhi.s .Error_StringToLong add.l D0,D0 ; Base = 2 - so add it! add.l D1,D0 ; Add also new count dbf D2,.DUC bra.s .End_StringToLong .Skip_Dot addq.l #1,A0 bra.s .DUC * ----------------------- * .Error_StringToLong movem.l (sp)+,D2-D3 moveq #-1,D1 rts .End_StringToLong movem.l (sp)+,D2-D3 moveq #0,D1 rts * ----------------------------------------------------- * * * * * * Data Array * * * * * * ----------------------------------------------------- * _Divutable dc.l 1000000000 dc.l 100000000 dc.l 10000000 dc.l 1000000 dc.l 100000 dc.l 10000 dc.l 1000 dc.l 100 dc.l 10 dc.l 1 _Image.1 dc.w 0,0,74,19,%1 dc.l 0 dc.b %1,%10 ; Plane pick, plane off dc.l 0 _Image.2 dc.w 0,0,74,19,%1 dc.l 0 dc.b %1,%10 ; Plane pick, plane off dc.l 0 _Image.3 dc.w 0,0,45,28,%11 dc.l 0 dc.b %11,%0 ; Plane pick, plane off dc.l 0 _Image.4 dc.w 0,0,45,28,%11 dc.l 0 dc.b %11,%0 ; Plane pick, plane off dc.l 0 _Channels dc.b 1,2,4,8 ; One of those channels I want to allocate... _GStr1 dc.b 'Ok',0 _GStr2 dc.b 'Abort',0 _ScreenName dc.b 'Viewer''s image screen',0 _WindowName dc.b ' Viewer V4.4 - © 92-99 ONIX',0 _IntuitionName dc.b 'intuition.library',0 _GfxName dc.b 'graphics.library',0 _DiskFontName dc.b 'diskfont.library',0 _DeviceName dc.b 'console.device',0 _AudioName dc.b 'audio.device',0 _ReqToolsName dc.b 'reqtools.library',0 _ArpName dc.b 'arp.library',0 _CyberGfxName dc.b 'cybergraphics.library',0 _AWTitle dc.b 'Load A File...',0 _SaveTitle dc.b 'Save Text File As...',0 _PageDef dc.b 'SCROLLWIDTH=',0 _WindowDef dc.b 'EXTENTWINDOW=',0 _WrapDef dc.b 'WRAP=ON',0 _FontSpecName dc.b 'FONT=',0 _OffsetSpecName dc.b 'WINDOWOFFSET=',0 _NoWarningName dc.b 'NOWARN',0 _NoCheckPrinterTxt dc.b 'NOPRTCHECK',0 _ExecuteTxt dc.b 'EXECUTE=',0 _NilName dc.b 'NIL:',0 * --------------------------------------------------- * _HelpText dc.b $9B,'1;31;42m' dc.b 'CRSR-down :-) (n) lines down ',10 dc.b 'CRSR-up :-) (n) lines up ',10 dc.b 'CRSR-right :-) line down ',10 dc.b 'CRSR-left :-) line up ',10 dc.b 'L-Key :-) load new file ',10 dc.b 'E-Key :-) enlarge window ',10 dc.b 'H-Key :-) this page ',10 dc.b 'A-Key :-) about page ',10 dc.b 'R-Key :-) restore page ',10 dc.b 'T/B-Keys :-) toggle Top/Bottom',10 dc.b 'HOME/END :-) toggle Top/Bottom',10 dc.b 'PgUp/PgDn :-) PageUp/PageDown ',10 dc.b 'Ret/Enter :-) one line down ',10 dc.b 'SHIFT-R :-) single step back ',10 dc.b 'S_KEY :-) search for string',10 dc.b 'N-Key :-) next occurrence ',10 dc.b 'P/F :-) file to prt/file ',10 dc.b 'W/C-Keys :-) page to prt/file ',10 dc.b 'PrtSc :-) page to prt ',10 dc.b $1B,'[0m' dc.b $9B,$48 ; Cursor Home dc.b $9B,'33C',' For more details read',10 dc.b $9B,'33C',' Viewer.doc.',10,10 dc.b $9B,'33C',' Press any key to continue.',10 _HelpTextEnd _SearchText dc.b $1B,'c',10,$1B,'[1mSearch for: ',$1B,'[0m' _SearchTextEnd * ** The first byte of a string contains the upper offset (Y-coordinate) ** where the text start (X-offset is computed). A linefeed (10) tells ** that a second (or more) string line(s) follow. NULL indicates the ** end of the string(s). ** If you have strings which only contain one line, the linefeed must ** also be set, also the NULL-byte (i.e. "30,'Decrunching failed!',10,0"). * _NoFileMsg dc.b 22,'You didn''t pick a file.',10 dc.b 'Press key "L" to load one.',10,0 _ErrorOpenWindowTxt dc.b 8,'Couldn''t open main-window with',10 dc.b 'leftedge at %d, topedge at %d -',10 dc.b 'with a width of %d pixels and a',10 dc.b 'height of %d rows!',10,0 _ErrorOpenDevTxt dc.b 22,'Couldn''t open the',10 dc.b '"console.device". Terminating.',10,0 _EmptyTxt dc.b 22,'Selected file contains no',10 dc.b 'datas. Loading file terminated.',10,0 _DirTxt dc.b 22,'You have chosen a directory and',10 dc.b 'I expected a file.',10,0 _ReadErrTxt dc.b 22,'Could not load that file, it',10 dc.b 'has a read error.',10,0 _OpenFileErrTxt dc.b 30,'Could not open file.',10,0 _AllocErrTxt dc.b 22,'Impossile to allocate memory',10 dc.b 'for this file.',10,0 _ExamineErrTxt dc.b 30,'DOS function examine failed!',10,0 _LockErrTxt dc.b 22,'Cannot get lock of file, thus',10 dc.b 'I cannot examine the file!',10,0 _ObjectFileTxt dc.b 8,'The selected file is an object',10 dc.b 'module, shall I display its',10 dc.b 'contents?',10 dc.b '(Converted size: %ld bytes)',10,0 _BinaryFileTxt dc.b 8,'The selected file contains ',10 dc.b 'binary datas.',10 dc.b 'Shall I display them?',10 dc.b '(Converted size: %ld bytes)',10,0 _NoReqTxt dc.b 22,'Impossible to work without',10 dc.b 'ReqTools or Arp libraries!',10,0 _OpenPrintErrTxt dc.b 22,'Unable to open file or printer',10 dc.b 'for output. Printjob aborted.',10,0 _WriteErrTxt dc.b 22,'Error while printing file.',10 dc.b 'Printjob aborted.',10,0 _PrintFileTxt dc.b 30,'Going to write whole file...',10,0 _PrintContentsTxt dc.b 30,'Going to write window contents...',10,0 _PrintCancelTxt dc.b 30,'Job cancelled.',10,0 _PrinterOFFTxt dc.b 16,'Printer is turned off or',10 dc.b 'there is no printer.',10 dc.b 'Printing failed.',10,0 _NotOnelineTxt dc.b 22,'Your printer is not online.',10 dc.b 'Printing failed.',10,0 * - These messages I love... - _AboutTxt dc.b 8,'Date: 12/08/1999 10:22:29 pm',10 dc.b 'Programmer: Joerg van de Loo.',10 dc.b 'Simple text, binary and image viewer.',10 dc.b 'Granted to use free of charge.',10,0 _InfoTxt dc.b 8,'CODE %ld - DATA %ld bytes,',10 dc.b 'DATA-CHIP = %ld bytes,',10 dc.b 'BSS = %ld bytes.',10 dc.b 'Assembled with HiSoft Devpac Amiga.',10,0 * - Messages for PowerPacker(.library) support - _PPCrunchTxt dc.b 8,'This is a PowerPacker',10 dc.b '(library) packed file.',10 dc.b 'Unpacked length: %ld bytes.',10 dc.b 'Shall I unpack it?',10,0 _DecrunchErrTxt dc.b 30,'Decrunching failed!',10,0 * - Message for displaying/loading pictures - _ILBMTxt dc.b 22,'This is an IFF-ILBM file.',10 dc.b 'Shall I display it?',10,0 _ACBMTxt dc.b 22,'This is an IFF-ACBM file.',10 dc.b 'Shall I display it?',10,0 _ImageInfoTxt dc.b 8,'Screen: %d * %d pixels.',10 dc.b 'Bitmap: %d * %d pixels.',10 dc.b 'Image: %d * %d pixels.',10 dc.b '%ld colours, %ld bytes.',10,0 _WarnMaskingTxt dc.b 8,'WARNING:',10 dc.b 'IFF makes use of masking.',10 dc.b 'This isn''t 100% supported.',10 dc.b 'Strange output may occur!',10,0 _WarnUncompressedTxt dc.b 22,'INFORMATION:',10 dc.b 'IFF already uncompressed.',10,0 _IncorrectSizeTxt dc.b 22,'ERROR:',10 dc.b 'Corrupt IFF-file!',10,0 _NoByteRunTxt dc.b 22,'ERROR:',10 dc.b 'Unknown compression method!',10,0 _AllocBufErrTxt dc.b 30,'Error allocating bitmaps!',10,0 _NoIFFFileTxt dc.b 22,'Bad or incomplete IFF!',10 dc.b 'Perhaps only a palette file?',10,0 _ErrorOpeningScreen dc.b 22,'Can''t open monitor/screen...',10 dc.b 'Too many bitplanes?!?!?',10,0 _ErrorInvalidIDTxt dc.b 16,'Cannot find right monitor for',10 dc.b 'installed alien gfx-board which',10 dc.b 'does support this resolution!',10,0 * - Messages for converting IFF to ASCII - _IFFAsciiTxt dc.b 16,'This IFF-file perhaps',10 dc.b 'contains embedded strings.',10 dc.b 'Shall I try to extract them?',10,0 _NoFreeStoreTxt dc.b 16,'Cannot allocate buffer',10 dc.b 'to store plain ASCII-',10 dc.b 'characters. Extracting aborted',10,0 _NoAsciiDatasTxt dc.b 16,'This file does not contain',10 dc.b 'ASCII-characters at all or I',10 dc.b 'cannot handle them!',10,0 _IncompleteIFFTxt dc.b 16,'IFF-file does not contain',10 dc.b 'all chunks it should have.',10 dc.b 'Incomplete (bad) IFF-file!',10,0 * - Messages for audio files - _8SVXTxt dc.b 22,'This is an audio file.',10 dc.b 'Shall I make it audible?',10,0 _8SVXErrTxt dc.b 8,'Error during setup of',10 dc.b '8SVX file. VHDR on invalid',10 dc.b 'position or I simply ran out of',10 dc.b 'memory!',10,0 _AudErrTxt dc.b 22,'Error while attempting to make',10 dc.b 'datas audible; channel stolen?',10,0 * - The standard... _ProgID dc.b '$VER: Viewer 4.4 (12.08.99)' * ^^^^ * Internal: 4 dc.b '© 1992-99 J.v.d.Loo (ONIX) - IFF-TEXT/ILBM/ACBM/8SVX viewer; RTG emulation.',0 _EndDatas **************************************************************** * * Image-data. Datas for gadgets, 1 colour, 190 bytes (for each). * SECTION GadgetImage,DATA_C _Gad.1 dc.w $AAAA,$AAAA,$AAAA,$AAAA,$AAC0,$D555,$5555,$5555,$5555,$55C0 dc.w $A000,$0000,$0000,$0000,$01C0,$C000,$0000,$0000,$0000,$01C0 dc.w $A000,$0000,$0000,$0000,$01C0,$C000,$0000,$0000,$0000,$01C0 dc.w $A000,$0000,$0000,$0000,$01C0,$C000,$0000,$0000,$0000,$01C0 dc.w $A000,$0000,$0000,$0000,$01C0,$C000,$0000,$0000,$0000,$01C0 dc.w $A000,$0000,$0000,$0000,$01C0,$C000,$0000,$0000,$0000,$01C0 dc.w $A000,$0000,$0000,$0000,$01C0,$C000,$0000,$0000,$0000,$01C0 dc.w $A000,$0000,$0000,$0000,$01C0,$C000,$0000,$0000,$0000,$01C0 dc.w $A000,$0000,$0000,$0000,$01C0,$DFFF,$FFFF,$FFFF,$FFFF,$FFC0 dc.w $FFFF,$FFFF,$FFFF,$FFFF,$FFC0 _Gad.2 dc.w $FFFF,$FFFF,$FFFF,$FFFF,$FFC0,$FFFF,$FFFF,$FFFF,$FFFF,$FEC0 dc.w $E000,$0000,$0000,$0000,$0140,$E000,$0000,$0000,$0000,$00C0 dc.w $E000,$0000,$0000,$0000,$0140,$E000,$0000,$0000,$0000,$00C0 dc.w $E000,$0000,$0000,$0000,$0140,$E000,$0000,$0000,$0000,$00C0 dc.w $E000,$0000,$0000,$0000,$0140,$E000,$0000,$0000,$0000,$00C0 dc.w $E000,$0000,$0000,$0000,$0140,$E000,$0000,$0000,$0000,$00C0 dc.w $E000,$0000,$0000,$0000,$0140,$E000,$0000,$0000,$0000,$00C0 dc.w $E000,$0000,$0000,$0000,$0140,$E000,$0000,$0000,$0000,$00C0 dc.w $E000,$0000,$0000,$0000,$0140,$EAAA,$AAAA,$AAAA,$AAAA,$AAC0 dc.w $D555,$5555,$5555,$5555,$5540 * ** Normal Audio Image: 45 x 28 x 2, bitmap: 48 x 28 x 2 (336 bytes) * _AudioGad.1_1 dc.w $0000,$0000,$0000,$0000,$0000,$0008,$0000,$0000,$0008,$0000 dc.w $0400,$0048,$0000,$0A00,$0048,$0000,$1A00,$0048,$0000,$2A00 dc.w $0048,$0000,$4A00,$0048,$003C,$8A00,$0048,$0043,$8A00,$0048 dc.w $0042,$8A00,$0048,$0042,$8A00,$0048,$0042,$8A00,$0048,$0042 dc.w $8A00,$0048,$0042,$8A00,$0048,$0042,$8A00,$0048,$0042,$8A00 dc.w $0048,$0043,$8A00,$0048,$003C,$8A00,$0048,$0000,$4A00,$0048 dc.w $0000,$2A00,$0048,$0000,$1A00,$0048,$0000,$0A00,$0048,$0000 dc.w $0400,$0048,$0FFF,$FFFF,$FFC8,$0000,$0000,$0008,$0000,$0000 dc.w $0008,$7FFF,$FFFF,$FFF8 _AudioGad.1_2 dc.w $FFFF,$FFFF,$FFF8,$8000,$0000,$0000,$8000,$0000,$0000,$9FFF dc.w $FBFF,$FF80,$9555,$5455,$5500,$9555,$4455,$5500,$9555,$5455 dc.w $5500,$9555,$3455,$5500,$9541,$7455,$5500,$953C,$7455,$5500 dc.w $953D,$7455,$5500,$953D,$7455,$5500,$953D,$7455,$5500,$953D dc.w $7455,$5500,$953D,$7455,$5500,$953D,$7455,$5500,$953D,$7455 dc.w $5500,$953C,$7455,$5500,$9540,$7455,$5500,$9540,$3455,$5500 dc.w $9550,$5455,$5500,$9555,$4455,$5500,$9555,$5455,$5500,$9555 dc.w $5155,$5500,$9000,$0000,$0000,$8000,$0000,$0000,$8000,$0000 dc.w $0000,$8000,$0000,$0000 * ** Select Audio Image: 45 x 28 x 2, bitmap: 48 x 28 x 2 (336 bytes) * _AudioGad.2_1 dc.w $FFFF,$FFFF,$FFF0,$8000,$0000,$0000,$8000,$0200,$4000,$8000 dc.w $0500,$8000,$8000,$0D01,$0020,$8000,$1502,$0020,$8000,$2504 dc.w $0020,$801E,$4500,$1820,$8021,$C500,$6020,$8021,$4501,$8020 dc.w $8021,$4500,$0020,$8021,$4500,$0020,$8021,$4500,$FC20,$8021 dc.w $4500,$0020,$8021,$4500,$0020,$8021,$4501,$8020,$8021,$C500 dc.w $6020,$801E,$4500,$1820,$8000,$2504,$0020,$8000,$1502,$0020 dc.w $8000,$0D01,$0020,$8000,$0500,$8020,$8000,$0200,$4020,$8000 dc.w $0000,$0020,$8000,$0000,$0020,$87FF,$FFFF,$FFE0,$8000,$0000 dc.w $0000,$8000,$0000,$0000 _AudioGad.2_2 dc.w $0000,$0000,$0008,$0000,$0000,$0008,$0000,$0000,$0008,$0000 dc.w $0200,$0008,$0FFF,$F27E,$EFC8,$0AAA,$AA28,$8A88,$0AAA,$9A2A dc.w $AA88,$0AA0,$BA2A,$2288,$0A9E,$3A2A,$8A88,$0A9E,$BA2A,$2888 dc.w $0A9E,$BA2A,$A288,$0A9E,$BA2A,$8A88,$0A9E,$BA2A,$0288,$0A9E dc.w $BA2A,$AA88,$0A9E,$BA2A,$8088,$0A9E,$BA2A,$2A88,$0A9E,$3A2A dc.w $8A88,$0AA0,$3A2A,$8288,$0AA0,$1A2A,$A288,$0AA8,$2A28,$A888 dc.w $0AAA,$A22A,$AA88,$0AAA,$AA2A,$2A88,$0AAA,$A82A,$AA88,$0AAA dc.w $AA2A,$8A88,$0AAA,$AA2A,$AA88,$0800,$0000,$0008,$0000,$0000 dc.w $0008,$7FFF,$FFFF,$FFF8 END