ANIMTOOL

Part of Color Max Deluxe available from the Color Computer Archive and in source form from https://github.com/milliluk/colormax

Allows to load and view MGE files, and save memory buffers to MGE files.

ANNOTATED ASSEMBLY SOURCE

Original Source: https://github.com/milliluk/colormax/blob/master/ANIMTOOL.TXT

NOTE: my comments may be wildly inaccurate.

Please contact me on the Color Computer Discord in the #programming channel if you have corrections.

;*****************************************************************************
;* ANIMTOOL
;*****************************************************************************

            NAM   MGE file utility

                              ; BEWARE !!
                              ; ERIK'S BEEN HERE!

;*****************************************************************************
;* EQUATES
;*****************************************************************************

PRSNXT:     equ   $9F         ; Parse NEXT char
PRSLST:     equ   $A5         ; Parse current char

;*****************************************************************************
; START
;*****************************************************************************

START:      lda   $200        ; POKE &H200,frame # (0-12)
            cmpa  #12         ; check for valid frame number (0-12)
            lbhi  FNCERR      ; >12 is a FN? error

                              ;***********************************************
                              ; calculate graphics page numbers in Extended RAM
            lsla              ; multiply frame number ...
            lsla              ; ... by 4 (4 x 8KB blocks per image)
            pshs  A           ; ... and store on stack
            lda   #$30        ; Now set up the default start 8K block num for frame 0
            suba  ,S+         ; subract the framebuffer size
            tfr   A,B         ; and move that to B for the first 8K block number of top half
            incb              ; and make the second 8K block number of top half
            std   GRP1+1,PCR  ; set the two 8K block values for top half of frame
            adda  #2          ; now add 2 to the first 8K block number
            addb  #2          ; now add 2 to the second 8K block number
            std   GRP2+1,PCR  ; set the second two 8K block numbers for bottom half of frame

                              ;***********************************************
            jsr   PRSLST      ; Get next character from command line
            cmpa  #':         ; Is it the ':' we expect?
            lbne  HELP        ; No; show help and exit
            jsr   PRSNXT      ; look ahead one character
            cmpa  #135        ; "?" TOKEN?
            lbeq  INFO        ; Yes, go show INFO and exit - same as help

                              ;***********************************************
            anda  #$DF        ; kill possible lowercase
            clrb              ; flag for monitor type
            cmpa  #'R         ; RGB? 
            beq   A@          ; or
            cmpa  #'C         ; CMP?
            lbne  SYNERR      ; No; SN? error
            ldb   #1          ; 1=CMP
A@          stb   MONTYP,PCR  ; save 0=RGB or 1=CMP to MONTYPE

                              ;***********************************************
            jsr   PRSNXT      ; Get next character from command line
            cmpa  #':         ; Is it the ':' we expect?
            lbne  SYNERR      ; No; SN? error
     
                              ;***********************************************
            jsr   PRSNXT      ; Get next character from command line
            anda  #$DF        ; kill possible lowercase
            cmpa  #'L         ; LOAD?
            beq   E@          ; or
            cmpa  #'S         ; SAVE?
            lbne  SYNERR      ; No; SN? error
            clra              ; 0=SAVE, >0=LOAD
E@          sta   TODO,PCR    ; store action in TODO

                              ;***********************************************
            jsr   PRSNXT      ; Get next character from command line
            cmpa  #':         ; Is it the ':' we expect?
            lbne  SYNERR      ; No; SN? error
      
                              ;***********************************************
            jsr   PRSNXT      ; Rest of the command is filename to work on
            lbsr  PRSENM      ; Parse the filename string

            lda   TODO,PCR    ; Now, are we loading or saving? Check TODO
            lbeq  SVEPIX      ; TODO=0 for SAVE so go do that

                              ;***********************************************
                              ;* Start loading the picture
                              ;***********************************************
            lbsr  OPENI       ; open file - input

            lbsr  GETBYT      ; get MGE resolution byte
            tsta              ; Not low-res!
            lbne  BADRES      ; Go report BADRES error and exit

                              ;***********************************************
                              ; now - read in the 16 palettes*
            leax  TEMP,PCR    ; Point to temp place to store
            ldb   #16         ; Going to read and save 16 values
