From 8bd7b3e350246d6611e0f4655a4dbe0cea2cbd1d Mon Sep 17 00:00:00 2001 From: alpine9000 Date: Sat, 26 Mar 2016 14:18:51 +1100 Subject: [PATCH] text work in progress --- 024.simple_text/Makefile | 25 ++ 024.simple_text/README.md | 19 ++ 024.simple_text/alpine_bootblock.s | 352 +++++++++++++++++++++++++++++ 024.simple_text/blit.s | 99 ++++++++ 024.simple_text/constants.i | 10 + 024.simple_text/cpu.s | 28 +++ 024.simple_text/disk.s | 27 +++ 024.simple_text/font.png | Bin 0 -> 7829 bytes 024.simple_text/image.s | 54 +++++ 024.simple_text/includes.i | 7 + 024.simple_text/init.s | 32 +++ 024.simple_text/link.script.x | 28 +++ 024.simple_text/module.s | 21 ++ 024.simple_text/palette.pal | 17 ++ 024.simple_text/simple_text.s | 139 ++++++++++++ 024.simple_text/trackloader.s | 203 +++++++++++++++++ 024.simple_text/utils.s | 44 ++++ 17 files changed, 1105 insertions(+) create mode 100644 024.simple_text/Makefile create mode 100644 024.simple_text/README.md create mode 100644 024.simple_text/alpine_bootblock.s create mode 100644 024.simple_text/blit.s create mode 100644 024.simple_text/constants.i create mode 100644 024.simple_text/cpu.s create mode 100644 024.simple_text/disk.s create mode 100644 024.simple_text/font.png create mode 100644 024.simple_text/image.s create mode 100644 024.simple_text/includes.i create mode 100644 024.simple_text/init.s create mode 100644 024.simple_text/link.script.x create mode 100644 024.simple_text/module.s create mode 100644 024.simple_text/palette.pal create mode 100644 024.simple_text/simple_text.s create mode 100644 024.simple_text/trackloader.s create mode 100644 024.simple_text/utils.s diff --git a/024.simple_text/Makefile b/024.simple_text/Makefile new file mode 100644 index 0000000..4940b17 --- /dev/null +++ b/024.simple_text/Makefile @@ -0,0 +1,25 @@ +EXAMPLE_NAME=simple_text + +USERSTACK_ADDRESS=7fffc # userstack used by bootblock +BASE_ADDRESS=4000 # if you change this you must also change link.script.x + # note: this must be high enough not to conflict with MFMbufE + +BOOTBLOCK_ASM=alpine_bootblock.s +OBJS=out/init.o out/utils.o out/trackloader.o out/image.o out/disk.o out/blit.o out/cpu.o + + +IMAGES=font.png +IMAGEDATA=$(addprefix out/, $(IMAGES:.png=.bin)) +VASM_EXTRA_ARGS= + +#SYMBOL_INFO=-M +LINK_COMMANDLINE=vlink -T link.script.x -brawbin1 $< $(OBJS) $(SYMBOL_INFO) -o out/main.bin + +include ../shared/base.mk + + +out/%.bin: ../assets/%.png + $(IMAGECON) --input $< $(IMAGECON_ARGS) --output-bitplanes --output-palette-asm --output-palette --output out/$* --colors=16 --use-palette palette.pal --output-mask + +out/main.o: $(IMAGEDATA) constants.i Makefile link.script.x palette.pal +out/init.o: constants.i Makefile \ No newline at end of file diff --git a/024.simple_text/README.md b/024.simple_text/README.md new file mode 100644 index 0000000..aacc3ee --- /dev/null +++ b/024.simple_text/README.md @@ -0,0 +1,19 @@ +photo slideshow +=============== + +The main theme of this demo is trackloading data whilst the application is running. + +We cram a DD floppy full of image and music data, then load and display each image in turn whilst playing a P61 module. + +There are quite a few new things in here: + + * We use a [modified bootloader](alpine_bootloader.s) that reads the size of the main program from the disk before trackloading it. + * Photon's trackloader is also now copied into the main program so it can be used to load subsequent data. + * We use multiple sections and a [linker script](link.script.x) to help with organising data on the ADF image. The linker script is not technically required, however I wanted to see what I could do with vlink and linker scripts. + * We switched to the [doynamite68k](https://github.com/AxisOxy/Planet-Rocklobster/tree/master/tools/doynamite68k) compressor/decompressor. The compressed file are larger than those generated by Shinkler, however the decompressor is a lot faster. + * P61 is configured to use CIA mode. + +try it +------ + * [Download disk image](bin/slideshow.adf?raw=true) + * Run in SAE diff --git a/024.simple_text/alpine_bootblock.s b/024.simple_text/alpine_bootblock.s new file mode 100644 index 0000000..1953463 --- /dev/null +++ b/024.simple_text/alpine_bootblock.s @@ -0,0 +1,352 @@ +*** hardware trackloader bootblock +*** original BootLoader.S by Photon ;NOTE: PC-relative code is PREFERRED. +*** see http://coppershade.org/asmskool/SOURCES/Photon-snippets/DDE5-BootLoader.S +*** this version hacked by alpine9000 + + include "../include/registers.i" + +LoaderVars equ $100 ;Useful variables, see CPUinfo: +Loader equ $120 ;start of load script + +MyUserStack equ USERSTACK_ADDRESS ;SSP is at a safe place, but set user + ;stack. + +MFMsync equ $4489 ;AmigaDOS standard sync marker. +MFMlen equ 12980 ;Legacy trackdata read length in bytes + +ShortWt:MACRO ;CPU-independent nop;nop replacement + tst.w (a6) + ENDM + + *** Boot Block starts here *** + +Boot: dc.b 'DOS',0 + dc.l 0,880 + +BootCode: ;gathers some data, turns off OS, copies itself to $100 + + *--- Fetch system info ---* + + move.l 4.w,a6 ;execbase (will soon be destroyed) + move.l 294(a6),d4 ;CPUinfo in lowest byte for your use. + sub.l a4,a4 ;VBR will always be 0 when booting + ;from floppy. No GetVBR needed. + *--- Fastmem available? ---* + + if 1 + move.l #$20004,d1 ;fast+largest + else + move.l #$20002,d1 ;chip+largest + endif + jsr -216(a6) ;AvailMem() + move.l d0,d5 + + sub.l #2048,d5 ;leave room for stacks to grow + moveq #4,d1 + jsr -198(a6) ;AllocMem() + and.l #-8,d0 + move.l d0,a5 ;Start Address + + *--- OS off ---* ;you're nice'n all, but now you die. + + lea $dff002,a6 ;Loader uses this custom base addr + + tst.w (a6) ;wait out blitter +.wblit: btst #6,(a6) + bne.s .wblit + + move.l #$7fff7fff,d1 + move.l d1,$9a-2(a6) ;disable interrupts & req + move.w d1,$9c-2(a6) ;play it again Sam + sub.w #$20,d1 ;don't affect Sprite DMA until Vblank + move.w d1,$96-2(a6) ;disable DMA + + lea MyUserStack,a7 ;some safe place compatible with + ;platform requirements + *--- Copy rest of code/data to fixed address ---* + + lea CopyStart(PC),a0 + lea (LoaderVars).w,a1 + moveq #(BootE-CopyStart)/8,d2 +.copyl: move.l (a0)+,(a1)+ + move.l (a0)+,(a1)+ + dbf d2,.copyl + JMP (Loader).w ;Info from Exec passed in 4 registers + +******************** $100.w ******************** + +CopyStart: + +CPUinfo: dc.l 0 ;$100 +FastMemSize: dc.l 0 ;$104 +SysVBR: dc.l 0 ;$108 +FastMemStart: dc.l 0 ;$10c + +MFMcyl: dc.w 0 +MFMhead: dc.w 0 +MFMdrv: dc.w 0 +MFMchk: dc.l 0 + + dc.w 0 ;padding to $120 + dc.w 0 ; + dc.w 0 ; + +LoadScript: ;At $120, sysinfo in 4 regs, a6=$dff002 + lea CPUinfo(PC),a3 ;Use this for PC-rel in a pinch. + movem.l d4/d5/a4/a5,(a3) + bsr.s WaitEOF + lea NullCop(PC),a0 + move.l a0,$80-2(a6) ;blank copper + move.w #$87d0,$96-2(a6) ;enable DMA (sprites enabled when used) + + *--- load first part ---* + + lea BASE_ADDRESS,a0 ; main entry point + + if 1 + moveq #2,d0 ;from sector 2 + move.w #-1,d1 ;num sectors, - ==Step0 + jsr LoadMFMB + + move.l 4(a0),d1 + add.l #512,d1 + lsr.l #6,d1 + lsr.l #3,d1 + moveq #2,d0 ;from sector 2 + jsr LoadMFMB + + lea $dff000,a6 ;restore plain custombase addr for demo + + move.l (a0),a0 + jmp (a0) ; -> main entry point + + else + + -moveq #2,d0 ;from sector 2 + move.w #-((mainEnd-mainStart)/512),d1;num sectors, - ==Step0 + jsr LoadMFMB + + jmp (a0) ; -> main entry point + + endif + + *** MFMLoader.S by Photon *** ;requires a6=$dff002 + +WaitEOF: + btst #0,5-2(a6) + beq.s WaitEOF +.w1: cmp.b #$37,6-2(a6) + bne.s .w1 +.w2: cmp.b #$37,6-2(a6) ;wait for last PAL line, $138 + beq.s .w2 + rts + +LoadMFMB: ;loadsectors.a0=dst,d0=startsec.W,d1=nrsecs.W(-=Step0) + MOVEM.L D0-D7/A0-A6,-(SP) + lea $bfd100,a4 + bsr MotorOn + tst.w d1 ;if neg length,then Step0 first + bpl.s .NoSt0 + neg.w d1 +.St0: btst #4,$f01(a4) ;head on cyl 0? + beq.s .Rdy0 + bsr.s StepOut + bra.s .St0 +.Rdy0: lea MFMcyl(PC),a1 + clr.w (a1) +.NoSt0: and.l #$ffff,d0 + divu #22,d0 ;startcyl + sub.w MFMcyl(PC),d0 ;delta-step + beq.s .StRdy + bmi.s .StOut + subq.w #1,d0 +.StIn: bsr.s StepIn + dbf d0,.StIn + bra.s .StRdy + not.w d0 ;=neg+sub#1 +.StOut: bsr.s StepOut + dbf d0,.StIn +.StRdy: swap d0 ;startsec within cyl + cmp.w #11,d0 + blt.s .Head0 + sub.w #11,d0 + bra.s .Head1 +.Head0: bset #2,(a4) + lea MFMhead(PC),a1 + clr.w (a1) + bsr LoadTrak ;read track+decode + beq.s .End +.Head1: bclr #2,(a4) ;Head 1 + lea MFMhead(PC),a1 + move.w #1,(a1) + bsr LoadTrak ;read track+decode + beq.s .End + bsr.s StepIn ;1 cyl forward + bra.s .Head0 +.End: bsr.s MotorOff + MOVEM.L (SP)+,D0-D7/A0-A6 + RTS + +StepOut: + bset #1,(a4) + lea MFMcyl(PC),a1 + subq.w #1,(a1) + ShortWt + bclr #0,(a4) + ShortWt + bset #0,(a4) + bsr.s StepWt + RTS + +StepIn: + bclr #1,(a4) + lea MFMcyl(PC),a1 + addq.w #1,(a1) + ShortWt + bclr #0,(a4) + ShortWt + bset #0,(a4) + bsr.s StepWt + RTS + +StepWt: + moveq #67,d6 ;wait >3 ms +LeaveLine: +.loop1: move.b 6-2(a6),d7 +.loop2: cmp.b 6-2(a6),d7 + beq.s .loop2 + dbf d6,.loop1 + RTS + +MotorOn: + move.w MFMdrv(PC),d7 + addq.w #3,d7 + or.b #$78,(a4) + bset d7,(a4) + ShortWt + bclr #7,(a4) ;turns motor on + ShortWt + bclr d7,(a4) + ShortWt +.DiskR: btst #5,$f01(a4) ;wait until motor running + bne.s .DiskR + RTS + +MotorOff: + move.w MFMdrv(PC),d7 + addq.w #3,d7 + bset d7,(a4) + ShortWt + bset #7,(a4) + ShortWt + bclr d7,(a4) + RTS + +LoadTrak: ;loadtrack+decode.a0=dst,d0=secoffs,d1=secsleft + MOVE.W D0,-(SP) + MOVE.W D1,-(SP) + ;; lea (MFMbuf).w,a1 + lea (MFMbuf),a1 + move.w #2,$9c-2(a6) ;Clr Req + move.l a1,$20-2(a6) + move.w #$8210,$96-2(a6) ;DskEna + move.w #MFMsync,$7e-2(a6) + move.w #$9500,$9e-2(a6) + move.w #$4000,$24-2(a6) + move.w #$8000+MFMlen/2,$24-2(a6);DskLen(12980)+DmaEn + move.w #$8000+MFMlen/2,$24-2(a6);start reading MFMdata +.Wrdy: + btst #1,$1f-2(a6) ;wait until data read + beq.s .Wrdy + move.w d0,d2 + add.w d1,d2 ;highest sec# (d0=lowest) + cmp.w #11,d2 + ble.s .NoOvr + moveq #11,d2 +.NoOvr: sub.w d0,d2 ;nrsecs + move.l #$55555555,d3 ;and-const + move.w d2,d1 + subq.w #1,d1 ;loopctr +.FindS: cmp.w #MFMsync,(a1)+ ;search for a sync word + bne.s .FindS + cmp.b (a1),d3 ;search for 0-nibble + bne.s .FindS + move.l (a1)+,d4 ;decode fmtbyte/trk#,sec#,eow# + move.l (a1)+,d5 + and.w d3,d4 + and.w d3,d5 + add.w d4,d4 + or.w d5,d4 + lsr.w #8,d4 ;sec# + sub.w d0,d4 ;do we want this sec? + bmi.s .Skip + cmp.w d2,d4 + blt.s .DeCode +.Skip: lea 48+1024(a1),a1 ;nope + bra.s .FindS +.DeCode:lea 40(a1),a1 ;found a sec,skip unnecessary data + move.l a1,d6 + lea MFMchk(PC),a1 + clr.l (a1) + move.l d6,a1 + move.l (a1)+,d6 ;decode data chksum.L + move.l (a1)+,d5 + and.l d3,d6 + and.l d3,d5 + add.l d6,d6 + or.l d5,d6 ;chksum + lea 512(a1),a2 + add.w d4,d4 ;x512 + lsl.w #8,d4 + lea (a0,d4.w),a3 ;dest addr for this sec + moveq #127,d7 +.DClup: move.l (a1)+,d4 + move.l (a2)+,d5 + and.l d3,d4 + and.l d3,d5 + eor.l d4,d6 ;EOR with checksum + eor.l d5,d6 ;EOR with checksum + add.l d4,d4 + or.l d5,d4 + move.l d4,(a3)+ + dbf d7,.DClup ;chksum should now be 0 if correct + lea MFMchk(PC),a1 + or.l d6,(a1) ;or with track total chksum + move.l a2,a1 + dbf d1,.FindS ;decode next sec + MOVE.W (SP)+,D1 + MOVE.W (SP)+,D0 + move.l MFMchk(PC),d3 ;track total chksum OK? + bne LoadTrak ;no,retry + moveq #0,d0 ;set to start of track + move.w d2,d3 + add.w d3,d3 + lsl.w #8,d3 + add.w d3,a0 + sub.w d2,d1 ;sub #secs loaded + RTS + +NullCop: + dc.w $1fc,0 + dc.w $100,$0200 + dc.w $96,$0020 ;ensure sprite DMA is off until needed + dc.w $ffdf,$fffe + dc.l -2 +BootE: + + *** Boot Block ends here *** + + dc.b "BootLoader by Photon/Scoopex" + ;pad bootblock to correct size + cnop 0,1024 + +;MFMbuf is placed here after bootblock end, $3c0.w or so when copied. +MFMbuf equ LoaderVars+(BootE-CopyStart) +MFMbufE equ MFMbuf+MFMlen ;lowest free address. $372e for a full bootblock. + +mainStart: + incbin "out/main.bin" + cnop 0,512 +mainEnd: + end + diff --git a/024.simple_text/blit.s b/024.simple_text/blit.s new file mode 100644 index 0000000..be994fc --- /dev/null +++ b/024.simple_text/blit.s @@ -0,0 +1,99 @@ + include "includes.i" + xdef blitObject64 + +;; BLTCON? configuration +;; http://amigadev.elowar.com/read/ADCD_2.1/Hardware_Manual_guide/node011C.html +;; blitter logic function minterm truth table +;; fill in D column for desired function +;; A(mask) B(bob) C(bg) D(dest) +;; - - - - +;; 0 0 0 0 +;; 0 0 1 1 +;; 0 1 0 0 +;; 0 1 1 1 +;; 1 0 0 0 +;; 1 0 1 0 +;; 1 1 0 1 +;; 1 1 1 1 +;; read D column from bottom up = 11001010 = $ca +;; this is used in the LF? bits + +BLIT_LF_MINTERM equ $ca +BLIT_DEST equ $100 +BLIT_SRCC equ $200 +BLIT_SRCB equ $400 +BLIT_SRCA equ $800 +BLIT_ASHIFTSHIFT equ 12 ;Bit index of ASH? bits + +BLIT_BOB_WIDTH equ 32 ; Must blit extra word to allow shifting +BLIT_BOB_HEIGHT equ 12 +BLIT_BOB_WIDTH_BYTES equ BLIT_BOB_WIDTH/8 +BLIT_BOB_WIDTH_WORDS equ BLIT_BOB_WIDTH/16 + +blitWait: + tst DMACONR(a6) ;for compatibility +.waitblit: + btst #6,DMACONR(a6) + bne.s .waitblit + rts + + ;; blitobject + ;; d0 - xpos + ;; d1 - ypos + ;; a0 - display + ;; a1 - object + ;; a2 - mask +blitObject64: + movem.l d0-a6,-(sp) + bsr blitWait + + ;; d0 = XPOS + ;; d1 = YPOS + ;; d4 = XPOS_BYTES + + move.w d0,d4 ; d4 = XPOS + lsr.w #3,d4 ; d4 = XPOS_BYTES + + if 1 + sub.w #8,d0 + endif + + ;; this shift will give us the bits to shift (bits 0-3) in bits (12-15) of d0 + lsl.w #8,d0 ; BLIT_SOURCE_SHIFT< sectors + lsr.l #3,d0 + add.l #2,d0 ; offset for bootblock + + + add.l #512,d1 + lsr.l #6,d1 ; bytes -> sectors + lsr.l #3,d1 + neg.w d1 + jsr LoadMFMB ; load the data! + + movem.l (sp)+,d0-a6 + rts diff --git a/024.simple_text/font.png b/024.simple_text/font.png new file mode 100644 index 0000000000000000000000000000000000000000..67f0b5448f1a2c8932a65e8d5083e39b3c448c59 GIT binary patch literal 7829 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 literal 0 HcmV?d00001 diff --git a/024.simple_text/image.s b/024.simple_text/image.s new file mode 100644 index 0000000..a0b31f8 --- /dev/null +++ b/024.simple_text/image.s @@ -0,0 +1,54 @@ + include "includes.i" + + xdef DisplayBitplane + +LoadImage: + ;; d0 - size + ;; a1 - start address + ;; a2 - InstallColorPalette(X) address + + lea bitplanes3,a0 + bsr LoadDiskData ; load data from disk + + ;; move.l nextbitplane,a1 ; decompress into offscreen bitplanesp(1/2) + + ;; a0 = Input buffer to be decompressed. Must be 16-bit aligned! + ;; a1 = Output buffer. Points to the end of the data at exit + jsr Depack + + jsr WaitVerticalBlank ; avoid tearing when we show the new image + jsr (a2) ; install new color palette + jsr DisplayBitplane ; display new image + + rts + + +DisplayBitplane: + ;; a0 - bitplane address + movem.l d0/a0-a1,-(sp) + moveq.l #0,d0 + move.l a0,a1 + lea copperListBplPtr,a0 + jsr PokeBitplanePointers + movem.l (sp)+,d0/a0-a1 + rts + +PokeBitplanePointers: + ; d0 = frame offset in bytes + ; a0 = BPLP copper list address + ; a1 = bitplanes pointer + movem.l d0-a6,-(sp) + add.l d0,a1 ; Offset for odd/even frames + moveq #SCREEN_BIT_DEPTH-1,d0 +.bitplaneloop: + move.l a1,d1 + move.w d1,2(a0) + swap d1 + move.w d1,6(a0) + lea SCREEN_WIDTH_BYTES(a1),a1 + addq #8,a0 + dbra d0,.bitplaneloop + movem.l (sp)+,d0-a6 + rts + + diff --git a/024.simple_text/includes.i b/024.simple_text/includes.i new file mode 100644 index 0000000..e5906ae --- /dev/null +++ b/024.simple_text/includes.i @@ -0,0 +1,7 @@ + include "../include/registers.i" + include "../include/vector.i" + include "../include/beambits.i" + include "../include/bplconbits.i" + include "hardware/dmabits.i" + include "hardware/intbits.i" + include "constants.i" \ No newline at end of file diff --git a/024.simple_text/init.s b/024.simple_text/init.s new file mode 100644 index 0000000..ba47adc --- /dev/null +++ b/024.simple_text/init.s @@ -0,0 +1,32 @@ + include "includes.i" + + xdef Init + + ;; custom chip base globally in a6 +Init: + movem.l d0-a6,-(sp) + ;; move #$7ff,DMACON(a6) ; disable all dma + ;; move #$7fff,INTENA(a6) ; disable all interrupts + + ;; lea Level3InterruptHandler,a3 + ;; move.l a3,LVL3_INT_VECTOR + + ;; set up playfield + move.w #(RASTER_Y_START<<8)|RASTER_X_START,DIWSTRT(a6) + move.w #((RASTER_Y_STOP-256)<<8)|(RASTER_X_STOP-256),DIWSTOP(a6) + + move.w #(RASTER_X_START/2-SCREEN_RES),DDFSTRT(a6) + move.w #(RASTER_X_START/2-SCREEN_RES)+(8*((SCREEN_WIDTH/16)-1)),DDFSTOP(a6) + + move.w #(SCREEN_BIT_DEPTH<<12)|COLOR_ON,BPLCON0(a6) + move.w #SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH-SCREEN_WIDTH_BYTES,BPL1MOD(a6) + move.w #SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH-SCREEN_WIDTH_BYTES,BPL2MOD(a6) + + ;; install copper list, then enable dma and selected interrupts + lea copperList,a0 + move.l a0,COP1LC(a6) + move.w COPJMP1(a6),d0 + move.w #(DMAF_BLITTER|DMAF_SETCLR!DMAF_COPPER!DMAF_RASTER!DMAF_MASTER),DMACON(a6) + ;; move.w #(INTF_SETCLR|INTF_VERTB|INTF_INTEN),INTENA(a6) + movem.l (sp)+,d0-a6 + rts \ No newline at end of file diff --git a/024.simple_text/link.script.x b/024.simple_text/link.script.x new file mode 100644 index 0000000..4933239 --- /dev/null +++ b/024.simple_text/link.script.x @@ -0,0 +1,28 @@ +MEMORY +{ + disk: org = 0x4000, len = 901120-0x4000 + ram: org = 0x00000, len = 0x80000 +} + +SECTIONS +{ + load : { + startCode = .; + *(.text) + *(.data) + *(CODE) + *(DATA) + endCode = .; + } > disk + + noload ALIGN(512) : { + startData = .; + *(.noload) + endData = .; + } > disk + + bss (NOLOAD) : { + . = endCode; + *(.bss) + } > ram; +} \ No newline at end of file diff --git a/024.simple_text/module.s b/024.simple_text/module.s new file mode 100644 index 0000000..fd10212 --- /dev/null +++ b/024.simple_text/module.s @@ -0,0 +1,21 @@ + xdef LoadModule + +LoadModule: + movem.l d0-a6,-(sp) + lea bitplanes1,a0 + lea compressedModule,a1 + move.l #endCompressedModule,d0 + sub.l #compressedModule,d0 + ;; a0 - destination address + ;; a1 - start address + ;; d0 - size + jsr LoadDiskData + + ;; a0 - input buffer to be decompressed. Must be 16-bit aligned! + ;; a1 - output buffer. Points to the end of the data at exit + lea bitplanes1,a0 + lea Module,a1 + jsr Depack + + movem.l (sp)+,d0-a6 + rts \ No newline at end of file diff --git a/024.simple_text/palette.pal b/024.simple_text/palette.pal new file mode 100644 index 0000000..85de45b --- /dev/null +++ b/024.simple_text/palette.pal @@ -0,0 +1,17 @@ +000 000 000 000 +255 255 255 255 +255 000 000 255 +000 255 000 255 +000 000 255 255 +555 555 555 255 +255 255 000 255 +255 255 000 255 +255 255 000 255 +255 255 000 255 +255 255 000 255 +255 255 000 255 +255 255 000 255 +255 255 000 255 +255 255 000 255 +255 255 000 255 + diff --git a/024.simple_text/simple_text.s b/024.simple_text/simple_text.s new file mode 100644 index 0000000..42d83ac --- /dev/null +++ b/024.simple_text/simple_text.s @@ -0,0 +1,139 @@ + include "includes.i" + + xdef PokeBitplanePointers + xdef copperList + xdef copperListAlternate + xdef bitplanes1 + xdef bitplanes2 + xdef bitplanes3 + xdef Module + xdef copperListBplPtr + xdef copperListAlternateBplPtr + +byteMap: + dc.l Entry + dc.l endCode-byteMap + +Entry: + lea userstack,a7 + lea CUSTOM,a6 + + move #$7ff,DMACON(a6) ; disable all dma + move #$7fff,INTENA(a6) ; disable all interrupts + + jsr InstallPalette + + lea Level3InterruptHandler,a3 + move.l a3,LVL3_INT_VECTOR + + move.w #(INTF_SETCLR|INTF_VERTB|INTF_INTEN),INTENA(a6) + + lea bitplanes1,a0 + move.l #4,d0 ;color + jsr CpuFillColor + + + jsr DisplayBitplane ; select it + + if 0 + lea bitplanes2,a0 + move.l #3,d0 ;color + jsr CpuFillColor + endif + + + jsr Init ; enable the playfield + +.mainLoop: + jsr WaitVerticalBlank + jsr WaitVerticalBlank + jsr WaitVerticalBlank + jsr WaitVerticalBlank + jsr WaitVerticalBlank + + ;; blitobject64 + ;; d0 - xpos + ;; d1 - ypos + ;; a0 - display + ;; a1 - object + ;; a2 - mask + + ;; add.l #1,xpos + move.l #4,xpos + move.l xpos,d0 + move.l #50,d1 + lea bitplanes1,a0 + if 1 + sub.l #2,a0 + endif + lea font,a1 + lea fontMask,a2 + jsr blitObject64 + + bra .mainLoop + +xpos: + dc.l 0 +Level3InterruptHandler: + movem.l d0-a6,-(sp) + lea CUSTOM,a6 +.checkVerticalBlank: + move.w INTREQR(a6),d0 + and.w #INTF_VERTB,d0 + beq.s .checkCopper + +.verticalBlank: + move.w #INTF_VERTB,INTREQ(a6) ; clear interrupt bit + +.checkCopper: + move.w INTREQR(a6),d0 + and.w #INTF_COPER,d0 + beq.s .interruptComplete +.copperInterrupt: + move.w #INTF_COPER,INTREQ(a6) ; clear interrupt bit + +.interruptComplete: + movem.l (sp)+,d0-a6 + rte + + +copperList: +copperListBplPtr: + dc.w BPL1PTL,0 + dc.w BPL1PTH,0 + dc.w BPL2PTL,0 + dc.w BPL2PTH,0 + dc.w BPL3PTL,0 + dc.w BPL3PTH,0 + dc.w BPL4PTL,0 + dc.w BPL4PTH,0 + dc.w BPL5PTL,0 + dc.w BPL5PTH,0 + dc.w BPL6PTL,0 + dc.w BPL6PTH,0 + dc.w $106,$c00 ;AGA sprites, palette and dual playfield reset + dc.w $1FC,0 ;AGA sprites and burst reset + dc.l $fffffffe + dc.l $fffffffe + +InstallPalette: + include "out/font-palette.s" + rts + +font: + incbin "out/font.bin" +fontMask: + incbin "out/font-mask.bin" + + section .bss +bitplanes1: + ds.b IMAGESIZE+(512) +bitplanes2: + ds.b IMAGESIZE+(512*2) +bitplanes3: + ds.b IMAGESIZE+(512*3) +startUserstack: + ds.b $1000 ; size of stack +userstack: + + diff --git a/024.simple_text/trackloader.s b/024.simple_text/trackloader.s new file mode 100644 index 0000000..92cf07a --- /dev/null +++ b/024.simple_text/trackloader.s @@ -0,0 +1,203 @@ +*** MFMLoader.S by Photon *** ;requires a6=$dff002 + + xdef LoadMFMB + +MFMsync equ $4489 ;AmigaDOS standard sync marker. +MFMlen equ 12980 ;Legacy trackdata read length in bytes + +ShortWt:MACRO ;CPU-independent nop;nop replacement + tst.w (a6) + ENDM + +MFMcyl: dc.w 0 +MFMhead: dc.w 0 +MFMdrv: dc.w 0 +MFMchk: dc.l 0 + +LoadMFMB: ;loadsectors.a0=dst,d0=startsec.W,d1=nrsecs.W(-=Step0) + MOVEM.L D0-D7/A0-A6,-(SP) + lea $bfd100,a4 + bsr MotorOn + tst.w d1 ;if neg length,then Step0 first + bpl.s .NoSt0 + neg.w d1 +.St0: btst #4,$f01(a4) ;head on cyl 0? + beq.s .Rdy0 + bsr.s StepOut + bra.s .St0 +.Rdy0: lea MFMcyl(PC),a1 + clr.w (a1) +.NoSt0: and.l #$ffff,d0 + divu #22,d0 ;startcyl + sub.w MFMcyl(PC),d0 ;delta-step + beq.s .StRdy + bmi.s .StOut + subq.w #1,d0 +.StIn: bsr.s StepIn + dbf d0,.StIn + bra.s .StRdy + not.w d0 ;=neg+sub#1 +.StOut: bsr.s StepOut + dbf d0,.StIn +.StRdy: swap d0 ;startsec within cyl + cmp.w #11,d0 + blt.s .Head0 + sub.w #11,d0 + bra.s .Head1 +.Head0: bset #2,(a4) + lea MFMhead(PC),a1 + clr.w (a1) + bsr LoadTrak ;read track+decode + beq.s .End +.Head1: bclr #2,(a4) ;Head 1 + lea MFMhead(PC),a1 + move.w #1,(a1) + bsr LoadTrak ;read track+decode + beq.s .End + bsr.s StepIn ;1 cyl forward + bra.s .Head0 +.End: bsr.s MotorOff + MOVEM.L (SP)+,D0-D7/A0-A6 + RTS + +StepOut: + bset #1,(a4) + lea MFMcyl(PC),a1 + subq.w #1,(a1) + ShortWt + bclr #0,(a4) + ShortWt + bset #0,(a4) + bsr.s StepWt + RTS + +StepIn: + bclr #1,(a4) + lea MFMcyl(PC),a1 + addq.w #1,(a1) + ShortWt + bclr #0,(a4) + ShortWt + bset #0,(a4) + bsr.s StepWt + RTS + +StepWt: + moveq #67,d6 ;wait >3 ms +LeaveLine: +.loop1: move.b 6-2(a6),d7 +.loop2: cmp.b 6-2(a6),d7 + beq.s .loop2 + dbf d6,.loop1 + RTS + +MotorOn: + move.w MFMdrv(PC),d7 + addq.w #3,d7 + or.b #$78,(a4) + bset d7,(a4) + ShortWt + bclr #7,(a4) ;turns motor on + ShortWt + bclr d7,(a4) + ShortWt +.DiskR: btst #5,$f01(a4) ;wait until motor running + bne.s .DiskR + RTS + +MotorOff: + move.w MFMdrv(PC),d7 + addq.w #3,d7 + bset d7,(a4) + ShortWt + bset #7,(a4) + ShortWt + bclr d7,(a4) + RTS + +LoadTrak: ;loadtrack+decode.a0=dst,d0=secoffs,d1=secsleft + MOVE.W D0,-(SP) + MOVE.W D1,-(SP) + lea MFMbuf,a1 + move.w #2,$9c-2(a6) ;Clr Req + move.l a1,$20-2(a6) + move.w #$8210,$96-2(a6) ;DskEna + move.w #MFMsync,$7e-2(a6) + move.w #$9500,$9e-2(a6) + move.w #$4000,$24-2(a6) + move.w #$8000+MFMlen/2,$24-2(a6);DskLen(12980)+DmaEn + move.w #$8000+MFMlen/2,$24-2(a6);start reading MFMdata +.Wrdy: + btst #1,$1f-2(a6) ;wait until data read + beq.s .Wrdy + move.w d0,d2 + add.w d1,d2 ;highest sec# (d0=lowest) + cmp.w #11,d2 + ble.s .NoOvr + moveq #11,d2 +.NoOvr: sub.w d0,d2 ;nrsecs + move.l #$55555555,d3 ;and-const + move.w d2,d1 + subq.w #1,d1 ;loopctr +.FindS: cmp.w #MFMsync,(a1)+ ;search for a sync word + bne.s .FindS + cmp.b (a1),d3 ;search for 0-nibble + bne.s .FindS + move.l (a1)+,d4 ;decode fmtbyte/trk#,sec#,eow# + move.l (a1)+,d5 + and.w d3,d4 + and.w d3,d5 + add.w d4,d4 + or.w d5,d4 + lsr.w #8,d4 ;sec# + sub.w d0,d4 ;do we want this sec? + bmi.s .Skip + cmp.w d2,d4 + blt.s .DeCode +.Skip: lea 48+1024(a1),a1 ;nope + bra.s .FindS +.DeCode:lea 40(a1),a1 ;found a sec,skip unnecessary data + move.l a1,d6 + lea MFMchk(PC),a1 + clr.l (a1) + move.l d6,a1 + move.l (a1)+,d6 ;decode data chksum.L + move.l (a1)+,d5 + and.l d3,d6 + and.l d3,d5 + add.l d6,d6 + or.l d5,d6 ;chksum + lea 512(a1),a2 + add.w d4,d4 ;x512 + lsl.w #8,d4 + lea (a0,d4.w),a3 ;dest addr for this sec + moveq #127,d7 +.DClup: move.l (a1)+,d4 + move.l (a2)+,d5 + and.l d3,d4 + and.l d3,d5 + eor.l d4,d6 ;EOR with checksum + eor.l d5,d6 ;EOR with checksum + add.l d4,d4 + or.l d5,d4 + move.l d4,(a3)+ + dbf d7,.DClup ;chksum should now be 0 if correct + lea MFMchk(PC),a1 + or.l d6,(a1) ;or with track total chksum + move.l a2,a1 + dbf d1,.FindS ;decode next sec + MOVE.W (SP)+,D1 + MOVE.W (SP)+,D0 + move.l MFMchk(PC),d3 ;track total chksum OK? + bne LoadTrak ;no,retry + moveq #0,d0 ;set to start of track + move.w d2,d3 + add.w d3,d3 + lsl.w #8,d3 + add.w d3,a0 + sub.w d2,d1 ;sub #secs loaded + RTS + +;MFMbuf is placed here after bootblock end, $3c0.w or so when copied. +MFMbuf: + dcb.b MFMlen diff --git a/024.simple_text/utils.s b/024.simple_text/utils.s new file mode 100644 index 0000000..e907da9 --- /dev/null +++ b/024.simple_text/utils.s @@ -0,0 +1,44 @@ + xdef WaitVerticalBlank + xdef WaitRaster + xdef Depack + +WaitVerticalBlank: + movem.l d0,-(sp) +.loop: move.l $dff004,d0 + and.l #$1ff00,d0 + cmp.l #303<<8,d0 ; wait for the scan line + bne.b .loop +.loop2 move.l $dff004,d0 + and.l #$1ff00,d0 + cmp.l #303<<8,d0 ; wait for the scal line to pass (A4000 is fast!) + beq.b .loop2 + movem.l (sp)+,d0 + rts + + +WaitRaster: ;wait for rasterline d0.w. Modifies d0-d2/a0. + movem.l d0-a6,-(sp) + move.l #$1ff00,d2 + lsl.l #8,d0 + and.l d2,d0 + lea $dff004,a0 +.wr: move.l (a0),d1 + and.l d2,d1 + cmp.l d1,d0 + bne.s .wr + movem.l (sp)+,d0-a6 + rts + + +Depack: + ;a0 = input buffer to be decompressed. Must be 16-bit aligned! + ;a1 = output buffer. Points to the end of the data at exit + movem.l d0-a6,-(sp) + bsr doynaxdepack ; decompress data + movem.l (sp)+,d0-a6 + rts + + ;; this is one FAST decompression routine! + include "../tools/external/doynamite68k/depacker_doynax.asm" + +