From 225dc6f4cc1975db14aa4c2d18411bb71704851f Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Fri, 12 May 2017 12:50:24 -0400 Subject: [PATCH 1/3] tfv: minimal sprite implementation --- gr-sim/gr-sim.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ gr-sim/gr-sim.h | 3 ++- gr-sim/tfv.c | 24 +++++++++++++++++++++++- 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/gr-sim/gr-sim.c b/gr-sim/gr-sim.c index a7a54aac..82bb5462 100644 --- a/gr-sim/gr-sim.c +++ b/gr-sim/gr-sim.c @@ -595,3 +595,51 @@ int basic_vlin(int y1, int y2, int at) { return 0; } + + +short gr_addr_lookup[48]={ + 0x400,0x480,0x500,0x580,0x600,0x680,0x700,0x780, + 0x428,0x4a8,0x528,0x5a8,0x628,0x6a8,0x728,0x7a8, + 0x450,0x4d0,0x550,0x5d0,0x650,0x6d0,0x750,0x7d0, +}; + +int grsim_put_sprite(unsigned char *sprite_data, int xpos, int ypos) { + + int i,j,xsize,ysize; + unsigned char *ptr; + short address; + ptr=sprite_data; + xsize=*ptr; + ptr++; + ysize=*ptr; + ptr++; + + for(j=0;j0) y-=2; + if (ch=='m') if (y<39) y+=2; + if (ch=='j') if (x>0) x--; + if (ch=='k') if (x<39) x++; + + gr_copy(0x800,0x400); + grsim_put_sprite(test_sprite,x,y); + + grsim_update(); usleep(100000); } From 4d846e778bd43f6950de8f0be89aa65f7ec5fb29 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Fri, 12 May 2017 14:29:21 -0400 Subject: [PATCH 2/3] tfv: initial screen copy routine --- gr-sim/gr-sim.c | 31 ++++++++++++++---- tfv/Makefile | 5 +-- tfv/apple2_1000.inc | 12 +++++++ tfv/tfv.s | 79 ++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 114 insertions(+), 13 deletions(-) create mode 100644 tfv/apple2_1000.inc diff --git a/gr-sim/gr-sim.c b/gr-sim/gr-sim.c index 82bb5462..61abdbfb 100644 --- a/gr-sim/gr-sim.c +++ b/gr-sim/gr-sim.c @@ -605,23 +605,40 @@ short gr_addr_lookup[48]={ int grsim_put_sprite(unsigned char *sprite_data, int xpos, int ypos) { - int i,j,xsize,ysize; + unsigned char i; unsigned char *ptr; short address; + ptr=sprite_data; - xsize=*ptr; + x=*ptr; ptr++; - ysize=*ptr; + ram[CV]=*ptr; ptr++; - for(j=0;j(title_image) sta GBASH @@ -62,14 +70,22 @@ TEMP2 EQU $FB sta GBASL jsr load_rle_gr + jsr gr_copy + lda #$4 sta BASH lda #$0 - sta BASL ; 0x400 is GR page 0 + sta BASL ; restore to 0x400 (page 0) + ; copy to 0x400 (page 0) + ; Return to BASIC? rts +;===================================================================== +;= ROUTINES +;===================================================================== + ;================= ; load RLE image ;================= @@ -184,4 +200,59 @@ set_gr_page0: bit GR ; set graphics rts + ;========================================================= + ; gr_copy + ;========================================================= + ; for now copy 0xc00 to 0x400 + ; 2 + 8*38 + 4*80*23 + 4*120*26 + 13 = 20,159 = 20ms = 50Hz +gr_copy: + ldx #0 ; set y to zero ; 2 + +gr_copy_loop: + stx TEMP ; save y ; 3 + txa ; move to A ; 2 + asl ; mult by 2 ; 2 + tay ; put into Y ; 2 + lda gr_offsets,Y ; lookup low byte for line addr ; 5 + sta OUTL ; out and in are the same ; 3 + sta INL ; 3 + lda gr_offsets+1,Y ; lookup high byte for line addr ; 5 + sta OUTH ; 3 + adc #$8 ; for now, fixed 0xc ; 2 + sta INH ; 3 + ldx TEMP ; restore y ; 3 + + ldy #0 ; set X counter to 0 ; 2 +gr_copy_line: + lda (INL),Y ; load a byte ; 5 + sta (OUTL),Y ; store a byte ; 6 + iny ; increment pointer ; 2 + + cpx #$4 ; don't want to copy bottom 4*40 ; 2 + bcs gr_copy_above4 ; 3 + +gr_copy_below4: + cpy #120 ; for early ones, copy 120 bytes ; 2 + bne gr_copy_line ; 3 + beq gr_copy_line_done ; 3 + +gr_copy_above4: ; for last four, just copy 80 bytes + cpy #80 ; 2 + bne gr_copy_line ; 3 + +gr_copy_line_done: + inx ; increment y value ; 2 + cpx #8 ; there are 8 of them ; 2 + bne gr_copy_loop ; if not, loop ; 3 + rts ; 6 + + ; waste memory with a lookup table + ; maybe faster than using GBASCALC? +gr_offsets: + .word $400,$480,$500,$580,$600,$680,$700,$780 + .word $428,$4a8,$528,$5a8,$628,$6a8,$728,$7a8 + .word $450,$4d0,$550,$5d0,$650,$6d0,$750,$7d0 + + + .include "title.inc" From 37cd697d773c9a68869ad3c530e3754203d7f0a8 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Fri, 12 May 2017 16:35:52 -0400 Subject: [PATCH 3/3] tfv: transparent sprite mostly working --- tfv/tfv.dsk | Bin 143360 -> 143360 bytes tfv/tfv.s | 298 +++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 281 insertions(+), 17 deletions(-) diff --git a/tfv/tfv.dsk b/tfv/tfv.dsk index 7dbb5d54bad0d12a465e902ddc45f2449c34fedd..4d50fb8f61c6fcf70167a37bc3728203c12eca5d 100644 GIT binary patch delta 2265 zcmb_dZ)h837=NF;_bz|CUP@0p=4{A%=>@x*G1Q47?X0-9nM-Xm`pIQO%l1w1i+;KY zJrO@hYtekPlxE8fCk>O85oCwBnj1w=DMJ{6f)cigk|k9}(ltKsrR(}hYPTcL^FHtM z|9$VCUs5aX6#l+}s04EQfCOW-L5P{|m*9m<+P;_JavS*kqD<)W;*IGKckcml8obMC z=!ExtGSFpfdFk5MKm3BGC(@sHf+EN+dhL7MKDBVO6F%5CEqV{6^;hBevxl(s7>?{-YBL>NynNmwCY9qIP@0#3yB%@mACvn$tc1%}G zN=eBmR_kN{^C^ci>g`{3H50kbvjP{iGmAC*ySe(I`B_8Om1NJT*)wc9%L%h*#O#Ti zNfpTMU@L(TKMo-{4dX~580V27?8v8^t7A_9;R7&$RwRya=*0;ASoGE?w$~gZI$#(8 z1fU-V;4m5vZ>-#w6f8}%36?I5UaWkWrDqv90s(#iJs1(-I^KlDF7kBJOE$~02v)Yq zu^A1w%|y6z8$F`KI3zq6#$35(fK$9#mT9(XIhGC^LE4PtS=2+q8{3R>v>3xQ8e^=K zxc3AkuxqIc3GYI}y8wZ>m!J==HngB_g9~_0JQJm(+!EeWLS&XAw?Sa@gu|QUz)u|e zsN+#|<)KKMd8LOI%|)OHdAJJmo4m-{z;`HlHxsy-*G=?z2@Z03l+dSHWWxuKz!il& z5;nJyo*j#|o#%5Hi83Wz-cP^}G1fMEak3kus^{T#08P41*^J$g*o^s`gJrbgtR-;PPD#PvB%@tl zMXI70{2~y1GLX4z4VOEuqc&Y!U0k(}*|fA;TD1mkZn0_&;iy$(-O__0#pM4rry85r zM;+8{%;_xosP>6BdxdY)*Y&k4v`ufEb?f)fX|)-WTbo)htk8MUeBZ8?sTsHbytU%C ze@b2?rc{sh26|4Jl3>ilCId{YXa`9brhTOUH?c1hA3$}LeV>21`m@`qYF@!dVQicSI3idyi?WJoukav&UNM13KMu3i`G zy_smF)ox{SZe8gWqEqX!Y9NElT&=Wz-PWv9y;NUR?5~o9rYI3o0ufUpaiv@;%~Dm! z3aXeDRae#(r#6iXwh$L>G48TmZkmV_=Sd_I&f4fa{%j)@Bq#A{R4SEifTQLhL&!md z|A&r`2OJ%Y-4Qw>fFVpFJrX!FjNKVJJ|1w?c8rdX2OLKj!0!kh2?IxX27J2+Cm@;z W#SkCFzdFv7zA8cAB}w`F=YIisJyn(f delta 139 zcmZp8z|jCiTNn)l7)7QV3NS`YcNAc>-+n@X(V2HLC)c;>jPi`d+#(DtS596zb9CMD zOOqQV#imb{XH;bsVPiRZ1jv=yep{ZgQh7S7BcsM-0WQwzt3^Jo2C_Oa ksxv;AUgH8}w}RLow*PTq6ky#fp!$V*n;#<&6Nq&m0HIkfrT_o{ diff --git a/tfv/tfv.s b/tfv/tfv.s index ab36385a..6f39fcb5 100644 --- a/tfv/tfv.s +++ b/tfv/tfv.s @@ -1,14 +1,22 @@ .define EQU = +KEYPRESS EQU $C000 +KEYRESET EQU $C010 + ;; SOFT SWITCHES -GR EQU $C050 -TEXT EQU $C051 -FULLGR EQU $C052 -TEXTGR EQU $C053 -PAGE0 EQU $C054 -PAGE1 EQU $C055 -LORES EQU $C056 -HIRES EQU $C057 +GR EQU $C050 +TEXT EQU $C051 +FULLGR EQU $C052 +TEXTGR EQU $C053 +PAGE0 EQU $C054 +PAGE1 EQU $C055 +LORES EQU $C056 +HIRES EQU $C057 + +PADDLE_BUTTON0 EQU $C061 +PADDL0 EQU $C064 +PTRIG EQU $C070 + ;; MONITOR ROUTINES HLINE EQU $F819 ;; HLINE Y,$2C at A @@ -38,15 +46,20 @@ H2 EQU $2C V2 EQU $2D MASK EQU $2E COLOR EQU $30 -FIRST EQU $F0 -TEMP EQU $FA -RUN EQU $FA -TEMP2 EQU $FB -INL EQU $FC -INH EQU $FD -OUTL EQU $FE -OUTH EQU $FF +FIRST EQU $F0 +LASTKEY EQU $F1 +PADDLE_STATUS EQU $F2 +XPOS EQU $F3 +YPOS EQU $F4 +TEMP EQU $FA +RUN EQU $FA +TEMP2 EQU $FB +TEMPY EQU $FB +INL EQU $FC +INH EQU $FD +OUTL EQU $FE +OUTH EQU $FF ;============================= ; set low-res graphics, page 0 @@ -72,12 +85,61 @@ OUTH EQU $FF jsr gr_copy + lda #20 + sta YPOS + lda #20 + sta XPOS + +main_loop: + + jsr gr_copy + + jsr put_sprite + + jsr wait_until_keypressed + + lda LASTKEY + + cmp #('Q') + beq exit + + cmp #('I') + bne check_down + dec YPOS + dec YPOS + +check_down: + cmp #('M') + bne check_left + inc YPOS + inc YPOS + +check_left: + cmp #('J') + bne check_right + dec XPOS + +check_right: + cmp #('K') + bne check_done + inc XPOS + +check_done: + jmp main_loop + + + +exit: + lda #$4 sta BASH lda #$0 sta BASL ; restore to 0x400 (page 0) ; copy to 0x400 (page 0) + ; call home + jsr HOME + ; Return to BASIC? rts @@ -205,6 +267,7 @@ set_gr_page0: ;========================================================= ; for now copy 0xc00 to 0x400 ; 2 + 8*38 + 4*80*23 + 4*120*26 + 13 = 20,159 = 20ms = 50Hz + ; gr_copy: ldx #0 ; set y to zero ; 2 @@ -246,6 +309,202 @@ gr_copy_line_done: bne gr_copy_loop ; if not, loop ; 3 rts ; 6 + ;========================================================== + ; Wait until keypressed + ;========================================================== + ; + +wait_until_keypressed: + lda KEYPRESS ; check if keypressed + bpl wait_until_keypressed ; if not, loop + jmp figure_out_key + + + ;========================================================== + ; Get Key + ;========================================================== + ; + +get_key: + +check_paddle_button: + + ; check for paddle button + + bit PADDLE_BUTTON0 + bpl no_button + lda #' '+128 + jmp save_key + +no_button: + lda KEYPRESS + bpl no_key + +figure_out_key: + cmp #' '+128 ; the mask destroys space + beq save_key ; so handle it specially + + and #$5f ; mask, to make upper-case +check_right_arrow: + cmp #$15 + bne check_left_arrow + lda #'K' +check_left_arrow: + cmp #$08 + bne check_up_arrow + lda #'J' +check_up_arrow: + cmp #$0B + bne check_down_arrow + lda #'I' +check_down_arrow: + cmp #$0A + bne check_escape + lda #'M' +check_escape: + cmp #$1B + bne save_key + lda #'Q' + jmp save_key + +no_key: + bit PADDLE_STATUS + bpl no_key_store + + ; check for paddle action + ; code from http://web.pdx.edu/~heiss/technotes/aiie/tn.aiie.06.html + + inc PADDLE_STATUS + lda PADDLE_STATUS + and #$03 + beq check_paddles + jmp no_key_store + +check_paddles: + lda PADDLE_STATUS + and #$80 + sta PADDLE_STATUS + + ldx #$0 + LDA PTRIG ;TRIGGER PADDLES + LDY #0 ;INIT COUNTER + NOP ;COMPENSATE FOR 1ST COUNT + NOP +PREAD2: LDA PADDL0,X ;COUNT EVERY 11 uSEC. + BPL RTS2D ;BRANCH WHEN TIMED OUT + INY ;INCREMENT COUNTER + BNE PREAD2 ;CONTINUE COUNTING + DEY ;COUNTER OVERFLOWED +RTS2D: ;RETURN W/VALUE 0-255 + + cpy #96 + bmi paddle_left + cpy #160 + bmi no_key_store + lda #'K' + jmp save_key +paddle_left: + lda #'J' + jmp save_key + +no_key_store: + lda #0 ; no key, so save a zero + +save_key: + sta LASTKEY ; save the key to our buffer + bit KEYRESET ; clear the keyboard buffer + rts + + ;============================================= + ; put_sprite + ;============================================= +put_sprite: + + lda #>tb1_sprite ; hardcoded for tb1 for now + sta INH + lda #