A@          lbsr  GETBYT      ; Go get one into A ...
            sta   ,X+         ; ... and store it to where X points, then add 1 to X
            decb              ; Count down one in palette read loop
            bne   A@          ; Hit zero? No, go back and read next

                              ;***********************************************
            lbsr  GETBYT      ; Next byte is monitor type 

                              ;***********************************************
                              ; A now holds which monitor type that the picture was made on
                              ; 0=RGB
                              ; 1=composite
                              ; Make 0/1 rather than 0/nz
            tsta              ; So, what is file palette type?
            beq   A@          ; Was A zero? if so, RGB and keep going
            lda   #1          ; Force A to 1 for Composite rather than "anything not zero"
A@

                              ;***********************************************
            cmpa  MONTYP,PCR  ; Should I convert the palettes?
            lbeq  NOCNV       ; NOPE! File palette type matches our monitor

            leax  RGBCMP,PCR  ; Go from RGB to Composite?
            tsta              ; Check previous result
            beq   A@          ; Yes; skip next
            leax  CMPRGB,PCR  ; Go from Composite to RGB?
A@

                              ;***********************************************
                              ; converts palettes from RGB to COMP or vice-versa
            leay  TEMP,PCR    ; Set Y to address of TEMP palette buffer
            ldb   #16         ; Set our loop counter to size of palettes
A@          lda   ,Y          ; Get file palette entry from addr in Y into A
            lda   A,X         ; Get matching conversion entry from table in X offset by A, back into A
            sta   ,Y+         ; Store A to temp palette entry and move Y pointer to next in table
            decb              ; Count down loop by 1
            bne   A@          ; Are we done? No; go back

                              ;***********************************************
                              ; Don't convert
NOCNV:      ldy   #$FFB0      ; Set Y to start of GIME palette registers
            leax  TEMP,PCR    ; Set X to start of TEMP palette buffer
            ldb   #16         ; Set loop counter to 16
A@          lda   ,X+         ; Load from TEMP into A and move X pointer 1
            sta   ,Y+         ; Start from A into GIME palette and move Y pointer by 1
            decb              ; Count down loop by 1
            bne   A@          ; Are we done? No; go back

                              ;***********************************************
                              ; PALETTES ARE SET!
                              ;***********************************************

                              ;***********************************************
            lbsr  GETBYT      ; get compression flag
            pshs  A           ; Store on stack for a few

                              ;***********************************************
                              ; ignore 32 byte picture-name*
            ldb   #32         ; Set B to count 32 characters of file name
A@          lbsr  GETBYT      ; Get a character
            decb              ; Count down one
            bne   A@          ; Done counting?

                              ;***********************************************
            puls  A           ; Get A back from stack
            tsta              ; compressed?
            lbne  NTCMP       ; Nope; do non-compressed read

                              ;***********************************************
                              ; COMPRESSED READ
                              ; read in the bitmap
            ldx   #$8000      ; Set X to start of framebuffer
CMPLP:      lbsr  GETBYT      ; get # of times to repeat
            tfr   A,B         ; Save repeat count into B
            lbsr  GETBYT      ; get byte to repeat

            tstb              ; length=0??
            beq   CMPEND      ; end.. close file and done

            lbsr  GRPPGE      ; page RAM in and ROM out
A@          sta   ,X+         ; repeat that
            decb              ; byte..
            bne   A@          ; done repeating? No; go back
            lbsr  NRMPGE      ; yes; page back ROMs into memory map
            bra   CMPLP       ; Go back to get next repeat count and byte to repeat

                              ;***********************************************
                              ; NON COMPRESSED READ
                              ; read in bitmap
NTCMP:      ldx   #$8000      ; Set X to start of framebuffer
NTLP:       lbsr  GETBYT      ; Get a byte from file
            lbsr  GRPPGE      ; flip pages - ROM out and RAM in
            sta   ,X+         ; Store value from file direct to RAM
            lbsr  NRMPGE      ; flip back - ROM in and RAM out
            cmpx  #$8000+32000  ; done? 
            blo   NTLP        ; nope; go back and keep reading and drawing

CMPEND:                       ; yes, time to finish
            lbsr  CLOSE       ; close the file
            rts               ; and return to BASIC

;*****************************************************************************
; SAVE PIX
;*****************************************************************************
SVEPIX:     lbsr  OPENO       ; open file for output

                              ;***********************************************
            clra              ; 0 for res=320x200 16 color
            lbsr  WRTBYT      ; Write that RES out to file

                              ;***********************************************
                              ; write the palette out
            ldb   #16         ; Set loop counter to 16 for palettes
            ldx   #$FFB0      ; Setup to read from GIME palette registers
