diff options
Diffstat (limited to 'src/col80_modified')
51 files changed, 4146 insertions, 0 deletions
diff --git a/src/col80_modified/Makefile b/src/col80_modified/Makefile new file mode 100644 index 0000000..4f3a9c6 --- /dev/null +++ b/src/col80_modified/Makefile @@ -0,0 +1,15 @@ + +all: col80_hacked.xex + +col80_hacked.xex: col80_hacked.dasm + dasm col80_hacked.dasm -ocol80_hacked.xex -f3 + binload -h col80_hacked.xex + +clean: + rm -f col80_hacked.xex + +test: + cp dos_20s.atr test.atr + cp col80_hacked.xex autorun.sys + axe -w autorun.sys test.atr + atari800 -nobasic test.atr diff --git a/src/col80_modified/autorun.sys b/src/col80_modified/autorun.sys Binary files differnew file mode 100644 index 0000000..bb432dd --- /dev/null +++ b/src/col80_modified/autorun.sys 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. + diff --git a/src/col80_modified/col80_hacked.xex b/src/col80_modified/col80_hacked.xex Binary files differnew file mode 100644 index 0000000..73ac7e3 --- /dev/null +++ b/src/col80_modified/col80_hacked.xex diff --git a/src/col80_modified/cruft/Makefile b/src/col80_modified/cruft/Makefile new file mode 100644 index 0000000..2152ced --- /dev/null +++ b/src/col80_modified/cruft/Makefile @@ -0,0 +1,45 @@ + +SRCFILES=col80_dosini_seg.s col80_header_seg.s col80_main.s \ + col80_runad_seg.s col80_startaddr.s + +all: cc65_hack + binload -h col80.xex + +cc65_hack: $(SRCFILES) col80.s + ca65 -t atari -DFUJICHAT col80.s + ld65 -C col80_cc65_hack.cfg -o col80_main.xex col80.o + ca65 -t atari -DFUJICHAT col80_startup.s + ld65 -o col80_startup.xex col80_startup.o + cat col80_main.xex col80_startup.xex > col80.xex + + +col80.xex: + $(MAKE) dasm_build || $(MAKE) ca65_build || $(MAKE) atasm_build + +dasm_build: $(SRCFILES) col80.dasm + dasm col80.dasm -f3 -ocol80.xex + +ca65_build: $(SRCFILES) col80.s + ca65 -t atari col80.s + ld65 -t atari -o col80.xex col80.o + +atasm_build: $(SRCFILES) col80.atasm + perl dasm2atasm col80_header_seg.s col80_header_seg.atasm + perl dasm2atasm col80_main.s col80_main.atasm + atasm -r -ocol80.xex col80.atasm + +check: col80.xex + @if cmp col80.xex col80_orig.xex; then \ + echo "OK: New binary is identical to original" ;\ + else \ + echo "BAD: New binary differs from original" ;\ + fi + +clean: + rm -f *.o col80_header_seg.atasm col80_main.atasm col80.xex + +test: + cp dos_20s.atr test.atr + cp col80.xex autorun.sys + axe -w autorun.sys test.atr + atari800 -nobasic test.atr diff --git a/src/col80_modified/cruft/README.txt b/src/col80_modified/cruft/README.txt new file mode 100644 index 0000000..720a1cc --- /dev/null +++ b/src/col80_modified/cruft/README.txt @@ -0,0 +1,89 @@ + +COL80 is a software 80-column driver for the Atari 8-bit computer. It +uses GRAPHICS 8 with 4x8 pixel character cells, and replaces the OS +ROM's E: handler. + +The file is found in various Atari archives, under various names such +as COL80.COM, COL80E.COM, COL80HND.COM. The original author and date of +publication are unknown. + +I've disassembled the binary and labelled/commented the source with +(hopefully) meaningful names. The resulting sources can be reassembled +with the DASM, ca65, or Atasm assemblers, which will result in a binary +that compares as identical to the original. + +If you have one of the supported assemblers available on your path, +plus a "make" utility (GNU, BSD, or probably Microsoft's nmake are OK), +you can use the provided Makefile to rebuild the binary (including your +own modified version, if you're into that sort of thing). + +File list: + +README.txt - you're reading it now + +Makefile - the usual + +col80_main.s - The actual source code for COL80 + +col80_dosini_seg.s, col80_header_seg.s, col80_runad_seg.s, and +col80_startaddr.s - Include files, used to build the multi-segment Atari +binary load format object file. + +col80.s, col80.dasm, col80.atasm - Top-level wrappers for the various +assemblers, which include the other files in the proper order and using +the proper syntax for the assembler being used. + +Modification Ideas: + +Implement the missing control character actions. COL80 only does EOL and +the clear-screen code (125), and the others (arrows, delete/insert/bell) +are just printed in their graphical form. + +The original COL80 loads the driver code at $7A00, so it'll be compatible +with BASIC, or other cartridge software. I've built a version org'ed at +$9A00, which works great with disk-only software and gives an extra 8K +of available RAM (change START_ADDR in col80_startaddr.s). + +It should be possible to use 4x7 or 4x6 character cells instead of +4x8. The font would of course need to be redesigned, and the characters +would be even smaller than they are now, but this would give you 27 or +32 rows of text on screen (or more, if you expand the display by a few +scanlines). With a good green or amber monitor and luma-only output, +this could be usable. + +Instead of inverse video for characters 128-255, could do an expanded +international character set (ISO Latin-1). Add a UTF-8 parser and you've +got Unicode on the Atari! + +Add a VT100/ANSI escape-sequence parser. Could render actual underlined +characters, and bold as inverse video. ANSI color codes we can't easily +do, but could at least strip them out. + +Squeeze the driver down to save RAM. Use the standard E: buffer in page 5, +move the code up so it ends just before the GR.8 display list, eliminate +the code that installs the handler as X: and checks for the SELECT key +being held down... get rid of the margin beep. Use RMARGN in zero page +instead of right_margin at $7C00, move the other COL80 variables to +page zero. Eliminate the lookup tables, if they can be replaced with +code that takes up less space and calculates the values on the fly. +The current driver code is 3 pages long; it might be possible to squish +it into 2 pages... like, say, page 6 and the cassette buffer, or make it +auto-relocate itself to MEMLO like Bob-Verter does. Using a 4x6 or 4x7 +font shrinks the font table, too... another thing to do would be to get +rid of the clear_screen routine (replace with a call to init_graphics_8) + +For XL/XE machines, turn COL80 into an OS patch. For modified 400/800 +machines with RAM at $C000-CFFF, move COL80 there. For 130XEs, use an +extended RAM bank for the driver, and another bank for the screen RAM +(separate ANTIC/CPU access mode, won't work on most upgraded 800XLs). Just +keep a tiny stub driver in main RAM, that switches in the driver's bank +and jumps to it. + +Make a COL64 driver (like the SpartaDOS X CON64.SYS). Use 5x8 characters +for 64 columns (or 5x6 for 64x32). Probably this would count more as +a rewrite than a modification. The font would have to be stored one +character per 8 bytes (take up twice as much space), and lots of shifting +would have to happen when writing to the screen (slow)... Could also +do 56 columns (7 pixel wide), and actually use the ROM font (just cut +off the high bit, and for 56x27 also cut off the bottom scanline). + diff --git a/src/col80_modified/cruft/autorun.sys b/src/col80_modified/cruft/autorun.sys Binary files differnew file mode 100644 index 0000000..e62d76d --- /dev/null +++ b/src/col80_modified/cruft/autorun.sys diff --git a/src/col80_modified/cruft/col80.atasm b/src/col80_modified/cruft/col80.atasm new file mode 100644 index 0000000..3fdd27a --- /dev/null +++ b/src/col80_modified/cruft/col80.atasm @@ -0,0 +1,6 @@ + + .include "col80_startaddr.s" + .include "col80_header_seg.atasm" + .include "col80_main.atasm" + .include "col80_dosini_seg.s" + .include "col80_runad_seg.s" diff --git a/src/col80_modified/cruft/col80.dasm b/src/col80_modified/cruft/col80.dasm new file mode 100644 index 0000000..b3a1de2 --- /dev/null +++ b/src/col80_modified/cruft/col80.dasm @@ -0,0 +1,10 @@ + + processor 6502 ; dasm + + .include col80_startaddr.s + .include col80_header_seg.s + .include col80_main.s + .include col80_dosini_seg.s + + .include col80_runad_seg.s + diff --git a/src/col80_modified/cruft/col80.info b/src/col80_modified/cruft/col80.info new file mode 100644 index 0000000..ad821a4 --- /dev/null +++ b/src/col80_modified/cruft/col80.info @@ -0,0 +1,152 @@ +global { + comments 4; + inputname "col80e.raw"; + outputname "col80e.dasm"; + startaddr $7A00; +}; + +range { + start $7A00; + end $7BFF; + type bytetable; +}; + +range { + start $7F48; + end $7F80; + type bytetable; +}; + +range { + start $7D52; + end $7D81; + type bytetable; +}; + +range { + start $7DEA; + end $7DF0; + type bytetable; +}; + +range { + start $7EE5; + end $7EF0; + type addrtable; +}; + +LABEL { NAME "s_dev_open_lo"; ADDR $E410; }; +LABEL { NAME "s_dev_open_hi"; ADDR $E411; }; + +LABEL { NAME "k_dev_get_lo"; ADDR $E424; }; +LABEL { NAME "k_dev_get_hi"; ADDR $E425; }; + +LABEL { NAME "DOSINI"; ADDR $0C; }; +LABEL { NAME "DOSINI+1"; ADDR $0D; }; +LABEL { NAME "TMPCHR"; ADDR $50; }; +LABEL { NAME "LMARGN"; ADDR $52; }; +LABEL { NAME "DINDEX"; ADDR $57; }; +LABEL { NAME "SAVMSC"; ADDR $58; }; +LABEL { NAME "SAVMSC+1"; ADDR $59; }; +LABEL { NAME "ICAX1Z"; ADDR $2A; }; +LABEL { NAME "ICAX2Z"; ADDR $2B; }; +LABEL { NAME "ROWCRS"; ADDR $54; }; +LABEL { NAME "COLCRS"; ADDR $55; }; +LABEL { NAME "BUFCNT"; ADDR $6B; }; +LABEL { NAME "SSFLAG"; ADDR $02FF; }; +LABEL { NAME "HATABS"; ADDR $031A; }; +LABEL { NAME "CIOV"; ADDR $E456; }; +LABEL { NAME "CONSOL"; ADDR $D01F; }; +LABEL { NAME "AUDF1"; ADDR $D200; }; +LABEL { NAME "AUDC1"; ADDR $D201; }; +LABEL { NAME "ICCOM"; ADDR $0342; }; +LABEL { NAME "ICBAL"; ADDR $0344; }; +LABEL { NAME "ICBAH"; ADDR $0345; }; +LABEL { NAME "COLOR1"; ADDR $02C5; }; +LABEL { NAME "COLOR2"; ADDR $02C6; }; +LABEL { NAME "MEMTOP"; ADDR $02E5; }; +LABEL { NAME "MEMTOP+1"; ADDR $02E6; }; + +LABEL { NAME "col80e_vector_tab"; ADDR $7EE5; }; +LABEL { NAME "col80e_open-1"; ADDR $7C00; }; +LABEL { NAME "col80e_open"; ADDR $7C01; }; +LABEL { NAME "col80e_close-1"; ADDR $7C3F; }; +LABEL { NAME "col80e_close"; ADDR $7C40; }; +LABEL { NAME "col80e_getbyte-1"; ADDR $7DF1; }; +LABEL { NAME "col80e_getbyte"; ADDR $7DF2; }; +LABEL { NAME "col80e_putbyte-1"; ADDR $7C42; }; +LABEL { NAME "col80e_putbyte"; ADDR $7C43; }; +LABEL { NAME "col80e_init"; ADDR $7EC0; }; + +LABEL { NAME "screen_ptr_lo"; ADDR $CB; }; +LABEL { NAME "screen_ptr_hi"; ADDR $CC; }; +LABEL { NAME "font_ptr_lo"; ADDR $CD; }; +LABEL { NAME "font_ptr_hi"; ADDR $CE; }; + +LABEL { NAME "font_data"; ADDR $7A00; }; +LABEL { NAME "lo_nybble_flag"; ADDR $7F48; }; + +LABEL { NAME "clear_screen"; ADDR $7D0B; }; +LABEL { NAME "regular_char"; ADDR $7C56; }; +LABEL { NAME "check_ssflag"; ADDR $7C7F; }; +LABEL { NAME "dosini_entry_point"; ADDR $7EF4; }; +LABEL { NAME "main_entry_point"; ADDR $7EF7; }; +LABEL { NAME "get_keystroke"; ADDR $7EB7; }; +LABEL { NAME "return_success"; ADDR $7D31; }; +LABEL { NAME "inverse_mask"; ADDR $7F49; }; +LABEL { NAME "not_inverse"; ADDR $7C60; }; +LABEL { NAME "open_s_dev"; ADDR $7C37; }; +LABEL { NAME "init_graphics_8"; ADDR $7C14; }; +LABEL { NAME "not_eol"; ADDR $7C4F; }; +LABEL { NAME "graphics_ok"; ADDR $7C73; }; +LABEL { NAME "setup_screen_ptr"; ADDR $7D34; }; +LABEL { NAME "setup_font_ptr"; ADDR $7CC9; }; +LABEL { NAME "hi_byte_ok"; ADDR $7D4F; }; +LABEL { NAME "row_low_offset_tab"; ADDR $7D52; }; +LABEL { NAME "row_high_offset_tab"; ADDR $7D6A; }; +LABEL { NAME "cls_loop"; ADDR $7D19; }; +LABEL { NAME "write_font_data_odd"; ADDR $7D82; }; +LABEL { NAME "write_font_data_even"; ADDR $7DB9; }; +LABEL { NAME "scroll_screen"; ADDR $7C87; }; +LABEL { NAME "advance_cursor"; ADDR $7CEE; }; +LABEL { NAME "skip_write"; ADDR $7C7C; }; +LABEL { NAME "skip_ninv"; ADDR $7C65; }; +LABEL { NAME "lo_nybble_odd"; ADDR $7D97; }; +LABEL { NAME "hi_nybble_even"; ADDR $7DC8; }; +LABEL { NAME "write_font_done_odd"; ADDR $7DB8; }; +LABEL { NAME "get_font_nybble_odd"; ADDR $7D8C; }; +LABEL { NAME "get_font_nybble_even"; ADDR $7DBD; }; +LABEL { NAME "screen_ptr_ok_odd"; ADDR $7DB0; }; +LABEL { NAME "screen_ptr_ok_even"; ADDR $7DE1; }; +LABEL { NAME "write_font_done_even"; ADDR $7DE9; }; +LABEL { NAME "scanline_offset_tab"; ADDR $7DEA; }; +LABEL { NAME "get_line"; ADDR $7E04; }; +LABEL { NAME "line_buffer_index"; ADDR $7F4A; }; +LABEL { NAME "line_buffer"; ADDR $7F4B; }; +LABEL { NAME "get_next_byte"; ADDR $7DF6; }; +LABEL { NAME "show_cursor"; ADDR $7E0B; }; +LABEL { NAME "keystroke_ok"; ADDR $7E2B; }; +LABEL { NAME "return_key_hit"; ADDR $7E52; }; +LABEL { NAME "check_backs_key"; ADDR $7E32; }; +LABEL { NAME "backs_key_hit"; ADDR $7E71; }; +LABEL { NAME "check_clear_key"; ADDR $7E39; }; +LABEL { NAME "clear_key_hit"; ADDR $7E64; }; +LABEL { NAME "normal_key_hit"; ADDR $7E40; }; +LABEL { NAME "beep"; ADDR $7E8F; }; +LABEL { NAME "beep_delay_x"; ADDR $7E93; }; +LABEL { NAME "beep_delay_y"; ADDR $7E99; }; +LABEL { NAME "buffer_character"; ADDR $7E47; }; +LABEL { NAME "print_space"; ADDR $7EA4; }; +LABEL { NAME "backs_key_done"; ADDR $7E8C; }; +LABEL { NAME "same_line"; ADDR $7E8A; }; +LABEL { NAME "next_hatab_slot"; ADDR $7EC2; }; +LABEL { NAME "register_x_handler"; ADDR $7ED1; }; +LABEL { NAME "no_e_handler"; ADDR $7F30; }; +LABEL { NAME "no_scroll"; ADDR $7D08; }; +LABEL { NAME "next_line"; ADDR $7D0A; }; +LABEL { NAME "font_hi_nybble"; ADDR $7CDB; }; +LABEL { NAME "scroll_line_loop"; ADDR $7C9C; }; +LABEL { NAME "blank_bottom_row"; ADDR $7CAA; }; +LABEL { NAME "blank_loop"; ADDR $7CBA; }; +LABEL { NAME "blank_tail"; ADDR $7CC3; }; + diff --git a/src/col80_modified/cruft/col80.s b/src/col80_modified/cruft/col80.s new file mode 100644 index 0000000..334082a --- /dev/null +++ b/src/col80_modified/cruft/col80.s @@ -0,0 +1,21 @@ + +; ca65 wrapper for building col80 + + .setcpu "6502" + + .segment "EXEHDR" + .include "col80_startaddr.s" + .include "col80_header_seg.s" + + .segment "CODE" + .include "col80_main.s" + + .ifndef FUJICHAT + .include "col80_dosini_seg.s" + + .segment "AUTOSTRT" + .include "col80_runad_seg.s" + .endif + + .segment "ZPSAVE" + ; nothing to see here, just shutting up ld65's warning diff --git a/src/col80_modified/cruft/col80.xex b/src/col80_modified/cruft/col80.xex Binary files differnew file mode 100644 index 0000000..5872c7f --- /dev/null +++ b/src/col80_modified/cruft/col80.xex diff --git a/src/col80_modified/cruft/col80_cc65_hack.cfg b/src/col80_modified/cruft/col80_cc65_hack.cfg new file mode 100644 index 0000000..82b2c25 --- /dev/null +++ b/src/col80_modified/cruft/col80_cc65_hack.cfg @@ -0,0 +1,41 @@ +FEATURES { + STARTADDRESS: default = $2E00; +} +SYMBOLS { + __STACKSIZE__ = $800; # 2K stack + __RESERVED_MEMORY__: value = $0, weak = yes; +} +MEMORY { + ZP: start = $0082, size = $007E, type = rw, define = yes; + HEADER: start = $0000, size = $0006, file = %O; + RAM: start = %S, size = $BC20 - __STACKSIZE__ - %S, file = %O; + TRAILER: start = $0000, size = $0006, file = %O; +} +SEGMENTS { + EXEHDR: load = HEADER, type = ro; + LOWCODE: load = RAM, type = ro, define = yes, optional = yes; + INIT: load = RAM, type = ro, optional = yes; + CODE: load = RAM, type = ro, define = yes; + RODATA: load = RAM, type = ro; + DATA: load = RAM, type = rw; + ZPSAVE: load = RAM, type = bss, define = yes; + BSS: load = RAM, type = bss, define = yes; + HEAP: load = RAM, type = bss, optional = yes; # must sit just below stack + ZEROPAGE: load = ZP, type = zp, optional = yes; + EXTZP: load = ZP, type = zp, optional = yes; + AUTOSTRT: load = TRAILER, type = ro, optional = yes; +} +FEATURES { + CONDES: segment = INIT, + type = constructor, + label = __CONSTRUCTOR_TABLE__, + count = __CONSTRUCTOR_COUNT__; + CONDES: segment = RODATA, + type = destructor, + label = __DESTRUCTOR_TABLE__, + count = __DESTRUCTOR_COUNT__; + CONDES: type = interruptor, + segment = RODATA, + label = __INTERRUPTOR_TABLE__, + count = __INTERRUPTOR_COUNT__; +} diff --git a/src/col80_modified/cruft/col80_dosini_seg.s b/src/col80_modified/cruft/col80_dosini_seg.s new file mode 100644 index 0000000..d92e7ed --- /dev/null +++ b/src/col80_modified/cruft/col80_dosini_seg.s @@ -0,0 +1,12 @@ + +; Second segment of the file loads at $0C (aka DOSINI), and just contains +; the address of dosini_entry_point + + .ifndef FUJICHAT + .word $FFFF ; unnecessary, though the original file had it + .endif + + .word $000C ; DOSINI + .word $000D + .word dosini_entry_point + diff --git a/src/col80_modified/cruft/col80_entry.s b/src/col80_modified/cruft/col80_entry.s new file mode 100644 index 0000000..edf0d96 --- /dev/null +++ b/src/col80_modified/cruft/col80_entry.s @@ -0,0 +1,61 @@ +; ---------------------------------------------------------------------------- +; 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: + jsr col80_init + .ifndef FUJICHAT + lda CONSOL + and #$04 + beq no_e_handler + .endif + lda #$0C + sta ICCOM + ldx #$00 + jsr CIOV + lda #$58 + sta font_ptr_lo + lda #$03 + sta ICCOM + lda #font_ptr_lo + sta ICBAL + lda #$00 + sta ICBAH + ldx #$00 + jsr CIOV + 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 + .ifdef FUJICHAT + ldy #$01 + rts + .else + jmp return_success + .endif + +; ---------------------------------------------------------------------------- +; (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 + diff --git a/src/col80_modified/cruft/col80_header_seg.s b/src/col80_modified/cruft/col80_header_seg.s new file mode 100644 index 0000000..2f96ad9 --- /dev/null +++ b/src/col80_modified/cruft/col80_header_seg.s @@ -0,0 +1,6 @@ + + .org START_ADDRESS-6 + .word $FFFF + .word START_ADDRESS + .word END_ADDRESS + diff --git a/src/col80_modified/cruft/col80_include.s b/src/col80_modified/cruft/col80_include.s new file mode 100644 index 0000000..943c579 --- /dev/null +++ b/src/col80_modified/cruft/col80_include.s @@ -0,0 +1,50 @@ +; ---------------------------------------------------------------------------- +; 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 +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 diff --git a/src/col80_modified/cruft/col80_init.s b/src/col80_modified/cruft/col80_init.s new file mode 100644 index 0000000..89ccf75 --- /dev/null +++ b/src/col80_modified/cruft/col80_init.s @@ -0,0 +1,35 @@ +; ---------------------------------------------------------------------------- +; 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. + +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 diff --git a/src/col80_modified/cruft/col80_main.s b/src/col80_modified/cruft/col80_main.s new file mode 100644 index 0000000..0ced210 --- /dev/null +++ b/src/col80_modified/cruft/col80_main.s @@ -0,0 +1,824 @@ +; 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). + + + .include "col80_include.s" + +; START_ADDRESS is defined in col80_startaddr.s + .org START_ADDRESS + +; ---------------------------------------------------------------------------- +; 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: + .ifdef FUJICHAT + .include "new_font.s" + .else + ; Low ATASCII graphics symbols (code 0-31) + .byte $04,$04,$A4,$E4,$E7,$44,$04,$04 + .byte $14,$14,$14,$14,$1C,$10,$10,$10 + .byte $40,$40,$40,$40,$CC,$44,$44,$44 + .byte $18,$18,$24,$24,$42,$42,$81,$81 + .byte $10,$10,$30,$30,$73,$73,$F3,$F3 + .byte $83,$83,$C3,$C3,$E0,$E0,$F0,$F0 + .byte $CF,$CF,$C0,$C0,$00,$00,$00,$00 + .byte $00,$00,$00,$00,$0C,$0C,$FC,$FC + .byte $00,$00,$00,$40,$A7,$44,$E4,$04 + .byte $04,$04,$04,$04,$FF,$04,$04,$04 + .byte $00,$00,$60,$F0,$FF,$6F,$0F,$0F + .byte $80,$80,$80,$80,$8F,$84,$84,$84 + .byte $4C,$4C,$4C,$4C,$FC,$0C,$0C,$0C + .byte $40,$4C,$48,$4C,$78,$0C,$06,$00 + .byte $00,$44,$E4,$44,$4E,$44,$00,$00 + .byte $00,$24,$42,$FF,$42,$24,$00,$00 + + ; Space ! " # etc (codes 32-63) + .byte $00,$04,$04,$04,$04,$00,$04,$00 + .byte $00,$A0,$AA,$AE,$0A,$0E,$0A,$00 + .byte $00,$40,$68,$82,$44,$28,$C2,$40 + .byte $00,$C4,$64,$E4,$60,$C0,$40,$00 + .byte $00,$44,$82,$82,$82,$82,$82,$44 + .byte $00,$04,$A4,$4E,$E4,$44,$A0,$00 + .byte $00,$00,$00,$0E,$00,$40,$40,$80 + .byte $00,$02,$02,$04,$04,$08,$48,$00 + .byte $00,$E4,$AC,$A4,$A4,$A4,$EE,$00 + .byte $00,$EE,$22,$22,$EE,$82,$EE,$00 + .byte $00,$AE,$A8,$AE,$E2,$22,$2E,$00 + .byte $00,$EE,$82,$E2,$A4,$A4,$E4,$00 + .byte $00,$EE,$AA,$EA,$AE,$A2,$EE,$00 + .byte $00,$00,$00,$44,$00,$44,$04,$08 + .byte $00,$20,$4E,$80,$4E,$20,$00,$00 + .byte $00,$8C,$42,$22,$44,$80,$04,$00 + + ; @ A B C etc (codes 64-95) + .byte $00,$6E,$9A,$BA,$BE,$8A,$6A,$00 + .byte $00,$C6,$A8,$C8,$A8,$A8,$C6,$00 + .byte $00,$CE,$A8,$AC,$A8,$A8,$CE,$00 + .byte $00,$E6,$88,$C8,$8A,$8A,$86,$00 + .byte $00,$AE,$A4,$E4,$A4,$A4,$AE,$00 + .byte $00,$2A,$2A,$2C,$2A,$2A,$CA,$00 + .byte $00,$8A,$8E,$8E,$8A,$8A,$EA,$00 + .byte $00,$C4,$AA,$AA,$AA,$AA,$A4,$00 + .byte $00,$EE,$AA,$EA,$8A,$8A,$8E,$03 + .byte $00,$C6,$A8,$AC,$C2,$A2,$AC,$00 + .byte $00,$EA,$4A,$4A,$4A,$4A,$4E,$00 + .byte $00,$AA,$AA,$AA,$AE,$AE,$4A,$00 + .byte $00,$AA,$4A,$4E,$44,$44,$A4,$00 + .byte $00,$EE,$28,$48,$88,$88,$E8,$0E + .byte $00,$8E,$82,$42,$42,$22,$22,$0E + .byte $00,$00,$40,$A0,$00,$00,$00,$0F + + ; diamond, lowercase letters, control codes (codes 96-127) + .byte $00,$00,$00,$46,$E2,$4E,$0E,$00 + .byte $00,$80,$80,$C6,$A8,$A8,$C6,$00 + .byte $00,$20,$20,$6E,$AE,$A8,$6E,$00 + .byte $00,$00,$C0,$86,$CA,$8E,$82,$0C + .byte $00,$80,$84,$80,$C4,$A4,$A4,$00 + .byte $00,$08,$28,$0A,$2C,$2A,$2A,$C0 + .byte $00,$40,$40,$4A,$4E,$4A,$4A,$00 + .byte $00,$00,$00,$CE,$AA,$AA,$AE,$00 + .byte $00,$00,$00,$C6,$AA,$C6,$82,$82 + .byte $00,$00,$00,$6E,$88,$86,$8E,$00 + .byte $00,$00,$40,$EA,$4A,$4A,$6E,$00 + .byte $00,$00,$00,$AA,$AA,$AE,$4A,$00 + .byte $00,$00,$00,$AA,$4A,$A6,$A2,$0C + .byte $00,$00,$04,$EE,$4E,$84,$EE,$00 + .byte $40,$4E,$4C,$4E,$4A,$42,$42,$40 + .byte $00,$28,$6C,$EE,$6C,$28,$00,$00 + .endif + +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 + .ifndef FUJICHAT + nop + nop + .endif + 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 + .ifndef FUJICHAT + nop + nop + nop + .endif + 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 + 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 + + .ifndef FUJICHAT + .include "col80_init.s" + .endif + +; ---------------------------------------------------------------------------- +; 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 + .ifdef FUJICHAT + .byte 0, 0, 0 ; heh. + .else + jmp col80_init + .endif + + .ifndef FUJICHAT + .include "col80_entry.s" + .endif + +; ---------------------------------------------------------------------------- +; 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. + + .ifdef FUJICHAT + .segment "CODE" + .endif + +lo_nybble_flag: + .byte $00 + +inverse_mask: + .byte $00 + +line_buffer_index: + .byte $12 + +; ---------------------------------------------------------------------------- +; 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 = $03FD ; 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 + +END_ADDRESS = *-1 + +; 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. + diff --git a/src/col80_modified/cruft/col80_main.s.orig b/src/col80_modified/cruft/col80_main.s.orig new file mode 100644 index 0000000..0b56ee3 --- /dev/null +++ b/src/col80_modified/cruft/col80_main.s.orig @@ -0,0 +1,895 @@ +; 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). + + +; START_ADDRESS is defined in col80_startaddr.s + .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 +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: + ; Low ATASCII graphics symbols (code 0-31) + .byte $04,$04,$A4,$E4,$E7,$44,$04,$04 ; 7A00 + .byte $14,$14,$14,$14,$1C,$10,$10,$10 ; 7A08 + .byte $40,$40,$40,$40,$CC,$44,$44,$44 ; 7A10 + .byte $18,$18,$24,$24,$42,$42,$81,$81 ; 7A18 + .byte $10,$10,$30,$30,$73,$73,$F3,$F3 ; 7A20 + .byte $83,$83,$C3,$C3,$E0,$E0,$F0,$F0 ; 7A28 + .byte $CF,$CF,$C0,$C0,$00,$00,$00,$00 ; 7A30 + .byte $00,$00,$00,$00,$0C,$0C,$FC,$FC ; 7A38 + .byte $00,$00,$00,$40,$A7,$44,$E4,$04 ; 7A40 + .byte $04,$04,$04,$04,$FF,$04,$04,$04 ; 7A48 + .byte $00,$00,$60,$F0,$FF,$6F,$0F,$0F ; 7A50 + .byte $80,$80,$80,$80,$8F,$84,$84,$84 ; 7A58 + .byte $4C,$4C,$4C,$4C,$FC,$0C,$0C,$0C ; 7A60 + .byte $40,$4C,$48,$4C,$78,$0C,$06,$00 ; 7A68 + .byte $00,$44,$E4,$44,$4E,$44,$00,$00 ; 7A70 + .byte $00,$24,$42,$FF,$42,$24,$00,$00 ; 7A78 + + ; Space ! " # etc (codes 32-63) + .byte $00,$04,$04,$04,$04,$00,$04,$00 ; 7A80 + .byte $00,$A0,$AA,$AE,$0A,$0E,$0A,$00 ; 7A88 + .byte $00,$40,$68,$82,$44,$28,$C2,$40 ; 7A90 + .byte $00,$C4,$64,$E4,$60,$C0,$40,$00 ; 7A98 + .byte $00,$44,$82,$82,$82,$82,$82,$44 ; 7AA0 + .byte $00,$04,$A4,$4E,$E4,$44,$A0,$00 ; 7AA8 + .byte $00,$00,$00,$0E,$00,$40,$40,$80 ; 7AB0 + .byte $00,$02,$02,$04,$04,$08,$48,$00 ; 7AB8 + .byte $00,$E4,$AC,$A4,$A4,$A4,$EE,$00 ; 7AC0 + .byte $00,$EE,$22,$22,$EE,$82,$EE,$00 ; 7AC8 + .byte $00,$AE,$A8,$AE,$E2,$22,$2E,$00 ; 7AD0 + .byte $00,$EE,$82,$E2,$A4,$A4,$E4,$00 ; 7AD8 + .byte $00,$EE,$AA,$EA,$AE,$A2,$EE,$00 ; 7AE0 + .byte $00,$00,$00,$44,$00,$44,$04,$08 ; 7AE8 + .byte $00,$20,$4E,$80,$4E,$20,$00,$00 ; 7AF0 + .byte $00,$8C,$42,$22,$44,$80,$04,$00 ; 7AF8 + + ; @ A B C etc (codes 64-95) + .byte $00,$6E,$9A,$BA,$BE,$8A,$6A,$00 ; 7B00 + .byte $00,$C6,$A8,$C8,$A8,$A8,$C6,$00 ; 7B08 + .byte $00,$CE,$A8,$AC,$A8,$A8,$CE,$00 ; 7B10 + .byte $00,$E6,$88,$C8,$8A,$8A,$86,$00 ; 7B18 + .byte $00,$AE,$A4,$E4,$A4,$A4,$AE,$00 ; 7B20 + .byte $00,$2A,$2A,$2C,$2A,$2A,$CA,$00 ; 7B28 + .byte $00,$8A,$8E,$8E,$8A,$8A,$EA,$00 ; 7B30 + .byte $00,$C4,$AA,$AA,$AA,$AA,$A4,$00 ; 7B38 + .byte $00,$EE,$AA,$EA,$8A,$8A,$8E,$03 ; 7B40 + .byte $00,$C6,$A8,$AC,$C2,$A2,$AC,$00 ; 7B48 + .byte $00,$EA,$4A,$4A,$4A,$4A,$4E,$00 ; 7B50 + .byte $00,$AA,$AA,$AA,$AE,$AE,$4A,$00 ; 7B58 + .byte $00,$AA,$4A,$4E,$44,$44,$A4,$00 ; 7B60 + .byte $00,$EE,$28,$48,$88,$88,$E8,$0E ; 7B68 + .byte $00,$8E,$82,$42,$42,$22,$22,$0E ; 7B70 + .byte $00,$00,$40,$A0,$00,$00,$00,$0F ; 7B78 + + ; diamond, lowercase letters, control codes (codes 96-127) + .byte $00,$00,$00,$46,$E2,$4E,$0E,$00 ; 7B80 + .byte $00,$80,$80,$C6,$A8,$A8,$C6,$00 ; 7B88 + .byte $00,$20,$20,$6E,$AE,$A8,$6E,$00 ; 7B90 + .byte $00,$00,$C0,$86,$CA,$8E,$82,$0C ; 7B98 + .byte $00,$80,$84,$80,$C4,$A4,$A4,$00 ; 7BA0 + .byte $00,$08,$28,$0A,$2C,$2A,$2A,$C0 ; 7BA8 + .byte $00,$40,$40,$4A,$4E,$4A,$4A,$00 ; 7BB0 + .byte $00,$00,$00,$CE,$AA,$AA,$AE,$00 ; 7BB8 + .byte $00,$00,$00,$C6,$AA,$C6,$82,$82 ; 7BC0 + .byte $00,$00,$00,$6E,$88,$86,$8E,$00 ; 7BC8 + .byte $00,$00,$40,$EA,$4A,$4A,$6E,$00 ; 7BD0 + .byte $00,$00,$00,$AA,$AA,$AE,$4A,$00 ; 7BD8 + .byte $00,$00,$00,$AA,$4A,$A6,$A2,$0C ; 7BE0 + .byte $00,$00,$04,$EE,$4E,$84,$EE,$00 ; 7BE8 + .byte $40,$4E,$4C,$4E,$4A,$42,$42,$40 ; 7BF0 + .byte $00,$28,$6C,$EE,$6C,$28,$00,$00 ; 7BF8 + +right_margin: + ; Default value is 79 decimal. Unsure why the author didn't use RMARGN at $53 + .byte $4F ; 7C00 4F + +; ---------------------------------------------------------------------------- +; Start of COL80 code. + +; Callback for CIO OPEN command. + +col80_open: + jsr init_graphics_8 ; 7C01 20 14 7C + lda #$00 ; 7C04 A9 00 + sta ROWCRS ; 7C06 85 54 + sta COLCRS ; 7C08 85 55 + nop ; 7C0A EA + nop ; 7C0B EA + sta BUFCNT ; 7C0C 85 6B + lda #$4F ; 7C0E A9 4F + sta right_margin ; 7C10 8D 00 7C + rts ; 7C13 60 + +; ---------------------------------------------------------------------------- +; Assembly version of GRAPHICS 8+16 command. + +init_graphics_8: + lda #$08 ; 7C14 A9 08 + sta ICAX2Z ; 7C16 85 2B + lda #$0C ; 7C18 A9 0C + sta ICAX1Z ; 7C1A 85 2A + jsr open_s_dev ; 7C1C 20 37 7C + + ; Set COL80's default colors + lda #$08 ; 7C1F A9 08 + sta COLOR2 ; 7C21 8D C6 02 + nop ; 7C24 EA + nop ; 7C25 EA + nop ; 7C26 EA + lda #$00 ; 7C27 A9 00 + sta COLOR1 ; 7C29 8D C5 02 + + ; Protect ourselves from BASIC and the OS + lda #<START_ADDRESS ; 7C2C A9 00 + sta MEMTOP ; 7C2E 8D E5 02 + lda #>START_ADDRESS ; 7C31 A9 7A + sta MEMTOP+1 ; 7C33 8D E6 02 + rts ; 7C36 60 + +; ---------------------------------------------------------------------------- +; 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 ; 7C37 AD 11 E4 + pha ; 7C3A 48 + lda s_dev_open_lo ; 7C3B AD 10 E4 + pha ; 7C3E 48 + rts ; 7C3F 60 + +; ---------------------------------------------------------------------------- +; 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 ; 7C43 C9 9B + bne check_clear ; 7C45 D0 08 + lda right_margin ; 7C47 AD 00 7C + sta COLCRS ; 7C4A 85 55 + jmp skip_write ; 7C4C 4C 7C 7C + +check_clear: + ; Clear (decimal 125)? + cmp #$7D ; 7C4F C9 7D + bne regular_char ; 7C51 D0 03 + jmp clear_screen ; 7C53 4C 0B 7D + + ; See if this is an inverse video char (code >= 128) +regular_char: + tax ; 7C56 AA + bpl not_inverse ; 7C57 10 07 + lda #$FF ; 7C59 A9 FF + sta inverse_mask ; 7C5B 8D 49 7F + bne skip_ninv ; 7C5E D0 05 + +not_inverse: + lda #$00 ; 7C60 A9 00 + sta inverse_mask ; 7C62 8D 49 7F + +skip_ninv: + txa ; 7C65 8A + and #$7F ; 7C66 29 7F + sta TMPCHR ; 7C68 85 50 + lda DINDEX ; 7C6A A5 57 + cmp #$08 ; 7C6C C9 08 + beq graphics_ok ; 7C6E F0 03 + ; If we're not in GRAPHICS 8 mode, reinitialize ourselves + jsr col80_open ; 7C70 20 01 7C + +graphics_ok: + ; Call the routines that actually print the character + jsr setup_font_ptr ; 7C73 20 C9 7C + jsr setup_screen_ptr ; 7C76 20 34 7D + jsr write_font_data ; 7C79 20 82 7D + +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 ; 7C7C 20 EE 7C + +check_ssflag: + ; The OS keyboard interrupt handler will toggle SSFLAG (start/stop fla + ; any time the user presses ctrl-1 + lda SSFLAG ; 7C7F AD FF 02 + bne check_ssflag ; 7C82 D0 FB + jmp return_success ; 7C84 4C 31 7D + +; ---------------------------------------------------------------------------- +; 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 ; 7C87 A5 58 + sta screen_ptr_lo ; 7C89 85 CB + clc ; 7C8B 18 + adc #$40 ; 7C8C 69 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 ; 7C8E 85 CD + lda SAVMSC+1 ; 7C90 A5 59 + sta screen_ptr_hi ; 7C92 85 CC + adc #$01 ; 7C94 69 01 + sta font_ptr_hi ; 7C96 85 CE + ldx #$1D ; 7C98 A2 1D + ldy #$00 ; 7C9A A0 00 + +scroll_line_loop: + lda (font_ptr_lo),y ; 7C9C B1 CD + sta (screen_ptr_lo),y ; 7C9E 91 CB + dey ; 7CA0 88 + bne scroll_line_loop ; 7CA1 D0 F9 + inc font_ptr_hi ; 7CA3 E6 CE + inc screen_ptr_hi ; 7CA5 E6 CC + dex ; 7CA7 CA + bne scroll_line_loop ; 7CA8 D0 F2 + +blank_bottom_row: + lda SAVMSC ; 7CAA A5 58 + clc ; 7CAC 18 + adc #$C0 ; 7CAD 69 C0 + sta screen_ptr_lo ; 7CAF 85 CB + lda SAVMSC+1 ; 7CB1 A5 59 + adc #$1C ; 7CB3 69 1C + sta screen_ptr_hi ; 7CB5 85 CC + lda #$00 ; 7CB7 A9 00 + tay ; 7CB9 A8 + +blank_loop: + sta (screen_ptr_lo),y ; 7CBA 91 CB + dey ; 7CBC 88 + bne blank_loop ; 7CBD D0 FB + inc screen_ptr_hi ; 7CBF E6 CC + ldy #$40 ; 7CC1 A0 40 + +blank_tail: + sta (screen_ptr_lo),y ; 7CC3 91 CB + dey ; 7CC5 88 + bpl blank_tail ; 7CC6 10 FB + rts ; 7CC8 60 + +; ---------------------------------------------------------------------------- +; 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 ; 7CC9 A9 00 + sta font_ptr_hi ; 7CCB 85 CE + sta lo_nybble_flag ; 7CCD 8D 48 7F + lda TMPCHR ; 7CD0 A5 50 + clc ; 7CD2 18 + ror ; 7CD3 6A + bcc font_hi_nybble ; 7CD4 90 05 + ldx #$FF ; 7CD6 A2 FF + stx lo_nybble_flag ; 7CD8 8E 48 7F + +font_hi_nybble: + clc ; 7CDB 18 + rol ; 7CDC 2A + rol ; 7CDD 2A + rol font_ptr_hi ; 7CDE 26 CE + rol ; 7CE0 2A + rol font_ptr_hi ; 7CE1 26 CE + adc #<font_data ; 7CE3 69 00 + sta font_ptr_lo ; 7CE5 85 CD + lda #>font_data ; 7CE7 A9 7A + adc font_ptr_hi ; 7CE9 65 CE + sta font_ptr_hi ; 7CEB 85 CE + rts ; 7CED 60 + +; ---------------------------------------------------------------------------- +; 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 ; 7CEE E6 55 + lda right_margin ; 7CF0 AD 00 7C + cmp COLCRS ; 7CF3 C5 55 + bcs same_line ; 7CF5 B0 13 + lda LMARGN ; 7CF7 A5 52 + sta COLCRS ; 7CF9 85 55 + lda ROWCRS ; 7CFB A5 54 + ; $17 is 25 decimal, one row below the lowest on the screen + cmp #$17 ; 7CFD C9 17 + bcc no_scroll ; 7CFF 90 07 + jsr scroll_screen ; 7D01 20 87 7C + ; Move to row 24 after scrolling + lda #$16 ; 7D04 A9 16 + sta ROWCRS ; 7D06 85 54 + +no_scroll: + inc ROWCRS ; 7D08 E6 54 + +same_line: + rts ; 7D0A 60 + +; ---------------------------------------------------------------------------- +; Clear the screen by setting all screen RAM bytes to zero. Slow, but not +; as slow as scrolling. + +clear_screen: + lda SAVMSC ; 7D0B A5 58 + sta screen_ptr_lo ; 7D0D 85 CB + lda SAVMSC+1 ; 7D0F A5 59 + sta screen_ptr_hi ; 7D11 85 CC + ldy #$00 ; 7D13 A0 00 + ldx #$1D ; 7D15 A2 1D + lda #$00 ; 7D17 A9 00 + +cls_loop: + sta (screen_ptr_lo),y ; 7D19 91 CB + dey ; 7D1B 88 + bne cls_loop ; 7D1C D0 FB + inc screen_ptr_hi ; 7D1E E6 CC + dex ; 7D20 CA + bne cls_loop ; 7D21 D0 F6 + jsr blank_bottom_row ; 7D23 20 AA 7C + lda LMARGN ; 7D26 A5 52 + sta COLCRS ; 7D28 85 55 + lda #$00 ; 7D2A A9 00 + sta ROWCRS ; 7D2C 85 54 + ; redundant JMP + jmp return_success ; 7D2E 4C 31 7D + +; ---------------------------------------------------------------------------- +; 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 ; 7D31 A0 01 + rts ; 7D33 60 + +; ---------------------------------------------------------------------------- +; 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 ; 7D34 A4 54 + lda SAVMSC ; 7D36 A5 58 + clc ; 7D38 18 + adc row_low_offset_tab,y ; 7D39 79 52 7D + sta screen_ptr_lo ; 7D3C 85 CB + lda SAVMSC+1 ; 7D3E A5 59 + adc row_high_offset_tab,y ; 7D40 79 6A 7D + sta screen_ptr_hi ; 7D43 85 CC + lda COLCRS ; 7D45 A5 55 + lsr ; 7D47 4A + clc ; 7D48 18 + adc screen_ptr_lo ; 7D49 65 CB + bcc hi_byte_ok ; 7D4B 90 02 + inc screen_ptr_hi ; 7D4D E6 CC + +hi_byte_ok: + sta screen_ptr_lo ; 7D4F 85 CB + rts ; 7D51 60 + +; ---------------------------------------------------------------------------- +; 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 ; 7D52 + .byte $00,$40,$80,$C0,$00,$40,$80,$C0 ; 7D5A + .byte $00,$40,$80,$C0,$00,$40,$80,$C0 ; 7D62 + +row_high_offset_tab: + .byte $00,$01,$02,$03,$05,$06,$07,$08 ; 7D6A + .byte $0A,$0B,$0C,$0D,$0F,$10,$11,$12 ; 7D72 + .byte $14,$15,$16,$17,$19,$1A,$1B,$1C ; 7D7A + +; ---------------------------------------------------------------------------- +; 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 ; 7D82 A5 55 + clc ; 7D84 18 + ror ; 7D85 6A + bcc write_font_data_even ; 7D86 90 31 + ldx #$00 ; 7D88 A2 00 + ldy #$00 ; 7D8A A0 00 + +get_font_nybble_odd: + lda (font_ptr_lo),y ; 7D8C B1 CD + bit lo_nybble_flag ; 7D8E 2C 48 7F + bne lo_nybble_odd ; 7D91 D0 04 + ; glyph we want is stored in top 4 bits of font byte, + ; shift it down to the bottom 4 bits + lsr ; 7D93 4A + lsr ; 7D94 4A + lsr ; 7D95 4A + lsr ; 7D96 4A + +lo_nybble_odd: + eor inverse_mask ; 7D97 4D 49 7F + and #$0F ; 7D9A 29 0F + sta TMPCHR ; 7D9C 85 50 + ldy scanline_offset_tab,x ; 7D9E BC EA 7D + lda (screen_ptr_lo),y ; 7DA1 B1 CB + and #$F0 ; 7DA3 29 F0 + ora TMPCHR ; 7DA5 05 50 + sta (screen_ptr_lo),y ; 7DA7 91 CB + inx ; 7DA9 E8 + cpx #$07 ; 7DAA E0 07 + bne screen_ptr_ok_odd ; 7DAC D0 02 + inc screen_ptr_hi ; 7DAE E6 CC + +screen_ptr_ok_odd: + cpx #$08 ; 7DB0 E0 08 + beq write_font_done_odd ; 7DB2 F0 04 + txa ; 7DB4 8A + tay ; 7DB5 A8 + bne get_font_nybble_odd ; 7DB6 D0 D4 + +write_font_done_odd: + rts ; 7DB8 60 + +; ---------------------------------------------------------------------------- +; Write data to even-numbered columns, very similar to the above + +write_font_data_even: + ldx #$00 ; 7DB9 A2 00 + ldy #$00 ; 7DBB A0 00 + +get_font_nybble_even: + lda (font_ptr_lo),y ; 7DBD B1 CD + bit lo_nybble_flag ; 7DBF 2C 48 7F + beq hi_nybble_even ; 7DC2 F0 04 + asl ; 7DC4 0A + asl ; 7DC5 0A + asl ; 7DC6 0A + asl ; 7DC7 0A + +hi_nybble_even: + eor inverse_mask ; 7DC8 4D 49 7F + and #$F0 ; 7DCB 29 F0 + sta TMPCHR ; 7DCD 85 50 + ldy scanline_offset_tab,x ; 7DCF BC EA 7D + lda (screen_ptr_lo),y ; 7DD2 B1 CB + and #$0F ; 7DD4 29 0F + ora TMPCHR ; 7DD6 05 50 + sta (screen_ptr_lo),y ; 7DD8 91 CB + inx ; 7DDA E8 + cpx #$07 ; 7DDB E0 07 + bne screen_ptr_ok_even ; 7DDD D0 02 + inc screen_ptr_hi ; 7DDF E6 CC + +screen_ptr_ok_even: + cpx #$08 ; 7DE1 E0 08 + beq write_font_done_even ; 7DE3 F0 04 + txa ; 7DE5 8A + tay ; 7DE6 A8 + bne get_font_nybble_even ; 7DE7 D0 D4 + +write_font_done_even: + rts ; 7DE9 60 + +; ---------------------------------------------------------------------------- + +scanline_offset_tab: + .byte $00,$28,$50,$78,$A0,$C8,$F0,$18 ; 7DEA + +; ---------------------------------------------------------------------------- +; 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 ; 7DF2 A5 6B + beq get_line ; 7DF4 F0 0E + +get_next_byte: + ldx line_buffer_index ; 7DF6 AE 4A 7F + lda line_buffer,x ; 7DF9 BD 4B 7F + dec BUFCNT ; 7DFC C6 6B + inc line_buffer_index ; 7DFE EE 4A 7F + jmp return_success ; 7E01 4C 31 7D + +; ---------------------------------------------------------------------------- +; Get a line of input from the user, terminated by the Return key. + +get_line: + lda #$00 ; 7E04 A9 00 + sta BUFCNT ; 7E06 85 6B + sta line_buffer_index ; 7E08 8D 4A 7F + +show_cursor: + lda #$20 ; 7E0B A9 20 + sta TMPCHR ; 7E0D 85 50 + lda #$FF ; 7E0F A9 FF + sta inverse_mask ; 7E11 8D 49 7F + jsr setup_font_ptr ; 7E14 20 C9 7C + jsr setup_screen_ptr ; 7E17 20 34 7D + jsr write_font_data ; 7E1A 20 82 7D + jsr get_keystroke ; 7E1D 20 B7 7E + cpy #$01 ; 7E20 C0 01 + beq keystroke_ok ; 7E22 F0 07 + ldy #$00 ; 7E24 A0 00 + sty line_buffer_index ; 7E26 8C 4A 7F + sty BUFCNT ; 7E29 84 6B + +keystroke_ok: + cmp #$9B ; 7E2B C9 9B + bne check_backs_key ; 7E2D D0 03 + jmp return_key_hit ; 7E2F 4C 52 7E + +check_backs_key: + cmp #$7E ; 7E32 C9 7E + bne check_clear_key ; 7E34 D0 03 + jmp backs_key_hit ; 7E36 4C 71 7E + +check_clear_key: + cmp #$7D ; 7E39 C9 7D + bne normal_key_hit ; 7E3B D0 03 + jmp clear_key_hit ; 7E3D 4C 64 7E + +normal_key_hit: + ldx BUFCNT ; 7E40 A6 6B + bpl buffer_character ; 7E42 10 03 + jmp beep ; 7E44 4C 8F 7E + +buffer_character: + sta line_buffer,x ; 7E47 9D 4B 7F + jsr col80_putbyte ; 7E4A 20 43 7C + inc BUFCNT ; 7E4D E6 6B + jmp show_cursor ; 7E4F 4C 0B 7E + +return_key_hit: + jsr print_space ; 7E52 20 A4 7E + lda #$9B ; 7E55 A9 9B + ldx BUFCNT ; 7E57 A6 6B + sta line_buffer,x ; 7E59 9D 4B 7F + inc BUFCNT ; 7E5C E6 6B + jsr col80_putbyte ; 7E5E 20 43 7C + jmp get_next_byte ; 7E61 4C F6 7D + +clear_key_hit: + jsr clear_screen ; 7E64 20 0B 7D + lda #$00 ; 7E67 A9 00 + sta line_buffer_index ; 7E69 8D 4A 7F + sta BUFCNT ; 7E6C 85 6B + jmp get_line ; 7E6E 4C 04 7E + +backs_key_hit: + jsr print_space ; 7E71 20 A4 7E + lda BUFCNT ; 7E74 A5 6B + beq backs_key_done ; 7E76 F0 14 + dec COLCRS ; 7E78 C6 55 + lda COLCRS ; 7E7A A5 55 + clc ; 7E7C 18 + adc #$01 ; 7E7D 69 01 + cmp LMARGN ; 7E7F C5 52 + bne backs_same_line ; 7E81 D0 07 + lda right_margin ; 7E83 AD 00 7C + sta COLCRS ; 7E86 85 55 + dec ROWCRS ; 7E88 C6 54 + +backs_same_line: + dec BUFCNT ; 7E8A C6 6B + +backs_key_done: + jmp show_cursor ; 7E8C 4C 0B 7E + +; ---------------------------------------------------------------------------- +; 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 + +beep: ldy #$00 ; 7E8F A0 00 + ldx #$AF ; 7E91 A2 AF + +beep_delay_x: + stx AUDF1 ; 7E93 8E 00 D2 + stx AUDC1 ; 7E96 8E 01 D2 + +beep_delay_y: + dey ; 7E99 88 + bne beep_delay_y ; 7E9A D0 FD + dex ; 7E9C CA + cpx #$9F ; 7E9D E0 9F + bne beep_delay_x ; 7E9F D0 F2 + jmp show_cursor ; 7EA1 4C 0B 7E + +; ---------------------------------------------------------------------------- +; Print a space character at the current cursor position. Does not +; update the cursor position. +print_space: + lda #$00 ; 7EA4 A9 00 + sta inverse_mask ; 7EA6 8D 49 7F + lda #$20 ; 7EA9 A9 20 + sta TMPCHR ; 7EAB 85 50 + jsr setup_font_ptr ; 7EAD 20 C9 7C + jsr setup_screen_ptr ; 7EB0 20 34 7D + jsr write_font_data ; 7EB3 20 82 7D + rts ; 7EB6 60 + +; ---------------------------------------------------------------------------- +; 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 ; 7EB7 AD 25 E4 + pha ; 7EBA 48 + lda k_dev_get_lo ; 7EBB AD 24 E4 + pha ; 7EBE 48 + rts ; 7EBF 60 + +; ---------------------------------------------------------------------------- +; 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. + +col80_init: + ldy #$00 ; 7EC0 A0 00 + +next_hatab_slot: + lda HATABS,y ; 7EC2 B9 1A 03 + beq register_x_handler ; 7EC5 F0 0A + iny ; 7EC7 C8 + iny ; 7EC8 C8 + iny ; 7EC9 C8 + cpy #$20 ; 7ECA C0 20 + bcc next_hatab_slot ; 7ECC 90 F4 + jmp return_success ; 7ECE 4C 31 7D + +register_x_handler: + lda #$58 ; 7ED1 A9 58 + sta HATABS,y ; 7ED3 99 1A 03 + lda #<col80_vector_tab ; 7ED6 A9 E5 + iny ; 7ED8 C8 + sta HATABS,y ; 7ED9 99 1A 03 + lda #>col80_vector_tab ; 7EDC A9 7E + iny ; 7EDE C8 + sta HATABS,y ; 7EDF 99 1A 03 + jmp return_success ; 7EE2 4C 31 7D + +; ---------------------------------------------------------------------------- +; 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 ; 7EE5 00 7C + .word col80_close-1 ; 7EE7 3F 7C + .word col80_getbyte-1 ; 7EE9 F1 7D + .word col80_putbyte-1 ; 7EEB 42 7C + .word col80_close-1 ; 7EED 3F 7C + .word col80_close-1 ; 7EEF 3F 7C + jmp col80_init ; 7EF1 4C C0 7E + +; ---------------------------------------------------------------------------- +; The OS jumps here on warmstart (also, this is the run address in our +; binary load file) + +dosini_entry_point: + nop ; 7EF4 EA + nop ; 7EF5 EA + nop ; 7EF6 EA + +main_entry_point: + jsr col80_init ; 7EF7 20 C0 7E + lda CONSOL ; 7EFA AD 1F D0 + and #$04 ; 7EFD 29 04 + beq no_e_handler ; 7EFF F0 2F + lda #$0C ; 7F01 A9 0C + sta ICCOM ; 7F03 8D 42 03 + ldx #$00 ; 7F06 A2 00 + jsr CIOV ; 7F08 20 56 E4 + lda #$58 ; 7F0B A9 58 + sta font_ptr_lo ; 7F0D 85 CD + lda #$03 ; 7F0F A9 03 + sta ICCOM ; 7F11 8D 42 03 + lda #$CD ; 7F14 A9 CD + sta ICBAL ; 7F16 8D 44 03 + lda #$00 ; 7F19 A9 00 + sta ICBAH ; 7F1B 8D 45 03 + ldx #$00 ; 7F1E A2 00 + jsr CIOV ; 7F20 20 56 E4 + ldy #$07 ; 7F23 A0 07 + lda #<col80_vector_tab ; 7F25 A9 E5 + sta HATABS,y ; 7F27 99 1A 03 + lda #>col80_vector_tab ; 7F2A A9 7E + iny ; 7F2C C8 + sta HATABS,y ; 7F2D 99 1A 03 +no_e_handler: + lda #<START_ADDRESS ; 7F30 A9 00 + sta MEMTOP ; 7F32 8D E5 02 + lda #>START_ADDRESS ; 7F35 A9 7A + sta MEMTOP+1 ; 7F37 8D E6 02 + jmp return_success ; 7F3A 4C 31 7D + +; ---------------------------------------------------------------------------- +; (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) + lda #<dosini_entry_point ; 7F3D A9 F4 + sta DOSINI ; 7F3F 85 0C + lda #>dosini_entry_point ; 7F41 A9 7E + sta DOSINI+1 ; 7F43 85 0D + jmp main_entry_point ; 7F45 4C F7 7E + +; ---------------------------------------------------------------------------- +; 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 ; 7F48 00 + +inverse_mask: + .byte $00 ; 7F49 00 + +line_buffer_index: + .byte $12 ; 7F4A 12 + +; ---------------------------------------------------------------------------- +; 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). + +line_buffer: + .byte $53,$20,$43,$4F,$4C,$38,$30,$20 ; 7F4B + .byte $37,$41,$30,$30,$20,$37,$46,$38 ; 7F53 + .byte $30,$9B,$20,$20,$20,$20,$9B,$27 ; 7F5B + .byte $40,$40,$40,$40,$28,$28,$28,$28 ; 7F63 + .byte $40,$40,$40,$40,$40,$40,$40,$40 ; 7F6B + .byte $40,$40,$40,$40,$40,$40,$40,$40 ; 7F73 + .byte $9B,$FD,$FD,$FD,$FD,$9B ; 7F7B + +END_ADDRESS = *-1 + +; 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. + diff --git a/src/col80_modified/cruft/col80_main.xex b/src/col80_modified/cruft/col80_main.xex Binary files differnew file mode 100644 index 0000000..90208c3 --- /dev/null +++ b/src/col80_modified/cruft/col80_main.xex diff --git a/src/col80_modified/cruft/col80_orig.xex b/src/col80_modified/cruft/col80_orig.xex Binary files differnew file mode 100644 index 0000000..f5f9548 --- /dev/null +++ b/src/col80_modified/cruft/col80_orig.xex diff --git a/src/col80_modified/cruft/col80_runad_seg.s b/src/col80_modified/cruft/col80_runad_seg.s new file mode 100644 index 0000000..234d621 --- /dev/null +++ b/src/col80_modified/cruft/col80_runad_seg.s @@ -0,0 +1,13 @@ + +; Third segment is the run address + +;.ifdef FUJICHAT +;INITAD = $02E2 +; .word INITAD +; .word INITAD+1 +; .word dosini_entry_point +;.else + .word RUNAD + .word RUNAD+1 + .word dosini_entry_point +;.endif diff --git a/src/col80_modified/cruft/col80_startaddr.s b/src/col80_modified/cruft/col80_startaddr.s new file mode 100644 index 0000000..d88203b --- /dev/null +++ b/src/col80_modified/cruft/col80_startaddr.s @@ -0,0 +1,7 @@ + + .ifdef FUJICHAT +START_ADDRESS = $9C01 ; subtract $0800 (2048) if using BASIC or other cart +;START_ADDRESS = $7A00 + .else +START_ADDRESS = $7A00 + .endif diff --git a/src/col80_modified/cruft/col80_startup.s b/src/col80_modified/cruft/col80_startup.s new file mode 100644 index 0000000..b170a3c --- /dev/null +++ b/src/col80_modified/cruft/col80_startup.s @@ -0,0 +1,4 @@ + + .include "col80_include.s" + .include "col80_init.s" + .include "col80_entry.s" diff --git a/src/col80_modified/cruft/dasm2atasm b/src/col80_modified/cruft/dasm2atasm new file mode 100755 index 0000000..b7ebe66 --- /dev/null +++ b/src/col80_modified/cruft/dasm2atasm @@ -0,0 +1,362 @@ +#!/usr/bin/perl -w + +=head1 NAME + +dasm2atasm - converts 6502 assembly in DASM syntax to ATASM (or MAC/65) format. + +=head1 SYNOPSIS + + dasm2atasm mycode.asm + +Writes output to I<mycode.m65> + + dasm2atasm stuff.asm other.m65 + +Reads from I<stuff.asm>, writes to I<other.m65> + +=head1 DESCRIPTION + +B<dasm2atasm> tries its best to convert DASM's syntax into something +that B<ATASM> can use. Since B<ATASM>'s syntax is 99% compatible with +that of B<MAC/65>, B<dasm2atasm> can be used for that as well. + +=head1 CAVEATS + +There are a few B<DASM> directives that aren't quite supported by +B<ATASM>. + +=over 4 + +=item echo + +In B<DASM> syntax, I<echo> can interpolate values, like so: + + echo $100-*, " bytes of zero page left" + +B<ATASM>'s closest equivalent to I<echo> is I<.warn>, but it doesn't +allow multiple arguments or interpolation. For now, B<dasm2atasm> just +comments out the line with the I<echo> directive. + +=item seg and seg.u + +B<ATASM> just plain doesn't support segments. These directives will +just be commented out. This I<shouldn't> have any effect on the +object code. + +=item sta.w, sty.w, stx.w + +B<ATASM> doesn't provide a way to force word addressing, when the operand +of a store instruction will allow zero page addressing to be used. You'll +run into this a lot in Atari 2600 code, or any other 6502 code that has to +maintain sync with an external piece of hardware (using word addressing +causes the 6502 to use an extra CPU cycle, which is the only way to cause +a 1-cycle delay). + +For now, we're just converting any I<st?.w> instructions to the appropriate +I<.byte> directives, like so: + + ;;;;; dasm2atasm: was `sta.w COLUPF', using .byte to generate opcode + .byte $8d, COLUPF, $00 + +This works fine if I<COLUPF> is a zero-page label. It's possible, though +unlikely, that you'll run across code where the programmer has used I<sta.w> +with a label that would already cause absolute word addressing to be used, +in which case the extra I<$00> will break our code (literally: I<$00> is +the I<BRK> instruction!) + +This isn't likely to be fixed by I<dasm2atasm>. The correct fix will be to +support I<sta.w> and friends in B<ATASM> itself, which may happen in the +future. + +=item . (dot) + +B<DASM> allows the use of I<.> or I<*> to represent the current program counter +in expressions. B<ATASM> only allows I<*>, and unless I want to include a +full expression-parser in B<dasm2atasm>, I can't reliably translate this. + +For now, you'll have to fix this yourself. Future versions will at least +make an attempt, but this one doesn't. + +=back + +=head1 AUTHOR + +B. Watson I<< <urchlay@urchlay.com> >>. Comments & constructive criticism +welcome, or just a friendly `hello'. Spam will be redirected to /dev/null +and so will the spammer's entire domain. + +=cut + +sub usage { + print <<EOF; +Usage: $0 -[aclmr] infile.asm [outfile.m65] + +EOF + exit 1; +} + +sub get_mac_sub { + my $rex = shift; + my $code = "sub { s/($rex)/\\U\$1/gio };"; + #warn "code is $code"; + return eval "$code"; +} + +sub unhex { + # makes a proper $xx, $xx, $xx list of bytes + # from a list of hex digits, spaces optional. + my $bytes = shift; + my $ret = ""; + + $bytes =~ s/\s//g; + + #warn "unhex: bytes is $bytes"; + + for($bytes =~ /(..)/g) { + #warn "unhex: found $_"; + $ret .= "\$$_, "; + } + + chop $ret; + chop $ret; + + return $ret; +} + +sub fix_include { + my $inc = shift; + my $old = $inc; + $inc =~ s/\.(\w+)("?)$/.m65$2/; + + if($recursive) { + system("$cmd $old $inc"); + } else { + warn "Don't forget to convert included file `$old' to .m65 format!\n"; + } + return $inc; +} + +sub do_subs { + # Do the dirty work of the substitutions. Only reason we have this + # as a subroutine of its own is for profiling purposes (and we do + # spend a *lot* of time here!) + my $line = shift; + + for($line) { + s/^(\@?\w+):/$1/; # no colons after labels, in atasm + s/%/~/g; # binary constant + s/!=/<>/g; # inequality + + s/^(\s+)\.?echo(.*)/;;;;;$1.warn$2/i && + do { warn "$in, line $.:\n\t`.warn' not fully compatible with dasm's `echo', commented out\n" } + && next; + + # This is supposed to change e.g. `bpl .label' to `bpl @label' + s/^(\s+)([a-z]{3})(\s+)\.(\w+)/$1$2$3\@$4/i + && next; + + + s/{(\d)}/%$1/g; # macro arg (gotta do this *after* bin. constants!) + +# atasm doesn't support shifts, emulate with multiply/divide + s/\s*<<\s*(\d+)/"*" . 2**$1/eg; + s/\s*>>\s*(\d+)/"\/" . 2**$1/eg; + +# atasm chokes sometimes when there's whitespace around an operator +# unfortunately, a construct like `bne *-1' can't afford to lose the +# space before the *... why, oh why, does * have to be both multiply and +# program counter? *sigh* + +# s/\s*([-!|\/+*&])\s*/$1/g; + +# ARGH. Why does dasm allow `byte #1, #2, #3'... and why do people *use* it?! + s/^(\s+)\.?byte(\s+)/$1.byte$2/i && do { s/#//g } && next; + s/^(\s+)\.?word(\s+)/$1.word$2/i && do { s/#//g } && next; + s/^(\s+)\.?dc\.w(\s+)/$1.word$2/i && do { s/#//g } && next; + s/^(\s+)\.?dc(?:\.b)?(\s+)/$1.byte$2/i && do { s/#//g } && next; + +# 20070529 bkw: turn ".DS foo" into ".DC foo 0" + s/^(\s+)\.?ds(\s+)(\S+)/$1.dc $3 0 /i && do { s/#//g } && next; + +# I really want to add `hex' to atasm. 'til then though, fake with .byte + s/^(\s+)\.?hex\s+(.*)/$1 . '.byte ' . + unhex($2)/ie && next; + + s/^(\s+)\.?subroutine(.*)/$1.local$2/i && next; + s/^(\s+)\.?include(\s+)(.*)/$1 . '.include' . $2 . fix_include($3)/gie + && next; + s/^(\s+)\.?equ\b/$1=/i && next; + s/^(\s+)\.?repeat\b/$1.rept/i && next; + s/^(\s+)\.?repend\b/$1.endr/i && next; + s/^(\s+)\.?endm\b/$1.endm/i && next; + s/^(\s+)\.?org(\s+)([^,]*).*$/$1*=$2$3/i && next; + s/^(\s+)\.?incbin\b/$1\.incbin/i && next; + s/^(\s+)\.?err(.*)/$1.error$2/i && next; # TODO: see if atasm allows `.error' with no message. + s/^(\s+)\.?ifconst\s+(.*)/$1.if .def $2/i + && next; # TODO: test this! + s/^(\s+)\.?else/$1.else/i && next; + s/^(\s+)\.?endif/$1.endif/i && next; + s/^(\s+)\.?if\s+(.*)/$1.if $2/i && next; + + # stuff that doesn't work: + s/^(\s+)(\.?seg(\..)?\s.*)/;;;;; dasm2atasm: `seg' not supported by atasm\n;;;;;$1$2/i + && next; + s/^(\s+)(\.?processor\s.*)/;;;;; dasm2atasm: `processor' not supported by atasm\n;;;;;$1$2/i + && next; + + s/^(\s+)sta\.w(\s+)(.*)/;;;;; dasm2atasm: was `sta.w $3', using .byte to generate opcode\n$1.byte \$8d, <$3, >$3/i + && next; + + s/^(\s+)stx\.w(\s+)(.*)/;;;;; dasm2atasm: was `stx.w $3', using .byte to generate opcode\n$1.byte \$8e, <$3, >$3/i + && next; + + s/^(\s+)sta\.w(\s+)(.*)/;;;;; dasm2atasm: was `sty.w $3', using .byte to generate opcode\n$1.byte \$8c, <$3, >$3/i + && next; + + # atasm lacks `align', so make up for it with a macro + if(s/(\s)\.?align(\s+)(.*)/$1ALIGN$2$3/i) { + if(!$align_defined) { # only gotta define it if not already defined. + for($align_macro) { + $_ =~ s/^/($linenum += 10) . " "/gme if $linenum; + $_ =~ s/\n/\x9b/g if $a8eol; + } + + print OUT $align_macro; # no, I wouldn't use these globals in a CS class assignment. + $align_defined++; + } + next; + } + + # macros. This is by far the biggest pain in the ass yet. + s/(\s)\.?mac\b/$1.macro/i; + if(/(\s)\.macro(\s+)(\w+)/) { + $mac_regex .= "|\\b$3\\b"; + $mac_sub = get_mac_sub($mac_regex); + } + + if(ref $mac_sub) { # if we've found at least one macro so far... + &$mac_sub; # CAPITALIZE everything matching a macro name + } # note: this code assumes macros are *always* defined before they're + # used. atasm requires this, but does dasm? + + } + return $line; +} + +## main() ## + +$ca65 = 0; +$a8eol = 0; +$linenum = 0; +$recursive = 0; + +$cmd = $0; + +while($ARGV[0] =~ /^-/i) { + my $opt = shift; + $cmd .= " $opt"; + + if($opt eq "-c") { + $ca65++; + } elsif($opt eq "-a") { + $a8eol++; + } elsif($opt eq "-l") { + $linenum = 1000; + } elsif($opt eq "-m") { + $a8eol++; + $linenum = 1000; + } elsif($opt eq "-r") { + $recursive++; + } elsif($opt eq "--") { + last; + } else { + warn "Unknown option '$opt'\n"; + usage; + } +} + +if($ca65 && ($linenum || $a8eol)) { + die "Can't use line numbers and/or Atari EOLs with ca65 output\n"; +} + +$align_macro = <<EOF; +;;;;;; ALIGN macro defined by dasm2atasm + .macro ALIGN + *= [[*/%1]+1] * %1 + .endm +EOF + +$align_defined = 0; # we only need to emit the macro definition once. + +$in = shift || usage; +$out = shift; + +($out = $in) =~ s/(\.\w+)?$/.m65/ unless $out; + +die "$0: can't use $in for both input and output\n" if $out eq $in; + +open IN, "<$in" or die "Can't read $in: $!\n"; +open OUT, ">$out" or die "Can't write to $out: $!\n"; + +$hdr = <<EOF; +;;; Converted from DASM syntax with command: +; $cmd $in $out + +EOF + +for($hdr) { + $_ =~ s/^/($linenum += 10) . " "/gme if $linenum; + $_ =~ s/\n/\x9b/g if $a8eol; +} + +print OUT $hdr; + +if($ca65) { + print OUT <<EOF; +;;; ca65 features enabled by dasm2atasm +; To build with ca65: +; ca65 -o foo.o -t none foo.asm +; ld65 -o foo.bin -t none foo.o +.FEATURE pc_assignment +.FEATURE labels_without_colons + +EOF +} + +$mac_regex = "!THIS_ISNT_SUPPOSED_TO_MATCH"; +$mac_sub = ""; # this will be the code ref we call to match $mac_regex + +while(<IN>) { + chomp; + s/\r//; # you might not want this on dos/win, not sure if it matters. + $label = ""; + + if(/^(\w+)\s*=\s*\1/i) { + print OUT ";;;;; dasm2atasm: labels are case-insensitive in atasm\n"; + $line = ";;;;; $_ ; This assignment is an error in atasm"; + next; + } + +# do this before we split out the label: + s/^\./\@/; # local label (dot in dasm, @ in atasm) + + if(s/^([^:;\s]*):?(\s+)/$2/) { + $label = $1; + } + + ($line, $comment) = split /;/, $_, 2; + next unless $line; + + $line = do_subs($line); + +} continue { + if($linenum) { + print OUT "$linenum "; + $linenum += 10; + } + + print OUT $label if $label; + print OUT $line if $line; + print OUT ";$comment" if $comment; + print OUT ($a8eol ? "\x9b" : "\n"); +} diff --git a/src/col80_modified/cruft/dos_20s.atr b/src/col80_modified/cruft/dos_20s.atr Binary files differnew file mode 100755 index 0000000..8016b73 --- /dev/null +++ b/src/col80_modified/cruft/dos_20s.atr diff --git a/src/col80_modified/cruft/font.bin b/src/col80_modified/cruft/font.bin Binary files differnew file mode 100644 index 0000000..d2fd3d4 --- /dev/null +++ b/src/col80_modified/cruft/font.bin diff --git a/src/col80_modified/cruft/font.s b/src/col80_modified/cruft/font.s new file mode 100644 index 0000000..78266ea --- /dev/null +++ b/src/col80_modified/cruft/font.s @@ -0,0 +1,54 @@ + .org 1000 + ; Space ! " # etc (codes 32-63) + .byte $00,$04,$04,$04,$04,$00,$04,$00 + .byte $00,$A0,$AA,$AE,$0A,$0E,$0A,$00 + .byte $00,$40,$68,$82,$44,$28,$C2,$40 + .byte $00,$C4,$64,$E4,$60,$C0,$40,$00 + .byte $00,$44,$82,$82,$82,$82,$82,$44 + .byte $00,$04,$A4,$4E,$E4,$44,$A0,$00 + .byte $00,$00,$00,$0E,$00,$40,$40,$80 + .byte $00,$02,$02,$04,$04,$08,$48,$00 + .byte $00,$E4,$AC,$A4,$A4,$A4,$EE,$00 + .byte $00,$EE,$22,$22,$EE,$82,$EE,$00 + .byte $00,$AE,$A8,$AE,$E2,$22,$2E,$00 + .byte $00,$EE,$82,$E2,$A4,$A4,$E4,$00 + .byte $00,$EE,$AA,$EA,$AE,$A2,$EE,$00 + .byte $00,$00,$00,$44,$00,$44,$04,$08 + .byte $00,$20,$4E,$80,$4E,$20,$00,$00 + .byte $00,$8C,$42,$22,$44,$80,$04,$00 + + ; @ A B C etc (codes 64-95) + .byte $00,$6E,$9A,$BA,$BE,$8A,$6A,$00 + .byte $00,$C6,$A8,$C8,$A8,$A8,$C6,$00 + .byte $00,$CE,$A8,$AC,$A8,$A8,$CE,$00 + .byte $00,$E6,$88,$C8,$8A,$8A,$86,$00 + .byte $00,$AE,$A4,$E4,$A4,$A4,$AE,$00 + .byte $00,$2A,$2A,$2C,$2A,$2A,$CA,$00 + .byte $00,$8A,$8E,$8E,$8A,$8A,$EA,$00 + .byte $00,$C4,$AA,$AA,$AA,$AA,$A4,$00 + .byte $00,$EE,$AA,$EA,$8A,$8A,$8E,$03 + .byte $00,$C6,$A8,$AC,$C2,$A2,$AC,$00 + .byte $00,$EA,$4A,$4A,$4A,$4A,$4E,$00 + .byte $00,$AA,$AA,$AA,$AE,$AE,$4A,$00 + .byte $00,$AA,$4A,$4E,$44,$44,$A4,$00 + .byte $00,$EE,$28,$48,$88,$88,$E8,$0E + .byte $00,$8E,$82,$42,$42,$22,$22,$0E + .byte $00,$00,$40,$A0,$00,$00,$00,$0F + + ; diamond, lowercase letters, control codes (codes 96-127) + .byte $00,$00,$00,$46,$E2,$4E,$0E,$00 + .byte $00,$80,$80,$C6,$A8,$A8,$C6,$00 + .byte $00,$20,$20,$6E,$AE,$A8,$6E,$00 + .byte $00,$00,$C0,$86,$CA,$8E,$82,$0C + .byte $00,$80,$84,$80,$C4,$A4,$A4,$00 + .byte $00,$08,$28,$0A,$2C,$2A,$2A,$C0 + .byte $00,$40,$40,$4A,$4E,$4A,$4A,$00 + .byte $00,$00,$00,$CE,$AA,$AA,$AE,$00 + .byte $00,$00,$00,$C6,$AA,$C6,$82,$82 + .byte $00,$00,$00,$6E,$88,$86,$8E,$00 + .byte $00,$00,$40,$EA,$4A,$4A,$6E,$00 + .byte $00,$00,$00,$AA,$AA,$AE,$4A,$00 + .byte $00,$00,$00,$AA,$4A,$A6,$A2,$0C + .byte $00,$00,$04,$EE,$4E,$84,$EE,$00 + .byte $40,$4E,$4C,$4E,$4A,$42,$42,$40 + .byte $00,$28,$6C,$EE,$6C,$28,$00,$00 diff --git a/src/col80_modified/cruft/font2xbm.pl b/src/col80_modified/cruft/font2xbm.pl new file mode 100644 index 0000000..3337139 --- /dev/null +++ b/src/col80_modified/cruft/font2xbm.pl @@ -0,0 +1,47 @@ +#!/usr/bin/perl -w + +use bytes; + +$name = "xbm"; +$width = 8; +$height = 384; +$cwidth = $width / 8; +$cheight = $height / 8; + +print <<EOF; +#define ${name}_width ${width} +#define ${name}_height ${height} +static unsigned char ${name}_bits[] = { +EOF + +undef $/; +$_ = <>; +@inbytes = split ""; + +# reverse bits, print 12 bytes/line + +$c = 0; +for($i=0; $i<@inbytes; $i++) { + $byte = ord $inbytes[$i]; + if(!$c) { + print " "; + } + + printf "0x%02x", reverse_bits($byte); + if($i != $#inbytes) { + if($c == 12) { + print ",\n"; + $c = 0; + } else { + print ", "; + $c++; + } + } +} + +print " };\n"; + +sub reverse_bits { + my $bitstr = reverse sprintf("%08b", $_[0]); + return eval "0b$bitstr"; +} diff --git a/src/col80_modified/cruft/new_font.s b/src/col80_modified/cruft/new_font.s new file mode 100644 index 0000000..f70ae8b --- /dev/null +++ b/src/col80_modified/cruft/new_font.s @@ -0,0 +1,48 @@ + .byte $00,$04,$04,$04,$04,$00,$04,$00 + .byte $00,$A0,$AA,$AE,$0A,$0E,$0A,$00 + .byte $00,$40,$68,$82,$44,$28,$C2,$40 + .byte $00,$44,$E4,$84,$60,$80,$E0,$40 + .byte $00,$44,$82,$82,$82,$82,$82,$44 + .byte $00,$00,$A4,$44,$EE,$44,$A4,$00 + .byte $00,$00,$00,$0E,$00,$40,$40,$80 + .byte $00,$02,$02,$04,$04,$08,$48,$00 + .byte $00,$E4,$AC,$A4,$A4,$A4,$EE,$00 + .byte $00,$EE,$22,$22,$EE,$82,$EE,$00 + .byte $00,$AE,$A8,$AE,$E2,$22,$2E,$00 + .byte $00,$EE,$82,$E2,$A4,$A4,$E4,$00 + .byte $00,$EE,$AA,$EA,$AE,$A2,$EE,$00 + .byte $00,$00,$00,$44,$00,$44,$04,$08 + .byte $00,$20,$4E,$80,$4E,$20,$00,$00 + .byte $00,$8C,$42,$22,$44,$80,$04,$00 + .byte $00,$6E,$9A,$BA,$BE,$8A,$6A,$00 + .byte $00,$C6,$A8,$C8,$A8,$A8,$C6,$00 + .byte $00,$CE,$A8,$AC,$A8,$A8,$CE,$00 + .byte $00,$E6,$88,$C8,$8A,$8A,$86,$00 + .byte $00,$AE,$A4,$E4,$A4,$A4,$AE,$00 + .byte $00,$2A,$2A,$2C,$2A,$2A,$CA,$00 + .byte $00,$8A,$8E,$8E,$8A,$8A,$EA,$00 + .byte $00,$C4,$AA,$AA,$AA,$AA,$A4,$00 + .byte $00,$EE,$AA,$EA,$8A,$8A,$8E,$03 + .byte $00,$C6,$A8,$AC,$C2,$A2,$AC,$00 + .byte $00,$EA,$4A,$4A,$4A,$4A,$4E,$00 + .byte $00,$AA,$AA,$AA,$AE,$AE,$4A,$00 + .byte $00,$AA,$4A,$4E,$44,$44,$A4,$00 + .byte $00,$EE,$28,$48,$88,$88,$E8,$0E + .byte $00,$8E,$82,$42,$42,$22,$22,$0E + .byte $00,$00,$40,$A0,$00,$00,$00,$0F + .byte $00,$00,$0C,$42,$E6,$4A,$0E,$00 + .byte $00,$80,$80,$C6,$A8,$A8,$C6,$00 + .byte $00,$20,$26,$6A,$AE,$A8,$6E,$00 + .byte $00,$00,$C0,$86,$CA,$8E,$82,$0C + .byte $00,$80,$84,$80,$C4,$A4,$A4,$00 + .byte $00,$08,$28,$0A,$2C,$2A,$2A,$C0 + .byte $00,$40,$40,$4A,$4E,$4A,$4A,$00 + .byte $00,$00,$00,$CE,$AA,$AA,$AE,$00 + .byte $00,$00,$00,$C6,$AA,$C6,$82,$83 + .byte $00,$00,$00,$6E,$88,$86,$8E,$00 + .byte $00,$00,$40,$EA,$4A,$4A,$6E,$00 + .byte $00,$00,$00,$AA,$AA,$AE,$4A,$00 + .byte $00,$00,$00,$AA,$4A,$A6,$A2,$0C + .byte $00,$06,$04,$E4,$48,$84,$E4,$06 + .byte $40,$4C,$44,$44,$42,$44,$44,$4C + .byte $00,$08,$5C,$AE,$0C,$08,$00,$00 diff --git a/src/col80_modified/cruft/new_font.xbm b/src/col80_modified/cruft/new_font.xbm new file mode 100644 index 0000000..a7fab38 --- /dev/null +++ b/src/col80_modified/cruft/new_font.xbm @@ -0,0 +1,35 @@ +#define font_width 8 +#define font_height 384 +static unsigned char font_bits[] = { + 0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0x20, 0x00, 0x00, 0x05, 0x55, 0x75, + 0x50, 0x70, 0x50, 0x00, 0x00, 0x02, 0x16, 0x41, 0x22, 0x14, 0x43, 0x02, + 0x00, 0x22, 0x27, 0x21, 0x06, 0x01, 0x07, 0x02, 0x00, 0x22, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x22, 0x00, 0x00, 0x25, 0x22, 0x77, 0x22, 0x25, 0x00, + 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, 0x02, 0x01, 0x00, 0x40, 0x40, 0x20, + 0x20, 0x10, 0x12, 0x00, 0x00, 0x27, 0x35, 0x25, 0x25, 0x25, 0x77, 0x00, + 0x00, 0x77, 0x44, 0x44, 0x77, 0x41, 0x77, 0x00, 0x00, 0x75, 0x15, 0x75, + 0x47, 0x44, 0x74, 0x00, 0x00, 0x77, 0x41, 0x47, 0x25, 0x25, 0x27, 0x00, + 0x00, 0x77, 0x55, 0x57, 0x75, 0x45, 0x77, 0x00, 0x00, 0x00, 0x00, 0x22, + 0x00, 0x22, 0x20, 0x10, 0x00, 0x04, 0x72, 0x01, 0x72, 0x04, 0x00, 0x00, + 0x00, 0x31, 0x42, 0x44, 0x22, 0x01, 0x20, 0x00, 0x00, 0x76, 0x59, 0x5d, + 0x7d, 0x51, 0x56, 0x00, 0x00, 0x63, 0x15, 0x13, 0x15, 0x15, 0x63, 0x00, + 0x00, 0x73, 0x15, 0x35, 0x15, 0x15, 0x73, 0x00, 0x00, 0x67, 0x11, 0x13, + 0x51, 0x51, 0x61, 0x00, 0x00, 0x75, 0x25, 0x27, 0x25, 0x25, 0x75, 0x00, + 0x00, 0x54, 0x54, 0x34, 0x54, 0x54, 0x53, 0x00, 0x00, 0x51, 0x71, 0x71, + 0x51, 0x51, 0x57, 0x00, 0x00, 0x23, 0x55, 0x55, 0x55, 0x55, 0x25, 0x00, + 0x00, 0x77, 0x55, 0x57, 0x51, 0x51, 0x71, 0xc0, 0x00, 0x63, 0x15, 0x35, + 0x43, 0x45, 0x35, 0x00, 0x00, 0x57, 0x52, 0x52, 0x52, 0x52, 0x72, 0x00, + 0x00, 0x55, 0x55, 0x55, 0x75, 0x75, 0x52, 0x00, 0x00, 0x55, 0x52, 0x72, + 0x22, 0x22, 0x25, 0x00, 0x00, 0x77, 0x14, 0x12, 0x11, 0x11, 0x17, 0x70, + 0x00, 0x71, 0x41, 0x42, 0x42, 0x44, 0x44, 0x70, 0x00, 0x00, 0x02, 0x05, + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x30, 0x42, 0x67, 0x52, 0x70, 0x00, + 0x00, 0x01, 0x01, 0x63, 0x15, 0x15, 0x63, 0x00, 0x00, 0x04, 0x64, 0x56, + 0x75, 0x15, 0x76, 0x00, 0x00, 0x00, 0x03, 0x61, 0x53, 0x71, 0x41, 0x30, + 0x00, 0x01, 0x21, 0x01, 0x23, 0x25, 0x25, 0x00, 0x00, 0x10, 0x14, 0x50, + 0x34, 0x54, 0x54, 0x03, 0x00, 0x02, 0x02, 0x52, 0x72, 0x52, 0x52, 0x00, + 0x00, 0x00, 0x00, 0x73, 0x55, 0x55, 0x75, 0x00, 0x00, 0x00, 0x00, 0x63, + 0x55, 0x63, 0x41, 0xc1, 0x00, 0x00, 0x00, 0x76, 0x11, 0x61, 0x71, 0x00, + 0x00, 0x00, 0x02, 0x57, 0x52, 0x52, 0x76, 0x00, 0x00, 0x00, 0x00, 0x55, + 0x55, 0x75, 0x52, 0x00, 0x00, 0x00, 0x00, 0x55, 0x52, 0x65, 0x45, 0x30, + 0x00, 0x60, 0x20, 0x27, 0x12, 0x21, 0x27, 0x60, 0x02, 0x32, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x32, 0x00, 0x10, 0x3a, 0x75, 0x30, 0x10, 0x00, 0x00 }; diff --git a/src/col80_modified/cruft/test.atr b/src/col80_modified/cruft/test.atr Binary files differnew file mode 100755 index 0000000..0127b33 --- /dev/null +++ b/src/col80_modified/cruft/test.atr diff --git a/src/col80_modified/cruft/xbm2font.pl b/src/col80_modified/cruft/xbm2font.pl new file mode 100644 index 0000000..758d57e --- /dev/null +++ b/src/col80_modified/cruft/xbm2font.pl @@ -0,0 +1,29 @@ +#!/usr/bin/perl -w + +use bytes; + +$c = 0; + +while(<>) { + next unless @bytes = (/0x([0-9a-fA-F]{2})/g); + for(@bytes) { + if(!($c % 8)) { + print " .byte "; + } + + printf "\$%02X", reverse_bits(hex $_); + + if(($c % 8 == 7) || ($c == $#bytes)) { + print "\n"; + $c = 0; + } else { + print ","; + $c++; + } + } +} + +sub reverse_bits { + my $bitstr = reverse sprintf("%08b", $_[0]); + return eval "0b$bitstr"; +} diff --git a/src/col80_modified/dos_20s.atr b/src/col80_modified/dos_20s.atr Binary files differnew file mode 100755 index 0000000..8016b73 --- /dev/null +++ b/src/col80_modified/dos_20s.atr diff --git a/src/col80_modified/font2xbm.pl b/src/col80_modified/font2xbm.pl new file mode 100644 index 0000000..c0ec3be --- /dev/null +++ b/src/col80_modified/font2xbm.pl @@ -0,0 +1,48 @@ +#!/usr/bin/perl -w + +use bytes; + +$name = "xbm"; +$width = 8; +$height = 384; +#$height = 512; +$cwidth = $width / 8; +$cheight = $height / 8; + +print <<EOF; +#define ${name}_width ${width} +#define ${name}_height ${height} +static unsigned char ${name}_bits[] = { +EOF + +undef $/; +$_ = <>; +@inbytes = split ""; + +# reverse bits, print 12 bytes/line + +$c = 0; +for($i=0; $i<@inbytes; $i++) { + $byte = ord $inbytes[$i]; + if(!$c) { + print " "; + } + + printf "0x%02x", reverse_bits($byte); + if($i != $#inbytes) { + if($c == 12) { + print ",\n"; + $c = 0; + } else { + print ", "; + $c++; + } + } +} + +print " };\n"; + +sub reverse_bits { + my $bitstr = reverse sprintf("%08b", $_[0]); + return eval "0b$bitstr"; +} diff --git a/src/col80_modified/icet.xbm b/src/col80_modified/icet.xbm new file mode 100644 index 0000000..946753b --- /dev/null +++ b/src/col80_modified/icet.xbm @@ -0,0 +1,43 @@ +#define xbm_width 8 +#define xbm_height 512 +static unsigned char xbm_bits[] = { + 0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0x20, 0x00, 0x00, 0x55, 0x75, 0x50, 0x70, + 0x50, 0x00, 0x00, 0x02, 0x16, 0x41, 0x22, 0x14, 0x43, 0x02, 0x00, 0x00, 0x42, + 0x25, 0x02, 0x05, 0x02, 0x04, 0x00, 0x00, 0x14, 0x22, 0x22, 0x22, 0x22, 0x14, + 0x00, 0x00, 0x25, 0x22, 0x77, 0x22, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x02, 0x01, 0x00, 0x40, 0x40, 0x20, 0x20, 0x12, 0x12, 0x00, 0x00, + 0x22, 0x35, 0x25, 0x25, 0x25, 0x72, 0x00, 0x00, 0x32, 0x45, 0x34, 0x42, 0x41, + 0x37, 0x00, 0x00, 0x75, 0x15, 0x35, 0x46, 0x44, 0x34, 0x00, 0x00, 0x72, 0x41, + 0x23, 0x25, 0x15, 0x12, 0x00, 0x00, 0x22, 0x55, 0x52, 0x65, 0x45, 0x22, 0x00, + 0x00, 0x00, 0x22, 0x00, 0x20, 0x22, 0x10, 0x00, 0x00, 0x04, 0x72, 0x01, 0x72, + 0x04, 0x00, 0x00, 0x00, 0x21, 0x52, 0x44, 0x22, 0x01, 0x20, 0x00, 0x00, 0x22, + 0x57, 0x57, 0x75, 0x51, 0x56, 0x00, 0x00, 0x63, 0x15, 0x13, 0x15, 0x15, 0x67, + 0x00, 0x00, 0x73, 0x15, 0x75, 0x15, 0x15, 0x73, 0x00, 0x00, 0x67, 0x11, 0x17, + 0x51, 0x51, 0x61, 0x00, 0x00, 0x75, 0x25, 0x27, 0x25, 0x25, 0x75, 0x00, 0x00, + 0x56, 0x54, 0x34, 0x54, 0x55, 0x52, 0x00, 0x00, 0x51, 0x71, 0x51, 0x51, 0x51, + 0x57, 0x00, 0x00, 0x74, 0x55, 0x57, 0x57, 0x55, 0x71, 0x00, 0x00, 0x73, 0x55, + 0x55, 0x53, 0x71, 0x41, 0x00, 0x00, 0x63, 0x15, 0x23, 0x45, 0x45, 0x35, 0x00, + 0x00, 0x57, 0x52, 0x52, 0x52, 0x52, 0x72, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, + 0x72, 0x52, 0x00, 0x00, 0x55, 0x55, 0x52, 0x22, 0x25, 0x25, 0x00, 0x00, 0x67, + 0x24, 0x22, 0x21, 0x21, 0x67, 0x00, 0x00, 0x31, 0x21, 0x22, 0x22, 0x24, 0x34, + 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x70, 0x00, 0x25, 0x2a, 0x25, 0xea, + 0x25, 0x2a, 0x25, 0x2a, 0x28, 0x28, 0x28, 0x38, 0x08, 0x08, 0x08, 0x08, 0x02, + 0x02, 0x02, 0x33, 0x22, 0x22, 0x22, 0x22, 0x00, 0x22, 0x52, 0x27, 0x07, 0x02, + 0x02, 0x00, 0x00, 0x42, 0x27, 0x12, 0x20, 0x47, 0x70, 0x00, 0x00, 0x01, 0xf2, + 0x54, 0x52, 0x51, 0x57, 0x00, 0x00, 0x24, 0x37, 0x22, 0x77, 0x21, 0x70, 0x00, + 0xf0, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xe0, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, + 0x00, 0x0f, 0x00, 0xf0, 0x00, 0x00, 0x01, 0x01, 0x01, 0xf1, 0x21, 0x21, 0x21, + 0x21, 0x02, 0x02, 0x02, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0xa2, 0xd2, 0xf2, 0xde, + 0x00, 0x10, 0x10, 0x50, 0x00, 0x00, 0x18, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x08, 0x4c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x34, 0x40, 0x70, 0x50, + 0x70, 0x00, 0x00, 0x01, 0x61, 0x13, 0x15, 0x15, 0x63, 0x00, 0x00, 0x04, 0x24, + 0x56, 0x75, 0x15, 0x66, 0x00, 0x00, 0x06, 0x61, 0x57, 0x51, 0x61, 0x41, 0x30, + 0x00, 0x21, 0x01, 0x33, 0x25, 0x25, 0x65, 0x00, 0x00, 0x14, 0x10, 0x54, 0x34, + 0x54, 0x54, 0x03, 0x00, 0x03, 0x52, 0x72, 0x52, 0x52, 0x56, 0x00, 0x00, 0x00, + 0x23, 0x55, 0x55, 0x55, 0x25, 0x00, 0x00, 0x00, 0x63, 0x55, 0x55, 0x63, 0x41, + 0x41, 0x00, 0x00, 0x66, 0x11, 0x21, 0x41, 0x31, 0x00, 0x00, 0x02, 0x57, 0x52, + 0x52, 0x52, 0x76, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x72, 0x52, 0x00, 0x00, + 0x00, 0x55, 0x55, 0x52, 0x65, 0x45, 0x30, 0x00, 0x60, 0x27, 0x14, 0x22, 0x21, + 0x67, 0x00, 0x02, 0x32, 0x22, 0x42, 0x22, 0x22, 0x32, 0x02, 0x0f, 0x2f, 0x2f, + 0x2f, 0x2f, 0x2f, 0x2f, 0x0f }; diff --git a/src/col80_modified/icet_packed.fnt b/src/col80_modified/icet_packed.fnt Binary files differnew file mode 100644 index 0000000..2b599b8 --- /dev/null +++ b/src/col80_modified/icet_packed.fnt diff --git a/src/col80_modified/icet_to_col80 b/src/col80_modified/icet_to_col80 Binary files differnew file mode 100755 index 0000000..9dac02c --- /dev/null +++ b/src/col80_modified/icet_to_col80 diff --git a/src/col80_modified/icet_to_col80.c b/src/col80_modified/icet_to_col80.c new file mode 100644 index 0000000..aa07223 --- /dev/null +++ b/src/col80_modified/icet_to_col80.c @@ -0,0 +1,26 @@ +#include <stdio.h> + +int main(int argc, char **argv) { + int c, d, byte = 0; + char out[8]; + + do { + c = getchar(); + if(byte == 16) { + for(byte = 0; byte < 8; ++byte) + putchar(out[byte]); + + byte = 0; + } + + if(c != EOF) { + if(byte < 8) { + out[byte] = (c & 0xf0); + ++byte; + } else if(byte < 16) { + out[byte - 8] |= (c & 0x0f); + ++byte; + } + } + } while(c != EOF); +} diff --git a/src/col80_modified/icet_vt.fnt b/src/col80_modified/icet_vt.fnt Binary files differnew file mode 100644 index 0000000..7c29cd1 --- /dev/null +++ b/src/col80_modified/icet_vt.fnt diff --git a/src/col80_modified/icetmod.raw b/src/col80_modified/icetmod.raw Binary files differnew file mode 100644 index 0000000..59e1331 --- /dev/null +++ b/src/col80_modified/icetmod.raw diff --git a/src/col80_modified/icetmod.s b/src/col80_modified/icetmod.s new file mode 100644 index 0000000..0c11274 --- /dev/null +++ b/src/col80_modified/icetmod.s @@ -0,0 +1,48 @@ + .byte $00,$02,$02,$02,$02,$00,$02,$00 + .byte $00,$55,$57,$05,$07,$05,$00,$00 + .byte $20,$34,$41,$22,$14,$61,$20,$00 + .byte $20,$31,$42,$30,$40,$30,$20,$00 + .byte $00,$14,$22,$22,$22,$22,$14,$00 + .byte $00,$52,$22,$77,$22,$52,$00,$00 + .byte $00,$00,$00,$07,$00,$20,$20,$40 + .byte $00,$01,$01,$02,$02,$24,$24,$00 + .byte $00,$22,$56,$52,$52,$52,$27,$00 + .byte $00,$26,$51,$16,$21,$41,$76,$00 + .byte $00,$57,$54,$56,$31,$11,$16,$00 + .byte $00,$27,$41,$62,$52,$54,$24,$00 + .byte $00,$22,$55,$25,$53,$51,$22,$00 + .byte $00,$00,$22,$00,$02,$22,$04,$00 + .byte $00,$10,$27,$40,$27,$10,$00,$00 + .byte $00,$42,$25,$11,$22,$40,$02,$00 + .byte $00,$22,$75,$75,$57,$45,$35,$00 + .byte $00,$63,$54,$64,$54,$54,$73,$00 + .byte $00,$67,$54,$57,$54,$54,$67,$00 + .byte $00,$73,$44,$74,$45,$45,$43,$00 + .byte $00,$57,$52,$72,$52,$52,$57,$00 + .byte $00,$35,$15,$16,$15,$55,$25,$00 + .byte $00,$4A,$4F,$4F,$49,$49,$79,$00 + .byte $00,$67,$55,$55,$55,$55,$57,$00 + .byte $00,$67,$55,$55,$65,$47,$41,$00 + .byte $00,$63,$54,$62,$51,$51,$56,$00 + .byte $00,$75,$25,$25,$25,$25,$27,$00 + .byte $00,$59,$59,$59,$5F,$2F,$2A,$00 + .byte $00,$55,$55,$25,$22,$52,$52,$00 + .byte $00,$73,$12,$22,$42,$42,$73,$00 + .byte $00,$46,$42,$22,$22,$12,$16,$00 + .byte $00,$20,$50,$00,$00,$00,$07,$00 + .byte $00,$20,$16,$01,$07,$05,$07,$00 + .byte $00,$40,$43,$64,$54,$54,$63,$00 + .byte $00,$10,$12,$35,$57,$54,$33,$00 + .byte $00,$30,$43,$75,$45,$43,$41,$06 + .byte $00,$42,$40,$66,$52,$52,$53,$00 + .byte $00,$14,$04,$15,$16,$15,$15,$60 + .byte $00,$60,$25,$27,$25,$25,$35,$00 + .byte $00,$00,$62,$55,$55,$55,$52,$00 + .byte $00,$00,$63,$55,$55,$63,$41,$41 + .byte $00,$00,$33,$44,$42,$41,$46,$00 + .byte $00,$20,$75,$25,$25,$25,$37,$00 + .byte $00,$00,$55,$55,$55,$27,$25,$00 + .byte $00,$00,$55,$55,$25,$53,$51,$06 + .byte $00,$03,$72,$14,$22,$42,$73,$00 + .byte $20,$26,$22,$21,$22,$22,$26,$20 + .byte $07,$01,$54,$A1,$04,$01,$04,$07 diff --git a/src/col80_modified/icetmod.xbm b/src/col80_modified/icetmod.xbm new file mode 100644 index 0000000..fb61a13 --- /dev/null +++ b/src/col80_modified/icetmod.xbm @@ -0,0 +1,35 @@ +#define icetmod_width 8 +#define icetmod_height 384 +static unsigned char icetmod_bits[] = { + 0x00, 0x40, 0x40, 0x40, 0x40, 0x00, 0x40, 0x00, 0x00, 0xaa, 0xea, 0xa0, + 0xe0, 0xa0, 0x00, 0x00, 0x04, 0x2c, 0x82, 0x44, 0x28, 0x86, 0x04, 0x00, + 0x04, 0x8c, 0x42, 0x0c, 0x02, 0x0c, 0x04, 0x00, 0x00, 0x28, 0x44, 0x44, + 0x44, 0x44, 0x28, 0x00, 0x00, 0x4a, 0x44, 0xee, 0x44, 0x4a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xe0, 0x00, 0x04, 0x04, 0x02, 0x00, 0x80, 0x80, 0x40, + 0x40, 0x24, 0x24, 0x00, 0x00, 0x44, 0x6a, 0x4a, 0x4a, 0x4a, 0xe4, 0x00, + 0x00, 0x64, 0x8a, 0x68, 0x84, 0x82, 0x6e, 0x00, 0x00, 0xea, 0x2a, 0x6a, + 0x8c, 0x88, 0x68, 0x00, 0x00, 0xe4, 0x82, 0x46, 0x4a, 0x2a, 0x24, 0x00, + 0x00, 0x44, 0xaa, 0xa4, 0xca, 0x8a, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, + 0x40, 0x44, 0x20, 0x00, 0x00, 0x08, 0xe4, 0x02, 0xe4, 0x08, 0x00, 0x00, + 0x00, 0x42, 0xa4, 0x88, 0x44, 0x02, 0x40, 0x00, 0x00, 0x44, 0xae, 0xae, + 0xea, 0xa2, 0xac, 0x00, 0x00, 0xc6, 0x2a, 0x26, 0x2a, 0x2a, 0xce, 0x00, + 0x00, 0xe6, 0x2a, 0xea, 0x2a, 0x2a, 0xe6, 0x00, 0x00, 0xce, 0x22, 0x2e, + 0xa2, 0xa2, 0xc2, 0x00, 0x00, 0xea, 0x4a, 0x4e, 0x4a, 0x4a, 0xea, 0x00, + 0x00, 0xac, 0xa8, 0x68, 0xa8, 0xaa, 0xa4, 0x00, 0x00, 0x52, 0xf2, 0xf2, + 0x92, 0x92, 0x9e, 0x00, 0x00, 0xe6, 0xaa, 0xaa, 0xaa, 0xaa, 0xea, 0x00, + 0x00, 0xe6, 0xaa, 0xaa, 0xa6, 0xe2, 0x82, 0x00, 0x00, 0xc6, 0x2a, 0x46, + 0x8a, 0x8a, 0x6a, 0x00, 0x00, 0xae, 0xa4, 0xa4, 0xa4, 0xa4, 0xe4, 0x00, + 0x00, 0x9a, 0x9a, 0x9a, 0xfa, 0xf4, 0x54, 0x00, 0x00, 0xaa, 0xaa, 0xa4, + 0x44, 0x4a, 0x4a, 0x00, 0x00, 0xce, 0x48, 0x44, 0x42, 0x42, 0xce, 0x00, + 0x00, 0x62, 0x42, 0x44, 0x44, 0x48, 0x68, 0x00, 0x00, 0x04, 0x0a, 0x00, + 0x00, 0x00, 0xe0, 0x00, 0x00, 0x04, 0x68, 0x80, 0xe0, 0xa0, 0xe0, 0x00, + 0x00, 0x02, 0xc2, 0x26, 0x2a, 0x2a, 0xc6, 0x00, 0x00, 0x08, 0x48, 0xac, + 0xea, 0x2a, 0xcc, 0x00, 0x00, 0x0c, 0xc2, 0xae, 0xa2, 0xc2, 0x82, 0x60, + 0x00, 0x42, 0x02, 0x66, 0x4a, 0x4a, 0xca, 0x00, 0x00, 0x28, 0x20, 0xa8, + 0x68, 0xa8, 0xa8, 0x06, 0x00, 0x06, 0xa4, 0xe4, 0xa4, 0xa4, 0xac, 0x00, + 0x00, 0x00, 0x46, 0xaa, 0xaa, 0xaa, 0x4a, 0x00, 0x00, 0x00, 0xc6, 0xaa, + 0xaa, 0xc6, 0x82, 0x82, 0x00, 0x00, 0xcc, 0x22, 0x42, 0x82, 0x62, 0x00, + 0x00, 0x04, 0xae, 0xa4, 0xa4, 0xa4, 0xec, 0x00, 0x00, 0x00, 0xaa, 0xaa, + 0xaa, 0xe4, 0xa4, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xa4, 0xca, 0x8a, 0x60, + 0x00, 0xc0, 0x4e, 0x28, 0x44, 0x42, 0xce, 0x00, 0x04, 0x64, 0x44, 0x84, + 0x44, 0x44, 0x64, 0x04, 0xe0, 0x80, 0x2a, 0x85, 0x20, 0x80, 0x20, 0xe0 }; diff --git a/src/col80_modified/icetmod_maybe.xbm b/src/col80_modified/icetmod_maybe.xbm new file mode 100644 index 0000000..60bc84c --- /dev/null +++ b/src/col80_modified/icetmod_maybe.xbm @@ -0,0 +1,35 @@ +#define icetmod_width 8 +#define icetmod_height 384 +static unsigned char icetmod_bits[] = { + 0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0x20, 0x00, 0x00, 0x55, 0x75, 0x50, + 0x70, 0x50, 0x00, 0x00, 0x02, 0x16, 0x41, 0x22, 0x14, 0x43, 0x02, 0x00, + 0x02, 0x46, 0x21, 0x06, 0x01, 0x06, 0x02, 0x00, 0x00, 0x14, 0x22, 0x22, + 0x22, 0x22, 0x14, 0x00, 0x00, 0x25, 0x22, 0x77, 0x22, 0x25, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, 0x02, 0x01, 0x00, 0x40, 0x40, 0x20, + 0x20, 0x12, 0x12, 0x00, 0x00, 0x22, 0x35, 0x25, 0x25, 0x25, 0x72, 0x00, + 0x00, 0x32, 0x45, 0x34, 0x42, 0x41, 0x37, 0x00, 0x00, 0x75, 0x15, 0x35, + 0x46, 0x44, 0x34, 0x00, 0x00, 0x72, 0x41, 0x23, 0x25, 0x15, 0x12, 0x00, + 0x00, 0x22, 0x55, 0x52, 0x65, 0x45, 0x22, 0x00, 0x00, 0x00, 0x22, 0x00, + 0x20, 0x22, 0x10, 0x00, 0x00, 0x04, 0x72, 0x01, 0x72, 0x04, 0x00, 0x00, + 0x00, 0x21, 0x52, 0x44, 0x22, 0x01, 0x20, 0x00, 0x00, 0x22, 0x57, 0x57, + 0x75, 0x51, 0x56, 0x00, 0x00, 0x63, 0x15, 0x13, 0x15, 0x15, 0x67, 0x00, + 0x00, 0x73, 0x15, 0x75, 0x15, 0x15, 0x73, 0x00, 0x00, 0x67, 0x11, 0x17, + 0x51, 0x51, 0x61, 0x00, 0x00, 0x75, 0x25, 0x27, 0x25, 0x25, 0x75, 0x00, + 0x00, 0x56, 0x54, 0x34, 0x54, 0x55, 0x52, 0x00, 0x00, 0x51, 0x71, 0x51, + 0x51, 0x51, 0x57, 0x00, 0x00, 0x73, 0x55, 0x55, 0x55, 0x55, 0x75, 0x00, + 0x00, 0x73, 0x55, 0x55, 0x53, 0x71, 0x41, 0x00, 0x00, 0x63, 0x15, 0x23, + 0x45, 0x45, 0x35, 0x00, 0x00, 0x57, 0x52, 0x52, 0x52, 0x52, 0x72, 0x00, + 0x00, 0x55, 0x55, 0x55, 0x55, 0x72, 0x52, 0x00, 0x00, 0x55, 0x55, 0x52, + 0x22, 0x25, 0x25, 0x00, 0x00, 0x67, 0x24, 0x22, 0x21, 0x21, 0x67, 0x00, + 0x00, 0x31, 0x21, 0x22, 0x22, 0x24, 0x34, 0x00, 0x00, 0x02, 0x05, 0x00, + 0x00, 0x00, 0x70, 0x00, 0x00, 0x02, 0x34, 0x40, 0x70, 0x50, 0x70, 0x00, + 0x00, 0x01, 0x61, 0x13, 0x15, 0x15, 0x63, 0x00, 0x00, 0x04, 0x24, 0x56, + 0x75, 0x15, 0x66, 0x00, 0x00, 0x06, 0x61, 0x57, 0x51, 0x61, 0x41, 0x30, + 0x00, 0x21, 0x01, 0x33, 0x25, 0x25, 0x65, 0x00, 0x00, 0x14, 0x10, 0x54, + 0x34, 0x54, 0x54, 0x03, 0x00, 0x03, 0x52, 0x72, 0x52, 0x52, 0x56, 0x00, + 0x00, 0x00, 0x23, 0x55, 0x55, 0x55, 0x25, 0x00, 0x00, 0x00, 0x63, 0x55, + 0x55, 0x63, 0x41, 0x41, 0x00, 0x00, 0x66, 0x11, 0x21, 0x41, 0x31, 0x00, + 0x00, 0x02, 0x57, 0x52, 0x52, 0x52, 0x76, 0x00, 0x00, 0x00, 0x55, 0x55, + 0x55, 0x72, 0x52, 0x00, 0x00, 0x00, 0x55, 0x55, 0x52, 0x65, 0x45, 0x30, + 0x00, 0x60, 0x27, 0x14, 0x22, 0x21, 0x67, 0x00, 0x02, 0x32, 0x22, 0x42, + 0x22, 0x22, 0x32, 0x02, 0x00, 0x20, 0x2a, 0x25, 0x20, 0x20, 0x20, 0x00 }; diff --git a/src/col80_modified/icetmod_old.xbm b/src/col80_modified/icetmod_old.xbm new file mode 100644 index 0000000..01fa394 --- /dev/null +++ b/src/col80_modified/icetmod_old.xbm @@ -0,0 +1,35 @@ +#define icetmod_width 8 +#define icetmod_height 384 +static unsigned char icetmod_bits[] = { + 0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0x20, 0x00, 0x00, 0x55, 0x75, 0x50, + 0x70, 0x50, 0x00, 0x00, 0x02, 0x16, 0x41, 0x22, 0x14, 0x43, 0x02, 0x00, + 0x00, 0x42, 0x25, 0x02, 0x05, 0x02, 0x04, 0x00, 0x00, 0x14, 0x22, 0x22, + 0x22, 0x22, 0x14, 0x00, 0x00, 0x25, 0x22, 0x77, 0x22, 0x25, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, 0x02, 0x01, 0x00, 0x40, 0x40, 0x20, + 0x20, 0x12, 0x12, 0x00, 0x00, 0x22, 0x35, 0x25, 0x25, 0x25, 0x72, 0x00, + 0x00, 0x32, 0x45, 0x34, 0x42, 0x41, 0x37, 0x00, 0x00, 0x75, 0x15, 0x35, + 0x46, 0x44, 0x34, 0x00, 0x00, 0x72, 0x41, 0x23, 0x25, 0x15, 0x12, 0x00, + 0x00, 0x22, 0x55, 0x52, 0x65, 0x45, 0x22, 0x00, 0x00, 0x00, 0x22, 0x00, + 0x20, 0x22, 0x10, 0x00, 0x00, 0x04, 0x72, 0x01, 0x72, 0x04, 0x00, 0x00, + 0x00, 0x21, 0x52, 0x44, 0x22, 0x01, 0x20, 0x00, 0x00, 0x22, 0x57, 0x57, + 0x75, 0x51, 0x56, 0x00, 0x00, 0x63, 0x15, 0x13, 0x15, 0x15, 0x67, 0x00, + 0x00, 0x73, 0x15, 0x75, 0x15, 0x15, 0x73, 0x00, 0x00, 0x67, 0x11, 0x17, + 0x51, 0x51, 0x61, 0x00, 0x00, 0x75, 0x25, 0x27, 0x25, 0x25, 0x75, 0x00, + 0x00, 0x56, 0x54, 0x34, 0x54, 0x55, 0x52, 0x00, 0x00, 0x51, 0x71, 0x51, + 0x51, 0x51, 0x57, 0x00, 0x00, 0x74, 0x55, 0x57, 0x57, 0x55, 0x71, 0x00, + 0x00, 0x73, 0x55, 0x55, 0x53, 0x71, 0x41, 0x00, 0x00, 0x63, 0x15, 0x23, + 0x45, 0x45, 0x35, 0x00, 0x00, 0x57, 0x52, 0x52, 0x52, 0x52, 0x72, 0x00, + 0x00, 0x55, 0x55, 0x55, 0x55, 0x72, 0x52, 0x00, 0x00, 0x55, 0x55, 0x52, + 0x22, 0x25, 0x25, 0x00, 0x00, 0x67, 0x24, 0x22, 0x21, 0x21, 0x67, 0x00, + 0x00, 0x31, 0x21, 0x22, 0x22, 0x24, 0x34, 0x00, 0x00, 0x02, 0x05, 0x00, + 0x00, 0x00, 0x70, 0x00, 0x00, 0x02, 0x34, 0x40, 0x70, 0x50, 0x70, 0x00, + 0x00, 0x01, 0x61, 0x13, 0x15, 0x15, 0x63, 0x00, 0x00, 0x04, 0x24, 0x56, + 0x75, 0x15, 0x66, 0x00, 0x00, 0x06, 0x61, 0x57, 0x51, 0x61, 0x41, 0x30, + 0x00, 0x21, 0x01, 0x33, 0x25, 0x25, 0x65, 0x00, 0x00, 0x14, 0x10, 0x54, + 0x34, 0x54, 0x54, 0x03, 0x00, 0x03, 0x52, 0x72, 0x52, 0x52, 0x56, 0x00, + 0x00, 0x00, 0x23, 0x55, 0x55, 0x55, 0x25, 0x00, 0x00, 0x00, 0x63, 0x55, + 0x55, 0x63, 0x41, 0x41, 0x00, 0x00, 0x66, 0x11, 0x21, 0x41, 0x31, 0x00, + 0x00, 0x02, 0x57, 0x52, 0x52, 0x52, 0x76, 0x00, 0x00, 0x00, 0x55, 0x55, + 0x55, 0x72, 0x52, 0x00, 0x00, 0x00, 0x55, 0x55, 0x52, 0x65, 0x45, 0x30, + 0x00, 0x60, 0x27, 0x14, 0x22, 0x21, 0x67, 0x00, 0x02, 0x32, 0x22, 0x42, + 0x22, 0x22, 0x32, 0x02, 0x00, 0x20, 0x2a, 0x25, 0x20, 0x20, 0x20, 0x00 }; diff --git a/src/col80_modified/lsr.pl b/src/col80_modified/lsr.pl new file mode 100644 index 0000000..915f769 --- /dev/null +++ b/src/col80_modified/lsr.pl @@ -0,0 +1,29 @@ +#!/usr/bin/perl -w + +use bytes; + +$c = 0; + +while(<>) { + next unless @bytes = (/0x([0-9a-fA-F]{2})/g); + for(@bytes) { + if(!($c % 8)) { + print " .byte "; + } + + printf "\$%02X", (reverse_bits(hex $_) >> 1); + + if(($c % 8 == 7) || ($c == $#bytes)) { + print "\n"; + $c = 0; + } else { + print ","; + $c++; + } + } +} + +sub reverse_bits { + my $bitstr = reverse sprintf("%08b", $_[0]); + return eval "0b$bitstr"; +} diff --git a/src/col80_modified/new_font.s b/src/col80_modified/new_font.s new file mode 100644 index 0000000..f4fcfa4 --- /dev/null +++ b/src/col80_modified/new_font.s @@ -0,0 +1,48 @@ + .byte $00,$04,$04,$04,$04,$00,$04,$00 + .byte $00,$AA,$AE,$0A,$0E,$0A,$00,$00 + .byte $40,$68,$82,$44,$28,$C2,$40,$00 + .byte $40,$62,$84,$60,$80,$60,$40,$00 + .byte $00,$28,$44,$44,$44,$44,$28,$00 + .byte $00,$A4,$44,$EE,$44,$A4,$00,$00 + .byte $00,$00,$00,$0E,$00,$40,$40,$80 + .byte $00,$02,$02,$04,$04,$48,$48,$00 + .byte $00,$44,$AC,$A4,$A4,$A4,$4E,$00 + .byte $00,$4C,$A2,$2C,$42,$82,$EC,$00 + .byte $00,$AE,$A8,$AC,$62,$22,$2C,$00 + .byte $00,$4E,$82,$C4,$A4,$A8,$48,$00 + .byte $00,$44,$AA,$4A,$A6,$A2,$44,$00 + .byte $00,$00,$44,$00,$04,$44,$08,$00 + .byte $00,$20,$4E,$80,$4E,$20,$00,$00 + .byte $00,$84,$4A,$22,$44,$80,$04,$00 + .byte $00,$44,$EA,$EA,$AE,$8A,$6A,$00 + .byte $00,$C6,$A8,$C8,$A8,$A8,$E6,$00 + .byte $00,$CE,$A8,$AE,$A8,$A8,$CE,$00 + .byte $00,$E6,$88,$E8,$8A,$8A,$86,$00 + .byte $00,$AE,$A4,$E4,$A4,$A4,$AE,$00 + .byte $00,$6A,$2A,$2C,$2A,$AA,$4A,$00 + .byte $00,$8A,$8E,$8A,$8A,$8A,$EA,$00 + .byte $00,$CE,$AA,$AA,$AA,$AA,$AE,$00 + .byte $00,$CE,$AA,$AA,$CA,$8E,$82,$00 + .byte $00,$C6,$A8,$C4,$A2,$A2,$AC,$00 + .byte $00,$EA,$4A,$4A,$4A,$4A,$4E,$00 + .byte $00,$AA,$AA,$AA,$AA,$4E,$4A,$00 + .byte $00,$AA,$AA,$4A,$44,$A4,$A4,$00 + .byte $00,$E6,$24,$44,$84,$84,$E6,$00 + .byte $00,$8C,$84,$44,$44,$24,$2C,$00 + .byte $00,$40,$A0,$00,$00,$00,$0E,$00 + .byte $00,$40,$2C,$02,$0E,$0A,$0E,$00 + .byte $00,$80,$86,$C8,$A8,$A8,$C6,$00 + .byte $00,$20,$24,$6A,$AE,$A8,$66,$00 + .byte $00,$60,$86,$EA,$8A,$86,$82,$0C + .byte $00,$84,$80,$CC,$A4,$A4,$A6,$00 + .byte $00,$28,$08,$2A,$2C,$2A,$2A,$C0 + .byte $00,$C0,$4A,$4E,$4A,$4A,$6A,$00 + .byte $00,$00,$C4,$AA,$AA,$AA,$A4,$00 + .byte $00,$00,$C6,$AA,$AA,$C6,$82,$82 + .byte $00,$00,$66,$88,$84,$82,$8C,$00 + .byte $00,$40,$EA,$4A,$4A,$4A,$6E,$00 + .byte $00,$00,$AA,$AA,$AA,$4E,$4A,$00 + .byte $00,$00,$AA,$AA,$4A,$A6,$A2,$0C + .byte $00,$06,$E4,$28,$44,$84,$E6,$00 + .byte $40,$4C,$44,$42,$44,$44,$4C,$40 + .byte $00,$04,$54,$A4,$04,$04,$04,$00 diff --git a/src/col80_modified/t.dasm b/src/col80_modified/t.dasm new file mode 100644 index 0000000..e32d950 --- /dev/null +++ b/src/col80_modified/t.dasm @@ -0,0 +1,3 @@ + .processor 6502 + .org 0 + .include icetmod.s diff --git a/src/col80_modified/test.atr b/src/col80_modified/test.atr Binary files differnew file mode 100755 index 0000000..57b2d13 --- /dev/null +++ b/src/col80_modified/test.atr diff --git a/src/col80_modified/xbm2font.pl b/src/col80_modified/xbm2font.pl new file mode 100644 index 0000000..758d57e --- /dev/null +++ b/src/col80_modified/xbm2font.pl @@ -0,0 +1,29 @@ +#!/usr/bin/perl -w + +use bytes; + +$c = 0; + +while(<>) { + next unless @bytes = (/0x([0-9a-fA-F]{2})/g); + for(@bytes) { + if(!($c % 8)) { + print " .byte "; + } + + printf "\$%02X", reverse_bits(hex $_); + + if(($c % 8 == 7) || ($c == $#bytes)) { + print "\n"; + $c = 0; + } else { + print ","; + $c++; + } + } +} + +sub reverse_bits { + my $bitstr = reverse sprintf("%08b", $_[0]); + return eval "0b$bitstr"; +} |