The 6502 version of the 64 column text code but it also supports 80 columns.
It can be assembled for the Acorn Atom (64 columns), Atari (64 or 80 columns), Plus/4 (80 columns), and C64 (80 columns)
80 columns requires 320 x 192, or 320 x 200 graphics resolutions.
While this code has much in common with the 6803 version, there are some significant differences.
Notes:
It can be assembled for the Acorn Atom (64 columns), Atari (64 or 80 columns), Plus/4 (80 columns), and C64 (80 columns)
80 columns requires 320 x 192, or 320 x 200 graphics resolutions.
While this code has much in common with the 6803 version, there are some significant differences.
Notes:
- The scroll uses columns rather than just rows. This was needed for speed.
- The address calculation and font data tables are unique to the 6502.
- This is a version from earlier this month but it is not the current version I'm working on.
- The Plus/4 code is almost complete, and the C64 code is preliminary. Neather have been assembled or tested yet, and the screen address tables might still need updating.
- I had trouble getting the assembler to properly generate the Atari display lists aligned on 256 byte boundaries, so you'll probably see some code that needs manual intervention reserving bytes to force the alignment. This is likely due to needing a new config setup for the assembler.
- The Atom code should still work, but I haven't assembled or tested it since adding the changes for the Atari or Commodores.
- Blogger barfed on the 1600+ lines of assembly, so the code has been split in two.
;************************************************** ;* File: print64.6502 ;************************************************** ;* Copyright (c) 2015, 2016, 2018 James Diffendaffer ;************************************************** ;* Description: ;* Emulates an 64 or 80 character by 24 line text display using ;* 4 bit wide characters on a 256 or 320 * 192 graphics display depending ;* on the target hardware. ;* This supports the Acorn Atom, Atari 8 bit, Commodore Plus/4, and Commodore 64 ;* ;* Contains functions to print a string at the current screen location, ;* print strings @ a specific screen location, line wrapping, scrolling, ;* clear screen, the character generator and a font. ;* Characters are stored with identical data in the left and right nibble ;* to make rendering faster and several loops have been unrolled for speed. ;* This code has been tested but has at least one known bug. ;* Assembles with the AS65 assembler included with the CC65 C compiler package. ;* ;* Derived from my Acorn Atom code ;************************************************** ;* Version history ;* Version Date Description ;* 0.19 Aug 6, 2018 Completed (mostly) initial Plus/4 version and added C64 hardware changes ;* 0.18 Aug 31, 2016 Added code to disable non maskable interrupts from the Atari hardware. MVN works now. ;* 0.17 Aug 27, 2016 80 Column code is working, added 65802/65816 memory move instruction option for scroll ;* 0.16 Aug 26, 2016 Changed page zero use for Atari, now runs fine in 64 columns. ;* 0.15 Aug 21, 2016 Added initial Atari 8 bit graphics support ;* 0.14 Nov 4, 2015 Added initial support for 80 columns and Commodore Plus/4, just starting Atari demo code ;* 0.13 Oct 6, 2015 Initial version with ability to print 2 characters at a time ;* 0.12 Oct 3, 2015 Additional unrolling of scroll loop, more code cleanup ;* 0.11 Oct 1, 2015 Integrated clearing last line of text display into the scroll ;* Code cleanup, inverted screen and BGColor addition ;* 0.09 Sept 30, 2015 Changed text printing code to use EOR to save clock cycles and shorten the code. ;* Added scroll that uses unrolled column scroll for faster speed, some dead code cleanup ;* 0.08 Sept 30, 2015 Added a CLC to the string generator code and changed CLC to SEC in print64 - Thanks Dave! ;* 0.07 Sept 30, 2015 Added CLC in several places to fix printing, scrolling, etc. Initial release version. ;* 0.06 Sept 29, 2015 Converted to AS65 assembler format, fixed a lot of # and > related bugs ;* 0.05 Sept 28, 2015 Bringing code in line with Z80 & 6803 versions ;* 0.04 Sept 20, 2015 Replaced LDA TAY with LDY and reordered code in left and right nibble print routines ;* 0.03 Sept 19, 2015 Added Atom ATM file header and started Plus/4 80 column version. ;* 0.02 Sept 9, 2015 Finished print@ and print functions ;* 0.01 Sept 8, 2015 Created initial 6502 character generation code ;************************************************** ;********************************************* ;* Pick the target machine here by setting to 1 ;********************************************* .define AcornAtom 0 .define Plus4 1 .define C64 0 .define Atari 0 ;********************************************* ;* Set to 1 to use 65816 code ;********************************************* .define Use65816 0 ;********************************************* ;* Font and and other universal defines ;********************************************* .define FontHeight 8 ; number of rows high the font is on screen .define efont EOF-font ; end of font .define unrollmore 1 ; increase loop unrolling ;********************************************* ;* 65816 support ;********************************************* .if Use65816 = 1 .P816 ;Memory Move Negative. Move from hi to lo address. ;Memory is moved at the rate of seven clock cycles per byte. ; MVN increments the X and Y registers, and decrements A .macro MOVEMEMN SourceAddress,DestAddress,BytesToMove,SourceBank,DestBank SEI ; LDA #0 ; STA NMIEN ; turn off ATARI non maskable interrupts for 65816 ; ; if you want to have it restored, you'll need a copy of the setting somewhere clc xce ; native mode rep #$31 ; set A, X, and Y to 16 bit, clear carry .A16 ; Tell assembler Accumulator is 16 bit .I16 ; Tell assembler Index registers are 16 bit LDX #SourceAddress ; The source address for the memory move LDY #DestAddress ; The destination address for the memory move LDA #BytesToMove-1 ; The number of bytes we want to move + 1 because MVN needs it MVN SourceBank,DestBank ; RAM banks, should be 00,00 on 64K system sep #$31 ; set A, X, and Y to 8 bits, set carry ; sec xce ; emulated mode .A8 ; Tell assembler Accumulator is 8 bit .I8 ; Tell assembler Index registers are 8 bit ; LDA NMIENSHADOWREGISTER ; STA NMIEN ; restore non maskable interrupts for 65816 CLI .endmacro .endif ;********************************************* ;* Acorn Atom specific defines ;********************************************* .if AcornAtom = 1 ScreenAdr: equ $8000 ; screen address of Atom .define BytesPerLine 32 ; screen width of RG6 mode ScreenHeight: equ 192 ; screen height of RG6 mode .endif ;********************************************* ;* Commodore Plus/4 specific defines ;********************************************* .if Plus4 = 1 //Commodore Plus/4 related settings TED EQU $FF00 ; TED Base Address TEDVMR EQU TED+6 ; TED Video Mode register VBASEREG EQU TED+20 ; 5 bit video matrix base register ColorRAM EQU $8000 ; Base address of color RAM VIDBASE EQU $8C00 ; Base address of our Screen memory VASet EQU $88 ; Video Address setting for VBASEREG VMSet EQU #$36 ; %00110110 ; from bit 7 down to bit 0: ; 0 - test bit, always 0 ; 0 - Extended Color Mode off ; 1 - Bitmap Mode On ; 1 - Screen On ; 0 - 24 Rows ; 110 - Vertical Scroll Position ScreenAdr: equ VIDBASE ; screen address of Plus/4 .define BytesPerLine 40 ; screen width of 2 color bitmapped mode ScreenHeight: equ 200 ; screen height .endif ;********************************************* ;* Commodore 64 specific defines ;********************************************* .if C64 = 1 ScreenAdr: equ $6000 ; screen address of Plus/4 .define BytesPerLine 40 ; screen width of 2 color bitmapped mode ScreenHeight: equ 200 ; screen height .endif ;********************************************* ; Atari specific defines ;********************************************* .if Atari = 1 .define BytesPerLine 32 ; screen width of mode 8 narrow playfield ;.define BytesPerLine 40 ; screen width of mode 8 normal playfield ;This all means my DLIST needs 3 blank lines, mode 8 + LSM, screen address, 89 mode 8s, mode 8 + LSM, next screen address, 101 mode 8s, JVB dlist .if BytesPerLine = 32 .define SCREEN 30720 ;($9000-(32*64)-4096) ;6144 bytes , 2 4K blocks needed, 128 rows in last 4K block, 64 in first 4K block .elseif BytesPerLine = 40 .define SCREEN 29168 ; ($9000-(40*90)-4096) ;7680 bytes , 2 4K blocks needed, 102 rows in last 4K block, 90 in first 4K block .endif .define ScreenAdr SCREEN ;$74C0 ;36864-2880-4096 ; screen address of Atari .define ScreenHeight 192 ; screen height of mode 8 .endif ;********************************************* .BSS .ZEROPAGE ; page zero variables ; .org $0010 ; Acorn Atom .org $0040 ; page zero variables string: .res 2 ; string pointer prntat: .res 2 ; Print @ location like Microsoft BASIC row: .res 1 ; col: .res 1 ; temp0: .res 2 ; temporary storage fscreen: .res 2 ; screen pointer for character generator fscreen1: .res 2 ; screen pointer for character generator firstchar: .res 1 secondchar: .res 1 length: .res 2 ; for 16 bit operations ytemp: .res 1 ; temporary storage for y BGColor: .res 1 ; screen background color .CODE ;**************************** ; Acorn Atom build ;**************************** .if AcornAtom = 1 .org $2B00 - 22 ; start 22 bytes early for header ;**************************** ;* Acorn Atom ATM file header ;**************************** FNAME: .byt "PRINT64",0,0,0,0,0,0,0,0,0 ;File Name up to 12 characters + zero padding ADDRESS: .word START ;current address is load address EXECADD: .word START ;current address is execute address FLENGTH: .word (EOF-START) ;file length = end of file value (EOF) munus start address ;**************************** ; org $2B00 ; free RAM on Atom .endif ;**************************** ; Commodore Plus/4 build ;**************************** .if Plus4 = 1 .org $4000-2 ; start address -2 for prg header .word START ; the start address ;DB $0B,$10,0,0,$9E,"4109",0,0,0 .endif ;**************************** ; Atari build ;**************************** .if Atari = 1 ;.segment "BSS" ; .org $0000 ; xex block header ;.segment "EXEHDR" .org $0600 - 7 .word $FFFF .word START ; code/data start .word EOF - 1;START ; end .org $0600 .endif .code START: ;************************************************** ;* graphics text routine macros ;************************************************** ; To be used similar to Microsoft BASIC's PRINT@ .macro PRINTAT loc,str lda #<loc sta prntat lda #>loc sta prntat+1 lda #>str sta string lda #>str sta string+1 jsr print_at .endmacro ; print a string starting at the current position .macro PRINT str lda #<str sta string lda #>str sta string+1 jsr print .endmacro ; incrament a 16 bit number .macro inc16 addr .scope inc addr bne Skip inc addr+1 Skip: .endscope .endmacro ; decrement a 16 bit number .macro dec16 addr .scope dec addr bne Skip dec addr+1 Skip: .endscope .endmacro ; invert the font data to you can print in inverse text ; ` .macro InvertFont mfont,msize lda #<mfont sta fscreen lda #>mfont sta fscreen+1 lda #<msize sta length lda #>msize sta length+1 jsr invert_mem .endmacro ;************************************************** ;* NAME: textdemo ;************************************************** ;* DESCRIPTION: ;* a short program to demonstrate the use of ;* routines in the graphics library ;************************************************** Textdemo: ;save registers pha txa pha tya pha .if Use65816 = 1 .if Atari = 1 LDA #0 STA NMIEN ; turn off ATARI non maskable display interrupts for 65816 ; if you keep a copy of NMIEN somewhere, the macro can be altered to disable/enable the interrupts .endif .endif jsr InitScreen ; call unique setup routine for the machine this is assembled for ; InvertFont(font,efont) ; lda #<font ; sta fscreen ; lda #>font ; sta fscreen+1 ; ;1344 bytes ; lda #$40 ; sta length ; lda #$06 ; should be 06 by my code in the invert_mem doesn't work correctly yet ; sta length+1 ; jsr invert_mem lda #0 sta row sta col ; 64/80 character/line demo, prints entire character set lda #<String sta string lda #>String sta string+1 ldy #0 lda #' ' ; the first character in the font @loop: sta (string),y iny clc adc #1 ; increment a cmp #'~'+1 ; are we past the last character in the font? bne @loop lda #0 sta (string),y Endless: PRINT String ; print the string we just built clc bcc Endless ;restore registers pla tay pla tax pla rts ;************************************************** ;* cls ;************************************************** ;* clears the Atom hi-res screen ;************************************************** cls: .if BytesPerLine = 32 lda #0 tax lda BGColor @sloop: sta ScreenAdr+0*FontHeight*BytesPerLine,x sta ScreenAdr+1*FontHeight*BytesPerLine,x sta ScreenAdr+2*FontHeight*BytesPerLine,x sta ScreenAdr+3*FontHeight*BytesPerLine,x sta ScreenAdr+4*FontHeight*BytesPerLine,x sta ScreenAdr+5*FontHeight*BytesPerLine,x sta ScreenAdr+6*FontHeight*BytesPerLine,x sta ScreenAdr+7*FontHeight*BytesPerLine,x sta ScreenAdr+8*FontHeight*BytesPerLine,x sta ScreenAdr+9*FontHeight*BytesPerLine,x sta ScreenAdr+10*FontHeight*BytesPerLine,x sta ScreenAdr+11*FontHeight*BytesPerLine,x sta ScreenAdr+12*FontHeight*BytesPerLine,x sta ScreenAdr+13*FontHeight*BytesPerLine,x sta ScreenAdr+14*FontHeight*BytesPerLine,x sta ScreenAdr+15*FontHeight*BytesPerLine,x sta ScreenAdr+16*FontHeight*BytesPerLine,x sta ScreenAdr+17*FontHeight*BytesPerLine,x sta ScreenAdr+18*FontHeight*BytesPerLine,x sta ScreenAdr+19*FontHeight*BytesPerLine,x sta ScreenAdr+20*FontHeight*BytesPerLine,x sta ScreenAdr+21*FontHeight*BytesPerLine,x sta ScreenAdr+22*FontHeight*BytesPerLine,x sta ScreenAdr+23*FontHeight*BytesPerLine,x ; last line of 192 line display .if ScreenHeight = 200 sta ScreenAdr+24*FontHeight*BytesPerLine,x ; for 200 line high display .endif inx beq @nxt jmp @sloop @nxt: .endif .if BytesPerLine = 40 lda #0 tax lda BGColor @sloop: sta ScreenAdr+0*FontHeight*BytesPerLine,x sta ScreenAdr+0*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+1*FontHeight*BytesPerLine,x sta ScreenAdr+1*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+2*FontHeight*BytesPerLine,x sta ScreenAdr+2*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+3*FontHeight*BytesPerLine,x sta ScreenAdr+3*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+4*FontHeight*BytesPerLine,x sta ScreenAdr+4*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+5*FontHeight*BytesPerLine,x sta ScreenAdr+5*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+6*FontHeight*BytesPerLine,x sta ScreenAdr+6*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+7*FontHeight*BytesPerLine,x sta ScreenAdr+7*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+8*FontHeight*BytesPerLine,x sta ScreenAdr+8*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+9*FontHeight*BytesPerLine,x sta ScreenAdr+9*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+10*FontHeight*BytesPerLine,x sta ScreenAdr+10*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+11*FontHeight*BytesPerLine,x sta ScreenAdr+11*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+12*FontHeight*BytesPerLine,x sta ScreenAdr+12*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+13*FontHeight*BytesPerLine,x sta ScreenAdr+13*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+14*FontHeight*BytesPerLine,x sta ScreenAdr+14*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+15*FontHeight*BytesPerLine,x sta ScreenAdr+15*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+16*FontHeight*BytesPerLine,x sta ScreenAdr+16*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+17*FontHeight*BytesPerLine,x sta ScreenAdr+17*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+18*FontHeight*BytesPerLine,x sta ScreenAdr+18*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+19*FontHeight*BytesPerLine,x sta ScreenAdr+19*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+20*FontHeight*BytesPerLine,x sta ScreenAdr+20*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+21*FontHeight*BytesPerLine,x sta ScreenAdr+21*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+22*FontHeight*BytesPerLine,x sta ScreenAdr+22*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines sta ScreenAdr+23*FontHeight*BytesPerLine,x ; last line of 192 line display sta ScreenAdr+23*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines .if ScreenHeight = 200 sta ScreenAdr+24*FontHeight*BytesPerLine,x ; for 200 line high display sta ScreenAdr+24*FontHeight*BytesPerLine+40*4,x ; since x would overflow to do the job, we do half lines .endif inx cpx #160 bmi @nxt jmp @sloop @nxt: .endif rts ;************************************************** ;* scroll ;************************************************** ;* scrolls the hi-res text display ;* Copies byte from one row to the next, then copies over that byte, etc... ;* and clears bytes in the last line ;************************************************** scroll: .if Use65816 = 1 MOVEMEMN (ScreenAdr+(BytesPerLine*FontHeight)),ScreenAdr,((BytesPerLine*ScreenHeight)-(BytesPerLine*FontHeight)),0,0 ; clear last line ldx #(BytesPerLine*4)-1 lda BGColor @sloop: .if ScreenHeight = 192 sta ScreenAdr+23*FontHeight*BytesPerLine,x sta ScreenAdr+23*FontHeight*BytesPerLine+BytesPerLine*FontHeight/2,x .endif .if ScreenHeight = 200 sta ScreenAdr+24*FontHeight*BytesPerLine,x sta ScreenAdr+24*FontHeight*BytesPerLine+BytesPerLine*FontHeight/2,x .endif dex bne @sloop .else .if BytesPerLine = 32 ldx #0 @sloop: lda ScreenAdr+( 1*FontHeight*BytesPerLine),x sta ScreenAdr+( 0*FontHeight*BytesPerLine),x lda ScreenAdr+( 2*FontHeight*BytesPerLine),x sta ScreenAdr+( 1*FontHeight*BytesPerLine),x lda ScreenAdr+( 3*FontHeight*BytesPerLine),x sta ScreenAdr+( 2*FontHeight*BytesPerLine),x lda ScreenAdr+( 4*FontHeight*BytesPerLine),x sta ScreenAdr+( 3*FontHeight*BytesPerLine),x lda ScreenAdr+( 5*FontHeight*BytesPerLine),x sta ScreenAdr+( 4*FontHeight*BytesPerLine),x lda ScreenAdr+( 6*FontHeight*BytesPerLine),x sta ScreenAdr+( 5*FontHeight*BytesPerLine),x lda ScreenAdr+( 7*FontHeight*BytesPerLine),x sta ScreenAdr+( 6*FontHeight*BytesPerLine),x lda ScreenAdr+( 8*FontHeight*BytesPerLine),x sta ScreenAdr+( 7*FontHeight*BytesPerLine),x lda ScreenAdr+( 9*FontHeight*BytesPerLine),x sta ScreenAdr+( 8*FontHeight*BytesPerLine),x lda ScreenAdr+(10*FontHeight*BytesPerLine),x sta ScreenAdr+( 9*FontHeight*BytesPerLine),x lda ScreenAdr+(11*FontHeight*BytesPerLine),x sta ScreenAdr+(10*FontHeight*BytesPerLine),x lda ScreenAdr+(12*FontHeight*BytesPerLine),x sta ScreenAdr+(11*FontHeight*BytesPerLine),x lda ScreenAdr+(13*FontHeight*BytesPerLine),x sta ScreenAdr+(12*FontHeight*BytesPerLine),x lda ScreenAdr+(14*FontHeight*BytesPerLine),x sta ScreenAdr+(13*FontHeight*BytesPerLine),x lda ScreenAdr+(15*FontHeight*BytesPerLine),x sta ScreenAdr+(14*FontHeight*BytesPerLine),x lda ScreenAdr+(16*FontHeight*BytesPerLine),x sta ScreenAdr+(15*FontHeight*BytesPerLine),x lda ScreenAdr+(17*FontHeight*BytesPerLine),x sta ScreenAdr+(16*FontHeight*BytesPerLine),x lda ScreenAdr+(18*FontHeight*BytesPerLine),x sta ScreenAdr+(17*FontHeight*BytesPerLine),x lda ScreenAdr+(19*FontHeight*BytesPerLine),x sta ScreenAdr+(18*FontHeight*BytesPerLine),x lda ScreenAdr+(20*FontHeight*BytesPerLine),x sta ScreenAdr+(19*FontHeight*BytesPerLine),x lda ScreenAdr+(21*FontHeight*BytesPerLine),x sta ScreenAdr+(20*FontHeight*BytesPerLine),x lda ScreenAdr+(22*FontHeight*BytesPerLine),x sta ScreenAdr+(21*FontHeight*BytesPerLine),x lda ScreenAdr+(23*FontHeight*BytesPerLine),x sta ScreenAdr+(22*FontHeight*BytesPerLine),x .if ScreenHeight = 200 lda ScreenAdr+(24*FontHeight*BytesPerLine),x sta ScreenAdr+(23*FontHeight*BytesPerLine),x .endif .if unrollmore = 1 lda ScreenAdr+1*FontHeight*BytesPerLine+1,x sta ScreenAdr+0*FontHeight*BytesPerLine+1,x lda ScreenAdr+2*FontHeight*BytesPerLine+1,x sta ScreenAdr+1*FontHeight*BytesPerLine+1,x lda ScreenAdr+3*FontHeight*BytesPerLine+1,x sta ScreenAdr+2*FontHeight*BytesPerLine+1,x lda ScreenAdr+4*FontHeight*BytesPerLine+1,x sta ScreenAdr+3*FontHeight*BytesPerLine+1,x lda ScreenAdr+5*FontHeight*BytesPerLine+1,x sta ScreenAdr+4*FontHeight*BytesPerLine+1,x lda ScreenAdr+6*FontHeight*BytesPerLine+1,x sta ScreenAdr+5*FontHeight*BytesPerLine+1,x lda ScreenAdr+7*FontHeight*BytesPerLine+1,x sta ScreenAdr+6*FontHeight*BytesPerLine+1,x lda ScreenAdr+8*FontHeight*BytesPerLine+1,x sta ScreenAdr+7*FontHeight*BytesPerLine+1,x lda ScreenAdr+9*FontHeight*BytesPerLine+1,x sta ScreenAdr+8*FontHeight*BytesPerLine+1,x lda ScreenAdr+10*FontHeight*BytesPerLine+1,x sta ScreenAdr+9*FontHeight*BytesPerLine+1,x lda ScreenAdr+11*FontHeight*BytesPerLine+1,x sta ScreenAdr+10*FontHeight*BytesPerLine+1,x lda ScreenAdr+12*FontHeight*BytesPerLine+1,x sta ScreenAdr+11*FontHeight*BytesPerLine+1,x lda ScreenAdr+13*FontHeight*BytesPerLine+1,x sta ScreenAdr+12*FontHeight*BytesPerLine+1,x lda ScreenAdr+14*FontHeight*BytesPerLine+1,x sta ScreenAdr+13*FontHeight*BytesPerLine+1,x lda ScreenAdr+15*FontHeight*BytesPerLine+1,x sta ScreenAdr+14*FontHeight*BytesPerLine+1,x lda ScreenAdr+16*FontHeight*BytesPerLine+1,x sta ScreenAdr+15*FontHeight*BytesPerLine+1,x lda ScreenAdr+17*FontHeight*BytesPerLine+1,x sta ScreenAdr+16*FontHeight*BytesPerLine+1,x lda ScreenAdr+18*FontHeight*BytesPerLine+1,x sta ScreenAdr+17*FontHeight*BytesPerLine+1,x lda ScreenAdr+19*FontHeight*BytesPerLine+1,x sta ScreenAdr+18*FontHeight*BytesPerLine+1,x lda ScreenAdr+20*FontHeight*BytesPerLine+1,x sta ScreenAdr+19*FontHeight*BytesPerLine+1,x lda ScreenAdr+21*FontHeight*BytesPerLine+1,x sta ScreenAdr+20*FontHeight*BytesPerLine+1,x lda ScreenAdr+22*FontHeight*BytesPerLine+1,x sta ScreenAdr+21*FontHeight*BytesPerLine+1,x lda ScreenAdr+23*FontHeight*BytesPerLine+1,x sta ScreenAdr+22*FontHeight*BytesPerLine+1,x .if ScreenHeight = 200 lda ScreenAdr+24*FontHeight*BytesPerLine+1,x sta ScreenAdr+23*FontHeight*BytesPerLine+1,x .endif .endif lda BGColor ; clear last line .if ScreenHeight = 192 sta ScreenAdr+23*FontHeight*BytesPerLine,x .endif .if ScreenHeight = 200 sta ScreenAdr+24*FontHeight*BytesPerLine,x .endif .if unrollmore = 1 .if ScreenHeight = 192 sta ScreenAdr+23*FontHeight*BytesPerLine+1,x .endif .if ScreenHeight = 200 sta ScreenAdr+24*FontHeight*BytesPerLine+1,x .endif inx .endif inx beq @nxt jmp @sloop @nxt: .endif .if BytesPerLine = 40 ldx #0 @sloop: lda ScreenAdr+( 1*FontHeight*BytesPerLine),x sta ScreenAdr+( 0*FontHeight*BytesPerLine),x lda ScreenAdr+( 1*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+( 0*FontHeight*BytesPerLine)+40*4,x lda ScreenAdr+( 2*FontHeight*BytesPerLine),x sta ScreenAdr+( 1*FontHeight*BytesPerLine),x lda ScreenAdr+( 2*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+( 1*FontHeight*BytesPerLine)+40*4,x lda ScreenAdr+( 3*FontHeight*BytesPerLine),x sta ScreenAdr+( 2*FontHeight*BytesPerLine),x lda ScreenAdr+( 3*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+( 2*FontHeight*BytesPerLine)+40*4,x lda ScreenAdr+( 4*FontHeight*BytesPerLine),x sta ScreenAdr+( 3*FontHeight*BytesPerLine),x lda ScreenAdr+( 4*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+( 3*FontHeight*BytesPerLine)+40*4,x lda ScreenAdr+( 5*FontHeight*BytesPerLine),x sta ScreenAdr+( 4*FontHeight*BytesPerLine),x lda ScreenAdr+( 5*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+( 4*FontHeight*BytesPerLine)+40*4,x lda ScreenAdr+( 6*FontHeight*BytesPerLine),x sta ScreenAdr+( 5*FontHeight*BytesPerLine),x lda ScreenAdr+( 6*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+( 5*FontHeight*BytesPerLine)+40*4,x lda ScreenAdr+( 7*FontHeight*BytesPerLine),x sta ScreenAdr+( 6*FontHeight*BytesPerLine),x lda ScreenAdr+( 7*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+( 6*FontHeight*BytesPerLine)+40*4,x lda ScreenAdr+( 8*FontHeight*BytesPerLine),x sta ScreenAdr+( 7*FontHeight*BytesPerLine),x lda ScreenAdr+( 8*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+( 7*FontHeight*BytesPerLine)+40*4,x lda ScreenAdr+( 9*FontHeight*BytesPerLine),x sta ScreenAdr+( 8*FontHeight*BytesPerLine),x lda ScreenAdr+( 9*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+( 8*FontHeight*BytesPerLine)+40*4,x lda ScreenAdr+(10*FontHeight*BytesPerLine),x sta ScreenAdr+( 9*FontHeight*BytesPerLine),x lda ScreenAdr+(10*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+( 9*FontHeight*BytesPerLine)+40*4,x lda ScreenAdr+(11*FontHeight*BytesPerLine),x sta ScreenAdr+(10*FontHeight*BytesPerLine),x lda ScreenAdr+(11*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+(10*FontHeight*BytesPerLine)+40*4,x lda ScreenAdr+(12*FontHeight*BytesPerLine),x sta ScreenAdr+(11*FontHeight*BytesPerLine),x lda ScreenAdr+(12*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+(11*FontHeight*BytesPerLine)+40*4,x lda ScreenAdr+(13*FontHeight*BytesPerLine),x sta ScreenAdr+(12*FontHeight*BytesPerLine),x lda ScreenAdr+(13*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+(12*FontHeight*BytesPerLine)+40*4,x lda ScreenAdr+(14*FontHeight*BytesPerLine),x sta ScreenAdr+(13*FontHeight*BytesPerLine),x lda ScreenAdr+(14*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+(13*FontHeight*BytesPerLine)+40*4,x lda ScreenAdr+(15*FontHeight*BytesPerLine),x sta ScreenAdr+(14*FontHeight*BytesPerLine),x lda ScreenAdr+(15*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+(14*FontHeight*BytesPerLine)+40*4,x lda ScreenAdr+(16*FontHeight*BytesPerLine),x sta ScreenAdr+(15*FontHeight*BytesPerLine),x lda ScreenAdr+(16*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+(15*FontHeight*BytesPerLine)+40*4,x lda ScreenAdr+(17*FontHeight*BytesPerLine),x sta ScreenAdr+(16*FontHeight*BytesPerLine),x lda ScreenAdr+(17*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+(16*FontHeight*BytesPerLine)+40*4,x lda ScreenAdr+(18*FontHeight*BytesPerLine),x sta ScreenAdr+(17*FontHeight*BytesPerLine),x lda ScreenAdr+(18*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+(17*FontHeight*BytesPerLine)+40*4,x lda ScreenAdr+(19*FontHeight*BytesPerLine),x sta ScreenAdr+(18*FontHeight*BytesPerLine),x lda ScreenAdr+(19*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+(18*FontHeight*BytesPerLine)+40*4,x lda ScreenAdr+(20*FontHeight*BytesPerLine),x sta ScreenAdr+(19*FontHeight*BytesPerLine),x lda ScreenAdr+(20*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+(19*FontHeight*BytesPerLine)+40*4,x lda ScreenAdr+(21*FontHeight*BytesPerLine),x sta ScreenAdr+(20*FontHeight*BytesPerLine),x lda ScreenAdr+(21*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+(20*FontHeight*BytesPerLine)+40*4,x lda ScreenAdr+(22*FontHeight*BytesPerLine),x sta ScreenAdr+(21*FontHeight*BytesPerLine),x lda ScreenAdr+(22*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+(21*FontHeight*BytesPerLine)+40*4,x lda ScreenAdr+(23*FontHeight*BytesPerLine),x sta ScreenAdr+(22*FontHeight*BytesPerLine),x lda ScreenAdr+(23*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+(22*FontHeight*BytesPerLine)+40*4,x .if ScreenHeight = 192 lda BGColor ; clear last line sta ScreenAdr+23*FontHeight*BytesPerLine,x sta ScreenAdr+23*FontHeight*BytesPerLine+40*4,x .endif .if ScreenHeight = 200 lda ScreenAdr+(24*FontHeight*BytesPerLine),x sta ScreenAdr+(23*FontHeight*BytesPerLine),x lda ScreenAdr+(24*FontHeight*BytesPerLine)+40*4,x sta ScreenAdr+(23*FontHeight*BytesPerLine)+40*4,x lda BGColor ; clear last line sta ScreenAdr+24*FontHeight*BytesPerLine,x sta ScreenAdr+24*FontHeight*BytesPerLine+40*4,x .endif inx cpx #160 beq @nxt jmp @sloop @nxt: .endif .endif rts ;************************************************** ;* invert_mem ;************************************************** ;* length contains the length ;************************************************** invert_mem: ldy #0 nxtaddr: lda (fscreen),y ; get original byte eor #$FF ; invert it sta (fscreen),y ; write it back inc16 fscreen dec16 length bne nxtaddr rts ;************************************************** ;* print_at ;************************************************** ;* Prints a string at a screen location ;* works similar to print@ in Microsoft BASIC ;* prntat contains @ location ;* string contains string pointer ;* falls through to _print ;************************************************** print_at: lda prntat ; and #%00111111 ; mask off row bits (BytesPerLine*2)-1 sta col ; save the column lda prntat ; copy LSB and #%11000000 ; mask off column bits 254-(BytesPerLine*2) asl ; rotate bits into bottom of a asl ; rol? asl sta row ; lda prntat+1 asl asl ; clc adc row sta row ; save row info ;************************************************** ;* print ;************************************************** ;* Prints a zero terminated string at the current x,y location ;* string contains the string pointer ;* maximum sting length is 256 ;************************************************** print: ldy #0 prn1: lda col lsr bcs print1 ;try to print 2 characters at a time lda (string),y cmp #0 ; strings are zero terminated beq _printexit iny lda (string),y dey cmp #0 ; strings are zero terminated beq print1a ; if we get here, we can print 2 characters at once sty ytemp jsr print_642 ldy ytemp iny inc col clc ; branch always bcc print2a ; since we are writing two at once, we know we can't go two past the end of the line print1: lda (string),y ; get a character from the string cmp #0 ; strings are zero terminated beq _printexit ; exit if it's a zero print1a: sty ytemp ; save x jsr print_64 ; print the character ldy ytemp ; restore x ;update column, row, and scroll when needed print2a: inc col ; next column lda col ; get column cmp #BytesPerLine*2 ; BytesPerLine * 2 = characters per line ; cmp #64 ; 64 chars / line (0-63) bcc _cexit ; is column past the end of a line? lda #0 sta col ; set column to zero inc row ; incrament row lda row ; get row cmp #24 ; (ScreenHeight/8) ; 24 lines (0-23) bcc _cexit ; branch if row isn't past the end of the screen dec row ; reduce row back to last line sty ytemp ; save x jsr scroll ; scroll the screen ldy ytemp ; restore x _cexit: iny ; increment the string pointer y bne prn1 ; keep printing inc string+1 ; update string pointer MSB bne prn1 ; keep printing _printexit: ; we are done rts
No comments:
Post a Comment