A@          lda   ,X+         ; Read from palette into A, then move pointer 1
            lbsr  WRTBYT      ; Write palette value out to file
            decb              ; Count down one in loop
            bne   A@          ; Loop done? No; loop back

                              ;***********************************************
                              ; write out the montype
            lda   MONTYP,PCR  ; MONTYPE 0=RGB, 1=CMP
            lbsr  WRTBYT      ; Write it to file

                              ;***********************************************
                              ; no compression
            lda   #255        ; COMPRESSION 0=compressed, not zero=uncompressed
            lbsr  WRTBYT      ; write it to file

                              ;***********************************************
                              ; Bozo title
            leax  UNT,PCR     ; Set X to point to UNTitled file name buffer
            ldb   #32         ; Set loop counter for 32 byte file name size
R@          lda   ,X+         ; Store the UNTitled buffer char to A and move X one
            lbsr  WRTBYT      ; Write title character to file
            decb              ; Count down loop by one
            bne   R@          ; Loop done? No; go back and keep writing name

                              ;***********************************************
                              ; write out the bitmap
            ldx   #$8000      ; Set X to point to start of bitmap
A@          lbsr  GRPPGE      ; Page out ROM and expose bitmap RAM
            lda   ,X+         ; Read a byte of bitmap into A and move X by 1
            lbsr  NRMPGE      ; Page out bitmap RAM and restore ROM before ...
            lbsr  WRTBYT      ; ... using ROM to write the byte to file
            cmpx  #$8000+32000  ; Has X reached end of bitmap?
            bne   A@          ; No; go back and keep writing bitmap

                              ;***********************************************
            lbsr  CLOSE       ; Yes; done so close the file
            rts               ; and return to basic

                              ; Bozo title
UNT:        fcc   "BASIC Pix",0


;*****************************************************************************
;* BADRES
;* Tells 'em that they're in a bad resolution!
;*****************************************************************************

            org   UNT+32      ; keep going after filename buffer ...

A@          fcc   "This file is at an incompatible",13
            fcc   "resolution",13,0

BADRES:     leax  A@,PCR      ; Set pointer X to start of BADRES error message
            bsr   PRTMS       ; Print characters until NUL
            lbra  FNCERR      ; and exit to BASIC ROM FN? error

;*****************************************************************************
;* GRPPGE
;* Pages in graphics screen at
;* $8000.. Kills interrupts, too.
;*****************************************************************************

GRPPGE:     pshs  X,D,Y,U     ; Save registers to stack
            lda   #52         ; Setup to ...
            sta   $FF03       ; ... disable interrupts in PIA
            lda   $FF02       ; ... and acknowledge any pending interrupt
GRP1:       ldd   #$3031      ; Setup 8K blocks to ...
            std   $FFA4       ; ... config MMU for extended RAM at 8000 and A000
GRP2:       ldd   #$3233      ; Setup 8K blocks to ...
            std   $FFA6       ; ... config MMU for extended RAM at C000 and E000
            puls  X,D,Y,U,PC  ; Restore registers and return

;*****************************************************************************
;* NRMPGE
;* Pages in normal memory
;* and re-enables interrupts.
;*****************************************************************************

NRMPGE:     pshs  X,D,Y,U     ; Save registers to stack
            ldd   #$3C3D      ; Setup 8K block numbers to ...
            std   $FFA4       ; ... config MMU for ROM at 8000 and A000
            ldd   #$3E3F      ; Setup 8K block numbers to ...
            std   $FFA6       ; ... config MMU for ROM at C000 and E000
            lda   #53         ; Setup to ...
            sta   $FF03       ; ... configure PIA for interrupts
            puls  X,D,Y,U,PC  ; Restore registers and return


;*****************************************************************************
;* OPENI
;* Opens a file for input
;* Entry: filename setup
;* Exit: file is opened!
;*****************************************************************************

OPENI:      pshs  X,D,Y,U     ; Save registers on stack
            ldx   #$C959      ; Rom 1.0 file input
            ldd   $C004       ; Which ROM??? Check DSKCON
            cmpd  #$D66C      ; Rom 1.0!
            beq   A@          ; !
            ldx   #$CA07      ; Rom 1.1 file input
A@          jsr   ,X          ; make call
            puls  X,D,Y,U,PC  ; Restore registers from stack and return

;*****************************************************************************
;* GETBYT
;* Gets a byte from the file
;* Entry: none
;* Exit : Byte's in A
;*****************************************************************************

GETBYT:     jmp   $A176       ; COLOR BASIC ROM CONSOLE IN

;*****************************************************************************
;* WRTBYT
;* writes a byte to file
;*****************************************************************************

