********************************************************************************
* overlay-test
* written : 95..97 by 42Bastian Schick (elw5basc@gp.fht-esslingen.de)
*
* - it now works with interrupts, both gpu-object and timer
* - free ram (without the current irq-routines)
*    $f70-$a8 = 3784 bytes
*     ^    ^__end of dispatcher
*     |_______start of interrupt routines
*
* NOTES: Do _NOT_ use the blitter in interrupt !
*        Do _NOT_ mess with the overlay-registers !
*
* free registers : bank 1 : r0..r19
*                  bank 0 : r0..r27
*
********************************************************************************

                path "\bjl\js\"
                include "macro\help.mac"
                include "macro\joypad1.mac"
                include "macro\overlay.mac"

                isyms "symbols\blit_eq.sym"

                include "include\dispatch.reg"
                include "include\dispatch.equ"

;----------------------
irq_routines    equ $f03f90     ; place at the end (above SP)

IRQ_SP.a        REG 31
IRQ_RTS.a       REG 30          ; redefined !!
IRQ_FLAGADR.a   REG 29
IRQ_FLAG.a      REG 28

IRQ_DUMMY3.a    REG  3
IRQ_DUMMY2.a    REG  2
IRQ_DUMMY1.a    REG  2
IRQ_DUMMY0.a    REG  0

sec.a           REG 25
ms.a            REG 24


                MACRO IRQ_PUSH
                subqt #4,IRQ_SP.a
                store \0,(IRQ_SP.a)
                ENDM

                MACRO IRQ_POP
                load (IRQ_SP.a),\0
                addqt #4,IRQ_SP.a
                ENDM


OBL             equ $8000
OBL0            equ OBL+32*32


                org $f03000
LastJoy         ds.l 2


                run OVLtab-4
; this is the main (first) function
                dc.l (MAIN.loc & $ffff)<<16|MAIN.num*12
; normal overlay-table
; These dc.l _MUST_ have the same order, as the function declarations !
; It is not possible to do a forward-call !

_OVLtab         dc.l InitTextScreen.st,InitTextScreen.len|$10000,InitTextScreen.loc
                dc.l InitIRQ.st,InitIRQ.len|$10000,InitIRQ.loc
                dc.l InitIRQ2.st,InitIRQ2.len|$10000,InitIRQ2.loc
                dc.l init.st,init.len|$10000,init.loc

                dc.l Print.st,Print.len|$10000,Print.loc
                dc.l cls.st,cls.len|$10000,cls.loc
                dc.l my_gfx.st,my_gfx.len|$10000,my_gfx.loc
                dc.l Joypad1.st,Joypad1.len|$10000,Joypad1.loc
                dc.l fak.st,fak.len|$10000,fak.loc
                dc.l MAIN.st,MAIN.len|$10000,MAIN.loc
OVLend

****************
TextScreen      equ $100000

ScreenPtr.a     reg 6
Cursor.a        reg 7

max_x           equ 40
max_y           equ 2
****************************
* Textscreen with 8x8-Font *
* created : 29.06.95       *
* (c) Bastian Schick       *
****************************
;global EQUs
; max_x, max_y must be preset !
;global registers
;Cursor.a       
;ScreenPtr.a                    ; must be initialized !
****************  
* InitTextScreen
clr             reg 2
ptr             reg 1
count           reg 0

                FUNCTION InitTextScreen
                PUSH r0,r1,r2
                movei #TextScreen,r0
                moveta r0,ScreenPtr.a
                movefa ScreenPtr.a,ptr
                xor clr,clr
                movei #max_x*max_y<<2-1,count

;>                subq #1,clr
                store clr,(ptr)
.loop           subq #1,count
                addqt #4,ptr
                jr nz,.loop
                store clr,(ptr)

                xor clr,clr
                moveta clr,Cursor.a
                movei #$f00400,ptr
                movei #$fff,clr
                store clr,(ptr)                 ; set color
                POP r2,r1,r0
                unreg clr,ptr,count
                ENDFUNC InitTextScreen
****************
FUNCTION InitIRQ,$f03000
                RETURN

                org $f03020
                movei #timer_irq,IRQ_RTS.a
                load (IRQ_FLAGADR.a),IRQ_FLAG.a
                jump (IRQ_RTS.a)
                load (IRQ_SP.a),IRQ_RTS.a

                org $f03030
                movei #obj_irq,IRQ_RTS.a
                load (IRQ_FLAGADR.a),IRQ_FLAG.a
                jump (IRQ_RTS.a)
                load (IRQ_SP.a),IRQ_RTS.a
                ENDFUNC InitIRQ,1
