From 78ba46877ad088de879951b7bc05b355e248e7da Mon Sep 17 00:00:00 2001 From: alpine9000 Date: Fri, 26 Feb 2016 15:37:46 +1100 Subject: [PATCH] Simple image display --- image/.gitignore | 3 ++ image/Makefile | 38 ++++++++++++++ image/README.md | 6 +++ image/bootblock.s | 30 +++++++++++ image/image.s | 69 +++++++++++++++++++++++++ image/images/hello.png | Bin 0 -> 12119 bytes {trackdisk => include}/registers.i | 0 tools/bitmap.py | 59 +++++++++++++++++++++ tools/bitmap.pyc | Bin 0 -> 2638 bytes tools/bitplanify.py | 79 +++++++++++++++++++++++++++++ tools/makeadf | Bin 0 -> 8784 bytes trackdisk/Makefile | 6 +-- trackdisk/main.s | 2 +- 13 files changed, 288 insertions(+), 4 deletions(-) create mode 100644 image/.gitignore create mode 100644 image/Makefile create mode 100644 image/README.md create mode 100644 image/bootblock.s create mode 100644 image/image.s create mode 100644 image/images/hello.png rename {trackdisk => include}/registers.i (100%) create mode 100644 tools/bitmap.py create mode 100644 tools/bitmap.pyc create mode 100755 tools/bitplanify.py create mode 100755 tools/makeadf diff --git a/image/.gitignore b/image/.gitignore new file mode 100644 index 0000000..bb875a0 --- /dev/null +++ b/image/.gitignore @@ -0,0 +1,3 @@ +out/ +bin/ +*~ \ No newline at end of file diff --git a/image/Makefile b/image/Makefile new file mode 100644 index 0000000..d266bb1 --- /dev/null +++ b/image/Makefile @@ -0,0 +1,38 @@ +MAKEADF=../tools/makeadf +FLOPPY=bin/image.adf +IMAGE_DATA=out/image-copper.s out/image-data.bin + +all: bin out $(MAKEADF) $(FLOPPY) + +gdrive: all + cp $(FLOPPY) ~/Google\ Drive + +bin: + mkdir bin + +out: + mkdir out + +$(MAKEADF): ../tools/makeadf.c + gcc ../tools/makeadf.c -o $(MAKEADF) + +$(FLOPPY): out/bootblock.bin + $(MAKEADF) out/bootblock.bin > $(FLOPPY) + +out/bootblock.bin: out/bootblock.o + vlink -brawbin1 $< -o $@ + +out/bootblock.o: bootblock.s out/main.bin + vc -c $< -o $@ + +out/main.o: image.s $(IMAGE_DATA) + vc -c $< -o $@ + +out/main.bin: out/main.o + vlink -brawbin1 $< -o $@ + +$(IMAGE_DATA): images/hello.png ../tools/bitplanify.py + ../tools/bitplanify.py images/hello.png --copper $(IMAGE_DATA) + +clean: + rm -rf out bin diff --git a/image/README.md b/image/README.md new file mode 100644 index 0000000..f7c370a --- /dev/null +++ b/image/README.md @@ -0,0 +1,6 @@ +Display a simple image +====================== + +Building on trackdisk.device, we now display a simple color image + +Image display code and conversion tools from https://github.com/vilcans/amiga-startup \ No newline at end of file diff --git a/image/bootblock.s b/image/bootblock.s new file mode 100644 index 0000000..16b7349 --- /dev/null +++ b/image/bootblock.s @@ -0,0 +1,30 @@ + include exec/io.i + include lvo/exec_lib.i + +bootblock: + dc.b "DOS",0 + dc.l 0 + dc.l 880 + +bootEntry: + ;; a6 = Exec base + ;; a1 = trackdisk.device I/O request pointer + + lea $70000,a5 ; main.s entry point + + ;; Load the progam from the floppy using trackdisk.device + move.l #mainEnd-mainStart,IO_LENGTH(a1) + move.l a5,IO_DATA(a1) + move.l #mainStart-bootblock,IO_OFFSET(a1) + jsr _LVODoIO(a6) + + jmp (a5) ; -> main.s entry point + + ;; Pad the remainder of the bootblock + cnop 0,1024 + +mainStart: + incbin "out/main.bin" + cnop 0,512 +mainEnd: + end \ No newline at end of file diff --git a/image/image.s b/image/image.s new file mode 100644 index 0000000..7770427 --- /dev/null +++ b/image/image.s @@ -0,0 +1,69 @@ + include ../include/registers.i + include hardware/dmabits.i + include hardware/intbits.i + +LVL3_INT_VECTOR equ $6c +SCREEN_WIDTH_BYTES equ (320/8) +SCREEN_BIT_DEPTH equ 4 + + +entry: + lea level3InterruptHandler(pc),a3 + move.l a3,LVL3_INT_VECTOR + + lea CUSTOM,a1 + + ;; install copper list and enable DMA + lea copper(pc),a0 + move.l a0,cop1lc(a1) + move.w COPJMP1(a1),d0 + move.w #(DMAF_SETCLR!DMAF_COPPER!DMAF_RASTER!DMAF_MASTER),dmacon(a1) + +.mainLoop: + bra.b .mainLoop + +level3InterruptHandler: + movem.l d0-a6,-(sp) + +.checkVerticalBlank: + lea CUSTOM,a5 + move.w INTREQR(a5),d0 + and.w #INTF_VERTB,d0 + beq.s .checkCopper + +.verticalBlank: + move.w #INTF_VERTB,INTREQ(a5) ; Clear interrupt bit + +.resetBitplanePointers: + lea bitplanes,a1 + lea $dff0e0,a2 + moveq #SCREEN_BIT_DEPTH,d0 +.bitplaneloop: + move.l a1,(a2) + lea SCREEN_WIDTH_BYTES(a1),a1 ; Bit plane data is interleaved + addq #4,a2 + dbra d0,.bitplaneloop + +.checkCopper: + lea CUSTOM,a5 + move.w INTREQR(a5),d0 + and.w #INTF_COPER,d0 + beq.s .interruptComplete +.copperInterrupt: + move.w #INTF_COPER,INTREQ(a5) ; Clear interrupt bit + +.interruptComplete: + movem.l (sp)+,d0-a6 + rte + +copper: + dc.w BPLCON0,(SCREEN_BIT_DEPTH<<12)|$200 ; Set color depth and enable COLOR + dc.w BPL1MOD,SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH-SCREEN_WIDTH_BYTES + dc.w BPL2MOD,SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH-SCREEN_WIDTH_BYTES + + include "out/image-copper.s" + + dc.l $fffffffe +bitplanes: + incbin "out/image-data.bin" + \ No newline at end of file diff --git a/image/images/hello.png b/image/images/hello.png new file mode 100644 index 0000000000000000000000000000000000000000..1048f4902a00f3b2027a1e948f44e274cc1c004a GIT binary patch literal 12119 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 N002ovPDHLkV1oL3=2HLw literal 0 HcmV?d00001 diff --git a/trackdisk/registers.i b/include/registers.i similarity index 100% rename from trackdisk/registers.i rename to include/registers.i diff --git a/tools/bitmap.py b/tools/bitmap.py new file mode 100644 index 0000000..610d370 --- /dev/null +++ b/tools/bitmap.py @@ -0,0 +1,59 @@ +from array import array + + +class BitplaneImage(object): + def __init__(self, byte_width, height, bitplanes): + self.byte_width = byte_width + self.height = height + self.bitplanes = bitplanes + + +def image_to_bitplanes(image, bit_depth): + """ + Convert a PIL image into bitplanes. + + Returns a bitmap image. + """ + bitplanes = [array('c') for _ in xrange(bit_depth)] + width, height = image.size + byte_width = (width + 7) // 8 + + for row in xrange(height): + for byte in xrange(byte_width): + planes = [0] * bit_depth + for bit in xrange(8): + palette_index = image.getpixel((byte * 8 + 7 - bit, row)) + for plane_index in range(bit_depth): + planes[plane_index] |= ((palette_index >> plane_index) & 1) << bit + for plane_index in range(bit_depth): + bitplanes[plane_index].append(chr(planes[plane_index])) + + return BitplaneImage(byte_width, height, bitplanes) + + +def write_interleaved(file, image): + """Write all bitplanes in interleaved mode to a file.""" + for row in xrange(image.height): + offset = row * image.byte_width + for plane in image.bitplanes: + plane[offset:offset + image.byte_width].write(file) + + +def write_bitplane(file, image, bitplane_index): + """Write a single bitplane to a file.""" + image.bitplanes[bitplane_index].write(file) + + +def to_amiga_colors(palette): + """ + Convert 24 bit colors to Amiga 12 bit colors. + palette is a sequence of integers: [r, g, b, ...] + """ + number_of_colors = len(palette) // 3 + amiga_colors = [] + for color_index in xrange(number_of_colors): + r, g, b = [c for c in palette[color_index * 3:(color_index + 1) * 3]] + rgb = ((r >> 4) << 8) | ((g >> 4) << 4) | (b >> 4) + amiga_colors.append(rgb) + + return amiga_colors diff --git a/tools/bitmap.pyc b/tools/bitmap.pyc new file mode 100644 index 0000000000000000000000000000000000000000..748acdb5836c4062f89687b57b720bf9dd2220d7 GIT binary patch literal 2638 zcmb_eO>-MX5ba%AvgO!`lem&NP{lexp$bNV6da&ZPH=n)MLDT;1s5h}Yo#5@t6J^K zyW?a-Nf*Lj;Ko1T!ighSj-2=zocICoUa$O-b0TS4Ju^KsJ>9S0ZtdUY#b18?>zkg; zJ~jN`M=N$9BK#alL`EX}B2MIrais4^RFj`XUW$CX?@Bbs&VEgzx+-%LHB_lfG_OiS zq6OJ)HL+#;hH?L7c`m2pFJ(?ugUGxAL|!NW+l{0(CtIMp<;6pzG82%oEjK z&mEs((kt`24X4LHW{Z*0Sl@=l0CCZXzjS2#;EGILvB;An=zs6Z(Xvc6_Cr^mx-y-U zX)oD}8L(XHpF4>pq zBGWs>K`^YzDtDhO%8kjq^j#WFFG%?@6Nn9T%`KTO$)qWhCBePcCKssP1BmZq-R7g( z-J{=S@90O_D?8_xt?M$Jvm|T7x&SZL9&6YXKj-Kltm>jYl07>w6U^hf@UsTkF+;^y z5Q`o@53=-`$*mW9j~{;R#YDarr#ACWLDybXL*LlrJS|{YA*Hfy>l{KY(u?OIV}c__ zlbC}ob`{TM9;O51bEZOY{DV=b4U8SfrAf3H)ky8b@z|u1CA@owxuT%Ow5yr=c~Toe zWX32O9v5gOsEJlmRUJf(Zj@)w^=y`!9-`%5=p1gPBrrzBSX5%1My9kEuvCqz{u#1g z57hPw_SH)SHVaNe&C`mT5Yl+xx#V1QuR2$qWwdp)_s~9Y75=PBrcvP!R+Msg2LIs< zSX-BeSipF|PU!XH#I$!>bkrxgoh9O2hPa`cXi~VuU!mL(zxYrQ%6{kn=u`vc3>l;uQFXi+#1bY^-vq*81 zS){xoP6vrO4c9A?;g%W-|1D_BtNz;@V+8C)h!a%2VdQb^>gp#4+{Q>jf5h#vh)Arb z==vEQGOHp3*StA(NVY&%S(0KA4M1l5U`T?+1Pp;G7_Rb<^a^!-`(SB?Ig;@Md0Ha@ zgLT2OpeB&zJuvGgh)UI(Y;J)xsc(UFfn$Ieq^jV2SN1TltH3GnR`4p1-T9R9_Ig>8 zWI#*@h zXFinOa+L#>-HOl#-8WVfmv~GToOh*zp@LVD`ij#4|9s}$axS|&Encdkasnmm^6f$? r+9!MYeEad&DL#Za^H8V=^bXbMANV zIp?1Homm*}<=el0yS0unWesB|S{P$tw5e9cPB9fd#x|kpXq+GFdtQ58JNz<@Hj2^+ zZ;L3-k1*tXNPBIl(M0&u!d{UWxiO?88clO<8xuD59BGa>x)GbfRF*aaA>1GVcEXD} zx9nWZst+~CyV~KzyI)$k*mVfXcx&Z=6OWG@$*f^wtU2CI8SkL9CoEHSMpon(w`?Pm3~GzQ^(EaNFF@a^N(UlVk^c@h8gp18t!I?1i$saPh-v$nY+ zURdVm#v|Muk8*T{^JMhj;;Ay;4(UMH8;@eGcY{H59?zswnY269yx+HEJa$R)2Se}v z1h=j;^z!d?aNwmEwf+J3H+H?( z4gr*)X`I4zp_PH@r#8P8?*sG(G_oV1_|)8bQ{2_01b_S_RtSx$XtYLm&N91`iCFi@ z@#F|F$$e;)$J@Uvn>K&3j};0RqbGO&P4ufX{%>fX{%>!2gqhVZHE^KKZMv7xI-ktxB8F=VogVy{J|6$x8vf z@ZEX(7Q7(l3UigG@VD-qwnT8@y`okvXg7=6k{&M$52YMB%R*-_&0Oy)%+mPB`n0Y% zQ}garczu1UrD-a-Jhi4_YJFMJs#xwB?WPr&)T+v)wiGy-U#j8bCG?SvjQi!Aj199&?ys266=(^ujJilI-pehA{oyv;EOyZH*UkLf4# zmD*u&R$Me*CRN~$g)>VR+2cAv$Ftn z(r z+W>Mz;kf5q!&Bqjm@wiw+rV9Vlvdo4iYC%*r#MDoyK&Zp`@}!)#pAk){*A8FG$iio zI&i|_{yzX5Pq2_eH*3yK+yjJh5$oQs(tRMEvC#b=6r;l)XzB_%fTtG^G+{b(@y@@| zgz0|LJ5L8*UQGYDb&lJ5@;U?QB%WW0{PofR#((dU+** h+@X#O9#L&i%{;Ytx}xl|hV|;ny15lw@lH^3{{ZpsHSPca literal 0 HcmV?d00001 diff --git a/trackdisk/Makefile b/trackdisk/Makefile index b858ced..e17ef4d 100644 --- a/trackdisk/Makefile +++ b/trackdisk/Makefile @@ -1,4 +1,4 @@ -MAKEADF=bin/makeadf +MAKEADF=../tools/makeadf FLOPPY=bin/test.adf all: bin out $(MAKEADF) $(FLOPPY) @@ -12,8 +12,8 @@ bin: out: mkdir out -$(MAKEADF): makeadf.c - gcc makeadf.c -o $(MAKEADF) +$(MAKEADF): ../tools/makeadf.c + gcc ../tools/makeadf.c -o $(MAKEADF) $(FLOPPY): out/bootblock.bin $(MAKEADF) out/bootblock.bin > $(FLOPPY) diff --git a/trackdisk/main.s b/trackdisk/main.s index 27a9b9c..e2d74a7 100644 --- a/trackdisk/main.s +++ b/trackdisk/main.s @@ -1,4 +1,4 @@ - include registers.i + include ../include/registers.i include hardware/dmabits.i include hardware/intbits.i