WRTBYT:     jmp   [$A002]     ; Indirect jump through CHROUT to ROM PUTCHR

;*****************************************************************************
;* OPENO
;* Open it for output
;*****************************************************************************

OPENO:      pshs  X,D,Y,U     ; Save registers on stack
            ldx   #$C956      ; DECB 1.0 Open Sequential for I/O
            ldd   $C004       ; Get value of DSKCON vector
            cmpd  #$D66C      ; Is it the DEBC ROM 1.0 version?
            beq   A@          ; Yes; go open file for output
            ldx   #$CA04      ; No; load addr of DECB 1.1 open
A@          jsr   ,X          ; Go open the for output file using chosen ROM
            puls  X,D,Y,U,PC  ; Restore registers from stack and return

;*****************************************************************************
;* CLOSE
;* Closes an open file
;* Entry: None
;* Exit: None
;*****************************************************************************

CLOSE:      jmp   $A42D       ; COLOR BASIC ROM CLOSE FILE HANDLER

;*****************************************************************************
;* PRTMS
;* Enter: X pointing to msg
;* Exit : Well.. It PRINTS the msg!
;*****************************************************************************

PRTMS:      lda   ,X+         ; Get next character to print from addr X+ into A
            beq   ?RTS        ; End of message (NUL)? yes; return
            jsr   [$A002]     ; No; print character
            bra   PRTMS       ; and keep going until we hit a NUL

;*****************************************************************************
;* PRSENM
;* Parse filename/extension:drivenumber using Disk BASIC ROM calls
;*****************************************************************************

PRSENM:     pshs  X,D,Y,U     ; Save regs on stack before use
            leax  A@,PCR      ; where is extension we're looking for?
            ldy   #$C88A      ; Address of Disk rom 1.0 get filename/ext
            ldd   $C004       ; Look at what is stored in DSKCON vector
            cmpd  #$D66C      ; Izzit 1.0
            beq   B@          ; yep
            ldy   #$C938      ; nope; setup addr of Disk rom 1.1 get filename/ext
B@          jsr   ,Y          ; Call DECB ROM get filename/ext:drivenum
            puls  X,D,Y,U,PC  ; Restore regs from stack and return

A@          fcc   "MGE"

;*****************************************************************************
;* SYNTAX ERROR
;*****************************************************************************

SYNERR:     jmp   $B277       ; ?SN ERROR

;*****************************************************************************
;* FUNCTION CALL ERROR
;*****************************************************************************

FNCERR:     jmp   $B44A       ; ?FC ERROR

;*****************************************************************************
;* PALETTE CONVERSION DATA
;*****************************************************************************

RGBCMP:
            fcb   00,14,02,14,05,10,03,16,13,11,30,28,11,12,30,29
            fcb   17,17,18,34,20,19,34,33,46,45,47,31,46,45,47,46
            fcb   07,06,21,06,07,24,38,29,26,43,27,43,25,09,41,42
            fcb   36,35,50,51,53,54,36,37,32,60,49,61,56,59,52,63

CMPRGB:
            fcb   00,02,02,06,00,04,33,32,32,45,05,09,13,08,01,00
            fcb   07,16,18,21,20,34,38,36,37,44,40,42,11,15,10,27
            fcb   56,23,19,49,48,55,38,39,37,46,47,41,11,25,24,26
            fcb   63,58,50,51,62,52,53,60,60,46,61,61,57,59,58,63


TODO:       rmb   1           ; 0=Load or !0=Save?
TEMP:       rmb   16          ; Temporarily hold 16 palette entries
MONTYP:     rmb   1           ; 0=RGB or !0=CMP

;*****************************************************************************
;* HELP / INFO
;*****************************************************************************

A@          fcc   "ANIMTOOL/BIN Version 1.0",13
            fcc   "(C) 1987 Milliluk Technologies",13
            fcc   "All rights reserved",13
            fcc   ' EXEC:montype:cmd:"name"',13
            fcc   "   montype=R or C",13
            fcc   "   cmd=S (save)",13
            fcc   "       L (load)",13
            fcc   "   POKE &H200,frame # (0-12)",13,0

HELP:
INFO:       jsr   $A928       ; COLOR BASIC ROM CLEAR SCREEN
            leax  A@,PCR      ; Set pointer to start of help/info text above
            lbsr  PRTMS       ; Print characters using BASIC ROM until NUL
            jsr   PRSNXT      ; Go get next character (GETNCH at $9F)
            rts               ; return to BASIC

;*****************************************************************************
;* END
;*****************************************************************************
            end   START

RTS

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies