SUB printat64 (y as uByte, x as uByte)
IF y<24 AND x<64 then
POKE @p64coords,x
POKE @p64coords+1,y
ELSE
asm
rst 8 ; error "5 Out of screen"
defb 4
end asm
END IF
END SUB
SUB print64 (characters$ as String)
ASM
; This frankencode created by Paul Fisher, Andrew Owen, Chris Born and Einar Saukas
; TODO:
; * Inverse
; * Bold (which will use a Second font)
LD L,(IX+4)
LD H,(IX+5) ; Get String address of characters$ into HL.
; Load BC with length of string, and move HL to point to first character.
ld c, (hl) ; 60020 78
inc hl ; 60021 35
ld b, (hl) ; 60022 70
inc hl ; 60023 35
; Test string length. If Zero, exit.
ld a, c ; 60024 121
or b ; 60025 176
jp z, p64_END ; 60026 200
examineChar:
ld a, (hl) ; Grab the character
cp 128 ; too high to print?
jr nc, nextChar ; then we go to next.
newLine:
cp 13 ; Is this a newline character? 60056 254 13
jr nz, p64_isPrintable ; If not, hop to testing to see if we can print this 60058 32 13
push hl
push bc
ld b,0
ld hl, p64_coords ; Get coords 60060 237 91 68 235
call BLp64_NEXT_ROW ; Go to next line. ; 60064 205 58 235
pop bc
pop hl
ld (p64_coords), de ; 60067 237 83 68 235
jr nextChar ; 60071 24 11
p64_isPrintable:
cp 31 ; Bigger than 31? 60073 254 31
jr c, nextChar ; If not, get the next one. 60075 56 7
push hl ; Save position 60077 229
push bc ; Save Count 60078 197
call p64_PrintChar ; Call Print SubRoutine
pop bc ; Recover length count 60082 193
pop hl ; Recover Position 60083 225
nextChar:
inc hl ; Point to next character 60084 35
dec bc ; Count off this character 60085 11
ld a, b ; Did we run out? 60086 120
or c ; 60087 177
jr nz, examineChar ; If not, examine the next one 60088 32 193
jp p64_END ; Otherwise hop to END. 60090 201
p64_PrintChar:
; Arrives with A as a byte to print.
ld hl,p64_coords
push hl ; save COL address for later
ld e, a ; store character value in E
ld b,0
ld c, (hl) ; store current column in BC
; Check if character font must be rotated, self-modifying the code accordingly
xor c ; compare BIT 0 from character value and column
rra
ld a, 256-(BLp64_END_LOOP-BLp64_SKIP_RLC) ; instruction DJNZ skipping rotation
jr nc, BLp64_NOT_RLC ; decide based on BIT 0 comparison
ld a, 256-(BLp64_END_LOOP-BLp64_INIT_RLC) ; instruction DJNZ using rotation
BLp64_NOT_RLC:
ld (BLp64_END_LOOP - 1), a ; modify DJNZ instruction directly
; Check the half screen byte to be changed, self-modifying the code accordingly
srl c ; check BIT 0 from current column
ld a, %00001111 ; mask to change left half of the screen byte
jr nc, BLp64_SCR_LEFT ; decide based on odd or even column
cpl ; mask to change right half of the screen byte
BLp64_SCR_LEFT:
ld (BLp64_SCR_MASK + 1), a ; modify screen mask value directly
cpl
ld (BLp64_FONT_MASK + 1), a ; modify font mask value directly
; Calculate location of the first byte to be changed on screen
; The row value is a 5 bits value (0-23), here represented as %000RRrrr
; The column value is a 6 bits value (0-63), here represented as %00CCCCCc
; Formula: 0x4000 + ((row & 0x18) << 8) + ((row & 0x07) << 5) + (col >> 1)
inc hl ; now HL references ROW address
ld a, (hl) ; now A = %000RRrrr
call 0e9eh ; now HL = %010RR000rrr00000
add hl, bc ; now HL = %010RR000rrrCCCCC
ex de, hl ; now DE = %010RR000rrrCCCCC
; and e=char -> l=char
; Calculate location of the character font data in p64_charset
; Formula: p64_charset + 7 * INT ((char-32)/2) - 1
ld h, b ; now HL = char (because b=0)
srl l ; now HL = INT (char/2)
ld c, l ; now BC = INT (char/2)
add hl, hl ; now HL = 2 * INT (char/2)
add hl, hl ; now HL = 4 * INT (char/2)
add hl, hl ; now HL = 8 * INT (char/2)
sbc hl, bc ; now HL = 7 * INT (char/2)
ld bc, p64_charset - 71h
add hl, bc ; now HL = p64_charset + 7 * INT (char/2) - 0x71
; Main loop to copy 8 font bytes into screen (1 blank + 7 from font data)
xor a ; first font byte is always blank
ld b, 8 ; execute loop 8 times
BLp64_INIT_RLC:
rlca ; switch position between bits 0-3 and bits 4-7
rlca
rlca
rlca
BLp64_SKIP_RLC:
; -----------------------------------------------------------------------------
; STANDARD OR INVERSE
;
BLp64_INV_C: nop ; either 'NOP' or 'CPL' (modified)
; -----------------------------------------------------------------------------
BLp64_FONT_MASK:
and %11110000 ; mask half of the font byte
ld c, a ; store half of the font byte in C
ld a, (de) ; get screen byte
BLp64_SCR_MASK:
and %00001111 ; mask half of the screen byte
or c ; combine half screen and half font
ld (de), a ; write result back to screen
inc d ; next screen location
inc hl ; next font data location
ld a, (hl) ; store next font byte in A
djnz BLp64_INIT_RLC ; repeat loop 8 times (this instruction gets modified)
BLp64_END_LOOP:
; attributes
ld de,(p64_coords) ; grab coords
and a ; clear carry
rr e ; divide x by 2 to get bytes instead of nybbles
ld a, d ; Get Y coord
sra a ;
sra a ;
sra a ; Multiply by 8 60155 203 47
add a, 88 ; Add to attribute base address
ld h, a ; Put high byte value for attribute into H.
ld a, d ; get y value again
and 7 ; set within third
rrca ;
rrca ;
rrca ;
add a, e ; add in x value
ld l, a ; Put low byte for attribute into l
ld a, (23693) ; Get permanent Colours from System Variable
ld (hl), a ; Write new attribute
pop hl ; restore AT_COL address
inc (hl) ; next column
bit 6, (hl) ; column lower than 64?
ret z ; return if so
BLp64_NEXT_ROW:
ld (hl), b ; reset AT_COL
inc hl ; store AT_ROW address in HL
inc (hl) ; next row
ld a, (hl)
cp 24 ; row lower than 23?
ret c ; return if so
ld (hl), b ; reset AT_ROW
ret ; done!
end asm
p64coords:
asm
p64_coords:
defb 0; X Coordinate store
defb 0; Y Coordinate Store
p64_charset: ; 60230
DEFB 2,2,2,2,0,2,0 ; Space !
DEFB 80,82,7,2,7,2,0 ; " #
DEFB 37,113,66,114,20,117,32 ; $ %
DEFB 34,84,32,96,80,96,0 ; & '
DEFB 36,66,66,66,66,36,0 ; ( )
DEFB 0,82,34,119,34,82,0 ; * +
DEFB 0,0,0,7,32,32,64 ; , -
DEFB 1,1,2,2,100,100,0 ; . /
DEFB 34,86,82,82,82,39,0 ; 0 1
DEFB 34,85,18,33,69,114,0 ; 2 3
DEFB 87,84,118,17,21,18,0 ; 4 5
DEFB 55,65,97,82,84,36,0 ; 6 7
DEFB 34,85,37,83,85,34,0 ; 8 9
DEFB 0,2,32,0,34,2,4 ; : ;
DEFB 0,16,39,64,39,16,0 ; < =
DEFB 2,69,33,18,32,66,0 ; > ?
DEFB 98,149,183,181,133,101,0 ; @ A
DEFB 98,85,100,84,85,98,0 ; B C
DEFB 103,84,86,84,84,103,0 ; D E
DEFB 114,69,116,71,69,66,0 ; F G
DEFB 87,82,114,82,82,87,0 ; H I
DEFB 53,21,22,21,85,37,0 ; J K
DEFB 69,71,71,69,69,117,0 ; L M
DEFB 82,85,117,117,85,82,0 ; N O
DEFB 98,85,85,103,71,67,0 ; P Q
DEFB 98,85,82,97,85,82,0 ; R S
DEFB 117,37,37,37,37,34,0 ; T U
DEFB 85,85,85,87,39,37,0 ; V W
DEFB 85,85,37,82,82,82,0 ; X Y
DEFB 119,20,36,36,68,119,0 ; Z [
DEFB 71,65,33,33,17,23,0 ; \ ]
DEFB 32,112,32,32,32,47,0 ; ^ _
DEFB 32,86,65,99,69,115,0 ; £ a
DEFB 64,66,101,84,85,98,0 ; b c
DEFB 16,18,53,86,84,35,0 ; d e
DEFB 32,82,69,101,67,69,2 ; f g
DEFB 66,64,102,82,82,87,0 ; h i
DEFB 20,4,53,22,21,85,32 ; j k
DEFB 64,69,71,71,85,37,0 ; l m
DEFB 0,98,85,85,85,82,0 ; n o
DEFB 0,99,85,85,99,65,65 ; p q
DEFB 0,99,84,66,65,70,0 ; r s
DEFB 64,117,69,69,85,34,0 ; t u
DEFB 0,85,85,87,39,37,0 ; v w
DEFB 0,85,85,35,81,85,2 ; x y
DEFB 0,113,18,38,66,113,0 ; z {
DEFB 32,36,34,35,34,36,0 ; | {
DEFB 6,169,86,12,6,9,6 ; ~ (c)
p64_END:
End Asm
End Sub