aboutsummaryrefslogtreecommitdiff
path: root/src/col80_modified/col80_hacked.dasm
diff options
context:
space:
mode:
Diffstat (limited to 'src/col80_modified/col80_hacked.dasm')
-rw-r--r--src/col80_modified/col80_hacked.dasm906
1 files changed, 906 insertions, 0 deletions
diff --git a/src/col80_modified/col80_hacked.dasm b/src/col80_modified/col80_hacked.dasm
new file mode 100644
index 0000000..ef6c5ac
--- /dev/null
+++ b/src/col80_modified/col80_hacked.dasm
@@ -0,0 +1,906 @@
+; THIS IS A MODIFIED VERSION, for use with FujiChat
+
+; COL80.COM, aka COL80E.COM, aka COL80HND.COM
+; (and probably several other names)
+
+; Original author unknown
+; License unknown
+; Disassembly and comments by Urchlay
+
+; This is a widely-distributed software 80-column driver for the Atari
+; 8-bit computers. It replaces the OS's E: driver, and uses GRAPHICS 8
+; for display, with 4x8 pixel character cells.
+
+; Disassembly was done with da65, with many iterations of "edit the
+; .info file, disassemble again", and the results were tweaked by hand
+; into something assemblable by dasm (and fairly compatible with other
+; assemblers).
+
+
+ .processor 6502
+
+START_ADDRESS = $9C2D
+;START_ADDRESS = $7C28 ; works with BASIC
+
+; xex segment header #1
+ .org START_ADDRESS-6
+ .word $FFFF
+ .word START_ADDRESS
+ .word END_ADDRESS
+
+ .org START_ADDRESS
+
+; ----------------------------------------------------------------------------
+; Zero page labels (OS equates)
+
+DOSINI = $000C
+ICAX1Z = $002A
+ICAX2Z = $002B
+TMPCHR = $0050
+LMARGN = $0052
+ROWCRS = $0054
+COLCRS = $0055
+DINDEX = $0057
+SAVMSC = $0058
+BUFCNT = $006B
+
+; ----------------------------------------------------------------------------
+; Zero page labels (COL80 equates)
+
+screen_ptr_lo = $00CB
+screen_ptr_hi = $00CC
+font_ptr_lo = $00CD
+font_ptr_hi = $00CE
+
+; ----------------------------------------------------------------------------
+; Non-zeropage RAM labels (OS equates)
+
+COLOR1 = $02C5
+COLOR2 = $02C6
+RUNAD = $02E0
+INITAD = $02E2
+MEMTOP = $02E5
+SSFLAG = $02FF
+HATABS = $031A
+ICCOM = $0342
+ICBAL = $0344
+ICBAH = $0345
+
+; ----------------------------------------------------------------------------
+; Hardware (memory-mapped I/O, OS equates)
+
+CONSOL = $D01F
+AUDF1 = $D200
+AUDC1 = $D201
+
+; ----------------------------------------------------------------------------
+; OS ROM labels
+
+s_dev_open_lo = $E410 ; (not named in OS sources)
+s_dev_open_hi = $E411 ; ""
+k_dev_get_lo = $E424 ; ""
+k_dev_get_hi = $E425 ; ""
+CIOV = $E456 ; Central Input/Output entry point
+
+; ----------------------------------------------------------------------------
+; Start of COL80. The font is stored in packed form. Each group of 8 bytes
+; defines two glyphs: the upper 4 bits of the 8 bytes, taken together,
+; define the bitmap for the first glyph, and the lower 4 bits are the second.
+; Note that the bits that make up a single character are spread across 8
+; bytes, so it's hard to visualize these even if you're used to reading hex
+; dumps.
+
+; The first 2 characters look like:
+
+; .... .O.. ; $04
+; .... .O.. ; $04
+; O.O. .O.. ; $A4
+; OOO. .O.. ; $E4
+; OOO. .OOO ; $E7
+; .O.. .O.. ; $44
+; .... .O.. ; $04
+; .... .O.. ; $04
+
+; These are the ATASCII heart symbol (character code 0) and the ATASCII
+; control-A line-drawing symbol (code 1).
+
+; Note: unlike the ROM font, this font is stored in ATASCII order instead
+; of the standard Atari character order imposed by the hardware. Like
+; the ROM font, inverse characters are not stored here (the bitmaps get
+; inverted by the driver)
+
+font_data:
+ .include "new_font.s"
+ ;.include "icetmod.s"
+
+right_margin:
+ ; Default value is 79 decimal. Unsure why the author didn't use RMARGN at $53
+ .byte $4F
+
+; ----------------------------------------------------------------------------
+; Start of COL80 code.
+
+; Callback for CIO OPEN command.
+
+col80_open:
+ jsr init_graphics_8
+ lda #$00
+ sta ROWCRS
+ sta COLCRS
+ sta BUFCNT
+ lda #$4F
+ sta right_margin
+ rts
+
+; ----------------------------------------------------------------------------
+; Assembly version of GRAPHICS 8+16 command.
+
+init_graphics_8:
+ lda #$08
+ sta ICAX2Z
+ lda #$0C
+ sta ICAX1Z
+ jsr open_s_dev
+
+ ; Set COL80's default colors
+ lda #$08
+ sta COLOR2
+ lda #$00
+ sta COLOR1
+
+ ; Protect ourselves from BASIC and the OS
+ lda #<START_ADDRESS
+ sta MEMTOP
+ lda #>START_ADDRESS
+ sta MEMTOP+1
+ rts
+
+; ----------------------------------------------------------------------------
+; Call the OPEN vector for the S: device, using the ROM vector table
+; at $E410. The table stores address-minus-one of each routine, which is
+; meant to actually be called via the RTS instruction (standard 6502
+; technique, but confusing the first time you encounter it)
+
+open_s_dev:
+ lda s_dev_open_hi
+ pha
+ lda s_dev_open_lo
+ pha
+ rts
+
+; ----------------------------------------------------------------------------
+; Callback for CIO CLOSE command. Note that the routine does nothing, really
+; (the OS will mark the E: device as being closed, but COL80 doesn't do any
+; cleanup).
+; The SPECIAL and GET STATUS callbacks in col80_vector_tab also point here.
+
+col80_close:
+ jmp return_success
+
+; ----------------------------------------------------------------------------
+; Callback for the internal put-one-byte, used by the OS to implement the
+; CIO PUT RECORD and PUT BYTES commands. This routine's one argument is
+; the byte in the accumulator (the character to print).
+
+; First, the routine checks for the cursor control characters it supports.
+; COL80 only handles the EOL and clear-screen codes; trying to print
+; backspaces, arrows, deletes, inserts, etc just causes their ATASCII
+; graphics character to print instead.
+
+col80_putbyte:
+ ; EOL (decimal 155)?
+ cmp #$9B
+;;; bne check_clear
+ bne regular_char
+ lda right_margin
+ sta COLCRS
+ jmp skip_write
+
+;;;check_clear:
+;;; .ifndef FUJICHAT ; save memory by not including clear_screen
+;;; ; (also, this lets us print the } character)
+;;; ; Clear (decimal 125)?
+;;; cmp #$7D
+;;; bne regular_char
+;;; jmp clear_screen
+;;; .endif
+;;;
+ ; See if this is an inverse video char (code >= 128)
+regular_char:
+ tax
+ bpl not_inverse
+ lda #$FF
+ sta inverse_mask
+ bne skip_ninv
+
+not_inverse:
+ lda #$00
+ sta inverse_mask
+
+skip_ninv:
+ txa
+ and #$7F
+ ;.ifdef FUJICHAT ; mask out low ASCII
+ sec
+ sbc #$20
+ bcs not_low_ascii
+ jmp return_success
+not_low_ascii:
+ ;.endif
+ sta TMPCHR
+ lda DINDEX
+ cmp #$08
+ beq graphics_ok
+ ; If we're not in GRAPHICS 8 mode, reinitialize ourselves
+ jsr col80_open
+
+graphics_ok:
+ ; Call the routines that actually print the character
+ jsr setup_font_ptr
+ jsr setup_screen_ptr
+ jsr write_font_data
+
+skip_write:
+ ; Move the cursor 1 space to the right. This will
+ ; advance us to the next line if we're at the margin,
+ ; and scroll the screen if needed
+ jsr advance_cursor
+
+check_ssflag:
+ ; The OS keyboard interrupt handler will toggle SSFLAG (start/stop fla
+ ; any time the user presses ctrl-1
+ ;lda SSFLAG
+ ;bne check_ssflag
+ jmp return_success
+
+; ----------------------------------------------------------------------------
+; Scroll the screen up one line (8 scanlines). This has to move almost 8K of
+; data, so it's noticeably slower than scrolling the GR.0 text screen.
+
+scroll_screen:
+ lda SAVMSC
+ sta screen_ptr_lo
+ clc
+ adc #$40
+ ; font_ptr_lo is actually being used here as a second pointer into
+ ; screen RAM, instead of its usual use as a pointer into the
+ ; font_data table
+ sta font_ptr_lo
+ lda SAVMSC+1
+ sta screen_ptr_hi
+ adc #$01
+ sta font_ptr_hi
+ ldx #$1D
+ ldy #$00
+
+scroll_line_loop:
+ lda (font_ptr_lo),y
+ sta (screen_ptr_lo),y
+ dey
+ bne scroll_line_loop
+ inc font_ptr_hi
+ inc screen_ptr_hi
+ dex
+ bne scroll_line_loop
+
+blank_bottom_row:
+ lda SAVMSC
+ clc
+ adc #$C0
+ sta screen_ptr_lo
+ lda SAVMSC+1
+ adc #$1C
+ sta screen_ptr_hi
+ lda #$00
+ tay
+
+blank_loop:
+ sta (screen_ptr_lo),y
+ dey
+ bne blank_loop
+ inc screen_ptr_hi
+ ldy #$40
+
+blank_tail:
+ sta (screen_ptr_lo),y
+ dey
+ bpl blank_tail
+ rts
+
+; ----------------------------------------------------------------------------
+; Set up font_ptr_lo/hi to point to the font_data bitmap for the character in
+; TMPCHR. Also sets lo_nybble_flag to let the caller know whether the
+; bitmap is in the upper or lower 4 bits of the bytes pointed to.
+
+setup_font_ptr:
+ lda #$00
+ sta font_ptr_hi
+ sta lo_nybble_flag
+ lda TMPCHR
+ clc
+ ror
+ bcc font_hi_nybble
+ ldx #$FF
+ stx lo_nybble_flag
+
+font_hi_nybble:
+ clc
+ rol
+ rol
+ rol font_ptr_hi
+ rol
+ rol font_ptr_hi
+ adc #<font_data
+ sta font_ptr_lo
+ lda #>font_data
+ adc font_ptr_hi
+ sta font_ptr_hi
+ rts
+
+; ----------------------------------------------------------------------------
+; Move the cursor one space to the right (to the next line if at the margin,
+; and scroll screen if on the last row)
+
+advance_cursor:
+ inc COLCRS
+ lda right_margin
+ cmp COLCRS
+ bcs same_line
+ lda LMARGN
+ sta COLCRS
+ lda ROWCRS
+ ; $17 is 25 decimal, one row below the lowest on the screen
+ cmp #$17
+ bcc no_scroll
+ jsr scroll_screen
+ ; Move to row 24 after scrolling
+ lda #$16
+ sta ROWCRS
+
+no_scroll:
+ inc ROWCRS
+
+same_line:
+ rts
+
+; ----------------------------------------------------------------------------
+; Clear the screen by setting all screen RAM bytes to zero. Slow, but not
+; as slow as scrolling.
+
+;;; .ifndef FUJICHAT
+;;;clear_screen:
+;;; lda SAVMSC
+;;; sta screen_ptr_lo
+;;; lda SAVMSC+1
+;;; sta screen_ptr_hi
+;;; ldy #$00
+;;; ldx #$1D
+;;; lda #$00
+;;;
+;;;cls_loop:
+;;; sta (screen_ptr_lo),y
+;;; dey
+;;; bne cls_loop
+;;; inc screen_ptr_hi
+;;; dex
+;;; bne cls_loop
+;;; jsr blank_bottom_row
+;;; lda LMARGN
+;;; sta COLCRS
+;;; lda #$00
+;;; sta ROWCRS
+;;; ; redundant JMP
+;;; jmp return_success
+;;; .endif
+
+; ----------------------------------------------------------------------------
+; CIO expects the Y register to contain a status code.
+; 1 means success (no error). Lots of COL80's routines
+; jump here.
+
+return_success:
+ ldy #$01
+ rts
+
+; ----------------------------------------------------------------------------
+; Set screen_ptr_lo/hi to point to the address of the first byte of graphics
+; data at the current cursor position.
+
+setup_screen_ptr:
+ ldy ROWCRS
+ lda SAVMSC
+ clc
+ adc row_low_offset_tab,y
+ sta screen_ptr_lo
+ lda SAVMSC+1
+ adc row_high_offset_tab,y
+ sta screen_ptr_hi
+ lda COLCRS
+ lsr
+ clc
+ adc screen_ptr_lo
+ bcc hi_byte_ok
+ inc screen_ptr_hi
+
+hi_byte_ok:
+ sta screen_ptr_lo
+ rts
+
+; ----------------------------------------------------------------------------
+; Tables of offsets for setup_screen_ptr, to avoid doing multiplication at
+; runtime (the 6502 lacks a MUL instruction, so it's slow...)
+
+row_low_offset_tab:
+ .byte $00,$40,$80,$C0,$00,$40,$80,$C0
+ .byte $00,$40,$80,$C0,$00,$40,$80,$C0
+ .byte $00,$40,$80,$C0,$00,$40,$80,$C0
+
+row_high_offset_tab:
+ .byte $00,$01,$02,$03,$05,$06,$07,$08
+ .byte $0A,$0B,$0C,$0D,$0F,$10,$11,$12
+ .byte $14,$15,$16,$17,$19,$1A,$1B,$1C
+
+; ----------------------------------------------------------------------------
+; Copy pixel data from the font table to screen RAM.
+; font_ptr_lo/hi must point to the correct character, and screen_ptr_lo/hi
+; must point to the correct screen address for the current cursor position.
+; This routine has separate execution paths for even- and odd-numbered
+; cursor positions, since each byte of screen RAM holds data for two
+; adjacent characters (and when printing to one of them, the other needs
+; to be left undisturbed!)
+
+write_font_data:
+ lda COLCRS
+ clc
+ ror
+ bcc write_font_data_even
+ ldx #$00
+ ldy #$00
+
+get_font_nybble_odd:
+ lda (font_ptr_lo),y
+ bit lo_nybble_flag
+ bne lo_nybble_odd
+ ; glyph we want is stored in top 4 bits of font byte,
+ ; shift it down to the bottom 4 bits
+ lsr
+ lsr
+ lsr
+ lsr
+
+lo_nybble_odd:
+ eor inverse_mask
+ and #$0F
+ sta TMPCHR
+ ldy scanline_offset_tab,x
+ lda (screen_ptr_lo),y
+ and #$F0
+ ora TMPCHR
+ sta (screen_ptr_lo),y
+ inx
+ cpx #$07
+ bne screen_ptr_ok_odd
+ inc screen_ptr_hi
+
+screen_ptr_ok_odd:
+ cpx #$08
+ beq write_font_done_odd
+ txa
+ tay
+ bne get_font_nybble_odd
+
+write_font_done_odd:
+ rts
+
+; ----------------------------------------------------------------------------
+; Write data to even-numbered columns, very similar to the above
+
+write_font_data_even:
+ ldx #$00
+ ldy #$00
+
+get_font_nybble_even:
+ lda (font_ptr_lo),y
+ bit lo_nybble_flag
+ beq hi_nybble_even
+ asl
+ asl
+ asl
+ asl
+
+hi_nybble_even:
+ eor inverse_mask
+ and #$F0
+ sta TMPCHR
+ ldy scanline_offset_tab,x
+ lda (screen_ptr_lo),y
+ and #$0F
+ ora TMPCHR
+ sta (screen_ptr_lo),y
+ inx
+ cpx #$07
+ bne screen_ptr_ok_even
+ inc screen_ptr_hi
+
+screen_ptr_ok_even:
+ cpx #$08
+ beq write_font_done_even
+ txa
+ tay
+ bne get_font_nybble_even
+
+write_font_done_even:
+ rts
+
+; ----------------------------------------------------------------------------
+
+scanline_offset_tab:
+ .byte $00,$28,$50,$78,$A0,$C8,$F0,$18
+
+; ----------------------------------------------------------------------------
+; Callback for the internal get-one-byte, used by the OS to implement the
+; CIO GET RECORD and GET BYTES commands. This routine takes no arguments,
+; and returns the read byte in the accumulator.
+
+; Internally, COL80 maintains a line buffer. Each time col80_getbyte is
+; called, it returns the next character in the buffer. If the buffer's
+; empty (or if the last call returned the last character), a new line
+; of input is read from the user (and the first character is returned).
+; This is exactly how the OS E: device works.
+
+col80_getbyte:
+ lda BUFCNT
+ beq get_line
+
+get_next_byte:
+ ldx line_buffer_index
+ lda line_buffer,x
+ dec BUFCNT
+ inc line_buffer_index
+ jmp return_success
+
+; ----------------------------------------------------------------------------
+; Get a line of input from the user, terminated by the Return key.
+
+get_line:
+ lda #$00
+ sta BUFCNT
+ sta line_buffer_index
+
+show_cursor:
+; .ifdef FUJICHAT
+ lda #$00
+; .else
+; lda #$20
+; .endif
+ sta TMPCHR
+ lda #$FF
+ sta inverse_mask
+ jsr setup_font_ptr
+ jsr setup_screen_ptr
+ jsr write_font_data
+ jsr get_keystroke
+ cpy #$01
+ beq keystroke_ok
+; .ifdef FUJICHAT
+ dey ; yes, we really care about 1-byte optimizations
+; .else
+; ldy #$00
+; .endif
+ sty line_buffer_index
+ sty BUFCNT
+
+keystroke_ok:
+; .ifdef FUJICHAT
+ cmp #$20
+ bcc show_cursor ; ignore low ASCII
+; .endif
+ cmp #$9B
+ bne check_backs_key
+ jmp return_key_hit
+
+check_backs_key:
+ cmp #$7E
+ bne check_clear_key
+ jmp backs_key_hit
+
+check_clear_key:
+ cmp #$7D
+ bne normal_key_hit
+ jmp clear_key_hit
+
+normal_key_hit:
+ ldx BUFCNT
+ bpl buffer_character
+; .ifdef FUJICHAT
+ jmp show_cursor
+; .else
+; jmp beep
+; .endif
+
+buffer_character:
+ sta line_buffer,x
+ jsr col80_putbyte
+ inc BUFCNT
+ jmp show_cursor
+
+return_key_hit:
+ jsr print_space
+ lda #$9B
+ ldx BUFCNT
+ sta line_buffer,x
+ inc BUFCNT
+ jsr col80_putbyte
+ jmp get_next_byte
+
+clear_key_hit:
+; .ifndef FUJICHAT
+; jsr clear_screen
+; .endif
+ lda #$00
+ sta line_buffer_index
+ sta BUFCNT
+ jmp get_line
+
+backs_key_hit:
+ jsr print_space
+ lda BUFCNT
+ beq backs_key_done
+ dec COLCRS
+ lda COLCRS
+ clc
+ adc #$01
+ cmp LMARGN
+ bne backs_same_line
+ lda right_margin
+ sta COLCRS
+ dec ROWCRS
+
+backs_same_line:
+ dec BUFCNT
+
+backs_key_done:
+ jmp show_cursor
+
+; ----------------------------------------------------------------------------
+; Ring the margin bell. COL80 doesn't implement the ctrl-2 bell (character
+; 253), and instead of using the GTIA keyclick speaker, it uses POKEY to
+; make a beep
+
+;;; .ifndef FUJICHAT
+;;;beep: ldy #$00
+;;; ldx #$AF
+;;;
+;;;beep_delay_x:
+;;; stx AUDF1
+;;; stx AUDC1
+;;;
+;;;beep_delay_y:
+;;; dey
+;;; bne beep_delay_y
+;;; dex
+;;; cpx #$9F
+;;; bne beep_delay_x
+;;; jmp show_cursor
+;;; .endif
+
+; ----------------------------------------------------------------------------
+; Print a space character at the current cursor position. Does not
+; update the cursor position.
+print_space:
+ lda #$00
+ sta inverse_mask
+;;; .ifndef FUJICHAT
+;;; lda #$20
+;;; .endif
+ sta TMPCHR
+ jsr setup_font_ptr
+ jsr setup_screen_ptr
+ jsr write_font_data
+ rts
+
+; ----------------------------------------------------------------------------
+; Get a keystroke (blocking). Just calls the OS K: get-one-byte routine
+; (call by pushing address-minus-one then doing an RTS)
+get_keystroke:
+ lda k_dev_get_hi
+ pha
+ lda k_dev_get_lo
+ pha
+ rts
+
+; ----------------------------------------------------------------------------
+; COL80 vector table, in the format required by the OS. Our HATABS entry
+; will point to this table, and the OS will call the routines listed here
+; via the "call by RTS" method (which is why they're address-minus-one).
+
+; See the entry on HATABS in "Mapping the Atari" or the OS manual.
+
+col80_vector_tab:
+ .word col80_open-1
+ .word col80_close-1
+ .word col80_getbyte-1
+ .word col80_putbyte-1
+ .word col80_close-1
+ .word col80_close-1
+ jmp col80_init
+
+END_ADDRESS = *-1
+
+START_ADDRESS_2 = $03FD
+
+; xex segment header #2
+ .word START_ADDRESS_2
+ .word END_ADDRESS_2
+
+ .rorg START_ADDRESS_2
+
+; ----------------------------------------------------------------------------
+; Various bits of runtime state here. It's unclear to me why the standard
+; OS buffer location couldn't have been used instead (normally the top
+; half of page 5), or why the other stuff couldn't have been stored in
+; zero page, in locations used by the ROM E: handler (thus unused when
+; it's replaced with COL80). line_buffer_index needs to be preserved
+; across calls to col80_getbyte, but lo_nybble_flag and inverse_mask are
+; freshly calculated every time they're used, so they could be almost
+; anywhere.
+
+lo_nybble_flag:
+ .byte $00
+
+inverse_mask:
+ .byte $00
+
+line_buffer_index:
+ .byte $12
+
+
+; ----------------------------------------------------------------------------
+; Initialization callback. The OS will call this on coldstart (or would do,
+; if the driver were in ROM), and also on warmstart (because we stole the
+; DOSINI vector).
+; This routine is also the first thing that gets called by the mainline
+; init code. Its job is to install COL80 in the handler table at HATABS.
+; Actually the handler is first installed as X:, then the main init code
+; fixes this up to E: unless the user is holding down SELECT. This allows
+; the user to toggle between the 40-column ROM E: and COL80 without doing
+; a full reboot. No idea if this was a documented feature or something the
+; author used for development/debugging.
+
+; .ifdef FUJICHAT
+;col80_init = return_success
+; .else
+col80_init:
+ ldy #$00
+
+next_hatab_slot:
+ lda HATABS,y
+ beq register_x_handler
+ iny
+ iny
+ iny
+ cpy #$20
+ bcc next_hatab_slot
+ jmp return_success
+
+register_x_handler:
+ lda #$58
+ sta HATABS,y
+ lda #<col80_vector_tab
+ iny
+ sta HATABS,y
+ lda #>col80_vector_tab
+ iny
+ sta HATABS,y
+ jmp return_success
+; .endif
+
+; ----------------------------------------------------------------------------
+; The OS jumps here on warmstart (also, this is the run address in our
+; binary load file)
+
+dosini_entry_point:
+;;; .ifndef FUJICHAT
+;;; nop
+;;; nop
+;;; nop
+;;; .endif
+
+main_entry_point:
+;;; .ifndef FUJICHAT
+ jsr col80_init
+;;; lda CONSOL
+;;; and #$04
+;;; beq no_e_handler
+;;; .endif
+ lda #$0C
+ sta ICCOM
+ ldx #$00
+ jsr CIOV
+; .ifndef FUJICHAT ; note: will not work with BASIC! DOS/etc OK
+ lda #$58
+ sta font_ptr_lo
+ lda #$03
+ sta ICCOM
+ lda #font_ptr_lo
+ sta ICBAL
+ lda #$00
+ sta ICBAH
+ ldx #$00
+ jsr CIOV
+; .endif
+ ldy #$07
+ lda #<col80_vector_tab
+ sta HATABS,y
+ lda #>col80_vector_tab
+ iny
+ sta HATABS,y
+no_e_handler:
+ lda #<START_ADDRESS
+ sta MEMTOP
+ lda #>START_ADDRESS
+ sta MEMTOP+1
+ jmp return_success
+
+END_ADDRESS_2 = *-1
+
+; xex segment header #3
+ ;.word RUNAD
+ ;.word RUNAD+1
+ .word INITAD
+ .word INITAD+1
+ .word main_entry_point
+
+; ----------------------------------------------------------------------------
+; (when does this actually get called? da65 can't find any references
+; to it, and it's not a run or init address in the binary load file)
+;;; .ifndef FUJICHAT
+;;; lda #<dosini_entry_point
+;;; sta DOSINI
+;;; lda #>dosini_entry_point
+;;; sta DOSINI+1
+;;; jmp main_entry_point
+;;; .endif
+
+; ----------------------------------------------------------------------------
+; There's absolutely no reason why this data needs to be included in the
+; binary load file: the line buffer's initial contents are meaningless, they
+; will be blown away the first time anything reads from the E: device.
+
+; Notice the author was running his debugger in COL80 when he built the
+; binary (ASCII "S COL80 7A00 7F80" command still in the buffer).
+
+ ;.ifdef FUJICHAT
+
+line_buffer = $0400 ; cassette buffer
+
+ ;.else
+;line_buffer:
+ ;.byte $53,$20,$43,$4F,$4C,$38,$30,$20
+ ;.byte $37,$41,$30,$30,$20,$37,$46,$38
+ ;.byte $30,$9B,$20,$20,$20,$20,$9B,$27
+ ;.byte $40,$40,$40,$40,$28,$28,$28,$28
+ ;.byte $40,$40,$40,$40,$40,$40,$40,$40
+ ;.byte $40,$40,$40,$40,$40,$40,$40,$40
+ ;.byte $9B,$FD,$FD,$FD,$FD,$9B
+ ;.endif
+
+
+; I've found a variant (modified version?) of this code, that doesn't
+; include the line_buffer in the file (no reason for it to be there),
+; or the $0C segment, and that has another segment, loaded at $6000,
+; with the run address changed to $6000. The code looks like:
+
+; .org $6000
+; jsr dosini_entry_point
+; lda #$50
+; sta RMARGN
+; lda #$00
+; sta COLOR2
+
+; also, the default colors have been changed in init_graphics_8.
+
+; There are at least two binaries floating around that contain
+; extra (garbage) bytes at the end, presumably from being transferred
+; over XMODEM or similar. They are otherwise identical.
+