****************
FUNCTION InitIRQ2,irq_routines
                RETURN
VBLflag         ds.l 1
****************
* ms-timer
****************
timer_irq::     bclr #3,IRQ_FLAG.a
                addq #4,IRQ_SP.a
                bset #11,IRQ_FLAG.a

                subq #1,ms.a
                jr nn,.cont
                addq #2,IRQ_RTS.a

                movei #999,ms.a
                addq #1,sec.a
.cont
                jump (IRQ_RTS.a)
                store IRQ_FLAG.a,(IRQ_FLAGADR.a)
****************
* object-irq

obj_irq::
                bclr #3,IRQ_FLAG.a
                addqt #4,IRQ_SP.a
                bset #12,IRQ_FLAG.a
                addqt #2,IRQ_RTS.a
;---------------                
                movei #$f00026,r0
                storew r1,(r0)                ; resume OP

                movei #VBLflag,r0
                load (r0),r1
                addq #1,r1
                store r1,(r0)
                subq #2,r1
                movei #$f00058,r0
                storew r1,(r0)
* no need to update the branch-objects => +$30
                movei #OBL+$30,r0
                movei #OBL0+$30,r1
                movei #3*2,r2                  ; max. 3 bitmap-objects

                loadp (r1),r3
.loop           addqt #8,r1
                subq  #1,r2
                storep r3,(r0)
                addqt #8,r0
                jr nz,.loop
                loadp (r1),r3
;---------------
                jump (IRQ_RTS.a)
                store IRQ_FLAG.a,(IRQ_FLAGADR.a)
****************
eof_irq:
                if eof_irq > $f03ffe
                fail "irq-routines out of internal RAM"
                else
                echo "eof_irq %Heof_irq"
                endif
                ENDFUNC InitIRQ2,1
****************
FUNCTION init
;- clear regs 0..19,0.a .. 19.a
                moveq #0,r0
                moveq #0,r1
                moveq #0,r2
                moveq #0,r3
                moveq #0,r4
                moveq #0,r5
                moveq #0,r6
                moveq #0,r7
                moveq #0,r8
                moveq #0,r9
                moveq #0,r10
                moveq #0,r12
                moveq #0,r13
                moveq #0,r14
                moveq #0,r15
                moveq #0,r16
                moveq #0,r17
                moveq #0,r18
                moveq #0,r19
                moveta r0,r0
                moveta r0,r1
                moveta r0,r2
                moveta r0,r3
                moveta r0,r4
                moveta r0,r5
                moveta r0,r6
                moveta r0,r7
                moveta r0,r8
                moveta r0,r9
                moveta r0,r10
                moveta r0,r11
                moveta r0,r12
                moveta r0,r13
                moveta r0,r14
                moveta r0,r15
                moveta r0,r16
                moveta r0,r17
                moveta r0,r18
                moveta r0,r19

                movei #$f03020,r0
                moveta r0,IRQ_SP.a
                movei #$f02100,r0
                moveta r0,IRQ_FLAGADR.a
                InitIRQ         ; init slots
                InitIRQ2        ; init subs
                InitTextScreen
;-------------------------
;- enable gpu-object-irq -

                movei #$f02100,r0
                load (r0),r1
                bset #7,r1      ; enable object irq
                bset #12,r1
                store r1,(r0)
                nop
                nop

;-------------------------
;-- set OBL here, so we sure get the first IRQ

                movei #OBL<<16|OBL>>16,r0
                movei #$f00020,r1
                store r0,(r1)
                movei #$6c1,r0
                movei #$f00028,r1
                storew r0,(r1)
;---------------
;- Init ms-Timer
                movei #$f02100,r0
                load (r0),r1
                bset #6,r1      ; enable timing irq
                store r1,(r0)
                nop
                nop

                movei #999,r0
                moveta r0,ms.a
                xor r0,r0
                moveta r0,sec.a

                movei #$f00050,r0
                movei #26590<<16,r1
                store r1,(r0)   ; Start
;---------------
                ENDFUNC init
****************
;------------------------------------------------------------------------------
****************
* Print        *
                FUNCTION Print
                JSR (r1)
                RETURN
****************
* Print char in r0
********************
PChelp1         reg 3
PChelp          reg 2
ptr             reg 1
CharPtr         reg 0
PrintChar::
                PUSH r1,r2,r3
                movei #ASCII+8,ptr
