; sprite.as - sprites test #1 (sprite mode 2) ; Copyright (C) 2000 ag0ny@ag0ny.com ; ********************* ; **** Definitions **** ; ********************* SPR_PAT equ 7 SPR_ATT equ 60 SPR_PATADDR equ SPR_PAT * 800h SPR_ATTADDR equ SPR_ATT * 128 SPR_COLADDR equ SPR_ATTADDR - 512 ; ************************** ; **** MSX-DOS(2) calls **** ; ************************** BDOS equ 00005h STROUT equ 009h ; ***************************************************** ; **** START of ag0ny standard routines and macros **** ; ***************************************************** ; ; v0.01/20001214: restoresys updated (SCREEN 0 called on exit, and ; a version string and copyright are printed) ; v0.01/20001120: fillvram, sprsize8, sprsize16, sprnormalsize, ; sprexpanded added ; ; list of macros/functions: ; ; type name function ; ----- --------------- ----------------------------------------------------- ; macro pushstd push standard set of registers ; macro popstd pop standard set of registers ; macro pushall push all registers ; macro popall pop all registers ; macro vdp send value in A to VDP register ; macro rdvdp read VDP status register ; macro selvram select VRAM access from the VDP ; macro selexpram select expanded RAM access from the VDP ; macro r2v8 copy RAM block to VRAM (up to 256 bytes) ; macro r2v16 copy RAM block to VRAM (up to 65536 bytes) ; macro set192lines set 192 lines VDP display mode ; macro set212lines set 212 lines VDP display mode ; macro checkkdb check keyboard line ; macro spriteson turn ON V9938/V9958 sprites display ; macro spritesoff turn OFF V9938/V9958 sprites display ; macro setintline set scan line number for vertical scanning interrupt ; macro vblankon turn ON vblank interrupts ; macro vblankoff turn OFF vblank interrupts ; macro lineinton turn ON line interrupts ; macro lineintoff turn OFF line interrupts ; func freezesys chenge the hook in 0038h to point to our interrupt code ; func restoresys restore the original interrupt handler and interrupt ; state ; func graphic3 set GRAPHIC 3 mode ; func setvramaddr_w set VRAM address for read/write (low 64Kb) ; macro fillvram fill VRAM with a value ; macro sprsize8 set sprites size to 8x8 pixels ; macro sprsize16 set sprites size to 16x16 pixels ; macro sprnormalsize set normal sprites size ; macro sprexpanded set expanded sprites (double size) ; RAM copy of VDP registers. ; vdpregs0 -> R#0..R#7 ; vdpregs1 -> R#8..R#23 ; vdpregs0 equ 0f3dfh vdpregs1 equ 0ffe7h-8 ; VDP ports ; vdpport0 equ 098h ; VRAM read/write vdpport1 equ 099h ; VDP registers read/write vdpport2 equ 09ah ; Palette registers write vdpport3 equ 09bh ; Indirect register write ; i8255 ports ; i8255porta equ 0a8h ; slot selection i8255portb equ 0a9h ; keyboard column input i8255portc equ 0aah ; leds, motor, cassette, kbd line i8255mode equ 0abh ; mode select for i8255 ports A,B,C ; pushstd: push standard set of registers (not alternate) ; syntax: pushstd ; modifies: SP ; note: alternate registers (*') are not pushed; use pushall for that ; pushstd macro push hl push bc push de push af endm ; popstd: pop standard set of registers (not alternate) ; syntax: popstd ; modifies: SP ; note: alternate registers (*') are not popped; use popall for that ; popstd macro pop af pop de pop bc pop hl endm ; pushall: push all registers (including alternate) ; syntax: pushall ; modifies: SP ; note: slower than pushstd; use only if alternate registers must be ; preserved ; pushall macro pushstd push hl' push bc' push de' push af' endm ; popall: pop all registers (including alternate) ; syntax: popall ; modifies: SP ; popall macro pop af' pop de' pop bc' pop hl' popstd endm ; vdp: send value in A to VDP register ; syntax: vdp reg# ; modifies: A ; note: **** INTERRUPTS MUST BE DISABLED **** ; vdp macro reg out (vdpport1),a ld a,reg or 080h out (vdpport1),a endm ; rdvdp: read VDP status register ; syntax: rdvdp reg# ; modifies: A ; note: **** INTERRUPTS MUST BE DISABLED **** ; rdvdp macro reg ld a,reg ld (vdpregs1+15),a vdp 15 ; set VDP status register to read in a,(vdpport1) endm ; selvram: select VRAM access from the VDP ; syntax: selvram ; modifies: A ; note: **** INTERRUPTS MUST BE DISABLED **** ; selvram macro ld a,(vdpregs1+45) and 010111111b ld (vdpregs1+45),a vdp 45 endm ; selexpram: select expanded RAM access from the VDP ; syntax: selexpram ; modifies: A ; note: **** INTERRUPTS MUST BE DISABLED **** ; selexpram macro ld a,(vdpregs1+45) or 001000000b ld (vdpregs1+45),a vdp 45 endm ; r2v8: copy RAM block to VRAM (up to 256 bytes) (low 64Kb) ; syntax: r2v8 ,, ; modifies: AF,HL,BC,DE ; note: **** INTERRUPTS MUST BE DISABLED **** ; r2v8 macro ram,vram,num ld de,vram call setvramaddr_w ld hl,ram ld bc,num*256 + vdpport0 otir endm r; r2v16: copy RAM block to VRAM (up to 65536 bytes) (low 64Kb) ; syntax: r2v16 ,, ; modifies: AF,HL,DE,C ; note: **** INTERRUPTS MUST BE DISABLED **** ; r2v16 macro ram,vram,num ld de,vram call setvramaddr_w ld de,num ld hl,ram ld c,vdpport0 ld a,(hl) ; jr jumps here out (c),a inc hl dec de ld a,d or e jr nz,$-7 endm ; set192lines: set 192 lines VDP display mode ; syntax: set192lines ; modifies: A ; note: **** INTERRUPTS MUST BE DISABLED **** ; set192lines macro ld a,(vdpregs1+9) and 001111111b ld (vdpregs1+9),a vdp 9 endm ; set212lines: set 212 lines VDP display mode ; syntax: set212lines ; modifies: A ; note: **** INTERRUPTS MUST BE DISABLED **** ; set212lines macro ld a,(vdpregs1+9) or 010000000b ld (vdpregs1+9),a vdp 9 endm ; spriteson: turn ON V9938/V9958 sprites display ; syntax: spriteson ; modifies: A ; note: **** INTERRUPTS MUST BE DISABLED **** ; spriteson macro ld a,(vdpregs1+8) and 011111101b ld (vdpregs1+8),a vdp 8 endm ; spritesoff: turn OFF V9938/V9958 sprites display ; syntax: spritesoff ; modifies: A ; note: **** INTERRUPTS MUST BE DISABLED **** ; spritesoff macro ld a,(vdpregs1+8) or 000000010b ld (vdpregs1+8),a vdp 8 endm ; setintline: set line number for vertical scanning interrupt ; syntax: setintline line# ; modifies: AF,HL ; note: **** INTERRUPTS MUST BE DISABLED **** ; note: The status of VDP register #23 is read and the interrupt ; line is set accordingly, so the interrupt line specifies the ; interrupt line ON THE PHYSICAL SCREEN, not on the VDP space. ; setintline macro line ld hl,vdpregs1+23 ld a,line add a,(hl) ld (vdpregs1+19),a vdp 19 endm ; vblankon: turn ON vblank interrupts ; syntax: vblankon ; modifies: A ; note: **** INTERRUPTS MUST BE DISABLED **** ; vblankon macro ld a,(vdpregs0+1) or 000100000b ld (vdpregs0+1),a vdp 1 endm ; vblankoff: turn OFF vblank interrupts ; syntax: vblankoff ; modifies: A ; note: **** INTERRUPTS MUST BE DISABLED **** ; vblankoff macro ld a,(vdpregs0+1) and 011011111b ld (vdpregs0+1),a vdp 1 endm ; lineinton: turn ON line interrupts ; syntax: lineinton ; modifies: A ; note: **** INTERRUPTS MUST BE DISABLED **** ; lineinton macro ld a,(vdpregs0+0) or 000010000b ld (vdpregs0+0),a vdp 0 endm ; lineintoff: turn OFF line interrupts ; syntax: lineintoff ; modifies: A ; note: **** INTERRUPTS MUST BE DISABLED **** ; lineintoff macro ld a,(vdpregs0+0) and 011101111b ld (vdpregs0+0),a vdp 0 endm ; checkkbd: check keyboard line ; syntax: checkkbd ; modifies: AF ; checkkbd macro kbdline in a,(i8255portc) and 011110000b ; upper 4 bits contain info to preserve or kbdline out (i8255portc),a in a,(i8255portb) endm ; fillvram: fill VRAM with a value ; syntax: fillvram
,, ; modifies: AF,DE,BC ; note: **** INTERRUPTS MUST BE DISABLED **** ; fillvram macro address,count,value ld de,address call setvramaddr_w ld de,count ld bc,value*256 + vdpport0 out (c),b ; jr jumps here dec de ld a,d or e jr nz,$-5 endm ; sprsize8: set sprites size to 8x8 pixels ; syntax: sprsize8 ; modifies: AF ; note: **** INTERRUPTS MUST BE DISABLED **** ; sprsize8 macro ld a,(vdpregs0+1) and 011111101b ld (vdpregs0+1),a vdp 1 endm ; sprsize16: set sprites size to 16x16 pixels ; syntax: sprsize16 ; modifies: AF ; note: **** INTERRUPTS MUST BE DISABLED **** ; sprsize16 macro ld a,(vdpregs0+1) or 000000010b ld (vdpregs0+1),a vdp 1 endm ; sprnormalsize: set normal sprites size ; syntax: sprnormalsize ; modifies: AF ; note: **** INTERRUPTS MUST BE DISABLED **** ; sprnormalsize macro ld a,(vdpregs0+1) and 011111110b ld (vdpregs0+1),a vdp 1 endm ; sprexpanded: set expanded sprites (double size) ; syntax: sprexpanded ; modifies: AF ; note: **** INTERRUPTS MUST BE DISABLED **** ; sprexpanded macro ld a,(vdpregs0+1) or 000000001b ld (vdpregs0+1),a vdp 1 endm ; jump to entry point ; jp start ; change the hook in 0038h to point to our interrupt code ; input: none ; output: none ; modifies: HL ; note: the old jump address is stored in (OLDINT) ; freezesys: ld hl,(00039h) ld (OLDINT),hl ld hl,i200 ; install new interrupt jump ld (00039h),hl ld a,(vdpregs1+18) ; save SET ADJUST state ld (OLDADJUST),a ret ; restore the original interrupt handler and interrupt state ; restoresys: ld hl,(OLDINT) ld (00039h),hl ld hl,(OLDSTACK) ld sp,hl lineintoff vblankon rdvdp 1 ; read VDP status register #1 rdvdp 0 ; read VDP statsu register #0 ld a,(OLDADJUST) ld (vdpregs1+18),a vdp 18 ld ix,0005fh ; set SCREEN 0 ld iy,00000h xor a call 0001ch ei ; MSX-DOS(2) environment is restored now ld c,STROUT ld de,DESCSTRING call BDOS ret ; Return to MSX-DOS(2) ; set GRAPHIC 3 mode ; input: none ; output: none ; modifies: A ; note: **** INTERRUPTS MUST BE DISABLED **** ; graphic3: ; set VDP mode GRAPHIC 3 ld a,(vdpregs0+0) and 011110001b or 000000100b ld (vdpregs0+0),a ; R#0 -> xxxx010xb vdp 0 ld a,(vdpregs0+1) and 011100111b ld (vdpregs0+1),a ; R#1 -> xxx00xxxb vdp 1 ld a,2 ; Pattern name table in 00800h ld (vdpregs0+2),a vdp 2 ld a,080h or 01fh ; Pattern color table in 02000h ld (vdpregs0+3),a vdp 3 xor a ld (vdpregs1+10),a vdp 10 xor a ; Pattern generator table at 00000h ld (vdpregs0+4),a vdp 4 ld a,SPR_PAT ; Sprite name table ld (vdpregs0+6),a vdp 6 ld a,SPR_ATT ; Spr. attr. table, color table ld (vdpregs0+5),a vdp 5 xor a ld (vdpregs1+11),a vdp 11 ret ; set VRAM address for read/write (low 64Kb) ; input: DE = VRAM address (bits A0-A15) ; modifies: A ; note: **** INTERRUPTS MUST BE DISABLED **** ; setvramaddr_w: ld a,d rlca rlca and 000000011b vdp 14 ; bits A16-A14 to VDP R#14 ld a,e out (vdpport1),a ; bits A7-A0 to VDP (low 16Kb) ld a,d and 000111111b or 001000000b out (vdpport1),a ; bits A13-A8 to VDP, bit 6 = 1 (W) ret ; *************************************************** ; **** END of ag0ny standard routines and macros **** ; *************************************************** ; interrupt code ; i200: pushstd in a,(vdpport1) ld hl,i224 ld (00038h+1),hl set192lines setintline 224 popstd ei ret ; this interrupt does all the NASTY work ; i224: pushstd in a,(vdpport1) set212lines setintline 200 ; adjust twin sprite tables ld a,(ATTR_Y) ; SPR 1 Y (+16) add a,16 ld (ATTR_Y+4),a ld a,(ATTR_X) ; SPR 1 X (+0) add a,16 ld (ATTR_Y+5),a r2v8 ATTR_Y,SPR_ATTADDR,16 ld hl,i200 ld (00038h+1),hl ; checkkbd 8 ld e,a bit 7,e ; RIGHT pressed? jr nz,i224_2 ; no ld a,(ATTR_X) ; yes, increase X inc a inc a ld (ATTR_X),a i224_2: bit 6,e ; DOWN pressed? jr nz,i224_3 ; no ld a,(ATTR_Y) ; yes, increase Y inc a inc a ld (ATTR_Y),a i224_3: bit 5,e ; UP pressed? jr nz,i224_4 ; no ld a,(ATTR_Y) ; yes, decrease Y dec a dec a ld (ATTR_Y),a i224_4: bit 4,e ; LEFT pressed? jr nz,i224_5 ; no, continue ld a,(ATTR_X) ; yes, decrease X dec a dec a ld (ATTR_X),a ; i224_5: checkkbd 7 ; ESC is in keyboard line #7 and 000000100b ; bit 2 = ESC key jp z,restoresys popstd ei ret ; ***************************** ; **** Program starts here **** ; ***************************** start: di ld (OLDSTACK),sp xor a ; bordercolor = o ld (vdpregs0+7),a vdp 7 call freezesys call graphic3 vblankoff ; turn OFF vBlank interrupts lineinton ; turn ON line interrupts setintline 200 ; set interrupt at line 200 set212lines ; set 212 lines display spriteson sprnormalsize sprsize16 fillvram 0,00800h,0 fillvram 02000h,00800h,0 fillvram SPR_PATADDR,00800h,0 fillvram SPR_COLADDR,512,0 fillvram SPR_ATTADDR,128,4 xor a ld (vdpregs1+23),a vdp 23 r2v8 patterns,SPR_PATADDR,32 r2v8 spritecol,SPR_COLADDR,16 r2v8 ATTR_Y,SPR_ATTADDR,240 rdvdp 1 ei loop: halt jr loop ; ************** ; **** Data **** ; ************** DESCSTRING: defb 'Sprite test #1 (v0.01/20001214)',10,13 defb 'Copyright (C) 2000 ag0ny@ag0ny.com',10,13,'$' OLDINT: defs 2 OLDADJUST: defs 1 OLDSTACK: defs 2 ATTR_Y: defb 96 ATTR_X: defb 127 SPRPAT: defb 0 defb 0 defb 0 defb 0 defb 1 defb 0 defb 0 defb 0 defb 2 defb 0 defb 0 defb 0 defb 3 defb 0 spritecol: defb 00fh,00eh,007h,005h,004h,00fh,00fh,00eh defb 00eh,007h,007h,005h,005h,004h,004h,004h patterns: defb 011111111b defb 011000000b defb 010100000b defb 010010000b defb 010001000b defb 010000100b defb 010000010b defb 010000001b defb 010000001b defb 010000010b defb 010000100b defb 010001000b defb 010010000b defb 010100000b defb 011000000b defb 011111111b defb 011111111b defb 000000011b defb 000000101b defb 000001001b defb 000010001b defb 000100001b defb 001000001b defb 010000001b defb 010000001b defb 001000001b defb 000100001b defb 000010001b defb 000001001b defb 000000101b defb 000000011b defb 011111111b