Jump to content
Sign in to follow this  
Karl G

7800 assembly "hello world"?

Recommended Posts

I love 7800Basic, but I am wanting to understand more about making 7800 games in assembly. I'm aware of the 7800 Software Guide for technical information, but does there exist a simple "hello world" type of example to help the uninitiated?

  • Like 2

Share this post


Link to post
Share on other sites
On 3/24/2021 at 2:28 PM, SmittyB said:

The closest thing I found when I started to look at the 7800 was this example code that I was then able to modify slightly to have a scrolling tile-map.

https://atarihq.com/danb/files/7800sprt.s

Just a caution for anyone using that code - the "build DL entries" section of code has a bug, which results in the code not correctly building DLs for more than one sprite. Prior to the "sty dlend,x" opcodes near the end of the top sprite update section, and the bottom sprite update section, you need to add an "iny" to get the correct DL ending stored.

 

The original 7800basic sprite DL update was based on Dan's code, but has been quite heavily modified to support different zone heights, vertical masking, double-buffering, etc., in addition to just optimising cycles.

 

  • Thanks 3

Share this post


Link to post
Share on other sites

IMHO one of the big challenges of programming the 7800 is the amount of data required to get anything to appear on screen - you need to generate the display lists and the display list list.  And once you get that done you realize it's non-trivial to dynamically generate those display lists efficiently.

  • Like 2

Share this post


Link to post
Share on other sites
1 hour ago, EricBall said:

IMHO one of the big challenges of programming the 7800 is the amount of data required to get anything to appear on screen - you need to generate the display lists and the display list list.  And once you get that done you realize it's non-trivial to dynamically generate those display lists efficiently.

The obvious way to do it is: for each zone, check whether each dynamic object is in that zone and if so, write the headers for those objects. It is O(zones * dynamic objects). I have not tested how this actually works. It's not great in principle but should be fine for "Hello, world" purposes.

 

Figuring out a better way felt, to me, like a rite of passage for programming the 7800. I don't want to take that away from anybody, but I also don't want to be coy. So I'll put my solution in a spoiler block.

 

Spoiler

What I came up with was:

  1. Set aside some temporary RAM, one byte for each playfield zone, first used for object counters. Initialize them to 0.
  2. For each dynamic object, increment the object counter for each zone it's in.
  3. For each playfield zone, write headers for any static objects, skip over enough bytes to later fill in headers for the dynamic objects, write the two-byte terminator, and replace the object counter with the address (low byte) that will contain the zone's first dynamic object's header.
  4. For each dynamic object, emplace the header for the object at the zone's address for dynamic headers, then increment that address.

"Object" here means something with its own header. In indirect mode, of course, there are multiple characters (aka tiles) per object.

 

Several loops but none are nested. It is O(zones + dynamic objects). My implementation takes about 100 cycles per zone plus 100 cycles per object per zone.

 

In my case, one page is enough for all of the headers. If you have enough zones and objects that the headers don't fit on a single page, the general idea should still work, but you need 2 bytes per zone, to store both bytes of header addresses.

 

  • Like 2

Share this post


Link to post
Share on other sites

My technique was to loop through the objects then append the entry to the relevant display list(s).  Just need to store an offset for the end of each list.  But whatever the method you have to transform the Y position to select the correct display list and then the graphics page offset.

  • Like 1

Share this post


Link to post
Share on other sites

My version in Mads ;)

Hello, World! - JS7800 emulator link

 

https://github.com/tebe6502/Mad-Assembler

http://mads.atari8.info/mads_eng.html

https://www.wudsn.com/index.php/ide

 

		icl 'maria.h'

		opt f+h-

		org $40
dest 	.ds 2 		;2 bytes


          ORG     $8000-128
HEADER       .byte    1  			; 0   Header version     - 1 byte
        .by    "ATARI7800       "	; 1..16  "ATARI7800   "  - 16 bytes
        .by    "Project name    "	; 17..48 Cart title      - 32 bytes
        .by    "Author          "	; 2 line
        DTA r	($8000)				; 49..52 data length      - 4 bytes (Big-endian format)
        .byte    $00,$00  			; 53..54 cart type      - 2 bytes
        .byte     1  ; 55   controller 1 type  - 1 byte
        .byte     0  ; 56   controller 2 type  - 1 byte
        .byte    0  ; 57 0 = NTSC 1 = PAL
        .byte    0  ; 58   Save data peripheral - 1 byte (version 2)
        .byte 0,0,0,0	;ORG     HEADER+63
        .byte    0  ; 63   Expansion module
	.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
        .by    "ACTUAL CART DATA STARTS HERE"

	.macro clear_ram
	ldy #$00
	mwa #:1 dest
	lda #$00
@	sta (dest),y
	inw dest
	lda dest+1
	cmp #>[:2+1]
	bne @-
	.endm


            org $8000
fnt		ins 'cmc.fnt'
;
START
		sei					;Disable interrupts
		cld					;Clear decimal mode
		mva #$07 INPTCTRL
		mva	#$7F CTRL
		mva	#$00 OFFSET
		mva #$00 INPTCTRL
		ldx	#$FF			;Reset stack pointer
		txs
;Clear zeropage,stack,RAM
		clear_ram $42,$FF	;skip $40&$41 (dest)
		clear_ram $140,$1FF
		clear_ram $1800,$1FFF
		clear_ram $2200,$27FF
	
; copy Display List List To RAM
      	ldy #0
copy  	mva .adr(DLLs),y DLLs,y+
	    cpy #.len DLLs
	    bne copy
;
		mva #<DLLs DPPL\ mva #>DLLs DPPH	;set display list list address
		jsr	WaitVBLANK						;wait until no DMA would happen

		mva	#>fnt	CHBASE
		mva	#$40	CTRL
;set colors
		mva	#$00 BACKGRND\ mva #$02 P0C1\ mva #$04 P0C2\ mva #$0c P0C3
jm 		jmp jm

NMI		RTI
IRQ		RTI

WaitVBLANK:	
WaitVBoff:
		bit		MSTAT
		bmi		WaitVBoff
WaitVBon:
		bit		MSTAT
		bpl		WaitVBon
		rts

; RAM
		ORG	$1800,*
.local DLLs
	:2	.byte	$0F,>emptyline,<emptyline
		.byte	$07,>line,<line
	:24	.byte	$0F,>emptyline,<emptyline

	.byte 0
line		.byte <text,$60,>text,0,20
emptyline	.byte $00,$00

text	.sb	'Hello, World!                   '
	.endl

;************** Cart reset vector **************************

	 ORG	$fff8
	.byte	$FF		;Region verification
	.byte	$87		;ROM start $8000
	.word	NMI
	.word	START
	.word	IRQ

 

maria.h helloworld.asm CMC.FNT helloworld.a78

  • Like 2

Share this post


Link to post
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.

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...
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...