Jump to content
IGNORED

Getting back into Atari programming


mdhughes

Recommended Posts

Programming the Atari 8-bit

 

I've started rewriting my old adventure game (originally AQUEST, certainly give it a new name before shipping) in Draper Pascal, and it's going well enough. The other classic compilers didn't work at all for me (except Action!, which I don't feel like dealing with that far low-level). If there's newer compilers that run on the Atari itself and make true binaries, not P-code, I might be interested.

 

I'm currently working entirely in emulator; real hardware testing when I get around to it. Are there any disk duplication services for people with actual floppies, or does everyone just use ATR "disks" now? Not sure I want to go full art-box crazy with this, but maybe a baggie with a couple pages manual wrapped around the floppy or cheapo SD card?

 

Once I get that up and out, are there other tools and applications people are in dire need of?

 

  • Like 2
Link to comment
Share on other sites

fast basic makes an xex file.
the example is 2,6kb small.

steer with the joystick.

 

 

greeting

 

 


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Proc Init
  ' Reserve 2k
  poke @RAMTOP, peek(@RAMTOP) - 8

  ' Sets ANTIC mode 4
  gr. 28

  ' Our player data:
  '  5 frames, one static, two going left, two going right
  data P0_Data() byte = $00,$00,$00,$00,$3c,$3c,$3c,$18,$00,$00,$00,$81,$00,$00,$00,$00,$00,$66,$66,
  data           byte = $00,$00,$00,$00,$3c,$3c,$3c,$18,$80,$00,$00,$01,$00,$00,$00,$00,$00,$36,$36,
  data           byte = $00,$00,$00,$00,$3c,$3c,$3c,$18,$01,$00,$00,$80,$00,$00,$00,$00,$00,$c3,$c3,
  data           byte = $00,$00,$00,$00,$3c,$3c,$3c,$18,$01,$00,$00,$80,$00,$00,$00,$00,$00,$6c,$6c,
  data           byte = $00,$00,$00,$00,$3c,$3c,$3c,$18,$80,$00,$00,$01,$00,$00,$00,$00,$00,$c3,$c3,
  data           byte = $00

  data P1_Data() byte = $00,$18,$3c,$7e,$00,$00,$00,$00,$18,$3c,$7e,$3c,$3c,$3c,$3c,$24,$66,$66,$66,
  data           byte = $00,$18,$3c,$3e,$00,$00,$00,$00,$18,$7c,$3e,$3c,$3c,$3c,$3c,$24,$24,$36,$36,
  data           byte = $00,$18,$3c,$3e,$00,$00,$00,$00,$18,$3e,$7c,$3c,$3c,$3c,$3c,$64,$46,$c7,$c3,
  data           byte = $00,$18,$3c,$7c,$00,$00,$00,$00,$18,$3e,$7c,$3c,$3c,$3c,$3c,$24,$24,$6c,$6c,
  data           byte = $00,$18,$3c,$7c,$00,$00,$00,$00,$18,$7c,$3e,$3c,$3c,$3c,$3c,$26,$62,$e3,$c3,
  data           byte = $00

  P0_Frame = Adr(P0_Data)
  P1_Frame = Adr(P1_Data)
  P0_Size  = 20

  ' Char data
  data Ch_Data() byte = $00,$00,$00,$00,$00,$00,$00,$00,
  data           byte = $AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA,
  data           byte = $88,$22,$88,$22,$88,$22,$88,$22,
  data           byte = $00,$14,$7D,$7D,$7D,$14,$00,$00,
  data           byte = $00,$A8,$A8,$A8,$A8,$A8,$00,$00,
  data           byte = $44,$11,$44,$11,$44,$11,$44,$11

  move Adr(Ch_Data), Peek(@RAMTOP) * 256, 8 * 6
  poke @CHBAS, Peek(@RAMTOP)

  Player_x = 56
  Player_y = 48

  P0Mem = Peek(@RAMTOP) * 256 + 1024
  P1Mem = P0Mem + 256
  poke @PCOLR0, $3A
  poke @PCOLR1, $84
  poke @GPRIOR, 33
  poke @SDMCTL, Peek(@SDMCTL) ! 24
  poke @PMBASE, Peek(@RAMTOP)
  poke @GRACTL, 2

