; 20070524 bkw: DASM source for GR.2 "LOADING..." screen.
; Object code is intended to be prepended to some other object
; file, so it uses INITAD rather than RUNAD.

; WARNING: if you modify this file such that the object code changes,
; make sure you edit cart2bin.c and correct the offset for the title
; screen text! As long as you don't change anything after the "loading"
; label, this won't be a problem.

 processor 6502

 include "equates.inc"

 seg.u ZP
 org $80

 if * > $ff
   echo "Zero page vars have overrun into the stack! * =", *
   err
 else
   echo *-$80, "bytes of zero page used,", $ff-*, "remain"
 endif

 seg CODE

LOAD_ADDR = $6000 ; load at 24K
origin = LOAD_ADDR-6;
 org origin ; make room for 6-byte header

; 2-byte Atari executable header:
 byte $FF, $FF ; let DOS know it's a binary load file

; start of first segment

; 4-byte segment header:
 word LOAD_ADDR ; Load address
 word endbin-1 ; Last byte to load

; Rest of segment contains code and data
pagesize byte 0   ; cart2bin will fill this in with the size of
                  ; the cart image code, in pages.
main:

; set RAMTOP to 28K, call GR.2, store "LOADING..." in screen RAM,
; then set RAMTOP back to original value.

 lda RAMTOP
 cmp #$C0     ; do we have 48K?
 bcs ram_ok

 ldx #0       ; no! print error message...
 lda #9
 sta ICCOM
 lda #<ram_msg
 sta ICBAL
 lda #>ram_msg
 sta ICBAH
 lda #ram_msg_len
 sta ICBLL
 stx ICBLH
 jsr CIOV
hang bcs hang ; spin forever

ram_msg byte "Need at least 48K to run this.", $9B
ram_msg_len = *-ram_msg+1

ram_ok
 ;sec          ; carry already set by cmp above!
 sbc pagesize  ; adjust RAMTOP to make room for the converted cart image
 pha           ; save old RAMTOP value on stack

 lda #$70      ; set RAMTOP to $7000 (28K). Later on we do GRAPHICS 2,
 sta RAMTOP    ; which will cause the DL and screen RAM to go here.

 ldx #$60      ; CLOSE #6 first
 lda #12       ; Command 12=CLOSE
 sta ICCOM,x
 jsr CIOV      ; call CIO, ignore any error

 ;ldx #$60     ; set up IOCB #6 for CIO GRAPHICS command
 lda #3        ; Command 3=OPEN
 sta ICCOM,x
 lda #12       ; 12=R/W access
 sta ICAX1,x
 lda #2        ; GR. mode 2
 sta ICAX2,x
 lda #<s_dev   ; S: device
 sta ICBAL,x
 lda #>s_dev
 sta ICBAH,x
 lda #s_dev_len
 sta ICBLL,x
 lda #0
 sta ICBLH,x
 jsr CIOV      ; call CIO

 lda #5        ; POSITION 5,5
 sta ROWCRS
 sta COLCRS
 lda #0
 sta COLCRS+1

 sta ICBLH,x   ; PRINT #6;"LOADING...
; ldx #$60
 lda #9        ; Command 9 = CIO "put record"
 sta ICCOM,x
 lda #<loading
 sta ICBAL,x
 lda #>loading
 sta ICBAH,x
 lda #loading_len
 sta ICBLL,x
 jsr CIOV      ; call CIO

; ldx #$60     ; CLOSE #6
 lda #12       ; Command 12=CLOSE
 sta ICCOM,x
 jsr CIOV      ; call CIO, ignore any error

 pla           ; get adjusted RAMTOP value
 sta RAMTOP

 rts           ; end of init routine, return control to DOS

s_dev byte "S:"
s_dev_len equ *-s_dev+1

; WARNING: if you change any code/data below this line, you'll probably need
; to change the offset in cart2bin.c as well.
loading byte "  LOADING"
        ds 6
title   ds 20      ; cart2bin will fill in these 20 bytes with the filename
        byte $9B   ; (or title, if -t is used)
loading_len equ *-loading+1

endbin ; end of first segment

 echo "Code is", *-origin+1, "bytes"

; start of second segment (which loads at INITAD, to tell DOS
; where to start running the init code loaded in segment 1)

 ; 4-byte segment header:
 word INITAD    ; load address (loading into INITAD lets our code run)
 word INITAD+1  ; Last byte to load

 ; Segment data contains 2 bytes (the actual run address)
 word main     ; the 2 bytes to stuff into RUNAD

 ; That's all, folks!
 echo "Title offset: loadscreen_bin_len - ", *-title