I was always jealous of other computers where you could redefine the fonts, so why not see if I can create a custom font rom for the apple 2.

There's an article on reactivemicro where they mention some "custom" character sets like Pigfont and ReActiveText: https://wiki.reactivemicro.com/Apple_IIe_Enhancement_Kit

So let's see what's in the Apple 2 character roms, we can just load them into the hi-res screen.

The apple 2 char rom is "reversed".

No lowercase characters here!


[Linked Image from i.imgur.com]

So let's reverse it and shift it a little bit, that looks better.

[Linked Image from i.imgur.com]

and look at the 2e rom:

[Linked Image from i.imgur.com]

and the 2c rom: (hey look, it's the running man!)

[Linked Image from i.imgur.com]

It's kind of cool to see the bit patterns that make up the lo-res colors. I think I'm finally understanding how the 560 pixel double hi-res works, it's just the same bit patterns that make up the lo-res colors.

and what if we look at some non-native character sets loaded into Apple hi-res:

(I put the apple2 configuration into black and white mode)

Colecovision:

[Linked Image from i.imgur.com]

Atari 800:
[Linked Image from i.imgur.com]

C64:
[Linked Image from i.imgur.com]

The coleco adam, pet2001 and the cpc300 char roms look pretty good too.

Code
stuck=nil
stuckmax=5000
function stuckcheck(stucklimit)
if stuck==nil then stuck =0 end
stuck=stuck+1
stucklimit=stucklimit or stuckmax
if stuck > stucklimit then print("STUCK hit loop "..stucklimit.."times") stuck=nil error("I may be STUCK in an infinite loop.  I've fallen and I can't get up") end
end

function loadfile(filename) if filename==nil then print("NO FILENAME") return nil end local f=assert(io.open(filename,"r")) local a=f:read("*a") f:close() if a==nil then print("NO DATA") else print("Loadfile (\""..filename.."\") = "..#a.." bytes read.") end return a end

function revbits(a) local r=0 for i=0,7 do r=(r<<1)+a%2 a=a>>1 end return r end

function drawblockloop(looplist,dofunc,xwrap)
--reset stuck counter
stuck=nil
looplist=looplist or {"y",8,"x",1}
xwrap = xwrap or 40  -- wrap the x at 40 bytes across, since apple screen is 40 bytes across
-- from left to right, outer --> inner
-- need to track value of each loop index and what type is it, an "x" loop or a "y" loop
-- iterate from inner out, so iterate in reverse order for i=looplevelcount,1,-1 
-- xsize (of all inners multiplied) * currentlevel value
-- and same goes for ycoordinate
-- so initialize all levels of our loop
-- and start from innermost level
-- add 1, if greater than loop size, then revert to zero and propagate the add to the next outer level
-- go up a level, add 1, if greater than bump up to next, rinse, repeat
-- if all levels done then exit
loopstate={}
looplevelcount=0
for i = 1,#looplist,2 do
  looplevelcount=looplevelcount+1
  loopstate[looplevelcount]={}
  loopstate[looplevelcount].axis=looplist[i]
  loopstate[looplevelcount].size=looplist[i+1]
  loopstate[looplevelcount].value=0
end
print(looplevelcount)
printt(loopstate)
print("Size of block should be ")
blocksize=1
for i=looplevelcount,1,-1 do
   blocksize=blocksize*loopstate[i].size 
   io.write(loopstate[i].size.." * ")
end
print("1 = "..blocksize)
index=0
while true do
stuckcheck()
-- now compute the x value
local coord=0
blocksize=1
for i=looplevelcount,1,-1 do
  if loopstate[i].axis=="x" then coord=coord+blocksize*loopstate[i].value
                                 blocksize=blocksize*loopstate[i].size 
end
end
xcoord=coord
coord=0
blocksize=1
for i=looplevelcount,1,-1 do
  if loopstate[i].axis=="y" then coord=coord+blocksize*loopstate[i].value blocksize=blocksize*loopstate[i].size 
end
end
ycoord=coord
xfinal=xcoord%xwrap
yfinal=ycoord+blocksize*math.floor(xcoord/xwrap)
dofunc(xfinal,yfinal,index)
index=index+1
-- now add 1 to inner levels
for i=looplevelcount,1,-1 do
  loopstate[i].value = loopstate[i].value + 1
  if loopstate[i].value <= loopstate[i].size-1 then break end
  loopstate[i].value = 0  -- set to value and propagate up to next level
  if i==1 then return end-- we need to stop everything since we are done
end
end
end --drawblockloop

function applemem() return manager:machine().devices[":maincpu"].spaces["program"] end

function revstring(a) local b="" for i=1,#a do b=b..string.char(revbits(a:byte(i))) end return b end
function shiftstringleft(a,numbits) local b="" for i=1,#a do b=b..string.char((a:byte(i)<<numbits)&0xff) end return b end
function andstring(a,andvalue) local b="" for i=1,#a do b=b..string.char(a:byte(i)&andvalue) end return b end
function invertstring(a) local b="" for i=1,#a do b=b..string.char(255-a:byte(i)) end return b end

Code

-- to draw the coleco font, uses a loadstring(executestr)() to execute some text code

hgr() hgrfull() hgrclr() 
filename="../../CHARSETS/coleco/r72114a_8317.u2" 
a=loadfile(filename) 
executestr="a=revstring(a) a=shiftstringleft(a,0) a=andstring(a,0x7f)" 
loadstring(executestr)()
stuckmax=16384 
startfrom=4096+4+152*8
drawblockloop({"y",16,"x",32,"y",8},function(x,y,index) applemem():write_u8(calc(y)+x,(a:sub(startfrom)):byte(index+1)) end,32) 
drawshapetext(font,filename,0,140,1,270,8) drawshapetext(font,executestr.." a:sub("..startfrom..")",0,150,1,270,10)


And one interesting discovery, though completely trivial: In studying the colecovision font, there's an error in the lowercase x, it doesn't look right.


[Linked Image from i.imgur.com]

and going to the tms9918 manual pdf, there's a picture and hex, but clearly the hex doesn't match the picture.

It should be 00 88 50 20 50 88 00.

[Linked Image from i.imgur.com]

[Linked Image from i.imgur.com]