# HG changeset patch # User Mike Pavone # Date 1378182167 25200 # Node ID 97ec271a513f9d89c5e6246f8932abf48b7c1a45 # Parent bbfa7bf6962000a08102cf3a57f36183a5af9c28 Bunch of changes diff -r bbfa7bf69620 -r 97ec271a513f Makefile --- a/Makefile Tue May 01 20:43:25 2012 -0700 +++ b/Makefile Mon Sep 02 21:22:47 2013 -0700 @@ -2,18 +2,33 @@ ghero.iso : fs.iso boot.bin tail -c +32769 fs.iso | cat boot.bin - > ghero.iso -fs.iso : filesystem/* +filesystem/slo.bin : slo.s68 + vasmm68k_mot -Fbin -m68000 -spaces slo.s68 -o filesystem/slo.bin + +filesystem/transfer.bin : transfer.s68 + vasmm68k_mot -Fbin -m68000 -spaces transfer.s68 -o filesystem/transfer.bin + +filesystem/slave.bin : slave.s68 + vasmm68k_mot -Fbin -m68000 -spaces slave.s68 -o filesystem/slave.bin + +fs.iso : filesystem/* filesystem/slo.bin filesystem/transfer.bin filesystem/slave.bin mkisofs -o fs.iso filesystem boot.bin : scd_header.s68 mainboot.bin subboot.bin security.bin - vasmm68k_mot -Fbin -m68000 scd_header.s68 -o boot.bin - + vasmm68k_mot -Fbin -m68000 -spaces scd_header.s68 -o boot.bin + mainboot.bin : mainboot.s68 - vasmm68k_mot -Fbin -m68000 mainboot.s68 -o mainboot.bin + vasmm68k_mot -Fbin -m68000 -spaces mainboot.s68 -o mainboot.bin subboot.bin : subboot.s68 - vasmm68k_mot -Fbin -m68000 subboot.s68 -o subboot.bin - + vasmm68k_mot -Fbin -m68000 -spaces subboot.s68 -o subboot.bin + +genesis.bin : genesis.s68 sprites.s68 + vasmm68k_mot -Fbin -m68000 -spaces genesis.s68 -o genesis.bin + clean : rm subboot.bin mainboot.bin boot.bin rm *.iso + +run : ghero.iso + /home/mike/bin/gens ghero.iso diff -r bbfa7bf69620 -r 97ec271a513f genesis.s68 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/genesis.s68 Mon Sep 02 21:22:47 2013 -0700 @@ -0,0 +1,393 @@ + dc.l $0, start + dc.l empty_handler + dc.l empty_handler + ;$10 + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + ;$20 + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + ;$30 + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + ;$40 + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + ;$50 + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + ;$60 + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + ;$70 + dc.l HINT + dc.l empty_handler + dc.l VINT + dc.l empty_handler + ;$80 + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + ;$90 + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + ;$A0 + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + ;$B0 + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + ;$C0 + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + ;$D0 + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + ;$E0 + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + ;$F0 + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + dc.l empty_handler + dc.b "SEGA" +empty_handler: + rte +start: +;background and sprite test + +ButtonState equ $FFFFEFF0 +ButtonStateNew equ ButtonState+2 +PalAddress equ ButtonStateNew+2 + +CRAMXferSizeCmd equ $9308 +CRAMDMACmd equ $C0100080 +StaticColors equ 8 + +USE_HINT equ 0 + move.b #$40, $A10009 + move.l #$C00000, a4 + move.l #$c00004, a5 + + move.l #$0, a7 + + move.w #$8104, (a5) ;turn off display + move.w #$8200, (a5) ;Table A = 0000 + move.w #$8400, (a5) ;Table B = 0000 + move.w #$857C, (a5) ;Sprite Table = F800 + move.w #$8B00, (a5) ;set full screen vertical and horizontal scrolling + move.w #$8C01, (a5) ;H40 mode, no shadow/hilight, no interlace + move.w #$8D3F, (a5) ;H Scroll = FC00 + move.w #$9001, (a5) ;64x32 scroll tables + + + + lea BgData(pc), a0 + move.w (a0)+, d0 ;size in words + move.w (a0)+, d1 ;width in cells + move.w (a0)+, d2 ;height in cells + move.w d2, d7 + + subq #1, d0 ;adjust for 68K dbra routine + move.w #$8f02, (a5) ;autoincrement = 2 + move.l #$50200000, (a5);beginning of background tile area +CopyTiles: + move.w (a0)+, (a4) ;copy tiles to VRAM + dbra d0, CopyTiles + + move.l #$40000000, d4 ;beginning of Plane A Name table + move.l #$00800000, d5 ;delta between lines + move.w #$81, d6 + subq #1, d1 + subq #1, d2 + move.w d1, d3 +WriteNamesY: + move.l d4, (a5) + move.w d3, d1 + +WriteNamesX: + move.w d6, (a4) + addq #1, d6 + dbra d1, WriteNamesX + + add.l d5, d4 + dbra d2, WriteNamesY + + move.l #$C0000000, (a5) ;setup writes to CRAM + moveq #(StaticColors-1), d0 ;copy first 12 colors (static pallete) +CopyColors: + move.w (a0)+, (a4) + dbra d0, CopyColors + + move.l a0, (PalAddress).w + + + move.l #$60000010, (a5) ;setup writes to VSRAM + move.w #$0, (a4) ;vscroll = 0 + + move.l #$7C000003, (a5) ;setup writes to HScroll Table FC00 + move.w #0, (a4) ;Plane A&B HScroll = 0; + move.w #0, (a4) ; + + move.l #$78000003, (a5) ;clear sprite table + move.l #0, (a4) + move.l #0, (a4) + + move.w #$8114, (a5) ;turn on DMA + + bsr InitSprites + bsr AddSprite + + move.w #$0, (a0) + + bsr LoadSpritePal + bsr InitFrameBigSprite + moveq #0, d3 + bsr ChangeFrameBigSprite + + + + + move.l #CRAMDMACmd, d5 ;setup DMA command word + + move.w #CRAMXferSizeCmd, (a5) ;set Transfer length + move.w #$9400, (a5) + + move.w #$8114, d6 + move.w #$8174, d7 + + if USE_HINT + + move.w #$8014, (a5) + move.w #$8A00, (a5) ;HINT occurs on every line + endif + + move.w #$8174, (a5) + move #$2300, SR + + +Loop: + if USE_HINT + bra Loop + endif +WaitTop: + cmpi.b #$FF, 4(a5) + bne.s WaitTop + +LineDone: + move.b 4(a5), d0 +WaitNextLine: + cmp.b 4(a5), d0 + beq WaitNextLine + + + +HINT: + ;move.w d6, (a5) + ;move.l d5, (a5) ;start DMA + ;move.w d7, (a5) + move.l d6, (a5) + move.l d7, (a5) + move.w #CRAMXferSizeCmd, (a5) ;set Transfer length + move.w #$9400, (a5) + + if USE_HINT + rte + endif + + cmp.b #223, 4(a5) + beq WaitTop + + bra LineDone + +VINT: + if USE_HINT + move.w #$8144, (a5) + endif + bsr SpriteCopyVRAM + + bsr ReadPad + + bsr Player1Vint + + move.l (PalAddress).w, d7 ;setup DMA source address + move.w #$9500, d6 + ror.l #1, d7 + move.b d7, d6 + move.w d6, (a5) + ror.l #8, d7 + move.b d7, d6 + add.w #$100, d6 + move.w d6,(a5) + ror.l #8, d7 + move.b d7, d6 + add.w #$100, d6 + and.b #$7F, d6 + move.w d6,(a5) + + ;move.l d5, (a5) ;do DMA for first line + + move.w #CRAMXferSizeCmd, (a5) ;set Transfer length + move.w #$9400, (a5) + + move.w #$8114, d6 ;VDP commands to turn screen on and off during HBlank + swap d6 + swap d5 + move.w d5, d6 + swap d5 + move.w d5, d7 + swap d7 + move.w #$8174, d7 + if USE_HINT + move.w d7, (a5) + endif + rte + +LoadSpritePal: + move.l #$C0200000, (a5) + moveq #$F, d0 + lea SpriteData, a0 +PalLoop: + move.w (a0)+, (a4) + dbra d0, PalLoop + rts + +Player1Vint: + move.b (ButtonState).w, d2 + move.b (ButtonStateNew).w, d3 + + moveq #0, d0 + move.w d0, d1 + + btst #5, d2 + bne ScrollRight + + btst #7, d2 + bne ScrollLeft + + btst #4, d3 + bne IncrementFrame + + + btst #6, d3 + bne DecrementFrame + + btst #2, d2 + beq PlayerShipNotLeft + subq #1, d0 +PlayerShipNotLeft: + + btst #3, d2 + beq PlayerShipNotRight + addq #1, d0 +PlayerShipNotRight: + + btst #0, d2 + beq PlayerShipNotDown + subq #1, d1 +PlayerShipNotDown: + + btst #1, d2 + beq PlayerShipNotUp + addq #1, d1 +PlayerShipNotUp: + + bsr MoveBigSprite + + rts +IncrementFrame: + move.w (PlayerShipFrame), d3 + addq #1, d3 + move.w d3, (PlayerShipFrame) + bsr ChangeFrameBigSprite + + rts + +DecrementFrame: + + move.w (PlayerShipFrame), d3 + subq #1, d3 + move.w d3, (PlayerShipFrame) + bsr ChangeFrameBigSprite + + rts + +ScrollRight: + move.w (ScrollValue), d0 + subq #1, d0 + move.l #$7C000003, (a5) ;setup writes to HScroll Table FC00 + move.w d0, (a4) + move.w d0, (a4) + move.w d0, (ScrollValue) + + rts + +ScrollLeft: + move.w (ScrollValue), d0 + addq #1, d0 + move.l #$7C000003, (a5) ;setup writes to HScroll Table FC00 + move.w d0, (a4) + move.w d0, (a4) + move.w d0, (ScrollValue) + + rts + + include sprites.s68 + +PlayerShipFrame: + dc.w 0 + + +ScrollValue: + dc.w 0 + +ReadPad: + move.b #$FF, $a10003 ;set TH for controller A + move.b $a10003, d0 ;CBRLUD + andi.b #$3F, d0 + move.b #0, $a10003 + move.b $a10003, d1 ;SA00UD + andi.b #$30, d1 + lsl.b #2, d1 + or.b d1, d0 ;SACBRLUD + not.b d0 + move.b (ButtonState).w, d1 + eor.b d0, d1 + and.b d0, d1 + move.b d0, (ButtonState).w + move.b d1, (ButtonStateNew).w + + rts + + +SpriteData: + incbin bultest.bin +BgData: + incbin logo.bin + diff -r bbfa7bf69620 -r 97ec271a513f img2tiles.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/img2tiles.py Mon Sep 02 21:22:47 2013 -0700 @@ -0,0 +1,174 @@ +#!/usr/bin/env python +from PIL import Image + +def gchannel(Val): + return (Val >> 4) & 0xE + +threshold = 127 + +def get_color_info(pixels, rng, threshold, exclude={}): + gencolors = {} + A = 255 + for idx in rng: + color = pixels[idx] + if len(color) == 4: + (R, G, B, A) = color + else: + (R, G, B) = color + if A > threshold: + gcolor = (gchannel(R), gchannel(G), gchannel(B)) + if not gcolor in exclude: + if gcolor in gencolors: + gencolors[gcolor] += 1 + else: + gencolors[gcolor] = 1 + glist = [(gencolors[color], color) for color in gencolors] + glist.sort() + glist.reverse() + return glist + +def totiles(im, palette): + pass + +def make_palette(im, trans_thresh, max_global, max_line): + pixels = im.getdata() + (width, height) = im.size + colors = get_color_info(pixels, xrange(0, height * width), trans_thresh) + glob_pal = {} + for idx in xrange(0, min(max_global, len(colors))): + (count, color) = colors[idx] + glob_pal[color] = idx + line_pals = [] + if max_global < len(colors): + for line in xrange(0, height): + linestart = line * width + linecolors = get_color_info(pixels, xrange(linestart, linestart+width), trans_thresh, glob_pal) + line_pal = {} + for idx in xrange(0, min(max_line, len(linecolors))): + (count, color) = linecolors[idx] + line_pal[color] = idx + line_pals.append(line_pal) + return (glob_pal, line_pals, max_global, max_line) + +def color_dist(a, b): + (ra, ga, ba) = a + (rb, gb, bb) = b + return (ra-rb)**2 + (ga-gb)**2 + (ba-bb)**2 + +def trans_image(im, trans_thresh, pal): + (global_pal, line_pals, _, _) = pal + pixels = im.getdata() + (width, height) = im.size + gpixels = [] + A = 255 + x = 0 + y = 0 + for pixel in pixels: + if x == width: + x = 0 + y += 1 + if width % 8: + for i in xrange(0, 8-(width%8)): + gpixels.append(0) + if len(pixel) == 4: + (R, G, B, A) = pixel + else: + (R, G, B) = pixel + if A > trans_thresh: + gpixel = (gchannel(R), gchannel(G), gchannel(B)) + if gpixel in global_pal: + gpixels.append(global_pal[gpixel]) + elif gpixel in line_pals[y]: + gpixels.append(line_pals[y][gpixel] + len(global_pal)) + else: + bestdist = color_dist((0,0,0), (15, 15, 15)) + bestpal = 0 + for cur in global_pal: + curdist = color_dist(gpixel, cur) + if curdist < bestdist: + bestdist = curdist + bestpal = global_pal[cur] + for cur in line_pals[y]: + curdist = color_dist(gpixel, cur) + if curdist < bestdist: + bestdist = curdist + bestpal = line_pals[y][cur] + gpixels.append(bestpal) + else: + gpixels.append(0) + x += 1 + if width % 8: + for i in xrange(0, 8-(width%8)): + gpixels.append(0) + width += 8-(width%8) + if height % 8: + for y in xrange(0, 8-(height%8)): + for x in xrange(0, width): + gpixels.append(0) + height += 8-(height%8) + + return (width, height, gpixels) + +def appendword(b, word): + b.append(word >> 8) + b.append(word & 0xff) + +def to_tiles(palpix): + (width, height, pixels) = palpix + b = bytearray() + cwidth = width/8 + cheight = height/8 + words = len(pixels)/4 + appendword(b, words) + appendword(b, cwidth) + appendword(b, cheight) + + for cy in xrange(0, cheight): + ystart = cy*8*width + for cx in xrange(0, cwidth): + startoff = (cx*8) + ystart + for row in xrange(0, 8): + rowoff = startoff + row*width + for bytecol in xrange(0, 4): + boff = bytecol * 2 + rowoff + #print 'boff:', boff, 'len(pixels)', len(pixels), 'cx', cx, 'cy', cy, 'cwidth', cwidth, 'cheight', cheight + #print 'pixels[boff]:', pixels[boff] + b.append(pixels[boff] << 4 | pixels[boff+1]) + return b + +def add_pal_entries(tiles, pal): + (global_pal, line_pals, max_global, max_line) = pal + pal_list = [(0, 0, 0)] * max_global + for entry in global_pal: + pal_list[global_pal[entry]] = entry + for entry in pal_list: + (R, G, B) = entry + tiles.append(B) + tiles.append(G << 4 | R) + for line in line_pals: + pal_list = [(0, 0, 0)] * max_line + for entry in line: + pal_list[line[entry]] = entry + for entry in pal_list: + (R, G, B) = entry + tiles.append(B) + tiles.append(G << 4 | R) + + + +def main(argv): + if len(argv) < 3: + print "Not enough arguments" + return + fname = argv[1] + im = Image.open(fname) + pal = make_palette(im, threshold, 8, 8) + palpix = trans_image(im, threshold, pal) + tiles = to_tiles(palpix) + bits = add_pal_entries(tiles, pal) + out = open(argv[2], 'wb') + out.write(tiles) + +if __name__ == '__main__': + import sys + main(sys.argv) diff -r bbfa7bf69620 -r 97ec271a513f mainboot.s68 --- a/mainboot.s68 Tue May 01 20:43:25 2012 -0700 +++ b/mainboot.s68 Mon Sep 02 21:22:47 2013 -0700 @@ -1,4 +1,390 @@ org $FF0000 incbin security.bin Main - bra Main +;background and sprite test + +ButtonState equ $FFFFEFF0 +ButtonStateNew equ ButtonState+2 + +CRAMXferSizeCmd equ $9304 +StaticColors equ 12 + +USE_HINT equ 0 + +Start + bsr ReadPad + + btst.b #7, (ButtonState).w + bne LoadSLO + + move.l #$C00000, a4 + move.l #$c00004, a5 + + move.l #$0, a7 + + lea BgFile, a0 + bsr FileByNameSimple + + move.w #$8104, (a5) ;turn off display + move.w #$8200, (a5) ;Table A = 0000 + move.w #$8400, (a5) ;Table B = 0000 + move.w #$857C, (a5) ;Sprite Table = F800 + move.w #$8B00, (a5) ;set full screen vertical and horizontal scrolling + move.w #$8D3F, (a5) ;H Scroll = FC00 + move.w #$9001, (a5) ;64x32 scroll tables + + + + lea $200000, a0 + move.w (a0)+, d0 ;size in words + move.w (a0)+, d1 ;width in cells + move.w (a0)+, d2 ;height in cells + move.w d2, d7 + + subq #1, d0 ;adjust for 68K dbra routine + move.w #$8f02, (a5) ;autoincrement = 2 + move.l #$50200000, (a5);beginning of background tile area +CopyTiles: + move.w (a0)+, (a4) ;copy tiles to VRAM + dbra d0, CopyTiles + + move.l #$40000000, d4 ;beginning of Plane A Name table + move.l #$00800000, d5 ;delta between lines + move.w #$81, d6 + subq #1, d1 + subq #1, d2 + move.w d1, d3 +WriteNamesY: + move.l d4, (a5) + move.w d3, d1 + +WriteNamesX: + move.w d6, (a4) + addq #1, d6 + dbra d1, WriteNamesX + + add.l d5, d4 + dbra d2, WriteNamesY + + move.l #$C0000000, (a5) ;setup writes to CRAM + moveq #(StaticColors-1), d0 ;copy first 12 colors (static pallete) +CopyColors: + move.w (a0)+, (a4) + dbra d0, CopyColors + + move.w d7, d0 + lsl.w #5, d0 + subq #1, d0 + lea PalData(pc), a1 + ;sub.l #2, a0 +.copypallines: + move.l (a0)+, (a1)+ + dbra d0, .copypallines + + + move.l #$60000010, (a5) ;setup writes to VSRAM + move.w #$0, (a4) ;vscroll = 0 + + move.l #$7C000003, (a5) ;setup writes to HScroll Table FC00 + move.w #0, (a4) ;Plane A&B HScroll = 0; + move.w #0, (a4) ; + + move.l #$78000003, (a5) ;clear sprite table + move.l #0, (a4) + move.l #0, (a4) + + move.w #$8114, (a5) ;turn on DMA + + bsr InitSprites + bsr AddSprite + + move.w #$0, (a0) + + bsr LoadSpritePal + bsr InitFrameBigSprite + moveq #0, d3 + bsr ChangeFrameBigSprite + + + + + move.l #$C0180080, d5 ;setup DMA command word + + move.w #CRAMXferSizeCmd, (a5) ;set Transfer length + move.w #$9400, (a5) + + move.w #$8114, d6 + move.w #$8174, d7 + + + + lea VINT(pc), a1 ;setup VINT handler + jsr $368 + + if USE_HINT + lea HINT(pc), a1 ;setup HINT handler and turn on HINTs + jsr $314 + + move.w #$8014, (a5) + move.w #$8A00, (a5) ;HINT occurs on every line + endif + + move.w #$8174, (a5) + + + +Loop: + if USE_HINT + bra Loop + endif +WaitTop: + cmpi.b #$FF, 4(a5) + bne.s WaitTop + +LineDone: + move.b 4(a5), d0 +WaitNextLine: + cmp.b 4(a5), d0 + beq WaitNextLine + + + +HINT: + ;move.w d6, (a5) + ;move.l d5, (a5) ;start DMA + ;move.w d7, (a5) + move.l d6, (a5) + move.l d7, (a5) + move.w #CRAMXferSizeCmd, (a5) ;set Transfer length + move.w #$9400, (a5) + + if USE_HINT + rte + endif + + cmp.b #223, 4(a5) + beq WaitTop + + bra LineDone + +VINT: + move.b #1, $A12000 ;trigger interrupt on Sub CPU + if USE_HINT + move.w #$8144, (a5) + endif + bsr SpriteCopyVRAM + + bsr ReadPad + + bsr Player1Vint + + move.l PalData, d7 ;setup DMA source address + move.w #$9500, d6 + ror.l #1, d7 + move.b d7, d6 + move.w d6, (a5) + ror.l #8, d7 + move.b d7, d6 + add.w #$100, d6 + move.w d6,(a5) + ror.l #8, d7 + move.b d7, d6 + add.w #$100, d6 + and.b #$7F, d6 + move.w d6,(a5) + + ;move.l d5, (a5) ;do DMA for first line + + move.w #CRAMXferSizeCmd, (a5) ;set Transfer length + move.w #$9400, (a5) + + move.w #$8114, d6 ;VDP commands to turn screen on and off during HBlank + swap d6 + swap d5 + move.w d5, d6 + swap d5 + move.w d5, d7 + swap d7 + move.w #$8174, d7 + if USE_HINT + move.w d7, (a5) + endif + rte + +LoadSpritePal: + move.l #$C0200000, (a5) + moveq #$F, d0 + lea SpriteData, a0 +PalLoop: + move.w (a0)+, (a4) + dbra d0, PalLoop + rts + +PalAddress: + dc.l 0 + +Player1Vint: + move.b (ButtonState).w, d2 + move.b (ButtonStateNew).w, d3 + + moveq #0, d0 + move.w d0, d1 + + btst #5, d2 + bne ScrollRight + + btst #7, d2 + bne ScrollLeft + + btst #4, d3 + bne IncrementFrame + + + btst #6, d3 + bne DecrementFrame + + btst #2, d2 + beq PlayerShipNotLeft + subq #1, d0 +PlayerShipNotLeft: + + btst #3, d2 + beq PlayerShipNotRight + addq #1, d0 +PlayerShipNotRight: + + btst #0, d2 + beq PlayerShipNotDown + subq #1, d1 +PlayerShipNotDown: + + btst #1, d2 + beq PlayerShipNotUp + addq #1, d1 +PlayerShipNotUp: + + bsr MoveBigSprite + + rts +IncrementFrame: + move.w (PlayerShipFrame), d3 + addq #1, d3 + move.w d3, (PlayerShipFrame) + bsr ChangeFrameBigSprite + + rts + +DecrementFrame: + + move.w (PlayerShipFrame), d3 + subq #1, d3 + move.w d3, (PlayerShipFrame) + bsr ChangeFrameBigSprite + + rts + +ScrollRight: + move.w (ScrollValue), d0 + subq #1, d0 + move.l #$7C000003, (a5) ;setup writes to HScroll Table FC00 + move.w d0, (a4) + move.w d0, (a4) + move.w d0, (ScrollValue) + + rts + +ScrollLeft: + move.w (ScrollValue), d0 + addq #1, d0 + move.l #$7C000003, (a5) ;setup writes to HScroll Table FC00 + move.w d0, (a4) + move.w d0, (a4) + move.w d0, (ScrollValue) + + rts + + include sprites.s68 + +PlayerShipFrame: + dc.w 0 + + +ScrollValue: + dc.w 0 + +ReadPad: + move.b #$FF, $a10003 ;set TH for controller A + move.b $a10003, d0 ;CBRLUD + andi.b #$3F, d0 + move.b #0, $a10003 + move.b $a10003, d1 ;SA00UD + andi.b #$30, d1 + lsl.b #2, d1 + or.b d1, d0 ;SACBRLUD + not.b d0 + move.b (ButtonState).w, d1 + eor.b d0, d1 + and.b d0, d1 + move.b d0, (ButtonState).w + move.b d1, (ButtonStateNew).w + + rts + +FileByNameSimple: + move.b #0, $a1200e + lea $a12010, a1 +.copyname + move.b (a0), (a1)+ + tst.b (a0)+ + bne .copyname + + bset #1, $A12003; give SUB CPU control of WordRAM + +.waitready + tst.b $a1200f + beq .waitready + + + move.b #3, $a1200e + +.waitdone + cmp.b #$FF, $a1200f + beq .notfound + tst.b $a1200f + bne .waitdone + + bclr #1, $a12003; get control of WordRAM + rts + +.notfound + bra .notfound + +LoadSLO: + lea LoaderFile(pc), a0 + bsr FileByNameSimple + move.w #(.copyEnd-.copy-1), d0 + lea .copy(pc), a0 + lea ($FFFF8000).w, a1 + move.l a1, a2 +.copycopy + move.b (a0)+, (a1)+ + dbra d0, .copycopy + move.w #$2000, d0; more than enough for slo.bin + lea $200000, a0 + lea $FF0000, a1 + jmp (a2) +.copy + move.b (a0)+, (a1)+ + dbra d0, .copy + jmp $FF0000 +.copyEnd + +SpriteData: + incbin bultest.bin +BgFile: + dc.b "LOGO.BIN",0 +LoaderFile: + dc.b "SLO.BIN",0 + +PalData: + diff -r bbfa7bf69620 -r 97ec271a513f subboot.s68 --- a/subboot.s68 Tue May 01 20:43:25 2012 -0700 +++ b/subboot.s68 Mon Sep 02 21:22:47 2013 -0700 @@ -1,19 +1,313 @@ org $6000 SubHeaderStart - dc.b 'MAIN FOOBAR', 0 + dc.b 'MAIN ', 0 align 4 dc.l 0 dc.l End-SubHeaderStart dc.l EntryPoints-SubHeaderStart + dc.l 0 EntryPoints dc.w Main-EntryPoints - dc.w Main-EntryPoints - dc.w Int2Handler-EntryPoints +; dc.w Main-EntryPoints +; dc.w Int2Handler-EntryPoints dc.w 0 Main - bra Main + andi.b #$FA,$FF8003 ;set 2Mbit mode + + lea Packet(pc),a5 + jsr ReadCD + + move.l $80A2,(a5) + move.l (a5),d0 + move.l $80AA,d0 + lsr.l #8,d0 + lsr.l #3,d0 + move.l d0,4(a5) + move.l #$8000,8(a5) + jsr ReadCD + + move.b #0,$FF800F + + +Wait: + tst.b $FF800E + bne Wait + move.b #1,$FF800F +Wait2: + tst.b $FF800E + beq Wait2 + + moveq #0,d0 + move.b $FF800E,d0 + cmpi.b #8,d0 + bgt Wait + add.w d0,d0 + add.w d0,d0 + jmp FuncTable(pc,d0) +FuncTable: + bra.w Wait ;0x0 + bra.w FileList ;0x1 + bra.w FileByNumber ;0x2 + bra.w FileByNameSimple ;0x3 + bra.w FileByNameExtended ;0x4 + bra.w SetExtended ;0x5 + bra.w Jump ;0x6 + bra.w JumpSub ;0x7 + bra.w PlayRAW ;0x8 + + + +FileList: + + move.l #$8000,a0 + move.l #$80000,a1 +NextFile: + moveq #0,d0 + move.b (a0),d0 ;get record length + beq EndList + move.l 6(a0),$20(a1) ;file location + move.l $E(a0),$24(a1) ;file length + moveq #0,d1 + move.b $20(a0),d1 ;file name length + subi.w #1,d1 + beq Terminate ;skip copy if length = 0 + lea $21(a0),a2 + movea.l a1,a4 +CopyName: + move.b (a2)+,(a4)+ ;copy filename to new table + dbra d1,CopyName +Terminate: + move.b #0,(a4) + + adda.l d0,a0 + add.l #$28,a1 + bra NextFile + +EndList: + move.b #$FF,(a1) + ori.b #1,$FF8003 + move.b #0,$FF800F + bra Wait + + + + + +FileByNumber: + lea Packet(pc),a5 + move.l $FF8010,(a5) + move.l $FF8014,d0 + move.l $FF8018,8(a5) +File: + move.l d0,$FF8020 + move.l d0,d1 + lsr.l #8,d1 + lsr.l #3,d1 + andi.l #$7FF,d0 + beq SectorAligned + addq #1,d1 + +SectorAligned: + move.l d1,4(a5) + + bsr ReadCD + + move.l $8000,d7 + + ori.b #1,$FF8003 + + move.b #0,$FF800F + bra Wait + + + + +FileByNameSimple: + lea Packet(pc),a5 + move.l #$80000,8(a5) + move.l #$40000,4(a5) + move.l #0,(BeginOffset) + +FileByNameExtended: + move.l #$FF8010,a0 + bsr FindFile + bcc FileNotFound + + lsl.l #8,d1 + lsl.l #3,d1 + add.l (BeginOffset),d1 + sub.l (BeginOffset),d0 + lsr.l #8,d1 + lsr.l #3,d1 + + lea Packet(pc),a5 + + move.l 4(a5),d3 + cmp.l d0,d3 + bgt TooBig ;File is either smaller than requested length or size of WordRAM + + move.l d3,d0 +TooBig: + + move.l d1,(a5) + bra File + +FileNotFound: + ori.b #1,$FF8003 + move.b #$FF,$FF800F + bra Wait + + + + +SetExtended: + lea Packet(pc),a5 + move.l $FF8010,8(a5) + move.l $FF8014,4(a5) + move.l $FF8018,(BeginOffset) + + move.b #0,$FF800F + bra Wait + + + +Jump: + move.l $FF8010,a0 + jmp (a0) + +JumpSub: + move.l $FF8010,a0 + jsr (a0) + + move.b #0,$FF800F + bra Wait + +PlayRAW: + + + move.l $FF8010,a0 ;get start address + move.w $FF8014,d2 ;get playback frequency + + + move.w #$F,d6 + move.b #$FF,d1 + + +BankLoop: + + addq #1,d1 ;increment bank + move.b d1,$FF000F ;turn off sound production,and set waveform memory bank + move.l #$FF2001,a1 + move.w #$FFF,d7 + +MoveIt: + move.b (a0)+,d0 + move.b d0,(a1) + addq #2,a1 + cmp.b #$FF,d0 + dbeq d7,MoveIt + + dbeq d6,BankLoop + + move.b #$40,$FF000F ;set control to channel 0 + + move.b #$FF,$FF0001 ;set volume + + move.b #$FF,$FF0003 ;set Pan + + move.b #$00,$FF0005 ;set FDL (Playback frequency low order byte) + + move.b #$08,$FF0007 ;set FDH (Playback frequency high order byte) + + move.b #$00,$FF0009 ;LSL (Loop Start Address low order byte) + + move.b #$00,$FF000B ;LSH (Loop Start Address high order byte) + + move.b #$00,$FF000D ;ST (Start address high order byte,low order byte is always equal to 0) + + move.b #$FE,$FF0011 ;turn on channel 0 + + move.b #$80,$FF000F ;start sound playback + + move.b #0,$FF800F + + bra Wait + + + +FindFile: + move.l #$8000,a2 + +NextName: + moveq #0,d3 + move.b (a2),d3 + beq NotFound + + lea $21(a2),a3 + move.l a0,a1 +Compare: + tst.b (a1) + beq Found + cmp.b (a1)+,(a3)+ + beq Compare + + add.l d3,a2 + bra NextName + +NotFound: + move #0,CCR + rts + +Found: + move.l $E(a2),d0 + move.l 6(a2),d1 + move #1,CCR + rts + + + + +ReadCD: + movea.l a5,a0 + move.w #$89,d0 ;init CD controller + jsr $5f22 + move.w #$20,d0 ;start read operation + jsr $5f22 + +Check: + move.w #$8A,d0 ;check for data + jsr $5f22 + bcs Check + +Check2: + move.w #$8B,d0 + jsr $5f22 + bcc Check2 + +Check3: + move.w #$8C,d0 + movea.l 8(a5),a0 + lea $C(a5),a1 + jsr $5f22 + bcc Check3 + + move.w #$8D,d0 + jsr $5f22 + + addi.l #$800,8(a5) + addq.l #1,(a5) + subq.l #1,4(a5) + bne Check + rts Int2Handler rte +BeginOffset: + dc.l $0 +Packet: + dc.l $10, 1, $8000, ExtraJunk, 0 +ExtraJunk: + dc.b 0 + End diff -r bbfa7bf69620 -r 97ec271a513f tiles2img.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tiles2img.py Mon Sep 02 21:22:47 2013 -0700 @@ -0,0 +1,229 @@ +#!/usr/bin/env python +from PIL import Image + +def gchannel(Val): + return (Val >> 4) & 0xE + +threshold = 127 + +def get_color_info(pixels, rng, threshold, exclude={}): + gencolors = {} + A = 255 + for idx in rng: + color = pixels[idx] + if len(color) == 4: + (R, G, B, A) = color + else: + (R, G, B) = color + if A > threshold: + gcolor = (gchannel(R), gchannel(G), gchannel(B)) + if not gcolor in exclude: + if gcolor in gencolors: + gencolors[gcolor] += 1 + else: + gencolors[gcolor] = 1 + glist = [(gencolors[color], color) for color in gencolors] + glist.sort() + glist.reverse() + return glist + +def totiles(im, palette): + pass + +def make_palette(im, trans_thresh, max_global, max_line): + pixels = im.getdata() + (width, height) = im.size + colors = get_color_info(pixels, xrange(0, height * width), trans_thresh) + glob_pal = {} + for idx in xrange(0, min(max_global, len(colors))): + (count, color) = colors[idx] + glob_pal[color] = idx + line_pals = [] + if max_global < len(colors): + for line in xrange(0, height): + linestart = line * width + linecolors = get_color_info(pixels, xrange(linestart, linestart+width), trans_thresh, glob_pal) + line_pal = {} + for idx in xrange(0, min(max_line, len(linecolors))): + (count, color) = linecolors[idx] + line_pal[color] = idx + line_pals.append(line_pal) + return (glob_pal, line_pals) + +def color_dist(a, b): + (ra, ga, ba) = a + (rb, gb, bb) = b + return abs(ra-rb)**2 + abs(ga-gb)**2 + abs(ba-bb)**2 + +def trans_image(im, trans_thresh, pal): + (global_pal, line_pals) = pal + pixels = im.getdata() + (width, height) = im.size + gpixels = [] + A = 255 + x = 0 + y = 0 + for pixel in pixels: + if x == width: + x = 0 + y += 1 + if width % 8: + for i in xrange(0, 8-(width%8)): + gpixels.append(0) + if len(pixel) == 4: + (R, G, B, A) = pixel + else: + (R, G, B) = pixel + if A > trans_thresh: + gpixel = (gchannel(R), gchannel(G), gchannel(B)) + if gpixel in global_pal: + gpixels.append(global_pal[gpixel]) + elif gpixel in line_pals[y]: + gpixels.append(line_pals[y][gpixel] + len(global_pal)) + else: + bestdist = color_dist((0,0,0), (15, 15, 15)) + bestpal = 0 + for cur in global_pal: + curdist = color_dist(gpixel, cur) + if curdist < bestdist: + bestdist = curdist + bestpal = global_pal[cur] + for cur in line_pals[y]: + curdist = color_dist(gpixel, cur) + if curdist < bestdist: + bestdist = curdist + bestpal = line_pals[y][cur] + gpixels.append(bestpal) + else: + gpixels.append(0) + x += 1 + if width % 8: + for i in xrange(0, 8-(width%8)): + gpixels.append(0) + width += 8-(width%8) + if height % 8: + for y in xrange(0, 8-(height%8)): + for x in xrange(0, width): + gpixels.append(0) + height += 8-(height%8) + + return (width, height, gpixels) + +def appendword(b, word): + b.append(word >> 8) + b.append(word & 0xff) + +def to_tiles(palpix): + (width, height, pixels) = palpix + b = bytearray() + cwidth = width/8 + cheight = height/8 + words = len(pixels)/4 + appendword(b, words) + appendword(b, cwidth) + appendword(b, cheight) + + for cy in xrange(0, cheight): + ystart = cy*8*width + for cx in xrange(0, cwidth): + startoff = (cx*8) + ystart + for row in xrange(0, 8): + rowoff = startoff + row*width + for bytecol in xrange(0, 4): + boff = bytecol * 2 + rowoff + #print 'boff:', boff, 'len(pixels)', len(pixels), 'cx', cx, 'cy', cy, 'cwidth', cwidth, 'cheight', cheight + #print 'pixels[boff]:', pixels[boff] + b.append(pixels[boff] << 4 | pixels[boff+1]) + return b + +def add_pal_entries(tiles, pal): + (global_pal, line_pals) = pal + pal_list = [()] * len(global_pal) + for entry in global_pal: + pal_list[global_pal[entry]] = entry + for entry in pal_list: + (R, G, B) = entry + tiles.append(B) + tiles.append(G << 4 | R) + for line in line_pals: + pal_list = [()] * len(line) + for entry in line: + pal_list[line[entry]] = entry + for entry in pal_list: + (R, G, B) = entry + tiles.append(B) + tiles.append(G << 4 | R) + +def getcolor(tiles, fixedpal, linepals, width, x, y): + celly = y/8 + cellx = x/8 + resty = y%8 + restx = x%8 + cellwidth = width / 8 + offset = celly * 32 * cellwidth + resty * 4 + cellx * 32 + restx / 2 + if restx & 1: + palidx = tiles[offset] & 0xF + else: + palidx = (tiles[offset] >> 4) & 0xF + if palidx < len(fixedpal): + return fixedpal[palidx] + return linepals[y][palidx - len(fixedpal)] + +def to_pixels(tiles, im): + (_, width, height), tiles, (fixedpal, linepals) = tiles + for y in xrange(0, height): + for x in xrange(0, width): + color = getcolor(tiles, fixedpal, linepals, width, x, y) + im.putpixel((x,y), color) + return im + +def expand_pal(pal): + def expand_pal_int(pal): + return ((pal << 4) & 0xE0, pal & 0xE0, (pal >> 4) & 0xE0) + fixedpal, linepals = pal + fixedpal = [expand_pal_int(color) for color in fixedpal] + linepals = [[expand_pal_int(color) for color in linepal] for linepal in linepals] + return (fixedpal, linepals) + +def open_tiles(name): + from struct import unpack, unpack_from + f = open(name, 'rb') + header = f.read(6) + words,width,height = unpack('>HHH', header) + width *= 8 + height *= 8 + meta = (words, width, height) + pixels = bytearray(f.read(words * 2)) + numfixed = 12 + numdynamic = 4 + fixedpalb = f.read(numfixed*2) + fixedpal = [] + for offset in xrange(0, numfixed*2, 2): + color, = unpack_from('>H', fixedpalb, offset) + fixedpal.append(color) + linepals = [] + linepalsize = numdynamic * height * 2 + linepalb = f.read(linepalsize) + for baseoffset in xrange(0, linepalsize, numdynamic * 2): + linepal = [] + for offset in xrange(baseoffset, baseoffset + numdynamic * 2, 2): + color, = unpack_from('>H', linepalb, offset) + linepal.append(color) + linepals.append(linepal) + return (meta, pixels, (fixedpal, linepals)) + +def main(argv): + if len(argv) < 3: + print "Not enough arguments" + return + fname = argv[1] + tiles = open_tiles(fname) + im = Image.new('RGB', (tiles[0][1], tiles[0][2])) + tiles = (tiles[0], tiles[1], expand_pal(tiles[2])) + to_pixels(tiles, im) + out = open(argv[2], 'wb') + im.save(out) + +if __name__ == '__main__': + import sys + main(sys.argv)