;>                subq #32,r0                     ; 8x16 starts from SPACE

                shlq #24,CharPtr
                movefa Cursor.a,PChelp          ; get current cursor
                shrq #24-3,CharPtr              ; (r0 and $ff)*8
                shrq #16,PChelp                 ; get x
                add ptr,CharPtr
                movefa ScreenPtr.a,ptr
                add PChelp,ptr
                movefa Cursor.a,PChelp
                movei #max_x<<3,PChelp1         ; bytes per line*8
                mult PChelp1,PChelp
                shrq #3,PChelp1                 ; = bytes per line
                add PChelp,ptr
                load (CharPtr),PChelp           ; get 4 bytes of char
                addq #4,CharPtr
                REPT 4
                  rorq #24,PChelp ; first byte down
                  storeb PChelp,(ptr)
                  add PChelp1,ptr
                ENDR
                load (CharPtr),PChelp
;---------------
; only for 8x16 fonts
;>                addq #4,CharPtr
;>                REPT 4
;>                  rorq #24,PChelp ; first byte down
;>                  storeb PChelp,(ptr)
;>                  add PChelp1,ptr
;>                ENDR
;>                load (CharPtr),PChelp
;>                addq #4,CharPtr
;>                REPT 4
;>                  rorq #24,PChelp ; first byte down
;>                  storeb PChelp,(ptr)
;>                  add PChelp1,ptr
;>                ENDR
;>                load (CharPtr),PChelp
;---------------
                REPT 3
                  rorq #24,PChelp ; first byte down
                  storeb PChelp,(ptr)
                  add PChelp1,ptr
                ENDR
                rorq #24,PChelp
                storeb PChelp,(ptr)
                movefa Cursor.a,PChelp
                move PChelp,r0
                shlq #16,r0
                shrq #16,PChelp
                shrq #16,r0
                addq #1,PChelp
                cmp PChelp,PChelp1
                jr nz,._1
                nop
                  moveq #0,PChelp
                  movei #max_y,PChelp1
                  addq #1,r0
                  cmp PChelp1,r0
                  jr nz,._1
                  nop
                    moveq #0,r0
._1             shlq #16,PChelp
                or PChelp,r0
                moveta r0,Cursor.a
                POP r3,r2,r1
                RTS

                unreg CharPtr,ptr,PChelp,PChelp1
***************
* prints r0 hex at cursor
printchar       reg 4
null            reg 3
PHhelp1         reg 2
PHHelp          reg 1
PrintHex::
                PUSH r0,r1,r2,r3,r4
                movei #"0",null
                move r0,r1
                movei #PrintChar,printchar
                REPT 4
                  rorq #24,r1
                  move r1,r0
                  shlq #24,r0     ; first byte up
                  move r0,r2
                  shrq #28,r0     ; high nibble down
                  shlq #4,r2      ; low nibble up
                  shrq #28,r2     ; low nibble down
                  cmpq #10,r0
                  jr n,._1@
                  add null,r0
                    addq #7,r0
._1@              cmpq #10,r2
                  jr n,._2@
                  add null,r2
                    addq #7,r2
._2@            JSR (printchar)
                move r2,r0
                JSR (printchar)
                INC@
                ENDR
                POP r4,r3,r2,r1,r0
                RTS
                unreg PHHelp,PHhelp1,null,printchar
****************
* prints text at r0 (C-style)
* text must be Long-aligned
****************
EXIT            reg 5
LOOP            reg 4
PRhelp          reg 3
printchar       reg 2
ptr             reg 1
PrintR0::
                PUSH r1,r2,r3,r4,r5
                move r0,ptr
                movei #.loop,LOOP
                movei #.exit,EXIT
                movei #PrintChar,printchar
                load (ptr),PRhelp
.loop           addq #4,ptr
                REPT 4
                  rorq #24,PRhelp
                  nop
                  move PRhelp,r0
                  shlq #24,r0
                  jump z,(EXIT)
                  shrq #24,r0     ; get byte
                  JSR (printchar)
                ENDR
                jump (LOOP)
                load (ptr),PRhelp

.exit           POP r5,r4,r3,r2,r1
                RTS
                unreg EXIT,LOOP,PRhelp,printchar,ptr
****************
                ENDFUNC Print
****************
                ALIGN 4
ASCII           ibytes "\bjl\font\light8x8.fnt"
****************
FUNCTION cls
                LOCAL
                PUSH r14
                movei #$f02200,r14
.wait           load (r14+$38),r0
                shrq #1,r0
                jr cc,.wait
                xor r0,r0
                store r0,(r14+$68)
                store r0,(r14+$6c)
                store r0,(r14+8)                ; a1_clip
                store r0,(r14+$c)               ; a1_pixel_ptr
                store r0,(r14+$18)              ; a1_pixel_ptr_frac

                movei #BLIT_PITCH1|BLIT_WID320|BLIT_PIXEL32|BLIT_XADDPHR,r0
                store r0,(r14+4)

                movei #$110000,r0
                store r0,(r14)                  ; dest

                movei #125<<16|344,r0
                store r0,(r14+$3c)

                movei #BLIT_PATDSEL,r0
                store r0,(r14+$38)