endproc

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Proc StartGame

  poke P0Mem, 0 : move P0Mem, P0Mem+1, 511 : ' Clears P/M
  put #6, 125                                ' Clear screen
  Poke @HITCLR, 0                            ' Clear collisions
  Sound                                      ' Clear sounds

  Player_x = 56
  Player_y = 48
  got = 0
  snd = 0

  ' Draws play-field
  color 34
  plot 0,0 : dr. 39,0 : dr. 39,23 : dr. 0,23 : dr. 0,0

  color 33
  plot 1,1 : dr. 38,1 : dr. 38,22 : dr. 1,22 : dr. 1,1

  color 35+128
  for i=0 to 20
     plot rand(15)*2 + 6, rand(15) + 5
  next i
  color 35
  for i=0 to 10
     plot rand(15)*2 + 6, rand(15) + 5
  next i
  color 36
  for i=0 to 10
     plot rand(15)*2 + 7, rand(15) + 5
  next i
endproc

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
proc GameLoop

  do
    pause 0   ' Waits for VB

    ' Reads HIT
    hit = peek(@P0PF) ! peek(@P1PF)

    ' Now, you should put here the code to copy variables to hardware registers,
    ' as we are synchronized to the screen.
    Poke @HPOSP0, Player_x   ' Player 0 and 1 are the player
    Poke @HPOSP1, Player_x
    Move P0_Frame, P0Mem + Player_y, P0_Size
    Move P1_Frame, P1Mem + Player_y, P0_Size
    Poke @COLOR3, Peek(@COLOR3)+1
    Poke @HITCLR, 0           ' Clear collisions

    ' Sound generation
    if got
      got = got - 1
      sound 0,snd,10,got
      snd = snd - 1
    endif

    ' Now, the game logic, this does not need to be synchronized

    ' Store old player position:
    Old_x = Player_x : Old_y = Player_y

    ' Moves Player
    Frame = 0
    if (Stick(0) &  = 0
       Player_x = Player_x + 1
       Frame = (not (Player_x & 2)) + 1
    endif
    if (Stick(0) & 4) = 0
       Player_x = Player_x - 1
       Frame = (not (Player_x & 2)) + 3
    endif
    if (Stick(0) & 2) = 0
       Player_y = Player_y + 1
    endif
    if (Stick(0) & 1) = 0
       Player_y = Player_y - 1
    endif
    ' Calculate address of player sprites
    Frame = Frame * 19
    P0_Frame = Adr(P0_Data) + Frame
    P1_Frame = Adr(P1_Data) + Frame

    ' Check if we are over a wall
    Screen1 = Dpeek(@SAVMSC) + (Player_x - 48) / 4 + ( (Player_y - 32) / 8 ) * 40
    Screen2 = Dpeek(@SAVMSC) + (Player_x - 48 + 7) / 4 + ( (Player_y - 32 + 18) / 8 ) * 40
    if Peek(Screen1)=1 or Peek(Screen2)=1
      Player_x = Old_x
      Player_y = Old_y
    endif

    ' Check if we are dead!
    if hit & 8
      exit
    elif hit & 6
      ' Got something, setup sound
      got = 16
      snd = hit * 40
      ' Brute force clear all behid our character
      Screen3 = Dpeek(@SAVMSC) + (Player_x - 48 + 7) / 4 + ( (Player_y - 32) / 8 ) * 40
      Screen4 = Dpeek(@SAVMSC) + (Player_x - 48) / 4 + ( (Player_y - 32 + 18) / 8 ) * 40
      Poke Screen1, 0 : Poke Screen1 + 1, 0 : Poke Screen3, 0 : Poke Screen3 - 1, 0
      Poke Screen1+40, 0 : Poke Screen1 + 41, 0 : Poke Screen3 + 40, 0 : Poke Screen3 + 39, 0
      Poke Screen4, 0 : Poke Screen4 + 1, 0 : Poke Screen2, 0 : Poke Screen2 - 1, 0
      Poke Screen4-40, 0 : Poke Screen4-39, 0 : Poke Screen2-40, 0 : Poke Screen2 - 41, 0
    endif

  loop

endproc

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Main Game

  Exec Init   ' Calls an initialization function, this sets graphics, loads P/M, etc.

  do
    Exec StartGame
    Exec GameLoop
  loop

end

Edited by funkheld
Link to comment
Share on other sites

Hi!

4 hours ago, mdhughes said:

Well, thanks, but FB is still shipping a VM, not a native binary (and I sure don't want to develop in BASIC, anything above trivial utilities is too messy).

FastBasic VM is fast and small, and binaries compiled by the IDE are completely self contained, so they don't need any runtime. The reason to use a VM is that it allows larger programs, as the code is smaller than 6502 assembly and the compilation is much simpler.

 

And if you really need the speed, I have a compiler to 6502 machine code available, but currently only as a cross compiler from a PC.

 

And about the language, IMHO, FastBasic language is much more advance than older BASICs, with control statements and procedures, and without GOTO and line numbers.

 

The example posted by @funkheld is old, newer FastBasic versions have P/M support making the code simpler, see attached. Also, the attached version can be compiled and run from the IDE. For another game written in FastBasic, look at Joyas:

 

Have Fun!

 

PD: Here is the "gameloop.bas" code:

' Simple demonstration game loop in FastBasic
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Proc Init

  ' Sets ANTIC mode 4
  gr. 28

  screen = Dpeek(88) ' SAVMSC

  ' Set P/M graphics
  pmg. 1

  ' Our player data:
  '  5 frames, one static, two going left, two going right
  data P0_Data() byte = $00,$00,$00,$00,$3c,$3c,$3c,$18,$00,$00,$00,$81,$00,$00,$00,$00,$00,$66,$66,
  data           byte = $00,$00,$00,$00,$3c,$3c,$3c,$18,$80,$00,$00,$01,$00,$00,$00,$00,$00,$36,$36,
  data           byte = $00,$00,$00,$00,$3c,$3c,$3c,$18,$01,$00,$00,$80,$00,$00,$00,$00,$00,$c3,$c3,
  data           byte = $00,$00,$00,$00,$3c,$3c,$3c,$18,$01,$00,$00,$80,$00,$00,$00,$00,$00,$6c,$6c,
  data           byte = $00,$00,$00,$00,$3c,$3c,$3c,$18,$80,$00,$00,$01,$00,$00,$00,$00,$00,$c3,$c3,
  data           byte = $00

  data P1_Data() byte = $00,$18,$3c,$7e,$00,$00,$00,$00,$18,$3c,$7e,$3c,$3c,$3c,$3c,$24,$66,$66,$66,
  data           byte = $00,$18,$3c,$3e,$00,$00,$00,$00,$18,$7c,$3e,$3c,$3c,$3c,$3c,$24,$24,$36,$36,
  data           byte = $00,$18,$3c,$3e,$00,$00,$00,$00,$18,$3e,$7c,$3c,$3c,$3c,$3c,$64,$46,$c7,$c3,
  data           byte = $00,$18,$3c,$7c,$00,$00,$00,$00,$18,$3e,$7c,$3c,$3c,$3c,$3c,$24,$24,$6c,$6c,
  data           byte = $00,$18,$3c,$7c,$00,$00,$00,$00,$18,$7c,$3e,$3c,$3c,$3c,$3c,$26,$62,$e3,$c3,
  data           byte = $00

  ' Our frame addresses
  dim P0_Frames(4), P1_Frames(4)
  for Frame = 0 to 4
    P0_Frames(Frame) = Adr(P0_Data) + Frame * 19
    P1_Frames(Frame) = Adr(P1_Data) + Frame * 19
  next

  P0_Size  = 20

  ' Char data
  data Ch_Data() byte = $00,$00,$00,$00,$00,$00,$00,$00,
  data           byte = $AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA,
  data           byte = $88,$22,$88,$22,$88,$22,$88,$22,
  data           byte = $00,$14,$7D,$7D,$7D,$14,$00,$00,
  data           byte = $00,$A8,$A8,$A8,$A8,$A8,$00,$00,
  data           byte = $44,$11,$44,$11,$44,$11,$44,$11

  ' Setup characters just before the P/M graphics
  move Adr(Ch_Data), PMAdr(-4), 8 * 6
  poke $2F4, PMAdr(-4)/256  ' CHBAS

  Player_x = 56
  Player_y = 48

  P0Mem = PMAdr(0)      ' Get P/M addresses for faster main loop
  P1Mem = PMAdr(1)
  poke $26f, 33         ' Set GPRIOR for mixed color P/M

  HITCLR = $D01E        ' P/M Hit clearing
  HITP0  = $D004        ' Collision Player 0 / Play-field
  HITP1  = $D005        ' Collision Player 1 / Play-field
endproc

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Proc StartGame

  mset P0Mem, 512, 0   ' Clears P/M
  cls #6               ' Cleat screen
  Poke HITCLR, 0       ' Clear collisions
  Sound                ' Clear sounds
  Setcolor -4, 3, 10   ' Player 0 color
  Setcolor -3, 8, 4    ' Player 1 color

  Player_x = 56
  Player_y = 48
  Frame = 0
  got = 0
  snd = 0

  ' Draws play-field
  color 34
  plot 0,0 : dr. 39,0 : dr. 39,23 : dr. 0,23 : dr. 0,0

  color 33
  plot 1,1 : dr. 38,1 : dr. 38,22 : dr. 1,22 : dr. 1,1

  color 35+128
  for i=0 to 20
     plot rand(15)*2 + 6, rand(15) + 5
  next i
  color 35
  for i=0 to 10
     plot rand(15)*2 + 6, rand(15) + 5
  next i
  color 36
  for i=0 to 10
     plot rand(15)*2 + 7, rand(15) + 5
  next i
endproc

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
proc GameLoop

  ' Keeps iteration counter for the colors
  iter = 0

  do
    pause 0   ' Waits for VB

    ' Reads HIT
    hit = peek(HITP0) ! peek(HITP1)

    ' Now, you should put here the code to copy variables to hardware registers,
    ' as we are synchronized to the screen.
    pmhpos 0, Player_x  ' Player 0 and 1 are the player
    pmhpos 1, Player_x
    Move P0_Frames(Frame), P0Mem + Player_y, P0_Size
    Move P1_Frames(Frame), P1Mem + Player_y, P0_Size

    Setcolor 3, 0, iter
    inc iter

    Poke HITCLR, 0      ' Clear collisions

    ' Sound generation
    if got
      dec got
      sound 0,snd,10,got
      dec snd
    endif

    ' Now, the game logic, this does not need to be synchronized

    ' Store old player position:
    Old_x = Player_x : Old_y = Player_y

    ' Moves Player
    Frame = 0
    if (Stick(0) & 8) = 0
       inc Player_x
       Frame = (not (Player_x & 2)) + 1
    endif
    if (Stick(0) & 4) = 0
       dec Player_x
       Frame = (not (Player_x & 2)) + 3
    endif
    if (Stick(0) & 2) = 0
       inc Player_y
    endif
    if (Stick(0) & 1) = 0
       dec Player_y
    endif

    ' Check if we are over a wall
    Screen1 = Screen + (Player_x - 48) / 4 + ( (Player_y - 32) / 8 ) * 40
    Screen2 = Screen + (Player_x - 48 + 7) / 4 + ( (Player_y - 32 + 18) / 8 ) * 40
    if Peek(Screen1)=1 or Peek(Screen2)=1
      Player_x = Old_x
      Player_y = Old_y
    endif

    ' Check if we are dead!
    if hit & 8
      exit
    elif hit & 6
      ' Got something, setup sound
      got = 16
      snd = hit * 40
      ' Brute force clear all behind our character
      Screen3 = Screen + (Player_x - 48 + 7) / 4 + ( (Player_y - 32) / 8 ) * 40
      Screen4 = Screen + (Player_x - 48) / 4 + ( (Player_y - 32 + 18) / 8 ) * 40
      Poke Screen1, 0 : Poke Screen1 + 1, 0 : Poke Screen3, 0 : Poke Screen3 - 1, 0
      Poke Screen1+40, 0 : Poke Screen1 + 41, 0 : Poke Screen3 + 40, 0 : Poke Screen3 + 39, 0
      Poke Screen4, 0 : Poke Screen4 + 1, 0 : Poke Screen2, 0 : Poke Screen2 - 1, 0
      Poke Screen4-40, 0 : Poke Screen4-39, 0 : Poke Screen2-40, 0 : Poke Screen2 - 41, 0
    endif

  loop

  ' Dead loop
  for iter = 10 to 0 step -1
    sound 0, iter, 2, iter
    Setcolor -4, 3, iter
    Setcolor -3, 8, iter * 4 / 10
    pause 1
  next

endproc

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Main Game

  Exec Init   ' Calls an initialization function, this sets graphics, loads P/M, etc.

  do
    Exec StartGame
    Exec GameLoop
  loop

end

 

gameloop.bas gameloop.xex

  • Like 3
Link to comment
Share on other sites

Hi

2 hours ago, funkheld said:

hello, dmsc, which is your latest version of fastbasic?

Last released version is 4.0, from GitHub link you posted above.

 

I should release a new version soon, but have had no time to finalize a few things, like the new DLI support.

 

Have fun!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...