.wait1          load (r14+$38),r0
                shrq #1,r0
                jr cc,.wait1
                nop
                POP r14
ENDFUNC cls
****************
FUNCTION my_gfx
****************
* circle and pcircle
* created : 31.05.95
* (c) 1995 Bastian Schick
* optimized as possible (next step => blitter)
* seems to be based on Bresenham for circles
****************
                JSR (r4)
                RETURN
****************
* circle
* r0-r21 zerst”rt
****************
CONT            reg 9
LOOP            reg 10
p1              reg 11
p2              reg 12
p3              reg 13
p4              reg 14
p5              reg 15
p6              reg 16
p7              reg 17
p8              reg 18
farbe           reg 19
a2              reg 20          ; redefined !! (used by dispatch)
a3              reg 21          ; redefined !! (used by dispatch)


CIRCLE::
                move r3,farbe

                movei #$110000,p1
                move r0,r6
                movei #.loop,LOOP
                shlq #1,r6
                add r6,p1       ; scr_ptr += 2*x
                movei #.cont,CONT
                move r1,r6
                movei #344*2,r8
                imult r8,r6
                add r6,p1       ; scr_ptr += 640*y

                move r2,r3
                moveq #0,r4

                move r2,r5
                shlq #1,r5
                move r2,r1
                imult r8,r1
                move r1,a2
                
                moveq #0,r7
                moveq #0,r0
                moveq #0,a3

                move r3,r6
                shlq #1,r6
                sub r6,r2

                move p1,p2
                move p1,p3
                move p1,p4
                move p1,p5
                move p1,p6
                move p1,p7
                move p1,p8

                add r5,p1
                sub r5,p2
                sub r5,p3
                add r5,p4

                add r1,p5
                sub r1,p7
                add a2,p6
                sub a2,p8

.loop           addq #8,farbe
                storew farbe,(p1)
                add r8,p1
                move r4,r6
                storew farbe,(p2)
                add r8,p2
                addq #1,r4
                storew farbe,(p3)
                sub r8,p3
                shlq #1,r6
                storew farbe,(p4)
                sub r8,p4
                addq #1,r6
                storew farbe,(p5)
                addq #2,p5
                storew farbe,(p6)
                subq #2,p6
                storew farbe,(p7)
                subq #2,p7
                storew farbe,(p8)               ; NNO

                add r6,r2
                addqt #2,p8
                jump n,(CONT)
                cmp r3,r4

                move r3,r6
                subq #1,r3
                shlq #1,r6
                subq #2,r6
                sub r6,r2

                subq #2,p1
                addq #2,p2
                addq #2,p3
                subq #2,p4

                sub r8,p5
                sub r8,p6
                add r8,p7
                add r8,p8
                
                cmp r3,r4
.cont           jump n,(LOOP)
                nop
                RTS

                UNREG CONT,LOOP,farbe,a2,a3
                UNREG p1,p2,p3,p4,p5,p6,p7,p8

****************
* PCIRCLE
* destroyed: r0..r18
* r0 = x, r1 = y, r2 = radius, r3 = color
****************
a0              reg 8
a1              reg 9
a2              reg 10
a3              reg 11
a4              reg 12
a5              reg 13
a6              reg 14
a7              reg 15
_640            reg 16
farbe           reg 17
LOOP            reg 18


PCIRCLE::
                move r3,farbe
                movei #$110000,a1
                movei #640,_640
                movei #.loop,LOOP

                shlq #1,r0
                imult _640,r1
                add r0,a1
                add r1,a1
                move r2,r3
                move r2,r5
                moveq #0,r4
                shlq #1,r5
                move r2,r1
                move r3,r6
                imult _640,r1
                shlq #1,r6
                sub r6,r2

                move a1,a4
                move a1,a5
                sub r5,a4
                sub r5,a5

                move a1,a6
                sub r1,a1
                add r1,a6


LOOPA           reg 1
LOOPC           reg 5
CONT            reg 7

                movei #.loopa,LOOPA
                movei #.loopc,LOOPC
                movei #.cont,CONT

.loop
                move a4,a0
                move a5,a7
                move r3,r0
.loopa          storew farbe,(a0)
                addq #2,a0
                storew farbe,(a0)
                addq #2,a0
                storew farbe,(a7)
                addq #2,a7
                storew farbe,(a7)
                subq #1,r0
                jump nn,(LOOPA)
                addq #2,a7

                move a6,a0
                move a1,a7
                move r4,r0
.loopc          storew farbe,(a0)
                addq #2,a0
                storew farbe,(a0)
                addq #2,a0
                storew farbe,(a7)
                addq #2,a7
                storew farbe,(a7)
                subq #1,r0
                jump nn,(LOOPC)
                addq #2,a7


                subq #2,a6

                move r4,r6
                addq #1,r4
                shlq #1,r6
                add _640,a4
                addq #1,r6
                sub _640,a5
                add r6,r2
                subqt #2,a1
                jump n,(CONT)
                nop

                move r3,r6
                subq #1,r3
                shlq #1,r6
                addq #2,a4
                subq #2,r6
                addq #2,a5
                sub r6,r2

                sub _640,a6
                add _640,a1
.cont           cmp r3,r4
                jump n,(LOOP)
                nop

                move a1,a0
                move a6,a7
                move r4,r0
.loope          storew farbe,(a0)
                addq #2,a0
                storew farbe,(a0)
                addq #2,a0
                storew farbe,(a7)
                addq #2,a7
                storew farbe,(a7)
                subq #1,r0
                jr nn,.loope
                addq #2,a7
                RTS

                UNREG a0,a1,a2,a3,a4,a5,a7,_640,farbe,LOOP,LOOPA,LOOPC,CONT

ENDFUNC my_gfx,1
****************
FUNCTION Joypad1
                PUSH r1,r2,r3,r4
                JOYPAD1
                POP r4,r3,r2,r1
ENDFUNC Joypad1
****************
FUNCTION fak
                PUSH r1
                cmpq #1,r0
                movei #.exit,r1
                jump z,(r1)
                nop
                PUSH r0
                subq #1,r0
                fak
                POP r1
                mult r1,r0
.exit           POP r1
                ENDFUNC fak



FUNCTION MAIN
                moveta CurrentFunction,CurrentFunction
                movei #irq_routines,SP
                moveta SP,SP

                movei #$f02100,r0
                movei #(1<<14)|(%11111<<9),r1
                store r1,(r0)
                nop
                nop             ; set bank 1, clear pending IRQs
                movefa CurrentFunction,CurrentFunction

                init

                movei #14<<16,r0
                moveta r0,Cursor.a
                movei #PrintR0,r1
                movei #Hallo,r0
                Print
;---------------
main::

radius          REG 5
radius_inc      REG 6

                movei #$f02100,r2
                xor r3,r3
                moveq #1,radius
                moveq #4,radius_inc
.loop
                movei #$f00058,r0
                xor r1,r1
                storew r1,(r0)
                movei #VBLflag,r0
                xor r1,r1
                load (r0),r2
                store r1,(r0)
.waitvbl        load (r0),r1
                cmpq #0,r1
                jr eq,.waitvbl
                nop

                movei #999,r0
                movefa ms.a,r1
                moveta r0,ms.a
                sub r0,r1
                abs r1
                shlq #16,r1
                or r1,r2
                moveq #0,r0
                moveta r0,Cursor.a
                move r2,r0
                movei #PrintHex,r1
                Print

                movei #.loopfak,r2
                movei #50,r1
.loopfak        moveq #9,r0
                fak
                subq #1,r1
                jump nz,(r2)
                nop

                moveq #1,r1
                moveta r1,Cursor.a
                movei #PrintHex,r1
                Print

                addq #1,r3

                PUSH r3,r5,r6
                cls
                movei #344>>1,r0
                movei #250>>1,r1
                move radius,r2
                movei #CIRCLE,r4
                my_gfx

                POP r6,r5,r3

                movei #$88ff,r1
                movei #$110000+343*2,r0
                storew r1,(r0)
                add radius_inc,radius
                jr gt,.ok
                nop
                neg radius_inc
                jr .cont1
                moveq #1,radius

.ok             movei #124,r0
                cmp radius,r0
                jr gt,.cont1
                nop
                neg radius_inc
.cont1

                movei #16<<16|1,r0
                moveta r0,Cursor.a
                Joypad1
                PUSH r0
                movei #PrintHex,r1
                Print

                POP r0
                movei #.loop,r1
                btst #16,r0
                jump z,(r1)
                btst #0,r0
                jump z,(r1)
                nop
                movei #$f02114,r0
                load (r0),r1
                bset #1,r1
                store r1,(r0)                 ; wake-up 68k

                nop
                STOP_GPU
                ENDFUNC MAIN,1

                align 4
Hallo           dc.b " Overlay-Demo",0
                align 8


                end

